Merge "Improve documentation of constants throughout the codebase"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 12 Apr 2019 21:38:16 +0000 (21:38 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 12 Apr 2019 21:38:16 +0000 (21:38 +0000)
2328 files changed:
.fresnel.yml
.gitignore
.phan/config.php [new file with mode: 0644]
.phan/internal_stubs/memcached.phan_php [new file with mode: 0644]
.phan/internal_stubs/oci8.phan_php [new file with mode: 0644]
.phan/internal_stubs/sqlsrv.phan_php [new file with mode: 0644]
.phan/internal_stubs/tideways.phan_php [new file with mode: 0644]
.phan/stubs/README [new file with mode: 0644]
.phan/stubs/excimer.php [new file with mode: 0644]
.phan/stubs/hhvm.php [new file with mode: 0644]
.phan/stubs/mail.php [new file with mode: 0644]
.phan/stubs/password.php [new file with mode: 0644]
.phan/stubs/phpunit4.php [new file with mode: 0644]
.phan/stubs/wikidiff.php [new file with mode: 0644]
.phpcs.xml
.travis.yml
HISTORY
INSTALL
RELEASE-NOTES-1.33
RELEASE-NOTES-1.34 [new file with mode: 0644]
autoload.php
composer.json
docs/export-0.10.xsd
docs/hooks.txt
docs/injection.txt
docs/ontology.owl
docs/sitescache.txt [deleted file]
img_auth.php
includes/ActorMigration.php
includes/AjaxResponse.php
includes/AuthPlugin.php [deleted file]
includes/AutoLoader.php
includes/Block.php
includes/Category.php
includes/CategoryViewer.php
includes/CommentStore.php
includes/ConfiguredReadOnlyMode.php
includes/ContentSecurityPolicy.php
includes/DefaultSettings.php
includes/Defines.php
includes/DevelopmentSettings.php
includes/EditPage.php
includes/FauxResponse.php [new file with mode: 0644]
includes/FeedUtils.php
includes/ForeignResourceManager.php
includes/FormOptions.php
includes/GlobalFunctions.php
includes/HeaderCallback.php
includes/HistoryBlob.php [deleted file]
includes/Html.php
includes/Linker.php
includes/MWGrants.php
includes/MWNamespace.php
includes/MagicWord.php
includes/MagicWordArray.php
includes/MediaWiki.php
includes/MediaWikiServices.php
includes/Message.php
includes/MovePage.php
includes/OutputPage.php
includes/PHPVersionCheck.php
includes/PageProps.php
includes/PathRouter.php
includes/Permissions/PermissionManager.php [new file with mode: 0644]
includes/Preferences.php [deleted file]
includes/PrefixSearch.php [deleted file]
includes/ProtectionForm.php
includes/ReadOnlyMode.php
includes/Revision.php
includes/Revision/MainSlotRoleHandler.php
includes/Revision/RevisionStore.php
includes/Revision/RevisionStoreCacheRecord.php [new file with mode: 0644]
includes/RevisionList.php [deleted file]
includes/ServiceWiring.php
includes/Setup.php
includes/SiteConfiguration.php
includes/Status.php
includes/Storage/DerivedPageDataUpdater.php
includes/Storage/NameTableStore.php
includes/Storage/SqlBlobStore.php
includes/TemplateParser.php
includes/TemplatesOnThisPageFormatter.php
includes/Title.php
includes/WebRequest.php
includes/WebRequestUpload.php
includes/WebResponse.php
includes/WikiMap.php
includes/Xml.php
includes/actions/CreditsAction.php
includes/actions/HistoryAction.php
includes/actions/McrUndoAction.php
includes/actions/RawAction.php
includes/actions/RevertAction.php
includes/actions/RollbackAction.php
includes/actions/pagers/HistoryPager.php [new file with mode: 0644]
includes/api/ApiAuthManagerHelper.php
includes/api/ApiBase.php
includes/api/ApiBlock.php
includes/api/ApiComparePages.php
includes/api/ApiContinuationManager.php
includes/api/ApiDelete.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFeedWatchlist.php
includes/api/ApiFormatBase.php
includes/api/ApiFormatPhp.php
includes/api/ApiHelp.php
includes/api/ApiImageRotate.php
includes/api/ApiLogin.php
includes/api/ApiMain.php
includes/api/ApiPageSet.php
includes/api/ApiParse.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllDeletedRevisions.php
includes/api/ApiQueryAllRevisions.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryDeletedRevisions.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryInfo.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQueryRevisionsBase.php
includes/api/ApiQuerySearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryUserContribs.php
includes/api/ApiQueryUserInfo.php
includes/api/ApiQueryUsers.php
includes/api/ApiQueryWatchlist.php
includes/api/ApiResult.php
includes/api/ApiSetNotificationTimestamp.php
includes/api/ApiStashEdit.php
includes/api/ApiUndelete.php
includes/api/ApiUpload.php
includes/api/i18n/ar.json
includes/api/i18n/cs.json
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/et.json
includes/api/i18n/fr.json
includes/api/i18n/he.json
includes/api/i18n/ja.json
includes/api/i18n/pt-br.json
includes/api/i18n/pt.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/api/i18n/sv.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zh-hant.json
includes/auth/AbstractPasswordPrimaryAuthenticationProvider.php
includes/auth/AuthManager.php
includes/auth/AuthManagerAuthPlugin.php [deleted file]
includes/auth/AuthManagerAuthPluginUser.php [deleted file]
includes/auth/AuthPluginPrimaryAuthenticationProvider.php [deleted file]
includes/auth/AuthenticationRequest.php
includes/auth/CheckBlocksSecondaryAuthenticationProvider.php
includes/auth/LocalPasswordPrimaryAuthenticationProvider.php
includes/auth/TemporaryPasswordPrimaryAuthenticationProvider.php
includes/block/BlockRestriction.php
includes/block/Restriction/AbstractRestriction.php
includes/block/Restriction/NamespaceRestriction.php
includes/block/Restriction/PageRestriction.php
includes/cache/CacheDependency.php [deleted file]
includes/cache/CacheHelper.php
includes/cache/HTMLFileCache.php
includes/cache/LinkCache.php
includes/cache/MessageBlobStore.php [deleted file]
includes/cache/MessageCache.php
includes/cache/dependency/CacheDependency.php [new file with mode: 0644]
includes/cache/dependency/ConstantDependency.php [new file with mode: 0644]
includes/cache/dependency/DependencyWrapper.php [new file with mode: 0644]
includes/cache/dependency/FileDependency.php [new file with mode: 0644]
includes/cache/dependency/GlobalDependency.php [new file with mode: 0644]
includes/cache/dependency/MainConfigDependency.php [new file with mode: 0644]
includes/cache/localisation/LCStoreCDB.php
includes/cache/localisation/LCStoreStaticArray.php
includes/cache/localisation/LocalisationCache.php
includes/changes/ChangesFeed.php
includes/changes/ChangesList.php
includes/changes/EnhancedChangesList.php
includes/changes/RCCacheEntryFactory.php
includes/changes/RecentChange.php
includes/changetags/ChangeTags.php
includes/changetags/ChangeTagsLogItem.php
includes/changetags/Taggable.php [new file with mode: 0644]
includes/clientpool/SquidPurgeClient.php
includes/collation/Collation.php
includes/collation/IcuCollation.php
includes/composer/ComposerVersionNormalizer.php
includes/config/ConfigFactory.php
includes/config/ConfigRepository.php
includes/config/EtcdConfig.php
includes/content/ContentHandler.php
includes/content/WikiTextStructure.php
includes/context/DerivativeContext.php
includes/context/RequestContext.php
includes/dao/DBAccessBase.php
includes/db/CloneDatabase.php
includes/db/DatabaseOracle.php
includes/db/MWLBFactory.php
includes/debug/DeprecationHelper.php
includes/debug/logger/MonologSpi.php
includes/debug/logger/monolog/MwlogHandler.php [new file with mode: 0644]
includes/deferred/AtomicSectionUpdate.php
includes/deferred/AutoCommitUpdate.php
includes/deferred/CdnCacheUpdate.php
includes/deferred/DeferredUpdates.php
includes/deferred/EnqueueableDataUpdate.php
includes/deferred/LinksDeletionUpdate.php
includes/deferred/LinksUpdate.php
includes/deferred/MWCallableUpdate.php
includes/deferred/WANCacheReapUpdate.php
includes/diff/DiffEngine.php
includes/diff/DifferenceEngine.php
includes/diff/RangeDifference.php [new file with mode: 0644]
includes/diff/TextSlotDiffRenderer.php
includes/editpage/TextConflictHelper.php
includes/exception/MWException.php
includes/exception/MWExceptionRenderer.php
includes/export/Dump7ZipOutput.php
includes/export/DumpLBZip2Output.php [new file with mode: 0644]
includes/export/DumpPipeOutput.php
includes/export/WikiExporter.php
includes/export/XmlDumpWriter.php
includes/externalstore/ExternalStore.php
includes/externalstore/ExternalStoreMwstore.php
includes/filebackend/FileBackendGroup.php
includes/filebackend/filejournal/DBFileJournal.php
includes/filebackend/lockmanager/LockManagerGroup.php
includes/filerepo/FileBackendDBRepoWrapper.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/file/File.php
includes/filerepo/file/ForeignAPIFile.php
includes/filerepo/file/ForeignDBFile.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php
includes/gallery/PackedHoverImageGallery.php [new file with mode: 0644]
includes/gallery/PackedOverlayImageGallery.php
includes/gallery/TraditionalImageGallery.php
includes/historyblob/ConcatenatedGzipHistoryBlob.php [new file with mode: 0644]
includes/historyblob/DiffHistoryBlob.php [new file with mode: 0644]
includes/historyblob/HistoryBlob.php [new file with mode: 0644]
includes/historyblob/HistoryBlobCurStub.php [new file with mode: 0644]
includes/historyblob/HistoryBlobStub.php [new file with mode: 0644]
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/OOUIHTMLForm.php
includes/htmlform/fields/HTMLCheckField.php
includes/htmlform/fields/HTMLDateTimeField.php
includes/htmlform/fields/HTMLExpiryField.php
includes/htmlform/fields/HTMLFormFieldWithButton.php
includes/htmlform/fields/HTMLInfoField.php
includes/htmlform/fields/HTMLNamespacesMultiselectField.php
includes/htmlform/fields/HTMLSelectAndOtherField.php
includes/htmlform/fields/HTMLTextField.php
includes/htmlform/fields/HTMLTitleTextField.php
includes/htmlform/fields/HTMLTitlesMultiselectField.php
includes/http/Http.php
includes/http/HttpRequestFactory.php
includes/http/PhpHttpRequest.php
includes/import/UploadSourceAdapter.php
includes/import/WikiImporter.php
includes/installer/CliInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/LocalSettingsGenerator.php
includes/installer/MssqlInstaller.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlInstaller.php
includes/installer/MysqlUpdater.php
includes/installer/PostgresInstaller.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteInstaller.php
includes/installer/WebInstaller.php
includes/installer/WebInstallerComplete.php
includes/installer/WebInstallerDocument.php
includes/installer/WebInstallerName.php
includes/installer/WebInstallerOptions.php
includes/installer/WebInstallerWelcome.php
includes/installer/i18n/ar.json
includes/installer/i18n/ast.json
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bg.json
includes/installer/i18n/cs.json
includes/installer/i18n/de.json
includes/installer/i18n/en.json
includes/installer/i18n/es.json
includes/installer/i18n/fa.json
includes/installer/i18n/fi.json
includes/installer/i18n/fr.json
includes/installer/i18n/ia.json
includes/installer/i18n/id.json
includes/installer/i18n/it.json
includes/installer/i18n/ko.json
includes/installer/i18n/mk.json
includes/installer/i18n/nl.json
includes/installer/i18n/pms.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/pt.json
includes/installer/i18n/qqq.json
includes/installer/i18n/ru.json
includes/installer/i18n/sh.json
includes/installer/i18n/sv.json
includes/installer/i18n/uk.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/interwiki/Interwiki.php
includes/jobqueue/GenericParameterJob.php [new file with mode: 0644]
includes/jobqueue/IJobSpecification.php
includes/jobqueue/Job.php
includes/jobqueue/JobQueue.php
includes/jobqueue/JobQueueDB.php
includes/jobqueue/JobQueueFederated.php
includes/jobqueue/JobQueueGroup.php
includes/jobqueue/JobQueueMemory.php
includes/jobqueue/JobQueueRedis.php
includes/jobqueue/JobSpecification.php
includes/jobqueue/RunnableJob.php [new file with mode: 0644]
includes/jobqueue/aggregator/JobQueueAggregator.php [deleted file]
includes/jobqueue/aggregator/JobQueueAggregatorRedis.php [deleted file]
includes/jobqueue/jobs/CategoryMembershipChangeJob.php
includes/jobqueue/jobs/CdnPurgeJob.php
includes/jobqueue/jobs/ClearUserWatchlistJob.php
includes/jobqueue/jobs/ClearWatchlistNotificationsJob.php
includes/jobqueue/jobs/DeletePageJob.php
includes/jobqueue/jobs/DuplicateJob.php
includes/jobqueue/jobs/EnqueueJob.php
includes/jobqueue/jobs/HTMLCacheUpdateJob.php
includes/jobqueue/jobs/NullJob.php
includes/jobqueue/jobs/RefreshLinksJob.php
includes/jobqueue/jobs/ThumbnailRenderJob.php
includes/jobqueue/jobs/UserGroupExpiryJob.php
includes/jobqueue/utils/PurgeJobUtils.php
includes/libs/ArrayUtils.php
includes/libs/CSSMin.php
includes/libs/CryptRand.php [deleted file]
includes/libs/DeferredStringifier.php
includes/libs/IP.php
includes/libs/MemoizedCallable.php
includes/libs/MultiHttpClient.php
includes/libs/filebackend/FSFileBackend.php
includes/libs/filebackend/FileBackend.php
includes/libs/filebackend/FileBackendMultiWrite.php
includes/libs/filebackend/FileBackendStore.php
includes/libs/jsminplus.php
includes/libs/mime/MimeAnalyzer.php
includes/libs/mime/XmlTypeCheck.php
includes/libs/objectcache/APCBagOStuff.php
includes/libs/objectcache/APCUBagOStuff.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/CachedBagOStuff.php
includes/libs/objectcache/EmptyBagOStuff.php
includes/libs/objectcache/HashBagOStuff.php
includes/libs/objectcache/IExpiringStore.php
includes/libs/objectcache/MemcachedBagOStuff.php
includes/libs/objectcache/MemcachedClient.php
includes/libs/objectcache/MemcachedPeclBagOStuff.php
includes/libs/objectcache/MemcachedPhpBagOStuff.php
includes/libs/objectcache/MultiWriteBagOStuff.php
includes/libs/objectcache/RESTBagOStuff.php
includes/libs/objectcache/RedisBagOStuff.php
includes/libs/objectcache/ReplicatedBagOStuff.php
includes/libs/objectcache/WANObjectCache.php
includes/libs/objectcache/WinCacheBagOStuff.php
includes/libs/rdbms/ChronologyProtector.php
includes/libs/rdbms/database/AtomicSectionIdentifier.php [deleted file]
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseDomain.php [deleted file]
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/MaintainableDBConnRef.php
includes/libs/rdbms/database/domain/DatabaseDomain.php [new file with mode: 0644]
includes/libs/rdbms/database/resultwrapper/ResultWrapper.php
includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php [new file with mode: 0644]
includes/libs/rdbms/encasing/MssqlBlob.php
includes/libs/rdbms/exception/DBQueryError.php
includes/libs/rdbms/exception/DBReadOnlyRoleError.php [new file with mode: 0644]
includes/libs/rdbms/exception/DBReplicationWaitError.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/lbfactory/LBFactoryMulti.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php
includes/libs/rdbms/loadmonitor/LoadMonitor.php
includes/libs/redis/RedisConnRef.php
includes/libs/redis/RedisConnectionPool.php
includes/linkeddata/PageDataRequestHandler.php
includes/logging/LogEntry.php
includes/logging/LogEventsList.php
includes/logging/LogFormatter.php
includes/logging/LogPager.php
includes/mail/EmailNotification.php
includes/media/BitmapHandler.php
includes/media/BitmapMetadataHandler.php
includes/media/DjVuHandler.php
includes/media/DjVuImage.php
includes/media/Exif.php
includes/media/GIFHandler.php
includes/media/JpegHandler.php
includes/media/MediaHandler.php
includes/media/MediaHandlerFactory.php
includes/media/MediaTransformError.php [new file with mode: 0644]
includes/media/MediaTransformOutput.php
includes/media/SVGMetadataExtractor.php
includes/media/SvgHandler.php
includes/media/ThumbnailImage.php [new file with mode: 0644]
includes/media/TransformParameterError.php [new file with mode: 0644]
includes/media/TransformTooBigImageAreaError.php [new file with mode: 0644]
includes/media/TransformationalImageHandler.php
includes/media/XCFHandler.php
includes/objectcache/ObjectCache.php
includes/objectcache/SqlBagOStuff.php
includes/page/Article.php
includes/page/ImageHistoryList.php
includes/page/ImagePage.php
includes/page/WikiFilePage.php
includes/page/WikiPage.php
includes/pager/IndexPager.php
includes/pager/RangeChronologicalPager.php
includes/pager/ReverseChronologicalPager.php
includes/pager/TablePager.php
includes/parser/BlockLevelPass.php
includes/parser/CoreParserFunctions.php
includes/parser/DateFormatter.php
includes/parser/DateFormatterFactory.php [new file with mode: 0644]
includes/parser/LinkHolderArray.php
includes/parser/Parser.php
includes/parser/ParserCache.php
includes/parser/ParserFactory.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/parser/Preprocessor.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php
includes/parser/RemexStripTagHandler.php
includes/parser/Sanitizer.php
includes/password/Password.php
includes/password/PasswordFactory.php
includes/password/UserPasswordPolicy.php
includes/poolcounter/PoolCounter.php
includes/poolcounter/PoolCounterNull.php [new file with mode: 0644]
includes/preferences/DefaultPreferencesFactory.php
includes/profiler/Profiler.php
includes/profiler/ProfilerStub.php
includes/profiler/output/ProfilerOutput.php
includes/profiler/output/ProfilerOutputText.php
includes/rcfeed/RedisPubSubFeedEngine.php
includes/rcfeed/UDPRCFeedEngine.php
includes/registration/ExtensionJsonValidator.php
includes/registration/ExtensionProcessor.php
includes/registration/ExtensionRegistry.php
includes/registration/Processor.php
includes/resourceloader/MessageBlobStore.php [new file with mode: 0644]
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderClientHtml.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderImage.php
includes/resourceloader/ResourceLoaderImageModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderOOUIFileModule.php
includes/resourceloader/ResourceLoaderOOUIModule.php
includes/resourceloader/ResourceLoaderSkinModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevDelList.php
includes/revisiondelete/RevDelLogItem.php
includes/revisionlist/RevisionItem.php [new file with mode: 0644]
includes/revisionlist/RevisionItemBase.php [new file with mode: 0644]
includes/revisionlist/RevisionList.php [new file with mode: 0644]
includes/revisionlist/RevisionListBase.php [new file with mode: 0644]
includes/search/NullIndexField.php
includes/search/PrefixSearch.php [new file with mode: 0644]
includes/search/SearchEngine.php
includes/search/SearchEngineDummy.php [new file with mode: 0644]
includes/search/SearchMySQL.php
includes/search/SearchOracle.php
includes/search/SearchPostgres.php
includes/search/SearchSqlite.php
includes/search/StringPrefixSearch.php [new file with mode: 0644]
includes/search/TitlePrefixSearch.php [new file with mode: 0644]
includes/session/CookieSessionProvider.php
includes/session/ImmutableSessionProviderWithCookie.php
includes/session/PHPSessionHandler.php
includes/session/Session.php
includes/session/SessionBackend.php
includes/session/SessionInfo.php
includes/session/SessionManager.php
includes/session/SessionProvider.php
includes/session/Token.php
includes/session/UserInfo.php
includes/shell/Command.php
includes/site/FileBasedSiteLookup.php
includes/site/Site.php
includes/site/SitesCacheFileBuilder.php [deleted file]
includes/skins/BaseTemplate.php
includes/skins/QuickTemplate.php
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specialpage/AuthManagerSpecialPage.php
includes/specialpage/ChangesListSpecialPage.php
includes/specialpage/FormSpecialPage.php
includes/specialpage/ImageQueryPage.php
includes/specialpage/QueryPage.php
includes/specialpage/RedirectSpecialArticle.php [new file with mode: 0644]
includes/specialpage/RedirectSpecialPage.php
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specialpage/SpecialRedirectToSpecial.php [new file with mode: 0644]
includes/specials/SpecialActiveusers.php
includes/specials/SpecialAllMessages.php
includes/specials/SpecialAncientpages.php
includes/specials/SpecialAutoblockList.php
includes/specials/SpecialBlock.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialBooksources.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialComparePages.php
includes/specials/SpecialConfirmemail.php
includes/specials/SpecialContributions.php
includes/specials/SpecialDeletedContributions.php
includes/specials/SpecialEditTags.php
includes/specials/SpecialEmailuser.php
includes/specials/SpecialExpandTemplates.php
includes/specials/SpecialImport.php
includes/specials/SpecialListusers.php
includes/specials/SpecialLog.php
includes/specials/SpecialMIMEsearch.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialMyRedirectPages.php [deleted file]
includes/specials/SpecialNewpages.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPagesWithProp.php
includes/specials/SpecialPasswordPolicies.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialRandomInCategory.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRecentchangeslinked.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialSearch.php
includes/specials/SpecialSpecialpages.php
includes/specials/SpecialTags.php
includes/specials/SpecialUnblock.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/specials/formfields/Licenses.php
includes/specials/forms/PreferencesFormOOUI.php
includes/specials/forms/UploadForm.php
includes/specials/helpers/ImportReporter.php
includes/specials/pagers/ActiveUsersPager.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/NewFilesPager.php
includes/specials/pagers/NewPagesPager.php
includes/specials/pagers/ProtectedPagesPager.php
includes/specials/redirects/SpecialAllMyUploads.php [new file with mode: 0644]
includes/specials/redirects/SpecialListAdmins.php [new file with mode: 0644]
includes/specials/redirects/SpecialListBots.php [new file with mode: 0644]
includes/specials/redirects/SpecialMycontributions.php [new file with mode: 0644]
includes/specials/redirects/SpecialMypage.php [new file with mode: 0644]
includes/specials/redirects/SpecialMytalk.php [new file with mode: 0644]
includes/specials/redirects/SpecialMyuploads.php [new file with mode: 0644]
includes/templates/EnhancedChangesListGroup.mustache
includes/tidy/RemexCompatFormatter.php
includes/tidy/RemexCompatMunger.php
includes/title/MediaWikiTitleCodec.php
includes/title/NamespaceInfo.php [new file with mode: 0644]
includes/upload/UploadBase.php
includes/upload/UploadStash.php
includes/user/BotPassword.php
includes/user/PasswordReset.php
includes/user/User.php
includes/utils/BatchRowUpdate.php
includes/utils/MWCryptRand.php
includes/utils/UIDGenerator.php
includes/watcheditem/NoWriteWatchedItemStore.php
includes/watcheditem/WatchedItemQueryService.php
includes/watcheditem/WatchedItemQueryServiceExtension.php
includes/watcheditem/WatchedItemStore.php
includes/watcheditem/WatchedItemStoreInterface.php
includes/widget/ExpiryInputWidget.php
includes/widget/search/InterwikiSearchResultSetWidget.php
includes/widget/search/InterwikiSearchResultWidget.php
jsduck.json
languages/Language.php
languages/LanguageConverter.php
languages/classes/LanguageFi.php
languages/classes/LanguageKk_cyrl.php
languages/i18n/ace.json
languages/i18n/aeb-arab.json
languages/i18n/ais.json
languages/i18n/an.json
languages/i18n/ar.json
languages/i18n/arq.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/avk.json
languages/i18n/az.json
languages/i18n/ba.json
languages/i18n/bcc.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.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/co.json
languages/i18n/cs.json
languages/i18n/csb.json
languages/i18n/cy.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/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/exif/ast.json
languages/i18n/exif/bg.json
languages/i18n/exif/diq.json
languages/i18n/exif/eu.json
languages/i18n/exif/fa.json
languages/i18n/exif/fy.json
languages/i18n/exif/it.json
languages/i18n/exif/ja.json
languages/i18n/exif/lb.json
languages/i18n/exif/lrc.json
languages/i18n/exif/mk.json
languages/i18n/exif/tr.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/fy.json
languages/i18n/ga.json
languages/i18n/gcr.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/gom-latn.json
languages/i18n/gu.json
languages/i18n/ha.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hif-latn.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/hyw.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ig.json
languages/i18n/ilo.json
languages/i18n/inh.json
languages/i18n/io.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kiu.json
languages/i18n/ko.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/kum.json
languages/i18n/lb.json
languages/i18n/lfn.json
languages/i18n/li.json
languages/i18n/lij.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/mai.json
languages/i18n/map-bms.json
languages/i18n/mg.json
languages/i18n/mhr.json
languages/i18n/min.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/ms.json
languages/i18n/my.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/pa.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/rue.json
languages/i18n/sah.json
languages/i18n/sat.json
languages/i18n/sc.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/sgs.json
languages/i18n/sh.json
languages/i18n/sk.json
languages/i18n/skr-arab.json
languages/i18n/sl.json
languages/i18n/so.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tay.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/tg-cyrl.json
languages/i18n/th.json
languages/i18n/tr.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vi.json
languages/i18n/war.json
languages/i18n/xmf.json
languages/i18n/yue.json
languages/i18n/zgh.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/i18n/zh-hk.json
languages/messages/MessagesCs.php
languages/messages/MessagesEn.php
languages/messages/MessagesNqo.php [new file with mode: 0644]
maintenance/7zip.inc
maintenance/Maintenance.php
maintenance/archives/patch-job-params-mediumblob.sql [new file with mode: 0644]
maintenance/benchmarks/benchmarkParse.php
maintenance/categoryChangesAsRdf.php
maintenance/cleanupInvalidDbKeys.php
maintenance/cleanupPreferences.php
maintenance/cleanupSpam.php
maintenance/cleanupTable.inc
maintenance/cleanupUsersWithNoId.php
maintenance/convertExtensionToRegistration.php
maintenance/convertLinks.php
maintenance/copyFileBackend.php
maintenance/deleteBatch.php
maintenance/deleteOrphanedRevisions.php
maintenance/dev/includes/router.php
maintenance/dev/installphp.sh
maintenance/dictionary/mediawiki.dic
maintenance/doMaintenance.php
maintenance/dumpCategoriesAsRdf.php
maintenance/dumpTextPass.php
maintenance/dumpUploads.php
maintenance/edit.php
maintenance/fetchText.php
maintenance/findHooks.php
maintenance/findMissingFiles.php
maintenance/findOrphanedFiles.php
maintenance/formatInstallDoc.php
maintenance/generateJsonI18n.php
maintenance/generateSitemap.php
maintenance/getConfiguration.php
maintenance/hhvm/makeRepo.php
maintenance/hhvm/run-server
maintenance/importDump.php
maintenance/importImages.php
maintenance/includes/BackupDumper.php
maintenance/includes/MigrateActors.php
maintenance/install.php
maintenance/jsduck/eg-iframe.html
maintenance/jsparse.php
maintenance/language/generateCollationData.php
maintenance/language/generateNormalizerDataAr.php
maintenance/language/generateNormalizerDataMl.php
maintenance/manageForeignResources.php [new file with mode: 0644]
maintenance/mctest.php
maintenance/mediawiki.Title/generateJsToUpperCaseList.js [new file with mode: 0644]
maintenance/mediawiki.Title/generatePhpCharToUpperMappings.php [new file with mode: 0755]
maintenance/mergeMessageFileList.php
maintenance/moveBatch.php
maintenance/mwdocgen.php
maintenance/mysql.php
maintenance/nukePage.php
maintenance/orphans.php
maintenance/pageExists.php
maintenance/populateBacklinkNamespace.php
maintenance/populateCategory.php
maintenance/populateContentModel.php
maintenance/populateContentTables.php
maintenance/populateImageSha1.php
maintenance/populatePPSortKey.php
maintenance/preprocessDump.php
maintenance/preprocessorFuzzTest.php
maintenance/protect.php
maintenance/purgeChangedFiles.php
maintenance/purgeChangedPages.php
maintenance/rebuildSitesCache.php [deleted file]
maintenance/rebuildrecentchanges.php
maintenance/rebuildtextindex.php
maintenance/renameDbPrefix.php
maintenance/resetUserEmail.php
maintenance/resources/foreign-resources.yaml [deleted file]
maintenance/resources/manageForeignResources.php [deleted file]
maintenance/runJobs.php
maintenance/storage/checkStorage.php
maintenance/storage/compressOld.php
maintenance/storage/dumpRev.php
maintenance/storage/recompressTracked.php
maintenance/syncFileBackend.php
maintenance/tables.sql
maintenance/undelete.php
maintenance/update.php
maintenance/updateCollation.php
maintenance/updateRestrictions.php
maintenance/updateSpecialPages.php
maintenance/validateRegistrationFile.php
maintenance/view.php
maintenance/wrapOldPasswords.php
mw-config/index.php
profileinfo.php
resources/Resources.php
resources/lib/foreign-resources.yaml [new file with mode: 0644]
resources/lib/jquery.ba-throttle-debounce.js [deleted file]
resources/lib/jquery.form.js [deleted file]
resources/lib/jquery.form/jquery.form.js [new file with mode: 0644]
resources/lib/jquery.fullscreen.js [deleted file]
resources/lib/jquery.fullscreen/jquery.fullscreen.js [new file with mode: 0644]
resources/lib/jquery.hoverIntent.js [deleted file]
resources/lib/jquery.hoverIntent/jquery.hoverIntent.js [new file with mode: 0644]
resources/lib/jquery.jStorage.js [deleted file]
resources/lib/jquery.jStorage/jstorage.js [new file with mode: 0644]
resources/lib/jquery.mockjax.js [deleted file]
resources/lib/jquery.throttle-debounce/jquery.ba-throttle-debounce.js [new file with mode: 0644]
resources/lib/jquery.ui/jquery.ui.spinner.js [deleted file]
resources/lib/jquery.ui/themes/smoothness/jquery.ui.spinner.css [deleted file]
resources/lib/jquery.xmldom.js [deleted file]
resources/lib/mustache/LICENSE
resources/lib/mustache/mustache.js
resources/lib/ooui/History.md
resources/lib/ooui/i18n/diq.json
resources/lib/ooui/i18n/fa.json
resources/lib/ooui/i18n/gl.json
resources/lib/ooui/oojs-ui-apex.js
resources/lib/ooui/oojs-ui-core-apex.css
resources/lib/ooui/oojs-ui-core-wikimediaui.css
resources/lib/ooui/oojs-ui-core.js
resources/lib/ooui/oojs-ui-core.js.map.json
resources/lib/ooui/oojs-ui-toolbars-apex.css
resources/lib/ooui/oojs-ui-toolbars-wikimediaui.css
resources/lib/ooui/oojs-ui-toolbars.js
resources/lib/ooui/oojs-ui-toolbars.js.map.json
resources/lib/ooui/oojs-ui-widgets-apex.css
resources/lib/ooui/oojs-ui-widgets-wikimediaui.css
resources/lib/ooui/oojs-ui-widgets.js
resources/lib/ooui/oojs-ui-widgets.js.map.json
resources/lib/ooui/oojs-ui-wikimediaui.js
resources/lib/ooui/oojs-ui-wikimediaui.js.map.json
resources/lib/ooui/oojs-ui-windows-apex.css
resources/lib/ooui/oojs-ui-windows-wikimediaui.css
resources/lib/ooui/oojs-ui-windows.js
resources/lib/ooui/oojs-ui-windows.js.map.json
resources/lib/ooui/themes/apex/icons-alerts.json
resources/lib/ooui/themes/apex/icons-content.json
resources/lib/ooui/themes/apex/icons-editing-citation.json
resources/lib/ooui/themes/apex/icons-interactions.json
resources/lib/ooui/themes/apex/indicators.json
resources/lib/ooui/themes/apex/textures.json
resources/lib/ooui/themes/wikimediaui/icons-accessibility.json
resources/lib/ooui/themes/wikimediaui/icons-alerts.json
resources/lib/ooui/themes/wikimediaui/icons-content.json
resources/lib/ooui/themes/wikimediaui/icons-editing-advanced.json
resources/lib/ooui/themes/wikimediaui/icons-editing-citation.json
resources/lib/ooui/themes/wikimediaui/icons-editing-core.json
resources/lib/ooui/themes/wikimediaui/icons-editing-list.json
resources/lib/ooui/themes/wikimediaui/icons-editing-styling.json
resources/lib/ooui/themes/wikimediaui/icons-interactions.json
resources/lib/ooui/themes/wikimediaui/icons-layout.json
resources/lib/ooui/themes/wikimediaui/icons-location.json
resources/lib/ooui/themes/wikimediaui/icons-media.json
resources/lib/ooui/themes/wikimediaui/icons-moderation.json
resources/lib/ooui/themes/wikimediaui/icons-movement.json
resources/lib/ooui/themes/wikimediaui/icons-user.json
resources/lib/ooui/themes/wikimediaui/icons-wikimedia.json
resources/lib/ooui/themes/wikimediaui/images/icons/add-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/add-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/add.png
resources/lib/ooui/themes/wikimediaui/images/icons/add.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alert-error.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/alert-error.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/alert-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/alert-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alert-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alert-warning.png
resources/lib/ooui/themes/wikimediaui/images/icons/alert-warning.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alert.png
resources/lib/ooui/themes/wikimediaui/images/icons/alert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter.png
resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft.png
resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignRight-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/alignRight-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignRight-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/alignRight.png
resources/lib/ooui/themes/wikimediaui/images/icons/alignRight.svg
resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articleSearch-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/articleSearch.png
resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/attachment-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/attachment-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/attachment.png
resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/beaker.png
resources/lib/ooui/themes/wikimediaui/images/icons/beaker.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bell-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bell.png
resources/lib/ooui/themes/wikimediaui/images/icons/bigger-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bigger-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bigger-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bigger.png
resources/lib/ooui/themes/wikimediaui/images/icons/bigger.svg
resources/lib/ooui/themes/wikimediaui/images/icons/block-destructive.png
resources/lib/ooui/themes/wikimediaui/images/icons/block-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/block.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-a-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-a.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-ain-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-ain.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-dad-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-dad.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-jeem-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-jeem.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-armn-to-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-armn-to.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-b-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-b.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-be-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-be.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-palochka.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-te-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-te.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-zhe-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-zhe.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-f-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-f.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-g-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-g.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-geor-man-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-geor-man.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-l-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-l-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-l.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-l.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-n-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-n-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-n-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-n.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-n.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-v-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-v-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-v-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bold-v.png
resources/lib/ooui/themes/wikimediaui/images/icons/bold-v.svg
resources/lib/ooui/themes/wikimediaui/images/icons/book-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/book-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/book-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/book-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/bookmark-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bookmark-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bookmark-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bookmark.png
resources/lib/ooui/themes/wikimediaui/images/icons/bookmark.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline.png
resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline.svg
resources/lib/ooui/themes/wikimediaui/images/icons/bright-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/bright-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/bright.png
resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/calendar-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/calendar-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/calendar-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/calendar.png
resources/lib/ooui/themes/wikimediaui/images/icons/calendar.svg
resources/lib/ooui/themes/wikimediaui/images/icons/camera-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/camera-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/camera-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/camera-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/camera.png
resources/lib/ooui/themes/wikimediaui/images/icons/camera.svg
resources/lib/ooui/themes/wikimediaui/images/icons/cancel-destructive.png
resources/lib/ooui/themes/wikimediaui/images/icons/cancel-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/cancel-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/cancel.png
resources/lib/ooui/themes/wikimediaui/images/icons/chart-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/chart-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/chart-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/chart.png
resources/lib/ooui/themes/wikimediaui/images/icons/chart.svg
resources/lib/ooui/themes/wikimediaui/images/icons/check-destructive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/check-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/check-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/check-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/check-success.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/check-success.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/check.png
resources/lib/ooui/themes/wikimediaui/images/icons/check.svg
resources/lib/ooui/themes/wikimediaui/images/icons/checkAll-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/checkAll-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/checkAll-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/checkAll.png
resources/lib/ooui/themes/wikimediaui/images/icons/checkAll.svg
resources/lib/ooui/themes/wikimediaui/images/icons/clear-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/clear-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/clear.png
resources/lib/ooui/themes/wikimediaui/images/icons/clock-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/clock-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/clock.png
resources/lib/ooui/themes/wikimediaui/images/icons/close-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/close.png
resources/lib/ooui/themes/wikimediaui/images/icons/code-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/code-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/code-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/code-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/code.png
resources/lib/ooui/themes/wikimediaui/images/icons/code.svg
resources/lib/ooui/themes/wikimediaui/images/icons/collapse-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/collapse-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/collapse-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/collapse.png
resources/lib/ooui/themes/wikimediaui/images/icons/collapse.svg
resources/lib/ooui/themes/wikimediaui/images/icons/die-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/die-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/die-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/die.png
resources/lib/ooui/themes/wikimediaui/images/icons/die.svg
resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle.png
resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle.svg
resources/lib/ooui/themes/wikimediaui/images/icons/download-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/download-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/download-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/download.png
resources/lib/ooui/themes/wikimediaui/images/icons/download.svg
resources/lib/ooui/themes/wikimediaui/images/icons/draggable-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/draggable-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/draggable-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/draggable.png
resources/lib/ooui/themes/wikimediaui/images/icons/draggable.svg
resources/lib/ooui/themes/wikimediaui/images/icons/edit-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/edit-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/edit-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/edit.png
resources/lib/ooui/themes/wikimediaui/images/icons/edit.svg
resources/lib/ooui/themes/wikimediaui/images/icons/editLock-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/editLock-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/editLock.png
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/ellipsis-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/ellipsis.png
resources/lib/ooui/themes/wikimediaui/images/icons/error-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/error-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/error-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/error-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/error.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/error.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/exitFullscreen-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/exitFullscreen-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/exitFullscreen.png
resources/lib/ooui/themes/wikimediaui/images/icons/exitFullscreen.svg
resources/lib/ooui/themes/wikimediaui/images/icons/expand-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/expand-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/expand-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/expand.png
resources/lib/ooui/themes/wikimediaui/images/icons/expand.svg
resources/lib/ooui/themes/wikimediaui/images/icons/eye-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/eye-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/eye-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/eye-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/eye.png
resources/lib/ooui/themes/wikimediaui/images/icons/eye.svg
resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed.png
resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed.svg
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/fullScreen-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/fullScreen-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/fullScreen.png
resources/lib/ooui/themes/wikimediaui/images/icons/fullScreen.svg
resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/funnel-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/funnel-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/globe-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/globe-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/globe.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/heart-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/heart.png
resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-invert.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-invert.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-progressive.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-progressive.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-invert.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-invert.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-progressive.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-progressive.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/icons/hieroglyph-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/hieroglyph.png
resources/lib/ooui/themes/wikimediaui/images/icons/highlight-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/highlight-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/highlight-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/highlight.png
resources/lib/ooui/themes/wikimediaui/images/icons/highlight.svg
resources/lib/ooui/themes/wikimediaui/images/icons/history-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/history-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/history-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/history-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/history.png
resources/lib/ooui/themes/wikimediaui/images/icons/history.svg
resources/lib/ooui/themes/wikimediaui/images/icons/image-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/image-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/image-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/image.png
resources/lib/ooui/themes/wikimediaui/images/icons/image.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/indent-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/indent-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/info-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/info-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/info.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-a-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-a.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-keheh-jeem-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-keheh-jeem.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-meem-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-meem.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-teh-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-teh.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-armn-sha-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-armn-sha.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-c-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-c.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-d-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-d.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-e-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-e-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/italic-e-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/italic-e.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-e.svg
resources/lib/ooui/themes/wikimediaui/images/icons/italic-geor-kan-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-geor-kan.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-i-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-i.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-k-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-k.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-s-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/italic-s.png
resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/key-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/key.png
resources/lib/ooui/themes/wikimediaui/images/icons/keyboard-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/keyboard-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/keyboard-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/keyboard.png
resources/lib/ooui/themes/wikimediaui/images/icons/keyboard.svg
resources/lib/ooui/themes/wikimediaui/images/icons/language-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/language-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/language.png
resources/lib/ooui/themes/wikimediaui/images/icons/largerText-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/largerText.png
resources/lib/ooui/themes/wikimediaui/images/icons/layout-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/layout-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/layout-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/layout-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/layout-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/layout-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/layout-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/layout-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/lightbulb-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/lightbulb.png
resources/lib/ooui/themes/wikimediaui/images/icons/link-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/link-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/link.png
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/linkSecure-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/linkSecure.png
resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/lock-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/lock.png
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logo-CC-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-CC.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikidata-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikidata.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Commons-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Commons.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Discovery-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Discovery.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia.svg
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikipedia-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikipedia.png
resources/lib/ooui/themes/wikimediaui/images/icons/map-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/map-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/map-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/map-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapPin-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapPin-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapPin.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapPinAdd-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapPinAdd.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail.png
resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail.svg
resources/lib/ooui/themes/wikimediaui/images/icons/markup-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/markup-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/markup-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/markup.png
resources/lib/ooui/themes/wikimediaui/images/icons/markup.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematics-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematics-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematics-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematics.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematics.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline.png
resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline.svg
resources/lib/ooui/themes/wikimediaui/images/icons/menu-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/menu.png
resources/lib/ooui/themes/wikimediaui/images/icons/message-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/message-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/message-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/message.png
resources/lib/ooui/themes/wikimediaui/images/icons/message.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moon-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/moon.png
resources/lib/ooui/themes/wikimediaui/images/icons/move-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/move-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/move-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/move.png
resources/lib/ooui/themes/wikimediaui/images/icons/move.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/musicalScore-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/musicalScore.png
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newline-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/newline-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/next-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/next-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText.png
resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText.svg
resources/lib/ooui/themes/wikimediaui/images/icons/notBright-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/notBright-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/notBright-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/notBright-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/notBright.png
resources/lib/ooui/themes/wikimediaui/images/icons/notBright.svg
resources/lib/ooui/themes/wikimediaui/images/icons/notice-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/notice-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/notice.png
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/outdent-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/outdent-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/outline-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/outline-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/outline-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/outline-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/outline-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/pageSettings-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/pageSettings.png
resources/lib/ooui/themes/wikimediaui/images/icons/pause-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/pause-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/pause-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/pause.png
resources/lib/ooui/themes/wikimediaui/images/icons/pause.svg
resources/lib/ooui/themes/wikimediaui/images/icons/play-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/play-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/play-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/play.png
resources/lib/ooui/themes/wikimediaui/images/icons/play.svg
resources/lib/ooui/themes/wikimediaui/images/icons/previous-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/previous-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/printer-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/printer-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/printer-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/printer.png
resources/lib/ooui/themes/wikimediaui/images/icons/printer.svg
resources/lib/ooui/themes/wikimediaui/images/icons/pushPin-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/pushPin-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/pushPin-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/pushPin.png
resources/lib/ooui/themes/wikimediaui/images/icons/pushPin.svg
resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/quotes-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/quotes-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/reference-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/reference-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/reference-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/reference.png
resources/lib/ooui/themes/wikimediaui/images/icons/reference.svg
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/references-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/references-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/references-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/references-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/reload-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/reload.png
resources/lib/ooui/themes/wikimediaui/images/icons/robot-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/robot-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/robot-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/robot-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/robot.png
resources/lib/ooui/themes/wikimediaui/images/icons/robot.svg
resources/lib/ooui/themes/wikimediaui/images/icons/search-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/search.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchDiacritics-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchDiacritics.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression.png
resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression.svg
resources/lib/ooui/themes/wikimediaui/images/icons/settings-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/settings-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/settings-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/settings-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/settings.png
resources/lib/ooui/themes/wikimediaui/images/icons/settings.svg
resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/smaller-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/smaller-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/smaller-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/smaller.png
resources/lib/ooui/themes/wikimediaui/images/icons/smaller.svg
resources/lib/ooui/themes/wikimediaui/images/icons/smallerText-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/smallerText.png
resources/lib/ooui/themes/wikimediaui/images/icons/specialCharacter-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/specialCharacter.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/star-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/star.png
resources/lib/ooui/themes/wikimediaui/images/icons/stop-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/stop-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/stop-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/stop.png
resources/lib/ooui/themes/wikimediaui/images/icons/stop.svg
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a.png
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a.svg
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-s-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-s.png
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y.png
resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y.svg
resources/lib/ooui/themes/wikimediaui/images/icons/stripeFlow-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeFlow-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/subscript-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/subscript-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/subtract.png
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/table-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/table-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/table-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/table-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/table.png
resources/lib/ooui/themes/wikimediaui/images/icons/table.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnAfter-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnAfter-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnAfter.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnAfter.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnBefore.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowAfter-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowAfter-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowAfter.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowAfter.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowBefore-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowBefore-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowBefore.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowBefore.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore.png
resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-destructive.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-destructive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-error.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-error.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-warning.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-warning.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-destructive.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-destructive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-error.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-error.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-warning.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-warning.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR.png
resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR.svg
resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL.png
resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL.svg
resources/lib/ooui/themes/wikimediaui/images/icons/textStyle-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/textStyle.png
resources/lib/ooui/themes/wikimediaui/images/icons/trash-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/trash.png
resources/lib/ooui/themes/wikimediaui/images/icons/tray-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/tray-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tray-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/tray.png
resources/lib/ooui/themes/wikimediaui/images/icons/tray.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unBlock.png
resources/lib/ooui/themes/wikimediaui/images/icons/unBlock.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/unLock-destructive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unLock-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/unLock-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unLock-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unLock.png
resources/lib/ooui/themes/wikimediaui/images/icons/unLock.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unStar-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/unStar.png
resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/unTrash.png
resources/lib/ooui/themes/wikimediaui/images/icons/unTrash.svg
resources/lib/ooui/themes/wikimediaui/images/icons/underline-a-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/underline-a.png
resources/lib/ooui/themes/wikimediaui/images/icons/underline-u-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/underline-u.png
resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr.svg
resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle.png
resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle.svg
resources/lib/ooui/themes/wikimediaui/images/icons/upload-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/upload-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/upload-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/upload.png
resources/lib/ooui/themes/wikimediaui/images/icons/upload.svg
resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous.png
resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous.svg
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatar-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatar.png
resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-ltr-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-rtl-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/viewCompact.png
resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-ltr.png
resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-rtl-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-rtl-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-rtl.png
resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-rtl.svg
resources/lib/ooui/themes/wikimediaui/images/icons/visionSimulator-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/visionSimulator.png
resources/lib/ooui/themes/wikimediaui/images/icons/web-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/web-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/web-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/web-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/web.png
resources/lib/ooui/themes/wikimediaui/images/icons/web.svg
resources/lib/ooui/themes/wikimediaui/images/icons/wikiText-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/wikiText-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/wikiText.png
resources/lib/ooui/themes/wikimediaui/images/icons/wikiText.svg
resources/lib/ooui/themes/wikimediaui/images/icons/window-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/window-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/window-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/window.png
resources/lib/ooui/themes/wikimediaui/images/icons/window.svg
resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn.png
resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn.svg
resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut.png
resources/lib/ooui/themes/wikimediaui/images/indicators/clear-invert.png
resources/lib/ooui/themes/wikimediaui/images/indicators/clear.png
resources/lib/ooui/themes/wikimediaui/images/indicators/down-invert.png
resources/lib/ooui/themes/wikimediaui/images/indicators/down-invert.svg
resources/lib/ooui/themes/wikimediaui/images/indicators/down.png
resources/lib/ooui/themes/wikimediaui/images/indicators/down.svg
resources/lib/ooui/themes/wikimediaui/images/indicators/required-invert.png
resources/lib/ooui/themes/wikimediaui/images/indicators/required.png
resources/lib/ooui/themes/wikimediaui/images/indicators/search-invert.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/indicators/search-invert.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/indicators/search.png [deleted file]
resources/lib/ooui/themes/wikimediaui/images/indicators/search.svg [deleted file]
resources/lib/ooui/themes/wikimediaui/images/indicators/up-invert.png
resources/lib/ooui/themes/wikimediaui/images/indicators/up-invert.svg
resources/lib/ooui/themes/wikimediaui/images/indicators/up.png
resources/lib/ooui/themes/wikimediaui/images/indicators/up.svg
resources/lib/ooui/themes/wikimediaui/images/textures/transparency.svg
resources/lib/ooui/themes/wikimediaui/indicators.json
resources/lib/ooui/themes/wikimediaui/textures.json
resources/src/jquery.spinner/images/spinner-large.gif [deleted file]
resources/src/jquery.spinner/images/spinner.gif [deleted file]
resources/src/jquery.spinner/spinner.css [deleted file]
resources/src/jquery.spinner/spinner.js
resources/src/jquery.spinner/spinner.less [new file with mode: 0644]
resources/src/jquery.tablesorter/jquery.tablesorter.js
resources/src/jquery/jquery.confirmable.js
resources/src/jquery/jquery.hidpi.js [deleted file]
resources/src/jquery/jquery.makeCollapsible.styles.less
resources/src/mediawiki.Title/.eslintrc.json [new file with mode: 0644]
resources/src/mediawiki.Title/Title.js
resources/src/mediawiki.Title/phpCharToUpper.js [deleted file]
resources/src/mediawiki.Title/phpCharToUpper.json [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.preview.js
resources/src/mediawiki.action/mediawiki.action.history.styles.css [deleted file]
resources/src/mediawiki.action/mediawiki.action.history.styles.less [new file with mode: 0644]
resources/src/mediawiki.base/mediawiki.base.js
resources/src/mediawiki.cldr/index.js [new file with mode: 0644]
resources/src/mediawiki.cookie.js [deleted file]
resources/src/mediawiki.cookie/.eslintrc.json [new file with mode: 0644]
resources/src/mediawiki.cookie/index.js [new file with mode: 0644]
resources/src/mediawiki.feedback/feedback.css
resources/src/mediawiki.feedback/feedback.js
resources/src/mediawiki.feedback/images/spinner.gif [deleted file]
resources/src/mediawiki.helplink/helplink.less
resources/src/mediawiki.helplink/images/help.png [deleted file]
resources/src/mediawiki.helplink/images/help.svg [deleted file]
resources/src/mediawiki.helplink/images/helpNotice.png [new file with mode: 0644]
resources/src/mediawiki.helplink/images/helpNotice.svg [new file with mode: 0644]
resources/src/mediawiki.htmlform.checker.js
resources/src/mediawiki.jqueryMsg/.eslintrc.json [new file with mode: 0644]
resources/src/mediawiki.jqueryMsg/mediawiki.jqueryMsg.js
resources/src/mediawiki.language/mediawiki.cldr.js [deleted file]
resources/src/mediawiki.legacy/protect.js
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.page.rollback.js [deleted file]
resources/src/mediawiki.pager.tablePager/TablePager.less
resources/src/mediawiki.rcfilters/.eslintrc.json [new file with mode: 0644]
resources/src/mediawiki.rcfilters/Controller.js
resources/src/mediawiki.rcfilters/HighlightColors.js
resources/src/mediawiki.rcfilters/UriProcessor.js
resources/src/mediawiki.rcfilters/dm/ChangesListViewModel.js
resources/src/mediawiki.rcfilters/dm/FilterGroup.js
resources/src/mediawiki.rcfilters/dm/FilterItem.js
resources/src/mediawiki.rcfilters/dm/FiltersViewModel.js
resources/src/mediawiki.rcfilters/dm/ItemModel.js
resources/src/mediawiki.rcfilters/dm/SavedQueriesModel.js
resources/src/mediawiki.rcfilters/dm/SavedQueryItemModel.js
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
resources/src/mediawiki.rcfilters/mw.rcfilters.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.less
resources/src/mediawiki.rcfilters/ui/ChangesLimitAndDateButtonWidget.js
resources/src/mediawiki.rcfilters/ui/ChangesLimitPopupWidget.js
resources/src/mediawiki.rcfilters/ui/ChangesListWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/CheckboxInputWidget.js
resources/src/mediawiki.rcfilters/ui/DatePopupWidget.js
resources/src/mediawiki.rcfilters/ui/FilterItemHighlightButton.js
resources/src/mediawiki.rcfilters/ui/FilterMenuHeaderWidget.js
resources/src/mediawiki.rcfilters/ui/FilterMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/FilterMenuSectionOptionWidget.js
resources/src/mediawiki.rcfilters/ui/FilterTagItemWidget.js
resources/src/mediawiki.rcfilters/ui/FilterTagMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/FilterWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/FormWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/GroupWidget.js
resources/src/mediawiki.rcfilters/ui/HighlightColorPickerWidget.js
resources/src/mediawiki.rcfilters/ui/HighlightPopupWidget.js
resources/src/mediawiki.rcfilters/ui/ItemMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/LiveUpdateButtonWidget.js
resources/src/mediawiki.rcfilters/ui/MainWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/MarkSeenButtonWidget.js
resources/src/mediawiki.rcfilters/ui/MenuSelectWidget.js
resources/src/mediawiki.rcfilters/ui/RcTopSectionWidget.js
resources/src/mediawiki.rcfilters/ui/RclTargetPageWidget.js
resources/src/mediawiki.rcfilters/ui/RclToOrFromWidget.js
resources/src/mediawiki.rcfilters/ui/RclTopSectionWidget.js
resources/src/mediawiki.rcfilters/ui/SaveFiltersPopupButtonWidget.js
resources/src/mediawiki.rcfilters/ui/SavedLinksListItemWidget.js
resources/src/mediawiki.rcfilters/ui/SavedLinksListWidget.js
resources/src/mediawiki.rcfilters/ui/TagItemWidget.js
resources/src/mediawiki.rcfilters/ui/ValuePickerWidget.js
resources/src/mediawiki.rcfilters/ui/ViewSwitchWidget.js
resources/src/mediawiki.rcfilters/ui/WatchlistTopSectionWidget.js
resources/src/mediawiki.rollback.confirmation.js [new file with mode: 0644]
resources/src/mediawiki.skinning/elements.css
resources/src/mediawiki.special.block.js
resources/src/mediawiki.special.changeslist.less [deleted file]
resources/src/mediawiki.special.changeslist/changeslist.less [new file with mode: 0644]
resources/src/mediawiki.special.changeslist/default.less [new file with mode: 0644]
resources/src/mediawiki.special.preferences.ooui/tabs.js
resources/src/mediawiki.special.preferences.styles.ooui.less
resources/src/mediawiki.special.recentchanges.js
resources/src/mediawiki.special.userlogin.signup.js
resources/src/mediawiki.special/apisandbox.css
resources/src/mediawiki.special/block.less
resources/src/mediawiki.special/comparepages.less
resources/src/mediawiki.special/edittags.css
resources/src/mediawiki.special/newpages.less
resources/src/mediawiki.special/pagesWithProp.css
resources/src/mediawiki.special/special.less
resources/src/mediawiki.special/upload.css
resources/src/mediawiki.special/userrights.css
resources/src/mediawiki.special/watchlist.css
resources/src/mediawiki.ui/components/checkbox.less
resources/src/mediawiki.ui/components/forms.less
resources/src/mediawiki.ui/components/radio.less
resources/src/mediawiki.user.js
resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/DateTimeInputWidget.js
resources/src/mediawiki.widgets.datetime/DiscordianDateTimeFormatter.js
resources/src/mediawiki.widgets.visibleLengthLimit/mediawiki.widgets.visibleLengthLimit.js
resources/src/mediawiki.widgets/MediaSearch/mw.widgets.MediaResultWidget.js
resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.styles.less
resources/src/mediawiki.widgets/mw.widgets.NamespacesMenuOptionWidget.js [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.NamespacesMultiselectWidget.js
resources/src/startup/mediawiki.js
resources/src/startup/startup.js
tests/common/TestSetup.php
tests/common/TestsAutoLoader.php
tests/integration/includes/shell/FirejailCommandIntegrationTest.php
tests/parser/ParserTestResultNormalizer.php
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phan/config.php [deleted file]
tests/phan/stubs/README [deleted file]
tests/phan/stubs/excimer.php [deleted file]
tests/phan/stubs/hhvm.php [deleted file]
tests/phan/stubs/mail.php [deleted file]
tests/phan/stubs/memcached.php [deleted file]
tests/phan/stubs/phpunit4.php [deleted file]
tests/phan/stubs/tideways.php [deleted file]
tests/phan/stubs/wikidiff.php [deleted file]
tests/phpunit/HamcrestPHPUnitIntegration.php
tests/phpunit/MediaWikiLoggerPHPUnitTestListener.php
tests/phpunit/MediaWikiPHPUnitCommand.php
tests/phpunit/MediaWikiPHPUnitResultPrinter.php
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/PHPUnit4And6Compat.php
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/bootstrap.php
tests/phpunit/documentation/ReleaseNotesTest.php
tests/phpunit/includes/ActorMigrationTest.php
tests/phpunit/includes/BlockTest.php
tests/phpunit/includes/CategoryTest.php [new file with mode: 0644]
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/MWNamespaceTest.php [deleted file]
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/Permissions/PermissionManagerTest.php [new file with mode: 0644]
tests/phpunit/includes/ReadOnlyModeTest.php
tests/phpunit/includes/Revision/McrReadNewRevisionStoreDbTest.php
tests/phpunit/includes/Revision/McrSchemaOverride.php
tests/phpunit/includes/Revision/McrWriteBothRevisionStoreDbTest.php
tests/phpunit/includes/Revision/NoContentModelRevisionStoreDbTest.php
tests/phpunit/includes/Revision/PreMcrRevisionStoreDbTest.php
tests/phpunit/includes/Revision/RevisionQueryInfoTest.php
tests/phpunit/includes/Revision/RevisionStoreCacheRecordTest.php [new file with mode: 0644]
tests/phpunit/includes/Revision/RevisionStoreDbTestBase.php
tests/phpunit/includes/Revision/RevisionStoreTest.php
tests/phpunit/includes/RevisionDbTestBase.php
tests/phpunit/includes/RevisionMcrReadNewDbTest.php
tests/phpunit/includes/ServiceWiringTest.php
tests/phpunit/includes/SiteStatsTest.php
tests/phpunit/includes/Storage/NameTableStoreTest.php
tests/phpunit/includes/TitleMethodsTest.php
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/WikiMapTest.php
tests/phpunit/includes/api/ApiBaseTest.php
tests/phpunit/includes/api/ApiBlockTest.php
tests/phpunit/includes/api/ApiDeleteTest.php
tests/phpunit/includes/api/ApiEditPageTest.php
tests/phpunit/includes/api/ApiMoveTest.php
tests/phpunit/includes/api/ApiParseTest.php
tests/phpunit/includes/api/ApiQuerySiteinfoTest.php
tests/phpunit/includes/api/ApiStashEditTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/api/ApiUnblockTest.php
tests/phpunit/includes/api/ApiUserrightsTest.php
tests/phpunit/includes/api/query/ApiQueryTestBase.php
tests/phpunit/includes/auth/AbstractPasswordPrimaryAuthenticationProviderTest.php
tests/phpunit/includes/auth/AuthManagerTest.php
tests/phpunit/includes/auth/AuthPluginPrimaryAuthenticationProviderTest.php [deleted file]
tests/phpunit/includes/auth/CheckBlocksSecondaryAuthenticationProviderTest.php
tests/phpunit/includes/auth/LocalPasswordPrimaryAuthenticationProviderTest.php
tests/phpunit/includes/auth/UserDataAuthenticationRequestTest.php
tests/phpunit/includes/block/Restriction/NamespaceRestrictionTest.php
tests/phpunit/includes/block/Restriction/PageRestrictionTest.php
tests/phpunit/includes/cache/MessageCacheTest.php
tests/phpunit/includes/changes/CategoryMembershipChangeTest.php
tests/phpunit/includes/changes/EnhancedChangesListTest.php
tests/phpunit/includes/changes/RCCacheEntryFactoryTest.php
tests/phpunit/includes/changetags/ChangeTagsTest.php
tests/phpunit/includes/content/ContentHandlerTest.php
tests/phpunit/includes/content/TextContentHandlerTest.php
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/db/DatabasePostgresTest.php
tests/phpunit/includes/db/DatabaseSqliteTest.php
tests/phpunit/includes/db/DatabaseTestHelper.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/db/LoadBalancerTest.php
tests/phpunit/includes/debug/logger/monolog/CeeFormatterTest.php
tests/phpunit/includes/diff/DifferenceEngineTest.php
tests/phpunit/includes/http/HttpTest.php
tests/phpunit/includes/jobqueue/JobQueueMemoryTest.php
tests/phpunit/includes/jobqueue/JobQueueTest.php
tests/phpunit/includes/jobqueue/JobTest.php
tests/phpunit/includes/jobqueue/jobs/ClearUserWatchlistJobTest.php
tests/phpunit/includes/libs/ArrayUtilsTest.php
tests/phpunit/includes/libs/objectcache/BagOStuffTest.php
tests/phpunit/includes/libs/objectcache/CachedBagOStuffTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/libs/rdbms/database/DBConnRefTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseDomainTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseMssqlTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php
tests/phpunit/includes/libs/stats/PrefixingStatsdDataFactoryProxyTest.php
tests/phpunit/includes/linkeddata/PageDataRequestHandlerTest.php
tests/phpunit/includes/linker/LinkRendererTest.php
tests/phpunit/includes/logging/UploadLogFormatterTest.php
tests/phpunit/includes/media/DjVuTest.php
tests/phpunit/includes/media/MediaWikiMediaTestCase.php
tests/phpunit/includes/media/SVGMetadataExtractorTest.php
tests/phpunit/includes/page/WikiPageDbTestBase.php
tests/phpunit/includes/parser/ParserOutputTest.php
tests/phpunit/includes/parser/SanitizerTest.php
tests/phpunit/includes/password/Pbkdf2PasswordFallbackTest.php
tests/phpunit/includes/password/UserPasswordPolicyTest.php
tests/phpunit/includes/poolcounter/PoolCounterTest.php
tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php
tests/phpunit/includes/resourceloader/DerivativeResourceLoaderContextTest.php
tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/search/SearchEngineTest.php
tests/phpunit/includes/session/SessionProviderTest.php
tests/phpunit/includes/session/TestUtils.php
tests/phpunit/includes/site/FileBasedSiteLookupTest.php [deleted file]
tests/phpunit/includes/site/SitesCacheFileBuilderTest.php [deleted file]
tests/phpunit/includes/specialpage/ChangesListSpecialPageTest.php
tests/phpunit/includes/specialpage/FormSpecialPageTestCase.php [new file with mode: 0644]
tests/phpunit/includes/specialpage/SpecialPageTest.php
tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php
tests/phpunit/includes/specials/SpecialBlockTest.php
tests/phpunit/includes/specials/SpecialPasswordResetTest.php [new file with mode: 0644]
tests/phpunit/includes/specials/SpecialWatchlistTest.php
tests/phpunit/includes/specials/pagers/BlockListPagerTest.php
tests/phpunit/includes/tidy/RemexDriverTest.php
tests/phpunit/includes/title/NamespaceInfoTest.php [new file with mode: 0644]
tests/phpunit/includes/user/PasswordResetTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/includes/watcheditem/WatchedItemQueryServiceUnitTest.php
tests/phpunit/includes/watcheditem/WatchedItemStoreIntegrationTest.php
tests/phpunit/includes/watcheditem/WatchedItemStoreUnitTest.php
tests/phpunit/maintenance/DumpAsserter.php [new file with mode: 0644]
tests/phpunit/maintenance/DumpTestCase.php
tests/phpunit/maintenance/backupTextPassTest.php
tests/phpunit/maintenance/backup_LogTest.php
tests/phpunit/maintenance/backup_PageTest.php
tests/phpunit/maintenance/categoryChangesAsRdfTest.php
tests/phpunit/maintenance/fetchTextTest.php
tests/phpunit/maintenance/xml.xsd [new file with mode: 0644]
tests/phpunit/structure/ApiStructureTest.php
tests/phpunit/structure/AutoLoaderStructureTest.php
tests/phpunit/structure/AvailableRightsTest.php
tests/phpunit/structure/PasswordPolicyStructureTest.php [new file with mode: 0644]
tests/phpunit/structure/ResourcesTest.php
tests/phpunit/structure/SpecialPageFatalTest.php
tests/phpunit/suites/ParserTestTopLevelSuite.php
tests/phpunit/tests/MediaWikiTestCaseTest.php
tests/qunit/QUnitTestResources.php
tests/qunit/data/load.mock.php
tests/qunit/data/mediawiki.loader.getScript.example.js [new file with mode: 0644]
tests/qunit/suites/resources/jquery/jquery.hidpi.test.js [deleted file]
tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js
tests/selenium/.eslintrc.json
tests/selenium/pageobjects/history.page.js
tests/selenium/specs/page.js
tests/selenium/specs/rollback.js [new file with mode: 0644]
tests/selenium/wdio-mediawiki/Api.js

index 5b7e0f2..e85de79 100644 (file)
@@ -1,12 +1,12 @@
 warmup: true
 runs: 5
 scenarios:
-  # Load a page view
-  # The only page that exists by default is the main page.
-  # But, its actual name is configurable/unknown (T216791).
-  # Omit 'title' to let MediaWiki show the defaul (which is the main page),
-  # and a query string to prevent the normalization redirect.
-  - url: "{MW_SERVER}{MW_SCRIPT_PATH}/index.php?noredirectplz"
+  Read a page:
+    # The only page that exists by default is the main page.
+    # But its actual name is configurable/unknown (T216791).
+    # Omit 'title' to let MediaWiki show the default (which is the main page),
+    # and a query string to prevent a normalization redirect.
+    url: "{MW_SERVER}{MW_SCRIPT_PATH}/index.php?noredirectplz"
     viewport:
       width: 1100
       height: 700
@@ -17,8 +17,8 @@ scenarios:
     probes:
       - screenshot
       - trace
-  # Load an 'edit' form
-  - url: "{MW_SERVER}{MW_SCRIPT_PATH}/index.php?action=edit"
+  Load the editor:
+    url: "{MW_SERVER}{MW_SCRIPT_PATH}/index.php?action=edit"
     viewport:
       width: 1100
       height: 700
@@ -29,8 +29,20 @@ scenarios:
     probes:
       - screenshot
       - trace
-  # View recent changes
-  - url: "{MW_SERVER}{MW_SCRIPT_PATH}/index.php?title=Special:RecentChanges"
+  View history of a page:
+    url: "{MW_SERVER}{MW_SCRIPT_PATH}/index.php?action=history"
+    viewport:
+      width: 1100
+      height: 700
+    reports:
+      - navtiming
+      - paint
+      - transfer
+    probes:
+      - screenshot
+      - trace
+  View recent changes:
+    url: "{MW_SERVER}{MW_SCRIPT_PATH}/index.php?title=Special:RecentChanges"
     viewport:
       width: 1100
       height: 700
index def5a08..8cacb1e 100644 (file)
@@ -50,6 +50,7 @@ sftp-config.json
 # Building & testing
 npm-debug.log
 node_modules/
+/resources/lib/.foreign
 /tests/phpunit/phpunit.phar
 /tests/selenium/log
 .eslintcache
diff --git a/.phan/config.php b/.phan/config.php
new file mode 100644 (file)
index 0000000..12e723d
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+$cfg = require __DIR__ . '/../vendor/mediawiki/mediawiki-phan-config/src/config.php';
+
+$cfg['file_list'] = array_merge(
+       $cfg['file_list'],
+       function_exists( 'register_postsend_function' ) ? [] : [ '.phan/stubs/hhvm.php' ],
+       function_exists( 'wikidiff2_do_diff' ) ? [] : [ '.phan/stubs/wikidiff.php' ],
+       class_exists( PEAR::class ) ? [] : [ '.phan/stubs/mail.php' ],
+       defined( 'PASSWORD_ARGON2I' ) ? [] : [ '.phan/stubs/password.php' ],
+       // Per composer.json, PHPUnit 6 is used for PHP 7.0+, PHPUnit 4 otherwise.
+       // Load the interface for the version of PHPUnit that isn't installed.
+       // Phan only supports PHP 7.0+ (and not HHVM), so we only need to stub PHPUnit 4.
+       class_exists( PHPUnit_TextUI_Command::class ) ? [] : [ '.phan/stubs/phpunit4.php' ],
+       class_exists( ProfilerExcimer::class ) ? [] : [ '.phan/stubs/excimer.php' ],
+       [
+               'maintenance/7zip.inc',
+               'maintenance/cleanupTable.inc',
+               'maintenance/CodeCleanerGlobalsPass.inc',
+               'maintenance/commandLine.inc',
+               'maintenance/sqlite.inc',
+               'maintenance/userDupes.inc',
+               'maintenance/language/checkLanguage.inc',
+               'maintenance/language/languages.inc',
+       ]
+);
+
+$cfg['autoload_internal_extension_signatures'] = [
+       'memcached' => '.phan/internal_stubs/memcached.phan_php',
+       'oci8' => '.phan/internal_stubs/oci8.phan_php',
+       'sqlsrv' => '.phan/internal_stubs/sqlsrv.phan_php',
+       'tideways' => '.phan/internal_stubs/tideways.phan_php',
+];
+
+$cfg['directory_list'] = [
+       'includes/',
+       'languages/',
+       'maintenance/',
+       'mw-config/',
+       'resources/',
+       'vendor/',
+       '.phan/stubs/',
+];
+
+$cfg['exclude_analysis_directory_list'] = [
+       'vendor/',
+       '.phan/stubs/',
+       // The referenced classes are not available in vendor, only when
+       // included from composer.
+       'includes/composer/',
+       // Directly references classes that only exist in Translate extension
+       'maintenance/language/',
+       // External class
+       'includes/libs/jsminplus.php',
+];
+
+$cfg['suppress_issue_types'] = array_merge( $cfg['suppress_issue_types'], [
+       // approximate error count: 18
+       "PhanAccessMethodInternal",
+       // approximate error count: 17
+       "PhanCommentParamOnEmptyParamList",
+       // approximate error count: 29
+       "PhanCommentParamWithoutRealParam",
+       // approximate error count: 2
+       "PhanCompatibleNegativeStringOffset",
+       // approximate error count: 21
+       "PhanParamReqAfterOpt",
+       // approximate error count: 26
+       "PhanParamSignatureMismatch",
+       // approximate error count: 4
+       "PhanParamSignatureMismatchInternal",
+       // approximate error count: 127
+       "PhanParamTooMany",
+       // approximate error count: 2
+       "PhanTraitParentReference",
+       // approximate error count: 30
+       "PhanTypeArraySuspicious",
+       // approximate error count: 27
+       "PhanTypeArraySuspiciousNullable",
+       // approximate error count: 26
+       "PhanTypeComparisonFromArray",
+       // approximate error count: 63
+       "PhanTypeInvalidDimOffset",
+       // approximate error count: 7
+       "PhanTypeInvalidLeftOperandOfIntegerOp",
+       // approximate error count: 2
+       "PhanTypeInvalidRightOperandOfIntegerOp",
+       // approximate error count: 154
+       "PhanTypeMismatchArgument",
+       // approximate error count: 27
+       "PhanTypeMismatchArgumentInternal",
+       // approximate error count: 2
+       "PhanTypeMismatchDimEmpty",
+       // approximate error count: 27
+       "PhanTypeMismatchDimFetch",
+       // approximate error count: 10
+       "PhanTypeMismatchForeach",
+       // approximate error count: 77
+       "PhanTypeMismatchProperty",
+       // approximate error count: 84
+       "PhanTypeMismatchReturn",
+       // approximate error count: 12
+       "PhanTypeObjectUnsetDeclaredProperty",
+       // approximate error count: 9
+       "PhanTypeSuspiciousNonTraversableForeach",
+       // approximate error count: 3
+       "PhanTypeSuspiciousStringExpression",
+       // approximate error count: 22
+       "PhanUndeclaredConstant",
+       // approximate error count: 3
+       "PhanUndeclaredInvokeInCallable",
+       // approximate error count: 237
+       "PhanUndeclaredMethod",
+       // approximate error count: 846
+       "PhanUndeclaredProperty",
+       // approximate error count: 2
+       "PhanUndeclaredVariableAssignOp",
+       // approximate error count: 55
+       "PhanUndeclaredVariableDim",
+] );
+
+$cfg['ignore_undeclared_variables_in_global_scope'] = true;
+$cfg['globals_type_map']['IP'] = 'string';
+
+return $cfg;
diff --git a/.phan/internal_stubs/memcached.phan_php b/.phan/internal_stubs/memcached.phan_php
new file mode 100644 (file)
index 0000000..8a85baf
--- /dev/null
@@ -0,0 +1,180 @@
+<?php
+// These stubs were generated by the phan stub generator.
+// @phan-stub-for-extension memcached@3.0.1
+
+namespace {
+class Memcached {
+
+    // constants
+    const LIBMEMCACHED_VERSION_HEX = 16777240;
+    const OPT_COMPRESSION = -1001;
+    const OPT_COMPRESSION_TYPE = -1004;
+    const OPT_PREFIX_KEY = -1002;
+    const OPT_SERIALIZER = -1003;
+    const OPT_USER_FLAGS = -1006;
+    const OPT_STORE_RETRY_COUNT = -1005;
+    const HAVE_IGBINARY = true;
+    const HAVE_JSON = true;
+    const HAVE_MSGPACK = true;
+    const HAVE_SESSION = true;
+    const HAVE_SASL = true;
+    const OPT_HASH = 2;
+    const HASH_DEFAULT = 0;
+    const HASH_MD5 = 1;
+    const HASH_CRC = 2;
+    const HASH_FNV1_64 = 3;
+    const HASH_FNV1A_64 = 4;
+    const HASH_FNV1_32 = 5;
+    const HASH_FNV1A_32 = 6;
+    const HASH_HSIEH = 7;
+    const HASH_MURMUR = 8;
+    const OPT_DISTRIBUTION = 9;
+    const DISTRIBUTION_MODULA = 0;
+    const DISTRIBUTION_CONSISTENT = 1;
+    const DISTRIBUTION_VIRTUAL_BUCKET = 6;
+    const OPT_LIBKETAMA_COMPATIBLE = 16;
+    const OPT_LIBKETAMA_HASH = 17;
+    const OPT_TCP_KEEPALIVE = 32;
+    const OPT_BUFFER_WRITES = 10;
+    const OPT_BINARY_PROTOCOL = 18;
+    const OPT_NO_BLOCK = 0;
+    const OPT_TCP_NODELAY = 1;
+    const OPT_SOCKET_SEND_SIZE = 4;
+    const OPT_SOCKET_RECV_SIZE = 5;
+    const OPT_CONNECT_TIMEOUT = 14;
+    const OPT_RETRY_TIMEOUT = 15;
+    const OPT_DEAD_TIMEOUT = 36;
+    const OPT_SEND_TIMEOUT = 19;
+    const OPT_RECV_TIMEOUT = 20;
+    const OPT_POLL_TIMEOUT = 8;
+    const OPT_CACHE_LOOKUPS = 6;
+    const OPT_SERVER_FAILURE_LIMIT = 21;
+    const OPT_AUTO_EJECT_HOSTS = 28;
+    const OPT_HASH_WITH_PREFIX_KEY = 25;
+    const OPT_NOREPLY = 26;
+    const OPT_SORT_HOSTS = 12;
+    const OPT_VERIFY_KEY = 13;
+    const OPT_USE_UDP = 27;
+    const OPT_NUMBER_OF_REPLICAS = 29;
+    const OPT_RANDOMIZE_REPLICA_READ = 30;
+    const OPT_REMOVE_FAILED_SERVERS = 35;
+    const OPT_SERVER_TIMEOUT_LIMIT = 37;
+    const RES_SUCCESS = 0;
+    const RES_FAILURE = 1;
+    const RES_HOST_LOOKUP_FAILURE = 2;
+    const RES_UNKNOWN_READ_FAILURE = 7;
+    const RES_PROTOCOL_ERROR = 8;
+    const RES_CLIENT_ERROR = 9;
+    const RES_SERVER_ERROR = 10;
+    const RES_WRITE_FAILURE = 5;
+    const RES_DATA_EXISTS = 12;
+    const RES_NOTSTORED = 14;
+    const RES_NOTFOUND = 16;
+    const RES_PARTIAL_READ = 18;
+    const RES_SOME_ERRORS = 19;
+    const RES_NO_SERVERS = 20;
+    const RES_END = 21;
+    const RES_ERRNO = 26;
+    const RES_BUFFERED = 32;
+    const RES_TIMEOUT = 31;
+    const RES_BAD_KEY_PROVIDED = 33;
+    const RES_STORED = 15;
+    const RES_DELETED = 22;
+    const RES_STAT = 24;
+    const RES_ITEM = 25;
+    const RES_NOT_SUPPORTED = 28;
+    const RES_FETCH_NOTFINISHED = 30;
+    const RES_SERVER_MARKED_DEAD = 35;
+    const RES_UNKNOWN_STAT_KEY = 36;
+    const RES_INVALID_HOST_PROTOCOL = 34;
+    const RES_MEMORY_ALLOCATION_FAILURE = 17;
+    const RES_CONNECTION_SOCKET_CREATE_FAILURE = 11;
+    const RES_E2BIG = 37;
+    const RES_KEY_TOO_BIG = 39;
+    const RES_SERVER_TEMPORARILY_DISABLED = 47;
+    const RES_SERVER_MEMORY_ALLOCATION_FAILURE = 48;
+    const RES_AUTH_PROBLEM = 40;
+    const RES_AUTH_FAILURE = 41;
+    const RES_AUTH_CONTINUE = 42;
+    const RES_PAYLOAD_FAILURE = -1001;
+    const SERIALIZER_PHP = 1;
+    const SERIALIZER_IGBINARY = 2;
+    const SERIALIZER_JSON = 3;
+    const SERIALIZER_JSON_ARRAY = 4;
+    const SERIALIZER_MSGPACK = 5;
+    const COMPRESSION_FASTLZ = 2;
+    const COMPRESSION_ZLIB = 1;
+    const GET_PRESERVE_ORDER = 1;
+    const GET_EXTENDED = 2;
+    const GET_ERROR_RETURN_VALUE = false;
+
+    // methods
+    public function __construct($persistent_id = null, $callback = null) {}
+    public function getResultCode() {}
+    public function getResultMessage() {}
+    public function get($key, $cache_cb = null, $get_flags = null) {}
+    public function getByKey($server_key, $key, $cache_cb = null, $get_flags = null) {}
+    public function getMulti(array $keys, $get_flags = null) {}
+    public function getMultiByKey($server_key, array $keys, $get_flags = null) {}
+    public function getDelayed(array $keys, $with_cas = null, $value_cb = null) {}
+    public function getDelayedByKey($server_key, array $keys, $with_cas = null, $value_cb = null) {}
+    public function fetch() {}
+    public function fetchAll() {}
+    public function set($key, $value, $expiration = null) {}
+    public function setByKey($server_key, $key, $value, $expiration = null) {}
+    public function touch($key, $expiration) {}
+    public function touchByKey($server_key, $key, $expiration) {}
+    public function setMulti(array $items, $expiration = null) {}
+    public function setMultiByKey($server_key, array $items, $expiration = null) {}
+    public function cas($cas_token, $key, $value, $expiration = null) {}
+    public function casByKey($cas_token, $server_key, $key, $value, $expiration = null) {}
+    public function add($key, $value, $expiration = null) {}
+    public function addByKey($server_key, $key, $value, $expiration = null) {}
+    public function append($key, $value, $expiration = null) {}
+    public function appendByKey($server_key, $key, $value, $expiration = null) {}
+    public function prepend($key, $value, $expiration = null) {}
+    public function prependByKey($server_key, $key, $value, $expiration = null) {}
+    public function replace($key, $value, $expiration = null) {}
+    public function replaceByKey($server_key, $key, $value, $expiration = null) {}
+    public function delete($key, $time = null) {}
+    public function deleteMulti($keys, $time = null) {}
+    public function deleteByKey($server_key, $key, $time = null) {}
+    public function deleteMultiByKey($server_key, $keys, $time = null) {}
+    public function increment($key, $offset = null, $initial_value = null, $expiry = null) {}
+    public function decrement($key, $offset = null, $initial_value = null, $expiry = null) {}
+    public function incrementByKey($server_key, $key, $offset = null, $initial_value = null, $expiry = null) {}
+    public function decrementByKey($server_key, $key, $offset = null, $initial_value = null, $expiry = null) {}
+    public function addServer($host, $port, $weight = null) {}
+    public function addServers(array $servers) {}
+    public function getServerList() {}
+    public function getServerByKey($server_key) {}
+    public function resetServerList() {}
+    public function quit() {}
+    public function flushBuffers() {}
+    public function getLastErrorMessage() {}
+    public function getLastErrorCode() {}
+    public function getLastErrorErrno() {}
+    public function getLastDisconnectedServer() {}
+    public function getStats($args) {}
+    public function getVersion() {}
+    public function getAllKeys() {}
+    public function flush($delay = null) {}
+    public function getOption($option) {}
+    public function setOption($option, $value) {}
+    public function setOptions($options) {}
+    public function setBucket($host_map, $forward_map, $replicas) {}
+    public function setSaslAuthData($username, $password) {}
+    public function isPersistent() {}
+    public function isPristine() {}
+}
+
+class MemcachedException extends \RuntimeException {
+
+    // properties
+    protected $message;
+    protected $code;
+    protected $file;
+    protected $line;
+}
+
+}
diff --git a/.phan/internal_stubs/oci8.phan_php b/.phan/internal_stubs/oci8.phan_php
new file mode 100644 (file)
index 0000000..78f334e
--- /dev/null
@@ -0,0 +1,589 @@
+<?php
+
+// @phan-stub-for-extension oci8@2.0.7
+
+
+class OCI_Lob  {
+
+       
+       public function load () {}
+
+       
+       public function tell () {}
+
+       
+       public function truncate ($length = 0) {}
+
+       
+       public function erase ($offset = null, $length = null) {}
+
+       
+       public function flush ($flag = null) {}
+
+       
+       public function setbuffering ($on_off) {}
+
+       
+       public function getbuffering () {}
+
+       
+       public function rewind () {}
+
+       
+       public function read ($length) {}
+
+       
+       public function eof () {}
+
+       
+       public function seek ($offset, $whence = OCI_SEEK_SET) {}
+
+       
+       public function write ($data, $length = null) {}
+
+       
+       public function append (OCI_Lob $lob_from) {}
+
+       
+       public function size () {}
+
+       
+       public function writetofile ($filename, $start, $length) {}
+
+       
+       public function export ($filename, $start = null, $length = null) {}
+
+       
+       public function import ($filename) {}
+
+       
+       public function writeTemporary ($data, $lob_type = OCI_TEMP_CLOB) {}
+
+       
+       public function close () {}
+
+       
+       public function save ($data, $offset = null) {}
+
+       
+       public function savefile ($filename) {}
+
+       
+       public function free () {}
+
+}
+
+
+class OCI_Collection  {
+
+       
+       public function append ($value) {}
+
+       
+       public function getelem ($index) {}
+
+       
+       public function assignelem ($index, $value) {}
+
+       
+       public function assign (OCI_Collection $from) {}
+
+       
+       public function size () {}
+
+       
+       public function max () {}
+
+       
+       public function trim ($num) {}
+
+       
+       public function free () {}
+
+}
+
+
+function oci_define_by_name ($statement, $column_name, &$variable, $type = SQLT_CHR) {}
+
+
+function oci_bind_by_name ($statement, $bv_name, &$variable, $maxlength = -1, $type = SQLT_CHR) {}
+
+
+function oci_bind_array_by_name ($statement, $name, array &$var_array, $max_table_length, $max_item_length = -1, $type = SQLT_AFC) {}
+
+
+function oci_field_is_null ($statement, $field) {}
+
+
+function oci_field_name ($statement, $field) {}
+
+
+function oci_field_size ($statement, $field) {}
+
+
+function oci_field_scale ($statement, $field) {}
+
+
+function oci_field_precision ($statement, $field) {}
+
+
+function oci_field_type ($statement, $field) {}
+
+
+function oci_field_type_raw ($statement, $field) {}
+
+
+function oci_execute ($statement, $mode = OCI_COMMIT_ON_SUCCESS) {}
+
+
+function oci_cancel ($statement) {}
+
+
+function oci_fetch ($statement) {}
+
+
+function oci_fetch_object ($statement) {}
+
+
+function oci_fetch_row ($statement) {}
+
+
+function oci_fetch_assoc ($statement) {}
+
+
+function oci_fetch_array ($statement, $mode = null) {}
+
+
+function ocifetchinto ($statement_resource, &$result, $mode = null) {}
+
+
+function oci_fetch_all ($statement, array &$output, $skip = 0, $maxrows = -1, $flags = OCI_FETCHSTATEMENT_BY_COLUMN | OCI_ASSOC) {}
+
+
+function oci_free_statement ($statement) {}
+
+
+function oci_internal_debug ($onoff) {}
+
+
+function oci_num_fields ($statement) {}
+
+
+function oci_parse ($connection, $sql_text) {}
+
+
+function oci_get_implicit_resultset ($statement) {}
+
+
+function oci_new_cursor ($connection) {}
+
+
+function oci_result ($statement, $field) {}
+
+
+function oci_client_version () {}
+
+
+function oci_server_version ($connection) {}
+
+
+function oci_statement_type ($statement) {}
+
+
+function oci_num_rows ($statement) {}
+
+
+function oci_close ($connection) {}
+
+
+function oci_connect ($username, $password, $connection_string = null, $character_set = null, $session_mode = null) {}
+
+
+function oci_new_connect ($username, $password, $connection_string = null, $character_set = null, $session_mode = null) {}
+
+
+function oci_pconnect ($username, $password, $connection_string = null, $character_set = null, $session_mode = null) {}
+
+
+function oci_error ($resource = null) {}
+
+
+function oci_free_descriptor ($descriptor) {}
+
+
+function oci_lob_is_equal (OCI_Lob $lob1, OCI_Lob $lob2) {}
+
+
+function oci_lob_copy (OCI_Lob $lob_to, OCI_Lob $lob_from, $length = 0) {}
+
+
+function oci_commit ($connection) {}
+
+
+function oci_rollback ($connection) {}
+
+
+function oci_new_descriptor ($connection, $type = OCI_DTYPE_LOB) {}
+
+
+function oci_set_prefetch ($statement, $rows) {}
+
+
+function oci_set_client_identifier ($connection, $client_identifier) {}
+
+
+function oci_set_edition ($edition) {}
+
+
+function oci_set_module_name ($connection, $module_name) {}
+
+
+function oci_set_action ($connection, $action_name) {}
+
+
+function oci_set_client_info ($connection, $client_info) {}
+
+
+function oci_password_change ($connection, $username, $old_password, $new_password) {}
+
+
+function oci_new_collection ($connection, $tdo, $schema = null) {}
+
+
+function oci_free_cursor ($statement_resource) {}
+
+
+function ocifreecursor ($statement_resource) {}
+
+
+function ocibindbyname ($statement, $column_name, &$variable, $maximum_length = -1, $type = SQLT_CHR) {}
+
+
+function ocidefinebyname ($statement, $column_name, &$variable, $type = SQLT_CHR) {}
+
+
+function ocicolumnisnull ($statement, $column_number_or_name) {}
+
+
+function ocicolumnname ($statement, $column_number) {}
+
+
+function ocicolumnsize ($statement, $column_number_or_name) {}
+
+
+function ocicolumnscale ($statement_resource, $column_number) {}
+
+
+function ocicolumnprecision ($statement_resource, $column_number) {}
+
+
+function ocicolumntype ($statement_resource, $column_number) {}
+
+
+function ocicolumntyperaw ($statement_resource, $column_number) {}
+
+
+function ociexecute ($statement_resource, $mode = OCI_COMMIT_ON_SUCCESS) {}
+
+
+function ocicancel ($statement_resource) {}
+
+
+function ocifetch ($statement_resource) {}
+
+
+function ocifetchstatement ($statement_resource, &$output, $skip, $maximum_rows, $flags) {}
+
+
+function ocifreestatement ($statement_resource) {}
+
+
+function ociinternaldebug ($mode) {}
+
+
+function ocinumcols ($statement_resource) {}
+
+
+function ociparse ($connection_resource, $sql_text) {}
+
+
+function ocinewcursor ($connection_resource) {}
+
+
+function ociresult ($statement_resource, $column_number_or_name) {}
+
+
+function ociserverversion ($connection_resource) {}
+
+
+function ocistatementtype ($statement_resource) {}
+
+
+function ocirowcount ($statement_resource) {}
+
+
+function ocilogoff ($connection_resource) {}
+
+
+function ocilogon ($username, $password, $connection_string, $character_set, $session_mode) {}
+
+
+function ocinlogon ($username, $password, $connection_string, $character_set, $session_mode) {}
+
+
+function ociplogon ($username, $password, $connection_string, $character_set, $session_mode) {}
+
+
+function ocierror ($connection_or_statement_resource) {}
+
+
+function ocifreedesc ($lob_descriptor) {}
+
+
+function ocisavelob ($lob_descriptor, $data, $offset) {}
+
+
+function ocisavelobfile ($lob_descriptor, $filename) {}
+
+
+function ociwritelobtofile ($lob_descriptor, $filename, $start, $length) {}
+
+
+function ociloadlob ($lob_descriptor) {}
+
+
+function ocicommit ($connection_resource) {}
+
+
+function ocirollback ($connection_resource) {}
+
+
+function ocinewdescriptor ($connection_resource, $type = OCI_DTYPE_LOB) {}
+
+
+function ocisetprefetch ($statement_resource, $number_of_rows) {}
+
+
+function ocipasswordchange ($connection_resource_or_connection_string_or_dbname, $username, $old_password, $new_password) {}
+
+
+function ocifreecollection ($collection) {}
+
+
+function ocinewcollection ($connection_resource, $tdo, $schema = null) {}
+
+
+function ocicollappend ($collection, $value) {}
+
+
+function ocicollgetelem ($collection, $index) {}
+
+
+function ocicollassignelem ($collection, $index, $value) {}
+
+
+function ocicollsize ($collection) {}
+
+
+function ocicollmax ($collection) {}
+
+
+function ocicolltrim ($collection, $number) {}
+
+
+
+function ociwritetemporarylob($lob_descriptor, $data, $lob_type = OCI_TEMP_CLOB ) {}
+
+
+function ocicloselob($lob_descriptor){}
+
+
+function ocicollassign($to, $from ) {}
+
+define ('OCI_DEFAULT', 0);
+
+
+define ('OCI_SYSOPER', 4);
+
+
+define ('OCI_SYSDBA', 2);
+
+
+define ('OCI_CRED_EXT', -2147483648);
+
+
+define ('OCI_DESCRIBE_ONLY', 16);
+
+
+define ('OCI_COMMIT_ON_SUCCESS', 32);
+
+
+define ('OCI_NO_AUTO_COMMIT', 0);
+
+
+define ('OCI_EXACT_FETCH', 2);
+
+
+define ('OCI_SEEK_SET', 0);
+
+
+define ('OCI_SEEK_CUR', 1);
+
+
+define ('OCI_SEEK_END', 2);
+
+
+define ('OCI_LOB_BUFFER_FREE', 1);
+
+
+define ('SQLT_BFILEE', 114);
+
+
+define ('SQLT_CFILEE', 115);
+
+
+define ('SQLT_CLOB', 112);
+
+
+define ('SQLT_BLOB', 113);
+
+
+define ('SQLT_RDD', 104);
+
+
+define ('SQLT_INT', 3);
+
+
+define ('SQLT_NUM', 2);
+
+
+define ('SQLT_RSET', 116);
+
+
+define ('SQLT_AFC', 96);
+
+
+define ('SQLT_CHR', 1);
+
+
+define ('SQLT_VCS', 9);
+
+
+define ('SQLT_AVC', 97);
+
+
+define ('SQLT_STR', 5);
+
+
+define ('SQLT_LVC', 94);
+
+
+define ('SQLT_FLT', 4);
+
+
+define ('SQLT_UIN', 68);
+
+
+define ('SQLT_LNG', 8);
+
+
+define ('SQLT_LBI', 24);
+
+
+define ('SQLT_BIN', 23);
+
+
+define ('SQLT_ODT', 156);
+
+
+define ('SQLT_BDOUBLE', 22);
+
+
+define ('SQLT_BFLOAT', 21);
+
+
+define ('OCI_B_NTY', 108);
+
+
+define ('SQLT_NTY', 108);
+
+
+define ('OCI_SYSDATE', "SYSDATE");
+
+
+define ('OCI_B_BFILE', 114);
+
+
+define ('OCI_B_CFILEE', 115);
+
+
+define ('OCI_B_CLOB', 112);
+
+
+define ('OCI_B_BLOB', 113);
+
+
+define ('OCI_B_ROWID', 104);
+
+
+define ('OCI_B_CURSOR', 116);
+
+
+define ('OCI_B_BIN', 23);
+
+
+define ('OCI_B_INT', 3);
+
+
+define ('OCI_B_NUM', 2);
+
+
+define ('OCI_FETCHSTATEMENT_BY_COLUMN', 16);
+
+
+define ('OCI_FETCHSTATEMENT_BY_ROW', 32);
+
+
+define ('OCI_ASSOC', 1);
+
+
+define ('OCI_NUM', 2);
+
+
+define ('OCI_BOTH', 3);
+
+
+define ('OCI_RETURN_NULLS', 4);
+
+
+define ('OCI_RETURN_LOBS', 8);
+
+
+define ('OCI_DTYPE_FILE', 56);
+
+
+define ('OCI_DTYPE_LOB', 50);
+
+
+define ('OCI_DTYPE_ROWID', 54);
+
+
+define ('OCI_D_FILE', 56);
+
+
+define ('OCI_D_LOB', 50);
+
+
+define ('OCI_D_ROWID', 54);
+
+
+define ('OCI_TEMP_CLOB', 2);
+
+
+define ('OCI_TEMP_BLOB', 1);
+
+
+define ('SQLT_BOL', 252);
+
+
+define ('OCI_B_BOL', 252);
diff --git a/.phan/internal_stubs/sqlsrv.phan_php b/.phan/internal_stubs/sqlsrv.phan_php
new file mode 100644 (file)
index 0000000..3fea0af
--- /dev/null
@@ -0,0 +1,276 @@
+<?php
+// @phan-stub-for-extension sqlsrv@3.0.1
+
+define('SQLSRV_ERR_ERRORS', 0);
+
+
+define('SQLSRV_ERR_WARNINGS', 1);
+
+
+define('SQLSRV_ERR_ALL', 2);
+
+
+define('SQLSRV_LOG_SYSTEM_ALL',-1);
+
+
+define('SQLSRV_LOG_SYSTEM_OFF', 0);
+
+
+define('SQLSRV_LOG_SYSTEM_INIT', 1);
+
+
+define('SQLSRV_LOG_SYSTEM_CONN', 2);
+
+
+define('SQLSRV_LOG_SYSTEM_STMT', 4);
+
+
+define('SQLSRV_LOG_SYSTEM_UTIL', 8);
+
+
+define('SQLSRV_LOG_SEVERITY_ALL', -1);
+
+
+define('SQLSRV_LOG_SEVERITY_ERROR', 1);
+
+
+define('SQLSRV_LOG_SEVERITY_NOTICE', 4);
+
+
+define('SQLSRV_LOG_SEVERITY_WARNING', 2);
+
+
+define('SQLSRV_FETCH_NUMERIC', 1);
+
+
+define('SQLSRV_FETCH_ASSOC', 2);
+
+
+define('SQLSRV_FETCH_BOTH', 3);
+
+
+define('SQLSRV_PHPTYPE_NULL', 1);
+
+
+define('SQLSRV_PHPTYPE_INT', 2);
+
+
+define('SQLSRV_PHPTYPE_FLOAT', 3);
+
+
+define('SQLSRV_PHPTYPE_DATETIME', 4);
+
+
+define('SQLSRV_ENC_BINARY', 'binary');
+
+
+define('SQLSRV_ENC_CHAR','char');
+
+
+define('SQLSRV_NULLABLE_NO', 0);
+
+
+define('SQLSRV_NULLABLE_YES', 1);
+
+
+define('SQLSRV_NULLABLE_UNKNOWN', 2);
+
+
+define('SQLSRV_SQLTYPE_BIGINT', -5);
+
+define('SQLSRV_SQLTYPE_BIT', -7);
+
+define('SQLSRV_SQLTYPE_DATETIME', 25177693);
+
+define('SQLSRV_SQLTYPE_FLOAT', 6);
+
+define('SQLSRV_SQLTYPE_IMAGE', -4);
+
+define('SQLSRV_SQLTYPE_INT', 4);
+
+define('SQLSRV_SQLTYPE_MONEY', 33564163);
+
+define('SQLSRV_SQLTYPE_NTEXT', -10);
+
+define('SQLSRV_SQLTYPE_TEXT', -1);
+
+define('SQLSRV_SQLTYPE_REAL', 7);
+
+define('SQLSRV_SQLTYPE_SMALLDATETIME', 8285);
+
+define('SQLSRV_SQLTYPE_SMALLINT', 5);
+
+define('SQLSRV_SQLTYPE_SMALLMONEY', 33559555);
+
+define('SQLSRV_SQLTYPE_TIMESTAMP', 4606);
+
+define('SQLSRV_SQLTYPE_TINYINT', -6);
+
+define('SQLSRV_SQLTYPE_UDT', -151);
+
+define('SQLSRV_SQLTYPE_UNIQUEIDENTIFIER', -11);
+
+define('SQLSRV_SQLTYPE_XML', -152);
+
+define('SQLSRV_SQLTYPE_DATE', 5211);
+
+define('SQLSRV_SQLTYPE_TIME', 58728806);
+
+define('SQLSRV_SQLTYPE_DATETIMEOFFSET', 58738021);
+
+define('SQLSRV_SQLTYPE_DATETIME2', 58734173);
+
+
+define('SQLSRV_PARAM_IN', 1);
+
+
+define('SQLSRV_PARAM_INOUT', 2);
+
+
+define('SQLSRV_PARAM_OUT', 4);
+
+
+define('SQLSRV_TXN_READ_UNCOMMITTED', 1);
+
+define('SQLSRV_TXN_READ_COMMITTED', 2);
+
+define('SQLSRV_TXN_REPEATABLE_READ', 4);
+
+define('SQLSRV_TXN_SERIALIZABLE', 8);
+
+define('SQLSRV_TXN_SNAPSHOT', 32);
+
+
+define('SQLSRV_SCROLL_NEXT', 1);
+
+define('SQLSRV_SCROLL_PRIOR', 4);
+
+define('SQLSRV_SCROLL_FIRST', 2);
+
+define('SQLSRV_SCROLL_LAST', 3);
+
+define('SQLSRV_SCROLL_ABSOLUTE', 5);
+
+define('SQLSRV_SCROLL_RELATIVE', 6);
+
+
+define('SQLSRV_CURSOR_FORWARD', 'forward');
+
+define('SQLSRV_CURSOR_STATIC', 'static');
+
+define('SQLSRV_CURSOR_DYNAMIC', 'dynamic');
+
+define('SQLSRV_CURSOR_KEYSET', 'keyset');
+
+define('SQLSRV_CURSOR_CLIENT_BUFFERED', 'buffered');
+
+
+
+function sqlsrv_connect($server_name, $connection_info = array()){}
+
+
+function sqlsrv_close($conn){}
+
+
+function sqlsrv_commit($conn){}
+
+
+function sqlsrv_begin_transaction($conn){}
+
+
+function sqlsrv_rollback($conn){}
+
+
+function sqlsrv_errors($errorsAndOrWarnings = SQLSRV_ERR_ALL){}
+
+
+function sqlsrv_configure($setting, $value){}
+
+
+function sqlsrv_get_config($setting){}
+
+
+function sqlsrv_prepare($conn, $tsql, $params=array(), $options=array()){}
+
+
+function sqlsrv_execute($stmt){}
+
+
+function sqlsrv_query($conn, $tsql, $params=array(), $options=array()){}
+
+
+function sqlsrv_fetch($stmt, $row=null, $offset=null){}
+
+
+function sqlsrv_get_field($stmt, $field_index, $get_as_type){}
+
+
+function sqlsrv_fetch_array($stmt, $fetch_type = null, $row=null, $offset=null){}
+
+
+function sqlsrv_fetch_object($stmt, $class_name=null, $ctor_params=null, $row=null, $offset=null){}
+
+
+function sqlsrv_has_rows($stmt){}
+
+
+function sqlsrv_num_fields($stmt){}
+
+
+function sqlsrv_next_result($stmt){}
+
+
+function sqlsrv_num_rows($stmt){}
+
+
+function sqlsrv_rows_affected($stmt){}
+
+
+function sqlsrv_client_info($conn){}
+
+
+function sqlsrv_server_info($conn){}
+
+
+function sqlsrv_cancel($stmt){}
+
+
+function sqlsrv_free_stmt($stmt){}
+
+
+function sqlsrv_field_metadata($stmt){}
+
+
+function sqlsrv_send_stream_data($stmt){}
+
+
+function SQLSRV_PHPTYPE_STREAM($encoding){}
+
+
+function SQLSRV_PHPTYPE_STRING($encoding){}
+
+
+function SQLSRV_SQLTYPE_BINARY($byteCount){}
+
+
+function SQLSRV_SQLTYPE_VARBINARY($byteCount){}
+
+
+
+function SQLSRV_SQLTYPE_VARCHAR($charCount) {}
+
+
+function SQLSRV_SQLTYPE_CHAR($charCount){}
+
+
+function SQLSRV_SQLTYPE_NCHAR($charCount){}
+
+
+function SQLSRV_SQLTYPE_NVARCHAR($charCount){}
+
+
+function SQLSRV_SQLTYPE_DECIMAL($precision, $scale){}
+
+
+function SQLSRV_SQLTYPE_NUMERIC($precision, $scale){}
+
diff --git a/.phan/internal_stubs/tideways.phan_php b/.phan/internal_stubs/tideways.phan_php
new file mode 100644 (file)
index 0000000..d87a6e4
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+// These stubs were generated by the phan stub generator.
+// @phan-stub-for-extension tideways@4.0.7
+
+namespace {
+function tideways_disable() {}
+function tideways_enable($flags = null, $options = null) {}
+function tideways_fatal_backtrace() {}
+function tideways_get_spans() {}
+function tideways_last_detected_exception() {}
+function tideways_last_fatal_error() {}
+function tideways_prepend_overwritten() {}
+function tideways_span_annotate($span = null, $annotations = null) {}
+function tideways_span_callback($name = null, $callback = null) {}
+function tideways_span_create($category = null) {}
+function tideways_span_timer_start($span = null) {}
+function tideways_span_timer_stop($span = null) {}
+function tideways_span_watch($name = null, $category = null) {}
+function tideways_sql_minify($sql = null) {}
+function tideways_transaction_name() {}
+const TIDEWAYS_FLAGS_CPU = 2;
+const TIDEWAYS_FLAGS_MEMORY = 4;
+const TIDEWAYS_FLAGS_NO_BUILTINS = 1;
+const TIDEWAYS_FLAGS_NO_COMPILE = 16;
+const TIDEWAYS_FLAGS_NO_HIERACHICAL = 64;
+const TIDEWAYS_FLAGS_NO_SPANS = 32;
+const TIDEWAYS_FLAGS_NO_USERLAND = 8;
+}
diff --git a/.phan/stubs/README b/.phan/stubs/README
new file mode 100644 (file)
index 0000000..c458ab5
--- /dev/null
@@ -0,0 +1,3 @@
+These stubs describe how code that is not available at analysis time should be
+used. No implementations are necessary, just define the classes and their
+methods and use phpdoc to describe what arguments are allowed.
diff --git a/.phan/stubs/excimer.php b/.phan/stubs/excimer.php
new file mode 100644 (file)
index 0000000..e87d4cd
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+
+// phpcs:ignoreFile
+
+define( 'EXCIMER_REAL', 0 );
+define( 'EXCIMER_CPU', 1 );
+
+class ExcimerProfiler {
+       public function __construct() {
+       }
+       public function setPeriod( $period ) {
+       }
+       public function setEventType( $event_type ) {
+       }
+       public function setMaxDepth( $maxDepth ) {
+       }
+       public function setFlushCallback( $callback, $max_samples ) {
+       }
+       public function clearFlushCallback() {
+       }
+       public function start() {
+       }
+       public function stop() {
+       }
+       public function getLog() {
+       }
+       public function flush() {
+       }
+}
+
+class ExcimerLog {
+       private final function __construct() {
+       }
+       function formatCollapsed() {
+       }
+       function aggregateByFunction() {
+       }
+       function getEventCount() {
+       }
+       function current() {
+       }
+       function key() {
+       }
+       function next() {
+       }
+       function rewind() {
+       }
+       function valid() {
+       }
+       function count() {
+       }
+       function offsetExists( $offset ) {
+       }
+       function offsetGet( $offset ) {
+       }
+       function offsetSet( $offset, $value ) {
+       }
+       function offsetUnset( $offset ) {
+       }
+
+}
+
+class ExcimerLogEntry {
+       private final function __construct() {
+       }
+       function getTimestamp() {
+       }
+       function getEventCount() {
+       }
+       function getTrace() {
+       }
+}
+
+class ExcimerTimer {
+       function setEventType( $event_type ) {
+       }
+       function setInterval( $interval ) {
+       }
+       function setPeriod( $period ) {
+       }
+       function setCallback( $callback ) {
+       }
+       function start() {
+       }
+       function stop() {
+       }
+       function getTime() {
+       }
+}
diff --git a/.phan/stubs/hhvm.php b/.phan/stubs/hhvm.php
new file mode 100644 (file)
index 0000000..090bdfe
--- /dev/null
@@ -0,0 +1,28 @@
+<?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
+ */
+
+// phpcs:ignoreFile
+
+define( 'HHVM_VERSION', '3.18.6-dev' );
+
+/**
+ * @param callable $callback
+ * @param mixed ...$parameters
+ */
+function register_postsend_function( $callback ) {
+}
diff --git a/.phan/stubs/mail.php b/.phan/stubs/mail.php
new file mode 100644 (file)
index 0000000..ba1efb9
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * Minimal set of classes necessary for UserMailer to be happy. Types
+ * taken from documentation at pear.php.net.
+ * phpcs:ignoreFile
+ */
+
+class PEAR {
+       /**
+        * @param mixed $data
+        * @return bool
+        */
+       public static function isError( $data ) {
+       }
+}
+
+class PEAR_Error {
+       /**
+        * @return string
+        */
+       public function getMessage() {
+       }
+}
+
+class Mail {
+       /**
+        * @param string $driver
+        * @param array $params
+        * @return self
+        */
+       static public function factory( $driver, array $params = [] ) {
+       }
+
+       /**
+        * @param mixed $recipients
+        * @param array $headers
+        * @param string $body
+        * @return bool|PEAR_Error
+        */
+       public function send( $recipients, array $headers, $body ) {
+       }
+}
+
+class Mail_smtp extends Mail {
+}
+
+class Mail_mime {
+       /**
+        * @param mixed $params
+        */
+       public function __construct( $params = [] ) {
+       }
+
+       /**
+        * @param string $data
+        * @param bool $isfile
+        * @param bool $append
+        * @return bool|PEAR_Error
+        */
+       public function setTXTBody( $data, $isfile = false, $append = false ) {
+       }
+
+       /**
+        * @param string $data
+        * @param bool $isfile
+        * @return bool|PEAR_Error
+        */
+       public function setHTMLBody( $data, $isfile = false ) {
+       }
+
+       /**
+        * @param array|null $parms
+        * @param mixed $filename
+        * @param bool $skip_head
+        * @return string|bool|PEAR_Error
+        */
+       public function get( $params = null, $filename = null, $skip_head = false ) {
+       }
+
+       /**
+        * @param array|null $xtra_headers
+        * @param bool $overwrite
+        * @param bool $skip_content
+        * @return array
+        */
+       public function headers( array $xtra_headers = null, $overwrite = false, $skip_content = false ) {
+       }
+}
diff --git a/.phan/stubs/password.php b/.phan/stubs/password.php
new file mode 100644 (file)
index 0000000..dd9cba4
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+// phpcs:ignoreFile
+
+// Password constants added in PHP 7.2 & 7.3
+
+const PASSWORD_ARGON2I = 2;
+const PASSWORD_ARGON2ID = 3;
+const PASSWORD_ARGON2_DEFAULT_MEMORY_COST = 1024;
+const PASSWORD_ARGON2_DEFAULT_THREADS = 2;
+const PASSWORD_ARGON2_DEFAULT_TIME_COST = 2;
+
diff --git a/.phan/stubs/phpunit4.php b/.phan/stubs/phpunit4.php
new file mode 100644 (file)
index 0000000..e5e88e6
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * Some old classes from PHPUnit 4 that MediaWiki (conditionally) references.
+ *
+ * phpcs:ignoreFile
+ */
+
+class PHPUnit_TextUI_Command {
+
+}
diff --git a/.phan/stubs/wikidiff.php b/.phan/stubs/wikidiff.php
new file mode 100644 (file)
index 0000000..02bcd1f
--- /dev/null
@@ -0,0 +1,39 @@
+<?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
+ */
+
+// phpcs:ignoreFile
+
+/**
+ * @param string $text1
+ * @param string $text2
+ * @param int $numContextLines
+ * @param int $movedParagraphDetectionCutoff
+ * @return string
+ */
+function wikidiff2_do_diff( $text1, $text2, $numContextLines, $movedParagraphDetectionCutoff = 0 ) {
+}
+
+/**
+ * @param string $text1
+ * @param string $text2
+ * @param int $numContextLines
+ * @param int $maxMovedLines
+ * @return string
+ */
+function wikidiff2_inline_diff( $text1, $text2, $numContextLines, $maxMovedLines = 25 ) {
+}
index 99afa3b..170e16d 100644 (file)
@@ -13,7 +13,6 @@
                <exclude name="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures" />
                <exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" />
                <exclude name="MediaWiki.Usage.DbrQueryUsage.DbrQueryFound" />
-               <exclude name="MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgAuth" />
                <exclude name="MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgContLang" />
                <exclude name="MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgParser" />
                <exclude name="MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgTitle" />
                        any new occurrences.
                -->
                <exclude-pattern>*/includes/Feed\.php</exclude-pattern>
-               <exclude-pattern>*/includes/RevisionList\.php</exclude-pattern>
                <exclude-pattern>*/includes/installer/PhpBugTests\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialMostinterwikis\.php</exclude-pattern>
-               <exclude-pattern>*/includes/cache/CacheDependency\.php</exclude-pattern>
                <exclude-pattern>*/includes/compat/XMPReader\.php</exclude-pattern>
                <exclude-pattern>*/includes/diff/DairikiDiff\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialAncientpages\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialMostlinkedtemplates\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialMostrevisions\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialMovepage\.php</exclude-pattern>
-               <exclude-pattern>*/includes/specials/SpecialMyRedirectPages\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialNewimages\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialRandompage\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialShortpages\.php</exclude-pattern>
                        Whitelist existing violations, but enable the sniff to prevent
                        any new occurrences.
                -->
-               <exclude-pattern>*/includes/actions/HistoryAction\.php</exclude-pattern>
                <exclude-pattern>*/includes/api/ApiErrorFormatter\.php</exclude-pattern>
                <exclude-pattern>*/includes/api/ApiImport\.php</exclude-pattern>
                <exclude-pattern>*/includes/api/ApiMessage\.php</exclude-pattern>
                <exclude-pattern>*/includes/api/ApiOpenSearch\.php</exclude-pattern>
                <exclude-pattern>*/includes/api/ApiRsd\.php</exclude-pattern>
-               <exclude-pattern>*/includes/AuthPlugin\.php</exclude-pattern>
-               <exclude-pattern>*/includes/cache/CacheDependency\.php</exclude-pattern>
                <exclude-pattern>*/includes/compat/XMPReader\.php</exclude-pattern>
                <exclude-pattern>*/includes/diff/DairikiDiff\.php</exclude-pattern>
-               <exclude-pattern>*/includes/diff/DiffEngine\.php</exclude-pattern>
                <exclude-pattern>*/includes/Feed\.php</exclude-pattern>
                <exclude-pattern>*/includes/filerepo/file/LocalFile\.php</exclude-pattern>
-               <exclude-pattern>*/includes/gallery/PackedOverlayImageGallery\.php</exclude-pattern>
-               <exclude-pattern>*/includes/HistoryBlob\.php</exclude-pattern>
                <exclude-pattern>*/includes/htmlform/HTMLFormElement\.php</exclude-pattern>
-               <exclude-pattern>*/includes/jobqueue/aggregator/JobQueueAggregator\.php</exclude-pattern>
                <exclude-pattern>*/includes/libs/filebackend/FileBackendStore\.php</exclude-pattern>
                <exclude-pattern>*/includes/libs/filebackend/FSFileBackend\.php</exclude-pattern>
                <exclude-pattern>*/includes/libs/filebackend/SwiftFileBackend\.php</exclude-pattern>
                <exclude-pattern>*/includes/logging/LogEntry\.php</exclude-pattern>
                <exclude-pattern>*/includes/logging/LogFormatter\.php</exclude-pattern>
-               <exclude-pattern>*/includes/media/MediaTransformOutput\.php</exclude-pattern>
                <exclude-pattern>*/includes/media/SVGMetadataExtractor\.php</exclude-pattern>
                <exclude-pattern>*/includes/parser/Preprocessor_DOM\.php</exclude-pattern>
                <exclude-pattern>*/includes/parser/Preprocessor_Hash\.php</exclude-pattern>
                <exclude-pattern>*/includes/parser/Preprocessor\.php</exclude-pattern>
                <exclude-pattern>*/includes/PathRouter\.php</exclude-pattern>
-               <exclude-pattern>*/includes/poolcounter/PoolCounter\.php</exclude-pattern>
-               <exclude-pattern>*/includes/PrefixSearch\.php</exclude-pattern>
                <exclude-pattern>*/includes/profiler/SectionProfiler\.php</exclude-pattern>
-               <exclude-pattern>*/includes/RevisionList\.php</exclude-pattern>
-               <exclude-pattern>*/includes/search/SearchEngine\.php</exclude-pattern>
                <exclude-pattern>*/includes/specialpage/LoginSignupSpecialPage\.php</exclude-pattern>
-               <exclude-pattern>*/includes/specialpage/RedirectSpecialPage\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/forms/PreferencesFormLegacy\.php</exclude-pattern>
-               <exclude-pattern>*/includes/specials/SpecialListusers\.php</exclude-pattern>
-               <exclude-pattern>*/includes/specials/SpecialMyRedirectPages\.php</exclude-pattern>
                <exclude-pattern>*/includes/StubObject\.php</exclude-pattern>
                <exclude-pattern>*/includes/upload/UploadStash\.php</exclude-pattern>
                <exclude-pattern>*/includes/utils/AutoloadGenerator\.php</exclude-pattern>
-               <exclude-pattern>*/includes/WebResponse\.php</exclude-pattern>
                <exclude-pattern>*/maintenance/dumpIterator\.php</exclude-pattern>
                <exclude-pattern>*/maintenance/Maintenance\.php</exclude-pattern>
                <exclude-pattern>*/maintenance/findDeprecated\.php</exclude-pattern>
index 07b18e6..e4a173d 100644 (file)
@@ -8,19 +8,11 @@
 #
 language: php
 
-
-# Use fast containers instead of the slower sudo-enabled VMs:
-sudo: false
 # Use Ubuntu 14 Trusty (not Ubuntu 12 Precise)
 # <https://docs.travis-ci.com/user/reference/trusty/>
-# - Required in order to use HHVM 3.6 or higher.
 # - Required for non-buggy xml library for XmlTypeCheck/UploadBaseTest (T75176).
 dist: trusty
 
-git:
-  depth: 3
-  quiet: true
-
 # Cache NPM and Composer directories
 # <https://docs.travis-ci.com/user/caching/>
 cache:
@@ -44,12 +36,8 @@ matrix:
       php: 7.1
     - env: dbtype=mysql dbuser=root
       php: 7
-    # https://docs.travis-ci.com/user/languages/php#HHVM-versions
-    - env: dbtype=mysql dbuser=root
-      php: hhvm-3.18
   allow_failures:
     - php: 7.3
-    - php: hhvm-3.18
 
 services:
   - mysql
diff --git a/HISTORY b/HISTORY
index 72ff437..426eb17 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1,7 +1,26 @@
-Change notes from older releases. For current info see RELEASE-NOTES-1.33.
+Change notes from older releases. For current info see RELEASE-NOTES-1.34.
 
 = MediaWiki 1.32 =
 
+== MediaWiki 1.32.1 ==
+
+=== Changes since MediaWiki 1.32.0 ===
+* (T213577) rdbms: avoid transaction status errors from ping() in rollback().
+* rdbms: Pass required parameter.
+* rdbms: do not treat SAVEPOINT and RELEASE SAVEPOINT as write queries.
+* (T204531) rdbms: reduce LoadBalancer replication log spam.
+* (T213489) Avoid session double-start in Setup.php.
+* (T213717) Correct namespace 'Template' for gom-deva
+* (T198054) Fix login page crash caused by unknown language via ?uselang
+* (T215324) (T210937) list=users mistakenly reports user as missing.
+* (T209483) Add ILBFactory::redefineLocalDomain method. This is intended for
+use with scripts like addWiki.php to avoid mismatched domain errors.
+* (T208871) The hard-coded Google search form on the database error page was
+removed.
+* (T204800) Fix Title::getFragmentForURL for bad interwiki prefix
+* (T215566) Fix installer being unable to determine if the database exists
+during a fresh installation.
+
 == MediaWiki 1.32.0 ==
 
 === Changes since MediaWiki 1.32.0-rc.2 ===
@@ -522,8 +541,8 @@ because of Phabricator reports.
 * SearchResult::setExtensionData argument has been changed from accepting an
   array to accepting a Closure that returns the array when called.
 * Class CryptRand, everything in MWCryptRand except generateHex() and function
-  MediaWikiServices::getCryptRand() are deprecated, use random_bytes() to
-  generate cryptographically secure random byte sequences.
+  MediaWikiServices::getInstance()->getCryptRand() are deprecated, use
+  random_bytes() to generate cryptographically secure random byte sequences.
 * Parser::getConverterLanguage() is deprecated.  Use ::getTargetLanguage()
   instead.
 * Language::markNoConversion() is deprecated.  It confused readers because
@@ -590,10 +609,12 @@ because of Phabricator reports.
 * All MagicWord static methods are now deprecated.  Use the MagicWordFactory
   methods instead.
 * PasswordFactory::init is deprecated. To get a password factory with the
-  standard configuration, use MediaWikiServices::getPasswordFactory.
-* $wgContLang is deprecated, use MediaWikiServices::getContentLanguage()
+  standard configuration, use
+  MediaWikiServices::getInstance()->getPasswordFactory.
+* $wgContLang is deprecated, use
+  MediaWikiServices::getInstance()->getContentLanguage() instead.
+* $wgParser is deprecated, use MediaWikiServices::getInstance()->getParser()
   instead.
-* $wgParser is deprecated, use MediaWikiServices::getParser() instead.
 * wfGetMainCache() is deprecated, use ObjectCache::getLocalClusterInstance()
   instead.
 * wfGetCache() is deprecated, use ObjectCache::getInstance() instead.
@@ -729,7 +750,8 @@ This is a security and maintenance release of the MediaWiki 1.31 branch.
 * (T196185) Don't allow setting $wgDBmysql5 in the installer.
 * (T196125) php-memcached 3.0 (provided with PHP 7.0) is now supported.
 * (T182366) UploadBase::checkXMLEncodingMissmatch() now works on PHP 7.1+
-* (T118683) Fix exception from &$user deref on HHVM in the TitleMoveComplete hook.
+* (T118683) Fix exception from &$user deref on HHVM in the TitleMoveComplete
+  hook.
 * (T196672) The mtime of extension.json files is now able to be zero
 * (T180403) Validate $length in padleft/padright parser functions.
 * (T143790) Make $wgEmailConfirmToEdit only affect edit actions.
@@ -753,7 +775,8 @@ This is a security and maintenance release of the MediaWiki 1.31 branch.
   apply patch-drop-ar_text.sql manually, you'll have to apply a default value
   to the ar_text and ar_flags columns of the archive table or make those
   columns nullable before upgrading to MediaWiki 1.31.
-  maintenance/archives/patch-nullable-ar_text.sql shows how to do this for MySQL.
+  maintenance/archives/patch-nullable-ar_text.sql shows how to do this for
+  MySQL.
 
 === Configuration changes in 1.31 ===
 * $wgEnableAPI and $wgEnableWriteAPI are now deprecated and will be removed in
@@ -1075,7 +1098,8 @@ changes to languages because of Phabricator reports.
 * Passing a ParserOptions object to OutputPage::parserOptions() is deprecated.
 * The RevisionInsertComplete hook is now deprecated; use instead the hook
   RevisionRecordInserted. RevisionInsertComplete is still called, but the second
-  and third parameter will always be null. Hard deprecation is scheduled for 1.32.
+  and third parameter will always be null. Hard deprecation is scheduled for
+  1.32.
 * The following methods that get and set ParserOutput state are deprecated.
   Callers should use the new stateless $options parameter to
   ParserOutput::getText() instead.
@@ -1216,20 +1240,23 @@ This is a security and maintenance release of the MediaWiki 1.30 branch.
   'newbie'.
 * (T194605, CVE-2018-0505) SECURITY: BotPasswords can bypass CentralAuth's
   account lock.
-* (T87572) Make FormatMetadata::flattenArrayReal() work for an associative array.
+* (T87572) Make FormatMetadata::flattenArrayReal() work for an associative
+  array.
 * Updated composer/spdx-licenses from 1.1.4 to 1.3.0 (development dependency).
 * (T189567) the CLI installer (maintenance/install.php) learned to detect and
   include extensions. Pass --with-extensions to enable that feature.
 * (T190503) Let built-in web server (maintenance/dev) handle .php requests.
 * (T167507) selenium: Run Chrome headlessly.
 * selenium: Pass -no-sandbox to Chrome under Docker.
-* (T179190) selenium: Move logic for running tests from package.json to selenium.sh
+* (T179190) selenium: Move logic for running tests from package.json to
+  selenium.sh
 * (T192584) Stop incorrectly passing USE INDEX to RecentChange::newFromConds().
 * Add default edit rate limit of 90 edits/minute for all users.
 * (T186565) Fix PHP Notice from `ob_end_flush()` in `FileRepo::streamFile()`.
 * oojs/oojs-ui updated to remove an unnecessary dependancy.
 * (T196125) php-memcached 3.0 (provided with PHP 7.0) is now supported.
-* (T118683) Fix exception from &$user deref on HHVM in the TitleMoveComplete hook.
+* (T118683) Fix exception from &$user deref on HHVM in the TitleMoveComplete
+  hook.
 * (T196672) The mtime of extension.json files is now able to be zero
 * (T180403) Validate $length in padleft/padright parser functions.
 * (T143790) Make $wgEmailConfirmToEdit only affect edit actions.
@@ -1277,19 +1304,19 @@ section).
 * (T163562) $wgRangeContributionsCIDRLimit was introduced to control the size
   of IP ranges that can be queried at Special:Contributions.
 * (T45547) $wgUsePigLatinVariant added (off by default).
-* (T152540) MediaWiki now supports a section ID escaping style that allows to display
-  non-Latin characters verbatim on many modern browsers. This is controlled by the
-  new configuration setting, $wgFragmentMode.
-* $wgExperimentalHtmlIds is now deprecated and will be removed in a future version,
-  use $wgFragmentMode to migrate off it to a modern alternative.
+* (T152540) MediaWiki now supports a section ID escaping style that allows to
+  display non-Latin characters verbatim on many modern browsers. This is
+  controlled by the new configuration setting, $wgFragmentMode.
+* $wgExperimentalHtmlIds is now deprecated and will be removed in a future
+  version, use $wgFragmentMode to migrate off it to a modern alternative.
 * $wgExternalInterwikiFragmentMode was introduced to control how fragments in
   sinterwikis going outside of current wiki farm are encoded.
-* (T120333) Soft-deprecated the use of PHP extension 'mysql' in favor of 'mysqli'.
-  This PHP extension was deprecated in PHP 5.5 and removed in PHP 7.0. MediaWiki
-  auto-selects the 'mysqli' driver since MediaWiki 1.22, except if explicitly
-  requested through the configuration parameter $wgDBservers.
-* $wgOOUIEditPage was removed, as it is now the default. This was documented as a
-  temporary variable during the migration period.
+* (T120333) Soft-deprecated the use of PHP extension 'mysql' in favor of
+  'mysqli'. This PHP extension was deprecated in PHP 5.5 and removed in PHP 7.0.
+  MediaWiki auto-selects the 'mysqli' driver since MediaWiki 1.22, except if
+  explicitly requested through the configuration parameter $wgDBservers.
+* $wgOOUIEditPage was removed, as it is now the default. This was documented as
+  temporary variable during the migration period.
 
 === New features in 1.30 ===
 * (T37247) Output from Parser::parse() will now be wrapped in a div with
@@ -1322,9 +1349,9 @@ section).
 * (T138166) Added ability for users to prohibit other users from sending them
   emails with Special:Emailuser. Can be enabled by setting
   $wgEnableUserEmailBlacklist to true.
-* (T67297) $wgBrowserBlacklist is deprecated, and changing it will have no effect.
-  Instead, users using browsers that do not support Unicode will be unable to edit
-  and should upgrade to a modern browser instead.
+* (T67297) $wgBrowserBlacklist is deprecated, and changing it will have no
+  effect. Instead, users using browsers that do not support Unicode will be
+  unable to edit and should upgrade to a modern browser instead.
 
 === External library changes in 1.30 ===
 
@@ -1415,9 +1442,10 @@ changes to languages because of Phabricator reports.
 * Two new hooks, LogEventsListLineEnding and NewPagesLineEnding, were added for
   manipulating Special:Log and Special:NewPages lines.
 * The OldChangesListRecentChangesLine, EnhancedChangesListModifyLineData,
-  PageHistoryLineEnding, ContributionsLineEnding and DeletedContributionsLineEnding
-  hooks have an additional parameter, for manipulating HTML data attributes of
-  RC/history lines. EnhancedChangesListModifyBlockLineData can do that via the
+  PageHistoryLineEnding, ContributionsLineEnding and
+  DeletedContributionsLineEnding hooks have an additional parameter, for
+  manipulating HTML data attributes of RC/history lines.
+  EnhancedChangesListModifyBlockLineData can do that via the
   $data['attribs'] subarray.
 * (T130632) The OutputPage::enableTOC() method was removed.
 * WikiPage::getParserOutput() will now throw an exception if passed
@@ -1428,10 +1456,10 @@ changes to languages because of Phabricator reports.
 * IP::isValidBlock() was deprecated. Use the equivalent IP::isValidRange().
 * DeprecatedGlobal no longer supports passing in a direct value, it requires a
   callable factory function or a class name.
-* The $parserMemc global, wfGetParserCacheStorage(), and ParserCache::singleton()
-  are all deprecated. The main ParserCache instance should be obtained from
-  MediaWikiServices instead. Access to the underlying BagOStuff is possible
-  through the new ParserCache::getCacheStorage() method.
+* The $parserMemc global, wfGetParserCacheStorage(), and
+  ParserCache::singleton() are all deprecated. The main ParserCache instance
+  should be obtained from MediaWikiServices instead. Access to the underlying
+  BagOStuff is possible through the new ParserCache::getCacheStorage() method.
 * .mw-ui-constructive CSS class (deprecated in 1.27) was removed.
 * Sanitizer::escapeId() was deprecated, use escapeIdForAttribute(),
   escapeIdForLink() or escapeIdForExternalInterwiki() instead.
@@ -1442,9 +1470,9 @@ changes to languages because of Phabricator reports.
 * mw.util.escapeId() was deprecated, use escapeIdForAttribute() or
   escapeIdForLink().
 * MagicWord::replaceMultiple() (deprecated in 1.25) was removed.
-* WikiImporter now requires the second parameter to be an instance of the Config,
-  class. Prior to that, the Config parameter was optional (a behavior deprecated in
-  1.25).
+* WikiImporter now requires the second parameter to be an instance of the
+  Config, class. Prior to that, the Config parameter was optional (a behavior
+  deprecated in 1.25).
 * Removed 'jquery.mwExtension' module. (deprecated since 1.26)
 * mediawiki.ui: Deprecate greys, which are not part of WikimediaUI color palette
   any more.
@@ -1454,55 +1482,60 @@ changes to languages because of Phabricator reports.
   should be used instead.
 * RunningStat class (deprecated in 1.27) was removed. The namespaced
   RunningStat\RunningStat should be used instead.
-* MWMemcached and MemCachedClientforWiki classes (deprecated in 1.27) were removed.
+* MWMemcached and MemCachedClientforWiki classes (deprecated in 1.27) were
+  removed.
   The MemcachedClient class should be used instead.
 * EditPage underwent some refactoring and deprecations:
   * EditPage::isOouiEnabled() is deprecated and will always return true.
-  * EditPage::getSummaryInput() and ::getSummaryInputOOUI() are deprecated. Please
-    use ::getSummaryInputWidget() instead.
+  * EditPage::getSummaryInput() and ::getSummaryInputOOUI() are deprecated.
+    Please use ::getSummaryInputWidget() instead.
   * EditPage::getCheckboxes() and ::getCheckboxesOOUI() are deprecated. Please
     use ::getCheckboxesWidget() instead.
-  * Creating an EditPage instance without calling EditPage::setContextTitle() should
-    be avoided and will be deprecated in a future release.
-  * EditPage::safeUnicodeInput() and ::safeUnicodeOutput() are deprecated and no-ops.
-  * EditPage::$isCssJsSubpage, ::$isCssSubpage, and ::$isJsSubpage are deprecated. The
-    corresponding methods from Title should be used instead.
+  * Creating an EditPage instance without calling EditPage::setContextTitle()
+    should be avoided and will be deprecated in a future release.
+  * EditPage::safeUnicodeInput() and ::safeUnicodeOutput() are deprecated and
+    no-ops.
+  * EditPage::$isCssJsSubpage, ::$isCssSubpage, and ::$isJsSubpage are
+    deprecated. The corresponding methods from Title should be used instead.
   * EditPage::$isWrongCaseCssJsPage is deprecated. There is no replacement.
-  * EditPage::$mArticle and ::$mTitle are deprecated for public usage. The getters
-    ::getArticle() and ::getTitle() should be used instead.
-  * Trying to control or fake EditPage context by overriding $wgUser, $wgRequest, $wgOut,
-    and $wgLang is no longer supported and won't work. The IContextSource returned from
-    EditPage::getContext() must be modified instead.
+  * EditPage::$mArticle and ::$mTitle are deprecated for public usage. The
+    getters ::getArticle() and ::getTitle() should be used instead.
+  * Trying to control or fake EditPage context by overriding $wgUser,
+    $wgRequest, $wgOut, and $wgLang is no longer supported and won't work. The
+    IContextSource returned from EditPage::getContext() must be modified
+    instead.
 * Parser::getRandomString() (deprecated in 1.26) was removed.
 * Parser::uniqPrefix() (deprecated in 1.26) was removed.
 * Parser::extractTagsAndParams() now only accepts three arguments. The fourth,
   $uniq_prefix was deprecated in 1.26 and has now been removed.
-* (T172514) The following tables have had their UNIQUE indexes turned into proper
-  PRIMARY KEYs for increased maintainability: categorylinks, imagelinks, iwlinks,
-  langlinks, log_search, module_deps, objectcache, pagelinks, query_cache, site_stats,
-  templatelinks, text, transcache, user_former_groups, user_properties.
+* (T172514) The following tables have had their UNIQUE indexes turned into
+  proper PRIMARY KEYs for increased maintainability: categorylinks, imagelinks,
+  iwlinks, langlinks, log_search, module_deps, objectcache, pagelinks,
+  query_cache, site_stats, templatelinks, text, transcache, user_former_groups,
+  user_properties.
 * IDatabase::nextSequenceValue() is no longer needed by any database backends
   (formerly it was needed by PostgreSQL and Oracle), and is now deprecated.
-* (T146591) The lc_lang_key index on the l10n_cache table has been changed into a
-  PRIMARY KEY.
+* (T146591) The lc_lang_key index on the l10n_cache table has been changed into
+  PRIMARY KEY.
 * (T157227) bot_password.bp_user, change_tag.ct_log_id, change_tag.ct_rev_id,
   page_restrictions.pr_user, tag_summary.ts_log_id, tag_summary.ts_rev_id and
   user_properties.up_user have all been made unsigned on MySQL.
 * DB_SLAVE is deprecated. DB_REPLICA should be used instead.
 * wfUsePHP() is deprecated.
 * wfFixSessionID() was removed.
-* wfShellExec() and related functions are deprecated, use Shell::command(). This also
-  slightly changes the behavior of how execution time limits are calculated when only
-  some of defaults are overridden per-call. When in doubt, always override both wall
-  clock and CPU time.
-* (T138166) SpecialEmailUser::getTarget() now requires a second argument, the sending
-  user object. Using the method without the second argument is deprecated.
+* wfShellExec() and related functions are deprecated, use Shell::command(). This
+  also slightly changes the behavior of how execution time limits are calculated
+  when only some of defaults are overridden per-call. When in doubt, always
+  override both wall clock and CPU time.
+* (T138166) SpecialEmailUser::getTarget() now requires a second argument, the
+  sending user object. Using the method without the second argument is
+  deprecated.
 * (T67297) Browsers that don't support Unicode will have their edits rejected.
-* (T178450) The module 'jquery.badge' is deprecated and will be removed in a future
-  release. For notifying the user of an event, the Notifications ("Echo") system
-  should be used instead.
-* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and browser
-  sends non-standard url escaping.
+* (T178450) The module 'jquery.badge' is deprecated and will be removed in a
+  future release. For notifying the user of an event, the Notifications ("Echo")
+  system should be used instead.
+* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and
+  browser sends non-standard url escaping.
 * (T165846) SECURITY: BotPassword login attempts weren't throttled.
 
 = MediaWiki 1.29 =
@@ -1555,7 +1588,8 @@ This is a security and maintenance release of the MediaWiki 1.29 branch.
 This is a security and maintenance release of the MediaWiki 1.29 branch.
 
 === Changes since 1.29.1 ===
-* (T166757) Avoid scoped lock errors in Category::refreshCounts() due to nesting.
+* (T166757) Avoid scoped lock errors in Category::refreshCounts() due to
+  nesting.
 * (T175439) Unbreak Postgres Updater when setting defaults for a column.
 * (T160298) Remove use of implicitGroupBy() in ActiveUsersPager.
 * Fixed login button label to accept RawMessage.
@@ -1564,19 +1598,20 @@ This is a security and maintenance release of the MediaWiki 1.29 branch.
 * (T163646) Pass a string not an int to mysql_real_escape_string().
 * (T180143) Bump justinrainbow/json-schema development dependency to ~5.2.
 * Updated dev dependancy phpunit/phpunit from v4.8.35 to v4.8.36.
-* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and browser
-  sends non-standard url escaping.
+* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and
+  browser sends non-standard url escaping.
 * (T165846) SECURITY: BotPassword login attempts weren't throttled.
 * (T128209) SECURITY: Reflected File Download from api.php.
 * (T134100) SECURITY: Do not reveal if user exists during login failure.
 * (T176247) SECURITY: Ensure Message::rawParams can't lead to XSS.
 * (T125163) SECURITY: Make anchor for headlines escape > and <.
 * (T180237) SECURITY: Protect vendor folder with .htaccess.
-* (T180231) SECURITY: Remove PHPUnit file with known RCE if exists in update.php.
+* (T180231) SECURITY: Remove PHPUnit file with known RCE if exists in
+  update.php.
 * (T124404) SECURITY: XSS in langconverter when regex hits pcre.backtrack_limit.
 * (T119158) SECURITY: Handle -{}- syntax in attributes safely.
-* (T180488) (T125177) "api.log contains passwords in plaintext" wasn't correctly fixed in all
-  branches in the previous security release.
+* (T180488) (T125177) "api.log contains passwords in plaintext" wasn't correctly
+  fixed in all branches in the previous security release.
 
 == MediaWiki 1.29.1 ==
 
@@ -1615,7 +1650,8 @@ packages.
 * $wgRunJobsAsync is now false by default (T142751). This change only affects
   wikis with $wgJobRunRate > 0.
 * (T158474) "Unknown user" has been added to $wgReservedUsernames.
-* (T156983) $wgRateLimitsExcludedIPs now accepts CIDR ranges as well as single IPs.
+* (T156983) $wgRateLimitsExcludedIPs now accepts CIDR ranges as well as single
+  IPs.
 * $wgDummyLanguageCodes is deprecated. Additional language code mappings may be
   added to $wgExtraLanguageCodes instead.
 * (T161453) LocalisationCache will no longer use the temporary directory in it's
@@ -1674,30 +1710,32 @@ packages.
 ==== Removed and replaced external libraries ====
 
 === Bug fixes in 1.29 ===
-* (T62604) Core parser functions returning a number now format the number according
-  to the page content language, not wiki content language.
-* (T27187) Search suggestions based on jquery.suggestions will now correctly only
-  highlight prefix matches in the results.
+* (T62604) Core parser functions returning a number now format the number
+  according to the page content language, not wiki content language.
+* (T27187) Search suggestions based on jquery.suggestions will now correctly
+  only highlight prefix matches in the results.
 * (T157035) "new mw.Uri()" was ignoring options when using default URI.
 * Special:Allpages can no longer be filtered by redirect in miser mode.
-* (T160519) CACHE_ANYTHING will not be CACHE_ACCEL if no accelerator is installed.
-* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow redirect
-  to interwiki links.
+* (T160519) CACHE_ANYTHING will not be CACHE_ACCEL if no accelerator is
+  installed.
+* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow
+  redirect to interwiki links.
 * (T144845) SECURITY: XSS in SearchHighlighter::highlightText() when
   $wgAdvancedSearchHighlighting is true.
 * (T125177) SECURITY: API parameters may now be marked as "sensitive" to keep
   their values out of the logs.
-* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a CSRF
-  token.
+* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a
+  CSRF token.
 * (T156184) SECURITY: Escape content model/format url parameter in message.
 * (T151735) SECURITY: SVG filter evasion using default attribute values in DTD
   declaration.
-* (T161453) SECURITY: LocalisationCache will no longer use the temporary directory
-  in it's fallback chain when trying to work out where to write the cache.
-* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file inclusion
-  syntax's link parameter.
-* (T108138) SECURITY: Sysops can undelete pages, although the page is protected against
-  it.
+* (T161453) SECURITY: LocalisationCache will no longer use the temporary
+  directory in it's fallback chain when trying to work out where to write the
+  cache.
+* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file
+  inclusion syntax's link parameter.
+* (T108138) SECURITY: Sysops can undelete pages, although the page is protected
+  against it.
 
 === Action API changes in 1.29 ===
 * Submitting sensitive authentication request parameters to action=login,
@@ -1712,8 +1750,8 @@ packages.
   parameter prefixes (e.g. all query submodules) will no longer be prefixed.
 * ApiPageSet-using modules will report the 'invalidreason' using the specified
   'errorformat'.
-* action=emailuser may return a "Warnings" status, and now returns 'warnings' and
-  'errors' subelements (as applicable) instead of 'message'.
+* action=emailuser may return a "Warnings" status, and now returns 'warnings'
+  and 'errors' subelements (as applicable) instead of 'message'.
 * action=imagerotate returns an 'errors' subelement rather than 'errormessage'.
 * action=move now reports errors when moving the talk page as an array under
   key 'talkmove-errors', rather than using 'talkmove-error-code' and
@@ -1783,8 +1821,8 @@ changes to languages because of Phabricator reports.
 
 ==== No fallback for Ukrainian ====
 * (T39314) The fallback from Ukrainian to Russian was removed. The Ukrainian
-  language will now use the default fallback language: English. When a translation
-  to Ukrainian is not available, an English string will be shown.
+  language will now use the default fallback language: English. When a
+  translation to Ukrainian is not available, an English string will be shown.
 
 === Other changes in 1.29 ===
 * Database::getSearchEngine() (deprecated in 1.28) was removed. Use
@@ -1799,8 +1837,8 @@ changes to languages because of Phabricator reports.
   were removed.
 * Article::getAutosummary() and WikiPage::getAutosummary() (deprecated in 1.21)
   were removed.
-* Hook ArticleViewCustom (deprecated in 1.21) was removed. Use ArticleContentViewCustom
-  instead.
+* Hook ArticleViewCustom (deprecated in 1.21) was removed. Use
+  ArticleContentViewCustom instead.
 * Hooks EditPageGetDiffText and ShowRawCssJs (deprecated in 1.21) were removed.
 * Class RevisiondeleteAction (deprecated in 1.25) was removed.
 * WikiPage::prepareTextForEdit() (deprecated in 1.21) was removed.
@@ -1811,13 +1849,16 @@ changes to languages because of Phabricator reports.
 * User::isPasswordReminderThrottled() (deprecated in 1.27) was removed.
 * Class FSRepo (deprecated in 1.19) was removed.
 * WebRequest::checkSessionCookie() (deprecated in 1.27) was removed. Use
-  \MediaWiki\Session\SessionManager::singleton()->getPersistedSessionId() instead.
+  \MediaWiki\Session\SessionManager::singleton()->getPersistedSessionId()
+  instead.
 * Class ImageGallery (deprecated in 1.22) was removed.
   Use ImageGalleryBase::factory instead.
-* Title::moveNoAuth() (deprecated in 1.25) was removed. Use MovePage class instead.
+* Title::moveNoAuth() (deprecated in 1.25) was removed. Use MovePage class
+  instead.
 * Hook UnknownAction (deprecated in 1.19) was actually deprecated (it will now
   emit warnings). Create a subclass of Action and add it to $wgActions instead.
-* WikiRevision::getText() (deprecated since 1.21) is no longer marked deprecated.
+* WikiRevision::getText() (deprecated since 1.21) is no longer marked
+  deprecated.
 * Linker::getInterwikiLinkAttributes() (deprecated since 1.25) was removed.
 * Linker::getInternalLinkAttributes() (deprecated since 1.25) was removed.
 * Linker::getInternalLinkAttributesObj() (deprecated since 1.25) was removed.
@@ -1825,9 +1866,10 @@ changes to languages because of Phabricator reports.
 * RedisConnectionPool::handleException (deprecated since 1.23) was removed.
 * The static properties mw.Api.errors and mw.Api.warnings, containing incomplete
   and outdated lists of errors/warnings returned by the API, are now deprecated.
-* wiki.phtml entry point was removed.  Refer to index.php instead. If you want "wiki.phtml"
-  URLs to continue to work, set up redirects. In Apache, this can be done by enabling
-  mod_rewrite and adding the following rules to your configuration:
+* wiki.phtml entry point was removed.  Refer to index.php instead. If you want
+  "wiki.phtml" URLs to continue to work, set up redirects. In Apache, this can
+  be done by enabling mod_rewrite and adding the following rules to your
+  configuration:
 
     RewriteEngine On
     RewriteBase /
@@ -1855,8 +1897,8 @@ changes to languages because of Phabricator reports.
 * Article::doEditContent() was marked as deprecated, to be removed in 1.30
   or later.
 * ContentHandler::runLegacyHooks() was removed.
-* refreshLinks.php now can be limited to a particular category with --category=...
-  or a tracking category with --tracking-category=...
+* refreshLinks.php now can be limited to a particular category with
+  --category=... or a tracking category with --tracking-category=...
 * User-like objects that are passed to SpecialUserRights and its subclasses are
   now required to have a getGroupMemberships() method. See UserRightsProxy for
   an example.
@@ -1930,28 +1972,34 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
 === Changes since 1.28.2 ==
 * (T168856) Allow SVGs created by Dia to be uploaded.
 * (T157545) Add missing doUpdates() call to refreshLinks.php.
-* (T165714) (T100085) Better handling of jobs execution in post-connection shutdown.
-* (T154425) (T154438) (T157679) Use AutoCommitUpdate instead of Database->onTransactionIdle.
+* (T165714) (T100085) Better handling of jobs execution in post-connection
+  shutdown.
+* (T154425) (T154438) (T157679) Use AutoCommitUpdate instead of
+  Database->onTransactionIdle.
 * (T154425) Make DeferredUpdates detect LBFactory transaction rounds.
-* (T149454) Restore erroneously removed realTableName call from DatabasePostgres.
+* (T149454) Restore erroneously removed realTableName call from
+  DatabasePostgres.
 * (T167798) Fix phrase search and highlighting for phrase queries.
 * (T151136) Provide credits information to callbacks in extension registration.
-* (T160462) Allow namespaces defined in extension.json to be overwritten locally.
+* (T160462) Allow namespaces defined in extension.json to be overwritten
+  locally.
 * (T168337) Fix ErrorPageError to work from non-UI contexts.
 * (T143788) Backports for PHP 7.0 and 7.1 support.
 * (T175439) Unbreak Postgres Updater when setting defaults for a column.
 * (T160298) Remove use of implicitGroupBy() in ActiveUsersPager.
 * (T174255) Declare uploadCount property in importDump.php.
-* (T180231) SECURITY: Updated dev dependancy phpunit/phpunit from v4.8.24 to v4.8.36.
-* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and browser
-  sends non-standard url escaping.
+* (T180231) SECURITY: Updated dev dependancy phpunit/phpunit from v4.8.24 to
+  v4.8.36.
+* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and
+  browser sends non-standard url escaping.
 * (T165846) SECURITY: BotPassword login attempts weren't throttled.
 * (T128209) SECURITY: Reflected File Download from api.php.
 * (T134100) SECURITY: Do not reveal if user exists during login failure.
 * (T176247) SECURITY: Ensure Message::rawParams can't lead to XSS.
 * (T125163) SECURITY: Make anchor for headlines escape > and <.
 * (T180237) SECURITY: Protect vendor folder with .htaccess.
-* (T180231) SECURITY: Remove PHPUnit file with known RCE if exists in update.php.
+* (T180231) SECURITY: Remove PHPUnit file with known RCE if exists in
+  update.php.
 * (T124404) SECURITY: XSS in langconverter when regex hits pcre.backtrack_limit.
 * (T119158) SECURITY: Handle -{}- syntax in attributes safely.
 
@@ -1970,8 +2018,8 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
 
 * $wgRunJobsAsync is now false by default (T142751). This change only affects
   wikis with $wgJobRunRate > 0.
-* Fix fatal from "WaitConditionLoop" not being found, experienced when a wiki has
-  more than one database server setup.
+* Fix fatal from "WaitConditionLoop" not being found, experienced when a wiki
+  has more than one database server setup.
 * (T152717) Better escaping for PHP mail() command,
 * (T154670) A missing method causing the MySQL installer to fatal in rare
   circumstances was restored.
@@ -1979,25 +2027,28 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
 * (T158766) Avoid SQL error on MSSQL when using selectRowCount().
 * (T145635) Fix too long index error when installing with MSSQL.
 * (T156184) $wgRawHtml will no longer apply to internationalization messages.
-* (T160519) CACHE_ANYTHING will not be CACHE_ACCEL if no accelerator is installed.
-* (T154872) Fix incorrect ar_usertext_timestamp index names in new 1.28 installs.
-* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow redirect
-  to interwiki links.
+* (T160519) CACHE_ANYTHING will not be CACHE_ACCEL if no accelerator is
+  installed.
+* (T154872) Fix incorrect ar_usertext_timestamp index names in new 1.28
+  installs.
+* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow
+  redirect to interwiki links.
 * (T144845) SECURITY: XSS in SearchHighlighter::highlightText() when
   $wgAdvancedSearchHighlighting is true.
 * (T125177) SECURITY: API parameters may now be marked as "sensitive" to keep
   their values out of the logs.
-* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a CSRF
-  token.
+* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a
+  CSRF token.
 * (T156184) SECURITY: Escape content model/format url parameter in message.
 * (T151735) SECURITY: SVG filter evasion using default attribute values in DTD
   declaration.
-* (T161453) SECURITY: LocalisationCache will no longer use the temporary directory
-  in it's fallback chain when trying to work out where to write the cache.
-* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file inclusion
-  syntax's link parameter.
-* (T108138) SECURITY: Sysops can undelete pages, although the page is protected against
-  it.
+* (T161453) SECURITY: LocalisationCache will no longer use the temporary
+  directory in it's fallback chain when trying to work out where to write the
+  cache.
+* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file
+  inclusion syntax's link parameter.
+* (T108138) SECURITY: Sysops can undelete pages, although the page is protected
+  against it.
 
 == MediaWiki 1.28 ==
 
@@ -2024,7 +2075,8 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
 * (T149759) manifest_version: 2 was removed.
 
 === Configuration changes in 1.28 ===
-* $wgSend404Code now affects status code of action=history if the page is not there.
+* $wgSend404Code now affects status code of action=history if the page is not
+  there.
 * BREAKING CHANGE: $wgHTTPProxy is now *required* for all external requests
   made by MediaWiki via a proxy. Relying on the http_proxy environment
   variable is no longer supported.
@@ -2048,16 +2100,19 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
 * When $wgEditSubmitButtonLabelPublish is true, MediaWiki will label the button
   to store-to-database-and-show-to-others as "Publish page"/"Publish changes";
   if false, the default, they will be "Save page"/"Save changes".
-* The 'editcontentmodel' permission is now granted to all logged-in users ('user').
+* The 'editcontentmodel' permission is now granted to all logged-in users
+  ('user').
   instead of just administrators ('sysop'). Documentation for this feature is
   available at <https://www.mediawiki.org/wiki/Help:ChangeContentModel>.
-* $wgRevisionCacheExpiry is now set to one week by default instead of being disabled.
-* Magic links are now disabled by default, and can be re-enabled by modifying the value
-  of $wgEnableMagicLinks. Their usage is discouraged, but if they are manually enabled,
-  a tracking category will be added to help identify usage and make it easier to migrate
-  away from. If you depend upon magic link functionality, it is requested that you comment
-  on <https://www.mediawiki.org/wiki/Requests_for_comment/Future_of_magic_links> and
-  explain your use case(s).
+* $wgRevisionCacheExpiry is now set to one week by default instead of being
+  disabled.
+* Magic links are now disabled by default, and can be re-enabled by modifying
+  the value of $wgEnableMagicLinks. Their usage is discouraged, but if they are
+  manually enabled, a tracking category will be added to help identify usage and
+  make it easier to migrate away from. If you depend upon magic link
+  functionality, it is requested that you comment on
+  <https://www.mediawiki.org/wiki/Requests_for_comment/Future_of_magic_links>
+  and explain your use case(s).
 * New config variable $wgCSPFalsePositiveUrls to control what URLs to ignore
   in upcoming Content-Security-Policy feature's reporting.
 
@@ -2072,21 +2127,24 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
   and the file description page, but does not run for uploads to stash.
 * (T141604) Extensions can now provide a better error message when their
   maintenance scripts are run without the extension being installed.
-* (T8948) Numeric sorting in categories is now supported by setting $wgCategoryCollation
-  to 'uca-default-u-kn' or 'uca-<langcode>-u-kn'. If you can't use UCA collations,
-  a 'numeric' collation is also available. If migrating from another
-  collation, you will need to run the updateCollation.php maintenance script.
-* Two new codes have been added to #time parser function: "xit" for days in current
-  month, and "xiz" for days passed in the year, both in Iranian calendar.
+* (T8948) Numeric sorting in categories is now supported by setting
+  $wgCategoryCollation to 'uca-default-u-kn' or 'uca-<langcode>-u-kn'. If you
+  can't use UCA collations, a 'numeric' collation is also available. If
+  migrating from another collation, you will need to run the updateCollation.php
+  maintenance script.
+* Two new codes have been added to #time parser function: "xit" for days in
+  current month, and "xiz" for days passed in the year, both in Iranian
+  calendar.
 * mw.Api has a new option, useUS, to use U+001F (Unit Separator) when
   appropriate for sending multi-valued parameters. This defaults to true when
   the mw.Api instance seems to be for the local wiki.
-* After a client performs an action which alters a database that has replica databases,
-  MediaWiki will wait for the replica databases to synchronize with the master database
-  while it renders the HTML output. However, if the output is a redirect to another wiki
-  on the wiki farm with a different domain, MediaWiki will instead alter the redirect
-  URL to include a ?cpPosTime parameter that triggers the database synchronization when
-  the URL is followed by the client. The same-domain case uses a new cpPosTime cookie.
+* After a client performs an action which alters a database that has replica
+  databases, MediaWiki will wait for the replica databases to synchronize with
+  the master database while it renders the HTML output. However, if the output
+  is a redirect to another wiki on the wiki farm with a different domain,
+  MediaWiki will instead alter the redirect URL to include a ?cpPosTime
+  parameter that triggers the database synchronization when the URL is followed
+  by the client. The same-domain case uses a new cpPosTime cookie.
 * Added new hooks, 'ApiQueryBaseBeforeQuery', 'ApiQueryBaseAfterQuery', and
   'ApiQueryBaseProcessRow', to make it easier for extensions to add 'prop' and
   'show' parameters to existing API query modules.
@@ -2103,7 +2161,8 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
 * Added wikimedia/wait-condition-loop v1.0.1
 
 === Bug fixes in 1.28 ===
-* (T146496) action=history pages should return 404 HTTP error code if the page does not exist
+* (T146496) action=history pages should return 404 HTTP error code if the page
+  does not exist
 * (T137264) SECURITY: XSS in unclosed internal links
 * (T133147) SECURITY: Escape '<' and ']]>' in inline <style> blocks
 * (T133147) SECURITY: Require login to preview user CSS pages
@@ -2130,9 +2189,9 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
   action=createaccount, action=linkaccount, and action=changeauthenticationdata
   in the query string is now deprecated and outputs a warning. They should be
   submitted in the POST body instead.
-* (T141960) Multi-valued parameters may now be separated using U+001F (Unit Separator)
-  instead of the pipe character. This will be useful if some of the multiple
-  values need to contain pipes, e.g. for action=options.
+* (T141960) Multi-valued parameters may now be separated using U+001F
+  (Unit Separator) instead of the pipe character. This will be useful if some of
+  the multiple values need to contain pipes, e.g. for action=options.
 * The API will now warn if input is not NFC-normalized Unicode or if it
   contains invalid characters.
 * The 'normalized' list output by action=query and other modules that use
@@ -2150,7 +2209,8 @@ This is a security and maintenance release of the MediaWiki 1.28 branch.
 * Added a new hook, 'ApiMakeParserOptions', to allow extensions to better
   interact with ApiParse and ApiExpandTemplates.
 * (T139565) SECURITY: API: Generate head items in the context of the given title
-* (T115333) SECURITY: Check read permission when loading page content in ApiParse
+* (T115333) SECURITY: Check read permission when loading page content in
+  ApiParse
 * ApiBase::getResultData() was removed (deprecated since 1.25)
 * ApiBase::makeHelpArrayToString() was removed (deprecated since 1.25)
 * ApiBase::makeHelpMsgParameters() was removed (deprecated since 1.25)
@@ -2200,7 +2260,8 @@ changes to languages because of Phabricator reports.
 * (T135867) shn (Shan), thanks to translators Khun Sar, Piangpha,
   Saiddzone Saimawnkham, Saosukham, and Sengwan.
 * Czech (cs) and Slovak (sk) set as reciprocal fallbacks.
-* (T146744) Livvi-Karelian (olo) namespace messages created thanks to translator Ilja.mos.
+* (T146744) Livvi-Karelian (olo) namespace messages created thanks to translator
+  Ilja.mos.
 
 === Other changes in 1.28 ===
 * (T128697) Improved handling of large diffs.
@@ -2209,8 +2270,8 @@ changes to languages because of Phabricator reports.
 * Deprecated APIEditBeforeSave hook in favor of EditFilterMergedContent.
 * The 'UploadVerification' hook is deprecated. Use 'UploadVerifyFile' instead.
 * SiteConfiguration::isLocalVHost() was removed (deprecated since 1.25).
-* The 'UserLoginComplete' hook has a new parameter to differentiate between actual
-  login and visiting the login page while already logged in.
+* The 'UserLoginComplete' hook has a new parameter to differentiate between
+  actual login and visiting the login page while already logged in.
 * ResourceLoader::makeLoaderURL() was removed (deprecated since 1.24).
 * $.fn.liveAndTestAtStart was removed (deprecated since 1.24).
 * mw.util.tooltipAccessKeyPrefix was removed (deprecated since 1.24).
@@ -2218,7 +2279,8 @@ changes to languages because of Phabricator reports.
 * Linker::link() and Linker::linkKnown() were deprecated; please instead use
   MediaWiki\Linker\LinkRenderer. In addition, the LinkBegin and LinkEnd hooks
   were replaced by HtmlPageLinkRendererBegin and HtmlPageLinkRendererEnd
-  respectively. See docs/hooks.txt for the specific changes needed for those hooks.
+  respectively. See docs/hooks.txt for the specific changes needed for those
+  hooks.
 * Linker::formatSize() was deprecated. Use Language::formatSize() directly.
 * Aliases for Linker methods, deprecated since 1.21, were removed from Skin:
   * Skin::commentBlock() (use Linker::commentBlock() instead)
@@ -2234,8 +2296,9 @@ changes to languages because of Phabricator reports.
   Use ...->stashFile()->getFileKey() instead.
 * "Public domain" was removed as a wiki license option from the installer, in
   favour of CC-0.
-* AuthenticationRequest::$required is now changed from REQUIRED to PRIMARY_REQUIRED
-  on requests needed by primary providers even if all primaries need them.
+* AuthenticationRequest::$required is now changed from REQUIRED to
+  PRIMARY_REQUIRED on requests needed by primary providers even if all primaries
+  need them.
   Primary providers are discouraged from returning multiple REQUIRED requests.
 * OOjs UI PHP widgets constructed with the `'infusable' => true` config option
   will no longer be automatically infused. You should call `OO.ui.infuse()`
@@ -2249,13 +2312,14 @@ changes to languages because of Phabricator reports.
 * IP::isConfiguredProxy() and IP::isTrustedProxy() were removed. Callers should
   migrate to using the same functions on a ProxyLookup instance, obtainable from
   MediaWikiServices.
-* The ArticleAfterFetchContent, ArticleInsertComplete, ArticleSave, ArticleSaveComplete,
-  ArticleViewCustom, EditFilterMerged, EditPageGetDiffText, EditPageGetPreviewText and
-  ShowRawCssJs hooks will now emit deprecation warnings if used.
+* The ArticleAfterFetchContent, ArticleInsertComplete, ArticleSave,
+  ArticleSaveComplete, ArticleViewCustom, EditFilterMerged, EditPageGetDiffText,
+  EditPageGetPreviewText and ShowRawCssJs hooks will now emit deprecation
+  warnings if used.
 * (T68404) CSS3 attr() function with url type is no longer allowed
   in inline styles.
-* Database::getSearchEngine() is deprecated, use SearchEngineFactory::getSearchEngineClass
-  instead.
+* Database::getSearchEngine() is deprecated, use
+  SearchEngineFactory::getSearchEngineClass instead.
 
 == Compatibility ==
 
@@ -2336,7 +2400,8 @@ This is a security and maintenance release of the MediaWiki 1.27 branch.
   account lock.
 * Upgraded Moment.js from v2.8.4 to v2.19.3.
 * (T160298) Fixed Special:ActiveUsers due to bad backport.
-* (T87572) Make FormatMetadata::flattenArrayReal() work for an associative array.
+* (T87572) Make FormatMetadata::flattenArrayReal() work for an associative
+  array.
 * Updated list of SPDX licenses for extensions.
 * (T189567) the CLI installer (maintenance/install.php) learned to detect and
   include extensions. Pass --with-extensions to enable that feature.
@@ -2344,7 +2409,8 @@ This is a security and maintenance release of the MediaWiki 1.27 branch.
 * Add default edit rate limit of 90 edits/minute for all users.
 * (T196125) php-memcached 3.0 (provided with PHP 7.0) is now supported.
 * (T196672) The mtime of extension.json files is now able to be zero.
-* (T118683) Fix exception from &$user deref on HHVM in the TitleMoveComplete hook.
+* (T118683) Fix exception from &$user deref on HHVM in the TitleMoveComplete
+  hook.
 * (T180403) Validate $length in padleft/padright parser functions.
 * (T143790) Make $wgEmailConfirmToEdit only affect edit actions.
 * Special:BotPasswords now requires reauthentication.
@@ -2361,27 +2427,30 @@ This is a security and maintenance release of the MediaWiki 1.27 branch.
 * (T141604) Support conditionally registered namespaces.
 * (T167798) Fix highlighting for phrase queries and phrase search.
 * (T151136) Provide credits information to callbacks.
-* (T160462) Allow namespaces defined in extension.json to be overwritten locally.
+* (T160462) Allow namespaces defined in extension.json to be overwritten
+  locally.
 * (T168856) Allow SVGs created by Dia to be uploaded.
-* (T144705) (T148662) Password reset link is no longer shown when no reset options are
-  available.
+* (T144705) (T148662) Password reset link is no longer shown when no reset
+  options are available.
 * (T143788) (T174262) Various backports for PHP 7.0 and 7.1 support.
-* (T66795) $wgUserEmailUseReplyTo is now true by default to work around restrictive DMARC
-  policies.
-* DB_REPLICA constant added from REL1_28+ to ease backports to extensions and core.
+* (T66795) $wgUserEmailUseReplyTo is now true by default to work around
+  restrictive DMARC policies.
+* DB_REPLICA constant added from REL1_28+ to ease backports to extensions and
+  core.
 * (T175439) Unbreak Postgres Updater when setting defaults for a column.
 * (T160298) Remove use of implicitGroupBy() in ActiveUsersPager.
 * (T142304) Allow putting the app ID in the password for bot passwords.
 * Updated dev dependancy phpunit/phpunit from v4.8.24 to v4.8.36.
-* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and browser
-  sends non-standard url escaping.
+* (T178451) SECURITY: Potential XSS when $wgShowExceptionDetails = false and
+  browser sends non-standard url escaping.
 * (T165846) SECURITY: BotPassword login attempts weren't throttled.
 * (T128209) SECURITY: Reflected File Download from api.php.
 * (T134100) SECURITY: Do not reveal if user exists during login failure.
 * (T176247) SECURITY: Ensure Message::rawParams can't lead to XSS.
 * (T125163) SECURITY: Make anchor for headlines escape > and <.
 * (T180237) SECURITY: Protect vendor folder with .htaccess.
-* (T180231) SECURITY: Remove PHPUnit file with known RCE if exists in update.php.
+* (T180231) SECURITY: Remove PHPUnit file with known RCE if exists in
+  update.php.
 * (T124404) SECURITY: XSS in langconverter when regex hits pcre.backtrack_limit.
 * (T119158) SECURITY: Handle -{}- syntax in attributes safely.
 
@@ -2400,8 +2469,8 @@ MediaWiki itself since 1.27.2, but none of them were security relevant.
 This is a security and maintenance release of the MediaWiki 1.27 branch.
 
 ApiCreateAccount was removed in 1.27.0. It was incorrectly still marked as
-deprecated (rather than already removed) in the RELEASE-NOTES at the point 1.27.0
-was released.
+deprecated (rather than already removed) in the RELEASE-NOTES at the point
+1.27.0 was released.
 
 === Changes since 1.27.1 ===
 
@@ -2420,24 +2489,26 @@ was released.
 * (T158766) Avoid SQL error on MSSQL when using selectRowCount()
 * (T145635) Fix too long index error when installing with MSSQL.
 * (T156184) $wgRawHtml will no longer apply to internationalization messages.
-* (T160519) CACHE_ANYTHING will not be CACHE_ACCEL if no accelerator is installed.
-* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow redirect
-  to interwiki links.
+* (T160519) CACHE_ANYTHING will not be CACHE_ACCEL if no accelerator is
+  installed.
+* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow
+  redirect to interwiki links.
 * (T144845) SECURITY: XSS in SearchHighlighter::highlightText() when
   $wgAdvancedSearchHighlighting is true.
 * (T125177) SECURITY: API parameters may now be marked as "sensitive" to keep
   their values out of the logs.
-* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a CSRF
-  token.
+* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a
+  CSRF token.
 * (T156184) SECURITY: Escape content model/format url parameter in message.
 * (T151735) SECURITY: SVG filter evasion using default attribute values in DTD
   declaration.
-* (T161453) SECURITY: LocalisationCache will no longer use the temporary directory
-  in it's fallback chain when trying to work out where to write the cache.
-* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file inclusion
-  syntax's link parameter.
-* (T108138) SECURITY: Sysops can undelete pages, although the page is protected against
-  it.
+* (T161453) SECURITY: LocalisationCache will no longer use the temporary
+  directory in it's fallback chain when trying to work out where to write the
+ cache.
+* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file
+  inclusion syntax's link parameter.
+* (T108138) SECURITY: Sysops can undelete pages, although the page is protected
+  against it.
 
 == MediaWiki 1.27.1 ==
 
@@ -2456,9 +2527,12 @@ This is a maintenance release of the MediaWiki 1.27 branch.
 * (T129738) SECURITY: Make $wgBlockDisablesLogin also restrict logged in
   permissions
 * (T129738) SECURITY: Make blocks log users out if $wgBlockDisablesLogin is true
-* (T115333) SECURITY: Check read permission when loading page content in ApiParse
-* (T57548) Remove support for $wgWellFormedXml = false, all output is now well formed
-* (T139670) Move 'UserGetRights' call before application of Session::getAllowedUserRights()
+* (T115333) SECURITY: Check read permission when loading page content in
+  ApiParse
+* (T57548) Remove support for $wgWellFormedXml = false, all output is now well
+  formed
+* (T139670) Move 'UserGetRights' call before application of
+  Session::getAllowedUserRights()
 
 == MediaWiki 1.27.0 ==
 
@@ -2585,11 +2659,15 @@ The following PHP extensions are strongly recommended:
 *** AbortLogin (create a MediaWiki\Auth\PreAuthenticationProvider instead)
 *** AbortNewAccount (create a MediaWiki\Auth\PreAuthenticationProvider instead)
 *** AddNewAccount (use LocalUserCreated instead)
-*** AuthPluginSetup (create a MediaWiki\Auth\PrimaryAuthenticationProvider instead)
+*** AuthPluginSetup (create a MediaWiki\Auth\PrimaryAuthenticationProvider
+    instead)
 *** ChangePasswordForm (use AuthChangeFormFields instead, or security levels)
-*** LoginUserMigrated (create a MediaWiki\Auth\PreAuthenticationProvider instead)
-*** UserCreateForm (create a MediaWiki\Auth\AuthenticationProvider of some type instead)
-*** UserLoginForm (create a MediaWiki\Auth\AuthenticationProvider of some type instead)
+*** LoginUserMigrated (create a MediaWiki\Auth\PreAuthenticationProvider
+    instead)
+*** UserCreateForm (create a MediaWiki\Auth\AuthenticationProvider of some type
+    instead)
+*** UserLoginForm (create a MediaWiki\Auth\AuthenticationProvider of some type
+    instead)
 ** The following hooks are removed:
 *** AbortChangePassword
 *** LoginPasswordResetMessage
@@ -2664,14 +2742,15 @@ The following PHP extensions are strongly recommended:
 * Added $wgAuthenticationTokenVersion, which if non-null prevents the
   user_token database field from being exposed in cookies. Setting this would
   be a good idea, but will log out all current sessions.
-* $wgEventRelayerConfig was added, for managing PubSub event relay configuration,
-  specifically for reliable CDN url purges.
+* $wgEventRelayerConfig was added, for managing PubSub event relay
+  configuration, specifically for reliable CDN url purges.
 * Requests have unique IDs, equal to the UNIQUE_ID environment variable (when
   MediaWiki is behind Apache+mod_unique_id or something similar) or a randomly-
   generated 24-character string. This request ID is used to annotate log records
-  and error messages. It is available client-side via mw.config.get( 'wgRequestId' ).
-  The request ID supplants exception IDs. Accordingly, MWExceptionHandler::getLogId()
-  is deprecated.
+  and error messages. It is available client-side via
+  mw.config.get( 'wgRequestId' ).
+  The request ID supplants exception IDs. Accordingly,
+  MWExceptionHandler::getLogId() is deprecated.
 * (T33313) Add a preference for watching uploads by default, also applies
   to API-based upload tools.
 * $wgJpegPixelFormat was added to override chroma subsampling for JPEG image
@@ -2681,7 +2760,8 @@ The following PHP extensions are strongly recommended:
   configuration of multiple authentication pieces that was possible with
   AuthPlugin. For example, it's now easy to plug in second-factor
   authentication, or add additional checks to the login process, or to support
-  multiple login methods at once, or to support non-password-based login methods.
+  multiple login methods at once, or to support non-password-based login
+  methods.
 ** Providers are configured via the global setting $wgAuthManagerConfig.
 ** A global, $wgDisableAuthManager, is temporarily available to disable
    AuthManager until extensions are ready to support it.
@@ -2694,8 +2774,9 @@ The following PHP extensions are strongly recommended:
 ** New hook, SecuritySensitiveOperationStatus, to work with the new mechanism
    for requiring a recent login before taking security-sensitive operations
    like changing a password.
-** Two new globals, $wgChangeCredentialsBlacklist and $wgRemoveCredentialsBlacklist
-   can be used to prevent the web UI and the API changing certain authentication data.
+** Two new globals, $wgChangeCredentialsBlacklist and
+   $wgRemoveCredentialsBlacklist can be used to prevent the web UI and the API
+   changing certain authentication data.
 * The file upload dialog (available if you install WikiEditor or VisualEditor)
   can now be configured using $wgUploadDialog.
 
@@ -2764,10 +2845,13 @@ The following PHP extensions are strongly recommended:
 * ApiBase::addTokenProperties() was removed (deprecated since 1.24).
 * ApiBase::getFinalPossibleErrors() was removed (deprecated since 1.24).
 * ApiBase::getFinalResultProperties() was removed (deprecated since 1.24).
-* ApiBase::getRequireAtLeastOneParameterErrorMessages() was removed (deprecated since 1.24).
+* ApiBase::getRequireAtLeastOneParameterErrorMessages() was removed (deprecated
+  since 1.24).
 * ApiBase::getPossibleErrors() was removed (deprecated since 1.24).
-* ApiBase::getRequireMaxOneParameterErrorMessages() was removed (deprecated since 1.24).
-* ApiBase::getRequireOnlyOneParameterErrorMessages() was removed (deprecated since 1.24).
+* ApiBase::getRequireMaxOneParameterErrorMessages() was removed (deprecated
+  since 1.24).
+* ApiBase::getRequireOnlyOneParameterErrorMessages() was removed (deprecated
+  since 1.24).
 * ApiBase::getResultProperties() was removed (deprecated since 1.24).
 * ApiBase::getTitleOrPageIdErrorMessage() was removed (deprecated since 1.24).
 * ApiBase::parseErrors() was removed (deprecated since 1.24).
@@ -2798,7 +2882,8 @@ changes to languages because of Phabricator reports.
 * (T116020) Aliases of magic words in MessagesXx.php are sorted by usage.
 
 === Other changes in 1.27 ===
-* Added dependency injection (DI) infrastructure, see docs/injection.txt for details.
+* Added dependency injection (DI) infrastructure, see docs/injection.txt for
+  details.
   It is planned to incrementally move MediaWiki code towards using DI, using the
   service locator (SL) pattern as a stepping stone.
 * ProfilerOutputUdp was removed. Note that there is a ProfilerOutputStats class.
@@ -2886,18 +2971,21 @@ changes to languages because of Phabricator reports.
   together but instead pick the final one, similar to image syntax.
 * XML-like parser tags (such as <gallery>), when unclosed, will be left unparsed
   rather than consume everything until the end of the page.
-* New maintenance script resetUserEmail.php allows sysadmins to reset user emails in case
-  a user forgot password/account was stolen.
+* New maintenance script resetUserEmail.php allows sysadmins to reset user
+  emails in case a user forgot password/account was stolen.
 * wfCheckEntropy() was removed (deprecated in 1.27).
 * Browser support for Internet Explorer 8 lowered from Grade A to Grade C.
 * ContentHandler::supportsCategories method added. Default is true.
   CategoryMembershipChangeJob updates are skipped for content that
   does not support categories.
-* wikidiff difference engine is no longer supported, anyone still using it are encouraged
-  to upgrade to wikidiff2 which is actively maintained and has better package availability.
-* Database logic was removed from WatchedItem and a WatchedItemStore was created:
-** WatchedItem::IGNORE_USER_RIGHTS and WatchedItem::CHECK_USER_RIGHTS were deprecated.
-   User::IGNORE_USER_RIGHTS and User::CHECK_USER_RIGHTS were introduced.
+* wikidiff difference engine is no longer supported, anyone still using it are
+  encouraged to upgrade to wikidiff2 which is actively maintained and has better
+  package availability.
+* Database logic was removed from WatchedItem and a WatchedItemStore was
+  created:
+** WatchedItem::IGNORE_USER_RIGHTS and WatchedItem::CHECK_USER_RIGHTS were
+   deprecated. User::IGNORE_USER_RIGHTS and User::CHECK_USER_RIGHTS were
+   introduced.
 ** WatchedItem::fromUserTitle was deprecated in favour of the constructor.
 ** WatchedItem::resetNotificationTimestamp was deprecated.
 ** WatchedItem::batchAddWatch was deprecated.
@@ -2907,8 +2995,9 @@ changes to languages because of Phabricator reports.
 ** WatchedItem::duplicateEntries was deprecated.
 ** EmailNotification::updateWatchlistTimestamp was deprecated.
 ** User::getWatchedItem was removed.
-* Unit tests don't work with external PHPUnit anymore, Composer is now the only supported
-  way. Run `composer install` to install it and other dev dependencies to run unit tests.
+* Unit tests don't work with external PHPUnit anymore, Composer is now the only
+  supported way. Run `composer install` to install it and other dev dependencies
+  to run unit tests.
 * wl_id field added to the watchlist table.
 * Revision::getRawText() was removed (deprecated since 1.21).
 * WikiPage::replaceSection() was removed (deprecated since 1.21).
@@ -2931,12 +3020,12 @@ changes to languages because of Phabricator reports.
 * Skin::newFromKey() was removed (deprecated since 1.24).
 * Skin::getUsableSkins() was removed (deprecated since 1.23).
 * LoadBalancer::pickRandom() was removed (deprecated in 1.21).
-* Article::getUndoText() and WikiPage::getUndoText were removed (deprecated since
-  1.21).
+* Article::getUndoText() and WikiPage::getUndoText were removed (deprecated
+  since 1.21).
 * DifferenceEngine::setText() was removed (deprecated in 1.21).
 * Title::newFromRedirectArray() was removed (deprecated in 1.21).
-* UserMailer::send() no longer accepts $replyto as the 5th argument and $contentType
-  as the 6th. These must be passed in the options array now.
+* UserMailer::send() no longer accepts $replyto as the 5th argument and
+  $contentType as the 6th. These must be passed in the options array now.
 * Title::newFromRedirectRecurse() was removed (deprecated in 1.21).
 * Skin::accesskey was removed (deprecated since 1.21).
 * Skin::blockLink was removed (deprecated since 1.21).
@@ -2987,15 +3076,15 @@ changes to languages because of Phabricator reports.
 * Skin::tooltipAndAccesskeyAttribs was removed (deprecated since 1.21).
 * Skin::userTalkLink was removed (deprecated since 1.21).
 * Skin::userToolLinksRedContribs was removed (deprecated since 1.21).
-* wikidiff3 is now the default and only PHP diff engine. It provides improved diff
-  performance on complex changes. $wgExternalDiffEngine = 'wikidiff3' therefore
-  makes no difference now. Users are still recommended to use wikidiff2 if possible,
-  though.
+* wikidiff3 is now the default and only PHP diff engine. It provides improved
+  diff performance on complex changes. $wgExternalDiffEngine = 'wikidiff3'
+  therefore makes no difference now. Users are still recommended to use
+  wikidiff2 if possible, though.
 * User::addNewUserLogEntry() was deprecated.
 * User::addNewUserLogEntryAutoCreate() was deprecated.
 * User::isPasswordReminderThrottled() was deprecated.
-* Bot-oriented parameters to Special:UserLogin (wpCookieCheck, wpSkipCookieCheck)
-  were removed.
+* Bot-oriented parameters to Special:UserLogin (wpCookieCheck,
+  wpSkipCookieCheck) were removed.
 * Installer can now be customized without patching MediaWiki code, see
   mw-config/overrides/README for details.
 
@@ -3061,7 +3150,8 @@ This is a maintenance release of the MediaWiki 1.26 branch.
 * (T129738) SECURITY: Make $wgBlockDisablesLogin also restrict logged in
   permissions
 * (T129738) SECURITY: Make blocks log users out if $wgBlockDisablesLogin is true
-* (T115333) SECURITY: Check read permission when loading page content in ApiParse
+* (T115333) SECURITY: Check read permission when loading page content in
+  ApiParse
 * Remove support for $wgWellFormedXml = false, all output is now well formed
 
 == MediaWiki 1.26.3 ==
@@ -3309,8 +3399,8 @@ changes to languages because of Phabricator reports.
 ** dty (डोटेली/Doteli), thanks to translators जनक राज भट्ट, बिप्लब आनन्द,
    मेश सिंह बोहरा, and राम प्रसाद जोशी
 ** luz (لئری دوٙمینی / Southern Luri)
-** olo (Livvinкarjala / Livvi-Karelian), thanks to translators Denö, Hiloin Natoi,
-   Ilja.mos, and Mashoi7
+** olo (Livvinкarjala / Livvi-Karelian), thanks to translators Denö, Hiloin
+   Natoi, Ilja.mos, and Mashoi7
 
 === Other changes in 1.26 ===
 * ChangeTags::tagDescription() will return false if the interface message
@@ -3346,8 +3436,8 @@ changes to languages because of Phabricator reports.
   - The $uniq_prefix argument for Parser::extractTagsAndParams() and the
     $prefix argument for StripState::_construct() are deprecated and their
     value is ignored.
-* wfSuppressWarnings() and wfRestoreWarnings() were split into a separate library,
-  mediawiki/at-ease, and are now deprecated. Callers should use
+* wfSuppressWarnings() and wfRestoreWarnings() were split into a separate
+  library, mediawiki/at-ease, and are now deprecated. Callers should use
   MediaWiki\suppressWarnings() and MediaWiki\restoreWarnings() directly.
 * The Block class constructor now takes an associative array of parameters
   instead of many optional positional arguments. Calling the constructor the old
@@ -3523,8 +3613,9 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   be installed and running for any such queues to work.
 * $wgAutopromoteOnce no longer supports the 'view' event. For keeping some
   compatibility, any 'view' event triggers will still trigger on 'edit'.
-* $wgExtensionDirectory was added for when your extensions directory is somewhere
-  other than $IP/extensions (as $wgStyleDirectory does with the skins directory).
+* $wgExtensionDirectory was added for when your extensions directory is
+  somewhere other than $IP/extensions (as $wgStyleDirectory does with the skins
+  directory).
 
 === New features in 1.25 ===
 * (T64861) Updated plural rules to CLDR 26. Includes incompatible changes
@@ -3532,11 +3623,11 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   that fall back to Russian.
 * (T60139) ResourceLoaderFileModule now supports language fallback
   for 'languageScripts'.
-* Added a new hook, "ContentAlterParserOutput", to allow extensions to modify the
-  parser output for a content object before links update.
+* Added a new hook, "ContentAlterParserOutput", to allow extensions to modify
+  the parser output for a content object before links update.
 * (T37785) Enhanced recent changes and extended watchlist are now default.
-  Documentation: https://meta.wikimedia.org/wiki/Special:MyLanguage/Help:Enhanced_recent_changes
-  and https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgDefaultUserOptions.
+  Documentation: https://meta.wikimedia.org/wiki/Help:Enhanced_recent_changes
+  and https://www.mediawiki.org/wiki/Manual:$wgDefaultUserOptions
 * (T69341) SVG images will no longer be base64-encoded when being embedded
   in CSS. This results in slight size increase before gzip compression (due to
   percent-encoding), but up to 20% decrease after it.
@@ -3545,10 +3636,12 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   snippets) usually displayed in the top-right corner of the page. They have
   been in use on Wikipedia for a long time, implemented using templates and CSS
   absolute positioning.
-  - Basic wikitext syntax: <indicator name="foo">[[File:Foo.svg|20px]]</indicator>
-  - Usage instructions: https://www.mediawiki.org/wiki/Help:Page_status_indicators
+  - Basic wikitext syntax:
+    <indicator name="foo">[[File:Foo.svg|20px]]</indicator>
+  - Usage instructions:
+    https://www.mediawiki.org/wiki/Help:Page_status_indicators
   - Adjusting custom skins to support indicators:
-    https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skinning#Page_status_indicators
+    https://www.mediawiki.org/wiki/Manual:Skinning#Page_status_indicators
 * Edit tokens may now be time-limited: passing a maximum age to
   User::matchEditToken will reject any older tokens.
 * The debug logging internals have been overhauled, and are now using the
@@ -3582,10 +3675,11 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   dynamically-compiled Mustache templates (currently uses lightncandy library).
 * Clickable anchors for each section heading in the content are now generated
   and appear in the gutter on hovering over the heading.
-* Added 'CategoryViewer::doCategoryQuery' and 'CategoryViewer::generateLink' hooks
-  to allow extensions to override how links to pages are rendered within NS_CATEGORY
-* (T19665) Special:WantedPages only lists page which having at least one red link
-  pointing to it.
+* Added 'CategoryViewer::doCategoryQuery' and 'CategoryViewer::generateLink'
+  hooks to allow extensions to override how links to pages are rendered within
+  NS_CATEGORY
+* (T19665) Special:WantedPages only lists page which having at least one red
+  link pointing to it.
 * New hooks 'ApiMain::moduleManager' and 'ApiQuery::moduleManager', can be
   used for conditional registration of API modules.
 * New hook 'EnhancedChangesList::getLogText' to alter, remove or add to the
@@ -3594,8 +3688,8 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   interface, reachable via IContextSource::getStats().
 * Move the jQuery Client library from being mastered in MediaWiki as v0.1.0 to a
   proper, published library, which is now tagged as v1.0.0.
-* A new message (defaulting to blank), 'editnotice-notext', can be shown to users
-  when they are editing if no edit notices apply to the page being edited.
+* A new message (defaulting to blank), 'editnotice-notext', can be shown to
+  users when they are editing if no edit notices apply to the page being edited.
 * (T94536) You can now make the sitenotice appear to logged-in users only by
   editing MediaWiki:Anonnotice and replacing its content with "". Setting it to
   "-" (default) will continue disable it and fallback to MediaWiki:Sitenotice.
@@ -3610,18 +3704,19 @@ This is a bug fix release of the MediaWiki 1.25 branch.
 ==== External libraries ====
 * MediaWiki now requires certain external libraries to be installed. In the past
   these were bundled inside the Git repository of MediaWiki core, but now they
-  need to be installed separately. For users using the tarball, this will be taken
-  care of and no action will be required. Users using Git will either need to use
-  composer to fetch dependencies or use the mediawiki/vendor repository which includes
-  all dependencies for MediaWiki core and ones used in Wikimedia deployment. Detailed
-  instructions can be found at:
+  need to be installed separately. For users using the tarball, this will be
+  taken care of and no action will be required. Users using Git will either need
+  to use composer to fetch dependencies or use the mediawiki/vendor repository
+  which includes all dependencies for MediaWiki core and ones used in Wikimedia
+  deployment. Detailed instructions can be found at:
   https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries
 * The following libraries are now required:
 ** psr/log
-   This library provides the interfaces set by the PSR-3 standard (http://www.php-fig.org/psr/psr-3/)
-   which are used by MediaWiki internally via the
-   MediaWiki\Logger\LoggerFactory class.
-   See the structured logging RfC (https://www.mediawiki.org/wiki/Special:MyLanguage/Requests_for_comment/Structured_logging)
+   This library provides the interfaces set by the PSR-3 standard
+   (http://www.php-fig.org/psr/psr-3/) which are used by MediaWiki internally
+   via the MediaWiki\Logger\LoggerFactory class.
+   See the structured logging RfC
+   <https://www.mediawiki.org/wiki/Requests_for_comment/Structured_logging>
    for more background information.
 ** cssjanus/cssjanus
    This library was formerly bundled with MediaWiki core and has been removed.
@@ -3630,11 +3725,13 @@ This is a bug fix release of the MediaWiki 1.25 branch.
    This library was formerly bundled with MediaWiki core and has been removed.
    It compiles LESS files into CSS.
 ** wikimedia/cdb
-   This library was formerly a part of MediaWiki core, and has been moved into a separate library.
-   It provides CDB functions which are used in the Interwiki and Localization caches.
-   More information about the library can be found at https://www.mediawiki.org/wiki/Special:MyLanguage/CDB.
+   This library was formerly a part of MediaWiki core, and has been moved into a
+   separate library. It provides CDB functions which are used in the Interwiki
+   and Localization caches. More information about the library can be found at
+   https://www.mediawiki.org/wiki/CDB.
 ** liuggio/statsd-php-client
-   This library provides a StatsD client API for logging application metrics to a remote server.
+   This library provides a StatsD client API for logging application metrics to
+   a remote server.
 
 === Bug fixes in 1.25 ===
 * (T73003) No additional code will be generated to try to load CSS-embedded
@@ -3655,21 +3752,27 @@ This is a bug fix release of the MediaWiki 1.25 branch.
 * (T70361) Autocomments containing "/*" are parsed correctly.
 * The Special:WhatLinksHere page linked from 'Number of redirects to this page'
   on action=info about a file page does not list file links anymore.
-* (T78637) Search bar is not autofocused unless it is empty so that proper scrolling using arrow keys is possible.
-* (T50853) Database::makeList() modified to handle 'NULL' separately when building IN clause
+* (T78637) Search bar is not autofocused unless it is empty so that proper
+  scrolling using arrow keys is possible.
+* (T50853) Database::makeList() modified to handle 'NULL' separately when
+  building IN clause
 * (T85192) Captcha position modified in Usercreate template. As a result:
 ** extrafields parameter added to Usercreate.php to insert additional data
-** 'extend' method added to QuickTemplate to append additional values to any field of data array
+** 'extend' method added to QuickTemplate to append additional values to any
+  field of data array
 * (T86974) Several Title methods now load from the database when necessary
   (instead of returning incorrect results) even when the page ID is known.
-* (T74070) Duplicate search for archived files on file upload now omits the extension.
+* (T74070) Duplicate search for archived files on file upload now omits the
+  extension.
   This requires the fa_sha1 field being populated.
 * Removed rel="archives" from the "View history" link, as it did not pass
   HTML validation.
 * $wgUseTidy is now set when parserTests are run with the tidy option to match
   output on wiki.
-* (T37472) update.php will purge ResourceLoader cache unless --nopurge is passed to it.
-* (T72109) mediawiki.language should respect $wgTranslateNumerals in convertNumber().
+* (T37472) update.php will purge ResourceLoader cache unless --nopurge is passed
+  to it.
+* (T72109) mediawiki.language should respect $wgTranslateNumerals in
+  convertNumber().
 
 === Action API changes in 1.25 ===
 * (T67403) XML tag highlighting is now only performed for formats
@@ -3728,7 +3831,8 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   log entry is not implemented yet.
 * list=tags has additional properties to indicate 'active' status and tag
   sources.
-* siprop=libraries was added to ApiQuerySiteInfo to list installed external libraries.
+* siprop=libraries was added to ApiQuerySiteInfo to list installed external
+  libraries.
 * (T88010) Added action=checktoken, to test a CSRF token's validity.
 * (T88010) Added intestactions to prop=info, to allow querying of
   Title::userCan() via the API.
@@ -3756,7 +3860,8 @@ This is a bug fix release of the MediaWiki 1.25 branch.
 * ApiHelp has been rewritten to support i18n and paginated HTML output.
   Most existing modules should continue working without changes, but should do
   the following:
-  * Add an i18n message "apihelp-{$moduleName}-description" to replace getDescription().
+  * Add an i18n message "apihelp-{$moduleName}-description" to replace
+    getDescription().
   * Add i18n messages "apihelp-{$moduleName}-param-{$param}" for each parameter
     to replace getParamDescription(). If necessary, the settings array returned
     by getParams() can use the new ApiBase::PARAM_HELP_MSG key to override the
@@ -3775,7 +3880,8 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   has been removed.
 * ApiFormatBase now always buffers. Output is done when
   ApiFormatBase::closePrinter is called.
-* Much of the logic in ApiQueryRevisions has been split into ApiQueryRevisionsBase.
+* Much of the logic in ApiQueryRevisions has been split into
+  ApiQueryRevisionsBase.
 * The 'revids' parameter supplied by ApiPageSet will now count deleted
   revisions as "good" if the user has the 'deletedhistory' right. New methods
   ApiPageSet::getLiveRevisionIDs() and ApiPageSet::getDeletedRevisionIDs() are
@@ -3883,7 +3989,8 @@ changes to languages because of Bugzilla reports.
 * Removed XmlDumpWriter::schemaVersion(). (deprecated since 1.20)
 * Removed LogEventsList::getDisplayTitle(). (deprecated since 1.20)
 * Removed Preferences::trySetUserEmail(). (deprecated since 1.20)
-* Removed mw.user.name() and mw.user.anonymous() methods. (deprecated since 1.20)
+* Removed mw.user.name() and mw.user.anonymous() methods. (deprecated since
+  1.20)
 * Removed 'ok' and 'err' parameters in the mediawiki.api modules. (deprecated
   since 1.20)
 * Removed 'async' parameter from the  mw.Api#getCategories() method. (deprecated
@@ -3907,7 +4014,8 @@ changes to languages because of Bugzilla reports.
 * Deprecated the getInternalLinkAttributes, getInternalLinkAttributesObj,
   and getInternalLinkAttributes methods in Linker, and removed
   getExternalLinkAttributes method, which was deprecated in MediaWiki 1.18.
-* Removed Sites class, which was deprecated in 1.21 and replaced by SiteSQLStore.
+* Removed Sites class, which was deprecated in 1.21 and replaced by
+  SiteSQLStore.
 * Added wgRelevantArticleId to the client-side config, for use on special pages.
 * Deprecated the TitleIsCssOrJsPage hook. Superseded by the
   ContentHandlerDefaultModelFor hook since MediaWiki 1.21.
@@ -3941,7 +4049,8 @@ changes to languages because of Bugzilla reports.
       $form->setDisplayFormat( 'vform' ); // throws exception
     Instead, do this:
       $form = HTMLForm::factory( 'vform', … );
-* Deprecated Revision methods getRawUser(), getRawUserText() and getRawComment().
+* Deprecated Revision methods getRawUser(), getRawUserText() and
+  getRawComment().
 * BREAKING CHANGE: mediawiki.user.generateRandomSessionId:
   The alphabet of the prior string returned was A-Za-z0-9 and now it is 0-9A-F
 * (T87504) Avoid serving SVG background-images in CSS for Opera 12, which
@@ -3949,16 +4058,18 @@ changes to languages because of Bugzilla reports.
 * Removed maintenance script dumpSisterSites.php.
 * DatabaseBase class constructors must be called using the array argument style.
   Ideally, DatabaseBase:factory() should be used instead in most cases.
-* Deprecated ParserOutput::addSecondaryDataUpdate and ParserOutput::getSecondaryDataUpdates.
-  This is a hard deprecation, with getSecondaryDataUpdates returning an empty array and
-  addSecondaryDataUpdate throwing an exception. These functions will be removed in 1.26,
-  since they interfere with caching of ParserOutput objects.
-* Introduced new hook 'SecondaryDataUpdates' that allows extensions to inject custom updates.
-* Introduced new hook 'OpportunisticLinksUpdate' that allows extensions to perform
-  updates when a page is re-rendered.
+* Deprecated ParserOutput::addSecondaryDataUpdate and
+  ParserOutput::getSecondaryDataUpdates.
+  This is a hard deprecation, with getSecondaryDataUpdates returning an empty
+  array and addSecondaryDataUpdate throwing an exception. These functions will
+  be removed in 1.26, since they interfere with caching of ParserOutput objects.
+* Introduced new hook 'SecondaryDataUpdates' that allows extensions to inject
+  custom updates.
+* Introduced new hook 'OpportunisticLinksUpdate' that allows extensions to
+  perform updates when a page is re-rendered.
 * EditPage::attemptSave has been modified not to call handleStatus itself and
-  instead just returns the Status object. Extension calling it should be aware of
-  this.
+  instead just returns the Status object. Extension calling it should be aware
+  of this.
 * Removed class DBObject. (unused since 1.10)
 * wfDiff() is deprecated.
 * The -m (maximum replication lag) option of refreshLinks.php was removed.
@@ -3969,8 +4080,8 @@ changes to languages because of Bugzilla reports.
   retrievedfrom, thisisdeleted, viewsourcelink, lastmodifiedat, laggedslavemode,
   protect-summary-cascade
 * All BloomCache related code has been removed. This was largely experimental.
-* $wgResourceModuleSkinStyles no longer supports per-module local or remote paths. They
-  can only be set for the entire skin.
+* $wgResourceModuleSkinStyles no longer supports per-module local or remote
+  paths. They can only be set for the entire skin.
 * Removed global function swap(). (deprecated since 1.24)
 * Deprecated the ".php5" file extension entry points and the $wgScriptExtension
   configuration variable. Refer to the ".php" files instead. If you want
@@ -4128,30 +4239,33 @@ This is a security and maintenance release of the MediaWiki 1.24 branch.
 * $wgCompiledFiles has been removed.
 * $wgSortSpecialPages was removed, the listing on Special:SpecialPages is
   now always sorted.
-* $wgSpecialPages may now use callback functions as an alternative to plain class names.
-  This allows more control over constructor parameters.
+* $wgSpecialPages may now use callback functions as an alternative to plain
+  class names. This allows more control over constructor parameters.
 * $wgHTCPMulticastAddress, $wgHTCPMulticastRouting and $wgHTCPPort were removed.
 * $wgRC2UDPAddress, $wgRC2UDPInterwikiPrefix, $wgRC2UDPOmitBots, $wgRC2UDPPort
   and $wgRC2UDPPrefix have been removed.
 * The default password type for MediaWiki has been changed from MD5 to PBKDF2.
-  Password hashes will automatically be updated as users log in. If necessary, the
-  old MD5 hashing can be restored by changing $wgPasswordDefault to 'B'. In addition,
-  there is a maintenance script wrapOldPassword.php that can wrap all passwords in
-  PBKDF2 (or the hashing algorithm of your choice) if you don't want to wait for your
-  users to log in.
+  Password hashes will automatically be updated as users log in. If necessary,
+  the old MD5 hashing can be restored by changing $wgPasswordDefault to 'B'.
+  In addition, there is a maintenance script wrapOldPassword.php that can wrap
+  all passwords in PBKDF2 (or the hashing algorithm of your choice) if you don't
+  want to wait for your users to log in.
 * $wgImportSources can now either be a regular array, or an associative map
   specifying subprojects on the interwiki map of the target wiki, or a mix of
   the two. Existing configurations will still work.
-* Users must be able to edit through a page's protection to be able to delete it.
-* The default thumb size ($wgDefaultUserOptions['thumbsize']) is now 300px, up from
-  180px. If you have altered the number of entries in $wgThumbLimits for your wiki, you
-  may need to adjust your default user settings to compensate for the index change.
-* $wgDeferredUpdateList is now deprecated, you should use DeferredUpdates::addUpdate()
-  instead.
+* Users must be able to edit through a page's protection to be able to delete
+  it.
+* The default thumb size ($wgDefaultUserOptions['thumbsize']) is now 300px, up
+  from 180px. If you have altered the number of entries in $wgThumbLimits for
+  your wiki, you may need to adjust your default user settings to compensate for
+  the index change.
+* $wgDeferredUpdateList is now deprecated, you should use
+  DeferredUpdates::addUpdate() instead.
 * $wgCanonicalLanguageLinks has been removed. Per Google recommendations, we
   will not send a rel=canonical pointing to a variant-neutral page, however
   we will send rel=alternate.
-* $wgResourceLoaderLESSFunctions has been deprecated and will be removed in the future.
+* $wgResourceLoaderLESSFunctions has been deprecated and will be removed in the
+  future.
 * $wgGoToEdit has been removed. Use the SpecialSearchNogomatch hook for similar
   functionality.
 
@@ -4222,7 +4336,8 @@ This is a security and maintenance release of the MediaWiki 1.24 branch.
   specified for backwards-compatibility and to define the path Special:Version
   uses to find extension license information.
 * Browser tests are now included to verify basic wiki functionality in developer
-  environments. For details on running tests, see tests/browser/README.mediawiki.
+  environments. For details on running tests, see
+  tests/browser/README.mediawiki.
 * Upgrade jStorage to v0.4.10.
 * {{!}} is now a magic word that produces the | character. This removes the need
   for Template:! for purposes such as passing pipes inside of parameters.
@@ -4258,8 +4373,8 @@ This is a security and maintenance release of the MediaWiki 1.24 branch.
 * (bug 4488) There is now a preference to watch pages where the user has
   rollbacked an edit by default.
 * (bug 15484) Users will now be redirected to the login page when they need to
-  log in, rather than being shown a page asking them to log in and having to click
-  another link to actually get to the login page.
+  log in, rather than being shown a page asking them to log in and having to
+  click another link to actually get to the login page.
 * A JsonContent and JsonContentHandler were added for extensions to extend.
 * (bug 35045) Redirects to sections will now update the URL in browser's address
   bar using the HTML5 History API. When [[Dog]] redirects to [[Animals#Dog]],
@@ -4269,14 +4384,15 @@ This is a security and maintenance release of the MediaWiki 1.24 branch.
 * Added HTMLAutoCompleteSelectField.
 * Added a new hook, "SkinPreloadExistence", to allow extensions to add titles to
   link existence cache before the page is rendered.
-* Config::set() was moved to its own interface, MutableConfig. GlobalVarConfig::set()
-  is now deprecated, does not implement MutableConfig.
-* A MutableConfig named HashConfig was added, that stores an array of configuration
-  settings.
+* Config::set() was moved to its own interface, MutableConfig.
+  GlobalVarConfig::set() is now deprecated, does not implement MutableConfig.
+* A MutableConfig named HashConfig was added, that stores an array of
+  configuration settings.
 * (bug 69418) A MultiConfig implementation was added that supports fallback
   to multiple Config instances.
 * Update CSSJanus to v1.1.0.
-* Added FormatJson::parse() returning status with result or localized error message
+* Added FormatJson::parse() returning status with result or localized error
+  message
 * Added DeletedContribsPager::reallyDoQuery hook allowing extensions to data to
   Special:DeletedContributions
 * Added DeletedContributionsLineEnding hook allowing extensions to format
@@ -4380,14 +4496,15 @@ This is a security and maintenance release of the MediaWiki 1.24 branch.
   $wgAPIPropModules, and $wgAPIListModules settings) now allow API modules
   to be specified using a "module spec" array instead of a plain class name.
   A "module spec" is an associative array containing at least the 'class' key
-  for the module's class, and optionally a 'factory' key for the factory function
-  to use for the module. This is intended for extensions that want control over
-  the instantiation of their API modules, to allow for proper dependency
-  injection.
+  for the module's class, and optionally a 'factory' key for the factory
+  function to use for the module. This is intended for extensions that want
+  control over the instantiation of their API modules, to allow for proper
+  dependency injection.
 * A new param type 'submodule' is available. Parameters of this type will take
   the list of valid values from the module's ApiModuleManager for the group
   corresponding to the parameter name.
-* The 'APIGetPossibleErrors' and 'APIGetResultProperties' hooks are no longer used.
+* The 'APIGetPossibleErrors' and 'APIGetResultProperties' hooks are no longer
+  used.
 * API token handling has been rewritten. Any API module using tokens will need
   to be updated:
   * ApiBase::needsToken now returns a token type instead of boolean true when a
@@ -4543,7 +4660,8 @@ changes to languages because of Bugzilla reports.
   is unused by any modern extension.
 * Removed maintenance/nextJobDB.php; no longer in use.
 * Removed global function wfViewPrevNext(). (deprecated since 1.19)
-* Removed global function xmlsafe() from Export.php. (moved to OAIRepo extension)
+* Removed global function xmlsafe() from Export.php. (moved to OAIRepo
+  extension)
 * Removed Title::userCanRead(). (deprecated since 1.19)
 * Removed maintenance script importTextFile.php. Use edit.php script instead.
 * A _from_namespace field has been added to the templatelinks, pagelinks,
@@ -4554,13 +4672,13 @@ changes to languages because of Bugzilla reports.
   userNotLoggedInPage() from EditPage.php. (deprecated since 1.19)
 * Removed functions getContent(), getPreloadedText(), mergeChangesInto() and
   setPreloadedText() from EditPage.php. (deprecated since 1.21)
-* Removed global functions wfArrayLookup(), wfArrayMerge(), wfDebugDieBacktrace()
-  and wfTime(). (deprecated since 1.22)
+* Removed global functions wfArrayLookup(), wfArrayMerge(),
+  wfDebugDieBacktrace() and wfTime(). (deprecated since 1.22)
 * Browser support for Internet Explorer 6 and 7 lowered from Grade A to Grade C,
   meaning that JavaScript is no longer executed in these browser versions.
 * Browser support for Opera 11 lowered from Grade A to Grade C.
-* Removed IEFixes module which existed purely to provide support for MSIE versions
-  below 7 (conditionally loaded only for those browsers).
+* Removed IEFixes module which existed purely to provide support for MSIE
+  versions below 7 (conditionally loaded only for those browsers).
 * Deprecated SpecialPageFactory::getList() in favor of
   SpecialPageFactory::getNames()
 * Action::checkCanExecute() no longer has a return value.
@@ -4783,6 +4901,11 @@ of files that are no longer available follows.
 
 = MediaWiki 1.23 =
 
+== MediaWiki 1.23.17 ==
+
+=== Changes since 1.23.16 === <!--T:69-->
+* Fix syntax errors introduced in 1.23.16 when running PHP 5.3.
+
 == MediaWiki 1.23.16 ==
 This is a security and maintenance release of the MediaWiki 1.23 branch.
 
@@ -4793,21 +4916,21 @@ This is a security and maintenance release of the MediaWiki 1.23 branch.
 * Submitting the lgtoken and lgpassword parameters in the query string to
   action=login is now deprecated and outputs a warning. They should be submitted
   in the POST body instead.
-* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow redirect
-  to interwiki links.
+* (T109140) (T122209) SECURITY: Special:UserLogin and Special:Search allow
+  redirect to interwiki links.
 * (T144845) SECURITY: XSS in SearchHighlighter::highlightText() when
   $wgAdvancedSearchHighlighting is true.
 * (T125177) SECURITY: API parameters may now be marked as "sensitive" to keep
   their values out of the logs.
-* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a CSRF
-  token.
+* (T150044) SECURITY: "Mark all pages visited" on the watchlist now requires a
+  CSRF token.
 * (T156184) SECURITY: Escape content model/format url parameter in message.
 * (T151735) SECURITY: SVG filter evasion using default attribute values in DTD
   declaration.
-* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file inclusion
-  syntax's link parameter.
-* (T108138) SECURITY: Sysops can undelete pages, although the page is protected against
-  it.
+* (T48143) SECURITY: Spam blacklist ineffective on encoded URLs inside file
+  inclusion syntax's link parameter.
+* (T108138) SECURITY: Sysops can undelete pages, although the page is protected
+  against it.
 
 == MediaWiki 1.23.15 ==
 
@@ -4826,7 +4949,8 @@ This is a maintenance release of the MediaWiki 1.23 branch.
 * (T129738) SECURITY: Make $wgBlockDisablesLogin also restrict logged in
   permissions
 * (T129738) SECURITY: Make blocks log users out if $wgBlockDisablesLogin is true
-* (T115333) SECURITY: Check read permission when loading page content in ApiParse
+* (T115333) SECURITY: Check read permission when loading page content in
+  ApiParse
 * Remove support for $wgWellFormedXml = false, all output is now well formed
 
 == MediaWiki 1.23.13 ==
@@ -5018,7 +5142,8 @@ This is a security and maintenance release of the MediaWiki 1.23 branch.
 
 * (bug 65839) SECURITY: Prevent external resources in SVG files.
 * (bug 67025) Special:Watchlist: Don't try to render empty row.
-* (bug 66922) Don't allow some E_NOTICE messages to end up in the LocalSettings.php.
+* (bug 66922) Don't allow some E_NOTICE messages to end up in the
+  LocalSettings.php.
 * (bug 66467) FileBackend: Avoid using popen() when "parallelize" is disabled.
 * (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects
   like only extracting the tail of the file partially or not at all.
@@ -5159,7 +5284,8 @@ This is a security and maintenance release of the MediaWiki 1.23 branch.
   buttons.
 * Special:UserLogin/signup now does AJAX checks for invalid and taken usernames,
   displaying the error live.
-* Added BaseTemplateAfterPortlet hook to allow injecting html after portlets in skins.
+* Added BaseTemplateAfterPortlet hook to allow injecting html after portlets in
+  skins.
 * Support has been added for a JSON based localisation file format. The
   installer has been updated to use it.
 * Changes to content typography (colors, line-height etc.). See
@@ -5168,11 +5294,12 @@ This is a security and maintenance release of the MediaWiki 1.23 branch.
   single icon (from nine). This should not affect local rules unless they were
   re-using these icons, which have now been deleted.
 * ResourceLoader: mw.loader.using() now implements a Promise interface.
-* Add new hook ChangesListInitRows accessed via ChangesList::initChangesListRows.
+* Add new hook ChangesListInitRows accessed via
+  ChangesList::initChangesListRows.
   If called by the ChangesList consumer this gives extensions a chance to batch
   process the result set prior to rendering.
-* A PoolCounterRedis class was added which can be make use of in $wgPoolCounterConf.
-  This requires at least one Redis 2.6+ server.
+* A PoolCounterRedis class was added which can be make use of in
+  $wgPoolCounterConf. This requires at least one Redis 2.6+ server.
 * $wgProfileToDatabase was removed. Set $wgProfiler to ProfilerSimpleDB
   in StartProfiler.php instead of using this.
 * (bug 63444) Made it possible to change the indent string (default: 4 spaces)
@@ -5544,28 +5671,43 @@ This is a maintenance release of the MediaWiki 1.22 branch.
 This is a security release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.11 ===
-* (bug 70672) SECURITY: OutputPage: Remove separation of css and js module allowance.
+* (bug 70672) SECURITY: OutputPage: Remove separation of css and js module
+  allowance.
 
 == MediaWiki 1.22.11 ==
 This is a security release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.10 ===
-* (bug 69008) SECURITY: Enhance CSS filtering in SVG files. Filter <style> elements; normalize style elements and attributes before filtering; add checks for attributes that contain css; add unit tests for html5sec and reported bugs.
+* (bug 69008) SECURITY: Enhance CSS filtering in SVG files. Filter <style>
+  elements; normalize style elements and attributes before filtering; add checks
+  for attributes that contain css; add unit tests for html5sec and reported
+  bugs.
 
 == MediaWiki 1.22.10 ==
 This is a maintenance release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.9 ===
 * (bug 64970) Fix support for blobs on DatabaseOracle::update
-* (bug 60719) In MediaWiki 1.22, the job queue execution on each page request was changed (Gerrit change 59797) so, instead of executing the job inside the same PHP process that's rendering the page, a new PHP cli command is spawned to execute runJobs.php in the background. It will only work if $wgPhpCli is set to an actual path or safe mode is off, otherwise, the old method will be used. https://www.mediawiki.org/wiki/Manual:Job_queue#Changes_introduced_in_MediaWiki_1.22 for more information. This change was in earlier releases of 1.22 but was not noted here until now.
+* (bug 60719) In MediaWiki 1.22, the job queue execution on each page request
+  was changed (Gerrit change 59797) so, instead of executing the job inside the
+  same PHP process that's rendering the page, a new PHP cli command is spawned
+  to execute runJobs.php in the background. It will only work if $wgPhpCli is
+  set to an actual path or safe mode is off, otherwise, the old method will be
+  used. See
+  https://www.mediawiki.org/wiki/Manual:Job_queue#Changes_in_MediaWiki_1.22
+  for more information. This change was in earlier releases of 1.22 but was not
+  noted here until now.
 
 == MediaWiki 1.22.9 ==
 This is a security and maintenance release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.8 ===
 * (bug 68187) SECURITY: Prepend jsonp callback with comment.
-* (bug 66608) SECURITY: Fix for XSS issue in bug 66608: Generate the URL used for loading a new page in Javascript,instead of relying on the URL in the link that has been clicked.
-* (bug 65778) SECURITY: Copy prevent-clickjacking between OutputPage and ParserOutput.
+* (bug 66608) SECURITY: Fix for XSS issue in bug 66608: Generate the URL used
+  for loading a new page in Javascript,instead of relying on the URL in the
+  link that has been clicked.
+* (bug 65778) SECURITY: Copy prevent-clickjacking between OutputPage and
+  ParserOutput.
 * (bug 59147) The img_metadata field was not being decoded from bytea into text.
 
 == MediaWiki 1.22.8 ==
@@ -5573,16 +5715,24 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.7 ===
 * (bug 65839) SECURITY: Prevent external resources in SVG files.
-* (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects like only extracting the tail of the file partially or not at all.
+* (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects like
+  only extracting the tail of the file partially or not at all.
 
 == MediaWiki 1.22.7 ==
 This is a security and maintenance release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.6 ===
-* (bug 65501) SECURITY: Don't parse usernames as wikitext on Special:PasswordReset.
+* (bug 65501) SECURITY: Don't parse usernames as wikitext on
+  Special:PasswordReset.
 * (bug 36356) Add space between two feed links.
-* (bug 63269) Email notifications were not correctly handling the MediaWiki:Helppage message being set to a full URL. This is a regression from the 1.22.5 point release, which made the default value for it a URL. If you customized MediaWiki:Enotif body (the text of email notifications), you'll need to edit it locally to include the URL via the new variable $HELPPAGE instead of the parser functions fullurl and canonicalurl; otherwise you don't have to do anything.
-Add missing uploadstash.us_props for PostgreSQL.
+* (bug 63269) Email notifications were not correctly handling the
+  MediaWiki:Helppage message being set to a full URL. This is a regression from
+  the 1.22.5 point release, which made the default value for it a URL. If you
+  customized MediaWiki:Enotif body (the text of email notifications), you'll
+  need to edit it locally to include the URL via the new variable $HELPPAGE
+  instead of the parser functions fullurl and canonicalurl; otherwise you don't
+  have to do anything.
+* Add missing uploadstash.us_props for PostgreSQL.
 * (bug 56047) Fixed stream wrapper in PhpHttpRequest.
 
 == MediaWiki 1.22.6 ==
@@ -5600,8 +5750,17 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 * Fix custom local MediaWiki:Helppage values.
 * mediawiki.js: Fix documentation breakage.
 * (bug 58153) Make MySQLi work with non standard port.
-* (bug 53887) Reintroduced a link to help pages in the default sidebar, that any sysop can customize by editing MediaWiki:Sidebar locally. The link now points to a mediawiki.org page which is guaranteed to exist. Nothing needs to be done on your end, but remember to adjust MediaWiki:Sidebar for the needs of your wikis. Everyone can help with the shared documentation by translating: https://www.mediawiki.org/wiki/Special:Translate/agg-Help_pages .
-* (bug 53888) Corrected a regression in 1.22 which introduced red links on the login page. If you previously installed 1.22.x and have created a local page to make the red link blue, write its title as in MediaWiki:helplogin-url if you didn't already. Otherwise, you don't need to do anything, but you can translate the help page at https://www.mediawiki.org/wiki/Help:Logging_in .
+* (bug 53887) Reintroduced a link to help pages in the default sidebar, that any
+  sysop can customize by editing MediaWiki:Sidebar locally. The link now points
+  to a mediawiki.org page which is guaranteed to exist. Nothing needs to be done
+  on your end, but remember to adjust MediaWiki:Sidebar for the needs of your
+  wikis. Everyone can help with the shared documentation by translating:
+  https://www.mediawiki.org/wiki/Special:Translate/agg-Help_pages .
+* (bug 53888) Corrected a regression in 1.22 which introduced red links on the
+  login page. If you previously installed 1.22.x and have created a local page
+  to make the red link blue, write its title as in MediaWiki:helplogin-url if
+  you didn't already. Otherwise, you don't need to do anything, but you can
+  translate the help page at <https://www.mediawiki.org/wiki/Help:Logging_in>.
 
 == MediaWiki 1.22.4 ==
 This is a maintenance release of the MediaWiki 1.22 branch.
@@ -5613,13 +5772,22 @@ This is a maintenance release of the MediaWiki 1.22 branch.
 This is a security and bugfix release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.2 ===
-* (bug 60771) SECURITY: Disallow uploading SVG files using non-whitelisted namespaces. Also disallow iframe elements. * User will get an error including the namespace name if they use a non- whitelisted namespace.
-* (bug 61346) SECURITY: Make token comparison use constant time. It seems like our token comparison would be vulnerable to timing attacks. This will take constant time.
+* (bug 60771) SECURITY: Disallow uploading SVG files using non-whitelisted
+  namespaces. Also disallow iframe elements. * User will get an error including
+  the namespace name if they use a non- whitelisted namespace.
+* (bug 61346) SECURITY: Make token comparison use constant time. It seems like
+  our token comparison would be vulnerable to timing attacks. This will take
+  constant time.
 * (bug 61362) SECURITY: API: Don't find links in the middle of api.php links.
-* (bug 53710) Add sequence support for upsert in DatabaseOracle in the same way as in selectInsert
-* (bug 60231, bug 58719) Various fixes to job running code in Wiki.php: Make it async on Windows. Fixed possible "invalid filename" errors on Windows. Redirect output to dev/null to avoid hanging PHP.
-* (bug 60083) Correct sequence name for fresh Postgres installation. Spotted by gebhkla
-* (bug 60531) Avoid variable naming conflicts in DatabasePostgres::selectSQLText. Spotted by gebhkla
+* (bug 53710) Add sequence support for upsert in DatabaseOracle in the same way
+  as in selectInsert
+* (bug 60231, bug 58719) Various fixes to job running code in Wiki.php: Make it
+  async on Windows. Fixed possible "invalid filename" errors on Windows.
+  Redirect output to dev/null to avoid hanging PHP.
+* (bug 60083) Correct sequence name for fresh Postgres installation. Spotted by
+  gebhkla
+* (bug 60531) Avoid variable naming conflicts in
+  DatabasePostgres::selectSQLText. Spotted by gebhkla
 * (bug 60094) Fix rebuildall.php fatal error with PostgreSQL.
 * (bug 43817) Add error handling if descriptionmsg isn't defined for extension.
 * (bug 60543) Special:PrefixIndex omits stripprefix=1 for "Next page" link.
@@ -5628,7 +5796,8 @@ This is a security and bugfix release of the MediaWiki 1.22 branch.
 This is a security and bugfix release of the MediaWiki 1.22 branch.
 
 === Changes since 1.22.1 ===
-* (bug 60339) SECURITY: Sanitize shell arguments to DjVu files, and other media formats
+* (bug 60339) SECURITY: Sanitize shell arguments to DjVu files, and other media
+  formats
 * (bug 58253) Check for very old PCRE versions in installer and updater
 * (bug 60054) Make WikiPage::$mPreparedEdit public
 
@@ -5642,10 +5811,17 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 * (bug 58553) SECURITY: Return error on invalid XML for SVG Uploads
 * (bug 58699) SECURITY: Fix RevDel log entry information leaks
 * (bug 58178) Restore compatibility with curl < 7.16.2.
-* (bug 56931) Updated the plural rules to CLDR 24. They are in new format which is detailed in UTS 35 Rev 33. The PHP parser and evaluator as well as the JavaScript evaluator were updated to support the new format. Plural rules for some languages have changed, most notably Russian. Affected software messages have been updated and marked for review at translatewiki.net. This change is backported from the development branch of MediaWiki 1.23.
+* (bug 56931) Updated the plural rules to CLDR 24. They are in new format which
+  is detailed in UTS 35 Rev 33. The PHP parser and evaluator as well as the
+  JavaScript evaluator were updated to support the new format. Plural rules for
+  some languages have changed, most notably Russian. Affected software messages
+  have been updated and marked for review at translatewiki.net. This change is
+  backported from the development branch of MediaWiki 1.23.
 * (bug 58434) The broken installer for database backend Oracle was fixed.
-* (bug 58167) The web installer no longer throws an exception when PHP is compiled without support for MySQL yet with support for another DBMS.
-* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages to appear blank or with missing text.
+* (bug 58167) The web installer no longer throws an exception when PHP is
+  compiled without support for MySQL yet with support for another DBMS.
+* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages to
+  appear blank or with missing text.
 * (bug 47055) Changed FOR UPDATE handling in Postgresql
 * (bug 57026) Avoid extra parsing in prepareContentForEdit()
 
@@ -5658,17 +5834,21 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 * $wgCascadingRestrictionLevels was added.
 * ftps, ssh, sftp, xmpp, sip, sips, tel, sms, bitcoin, magnet, urn, and geo
   have been whitelisted inside of $wgUrlProtocols.
-* $wgDocType and $wgDTD have been removed and are no longer used for the DOCTYPE.
-* $wgHtml5 is no longer used by core. Setting it to false will no longer disable HTML5.
-  It is still set to true for extension compatibility but doing so in extensions is deprecated.
-* $wgXhtmlDefaultNamespace is no longer used by core. Setting it will no longer change the
-  xmlns used by MediaWiki. Reliance on this variable by extensions is deprecated.
+* $wgDocType and $wgDTD have been removed and are no longer used for the
+  DOCTYPE.
+* $wgHtml5 is no longer used by core. Setting it to false will no longer disable
+  HTML5. It is still set to true for extension compatibility but doing so in
+  extensions is deprecated.
+* $wgXhtmlDefaultNamespace is no longer used by core. Setting it will no longer
+  change the xmlns used by MediaWiki. Reliance on this variable by extensions
+  is deprecated.
 * $wgHandheldStyle was removed.
 * $wgHandheldForIPhone was removed.
 * $wgJsMimeType is no longer used by core. Most usage has been removed since
   HTML output is now exclusively HTML5.
 * $wgDBOracleDRCP added. True enables persistent connection with DRCP on Oracle.
-* $wgLogAutopatrol added to allow disabling logging of autopatrol edits in the logging table.
+* $wgLogAutopatrol added to allow disabling logging of autopatrol edits in the
+  logging table.
   Default for $wgLogAutopatrol is true.
 * The 'edit' right no longer allows for editing a user's own CSS and JS.
 * New rights 'editmyusercss', 'editmyuserjs', 'viewmywatchlist',
@@ -5684,26 +5864,27 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 * (bug 40866) wgOldChangeTagsIndex removed.
 * $wgNoFollowDomainExceptions now only matches entire domains. For example,
   an entry for 'bar.com' will still match 'foo.bar.com' but not 'foobar.com'.
-* $wgCopyUploadTimeout and $wgCopyUploadAsyncTimeout added to change the timeout times for
-  fetching the file during upload by url.
+* $wgCopyUploadTimeout and $wgCopyUploadAsyncTimeout added to change the timeout
+  times for fetching the file during upload by url.
 * New key added to $wgGalleryOptions - $wgGalleryOptions['mode'] to set
   default gallery mode.
 * New hook 'GalleryGetModes' to allow extensions to make new gallery modes.
-* The checkbox for staying in HTTPS displayed on the login form when $wgSecureLogin is
-  enabled has been removed. Instead, whether the user stays in HTTPS will be determined
+* The checkbox for staying in HTTPS displayed on the login form when
+  $wgSecureLogin is enabled has been removed. Instead, whether the user stays in
+  HTTPS will be determined
   based on the user's preferences, and whether they came from HTTPS or not.
 * $wgRC2UDPAddress, $wgRC2UDPInterwikiPrefix, $wgRC2UDPOmitBots, $wgRC2UDPPort,
   and $wgRC2UDPPrefix configuration options have been deprecated in favor of a
   $wgRCFeeds configuration array. $wgRCFeeds makes both the format and
   destination of recent change notifications customizable, and allows for
   multiple destinations to be specified.
-* (bug 53862) portal-url, currentevents-url and helppage have been removed from the
-  default Sidebar.
+* (bug 53862) portal-url, currentevents-url and helppage have been removed from
+  the default Sidebar.
 * The 'vector-simplesearch' preference is now enabled by default. Previously
   it was only enabled if the Vector extension was installed.
-* The precise format of metric datagrams produced by the UDP profiler and stats counter
-  may now be specified as $wgUDPProfilerFormatString and $wgStatsFormatString,
-  respectively.
+* The precise format of metric datagrams produced by the UDP profiler and stats
+  counter may now be specified as $wgUDPProfilerFormatString and
+  $wgStatsFormatString, respectively.
 * (bug 54597) $wgBlockOpenProxies, $wgProxyPorts, $wgProxyScriptPath, and
   $wgProxyMemcExpiry have been removed, along with the open proxy scanner
   script they were added for.
@@ -5712,7 +5893,8 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 === New features in 1.22 ===
 * You can now install extensions using Composer.
   See https://www.mediawiki.org/wiki/Composer
-* (bug 44525) mediawiki.jqueryMsg can now parse (whitelisted) HTML elements and attributes.
+* (bug 44525) mediawiki.jqueryMsg can now parse (whitelisted) HTML elements and
+  attributes.
 * (bug 33454) Language::sprintfDate now has a timezone parameter, and supports
   the "eIOPTZ" formatting characters.
 * EditWarning: A warning is shown when an editor leaves the edit form without
@@ -5722,16 +5904,18 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
   version of the Vector extension as this feature may conflict.
 * New 'mediawiki.ui' CSS module providing mw-ui-* styles for buttons and a
   compact vertical form layout.
-* HTMLForm supports a new display format 'vform' which applies this compact vertical
+* HTMLForm supports a new display format 'vform' which applies this compact
+  vertical
   layout and button styling. Special:PasswordReset uses this format.
 * New versions of login (Special:UserLogin) and create account
-  (Special:UserLogin/signup) forms using the "vform" compact vertical form layout.
-  These forms use new messages that assume a "Help logging in" link, see
+  (Special:UserLogin/signup) forms using the "vform" compact vertical form
+  layout. These forms use new messages that assume a "Help logging in" link, see
   https://www.mediawiki.org/wiki/Manual:Page_customizations;
-  https://www.mediawiki.org/wiki/Account_creation_user_experience/Strings lists the
-  message key changes.
-* (bug 23343) Implemented ability to apply IP blocks to the contents of X-Forwarded-For headers
-  by adding a new configuration variable $wgApplyIpBlocksToXff (disabled by default).
+  https://www.mediawiki.org/wiki/Account_creation_user_experience/Strings lists
+  the message key changes.
+* (bug 23343) Implemented ability to apply IP blocks to the contents of
+  X-Forwarded-For headers by adding a new configuration variable
+  $wgApplyIpBlocksToXff (disabled by default).
 * The new hook 'APIGetPossibleErrors' to modify the list of possible errors was
   added.
 * (bug 25592) LogEventsList::showLogExtract() will now ignore various
@@ -5753,8 +5937,10 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
   well.
 * (bug 45535) introduced the new 'LanguageLinks' hook for manipulating the
   language links associated with a page before display.
-* Chosen (http://harvesthq.github.io/chosen/) was added as module 'jquery.chosen'
-* HTMLForm will turn multiselect checkboxes into a Chosen interface when setting cssclass 'mw-chosen'
+* Chosen (http://harvesthq.github.io/chosen/) was added as module
+  'jquery.chosen'
+* HTMLForm will turn multiselect checkboxes into a Chosen interface when setting
+  cssclass 'mw-chosen'
 * rebuildLocalisationCache learned --lang option. Let you rebuild l10n caches
   of the specified languages instead of all of them.
 * New GetNewMessagesAlert hook allowing extensions to disable or modify the new
@@ -5766,22 +5952,25 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 * mediawiki.log: Added log.warn wrapper (uses console.warn and console.trace).
 * mediawiki.log: Implemented log.deprecate. This method defines a property and
   uses ES5 getter/setter to emit a warning when they are used.
-* $wgCascadingRestrictionLevels was added, allowing one to specify restriction levels
-  which can be cascading (previously 'sysop' was hard-coded as the only one).
-* XHTML5 support has been improved. If you set $wgMimeType = 'application/xhtml+xml'
-  MediaWiki will try outputting markup according to XHTML5 rules.
+* $wgCascadingRestrictionLevels was added, allowing one to specify restriction
+  levels which can be cascading (previously 'sysop' was hard-coded as the only
+  one).
+* XHTML5 support has been improved. If you set
+  $wgMimeType = 'application/xhtml+xml' MediaWiki will try outputting markup
+  according to XHTML5 rules.
 * Altered hook 'ProtectionForm::save', adding the reason page protection is
   changed as third parameter.
 * New hook 'TitleSquidURLs' for manipulating the list of URLs to be purged from
   HTTP caches when a page is changed.
-* Changed the patrolling system to always show the link for patrolling in case the
-  current revision is patrollable. This also removed the usage of the rcid URI parameters.
+* Changed the patrolling system to always show the link for patrolling in case
+  the current revision is patrollable. This also removed the usage of the rcid
+  URI parameters.
 * Oracle DB backend now supports Database Resident Connection Pooling (DRCP).
   Can be enabled by setting $wgDBOracleDRCP=true.
   Requires Oracle DB 11gR1 or above, enabled DRCP inside the DB itself and a
   propper connect string.
   More about DRCP can be found at:
-  http://www.oracle-base.com/articles/11g/database-resident-connection-pool-11gr1.php
+  https://oracle-base.com/articles/11g/database-resident-connection-pool-11gr1
 * Add a new parameter $patrolFooterShown to hook ArticleViewFooter so the hook
   handlers can take further action based on the status of the patrol footer
 * A new hook TitleQuickPermissions was added to allow overriding of quick
@@ -5834,8 +6023,8 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
   right?" check is used to avoid more expensive checks.
 * (bug 14431) Display "(No difference)" instead of an empty diff (when comparing
   revisions in the history or when previewing changes while editing).
-* New hook 'IsUploadAllowedFromUrl' is added which can be used to intercept uploads by
-  URL, useful for blacklisting specific URLs
+* New hook 'IsUploadAllowedFromUrl' is added which can be used to intercept
+  uploads by URL, useful for blacklisting specific URLs
 * (bug 21912) Watchlist token implementation has been refactored and
   Special:ResetTokens was added to allow users to reset their tokens
   instead of presenting them in Preferences.
@@ -5852,7 +6041,8 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
   too. Can be used whenever several multicast group could be interested by a
   specific purge.
 * (bug 25931) Add Special:RandomInCategory.
-* mediawiki.util: addPortletLink now supports passing a jQuery object as nextnode.
+* mediawiki.util: addPortletLink now supports passing a jQuery object as
+  nextnode.
 * <wbr> can now be used inside WikiText.
 * WebResponse::setcookie is much more featureful. Callers using PHP's
   setcookie() or setrawcookie() should begin using this instead.
@@ -5865,8 +6055,8 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 * (bug 30607) Special:ListFiles can now show old versions of files. Additionally
   Special:AllMyUploads was introduced so the user can get a list of all things
   they have ever uploaded, even if it was subsequently overridden.
-* Introduced Special:MyFiles and Special:AllMyFiles as an alias for Special:MyUploads
-  and Special:AllMyUploads respectively.
+* Introduced Special:MyFiles and Special:AllMyFiles as an alias for
+  Special:MyUploads and Special:AllMyUploads respectively.
 * IPv6 addresses in X-Forwarded-For headers are now normalised before checking
   against allowed proxy lists.
 * Add deferrable update support for callback/closure.
@@ -5882,7 +6072,8 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
    declared for all LESS files. Additional variables may be registered by
    adding keys to the array.
 ** $wgResourceLoaderLESSFunctions is an associative array of custom LESS
-   function names to PHP callables. See <http://leafo.net/lessphp/docs/#custom_functions>
+   function names to PHP callables. See
+   <http://leafo.net/lessphp/docs/#custom_functions>
    for more details regarding custom functions.
 ** $wgResourceLoaderLESSImportPaths is an array of file system paths. Files
    referenced in LESS '@import' statements are looked up here first.
@@ -5893,16 +6084,16 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
   the output of the API query meta=siteinfo&siprop=statistics
 * Primary keys have been added to both the archive table and the externallinks
   tables.
-* Added $wgEnableParserLimitReporting to control whether the NewPP limit report is
-  output in a HTML comment.
+* Added $wgEnableParserLimitReporting to control whether the NewPP limit report
+  is output in a HTML comment.
 * The 'UnwatchArticle' and 'WatchArticle' hooks now support a Status object
   instead of just a boolean return value to abort the hook.
 * Added a hook, SpecialWatchlistGetNonRevisionTypes, to allow extensions
   with custom recentchanges entries to hook into the Watchlist without
   clobbering each other.
-* A hidden, empty input field was added to the edit form, and any edit that fills
-  it in will be rejected. This prevents against the simplest form of spambots.
-  Previously in the "SimpleAntiSpam" extension by Ryan Schmidt.
+* A hidden, empty input field was added to the edit form, and any edit that
+  fills it in will be rejected. This prevents against the simplest form of
+  spambots. Previously in the "SimpleAntiSpam" extension by Ryan Schmidt.
 * populateRevisionLength.php maintenance script updated to also populate
   archive.ar_len field.
 * (bug 43571) DatabaseMySQLBase learned to list views, optionally filtered by a
@@ -5924,7 +6115,8 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
 * Pager's properly validate which fields are allowed to be sorted on.
 * mw.util.tooltipAccessKeyRegexp: The regex now matches "option-" as well.
   Support for Mac "option" was added in 1.16, but the regex was never updated.
-* (bug 46768) Usernames of blocking users now display correctly, even if numeric.
+* (bug 46768) Usernames of blocking users now display correctly, even if
+  numeric.
 * (bug 39590) Self-transclusions now show the most up to date result always
   after save instead of being a revision behind.
 * A bias in wfRandomString() toward digits 1-7 has been corrected. Generated
@@ -5949,8 +6141,10 @@ This is a security and maintenance release of the MediaWiki 1.22 branch.
   warning will instead be issued if 'title' is non-default, unless no props are
   requested.
 * Special:Recentchangeslinked will now include upload log entries
-* (bug 41281) Fixed ugly output if file size could not be extracted for multi-page media.
-* (bug 50315) list=logevents API module will now output log entries by anonymous users.
+* (bug 41281) Fixed ugly output if file size could not be extracted for
+  multi-page media.
+* (bug 50315) list=logevents API module will now output log entries by anonymous
+  users.
 * (bug 38911) Handle headers with rowspan in jquery.tablesorter
 * (bug 658) Converted the table of contents on wiki pages from <table> to <div>
   and adjusted skin CSS accordingly. The CSS was carefully crafted to be
@@ -6090,8 +6284,8 @@ changes to languages because of Bugzilla reports.
   part of the Nostalgia extension.
 * Event namespace used by jquery.makeCollapsible has been changed from
   'mw-collapse' to 'mw-collapsible' for consistency with the module name.
-* BREAKING CHANGE: The "ExternalAuth" authentication subsystem was removed, along
-  with its associated globals of $wgExternalAuthType, $wgExternalAuthConf,
+* BREAKING CHANGE: The "ExternalAuth" authentication subsystem was removed,
+  along with its associated globals of $wgExternalAuthType, $wgExternalAuthConf,
   $wgAutocreatePolicy and $wgAllowPrefChange. Affected users are encouraged to
   use AuthPlugin for external authentication/authorization needs.
 * The Quickbar feature of the legacy skin model and the last remnants of it
@@ -6119,8 +6313,9 @@ changes to languages because of Bugzilla reports.
 * (bug 40785) mediawiki.legacy.ajax has been marked as deprecated. The following
   properties now emit mw.log.warn when accessed: sajax_debug, sajax_init_object,
   sajax_do_call and wfSupportsAjax.
-* BREAKING CHANGE: meta keywords are no longer supported. A <meta name="keywords"
-  will no longer be output and OutputPage::addKeyword no longer exists.
+* BREAKING CHANGE: meta keywords are no longer supported. A
+  <meta name="keywords" will no longer be output and OutputPage::addKeyword no
+  longer exists.
 * Methods Title::userCanEditCssSubpage and Title::userCanEditJsSubpage,
   deprecated since 1.19, have been removed.
 * (bug 50134) Hook functions are no longer required to return a value. When a
@@ -6157,23 +6352,24 @@ changes to languages because of Bugzilla reports.
   35981).
 * BREAKING CHANGE: The 'mediawiki.legacy.wikiprintable' module has been removed.
   The skins/common/wikiprintable.css file no longer exists. Return value of
-  Skin#commonPrintStylesheet is ignored. Please use the 'mediawiki.legacy.commonPrint'
-  module instead or base your skin on SkinTemplate.
+  Skin#commonPrintStylesheet is ignored. Please use the
+  'mediawiki.legacy.commonPrint' module instead or base your skin on
+  SkinTemplate.
 * (bug 49629) The hook ExtractThumbParameters has been deprecated in favour
   of media handler overriding MediaHandler::parseParamString.
-* (bug 46512) The collapsibleNav feature from the Vector extension has been moved
-  to the Vector skin in core.
+* (bug 46512) The collapsibleNav feature from the Vector extension has been
+  moved to the Vector skin in core.
 * SpecialRecentChanges::addRecentChangesJS() function has been renamed
   to addModules() and made protected.
 * Methods WatchAction::doWatch and WatchAction::doUnwatch now return a Status
   object instead of a boolean.
 * Information boxes (CSS classes errorbox, warningbox, successbox) have been
   made more subtle.
-* BREAKING CHANGE: The module 'mediawiki.legacy.IEFixes' has been removed as it was
-  unused. The file skins/common/IEFixes.js remains but is only used by wikibits.
-  The file never contained any re-usable components. To use it in a skin, load
-  'mediawiki.legacy.wikibits' (which IEFixes depends on) and that will import
-  IEFixes automatically if user agent conditions are met.
+* BREAKING CHANGE: The module 'mediawiki.legacy.IEFixes' has been removed as it
+  was unused. The file skins/common/IEFixes.js remains but is only used by
+  wikibits. The file never contained any re-usable components. To use it in a
+  skin, load 'mediawiki.legacy.wikibits' (which IEFixes depends on) and that
+  will import IEFixes automatically if user agent conditions are met.
 * Code specific to the Math extension was marked as deprecated.
 * mediawiki.util: mw.util.wikiGetlink has been renamed to getUrl. (The old name
   still works, but is deprecated.)
@@ -6185,13 +6381,15 @@ This is a security and maintenance release of the MediaWiki 1.21 branch.
 
 === Changes since 1.21.10 ===
 * (bug 65839) SECURITY: Prevent external resources in SVG files.
-* (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects like only extracting the tail of the file partially or not at all.
+* (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects like
+  only extracting the tail of the file partially or not at all.
 
 == MediaWiki 1.21.10 ==
 This is a security and maintenance release of the MediaWiki 1.21 branch.
 
 === Changes since 1.21.9 ===
-* (bug 65501) SECURITY: Don't parse usernames as wikitext on Special:PasswordReset.
+* (bug 65501) SECURITY: Don't parse usernames as wikitext on
+  Special:PasswordReset.
 * (bug 36356) Add space between two feed links.
 
 == MediaWiki 1.21.9 ==
@@ -6199,7 +6397,8 @@ This is a security and maintenance release of the MediaWiki 1.21 branch.
 
 === Changes since 1.21.8 ===
 * (bug 63251) SECURITY: Escape sortKey in pageInfo.
-* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages to appear blank or with missing text.
+* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages to
+  appear blank or with missing text.
 
 == MediaWiki 1.21.8 ==
 This is a security and maintenance release of the MediaWiki 1.21 branch.
@@ -6218,15 +6417,21 @@ This is a maintenance release of the MediaWiki 1.21 branch.
 This is a security release of the MediaWiki 1.21 branch.
 
 === Changes since 1.21.5 ===
-* (bug 60771) SECURITY: Disallow uploading SVG files using non-whitelisted namespaces. Also disallow iframe elements. * User will get an error including the namespace name if they use a non- whitelisted namespace.
-* (bug 61346) SECURITY: Make token comparison use constant time. It seems like our token comparison would be vulnerable to timing attacks. This will take constant time.
+* (bug 60771) SECURITY: Disallow uploading SVG files using non-whitelisted
+  namespaces. Also disallow iframe elements.
+* User will get an error including the namespace name if they use a
+  non-whitelisted namespace.
+* (bug 61346) SECURITY: Make token comparison use constant time. It seems like
+  our token comparison would be vulnerable to timing attacks. This will take
+  constant time.
 * (bug 61362) SECURITY: API: Don't find links in the middle of api.php links.
 
 == MediaWiki 1.21.5 ==
 This is a security release of the MediaWiki 1.21 branch.
 
 === Changes since 1.21.4 ===
-* (bug 60339) SECURITY: Sanitize shell arguments to DjVu files, and other media formats
+* (bug 60339) SECURITY: Sanitize shell arguments to DjVu files, and other media
+  formats
 
 == MediaWiki 1.21.4 ==
 This is a security release of the MediaWiki 1.21 branch.
@@ -6253,16 +6458,19 @@ This is a security and maintenance release of the MediaWiki 1.21 branch.
 
 === Changes since 1.21.1 ===
 * SECURITY: Fix extension detection with 2 .'s
-* SECURITY: Support for the 'gettoken' parameter to action=block and action=unblock, deprecated since 1.20, has been removed.
+* SECURITY: Support for the 'gettoken' parameter to action=block and
+  action=unblock, deprecated since 1.20, has been removed.
 * SECURITY: Sanitize ResourceLoader exception messages
 * Purge upstream caches when deleting file assets.
-* Unit test suite now runs the AutoLoader tests. Also fixed the autoloading entry for the PageORMTableForTesting class though it had no impact.
+* Unit test suite now runs the AutoLoader tests. Also fixed the autoloading
+  entry for the PageORMTableForTesting class though it had no impact.
 
 == MediaWiki 1.21.1 ==
 This is a maintenance release of the MediaWiki 1.21 branch.
 
 === Changes since 1.21.0 ===
-* An incorrect version number was used for 1.21.0. 1.21.1 has the correct number.
+* An incorrect version number was used for 1.21.0. 1.21.1 has the correct
+  number.
 * A problem with the Oracle SQL table creation was fixed.
 * (PdfHandler extension) Fix warning if pdfinfo fails but pdftext succeeds.
 
@@ -6364,7 +6572,8 @@ This is a maintenance release of the MediaWiki 1.21 branch.
 * maintenance/sql.php learned the --cluster option. Let you run the script
   on some external cluster instead of the primary cluster for a given wiki.
 * (bug 20281) test the parsing of inline URLs.
-* Added Special:PagesWithProp, which lists pages using a particular page property.
+* Added Special:PagesWithProp, which lists pages using a particular page
+  property.
 * Implemented language-specific collations for category sorting for 67 languages
   based in latin, greek and cyrillic alphabets. This allows one to *finally* get
   articles to be correctly sorted on category pages. They are named
@@ -6445,7 +6654,8 @@ This is a maintenance release of the MediaWiki 1.21 branch.
 * (bug 43379) Gracefully fail if rev_len is unavailable for a revision on the
   History page.
 * (bug 42949) API no longer assumes all exceptions are MWException.
-* (bug 41733) Hide "New user message" (.usermessage) element from printable view.
+* (bug 41733) Hide "New user message" (.usermessage) element from printable
+  view.
 * (bug 39062) Special:Contributions will display changes that don't have
   a parent id instead of just an empty bullet item.
 * (bug 37209) "LinkCache doesn't currently know about this title" error fixed.
@@ -6463,7 +6673,8 @@ This is a maintenance release of the MediaWiki 1.21 branch.
   extensions) performed using Git 1.7.8+ should now appear.
 * (bug 42184) $wgUploadSizeWarning missing second variable
 * (bug 40326) Check if files exist with a different extension during uploading
-* (bug 34798) Updated CSS for Atom/RSS recent changes feeds to match on-wiki diffs.
+* (bug 34798) Updated CSS for Atom/RSS recent changes feeds to match on-wiki
+  diffs.
 * (bug 42430) Calling numRows on MySQL no longer propagates unrelated errors.
 * (bug 44719) Removed mention of non-existing maintenance/migrateCurStubs.php
   script in includes/DefaultSettings.php
@@ -6477,13 +6688,14 @@ This is a maintenance release of the MediaWiki 1.21 branch.
 * action=edit and action=parse now support contentmodel and contentformat
   parameters to control the interpretation of page content.
   See docs/contenthandler.txt for details.
-* (bug 35693) ApiQueryImageInfo now suppresses errors when unserializing metadata.
+* (bug 35693) ApiQueryImageInfo now suppresses errors when unserializing
+  metadata.
 * (bug 40111) Disable minor edit for page/section creation by API.
 * (bug 41042) Revert change to action=parse&page=... behavior when the page
   does not exist.
 * (bug 27202) Add timestamp sort to list=allimages.
-* (bug 43137) Don't return the sha1 of revisions through the API if the content is
-  revision-deleted.
+* (bug 43137) Don't return the sha1 of revisions through the API if the content
+  is revision-deleted.
 * ApiQueryImageInfo now also returns imageinfo for redirects.
 * list=alltransclusions added to enumerate every instance of page embedding
 * list=alllinks & alltransclusions now allow both 'from' and 'continue' in
@@ -6505,14 +6717,16 @@ This is a maintenance release of the MediaWiki 1.21 branch.
   a redirect and its target.
 * (bug 43849) ApiQueryImageInfo no longer throws exceptions with ForeignDBRepo
   redirects.
-* On error, any warnings generated before that error will be shown in the result.
-* action=help supports generalized submodules (modules=query+value), querymodules obsolete
+* On error, any warnings generated before that error will be shown in the
+  result.
+* action=help supports generalized submodules (modules=query+value),
+  querymodules obsolete
 * ApiQueryImageInfo continuation is more reliable. The only major change is
   that the imagerepository property will no longer be set on page objects not
   processed in the current query (i.e. non-images or those skipped due to
   iicontinue).
-* Add supports for all pageset capabilities - generators, redirects, converttitles to
-  action=purge and action=setnotificationtimestamp.
+* Add supports for all pageset capabilities - generators, redirects,
+  converttitles to action=purge and action=setnotificationtimestamp.
 * (bug 43251) prop=pageprops&ppprop= now accepts multiple props to query.
 * ApiQueryImageInfo will now limit the number of calls to File::transform made
   in any one query. If there are too many, iicontinue will be returned.
@@ -6526,7 +6740,8 @@ This is a maintenance release of the MediaWiki 1.21 branch.
   HTTP OPTIONS request.
 * (bug 44923) action=upload works correctly if the entire file is uploaded in
   the first chunk.
-* Added 'continue=' parameter to streamline client iteration over complex query results
+* Added 'continue=' parameter to streamline client iteration over complex query
+  results
 * (bug 44909) API parameters may now be marked as type "upload", which is now
   used for action=upload's 'file' and 'chunk' parameters. This type will raise
   an error during parameter validation if the parameter is given but not
@@ -6543,15 +6758,20 @@ This is a maintenance release of the MediaWiki 1.21 branch.
   longer be), and will no longer choke on booleans.
 
 === API internal changes in 1.21 ===
-* For debugging only, a new global $wgDebugAPI removes many API restrictions when true.
+* For debugging only, a new global $wgDebugAPI removes many API restrictions
+  when true.
   Never use on the production servers, as this flag introduces security holes.
   Whenever enabled, a warning will also be added to all output.
-* ApiModuleManager now handles all submodules (actions,props,lists) and instantiation
+* ApiModuleManager now handles all submodules (actions,props,lists) and
+  instantiation
 * Query stores prop/list/meta as submodules
-* ApiPageSet can now be used in any action to process titles/pageids/revids or any generator.
-* BREAKING CHANGE: ApiPageSet constructor now has two params instead of three, with only the
-  first one keeping its meaning. ApiPageSet is now derived from ApiBase.
-* BREAKING CHANGE: ApiQuery::newGenerator() and executeGeneratorModule() were deleted.
+* ApiPageSet can now be used in any action to process titles/pageids/revids or
+  any generator.
+* BREAKING CHANGE: ApiPageSet constructor now has two params instead of three,
+  with only the first one keeping its meaning. ApiPageSet is now derived from
+  ApiBase.
+* BREAKING CHANGE: ApiQuery::newGenerator() and executeGeneratorModule() were
+  deleted.
 * ApiQueryGeneratorBase::setGeneratorMode() now requires a pageset param.
 * $wgAPIGeneratorModules is now obsolete and will be ignored.
 * Added flags ApiResult::OVERRIDE and ADD_ON_TOP to setElement() and addValue()
@@ -6579,7 +6799,8 @@ changes to languages because of Bugzilla reports.
   were using it, you have to either copy it to your extension, or install the
   Vector extension (and possibly disable its features using config settings if
   you don't want them).
-* Experimental IBM DB2 support was removed due to lack of interest and maintainership
+* Experimental IBM DB2 support was removed due to lack of interest and
+  maintainership
 * BREAKING CHANGE: Filenames of maintenance scripts were standardized into
   lowerCamelCase format, and made more explicit:
   - clear_stats.php -> clearCacheStats.php
@@ -6621,8 +6842,10 @@ This is a security release of the MediaWiki 1.20 branch.
 This is a security and maintenance release of the MediaWiki 1.20 branch.
 
 === Changes since 1.20.5 ===
-* (bug 48306) SECURITY: Run file validation checks on chunked uploads, and chunks of upload, during the upload process.
-* (bug 44327) mediawiki.user: Use session ID instead of 1-year cross-session cookies
+* (bug 48306) SECURITY: Run file validation checks on chunked uploads, and
+  chunks of upload, during the upload process.
+* (bug 44327) mediawiki.user: Use session ID instead of 1-year cross-session
+  cookies
 * (bug 47202) wikibits: FF2Fixes.css should not be loaded in Firefox 20.
 * (bug 31044) Make ResourceLoader behave in read-only mode
 
@@ -6650,14 +6873,17 @@ This is a security release of the MediaWiki 1.20 branch.
 This is a security and maintenance release of the MediaWiki 1.20 branch.
 
 === Changes since MediaWiki 1.20.2 ===
-* New preference type - 'api'. Preferences of this type are not shown on Special:Preferences, but are still available via the action=options API. (Unbreaks MLEB.)
+* New preference type - 'api'. Preferences of this type are not shown on
+  Special:Preferences, but are still available via the action=options API.
+  (Unbreaks MLEB.)
 * (bug 44010) Context is passed to UserGetLanguageObject.
 * The recursion guard on RequestContext::getLanguage() was weakened.
 * (bug 40585) Don't drop 'step="any"' in HTML input fields.
 * (bug 44024) Fixed problems in ObjectCache when using XCache.
 * (bug 44010) FauxRequest leaked cookie data from primary request.
 * (bug 44135/bug 42441) Pass '2' instead of 'true' to CURLOPT_SSL_VERIFYHOST
-* (bug 43518) API action=unblock should return the user name, not the full user object
+* (bug 43518) API action=unblock should return the user name, not the full user
+  object
 * (bug 45355) Prevent read of arbitrary files through mwdoc-filter.php
 
 == MediaWiki 1.20.2 ==
@@ -6665,7 +6891,9 @@ This is a maintenance release of the MediaWiki 1.20 branch
 
 === Changes since MediaWiki 1.20.1 ===
 * (bug 42638) Fix API action=options&reset=1 & unit tests.
-* (bug 42370) Fixed backport of 60cc060 to use mDoneWrites — caused * (bug 42592) User rights, preferences and other things are not saving in 1.20.1.
+* (bug 42370) Fixed backport of 60cc060 to use mDoneWrites — caused
+* (bug 42592) User rights, preferences and other things are not saving in
+  1.20.1.
 
 == MediaWiki 1.20.1 ==
 This is a security release of the MediaWiki 1.20 branch
@@ -6687,51 +6915,59 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 === Configuration changes in 1.20 ===
 * $wgGitRepositoryViewers defines a mapping from Git remote repository to the
   Gitweb instance URL used in Special:Version.
-* `$wgUsePathInfo = true;` is no longer needed to make $wgArticlePath work on servers
-  using like nginx, lighttpd, and apache over fastcgi. MediaWiki now always extracts
-  path info from REQUEST_URI if it's available.
+* `$wgUsePathInfo = true;` is no longer needed to make $wgArticlePath work on
+  servers using like nginx, lighttpd, and apache over fastcgi. MediaWiki now
+  always extracts path info from REQUEST_URI if it's available.
 * The user right 'upload_by_url' is no longer given to sysops by default.
   This only affects installations which have $wgAllowCopyUploads set to true.
 * Removed f-prot support from $wgAntivirusSetup.
 * New variable $wgDBerrorLogTZ to provide dates in the error log in a
   different timezone than the wiki timezone set by $wgLocaltimezone.
-* New variables $wgDBssl and $wgDBcompress to enable SSL and compression for database
-  connections, if either are available for the selected DB type.
-* $wgUseCombinedLoginLink now defaults to false, making MediaWiki output separate
-  login and create account links by default.
+* New variables $wgDBssl and $wgDBcompress to enable SSL and compression for
+  database connections, if either are available for the selected DB type.
+* $wgUseCombinedLoginLink now defaults to false, making MediaWiki output
+  separate login and create account links by default.
 
 === New features in 1.20 ===
-* Added TitleIsAlwaysKnown hook which gets called when determining if a page exists.
+* Added TitleIsAlwaysKnown hook which gets called when determining if a page
+  exists.
 * Added NamespaceIsMovable hook which gets called when determining if pages in a
   certain namespace can be moved.
-* Added SpecialPageBeforeExecute hook which gets called before SpecialPage::execute.
-* Added SpecialPageAfterExecute hook which gets called after SpecialPage::execute.
+* Added SpecialPageBeforeExecute hook which gets called before
+  SpecialPage::execute.
+* Added SpecialPageAfterExecute hook which gets called after
+  SpecialPage::execute.
 * Added ORMTable, ORMRow and ORMResult classes for additional abstraction of
   database interaction.
-* Added CacheHelper and associated SpecialCachedPage and CachedAction helper classes.
+* Added CacheHelper and associated SpecialCachedPage and CachedAction helper
+  classes.
 * (bug 32341) Add upload by URL domain limitation.
-* &useskin=default will now always display the default skin. Useful for users with a
-  preference for the non-default skin to look at something using the default skin.
+* &useskin=default will now always display the default skin. Useful for users
+  with a preference for the non-default skin to look at something using the
+  default skin.
 * (bug 27619) Remove preference option to display broken links as link?
 * (bug 34896) jQuery JSON plugin upgraded to v2.3 (2011-09-17).
 * (bug 34302) Add CSS classes to email fields in user preferences.
-* Introduced $wgDebugDBTransactions to trace transaction status (currently PostgreSQL only).
+* Introduced $wgDebugDBTransactions to trace transaction status (currently
+  PostgreSQL only).
 * (bug 23795) Add parser itself to ParserMakeImageParams hook.
 * Introduce a cryptographic random number generator source api for use when
   generating various tokens.
-* (bug 30963) Option on Special:Prefixindex and Special:Allpages to not show redirects.
+* (bug 30963) Option on Special:Prefixindex and Special:Allpages to not show
+  redirects.
 * (bug 18062) New message when edit or create the local page of a shared file.
 * (bug 22870) Separate interface message when creating a page.
 * (bug 17615) nosummary option should be reassigned on preview/captcha.
 * (bug 34355) Add a variable and parser function for the namespace number.
-* (bug 35649) Special:Version now shows hashes of extensions checked out from git.
+* (bug 35649) Special:Version now shows hashes of extensions checked out from
+  git.
 * (bug 35728) Git revisions are now linked on Special:Version.
 * "Show Changes" on default messages shows now diff against default message text
 * (bug 23006) create #speciale parser function.
 * generateSitemap can now optionally skip redirect pages.
 * (bug 27757) New API command just for retrieving tokens (not page-based).
-* Added GitViewers hook for extensions using external git repositories to have a web-based
-  repository viewer linked to from Special:Version.
+* Added GitViewers hook for extensions using external git repositories to have a
+  web-based repository viewer linked to from Special:Version.
 * Memcached debug logs can now be sent to their own file logs by setting
   $wgDebugLogFile['memcached'] to some filepath.
 * (bug 35685) api.php URL and other entry point URLs are now listed on
@@ -6747,15 +6983,17 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * Added $wgLogExceptionBacktrace, on by default, to allow logging of exception
   backtraces.
 * Added device detection for determining device capabilities.
-* QUnit.newMwEnvironment now supports passing a custom setup and/or teardown function.
-  Arguments signature has changed. First arguments is now an options object of which
-  'config' can be a property. Previously 'config' itself was the first and only argument.
+* QUnit.newMwEnvironment now supports passing a custom setup and/or teardown
+  function. Arguments signature has changed. First arguments is now an options
+  object of which 'config' can be a property. Previously 'config' itself was the
+  first and only argument.
 * New getCreator and getOldestRevision methods added to WikiPage class
 * (bug 4220) the XML dump format schema now have unique identity constraints
   for page and revision identifiers. Patch by Elvis Stansvik.
-* cleanupSpam.php now can delete spam pages if --delete was specified instead of blanking
-  them.
-* Added new hook ChangePasswordForm to allow adding of additional fields in Special:ChangePassword
+* cleanupSpam.php now can delete spam pages if --delete was specified instead of
+  blanking them.
+* Added new hook ChangePasswordForm to allow adding of additional fields in
+  Special:ChangePassword
 * Added new function getDomain to AuthPlugin for getting a user's domain
 * (bug 23427) New magic word {{PAGEID}} which gives the current page ID.
   Will be null on previewing a page being created.
@@ -6765,21 +7003,23 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
   tags with class "mw-watched". Instead, each line now has a class
   "mw-changeslist-line-watched" or "mw-changeslist-line-not-watched", and the
   title itself is surrounded by <span></span> tags with class "mw-title".
-* Added ContribsPager::reallyDoQuery hook allowing extensions to data to MyContribs
+* Added ContribsPager::reallyDoQuery hook allowing extensions to data to
+  MyContribs
 * Added new hook ParserAfterParse to allow extensions to affect parsed output
   after the parse is complete but before block level processing, link holder
   replacement, and so on.
-* (bug 34678) Added InternalParseBeforeSanitize hook which gets called during Parser's
-  internalParse method just before the parser removes unwanted/dangerous HTML tags.
-* Added new hook AfterFinalPageOutput to allow modifications to buffered page output before sent
-  to the client.
+* (bug 34678) Added InternalParseBeforeSanitize hook which gets called during
+  Parser's internalParse method just before the parser removes
+  unwanted/dangerous HTML tags.
+* Added new hook AfterFinalPageOutput to allow modifications to buffered page
+  output before sent to the client.
 * (bug 36783) Implement jQuery Promise interface in mediawiki.api module.
 * Make dates in sortable tables sort according to the page content language
   instead of the site content language
 * (bug 37926) Deleterevision will no longer allow users to delete log entries,
   the new deletelogentry permission is required for this.
-* (bug 14237) Allow PAGESINCATEGORY to distinguish between 'all', 'pages', 'files'
-  and 'subcats'
+* (bug 14237) Allow PAGESINCATEGORY to distinguish between 'all', 'pages',
+  'files' and 'subcats'
 * (bug 38362) Make Special:Listuser includeable on wiki pages.
 * Added support in jquery.localize for placeholder attributes.
 * (bug 38151) Implemented mw.user.getRights for getting and caching the current
@@ -6796,12 +7036,15 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * HTMLForm mutators can now be chained (they return $this)
 * A new message, "api-error-filetype-banned-type", is available for formatting
   API upload errors due to the file extension blacklist.
-* New hook 'ParserTestGlobals' allows to set globals before running parser tests.
+* New hook 'ParserTestGlobals' allows to set globals before running parser
+  tests.
 * Allow importing pages as subpage.
 * Add lang and hreflang attributes to language links on Login page.
 * (bug 22749) Create Special:MostInterwikis.
-* Show change tags when transclude Special:Recentchanges(linked) or Special:Newpages.
-* (bug 23226) Add |class= parameter to image links in order to add class(es) to HTML img tag.
+* Show change tags when transclude Special:Recentchanges(linked) or
+  Special:Newpages.
+* (bug 23226) Add |class= parameter to image links in order to add class(es) to
+  HTML img tag.
 * (bug 39431) SVG animated status is now shown in long description.
 * (bug 39376) jquery.form upgraded to 3.14.
 * SVG files will now show the actual width in the SVG's specified units
@@ -6809,10 +7052,11 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * Added ResourceLoader module "jquery.jStorage" (v0.3.0, http://jStorage.info/).
 * (bug 39273) Added AJAX support for "Show changes" (diff) in LivePreview.
 * Added ResourceLoader module "jquery.badge".
-* mw.util.$content now points to the overall content area in the skin rather than just
-  page text content area. If you need the old behavior please use $( '#mw-content-text').
-* jsMessage has been replaced with a floating bubble notification system complete
-  with auto-hide, multi-message support, and message replacement tags.
+* mw.util.$content now points to the overall content area in the skin rather
+  than just page text content area. If you need the old behavior please use
+  $( '#mw-content-text').
+* jsMessage has been replaced with a floating bubble notification system
+  complete with auto-hide, multi-message support, and message replacement tags.
 * jquery.messageBox which appears to be unused by both core and extensions has
   been removed.
 * (bug 34939) Made link parsing insensitive ([HttP://]).
@@ -6831,12 +7075,14 @@ milestone in Bugzilla.
 * (bug 35894): Reports of secret key generation "hanging" on windows
     This is probably a bug that has been fixed in PHP.  If you run
     into this, try upgrading your PHP.
-* (bug 38334): PHP Notice:  Undefined index: href in /www/w/skins/Vector.php on line 416
+* (bug 38334): PHP Notice:  Undefined index: href in /www/w/skins/Vector.php on
+  line 416
     We think this is a problem in some extension.  If you see this,
     try disabling your extensions and check out the logging patch on
     this bug.  Or try this patch:
     <https://gerrit.wikimedia.org/r/#/c/27937/1/skins/Vector.php>
-* (bug 39268): [Regression] Toolbar inserts in main textarea only (instead of the focussed textarea)
+* (bug 39268): [Regression] Toolbar inserts in main textarea only (instead of
+  the focussed textarea)
     This should only be an issue if you are using the ProofreadPage
     extension.
 * (bug 40641): Clicking "others" in Special:Version asks to download a file
@@ -6844,8 +7090,10 @@ milestone in Bugzilla.
     CREDITS file with text/plain MIME type to fix it.
 
 === Bug fixes in 1.20 ===
-* (bug 40939): [Regression] InfoAction: Call to a member function getUserText() on a non-object
-* (bug 40780): searchsuggest-containing line ("containing...") doesn't include the entered text
+* (bug 40939): [Regression] InfoAction: Call to a member function getUserText()
+  on a non-object
+* (bug 40780): searchsuggest-containing line ("containing...") doesn't include
+  the entered text
 * (bug 37714): [Regression] Incomplete log entries
 * (bug 27202): API: Add timestamp sort to list=allimages
 * (bug 30245) Use the correct way to construct a log page title.
@@ -6854,14 +7102,17 @@ milestone in Bugzilla.
 * (bug 32210) New edit emails for watched pages always provide a link to the
   edit which triggered the mail.
 * (bug 12021) Added user talk link on Special:Listusers.
-* (bug 34445) section edit and TOC hide/show links are excluded from selection and
-  copy/paste on supporting browsers.
+* (bug 34445) section edit and TOC hide/show links are excluded from selection
+  and copy/paste on supporting browsers.
 * (bug 34428) Fixed incorrect hash mismatch errors in the DiffHistoryBlob
   history compression method.
 * (bug 34702) Localised parentheses are now used in more special pages.
-* (bug 34723) When editing a script page on a RTL wiki the textbox should be LTR.
-* (bug 34762) Calling close() on a DatabaseBase object now clears the connection.
-* (bug 34863) Show deletion log extract on non-existent file pages if applicable.
+* (bug 34723) When editing a script page on a RTL wiki the textbox should be
+  LTR.
+* (bug 34762) Calling close() on a DatabaseBase object now clears the
+  connection.
+* (bug 34863) Show deletion log extract on non-existent file pages if
+  applicable.
 * (bug 28019) Let ?preloadtitle=foo be passed on to target of
   Special:MyPage and Special:MyTalk.
 * (bug 34929) Show the correct diff when a section edit is rejected by the spam
@@ -6883,13 +7134,16 @@ milestone in Bugzilla.
   Subversion when invoked with the --modified option.
 * (bug 35069) On history pages, the " . . " separator after the number of
   characters changed in a revision is now suppressed if no text would follow.
-* (bug 18704) Add a unique CSS class or ID to the tagfilter table row at RecentChanges
+* (bug 18704) Add a unique CSS class or ID to the tagfilter table row at
+  RecentChanges
 * (bug 33564) transwiki import sometimes result in invalid title.
-* (bug 35572) Blocks appear to succeed even if query fails due to wrong DB structure
+* (bug 35572) Blocks appear to succeed even if query fails due to wrong DB
+  structure
 * (bug 31757) Add a word-separator between help-messages in HTMLForm
 * (bug 30410) Removed deprecated $wgFilterCallback and the 'filtered' API error.
 * (bug 32604) Some messages needs escaping of wikitext inside username.
-* (bug 36537) Rename wfArrayToCGI to wfArrayToCgi for consistency with wfCgiToArray.
+* (bug 36537) Rename wfArrayToCGI to wfArrayToCgi for consistency with
+  wfCgiToArray.
 * (bug 25946) The message on the top of Special:RecentChanges is now displayed
   in user language instead of content language.
 * (bug 35264) Wrong type used for <ns> in export.xsd
@@ -6924,8 +7178,8 @@ milestone in Bugzilla.
 * (bug 38953) --memory-limit switch not working for runJobs.php.
 * (bug 33037) Make subpage of Special:newfiles control how many files
   are returned, like in previous versions.
-* (bug 36524) "Show" options on Special:RecentChanges and Special:RecentChangesLinked
-  are now remembered between successive clicks.
+* (bug 36524) "Show" options on Special:RecentChanges and
+  Special:RecentChangesLinked are now remembered between successive clicks.
 * (bug 26069) Page title is no longer "Error" for all error pages.
 * (bug 39297) Show warning if thumbnail of animated image will not be animated.
 * (bug 38249) Parser will throw an exception instead of outputting gibberish if
@@ -6933,26 +7187,33 @@ milestone in Bugzilla.
 * (bug 30390) Suggested file name on Special:Upload should not contain
   illegal characters.
 * EXIF below sea level GPS altitude data is now shown correctly.
-* (bug 39284) jquery.tablesorter should not consider "."" or "?"" to be a currency.
-* (bug 39273) "Show changes" should not be incorrectly displayed in the Live Preview state.
+* (bug 39284) jquery.tablesorter should not consider "."" or "?"" to be a
+  currency.
+* (bug 39273) "Show changes" should not be incorrectly displayed in the Live
+  Preview state.
 * Made body-content lang attribute honor the variant language when it is set.
-* (bug 36761) "Mark pages as visited" now submits previously established filter options.
+* (bug 36761) "Mark pages as visited" now submits previously established filter
+  options.
 * (bug 39635) PostgreSQL LOCK IN SHARE MODE option is a syntax error.
-* (bug 36329) Accesskey tooltips for Firefox 14 on Mac should use "ctrl-option-" prefix.
+* (bug 36329) Accesskey tooltips for Firefox 14 on Mac should use "ctrl-option-"
+  prefix.
 * (bug 32552) Drop unused database field cat_hidden from table category.
 * (bug 24502) Do not allow multiple language links to the same language.
 * (bug 40214) Category pages no longer use deprecated "width" HTML attribute.
 * (bug 39941) Add missing stylesheets to the installer pages
 * In HTML5 mode, allow new input element types values (such as color, range..)
 * (bug 36151) mw.Title: Don't limit extension in title parsing.
-* (bug 38158) jquery.byteLimit sometimes causes an unexpected 0 maxLength being enforced.
-* (bug 38163) jquery.byteLimit incorrectly limits input when using methods other than
-  basic per-char typing.
+* (bug 38158) jquery.byteLimit sometimes causes an unexpected 0 maxLength being
+  enforced.
+* (bug 38163) jquery.byteLimit incorrectly limits input when using methods other
+  than basic per-char typing.
 * (bug 34495) patrol log now credit the user patrolling (instead of patrolled
   user).
 * (bug 31676) ResourceLoader should work around IE stylesheet limit.
-* (bug 40498) ResourceLoader should not output an empty "@media print { }" block.
-* (bug 40500) ResourceLoader should not ignore media-type for urls in debug mode.
+* (bug 40498) ResourceLoader should not output an empty "@media print { }"
+  block.
+* (bug 40500) ResourceLoader should not ignore media-type for urls in debug
+  mode.
 * (bug 40660) ResourceLoaderWikiModule should not convert "&nbsp;" to a space
   for pages from the MediaWiki-namespace.
 * (bug 40329) (bug 40632) Removed CleanupPresentationalAttributes feature.
@@ -6967,33 +7228,40 @@ milestone in Bugzilla.
 * (bug 32492) API now allows editing using pageid.
 * (bug 32497) API now allows changing of protection level using pageid.
 * (bug 32498) API now allows comparing pages using pageids.
-* (bug 30975) API import of pages with invalid characters in this wiki leads to Fatal Error.
-* (bug 30488) API now allows listing of backlinks/embeddedin/imageusage per pageid.
+* (bug 30975) API import of pages with invalid characters in this wiki leads to
+  Fatal Error.
+* (bug 30488) API now allows listing of backlinks/embeddedin/imageusage per
+  pageid.
 * (bug 34927) Output media_type for list=filearchive.
 * (bug 28814) add properties to output of action=parse.
 * (bug 33224) add variants of content language to meta=siteinfo.
-* (bug 32643) action=purge with forcelinkupdate no longer crashes when ratelimit is reached.
+* (bug 32643) action=purge with forcelinkupdate no longer crashes when ratelimit
+  is reached.
 * The paraminfo module now also contains result properties for most modules.
 * (bug 32348) Allow descending order for list=alllinks.
 * (bug 31777) Upload unknown error ``fileexists-forbidden''.
 * (bug 32382) Allow descending order for list=iwbacklinks.
-* (bug 32381) Allow descending order for list=backlinks, list=embeddedin and list=imageusage.
+* (bug 32381) Allow descending order for list=backlinks, list=embeddedin and
+  list=imageusage.
 * (bug 32383) Allow descending order for list=langbacklinks.
 * API meta=siteinfo can now return the list of known variable IDs.
-* (bug 35980) list=deletedrevs now honors drdir correctly in "all" mode (mode #3).
+* (bug 35980) list=deletedrevs now honors drdir correctly in "all" mode
+  (mode #3).
 * (bug 29290) API avoids mangling fields in continuation parameters
 * (bug 36987) API avoids mangling fields in continuation parameters
-* (bug 30836) siteinfo prop=specialpagealiases will no longer return nonexistent special pages
+* (bug 30836) siteinfo prop=specialpagealiases will no longer return nonexistent
+  special pages
 * (bug 38190) Add "required" flag to some token params for hint in api docs.
 * (bug 27567) Add file repo support to prop=duplicatefiles.
 * (bug 27610) Add archivename for non-latest image version to list=filearchive
 * (bug 38231) Add xml parse tree to action=parse.
-* Watchlist notification timestamp may be queried by page and may be updated via the API.
+* Watchlist notification timestamp may be queried by page and may be updated via
+  the API.
 * (bug 38904) prop=revisions&rvstart=... no longer blows up when continuing.
 * (bug 39032) ApiQuery generates help in constructor.
 * (bug 11142) Improve file extension blacklist error reporting in API upload.
-* (bug 39665) List of query generators is now not built using reflection, instead it is
-  defined in code.
+* (bug 39665) List of query generators is now not built using reflection,
+  instead it is defined in code.
 * (bug 35993) Deprecated gettoken parameter - support will be removed in 1.22.
 
 === Languages updated in 1.20 ===
@@ -7032,8 +7300,8 @@ changes to languages because of Bugzilla reports.
 * OutputPage::wrapWikiMsg() no longer supports the 'options' parameter. It was
   not used and complicated migration to Message class.
 * Live preview functionality has been improved and moved into the
- 'mediawiki.action.edit.preview' module. The old 'mediawiki.legacy.preview' module
-  has been removed.
+ 'mediawiki.action.edit.preview' module. The old 'mediawiki.legacy.preview'
+  module has been removed.
 * (bug 40448) Removed mediawiki.legacy.mwsuggest module, and removed the
   following that has become obsolete:
   - globals $wgEnableMWSuggest and $wgMWSuggestTemplate.
@@ -7042,52 +7310,111 @@ changes to languages because of Bugzilla reports.
 
 == MediaWiki 1.19 ==
 
+== MediaWiki 1.19.24 ==
+
+This is a security and maintenance release of the MediaWiki 1.19 branch.
+
+=== Changes since 1.19.23 ===
+
+* ({{bug|T85848}}, {{bug|T71210}}) SECURITY: Don't parse XMP blocks that
+contain XML entities, to prevent various DoS attacks.
+* ({{bug|T88310}}) SECURITY: Always expand xml entities when checking SVG's.
+* ({{bug|T73394}}) SECURITY: Escape > in Html::expandAttributes to prevent XSS.
+* ({{bug|T85855}}) SECURITY: Don't execute another user's CSS or JS on preview.
+* ({{bug|T85349}}, {{bug|T85850}}, {{bug|T86711}}) SECURITY: Multiple issues
+fixed in SVG filtering to prevent XSS and protect viewer's privacy.
+
+== MediaWiki 1.19.23 ==
+
+This is a security and maintenance release of the MediaWiki 1.19 branch.
+
+=== Changes since 1.19.22 ===
+
+* (bug T76686) [SECURITY] thumb.php outputs wikitext message as raw HTML, which
+could lead to xss. Permission to edit MediaWiki namespace is required to
+exploit this.
+* (bug T74222) The original patch for T74222 was reverted as unnecessary.
+* Add missing $ in front of variable in OutputPage.php
+
+== MediaWiki 1.19.22 ==
+
+This is a security and maintenance release of the MediaWiki 1.19 branch.
+
+=== Changes since 1.19.21 ===
+
+* ({{bug|66776}}, {{bug|71478}}) SECURITY:  User PleaseStand reported a way to
+inject code into API clients that used format=php to process pages that
+underwent flash policy mangling. This was fixed along with improving how the
+mangling was done for format=json, and allowing sites to disable the mangling
+using $wgMangleFlashPolicy.
+* ({{bug|72222}}) SECURITY: Do not show log action when the entry is revdeleted
+with DELETED_ACTION. NOTICE: this may be reverted in a future release pending a
+public RFC about the desired functionality. This issue was reported by user
+Bawolff.
+* ({{bug|71621}}) Make allowing site-wide styles on restricted special pages a
+config option.
+* $wgMangleFlashPolicy was added to make MediaWiki's mangling of anything that
+might be a flash policy directive configurable.
+
 == MediaWiki 1.19.21 ==
 This is a maintenance release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.20 ===
 * (bug 67440) Allow classes to be registered properly from installer.
-* (bug 47281) Fixed a dumpBackup.php error with --uploads --include-filesoptions: Unable to find the wrapper "mwstore". * System administrators are encouraged to upgrade to this release or 1.22+ and produce a full data dump. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Backing_up_a_wiki
-* (bug 63049) Removed anonymous functions from ApiFormatBase, added in1.19.13 as part of the fix for bug 61362, for PHP 5.2 compatibility.
+* (bug 47281) Fixed a dumpBackup.php error with --uploads
+ --include-filesoptions: Unable to find the wrapper "mwstore".
+* System administrators are encouraged to upgrade to this release or 1.22+ and
+  produce a full data dump.
+  https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Backing_up_a_wiki
+* (bug 63049) Removed anonymous functions from ApiFormatBase, added in1.19.13 as
+  part of the fix for bug 61362, for PHP 5.2 compatibility.
 
 == MediaWiki 1.19.20 ==
 This is a security release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.19 ===
-* (bug 70672) SECURITY: OutputPage: Remove separation of css and js module allowance.
+* (bug 70672) SECURITY: OutputPage: Remove separation of css and js module
+  allowance.
 
 == MediaWiki 1.19.19 ==
 This is a security release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.18 ===
-* (bug 69008) SECURITY: Enhance CSS filtering in SVG files. Filter <style> elements; normalize style elements and attributes before filtering; add checks for attributes that contain css; add unit tests for html5sec and reported bugs.
+* (bug 69008) SECURITY: Enhance CSS filtering in SVG files. Filter <style>
+  elements; normalize style elements and attributes before filtering; add checks
+  for attributes that contain css; add unit tests for html5sec and reported
+  bugs.
 
 == MediaWiki 1.19.18 ==
 This is a security release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.17 ===
 * (bug 68187) SECURITY: Prepend jsonp callback with comment.
-* (bug 65778) SECURITY: Copy prevent-clickjacking between OutputPage and ParserOutput.
+* (bug 65778) SECURITY: Copy prevent-clickjacking between OutputPage and
+  ParserOutput.
 
 == MediaWiki 1.19.17 ==
 This is a security and maintenance release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.16 ===
 * (bug 65839) SECURITY: Prevent external resources in SVG files.
-* (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects like only extracting the tail of the file partially or not at all.
+* (bug 66428) MimeMagic: Don't seek before BOF. This has weird side effects like
+  only extracting the tail of the file partially or not at all.
 
 == MediaWiki 1.19.16 ==
 This is a security release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.15 ===
-* (bug 65501) SECURITY: Don't parse usernames as wikitext on Special:PasswordReset.
+* (bug 65501) SECURITY: Don't parse usernames as wikitext on
+  Special:PasswordReset.
 
 == MediaWiki 1.19.15 ==
 This is a security and maintenance release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.14 ===
 Fixed resetting passwords.
-* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages to appear blank or with missing text.
+* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages to
+  appear blank or with missing text.
 
 == MediaWiki 1.19.14 ==
 This is a security and maintenance release of the MediaWiki 1.19 branch.
@@ -7107,14 +7434,19 @@ This is a security and maintenance release of the MediaWiki 1.19 branch.
 This is a security release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.11 ===
-* (bug 60771) SECURITY: Disallow uploading SVG files using non-whitelisted namespaces. Also disallow iframe elements. * User will get an error including the namespace name if they use a non- whitelisted namespace.
-* (bug 61346) SECURITY: Make token comparison use constant time. It seems like our token comparison would be vulnerable to timing attacks. This will take constant time.
+* (bug 60771) SECURITY: Disallow uploading SVG files using non-whitelisted
+  namespaces. Also disallow iframe elements. * User will get an error including
+  the namespace name if they use a non- whitelisted namespace.
+* (bug 61346) SECURITY: Make token comparison use constant time. It seems like
+  our token comparison would be vulnerable to timing attacks. This will take
+  constant time.
 
 == MediaWiki 1.19.11 ==
 This is a security release of the MediaWiki 1.19 branch.
 
 === Changes since 1.19.10 ===
-* (bug 60339) SECURITY: Sanitize shell arguments to DjVu files, and other media formats
+* (bug 60339) SECURITY: Sanitize shell arguments to DjVu files, and other media
+  formats
 
 == MediaWiki 1.19.10 ==
 This is a security release of the MediaWiki 1.19 branch.
@@ -7154,7 +7486,8 @@ This is a security and maintenance release of the MediaWiki 1.19 branch.
 This is a security release of the MediaWiki 1.19 branch
 
 === Changes since 1.19.6 ===
-* (bug 48306) SECURITY: Run file validation checks on chunked uploads, and chunks of upload, during the upload process.
+* (bug 48306) SECURITY: Run file validation checks on chunked uploads, and
+  chunks of upload, during the upload process.
 
 == MediaWiki 1.19.6 ==
 2013-04-30
@@ -7163,7 +7496,8 @@ This is a security and maintenance release of the MediaWiki 1.19 branch
 
 === Changes since 1.19.5 ===
 * (bug 47304) SECURITY: Check SVG xml encoding against whitelist
-* (bug 46590) Added AbortChangePassword hook to allow extensions to abort password changes from Special:ChangePassword
+* (bug 46590) Added AbortChangePassword hook to allow extensions to abort
+  password changes from Special:ChangePassword
 * Localisation updates from http://translatewiki.net.
 * mwdocgen.php: Implement --version option.
 * Remove svnstat stuff used in Doxygen generation
@@ -7187,11 +7521,13 @@ This is a security and maintenance release of the MediaWiki 1.19 branch
 This is a security release of the MediaWiki 1.19 branch
 
 === Changes since 1.19.3 ===
-* New preference type - 'api'. Preferences of this type are not shown on Special:Preferences, but are still available via the action=options API.
+* New preference type - 'api'. Preferences of this type are not shown on
+  Special:Preferences, but are still available via the action=options API.
 * (bug 44010) Context is passed to UserGetLanguageObject.
 * The recursion guard on RequestContext::getLanguage() was weakened.
 * (bug 44135/bug 42441) Pass '2' instead of 'true' to CURLOPT_SSL_VERIFYHOST
-* (bug 43518) API action=unblock should return the user name, not the full user object
+* (bug 43518) API action=unblock should return the user name, not the full user
+  object
 
 == MediaWiki 1.19.3 ==
 2012-11-30
@@ -7201,7 +7537,8 @@ This is a security release of the MediaWiki 1.19 branch
 === Changes since 1.19.2 ===
 * (bug 40995) Prevent session fixation in Special:UserLogin (CVE-2012-5391)
 * (bug 41400) Prevent linker regex from exceeding PCRE backtrack limit
-* Increase permitted runtime for testParserTest (only used for continuous integration).
+* Increase permitted runtime for testParserTest (only used for continuous
+  integration).
 * Updated messages translations from http://translatewiki.net/
 
 == MediaWiki 1.19.2 ==
@@ -7255,8 +7592,9 @@ release and submitting bug reports.
 * (bug 34889) User name should be normalized on Special:Contributions
 * (bug 35051) If heading has a trailing space after == then its name is not
   preloaded into edit summary on section edit
-* (bug 31417) New ID mw-content-text around the actual page text, without categories,
-  contentSub, ... The same div often also contains the class mw-content-ltr/rtl.
+* (bug 31417) New ID mw-content-text around the actual page text, without
+  categories, contentSub, ... The same div often also contains the class
+  mw-content-ltr/rtl.
 * (bug 35303) Proxy and DNS blacklist blocking works again
 * (bug 22555) Remove or skip strip markers from tag hooks like &lt;nowiki&gt; in
   core parser functions which operate on strings, such as padleft.
@@ -7264,8 +7602,8 @@ release and submitting bug reports.
   inside a heading.
 * (bug 34212) ApiBlock/ApiUnblock allow action to take place without a token
   parameter present.
-* (bug 34907) Fixed exposure of tokens through load.php that could have facilitated
-  CSRF attacks.
+* (bug 34907) Fixed exposure of tokens through load.php that could have
+  facilitated CSRF attacks.
 * (bug 35317) CSRF in Special:Upload.
 
 === Configuration changes in 1.19 ===
@@ -7335,7 +7673,8 @@ release and submitting bug reports.
   converted to css.
 * (bug 31297) Add support for namespaces in Special:RecentChanges subpage filter
   syntax.
-* The default user signature now contains a talk link in addition to the user link.
+* The default user signature now contains a talk link in addition to the user
+  link.
 * (bug 25306) Add link of old page title to MediaWiki:Delete_and_move_reason.
 * Added hook BitmapHandlerCheckImageArea.
 * (bug 30062) Add $wgDBprefix option to cli installer.
@@ -7350,8 +7689,8 @@ release and submitting bug reports.
   containing HTML or JS. DISABLING THESE CHECKS IS VERY DANGEROUS.
 * New path mappings can be added using the WebRequestPathInfoRouter hook
   and adding paths to the PathRouter.
-* (bug 32666) Special:ActiveUsers now allows a subpage to be used as value for the
-  "target" query parameter (eg. Special:ActiveUsers/Username).
+* (bug 32666) Special:ActiveUsers now allows a subpage to be used as value for
+  the "target" query parameter (eg. Special:ActiveUsers/Username).
 * New JavaScript variable wgPageContentLanguage.
 * Added new debugging toolbar, enabled with $wgDebugToolbar.
 * Differences in the history page now uses slightly better colors for people
@@ -7363,16 +7702,18 @@ release and submitting bug reports.
 * (bug 32512) Add 'Associated namespace' checkbox to Special:Contributions.
 * Added $wgSend404Code, true by default, which can be set to false to send a
   200 status code instead of 404 for nonexistent articles.
-* (bug 33447) Link to the broken image tracking category from Special:Wantedfiles.
+* (bug 33447) Link to the broken image tracking category from
+  Special:Wantedfiles.
 * (bug 27724) Add timestamp to job queue.
-* (bug 30339) Implement SpecialPage for running javascript tests. Disabled by default, due to
-  tests potentially being harmful, not to be run on a production wiki.
-  Enable by setting $wgEnableJavaScriptTest to true.
+* (bug 30339) Implement SpecialPage for running javascript tests. Disabled by
+  default, due to tests potentially being harmful, not to be run on a production
+  wiki. Enable by setting $wgEnableJavaScriptTest to true.
 * Extensions can use the RequestContextCreateSkin hook to override what skin is
   loaded in some contexts.
 * (bug 33456) Show $wgQueryCacheLimit on cached query pages.
 * (bug 10574) Add an option to allow all pages to be exported by Special:Export.
-* mediawiki.js Message object constructor is now publicly available as mw.Message.
+* mediawiki.js Message object constructor is now publicly available as
+  mw.Message.
 * (bug 29309) Allow CSS class per tooltip (tipsy).
 * (bug 33565) Add accesskey/tooltip to submit buttons on Special:EditWatchlist.
 * (bug 17959) Inline rendering/thumbnailing for Gimp XCF images.
@@ -7390,9 +7731,9 @@ release and submitting bug reports.
   until the second was introduced in 1.17.
 * BREAKING CHANGE:  Style rules for wikitable are now more specific and prevent
   inheritance to nested tables which caused various issues (bug 30485 and bug
-  33434). If your wiki has overridden rules for ".wikitable", please revise them and
-  adjust where necessary. For comparison, use the "table.wikitable" section in
-  skins/common/shared.css as base.
+  33434). If your wiki has overridden rules for ".wikitable", please revise them
+  and adjust where necessary. For comparison, use the "table.wikitable" section
+  in skins/common/shared.css as base.
 * $wgUploadNavigationUrl is now used for file redlinks if
   $wgUploadMissingFileUrl is not set. The former was used for this until the
   second was introduced in 1.17.
@@ -7414,8 +7755,8 @@ release and submitting bug reports.
 * Show --batch-size option in help of maintenance scripts that support it.
 * (bug 4381) Magic quotes cleaning was not comprehensive, key strings were not
   unescaped.
-* (bug 23057) Importers no longer can 'edit' or 'create' a fully-protected page by
-  importing a new revision into it.
+* (bug 23057) Importers no longer can 'edit' or 'create' a fully-protected page
+  by importing a new revision into it.
 * Allow moving the associated talk pages of subpages even if the base page
   has no subpage.
 * Per page edit-notices now work in namespaces without subpages enabled.
@@ -7446,7 +7787,8 @@ release and submitting bug reports.
 * (bug 30368) Special:Newpages now shows the new page name for moved pages.
 * (bug 1697) The way to search blocked usernames in block log should be clearer.
 * (bug 29747) eAccelerator shared memory caching has been removed since it is
-  now disabled by default and is buggy. APC, XCache and WinCache are not affected.
+  now disabled by default and is buggy. APC, XCache and WinCache are not
+  affected.
 * Installer now refuses to install if php was not compiled with Ctype support.
 * (bug 29475) Remove "trackback" feature entirely from core.
 * (bug 32665) Special:BlockList prefills the username in the input field if
@@ -7491,28 +7833,33 @@ release and submitting bug reports.
 * Files with IPTC blocks we can't read no longer prevent extraction of exif
   or other metadata.
 * (bug 33587) Remove action "historysubmit" from history pages.
-* (bug 25800) mw.config wgAction should contain the actually performed action instead
-  of whatever the query value contains.
+* (bug 25800) mw.config wgAction should contain the actually performed action
+  instead of whatever the query value contains.
 * (bug 4438) Add CSS hook for current WikiPage action.
-* (bug 33703) Common border-bottom color for <abbr> should inherit default (text) color.
+* (bug 33703) Common border-bottom color for <abbr> should inherit default
+  (text) color.
 * (bug 33819) Display file sizes in appropriate units.
-* (bug 32948) {{REVISIONID}} and related variables are no longer blank after doing
-  a null edit.
-* (bug 33880) $wgUsersNotifiedOnAllChanges should not send e-mail to user who made
-  the edit.
+* (bug 32948) {{REVISIONID}} and related variables are no longer blank after
+  doing a null edit.
+* (bug 33880) $wgUsersNotifiedOnAllChanges should not send e-mail to user who
+  made the edit.
 * (bug 33902) Decoding %2B with mw.Uri.decode results in ' ' instead of +.
 * (bug 33762) QueryPage-based special pages no longer misses *-summary message.
-* Other sizes links are no longer generated for wikis without a 404 thumbnail handler.
+* Other sizes links are no longer generated for wikis without a 404 thumbnail
+  handler.
 * (bug 29454) Enforce byteLimit for page title input on Special:MovePage.
 * (bug 34114) CSSMin::remap() doesn't respect its $embed parameter.
-* Special:Contributions/newbies now shows the contributions for the user "newbies".
-  New user contributions are obtained using the form or using ?contribs=newbie in URL.
-* It is now possible to delete images that have no corresponding description pages.
+* Special:Contributions/newbies now shows the contributions for the user
+  "newbies". New user contributions are obtained using the form or using
+  ?contribs=newbie in URL.
+* It is now possible to delete images that have no corresponding description
+  pages.
 * (bug 33165) GlobalFunctions.php line 1312: Call to a member function
   getText() on a non-object.
 * (bug 31676) Group dynamically inserted CSS into a single <style> tag, to work
   around a bug where not all styles were applied in Internet Explorer.
-* (bug 28936, bug 5280) Broken or invalid titles can't be removed from watchlist.
+* (bug 28936, bug 5280) Broken or invalid titles can't be removed from
+  watchlist.
 * (bug 34600) Older skins using useHeadElement=false were broken in 1.18.
 * (bug 34604) [mw.config] wgActionPaths should be an object instead of a numeral
   array.
@@ -7525,8 +7872,8 @@ release and submitting bug reports.
   [[Special:WhatLinksHere/Example]]
 
 === API changes in 1.19 ===
-* Made action=edit less likely to return "unknownerror", by returning the actual error
-  message (which may have come from a hook call or similar).
+* Made action=edit less likely to return "unknownerror", by returning the actual
+  error message (which may have come from a hook call or similar).
 * (bug 19838) siprop=interwikimap can now use the interwiki cache.
 * (bug 29748) Add API search prefix support.
 * (bug 29684) Set forgotten parameter types in ApiQueryIWLinks.
@@ -7588,34 +7935,50 @@ changes to languages because of Bugzilla reports.
 * jquery.mwPrototypes module was renamed to jquery.mwExtension.
 * The maintenance script populateSha1.php was renamed to the more concise
   populateImageSha1.php.
-* The Client-IP header is no longer checked for when trying to resolve a client's
-  real IP address.
-* (bug 22096) Although IE5.x and below was already unsupported officially, stylesheets
-  existing exclusively for IE5.0 and IE5.5 have now been removed (which were in skins
-  'chick' and 'monobook').
+* The Client-IP header is no longer checked for when trying to resolve a
+  client's real IP address.
+* (bug 22096) Although IE5.x and below was already unsupported officially,
+  stylesheets existing exclusively for IE5.0 and IE5.5 have now been removed
+  (which were in skins 'chick' and 'monobook').
 * The constructor for CategoryView has changed, the second parameter is now a
   Context source and is required.
 * The Title::escape{Local,Full,Canonical}URL methods are deprecated, please use
   proper html building methods to escape the normal get{...}URL methods instead.
 * The $variant arguments in the Title::get{Local,Full,Link,Canonical}URL methods
   have been replaced with a secondary query argument.
-* The $variant argument in the hooks for the Title::get{Local,Full,Link,Canonical}URL
-  methods have been removed, the variant is now part of the $query argument.
+* The $variant argument in the hooks for the
+  Title::get{Local,Full,Link,Canonical}URL methods have been removed, the
+  variant is now part of the $query argument.
 * Removed Title::isValidCssJsSubpage(), deprecated since 1.17 in favor of
   using Title::isCssJsSubpage() or checking Title::isWrongCaseCssJsPage().
 * Support for the deprecated hook MagicWordMagicWords was removed.
 * The Xml::namespaceSelector method has been deprecated, please use
   Html::namespaceSelector instead (note that the parameters have changed also).
-* (bug 33746) Preload popular ResourceLoader modules (mediawiki.util) as stop-gap
-  for scripts missing dependencies.
-  New configuration variable $wgPreloadJavaScriptMwUtil has been introduced for this
-  (set to false by default for new installations). Set to true if your wiki has a large
-  amount of user/site scripts that are lacking dependency information. In the short to
-  medium term these user/site scripts should be fixed by adding the used modules to the
-  dependencies in the module registry and/or wrapping them in a callback to mw.loader.using.
+* (bug 33746) Preload popular ResourceLoader modules (mediawiki.util) as
+  stop-gap for scripts missing dependencies.
+  New configuration variable $wgPreloadJavaScriptMwUtil has been introduced for
+  this (set to false by default for new installations). Set to true if your wiki
+  has a large amount of user/site scripts that are lacking dependency
+  information. In the short to medium term these user/site scripts should be
+  fixed by adding the used modules to the dependencies in the module registry
+  and/or wrapping them in a callback to mw.loader.using.
 
 == MediaWiki 1.18 ==
 
+== MediaWiki 1.18.6 ==
+2012-11-29
+
+This is a maintenance and security release of the MediaWiki 1.18 branch
+
+=== Changes since 1.18.5 ===
+* ([[bugzilla:40995|bug 40995]]) Prevent session fixation in Special:UserLogin
+(CVE-2012-5391)
+* ([[bugzilla:41400|bug 41400]]) Prevent linker regex from exceeding PCRE
+backtrack limit
+* Localisation updates
+* Increase permitted runtime for testParserTest
+* ([[bugzilla:36179|bug 36179]]) Unquote 'null' for PostgreSQL.
+
 == MediaWiki 1.18.5 ==
 2012-08-30
 
@@ -7646,7 +8009,8 @@ This is a maintenance release of the MediaWiki 1.18 branch.
 === Changes since 1.18.2 ===
 * (bug 35446) Using "{{nse:}}" with an invalid namespace name no longer throws
   a PHP warning.
-* (bug 35567) The whole password reminder e-mail is now sent in the same language.
+* (bug 35567) The whole password reminder e-mail is now sent in the same
+  language.
 * (bug 35961) Hash comparison should always be strict.
 * (bug 35671) PHP Notice: Undefined index: gettoken in includes/api/ApiMain.php
   on line 598.
@@ -7672,8 +8036,8 @@ This is a maintenance and security release of the MediaWiki 1.18 branch.
   core parser functions which operate on strings, such as formatnum.
 * (bug 34212) ApiBlock/ApiUnblock allow action to take place without a token
   parameter present.
-* (bug 34907) Fixed exposure of tokens through load.php that could have facilitated
-  CSRF attacks.
+* (bug 34907) Fixed exposure of tokens through load.php that could have
+  facilitated CSRF attacks.
 * (bug 35317) CSRF in Special:Upload.
 
 == MediaWiki 1.18.1 ==
@@ -7682,13 +8046,16 @@ This is a maintenance and security release of the MediaWiki 1.18 branch.
 This a maintenance and security release of the MediaWiki 1.18 branch.
 
 === Changes since 1.18.0 ===
-* (bug 32712) Fix for search indexing of pages with certain unicode chars following URL.
-* (bug 3901) Lang, hreflang attribs added to sidebar interlanguage links for screen readers.
+* (bug 32712) Fix for search indexing of pages with certain unicode chars
+  following URL.
+* (bug 3901) Lang, hreflang attribs added to sidebar interlanguage links for
+  screen readers.
 * (bug 30774) mediawiki.html: Add support for numbers and booleans in the
   attribute values and element contents.
 * (bug 32473) [[Special:PasswordReset]] can not be used on private wiki.
 * (bug 32853) Fixed CACHE_DBA object cache type.
-* (bug 32786) Backward compatibility for extension using 1.17's Database::newFromType().
+* (bug 32786) Backward compatibility for extension using 1.17's
+  Database::newFromType().
 * Fixed exception when using Special:WhatLinksHere on a Media: file.
 * (bug 32709) Private Wiki users were always taken to Special:Badtitle on login.
 * (bug 33240) Sort images are missing but referenced in css.
@@ -7697,17 +8064,20 @@ This a maintenance and security release of the MediaWiki 1.18 branch.
 * (bug 32702) Removed method Skin::makeGlobalVariablesScript() has been readded
   for backward compatibility.
 * (bug 30172) The check for posix_isatty() in maintenance scripts did not detect
-  when the function exists but is disabled. Introduced Maintenance::posix_isatty().
+  when the function exists but is disabled. Introduced
+  Maintenance::posix_isatty().
 * (bug 33305) Make mw.util.addCSS resistant to IE's @font-face bug by setting
   cssText after DOM insertion.
-* (bug 29102) Upgrades no longer fail with the error "Unknown character set: 'mysql4'.
+* (bug 29102) Upgrades no longer fail with the error "Unknown character set:
+  'mysql4'.
 * (bug 25355) Parser generates edit section links for special pages.
-* (bug 33321) Adding a line to MediaWiki:Sidebar that contains a pipe, but doesn't
-  have any pipes after being transformed by MessageCache, causes exception on
-  all pages.
-* Fixed recentchanges FK violation on page delete and cache purge error in updater
-  for Oracle DB.
-* (bug 33117) prop=revisions allows deleted text to be exposed through cache pollution.
+* (bug 33321) Adding a line to MediaWiki:Sidebar that contains a pipe, but
+  doesn't have any pipes after being transformed by MessageCache, causes
+  exception on all pages.
+* Fixed recentchanges FK violation on page delete and cache purge error in
+  updater for Oracle DB.
+* (bug 33117) prop=revisions allows deleted text to be exposed through cache
+  pollution.
 
 == MediaWiki 1.18.0 ==
 2011-11-24
@@ -7719,37 +8089,40 @@ This is the first stable release of the MediaWiki 1.18 branch.
 Selected changes since MediaWiki 1.17 that may be of interest:
 
 * Some of the more commonly used MediaWiki extensions are now included in the
-  release tarball. These extensions are ConfirmEdit, Gadgets, Nuke, ParserFunctions,
-  Renameuser, Vector and WikiEditor.
+  release tarball. These extensions are ConfirmEdit, Gadgets, Nuke,
+  ParserFunctions, Renameuser, Vector and WikiEditor.
 
-* Gender support has been improved, meaning user pages can display the correct gender
-  variant of "User" can now be used.
+* Gender support has been improved, meaning user pages can display the correct
+  gender variant of "User" can now be used.
 
-* MediaWiki can now detect the camera orientation of an image from the Exif metadata, and
-  can rotate the image thumbnail appropriately. Metadata support has been generally
-  improved, and can now extract IPTC and XMP metadata.
+* MediaWiki can now detect the camera orientation of an image from the Exif
+  metadata, and can rotate the image thumbnail appropriately. Metadata support
+  has been generally improved, and can now extract IPTC and XMP metadata.
 
-* Improved directionality support in 1.18 means that MediaWiki is better to use for
-  RTL users.
+* Improved directionality support in 1.18 means that MediaWiki is better to use
+  for RTL users.
 
-* MediaWiki now supports protocol - relative URLs in links, interwiki targets and $wgServer
+* MediaWiki now supports protocol - relative URLs in links, interwiki targets
+  and $wgServer
 
 * Math support has been removed from core
 
 === Changes since 1.18.0rc1 ===
-* (bug 32228) regression in Special:Search which did not conserve profile on new search
+* (bug 32228) regression in Special:Search which did not conserve profile on
+  new search
 * (bug 32460) Categories were improperly aligned in Simple and CologneBlue
 * (bug 32412) TOC links on [[Special:EditWatchlist]] points to the fieldsets
 * (bug 32582) Fix TOC show/hide link regression on IE 8
 
 === Changes since 1.18 beta 1 ===
-* (bug 31886) Wrong titles redirecting to Special:Badtitle in the 1.18 deployment.
+* (bug 31886) Wrong titles redirecting to Special:Badtitle in the 1.18
+  deployment.
 * (bug 32051) Fix description for wlprop=sizes.
 * (bug 31913) Special:MostLinkedTemplates had an incorrect GROUP BY clause
   under Microsoft SQL.
 * (bug 32100) installer complains about suhosin GET limit.
-* (bug 31933) fix 1.18 regression in Monobook sidebar: huge spacing between portlets
-  on IE 7 and IE 8/9 in compatibility view.
+* (bug 31933) fix 1.18 regression in Monobook sidebar: huge spacing between
+  portlets on IE 7 and IE 8/9 in compatibility view.
 * (bug 32126) Fix 1.18 regression in watchlist editor when items already removed
   from watchlist.
 * (bug 32183) remove the client-* classes added from user-agent-sniffing onto
@@ -7824,7 +8197,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
 * $wgProto has been removed. You now only need to set $wgServer to change the
   URL protocol.
 * $wgRateLimitsExcludedGroups (deprecated in 1.13) has been removed.
-* $wgInputEncoding and $wgOutputEncoding (deprecated in 1.5) have now been removed.
+* $wgInputEncoding and $wgOutputEncoding (deprecated in 1.5) have now been
+  removed.
 * $wgAllowUserSkin (deprecated in 1.16) has now been removed.
 * $wgExtraRandompageSQL (deprecated in 1.16) has now been removed.
 * LogReader and LogViewer classes (deprecated in 1.14) have now been removed.
@@ -7834,9 +8208,10 @@ Selected changes since MediaWiki 1.17 that may be of interest:
   and the functionality has been moved to the relevant extensions. See
   https://www.mediawiki.org/wiki/Extension:DublinCoreRdf and
   https://www.mediawiki.org/wiki/Extension:CreativeCommonsRdf as appropriate.
-* (bug 21107) Split error "customcssjsprotected" into separate messages for JS and CSS
-* Removed $wgCheckCopyrightUpload from DefaultSettings, since the relevant feature
-  was removed in about 1.5.
+* (bug 21107) Split error "customcssjsprotected" into separate messages for JS
+  and CSS
+* Removed $wgCheckCopyrightUpload from DefaultSettings, since the relevant
+  feature was removed in about 1.5.
 * LogPageValidTypes, LogPageLogName, LogPageLogHeader and LogPageActionText
   hooks have been removed.
 * New hook "Collation::factory" to allow extensions to create custom
@@ -7848,9 +8223,10 @@ Selected changes since MediaWiki 1.17 that may be of interest:
 === New features in 1.18 ===
 * BREAKING CHANGE: action=watch / action=unwatch now requires a token.
 * BREAKING CHANGE: Article class hierarchy split into WikiPage (backend)
-  and Article (frontend) hierarchies. Several hooks now pass a WikiPage object instead
-  of an Article object. These hooks all use an $article parameter as documented in hooks.txt.
-  Extensions should be updated to account for this, though most won't require any changes.
+  and Article (frontend) hierarchies. Several hooks now pass a WikiPage object
+  instead of an Article object. These hooks all use an $article parameter as
+  documented in hooks.txt. Extensions should be updated to account for this,
+  though most won't require any changes.
 * (bug 27860) Minor edit after clicking 'new section' tab
   Now the "This is a minor edit" checkbox is not available when you
   create a page or new section.
@@ -7878,8 +8254,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
   (maintenance/fixDoubleRedirects.php).
 * (bug 23315) New body classes to allow easier styling of special pages.
 * (bug 27159) Make email confirmation code expiration time configurable.
-* (bug 29047) CSS/JS for each user group is imported from MediaWiki:Group-sysop.js,
-  MediaWiki:Group-autoconfirmed.css, etc.
+* (bug 29047) CSS/JS for each user group is imported from
+  MediaWiki:Group-sysop.js, MediaWiki:Group-autoconfirmed.css, etc.
 * (bug 24230) Uploads of ZIP types, such as MS Office or OpenOffice can now be
   safely enabled. A ZIP file reader was added which can scan a ZIP file for
   potentially dangerous Java applets. This allows applets to be blocked
@@ -7937,7 +8313,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
 * (bug 29067) Expose user.tokens (like we do user.options) in ResourceLoader.
 * New 'Debug' hook used by wfDebug() and wfDebugLog().
 * (bug 27655) Require token for watching/unwatching pages)
-* (bug 28904) (bug 29773) Update jQuery version from 1.4.4 to 1.6.2 (the latest version)
+* (bug 28904) (bug 29773) Update jQuery version from 1.4.4 to 1.6.2 (the latest
+  version)
 * (bug 29441) Expose CapitalLinks config in JS to allow modules to properly
   handle titles on case-sensitive wikis.
 * (bug 29397) Implement mw.Title module in core.
@@ -7964,16 +8341,18 @@ Selected changes since MediaWiki 1.17 that may be of interest:
   Suggests possible categories when typing, all saves are done via AJAX.
   Supports editing of multiple categories and then saving them in one batch.
 * $wgAutopromoteOnce was added, allowing for users to be automatically promoted
-  to explicit usergroups. If a group is removed from a user via Special:UserRights,
-  it will not automatically be re-added. Configuration is similar to
-  $wgAutopromote (see DefaultSettings.php).
-* The PerformRetroactiveAutoblock hook was added to allow overriding or complementing
-  retroactive autoblock handling. This runs when blocking a user with the 'autoblock' option.
+  to explicit usergroups. If a group is removed from a user via
+  Special:UserRights, it will not automatically be re-added. Configuration is
+  similar to $wgAutopromote (see DefaultSettings.php).
+* The PerformRetroactiveAutoblock hook was added to allow overriding or
+  complementing retroactive autoblock handling. This runs when blocking a user
+  with the 'autoblock' option.
 * MediaWiki now supports using protocol-relative URLs in links, interwiki
   targets and $wgServer.
 * Introduced $wgVaryOnXFPForAPI which will cause the API to send
   Vary: X-Forwarded-Proto headers.
-* New maintenance script to refresh image metadata (maintenance/refreshImageMetadata.php).
+* New maintenance script to refresh image metadata
+  (maintenance/refreshImageMetadata.php).
 * (bug 16428) Include permalink in printable version.
 * (bug 30722) Add an identity collation that sorts things based on what the
   unicode code point is (aka pre-1.17 behavior).
@@ -7982,16 +8361,17 @@ Selected changes since MediaWiki 1.17 that may be of interest:
   values for preferences a hook has been introduced in User:getDefaultOptions().
   Setting preferences in $wgDefaultUserOptions still work fine, but when reading
   them (i.e. with array_keys) to get a list of all preferences, then
-  $wgDefaultUserOptions should no longer be used as it will contain those set via
-  User:getDefaultOptions().
+  $wgDefaultUserOptions should no longer be used as it will contain those set
+  via User:getDefaultOptions().
 * (bug 30497) Add client-nojs and client-js classes on document element
   to let styles easily hide or show things based on general JS availability.
 * (bug 31293) If Special:Userlogin is loaded over HTTPS, display
   MediaWiki:loginend-https instead of MediaWiki:loginend, if it's not empty.
   Same for signupend on the account creation page.
-* (bug 31233) New OutputPage::addJsConfigVars() method to make the output page specific
-  mw.config map extendable.
-* mw.util.wikiScript has been implemented (like wfScript in GlobalFunctions.php).
+* (bug 31233) New OutputPage::addJsConfigVars() method to make the output page
+  specific mw.config map extendable.
+* mw.util.wikiScript has been implemented (like wfScript in
+  GlobalFunctions.php).
 
 === Bug fixes in 1.18 ===
 * (bug 27860) Minor edit after clicking 'new section' tab.
@@ -8145,8 +8525,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
   LTR/RTL screen layout.
 * (bug 28992) Revision numbers in the patrol log are transformed in the user
   language.
-* (bug 27073) ResourceLoaderDynamicStyles marker should be dynamically appended to
-  the document head if it doesn't exist.
+* (bug 27073) ResourceLoaderDynamicStyles marker should be dynamically appended
+  to the document head if it doesn't exist.
 * (bug 27023) After the document is ready, mw.loader is broken (calls callback
   before module is parsed).
 * (bug 4330) External URLs without a custom title should be treated as LTR,
@@ -8163,7 +8543,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
 * The class JpegOrTiffHandler was renamed ExifBitmapHandler.
 * (bug 29443) Special:Undelete should use JavaScript to invert all checkboxes
   instead of reloading the page.
-* (bug 29325) Setting $wgStrictFileExtensions to false no longer gives incorrect warning.
+* (bug 29325) Setting $wgStrictFileExtensions to false no longer gives incorrect
+  warning.
 * (bug 29437) Multiple apostrophes in deleted article title cause odd rendering.
 * (bug 29485) RSS feed of Special:RecentChange grouped together multiple
   consecutive edits by same user in included diff, but then linked to
@@ -8171,7 +8552,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
 * Do not try to group together a page creation and edit in the RSS feed of RC.
 * (bug 29342) Patrol preferences shouldn't be visible to users who don't have
   patrol permissions.
-* (bug 29471) Exception no longer thrown for files with invalid date in metadata.
+* (bug 29471) Exception no longer thrown for files with invalid date in
+  metadata.
 * (bug 29492) Long-running steps in the installer (such as Upgrade and Install)
   no longer cause timeouts.
 * (bug 29507) Change 'image link' to 'file link' in Special:Whatlinkshere.
@@ -8186,8 +8568,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
 * Use content language in formatting of dates in revertpage message
   (rollback revert edit summary) and do not adjust for user timezone.
 * (bug 29277) MediaWiki:Filepage.css is also shown on the local wiki
-* Make sure Backlink cache does not retrieve interwiki redirects when looking for
-  redirects to a local page.
+* Make sure Backlink cache does not retrieve interwiki redirects when looking
+  for redirects to a local page.
 * (bug 6100) Allow different directionality (LTR/RTL) for user interface
   and wiki content, along with many other RTL and directionality improvements
   (such as bugs 28030, 12406, 28349).
@@ -8218,24 +8600,26 @@ Selected changes since MediaWiki 1.17 that may be of interest:
 * Installer checked for magic_quotes_runtime instead of register_globals.
 * (bug 30131) XCache with variable caching disabled no longer used for variable
   caching (CACHE_ACCEL)
-* $wgSVGMaxSize is now applied to the smaller of width or height, making very wide
-  pano/timeline/diagram SVGs renderable at saner sizes.
+* $wgSVGMaxSize is now applied to the smaller of width or height, making very
+  wide pano/timeline/diagram SVGs renderable at saner sizes.
 * (bug 30219) The page shown when LocalSettings.php does not exist was broken on
   Windows servers.
 * (bug 30074) Moving user JS subpages resulted in JS errors because
   #REDIRECT [[Foo]] is invalid JS.
 * (bug 30335) Fix for HTMLForms using GET breaking when non-friendly URLs
   are used.
-* (bug 30264) Changed installer-generated LocalSettings.php to use require_once()
-  instead of require() for included extensions.
+* (bug 30264) Changed installer-generated LocalSettings.php to use
+  require_once() instead of require() for included extensions.
 * Tracking categories are no longer shown in footer for special pages.
-* (bug 30684) Fix bad escaping in mw.message for inexistent messages (i.e. <key>).
+* (bug 30684) Fix bad escaping in mw.message for inexistent messages (i.e.
+  <key>).
 * $wgOverrideSiteFeed no longer double escapes urls.
 * The preprocessor no longer fails with a PHP warning about XML_PARSE_HUGE when
   processing complex pages using newer versions of libxml2.
 * (bug 30907) Special:Unusedcategories should sort ascendingly.
 * (bug 28545) When using the uca-default collation, sortkey's starting with a
-  space (U+20) will sort under an invisible header like in 1.16 rather than a U+6DE.
+  space (U+20) will sort under an invisible header like in 1.16 rather than a
+  U+6DE.
 * (bug 30192) Thumbnails of archived files are now deleted.
 * (bug 30843) mediawiki.Title should not convert extensions (anything after the
   last full stop) to lower case).
@@ -8489,12 +8873,13 @@ Selected changes since MediaWiki 1.16 that may be of interest:
   core parser functions which operate on strings, such as padleft.
 * (bug 34212) ApiBlock/ApiUnblock allow action to take place without a token
   parameter present.
-* (bug 34907) Fixed exposure of tokens through load.php that could have facilitated
-  CSRF attacks.
+* (bug 34907) Fixed exposure of tokens through load.php that could have
+  facilitated CSRF attacks.
 * (bug 35317) CSRF in Special:Upload.
 
 === Changes since 1.17.1 ===
-* (bug 33117) prop=revisions allows deleted text to be exposed through cache pollution.
+* (bug 33117) prop=revisions allows deleted text to be exposed through cache
+  pollution.
 * (bug 32709) Private Wiki users were always taken to Special:Badtitle on login.
 
 === Changes since 1.17.0 ===
@@ -8520,16 +8905,17 @@ Selected changes since MediaWiki 1.16 that may be of interest:
 * Installer checked for magic_quotes_runtime instead of register_globals
 * (bug 30131) XCache with variable caching disabled no longer used for variable
   caching (CACHE_ACCEL)
-* (bug 30264) Changed installer-generated LocalSettings.php to use require_once()
-  instead require() for included extensions.
+* (bug 30264) Changed installer-generated LocalSettings.php to use
+  require_once() instead require() for included extensions.
 * (bug 26486) ResourceLoader modules with paths to nonexistent files cause PHP
   warnings/notices to be thrown
 * (bug 30907) Special:Unusedcategories should sort ascendingly.
 * (bug 30219) The page shown when LocalSettings.php does not exist was broken on
   Windows servers.
-* Hardcoded NLS_NUMERIC_CHARACTERS for Oracle DB to prevent type conversion errors.
-* Fixed recentchanges FK violation on page delete and cache purge error in updater
-  for Oracle DB.
+* Hardcoded NLS_NUMERIC_CHARACTERS for Oracle DB to prevent type conversion
+  errors.
+* Fixed recentchanges FK violation on page delete and cache purge error in
+  updater for Oracle DB.
 * (bug 32276) Skins were generating output using the internal page title which
   would allow anonymous users to determine whether a page exists, potentially
   leaking private data. In fact, the curid and oldid request parameters would
@@ -8588,11 +8974,12 @@ Selected changes since MediaWiki 1.16 that may be of interest:
 * Fixed JS error due to missing dependency for jquery.suggestions.
 * Exposed $wgExtensionAssetsPath in JavaScript.
 * (bug 28738) Made ResourceLoader support environments with small URL length
-  limits. The length limit can be configured via $wgResourceLoaderMaxQueryLength,
-  and this is set automatically in the generated LocalSettings.php when the
-  php.ini variable "suhosin.get.max_value_length" is set. When a URL exceeds
-  this limit, the request is split up. Also, reduced the average length of
-  load.php URLs by using a more compact parameter format.
+  limits. The length limit can be configured via
+  $wgResourceLoaderMaxQueryLength, and this is set automatically in the
+  generated LocalSettings.php when the php.ini variable
+  "suhosin.get.max_value_length" is set. When a URL exceeds this limit, the
+  request is split up. Also, reduced the average length of load.php URLs by
+  using a more compact parameter format.
 * (bug 25262) Fix for minification of hardcoded data: URIs in CSS.
 * (bug 25124) Respect $wgStyleDirectory in ResourceLoader.
 * Allow installation when no HTTP client is available, don't throw an exception.
@@ -8716,7 +9103,8 @@ Selected changes since MediaWiki 1.16 that may be of interest:
 * Non-file pages can no longer be moved to the file namespace, nor vice versa.
 * (bug 671) The <dfn>, <kbd> and <samp> elements have been whitelisted in user
   input.
-* (bug 21503) There's now a "reason" field when creating account for other users.
+* (bug 21503) There's now a "reason" field when creating account for other
+  users.
 * (bug 24418) action=markpatrolled now requires a token.
 * A variety of category sort-related fixes, including:
 ** (bug 164) In English, lowercase and uppercase letters now sort the same.
@@ -8921,7 +9309,8 @@ Selected changes since MediaWiki 1.16 that may be of interest:
 * (bug 23747) Make sure that on History pages, the RevDel button is not
   accidentally activated when hitting enter.
 * (bug 23845) Special:ListFiles now uses correct file names without underscores.
-* Ask for permanent login in Special:Preferences only if $wgCookieExpiration > 0.
+* Ask for permanent login in Special:Preferences only if $wgCookieExpiration >
+  0.
 * (bug 16356) Repair dumpInterwiki.inc to use proper normalization.
 * (bug 24006) deleteArchivedRevisions.php maintenance script now longer throws
   a fatal error.
@@ -8989,7 +9378,8 @@ Selected changes since MediaWiki 1.16 that may be of interest:
   $wgGroupPermissions now appear on Special:ListGroupRights.
 * (bug 23923) Special:Prefixindex no longer shows results if nothing was
   requested.
-* (bug 22308) Search now finds text in default main page immediately after setup.
+* (bug 22308) Search now finds text in default main page immediately after
+  setup.
 * (bug 25697) Make sure empty lines render in diff view.
 * Use an actual minus sign in diff views, instead of a hyphen.
 * (bug 23732) Clarified "n links" message on Special:MostLinkedFiles.
@@ -9011,7 +9401,8 @@ Selected changes since MediaWiki 1.16 that may be of interest:
   parameters.
 * (bug 25175) HTML file cache now honor $wgCacheDirectory if
   $wgFileCacheDirectory is not set.
-* (bug 13353) Diff3 version checks were too strict, did not detect working diff3.
+* (bug 13353) Diff3 version checks were too strict, did not detect working
+  diff3.
 * (bug 25843) Links to special pages using link= attribute on images are now
   normalised like normal links to special pages.
 * (bug 21364) External links using link= attribute on images now respect
@@ -9038,7 +9429,8 @@ Selected changes since MediaWiki 1.16 that may be of interest:
   absolute URLs in the sitemap index (as required e.g. by Google).
 * Partial workaround for bug 6220: at least make files on shared repositories
   show up as (struck-out) bluelinks instead of redlinks on Special:WantedFiles.
-* rebuildFileCache.php no longer creates inappropriate cache files for redirects.
+* rebuildFileCache.php no longer creates inappropriate cache files for
+  redirects.
 * (bug 25512) Subcategory list should not include category prefix for members.
 * (bug 10871) Javascript and CSS pages in MediaWiki namespace are no longer
   treated as wikitext on preview.
@@ -9047,31 +9439,35 @@ Selected changes since MediaWiki 1.16 that may be of interest:
 * (bug 22753) Output from update.php is more clear when things changed, entries
   indicating nothing changed are now all prefixed by "..."
 * (bug 16019) $wgArticlePath = "/$1" no longer breaks API edit/watch actions.
-* (bug 18372) File types blacklisted by $wgFileBlacklist will no longer be shown as
-  "Permitted file types" on the upload form.
+* (bug 18372) File types blacklisted by $wgFileBlacklist will no longer be shown
+  as "Permitted file types" on the upload form.
 * (bug 26540) Fixed wrong call to applyPatch in MysqlUpdater.
 * (bug 26034) Make the "View / Read" tab in content_navigation style tabs remain
   selected when the action is "purge".
 * (bug 26733) Wrap initial table creation in transaction.
 * (bug 26208) Mark directionality of some interlanguage links.
-* (bug 26716) Provide link to instructions for external editor related preferences.
+* (bug 26716) Provide link to instructions for external editor related
+  preferences.
 * (bug 26961) Hide anon edits in watchlist preference now actually works.
 * (bug 1379) Installer directory conflicts with some hosts' configuration panel.
-* (bug 27781) Installer does not warn about 5.1.x. Added a compatibility function
-  for array_key_exists().
+* (bug 27781) Installer does not warn about 5.1.x. Added a compatibility
+  function for array_key_exists().
 * Fix XML well-formedness on a few pages when $wgHtml5 is true (the default).
 * (bug 28069) MediaWiki fails streaming files when mod_deflate and ob_gzhandler
   are also set.
 * (bug 26223) Concurrently moving an article to different titles leaks a
   redirect revision with no page.
 * (bug 15641) Fixed permissions checks in Special:Import which allowed users
-  without the 'import' permission to import pages from configured import sources.
+  without the 'import' permission to import pages from configured import
+  sources.
 * (bug 26449) Keep underlines from headings outside of tables and thumbs by
   adding overflow:hidden to h1,h2,h3,h4,h5,h6 (also fixes editsection bunching).
 * (bug 26708) Remove background-color:white from tables in Monobook and Vector.
-* (bug 26781) {{PAGENAME}} and related parser functions escape their output better.
-* (bug 26716) Provide link to instructions for external editor related preferences
-  and add a comment to the ini control file explaining what is going on.
+* (bug 26781) {{PAGENAME}} and related parser functions escape their output
+  better.
+* (bug 26716) Provide link to instructions for external editor related
+  preferences and add a comment to the ini control file explaining what is going
+  on.
 * (bug 28422) Remove color:black from tables in Monobook and Vector. And add it
   to table.wikitable instead.
 * (bug 27560) Search queries no longer fail in walloon language.
@@ -9099,7 +9495,8 @@ Selected changes since MediaWiki 1.16 that may be of interest:
 * (bug 27508) SVGMetadataExtractor takes too much resources on huge svgs.
 * (bug 27465) SVG thumbnail generation.
 * (bug 27467) preload can leave UNIQ.
-* (bug 27539) Allow attributes beginning with a digit in wikitext tag parameters.
+* (bug 27539) Allow attributes beginning with a digit in wikitext tag
+  parameters.
 * (bug 27328) using relative paths in CSS imports in MediaWiki:Common.css broken
   in 1.17.
 * (bug 27333) Fix repetitive last-seen time queries on page history.
@@ -9287,8 +9684,8 @@ Other significant changes to MediaWiki's language support:
 * Removed $wgRemoteUploads. It was not well supported and superseded by
   $wgUploadNavigationUrl.
 * (bug 26253) $wgPostCommitUpdateList has been removed
-* The PHPUnit test suite has been removed from this release due to serious issues
-  which should be resolved by the 1.18 release.
+* The PHPUnit test suite has been removed from this release due to serious
+  issues which should be resolved by the 1.18 release.
 * Oracle DB now uses the __destruct function to commit/close connection as it
   doesn't commit on close if transation is triggered in OCI.
 
@@ -10140,10 +10537,11 @@ comment from another wiki.
   skin-specific JS pages
 * (bug 5061) Use the more precise thumbcaption thumbimage and thumbinner classes
   for image divs.
-* (bug 22096) IE50Fixes.css and IE55Fixes.css have been dropped from the Monobook
-  and Chick skins
+* (bug 22096) IE50Fixes.css and IE55Fixes.css have been dropped from the
+  Monobook and Chick skins
 * Fixed bug involving unclosed "-{" markup in the language converter
-* (bug 21870) No longer include Google logo from an external server on wiki error.
+* (bug 21870) No longer include Google logo from an external server on wiki
+  error.
 * (bug 22181) Do not truncate if the ellipsis actually make the string longer
 * (bug 16039) Text disappearing after a bad image
 * (bug 18784) Internal links like [[File:Foo|caption]] should read 'caption',
@@ -10242,10 +10640,12 @@ comment from another wiki.
 * (bug 20233) ApiLogin::execute() doesn't handle LoginForm :: RESET_PASS
 * (bug 22061) API: add prop=headitems to action=parse
 * (bug 22240) API: include time in siteinfo
-* (bug 22241) Quick edit is still using the deprecated watch parameter (API: Setting default for watch/unwatch wrongly set)
+* (bug 22241) Quick edit is still using the deprecated watch parameter (API:
+  Setting default for watch/unwatch wrongly set)
 * (bug 22245) blfilterredirect=nonredirects in blredirect mode wrongly filtering
 * (bug 22248) Output extension URLs in meta=siteinfo&siprop=extensions
-* Support key-params arrays in 'descriptionmsg' in meta=siteinfo&siprop=extensions
+* Support key-params arrays in 'descriptionmsg' in
+  meta=siteinfo&siprop=extensions
 * (bug 21922) YAML output should quote asterisk when used as key
 * (bug 22297) safesubst: to allow substitution without breaking transclusion
 * (bug 18758) API read of watchlist's wl_notificationtimestamp
@@ -10479,26 +10879,28 @@ changes to languages because of Bugzilla reports.
   with class 'mw-specialpage-summary'
 * $wgSummarySpamRegex added to handle edit summary spam. This is used *instead*
   of $wgSpamRegex for edit summary checks. Text checks still use $wgSpamRegex.
-* New function to convert content text to specified language (only applies on wiki with
-  LanguageConverter class)
+* New function to convert content text to specified language (only applies on
+  wiki with LanguageConverter class)
 * (bug 17844) Redirect users to a specific page when they log in, see
   $wgRedirectOnLogin
-* Added a link to Special:UserRights on Special:Contributions for privileged users
+* Added a link to Special:UserRights on Special:Contributions for privileged
+  users
 * (bug 10336) Added new magic word {{REVISIONUSER}}, which displays the editor
   of the displayed revision
 * LinkerMakeExternalLink now has an $attribs parameter for link attributes and
   a $linkType parameter for the type of external link being made
-* (bug 17785) Dynamic dates surrounded with a <span> tag, fixing sortable tables with
-  dynamic dates.
-* (bug 4582) Provide preference-based autoformatting of unlinked dates with the dateformat
-  parser function.
-* (bug 17886) Special:Export now allows you to export a whole namespace (limited to 5000 pages)
+* (bug 17785) Dynamic dates surrounded with a <span> tag, fixing sortable tables
+  with dynamic dates.
+* (bug 4582) Provide preference-based autoformatting of unlinked dates with the
+  dateformat parser function.
+* (bug 17886) Special:Export now allows you to export a whole namespace (limited
+  to 5000 pages)
 * (bug 17714) Limited TIFF upload support now built in if 'tif' extension is
-  enabled. Image width and height are now recognized, and when using ImageMagick,
-  optional flattening to PNG or JPEG for inline display can be enabled by setting
-  $wgTiffThumbnailType
-* Renamed two input IDs on Special:Log from 'page' and 'user' to 'mw-log-page' and
-  'mw-log-user', respectively
+  enabled. Image width and height are now recognized, and when using
+  ImageMagick, optional flattening to PNG or JPEG for inline display can be
+  enabled by setting $wgTiffThumbnailType
+* Renamed two input IDs on Special:Log from 'page' and 'user' to 'mw-log-page'
+  and 'mw-log-user', respectively
 * Added $wgInvalidUsernameCharacters to disallow certain characters in
   usernames during registration (such as "@")
 * Added $wgUserrightsInterwikiDelimiter to allow changing the delimiter
@@ -10506,10 +10908,10 @@ changes to languages because of Bugzilla reports.
   on a different database
 * Add a class if 'missingsummary' is triggered to allow styling of the summary
   line
-* Title attributes are now always blank on framed and thumbnailed images, and default to blank
-  on inline images instead of defaulting to the image's filename. Additionally, the alt
-  attribute now defaults to the filename on framed and thumbnailed images if no caption or alt
-  attribute is specified.
+* Title attributes are now always blank on framed and thumbnailed images, and
+  default to blank on inline images instead of defaulting to the image's
+  filename. Additionally, the alt attribute now defaults to the filename on
+  framed and thumbnailed images if no caption or alt attribute is specified.
 
 === Bug fixes in 1.15 ===
 * (bug 16968) Special:Upload no longer throws useless warnings.
@@ -10620,7 +11022,8 @@ changes to languages because of Bugzilla reports.
   queue
 * (bug 17761) "show/hide" link in page history in now works for the first
   displayed revision if it's not the current one
-* (bug 17722) Fix regression where users are unable to change temporary passwords
+* (bug 17722) Fix regression where users are unable to change temporary
+  passwords
 * (bug 17799) Special:Random no longer throws a database error when a non-
   namespace is given, silently falls back to NS_MAIN
 * (bug 17751) The message for bad titles in WantedPages is now localized
@@ -10642,11 +11045,14 @@ changes to languages because of Bugzilla reports.
   IS NULL
 * (bug 18018) Deleting a file redirect leaves behind a malfunctioning redirect
 * (bug 17537) Disable bad zlib.output_compression output on HTTP 304 responses
-* (bug 11213) [edit] section links in printable version no longer appear when you cut-and-paste article text
+* (bug 11213) [edit] section links in printable version no longer appear when
+  you cut-and-paste article text
 * (bug 17405) "Did you mean" to mirror Go/Search behavior of original request
 * (bug 18116) 'edittools' is now output identically on edit and upload pages
-* (bug 17241) The diffonly URI parameter should cascade to "Next edit" and "Previous edit" diff links
-* (bug 16823) 'Sidebar search form should not use Special:Search view URL as target'
+* (bug 17241) The diffonly URI parameter should cascade to "Next edit" and
+  "Previous edit" diff links
+* (bug 16823) Sidebar search form should not use Special:Search view URL as
+  target
 * (bug 16343) Non-existing, but in use, category pages can be "go" match hits
 * Fixed a CSS validation issue which allowed external images to be included
   into wikis where that is disallowed by configuration.
@@ -10729,8 +11135,8 @@ changes to languages because of Bugzilla reports.
 * (bug 17288) Messages improved for default language (English)
 * (bug 12937) Update native name for Afar
 * (bug 16909) 'histlegend' now reuses messages instead of copying them
-* (bug 17832) action=delete returns 'unknownerror' instead of 'permissiondenied' when
-  the user is blocked
+* (bug 17832) action=delete returns 'unknownerror' instead of 'permissiondenied'
+  when the user is blocked
 * Traditional/Simplified Gan Chinese conversion support
 
 == MediaWiki 1.14 ==
@@ -10956,18 +11362,20 @@ The following extensions are migrated into MediaWiki 1.14:
 * Dropped old Paser_OldPP class. Only new parser with preprocessor is used.
 * Moved password reset form from Special:Preferences to Special:ResetPass
 * Added Special:ChangePassword as a special page alias for Special:ResetPass
-* Added complementary function for addHandler() called removeHandler() for removing events
+* Added complementary function for addHandler() called removeHandler() for
+  removing events
 * Improved security of file uploads for IE clients, using a reverse-engineered
   algorithm very similar to IE's content detection algorithm.
 * Cascading protection no longer requires that both edit and move are restricted
   to sysop, just edit=sysop is enough
-* (bug 2391) A warning is now shown for invalid ISBN numbers on Special:Booksources.
-* Installer has been updated to reflect the release of the GFDL 1.3. The URL for 1.2
-  has been updated, and the 1.3 URL has been given. 1.2 is still Wikipedia-compatible.
-  RightsCode was changed from 'gfdl' to 'gfdl1_2', so we can now support 1.2 as well
-  as 1.3 (gfdl1_3).
-* (bug 16293) PD URL was changed to the CreativeCommons site on PD (which auto-detects
-  your language) instead of Wikipedia.
+* (bug 2391) A warning is now shown for invalid ISBN numbers on
+  Special:Booksources.
+* Installer has been updated to reflect the release of the GFDL 1.3. The URL for
+  1.2 has been updated, and the 1.3 URL has been given. 1.2 is still
+  Wikipedia-compatible. RightsCode was changed from 'gfdl' to 'gfdl1_2', so we
+  can now support 1.2 as well as 1.3 (gfdl1_3).
+* (bug 16293) PD URL was changed to the CreativeCommons site on PD (which
+  auto-detects your language) instead of Wikipedia.
 * (bug 16635) The "view and edit watchlist" page (Special:Watchlist/edit) now
   includes a table of contents
 * File objects returned by wfFindFile() are now cached by default
@@ -10977,8 +11385,8 @@ The following extensions are migrated into MediaWiki 1.14:
 * (bug 16459) Use native getElementsByClassName where possible, for better
   performance in modern browsers
 * Enable \cancel and \cancelto in texvc (recompile required)
-* Added 'UserCryptPassword' and 'UserComparePasswords' hooks to allow extensions to implement
-  their own password hashing methods.
+* Added 'UserCryptPassword' and 'UserComparePasswords' hooks to allow extensions
+  to implement their own password hashing methods.
 * (bug 16760) Add CSS-class to action links of Special:Log
 * (bug 505) Time zones can now be specified by location in user preferences,
   avoiding the need to manually update for DST. Patch by Brad Jorsch.
@@ -11339,6 +11747,43 @@ regularly. Below only new and removed languages are listed.
 
 == MediaWiki 1.13 ==
 
+== MediaWiki 1.13.5 ==
+
+February 22, 2009
+
+This is a maintenance update to the Summer 2008 snapshot release of MediaWiki.
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept
+"ready to run", and in fact runs our own sites on Wikipedia.
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature developments
+will be made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain
+it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+
+== Changes since 1.13.4 ==
+
+* (bug 17449) Fixed PostgreSQL installation
+* (bug 17527) Fixed missing MySQL-specific options in installer
+
+== Changes since 1.13.3 ==
+
+A number of cross-site scripting (XSS) security vulnerabilities were discovered
+in the web-based installer (config/index.php). These vulnerabilities all
+require a live installer -- once the installer has been used to install a wiki,
+it is deactivated.
+
+Note that cross-site scripting vulnerabilities can be used to attack any website
+in the same cookie domain. So if you have an uninstalled copy of MediaWiki on
+the same site as an active web service, MediaWiki could be used to attack the
+active service.
+
+If you are hosting an old copy of MediaWiki that you have never installed, you
+are advised to remove it from the web.
+
 == Changes since 1.13.2 ==
 
 David Remahl of Apple's Product Security team has identified a number of
@@ -11440,8 +11885,8 @@ Other changes in this release:
   checked
 * (bug 13376) Use $wgPasswordSender, not $wgEmergencyContact, as return
   address for page update notification mails.
-* API: Registration time of users registered before the DB field was created is now
-  shown as empty instead of the current time.
+* API: Registration time of users registered before the DB field was created is
+  now shown as empty instead of the current time.
 * (bug 14904): fragments were lost when redirects were fixed.
 * Added magic word __STATICREDIRECT__ to suppress the redirect fixer
 * (bug 15035) Revert English linkTrail to /^([a-z]+)(.*)$/sD, as it was before
@@ -11467,15 +11912,16 @@ Other changes in this release:
     $wgAutopromote['emailconfirmed'] = APCOND_EMAILCONFIRMED;
   in your LocalSettings.php.
 * (bug 2396) New shared database configuration variables. $wgSharedPrefix allows
-  you to use a shared database with a different prefix. Or you can now use a local
-  database and use prefixes to separate wiki and the shared tables. And the new
-  $wgSharedTables variable allows you to specify a list of tables to share.
+  you to use a shared database with a different prefix. Or you can now use a
+  local database and use prefixes to separate wiki and the shared tables. And
+  the new $wgSharedTables variable allows you to specify a list of tables to
+  share.
 * Automatic edit summaries can be disabled with $wgUseAutomaticEditSummaries
 * Duplicates of images are now shown on the image page
-* $wgRCFilterByAge allows for the list of dates in recent changes special pages to
-  be filtered to only those within the range of $wgRCMaxAge
-* $wgRCLinkLimits and $wgRCLinkDays allow for customization of the list and limits
-  displayed on the recent changes special pages
+* $wgRCFilterByAge allows for the list of dates in recent changes special pages
+  to be filtered to only those within the range of $wgRCMaxAge
+* $wgRCLinkLimits and $wgRCLinkDays allow for customization of the list and
+  limits displayed on the recent changes special pages
 * The "createpage" permission is no longer required when uploading if the target
   image page already exists
 * $wgMaximumMovedPages restricts the number of pages that can be moved at once
@@ -11493,8 +11939,8 @@ Other changes in this release:
   Default: false
 * Removed $wgEnableCascadingProtection option. Disabling cascading protection
   is no longer possible.
-* $wgMessageCacheType defines now the type of cache used by the MessageCache class,
-  previously it was choosen based on $wgParserCacheType
+* $wgMessageCacheType defines now the type of cache used by the MessageCache
+  class, previously it was choosen based on $wgParserCacheType
 * $wgExtensionAliasesFiles option to simplify adding aliases to special pages
   provided by extensions, in a similar way to $wgExtensionMessagesFiles
 * Added $wgXMLMimeTypes, an array of XML mimetypes we can check for
@@ -11584,8 +12030,8 @@ Other changes in this release:
   'import-upload' instead of 'upload'
 * Add information about user group membership to Special:Preferences
 * (bug 14146) Wrap usage section on imagepages into <div>s.
-* New layout for Special:Specialpages. Restricted pages are marked but not separated
-  from other pages in their group.
+* New layout for Special:Specialpages. Restricted pages are marked but not
+  separated from other pages in their group.
 * (bug 14263) Show a diff of the revert on rollback notification page.
 * (bug 13434) Show a warning when hash identical files exist
 * Sidebar is now cached for all languages
@@ -11594,15 +12040,16 @@ Other changes in this release:
   edits in the last $wgActiveUserDays days.
 * SpecialSearchResults hook now passes results by reference, so they can be
   changed by extensions.
-* Add a new hook LinkerMakeExternalLink to allow extensions to modify the output of
-  external links.
+* Add a new hook LinkerMakeExternalLink to allow extensions to modify the output
+  of external links.
 * (bug 14132) Allow user to disable bot edits from being output to UDP.
-* (bug 14328) jsMsg() within Wikibits now accepts a DOM object, not just a string
+* (bug 14328) jsMsg() within Wikibits now accepts a DOM object, not just a
+  string
 * (bug 14558) New system message (emailuserfooter) is now added to the footer of
   e-mails sent with Special:Emailuser
 * Add support for Hijri (Islamic) calendar
-* Add a new hook LinkerMakeExternalImage to allow extensions to modify the output
-  of external (hotlinked) images.
+* Add a new hook LinkerMakeExternalImage to allow extensions to modify the
+  output of external (hotlinked) images.
 * (bug 14604) Introduced the following features for the LanguageConverter:
   Multi-tag support, single conversion flag, remove conversion flag on a single
   page, description flag, variant name, multi-variant fallbacks.
@@ -11619,13 +12066,13 @@ Other changes in this release:
 * Allow the search box, toolbox and languages box in the Monobook sidebar to be
   moved around arbitrarily using special sections in [[MediaWiki:Sidebar]]:
   SEARCH, TOOLBOX and LANGUAGES
-* Add a new hook NormalizeMessageKey to allow extensions to replace messages before
-  the database is potentially queried
+* Add a new hook NormalizeMessageKey to allow extensions to replace messages
+  before the database is potentially queried
 * (bug 9736) Redirects on Special:Fewestrevisions are now marked as such.
 * New date/time formats in Cs localization according to ČSN and PČP.
 * Special:Recentchangeslinked now includes changes to transcluded pages and
-  displayed images; also, the "Show changes to pages linked" checkbox now works on
-  category pages too, showing all links that are not categorizations
+  displayed images; also, the "Show changes to pages linked" checkbox now works
+  on category pages too, showing all links that are not categorizations
 * (bug 4578) Automatically fix redirects broken by a page move
 
 === Bug fixes in 1.13 ===
@@ -11638,7 +12085,8 @@ Other changes in this release:
 * Make the default filepageexists message accurate
 * (bug 12988) $wgMinimalPasswordLength no longer breaks create user by email
 * (bug 13022) Fix upload from URL on PHP 5.0.x
-* (bug 13132) Unable to unprotect pages protected with earlier versions of MediaWiki
+* (bug 13132) Unable to unprotect pages protected with earlier versions of
+  MediaWiki
 * (bug 12723) OpenSearch description name now uses more compact language code
   to avoid passing the length limit as often, is customizable per site via
   'opensearch-desc' message.
@@ -11647,7 +12095,8 @@ Other changes in this release:
 * (bug 12575) Prevent duplicate patrol log entries from being created
 * (bug 13174) __HIDDENCAT__ now applies only to category pages
 * (bug 13031) Add links to user pages in e-mail form
-* (bug 13147) Description for categoriespagetext (used in Special:Categories) reworded
+* (bug 13147) Description for categoriespagetext (used in Special:Categories)
+  reworded
 * (bug 11561) Fix fatal error when calling action=revert to non-image page
 * (bug 12430) Fix call to private method LinkFilter::makeRegex fatal error in
   maintenance/cleanupSpam.php
@@ -11662,7 +12111,8 @@ Other changes in this release:
 * (bug 13274) Change links for messages to ucfirst
 * (bug 13273) Un-hardcode some punctuation (add new messages colon-separator,
   autocomment-prefix)
-* Parse MediaWiki message translations with a correct language setting on preview
+* Parse MediaWiki message translations with a correct language setting on
+  preview
 * (bug 13281) Treat X-Forwarded-For, Client-ip and User-Agent headers as
   case-insensitive names.
 * Adding the fix for lists in RTL wikis to more skins, and fixing the image toc
@@ -11716,7 +12166,8 @@ Other changes in this release:
 * (bug 13576) maintenance/rebuildrecentchanges.php fails
 * (bug 13441) Allow Special:Recentchanges to show bots only
 * (bug 13431) Show true message source in Special:Allmessages&ot=php / xml
-* (bug 13463) Login successful page doesn't use user's preferred interface language
+* (bug 13463) Login successful page doesn't use user's preferred interface
+  language
 * (bug 13630) Fixed warnings for pass by reference at call time in
   Special:Revisiondelete when generating the log entry.
 * (bug 12064) BeforePageDisplay hook is now called for all skins
@@ -11746,7 +12197,8 @@ Other changes in this release:
 * Do not display empty columns on Special:UserRights if all groups are
   changeable or all unchangeable
 * Fix fatal error on calling PAGESINCATEGORY with invalid category name
-* (bug 13793) Special:Whatlinkshere filters wrong - after paginating instead of before
+* (bug 13793) Special:Whatlinkshere filters wrong - after paginating instead of
+  before
 * (bug 13796) Show links to parent pages even if some of them are missing
 * (bug 13816) Filter by main namespace doesn't work on WhatLinksHere
 * (bug 13822) Fatal error on some pages when calculating subpage subtitle
@@ -11772,12 +12224,15 @@ Other changes in this release:
 * (bug 13934) Fixing the link to GNU General Public License Version 2
 * Show correct accesskey prefix for Firefox 3 beta (Alt-Shift-, not Alt-)
 * (bug 13949) Special:PrefixIndex/AllPages paging links contain invalid XML
-* (bug 13770) Use Preprocessor_Hash by default to avoid missing DOM module errors
+* (bug 13770) Use Preprocessor_Hash by default to avoid missing DOM module
+  errors
 * (bug 13982) Disable ccmeonemails preference when user-to-user mails disabled
 * (bug 13615) Update case mappings and normalization to Unicode 5.1.0
-  Note that case mappings will only be used if mbstring extension is not present.
+  Note that case mappings will only be used if mbstring extension is not
+  present.
 * (bug 14044) Don't increment page view counters on views from bot users
-* (bug 14042) Calling Database::limitResult() misplaced the comment in the log file
+* (bug 14042) Calling Database::limitResult() misplaced the comment in the log
+  file
 * (bug 14047) Fix regression in installer which hid DB-specific options
   Also makes SQLite path configurable in the installer.
 * (bug 13546) Follow image redirects on image page
@@ -11981,9 +12436,143 @@ Other changes in this release:
   the page
 * list=exturlusage in "list all links" mode can now filter by protocol
 
+== MediaWiki 1.12 ==
+
+== MediaWiki 1.12.4 ==
 
+February 7, 2009
 
-== MediaWiki 1.12 ==
+A number of cross-site scripting (XSS) security vulnerabilities were discovered
+in the web-based installer (config/index.php). These vulnerabilities all
+require a live installer -- once the installer has been used to install a wiki,
+it is deactivated.
+
+Note that cross-site scripting vulnerabilities can be used to attack any
+website in the same cookie domain. So if you have an uninstalled copy of
+MediaWiki on the same site as an active web service, MediaWiki could be used to
+attack the active service.
+
+If you are hosting an old copy of MediaWiki that you have never installed, you
+are advised to remove it from the web.
+
+== MediaWiki 1.12.3 ==
+
+* Fixed packaging/distribution error. Many files were missing from the
+distributed tarball.
+
+== MediaWiki 1.12.2 ==
+
+David Remahl of Apple's Product Security team has identified a number of
+security issues in previous releases of MediaWiki. Subsequent analysis by the
+MediaWiki development team expanded the scope of these vulnerabilities. The
+issues with a significant impact are as follows:
+
+* A local script injection vulnerability affecting Internet Explorer clients
+for all MediaWiki installations with uploads enabled. [CVE-2008-5250]
+* A local script injection vulnerability affecting clients with SVG scripting
+capability (such as Firefox 1.5+), for all MediaWiki installations with SVG
+uploads enabled. [CVE-2008-5250]
+* A CSRF vulnerability affecting the Special:Import feature, for all MediaWiki
+installations since the feature was introduced in 1.3.0. [CVE-2008-5252]
+
+A local script injection vulnerability allows an attacker with a wiki account
+to steal another user's login session, and to act as that user on the wiki. The
+attacker uploads a malicious script file, and tricks the victim into executing
+it.
+
+CSRF vulnerabilities allow an attacker to act as an authorised user on the
+wiki, but unlike an XSS vulnerability, the attacker can only act as the user in
+a specific and restricted way. The present CSRF vulnerability allows pages to
+be edited, with forged revision histories. Like an XSS vulnerability, the
+authorised user must visit the malicious web page to activate the attack.
+
+These three vulnerabilities are all fixed in this release.
+
+David Remahl also reminded us of some security-related configuration issues:
+
+* By default, MediaWiki stores a backup of deleted images in the images/deleted
+directory. If you do not want these images to be publically accessible, make
+sure this directory is not accessible from the web. MediaWiki takes some steps
+to avoid leaking these images, but these measures are not perfect.
+* Set display_errors=off in your php.ini to avoid path disclosure via PHP fatal
+errors. This is the default on most shared web hosts.
+* Enabling MediaWiki's debugging features, such as $wgShowExceptionDetails, may
+lead to path disclosure.
+
+Other changes in this release:
+
+* Avoid fatal error in profileinfo.php when not configured.
+* Add a .htaccess to deleted images directory for additional protection against
+exposure of deleted files with known SHA-1 hashes on default installations.
+* Avoid streaming uploaded files to the user via index.php. This allows
+security-conscious users to serve uploaded files via a different domain, and
+thus client-side scripts executed from that domain cannot access the login
+cookies. Affects Special:Undelete, img_auth.php and thumb.php.
+* When streaming files via index.php, use the MIME type detected from the file
+extension, not from the data. This reduces the XSS attack surface.
+* Blacklist redirects via Special:Filepath. Such redirects exacerbate any XSS
+vulnerabilities involving uploads of files containing scripts.
+* Internationalisation updates.
+
+== MediaWiki 1.12.1 ==
+
+Changes since 1.12.0:
+* (bug [[bugzilla:13522|13522]]) Fix fatal error in Parser::extractTagsAndParams
+* (bug [[bugzilla:12077|12077]]) Fix HTML nesting for TOC
+* (bug [[bugzilla:13532|13532]]) Use proper timestamp call when reverting images
+* (bug [[bugzilla:13649|13649]], [[bugzilla:14084|14084]]) Bad call to
+wfTimestamp()
+* (bug [[bugzilla:13770|13770]]) Use Preprocessor_Hash by default to avoid
+missing DOM module errors
+* (bug [[bugzilla:13442|13442]]) API: Missing pages in prop=langlinks and
+prop=extlinks are now handled properly.
+* (bug [[bugzilla:13482|13482]]) API: Disabled search types handled properly
+* (bug [[bugzilla:13836|13836]]) API: Fixed fatal errors resulting from
+combining iiprop=metadata  with format=xml
+* (bug [[bugzilla:11633|11633]]) API: Explicitly convert redirect titles to
+strings due to PHP's very weak typing on array keys.
+* API: Fixing main page display in meta=siteinfo
+* (bug [[bugzilla:11719|11719]]) API: Remove trailing blanks in YAML output.
+* (bug [[bugzilla:13718|13718]]) API: Return the proper continue parameter for
+cmsort=timestamp
+* Security: Work around misconfiguration by requiring strict comparisons for
+in_array in User::isAllowed().
+* Security: Fixed XSS vulnerability in useskin parameter.
+
+== MediaWiki 1.12.0 ==
+
+This is the quarterly branch release of [[MediaWiki]] for Winter 2008.
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept "ready
+to run", and in fact runs our own sites on [[wikipedia:|Wikipedia]].
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature developments will be
+made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain it
+from source control: [[Download from SVN]].
+
+Changes since 1.12.0rc1:
+*(bug [[bugzilla:13359|13359]]) Double-escaping in [[Special:Allpages]].
+*Localization updates.
+
+== MediaWiki 1.12.0rc1 ==
+
+This is a release candidate of the Winter 2008 quarterly snapshot release of
+[[MediaWiki]].
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept "ready
+to run", and in fact runs our own sites on [[wikipedia:|Wikipedia]].
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature developments will be
+made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain it
+from source control: [[Download from SVN]].
 
 This is the Winter 2007 quarterly release.
 
@@ -12141,7 +12730,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 12857) Patrol link on new pages should clear floats
 * (bug 12968) Render redirect wikilinks in a redirect class for customization
   via user/site CSS.
-* EditPageBeforeEditButtons hook added for altering the edit buttons below the edit box
+* EditPageBeforeEditButtons hook added for altering the edit buttons below the
+  edit box
 
 === Bug fixes in 1.12 ===
 
@@ -12361,9 +12951,11 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * Fixing message cache updates for MediaWiki messages moves
 * (bug 12815) Signature timestamps were always in UTC, even if the timezone code
   in parentheses after them claimed otherwise
-* (bug 12732) Fix installer and searching to handle built-in tsearch2 for Postgres.
+* (bug 12732) Fix installer and searching to handle built-in tsearch2 for
+  Postgres.
 * (bug 12784) Change "bool" types to smallint to handle Postgres 8.3 strictness.
-* (bug 12301) Allow maintenance/findhooks.php to search hooks in multiple directories.
+* (bug 12301) Allow maintenance/findhooks.php to search hooks in multiple
+  directories.
 * (bug 7681, 11559) Cookie values no longer override GET and POST variables.
 * (bug 5262) Fully-qualified $wgStylePath no longer corrupted on XML feeds
 * (bug 3269) Inaccessible titles ending in '/.' or '/..' now forbidden.
@@ -12372,8 +12964,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 11567) Fix error checking for PEAR::Mail. UserMailer::send() now returns
   true-or-WikiError, which seems to be the calling convention expected by half
   its callers already
-* (bug 12846) IE rtl.css issue in RTL wikis special:Preferences when selecting an
-  LTR user language
+* (bug 12846) IE rtl.css issue in RTL wikis special:Preferences when selecting
+  an LTR user language
 * (bug 13005) DISPLAYTITLE does not work on preview
 * (bug 13004) Fix error on Postgres searches that return too many results.
 
@@ -12537,6 +13129,76 @@ Full API documentation is available at https://www.mediawiki.org/wiki/API
 
 == MediaWiki 1.11 ==
 
+== MediaWiki 1.11.2 ==
+
+March 2, 2008
+
+This is a security release of the Fall 2007 snapshot release of MediaWiki.
+Possible cross-site information leaks using the callback parameter for
+JSON-formatted results in the API are prevented by dropping user credentials.
+
+MediaWiki release versions prior to 1.11 are not vulnerable, as they do not
+include the callback feature which allows client-side JavaScript on other sites
+to reach API data.
+
+Changes in this release:
+
+* User credentials are dropped for API JSON requests using a callback
+* Edit tokens are not reported for API JSON requests using a callback
+
+== MediaWiki 1.11.1 ==
+
+January 23, 2008
+
+This is a security and bugfix release of the Fall 2007 snapshot release of
+ MediaWiki. A potential XSS injection vector affecting api.php only for
+ Microsoft Internet Explorer users has been closed.
+
+Changes in this release:
+* (bug [[bugzilla:11450|11450]]) Fix creation of objectcache table on upgrade
+* (bug [[bugzilla:11462|11462]]) Fix typo in LanguageGetSpecialPageAliases hook
+name
+* Fix regression in LinkBatch.php breaking PHP 5.0
+* Security fix for API on MSIE
+
+To work around the vulnerability without upgrading, you may disable the API if
+you don't need it:
+:[[Manual:$wgEnableAPI|$wgEnableAPI]] = false;
+
+Not vulnerable versions:
+* 1.12 or later
+* 1.11 >= 1.11.1
+* 1.10 >= 1.10.3
+* 1.9 >= 1.9.5
+* 1.8 any version (if $wgEnableAPI has been left off)
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.2
+* 1.9 <= 1.9.4
+* 1.8 any version (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include the API
+functionality, however the BotQuery extension is similarly vulnerable unless
+updated to the latest SVN version.
+
+== MediaWiki 1.11.0 ==
+
+September 10, 2007
+
+This is the Fall 2007 snapshot release of MediaWiki.
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept "ready
+to run", and in fact runs our own sites on Wikipedia.
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature developments will be
+made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain it
+from source control: [[Download from SVN]]
+
 This is the Summer 2007 branch release of MediaWiki.
 
 MediaWiki is now using a "continuous integration" development model with
@@ -12550,6 +13212,33 @@ will be made on the development trunk and appear in the next quarterly release.
 Those wishing to use the latest code instead of a branch release can obtain
 it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 
+== Changes since 1.11.0rc1 ==
+
+A possible HTML/XSS injection vector in the API pretty-printing mode has been
+found and fixed.
+
+The vulnerability may be worked around in an unfixed version by simply
+disabling the API interface if it is not in use, by adding this to
+[[Manual:LocalSettings.php|LocalSettings.php]]:<br />
+<code>[[Manual:$wgEnableAPI|$wgEnableAPI]] = false;</code> <br />
+(This is the default setting in 1.8.x.)
+
+Not vulnerable versions:
+* 1.11 >= 1.11.0
+* 1.10 >= 1.10.2
+* 1.9 >= 1.9.4
+* 1.8 >= 1.8.5
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.1
+* 1.9 <= 1.9.3
+* 1.8 <= 1.8.4 (if [[Manual:$wgEnableAPI|$wgEnableAPI]] has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include the faulty
+function, however the [[Extension:BotQuery|BotQuery extension]] is similarly
+vulnerable unless updated to the latest SVN version.
+
 == Configuration changes since 1.10 ==
 
 * $wgThumbUpright - Adjust width of upright images when parameter 'upright' is
@@ -12558,7 +13247,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
   usergroups
 * $wgEnotifImpersonal, $wgEnotifUseJobQ - Bulk mail options for large sites
 * $wgShowHostnames - Expose server host names through the API and HTML comments
-* $wgSaveDeletedFiles has been removed, the feature is now enabled unconditionally
+* $wgSaveDeletedFiles has been removed, the feature is now enabled
+unconditionally
 
 == New features since 1.10 ==
 
@@ -12679,8 +13369,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
   than good.  Proper handheld support will be added at a future date.  For now,
   display should be acceptable either with CSS turned off or when using a so-
   phisticated handheld browser.
-* (bug 3173) Option to offer exported pages as a download, rather than displaying
-  inline, as in most browsers
+* (bug 3173) Option to offer exported pages as a download, rather than
+  displaying inline, as in most browsers
 * Pass the user as an argument to 'isValidPassword' hook callbacks; see
   docs/hooks.txt for more information
 * Introduce 'UserGetRights' hook; see docs/hooks.txt for more information
@@ -12876,7 +13566,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 6965) Cannot include "Template:R" with {{R}} (magic word conflict)
 * Padding parser functions now work with strings like '0' that evaluate to false
 * (bug 10332) Title->userCan( 'edit' ) may return false positive
-* Fix bug with <nowiki> in front of links for wikis where linkPrefixExtension is true
+* Fix bug with <nowiki> in front of links for wikis where linkPrefixExtension is
+  true
 * (bug 10552) Suppress rollback link in history for single-revision pages
 * (bug 10538) Gracefully handle invalid input on move success page
 * Fix for Esperanto double-x-encoding in move success page
@@ -13006,8 +13697,9 @@ Full API documentation is available at https://www.mediawiki.org/wiki/API
 * (bug 10392) Include MediaWiki version details in version output
 * (bug 10411) Site language in meta=siteinfo
 * (bug 10391) action=help doesn't return help if format is fancy markup
-* backlinks, embeddedin and imageusage lists should use (bl|ei|iu)title parameter
-  instead of titles. Titles for these lists is obsolete and might stop working soon.
+* backlinks, embeddedin and imageusage lists should use (bl|ei|iu)title
+  parameter instead of titles. Titles for these lists is obsolete and might stop
+  working soon.
 * Added prop=imageinfo - gets image properties and upload history
 * (bug 10211) Added db server replication lag information in meta=siteinfo
 * Added external url search within wiki pages (list=exturlusage)
@@ -13015,9 +13707,12 @@ Full API documentation is available at https://www.mediawiki.org/wiki/API
 * Added registered users enumeration (list=allusers)
 * Added full text search in titles and content (list=search)
 * (bug 10684) Expanded list=allusers functionality
-* Possible breaking change: prop=revisions no longer includes pageid for rvprop=ids
-* Added rvprop=size to prop=revisions (The size will not be shown if it is NULL in the database)
-* list=allpages now allows to filter by article min/max size and protection status
+* Possible breaking change: prop=revisions no longer includes pageid for
+  rvprop=ids
+* Added rvprop=size to prop=revisions (The size will not be shown if it is NULL
+  in the database)
+* list=allpages now allows to filter by article min/max size and protection
+  status
 * Added site statistics (siprop=statistics for meta=siteinfo)
 * (bug 10902) Unable to fetch user contributions from IP addresses
 * `list=usercontribs` no longer requires that the user exist
@@ -13031,7 +13726,8 @@ Full API documentation is available at https://www.mediawiki.org/wiki/API
 * (bug 10898) API does not return an edit token for non-existent pages
 * (bug 10890) Timestamp support for categorymembers query
 * (bug 10980) Add exclude redirects on backlinks
-* IPv6 titles in User namespace are normalized (run cleanupTitles.php to fix any old stray pages)
+* IPv6 titles in User namespace are normalized (run cleanupTitles.php to fix any
+  old stray pages)
 
 == Maintenance script changes since 1.10 ==
 
@@ -13125,6 +13821,121 @@ Full API documentation is available at https://www.mediawiki.org/wiki/API
 
 == MediaWiki 1.10 ==
 
+== MediaWiki 1.10.4 ==
+
+March 2, 2008
+
+* Correction for API path fix, broken in 1.10.3
+
+== MediaWiki 1.10.3 ==
+
+January 23, 2008
+
+This is a security update to the Winter 2007 quarterly release. A potential
+XSS injection vector affecting api.php only for Microsoft Internet Explorer
+users has been closed.
+
+
+To work around the vulnerability without upgrading, you may disable the API if
+you don't need it:
+
+:[[Manual:$wgEnableAPI|$wgEnableAPI]] = false;
+
+Not vulnerable versions:
+* 1.12 or later
+* 1.11 >= 1.11.1
+* 1.10 >= 1.10.3
+* 1.9 >= 1.9.5
+* 1.8 any version (if $wgEnableAPI has been left off)
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.2
+* 1.9 <= 1.9.4
+* 1.8 any version (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include the API
+functionality, however the BotQuery extension is similarly vulnerable unless
+updated to the latest SVN version.
+
+== MediaWiki 1.10.2 ==
+September 10, 2007
+
+This is a security fix update to the Spring 2007 quarterly release snapshot. A
+possible HTML/XSS injection vector in the API pretty-printing mode has been
+found and fixed.
+
+The vulnerability may be worked around in an unfixed version by simply
+disabling the API interface if it is not in use, by adding this to
+LocalSettings.php:
+:[[Manual:$wgEnableAPI|$wgEnableAPI]] = false;
+
+Not vulnerable versions:
+* 1.11 >= 1.11.0
+* 1.10 >= 1.10.2
+* 1.9 >= 1.9.4
+* 1.8 >= 1.8.5
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.1
+* 1.9 <= 1.9.3
+* 1.8 <= 1.8.4 (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include the faulty
+function, however the BotQuery extension is similarly vulnerable unless updated
+to the latest SVN version.
+
+== MediaWiki 1.10.1 ==
+July 13, 2007
+
+This is a bugfix update to the Spring 2007 quarterly release snapshot. A number
+of fixes to improve compatibility with PostgreSQL, some versions of MySQL, and
+some PHP configurations are included.
+
+Changes since 1.10.0:
+
+* (bug [[bugzilla:9417|9417]]) Uploading new versions of images when using
+Postgres no longer  throws warnings.
+* (bug [[bugzilla:9908|9908]]) Using tsearch2 with Postgres 8.1 no longer gives
+an error.
+* (bug [[bugzilla:9973|9973]]) Changed size was shown in advanced recentchanges
+collapsible items with $wgRCShowChangedSized = false.
+* Fixed installation on MyISAM or old InnoDB with charset=utf8, was giving
+overlong key errors.
+* Fixed zero-padding issues with MySQL 5 binary schema
+* (bug [[bugzilla:9820|9820]]) session.save_path check no longer halts
+installation, but warns of possible bad values
+* (bug [[bugzilla:9978|9978]]) Fixed session.save_path validation when using
+extended configuration format, e.g. "5;/tmp"
+
+== MediaWiki 1.10.0 ==
+May 9, 2007
+
+This is the quarterly release snapshot for Spring 2007. See below for a full
+list of changes since the 1.9.x series.
+
+Changes since 1.10.0rc2:
+
+* (bug [[bugzilla:9808|9808]]) Fix regression that ignored user 'rclimit'
+option for Special:Contributions
+
+== MediaWiki 1.10.0rc2 ==
+May 4, 2007
+
+THIS IS A RELEASE CANDIDATE MADE AVAILABLE FOR TESTING!
+A FINAL 1.10.0 RELEASE WILL APPEAR WITHIN A FEW DAYS.
+
+Changes since 1.10.0rc1:
+* Various l10n fixes and updates
+* Fix for upgrade of page_restrictions table
+* (bug [[bugzilla:9780|9780]]) Fix normalization of titles with initial colon
+followed by whitespace
+* Fix for regression in upload: wrong size info saved into image table
+* Avoid cyclic stub problems when authorization hooks do funny things with the
+user and the database at load time
+
+== MediaWiki 1.10.0rc1 ==
 This is the Spring 2007 branch release of MediaWiki.
 
 MediaWiki is now using a "continuous integration" development model with
@@ -13140,14 +13951,14 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 
 == Configuration changes ==
 
-* A new switch $wgCommandLineDarkBg used by maintenance scripts (parserTests.php).
-  It lets you specify if your terminal use a dark background, the colorized
-  output will be made lighter making things easier to read.
+* A new switch $wgCommandLineDarkBg used by maintenance scripts
+  (parserTests.php). It lets you specify if your terminal use a dark background,
+  the colorized output will be made lighter making things easier to read.
 * The minimum permissions needed to edit a page in each namespace can now be
   customized via the $wgNamespaceProtection array. By default, editing pages in
   the MediaWiki namespace requires "editinterface" permission, as before.
-* Allow restriction of autoconfirmed permission by edit count. New global setting
-  $wgAutoConfirmCount (defaulting to zero, naturally).
+* Allow restriction of autoconfirmed permission by edit count. New global
+  setting $wgAutoConfirmCount (defaulting to zero, naturally).
 * Added rate limiter for Special:Emailuser
 * Private logs can now be created using $wgLogRestrictions
 * (Bug 8590) limited HTML is now always enabled ($wgUserHtml = true).
@@ -13214,7 +14025,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 6997) Link from Special:log/block to unblock form
 * (bug 9117) Link from Special:log/delete to undelete form
 * Link from Special:log/protect to change protection form
-* (bug 1196) Add IPv6 support added to blocks, more consistancy for IPv6 contribs
+* (bug 1196) Add IPv6 support added to blocks, more consistancy for IPv6
+  contribs
 * (bug 3984) Searching in logs by title%
 * Show thumbnail of existing image if image exists already under this filename
 * (bug 5546) Watchlist reflects logged actions like move, protection, undelete
@@ -13223,19 +14035,21 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * Warning on upload of images with uppercase extension if image with lowercase
   extension exists
 * (bug 4624) Namespace selection for Special:Whatlinkshere
-* Introduce PageHistoryBeforeList and PageHistoryLineEnding hooks; see docs/hooks.txt
-  for more information
-* (bug 9397) Introduce "sp-contributions-footer" and "sp-contributions-footer-anon"
-  messages, shown at the end of Special:Contributions as appropriate for the target
+* Introduce PageHistoryBeforeList and PageHistoryLineEnding hooks; see
+  docs/hooks.txt for more information
+* (bug 9397) Introduce "sp-contributions-footer" and
+  "sp-contributions-footer-anon" messages, shown at the end of
+  Special:Contributions as appropriate for the target
 * (bug 8421) Expose current action in JavaScript globals (as 'wgAction')
 * (bug 9069) Use galleries in query pages dedicated to images
-* (bug 9177) Installer now warns of various conditions affecting session.save_path
-  which can lead to broken session storage
+* (bug 9177) Installer now warns of various conditions affecting
+  session.save_path which can lead to broken session storage
 * (bug 9046) Special page to list pages without language links
 * (bug 9508) Special page to list articles with the fewest revisions
 * Introduce 'FileUpload' hook; see docs/hooks.txt for more information
 * Introduce 'SearchUpdate' hook; see docs/hooks.txt for more information
-* Introduce 'mywatchlist' message; used on personal menu to link to watchlist page
+* Introduce 'mywatchlist' message; used on personal menu to link to watchlist
+  page
 * Introduce magic word {{NUMBEROFEDITS}}
 * Introduced media handlers for file-type specific operations.
 * Improved error reporting for image thumbnailing
@@ -13244,7 +14058,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
   500 characters
 * Predefined block reasons added to Special:Blockip
 * (bug 9196) Installer now check that zend.ze1_compatibility_mode is off
-* (bug 9697) Introduce 'InternalParseBeforeLinks' hook; see docs/hooks.txt for more information
+* (bug 9697) Introduce 'InternalParseBeforeLinks' hook; see docs/hooks.txt for
+  more information
 * 'contribsub' message changed to 'contribsub2' with two parameters to permit
   better localization.  Change is reverse-compatible and can be ignored for
   most wikis.
@@ -13302,8 +14117,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * Ignore self closing on closing tags ( '</div />' now gives '</div>')
 * (bug 8673) Minor fix for web service API content-type header
 * Fix API revision list on PHP 5.2.1; bad reference assignment
-* (bug 8688) Handle underscores/spaces in Special:Blockip and Special:Ipblocklist
-  in a consistent manner
+* (bug 8688) Handle underscores/spaces in Special:Blockip and
+  Special:Ipblocklist in a consistent manner
 * (bug 8701) Check database lock status when blocking/unblocking users
 * ParserOptions and ParserOutput classes are now in their own files
 * (bug 8708) Namespace translations for Zealandic language
@@ -13506,8 +14321,8 @@ it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 8780) Clarify message for command-line scripts if LocalSettings.php
   exists but is not readable
 * dumpBackup / importDump now work with PostgreSQL
-* (bug 8975) Use "Maintenance script" as the default username for importImages.php
-  and importTextFile.php scripts
+* (bug 8975) Use "Maintenance script" as the default username for
+  importImages.php and importTextFile.php scripts
 * (bug 8933) Fix maintenance/reassignEdits.php script
 * (bug 9440) Added "mediawikiwiki" interwiki prefix to MediaWiki.org
 * (bug 2979) Import now gracefully skips invalid titles with a warning
@@ -13614,21 +14429,170 @@ break. Don't forget to always back up your database before upgrading!
 See the file UPGRADE for more detailed upgrade instructions.
 
 = MediaWiki release notes =
-
 Security reminder: MediaWiki does not require PHP's register_globals
 setting since version 1.2.0. If you have it on, turn it *off* if you can.
 
+= MediaWiki 1.9 =
 
-== Changes since 1.8 ==
+== MediaWiki 1.9.6 ==
 
-* (bug 8200) Make category lists sorted by name when using Postgres.
-* (bug 7841) Support 'IGNORE' inserts for Postgres, fixes watchlist
-  adding problem.
-* (bug 6835) Removing the includes/Parser.php::getTemplateArgs() function,
-  because it seems to be unused.
-* (bug 7139) Increasing the visual width of the edit summary field on larger
-  screen sizes, for the default monobook skin.
-* Fix PHP notice and estimates for dumpBackup.php and friends
+March 2, 2008
+
+* Correction for API path fix, broken in 1.9.5
+
+== MediaWiki 1.9.5 ==
+
+January 23, 2008
+
+This is a security update to the Winter 2007 quarterly release. A potential XSS
+injection vector affecting api.php only for Microsoft Internet Explorer users
+has been closed.
+
+
+To work around the vulnerability without upgrading, you may disable the API if
+you don't need it:
+
+:[[Manual:$wgEnableAPI|$wgEnableAPI]] = false;
+
+Not vulnerable versions:
+* 1.12 or later
+* 1.11 >= 1.11.1
+* 1.10 >= 1.10.3
+* 1.9 >= 1.9.5
+* 1.8 any version (if $wgEnableAPI has been left off)
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.2
+* 1.9 <= 1.9.4
+* 1.8 any version (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include the API
+functionality, however the BotQuery extension is similarly vulnerable unless
+updated to the latest SVN version.
+
+== MediaWiki 1.9.4 ==
+
+September 10, 2007
+
+This is a security and bug fix update to the Winter 2007 quarterly release.
+Minor compatibility fixes for IIS 5 are included.
+
+* (bug [[bugzilla:8847|8847]]) Strip spurious #fragments from request URI to
+fix redirect loops on some server configurations
+* A possible HTML/XSS injection vector in the API pretty-printing mode has been
+found and fixed.
+
+The vulnerability may be worked around in an unfixed version by simply
+disabling the API interface if it is not in use, by adding this to
+LocalSettings.php:
+
+:[[Manual:$wgEnableAPI|$wgEnableAPI]] = false;
+
+Not vulnerable versions:
+* 1.11 >= 1.11.0
+* 1.10 >= 1.10.2
+* 1.9 >= 1.9.4
+* 1.8 >= 1.8.5
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.1
+* 1.9 <= 1.9.3
+* 1.8 <= 1.8.4 (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include the faulty
+function, however the BotQuery extension is similarly vulnerable unless updated
+to the latest SVN version.
+
+== MediaWiki 1.9.3 ==
+
+February 20, 2007
+
+This is a security and bug-fix update to the Winter 2007 quarterly release.
+Minor compatibility fixes for IIS and PostgreSQL are included.
+
+An XSS injection vulnerability based on Microsoft Internet Explorer's UTF-7
+charset autodetection was located in the AJAX support module, affecting MSIE
+users on MediaWiki 1.6.x and up when the optional setting $wgUseAjax is enabled.
+
+If you are using an extension based on the optional Ajax module, either disable
+it or upgrade to a version containing the fix:
+
+* 1.9: fixed in 1.9.3
+* 1.8: fixed in 1.8.4
+* 1.7: fixed in 1.7.3
+* 1.6: fixed in 1.6.10
+
+There is no known danger in the default configuration, with ''$wgUseAjax'' off.
+
+* ([[mediazilla:8992|8992]]) Fix a remaining raw use of REQUEST_URI in history
+* ([[mediazilla:8984|8984]]) Fix a database error in
+Special:Recentchangeslinked when using the PostgreSQL database.
+* Add ''charset'' to Content-Type headers on various HTTP error responses to
+forestall additional UTF-7-autodetect XSS issues. PHP sends only ''text/html''
+by default when the script didn't specify more details, which some
+inconsiderate browsers consider a license to autodetect the deadly,
+hard-to-escape UTF-7. This fixes an issue with the Ajax interface error message
+on MSIE when ''$wgUseAjax'' is enabled (not default configuration); this UTF-7
+variant on a previously fixed attack vector was discovered by Moshe BA from
+BugSec: [http://www.bugsec.com/articles.php?Security=24
+http://www.bugsec.com/articles.php?Security=24]
+* Trackback responses now specify XML content type
+
+== MediaWiki 1.9.2 ==
+
+February 4, 2007
+
+This is a bug-fix update that fixes some installation and other minor issues
+with the 1.9.1 release as well as a security issue which was introduced in the
+1.9 branch.
+
+JavaScript code which regenerated the "sortable tables" feature did not
+properly sanitize input, leading to an HTML injection vulnerability.
+
+* ([[mediazilla:8774|8774]]) Fix path for GNU FDL rights icon on new installs
+* ([[mediazilla:8819|8819]]) Fix full path disclosure with skins dependencies
+* ([[mediazilla:8819|8819]]) Fixed data-loss bug in compressOld batch text
+compression affecting pages which had null edits (move, protect, etc) as second
+edit in a batch group. Isolated and patched by Travis Derouin.
+* Security fix for sortable tables JavaScript
+
+== MediaWiki 1.9.1 ==
+
+January 24, 2007
+
+This is a bug-fix update that fixes some installation and upgrade issues with
+the original 1.9.0 release.
+
+* ([[mediazilla:3000|3000]]) Fall back to SCRIPT_NAME plus QUERY_STRING when
+REQUEST_URI is not available, as on IIS with PHP-CGI
+* Security fix for DjVu images. (Only affects servers where .djvu file  uploads
+are enabled and ''$wgDjvuToXML'' is set.)
+* ([[mediazilla:8638|8638]]) Fix update from 1.4 and earlier
+* ([[mediazilla:8641|8641]]) Fix order of updates to ipblocks table for updates
+from <=1.7
+* ([[mediazilla:8673|8673]]) Minor fix for web service API content-type header
+* Fix API revision list on PHP 5.2.1; bad reference assignment
+* Fixed up the AjaxSearch
+* Exclude settings files when generating documentation. That could expose the
+database user and password to remote users.
+* ar: fix the 'create a new page' on search page when no exact match found
+* Correct tooltip accesskey hint for Opera on the Macintosh (uses Shift-Esc-,
+not Ctrl-).
+* ([[mediazilla:8719|8719]]) Firefox release notes lie! Fix tooltips for
+Firefox 2 on x11; accesskeys default settings appear to be same as Windows.
+
+== Changes since 1.8 ==
+
+* (bug 8200) Make category lists sorted by name when using Postgres.
+* (bug 7841) Support 'IGNORE' inserts for Postgres, fixes watchlist
+  adding problem.
+* (bug 6835) Removing the includes/Parser.php::getTemplateArgs() function,
+  because it seems to be unused.
+* (bug 7139) Increasing the visual width of the edit summary field on larger
+  screen sizes, for the default monobook skin.
+* Fix PHP notice and estimates for dumpBackup.php and friends
 * Improved register_globals paranoia checks
 * (bug 7545) Fix PHP version check on install
 * Disable PHP exception backtrace printing unless $wgShowExceptionDetails
@@ -13668,7 +14632,8 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * (bug 6427) Block blocked IPs from using the mail password function
   to allow blocking of flooders
 * Include common.css from classic-style skins in main HTML with the bump URL
-* (bug 7607) Add Karakalpak (kaa) to Names.php and stub message file for linktrail
+* (bug 7607) Add Karakalpak (kaa) to Names.php and stub message file for
+  linktrail
 * (bug 7582) Add 'tog-nolangconversion' to MessagesEn.php.
   This key is need for languages with variants (zh, sr, kk)
 * (bug 7606) MediaWiki messages for "rss" and "atom" missing
@@ -13697,7 +14662,7 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * (bug 7741) MATH: fixed broken syntax of underbrace etc. Fixed arrays
 * Fix purging for updated SVG files
 * (bug 7745) Add id attribute to search button in Monobook
-* (bug 7749) MATH: added some more LaTeX symbols, e.g. parallel, diamond, ast...
+* (bug 7749) MATH: added some more LaTeX symbols, e.g. parallel, diamond, ast...
 * (bug 7304) Added code in Article.php to keep redirect table up to date.
 * Made special page names case-insensitive and localisable. Care has been taken
   to maintain backwards compatibility.
@@ -13721,7 +14686,8 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * Remove entries from redirect table on article deletion
 * (bug 7788) Force section headers in new section links for users who have
   'prompt for blank edit summaries' on.
-* (bug 1133) Special:Emailuser: add an option to send yourself a copy of your mail.
+* (bug 1133) Special:Emailuser: add an option to send yourself a copy of your
+  mail.
 * (bug 461) Allow "Categories:" link at bottom of pages to be customized via
   pagecategorieslink message.
 * Sort the list of skins in "My Preferences" -> Skins by alphabetical order.
@@ -13734,7 +14700,8 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
   without the ipb_enable_autoblock option no longer show up as "autoblock
   disabled" on Special:Ipblocklist.
 * (bug 7774) MATH: aded more amstex functions
-* (bug 1182) MATH: fixed inconsistent rendering of upper case Greek letters in TeX
+* (bug 1182) MATH: fixed inconsistent rendering of upper case Greek letters in
+  TeX
 * Fix regression in streaming page dump generation
 * (bug 7801) Add support for parser function hooks in parser tests
 * checkUsernames.php now uses wfDebugLog instead of hardcoded path to log
@@ -13747,12 +14714,14 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * (bug 7826) Fix typos in two English messages.
 * (bug 5365) Stop users being prompted to enter an edit summary for null edits,
   if they have selected that option in preferences.
-* (bug 5936) Show an 'm' to the left of the edit summary on diff pages for minor edits.
+* (bug 5936) Show an 'm' to the left of the edit summary on diff pages for minor
+  edits.
 * (bug 7820) Improve error reporting for uploads via URL.
-* (bug 5149) When autoblocks are enabled, retroactively apply an autoblock to the most
-  recently used IP of a user when they are blocked.
-* Add an index on (rc_user_text,rc_timestamp) on the recentchanges table. This will
-  make CheckUser.php and the new retroactive autoblock functionality faster.
+* (bug 5149) When autoblocks are enabled, retroactively apply an autoblock to
+  the most recently used IP of a user when they are blocked.
+* Add an index on (rc_user_text,rc_timestamp) on the recentchanges table. This
+  will make CheckUser.php and the new retroactive autoblock functionality
+  faster.
 * Fix regression in Special:Undelete for revisions deleted under MediaWiki 1.4
   with compression or legacy encoding
 * (bug 6737) Fixes for MySQL 5 schema in strict mode
@@ -13772,13 +14741,15 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * Do a check for the PHP 5.0.x 64-bit bug, since this is much more disruptive
   as of MW 1.8 than it used to be. Install or upgrade now aborts with a
   warning and a request to upgrade.
-* (bug 6440) Updated indexes to improve backlinking queries (links, templates, images)
+* (bug 6440) Updated indexes to improve backlinking queries (links, templates,
+  images)
 * Switched 'anon-only' block mode to default for IP blocks
 * (bug 3687, 7892) Add distinct heading for media files in category display,
   with count.
 * (bug 1578) Add different icons for external links to audio, video, or PDF in
   Monobook.
-* Made autoblocks block account creation if the user block has that option enabled.
+* Made autoblocks block account creation if the user block has that option
+  enabled.
 * Add auto-summaries to blankings and large removals without summaries.
 * (bug 7811) Allow preview of edit summaries.
 * (bug 6839) Wikibits.js minor changes to make JS-lint happier.
@@ -13804,16 +14775,19 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * (bug 7554) The correct MIME type for SVG images is now displayed on the
   image page (image/svg+xml, not image/svg).
 * (bug 7883) Added autoblock whitelisting feature, using which specific ranges
-   can be protected from autoblocking. These ranges are specified, in list format,
-   in the autoblock_whitelist system message.
+   can be protected from autoblocking. These ranges are specified, in list
+  format, in the autoblock_whitelist system message.
 * Added placeholders for text injection by hooks to EditPage.php
-* (bug 8009) Automatic edit summary for redirects is not filled for edits in existing pages
+* (bug 8009) Automatic edit summary for redirects is not filled for edits in
+  existing pages
 * Installer support for experimental MySQL 4.1/5.0 binary-safe schema
 * Use INSERT IGNORE for db-based BagOStuff add/insert, for more memcache-like
   behavior when keys already exist on add (instead of dying with an error...)
 * Add a hook 'UploadForm:initial' before the upload form is generated, and two
-  member variable for text injection into the form, which can be filled by the hooks.
-* (bug 6295) Add a "revision patching" functionality, where an edit can be undone
+  member variable for text injection into the form, which can be filled by the
+  hooks.
+* (bug 6295) Add a "revision patching" functionality, where an edit can be
+  undone
   (with a functionality similar to diff rev1 rev2 | patch -R rev3 -o rev3).
   This is triggered by including &undo=revid in an edit URL. A link to a URL
   that will undo a given edit is shown on NEW revision headers on diff pages.
@@ -13850,12 +14824,14 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * Added a configuration variable allowing the "break out of framesets" feature
   to be switched on and off ($wgBreakFrames). Off by default.
 * Allow Xml::check() $attribs parameter to override 'value' attribute
-* DB schema change: added two columns (rc_old_len and rc_new_len) to the recentchanges table to store
-  the text lengths before and after the edit
-* (bug 1085) Made Special:Recentchanges show the character difference between the changed revisions
-* Removed a redundant <strong> tag from diff pages that was causing display issues for some users
-* (bug 8203) The keyboard shortcut for "log out" was removed, because users were pressing it
-  when they intended to press the shortcut for "preview".
+* DB schema change: added two columns (rc_old_len and rc_new_len) to the
+  recentchanges table to store the text lengths before and after the edit
+* (bug 1085) Made Special:Recentchanges show the character difference between
+  the changed revisions
+* Removed a redundant <strong> tag from diff pages that was causing display
+  issues for some users
+* (bug 8203) The keyboard shortcut for "log out" was removed, because users
+  were pressing it when they intended to press the shortcut for "preview".
 * (bug 8148) Handle non-removable output buffers gracefully when cleaning
   buffers for HTTP 304 responses, StreamFile, and Special:Export.
   Duplicated code merged into wfResetOutputBuffers() and wfClearOutputBuffers()
@@ -13985,8 +14961,8 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
   revisions
 * (bug 8214) Output file size limit and actual file size in appropriate units
   on Special:Upload
-* (bug 8016) Purge objectcache table during upgrade processes - use the --nopurge
-  option to prevent this when running maintenance/update.php
+* (bug 8016) Purge objectcache table during upgrade processes - use the
+  --nopurge option to prevent this when running maintenance/update.php
 * (bug 7612) Remove superfluous link to Special:Categories from result items
   on Special:Mostcategories
 * {{PLURAL:}} now handles formatted numbers correctly
@@ -14069,8 +15045,9 @@ setting since version 1.2.0. If you have it on, turn it *off* if you can.
 * (bug 8372) Return nothing on empty <math> tags.
 * New maintenance script to show the cached statistics : showStats.php.
 * Count deleted edits when regenerating total edits in maintenance/initStats.php
-* (bug 3706) Allow users to be exempted from IP blocks. The ipblock-exempt permission
-  key has been added to enable this behavior, by default assigned to sysops.
+* (bug 3706) Allow users to be exempted from IP blocks. The ipblock-exempt
+  permission key has been added to enable this behavior, by default assigned to
+  sysops.
 * (bug 7948) importDump.php now warn that Recentchanges need to be rebuild.
 * (bug 7667) allow XHTML namespaces customization
 * (bug 8531) Correct local name of Lingála (patch by Raymond)
@@ -14308,6 +15285,154 @@ MediaWiki's parser test suite can now be expanded with additional test
 files. Custom extensions can add their test files to this array, and
 they will be run along with the main tests by maintenance/parserTests.php
 
+= MediaWiki 1.8=
+
+== MediaWiki 1.8.5 ==
+
+September 10, 2007
+
+This is a security fix update to the Fall 2006 quarterly release snapshot. A
+possible HTML/XSS injection vector in the API pretty-printing mode has been
+found and fixed.
+
+The vulnerability may be worked around in an unfixed version by simply
+disabling the API interface if it is not in use, by adding this to
+LocalSettings.php:
+
+:[[Manual:$wgEnableAPI|$wgEnableAPI]] = false;
+
+(This is the default setting in 1.8.x.)
+
+Not vulnerable versions:
+* 1.11 >= 1.11.0
+* 1.10 >= 1.10.2
+* 1.9 >= 1.9.4
+* 1.8 >= 1.8.5
+
+Vulnerable versions:
+* 1.11 <= 1.11.0rc1
+* 1.10 <= 1.10.1
+* 1.9 <= 1.9.3
+* 1.8 <= 1.8.4 (if $wgEnableAPI has been switched on)
+
+MediaWiki 1.7 and below are not affected as they do not include the faulty
+function, however the BotQuery extension is similarly vulnerable unless updated
+to the latest SVN version.
+
+== MediaWiki 1.8.4 ==
+
+February 20, 2007
+
+This is a security and bug-fix update to the Fall 2006 quarterly release.
+
+An XSS injection vulnerability based on Microsoft Internet Explorer's UTF-7
+charset autodetection was located in the AJAX support module, affecting MSIE
+users on MediaWiki 1.6.x and up when the optional setting
+[[Manual:$wgUseAjax|$wgUseAjax]] is enabled.
+
+If you are using an extension based on the optional Ajax module, either disable
+it or upgrade to a version containing the fix:
+* 1.9: fixed in 1.9.3
+* 1.8: fixed in 1.8.4
+* 1.7: fixed in 1.7.3
+* 1.6: fixed in 1.6.10
+
+There is no known danger in the default configuration, with $wgUseAjax off.
+
+* (bug [[bugzilla:8819|8819]]) Fix full path disclosure with skins dependencies
+* Add 'charset' to Content-Type headers on various HTTP error responses to
+forestall additional UTF-7-autodetect XSS issues. PHP sends only 'text/html' by
+default when the script didn't specify more details, which some inconsiderate
+browsers consider a license to autodetect the deadly, hard-to-escape UTF-7.
+This fixes an issue with the Ajax interface error message on MSIE when
+[[Manual:$wgUseAjax|$wgUseAjax]] is enabled (not default configuration); this
+UTF-7 variant on a previously fixed attack vector was discovered by Moshe BA
+from BugSec: http://www.bugsec.com/articles.php?Security=24
+* Trackback responses now specify XML content type
+
+== MediaWiki 1.8.3 ==
+
+January 9, 2007
+
+MediaWiki 1.8.3 fixes several issues in the Fall 2006 snapshot release:
+
+* ([[mediazilla:7831|7831]]) Regression in AutoAuthenticate hook
+* Run PHP install version checks on update.php so command-line updaters see new
+version requirements
+* Do a check for the PHP 5.0.x 64-bit bug, since this is much more disruptive
+as of MW 1.8 than it used to be. Install or upgrade now aborts with a warning
+and a request to upgrade.
+* XSS fix in AJAX module
+
+An XSS injection vulnerability was located in the AJAX support module,
+affecting MediaWiki 1.6.x and up when the optional setting $wgUseAjax is
+enabled.
+
+There is no danger in the default configuration, with $wgUseAjax off.
+
+If you are using an extension based on the optional AJAX module, either disable
+it or upgrade to a version containing the fix:
+
+== MediaWiki 1.8.2 ==
+
+October 13, 2006
+
+MediaWiki 1.8.2 fixes several issues in the Fall 2006 snapshot release:
+
+* ([[mediazilla:7565|7565]]) Fixed typos in German localisation
+* ([[mediazilla:7562|7562]]) Fix non-ASCII namespaces on Windows/XAMPP servers
+
+== MediaWiki 1.8.1 ==
+
+October 11, 2006
+
+MediaWiki 1.8.1 fixes several issues in the Fall 2006 snapshot release:
+
+* Fix PHP notice and estimates for dumpBackup.php and friends
+* Improved register_globals paranoia checks
+* ([[mediazilla:7545|7545]]) Fix PHP version check on install
+* Experimental web API disabled by default
+* Disable PHP exception backtrace printing unless $wgShowExceptionDetails is
+set. Backtraces may contain sensitive information in function call parameters.
+
+== MediaWiki 1.8.0 ==
+
+October 10, 2006
+
+This is the quarterly release snapshot for Fall 2006. While the code has been
+running on Wikipedia for some time, installation and upgrade bits may be less
+well tested. Bug fix releases may follow in the coming days or weeks.
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept "ready
+to run", and in fact runs our own sites on Wikipedia.
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature development happen
+will be made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain it
+from source control: [[Download from SVN]]
+
+== Configuration changes ==
+* $wgUseETag, to enable/disable sending of HTTP ETag headers (default: disabled)
+* $wgLegalTitleChars now includes '+' by default for better compatibility with
+importing data dumps from Wikipedia
+* $wgDefaultUserOptions now includes all default option settings instead of
+only overrides.
+
+== Major new features ==
+* ([[mediazilla:7098|7098]]) Add an option to disable/enable sending of HTTP
+ETag headers, as it seems to result in broken behaviour in combination with
+Squid 2.6 (disabled by default).
+* ([[mediazilla:550|550]]) Allow blocks on anonymous users only.
+* ([[mediazilla:6420|6420]]) Render thumbnails for DJVU images, support
+multipage DJVU display on image pages. Added new 'page=' thumbnail option to
+select a page from a multipage djvu for thumbnail generation.
+* Full Postgres support is now enabled. It requires version 8.1 or better, and
+needs to have both plpgsql and tsearch2 already installed.
+* ([[mediazilla:6386|6386]]) fix grammatical errors in danish naming of talk
+namespaces.
 
 == Changes since 1.7 ==
 
@@ -14354,7 +15479,8 @@ they will be run along with the main tests by maintenance/parserTests.php
   (blocked mid-edit) and the page doesn't exist
 * Improve default value of "blockedtext"
 * (bug 6680) Added localisation for Dutch bookstore list (nl)
-* Renamed maintainace script redundanttrans.php to unusedMessages.php - clearer usage
+* Renamed maintainace script redundanttrans.php to unusedMessages.php - clearer
+  usage
 * Fix regression which allowed some blocked users to create additional accounts
 * (bug 6657) Fix Hungarian linktrail
 * (bug 6751) Fix preview of blanked section with edit on first preview option
@@ -14388,8 +15514,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Added "serialized" directory, for storing precompiled data in serialized form.
 * Fix regression in auto-set NS_PROJECT_TALK namespace
 * Fix regression in ordering of namespaces
-* (bug 6806, 6030) Added several global JS variables for article path, user name,
-  page title, etc.
+* (bug 6806, 6030) Added several global JS variables for article path, user
+  name, page title, etc.
 * hooks registered with addOnloadHook are now called at the one of the html body
   by all skins.
 * Split ajax aided search from core ajax framework. Use wgUseAjax to enable the
@@ -14402,12 +15528,15 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 6919) Add English alias magic words for Tatar (tt) language file.
 * (bug 6753) Fixed broken Kazakh linktrail (kk)
 * (bug 6700) Added Kazakh language variants to Names.php
-* (bug 6827) some i18n specific maintenance scripts fails after merge of localisation-work branch
-* Throwed an exception for the deprecated functions OutputPage::sysopRequired and
-  OutputPage::developerRequired - use OutputPage::permissionRequired instead.
-* Removed the deprecated functions User::isSysop, User::isBureaucrat and User::isDeveloper -
-  use User::isAllowed instead.
-* (bug 769) OutputPage::permissionRequired() should suggest groups with the needed permission
+* (bug 6827) some i18n specific maintenance scripts fails after merge of
+  localisation-work branch
+* Throwed an exception for the deprecated functions OutputPage::sysopRequired
+  and OutputPage::developerRequired - use OutputPage::permissionRequired
+  instead.
+* Removed the deprecated functions User::isSysop, User::isBureaucrat and
+  User::isDeveloper - use User::isAllowed instead.
+* (bug 769) OutputPage::permissionRequired() should suggest groups with the
+  needed permission
 * (bug 6971) Fix regression in Special:Export history view
 * Revamped Special:Imagelist
 * (bug 7000) updated MessagesPl.php
@@ -14429,8 +15558,10 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 7044) Introduce "padleft" and "padright" colon functions
 * Pass page title as parameters to "linkshere" and "nolinkshere" and update
   default message text
-* Allows to upload from publicy accessible URL. Set $wgAllowCopyUploads = true ; in LocalSettings.php
-  Limited to $wgMaxUploadSize (default:100MB); URL upload is limited to sysops by default, and displayed as a second line if appropriate
+* Allows to upload from publicy accessible URL. Set $wgAllowCopyUploads = true;
+  in LocalSettings.php
+  Limited to $wgMaxUploadSize (default:100MB); URL upload is limited to sysops
+  by default, and displayed as a second line if appropriate
 * (bug 832) Return to user page after emailing a user
 * (bug 366) Add local-system-timezone equivalents for date/time variables
 * (bug 7109) Fix Atom feed version number in header links
@@ -14440,17 +15571,18 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Fix bug in wfRunHooks which caused corruption of objects in the hook list
 * (bug 4979) Use simplified email addresses when running on Windows
 * (bug 4434) Show block log fragment on Special:Blockip
-* [[MediaWiki:Disambiguationspage]] may optionally contain wiki links to any number
-  of disambiguation templates.
-* [[Special:Disambiguations]] now shows pages in NS:0 that link to any pages that embed
-  any of the templates listed at [[MediaWiki:Disambiguationspage]].
+* [[MediaWiki:Disambiguationspage]] may optionally contain wiki links to any
+  number of disambiguation templates.
+* [[Special:Disambiguations]] now shows pages in NS:0 that link to any pages
+  that embed any of the templates listed at [[MediaWiki:Disambiguationspage]].
 * Fix formatting of titles on Special:Undelete
 * (bug 7026) Fix action=raw&templates=expand
 * (bug 6976) Add namespace and direction classes to classic skins
-* (bug 7144) Don't "return to main" from OutputPage::loginToUse() if the user can't
-  read the main page in the first place
+* (bug 7144) Don't "return to main" from OutputPage::loginToUse() if the user
+  can't read the main page in the first place
 * (bug 7188) Fix minor borkage in HTMLForm
-* (bug 6675) Replaced message 'watchthis' with new message 'watchthisupload in Special:Upload
+* (bug 6675) Replaced message 'watchthis' with new message 'watchthisupload in
+  Special:Upload
 * Add a quickie script dumpSisterSites.php for generating a page list in the
   format for WSR-1 SisterSites support
 * (bug 7223) Monobook.js is used for site content, should not be localized
@@ -14458,11 +15590,15 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Added Xml::option() for generating <option>s easily
 * Localized page numbers in drop-down for DjVu page selection
 * Fixed linktrail for vi
-* (bug 6893) "Call to a member function exists() on a non-object" on trackback.php with bad input
+* (bug 6893) "Call to a member function exists() on a non-object" on
+  trackback.php with bad input
 * (bug 6886) PHP undefined offset on bad input to Special:Revisiondelete
-* (bug 6887) PHP error for call to getId() on bad input to Special:Revisiondelete
-* (bug 6888) PHP error for call to getTimestamp() on bad input to Special:Revisiondelete
-* (bug 7252) Use dvipng support in texvc math rastrization. dvipng is required if texvc is rebuilt.
+* (bug 6887) PHP error for call to getId() on bad input to
+  Special:Revisiondelete
+* (bug 6888) PHP error for call to getTimestamp() on bad input to
+  Special:Revisiondelete
+* (bug 7252) Use dvipng support in texvc math rastrization. dvipng is required
+  if texvc is rebuilt.
 * (bug 7279) Use wfBaseName in place of basename() in more places
 * Clear newtalk marker on diff links with explicit current revision number
 * (bug 7064) Replace hard-coded empty message checks with wfEmptyMsg calls
@@ -14477,7 +15613,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Set Vary: Cookie on action=raw generated CSS and JS, to ensure that user
   preferences don't get stuck in proxy caches for other people
 * (bug 7324) Fix error message for failure of Database::sourceFile()
-* (bug 7309) Plurals: use singular form for zero in French and Brazilian Portuguese
+* (bug 7309) Plurals: use singular form for zero in French and Brazilian
+  Portuguese
 * Add page_no_title_convert field to support language variant conversion
   for page titles which shouldn't be converted on display/linking
 * Lazy extraction of text chunks in Revision objects, may reduce hits to
@@ -14486,16 +15623,19 @@ they will be run along with the main tests by maintenance/parserTests.php
   in $wgMemc, to further reduce hits to external storage.
   Set to 0 (disabled) by default.
 * Minor changes to the installer.
-* Remove ":" for 'youremail' and 'yourrealname' in includes/templates/Userlogin.php
-  so that ":" could be used in i18n for Special:Preferences (like 'username' and 'uid').
-* Fix layout for Special:Preferences->Date and Time (position for 'timezonetext').
+* Remove ":" for 'youremail' and 'yourrealname' in
+  includes/templates/Userlogin.php so that ":" could be used in i18n for
+  Special:Preferences (like 'username' and 'uid').
+* Fix layout for Special:Preferences->Date and Time (position for
+  'timezonetext').
 * Updates to language variant code for Serbian et al
 * (bug 6756) Enabling RTL direction for kk-cn
 * (bug 6701) Kazakh language variants in MessagesEn.php
 * (bug 7335) SVN revision check in Special:Version fails on SVN 1.4 working copy
-* (bug 6518) Replaced 'lastmodified' with 'lastmodifiedat' and 'lastmodifiedby' with 'lastmodifiedatby'
-  with separated parameters for date and time to allow better localisation. Updated all message files
-  to display the old format for compatibility.
+* (bug 6518) Replaced 'lastmodified' with 'lastmodifiedat' and 'lastmodifiedby'
+  with 'lastmodifiedatby' with separated parameters for date and time to allow
+  better localisation. Updated all message files to display the old format for
+  compatibility.
 * (bug 7357) Make supposedly static methods of Skin actually static
 * Added info text to Special:Deadendpages and Special:Lonelypages
 * Fix regression in cachability of generated CSS and JS for MonoBook skin,
@@ -14503,21 +15643,22 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 6849) Block @ from usernames; interferes with multi-database tools and
   was meant to be banned years ago... For now existing accounts will not be
   prevented fromm login.
-* (bug 6092) Introduce magic words {{REVISIONDAY}}, {{REVISIONDAY2}, {{REVISIONMONTH}},
-  {{REVISIONYEAR}} and {{REVISIONTIMESTAMP}}
+* (bug 6092) Introduce magic words {{REVISIONDAY}}, {{REVISIONDAY2},
+  {{REVISIONMONTH}}, {{REVISIONYEAR}} and {{REVISIONTIMESTAMP}}
 * (bug 7425) Preceeding whitespace in [[...]] breaks subpages
 * Try to reconnect after transitory database errors in dumpTextPass.php
-* (bug 6023) Fixed mismatch of 0/NULL for wl_notificationtimestamp; now notification
-  mails are working after 'Mark all pages visited' button on Special:Watchlist is clicked
+* (bug 6023) Fixed mismatch of 0/NULL for wl_notificationtimestamp; now
+  notification mails are working after 'Mark all pages visited' button on
+  Special:Watchlist is clicked
 * Made {{INT:}} a core parser function instead of a special case. The syntax
   and behavior is largely unchanged.
 * (bug 7448) Fixing the native name for Ewe (ee)
-* (bug 6864) Replace message 'editing' with new message 'editinguser' in Special:Userrights
-  to allow better localisation
-* Add '*-summary' for special pages to MessagesEn.php to allow customizing/translation
-  directly through Special:Allmessages
-* (bug 6130, bug 5818) Replaced message 'go'  with the new message 'searcharticle' in skins
-  to allow better localisation
+* (bug 6864) Replace message 'editing' with new message 'editinguser' in
+  Special:Userrights to allow better localisation
+* Add '*-summary' for special pages to MessagesEn.php to allow
+  customizing/translation directly through Special:Allmessages
+* (bug 6130, bug 5818) Replaced message 'go'  with the new message
+  'searcharticle' in skins to allow better localisation
 * Add + to $wgLegalTitleChars by default. Some sites may have occasional
   problems with hard-to-reach pages, but it should be less trouble than
   "I can't import dumps from Wikipedia" complaints
@@ -14550,14 +15691,184 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 7520) Update article counts on XML import
 * (bug 7526) Make $wgDefaultUserOptions work again
 * (bug 7472) Localize Help namespace for Basque
-* (bug 7529) Including a non-existent category in an article places that article in the category
+* (bug 7529) Including a non-existent category in an article places that article
+  in the category
 * (bug 4528) Lack of important LaTeX functions stackrel, rightleftharpoon
-* (bug 6721) missing symbols ulcorner, urcorner, llcorner, lrcorner, twoheadrightarrow, twoheadleftarrow
-* (bug 7367) Hyphens sometimes erroneously appended to equations when not converted to PNG
-* Add "title" to the opensearch link to allow automatic adding of the search engine in Firefox 2
+* (bug 6721) missing symbols ulcorner, urcorner, llcorner, lrcorner,
+  twoheadrightarrow, twoheadleftarrow
+* (bug 7367) Hyphens sometimes erroneously appended to equations when not
+  converted to PNG
+* Add "title" to the opensearch link to allow automatic adding of the search
+  engine in Firefox 2
 * (bug 7537) Add php5 to $wgFileBlacklist
 * (bug 6929) Restore AutoAuthenticate hook
 
+== Languages updated ==
+* Albanian (sq)
+* Bashkir (ba)
+* Bavarian (bar) stub file
+* Belarusian (be)
+* Bishnupriya (bpy) stub file
+* Brazilian Portuguese (pt-br)
+* Cantonese (zh-yue)
+* Catalan (ca)
+* Czech (cs)
+* Dutch (nl)
+* English (en)
+* Finnish (fi)
+* French (fr)
+* Georgian (ka)
+* German (de)
+* Hebrew (he)
+* Hungarian (hu)
+* Indonesian (id)
+* Japanese (ja)
+* Korean (ko)
+* Latin (la)
+* Lojban (jbo)
+* Macedonian (mk)
+* Mazandarani (mzn)
+* Polish (pl)
+* Portuguese (pt)
+* Ripuarian (ksh)
+* Romani (rmy)
+* Russian (ru)
+* Slovak (sk)
+* Spanish (es)
+* Tajic (tg)
+* Tatar (tt)
+* Telugu (te)
+* Uzbek (uz)
+* Yiddish (yi)
+
+== Compatibility ==
+MediaWiki 1.8 requires PHP 5 (5.1 recommended). PHP 4 is no longer supported.
+
+MySQL 3.23.x is no longer supported; some older hosts may need to upgrade. At
+this time we still recommend 4.0, but 4.1/5.0 will work fine in most cases.
+
+== Upgrading ==
+Some minor database changes have been made since 1.7:
+* new fields and indexes on ipblocks
+* index change on recentchanges
+
+Several changes from 1.5 and 1.6 do require updates to be run on upgrade. To
+ensure that these tables are filled with data, run refreshLinks.php after the
+upgrade.
+
+If you are upgrading from MediaWiki 1.4.x or earlier, some major database
+changes are made, and there is a slightly higher chance that things could
+break. Don't forget to always back up your database before upgrading!
+
+=== Caveats ===
+Some output, particularly involving user-supplied inline HTML, may not produce
+100% valid or well-formed XHTML output. Testers are welcome to set $wgMimeType
+= "application/xhtml+xml"; to test for remaining problem cases, but this is not
+recommended on live sites. (This must be set for MathML to display properly in
+Mozilla.)
+
+= MediaWiki 1.7=
+
+== MediaWiki 1.7.3 ==
+
+February 20, 2007
+
+This is a security and bug-fix update to the Summer 2006 quarterly release.
+
+An XSS injection vulnerability based on Microsoft Internet Explorer's UTF-7
+charset autodetection was located in the AJAX support module, affecting MSIE
+users on MediaWiki 1.6.x and up when the optional setting
+[[Manual:$wgUseAjax|$wgUseAjax]] is enabled.
+
+If you are using an extension based on the optional Ajax module, either disable
+it or upgrade to a version containing the fix:
+
+* 1.9: fixed in 1.9.3
+* 1.8: fixed in 1.8.4
+* 1.7: fixed in 1.7.3
+* 1.6: fixed in 1.6.10
+
+There is no known danger in the default configuration, with
+[[Manual:$wgUseAjax|$wgUseAjax]] off.
+
+* Add 'charset' to Content-Type headers on various HTTP error responses to
+forestall additional UTF-7-autodetect XSS issues. PHP sends only 'text/html' by
+default when the script didn't specify more details, which some inconsiderate
+browsers consider a license to autodetect the deadly, hard-to-escape UTF-7.
+This fixes an issue with the Ajax interface error message on MSIE when
+[[Manual:$wgUseAjax|$wgUseAjax]] is enabled (not default configuration); this
+UTF-7 variant on a previously fixed attack vector was discovered by Moshe BA
+from BugSec: http://www.bugsec.com/articles.php?Security=24
+* Trackback responses now specify XML content type
+
+== MediaWiki 1.7.2 ==
+
+January 9, 2007
+
+* Note about $wgUploadSizeWarning using byte
+* Update to German bookstore list (de)
+* (bug [[bugzilla:6680|6680]]) Added localisation for Dutch bookstore list (nl)
+* (bug [[bugzilla:6708|6708]]) Minor updates to Russian translation (ru)
+* (bug [[bugzilla:6730|6730]]) Clearer usage of message 'titlematch' in German
+translation (de)
+* Added direction mark to Special:Listredirects
+* XSS fix in AJAX module
+
+An XSS injection vulnerability was located in the AJAX support module,
+affecting MediaWiki 1.6.x and up when the optional setting
+[[Manual:$wgUseAjax|$wgUseAjax]] is enabled.
+
+There is no danger in the default configuration, with
+[[Manual:$wgUseAjax|$wgUseAjax]] off.
+
+If you are using an extension based on the optional AJAX module, either disable
+it or upgrade to a version containing the fix:
+
+* 1.9: fixed in 1.9.0rc2
+* 1.8: fixed in 1.8.3
+* 1.7: fixed in 1.7.2
+* 1.6: fixed in 1.6.9
+
+
+== MediaWiki 1.7.1 ==
+
+July 8, 2006
+
+MediaWiki 1.7.1 is a security and bugfix maintenance release of the Summer 2006
+snapshot:
+
+A potential HTML/JavaScript-injection vulnerability in a debugging script has
+been fixed. Only versions and configurations of PHP vulnerable to the $GLOBALS
+overwrite vulnerability are affected.
+
+As a workaround for existing installs, profileinfo.php may simply be deleted if
+it's not being used.
+
+* Fix for 'emailconfirmed' implicit user group
+* Fix for upgrades on some versions of MySQL 4.0.x
+* Fixed potential XSS in profileinfo.php
+* Installer now shows clear error message about old PHP versions rather than a
+confusing parse error
+
+== MediaWiki 1.7.0 ==
+July 6, 2006
+
+This is the quarterly release snapshot for Summer 2006. While the code
+has been running on Wikipedia for some time, installation and upgrade
+bits may be less well tested. Bug fix releases may follow in the coming
+days or weeks.
+
+MediaWiki is now using a "[[w:en:Continuous_integration|continuous
+integration]]" development model with
+quarterly snapshot releases. The latest development code is always kept
+"ready to run", and in fact runs our own sites on Wikipedia.
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature development happen
+will be made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain
+it from source control: [[Download from SVN]]
 
 == Changes since 1.6 ==
 
@@ -14713,18 +16024,21 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 5593) Change "bureaucrat log" to "rights log"
 * Show a boilerplate "(none)" in place of a blank within the log action text for
   user rights
-* (bug 137) Commented out translations for copyrightwarning which mention GNU FDL
-* (bug 5723) Don't count pages linked to from the MediaWiki namespace as "wanted"
+* (bug 137) Commented out translations for copyrightwarning which mention GNU
+  FDL
+* (bug 5723) Don't count pages linked to from the MediaWiki namespace as
+  "wanted"
 * (bug 5696) Add a third parameter, $3, to "rcnote", passing the current time
   formatted according to the current user's settings
 * (bug 5780) Thousands and decimal separators for Norwegian
 * Updated initStats maintenance script
 * (bug 5767) Fix date formats in Vietnamese locale
 * (bug 361) URL in URL, they were almost fixed. Now they are.
-* (bug 4876) Add __NEWSECTIONLINK__ magic word to force the "new section" link/tab to
-  show up on specific pages on demand
+* (bug 4876) Add __NEWSECTIONLINK__ magic word to force the "new section"
+  link/tab to show up on specific pages on demand
 * Bidi-aid on list pages
-* (bug 5782) Allow entries in the bad image list to use canonical namespace names
+* (bug 5782) Allow entries in the bad image list to use canonical namespace
+  names
 * (bug 5789) Treat "loginreqpagetext" as wikitext
 * Sanitizer: now handles nested <li> in <ul> or <ol>
 * (bug 5796) We require MySQL >=4.0.14
@@ -14735,9 +16049,10 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Clean up Special:Listusers; add an "(all)" label to the group selection box
 * (bug 5812) Use appropriate link colour in Special:Mostlinked
 * (bug 5802) {{CURRENTMONTHNAME}} variable broken in Vietnamese locale
-* (bug 5817) Appropriate handling for Special:Recentchangeslinked where the target
-  page doesn't exist
-* Special:Randompage now additionally accepts English namespace name as parameter
+* (bug 5817) Appropriate handling for Special:Recentchangeslinked where the
+  target page doesn't exist
+* Special:Randompage now additionally accepts English namespace name as
+  parameter
 * (bug 2981) Really fixed linktrail for Tamil (ta)
 * Disallow substituting Special pages when included into a page
 * (bug 5587) Clean up the languages from references to the Groups special page
@@ -14745,10 +16060,12 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Rewritten removeUnusedAccounts to be more efficient, print names of inactive
   accounts
 * Redirect Special:Userlist to Special:Listusers
-* Introduce $wgAllowTitlesInSVG, which allows the <title> attribute in uploaded files
-  bearing the image/svg MIME type. Disabled by default due to the vast majority of
-  web servers being hideously misconfigured. See DefaultSettings.php for more details.
-* Changed default LocalSettings.php to append the previous include path when setting it
+* Introduce $wgAllowTitlesInSVG, which allows the <title> attribute in uploaded
+  files bearing the image/svg MIME type. Disabled by default due to the vast
+  majority of web servers being hideously misconfigured. See DefaultSettings.php
+  for more details.
+* Changed default LocalSettings.php to append the previous include path when
+  setting it
 * (bug 5837) Use "members" for the value descriptor in Special:Categories,
   Special:Wantedcategories and Special:Mostlinkedcategories.
 * (bug 3309) Allow comments when undeleting pages
@@ -14757,7 +16074,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Clean up Special:Imagelist a bit
 * (bug 5838) Namespace names for Nds-NL
 * (bug 5749) Added Tyvan language files
-* (bug 5791) Fix SQL syntax in Special:BrokenRedirects, was causing incorrect data to show
+* (bug 5791) Fix SQL syntax in Special:BrokenRedirects, was causing incorrect
+  data to show
 * (bug 5839) Prevent access to Special:Confirmemail for logged-out users
 * (bug 5853) Update for Portuguese messages (pt)
 * (bug 5851) Use Cyrillic for Kirghiz language name
@@ -14796,7 +16114,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Ignore the user and user talk namespaces on Special:Wantedpages
 * Introduce NUMBEROFPAGES magic word
 * (bug 5833) Introduce CURRENTVERSION magic word
-* (bug 5370) Allow throttling of password reminder requests with the rate limiter
+* (bug 5370) Allow throttling of password reminder requests with the rate
+  limiter
 * (bug 5683) Respect parser output marked as uncacheable when saving
 * (bug 5918) Links autonumbering now work for all defined protocols
 * (bug 5935) Improvement to German localisation (de)
@@ -14820,22 +16139,24 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 5849) Remove some hard-coded references to "Wikipedia" in messages
 * (bug 5967) Improvement to German localisation (de)
 * (bug 5962) Update for Italian language (it)
-* Suppress images in galleries which appear on the bad image list (when rendering
-  for a wiki page; galleries in special pages and categories are unaffected)
+* Suppress images in galleries which appear on the bad image list (when
+  rendering for a wiki page; galleries in special pages and categories are
+  unaffected)
 * Maintenance script to remove orphaned revisions from the database
 * (bug 5991) Update for Russian language (ru)
-* (bug 6001) PAGENAMEE and FULLPAGENAMEE don't work in FULLURL and LOCALURL magic
-  words
+* (bug 6001) PAGENAMEE and FULLPAGENAMEE don't work in FULLURL and LOCALURL
+  magic words
 * (bug 5958) Switch Uzbek language name to use latin script
 * (bug 839) Add URLENCODE magic word
 * (bug 6004) Update for Polish language (pl)
 * (bug 5971) Improvement to German localisation (de)
-* (bug 4873) Don't overwrite the subtitle navigation when viewing a redirect page
-  that isn't current
+* (bug 4873) Don't overwrite the subtitle navigation when viewing a redirect
+  page that isn't current
 * (bug 2203) Namespace updates for Thai
-* Fix breakage in parser test suite which caused incorrect reporting of the failure of
-  {{NUMBEROFFILES}}. Now initialises the site_stats table with some dumb data. Updated
-  the expected output for {{NUMBEROFARTICLES}} to reflect this.
+* Fix breakage in parser test suite which caused incorrect reporting of the
+  failure of {{NUMBEROFFILES}}. Now initialises the site_stats table with some
+  dumb data. Updated the expected output for {{NUMBEROFARTICLES}} to reflect
+  this.
 * (bug 6009) Use {{ns:project}} in messages where appropriate
 * (bug 6012) Update to Indonesian localisation (id)
 * (bug 6017) Update list of bookstores in German localisation files
@@ -14850,13 +16171,14 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 6039) Update for Portuguese localisation (pt)
 * (bug 764) Add CREATE TEMPORARY TABLES to default database permissions
 * Big update to Swedish localisation (sv)
-* Use appropriate HTML functions to create the tool links on image pages, so they don't
-  look garbled when tidy isn't on
+* Use appropriate HTML functions to create the tool links on image pages, so
+  they don't look garbled when tidy isn't on
 * (bug 5511) Fix URL-encoding of usernames in links on Special:Ipblocklist
 * (bug 6046) Update to Indonesian localisation (id) #15
 * (bug 5523) $wgNoFollowNsExceptions to allow disabling rel="nofollow" in
   specially-selected namespaces.
-* (bug 6055) Fix for HTML/JS injection bug in variable handler (found by Nick Jenkins)
+* (bug 6055) Fix for HTML/JS injection bug in variable handler (found by Nick
+  Jenkins)
 * Reordered wiki table handling and __TOC__ extraction in the parser to better
   handle some overlapping tag cases.
 * Only the first __TOC__ is now turned into a TOC
@@ -14907,7 +16229,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 1017) fixed thumbnails of animated gifs.
 * Add APC as object caching option
 * Update to Albanian localization (sq)
-* (bug 6099) Introduce {{DIRECTIONMARK}} magic word (with {{DIRMARK}} as an alias)
+* (bug 6099) Introduce {{DIRECTIONMARK}} magic word (with {{DIRMARK}} as an
+  alias)
 * Use optimized php5-only microtime()
 * Add possibility to store local message cache as PHP executable script
 * Fix profiling table definition
@@ -15001,8 +16324,9 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 5945) Introduce {{CONTENTLANGUAGE}} magic word
 * {{PLURAL}} can now take up to five forms
 * (bug 6243) Fix email for usernames containing dots when using PEAR::Mail
-* Remove a number of needless {{ns:project}}-type transforms from messages files. These
-  usages already have separate label text. Such transforms are wasteful on each page view.
+* Remove a number of needless {{ns:project}}-type transforms from messages
+  files. These usages already have separate label text. Such transforms are
+  wasteful on each page view.
 * Update to Yiddish localization (yi)
 * (bug 6254) Update to Indonesian translation (id) #20
 * (bug 6255) Fix transclusions starting with "#" or "*" in HTML attributes
@@ -15015,13 +16339,15 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Avoid some notices in page history with bad input
 * Use double quoted consistently on attributes in linker output; preparing
   for new normalization code when tidy not in use
-* Replace "nogomatch" with "noexactmatch" and place the magic colon in the messages
-  themselves. Some minor tweaks to the actual message content.
-* Introduce $wgContentNamespaces which allows for articles to exist in namespaces other
-  than the main namespace, and still be counted as valid content in the site statistics.
+* Replace "nogomatch" with "noexactmatch" and place the magic colon in the
+  messages themselves. Some minor tweaks to the actual message content.
+* Introduce $wgContentNamespaces which allows for articles to exist in
+  namespaces other than the main namespace, and still be counted as valid
+  content in the site statistics.
 * (bug 5932) Introduce {{PAGESINNAMESPACE}} magic word
 * Disable $wgAllowExternalImages by default.
-* (bug 2700) Nice things like link completion and signatures now work in <gallery> tags.
+* (bug 2700) Nice things like link completion and signatures now work in
+  <gallery> tags.
 * Cancel output buffering in StreamFile; when used inside gzip buffering this
   could cause funny timeout behavior as the Content-Length was wrong.
 * Return correct content-type header with 304 responses for StreamFile;
@@ -15056,7 +16382,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 6345) Update to Indonesian localisation (id) #22
 * (bug 6279) Add genitive month names to Slovenian localisation
 * (bug 6351) Update to German translation (de)
-* Respect language directionality when displaying arrow in Special:Brokenredirects
+* Respect language directionality when displaying arrow in
+  Special:Brokenredirects
 * Remove unused "validation" table definitions from the schema files
 * (bug 6398) Work around apparent PCRE bug breaking section editing when
   massively-indented preformatted text immediately followed a header
@@ -15080,12 +16407,14 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 6423) Don't update newtalk flag if page content didn't change (null edits
   were causing the newtalk flag to trigger inappropriately)
 * Parser functions are now set using magic words.
-* (bug 6428) Incorrect form action URL on Special:Newimages with hidebots = 0 set
-* (bug 4990) Show page source to blocked users on edits, or their modified version
-  if blocked during an edit
+* (bug 6428) Incorrect form action URL on Special:Newimages with hidebots = 0
+  set
+* (bug 4990) Show page source to blocked users on edits, or their modified
+  version if blocked during an edit
 * (bug 5903) When requesting the raw source of a non-existent message page,
   return blank content (as opposed to the message key)
-* Improve default blank content of MediaWiki:Common.css and MediaWiki:Monobook.css
+* Improve default blank content of MediaWiki:Common.css and
+  MediaWiki:Monobook.css
 * (bug 6434) Allow customisation of submit button text on Special:Export
 * (bug 6314) Add user tool links on page histories
 * Fix display of file-type icons in galleries when $wgIgnoreImageErrors is off
@@ -15094,8 +16423,8 @@ they will be run along with the main tests by maintenance/parserTests.php
   localizble extensions magic words.
 * Update to Romanian translation (ro)
 * Update to Esperanto translation (eo)
-* Check for preg_match() existence when installing and die out whining about PCRE
-  if it's not there, instead of throwing a fatal error
+* Check for preg_match() existence when installing and die out whining about
+  PCRE if it's not there, instead of throwing a fatal error
 * (bug 672) Add MathAfterTexvc hook
 * Update to Piedmontese localization (pms)
 * dumpBackup can optionally compress via dbzip2
@@ -15112,7 +16441,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Fix transwiki import of pages with space in name
 * Save null edit when importing pages through Special:Import
 * Update to Korean translation (ko)
-* Show a more specific message when an anonymous user tries to access Special:Watchlist
+* Show a more specific message when an anonymous user tries to access
+  Special:Watchlist
 * (bug 3278) Paging links in Special:Prefixindex
 * Added Latvian localization (lv)
 * (bug 6472) Fix regression in Special:Export with multiple pages
@@ -15123,9 +16453,11 @@ they will be run along with the main tests by maintenance/parserTests.php
 * Show some error results in moveBatch.php
 * (bug 6479) Allow specification of the skin to use during HTML dumps
 * (bug 6461) Link to page histories in Special:Newpages
-* (bug 6484) Don't do message transformations when preloading messages for editing
+* (bug 6484) Don't do message transformations when preloading messages for
+  editing
 * (bug 6201) Treat spaces as underscores in parameters to {{ns:}}
-* (bug 6006) Allow hiding the password change fields using an authentication plugin
+* (bug 6006) Allow hiding the password change fields using an authentication
+  plugin
 * (bug 6489) Use appropriate link colour on Special:Shortpages
 * Added formatnum magic word
 * Added Javanese localization (jv)
@@ -15148,7 +16480,8 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 6506) Update to German localisation (de)
 * (bug 502) Avoid silly tabs on bad title by using virtual special page
 * (bug 6511) Add diff links to old revision navigation bar
-* (bug 6511) Replace 'oldrevisionnavigation' message with 'old-revision-navigation'
+* (bug 6511) Replace 'oldrevisionnavigation' message with
+  'old-revision-navigation'
 * Fix regression in Polish genitive month forms
 * (bug 4037) Make input handling in Special:Allpages and Special:Prefixindex
   more consistent: Accept just a namespace prefix and a colon, reject input
@@ -15178,10 +16511,416 @@ they will be run along with the main tests by maintenance/parserTests.php
 * (bug 6560) Avoid PHP notice when trimming ISBN whitespace
 * Added namespace translation to Kannada (ka)
 * (bug 6566) Improve input validation on timestamp conversion
-* Implicit group "emailconfirmed" for all users whose email addresses are confirmed
+* Implicit group "emailconfirmed" for all users whose email addresses are
+  confirmed
 * (bug 6577) Avoid multiline parser breakage on <pre> with newline in attribute
 * (bug 6771) Make old revisions of MediaWiki pages available with action=raw
 
+
+== Compatibility ==
+MediaWiki 1.7 requires PHP 5 (5.1 recommended). PHP 4 is no longer supported.
+
+If you are unable to run PHP 5, you may have to stick with 1.6 for now.
+
+MySQL 3.23.x is no longer supported; some older hosts may need to upgrade.
+At this time we still recommend 4.0, but 4.1/5.0 will work fine in most cases.
+
+Experimental Oracle support has been dropped as it is unmaintained.
+
+== Upgrading ==
+Several changes to the database have been made from 1.6:
+
+* A new "langlinks" table tracks interlanguage links
+* A new "filearchive" table stores information on deleted files
+* A new "querycache_info" table stores information on query page updates
+
+To ensure that these tables are filled with data, run refreshLinks.php after
+the upgrade.
+
+If you are upgrading from MediaWiki 1.4.x or earlier, some major database
+changes are made, and there is a slightly higher chance that things could
+break. Don't forget to always back up your database before upgrading!
+
+== Configuration changes ==
+
+Some configuration options have changed:
+* $wgAllowExternalImages now defaults to off for increased security.
+* $wgLocalTZoffset was in hours, it is now using minutes.
+* Extensions may register special pages via the $wgSpecialPages array without
+forcing an early load of the SpecialPage.php class file.
+
+== Major new features ==
+
+* Deleted files can now be archived and undeleted, if you set up an appropriate
+non-web-accessible directory. Set $wgSaveDeletedFiles on and an appropriate
+directory path in $wgFileStore['deleted']['directory']
+* Experimental PostgreSQL support has been updated. It may or may not be in
+usable shape; those interested in PostgreSQL are encouraged to follow 1.8
+development.
+
+=== Caveats ===
+Some output, particularly involving user-supplied inline HTML, may not
+produce 100% valid or well-formed XHTML output. Testers are welcome to
+set $wgMimeType = "application/xhtml+xml"; to test for remaining problem
+cases, but this is not recommended on live sites. (This must be set for
+MathML to display properly in Mozilla.)
+
+= MediaWiki 1.6 =
+
+== MediaWiki 1.6.12 ==
+
+February 7, 2009
+
+This is a security update to the Spring 2006 quarterly release.
+
+A number of cross-site scripting (XSS) security vulnerabilities were discovered
+in the web-based installer (config/index.php). These vulnerabilities all
+require a live installer -- once the installer has been used to install a
+wiki,  it is deactivated.
+
+Note that cross-site scripting vulnerabilities can be used to attack any
+website in the same cookie domain. So if you have an uninstalled copy of
+MediaWiki on the same site as an active web service, MediaWiki could be used to
+attack the active service.
+
+If you are hosting an old copy of MediaWiki that you have never installed, you
+are advised to remove it from the web.
+
+== MediaWiki 1.6.11 ==
+
+December 15, 2008
+
+This is a security update to the Spring 2006 quarterly release.
+
+David Remahl of Apple's Product Security team has identified a number of
+security issues in previous releases of MediaWiki. Subsequent analysis by the
+MediaWiki development team expanded the scope of these vulnerabilities. The
+issues with a significant impact are as follows:
+
+* An XSS vulnerability affecting Internet Explorer clients for all MediaWiki
+installations with uploads enabled. [CVE-2008-5250]
+* An XSS vulnerability affecting clients with SVG scripting capability (such as
+Firefox 1.5+), for all MediaWiki installations with SVG uploads enabled.
+[CVE-2008-5250]
+* A CSRF vulnerability affecting the Special:Import feature, for all MediaWiki
+installations since the feature was introduced in 1.3.0. [CVE-2008-5252]
+
+XSS (cross-site scripting) vulnerabilities allow an attacker to steal an
+authorised user's login session, and to act as that user on the wiki. The
+authorised user must visit a web page controlled by the attacker in order to
+activate the attack. Intranet wikis are vulnerable if the attacker can
+determine the intranet URL, even if the attacker cannot access it.
+
+CSRF vulnerabilities allow an attacker to act as an authorised user on the
+wiki, but unlike an XSS vulnerability, the attacker can only act as the user in
+a specific and restricted way. The present CSRF vulnerability allows pages to
+be edited, with forged revision histories. Like an XSS vulnerability, the
+authorised user must visit the malicious web page to activate the attack.
+
+Rather than backport our SVG validation code to this ancient branch, we have
+instead disabled SVG uploads. To enable SVG uploads, please upgrade to
+MediaWiki 1.13.3 or later.
+
+The other two issues have been fixed.
+
+== MediaWiki 1.6.10 ==
+
+February 20, 2007
+
+This is a security and bug-fix update to the Spring 2006 quarterly release.
+
+An XSS injection vulnerability based on Microsoft Internet Explorer's UTF-7
+charset autodetection was located in the AJAX support module, affecting MSIE
+users on MediaWiki 1.6.x and up when the optional setting $wgUseAjax is enabled.
+
+If you are using an extension based on the optional Ajax module, either disable
+it or upgrade to a version containing the fix:
+
+* 1.9: fixed in 1.9.3
+* 1.8: fixed in 1.8.4
+* 1.7: fixed in 1.7.3
+* 1.6: fixed in 1.6.10
+
+There is no known danger in the default configuration, with $wgUseAjax off.
+
+* ([[mediazilla:8819|bug 8819]]) Fix full path disclosure with skins
+dependencies
+* Add 'charset' to Content-Type headers on various HTTP error responses to
+forestall additional UTF-7-autodetect XSS issues. PHP sends only 'text/html' by
+default when the script didn't specify more details, which some inconsiderate
+browsers consider a license to autodetect the deadly, hard-to-escape UTF-7.
+This fixes an issue with the Ajax interface error message on MSIE when
+$wgUseAjax is enabled (not default configuration); this UTF-7 variant on a
+previously fixed attack vector was discovered by Moshe BA from BugSec:
+http://www.bugsec.com/articles.php?Security=24
+* Trackback responses now specify XML content type
+
+== MediaWiki 1.6.9 ==
+
+January 9, 2007
+
+* ([[mediazilla:6621|bug 6621]]) Backported German translation for
+'eauthentsent'
+
+* ([[mediazilla:6680|bug 6680]]) Added localisation for Dutch bookstore list
+(nl)
+* ([[mediazilla:6730|bug 6730]]) Clearer usage of message 'titlematch' in
+German translation (de)
+* XSS fix in AJAX module
+
+An XSS injection vulnerability was located in the AJAX support module,
+affecting MediaWiki 1.6.x and up when the optional setting $wgUseAjax is
+enabled.
+
+There is no danger in the default configuration, with $wgUseAjax off.
+
+If you are using an extension based on the optional AJAX module, either disable
+it or upgrade to a version containing the fix:
+
+* 1.9: fixed in 1.9.0rc2
+* 1.8: fixed in 1.8.3
+* 1.7: fixed in 1.7.2
+* 1.6: fixed in 1.6.9
+
+== MediaWiki 1.6.8 ==
+
+July 8, 2006
+
+MediaWiki 1.6.8 is a security and bugfix maintenance release of the Spring 2006
+snapshot:
+
+A potential HTML/JavaScript-injection vulnerability in a debugging script has
+been fixed. Only versions and configurations of PHP vulnerable to the $GLOBALS
+overwrite vulnerability are affected.
+
+As a workaround for existing installs, profileinfo.php may simply be deleted if
+it's not being used.
+
+* ([[mediazilla:5957|bug 5957]]) Updates to Hebrew translation (he)
+* Respect language directionality when displaying arrow in
+Special:Brokenredirects
+* ([[mediazilla:6415|bug 6415]]) Typo in Parser.php
+* Fixed potential XSS in profileinfo.php
+
+== MediaWiki 1.6.7 ==
+
+June 6, 2006
+
+MediaWiki 1.6.7 is a security and bugfix maintenance release of the Spring 2006
+snapshot:
+
+An HTML/JavaScript-injection vulnerability in the edit form has been closed.
+This vulnerability was new in 1.6.0; MediaWiki versions 1.5.x or earlier are
+not affected.
+
+Extensions, comments, and <nowiki><nowiki></nowiki> sections are now handled in
+a one-pass way which is more reliable and safer. Under earlier versions of
+MediaWiki, certain extensions could be abused to inject HTML/JavaScript into
+the page.
+
+Additional precautions are made against offsite form submissions when the
+restricted raw HTML mode is enabled.
+
+Some small localization and user interface updates are also included.
+
+*([[MediaZilla:6051|bug 6051]]) Improvement to German localisation (de)
+*([[MediaZilla:6017|bug 6017]]) Update bookstore list for German language (de)
+*([[MediaZilla:6138|bug 6138]]) Minor grammar tweak in "loginreqlink"
+*([[MediaZilla:5957|bug 5957]]) Update for Hebrew language (he)
+*Increase robustness of parser placeholders; fixes some glitches when adjacent
+to identifier-ish constructs such as URLs.
+*([[MediaZilla:5384|bug 5384]]) Fix <nowiki><!-- comments --> in <ref></nowiki>
+extension
+*Nesting of different tag extensions and comments should now work more
+consistently and more safely. A cleaner, one-pass tag strip lets the 'outer'
+tag either take source (<nowiki><nowiki></nowiki>-style) or pass it down to
+further parsing (<nowiki><ref></nowiki>-style). There should no longer be
+surprise expansion of foreign extensions inside HTML output, or differences in
+behavior based on the order tags are loaded.
+*([[MediaZilla:885|bug 885]]) Pre-save transform no longer silently appends
+close tags
+*Pre-save transform no longer changes the case of close tags
+*Edit security precautions in raw HTML mode, etc
+
+== MediaWiki 1.6.6 ==
+
+May 23, 2006
+
+MediaWiki 1.6.6 is a security and bugfix maintenance release.
+
+An XSS injection vector in brace replacement has been fixed, as have some
+potential problems with table parsing. Upgrading is strongly recommended for
+all users of 1.6. MediaWiki versions 1.5 and earlier are not affected.
+
+Additionally some localization and user interface updates are included.
+
+* Correct "revertpage" message in English
+* ([[MediaZilla:5507|bug 5507]]) Logouttext now uses wiki markup
+* (bugs [[MediaZilla:5857|5857]], [[MediaZilla:5957|5957]]) Update for German
+localisation (de)
+* ([[MediaZilla:5586|bug 5586]]) <nowiki><gallery></nowiki> treated text as
+links
+* ([[MediaZilla:5957|bug 5957]]) Update for Hebrew language (he)
+* ([[MediaZilla:6025|bug 6025]]) SpecialImport: wrong message when no file
+selected
+* ([[MediaZilla:6015|bug 6015]]) EditPage: add spacing in the boxes "edit is
+minor" and "watch this"
+* ([[MediaZilla:6018|bug 6018]]) Userrights: new message when no user specified
+('nouserspecified')
+* ([[MediaZilla:6055|bug 6055]]) Fix for HTML/JS injection bug in variable
+handler (found by Nick Jenkins)
+* Reordered wiki table handling and <nowiki>__TOC__</nowiki> extraction in the
+parser to better handle some overlapping tag cases.
+* Only the first <nowiki>__TOC__</nowiki> is now turned into a TOC.
+* ([[MediaZilla:361|bug 361]]) URL in URL, they were almost fixed. Now they are.
+
+== MediaWiki 1.6.5 ==
+
+May 2, 2006
+
+* Rolled back the buggy patch for [[MediaZilla:5497|bug 5497]].
+
+== MediaWiki 1.6.4 ==
+
+May 2, 2006
+
+* Further improvements to Hebrew localisation
+* ([[MediaZilla:5544|bug 5544]]) Fix redirect arrow in Special:Listredirects
+for right-to-left languages
+* Replace "doubleredirectsarrow" with a content language check that picks the
+appropriate arrow
+* Remove live debugging hack which caused errors with certain database names
+* ([[MediaZilla:5510|bug 5510]]) Warning produced when using
+<nowiki>{{SUBPAGENAME}}</nowiki> in some namespaces
+* ([[MediaZilla:5548|bug 5548]]) Improvements to Indonesian localisation
+[patch: Ivan Lanin]
+* ([[MediaZilla:5403|bug 5403]]) Fix Special:Newpages RSS/Atom feeds
+* ([[MediaZilla:3359|bug 3359]]) Add hooks on completion of file upload
+* ([[MediaZilla:5184|bug 5184]]) CSS misapplied to elements in
+Special:Allmessages due to conflicting anchor identifiers
+* ([[MediaZilla:5519|bug 5519]]) Allow sidebar cache to be disabled; disable it
+by default.
+* Add $wgReservedUsernames configuration directive to block account creation/use
+* ([[MediaZilla:5576|bug 5576]]) Remove debugging hack in session check
+* ([[MediaZilla:5181|bug 5181]]) Update "nogomatch" for Slovak
+* ([[MediaZilla:5594|bug 5594]]) Id translation up to '# Login and logout
+pages' section
+* ([[MediaZilla:5536|bug 5536]]) Use content language for editing help link
+* Minor improvements to English language files
+* Improvements to German localisation files
+* ([[MediaZilla:5628|bug 5628]]) Translations for MessagesHr.php
+* (bugs [[MediaZilla:5595|5595]], [[MediaZilla:5644|5644]]) Localisation for
+Bosnian language (bs)
+* ([[MediaZilla:5592|bug 5592]]) Actions are logged with the default language
+for the wiki, not the language of the user performing the operation.
+* ([[MediaZilla:5646|bug 5646]]) Compare for identical types in wfElement()
+* Fix for concurrency problem in job queue (image description page invalidation)
+* ([[MediaZilla:5497|bug 5497]]) regeression in HTML normalization in 1.6
+(unclosed <nowiki><li>,<dd>,<dt></nowiki>)
+* ([[MediaZilla:5709|bug 5709]]) Allow customisation of separator for categories
+* ([[MediaZilla:4834|bug 4834]]) Fix XHTML output when using $wgMaxTocLevel
+* Improvements to update scripts; print out the version, check for superuser
+credentials before attempting a connection, and produce a friendlier error if
+the connection fails
+* ([[MediaZilla:5005|bug 5005]]): Fix XHTML <nowiki><gallery></nowiki> output.
+* ([[MediaZilla:5315|bug 5315]]) "Expires: -1" HTTP header made strictly valid
+(using 1970 date).
+* ([[MediaZilla:4825|bug 4825]]): note in DefaultSettings.php about 'profiling'
+table creation
+* Remove unneeded extra whitespace at top of Special:Categories
+* Rewrite reassignEdits script to be more efficient; support optional updates
+to recent changes table; add reporting and silent modes
+* Updated initStats maintenance script
+* ([[MediaZilla:5723|bug 5723]]) Don't count pages linked to from the MediaWiki
+namespace as "wanted"
+* ([[MediaZilla:5789|bug 5789]]) Treat "loginreqpagetext" as wikitext
+* ([[MediaZilla:5796|bug 5796]]) We require MySQL >=4.0.14
+
+== MediaWiki 1.6.3 ==
+
+April 10, 2006
+
+* Fix disappearing red-linked items in the watchlist editing view
+* ([[MediaZilla:5512|bug 5512]]) Spacing in "page has a history" deletion
+warning
+* ([[MediaZilla:5508|bug 5508]]) Switch ENGINE in table statements back to
+TYPE; fixes regression where some versions of MySQL 4.0.x wouldn't work
+* Added note about [[Manual:$wgUrlProtocols|$wgUrlProtocols]] format change
+
+== MediaWiki 1.6.2 ==
+
+April 8, 2006
+
+* Further improvements to Hebrew localisation
+* Fix 'copyright' message for Romanian
+* ([[MediaZilla:5476|bug 5476]]) Invalid xhtml in German localization
+* ([[MediaZilla:5479|bug 5479]]) Id translation for preferences tabs caption
+* ([[MediaZilla:5493|bug 5493]]) Id translation for special pages
+* Additional path fixes in the updater
+* ([[MediaZilla:5344|bug 5344]]) Fix regression that broke slashes in extension
+tag parameters
+
+== MediaWiki 1.6.1 ==
+
+April 5, 2006
+
+Some minor issues in the 1.6.0 release have been corrected:
+* ([[MediaZilla:5458|bug 5458]]) Fix double-URL encoding in block log link in
+contribs and contribs link in block log
+* ([[MediaZilla:5462|bug 5462]]) Bogus missing patch warning in updater
+* ([[MediaZilla:5461|bug 5461]]) Use of deprecated "showhideminor" in
+Special:Recentchangeslinked
+* PHP warning when allow_call_time_pass_reference is off
+* Update to Finnish localization
+
+== MediaWiki 1.6.0 ==
+
+April 5, 2006
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept "ready
+to run", and in fact runs our own sites on Wikipedia.
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature development will take
+place on the development trunk and will appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can [[Download
+from SVN|obtain it from source control]].
+
+=== What's new in 1.6 ===
+
+'''User interface:'''
+* The account creation form has been separated from the user login form.
+* Page protection/unprotection uses a new, expanded form
+
+'''Templates:'''
+* Categories and "what links here" now update as expected when adding or
+removing links in a template.
+* Template parameters can now have default values, as <nowiki>{{{name|default
+value}}}</nowiki>
+
+'''Uploads:'''
+* Optional support for rasterizing SVG images to PNG for inline display
+
+'''Feeds:'''
+* Feed generation upgraded to Atom 1.0
+* Diffs in RSS and Atom feeds are now colored for improved readability.
+
+'''Database:'''
+* MySQL 3.23.x support dropped; 4.0 or later required
+* Experimental support for Unicode mode of MySQL 4.1/5.0 (moderately tested)
+* Experimental Oracle support (not well tested!)
+
+'''Anti-spam extension support:'''
+* [[meta:SpamBlacklist extension|SpamBlacklist extension]] now has support for
+automated cleanup.
+* Support for a [[meta:ConfirmEdit extension|captcha extension]] to restrict
+automated spam edits.
+
+Numerous bug fixes and other behind-the-scenes changes have been made; see the
+file HISTORY for a complete change list.
+
 == Changes since 1.5 ==
 
 * (bug 2885) More PHP 5.1 fixes: skin, search, log, undelete
@@ -15302,15 +17041,16 @@ Installer:
 * Add basic check for session support in PHP and die if not present
 
 Maintenance:
-* Fix problem reported on mailing list where re-initialising stats didn't work (can't insert
-  duplicate rows with the same id field)
+* Fix problem reported on mailing list where re-initialising stats didn't work
+  (can't insert duplicate rows with the same id field)
 * Added --conf option to command line scripts, allowing the user to specify a
   different LocalSettings.php.
 * Maintenance script to delete unused text records
 * Maintenance script to delete non-current revisions
 * Maintenance script to wipe a page and all revisions from the database
 * Maintenance script to reassign edits from one user to another
-* Maintenance script to find and remove links to a given domain (cleanupSpam.php)
+* Maintenance script to find and remove links to a given domain
+  (cleanupSpam.php)
 * Fix --report interval option for dumpTextPass
 
 i18n / Languages:
@@ -15351,7 +17091,8 @@ i18n / Languages:
 * (bug 2981) Linktrail for Tamil (ta)
 * (bug 3722) Update of Arabic language (ar) Namespace changes
 * Removed hardcoded Norwegian (no) project namespaces
-* (bug 2324) image for redirects should be without text and oriented according to content language
+* (bug 2324) image for redirects should be without text and oriented according
+  to content language
 * (bug 3666) Don't spew PHP warnings in prefs on unrecognized site language
 * (bug 3817) Use localized date formats in preferences; 'no preference' option
   localizable as 'datedefault' message. Tweaked lots of languages files...
@@ -15423,7 +17164,8 @@ i18n / Languages:
 * Typo in English messages file
 * (bug 4114) Spacing in watchlist rows (in editing mode)
 * Update default "exporttext" to reflect that Special:Import exists
-* (bug 4960) Add additional namespaces variants to Yi projects: Yiddish Wikinews fix
+* (bug 4960) Add additional namespaces variants to Yi projects: Yiddish Wikinews
+  fix
 * (bug 5357) Add the icon near the user name also in RTL interfaces
 * (bug 5156) Update for Hebrew language (he)
 * (bug 4497,4704,5010) Added some new language codes.
@@ -15471,7 +17213,8 @@ Upload:
 * (bug 2527) Always set destination filename when new file is selected
 * (bug 3076) Support MacBinary-encoded uploads from IE/Mac
 * (bug 2554) Tell users they are uploading too large file
-* Support for a license selection box on Special:Upload, configurable from MediaWiki:Licenses
+* Support for a license selection box on Special:Upload, configurable from
+  MediaWiki:Licenses
 * Add 'reupload' and 'reupload-shared' permission keys to restrict new uploads
   overwriting existing files; default is the old behavior (allowed).
 
@@ -15506,10 +17249,12 @@ Security:
   MIME type to the default blacklist. Prevented inline display of images
   which are not of known image types. This is in response to
   http://en.wikipedia.org/wiki/Windows_Metafile_vulnerability
-* Blocked users can no longer roll back, change the protection of, or delete/undelete pages
+* Blocked users can no longer roll back, change the protection of, or
+  delete/undelete pages
 * Protect against spoofing of X-Forwarded-For header
 * XSS issue : now sanitize search query input (fixed in 1.5rc3)
-* Remove deprecated $wgOnlySysopsCanPatrol references; use User::isAllowed( 'patrol' )
+* Remove deprecated $wgOnlySysopsCanPatrol references; use
+  User::isAllowed( 'patrol' )
   per bug 5282. Patch by Alan Harder.
 * Prevent registration/login with the username "MediaWiki default"
 
@@ -15564,15 +17309,18 @@ Special Pages:
 * JavaScript filter for Special:Allmessages
 * (bug 3047) Don't mention talk pages on Special:Movepage when there isn't one
 * Show links to user page, talk page and contributions page on Special:Newpages
-* Special:Export can now export a list of all contributors to an article (off by default)
+* Special:Export can now export a list of all contributors to an article (off by
+  default)
 * (bug 5372) Add number of files to Special:Statistics
 * (bug 2871) Links to talk pages in watchlist editing view
 * (bug 5385) Allow hiding anonymous edits on Special:Recentchanges
 * (bug 2544) Illogical error reporting order in Special:Userlogin
-* (bug 5409) Hide "show/hide patrolled edits" in Special:Recentchanges if patrolling
-  is disabled
-* (bug 5447) Convert first letter of username to uppercase before searching in Special:Listusers
-* (bug 759) Wrap redirects on the watchlist editing page in a span, class "watchlistredir"
+* (bug 5409) Hide "show/hide patrolled edits" in Special:Recentchanges if
+  patrolling is disabled
+* (bug 5447) Convert first letter of username to uppercase before searching in
+  Special:Listusers
+* (bug 759) Wrap redirects on the watchlist editing page in a span, class
+  "watchlistredir"
 * (bug 1862) Namespace filtering in watchlists
 
 Misc.:
@@ -15609,8 +17357,10 @@ fully support the editing toolbar, but was found to be too confusing.
   dumpBackup.php
 * (bug 3595) Warn and abort if importDump.php called in read-only mode.
 * (bug 3598) Update message cache on message page deletion, patch by Tietew
-* Added separate noarticletext and newarticletext messages for logged in and anon users.
-* (bug 3332) Installation now uses Monobook, validates, plus usability improvements.
+* Added separate noarticletext and newarticletext messages for logged in and
+  anon users.
+* (bug 3332) Installation now uses Monobook, validates, plus usability
+  improvements.
 * (bug 3660) Update diff3 detection to work with Windows/Cygwin
 * (bug 2330) Don't do funny thinks with "links" in MediaWiki:Undeletedtext
 * Two-pass data dump for friendliness to the DB (--stub, then dumpTextPass.php)
@@ -15732,8 +17482,8 @@ fully support the editing toolbar, but was found to be too confusing.
 * Cleanup and error checking on Special:Listredirects
 * Clear up some instances of old OutputPage::sysopRequired() function usage
 * Improve "upload disabled" notice
-* Move parts of index.php to include/Wiki.php in an attempt to both cleanup index.php
-  and create a MediaWiki-class mediaWiki base object
+* Move parts of index.php to include/Wiki.php in an attempt to both cleanup
+  index.php and create a MediaWiki-class mediaWiki base object
 * (bug 4104) Added OutputPageBeforeHTML hook for tweaking primary wiki output
   HTML on final output (cached or not)
 * Avoid PHP notice on command-line scripts if empty argument is passed ('')
@@ -15766,10 +17516,10 @@ fully support the editing toolbar, but was found to be too confusing.
 * (bug 3990) Use existing session name if session.auto_start is on
   Fixes checks for open sessions, such as the cookie warning on login.
   Patch by Zbigniew Braniecki.
-* Add cache-safe alternate sitenotice for anonymous users. (MediaWiki:Anonnotice)
-  This is displayed instead of the regular sitenotice, if it exists. If not, the
-  regular sitenotice shows. If that doesn't exist, the value of $wgSiteNotice is used,
-  and if that's null, then nothing is shown.
+* Add cache-safe alternate sitenotice for anonymous users.
+  (MediaWiki:Anonnotice) This is displayed instead of the regular sitenotice,
+  if it exists. If not, the regular sitenotice shows. If that doesn't exist,
+  the value of $wgSiteNotice is used, and if that's null, then nothing is shown.
 * Spit the generated LocalSettings code out during the installer as an aid
   to debugging issues. (Keep this?)
 * Use __FILE__ to form path in new LocalSettings.php, so it stays accurate
@@ -15858,12 +17608,15 @@ fully support the editing toolbar, but was found to be too confusing.
 * Fix explicit s-maxage=0 on raw pages; should help with proxy issues in
   generated stylesheets... hopefully...
 * (bug 4685) More fixes for Slovenian project namespace
-* Fixed and enhanced a little the Live Preview, which had been broken for some time
+* Fixed and enhanced a little the Live Preview, which had been broken for some
+  time
 * Added article size limit, $wgMaxArticleSize
 * (bug 4974) Don't follow redirected talk page on "new messages" link
 * (bug 4970) Make category paging limits configurable
-* (bug 4535) Warn user when editing CSS or JS subpage of a skin that doesn't exist
-* Make Live Preview an user preference, still controllable by the global variable
+* (bug 4535) Warn user when editing CSS or JS subpage of a skin that doesn't
+  exist
+* Make Live Preview an user preference, still controllable by the global
+  variable
 * Rename the stub LanguageAls / LanguageGem_alsation to LanguageGsw to follow
   updated language code assignments
 * (bug 5081) Remove bogus fix for invalid characters in links which simply
@@ -15880,7 +17633,8 @@ fully support the editing toolbar, but was found to be too confusing.
 * (bug 5141) Gracefully handle the new account link when createaccount off
 * (bug 5150 and related) Fix missing ID attribute in HTML namespace selector
 * (bug 5152) Proper HTML escaping on subpage breadcrumbs
-* (bug 4855) Section edit links now have the section name in the title attribute.
+* (bug 4855) Section edit links now have the section name in the title
+  attribute.
 * (bug 2115) Support shift-selecting multiple checkboxes with JavaScript.
 * (bug 5161) Don't try to load template list for nonexistent pages
 * (bug 5228) Workaround for broken LanguageConverter title overrides; avoid
@@ -15903,14 +17657,18 @@ fully support the editing toolbar, but was found to be too confusing.
   reliable beyond the hostname where it's used for the spam bulk checker.
 * Don't URL-decode in the title attribute for URL links; it can produce false
   results that don't code back to their original values.
-* (bug 4611) Add user preference (default on) to add new pages to creators's watchlist
+* (bug 4611) Add user preference (default on) to add new pages to creators's
+  watchlist
 * (bug 5286) Fix regression in display of missing/bad revision IDs
-* (bug 4729) Add user preference that marks a user's edits as patrolled if user is able to
-* (bug 4630) Add user preference to prompt users when entering blank edit summaries
+* (bug 4729) Add user preference that marks a user's edits as patrolled if user
+  is able to
+* (bug 4630) Add user preference to prompt users when entering blank edit
+  summaries
 * Added optional suggest feature for the search box. Set wgUseAjax to true to
   enable it.
 * (bug 5277) Use audio/midi rather that audio/mid
-* (bug 5410) Use namespace name when a custom namespace's nstab-NS message is nonexistent
+* (bug 5410) Use namespace name when a custom namespace's nstab-NS message is
+  nonexistent
 * (bug 5432) Fix inconsistencies in cookie names when using table prefixes
 * Additional protections against HTML breakage in table parsing
 * (bug 5355) Include skin name and style JS settings in page source;
@@ -15921,14 +17679,54 @@ fully support the editing toolbar, but was found to be too confusing.
 * (bug 5195) rebuildrecentchanges.php works again; Database::insertSelect now
   has a parameter for select options.
 * Fix updateSearchIndex.php for new schema
-* Fix bogus "filename too short" error when uploading files with a period in the base
-  name, e.g. "Mr. Zee.png"
+* Fix bogus "filename too short" error when uploading files with a period in the
+  base name, e.g. "Mr. Zee.png"
 * (bug 2139) Show page title in subtitle when viewing "read only" page
 * (bug 5452) Update language name for Cree
 
+== Compatibility ==
+
+Older PHP 4.2 and 4.1 releases are no longer supported; PHP 4 users must
+upgrade to 4.3 or later.
 
+MediaWiki 1.6 is the last major version to support PHP 4; future versions will
+require PHP 5.
 
-----
+MySQL 3.23.x is no longer supported; some older hosts may need to upgrade.
+At this time we still recommend 4.0, but 4.1/5.0 will work fine in most cases.
+
+== Upgrading ==
+
+Several changes to the database have been made from 1.5; these are relatively
+minor but do require that the update process be run before the new code will
+work properly:
+
+* A new "templatelinks" table tracks template inclusions.
+* A new "externallinks" table tracks URL links; this can be used by a mass
+spam-cleanup tool in the SpamBlacklist extension.
+* A new "jobs" table stores a queue of pages to update in the background; this
+is used to update links in including pages when templates are edited.
+
+To ensure that these tables are filled with data, run refreshLinks.php after
+the upgrade.
+
+If you are upgrading from MediaWiki 1.4.x or earlier, some major database
+changes are made, and there is a slightly higher chance that things could
+break. Don't forget to always back up your database before upgrading!
+
+=== Caveats ===
+
+Some output, particularly involving user-supplied inline HTML, may not produce
+100% valid or well-formed XHTML output. Testers are welcome to set $wgMimeType
+= "application/xhtml+xml"; to test for remaining problem cases, but this is not
+recommended on live sites. (This must be set for MathML to display properly in
+Mozilla.)
+
+
+= MediaWiki 1.5 =
+
+== MediaWiki 1.5.9 ==
+* (bug 3359) Add hooks on completion of file upload
 
 == MediaWiki 1.5.8 ==
 
@@ -16139,7 +17937,8 @@ Uploads:
   It's now possible to specify the final filename of an upload distinct
   from the original filename on your disk.
 
-  An image link for a missing file will now take you straight to the upload page.
+  An image link for a missing file will now take you straight to the upload
+  page.
 
   More metadata is pre-extracted from uploaded images, which will ease pressure
   on disk or NFS volumes used to store images. EXIF metadata is displayed on
@@ -16405,31 +18204,41 @@ Various bugfixes, small features, and a few experimental things:
 * 'live preview' reduces preview reload burden on supported browsers
 * support for external editors for files and wiki pages:
   https://www.mediawiki.org/wiki/Manual:External_editors
-* Schema reworking: https://www.mediawiki.org/wiki/Proposed_Database_Schema_Changes/October_2004
-* (bug 15) Allow editors to view diff of their change before actually submitting an edit
+* Schema reworking:
+  https://www.mediawiki.org/wiki/Proposed_Database_Schema_Changes/October_2004
+* (bug 15) Allow editors to view diff of their change before actually submitting
+  an edit
 * (bug 190) Hide your own edits on the watchlist
 * (bug 510): Special:Randompage now works for other namespaces than NS_MAIN.
 * (bug 1015) support for the full wikisyntax in <gallery> captions.
 * (bug 1105) A "Destination filename" (save as) added to Special:Upload Upload.
-* (bug 1352) Images on description pages now get thumbnailed regardless of whether the thumbnail is larger than the original.
-* (bug 1662) A new magicword, {{CURRENTMONTHABBREV}} returns the abbreviation of the current month
+* (bug 1352) Images on description pages now get thumbnailed regardless of
+  whether the thumbnail is larger than the original.
+* (bug 1662) A new magicword, {{CURRENTMONTHABBREV}} returns the abbreviation of
+  the current month
 * (bug 1668) 'Date format' supported for other languages than English, see:
   http://mail.wikipedia.org/pipermail/wikitech-l/2005-March/028364.html
-* (bug 1739) A new magicword, {{REVISIONID}} give you the article or diff database
-  revision id, useful for proper citation.
+* (bug 1739) A new magicword, {{REVISIONID}} give you the article or diff
+  database revision id, useful for proper citation.
 * (bug 1998) Updated the Russian translation.
 * (bug 2064) Configurable JavaScript mimetype with $wgJsMimeType
-* (bug 2084) Fixed a regular expression in includes/Title.php that was accepting invalid syntax like #REDIRECT [[foo] in redirects
-* It's now possible to invert the namespace selection at Special:Allpages and Special:Contributions
+* (bug 2084) Fixed a regular expression in includes/Title.php that was accepting
+  invalid syntax like #REDIRECT [[foo] in redirects
+* It's now possible to invert the namespace selection at Special:Allpages and
+  Special:Contributions
 * No longer using sorbs.net to check for open proxies by default.
-* What was $wgDisableUploads is now $wgEnableUploads, and should be set to true if one wishes to enable uploads.
+* What was $wgDisableUploads is now $wgEnableUploads, and should be set to true
+  if one wishes to enable uploads.
 * Supplying a reason for a block is no longer mandatory
 * Language conversion support for category pages
 * $wgStyleSheetDirectory is no longer an alias for $wgStyleDirectory;
 * Special:Movepage can now take parameters like Special:Movepage/Page_to_move
-  (used to just be able to take parameters via a GET request like index.php?title=Special:Movepage&target=Page_to_move)
-* (bug 2151) The delete summary now includes editor name, if only one has edited the article.
-* (bug 2105) Fixed from argument to the PHP mail() function. A missing space could prevent sending mail with some versions of sendmail.
+  (used to just be able to take parameters via a GET request like
+  index.php?title=Special:Movepage&target=Page_to_move)
+* (bug 2151) The delete summary now includes editor name, if only one has edited
+  the article.
+* (bug 2105) Fixed from argument to the PHP mail() function. A missing space
+  could prevent sending mail with some versions of sendmail.
 * (bug 2228) Updated the Slovak translation
 * ...and more!
 
@@ -16445,7 +18254,8 @@ Various bugfixes, small features, and a few experimental things:
 * (bug 898) The wiki can now do advanced sanity check on uploaded files
   including virus checks using external programs.
 * (bug 1692) Fix margin on unwatch tab
-* (bug 1906) Generalize project namespace for Latin localization, update namespaces
+* (bug 1906) Generalize project namespace for Latin localization, update
+  namespaces
 * (bug 1975) The name for Limburgish (li) changed from "Lèmburgs" to "Limburgs
 * (bug 2019) Wrapped the output of Special:Version in <div dir='ltr'> in order
   to preserve the correct flow of text on RTL wikis.
@@ -16454,7 +18264,8 @@ Various bugfixes, small features, and a few experimental things:
 * (bug 2079) Removed links to Special:Maintenance from movepagetext message
 * (bug 2094) Multiple use of a template produced wrong results in some cases
 * (bug 2095) Triple-closing-bracket thing partly fixed
-* (bug 2110) "noarticletext" should not display on Image page for "sharedupload" media
+* (bug 2110) "noarticletext" should not display on Image page for "sharedupload"
+  media
 * (bug 2150) Fix tab indexes on edit form
 * (bug 2152) Add missing bgcolor to attribute whitelist for <td> and <th>
 * (bug 2176) Section edit 'show changes' button works correctly now
@@ -16505,7 +18316,8 @@ Various bugfixes, small features, and a few experimental things:
 * (bug 2053) Move comment whitespace trimming from edit page to save;
   leaves the whitespace from the section comment there on preview.
 * (bug 2274) Respect stub threshold in category page list
-* (bug 2173) Fatal error when removing an article with an empty title from the watchlist
+* (bug 2173) Fatal error when removing an article with an empty title from the
+  watchlist
 * Removed -f parameter from mail() usage, likely to cause failures and bounces.
 * (bug 2130) Fixed interwiki links with fragments
 * (bug 684) Accept an attribute parameter array on parser hook tags
@@ -16552,7 +18364,8 @@ Various bugfixes, small features, and a few experimental things:
 * (bug 1120) Updated the Czech translation
 * A new magic word, {{SCRIPTPATH}}, returns $wgScriptPath
 * A new magic word, {{SERVERNAME}}, returns $wgServerName
-* A new magic word, {{NUMBEROFFILES}}, returns the number of rows in the image table
+* A new magic word, {{NUMBEROFFILES}}, returns the number of rows in the image
+  table
 * Special:Imagelist displays titles with " " instead of "_"
 * Less gratuitous munging of content sample in delete summary
 * badaccess/badaccesstext to supercede sysop*, developer* messages
@@ -16697,8 +18510,10 @@ of MediaWiki:Newpagetext) to &action=edit, if page is new.
 * (bug 1170) Fixed linktrail for da: and ru:
 * (bug 2683) Really fix apostrophe escaping for toolbox tips
 * (bug 923) Fix title and subtitle for rclinked special page
-* (bug 2642) watchdetails message in several languages used  <a></a> instead of [ ]
-* (bug 2181) basic CSB language localisation by Tomasz G. Sienicki (thanks for the patch)
+* (bug 2642) watchdetails message in several languages used  <a></a> instead of
+  [ ]
+* (bug 2181) basic CSB language localisation by Tomasz G. Sienicki (thanks for
+  the patch)
 * Fix correct use of escaping in edit toolbar bits
 * Removed language conversion support from Icelandic
 * (bug 2616) Fix proportional image scaling, giving correct height
@@ -16713,7 +18528,8 @@ of MediaWiki:Newpagetext) to &action=edit, if page is new.
 == Changes since 1.5beta2 ==
 
 * Escaped & correctly in Special:Contributions
-* (bug 2534) Hide edit sections with CSS to make right click to edit section work
+* (bug 2534) Hide edit sections with CSS to make right click to edit section
+  work
 * (bug 2708) Avoid undefined notice on cookieless login attempt
 * (bug 2188) Correct template namespace for Greek localization
 * Fixed number formatting for Dutch
@@ -16722,15 +18538,18 @@ of MediaWiki:Newpagetext) to &action=edit, if page is new.
 * Massive update for Arab (ar) language using Wikipédia
 * (bug 1560) Massive update for Kurdish (ku) language using Wikipédia
 * (bug 2709) Some messages were not read from database
-* (bug 2416) Don't allow search engine robots to index or follow nonexisting articles
+* (bug 2416) Don't allow search engine robots to index or follow nonexisting
+  articles
 * Fix escaping in page move template.
 * (bug 153) Discrepancy between thumbnail size and <img> height attribute
 
 == Changes since 1.5beta3 ==
 
 * Fix talk page move handling
-* (bug 2721) New language file for Vietnamese with the Vietnamese number notation
-* (bug 2749) &nbsp; would appear as a literal in image galleries for Cs, Fr, Fur, Pl and Sv
+* (bug 2721) New language file for Vietnamese with the Vietnamese number
+  notation
+* (bug 2749) &nbsp; would appear as a literal in image galleries for Cs, Fr,
+  Fur, Pl and Sv
 * (bug 787) external links being rendered when they only have one slash
 * Fixed a missing typecast in Language::dateFormat() that would cause some
   interesting errors with signitures.
@@ -17032,7 +18851,8 @@ of MediaWiki:Newpagetext) to &action=edit, if page is new.
 === Changes since 1.5.7 ===
 
 * (bug 5180) User login page shows inappropriate email blurb
-* Add the "AbortNewAccount" hook on account creation; see hooks.txt for more info.
+* Add the "AbortNewAccount" hook on account creation; see hooks.txt for more
+  info.
 * Update default "exporttext" to reflect that Special:Import exists
 * Add links to useful material to the default main page content
 * Fix fragment HTML injection
@@ -17054,7 +18874,141 @@ set $wgMimeType = "application/xhtml+xml"; to test for remaining problem
 cases, but this is not recommended on live sites. (This must be set for
 MathML to display properly in Mozilla.)
 
-----
+= MediaWiki 1.4 =
+
+== MediaWiki 1.4.15 ==
+
+(released March 26, 2006) MediaWiki 1.4.15 is a security maintenance release. A
+bug in decoding of certain encoded links could allow injection of raw HTML into
+page output; this could potentially lead to XSS attacks. Additionally, this
+release may display more correctly in IE7 betas.
+
+== MediaWiki 1.4.14 ==
+(released January 19, 2006) MediaWiki 1.4.14 is a security and bugfix
+maintenance release. A bug in edit comment formatting could send PHP into an
+infinite loop if certain malformed links were included. In most installations,
+this would cause the script to fail after PHP's 30-second failsafe timeout. For
+several other minor fixes, see the complete changelog at the end of this file.
+
+== MediaWiki 1.4.13 ==
+(released January 5, 2006) MediaWiki 1.4.13 is a security maintenance
+release.Detection for uploads of Windows Metafile (.wmf) images has been added
+to help protect against a client-side vulnerability in unpatched Microsoft
+Windows operating systems. Sites which have enabled uploads and added
+non-standard file types (such as .ogg, .doc, or .pdf) should upgrade to this
+release to ensure that malicious .wmf files can't be uploaded with a fake
+extension; such files could put visitors to the site at risk. For more details
+on this, see: http://en.wikipedia.org/wiki/Windows_Metafile_vulnerability
+
+== MediaWiki 1.4.12 ==
+(released 2005-11-02) MediaWiki 1.4.12 is a bugfix and security maintenance
+release. A change in PHP 4.4.1 broke handling of extension and
+<nowiki><pre></nowiki> sections, causing garbage data to be inserted in output
+and saved edits. This version works around the change. This release includes
+further corrections to the inline CSS style sanitation which works around a
+JavaScript "feature" on Microsoft Internet Explorer. Users of Microsoft
+Internet Explorer for Windows may be vulnerable to XSS injections on prior 1.4
+releases; users of standards-compliant browsers are not vulnerable.
+
+== MediaWiki 1.4.11 ==
+(released 2005-10-05) MediaWiki 1.4.11 is a security maintenance release.
+Unsafe handling of CSS by Microsoft Internet Explorer could be exploited to
+produce cross-site scripting attacks by JavaScript injection to clients running
+that browser. This release blacklists several additional variants from use in
+HTML inline style attributes. All publicly accessible wikis are recommended to
+upgrade to reduce the risk to visitors using Microsoft web browsers. Note: the
+MediaWiki 1.4.x series is not compatible with PHP 5.0.5 or higher. Upgrade to
+the 1.5.0 release if you require this version of PHP 5.
+
+== MediaWiki 1.4.10 ==
+(released 2005-09-21) MediaWiki 1.4.10 is a security maintenance release. A bug
+in edit submission handling could cause corruption of the previous revision in
+the database if an abnormal URL was used, such as those used by some spambots.
+Affected releases:
+* 1.4.x <= 1.4.9; fixed in 1.4.10
+* 1.3.x <= 1.3.15; fixed in 1.3.16
+1.5 release candidates are not affected by this problem. All publicly editable
+wikis are strongly recommended to upgrade immediately.
+1.4 releases can be manually patched by changing this bit in EditPage.php:
+
+<syntaxhighlight lang="php">
+function importFormData( &$request ) {
+        if( $request->wasPosted() ) {
+</syntaxhighlight>
+to:
+<syntaxhighlight lang="php">
+    function importFormData( &$request ) {
+        if( $request->getVal( 'action' ) == 'submit' && $request->wasPosted() )
+        {
+</syntaxhighlight>
+== MediaWiki 1.4.9 ==
+(released 2005-08-29) MediaWiki 1.4.9 is a security maintenance release. It
+corrects two cross-site scripting security bugs:
+* <nowiki><math></nowiki> tags were handled incorrectly when TeX rendering
+support is off, as in the default configuration.
+* Extension or <nowiki><nowiki></nowiki> sections in Wiki table syntax could
+bypass HTML style attribute restrictions for cross-site scripting attacks
+against Microsoft Internet Explorer Wikis where the optional math support has
+been *enabled* are not vulnerable to the first, but are vulnerable to the
+second.
+
+== MediaWiki 1.4.8 ==
+(released 2005-08-23) MediaWiki 1.4.8 is a bug fix and security maintenance
+release. A flaw in the interaction between extensions and HTML attribute
+sanitization was discovered which could allow unauthorized use of offsite
+resources in style sheets, and possible exploitation of a JavaScript injection
+feature on Microsoft Internet Explorer. This version expands the returned text
+and properly checks it before output. Additionally, an update to
+skins/MonoBook.php ensures that sites using the default MonoBook skin will
+display correctly in the Internet Explorer 7 beta. (1.3 and 1.5 are not
+affected by this bug.)
+
+== MediaWiki 1.4.7 ==
+(released 2005-07-16)
+MediaWiki 1.4.7 is a bug fix release. Those affected by the following problems
+in 1.4.6 should upgrade:
+* Watchlist breakage on MySQL 3.23.x and with table prefix enabled
+* Possible breakage in watchlist, some image resizing modes on PHP 4.1.2 1.4.6
+included a fix for a cross-site scripting vulnerability, so anyone running
+older 1.4 releases is very strongly encouraged to upgrade as well. Note to
+upgraders: this version of MediaWiki is known to produce a large number of
+notice-level warnings under the newly released PHP 4.4.0. These appear however
+to be harmless; if you encounter them add this to your LocalSettings.php to
+suppress the notices: error_reporting( E_ALL & ~E_NOTICE ); PHP 5.1.0beta3 is
+known to be incompatible at this time.
+
+== MediaWiki 1.4.6 ==
+(released 2005-07-07) MediaWiki 1.4.6 is a bug fix and security update release.
+Incorrect escaping of a parameter in the page move template could
+be used to inject JavaScript code by getting a victim to visit a maliciously
+constructed URL. Users of vulnerable releases are recommended to upgrade to
+this release. Vulnerable versions:
+* 1.5 preview series: n <= 1.5beta2 vulnerable, fixed in 1.5beta3
+* 1.4 stable series: 1.4beta6 <= n <= 1.4.5 vulnerable, fixed in 1.4.6
+* 1.3 legacy series: not vulnerable This release also includes fixes for some
+rare bug annoying HTTP errors, a PHP 4.1.2 breakage bug, and works around some
+template limitations introduced in 1.4.5. See the changelog at the end of this
+file for a detailed list of bugs fixed.
+
+== MediaWiki 1.4.5 ==
+(released 2005-06-03) MediaWiki 1.4.5 is a security update and bugfix release.
+Incorrect handling of page template inclusions made it possible to inject
+JavaScript code into HTML attributes, which could lead to cross-site scripting
+attacks on a publicly editable wiki. Vulnerable releases and fix:
+* 1.5 prerelease: fixed in 1.5alpha2
+* 1.4 stable series: fixed in 1.4.5
+* 1.3 legacy series: fixed in 1.3.13
+* 1.2 series no longer supported; upgrade to 1.4.5 strongly recommended This
+release also includes a number of bug fixes (see changelog below) and merges
+some large-server load balancing patches from Wikipedia. An experimental rate
+limiter for page edits and moves can be enabled with global, per-IP,
+per-subnet, or per-user bases. See configuration options in
+includes/DefaultSettings.php
+
+== MediaWiki 1.4.4 ==
+(released 2005-05-04) MediaWiki 1.4.4 is a bugfix release for the 1.4 stable
+release series. Some bugs in the installer/updater and refreshLinks maintenance
+script were introduced in the last release and have been corrected.
 
 == MediaWiki 1.4.3 ==
 
@@ -17271,8 +19225,8 @@ pages for purposes of page relevancy ranking.
 === Misc bugs fixed in beta 1 ===
 
 * (bug 95) Templates no longer limited to 5 inclusions per page
-* New user preference for limiting the image size for images on image description
-  pages
+* New user preference for limiting the image size for images on image
+  description pages
 * (bug 530) Allow user to preview article on first edit
 * (bug 479) [[RFC 1234]] will now make an internal link
 * (bug 511) PhpTal skins shown bogus 'What links here' etc on special pages
@@ -17389,7 +19343,8 @@ pages for purposes of page relevancy ranking.
   in diff-view
 * Use user's local timezone in Special:Log display
 * Show filename for images in gallery by default (restore beta 3 behavior)
-* (bug 1201) Double-escaping in brokenlinks, imagelinks, categorylinks, searchindex
+* (bug 1201) Double-escaping in brokenlinks, imagelinks, categorylinks,
+  searchindex
 * When using squid reverse proxy, cache the redirect to the Main_Page
 * (bug 1302) Fix Norwegian language file
 * (bug 1205) Fix broken article saving in PHP 5.1
@@ -17446,7 +19401,8 @@ pages for purposes of page relevancy ranking.
 * Add fur/Furlan/Friulian to language names list
 * Add TitleMoveComplete hook on page renames
 * Allow simple comments for each translation rules in MW:Zhconversiontable
-* (bug 1402) Make link color of tab subject page link on talk page indicate whether article exists
+* (bug 1402) Make link color of tab subject page link on talk page indicate
+  whether article exists
 * (bug 1368) Fix SQL error on stopword/short word search w/ MySQL 3.x
 * Translated Hebrew namespace names
 * (bug 1429) Stop double-escaping of block comments; fix formatting
@@ -17505,7 +19461,8 @@ pages for purposes of page relevancy ranking.
 * (bug 563) Fix UTF-8 interwiki URL redirects via Latin-1 wikis
 * (bug 1536) Fix page info
 * Support os (Ossetic) as language code, using Russian localization base
-* (bug 1610) Support non (Old Norse) as language code, using Icelandic localization base
+* (bug 1610) Support non (Old Norse) as language code, using Icelandic
+  localization base
 * (bug 1618) Properly list custom namespaces in Special:Allpages
 * (bug 1622) Remove trailing' >' when using category browser
 * (bug 1570) Fix php 4.2.x error on conflict merging
@@ -17647,3 +19604,384 @@ going to run a public MediaWiki, so you can be notified of security fixes.
 === IRC help ===
 
 There's usually someone online in #mediawiki on irc.freenode.net
+
+=MediaWiki 1.3=
+
+== MediaWiki 1.3.18 ==
+(released 2005-11-02)
+MediaWiki 1.3.18 is a bugfix and security maintenance release. A change in PHP
+4.4.1 broke handling of extension and <nowiki><pre></nowiki> sections, causing
+garbage data to be inserted in output and saved edits. This version works
+around the change. This release includes further corrections to the inline CSS
+style sanitation which works around a JavaScript "feature" on Microsoft
+Internet Explorer. Users of Microsoft Internet Explorer for Windows may be
+vulnerable to XSS injections on prior 1.3 releases; users of
+standards-compliant browsers are not vulnerable.
+
+== MediaWiki 1.3.17 ==
+(released 2005-10-05)
+MediaWiki 1.3.17 is a security maintenance release. Unsafe handling of CSS by
+Microsoft Internet Explorer could be exploited to produce cross-site scripting
+attacks by JavaScript injection to clients running that browser. This release
+blacklists several additional variants from use in HTML inline style
+attributes. All publicly accessible wikis are recommended to upgrade to reduce
+the risk to visitors using Microsoft web browsers.Note: the MediaWiki 1.3.x
+series is not compatible with PHP 5.0.5 or higher. Upgrade to the 1.5.0 release
+if you require this version of PHP 5.
+
+== MediaWiki 1.3.16 ==
+(released 2005-09-21)
+MediaWiki 1.3.16 is a security maintenance release. A bug in edit submission
+handling could cause corruption of the previous revision in the database if an
+abnormal URL was used, such as those used by some spambots. Affected releases:
+* 1.4.x <= 1.4.9; fixed in 1.4.10
+* 1.3.x <= 1.3.15; fixed in 1.3.16
+1.5 release candidates are not affected by this problem. All publicly editable
+wikis are strongly recommended to upgrade immediately.
+1.3 releases can be manually patched by changing this bit in
+{{manual|EditPage.php}}:
+<syntaxhighlight lang="php">
+    if( $this->tokenOk( $request ) ) {
+        $this->save    = $request->wasPosted() && !$this->preview;
+    } else {
+</syntaxhighlight>
+to:
+<syntaxhighlight lang="php">
+    if( $this->tokenOk( $request ) ) {
+        $this->save    = $request->getVal( 'action' ) == 'submit' &&
+                         $request->wasPosted() && !$this->preview;
+    } else {
+</syntaxhighlight>
+
+== MediaWiki 1.3.15, 2005-08-29 ==
+MediaWiki 1.3.15 is a security maintenance release. It corrects across-site
+scripting security bug:
+* <nowiki><math></nowiki> tags were handled incorrectly when TeX rendering
+support is off, as in the default configuration. Wikis where the optional math
+support has been *enabled* are not vulnerable. The 1.3.x series is no longer
+maintained except for security fixes; new users and those seeking bug fixes
+should upgrade to 1.4.9 or 1.5.0.
+
+== MediaWiki 1.3.14, 2005-08-23 ==
+MediaWiki 1.3.14 is a security maintenance release. A flaw in the interaction
+between extensions and HTML attribute sanitization was discovered which could
+allow unauthorized use of offsite resources in style sheets, and possible
+exploitation of a JavaScript injection feature on Microsoft Internet Explorer.
+The 1.3.x series is no longer maintained except for security fixes; new users
+and those seeking bug fixes should upgrade to 1.4.8 or 1.5.0. Existing 1.3.x
+installations not willing to upgrade to the current stable release should apply
+the change manually:
+In includes/Parser.php, function {{code|inline=y|lang=php|fixTagAttributes()}}
+add:
+<syntaxhighlight lang="php">
+       # Any placeholder items should have been unstripped already before
+       # we got to this point. Raw text inserted later could be dangerous.
+       if( strpos( $t, UNIQ_PREFIX ) !== false ) {
+           wfDebug( "Parser::fixTagAttributes found stripped data placeholder;
+           dropping attributes\n" );
+           $t = '';
+       }
+</syntaxhighlight>
+If you are actively using extensions to generate HTML attribute values, upgrade
+to 1.4 or 1.5 for a more thorough fix.
+
+== MediaWiki 1.3.13, 2005-06-03 ==
+MediaWiki 1.3.13 is a security maintenance release. Incorrect handling of page
+template inclusions made it possible to inject JavaScript code into HTML
+attributes, which could lead to cross-site scripting attacks on a publicly
+editable wiki. Vulnerable releases and fix:
+* 1.5 prerelease: fixed in 1.5alpha2
+* 1.4 stable series: fixed in 1.4.5
+* 1.3 legacy series: fixed in 1.3.13
+* 1.2 series no longer supported; upgrade to 1.4.5 strongly recommended The
+1.3.x series is no longer maintained except for security fixes; new users and
+those seeking general bug fixes should install 1.4.5. Existing 1.3.x
+installations not willing or able to upgrade to the current stable relase
+should update the installation to 1.3.13; only includes/Parser.php has changed
+from 1.3.12.
+
+== MediaWiki 1.3.12, 2005-02-20 ==
+MediaWiki 1.3.12 is a security maintenance release. A cross-site scripting
+injection vulnerability was discovered, which affects only MSIE clients and is
+only open if MediaWiki has been manually configured to run output through HTML
+Tidy ($wgUseTidy). The 1.3.x series is no longer maintained except for security
+fixes; new users and those seeking bug fixes should upgrade to 1.4.2. Existing
+1.3.x installations using Tidy not willing to upgrade to the current stable
+relase should either turn off Tidy or update the installation to 1.3.12.
+
+== MediaWiki 1.3.11, 2005-02-20 ==
+MediaWiki 1.3.11 is a security release.
+A security audit found and fixed a number of problems. Users of MediaWiki
+1.3.10 and earlier should upgrade to 1.3.11; users of 1.4 beta releases should
+upgrade to 1.4rc1.
+
+=== Cross-site scripting vulnerability ===
+XSS injection points can be used to hijack session and authentication cookies
+as well as more serious attacks.
+* Media: links output raw text into an attribute value, potentially abusable
+for JavaScript injection. This has been corrected.
+* Additional checks added to file upload to protect against MSIE and Safari
+MIME-type autodetection bugs.
+As of <code>1.3.10/1.4beta6</code>, per-user customized CSS and JavaScript is
+disabled by default as a general precaution. Sites which want this ability may
+set {{wg|AllowUserCss}} and {{wg|AllowUserJs}} in LocalSettings.php.
+
+=== Cross-site request forgery ===
+An attacker could use JavaScript-submitted forms to perform various restricted
+actions by tricking an authenticated user into visiting a malicious web page. A
+fix for page editing in 1.3.10/1.4beta6 has been expanded in this release to
+other forms and functions. Authors of bot tools may need to update their code
+to include the additional fields.
+
+=== Directory traversal ===
+An unchecked parameter in image deletion could allow an authenticated
+administrator to delete arbitary files in directories writable by the web
+server, and confirm existence of files not deletable.
+
+== MediaWiki 1.3.10, 2005-02-03 ==
+MediaWiki 1.3.10 is a security release.
+An attacker could craft a URL which, when visited by a particular logged-in
+user, would execute arbitrary JavaScript code on the user's browser in the
+wiki's site context. This attack has been blocked, and as an extra precaution
+the user CSS and JavaScript subpage support is now disabled by default. Sites
+which want this ability may set {{wg|AllowUserCss}} and {{wg|AllowUserJs}} in
+{{manual|LocalSettings.php}}. Additional protections have been added against
+off-site form submissions
+hijacking user credentials. Authors of bot tools may need to update their code
+to include additional fields. All wikis running 1.3.x are strongly urged to
+upgrade to 1.3.10.
+Changes from 1.3.9:
+* Logged-in edits and preview of user CSS/JS are now locked to a session token.
+* Per-user CSS and JavaScript subpage customizations now disabled by default.
+They can be re-enabled via {{wg|AllowUserJs}} and {{wg|AllowUserCss}}.
+* Removed .ogg from the default uploads whitelist as an extra precaution. If
+your web server is configured to serve Ogg files with the correct Content-Type
+header, you can re-add it in LocalSettings.php: {{wg|FileExtensions}}<code>[] =
+'ogg'</code>
+
+== MediaWiki 1.3.9, 2004-12-12 ==
+MediaWiki 1.3.9 is a security and bug fix release.
+A flaw in upload handling has been found which may allow upload and  execution
+of arbitrary scripts with the permissions of the web server. Only wikis that
+have enabled uploads and have a vulnerable Apache  configuration will be
+affected, but to be safe all wikis should upgrade. Wikis with uploads available
+should either disable uploads or upgrade to 1.3.9 immediately; if other files
+are customized and require merging changes,
+includes/{{manual|SpecialUpload.php}} may be replaced individually to add the
+fix. (It is also recommended to configure your web server to disable script
+execution in the 'images' subdirectory where uploads are placed, which prevents
+most attacks even if the wiki fails.)
+Changes from 1.3.8:
+* Backported "Templates used in this page"-feature of EditPage
+* Allow "MySkin" as a default skin.
+* ({{bugzilla|938}}) Parse namespaces correctly on self-interwiki links
+* ({{bugzilla|1010}}) fix broken Commons image link on [[Skin:Classic|Classic]]
+& [[Skin:Cologne Blue|Cologne Blue]]
+* ({{bugzilla|1004}}) Norsk language names for interwiki links changed, Nauruan
+language name changed
+* Enhance upload extension blacklist to protect against vulnerable Apache
+configurations
+
+== MediaWiki 1.3.8, 2004-11-15 ==
+MediaWiki 1.3.8 is a bugfix release. Those running wikis with uploads enabled
+are strongly recommended to upgrade as this fixes several problems with
+overwriting previously-uploaded files.
+Changes from 1.3.7:
+* ({{bugzilla|506}}) fix {{code|inline=y|lang=html|array_key_exists()}} warning
+for IIS servers using ISAPI mode
+* ({{bugzilla|718}}) fix bad charset in (file) cached pages
+* use local numerals in category page (for Hindi et al)
+* alias month abbreviations to month names in Hindi
+* add localized numerals for Gujarati and Kannada
+* fix Category and project namespaces for Hindi
+* Don't output bogus timestamp on [[Special:RecentChanges]] if no entries
+* Correct template include path which broke some but not all Windows installs
+* Fix edit form submission problem with some PHP versions
+* Disallow unreachable titles with %XX hex codes
+* Allow page [[0]] to be renamed
+* ({{bugzilla|774}}) when saving with <code>section=new</code>, return to the
+anchor as with existing numbered section edits
+* Experimental shared upload overlay area (disabled by default)
+* ({{bugzilla|806}}) Removed some "Wikipedia" hardcoding in German localization
+* User option localization fix for some extensions
+* ({{bugzilla|809}}) now try to load the mysql php extension if it isn't loaded
+* ({{bugzilla|848}}) fix error message in [[Special:Newpages]] RSS and Atom
+feeds
+* ({{bugzilla|26}}) fix cache headers on anon talk page notification
+* ({{bugzilla|874}}) added 'cgi' to {{wg|FileBlacklist}}
+* ({{bugzilla|862}}) localize date and time format for Finnish
+* ({{bugzilla|548}}) Don't overwrite images until the user confirms it
+
+== MediaWiki 1.3.7, 2004-10-18 ==
+Changes from 1.3.6:
+* Fix protected-page related security issue.
+
+== MediaWiki 1.3.6, 2004-10-14 ==
+Changes from 1.3.5:
+* ({{bugzilla|296}}) Variables in user interface messages are no longer
+substituted at install time, so changes to the site name etc should be easier
+to make
+* ({{bugzilla|149}}) [[Special:RecentChanges]] "changes from" link preserves
+limit
+* ({{bugzilla|433}}) tooltip for "Undelete" tab now labeled correctly
+* ({{bugzilla|439}}) unclickable "Move" tab no longer displays on protected
+pages
+* ({{bugzilla|484}}) graceful deletion of images where the actual file is
+missing
+* ({{bugzilla|686}}) fixed [[plural]]s in Catalan localization
+* Fixed potential HTML/JavaScript injection attack in the
+[[Extension:UnicodeConverter|UnicodeConverter]] extension. (This extension is
+not enabled by default.)
+* Fixed potential HTML/JavaScript injection attack via raw page views to a
+maliciously crafted wiki page.
+* ({{bugzilla|187}}, {{bugzilla|669}}) Fixed centered thumbnails, using
+{{code|inline=y|lang=html|<div>}} instead of {{code|inline=y|lang=html|<span>}}.
+* catch MySQL error 2000 during installation.
+* ({{bugzilla|704}}) Removed misleading LocalSettings.sample
+* Fix cross site scripting bugs in [[Special:Ipblocklist]],
+[[Special:EmailUser]]
+* Fix SQL injection and cross site scripting bugs in Special:Maintenance
+* Fix cross site scripting bugs and possible filename validation vulnerability
+in ImagePage.
+* and more of that sort
+
+== MediaWiki 1.3.5, 2004-09-30 ==
+Changes from 1.3.4:
+* Clean up input validation in 'raw' page output mode which was a potential
+cross-site scripting opportunity.
+
+== MediaWiki 1.3.4, 2004-09-28 ==
+=== SECURITY NOTE ===
+As of 1.3.4, MediaWiki performs some screening of newly uploaded files for
+validity. (Some)  corrupt image files, and HTML files mistakenly or maliciously
+masquerading as images, should now be rejected. These checks protect against
+Internet Explorer security holes relating to type autodetection which are a
+potential cross-site scripting attack vector, and also rejects at least one
+known version of the "JPEG virus" which might attack unpatched clients. If you
+already have invalid files uploaded this will not protect against them. If you
+have expanded the <code>filetype</code> whitelist or disabled the strict type
+checking, other dangerous file types may still get through. You should always
+be careful when allowing uploads!
+Changes from 1.3.3:
+* Fixed lots of template-related bugs, esp. for cases where template variables
+are used for links, images, etc.
+* Fixed transformation of page messages when viewing [[Special:Allmessages]]
+* Handle "ISBN ISBN 1234" correctly
+* Fixed warning on Category pages
+* Fixed some bad error messages on login page
+* Fixed history entry for initial main page on install
+* Removed problematic <code>{</code> and <code>}</code> from legal title
+characters
+* Strip leading blank from output in preformatted text.
+* Fixed problem when moving pages to titles with '#' in
+* Optional {{wg|RawHtml}} for raw {{code|inline=y|lang=html|<html>}} sections.
+Use only on limited- participation 'trusted' wikis, as it does not protect
+against cross-site scripting attacks. For security, this option can only be
+enabled if in {{wg|WhitelistEdit}} mode.
+* Fixed problem where pages which were created as a redirect following a move
+never showed on [[Special:Randompage]].
+* Fixed line spacing on printed table of contents
+* Allow links to pages with names of the form [[RFC 1234]]
+* Fixed broken edit links being shown for sections from included templates
+* Verify that uploaded image files are of the claimed type.
+
+== MediaWiki 1.3.3, 2004-09-09 ==
+Changes from 1.3.2:
+* Fix for long numeric page titles
+* Fix Go search for "0", numeric almost-self-links
+* Avoid caching of pages with "You have new messages" headers
+* Fix for upgrades as non-root users from 1.2 command-line installs.
+* Fix for {{wg|DebugDumpSql}} debug mode.
+* {{wg|ExtraNamespaces}} setting for configuring additional namespaces (see
+note in {{manual|DefaultSettings.php}})
+* 'recache' on query pages now disabled when miser mode is on; special case the
+global settings in your {{manual|LocalSettings.php}} to do automatic updates.
+* Don't block UTF-8 titles containing byte 0xA0 (bug added in 1.3.2)
+* Watch/unwatch tabs now shown on edit pages in MonoBook.
+* Fix default skin in Irish localization (ga)
+* Add Traditional Chinese localization (zh-tw)
+* Changed default sortkey of subcategories. Don't include "Category:"-prefix
+any longer
+* More helpful info on spam catcher.
+* Allow larger offsets for queries such as [[Special:Listusers]]
+* Semicolon (;) added to French non-break space rules
+* Possible fix for some install errors with path names permission problems.
+* Removed [[Project:All system messages]], which has been superseded by the
+much faster [[Special:Allmessages]]. This speeds up installation considerably.
+
+== MediaWiki 1.3.2, 2004-08-30 ==
+Changes from 1.3.1:
+* Fix namespaced page creation links when no go match
+* When cookies are disabled, don't show login screen twice
+* Install should no longer die when PHP is pre-configured to compress output
+* Fixed bug that caused long Japanese pages to time out with Tidy active
+* When session.handler is set incorrectly, try automatic override to 'files'
+* Watch/Unwatch links back to the affected page instead of Main Page
+* Upload link no longer displayed on Monobook if uploading is disabled
+* Special:Allmessages faster, shows correct original text, works in safe mode
+
+== MediaWiki 1.3.1, 2004-08-14 ==
+Changes from 1.3.0:
+* Watchlist parameters now work with register_globals off
+* Fixed parsing of ''italics'' and '''bold''' mark-up (again)
+* Special:Allpages display is more sensible on smaller wikis
+* Fixed XHTML parsing error in classic skins
+* Moved pages update watchlist correctly
+* Fixed rebuildall.php on case-sensitive Unix filesystems
+* Disabled file cache compression by default due to incompatibility with output
+buffer compression (ob_gzhandler)
+* New magic word {{code|inline=y|PAGENAMEE}} (URL-escaped version of
+{{code|inline=y|PAGENAME}})
+* Installation avoids blank username; better message on missing XML module
+* {{wg|WhitelistAccount}} no longer breaks all logins.
+
+== MediaWiki 1.3.0, 2004-08-11 ==
+Look & layout:
+* New default layout '[[Skin:MonoBook|MonoBook]]' (available on PHP4 only
+currently)
+* Print stylesheet now built-in to every page
+* More or less correct XHTML 1.0 (served as text/html by default)
+Wiki features:
+* Image captions can now include links and other basic formatting
+* Image bounding box can be specified instead of width, e.g. as 100x100px,
+making the image not wider than 100px and not higher than 100px, keeping aspect
+ratio.
+* Templates have been expanded with parameters, and separated from the
+MediaWiki: localization scheme.
+* Categories more or less work
+* added a special page for listing users with sysop rights.
+Editing:
+* Automatic merging of edit conflicts that don't directly interfere
+* Edit summaries can now include basic formatting and links
+Metadata and output:
+* Linked Creative Commons copyright metadata (optional)
+* RSS 2.0 & Atom 0.3 feeds for Recent Changes, New Pages
+Optional modules:
+* WikiHiero hieroglyphic module can be added (separate download)
+* Timeline module can be added (separate download). Requires ploticus.
+* TeX now has an experimental MathML output mode (incomplete!)
+Installation and upgrading:
+* The old install.php and update.php have been removed. In-place installation
+introduced in 1.2 is now the standard installation and upgrade method, see
+INSTALL and UPGRADE for directions.
+Database:
+* The links table has been changed to use a cur_id for l_from. The link tables
+must be converted on upgrade, which may entail some downtime.
+Code and compatibility:
+* Should now run clean with error reporting set to E_ALL.
+* register_globals hack from 1.2 has been replaced with safer code
+* Bundled PHPTAL 0.7.0 from http://phptal.sourceforge.net/ (with some patches)
+* Most image-related code moved to Image.php
+* More fixes for PHP 4.1.2 (thanks to Asheesh Laroia)
+* URL encoding fix for anchors
+* All languages now available in UTF-8 mode
+* Various other fixes
+
+=== Caveats ===
+Some output, particularly involving user-supplied inline HTML, may not produce
+100% valid or well-formed XHTML output. Testers are welcome to set $wgMimeType
+= "application/xhtml+xml"; to test for remaining problem cases, but this is not
+recommended on live sites. (This must be set for MathML to display properly in
+Mozilla.) The new 'MonoBook' skin is not compatible with PHP 5 due to bugs in
+the underlying PHPTAL library. It will be automatically disabled when running
+on PHP5; the older look and feel will be used instead.
diff --git a/INSTALL b/INSTALL
index b6364e1..f31f753 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -10,7 +10,7 @@ Required software:
 * A SQL server, the following types are supported
 ** MySQL 5.5.8 or higher
 ** PostgreSQL 9.2 or higher
-** SQLite 3.3.7 or higher
+** SQLite 3.8.0 or higher
 ** Oracle 9.0.1 or higher
 ** Microsoft SQL Server 2005 (9.00.1399)
 
index 4a923c5..db5fea0 100644 (file)
-== MediaWiki 1.33 ==
+= MediaWiki 1.33 =
+
+== MediaWiki 1.33.0-PRERELEASE ==
 
 THIS IS NOT A RELEASE YET
 
-MediaWiki 1.33 is an alpha-quality branch and is not recommended for use in
-production.
+MediaWiki 1.33 is a pre-release testing branch, and is not recommended for use
+in production.
 
-=== Configuration changes in 1.33 ===
+== Upgrading notes for 1.33 ==
+1.33 has several database changes since 1.32, and will not work without schema
+updates. Note that due to changes to some very large tables like the revision
+table, the schema update may take quite long (minutes on a medium sized site,
+many hours on a large site).
 
-==== New configuration ====
-* $wgEnablePartialBlocks – This enables the Partial Blocks feature, which gives
-  accounts with block permissions the ability to block users, IPs, and IP ranges
-  from editing specific pages, while allowing them to edit the rest of the wiki.
-* $wgMediaInTargetLanguage – whether multilingual images should be dispalyed in
-  the current parse language where available.
+Don't forget to always back up your database before upgrading!
+
+See the file UPGRADE for more detailed upgrade instructions, including
+important information when upgrading from versions prior to 1.11.
+
+Some specific notes for MediaWiki 1.33 upgrades are below:
 
-==== Changed configuration ====
 * Some external link searches will not work correctly until update.php (or
   refreshExternallinksIndex.php) is run. These include searches for links using
   IP addresses, internationalized domain names, and possibly mailto links.
-* (T193868) $wgChangeTagsSchemaMigrationStage — This temporary setting, added in
-  MediaWiki 1.32, now defaults to MIGRATION_NEW instead of MIGRATION_WRITE_BOTH.
-* Special:ActiveUsers will no longer filter out users who became inactive since
-  the last time the active users query cache was updated.
 * If you ran migrateActors.php using an older version of MediaWiki and want to
   run your wiki with $wgActorTableSchemaMigrationStage SCHEMA_COMPAT_READ_OLD,
   note that log_search rows needed to find revision deletions by target user
   were incorrectly deleted. See T215464 for details.
+* If revision deletions were performed when the wiki was configured with
+  $wgActorTableSchemaMigrationStage SCHEMA_COMPAT_WRITE_BOTH and without
+  migrateActors.php having been run, the log_search table may contain rows with
+  empty values for "target_author_actor" which will prevent log searches for
+  revision deletions by target user from finding those log entries. These rows
+  may be corrected by (re-)running migrateActors.php.
+
+For notes on 1.32.x and older releases, see HISTORY.
+
+=== Configuration changes for system administrators in 1.33 ===
+
+==== New configuration ====
+* $wgEnablePartialBlocks – This enables the Partial Blocks feature, which gives
+  accounts with block permissions the ability to block users, IPs, and IP ranges
+  from editing specific pages, while allowing them to edit the rest of the wiki.
+  It is a temporary setting for gradual enablement, current default to `false`,
+  and will be set to `true` and then removed once initial development completes.
+
+==== Changed configuration ====
+* $wgChangeTagsSchemaMigrationStage (T193868) — This temporary setting, added in
+  MediaWiki 1.32, now defaults to MIGRATION_NEW instead of MIGRATION_WRITE_BOTH.
+* $wgPasswordPolicy – There is a new password policy to check that the account's
+  password is not in the large blacklist. This is enabled by default for the
+  built-in user groups bureaucrat, sysop, interface-admin, and bot. To configure
+  this for other user groups, set the `PasswordNotInLargeBlacklist` flag `true`.
+* wgPasswordDefault – There is a new password type configuration using Argon2
+  password hashing (which requires PHP 7.2 and above). It's designed to resist
+  timing attacks, and (on systems with PHP 7.3+) GPU hacking; if you configure
+  argon2 to be used, by default, it will automatically choose the best available
+  algorithm depending on which version of PHP you have available. To use this,
+  you can set `$wgPasswordDefault = 'argon2';`.
+* $wgActorTableSchemaMigrationStage now defaults to reading the new schema.
+  update.php will back-populate the new database fields due to the changed
+  setting, which may take some time on large wikis. You can avoid downtime by
+  following a process like that described in T188327.
 
 ==== Removed configuration ====
-* (T199334) $wgTagStatisticsNewTable — This temporary setting, added in
+* $wgTagStatisticsNewTable (T199334) — This temporary setting, added in
   MediaWiki 1.32, has now been removed. When loading Special:Tags, MediaWiki
   will now always use the `change_tag_def` instead of the `change_tag` table.
-* MediaWiki now always tidies user output, and most related
-  configuration has been removed. Thus $wgUseTidy, $wgTidyBin,
-  $wgTidyConf, $wgTidyOpts, $wgTidyInternal, and $wgDebugTidy, all
-  deprecated since 1.26, have now all been removed. The $wgTidyConfig
-  setting remains only for Remex experimental features or debugging.
-* $wgEnableParserCache, deprecated since 1.26, was removed.
-  If disabling the parser cache is still desirable,
-  set `$wgParserCacheType = CACHE_NONE;` instead.
-* $wgCommentTableSchemaMigrationStage has been removed. Extension code finding
-  it unset should treat it as being MIGRATION_NEW.
-
-=== New features in 1.33 ===
+* $wgUseTidy, $wgTidyBin, $wgTidyConf, $wgTidyOpts, $wgTidyInternal, and
+  $wgDebugTidy – These options, all deprecated since 1.26, have now all been
+  removed, as MediaWiki now always tidies user output. The $wgTidyConfig setting
+  remains only for experimental features and debugging, and should not be used.
+* $wgEnableParserCache – This setting has been deprecated since 1.26, has now
+  been removed. If you still desire to disable the parser cache, instead you can
+  set `$wgParserCacheType = CACHE_NONE;`.
+* $wgCommentTableSchemaMigrationStage – This temporary migration setting has now
+  been removed. Code finding it unset should treat it as being MIGRATION_NEW.
+* $wgAuth – This old setting, deprecated in 1.27, has been removed as part of
+  the removal of AuthPlugin.
+* $wgSitesCacheFile – This configuration was introduced in 1.25 with the intent
+  to allow sites to configure a file in which to cache the SiteStore database
+  table, but it was never used. SiteStore already caches its information by
+  default using BagOStuff (e.g. Memcached or APC).
+* $wgClockSkewFudge – This setting was used by User.php to let sites adjust by
+  how much MediaWiki would fudge when trying to minimize the chances of a
+  user.user_touched database update to the "current" timestamp being before the
+  value already there (e.g. due to clock skew between different servers). This
+  is no longer a problem, because the code now ensures the timestamp is always
+  higher than the previous one. The writes are guarded with CAS logic (check
+  and set), which prevents updates that would overlap.
+* $wgDBmysql5 (T196185) - This experimental setting, deprecated in 1.31, has
+  been removed.
+
+=== New user-facing features in 1.33 ===
 * (T96041) __EXPECTUNUSEDCATEGORY__ on a category page causes the category
   to be hidden on Special:UnusedCategories.
-* Add PasswordPolicy to check the password isn't in the large blacklist.
+* (T210814) SVGs are now by default displayed in wiki language on image
+  pages.
+* Special:CreateAccount now warns the user if their chosen username has to be
+  normalized.
+* (T205040) Multilingual images are now be displayed in the current parse
+  language where available.
+* Special:ActiveUsers will no longer filter out users who became inactive since
+  the last time the active users query cache was updated.
+* (T215675) RecentChange and ManualLogEntry implement new Taggable interface.
+* (T215675) Added a hook, ManualLogEntryBeforePublish, to allow extensions
+  to modify (example: add tags) log entries.
+
+=== New developer features in 1.33 ===
 * The AuthManagerLoginAuthenticateAudit hook has a new parameter for
   additional information about the authentication event.
 * TextContent::getText() was introduced as a replacement for
   Content::getNativeData() for text-based content models.
-* (T210814) SVGs are now by default displayed in wiki language on image
-  pages.
 * (T214706) LinksUpdate::getAddedExternalLinks() and
   LinksUpdate::getRemovedExternalLinks() were introduced.
-* Argon2 password hashing is now available, can be enabled via
-  $wgPasswordDefault = 'argon2'. It's designed to resist timing attacks
-  (requires PHP 7.2+) and GPU hacking (7.3+).
+* (T213893) Added 'MaintenanceUpdateAddParams' hook
+* (T219655) The MarkPatrolled hook has a new parameter for the tags
+  associated with this entry in the patrol log.
 
 === External library changes in 1.33 ===
 
@@ -66,7 +126,7 @@ production.
 * Added jakub-onderka/php-console-highlighter 0.3.2 explicitly (dev-only).
 
 ==== Changed external libraries ====
-* Updated OOUI from v0.29.2 to v0.30.3.
+* Updated OOUI from v0.29.2 to v0.31.2.
 * Updated OOjs Router from pre-release to v0.2.0.
 * Updated moment from v2.19.3 to v2.24.0.
 * Updated wikimedia/xmp-reader from 0.6.0 to 0.6.2.
@@ -83,10 +143,13 @@ production.
 * Updated wikimedia/php-session-serializer from 1.0.6 to 1.0.7.
 
 ==== Removed external libraries ====
+* (T219403) jquery.ui.spinner, deprecated since 1.31, was removed.
 
 === Bug fixes in 1.33 ===
 * (T164211) Special:UserRights could sometimes fail with a
   "conflict detected" error when there weren't any conflicts.
+* (T216029) Chrome redirects to Special:BadTitle after editing a section with
+  a non-Latin name on a page with non-Latin characters in title.
 
 === Action API changes in 1.33 ===
 * (T198913) Added 'ApiOptions' hook.
@@ -104,6 +167,8 @@ production.
   if entirewatchlist is set, so updates may not be visible immediately
 * Block info will be added to "blocked" errors from more modules.
 * (T216245) Autoblocks will now be spread by action=edit and action=move.
+* action=query&meta=userinfo has a new uiprop, 'latestcontrib', that returns
+  the date of user's latest contribution.
 
 === Action API internal changes in 1.33 ===
 * A number of deprecated methods for API documentation, intended for overriding
@@ -122,6 +187,8 @@ production.
   passed a bad code.
 * ApiBase::checkTitleUserPermissions() now takes an options array as its third
   parameter. Passing a User object or null is deprecated.
+* The api-feature-usage log channel now has log context. The text message is
+  deprecated and will be removed in the future.
 
 === Languages updated in 1.33 ===
 MediaWiki supports over 350 languages. Many localisations are updated regularly.
@@ -265,6 +332,35 @@ because of Phabricator reports.
 * MessageBlobStore::__construct() now requires its $rl parameter.
 * Second parameter to Sanitizer::escapeIdReferenceList() (deprecated in 1.31)
   has been removed.
+* The 'jquery.xmldom' module has been removed.
+* The 'jquery.mockjax' module has been removed.
+* The 'jquery.hidpi' module, deprecated in 1.32, has been removed.
+* AuthPlugin and related code, deprecated in 1.27, has been removed. Extensions
+  should instead use AuthManager. The following no longer exist:
+  * The AuthPlugin class itself and the related AuthPluginUser class and i18n
+  * The AuthPluginSetup and AuthPluginAutoCreate hooks
+  * The transitional wrapper classes AuthPluginPrimaryAuthenticationProvider,
+    AuthManagerAuthPlugin, and AuthManagerAuthPluginUser.
+  * The $wgAuth configuration setting and its use in Setup.php and unit tests
+* (T217772) The 'wgAvailableSkins' mw.config key in JavaScript, was removed.
+* Language::markNoConversion, deprecated in 1.32, has been removed. Use
+  LanguageConverter::markNoConversion instead.
+* BagOStuff::modifySimpleRelayEvent() method has been removed.
+* ParserOutput::getLegacyOptions, deprecated in 1.30, has been removed.
+  Use ParserOutput::allCacheVaryingOptions instead.
+* CdnCacheUpdate::newSimplePurge, deprecated in 1.27, has been removed.
+  Use CdnCacheUpdate::newFromTitles() instead.
+* Handling of multiple arguments by the Block constructor, deprecated in 1.26,
+  has been removed.
+* The translation of main page in Sardinian (sc) was changed from "Pàgina Base"
+  to "Pàgina printzipale". Existing wikis using this content language need to
+  move the main page or change the name through MediaWiki:Mainpage page.
+* wfSplitWikiID(), deprecated in 1.32, has been removed.
+* MessageBlobStore::getBlob(), deprecated in 1.27, has been removed.
+  Use ::getBlobs() instead.
+* The .background-size() LESS mixin, deprecated in 1.27, has been removed.
+* ReadOnlyMode::clearCache() and ConfiguredReadOnlyMode::clearCache() have been
+  removed. Use MediaWikiTestCase::overrideMwServices() instead.
 
 === Deprecations in 1.33 ===
 * The configuration option $wgUseESI has been deprecated, and is expected
@@ -321,6 +417,20 @@ because of Phabricator reports.
   Block::isCreateAccountBlocked and Block::isUsertalkEditAllowed to get and set
   block properties; use Block::appliesToRight and Block::appliesToUsertalk to
   check block behaviour.
+* The api-feature-usage log channel now has log context. The text message is
+  deprecated and will be removed in the future.
+* The FileBasedSiteLookup class has been deprecated. For a cacheable SiteLookup
+  implementation, use CachingSiteStore instead.
+* Language::viewPrevNext function is deprecated, use
+  SpecialPage::buildPrevNextNavigation instead
+* ManualLogEntry::setTags() is deprecated, use ManualLogEntry::addTags()
+  instead. The setTags() method was overriding the tags, addTags() doesn't
+  override, only adds new tags.
+* Block::isValid is deprecated, since it is no longer needed in core.
+* Calling Maintenance::hasArg() as well as Maintenance::getArg() with no
+  parameter has been deprecated. Please pass the argument number 0.
+* ResourceLoaderContext::expandModuleNames has been deprecated.
+  Use ResourceLoader::expandModuleNames instead.
 
 === Other changes in 1.33 ===
 * (T201747) Html::openElement() warns if given an element name with a space
@@ -328,6 +438,16 @@ because of Phabricator reports.
 * The implementation of buildStringCast() in Wikimedia\Rdbms\Database has
   changed to explicitly cast. Subclasses relying on the base-class
   implementation should check whether they need to override it now.
+* BagOStuff::add is now abstract and must explicitly be defined in subclasses.
+* LinksDeletionUpdate is now a subclass of LinksUpdate. As a consequence,
+  the following hooks will now be triggered upon page deletion in addition
+  to page updates: LinksUpdateConstructed, LinksUpdate, LinksUpdateComplete.
+  LinksUpdateAfterInsert is not triggered since deletions do not cause
+  insertions into links tables.
+* Category::newFromID( $id )->getID() will now return $id without any
+  validation, to avoid a mostly unnecessary DB query.
+* On Special:Version, the name for an extension can no longer be arbitrary
+  html when no link is specified.
 
 == Compatibility ==
 MediaWiki 1.33 requires PHP 7.0.13 or later. Although HHVM 3.18.5 or later is
@@ -342,23 +462,10 @@ The supported versions are:
 
 * MySQL 5.5.8 or later
 * PostgreSQL 9.2 or later
-* SQLite 3.3.7 or later
+* SQLite 3.8.0 or later
 * Oracle 9.0.1 or later
 * Microsoft SQL Server 2005 (9.00.1399)
 
-== Upgrading ==
-1.33 has several database changes since 1.32, and will not work without schema
-updates. Note that due to changes to some very large tables like the revision
-table, the schema update may take quite long (minutes on a medium sized site,
-many hours on a large site).
-
-Don't forget to always back up your database before upgrading!
-
-See the file UPGRADE for more detailed upgrade instructions, including
-important information when upgrading from versions prior to 1.11.
-
-For notes on 1.32.x and older releases, see HISTORY.
-
 == Online documentation ==
 Documentation for both end-users and site administrators is available on
 MediaWiki.org, and is covered under the GNU Free Documentation License (except
diff --git a/RELEASE-NOTES-1.34 b/RELEASE-NOTES-1.34
new file mode 100644 (file)
index 0000000..ba4ac51
--- /dev/null
@@ -0,0 +1,132 @@
+= MediaWiki 1.34 =
+
+== MediaWiki 1.34.0-PRERELEASE ==
+
+THIS IS NOT A RELEASE YET
+
+MediaWiki 1.34 is an alpha-quality development branch, and is not recommended
+for use in production.
+
+== Upgrading notes for 1.34 ==
+1.34 has several database changes since 1.33, and will not work without schema
+updates. Note that due to changes to some very large tables like the revision
+table, the schema update may take quite long (minutes on a medium sized site,
+many hours on a large site).
+
+Don't forget to always back up your database before upgrading!
+
+See the file UPGRADE for more detailed upgrade instructions, including
+important information when upgrading from versions prior to 1.11.
+
+Some specific notes for MediaWiki 1.34 upgrades are below:
+
+* …
+
+For notes on 1.33.x and older releases, see HISTORY.
+
+=== Configuration changes for system administrators in 1.34 ===
+==== New configuration ====
+* …
+
+==== Changed configuration ====
+* …
+
+==== Removed configuration ====
+* …
+
+=== New user-facing features in 1.34 ===
+* …
+
+=== New developer features in 1.34 ===
+* …
+
+=== External library changes in 1.34 ===
+==== New external libraries ====
+* …
+
+==== Changed external libraries ====
+* Updated Mustache from 1.0.0 to v3.0.1.
+* …
+
+==== Removed external libraries ====
+* …
+
+=== Bug fixes in 1.34 ===
+* …
+
+=== Action API changes in 1.34 ===
+* …
+
+=== Action API internal changes in 1.34 ===
+* …
+
+=== Languages updated in 1.34 ===
+MediaWiki supports over 350 languages. Many localisations are updated regularly.
+Below only new and removed languages are listed, as well as changes to languages
+because of Phabricator reports.
+
+* …
+
+=== Breaking changes in 1.34 ===
+* Preferences class, deprecated in 1.31, has been removed.
+* The following parts of code, deprecated in 1.32, were removed in favor of
+  built-in PHP functions:
+  * CryptRand class
+  * CryptRand service
+  * Functions of the MWCryptRand class: singleton(), wasStrong() and generate().
+* Language::setCode, deprecated in 1.32, was removed. Use Language::factory to
+  create a new Language object with a different language code.
+* MWNamespace::clearCaches() has been removed.  So has the $rebuild parameter
+  to MWNamespace::getCanonicalNamespaces(), which was deprecated since 1.31.
+  Instead, reset services, such as by calling $this->overrideMwServices() (if
+  your test extends MediaWikiTestCase). Services will generally not pick up
+  configuration changes from after they were created, so you must reset
+  services after any configuration change. Even if your code works now, it is
+  likely to break in future versions as more code is moved to services.
+* The ill-defined "DatabaseOraclePostInit" hook has been removed.
+
+=== Deprecations in 1.34 ===
+* The MWNamespace class is deprecated. Use MediaWikiServices::getNamespaceInfo.
+* …
+
+=== Other changes in 1.34 ===
+* …
+
+== Compatibility ==
+MediaWiki 1.34 requires PHP 7.0.13 or later. Although HHVM 3.18.5 or later is
+supported, it is generally advised to use PHP 7.0.13 or later for long term
+support.
+
+MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
+but support for them is somewhat less mature. There is experimental support for
+Oracle and Microsoft SQL Server.
+
+The supported versions are:
+
+* MySQL 5.5.8 or later
+* PostgreSQL 9.2 or later
+* SQLite 3.8.0 or later
+* Oracle 9.0.1 or later
+* Microsoft SQL Server 2005 (9.00.1399)
+
+== Online documentation ==
+Documentation for both end-users and site administrators is available on
+MediaWiki.org, and is covered under the GNU Free Documentation License (except
+for pages that explicitly state that their contents are in the public domain):
+
+       https://www.mediawiki.org/wiki/Special:MyLanguage/Documentation
+
+== Mailing list ==
+A mailing list is available for MediaWiki user support and discussion:
+
+       https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
+
+A low-traffic announcements-only list is also available:
+
+       https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
+
+It's highly recommended that you sign up for one of these lists if you're
+going to run a public MediaWiki, so you can be notified of security fixes.
+
+== IRC help ==
+There's usually someone online in #mediawiki on irc.freenode.net.
index aaf6f51..a74a0b8 100644 (file)
@@ -166,8 +166,6 @@ $wgAutoloadLocalClasses = [
        'AttachLatest' => __DIR__ . '/maintenance/attachLatest.php',
        'AugmentPageProps' => __DIR__ . '/includes/search/AugmentPageProps.php',
        'AuthManagerSpecialPage' => __DIR__ . '/includes/specialpage/AuthManagerSpecialPage.php',
-       'AuthPlugin' => __DIR__ . '/includes/AuthPlugin.php',
-       'AuthPluginUser' => __DIR__ . '/includes/AuthPlugin.php',
        'AutoCommitUpdate' => __DIR__ . '/includes/deferred/AutoCommitUpdate.php',
        'AutoLoader' => __DIR__ . '/includes/AutoLoader.php',
        'AutoloadGenerator' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
@@ -219,7 +217,7 @@ $wgAutoloadLocalClasses = [
        'BufferingStatsdDataFactory' => __DIR__ . '/includes/libs/stats/BufferingStatsdDataFactory.php',
        'CLIParser' => __DIR__ . '/maintenance/parse.php',
        'CSSMin' => __DIR__ . '/includes/libs/CSSMin.php',
-       'CacheDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
+       'CacheDependency' => __DIR__ . '/includes/cache/dependency/CacheDependency.php',
        'CacheHelper' => __DIR__ . '/includes/cache/CacheHelper.php',
        'CacheTime' => __DIR__ . '/includes/parser/CacheTime.php',
        'CachedAction' => __DIR__ . '/includes/actions/CachedAction.php',
@@ -300,12 +298,12 @@ $wgAutoloadLocalClasses = [
        'ComposerVendorHtaccessCreator' => __DIR__ . '/includes/composer/ComposerVendorHtaccessCreator.php',
        'ComposerVersionNormalizer' => __DIR__ . '/includes/composer/ComposerVersionNormalizer.php',
        'CompressOld' => __DIR__ . '/maintenance/storage/compressOld.php',
-       'ConcatenatedGzipHistoryBlob' => __DIR__ . '/includes/HistoryBlob.php',
+       'ConcatenatedGzipHistoryBlob' => __DIR__ . '/includes/historyblob/ConcatenatedGzipHistoryBlob.php',
        'Config' => __DIR__ . '/includes/config/Config.php',
        'ConfigException' => __DIR__ . '/includes/config/ConfigException.php',
        'ConfigFactory' => __DIR__ . '/includes/config/ConfigFactory.php',
        'ConfiguredReadOnlyMode' => __DIR__ . '/includes/ConfiguredReadOnlyMode.php',
-       'ConstantDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
+       'ConstantDependency' => __DIR__ . '/includes/cache/dependency/ConstantDependency.php',
        'Content' => __DIR__ . '/includes/content/Content.php',
        'ContentHandler' => __DIR__ . '/includes/content/ContentHandler.php',
        'ContentModelLogFormatter' => __DIR__ . '/includes/logging/ContentModelLogFormatter.php',
@@ -329,7 +327,6 @@ $wgAutoloadLocalClasses = [
        'CreditsAction' => __DIR__ . '/includes/actions/CreditsAction.php',
        'CrhConverter' => __DIR__ . '/languages/classes/LanguageCrh.php',
        'CryptHKDF' => __DIR__ . '/includes/libs/CryptHKDF.php',
-       'CryptRand' => __DIR__ . '/includes/libs/CryptRand.php',
        'CssContent' => __DIR__ . '/includes/content/CssContent.php',
        'CssContentHandler' => __DIR__ . '/includes/content/CssContentHandler.php',
        'CsvStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
@@ -366,6 +363,7 @@ $wgAutoloadLocalClasses = [
        'DatabaseUpdater' => __DIR__ . '/includes/installer/DatabaseUpdater.php',
        'DateFormats' => __DIR__ . '/maintenance/language/date-formats.php',
        'DateFormatter' => __DIR__ . '/includes/parser/DateFormatter.php',
+       'DateFormatterFactory' => __DIR__ . '/includes/parser/DateFormatterFactory.php',
        'DeadendPagesPage' => __DIR__ . '/includes/specials/SpecialDeadendpages.php',
        'DeduplicateArchiveRevId' => __DIR__ . '/maintenance/deduplicateArchiveRevId.php',
        'DeferrableCallback' => __DIR__ . '/includes/deferred/DeferrableCallback.php',
@@ -389,7 +387,7 @@ $wgAutoloadLocalClasses = [
        'DeleteSelfExternals' => __DIR__ . '/maintenance/deleteSelfExternals.php',
        'DeletedContribsPager' => __DIR__ . '/includes/specials/pagers/DeletedContribsPager.php',
        'DeletedContributionsPage' => __DIR__ . '/includes/specials/SpecialDeletedContributions.php',
-       'DependencyWrapper' => __DIR__ . '/includes/cache/CacheDependency.php',
+       'DependencyWrapper' => __DIR__ . '/includes/cache/dependency/DependencyWrapper.php',
        'DeprecatedGlobal' => __DIR__ . '/includes/DeprecatedGlobal.php',
        'DeprecatedInterfaceFinder' => __DIR__ . '/maintenance/findDeprecated.php',
        'DeprecationHelper' => __DIR__ . '/includes/debug/DeprecationHelper.php',
@@ -400,7 +398,7 @@ $wgAutoloadLocalClasses = [
        'Diff' => __DIR__ . '/includes/diff/DairikiDiff.php',
        'DiffEngine' => __DIR__ . '/includes/diff/DiffEngine.php',
        'DiffFormatter' => __DIR__ . '/includes/diff/DiffFormatter.php',
-       'DiffHistoryBlob' => __DIR__ . '/includes/HistoryBlob.php',
+       'DiffHistoryBlob' => __DIR__ . '/includes/historyblob/DiffHistoryBlob.php',
        'DiffOp' => __DIR__ . '/includes/diff/DairikiDiff.php',
        'DiffOpAdd' => __DIR__ . '/includes/diff/DairikiDiff.php',
        'DiffOpChange' => __DIR__ . '/includes/diff/DairikiDiff.php',
@@ -428,6 +426,7 @@ $wgAutoloadLocalClasses = [
        'DumpFilter' => __DIR__ . '/includes/export/DumpFilter.php',
        'DumpGZipOutput' => __DIR__ . '/includes/export/DumpGZipOutput.php',
        'DumpIterator' => __DIR__ . '/maintenance/dumpIterator.php',
+       'DumpLBZip2Output' => __DIR__ . '/includes/export/DumpLBZip2Output.php',
        'DumpLatestFilter' => __DIR__ . '/includes/export/DumpLatestFilter.php',
        'DumpLinks' => __DIR__ . '/maintenance/dumpLinks.php',
        'DumpMessages' => __DIR__ . '/maintenance/language/dumpMessages.php',
@@ -498,7 +497,7 @@ $wgAutoloadLocalClasses = [
        'FakeResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php',
        'FatalError' => __DIR__ . '/includes/exception/FatalError.php',
        'FauxRequest' => __DIR__ . '/includes/FauxRequest.php',
-       'FauxResponse' => __DIR__ . '/includes/WebResponse.php',
+       'FauxResponse' => __DIR__ . '/includes/FauxResponse.php',
        'FeedItem' => __DIR__ . '/includes/Feed.php',
        'FeedUtils' => __DIR__ . '/includes/FeedUtils.php',
        'FetchText' => __DIR__ . '/maintenance/fetchText.php',
@@ -521,7 +520,7 @@ $wgAutoloadLocalClasses = [
        'FileContentHandler' => __DIR__ . '/includes/content/FileContentHandler.php',
        'FileContentsHasher' => __DIR__ . '/includes/utils/FileContentsHasher.php',
        'FileDeleteForm' => __DIR__ . '/includes/FileDeleteForm.php',
-       'FileDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
+       'FileDependency' => __DIR__ . '/includes/cache/dependency/FileDependency.php',
        'FileDuplicateSearchPage' => __DIR__ . '/includes/specials/SpecialFileDuplicateSearch.php',
        'FileJournal' => __DIR__ . '/includes/libs/filebackend/filejournal/FileJournal.php',
        'FileOp' => __DIR__ . '/includes/libs/filebackend/fileop/FileOp.php',
@@ -566,12 +565,13 @@ $wgAutoloadLocalClasses = [
        'GenerateNormalizerDataMl' => __DIR__ . '/maintenance/language/generateNormalizerDataMl.php',
        'GenerateSitemap' => __DIR__ . '/maintenance/generateSitemap.php',
        'GenericArrayObject' => __DIR__ . '/includes/libs/GenericArrayObject.php',
+       'GenericParameterJob' => __DIR__ . '/includes/jobqueue/GenericParameterJob.php',
        'GetConfiguration' => __DIR__ . '/maintenance/getConfiguration.php',
        'GetLagTimes' => __DIR__ . '/maintenance/getLagTimes.php',
        'GetReplicaServer' => __DIR__ . '/maintenance/getReplicaServer.php',
        'GetTextMaint' => __DIR__ . '/maintenance/getText.php',
        'GitInfo' => __DIR__ . '/includes/GitInfo.php',
-       'GlobalDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
+       'GlobalDependency' => __DIR__ . '/includes/cache/dependency/GlobalDependency.php',
        'GlobalVarConfig' => __DIR__ . '/includes/config/GlobalVarConfig.php',
        'GuzzleHttpRequest' => __DIR__ . '/includes/http/GuzzleHttpRequest.php',
        'HHVMMakeRepo' => __DIR__ . '/maintenance/hhvm/makeRepo.php',
@@ -629,10 +629,10 @@ $wgAutoloadLocalClasses = [
        'HashSiteStore' => __DIR__ . '/includes/site/HashSiteStore.php',
        'HashtableReplacer' => __DIR__ . '/includes/libs/replacers/HashtableReplacer.php',
        'HistoryAction' => __DIR__ . '/includes/actions/HistoryAction.php',
-       'HistoryBlob' => __DIR__ . '/includes/HistoryBlob.php',
-       'HistoryBlobCurStub' => __DIR__ . '/includes/HistoryBlob.php',
-       'HistoryBlobStub' => __DIR__ . '/includes/HistoryBlob.php',
-       'HistoryPager' => __DIR__ . '/includes/actions/HistoryAction.php',
+       'HistoryBlob' => __DIR__ . '/includes/historyblob/HistoryBlob.php',
+       'HistoryBlobCurStub' => __DIR__ . '/includes/historyblob/HistoryBlobCurStub.php',
+       'HistoryBlobStub' => __DIR__ . '/includes/historyblob/HistoryBlobStub.php',
+       'HistoryPager' => __DIR__ . '/includes/actions/pagers/HistoryPager.php',
        'Hooks' => __DIR__ . '/includes/Hooks.php',
        'Html' => __DIR__ . '/includes/Html.php',
        'HtmlArmor' => __DIR__ . '/includes/libs/HtmlArmor.php',
@@ -706,9 +706,6 @@ $wgAutoloadLocalClasses = [
        'JavaScriptMinifier' => __DIR__ . '/includes/libs/JavaScriptMinifier.php',
        'Job' => __DIR__ . '/includes/jobqueue/Job.php',
        'JobQueue' => __DIR__ . '/includes/jobqueue/JobQueue.php',
-       'JobQueueAggregator' => __DIR__ . '/includes/jobqueue/aggregator/JobQueueAggregator.php',
-       'JobQueueAggregatorNull' => __DIR__ . '/includes/jobqueue/aggregator/JobQueueAggregator.php',
-       'JobQueueAggregatorRedis' => __DIR__ . '/includes/jobqueue/aggregator/JobQueueAggregatorRedis.php',
        'JobQueueConnectionError' => __DIR__ . '/includes/jobqueue/exception/JobQueueConnectionError.php',
        'JobQueueDB' => __DIR__ . '/includes/jobqueue/JobQueueDB.php',
        'JobQueueEnqueueUpdate' => __DIR__ . '/includes/deferred/JobQueueEnqueueUpdate.php',
@@ -847,12 +844,12 @@ $wgAutoloadLocalClasses = [
        'MagicWordArray' => __DIR__ . '/includes/MagicWordArray.php',
        'MagicWordFactory' => __DIR__ . '/includes/MagicWordFactory.php',
        'MailAddress' => __DIR__ . '/includes/mail/MailAddress.php',
-       'MainConfigDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
+       'MainConfigDependency' => __DIR__ . '/includes/cache/dependency/MainConfigDependency.php',
        'MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
        'Maintenance' => __DIR__ . '/maintenance/Maintenance.php',
        'MakeTestEdits' => __DIR__ . '/maintenance/makeTestEdits.php',
        'MalformedTitleException' => __DIR__ . '/includes/title/MalformedTitleException.php',
-       'ManageForeignResources' => __DIR__ . '/maintenance/resources/manageForeignResources.php',
+       'ManageForeignResources' => __DIR__ . '/maintenance/manageForeignResources.php',
        'ManageJobs' => __DIR__ . '/maintenance/manageJobs.php',
        'ManualLogEntry' => __DIR__ . '/includes/logging/LogEntry.php',
        'MapCacheLRU' => __DIR__ . '/includes/libs/MapCacheLRU.php',
@@ -864,7 +861,7 @@ $wgAutoloadLocalClasses = [
        'MediaHandler' => __DIR__ . '/includes/media/MediaHandler.php',
        'MediaHandlerFactory' => __DIR__ . '/includes/media/MediaHandlerFactory.php',
        'MediaStatisticsPage' => __DIR__ . '/includes/specials/SpecialMediaStatistics.php',
-       'MediaTransformError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
+       'MediaTransformError' => __DIR__ . '/includes/media/MediaTransformError.php',
        'MediaTransformInvalidParametersException' => __DIR__ . '/includes/media/MediaTransformInvalidParametersException.php',
        'MediaTransformOutput' => __DIR__ . '/includes/media/MediaTransformOutput.php',
        'MediaWiki' => __DIR__ . '/includes/MediaWiki.php',
@@ -872,6 +869,7 @@ $wgAutoloadLocalClasses = [
        'MediaWikiSite' => __DIR__ . '/includes/site/MediaWikiSite.php',
        'MediaWikiTitleCodec' => __DIR__ . '/includes/title/MediaWikiTitleCodec.php',
        'MediaWikiVersionFetcher' => __DIR__ . '/includes/MediaWikiVersionFetcher.php',
+       'MediaWiki\\ChangeTags\\Taggable' => __DIR__ . '/includes/changetags/Taggable.php',
        'MediaWiki\\Config\\ConfigRepository' => __DIR__ . '/includes/config/ConfigRepository.php',
        'MediaWiki\\DB\\PatchFileLocation' => __DIR__ . '/includes/db/PatchFileLocation.php',
        'MediaWiki\\Diff\\ComplexityException' => __DIR__ . '/includes/diff/ComplexityException.php',
@@ -900,6 +898,7 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Logger\\Monolog\\LegacyHandler' => __DIR__ . '/includes/debug/logger/monolog/LegacyHandler.php',
        'MediaWiki\\Logger\\Monolog\\LineFormatter' => __DIR__ . '/includes/debug/logger/monolog/LineFormatter.php',
        'MediaWiki\\Logger\\Monolog\\LogstashFormatter' => __DIR__ . '/includes/debug/logger/monolog/LogstashFormatter.php',
+       'MediaWiki\\Logger\\Monolog\\MwlogHandler' => __DIR__ . '/includes/debug/logger/monolog/MwlogHandler.php',
        'MediaWiki\\Logger\\Monolog\\SyslogHandler' => __DIR__ . '/includes/debug/logger/monolog/SyslogHandler.php',
        'MediaWiki\\Logger\\Monolog\\WikiProcessor' => __DIR__ . '/includes/debug/logger/monolog/WikiProcessor.php',
        'MediaWiki\\Logger\\NullSpi' => __DIR__ . '/includes/debug/logger/NullSpi.php',
@@ -974,7 +973,7 @@ $wgAutoloadLocalClasses = [
        'MergeMessageFileList' => __DIR__ . '/maintenance/mergeMessageFileList.php',
        'MergeableUpdate' => __DIR__ . '/includes/deferred/MergeableUpdate.php',
        'Message' => __DIR__ . '/includes/Message.php',
-       'MessageBlobStore' => __DIR__ . '/includes/cache/MessageBlobStore.php',
+       'MessageBlobStore' => __DIR__ . '/includes/resourceloader/MessageBlobStore.php',
        'MessageCache' => __DIR__ . '/includes/cache/MessageCache.php',
        'MessageCacheUpdate' => __DIR__ . '/includes/deferred/MessageCacheUpdate.php',
        'MessageContent' => __DIR__ . '/includes/content/MessageContent.php',
@@ -1017,6 +1016,7 @@ $wgAutoloadLocalClasses = [
        'NamespaceAwareForeignTitleFactory' => __DIR__ . '/includes/title/NamespaceAwareForeignTitleFactory.php',
        'NamespaceDupes' => __DIR__ . '/maintenance/namespaceDupes.php',
        'NamespaceImportTitleFactory' => __DIR__ . '/includes/title/NamespaceImportTitleFactory.php',
+       'NamespaceInfo' => __DIR__ . '/includes/title/NamespaceInfo.php',
        'NewFilesPager' => __DIR__ . '/includes/specials/pagers/NewFilesPager.php',
        'NewPagesPager' => __DIR__ . '/includes/specials/pagers/NewPagesPager.php',
        'NewUsersLogFormatter' => __DIR__ . '/includes/logging/NewUsersLogFormatter.php',
@@ -1072,7 +1072,7 @@ $wgAutoloadLocalClasses = [
        'PPNode_Hash_Tree' => __DIR__ . '/includes/parser/Preprocessor_Hash.php',
        'PPTemplateFrame_DOM' => __DIR__ . '/includes/parser/Preprocessor_DOM.php',
        'PPTemplateFrame_Hash' => __DIR__ . '/includes/parser/Preprocessor_Hash.php',
-       'PackedHoverImageGallery' => __DIR__ . '/includes/gallery/PackedOverlayImageGallery.php',
+       'PackedHoverImageGallery' => __DIR__ . '/includes/gallery/PackedHoverImageGallery.php',
        'PackedImageGallery' => __DIR__ . '/includes/gallery/PackedImageGallery.php',
        'PackedOverlayImageGallery' => __DIR__ . '/includes/gallery/PackedOverlayImageGallery.php',
        'Page' => __DIR__ . '/includes/page/Page.php',
@@ -1108,10 +1108,10 @@ $wgAutoloadLocalClasses = [
        'PhpXmlBugTester' => __DIR__ . '/includes/installer/PhpBugTests.php',
        'Pingback' => __DIR__ . '/includes/Pingback.php',
        'PoolCounter' => __DIR__ . '/includes/poolcounter/PoolCounter.php',
+       'PoolCounterNull' => __DIR__ . '/includes/poolcounter/PoolCounterNull.php',
        'PoolCounterRedis' => __DIR__ . '/includes/poolcounter/PoolCounterRedis.php',
        'PoolCounterWork' => __DIR__ . '/includes/poolcounter/PoolCounterWork.php',
        'PoolCounterWorkViaCallback' => __DIR__ . '/includes/poolcounter/PoolCounterWorkViaCallback.php',
-       'PoolCounter_Stub' => __DIR__ . '/includes/poolcounter/PoolCounter.php',
        'PoolWorkArticleView' => __DIR__ . '/includes/poolcounter/PoolWorkArticleView.php',
        'PopulateArchiveRevId' => __DIR__ . '/maintenance/populateArchiveRevId.php',
        'PopulateBacklinkNamespace' => __DIR__ . '/maintenance/populateBacklinkNamespace.php',
@@ -1134,11 +1134,10 @@ $wgAutoloadLocalClasses = [
        'PostgreSqlLockManager' => __DIR__ . '/includes/libs/lockmanager/PostgreSqlLockManager.php',
        'PostgresInstaller' => __DIR__ . '/includes/installer/PostgresInstaller.php',
        'PostgresUpdater' => __DIR__ . '/includes/installer/PostgresUpdater.php',
-       'Preferences' => __DIR__ . '/includes/Preferences.php',
        'PreferencesForm' => __DIR__ . '/includes/specials/forms/PreferencesFormLegacy.php',
        'PreferencesFormLegacy' => __DIR__ . '/includes/specials/forms/PreferencesFormLegacy.php',
        'PreferencesFormOOUI' => __DIR__ . '/includes/specials/forms/PreferencesFormOOUI.php',
-       'PrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
+       'PrefixSearch' => __DIR__ . '/includes/search/PrefixSearch.php',
        'PrefixingStatsdDataFactoryProxy' => __DIR__ . '/includes/libs/stats/PrefixingStatsdDataFactoryProxy.php',
        'PreprocessDump' => __DIR__ . '/maintenance/preprocessDump.php',
        'Preprocessor' => __DIR__ . '/includes/parser/Preprocessor.php',
@@ -1188,7 +1187,7 @@ $wgAutoloadLocalClasses = [
        'RSSFeed' => __DIR__ . '/includes/Feed.php',
        'RandomPage' => __DIR__ . '/includes/specials/SpecialRandompage.php',
        'RangeChronologicalPager' => __DIR__ . '/includes/pager/RangeChronologicalPager.php',
-       'RangeDifference' => __DIR__ . '/includes/diff/DiffEngine.php',
+       'RangeDifference' => __DIR__ . '/includes/diff/RangeDifference.php',
        'RawAction' => __DIR__ . '/includes/actions/RawAction.php',
        'RawMessage' => __DIR__ . '/includes/RawMessage.php',
        'ReadOnlyError' => __DIR__ . '/includes/exception/ReadOnlyError.php',
@@ -1199,13 +1198,12 @@ $wgAutoloadLocalClasses = [
        'RebuildLocalisationCache' => __DIR__ . '/maintenance/rebuildLocalisationCache.php',
        'RebuildMessages' => __DIR__ . '/maintenance/rebuildmessages.php',
        'RebuildRecentchanges' => __DIR__ . '/maintenance/rebuildrecentchanges.php',
-       'RebuildSitesCache' => __DIR__ . '/maintenance/rebuildSitesCache.php',
        'RebuildTextIndex' => __DIR__ . '/maintenance/rebuildtextindex.php',
        'RecentChange' => __DIR__ . '/includes/changes/RecentChange.php',
        'RecentChangesUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/RecentChangesUpdateJob.php',
        'RecompressTracked' => __DIR__ . '/maintenance/storage/recompressTracked.php',
        'RecountCategories' => __DIR__ . '/maintenance/recountCategories.php',
-       'RedirectSpecialArticle' => __DIR__ . '/includes/specialpage/RedirectSpecialPage.php',
+       'RedirectSpecialArticle' => __DIR__ . '/includes/specialpage/RedirectSpecialArticle.php',
        'RedirectSpecialPage' => __DIR__ . '/includes/specialpage/RedirectSpecialPage.php',
        'RedisBagOStuff' => __DIR__ . '/includes/libs/objectcache/RedisBagOStuff.php',
        'RedisConnRef' => __DIR__ . '/includes/libs/redis/RedisConnRef.php',
@@ -1280,10 +1278,10 @@ $wgAutoloadLocalClasses = [
        'Revision' => __DIR__ . '/includes/Revision.php',
        'RevisionDeleteUser' => __DIR__ . '/includes/revisiondelete/RevisionDeleteUser.php',
        'RevisionDeleter' => __DIR__ . '/includes/revisiondelete/RevisionDeleter.php',
-       'RevisionItem' => __DIR__ . '/includes/RevisionList.php',
-       'RevisionItemBase' => __DIR__ . '/includes/RevisionList.php',
-       'RevisionList' => __DIR__ . '/includes/RevisionList.php',
-       'RevisionListBase' => __DIR__ . '/includes/RevisionList.php',
+       'RevisionItem' => __DIR__ . '/includes/revisionlist/RevisionItem.php',
+       'RevisionItemBase' => __DIR__ . '/includes/revisionlist/RevisionItemBase.php',
+       'RevisionList' => __DIR__ . '/includes/revisionlist/RevisionList.php',
+       'RevisionListBase' => __DIR__ . '/includes/revisionlist/RevisionListBase.php',
        'RiffExtractor' => __DIR__ . '/includes/libs/RiffExtractor.php',
        'RightsLogFormatter' => __DIR__ . '/includes/logging/RightsLogFormatter.php',
        'RollbackAction' => __DIR__ . '/includes/actions/RollbackAction.php',
@@ -1291,6 +1289,7 @@ $wgAutoloadLocalClasses = [
        'RowUpdateGenerator' => __DIR__ . '/includes/utils/RowUpdateGenerator.php',
        'RunBatchedQuery' => __DIR__ . '/maintenance/runBatchedQuery.php',
        'RunJobs' => __DIR__ . '/maintenance/runJobs.php',
+       'RunnableJob' => __DIR__ . '/includes/jobqueue/RunnableJob.php',
        'SVGMetadataExtractor' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
        'SVGReader' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
        'SamplingStatsdClient' => __DIR__ . '/includes/libs/stats/SamplingStatsdClient.php',
@@ -1301,7 +1300,7 @@ $wgAutoloadLocalClasses = [
        'SearchDump' => __DIR__ . '/maintenance/dumpIterator.php',
        'SearchEngine' => __DIR__ . '/includes/search/SearchEngine.php',
        'SearchEngineConfig' => __DIR__ . '/includes/search/SearchEngineConfig.php',
-       'SearchEngineDummy' => __DIR__ . '/includes/search/SearchEngine.php',
+       'SearchEngineDummy' => __DIR__ . '/includes/search/SearchEngineDummy.php',
        'SearchEngineFactory' => __DIR__ . '/includes/search/SearchEngineFactory.php',
        'SearchExactMatchRescorer' => __DIR__ . '/includes/search/SearchExactMatchRescorer.php',
        'SearchHighlighter' => __DIR__ . '/includes/search/SearchHighlighter.php',
@@ -1336,7 +1335,6 @@ $wgAutoloadLocalClasses = [
        'SiteStatsInit' => __DIR__ . '/includes/SiteStatsInit.php',
        'SiteStatsUpdate' => __DIR__ . '/includes/deferred/SiteStatsUpdate.php',
        'SiteStore' => __DIR__ . '/includes/site/SiteStore.php',
-       'SitesCacheFileBuilder' => __DIR__ . '/includes/site/SitesCacheFileBuilder.php',
        'Skin' => __DIR__ . '/includes/skins/Skin.php',
        'SkinApi' => __DIR__ . '/includes/skins/SkinApi.php',
        'SkinApiTemplate' => __DIR__ . '/includes/skins/SkinApiTemplate.php',
@@ -1349,7 +1347,7 @@ $wgAutoloadLocalClasses = [
        'SlotDiffRenderer' => __DIR__ . '/includes/diff/SlotDiffRenderer.php',
        'SpecialActiveUsers' => __DIR__ . '/includes/specials/SpecialActiveusers.php',
        'SpecialAllMessages' => __DIR__ . '/includes/specials/SpecialAllMessages.php',
-       'SpecialAllMyUploads' => __DIR__ . '/includes/specials/SpecialMyRedirectPages.php',
+       'SpecialAllMyUploads' => __DIR__ . '/includes/specials/redirects/SpecialAllMyUploads.php',
        'SpecialAllPages' => __DIR__ . '/includes/specials/SpecialAllPages.php',
        'SpecialApiHelp' => __DIR__ . '/includes/specials/SpecialApiHelp.php',
        'SpecialApiSandbox' => __DIR__ . '/includes/specials/SpecialApiSandbox.php',
@@ -1379,8 +1377,8 @@ $wgAutoloadLocalClasses = [
        'SpecialImport' => __DIR__ . '/includes/specials/SpecialImport.php',
        'SpecialJavaScriptTest' => __DIR__ . '/includes/specials/SpecialJavaScriptTest.php',
        'SpecialLinkAccounts' => __DIR__ . '/includes/specials/SpecialLinkAccounts.php',
-       'SpecialListAdmins' => __DIR__ . '/includes/specials/SpecialListusers.php',
-       'SpecialListBots' => __DIR__ . '/includes/specials/SpecialListusers.php',
+       'SpecialListAdmins' => __DIR__ . '/includes/specials/redirects/SpecialListAdmins.php',
+       'SpecialListBots' => __DIR__ . '/includes/specials/redirects/SpecialListBots.php',
        'SpecialListFiles' => __DIR__ . '/includes/specials/SpecialListfiles.php',
        'SpecialListGrants' => __DIR__ . '/includes/specials/SpecialListgrants.php',
        'SpecialListGroupRights' => __DIR__ . '/includes/specials/SpecialListgrouprights.php',
@@ -1389,10 +1387,10 @@ $wgAutoloadLocalClasses = [
        'SpecialLog' => __DIR__ . '/includes/specials/SpecialLog.php',
        'SpecialMergeHistory' => __DIR__ . '/includes/specials/SpecialMergeHistory.php',
        'SpecialMyLanguage' => __DIR__ . '/includes/specials/SpecialMyLanguage.php',
-       'SpecialMycontributions' => __DIR__ . '/includes/specials/SpecialMyRedirectPages.php',
-       'SpecialMypage' => __DIR__ . '/includes/specials/SpecialMyRedirectPages.php',
-       'SpecialMytalk' => __DIR__ . '/includes/specials/SpecialMyRedirectPages.php',
-       'SpecialMyuploads' => __DIR__ . '/includes/specials/SpecialMyRedirectPages.php',
+       'SpecialMycontributions' => __DIR__ . '/includes/specials/redirects/SpecialMycontributions.php',
+       'SpecialMypage' => __DIR__ . '/includes/specials/redirects/SpecialMypage.php',
+       'SpecialMytalk' => __DIR__ . '/includes/specials/redirects/SpecialMytalk.php',
+       'SpecialMyuploads' => __DIR__ . '/includes/specials/redirects/SpecialMyuploads.php',
        'SpecialNewFiles' => __DIR__ . '/includes/specials/SpecialNewimages.php',
        'SpecialNewpages' => __DIR__ . '/includes/specials/SpecialNewpages.php',
        'SpecialPage' => __DIR__ . '/includes/specialpage/SpecialPage.php',
@@ -1414,7 +1412,7 @@ $wgAutoloadLocalClasses = [
        'SpecialRecentChanges' => __DIR__ . '/includes/specials/SpecialRecentchanges.php',
        'SpecialRecentChangesLinked' => __DIR__ . '/includes/specials/SpecialRecentchangeslinked.php',
        'SpecialRedirect' => __DIR__ . '/includes/specials/SpecialRedirect.php',
-       'SpecialRedirectToSpecial' => __DIR__ . '/includes/specialpage/RedirectSpecialPage.php',
+       'SpecialRedirectToSpecial' => __DIR__ . '/includes/specialpage/SpecialRedirectToSpecial.php',
        'SpecialRemoveCredentials' => __DIR__ . '/includes/specials/SpecialRemoveCredentials.php',
        'SpecialResetTokens' => __DIR__ . '/includes/specials/SpecialResetTokens.php',
        'SpecialRevisionDelete' => __DIR__ . '/includes/specials/SpecialRevisiondelete.php',
@@ -1452,7 +1450,7 @@ $wgAutoloadLocalClasses = [
        'StorageTypeStats' => __DIR__ . '/maintenance/storage/storageTypeStats.php',
        'StoreFileOp' => __DIR__ . '/includes/libs/filebackend/fileop/StoreFileOp.php',
        'StreamFile' => __DIR__ . '/includes/StreamFile.php',
-       'StringPrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
+       'StringPrefixSearch' => __DIR__ . '/includes/search/StringPrefixSearch.php',
        'StringUtils' => __DIR__ . '/includes/libs/StringUtils.php',
        'StripState' => __DIR__ . '/includes/parser/StripState.php',
        'StubObject' => __DIR__ . '/includes/StubObject.php',
@@ -1482,7 +1480,7 @@ $wgAutoloadLocalClasses = [
        'TextStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'TgConverter' => __DIR__ . '/languages/classes/LanguageTg.php',
        'ThrottledError' => __DIR__ . '/includes/exception/ThrottledError.php',
-       'ThumbnailImage' => __DIR__ . '/includes/media/MediaTransformOutput.php',
+       'ThumbnailImage' => __DIR__ . '/includes/media/ThumbnailImage.php',
        'ThumbnailRenderJob' => __DIR__ . '/includes/jobqueue/jobs/ThumbnailRenderJob.php',
        'TidyUpT39714' => __DIR__ . '/maintenance/tidyUpT39714.php',
        'TiffHandler' => __DIR__ . '/includes/media/TiffHandler.php',
@@ -1493,14 +1491,14 @@ $wgAutoloadLocalClasses = [
        'TitleCleanup' => __DIR__ . '/maintenance/cleanupTitles.php',
        'TitleFormatter' => __DIR__ . '/includes/title/TitleFormatter.php',
        'TitleParser' => __DIR__ . '/includes/title/TitleParser.php',
-       'TitlePrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
+       'TitlePrefixSearch' => __DIR__ . '/includes/search/TitlePrefixSearch.php',
        'TitleValue' => __DIR__ . '/includes/title/TitleValue.php',
        'TrackBlobs' => __DIR__ . '/maintenance/storage/trackBlobs.php',
        'TrackingCategories' => __DIR__ . '/includes/TrackingCategories.php',
        'TraditionalImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
        'TransactionRoundDefiningUpdate' => __DIR__ . '/includes/deferred/TransactionRoundDefiningUpdate.php',
-       'TransformParameterError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
-       'TransformTooBigImageAreaError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
+       'TransformParameterError' => __DIR__ . '/includes/media/TransformParameterError.php',
+       'TransformTooBigImageAreaError' => __DIR__ . '/includes/media/TransformTooBigImageAreaError.php',
        'TransformationalImageHandler' => __DIR__ . '/includes/media/TransformationalImageHandler.php',
        'UDPRCFeedEngine' => __DIR__ . '/includes/rcfeed/UDPRCFeedEngine.php',
        'UDPTransport' => __DIR__ . '/includes/libs/UDPTransport.php',
@@ -1627,7 +1625,7 @@ $wgAutoloadLocalClasses = [
        'WikiTextStructure' => __DIR__ . '/includes/content/WikiTextStructure.php',
        'Wikimedia\\Http\\HttpAcceptNegotiator' => __DIR__ . '/includes/libs/http/HttpAcceptNegotiator.php',
        'Wikimedia\\Http\\HttpAcceptParser' => __DIR__ . '/includes/libs/http/HttpAcceptParser.php',
-       'Wikimedia\\Rdbms\\AtomicSectionIdentifier' => __DIR__ . '/includes/libs/rdbms/database/AtomicSectionIdentifier.php',
+       'Wikimedia\\Rdbms\\AtomicSectionIdentifier' => __DIR__ . '/includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php',
        'Wikimedia\\Rdbms\\Blob' => __DIR__ . '/includes/libs/rdbms/encasing/Blob.php',
        'Wikimedia\\Rdbms\\ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php',
        'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php',
@@ -1640,13 +1638,14 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\DBQueryError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryError.php',
        'Wikimedia\\Rdbms\\DBQueryTimeoutError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryTimeoutError.php',
        'Wikimedia\\Rdbms\\DBReadOnlyError' => __DIR__ . '/includes/libs/rdbms/exception/DBReadOnlyError.php',
+       'Wikimedia\\Rdbms\\DBReadOnlyRoleError' => __DIR__ . '/includes/libs/rdbms/exception/DBReadOnlyRoleError.php',
        'Wikimedia\\Rdbms\\DBReplicationWaitError' => __DIR__ . '/includes/libs/rdbms/exception/DBReplicationWaitError.php',
        'Wikimedia\\Rdbms\\DBTransactionError' => __DIR__ . '/includes/libs/rdbms/exception/DBTransactionError.php',
        'Wikimedia\\Rdbms\\DBTransactionSizeError' => __DIR__ . '/includes/libs/rdbms/exception/DBTransactionSizeError.php',
        'Wikimedia\\Rdbms\\DBTransactionStateError' => __DIR__ . '/includes/libs/rdbms/exception/DBTransactionStateError.php',
        'Wikimedia\\Rdbms\\DBUnexpectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBUnexpectedError.php',
        'Wikimedia\\Rdbms\\Database' => __DIR__ . '/includes/libs/rdbms/database/Database.php',
-       'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php',
+       'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/domain/DatabaseDomain.php',
        'Wikimedia\\Rdbms\\DatabaseMssql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMssql.php',
        'Wikimedia\\Rdbms\\DatabaseMysqlBase' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqlBase.php',
        'Wikimedia\\Rdbms\\DatabaseMysqli' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqli.php',
@@ -1709,8 +1708,8 @@ $wgAutoloadLocalClasses = [
        'ZhConverter' => __DIR__ . '/languages/classes/LanguageZh.php',
        'ZipDirectoryReader' => __DIR__ . '/includes/utils/ZipDirectoryReader.php',
        'ZipDirectoryReaderError' => __DIR__ . '/includes/utils/ZipDirectoryReaderError.php',
-       'concatenatedgziphistoryblob' => __DIR__ . '/includes/HistoryBlob.php',
-       'historyblobcurstub' => __DIR__ . '/includes/HistoryBlob.php',
-       'historyblobstub' => __DIR__ . '/includes/HistoryBlob.php',
+       'concatenatedgziphistoryblob' => __DIR__ . '/includes/historyblob/ConcatenatedGzipHistoryBlob.php',
+       'historyblobcurstub' => __DIR__ . '/includes/historyblob/HistoryBlobCurStub.php',
+       'historyblobstub' => __DIR__ . '/includes/historyblob/HistoryBlobStub.php',
        'profile_point' => __DIR__ . '/profileinfo.php',
 ];
index 0169d45..b6814c5 100644 (file)
@@ -27,7 +27,7 @@
                "ext-xml": "*",
                "guzzlehttp/guzzle": "6.3.3",
                "liuggio/statsd-php-client": "1.0.18",
-               "oojs/oojs-ui": "0.30.3",
+               "oojs/oojs-ui": "0.31.3",
                "pear/mail": "1.4.1",
                "pear/mail_mime": "1.10.2",
                "pear/net_smtp": "1.8.1",
@@ -64,9 +64,8 @@
                "hamcrest/hamcrest-php": "^2.0",
                "jakub-onderka/php-console-highlighter": "0.3.2",
                "jakub-onderka/php-parallel-lint": "0.9.2",
-               "jetbrains/phpstorm-stubs": "dev-master#38ff1a581b297f7901e961b8c923862ea80c3b96",
                "justinrainbow/json-schema": "~5.2",
-               "mediawiki/mediawiki-codesniffer": "24.0.0",
+               "mediawiki/mediawiki-codesniffer": "25.0.0",
                "monolog/monolog": "~1.22.1",
                "nikic/php-parser": "3.1.5",
                "seld/jsonlint": "1.7.1",
@@ -75,7 +74,8 @@
                "psy/psysh": "0.9.9",
                "wikimedia/avro": "1.8.0",
                "wikimedia/testing-access-wrapper": "~1.0",
-               "wmde/hamcrest-html-matchers": "^0.1.0"
+               "wmde/hamcrest-html-matchers": "^0.1.0",
+               "mediawiki/mediawiki-phan-config": "0.5.0"
        },
        "replace": {
                "symfony/polyfill-ctype": "1.99",
index 9d5d49e..6291bfc 100644 (file)
                                <!-- This isn't a good idea; we should be using "ID" instead of "NMTOKEN" -->
                                <!-- However, "NMTOKEN" is strictest definition that is both compatible with existing -->
                                <!-- usage ([0-9]+) and with the "ID" type. -->
-                               <attribute name="id" type="NMTOKEN" />
+                               <attribute name="id" use="optional" type="NMTOKEN" />
                                <attribute name="bytes" use="optional" type="nonNegativeInteger" />
                        </extension>
                </simpleContent>
index 8b5e4d7..b2f1e81 100644 (file)
@@ -787,16 +787,6 @@ $extraData: An array (string => string) with extra information, intended to be
   added to log contexts. Fields it might include:
   - appId: the application ID, only if the login was with a bot password
 
-'AuthPluginAutoCreate': DEPRECATED since 1.27! Use the 'LocalUserCreated' hook
-instead. Called when creating a local account for an user logged in from an
-external authentication method.
-$user: User object created locally
-
-'AuthPluginSetup': DEPRECATED since 1.27! Extensions should be updated to use
-AuthManager. Update or replace authentication plugin object ($wgAuth). Gives a
-chance for an extension to set it programmatically to a variable class.
-&$auth: the $wgAuth object, probably a stub
-
 'AutopromoteCondition': Check autopromote condition for user.
 $type: condition type
 $args: arguments
@@ -1203,9 +1193,6 @@ a custom editor, e.g. for a special namespace, etc.
 $article: Article being edited
 $user: User performing the edit
 
-'DatabaseOraclePostInit': Called after initialising an Oracle database
-$db: the DatabaseOracle object
-
 'DeletedContribsPager::reallyDoQuery': Called before really executing the query
 for Special:DeletedContributions
 Similar to ContribsPager::reallyDoQuery
@@ -1622,7 +1609,7 @@ $out: OutputPage object
 notifications.
 &$title: Title object of page
 &$url: string value as output (out parameter, can modify)
-$query: query options passed to Title::getCanonicalURL()
+$query: query options as string passed to Title::getCanonicalURL()
 
 'GetContentModels': Add content models to the list of available models.
 &$models: array containing current model list, as strings. Extensions should add to this list.
@@ -1660,7 +1647,7 @@ $single: Only extract the current language; if false, the prop value should
 'GetFullURL': Modify fully-qualified URLs used in redirects/export/offsite data.
 &$title: Title object of page
 &$url: string value as output (out parameter, can modify)
-$query: query options passed to Title::getFullURL()
+$query: query options as string passed to Title::getFullURL()
 
 'GetHumanTimestamp': Pre-emptively override the human-readable timestamp
 generated by MWTimestamp::getHumanTimestamp(). Return false in this hook to use
@@ -1674,7 +1661,7 @@ $lang: Language that will be used to render the timestamp
 'GetInternalURL': Modify fully-qualified URLs used for squid cache purging.
 &$title: Title object of page
 &$url: string value as output (out parameter, can modify)
-$query: query options passed to Title::getInternalURL()
+$query: query options as string passed to Title::getInternalURL()
 
 'GetIP': modify the ip of the current user (called only once).
 &$ip: string holding the ip as determined so far
@@ -1699,7 +1686,7 @@ be buggy for internal urls on render if you do not re-implement the horrible
 hack that Title::getLocalURL uses in your own extension.
 &$title: Title object of page
 &$url: string value as output (out parameter, can modify)
-$query: query options passed to Title::getLocalURL()
+$query: query options as string passed to Title::getLocalURL()
 
 'GetLocalURL::Article': Modify local URLs specifically pointing to article paths
 without any fancy queries or variants.
@@ -1709,7 +1696,7 @@ without any fancy queries or variants.
 'GetLocalURL::Internal': Modify local URLs to internal pages.
 &$title: Title object of page
 &$url: string value as output (out parameter, can modify)
-$query: query options passed to Title::getLocalURL()
+$query: query options as string passed to Title::getLocalURL()
 
 'GetLogTypesOnUser': Add log types where the target is a userpage
 &$types: Array of log types
@@ -2208,6 +2195,16 @@ Special:LonelyPages.
 'MagicWordwgVariableIDs': When defining new magic words IDs.
 &$variableIDs: array of strings
 
+'MaintenanceUpdateAddParams': allow extensions to add params to the update.php
+maintenance script.
+&$params: array to populate with the params to be added. Array elements are keyed by
+the param name. Each param is an associative array that must include the following keys:
+  - desc The description of the param to show on --help
+  - require Is the param required? Defaults to false if not set.
+  - withArg Is an argument required with this option?  Defaults to false if not set.
+  - shortName Character to use as short name, or false if none.  Defaults to false if not set.
+  - multiOccurrence Can this option be passed multiple times?  Defaults to false if not set.
+
 'MaintenanceRefreshLinksInit': before executing the refreshLinks.php maintenance
 script.
 $refreshLinks: RefreshLinks object
@@ -2220,12 +2217,17 @@ ResourceLoaderGetConfigVars instead.
   Skin::makeVariablesScript
 $out: The OutputPage which called the hook, can be used to get the real title.
 
+'ManualLogEntryBeforePublish': Allows to access or modify log entry just before it is
+published.
+$logEntry: ManualLogEntry object
+
 'MarkPatrolled': Before an edit is marked patrolled.
 $rcid: ID of the revision to be marked patrolled
 &$user: the user (object) marking the revision as patrolled
 $wcOnlySysopsCanPatrol: config setting indicating whether the user needs to be a
   sysop in order to mark an edit patrolled.
 $auto: true if the edit is being marked as patrolled automatically
+&$tags: the tags to be applied to the patrol log entry
 
 'MarkPatrolledComplete': After an edit is marked patrolled.
 $rcid: ID of the revision marked as patrolled
@@ -2328,7 +2330,7 @@ namespace.
 $index: Integer; the index of the namespace being checked.
 &$result: Boolean; whether MediaWiki currently thinks that pages in this
   namespace are movable. Hooks may change this value to override the return
-  value of MWNamespace::isMovable().
+  value of NamespaceInfo::isMovable().
 
 'NewDifferenceEngine': Called when a new DifferenceEngine object is made
 $title: the diff page title (nullable)
@@ -2441,19 +2443,25 @@ $flags: Flags passed to WikiPage::doEditContent()
 $revision: New Revision of the article
 
 'PageContentLanguage': Allows changing the language in which the content of a
-page is written. Defaults to the wiki content language ($wgContLang).
+page is written. Defaults to the wiki content language.
 $title: Title object
-&$pageLang: the page content language (either an object or a language code)
-$wgLang: the user language
+&$pageLang: the page content language. Input can be anything (under control of
+  hook subscribers), but hooks should return Language objects. Language code
+  strings are deprecated.
+$userLang: the user language (Language or StubUserLang object)
 
 'PageContentSave': Before an article is saved.
 $wikiPage: the WikiPage (object) being saved
 $user: the user (object) saving the article
 $content: the new article content, as a Content object
-$summary: the article summary (comment)
-$isminor: minor flag
-$iswatch: watch flag
-$section: section #
+&$summary: CommentStoreComment object containing the edit comment. Can be replaced with a new one.
+$isminor: Boolean flag specifying if the edit was marked as minor.
+$iswatch: Previously a watch flag. Currently unused, always null.
+$section: Previously the section number being edited. Currently unused, always null.
+$flags: All EDIT_… flags (including EDIT_MINOR) as an integer number. See WikiPage::doEditContent
+  documentation for flags' definition.
+$status: StatusValue object for the hook handlers resulting status. Either set $status->fatal() or
+  return false to abort the save action.
 
 'PageContentSaveComplete': After an article has been updated.
 $wikiPage: WikiPage modified
@@ -3837,6 +3845,23 @@ the database) have been saved. Compare to the UserSaveOptions hook, which is
 called before.
 $user: The User for which the options have been saved
 
+'UserSendConfirmationMail': Called just before a confirmation email is sent to
+a user. Hook handlers can modify the email that will be sent.
+$user: The User for which the confirmation email is going to be sent
+&$mail: Associative array describing the email, with the following keys:
+  - subject: Subject line of the email
+  - body: Email body. Can be a string, or an array with keys 'text' and 'html'
+  - from: User object, or null meaning $wgPasswordSender will be used
+  - replyTo: MailAddress object or null
+$info: Associative array with additional information:
+  - type: 'created' if the user's account was just created; 'set' if the user
+    set an email address when they previously didn't have one; 'changed' if
+    the user had an email address and changed it
+  - ip: The IP address from which the user set/changed their email address
+  - confirmURL: URL the user should visit to confirm their email
+  - invalidateURL: URL the user should visit to invalidate confirmURL
+  - expiration: time and date when confirmURL expires
+
 'UserSetCookies': DEPRECATED since 1.27! If you're trying to replace core
 session cookie handling, you want to create a subclass of
 MediaWiki\Session\CookieSessionProvider instead. Otherwise, you can no longer
index 2badea9..83a14c7 100644 (file)
@@ -219,7 +219,7 @@ already known to MediaWikiServices (if not, see above).
   variables.
 * Add a constructor to MyExtHooks that takes a Bar service as a parameter.
 * Add a static method called newFromGlobalState() with no parameters. It should
-  just return new MyExtHooks( MediaWikiServices::getBar() ).
+  just return new MyExtHooks( MediaWikiServices::getInstance()->getBar() ).
 * The original static handler method onFoo( $x ) is then implemented as
   self::newFromGlobalState()->doFoo( $x ).
 
index 19476a3..998292c 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <!DOCTYPE rdf:RDF [
+  <!ENTITY cc "http://creativecommons.org/ns#">
   <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
   <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
   <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
   xmlns:rdf="&rdf;"
   xmlns:rdfs="&rdfs;"
   xmlns:owl="&owl;"
+  xmlns:cc="&cc;"
 >
 
   <owl:Ontology rdf:about="&mediawiki;">
     <rdfs:label>MediaWiki ontology</rdfs:label>
     <rdfs:comment>The ontology of MediaWiki</rdfs:comment>
+    <cc:licence rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
   </owl:Ontology>
 
   <!--
diff --git a/docs/sitescache.txt b/docs/sitescache.txt
deleted file mode 100644 (file)
index 13bf371..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-MediaWiki's SiteStore can be cached and stored in a flat file,
-in a json format. If the SiteStore is frequently accessed, the
-file cache may provide a performance benefit over a database
-store, even with memcached in front of it.
-
-Configuration:
-
-File-based caching can be enabled by setting $wgSitesCacheFile
-to the file path of the cache file.
-
-The file can then be generated with the rebuildSitesCache.php
-maintenance script.
-
-Format:
-
-In the sites cache file, sites are listed in a key-value
-map, with the key being the site's global id (e.g. "enwiki")
-and a key-value map as the value. The site list is wrapped
-with in a "sites" key.
-
-Example:
-
-"sites": {
-       "aawiktionary": {
-               "globalid": "aawiktionary",
-               "type": "mediawiki",
-               "group": "wiktionary",
-               "source": "local",
-               "language": "aa",
-               "localids": [],
-               "config": [],
-               "data": {
-                       "paths": {
-                               "file_path": "http:\/\/aa.wiktionary.org\/w\/$1",
-                               "page_path": "http:\/\/aa.wiktionary.org\/wiki\/$1"
-                       }
-               },
-               "forward": false,
-               "internalid": 2666,
-               "identifiers": []
-       }
-}
index ca69d31..0a209e9 100644 (file)
@@ -148,7 +148,7 @@ function wfImageAuthMain() {
                }
 
                // Run hook for extension authorization plugins
-               /** @var $result array */
+               /** @var array $result */
                $result = null;
                if ( !Hooks::run( 'ImgAuthBeforeStream', [ &$title, &$path, &$name, &$result ] ) ) {
                        wfForbidden( $result[0], $result[1], array_slice( $result, 2 ) );
@@ -186,13 +186,12 @@ function wfImageAuthMain() {
  * subsequent arguments to $msg2 will be passed as parameters only for replacing in $msg2
  * @param string $msg1
  * @param string $msg2
+ * @param mixed ...$args To pass as params to wfMessage() with $msg2. Either variadic, or a single
+ *   array argument.
  */
-function wfForbidden( $msg1, $msg2 ) {
+function wfForbidden( $msg1, $msg2, ...$args ) {
        global $wgImgAuthDetails;
 
-       $args = func_get_args();
-       array_shift( $args );
-       array_shift( $args );
        $args = ( isset( $args[0] ) && is_array( $args[0] ) ) ? $args[0] : $args;
 
        $msgHdr = wfMessage( $msg1 )->escaped();
index 0c33eb9..597b8e7 100644 (file)
@@ -136,11 +136,7 @@ class ActorMigration {
         * @return string[] [ $text, $actor ]
         */
        private static function getFieldNames( $key ) {
-               if ( isset( self::$specialFields[$key] ) ) {
-                       return self::$specialFields[$key];
-               }
-
-               return [ $key . '_text', substr( $key, 0, -5 ) . '_actor' ];
+               return self::$specialFields[$key] ?? [ $key . '_text', substr( $key, 0, -5 ) . '_actor' ];
        }
 
        /**
index dfcf467..5f889ad 100644 (file)
@@ -162,7 +162,7 @@ class AjaxResponse {
                        // For back-compat, it is supported that mResponseCode be a string like " 200 OK"
                        // (with leading space and the status message after). Cast response code to an integer
                        // to take advantage of PHP's conversion rules which will turn "  200 OK" into 200.
-                       // https://secure.php.net/manual/en/language.types.string.php#language.types.string.conversion
+                       // https://www.php.net/manual/en/language.types.string.php#language.types.string.conversion
                        $n = intval( trim( $this->mResponseCode ) );
                        HttpStatus::header( $n );
                }
@@ -282,7 +282,8 @@ class AjaxResponse {
                        return false;
                }
 
-               $mcvalue = ObjectCache::getMainWANInstance()->get( $mckey );
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+               $mcvalue = $cache->get( $mckey );
                if ( $mcvalue ) {
                        # Check to see if the value has been invalidated
                        if ( $touched <= $mcvalue['timestamp'] ) {
@@ -304,11 +305,13 @@ class AjaxResponse {
         * @return bool
         */
        function storeInMemcached( $mckey, $expiry = 86400 ) {
-               ObjectCache::getMainWANInstance()->set( $mckey,
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+               $cache->set( $mckey,
                        [
                                'timestamp' => wfTimestampNow(),
                                'value' => $this->mText
-                       ], $expiry
+                       ],
+                       $expiry
                );
 
                return true;
diff --git a/includes/AuthPlugin.php b/includes/AuthPlugin.php
deleted file mode 100644 (file)
index e12db24..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-<?php
-/**
- * Authentication plugin interface
- *
- * Copyright © 2004 Brion Vibber <brion@pobox.com>
- * https://www.mediawiki.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Authentication plugin interface. Instantiate a subclass of AuthPlugin
- * and set $wgAuth to it to authenticate against some external tool.
- *
- * The default behavior is not to do anything, and use the local user
- * database for all authentication. A subclass can require that all
- * accounts authenticate externally, or use it only as a fallback; also
- * you can transparently create internal wiki accounts the first time
- * someone logs in who can be authenticated externally.
- *
- * @deprecated since 1.27
- */
-class AuthPlugin {
-       /**
-        * @var string
-        */
-       protected $domain;
-
-       /**
-        * Check whether there exists a user account with the given name.
-        * The name will be normalized to MediaWiki's requirements, so
-        * you might need to munge it (for instance, for lowercase initial
-        * letters).
-        *
-        * @param string $username Username.
-        * @return bool
-        */
-       public function userExists( $username ) {
-               # Override this!
-               return false;
-       }
-
-       /**
-        * Check if a username+password pair is a valid login.
-        * The name will be normalized to MediaWiki's requirements, so
-        * you might need to munge it (for instance, for lowercase initial
-        * letters).
-        *
-        * @param string $username Username.
-        * @param string $password User password.
-        * @return bool
-        */
-       public function authenticate( $username, $password ) {
-               # Override this!
-               return false;
-       }
-
-       /**
-        * Modify options in the login template.
-        *
-        * @param BaseTemplate &$template
-        * @param string &$type 'signup' or 'login'. Added in 1.16.
-        */
-       public function modifyUITemplate( &$template, &$type ) {
-               # Override this!
-               $template->set( 'usedomain', false );
-       }
-
-       /**
-        * Set the domain this plugin is supposed to use when authenticating.
-        *
-        * @param string $domain Authentication domain.
-        */
-       public function setDomain( $domain ) {
-               $this->domain = $domain;
-       }
-
-       /**
-        * Get the user's domain
-        *
-        * @return string
-        */
-       public function getDomain() {
-               return $this->domain ?? 'invaliddomain';
-       }
-
-       /**
-        * Check to see if the specific domain is a valid domain.
-        *
-        * @param string $domain Authentication domain.
-        * @return bool
-        */
-       public function validDomain( $domain ) {
-               # Override this!
-               return true;
-       }
-
-       /**
-        * When a user logs in, optionally fill in preferences and such.
-        * For instance, you might pull the email address or real name from the
-        * external user database.
-        *
-        * The User object is passed by reference so it can be modified; don't
-        * forget the & on your function declaration.
-        *
-        * @deprecated since 1.26, use the UserLoggedIn hook instead. And assigning
-        *  a different User object to $user is no longer supported.
-        * @param User &$user
-        * @return bool
-        */
-       public function updateUser( &$user ) {
-               # Override this and do something
-               return true;
-       }
-
-       /**
-        * Return true if the wiki should create a new local account automatically
-        * when asked to login a user who doesn't exist locally but does in the
-        * external auth database.
-        *
-        * If you don't automatically create accounts, you must still create
-        * accounts in some way. It's not possible to authenticate without
-        * a local account.
-        *
-        * This is just a question, and shouldn't perform any actions.
-        *
-        * @return bool
-        */
-       public function autoCreate() {
-               return false;
-       }
-
-       /**
-        * Allow a property change? Properties are the same as preferences
-        * and use the same keys. 'Realname' 'Emailaddress' and 'Nickname'
-        * all reference this.
-        *
-        * @param string $prop
-        *
-        * @return bool
-        */
-       public function allowPropChange( $prop = '' ) {
-               if ( $prop == 'realname' && is_callable( [ $this, 'allowRealNameChange' ] ) ) {
-                       return $this->allowRealNameChange();
-               } elseif ( $prop == 'emailaddress' && is_callable( [ $this, 'allowEmailChange' ] ) ) {
-                       return $this->allowEmailChange();
-               } elseif ( $prop == 'nickname' && is_callable( [ $this, 'allowNickChange' ] ) ) {
-                       return $this->allowNickChange();
-               } else {
-                       return true;
-               }
-       }
-
-       /**
-        * Can users change their passwords?
-        *
-        * @return bool
-        */
-       public function allowPasswordChange() {
-               return true;
-       }
-
-       /**
-        * Should MediaWiki store passwords in its local database?
-        *
-        * @return bool
-        */
-       public function allowSetLocalPassword() {
-               return true;
-       }
-
-       /**
-        * Set the given password in the authentication database.
-        * As a special case, the password may be set to null to request
-        * locking the password to an unusable value, with the expectation
-        * that it will be set later through a mail reset or other method.
-        *
-        * Return true if successful.
-        *
-        * @param User $user
-        * @param string $password Password.
-        * @return bool
-        */
-       public function setPassword( $user, $password ) {
-               return true;
-       }
-
-       /**
-        * Update user information in the external authentication database.
-        * Return true if successful.
-        *
-        * @deprecated since 1.26, use the UserSaveSettings hook instead.
-        * @param User $user
-        * @return bool
-        */
-       public function updateExternalDB( $user ) {
-               return true;
-       }
-
-       /**
-        * Update user groups in the external authentication database.
-        * Return true if successful.
-        *
-        * @deprecated since 1.26, use the UserGroupsChanged hook instead.
-        * @param User $user
-        * @param array $addgroups Groups to add.
-        * @param array $delgroups Groups to remove.
-        * @return bool
-        */
-       public function updateExternalDBGroups( $user, $addgroups, $delgroups = [] ) {
-               return true;
-       }
-
-       /**
-        * Check to see if external accounts can be created.
-        * Return true if external accounts can be created.
-        * @return bool
-        */
-       public function canCreateAccounts() {
-               return false;
-       }
-
-       /**
-        * Add a user to the external authentication database.
-        * Return true if successful.
-        *
-        * @param User $user Only the name should be assumed valid at this point
-        * @param string $password
-        * @param string $email
-        * @param string $realname
-        * @return bool
-        */
-       public function addUser( $user, $password, $email = '', $realname = '' ) {
-               return true;
-       }
-
-       /**
-        * Return true to prevent logins that don't authenticate here from being
-        * checked against the local database's password fields.
-        *
-        * This is just a question, and shouldn't perform any actions.
-        *
-        * @return bool
-        */
-       public function strict() {
-               return false;
-       }
-
-       /**
-        * Check if a user should authenticate locally if the global authentication fails.
-        * If either this or strict() returns true, local authentication is not used.
-        *
-        * @param string $username Username.
-        * @return bool
-        */
-       public function strictUserAuth( $username ) {
-               return false;
-       }
-
-       /**
-        * When creating a user account, optionally fill in preferences and such.
-        * For instance, you might pull the email address or real name from the
-        * external user database.
-        *
-        * The User object is passed by reference so it can be modified; don't
-        * forget the & on your function declaration.
-        *
-        * @deprecated since 1.26, use the UserLoggedIn hook instead. And assigning
-        *  a different User object to $user is no longer supported.
-        * @param User &$user
-        * @param bool $autocreate True if user is being autocreated on login
-        */
-       public function initUser( &$user, $autocreate = false ) {
-               # Override this to do something.
-       }
-
-       /**
-        * If you want to munge the case of an account name before the final
-        * check, now is your chance.
-        * @param string $username
-        * @return string
-        */
-       public function getCanonicalName( $username ) {
-               return $username;
-       }
-
-       /**
-        * Get an instance of a User object
-        *
-        * @param User &$user
-        *
-        * @return AuthPluginUser
-        */
-       public function getUserInstance( User &$user ) {
-               return new AuthPluginUser( $user );
-       }
-
-       /**
-        * Get a list of domains (in HTMLForm options format) used.
-        *
-        * @return array
-        */
-       public function domainList() {
-               return [];
-       }
-}
-
-/**
- * @deprecated since 1.27
- */
-class AuthPluginUser {
-       function __construct( $user ) {
-               # Override this!
-       }
-
-       public function getId() {
-               # Override this!
-               return -1;
-       }
-
-       /**
-        * Indicate whether the user is locked
-        * @deprecated since 1.26, use the UserIsLocked hook instead.
-        * @return bool
-        */
-       public function isLocked() {
-               # Override this!
-               return false;
-       }
-
-       /**
-        * Indicate whether the user is hidden
-        * @deprecated since 1.26, use the UserIsHidden hook instead.
-        * @return bool
-        */
-       public function isHidden() {
-               # Override this!
-               return false;
-       }
-
-       /**
-        * @deprecated since 1.28, use SessionManager::invalidateSessionForUser() instead.
-        * @return bool
-        */
-       public function resetAuthToken() {
-               # Override this!
-               return true;
-       }
-}
index f8fbf83..fa11bcb 100644 (file)
@@ -134,6 +134,7 @@ class AutoLoader {
                        'MediaWiki\\Edit\\' => __DIR__ . '/edit/',
                        'MediaWiki\\EditPage\\' => __DIR__ . '/editpage/',
                        'MediaWiki\\Linker\\' => __DIR__ . '/linker/',
+                       'MediaWiki\\Permissions\\' => __DIR__ . '/Permissions/',
                        'MediaWiki\\Preferences\\' => __DIR__ . '/preferences/',
                        'MediaWiki\\Revision\\' => __DIR__ . '/Revision/',
                        'MediaWiki\\Session\\' => __DIR__ . '/session/',
index 09f6d9f..c6b9482 100644 (file)
@@ -121,6 +121,9 @@ class Block {
         *                          created by MediaWiki rather than being stored
         *                          in the database. Value is a string to return
         *                          from self::getSystemBlockType().
+        *     sitewide bool        Disallow editing all pages and all contribution
+        *                          actions, except those specifically allowed by
+        *                          other block flags
         *
         * @since 1.26 accepts $options array instead of individual parameters; order
         * of parameters above reflects the original order
@@ -145,14 +148,6 @@ class Block {
                        'sitewide'        => true,
                ];
 
-               if ( func_num_args() > 1 || !is_array( $options ) ) {
-                       $options = array_combine(
-                               array_slice( array_keys( $defaults ), 0, func_num_args() ),
-                               func_get_args()
-                       );
-                       wfDeprecated( __METHOD__ . ' with multiple arguments', '1.26' );
-               }
-
                $options += $defaults;
 
                $this->setTarget( $options['address'] );
@@ -170,13 +165,13 @@ class Block {
                        $this->setBlocker( $options['byText'] );
                }
 
-               $this->mReason = $options['reason'];
-               $this->mTimestamp = wfTimestamp( TS_MW, $options['timestamp'] );
-               $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $options['expiry'] );
+               $this->setReason( $options['reason'] );
+               $this->setTimestamp( wfTimestamp( TS_MW, $options['timestamp'] ) );
+               $this->setExpiry( wfGetDB( DB_REPLICA )->decodeExpiry( $options['expiry'] ) );
 
                # Boolean settings
                $this->mAuto = (bool)$options['auto'];
-               $this->mHideName = (bool)$options['hideName'];
+               $this->setHideName( (bool)$options['hideName'] );
                $this->isHardblock( !$options['anonOnly'] );
                $this->isAutoblocking( (bool)$options['enableAutoblock'] );
                $this->isSitewide( (bool)$options['sitewide'] );
@@ -301,12 +296,12 @@ class Block {
                        && $this->mAuto == $block->mAuto
                        && $this->isHardblock() == $block->isHardblock()
                        && $this->isCreateAccountBlocked() == $block->isCreateAccountBlocked()
-                       && $this->mExpiry == $block->mExpiry
+                       && $this->getExpiry() == $block->getExpiry()
                        && $this->isAutoblocking() == $block->isAutoblocking()
-                       && $this->mHideName == $block->mHideName
+                       && $this->getHideName() == $block->getHideName()
                        && $this->isEmailBlocked() == $block->isEmailBlocked()
                        && $this->isUsertalkEditAllowed() == $block->isUsertalkEditAllowed()
-                       && $this->mReason == $block->mReason
+                       && $this->getReason() == $block->getReason()
                        && $this->isSitewide() == $block->isSitewide()
                        // Block::getRestrictions() may perform a database query, so keep it at
                        // the end.
@@ -476,18 +471,20 @@ class Block {
                        $row->ipb_by, $row->ipb_by_text, $row->ipb_by_actor ?? null
                ) );
 
-               $this->mTimestamp = wfTimestamp( TS_MW, $row->ipb_timestamp );
+               $this->setTimestamp( wfTimestamp( TS_MW, $row->ipb_timestamp ) );
                $this->mAuto = $row->ipb_auto;
-               $this->mHideName = $row->ipb_deleted;
+               $this->setHideName( $row->ipb_deleted );
                $this->mId = (int)$row->ipb_id;
                $this->mParentBlockId = $row->ipb_parent_block_id;
 
                // I wish I didn't have to do this
                $db = wfGetDB( DB_REPLICA );
-               $this->mExpiry = $db->decodeExpiry( $row->ipb_expiry );
-               $this->mReason = CommentStore::getStore()
+               $this->setExpiry( $db->decodeExpiry( $row->ipb_expiry ) );
+               $this->setReason(
+                       CommentStore::getStore()
                        // Legacy because $row may have come from self::selectFields()
-                       ->getCommentLegacy( $db, 'ipb_reason', $row )->text;
+                       ->getCommentLegacy( $db, 'ipb_reason', $row )->text
+               );
 
                $this->isHardblock( !$row->ipb_anon_only );
                $this->isAutoblocking( $row->ipb_enable_autoblock );
@@ -684,7 +681,7 @@ class Block {
         * @return array
         */
        protected function getDatabaseArray( IDatabase $dbw ) {
-               $expiry = $dbw->encodeExpiry( $this->mExpiry );
+               $expiry = $dbw->encodeExpiry( $this->getExpiry() );
 
                if ( $this->forcedTargetID ) {
                        $uid = $this->forcedTargetID;
@@ -695,7 +692,7 @@ class Block {
                $a = [
                        'ipb_address'          => (string)$this->target,
                        'ipb_user'             => $uid,
-                       'ipb_timestamp'        => $dbw->timestamp( $this->mTimestamp ),
+                       'ipb_timestamp'        => $dbw->timestamp( $this->getTimestamp() ),
                        'ipb_auto'             => $this->mAuto,
                        'ipb_anon_only'        => !$this->isHardblock(),
                        'ipb_create_account'   => $this->isCreateAccountBlocked(),
@@ -703,12 +700,12 @@ class Block {
                        'ipb_expiry'           => $expiry,
                        'ipb_range_start'      => $this->getRangeStart(),
                        'ipb_range_end'        => $this->getRangeEnd(),
-                       'ipb_deleted'          => intval( $this->mHideName ), // typecast required for SQLite
+                       'ipb_deleted'          => intval( $this->getHideName() ), // typecast required for SQLite
                        'ipb_block_email'      => $this->isEmailBlocked(),
                        'ipb_allow_usertalk'   => $this->isUsertalkEditAllowed(),
                        'ipb_parent_block_id'  => $this->mParentBlockId,
                        'ipb_sitewide'         => $this->isSitewide(),
-               ] + CommentStore::getStore()->insert( $dbw, 'ipb_reason', $this->mReason )
+               ] + CommentStore::getStore()->insert( $dbw, 'ipb_reason', $this->getReason() )
                        + ActorMigration::newMigration()->getInsertValues( $dbw, 'ipb_by', $this->getBlocker() );
 
                return $a;
@@ -721,10 +718,10 @@ class Block {
        protected function getAutoblockUpdateArray( IDatabase $dbw ) {
                return [
                        'ipb_create_account'   => $this->isCreateAccountBlocked(),
-                       'ipb_deleted'          => (int)$this->mHideName, // typecast required for SQLite
+                       'ipb_deleted'          => (int)$this->getHideName(), // typecast required for SQLite
                        'ipb_allow_usertalk'   => $this->isUsertalkEditAllowed(),
                        'ipb_sitewide'         => $this->isSitewide(),
-               ] + CommentStore::getStore()->insert( $dbw, 'ipb_reason', $this->mReason )
+               ] + CommentStore::getStore()->insert( $dbw, 'ipb_reason', $this->getReason() )
                        + ActorMigration::newMigration()->getInsertValues( $dbw, 'ipb_by', $this->getBlocker() );
        }
 
@@ -888,7 +885,7 @@ class Block {
                        # Check if the block is an autoblock and would exceed the user block
                        # if renewed. If so, do nothing, otherwise prolong the block time...
                        if ( $ipblock->mAuto && // @todo Why not compare $ipblock->mExpiry?
-                               $this->mExpiry > self::getAutoblockExpiry( $ipblock->mTimestamp )
+                               $this->getExpiry() > self::getAutoblockExpiry( $ipblock->getTimestamp() )
                        ) {
                                # Reset block timestamp to now and its expiry to
                                # $wgAutoblockExpiry in the future
@@ -902,26 +899,28 @@ class Block {
                wfDebug( "Autoblocking {$this->getTarget()}@" . $autoblockIP . "\n" );
                $autoblock->setTarget( $autoblockIP );
                $autoblock->setBlocker( $this->getBlocker() );
-               $autoblock->mReason = wfMessage( 'autoblocker', $this->getTarget(), $this->mReason )
-                       ->inContentLanguage()->plain();
+               $autoblock->setReason(
+                       wfMessage( 'autoblocker', $this->getTarget(), $this->getReason() )
+                               ->inContentLanguage()->plain()
+               );
                $timestamp = wfTimestampNow();
-               $autoblock->mTimestamp = $timestamp;
+               $autoblock->setTimestamp( $timestamp );
                $autoblock->mAuto = 1;
                $autoblock->isCreateAccountBlocked( $this->isCreateAccountBlocked() );
                # Continue suppressing the name if needed
-               $autoblock->mHideName = $this->mHideName;
+               $autoblock->setHideName( $this->getHideName() );
                $autoblock->isUsertalkEditAllowed( $this->isUsertalkEditAllowed() );
                $autoblock->mParentBlockId = $this->mId;
                $autoblock->isSitewide( $this->isSitewide() );
                $autoblock->setRestrictions( $this->getRestrictions() );
 
-               if ( $this->mExpiry == 'infinity' ) {
+               if ( $this->getExpiry() == 'infinity' ) {
                        # Original block was indefinite, start an autoblock now
-                       $autoblock->mExpiry = self::getAutoblockExpiry( $timestamp );
+                       $autoblock->setExpiry( self::getAutoblockExpiry( $timestamp ) );
                } else {
                        # If the user is already blocked with an expiry date, we don't
                        # want to pile on top of that.
-                       $autoblock->mExpiry = min( $this->mExpiry, self::getAutoblockExpiry( $timestamp ) );
+                       $autoblock->setExpiry( min( $this->getExpiry(), self::getAutoblockExpiry( $timestamp ) ) );
                }
 
                # Insert the block...
@@ -956,18 +955,21 @@ class Block {
                $timestamp = wfTimestampNow();
                wfDebug( "Block::isExpired() checking current " . $timestamp . " vs $this->mExpiry\n" );
 
-               if ( !$this->mExpiry ) {
+               if ( !$this->getExpiry() ) {
                        return false;
                } else {
-                       return $timestamp > $this->mExpiry;
+                       return $timestamp > $this->getExpiry();
                }
        }
 
        /**
         * Is the block address valid (i.e. not a null string?)
+        *
+        * @deprecated since 1.33 No longer needed in core.
         * @return bool
         */
        public function isValid() {
+               wfDeprecated( __METHOD__, '1.33' );
                return $this->getTarget() != null;
        }
 
@@ -976,14 +978,14 @@ class Block {
         */
        public function updateTimestamp() {
                if ( $this->mAuto ) {
-                       $this->mTimestamp = wfTimestamp();
-                       $this->mExpiry = self::getAutoblockExpiry( $this->mTimestamp );
+                       $this->setTimestamp( wfTimestamp() );
+                       $this->setExpiry( self::getAutoblockExpiry( $this->getTimestamp() ) );
 
                        $dbw = wfGetDB( DB_MASTER );
                        $dbw->update( 'ipblocks',
                                [ /* SET */
-                                       'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
-                                       'ipb_expiry' => $dbw->timestamp( $this->mExpiry ),
+                                       'ipb_timestamp' => $dbw->timestamp( $this->getTimestamp() ),
+                                       'ipb_expiry' => $dbw->timestamp( $this->getExpiry() ),
                                ],
                                [ /* WHERE */
                                        'ipb_id' => $this->getId(),
@@ -1037,10 +1039,7 @@ class Block {
         * @return int (0 for foreign users)
         */
        public function getBy() {
-               $blocker = $this->getBlocker();
-               return ( $blocker instanceof User )
-                       ? $blocker->getId()
-                       : 0;
+               return $this->getBlocker()->getId();
        }
 
        /**
@@ -1049,10 +1048,7 @@ class Block {
         * @return string
         */
        public function getByName() {
-               $blocker = $this->getBlocker();
-               return ( $blocker instanceof User )
-                       ? $blocker->getName()
-                       : (string)$blocker; // username
+               return $this->getBlocker()->getName();
        }
 
        /**
@@ -1079,6 +1075,46 @@ class Block {
                return $this;
        }
 
+       /**
+        * Get the reason given for creating the block
+        *
+        * @since 1.33
+        * @return string
+        */
+       public function getReason() {
+               return $this->mReason;
+       }
+
+       /**
+        * Set the reason for creating the block
+        *
+        * @since 1.33
+        * @param string $reason
+        */
+       public function setReason( $reason ) {
+               $this->mReason = $reason;
+       }
+
+       /**
+        * Get whether the block hides the target's username
+        *
+        * @since 1.33
+        * @return bool The block hides the username
+        */
+       public function getHideName() {
+               return $this->mHideName;
+       }
+
+       /**
+        * Set whether ths block hides the target's username
+        *
+        * @since 1.33
+        * @param bool $hideName The block hides the username
+        */
+       public function setHideName( $hideName ) {
+               $this->mHideName = $hideName;
+       }
+
        /**
         * Get the system block type, if any
         * @since 1.29
@@ -1261,7 +1297,7 @@ class Block {
                                // their own talk page unless a restriction exists on the
                                // page or User_talk: namespace
                                wfSetVar( $this->allowUsertalk, $x === null ? null : !$x );
-                               $res = !$this->isUserTalkEditAllowed();
+                               $res = !$this->isUsertalkEditAllowed();
 
                                // edit own user talk can be disabled by config
                                if ( !$blockAllowsUTEdit ) {
@@ -1291,10 +1327,10 @@ class Block {
         */
        public function getRedactedName() {
                if ( $this->mAuto ) {
-                       return Html::rawElement(
+                       return Html::element(
                                'span',
                                [ 'class' => 'mw-autoblockid' ],
-                               wfMessage( 'autoblockid', $this->mId )
+                               wfMessage( 'autoblockid', $this->mId )->text()
                        );
                } else {
                        return htmlspecialchars( $this->getTarget() );
@@ -1665,14 +1701,45 @@ class Block {
        }
 
        /**
-        * @since 1.19
+        * Get the block expiry time
         *
-        * @return mixed|string
+        * @since 1.19
+        * @return string
         */
        public function getExpiry() {
                return $this->mExpiry;
        }
 
+       /**
+        * Set the block expiry time
+        *
+        * @since 1.33
+        * @param string $expiry
+        */
+       public function setExpiry( $expiry ) {
+               $this->mExpiry = $expiry;
+       }
+
+       /**
+        * Get the timestamp indicating when the block was created
+        *
+        * @since 1.33
+        * @return string
+        */
+       public function getTimestamp() {
+               return $this->mTimestamp;
+       }
+
+       /**
+        * Set the timestamp indicating when the block was created
+        *
+        * @since 1.33
+        * @param string $timestamp
+        */
+       public function setTimestamp( $timestamp ) {
+               $this->mTimestamp = $timestamp;
+       }
+
        /**
         * Set the target for this block, and update $this->type accordingly
         * @param mixed $target
@@ -1835,7 +1902,7 @@ class Block {
                        $link = $blocker;
                }
 
-               $reason = $this->mReason;
+               $reason = $this->getReason();
                if ( $reason == '' ) {
                        $reason = $context->msg( 'blockednoreason' )->text();
                }
@@ -1852,9 +1919,9 @@ class Block {
                        $context->getRequest()->getIP(),
                        $this->getByName(),
                        $systemBlockType ?? $this->getId(),
-                       $lang->formatExpiry( $this->mExpiry ),
+                       $lang->formatExpiry( $this->getExpiry() ),
                        (string)$intended,
-                       $lang->userTimeAndDate( $this->mTimestamp, $context->getUser() ),
+                       $lang->userTimeAndDate( $this->getTimestamp(), $context->getUser() ),
                ];
        }
 
@@ -2054,4 +2121,46 @@ class Block {
 
                return null;
        }
+
+       /**
+        * Check if the block should be tracked with a cookie.
+        *
+        * @since 1.33
+        * @param bool $isIpUser The user is logged out
+        * @return bool The block should be tracked with a cookie
+        */
+       public function shouldTrackWithCookie( $isIpUser ) {
+               $config = RequestContext::getMain()->getConfig();
+               switch ( $this->getType() ) {
+                       case self::TYPE_IP:
+                       case self::TYPE_RANGE:
+                               return $isIpUser && $config->get( 'CookieSetOnIpBlock' );
+                       case self::TYPE_USER:
+                               return !$isIpUser && $config->get( 'CookieSetOnAutoblock' ) && $this->isAutoblocking();
+                       default:
+                               return false;
+               }
+       }
+
+       /**
+        * Check if the block prevents a user from resetting their password
+        *
+        * @since 1.33
+        * @return bool The block blocks password reset
+        */
+       public function appliesToPasswordReset() {
+               switch ( $this->getSystemBlockType() ) {
+                       case null:
+                       case 'global-block':
+                               return $this->isCreateAccountBlocked();
+                       case 'proxy':
+                               return true;
+                       case 'dnsbl':
+                       case 'wgSoftBlockRanges':
+                               return false;
+                       default:
+                               return true;
+               }
+       }
+
 }
index 3352c2c..ca16536 100644 (file)
@@ -299,10 +299,10 @@ class Category {
        /**
         * Generic accessor
         * @param string $key
-        * @return bool
+        * @return mixed
         */
        private function getX( $key ) {
-               if ( !$this->initialize( self::LAZY_INIT_ROW ) ) {
+               if ( $this->{$key} === null && !$this->initialize( self::LAZY_INIT_ROW ) ) {
                        return false;
                }
                return $this->{$key};
index a07e1b4..f78597b 100644 (file)
@@ -125,7 +125,7 @@ class CategoryViewer extends ContextSource {
                        // @todo FIXME: Cannot be completely suppressed because it
                        //        is unknown if 'until' or 'from' makes this
                        //        give 0 results.
-                       $r = $r . $this->getCategoryTop();
+                       $r = $this->getCategoryTop();
                } else {
                        $r = $this->getCategoryTop() .
                                $r .
@@ -339,7 +339,7 @@ class CategoryViewer extends ContextSource {
                                        'ORDER BY' => $this->flip[$type] ? 'cl_sortkey DESC' : 'cl_sortkey',
                                ],
                                [
-                                       'categorylinks' => [ 'INNER JOIN', 'cl_from = page_id' ],
+                                       'categorylinks' => [ 'JOIN', 'cl_from = page_id' ],
                                        'category' => [ 'LEFT JOIN', [
                                                'cat_title = page_title',
                                                'page_namespace' => NS_CATEGORY
index 1a60bb7..4a673c4 100644 (file)
@@ -202,6 +202,7 @@ class CommentStore {
         *   - fields: (string[]) to include in the `$vars` to `IDatabase->select()`
         *   - joins: (array) to include in the `$join_conds` to `IDatabase->select()`
         *  All tables, fields, and joins are aliased, so `+` is safe to use.
+        * @phan-return array{tables:string[],fields:string[],joins:array}
         */
        public function getJoin( $key = null ) {
                $key = $this->getKey( $key );
index af7c7cb..7df2aed 100644 (file)
@@ -2,7 +2,7 @@
 
 /**
  * A read-only mode service which does not depend on LoadBalancer.
- * To obtain an instance, use MediaWikiServices::getConfiguredReadOnlyMode().
+ * To obtain an instance, use MediaWikiServices::getInstance()->getConfiguredReadOnlyMode().
  *
  * @since 1.29
  */
@@ -63,11 +63,4 @@ class ConfiguredReadOnlyMode {
        public function setReason( $msg ) {
                $this->overrideReason = $msg;
        }
-
-       /**
-        * Clear the cache of the read only file
-        */
-       public function clearCache() {
-               $this->fileReason = null;
-       }
 }
index 6216046..be598ea 100644 (file)
@@ -98,11 +98,14 @@ class ContentSecurityPolicy {
         *
         * @param int $reportOnly Either self::REPORT_ONLY_MODE or self::FULL_MODE
         * @return string Name of http header
+        * @throws UnexpectedValueException
         */
        private function getHeaderName( $reportOnly ) {
                if ( $reportOnly === self::REPORT_ONLY_MODE ) {
                        return 'Content-Security-Policy-Report-Only';
-               } elseif ( $reportOnly === self::FULL_MODE ) {
+               }
+
+               if ( $reportOnly === self::FULL_MODE ) {
                        return 'Content-Security-Policy';
                }
                throw new UnexpectedValueException( $reportOnly );
@@ -111,7 +114,8 @@ class ContentSecurityPolicy {
        /**
         * Determine what CSP policies to set for this page
         *
-        * @param array|bool $config Policy configuration (Either $wgCSPHeader or $wgCSPReportOnlyHeader)
+        * @param array|bool $policyConfig Policy configuration
+        *   (Either $wgCSPHeader or $wgCSPReportOnlyHeader)
         * @param int $mode self::REPORT_ONLY_MODE, self::FULL_MODE
         * @return string Policy directives, or empty string for no policy.
         */
@@ -152,8 +156,8 @@ class ContentSecurityPolicy {
                        }
                }
                // Note: default on if unspecified.
-               if ( !isset( $policyConfig['unsafeFallback'] )
-                       || $policyConfig['unsafeFallback'] )
+               if ( !isset( $policyConfig['unsafeFallback'] )
+                       || $policyConfig['unsafeFallback']
                ) {
                        // unsafe-inline should be ignored on browsers
                        // that support 'nonce-foo' sources.
index 93113df..828af49 100644 (file)
@@ -72,7 +72,7 @@ $wgConfigRegistry = [
  * MediaWiki version number
  * @since 1.2
  */
-$wgVersion = '1.33.0-alpha';
+$wgVersion = '1.34.0-alpha';
 
 /**
  * Name of the site. It must be changed in LocalSettings.php
@@ -749,7 +749,7 @@ $wgUploadDialog = [
  *   - a) Whether it is fully qualified or wiki-relative.
  *        By default, the paths of files are relative to the current wiki,
  *        which works via prefixing them with the current wiki ID when accessed.
- *        Setting 'wikiId' forces the backend to be fully qualified by prefixing
+ *        Setting 'domainId' forces the backend to be fully qualified by prefixing
  *        all paths with the specified value instead. This can be useful if
  *        multiple wikis need to share the same data. Note that 'name' is *not*
  *        part of any prefix and thus should not be relied upon for namespacing.
@@ -782,7 +782,7 @@ $wgLockManagers = [];
 
 /**
  * Show Exif data, on by default if available.
- * Requires PHP's Exif extension: https://secure.php.net/manual/en/ref.exif.php
+ * Requires PHP's Exif extension: https://www.php.net/manual/en/ref.exif.php
  *
  * @note FOR WINDOWS USERS:
  * To enable Exif functions, add the following line to the "Windows
@@ -1935,7 +1935,8 @@ $wgSearchType = null;
 $wgSearchTypeAlternatives = null;
 
 /**
- * Table name prefix; this should be alphanumeric and not contain spaces nor hyphens
+ * Table name prefix.
+ * This should be alphanumeric, contain neither spaces nor hyphens, and end in "_"
  */
 $wgDBprefix = '';
 
@@ -2099,7 +2100,7 @@ $wgDBerrorLog = false;
  * Defaults to the wiki timezone ($wgLocaltimezone).
  *
  * A list of usable timezones can found at:
- * https://secure.php.net/manual/en/timezones.php
+ * https://www.php.net/manual/en/timezones.php
  *
  * @par Examples:
  * @code
@@ -2114,26 +2115,6 @@ $wgDBerrorLog = false;
  */
 $wgDBerrorLogTZ = false;
 
-/**
- * Set to true to engage MySQL 4.1/5.0 charset-related features;
- * for now will just cause sending of 'SET NAMES=utf8' on connect.
- *
- * @warning THIS IS EXPERIMENTAL!
- *
- * May break if you're not using the table defs from mysql5/tables.sql.
- * May break if you're upgrading an existing wiki if set differently.
- * Broken symptoms likely to include incorrect behavior with page titles,
- * usernames, comments etc containing non-ASCII characters.
- * Might also cause failures on the object cache and other things.
- *
- * Even correct usage may cause failures with Unicode supplementary
- * characters (those not in the Basic Multilingual Plane) unless MySQL
- * has enhanced their Unicode support.
- *
- * @deprecated since 1.31
- */
-$wgDBmysql5 = false;
-
 /**
  * Set true to enable Oracle DCRP (supported from 11gR1 onward)
  *
@@ -2677,14 +2658,6 @@ $wgSidebarCacheExpiry = 86400;
  */
 $wgUseGzip = false;
 
-/**
- * Clock skew or the one-second resolution of time() can occasionally cause cache
- * problems when the user requests two pages within a short period of time. This
- * variable adds a given number of seconds to vulnerable timestamps, thereby giving
- * a grace period.
- */
-$wgClockSkewFudge = 5;
-
 /**
  * Invalidate various caches when LocalSettings.php changes. This is equivalent
  * to setting $wgCacheEpoch to the modification time of LocalSettings.php, as
@@ -3197,7 +3170,7 @@ $wgForceUIMsgAsContentMsg = [];
  * timezone-nameinlowercase like timezone-utc.
  *
  * A list of usable timezones can found at:
- * https://secure.php.net/manual/en/timezones.php
+ * https://www.php.net/manual/en/timezones.php
  *
  * @par Examples:
  * @code
@@ -3992,18 +3965,6 @@ $wgInterwikiFallbackSite = 'wiki';
 
 /** @} */ # end of Interwiki caching settings.
 
-/**
- * @name SiteStore caching settings.
- * @{
- */
-
-/**
- * Specify the file location for the Sites json cache file.
- */
-$wgSitesCacheFile = false;
-
-/** @} */ # end of SiteStore caching settings.
-
 /**
  * If local interwikis are set up which allow redirects,
  * set this regexp to restrict URLs which will be displayed
@@ -4031,13 +3992,12 @@ $wgRedirectSources = false;
 $wgCapitalLinks = true;
 
 /**
- * @since 1.16 - This can now be set per-namespace. Some special namespaces (such
- * as Special, see MWNamespace::$alwaysCapitalizedNamespaces for the full list) must be
- * true by default (and setting them has no effect), due to various things that
- * require them to be so. Also, since Talk namespaces need to directly mirror their
- * associated content namespaces, the values for those are ignored in favor of the
- * subject namespace's setting. Setting for NS_MEDIA is taken automatically from
- * NS_FILE.
+ * @since 1.16 - This can now be set per-namespace. Some special namespaces (such as Special, see
+ * NamespaceInfo::$alwaysCapitalizedNamespaces for the full list) must be true by default (and
+ * setting them has no effect), due to various things that require them to be so. Also, since Talk
+ * namespaces need to directly mirror their associated content namespaces, the values for those are
+ * ignored in favor of the subject namespace's setting. Setting for NS_MEDIA is taken automatically
+ * from NS_FILE.
  *
  * @par Example:
  * @code
@@ -4445,6 +4405,11 @@ $wgCentralIdLookupProvider = 'local';
  * - value: (number, boolean or null) the value to pass to the callback
  * - forceChange: (bool, default false) if the password is invalid, do
  *   not let the user log in without changing the password
+ * - suggestChangeOnLogin: (bool, default false) if true and the password is
+ *   invalid, suggest a password change if logging in. If all the failing policies
+ *   that apply to the user have this set to false, the password change
+ *   screen will not be shown. 'forceChange' takes precedence over
+ *   'suggestChangeOnLogin' if they are both present.
  * As a shorthand for [ 'value' => <value> ], simply <value> can be written.
  * When multiple password policies are defined for a user, the settings
  * arrays are merged, and for fields which are set in both arrays, the
@@ -4480,6 +4445,13 @@ $wgCentralIdLookupProvider = 'local';
  *             100,000 commonly used passwords. Due to the size of the list this
  *      is a probabilistic test.
  *
+ * If you add custom checks, for Special:PasswordPolicies to display them correctly,
+ * every check should have a corresponding passwordpolicies-policy-<check> message,
+ * and every settings field other than 'value' should have a corresponding
+ * passwordpolicies-policyflag-<flag> message (<check> and <flag> are in lowercase).
+ * The check message receives the policy value as a parameter, the flag message
+ * receives the flag value (or values if it's an array).
+ *
  * @since 1.26
  * @see PasswordPolicyChecks
  * @see User::checkPasswordValidity()
@@ -4507,10 +4479,10 @@ $wgPasswordPolicy = [
                        'PasswordNotInLargeBlacklist' => true,
                ],
                'default' => [
-                       'MinimalPasswordLength' => 1,
-                       'PasswordCannotMatchUsername' => true,
-                       'PasswordCannotMatchBlacklist' => true,
-                       'MaximalPasswordLength' => 4096,
+                       'MinimalPasswordLength' => [ 'value' => 1, 'suggestChangeOnLogin' => true ],
+                       'PasswordCannotMatchUsername' => [ 'value' => true, 'suggestChangeOnLogin' => true ],
+                       'PasswordCannotMatchBlacklist' => [ 'value' => true, 'suggestChangeOnLogin' => true ],
+                       'MaximalPasswordLength' => [ 'value' => 4096, 'suggestChangeOnLogin' => true ],
                ],
        ],
        'checks' => [
@@ -4885,6 +4857,7 @@ $wgDefaultUserOptions = [
        'rows' => 25, // @deprecated since 1.29 No longer used in core
        'showhiddencats' => 0,
        'shownumberswatching' => 1,
+       'showrollbackconfirmation' => 0,
        'skin' => false,
        'stubthreshold' => 0,
        'thumbsize' => 5,
@@ -6451,7 +6424,7 @@ $wgStatsdServer = false;
 /**
  * Prefix for metric names sent to $wgStatsdServer.
  *
- * @see MediaWikiServices::getStatsdDataFactory
+ * @see MediaWikiServices::getInstance()->getStatsdDataFactory
  * @see BufferingStatsdDataFactory
  * @since 1.25
  */
@@ -7464,13 +7437,6 @@ $wgAutoloadAttemptLowercase = true;
  */
 $wgExtensionCredits = [];
 
-/**
- * Authentication plugin.
- * @var $wgAuth AuthPlugin
- * @deprecated since 1.27 use $wgAuthManagerConfig instead
- */
-$wgAuth = null;
-
 /**
  * Global list of hooks.
  *
@@ -7604,14 +7570,6 @@ $wgJobTypeConf = [
        'default' => [ 'class' => JobQueueDB::class, 'order' => 'random', 'claimTTL' => 3600 ],
 ];
 
-/**
- * Which aggregator to use for tracking which queues have jobs.
- * These settings should be global to all wikis.
- */
-$wgJobQueueAggregator = [
-       'class' => JobQueueAggregatorNull::class
-];
-
 /**
  * Whether to include the number of jobs that are queued
  * for the API's maxlag parameter.
@@ -7682,7 +7640,7 @@ $wgCategoryPagingLimit = 200;
  *     all languages in a mediocre way. However, it is better than "uppercase".
  *
  * To use the uca-default collation, you must have PHP's intl extension
- * installed. See https://secure.php.net/manual/en/intl.setup.php . The details of the
+ * installed. See https://www.php.net/manual/en/intl.setup.php . The details of the
  * resulting collation will depend on the version of ICU installed on the
  * server.
  *
@@ -7926,6 +7884,7 @@ $wgActionFilteredLogs = [
        'upload' => [
                'upload' => [ 'upload' ],
                'overwrite' => [ 'overwrite' ],
+               'revert' => [ 'revert' ],
        ],
 ];
 
@@ -8990,6 +8949,12 @@ $wgInterwikiPrefixDisplayTypes = [];
  */
 $wgMultiContentRevisionSchemaMigrationStage = SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW;
 
+/**
+ * The schema to use per default when generating XML dumps. This allows sites to control
+ * explicitly when to make breaking changes to their export and dump format.
+ */
+$wgXmlDumpSchemaVersion = XML_DUMP_SCHEMA_VERSION_10;
+
 /**
  * Actor table schema migration stage.
  *
@@ -9006,7 +8971,7 @@ $wgMultiContentRevisionSchemaMigrationStage = SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_
  * @since 1.32 changed allowed flags
  * @var int An appropriate combination of SCHEMA_COMPAT_XXX flags.
  */
-$wgActorTableSchemaMigrationStage = SCHEMA_COMPAT_OLD;
+$wgActorTableSchemaMigrationStage = SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW;
 
 /**
  * Flag to enable Partial Blocks. This allows an admin to prevent a user from editing specific pages
@@ -9018,15 +8983,6 @@ $wgActorTableSchemaMigrationStage = SCHEMA_COMPAT_OLD;
  */
 $wgEnablePartialBlocks = false;
 
-/**
- * Enable confirmation prompt for rollback actions to prevent accidental rollbacks.
- * May be disabled to reduce number of clicks needed to perform rollbacks.
- *
- * @since 1.33
- * @var bool
- */
-$wgEnableRollbackConfirmationPrompt = true;
-
 /**
  * Enable stats monitoring when Block Notices are displayed in different places around core
  * and extensions.
@@ -9055,6 +9011,16 @@ $wgOriginTrials = [];
  */
 $wgPriorityHints = false;
 
+/**
+ * Enable Element Timing.
+ *
+ * @warning EXPERIMENTAL!
+ *
+ * @since 1.34
+ * @var bool
+ */
+$wgElementTiming = false;
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index 720e8d0..5f98b44 100644 (file)
@@ -317,3 +317,13 @@ define( 'MIGRATION_WRITE_BOTH', 0x10000000 | SCHEMA_COMPAT_READ_BOTH | SCHEMA_CO
 define( 'MIGRATION_WRITE_NEW', 0x20000000 | SCHEMA_COMPAT_READ_BOTH | SCHEMA_COMPAT_WRITE_NEW );
 define( 'MIGRATION_NEW', 0x30000000 | SCHEMA_COMPAT_NEW );
 /**@}*/
+
+/**@{
+ * XML dump schema versions, for use with XmlDumpWriter.
+ * See also the corresponding export-nnnn.xsd files in the docs directory,
+ * which are also listed at <https://www.mediawiki.org/xml/>.
+ * Note that not all old schema versions are represented here, as several
+ * were already unsupported at the time these constants were introduced.
+ */
+define( 'XML_DUMP_SCHEMA_VERSION_10', '0.10' );
+/**@}*/
index 8b32de4..7f00c6c 100644 (file)
@@ -36,6 +36,9 @@ $wgShowExceptionDetails = true;
 $wgShowHostnames = true;
 $wgDebugRawPage = true; // T49960
 
+// Enable MariaDB/MySQL strict mode
+$wgSQLMode = 'TRADITIONAL';
+
 // Enable log files
 $logDir = getenv( 'MW_LOG_DIR' );
 if ( $logDir ) {
index 300c5f3..add48d9 100644 (file)
@@ -869,7 +869,7 @@ class EditPage {
                } elseif ( $this->section == 'new' ) {
                        // Nothing *to* preview for new sections
                        return false;
-               } elseif ( ( $request->getVal( 'preload' ) !== null || $this->mTitle->exists() )
+               } elseif ( ( $request->getCheck( 'preload' ) || $this->mTitle->exists() )
                        && $this->context->getUser()->getOption( 'previewonfirst' )
                ) {
                        // Standard preference behavior
@@ -975,7 +975,7 @@ class EditPage {
 
                        $this->scrolltop = $request->getIntOrNull( 'wpScrolltop' );
 
-                       if ( $this->textbox1 === '' && $request->getVal( 'wpTextbox1' ) === null ) {
+                       if ( $this->textbox1 === '' && !$request->getCheck( 'wpTextbox1' ) ) {
                                // wpTextbox1 field is missing, possibly due to being "too big"
                                // according to some filter rules such as Suhosin's setting for
                                // suhosin.request.max_value_length (d'oh)
@@ -1214,149 +1214,147 @@ class EditPage {
                                $content = $this->getPreloadedContent( $preload, $params );
                        }
                // For existing pages, get text based on "undo" or section parameters.
-               } else {
-                       if ( $this->section != '' ) {
-                               // Get section edit text (returns $def_text for invalid sections)
-                               $orig = $this->getOriginalContent( $user );
-                               $content = $orig ? $orig->getSection( $this->section ) : null;
+               } elseif ( $this->section != '' ) {
+                       // Get section edit text (returns $def_text for invalid sections)
+                       $orig = $this->getOriginalContent( $user );
+                       $content = $orig ? $orig->getSection( $this->section ) : null;
 
-                               if ( !$content ) {
-                                       $content = $def_content;
-                               }
-                       } else {
-                               $undoafter = $request->getInt( 'undoafter' );
-                               $undo = $request->getInt( 'undo' );
-
-                               if ( $undo > 0 && $undoafter > 0 ) {
-                                       $undorev = Revision::newFromId( $undo );
-                                       $oldrev = Revision::newFromId( $undoafter );
-                                       $undoMsg = null;
-
-                                       # Sanity check, make sure it's the right page,
-                                       # the revisions exist and they were not deleted.
-                                       # Otherwise, $content will be left as-is.
-                                       if ( !is_null( $undorev ) && !is_null( $oldrev ) &&
-                                               !$undorev->isDeleted( Revision::DELETED_TEXT ) &&
-                                               !$oldrev->isDeleted( Revision::DELETED_TEXT )
+                       if ( !$content ) {
+                               $content = $def_content;
+                       }
+               } else {
+                       $undoafter = $request->getInt( 'undoafter' );
+                       $undo = $request->getInt( 'undo' );
+
+                       if ( $undo > 0 && $undoafter > 0 ) {
+                               $undorev = Revision::newFromId( $undo );
+                               $oldrev = Revision::newFromId( $undoafter );
+                               $undoMsg = null;
+
+                               # Sanity check, make sure it's the right page,
+                               # the revisions exist and they were not deleted.
+                               # Otherwise, $content will be left as-is.
+                               if ( !is_null( $undorev ) && !is_null( $oldrev ) &&
+                                       !$undorev->isDeleted( Revision::DELETED_TEXT ) &&
+                                       !$oldrev->isDeleted( Revision::DELETED_TEXT )
+                               ) {
+                                       if ( WikiPage::hasDifferencesOutsideMainSlot( $undorev, $oldrev )
+                                               || !$this->isSupportedContentModel( $oldrev->getContentModel() )
                                        ) {
-                                               if ( WikiPage::hasDifferencesOutsideMainSlot( $undorev, $oldrev )
-                                                       || !$this->isSupportedContentModel( $oldrev->getContentModel() )
-                                               ) {
-                                                       // Hack for undo while EditPage can't handle multi-slot editing
-                                                       $this->context->getOutput()->redirect( $this->mTitle->getFullURL( [
-                                                               'action' => 'mcrundo',
-                                                               'undo' => $undo,
-                                                               'undoafter' => $undoafter,
-                                                       ] ) );
-                                                       return false;
-                                               } else {
-                                                       $content = $this->page->getUndoContent( $undorev, $oldrev );
+                                               // Hack for undo while EditPage can't handle multi-slot editing
+                                               $this->context->getOutput()->redirect( $this->mTitle->getFullURL( [
+                                                       'action' => 'mcrundo',
+                                                       'undo' => $undo,
+                                                       'undoafter' => $undoafter,
+                                               ] ) );
+                                               return false;
+                                       } else {
+                                               $content = $this->page->getUndoContent( $undorev, $oldrev );
 
-                                                       if ( $content === false ) {
-                                                               # Warn the user that something went wrong
-                                                               $undoMsg = 'failure';
-                                                       }
+                                               if ( $content === false ) {
+                                                       # Warn the user that something went wrong
+                                                       $undoMsg = 'failure';
                                                }
+                                       }
 
-                                               if ( $undoMsg === null ) {
-                                                       $oldContent = $this->page->getContent( Revision::RAW );
-                                                       $popts = ParserOptions::newFromUserAndLang(
-                                                               $user, MediaWikiServices::getInstance()->getContentLanguage() );
-                                                       $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
-                                                       if ( $newContent->getModel() !== $oldContent->getModel() ) {
-                                                               // The undo may change content
-                                                               // model if its reverting the top
-                                                               // edit. This can result in
-                                                               // mismatched content model/format.
-                                                               $this->contentModel = $newContent->getModel();
-                                                               $this->contentFormat = $oldrev->getContentFormat();
-                                                       }
+                                       if ( $undoMsg === null ) {
+                                               $oldContent = $this->page->getContent( Revision::RAW );
+                                               $popts = ParserOptions::newFromUserAndLang(
+                                                       $user, MediaWikiServices::getInstance()->getContentLanguage() );
+                                               $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
+                                               if ( $newContent->getModel() !== $oldContent->getModel() ) {
+                                                       // The undo may change content
+                                                       // model if its reverting the top
+                                                       // edit. This can result in
+                                                       // mismatched content model/format.
+                                                       $this->contentModel = $newContent->getModel();
+                                                       $this->contentFormat = $oldrev->getContentFormat();
+                                               }
 
-                                                       if ( $newContent->equals( $oldContent ) ) {
-                                                               # Tell the user that the undo results in no change,
-                                                               # i.e. the revisions were already undone.
-                                                               $undoMsg = 'nochange';
-                                                               $content = false;
-                                                       } else {
-                                                               # Inform the user of our success and set an automatic edit summary
-                                                               $undoMsg = 'success';
-
-                                                               # If we just undid one rev, use an autosummary
-                                                               $firstrev = $oldrev->getNext();
-                                                               if ( $firstrev && $firstrev->getId() == $undo ) {
-                                                                       $userText = $undorev->getUserText();
-                                                                       if ( $userText === '' ) {
-                                                                               $undoSummary = $this->context->msg(
-                                                                                       'undo-summary-username-hidden',
-                                                                                       $undo
-                                                                               )->inContentLanguage()->text();
-                                                                       } else {
-                                                                               $undoSummary = $this->context->msg(
-                                                                                       'undo-summary',
-                                                                                       $undo,
-                                                                                       $userText
-                                                                               )->inContentLanguage()->text();
-                                                                       }
-                                                                       if ( $this->summary === '' ) {
-                                                                               $this->summary = $undoSummary;
-                                                                       } else {
-                                                                               $this->summary = $undoSummary . $this->context->msg( 'colon-separator' )
-                                                                                       ->inContentLanguage()->text() . $this->summary;
-                                                                       }
-                                                                       $this->undidRev = $undo;
+                                               if ( $newContent->equals( $oldContent ) ) {
+                                                       # Tell the user that the undo results in no change,
+                                                       # i.e. the revisions were already undone.
+                                                       $undoMsg = 'nochange';
+                                                       $content = false;
+                                               } else {
+                                                       # Inform the user of our success and set an automatic edit summary
+                                                       $undoMsg = 'success';
+
+                                                       # If we just undid one rev, use an autosummary
+                                                       $firstrev = $oldrev->getNext();
+                                                       if ( $firstrev && $firstrev->getId() == $undo ) {
+                                                               $userText = $undorev->getUserText();
+                                                               if ( $userText === '' ) {
+                                                                       $undoSummary = $this->context->msg(
+                                                                               'undo-summary-username-hidden',
+                                                                               $undo
+                                                                       )->inContentLanguage()->text();
+                                                               } else {
+                                                                       $undoSummary = $this->context->msg(
+                                                                               'undo-summary',
+                                                                               $undo,
+                                                                               $userText
+                                                                       )->inContentLanguage()->text();
+                                                               }
+                                                               if ( $this->summary === '' ) {
+                                                                       $this->summary = $undoSummary;
+                                                               } else {
+                                                                       $this->summary = $undoSummary . $this->context->msg( 'colon-separator' )
+                                                                               ->inContentLanguage()->text() . $this->summary;
                                                                }
-                                                               $this->formtype = 'diff';
+                                                               $this->undidRev = $undo;
                                                        }
+                                                       $this->formtype = 'diff';
                                                }
-                                       } else {
-                                               // Failed basic sanity checks.
-                                               // Older revisions may have been removed since the link
-                                               // was created, or we may simply have got bogus input.
-                                               $undoMsg = 'norev';
                                        }
-
-                                       $out = $this->context->getOutput();
-                                       // Messages: undo-success, undo-failure, undo-main-slot-only, undo-norev,
-                                       // undo-nochange.
-                                       $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
-                                       $this->editFormPageTop .= Html::rawElement(
-                                               'div', [ 'class' => $class ],
-                                               $out->parseAsInterface(
-                                                       $this->context->msg( 'undo-' . $undoMsg )->plain()
-                                               )
-                                       );
+                               } else {
+                                       // Failed basic sanity checks.
+                                       // Older revisions may have been removed since the link
+                                       // was created, or we may simply have got bogus input.
+                                       $undoMsg = 'norev';
                                }
 
-                               if ( $content === false ) {
-                                       // Hack for restoring old revisions while EditPage
-                                       // can't handle multi-slot editing.
+                               $out = $this->context->getOutput();
+                               // Messages: undo-success, undo-failure, undo-main-slot-only, undo-norev,
+                               // undo-nochange.
+                               $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
+                               $this->editFormPageTop .= Html::rawElement(
+                                       'div', [ 'class' => $class ],
+                                       $out->parseAsInterface(
+                                               $this->context->msg( 'undo-' . $undoMsg )->plain()
+                                       )
+                               );
+                       }
 
-                                       $curRevision = $this->page->getRevision();
-                                       $oldRevision = $this->mArticle->getRevisionFetched();
+                       if ( $content === false ) {
+                               // Hack for restoring old revisions while EditPage
+                               // can't handle multi-slot editing.
 
-                                       if ( $curRevision
-                                               && $oldRevision
-                                               && $curRevision->getId() !== $oldRevision->getId()
-                                               && ( WikiPage::hasDifferencesOutsideMainSlot( $oldRevision, $curRevision )
-                                                       || !$this->isSupportedContentModel( $oldRevision->getContentModel() ) )
-                                       ) {
-                                               $this->context->getOutput()->redirect(
-                                                       $this->mTitle->getFullURL(
-                                                               [
-                                                                       'action' => 'mcrrestore',
-                                                                       'restore' => $oldRevision->getId(),
-                                                               ]
-                                                       )
-                                               );
+                               $curRevision = $this->page->getRevision();
+                               $oldRevision = $this->mArticle->getRevisionFetched();
 
-                                               return false;
-                                       }
-                               }
+                               if ( $curRevision
+                                       && $oldRevision
+                                       && $curRevision->getId() !== $oldRevision->getId()
+                                       && ( WikiPage::hasDifferencesOutsideMainSlot( $oldRevision, $curRevision )
+                                               || !$this->isSupportedContentModel( $oldRevision->getContentModel() ) )
+                               ) {
+                                       $this->context->getOutput()->redirect(
+                                               $this->mTitle->getFullURL(
+                                                       [
+                                                               'action' => 'mcrrestore',
+                                                               'restore' => $oldRevision->getId(),
+                                                       ]
+                                               )
+                                       );
 
-                               if ( $content === false ) {
-                                       $content = $this->getOriginalContent( $user );
+                                       return false;
                                }
                        }
+
+                       if ( $content === false ) {
+                               $content = $this->getOriginalContent( $user );
+                       }
                }
 
                return $content;
@@ -1667,11 +1665,10 @@ class EditPage {
                        case self::AS_SUCCESS_NEW_ARTICLE:
                                $query = $resultDetails['redirect'] ? 'redirect=no' : '';
                                if ( $extraQueryRedirect ) {
-                                       if ( $query === '' ) {
-                                               $query = $extraQueryRedirect;
-                                       } else {
-                                               $query = $query . '&' . $extraQueryRedirect;
+                                       if ( $query !== '' ) {
+                                               $query .= '&';
                                        }
+                                       $query .= $extraQueryRedirect;
                                }
                                $anchor = $resultDetails['sectionanchor'] ?? '';
                                $out->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
@@ -1688,18 +1685,16 @@ class EditPage {
                                );
 
                                if ( $resultDetails['redirect'] ) {
-                                       if ( $extraQuery == '' ) {
-                                               $extraQuery = 'redirect=no';
-                                       } else {
-                                               $extraQuery = 'redirect=no&' . $extraQuery;
+                                       if ( $extraQuery !== '' ) {
+                                               $extraQuery = '&' . $extraQuery;
                                        }
+                                       $extraQuery = 'redirect=no' . $extraQuery;
                                }
                                if ( $extraQueryRedirect ) {
-                                       if ( $extraQuery === '' ) {
-                                               $extraQuery = $extraQueryRedirect;
-                                       } else {
-                                               $extraQuery = $extraQuery . '&' . $extraQueryRedirect;
+                                       if ( $extraQuery !== '' ) {
+                                               $extraQuery .= '&';
                                        }
+                                       $extraQuery .= $extraQueryRedirect;
                                }
 
                                $out->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
@@ -2807,11 +2802,9 @@ ERROR;
 
                $out->addHTML( $this->editFormTextTop );
 
-               if ( $this->wasDeletedSinceLastEdit() ) {
-                       if ( $this->formtype !== 'save' ) {
-                               $out->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
-                                       'deletedwhileediting' );
-                       }
+               if ( $this->wasDeletedSinceLastEdit() && $this->formtype !== 'save' ) {
+                       $out->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
+                               'deletedwhileediting' );
                }
 
                // @todo add EditForm plugin interface and use it here!
@@ -3079,12 +3072,12 @@ ERROR;
                        $this->addExplainConflictHeader( $out );
                        $this->editRevId = $this->page->getLatest();
                } else {
-                       if ( $this->section != '' && $this->section != 'new' ) {
-                               if ( !$this->summary && !$this->preview && !$this->diff ) {
-                                       $sectionTitle = self::extractSectionTitle( $this->textbox1 ); // FIXME: use Content object
-                                       if ( $sectionTitle !== false ) {
-                                               $this->summary = "/* $sectionTitle */ ";
-                                       }
+                       if ( $this->section != '' && $this->section != 'new' && !$this->summary &&
+                               !$this->preview && !$this->diff
+                       ) {
+                               $sectionTitle = self::extractSectionTitle( $this->textbox1 ); // FIXME: use Content object
+                               if ( $sectionTitle !== false ) {
+                                       $this->summary = "/* $sectionTitle */ ";
                                }
                        }
 
@@ -3191,44 +3184,42 @@ ERROR;
                                        'anonpreviewwarning'
                                );
                        }
-               } else {
-                       if ( $this->mTitle->isUserConfigPage() ) {
-                               # Check the skin exists
-                               if ( $this->isWrongCaseUserConfigPage() ) {
-                                       $out->wrapWikiMsg(
-                                               "<div class='error' id='mw-userinvalidconfigtitle'>\n$1\n</div>",
-                                               [ 'userinvalidconfigtitle', $this->mTitle->getSkinFromConfigSubpage() ]
-                                       );
-                               }
-                               if ( $this->getTitle()->isSubpageOf( $user->getUserPage() ) ) {
-                                       $isUserCssConfig = $this->mTitle->isUserCssConfigPage();
-                                       $isUserJsonConfig = $this->mTitle->isUserJsonConfigPage();
-                                       $isUserJsConfig = $this->mTitle->isUserJsConfigPage();
-
-                                       $warning = $isUserCssConfig
-                                               ? 'usercssispublic'
-                                               : ( $isUserJsonConfig ? 'userjsonispublic' : 'userjsispublic' );
-
-                                       $out->wrapWikiMsg( '<div class="mw-userconfigpublic">$1</div>', $warning );
-
-                                       if ( $this->formtype !== 'preview' ) {
-                                               $config = $this->context->getConfig();
-                                               if ( $isUserCssConfig && $config->get( 'AllowUserCss' ) ) {
-                                                       $out->wrapWikiMsg(
-                                                               "<div id='mw-usercssyoucanpreview'>\n$1\n</div>",
-                                                               [ 'usercssyoucanpreview' ]
-                                                       );
-                                               } elseif ( $isUserJsonConfig /* No comparable 'AllowUserJson' */ ) {
-                                                       $out->wrapWikiMsg(
-                                                               "<div id='mw-userjsonyoucanpreview'>\n$1\n</div>",
-                                                               [ 'userjsonyoucanpreview' ]
-                                                       );
-                                               } elseif ( $isUserJsConfig && $config->get( 'AllowUserJs' ) ) {
-                                                       $out->wrapWikiMsg(
-                                                               "<div id='mw-userjsyoucanpreview'>\n$1\n</div>",
-                                                               [ 'userjsyoucanpreview' ]
-                                                       );
-                                               }
+               } elseif ( $this->mTitle->isUserConfigPage() ) {
+                       # Check the skin exists
+                       if ( $this->isWrongCaseUserConfigPage() ) {
+                               $out->wrapWikiMsg(
+                                       "<div class='error' id='mw-userinvalidconfigtitle'>\n$1\n</div>",
+                                       [ 'userinvalidconfigtitle', $this->mTitle->getSkinFromConfigSubpage() ]
+                               );
+                       }
+                       if ( $this->getTitle()->isSubpageOf( $user->getUserPage() ) ) {
+                               $isUserCssConfig = $this->mTitle->isUserCssConfigPage();
+                               $isUserJsonConfig = $this->mTitle->isUserJsonConfigPage();
+                               $isUserJsConfig = $this->mTitle->isUserJsConfigPage();
+
+                               $warning = $isUserCssConfig
+                                       ? 'usercssispublic'
+                                       : ( $isUserJsonConfig ? 'userjsonispublic' : 'userjsispublic' );
+
+                               $out->wrapWikiMsg( '<div class="mw-userconfigpublic">$1</div>', $warning );
+
+                               if ( $this->formtype !== 'preview' ) {
+                                       $config = $this->context->getConfig();
+                                       if ( $isUserCssConfig && $config->get( 'AllowUserCss' ) ) {
+                                               $out->wrapWikiMsg(
+                                                       "<div id='mw-usercssyoucanpreview'>\n$1\n</div>",
+                                                       [ 'usercssyoucanpreview' ]
+                                               );
+                                       } elseif ( $isUserJsonConfig /* No comparable 'AllowUserJson' */ ) {
+                                               $out->wrapWikiMsg(
+                                                       "<div id='mw-userjsonyoucanpreview'>\n$1\n</div>",
+                                                       [ 'userjsonyoucanpreview' ]
+                                               );
+                                       } elseif ( $isUserJsConfig && $config->get( 'AllowUserJs' ) ) {
+                                               $out->wrapWikiMsg(
+                                                       "<div id='mw-userjsyoucanpreview'>\n$1\n</div>",
+                                                       [ 'userjsyoucanpreview' ]
+                                               );
                                        }
                                }
                        }
@@ -3312,10 +3303,8 @@ ERROR;
                        if ( $this->nosummary ) {
                                return;
                        }
-               } else {
-                       if ( !$this->mShowSummaryField ) {
-                               return;
-                       }
+               } elseif ( !$this->mShowSummaryField ) {
+                       return;
                }
 
                $labelText = $this->context->msg( $isSubjectPreview ? 'subject' : 'summary' )->parse();
@@ -4453,16 +4442,14 @@ ERROR;
                                        $lang->formatNum( $maxArticleSize )
                                ]
                        );
-               } else {
-                       if ( !$this->context->msg( 'longpage-hint' )->isDisabled() ) {
-                               $out->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
-                                       [
-                                               'longpage-hint',
-                                               $lang->formatSize( strlen( $this->textbox1 ) ),
-                                               strlen( $this->textbox1 )
-                                       ]
-                               );
-                       }
+               } elseif ( !$this->context->msg( 'longpage-hint' )->isDisabled() ) {
+                       $out->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
+                               [
+                                       'longpage-hint',
+                                       $lang->formatSize( strlen( $this->textbox1 ) ),
+                                       strlen( $this->textbox1 )
+                               ]
+                       );
                }
        }
 
@@ -4560,7 +4547,10 @@ ERROR;
                        return $wgParser->guessLegacySectionNameFromWikiText( $text );
                }
                // Meanwhile, real browsers get real anchors
-               return $wgParser->guessSectionNameFromWikiText( $text );
+               $name = $wgParser->guessSectionNameFromWikiText( $text );
+               // With one little caveat: per T216029, fragments in HTTP redirects need to be urlencoded,
+               // otherwise Chrome double-escapes the rest of the URL.
+               return '#' . urlencode( mb_substr( $name, 1 ) );
        }
 
        /**
diff --git a/includes/FauxResponse.php b/includes/FauxResponse.php
new file mode 100644 (file)
index 0000000..24c396e
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Classes used to send headers and cookies back to the user
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @ingroup HTTP
+ */
+class FauxResponse extends WebResponse {
+       private $headers;
+       private $cookies = [];
+       private $code;
+
+       /**
+        * Stores a HTTP header
+        * @param string $string Header to output
+        * @param bool $replace Replace current similar header
+        * @param null|int $http_response_code Forces the HTTP response code to the specified value.
+        */
+       public function header( $string, $replace = true, $http_response_code = null ) {
+               if ( substr( $string, 0, 5 ) == 'HTTP/' ) {
+                       $parts = explode( ' ', $string, 3 );
+                       $this->code = intval( $parts[1] );
+               } else {
+                       list( $key, $val ) = array_map( 'trim', explode( ":", $string, 2 ) );
+
+                       $key = strtoupper( $key );
+
+                       if ( $replace || !isset( $this->headers[$key] ) ) {
+                               $this->headers[$key] = $val;
+                       }
+               }
+
+               if ( $http_response_code !== null ) {
+                       $this->code = intval( $http_response_code );
+               }
+       }
+
+       /**
+        * @since 1.26
+        * @param int $code Status code
+        */
+       public function statusHeader( $code ) {
+               $this->code = intval( $code );
+       }
+
+       public function headersSent() {
+               return false;
+       }
+
+       /**
+        * @param string $key The name of the header to get (case insensitive).
+        * @return string|null The header value (if set); null otherwise.
+        */
+       public function getHeader( $key ) {
+               $key = strtoupper( $key );
+
+               return $this->headers[$key] ?? null;
+       }
+
+       /**
+        * Get the HTTP response code, null if not set
+        *
+        * @return int|null
+        */
+       public function getStatusCode() {
+               return $this->code;
+       }
+
+       /**
+        * @param string $name The name of the cookie.
+        * @param string $value The value to be stored in the cookie.
+        * @param int|null $expire Ignored in this faux subclass.
+        * @param array $options Ignored in this faux subclass.
+        */
+       public function setCookie( $name, $value, $expire = 0, $options = [] ) {
+               global $wgCookiePath, $wgCookiePrefix, $wgCookieDomain;
+               global $wgCookieSecure, $wgCookieExpiration, $wgCookieHttpOnly;
+
+               $options = array_filter( $options, function ( $a ) {
+                       return $a !== null;
+               } ) + [
+                       'prefix' => $wgCookiePrefix,
+                       'domain' => $wgCookieDomain,
+                       'path' => $wgCookiePath,
+                       'secure' => $wgCookieSecure,
+                       'httpOnly' => $wgCookieHttpOnly,
+                       'raw' => false,
+               ];
+
+               if ( $expire === null ) {
+                       $expire = 0; // Session cookie
+               } elseif ( $expire == 0 && $wgCookieExpiration != 0 ) {
+                       $expire = time() + $wgCookieExpiration;
+               }
+
+               $this->cookies[$options['prefix'] . $name] = [
+                       'value' => (string)$value,
+                       'expire' => (int)$expire,
+                       'path' => (string)$options['path'],
+                       'domain' => (string)$options['domain'],
+                       'secure' => (bool)$options['secure'],
+                       'httpOnly' => (bool)$options['httpOnly'],
+                       'raw' => (bool)$options['raw'],
+               ];
+       }
+
+       /**
+        * @param string $name
+        * @return string|null
+        */
+       public function getCookie( $name ) {
+               if ( isset( $this->cookies[$name] ) ) {
+                       return $this->cookies[$name]['value'];
+               }
+               return null;
+       }
+
+       /**
+        * @param string $name
+        * @return array|null
+        */
+       public function getCookieData( $name ) {
+               return $this->cookies[$name] ?? null;
+       }
+
+       /**
+        * @return array
+        */
+       public function getCookies() {
+               return $this->cookies;
+       }
+}
index 899ac09..0a88b23 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Feed
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Helper functions for feeds
@@ -41,7 +42,7 @@ class FeedUtils {
                $purge = $wgRequest->getVal( 'action' ) === 'purge';
                // Allow users with 'purge' right to clear feed caches
                if ( $purge && $wgUser->isAllowed( 'purge' ) ) {
-                       $cache = ObjectCache::getMainWANInstance();
+                       $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                        $cache->delete( $timekey, 1 );
                        $cache->delete( $key, 1 );
                }
index 18014fa..dddbad5 100644 (file)
@@ -30,10 +30,12 @@ class ForeignResourceManager {
        private $registryFile;
        private $libDir;
        private $tmpParentDir;
+       private $cacheDir;
        private $infoPrinter;
        private $errorPrinter;
        private $verbosePrinter;
        private $action;
+       private $registry;
 
        /**
         * @param string $registryFile Path to YAML file
@@ -60,8 +62,11 @@ class ForeignResourceManager {
 
                // Use a temporary directory under the destination directory instead
                // of wfTempDir() because PHP's rename() does not work across file
-               // systems, as the user's /tmp and $IP may be on different filesystems.
-               $this->tmpParentDir = "{$this->libDir}/.tmp";
+               // systems, and the user's /tmp and $IP may be on different filesystems.
+               $this->tmpParentDir = "{$this->libDir}/.foreign/tmp";
+
+               $cacheHome = getenv( 'XDG_CACHE_HOME' ) ? realpath( getenv( 'XDG_CACHE_HOME' ) ) : false;
+               $this->cacheDir = $cacheHome ? "$cacheHome/mw-foreign" : "{$this->libDir}/.foreign/cache";
        }
 
        /**
@@ -69,18 +74,24 @@ class ForeignResourceManager {
         * @throws Exception
         */
        public function run( $action, $module ) {
-               if ( !in_array( $action, [ 'update', 'verify', 'make-sri' ] ) ) {
-                       throw new Exception( 'Invalid action parameter.' );
+               $actions = [ 'update', 'verify', 'make-sri' ];
+               if ( !in_array( $action, $actions ) ) {
+                       $this->error( "Invalid action.\n\nMust be one of " . implode( ', ', $actions ) . '.' );
+                       return false;
                }
                $this->action = $action;
 
-               $registry = $this->parseBasicYaml( file_get_contents( $this->registryFile ) );
+               $this->registry = $this->parseBasicYaml( file_get_contents( $this->registryFile ) );
                if ( $module === 'all' ) {
-                       $modules = $registry;
-               } elseif ( isset( $registry[ $module ] ) ) {
-                       $modules = [ $module => $registry[ $module ] ];
+                       $modules = $this->registry;
+               } elseif ( isset( $this->registry[ $module ] ) ) {
+                       $modules = [ $module => $this->registry[ $module ] ];
                } else {
-                       throw new Exception( 'Unknown module name.' );
+                       $this->error( "Unknown module name.\n\nMust be one of:\n" .
+                               wordwrap( implode( ', ', array_keys( $this->registry ) ), 80 ) .
+                               '.'
+                       );
+                       return false;
                }
 
                foreach ( $modules as $moduleName => $info ) {
@@ -121,8 +132,8 @@ class ForeignResourceManager {
                        }
                }
 
-               $this->cleanUp();
                $this->output( "\nDone!\n" );
+               $this->cleanUp();
                if ( $this->hasErrors ) {
                        // The verify mode should check all modules/files and fail after, not during.
                        return false;
@@ -131,7 +142,29 @@ class ForeignResourceManager {
                return true;
        }
 
+       private function cacheKey( $src, $integrity ) {
+               $key = basename( $src ) . '_' . substr( $integrity, -12 );
+               $key = preg_replace( '/[.\/+?=_-]+/', '_', $key );
+               return rtrim( $key, '_' );
+       }
+
+       /** @return string|false */
+       private function cacheGet( $key ) {
+               return Wikimedia\quietCall( 'file_get_contents', "{$this->cacheDir}/$key.data" );
+       }
+
+       private function cacheSet( $key, $data ) {
+               wfMkdirParents( $this->cacheDir );
+               file_put_contents( "{$this->cacheDir}/$key.data", $data, LOCK_EX );
+       }
+
        private function fetch( $src, $integrity ) {
+               $key = $this->cacheKey( $src, $integrity );
+               $data = $this->cacheGet( $key );
+               if ( $data ) {
+                       return $data;
+               }
+
                $req = MWHttpRequest::factory( $src, [ 'method' => 'GET', 'followRedirects' => false ] );
                if ( !$req->execute()->isOK() ) {
                        throw new Exception( "Failed to download resource at {$src}" );
@@ -144,15 +177,14 @@ class ForeignResourceManager {
                $actualIntegrity = $algo . '-' . base64_encode( hash( $algo, $data, true ) );
                if ( $integrity === $actualIntegrity ) {
                        $this->verbose( "... passed integrity check for {$src}\n" );
+                       $this->cacheSet( $key, $data );
+               } elseif ( $this->action === 'make-sri' ) {
+                       $this->output( "Integrity for {$src}\n\tintegrity: ${actualIntegrity}\n" );
                } else {
-                       if ( $this->action === 'make-sri' ) {
-                               $this->output( "Integrity for {$src}\n\tintegrity: ${actualIntegrity}\n" );
-                       } else {
-                               throw new Exception( "Integrity check failed for {$src}\n" .
-                                       "\tExpected: {$integrity}\n" .
-                                       "\tActual: {$actualIntegrity}"
-                               );
-                       }
+                       throw new Exception( "Integrity check failed for {$src}\n" .
+                               "\tExpected: {$integrity}\n" .
+                               "\tActual: {$actualIntegrity}"
+                       );
                }
                return $data;
        }
@@ -234,6 +266,7 @@ class ForeignResourceManager {
                                                $from,
                                                RecursiveDirectoryIterator::SKIP_DOTS
                                        ) );
+                                       /** @var SplFileInfo $file */
                                        foreach ( $rii as $file ) {
                                                $remote = $file->getPathname();
                                                $local = strtr( $remote, [ $from => $to ] );
@@ -270,6 +303,23 @@ class ForeignResourceManager {
 
        private function cleanUp() {
                wfRecursiveRemoveDir( $this->tmpParentDir );
+
+               // Prune the cache of files we don't recognise.
+               $knownKeys = [];
+               foreach ( $this->registry as $info ) {
+                       if ( $info['type'] === 'file' || $info['type'] === 'tar' ) {
+                               $knownKeys[] = $this->cacheKey( $info['src'], $info['integrity'] );
+                       } elseif ( $info['type'] === 'multi-file' ) {
+                               foreach ( $info['files'] as $file ) {
+                                       $knownKeys[] = $this->cacheKey( $file['src'], $file['integrity'] );
+                               }
+                       }
+               }
+               foreach ( glob( "{$this->cacheDir}/*" ) as $cacheFile ) {
+                       if ( !in_array( basename( $cacheFile, '.data' ), $knownKeys ) ) {
+                               unlink( $cacheFile );
+                       }
+               }
        }
 
        /**
index 53ddac9..a6e01cc 100644 (file)
@@ -381,7 +381,7 @@ class FormOptions implements ArrayAccess {
 
        /** @name ArrayAccess functions
         * These functions implement the ArrayAccess PHP interface.
-        * @see https://secure.php.net/manual/en/class.arrayaccess.php
+        * @see https://www.php.net/manual/en/class.arrayaccess.php
         */
        /* @{ */
        /**
index 51fe167..b6a1470 100644 (file)
@@ -334,6 +334,7 @@ function wfUrlencode( $s ) {
        static $needle;
 
        if ( is_null( $s ) ) {
+               // Reset $needle for testing.
                $needle = null;
                return '';
        }
@@ -1749,13 +1750,11 @@ function wfResetOutputBuffers( $resetGzipEncoding = true ) {
                        // to avoid getting in some kind of infinite loop.
                        break;
                }
-               if ( $resetGzipEncoding ) {
-                       if ( $status['name'] == 'ob_gzhandler' ) {
-                               // Reset the 'Content-Encoding' field set by this handler
-                               // so we can start fresh.
-                               header_remove( 'Content-Encoding' );
-                               break;
-                       }
+               if ( $resetGzipEncoding && $status['name'] == 'ob_gzhandler' ) {
+                       // Reset the 'Content-Encoding' field set by this handler
+                       // so we can start fresh.
+                       header_remove( 'Content-Encoding' );
+                       break;
                }
        }
 }
@@ -2051,7 +2050,7 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) {
  */
 function wfRecursiveRemoveDir( $dir ) {
        wfDebug( __FUNCTION__ . "( $dir )\n" );
-       // taken from https://secure.php.net/manual/en/function.rmdir.php#98622
+       // taken from https://www.php.net/manual/en/function.rmdir.php#98622
        if ( is_dir( $dir ) ) {
                $objects = scandir( $dir );
                foreach ( $objects as $object ) {
@@ -2137,7 +2136,7 @@ function wfStringToBool( $val ) {
  * @param string|string[] ...$args strings to escape and glue together,
  *  or a single array of strings parameter
  * @return string
- * @deprecated since 1.30 use MediaWiki\Shell::escape()
+ * @deprecated since 1.30 use MediaWiki\Shell\Shell::escape()
  */
 function wfEscapeShellArg( ...$args ) {
        return Shell::escape( ...$args );
@@ -2609,22 +2608,6 @@ function wfWikiID() {
        }
 }
 
-/**
- * Split a wiki ID into DB name and table prefix
- *
- * @param string $wiki
- *
- * @return array
- * @deprecated 1.32
- */
-function wfSplitWikiID( $wiki ) {
-       $bits = explode( '-', $wiki, 2 );
-       if ( count( $bits ) < 2 ) {
-               $bits[] = '';
-       }
-       return $bits;
-}
-
 /**
  * Get a Database object.
  *
@@ -2657,8 +2640,8 @@ function wfGetDB( $db, $groups = [], $wiki = false ) {
 /**
  * Get a load balancer object.
  *
- * @deprecated since 1.27, use MediaWikiServices::getDBLoadBalancer()
- *              or MediaWikiServices::getDBLoadBalancerFactory() instead.
+ * @deprecated since 1.27, use MediaWikiServices::getInstance()->getDBLoadBalancer()
+ *              or MediaWikiServices::getInstance()->getDBLoadBalancerFactory() instead.
  *
  * @param string|bool $wiki Wiki ID, or false for the current wiki
  * @return \Wikimedia\Rdbms\LoadBalancer
@@ -2675,7 +2658,7 @@ function wfGetLB( $wiki = false ) {
 /**
  * Get the load balancer factory object
  *
- * @deprecated since 1.27, use MediaWikiServices::getDBLoadBalancerFactory() instead.
+ * @deprecated since 1.27, use MediaWikiServices::getInstance()->getDBLoadBalancerFactory() instead.
  *
  * @return \Wikimedia\Rdbms\LBFactory
  */
index b2ca673..650a3a8 100644 (file)
@@ -22,8 +22,12 @@ class HeaderCallback {
                // Prevent caching of responses with cookies (T127993)
                $headers = [];
                foreach ( headers_list() as $header ) {
-                       list( $name, $value ) = explode( ':', $header, 2 );
-                       $headers[strtolower( trim( $name ) )][] = trim( $value );
+                       $header = explode( ':', $header, 2 );
+
+                       // Note: The code below (currently) does not care about value-less headers
+                       if ( isset( $header[1] ) ) {
+                               $headers[ strtolower( trim( $header[0] ) ) ][] = trim( $header[1] );
+                       }
                }
 
                if ( isset( $headers['set-cookie'] ) ) {
diff --git a/includes/HistoryBlob.php b/includes/HistoryBlob.php
deleted file mode 100644 (file)
index bca6c7e..0000000
+++ /dev/null
@@ -1,711 +0,0 @@
-<?php
-/**
- * Efficient concatenated text storage.
- *
- * 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
- */
-
-/**
- * Base class for general text storage via the "object" flag in old_flags, or
- * two-part external storage URLs. Used for represent efficient concatenated
- * storage, and migration-related pointer objects.
- */
-interface HistoryBlob {
-       /**
-        * Adds an item of text, returns a stub object which points to the item.
-        * You must call setLocation() on the stub object before storing it to the
-        * database
-        *
-        * @param string $text
-        *
-        * @return string The key for getItem()
-        */
-       function addItem( $text );
-
-       /**
-        * Get item by key, or false if the key is not present
-        *
-        * @param string $key
-        *
-        * @return string|bool
-        */
-       function getItem( $key );
-
-       /**
-        * Set the "default text"
-        * This concept is an odd property of the current DB schema, whereby each text item has a revision
-        * associated with it. The default text is the text of the associated revision. There may, however,
-        * be other revisions in the same object.
-        *
-        * Default text is not required for two-part external storage URLs.
-        *
-        * @param string $text
-        */
-       function setText( $text );
-
-       /**
-        * Get default text. This is called from Revision::getRevisionText()
-        *
-        * @return string
-        */
-       function getText();
-}
-
-/**
- * Concatenated gzip (CGZ) storage
- * Improves compression ratio by concatenating like objects before gzipping
- */
-class ConcatenatedGzipHistoryBlob implements HistoryBlob {
-       public $mVersion = 0, $mCompressed = false, $mItems = [], $mDefaultHash = '';
-       public $mSize = 0;
-       public $mMaxSize = 10000000;
-       public $mMaxCount = 100;
-
-       public function __construct() {
-               if ( !function_exists( 'gzdeflate' ) ) {
-                       throw new MWException( "Need zlib support to read or write this "
-                               . "kind of history object (ConcatenatedGzipHistoryBlob)\n" );
-               }
-       }
-
-       /**
-        * @param string $text
-        * @return string
-        */
-       public function addItem( $text ) {
-               $this->uncompress();
-               $hash = md5( $text );
-               if ( !isset( $this->mItems[$hash] ) ) {
-                       $this->mItems[$hash] = $text;
-                       $this->mSize += strlen( $text );
-               }
-               return $hash;
-       }
-
-       /**
-        * @param string $hash
-        * @return array|bool
-        */
-       public function getItem( $hash ) {
-               $this->uncompress();
-               if ( array_key_exists( $hash, $this->mItems ) ) {
-                       return $this->mItems[$hash];
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * @param string $text
-        * @return void
-        */
-       public function setText( $text ) {
-               $this->uncompress();
-               $this->mDefaultHash = $this->addItem( $text );
-       }
-
-       /**
-        * @return array|bool
-        */
-       public function getText() {
-               $this->uncompress();
-               return $this->getItem( $this->mDefaultHash );
-       }
-
-       /**
-        * Remove an item
-        *
-        * @param string $hash
-        */
-       public function removeItem( $hash ) {
-               $this->mSize -= strlen( $this->mItems[$hash] );
-               unset( $this->mItems[$hash] );
-       }
-
-       /**
-        * Compress the bulk data in the object
-        */
-       public function compress() {
-               if ( !$this->mCompressed ) {
-                       $this->mItems = gzdeflate( serialize( $this->mItems ) );
-                       $this->mCompressed = true;
-               }
-       }
-
-       /**
-        * Uncompress bulk data
-        */
-       public function uncompress() {
-               if ( $this->mCompressed ) {
-                       $this->mItems = unserialize( gzinflate( $this->mItems ) );
-                       $this->mCompressed = false;
-               }
-       }
-
-       /**
-        * @return array
-        */
-       function __sleep() {
-               $this->compress();
-               return [ 'mVersion', 'mCompressed', 'mItems', 'mDefaultHash' ];
-       }
-
-       function __wakeup() {
-               $this->uncompress();
-       }
-
-       /**
-        * Helper function for compression jobs
-        * Returns true until the object is "full" and ready to be committed
-        *
-        * @return bool
-        */
-       public function isHappy() {
-               return $this->mSize < $this->mMaxSize
-                       && count( $this->mItems ) < $this->mMaxCount;
-       }
-}
-
-/**
- * Pointer object for an item within a CGZ blob stored in the text table.
- */
-class HistoryBlobStub {
-       /**
-        * @var array One-step cache variable to hold base blobs; operations that
-        * pull multiple revisions may often pull multiple times from the same
-        * blob. By keeping the last-used one open, we avoid redundant
-        * unserialization and decompression overhead.
-        */
-       protected static $blobCache = [];
-
-       /** @var int */
-       public $mOldId;
-
-       /** @var string */
-       public $mHash;
-
-       /** @var string */
-       public $mRef;
-
-       /**
-        * @param string $hash The content hash of the text
-        * @param int $oldid The old_id for the CGZ object
-        */
-       function __construct( $hash = '', $oldid = 0 ) {
-               $this->mHash = $hash;
-       }
-
-       /**
-        * Sets the location (old_id) of the main object to which this object
-        * points
-        * @param int $id
-        */
-       function setLocation( $id ) {
-               $this->mOldId = $id;
-       }
-
-       /**
-        * Sets the location (old_id) of the referring object
-        * @param string $id
-        */
-       function setReferrer( $id ) {
-               $this->mRef = $id;
-       }
-
-       /**
-        * Gets the location of the referring object
-        * @return string
-        */
-       function getReferrer() {
-               return $this->mRef;
-       }
-
-       /**
-        * @return string|false
-        */
-       function getText() {
-               if ( isset( self::$blobCache[$this->mOldId] ) ) {
-                       $obj = self::$blobCache[$this->mOldId];
-               } else {
-                       $dbr = wfGetDB( DB_REPLICA );
-                       $row = $dbr->selectRow(
-                               'text',
-                               [ 'old_flags', 'old_text' ],
-                               [ 'old_id' => $this->mOldId ]
-                       );
-
-                       if ( !$row ) {
-                               return false;
-                       }
-
-                       $flags = explode( ',', $row->old_flags );
-                       if ( in_array( 'external', $flags ) ) {
-                               $url = $row->old_text;
-                               $parts = explode( '://', $url, 2 );
-                               if ( !isset( $parts[1] ) || $parts[1] == '' ) {
-                                       return false;
-                               }
-                               $row->old_text = ExternalStore::fetchFromURL( $url );
-
-                       }
-
-                       if ( !in_array( 'object', $flags ) ) {
-                               return false;
-                       }
-
-                       if ( in_array( 'gzip', $flags ) ) {
-                               // This shouldn't happen, but a bug in the compress script
-                               // may at times gzip-compress a HistoryBlob object row.
-                               $obj = unserialize( gzinflate( $row->old_text ) );
-                       } else {
-                               $obj = unserialize( $row->old_text );
-                       }
-
-                       if ( !is_object( $obj ) ) {
-                               // Correct for old double-serialization bug.
-                               $obj = unserialize( $obj );
-                       }
-
-                       // Save this item for reference; if pulling many
-                       // items in a row we'll likely use it again.
-                       $obj->uncompress();
-                       self::$blobCache = [ $this->mOldId => $obj ];
-               }
-
-               return $obj->getItem( $this->mHash );
-       }
-
-       /**
-        * Get the content hash
-        *
-        * @return string
-        */
-       function getHash() {
-               return $this->mHash;
-       }
-}
-
-/**
- * To speed up conversion from 1.4 to 1.5 schema, text rows can refer to the
- * leftover cur table as the backend. This avoids expensively copying hundreds
- * of megabytes of data during the conversion downtime.
- *
- * Serialized HistoryBlobCurStub objects will be inserted into the text table
- * on conversion if $wgLegacySchemaConversion is set to true.
- */
-class HistoryBlobCurStub {
-       /** @var int */
-       public $mCurId;
-
-       /**
-        * @param int $curid The cur_id pointed to
-        */
-       function __construct( $curid = 0 ) {
-               $this->mCurId = $curid;
-       }
-
-       /**
-        * Sets the location (cur_id) of the main object to which this object
-        * points
-        *
-        * @param int $id
-        */
-       function setLocation( $id ) {
-               $this->mCurId = $id;
-       }
-
-       /**
-        * @return string|bool
-        */
-       function getText() {
-               $dbr = wfGetDB( DB_REPLICA );
-               $row = $dbr->selectRow( 'cur', [ 'cur_text' ], [ 'cur_id' => $this->mCurId ] );
-               if ( !$row ) {
-                       return false;
-               }
-               return $row->cur_text;
-       }
-}
-
-/**
- * Diff-based history compression
- * Requires xdiff 1.5+ and zlib
- */
-class DiffHistoryBlob implements HistoryBlob {
-       /** @var array Uncompressed item cache */
-       public $mItems = [];
-
-       /** @var int Total uncompressed size */
-       public $mSize = 0;
-
-       /**
-        * @var array Array of diffs. If a diff D from A to B is notated D = B - A,
-        * and Z is an empty string:
-        *
-        *              { item[map[i]] - item[map[i-1]]   where i > 0
-        *    diff[i] = {
-        *              { item[map[i]] - Z                where i = 0
-        */
-       public $mDiffs;
-
-       /** @var array The diff map, see above */
-       public $mDiffMap;
-
-       /** @var int The key for getText()
-        */
-       public $mDefaultKey;
-
-       /** @var string Compressed storage */
-       public $mCompressed;
-
-       /** @var bool True if the object is locked against further writes */
-       public $mFrozen = false;
-
-       /**
-        * @var int The maximum uncompressed size before the object becomes sad
-        * Should be less than max_allowed_packet
-        */
-       public $mMaxSize = 10000000;
-
-       /** @var int The maximum number of text items before the object becomes sad */
-       public $mMaxCount = 100;
-
-       /** Constants from xdiff.h */
-       const XDL_BDOP_INS = 1;
-       const XDL_BDOP_CPY = 2;
-       const XDL_BDOP_INSB = 3;
-
-       function __construct() {
-               if ( !function_exists( 'gzdeflate' ) ) {
-                       throw new MWException( "Need zlib support to read or write DiffHistoryBlob\n" );
-               }
-       }
-
-       /**
-        * @throws MWException
-        * @param string $text
-        * @return int
-        */
-       function addItem( $text ) {
-               if ( $this->mFrozen ) {
-                       throw new MWException( __METHOD__ . ": Cannot add more items after sleep/wakeup" );
-               }
-
-               $this->mItems[] = $text;
-               $this->mSize += strlen( $text );
-               $this->mDiffs = null; // later
-               return count( $this->mItems ) - 1;
-       }
-
-       /**
-        * @param string $key
-        * @return string
-        */
-       function getItem( $key ) {
-               return $this->mItems[$key];
-       }
-
-       /**
-        * @param string $text
-        */
-       function setText( $text ) {
-               $this->mDefaultKey = $this->addItem( $text );
-       }
-
-       /**
-        * @return string
-        */
-       function getText() {
-               return $this->getItem( $this->mDefaultKey );
-       }
-
-       /**
-        * @throws MWException
-        */
-       function compress() {
-               if ( !function_exists( 'xdiff_string_rabdiff' ) ) {
-                       throw new MWException( "Need xdiff 1.5+ support to write DiffHistoryBlob\n" );
-               }
-               if ( isset( $this->mDiffs ) ) {
-                       // Already compressed
-                       return;
-               }
-               if ( $this->mItems === [] ) {
-                       return;
-               }
-
-               // Create two diff sequences: one for main text and one for small text
-               $sequences = [
-                       'small' => [
-                               'tail' => '',
-                               'diffs' => [],
-                               'map' => [],
-                       ],
-                       'main' => [
-                               'tail' => '',
-                               'diffs' => [],
-                               'map' => [],
-                       ],
-               ];
-               $smallFactor = 0.5;
-
-               $mItemsCount = count( $this->mItems );
-               for ( $i = 0; $i < $mItemsCount; $i++ ) {
-                       $text = $this->mItems[$i];
-                       if ( $i == 0 ) {
-                               $seqName = 'main';
-                       } else {
-                               $mainTail = $sequences['main']['tail'];
-                               if ( strlen( $text ) < strlen( $mainTail ) * $smallFactor ) {
-                                       $seqName = 'small';
-                               } else {
-                                       $seqName = 'main';
-                               }
-                       }
-                       $seq =& $sequences[$seqName];
-                       $tail = $seq['tail'];
-                       $diff = $this->diff( $tail, $text );
-                       $seq['diffs'][] = $diff;
-                       $seq['map'][] = $i;
-                       $seq['tail'] = $text;
-               }
-               unset( $seq ); // unlink dangerous alias
-
-               // Knit the sequences together
-               $tail = '';
-               $this->mDiffs = [];
-               $this->mDiffMap = [];
-               foreach ( $sequences as $seq ) {
-                       if ( $seq['diffs'] === [] ) {
-                               continue;
-                       }
-                       if ( $tail === '' ) {
-                               $this->mDiffs[] = $seq['diffs'][0];
-                       } else {
-                               $head = $this->patch( '', $seq['diffs'][0] );
-                               $this->mDiffs[] = $this->diff( $tail, $head );
-                       }
-                       $this->mDiffMap[] = $seq['map'][0];
-                       $diffsCount = count( $seq['diffs'] );
-                       for ( $i = 1; $i < $diffsCount; $i++ ) {
-                               $this->mDiffs[] = $seq['diffs'][$i];
-                               $this->mDiffMap[] = $seq['map'][$i];
-                       }
-                       $tail = $seq['tail'];
-               }
-       }
-
-       /**
-        * @param string $t1
-        * @param string $t2
-        * @return string
-        */
-       function diff( $t1, $t2 ) {
-               # Need to do a null concatenation with warnings off, due to bugs in the current version of xdiff
-               # "String is not zero-terminated"
-               Wikimedia\suppressWarnings();
-               $diff = xdiff_string_rabdiff( $t1, $t2 ) . '';
-               Wikimedia\restoreWarnings();
-               return $diff;
-       }
-
-       /**
-        * @param string $base
-        * @param string $diff
-        * @return bool|string
-        */
-       function patch( $base, $diff ) {
-               if ( function_exists( 'xdiff_string_bpatch' ) ) {
-                       Wikimedia\suppressWarnings();
-                       $text = xdiff_string_bpatch( $base, $diff ) . '';
-                       Wikimedia\restoreWarnings();
-                       return $text;
-               }
-
-               # Pure PHP implementation
-
-               $header = unpack( 'Vofp/Vcsize', substr( $diff, 0, 8 ) );
-
-               # Check the checksum if hash extension is available
-               $ofp = $this->xdiffAdler32( $base );
-               if ( $ofp !== false && $ofp !== substr( $diff, 0, 4 ) ) {
-                       wfDebug( __METHOD__ . ": incorrect base checksum\n" );
-                       return false;
-               }
-               if ( $header['csize'] != strlen( $base ) ) {
-                       wfDebug( __METHOD__ . ": incorrect base length\n" );
-                       return false;
-               }
-
-               $p = 8;
-               $out = '';
-               while ( $p < strlen( $diff ) ) {
-                       $x = unpack( 'Cop', substr( $diff, $p, 1 ) );
-                       $op = $x['op'];
-                       ++$p;
-                       switch ( $op ) {
-                               case self::XDL_BDOP_INS:
-                                       $x = unpack( 'Csize', substr( $diff, $p, 1 ) );
-                                       $p++;
-                                       $out .= substr( $diff, $p, $x['size'] );
-                                       $p += $x['size'];
-                                       break;
-                               case self::XDL_BDOP_INSB:
-                                       $x = unpack( 'Vcsize', substr( $diff, $p, 4 ) );
-                                       $p += 4;
-                                       $out .= substr( $diff, $p, $x['csize'] );
-                                       $p += $x['csize'];
-                                       break;
-                               case self::XDL_BDOP_CPY:
-                                       $x = unpack( 'Voff/Vcsize', substr( $diff, $p, 8 ) );
-                                       $p += 8;
-                                       $out .= substr( $base, $x['off'], $x['csize'] );
-                                       break;
-                               default:
-                                       wfDebug( __METHOD__ . ": invalid op\n" );
-                                       return false;
-                       }
-               }
-               return $out;
-       }
-
-       /**
-        * Compute a binary "Adler-32" checksum as defined by LibXDiff, i.e. with
-        * 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
-        */
-       function xdiffAdler32( $s ) {
-               if ( !function_exists( 'hash' ) ) {
-                       return false;
-               }
-
-               static $init;
-               if ( $init === null ) {
-                       $init = str_repeat( "\xf0", 205 ) . "\xee" . str_repeat( "\xf0", 67 ) . "\x02";
-               }
-
-               // The real Adler-32 checksum of $init is zero, so it initialises the
-               // state to zero, as it is at the start of LibXDiff's checksum
-               // algorithm. Appending the subject string then simulates LibXDiff.
-               return strrev( hash( 'adler32', $init . $s, true ) );
-       }
-
-       function uncompress() {
-               if ( !$this->mDiffs ) {
-                       return;
-               }
-               $tail = '';
-               $mDiffsCount = count( $this->mDiffs );
-               for ( $diffKey = 0; $diffKey < $mDiffsCount; $diffKey++ ) {
-                       $textKey = $this->mDiffMap[$diffKey];
-                       $text = $this->patch( $tail, $this->mDiffs[$diffKey] );
-                       $this->mItems[$textKey] = $text;
-                       $tail = $text;
-               }
-       }
-
-       /**
-        * @return array
-        */
-       function __sleep() {
-               $this->compress();
-               if ( $this->mItems === [] ) {
-                       $info = false;
-               } else {
-                       // Take forward differences to improve the compression ratio for sequences
-                       $map = '';
-                       $prev = 0;
-                       foreach ( $this->mDiffMap as $i ) {
-                               if ( $map !== '' ) {
-                                       $map .= ',';
-                               }
-                               $map .= $i - $prev;
-                               $prev = $i;
-                       }
-                       $info = [
-                               'diffs' => $this->mDiffs,
-                               'map' => $map
-                       ];
-               }
-               if ( isset( $this->mDefaultKey ) ) {
-                       $info['default'] = $this->mDefaultKey;
-               }
-               $this->mCompressed = gzdeflate( serialize( $info ) );
-               return [ 'mCompressed' ];
-       }
-
-       function __wakeup() {
-               // addItem() doesn't work if mItems is partially filled from mDiffs
-               $this->mFrozen = true;
-               $info = unserialize( gzinflate( $this->mCompressed ) );
-               unset( $this->mCompressed );
-
-               if ( !$info ) {
-                       // Empty object
-                       return;
-               }
-
-               if ( isset( $info['default'] ) ) {
-                       $this->mDefaultKey = $info['default'];
-               }
-               $this->mDiffs = $info['diffs'];
-               if ( isset( $info['base'] ) ) {
-                       // Old format
-                       $this->mDiffMap = range( 0, count( $this->mDiffs ) - 1 );
-                       array_unshift( $this->mDiffs,
-                               pack( 'VVCV', 0, 0, self::XDL_BDOP_INSB, strlen( $info['base'] ) ) .
-                               $info['base'] );
-               } else {
-                       // New format
-                       $map = explode( ',', $info['map'] );
-                       $cur = 0;
-                       $this->mDiffMap = [];
-                       foreach ( $map as $i ) {
-                               $cur += $i;
-                               $this->mDiffMap[] = $cur;
-                       }
-               }
-               $this->uncompress();
-       }
-
-       /**
-        * Helper function for compression jobs
-        * Returns true until the object is "full" and ready to be committed
-        *
-        * @return bool
-        */
-       function isHappy() {
-               return $this->mSize < $this->mMaxSize
-                       && count( $this->mItems ) < $this->mMaxCount;
-       }
-
-}
-
-// phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
-if ( false ) {
-       // Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
-       // class name coerced to lowercase. We can improve efficiency by adding
-       // autoload entries for the lowercase variants of these classes (T166759).
-       // The code below is never executed, but it is picked up by the AutoloadGenerator
-       // parser, which scans for class_alias() calls.
-       class_alias( ConcatenatedGzipHistoryBlob::class, 'concatenatedgziphistoryblob' );
-       class_alias( HistoryBlobCurStub::class, 'historyblobcurstub' );
-       class_alias( HistoryBlobStub::class, 'historyblobstub' );
-}
index 0aea7ea..aa51243 100644 (file)
@@ -213,7 +213,7 @@ class Html {
                        // Silly XML.
                        return substr( $start, 0, -1 ) . '/>';
                } else {
-                       return "$start$contents" . self::closeElement( $element );
+                       return $start . $contents . self::closeElement( $element );
                }
        }
 
@@ -574,10 +574,8 @@ class Html {
                $attrs = [];
                if ( $nonce !== null ) {
                        $attrs['nonce'] = $nonce;
-               } else {
-                       if ( ContentSecurityPolicy::isNonceRequired( RequestContext::getMain()->getConfig() ) ) {
-                               wfWarn( "no nonce set on script. CSP will break it" );
-                       }
+               } elseif ( ContentSecurityPolicy::isNonceRequired( RequestContext::getMain()->getConfig() ) ) {
+                       wfWarn( "no nonce set on script. CSP will break it" );
                }
 
                if ( preg_match( '/<\/?script/i', $contents ) ) {
@@ -600,10 +598,8 @@ class Html {
                $attrs = [ 'src' => $url ];
                if ( $nonce !== null ) {
                        $attrs['nonce'] = $nonce;
-               } else {
-                       if ( ContentSecurityPolicy::isNonceRequired( RequestContext::getMain()->getConfig() ) ) {
-                               wfWarn( "no nonce set on script. CSP will break it" );
-                       }
+               } elseif ( ContentSecurityPolicy::isNonceRequired( RequestContext::getMain()->getConfig() ) ) {
+                       wfWarn( "no nonce set on script. CSP will break it" );
                }
 
                return self::element( 'script', $attrs );
@@ -973,7 +969,7 @@ class Html {
                if ( $isXHTML ) { // XHTML5
                        // XML MIME-typed markup should have an xml header.
                        // However a DOCTYPE is not needed.
-                       $ret .= "<?xml version=\"1.0\" encoding=\"UTF-8\" ?" . ">\n";
+                       $ret .= "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
 
                        // Add the standard xmlns
                        $attribs['xmlns'] = 'http://www.w3.org/1999/xhtml';
@@ -983,7 +979,6 @@ class Html {
                                $attribs["xmlns:$tag"] = $ns;
                        }
                } else { // HTML5
-                       // DOCTYPE
                        $ret .= "<!DOCTYPE html>\n";
                }
 
index 049fb07..4f0ab6a 100644 (file)
@@ -112,7 +112,7 @@ class Linker {
                if ( $html !== null ) {
                        $text = new HtmlArmor( $html );
                } else {
-                       $text = $html; // null
+                       $text = null;
                }
 
                if ( in_array( 'known', $options, true ) ) {
@@ -823,13 +823,20 @@ class Linker {
 
        /**
         * Make an external link
+        *
         * @since 1.16.3. $title added in 1.21
         * @param string $url URL to link to
+        * @param-taint $url escapes_html
         * @param string $text Text of link
+        * @param-taint $text escapes_html
         * @param bool $escape Do we escape the link text?
+        * @param-taint $escape none
         * @param string $linktype Type of external link. Gets added to the classes
+        * @param-taint $linktype escapes_html
         * @param array $attribs Array of extra attributes to <a>
+        * @param-taint $attribs escapes_html
         * @param Title|null $title Title object used for title specific link attributes
+        * @param-taint $title none
         * @return string
         */
        public static function makeExternalLink( $url, $text, $escape = true,
@@ -994,7 +1001,7 @@ class Linker {
         * @return string
         */
        public static function userToolLinksRedContribs( $userId, $userText, $edits = null ) {
-               return self::userToolLinks( $userId, $userText, true, 0, $edits );
+               return self::userToolLinks( $userId, $userText, true, 0, $edits, false );
        }
 
        /**
@@ -1070,21 +1077,23 @@ class Linker {
         * @since 1.16.3
         * @param Revision $rev
         * @param bool $isPublic Show only if all users can see it
+        * @param bool $useParentheses (optional) Wrap comments in parentheses where needed
         * @return string HTML
         */
-       public static function revUserTools( $rev, $isPublic = false ) {
+       public static function revUserTools( $rev, $isPublic = false, $useParentheses = true ) {
                if ( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
                        $link = wfMessage( 'rev-deleted-user' )->escaped();
                } elseif ( $rev->userCan( Revision::DELETED_USER ) ) {
                        $userId = $rev->getUser( Revision::FOR_THIS_USER );
                        $userText = $rev->getUserText( Revision::FOR_THIS_USER );
                        $link = self::userLink( $userId, $userText )
-                               . self::userToolLinks( $userId, $userText );
+                               . self::userToolLinks( $userId, $userText, false, 0, null,
+                                       $useParentheses );
                } else {
                        $link = wfMessage( 'rev-deleted-user' )->escaped();
                }
                if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
-                       return ' <span class="history-deleted">' . $link . '</span>';
+                       return ' <span class="history-deleted mw-userlink">' . $link . '</span>';
                }
                return $link;
        }
@@ -1510,7 +1519,7 @@ class Linker {
                        $block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
                }
                if ( $rev->isDeleted( Revision::DELETED_COMMENT ) ) {
-                       return " <span class=\"history-deleted\">$block</span>";
+                       return " <span class=\"history-deleted comment\">$block</span>";
                }
                return $block;
        }
@@ -1525,9 +1534,8 @@ class Linker {
                        $stxt = wfMessage( 'historyempty' )->escaped();
                } else {
                        $stxt = wfMessage( 'nbytes' )->numParams( $size )->escaped();
-                       $stxt = wfMessage( 'parentheses' )->rawParams( $stxt )->escaped();
                }
-               return "<span class=\"history-size\">$stxt</span>";
+               return "<span class=\"history-size mw-diff-bytes\">$stxt</span>";
        }
 
        /**
@@ -1600,9 +1608,8 @@ class Linker {
         * @return string Full html of the TOC
         */
        public static function tocList( $toc, $lang = null ) {
-               global $wgLang;
-               $lang = $lang ?? $wgLang;
-               if ( !is_object( $lang ) ) {
+               $lang = $lang ?? RequestContext::getMain()->getLanguage();
+               if ( !$lang instanceof Language ) {
                        wfDeprecated( __METHOD__ . ' with type other than Language for $lang', '1.33' );
                        $lang = wfGetLangObj( $lang );
                }
@@ -1704,12 +1711,8 @@ class Linker {
        static function splitTrail( $trail ) {
                $regex = MediaWikiServices::getInstance()->getContentLanguage()->linkTrail();
                $inside = '';
-               if ( $trail !== '' ) {
-                       $m = [];
-                       if ( preg_match( $regex, $trail, $m ) ) {
-                               $inside = $m[1];
-                               $trail = $m[2];
-                       }
+               if ( $trail !== '' && preg_match( $regex, $trail, $m ) ) {
+                       list( , $inside, $trail ) = $m;
                }
                return [ $inside, $trail ];
        }
@@ -1762,6 +1765,12 @@ class Linker {
                        $inner = $context->msg( 'brackets' )->rawParams( $inner )->escaped();
                }
 
+               if ( $context->getUser()->getBoolOption( 'showrollbackconfirmation' ) ) {
+                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                       $stats->increment( 'rollbackconfirmation.event.load' );
+                       $context->getOutput()->addModules( 'mediawiki.page.rollback.confirmation' );
+               }
+
                return '<span class="mw-rollback-link">' . $inner . '</span>';
        }
 
@@ -1855,20 +1864,24 @@ class Linker {
                }
 
                $title = $rev->getTitle();
+
                $query = [
                        'action' => 'rollback',
                        'from' => $rev->getUserText(),
                        'token' => $context->getUser()->getEditToken( 'rollback' ),
                ];
+
                $attrs = [
                        'data-mw' => 'interface',
-                       'title' => $context->msg( 'tooltip-rollback' )->text(),
+                       'title' => $context->msg( 'tooltip-rollback' )->text()
                ];
+
                $options = [ 'known', 'noclasses' ];
 
                if ( $context->getRequest()->getBool( 'bot' ) ) {
+                       //T17999
+                       $query['hidediff'] = '1';
                        $query['bot'] = '1';
-                       $query['hidediff'] = '1'; // T17999
                }
 
                $disableRollbackEditCount = false;
index 3079c65..cbe5a1a 100644 (file)
@@ -86,10 +86,8 @@ class MWGrants {
         * @return string[] Corresponding grant descriptions
         */
        public static function grantNames( array $grants, $lang = null ) {
-               if ( $lang !== null ) {
-                       if ( is_string( $lang ) ) {
-                               $lang = Language::factory( $lang );
-                       }
+               if ( $lang !== null && is_string( $lang ) ) {
+                       $lang = Language::factory( $lang );
                }
 
                $ret = [];
index 98e70bf..1529473 100644 (file)
 use MediaWiki\MediaWikiServices;
 
 /**
- * This is a utility class with only static functions
- * for dealing with namespaces that encodes all the
- * "magic" behaviors of them based on index.  The textual
- * names of the namespaces are handled by Language.php.
- *
- * These are synonyms for the names given in the language file
- * Users and translators should not change them
+ * @deprecated since 1.34, use NamespaceInfo instead
  */
 class MWNamespace {
-
-       /**
-        * These namespaces should always be first-letter capitalized, now and
-        * forevermore. Historically, they could've probably been lowercased too,
-        * but some things are just too ingrained now. :)
-        */
-       private static $alwaysCapitalizedNamespaces = [ NS_SPECIAL, NS_USER, NS_MEDIAWIKI ];
-
-       /** @var string[]|null Canonical namespaces cache */
-       private static $canonicalNamespaces = null;
-
-       /** @var array|false Canonical namespaces index cache */
-       private static $namespaceIndexes = false;
-
-       /** @var int[]|null Valid namespaces cache */
-       private static $validNamespaces = null;
-
-       /**
-        * Throw an exception when trying to get the subject or talk page
-        * for a given namespace where it does not make sense.
-        * Special namespaces are defined in includes/Defines.php and have
-        * a value below 0 (ex: NS_SPECIAL = -1 , NS_MEDIA = -2)
-        *
-        * @param int $index
-        * @param string $method
-        *
-        * @throws MWException
-        * @return bool
-        */
-       private static function isMethodValidFor( $index, $method ) {
-               if ( $index < NS_MAIN ) {
-                       throw new MWException( "$method does not make any sense for given namespace $index" );
-               }
-               return true;
-       }
-
-       /**
-        * Clear internal caches
-        *
-        * For use in unit testing when namespace configuration is changed.
-        *
-        * @since 1.31
-        */
-       public static function clearCaches() {
-               self::$canonicalNamespaces = null;
-               self::$namespaceIndexes = false;
-               self::$validNamespaces = null;
-       }
-
        /**
         * Can pages in the given namespace be moved?
         *
@@ -87,16 +32,7 @@ class MWNamespace {
         * @return bool
         */
        public static function isMovable( $index ) {
-               global $wgAllowImageMoving;
-
-               $result = !( $index < NS_MAIN || ( $index == NS_FILE && !$wgAllowImageMoving ) );
-
-               /**
-                * @since 1.20
-                */
-               Hooks::run( 'NamespaceIsMovable', [ $index, &$result ] );
-
-               return $result;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->isMovable( $index );
        }
 
        /**
@@ -107,7 +43,7 @@ class MWNamespace {
         * @since 1.19
         */
        public static function isSubject( $index ) {
-               return !self::isTalk( $index );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->isSubject( $index );
        }
 
        /**
@@ -117,8 +53,7 @@ class MWNamespace {
         * @return bool
         */
        public static function isTalk( $index ) {
-               return $index > NS_MAIN
-                       && $index % 2;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->isTalk( $index );
        }
 
        /**
@@ -128,10 +63,7 @@ class MWNamespace {
         * @return int
         */
        public static function getTalk( $index ) {
-               self::isMethodValidFor( $index, __METHOD__ );
-               return self::isTalk( $index )
-                       ? $index
-                       : $index + 1;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getTalk( $index );
        }
 
        /**
@@ -142,14 +74,7 @@ class MWNamespace {
         * @return int
         */
        public static function getSubject( $index ) {
-               # Handle special namespaces
-               if ( $index < NS_MAIN ) {
-                       return $index;
-               }
-
-               return self::isTalk( $index )
-                       ? $index - 1
-                       : $index;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getSubject( $index );
        }
 
        /**
@@ -161,15 +86,7 @@ class MWNamespace {
         * @return int|null If no associated namespace could be found
         */
        public static function getAssociated( $index ) {
-               self::isMethodValidFor( $index, __METHOD__ );
-
-               if ( self::isSubject( $index ) ) {
-                       return self::getTalk( $index );
-               } elseif ( self::isTalk( $index ) ) {
-                       return self::getSubject( $index );
-               } else {
-                       return null;
-               }
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getAssociated( $index );
        }
 
        /**
@@ -181,8 +98,7 @@ class MWNamespace {
         * @since 1.19
         */
        public static function exists( $index ) {
-               $nslist = self::getCanonicalNamespaces();
-               return isset( $nslist[$index] );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->exists( $index );
        }
 
        /**
@@ -200,7 +116,7 @@ class MWNamespace {
         * @since 1.19
         */
        public static function equals( $ns1, $ns2 ) {
-               return $ns1 == $ns2;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->equals( $ns1, $ns2 );
        }
 
        /**
@@ -215,36 +131,19 @@ class MWNamespace {
         * @since 1.19
         */
        public static function subjectEquals( $ns1, $ns2 ) {
-               return self::getSubject( $ns1 ) == self::getSubject( $ns2 );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->
+                       subjectEquals( $ns1, $ns2 );
        }
 
        /**
         * Returns array of all defined namespaces with their canonical
         * (English) names.
         *
-        * @param bool $rebuild Rebuild namespace list (default = false). Used for testing.
-        *  Deprecated since 1.31, use self::clearCaches() instead.
-        *
         * @return array
         * @since 1.17
         */
-       public static function getCanonicalNamespaces( $rebuild = false ) {
-               if ( $rebuild ) {
-                       self::clearCaches();
-               }
-
-               if ( self::$canonicalNamespaces === null ) {
-                       global $wgExtraNamespaces, $wgCanonicalNamespaceNames;
-                       self::$canonicalNamespaces = [ NS_MAIN => '' ] + $wgCanonicalNamespaceNames;
-                       // Add extension namespaces
-                       self::$canonicalNamespaces +=
-                               ExtensionRegistry::getInstance()->getAttribute( 'ExtensionNamespaces' );
-                       if ( is_array( $wgExtraNamespaces ) ) {
-                               self::$canonicalNamespaces += $wgExtraNamespaces;
-                       }
-                       Hooks::run( 'CanonicalNamespaces', [ &self::$canonicalNamespaces ] );
-               }
-               return self::$canonicalNamespaces;
+       public static function getCanonicalNamespaces() {
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getCanonicalNamespaces();
        }
 
        /**
@@ -254,8 +153,7 @@ class MWNamespace {
         * @return string|bool If no canonical definition.
         */
        public static function getCanonicalName( $index ) {
-               $nslist = self::getCanonicalNamespaces();
-               return $nslist[$index] ?? false;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getCanonicalName( $index );
        }
 
        /**
@@ -266,17 +164,7 @@ class MWNamespace {
         * @return int
         */
        public static function getCanonicalIndex( $name ) {
-               if ( self::$namespaceIndexes === false ) {
-                       self::$namespaceIndexes = [];
-                       foreach ( self::getCanonicalNamespaces() as $i => $text ) {
-                               self::$namespaceIndexes[strtolower( $text )] = $i;
-                       }
-               }
-               if ( array_key_exists( $name, self::$namespaceIndexes ) ) {
-                       return self::$namespaceIndexes[$name];
-               } else {
-                       return null;
-               }
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getCanonicalIndex( $name );
        }
 
        /**
@@ -285,17 +173,7 @@ class MWNamespace {
         * @return array
         */
        public static function getValidNamespaces() {
-               if ( is_null( self::$validNamespaces ) ) {
-                       foreach ( array_keys( self::getCanonicalNamespaces() ) as $ns ) {
-                               if ( $ns >= 0 ) {
-                                       self::$validNamespaces[] = $ns;
-                               }
-                       }
-                       // T109137: sort numerically
-                       sort( self::$validNamespaces, SORT_NUMERIC );
-               }
-
-               return self::$validNamespaces;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getValidNamespaces();
        }
 
        /**
@@ -307,6 +185,7 @@ class MWNamespace {
         * @return bool True if this namespace either is or has a corresponding talk namespace.
         */
        public static function canTalk( $index ) {
+               wfDeprecated( __METHOD__, '1.30' );
                return self::hasTalkNamespace( $index );
        }
 
@@ -319,7 +198,7 @@ class MWNamespace {
         * @return bool True if this namespace either is or has a corresponding talk namespace.
         */
        public static function hasTalkNamespace( $index ) {
-               return $index >= NS_MAIN;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->hasTalkNamespace( $index );
        }
 
        /**
@@ -330,8 +209,7 @@ class MWNamespace {
         * @return bool
         */
        public static function isContent( $index ) {
-               global $wgContentNamespaces;
-               return $index == NS_MAIN || in_array( $index, $wgContentNamespaces );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->isContent( $index );
        }
 
        /**
@@ -342,8 +220,7 @@ class MWNamespace {
         * @return bool
         */
        public static function wantSignatures( $index ) {
-               global $wgExtraSignatureNamespaces;
-               return self::isTalk( $index ) || in_array( $index, $wgExtraSignatureNamespaces );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->wantSignatures( $index );
        }
 
        /**
@@ -353,7 +230,7 @@ class MWNamespace {
         * @return bool
         */
        public static function isWatchable( $index ) {
-               return $index >= NS_MAIN;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->isWatchable( $index );
        }
 
        /**
@@ -363,8 +240,7 @@ class MWNamespace {
         * @return bool
         */
        public static function hasSubpages( $index ) {
-               global $wgNamespacesWithSubpages;
-               return !empty( $wgNamespacesWithSubpages[$index] );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->hasSubpages( $index );
        }
 
        /**
@@ -372,15 +248,7 @@ class MWNamespace {
         * @return array Array of namespace indices
         */
        public static function getContentNamespaces() {
-               global $wgContentNamespaces;
-               if ( !is_array( $wgContentNamespaces ) || $wgContentNamespaces === [] ) {
-                       return [ NS_MAIN ];
-               } elseif ( !in_array( NS_MAIN, $wgContentNamespaces ) ) {
-                       // always force NS_MAIN to be part of array (to match the algorithm used by isContent)
-                       return array_merge( [ NS_MAIN ], $wgContentNamespaces );
-               } else {
-                       return $wgContentNamespaces;
-               }
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getContentNamespaces();
        }
 
        /**
@@ -390,10 +258,7 @@ class MWNamespace {
         * @return array Array of namespace indices
         */
        public static function getSubjectNamespaces() {
-               return array_filter(
-                       self::getValidNamespaces(),
-                       'MWNamespace::isSubject'
-               );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getSubjectNamespaces();
        }
 
        /**
@@ -403,10 +268,7 @@ class MWNamespace {
         * @return array Array of namespace indices
         */
        public static function getTalkNamespaces() {
-               return array_filter(
-                       self::getValidNamespaces(),
-                       'MWNamespace::isTalk'
-               );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->getTalkNamespaces();
        }
 
        /**
@@ -416,23 +278,7 @@ class MWNamespace {
         * @return bool
         */
        public static function isCapitalized( $index ) {
-               global $wgCapitalLinks, $wgCapitalLinkOverrides;
-               // Turn NS_MEDIA into NS_FILE
-               $index = $index === NS_MEDIA ? NS_FILE : $index;
-
-               // Make sure to get the subject of our namespace
-               $index = self::getSubject( $index );
-
-               // Some namespaces are special and should always be upper case
-               if ( in_array( $index, self::$alwaysCapitalizedNamespaces ) ) {
-                       return true;
-               }
-               if ( isset( $wgCapitalLinkOverrides[$index] ) ) {
-                       // $wgCapitalLinkOverrides is explicitly set
-                       return $wgCapitalLinkOverrides[$index];
-               }
-               // Default to the global setting
-               return $wgCapitalLinks;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->isCapitalized( $index );
        }
 
        /**
@@ -444,7 +290,8 @@ class MWNamespace {
         * @return bool
         */
        public static function hasGenderDistinction( $index ) {
-               return $index == NS_USER || $index == NS_USER_TALK;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->
+                       hasGenderDistinction( $index );
        }
 
        /**
@@ -455,8 +302,7 @@ class MWNamespace {
         * @return bool
         */
        public static function isNonincludable( $index ) {
-               global $wgNonincludableNamespaces;
-               return $wgNonincludableNamespaces && in_array( $index, $wgNonincludableNamespaces );
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->isNonincludable( $index );
        }
 
        /**
@@ -471,9 +317,8 @@ class MWNamespace {
         * @return null|string Default model name for the given namespace, if set
         */
        public static function getNamespaceContentModel( $index ) {
-               $config = MediaWikiServices::getInstance()->getMainConfig();
-               $models = $config->get( 'NamespaceContentModels' );
-               return $models[$index] ?? null;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->
+                       getNamespaceContentModel( $index );
        }
 
        /**
@@ -486,64 +331,8 @@ class MWNamespace {
         * @return array
         */
        public static function getRestrictionLevels( $index, User $user = null ) {
-               global $wgNamespaceProtection, $wgRestrictionLevels;
-
-               if ( !isset( $wgNamespaceProtection[$index] ) ) {
-                       // All levels are valid if there's no namespace restriction.
-                       // But still filter by user, if necessary
-                       $levels = $wgRestrictionLevels;
-                       if ( $user ) {
-                               $levels = array_values( array_filter( $levels, function ( $level ) use ( $user ) {
-                                       $right = $level;
-                                       if ( $right == 'sysop' ) {
-                                               $right = 'editprotected'; // BC
-                                       }
-                                       if ( $right == 'autoconfirmed' ) {
-                                               $right = 'editsemiprotected'; // BC
-                                       }
-                                       return ( $right == '' || $user->isAllowed( $right ) );
-                               } ) );
-                       }
-                       return $levels;
-               }
-
-               // First, get the list of groups that can edit this namespace.
-               $namespaceGroups = [];
-               $combine = 'array_merge';
-               foreach ( (array)$wgNamespaceProtection[$index] as $right ) {
-                       if ( $right == 'sysop' ) {
-                               $right = 'editprotected'; // BC
-                       }
-                       if ( $right == 'autoconfirmed' ) {
-                               $right = 'editsemiprotected'; // BC
-                       }
-                       if ( $right != '' ) {
-                               $namespaceGroups = call_user_func( $combine, $namespaceGroups,
-                                       User::getGroupsWithPermission( $right ) );
-                               $combine = 'array_intersect';
-                       }
-               }
-
-               // Now, keep only those restriction levels where there is at least one
-               // group that can edit the namespace but would be blocked by the
-               // restriction.
-               $usableLevels = [ '' ];
-               foreach ( $wgRestrictionLevels as $level ) {
-                       $right = $level;
-                       if ( $right == 'sysop' ) {
-                               $right = 'editprotected'; // BC
-                       }
-                       if ( $right == 'autoconfirmed' ) {
-                               $right = 'editsemiprotected'; // BC
-                       }
-                       if ( $right != '' && ( !$user || $user->isAllowed( $right ) ) &&
-                               array_diff( $namespaceGroups, User::getGroupsWithPermission( $right ) )
-                       ) {
-                               $usableLevels[] = $level;
-                       }
-               }
-
-               return $usableLevels;
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->
+                       getRestrictionLevels( $index, $user );
        }
 
        /**
@@ -557,14 +346,7 @@ class MWNamespace {
         * @return string One of 'subcat', 'file', 'page'
         */
        public static function getCategoryLinkType( $index ) {
-               self::isMethodValidFor( $index, __METHOD__ );
-
-               if ( $index == NS_CATEGORY ) {
-                       return 'subcat';
-               } elseif ( $index == NS_FILE ) {
-                       return 'file';
-               } else {
-                       return 'page';
-               }
+               return MediaWikiServices::getInstance()->getNamespaceInfo()->
+                       getCategoryLinkType( $index );
        }
 }
index 4420d1d..3c77234 100644 (file)
@@ -125,6 +125,7 @@ class MagicWord {
         * @deprecated since 1.32, use MagicWordFactory::get
         */
        public static function get( $id ) {
+               wfDeprecated( __METHOD__, '1.32' );
                return MediaWikiServices::getInstance()->getMagicWordFactory()->get( $id );
        }
 
@@ -135,6 +136,7 @@ class MagicWord {
         * @deprecated since 1.32, use MagicWordFactory::getVariableIDs
         */
        public static function getVariableIDs() {
+               wfDeprecated( __METHOD__, '1.32' );
                return MediaWikiServices::getInstance()->getMagicWordFactory()->getVariableIDs();
        }
 
@@ -144,6 +146,7 @@ class MagicWord {
         * @deprecated since 1.32, use MagicWordFactory::getSubstIDs
         */
        public static function getSubstIDs() {
+               wfDeprecated( __METHOD__, '1.32' );
                return MediaWikiServices::getInstance()->getMagicWordFactory()->getSubstIDs();
        }
 
@@ -155,6 +158,7 @@ class MagicWord {
         * @deprecated since 1.32, use MagicWordFactory::getCacheTTL
         */
        public static function getCacheTTL( $id ) {
+               wfDeprecated( __METHOD__, '1.32' );
                return MediaWikiServices::getInstance()->getMagicWordFactory()->getCacheTTL( $id );
        }
 
@@ -165,6 +169,7 @@ class MagicWord {
         * @deprecated since 1.32, use MagicWordFactory::getDoubleUnderscoreArray
         */
        public static function getDoubleUnderscoreArray() {
+               wfDeprecated( __METHOD__, '1.32' );
                return MediaWikiServices::getInstance()->getMagicWordFactory()->getDoubleUnderscoreArray();
        }
 
index fde32ce..707c644 100644 (file)
@@ -268,10 +268,7 @@ class MagicWordArray {
                        return $hash[1][$text];
                }
                $lc = $this->factory->getContentLanguage()->lc( $text );
-               if ( isset( $hash[0][$lc] ) ) {
-                       return $hash[0][$lc];
-               }
-               return false;
+               return $hash[0][$lc] ?? false;
        }
 
        /**
index 43512e1..990ed4e 100644 (file)
@@ -330,7 +330,7 @@ class MediaWiki {
 
                if ( $request->getVal( 'action', 'view' ) != 'view'
                        || $request->wasPosted()
-                       || ( $request->getVal( 'title' ) !== null
+                       || ( $request->getCheck( 'title' )
                                && $title->getPrefixedDBkey() == $request->getVal( 'title' ) )
                        || count( $request->getValueNames( [ 'action', 'title' ] ) )
                        || !Hooks::run( 'TestCanonicalRedirect', [ $request, $title, $output ] )
@@ -428,11 +428,9 @@ class MediaWiki {
                        if ( !$ignoreRedirect && ( $target || $page->isRedirect() ) ) {
                                // Is the target already set by an extension?
                                $target = $target ?: $page->followRedirect();
-                               if ( is_string( $target ) ) {
-                                       if ( !$this->config->get( 'DisableHardRedirects' ) ) {
-                                               // we'll need to redirect
-                                               return $target;
-                                       }
+                               if ( is_string( $target ) && !$this->config->get( 'DisableHardRedirects' ) ) {
+                                       // we'll need to redirect
+                                       return $target;
                                }
                                if ( is_object( $target ) ) {
                                        // Rewrite environment to redirected article
@@ -937,7 +935,7 @@ class MediaWiki {
        ) {
                if ( $config->get( 'StatsdServer' ) && $stats->hasData() ) {
                        try {
-                               $statsdServer = explode( ':', $config->get( 'StatsdServer' ) );
+                               $statsdServer = explode( ':', $config->get( 'StatsdServer' ), 2 );
                                $statsdHost = $statsdServer[0];
                                $statsdPort = $statsdServer[1] ?? 8125;
                                $statsdSender = new SocketSender( $statsdHost, $statsdPort );
index 292e8df..655946f 100644 (file)
@@ -6,7 +6,7 @@ use CommentStore;
 use Config;
 use ConfigFactory;
 use CryptHKDF;
-use CryptRand;
+use DateFormatterFactory;
 use EventRelayerGroup;
 use GenderCache;
 use GlobalVarConfig;
@@ -14,6 +14,7 @@ use Hooks;
 use IBufferingStatsdDataFactory;
 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 use MediaWiki\Http\HttpRequestFactory;
+use MediaWiki\Permissions\PermissionManager;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
 use MediaWiki\Revision\RevisionRenderer;
@@ -38,6 +39,7 @@ use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\Linker\LinkRendererFactory;
 use MWException;
 use MimeAnalyzer;
+use NamespaceInfo;
 use ObjectCache;
 use Parser;
 use ParserCache;
@@ -515,13 +517,11 @@ class MediaWikiServices extends ServiceContainer {
        }
 
        /**
-        * @since 1.28
-        * @deprecated since 1.32, use random_bytes()/random_int()
-        * @return CryptRand
+        * @since 1.33
+        * @return DateFormatterFactory
         */
-       public function getCryptRand() {
-               wfDeprecated( __METHOD__, '1.32' );
-               return $this->getService( 'CryptRand' );
+       public function getDateFormatterFactory() {
+               return $this->getService( 'DateFormatterFactory' );
        }
 
        /**
@@ -666,6 +666,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'MimeAnalyzer' );
        }
 
+       /**
+        * @since 1.34
+        * @return NamespaceInfo
+        */
+       public function getNamespaceInfo() : NamespaceInfo {
+               return $this->getService( 'NamespaceInfo' );
+       }
+
        /**
         * @since 1.32
         * @return NameTableStoreFactory
@@ -675,6 +683,7 @@ class MediaWikiServices extends ServiceContainer {
        }
 
        /**
+        * @since 1.32
         * @return OldRevisionImporter
         */
        public function getOldRevisionImporter() {
@@ -721,6 +730,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'PerDbNameStatsdDataFactory' );
        }
 
+       /**
+        * @since 1.33
+        * @return PermissionManager
+        */
+       public function getPermissionManager() {
+               return $this->getService( 'PermissionManager' );
+       }
+
        /**
         * @since 1.31
         * @return PreferencesFactory
index 4049e11..0b3113f 100644 (file)
@@ -1163,14 +1163,11 @@ class Message implements MessageSpecifier, Serializable {
                                        // escaped, breaking the replacement and avoiding XSS.
                                        $replacementKeys['$' . ( $n + 1 )] = $marker . ( $n + 1 );
                                }
-                       } else {
-                               if ( $paramType === 'after' ) {
-                                       $replacementKeys[$marker . ( $n + 1 )] = $value;
-                               }
+                       } elseif ( $paramType === 'after' ) {
+                               $replacementKeys[$marker . ( $n + 1 )] = $value;
                        }
                }
-               $message = strtr( $message, $replacementKeys );
-               return $message;
+               return strtr( $message, $replacementKeys );
        }
 
        /**
index bcec0a1..24178ac 100644 (file)
@@ -106,7 +106,7 @@ class MovePage {
 
                $oldid = $this->oldTitle->getArticleID();
 
-               if ( strlen( $this->newTitle->getDBkey() ) < 1 ) {
+               if ( $this->newTitle->getDBkey() === '' ) {
                        $status->fatal( 'articleexists' );
                }
                if (
@@ -272,7 +272,8 @@ class MovePage {
                        [ 'cl_from' => $pageid ],
                        __METHOD__
                );
-               $type = MWNamespace::getCategoryLinkType( $this->newTitle->getNamespace() );
+               $type = MediaWikiServices::getInstance()->getNamespaceInfo()->
+                       getCategoryLinkType( $this->newTitle->getNamespace() );
                foreach ( $prefixes as $prefixRow ) {
                        $prefix = $prefixRow->cl_sortkey_prefix;
                        $catTo = $prefixRow->cl_to;
@@ -427,8 +428,8 @@ class MovePage {
         * Can also be used to revert after a DB failure.
         *
         * @private
-        * @param Title Old location to move the file from.
-        * @param Title New location to move the file to.
+        * @param Title $oldTitle Old location to move the file from.
+        * @param Title $newTitle New location to move the file to.
         * @return Status
         */
        private function moveFile( $oldTitle, $newTitle ) {
index 461df94..1da8ac8 100644 (file)
@@ -152,9 +152,6 @@ class OutputPage extends ContextSource {
        /** @var array */
        protected $mModules = [];
 
-       /** @var array */
-       protected $mModuleScripts = [];
-
        /** @var array */
        protected $mModuleStyles = [];
 
@@ -552,30 +549,12 @@ class OutputPage extends ContextSource {
        }
 
        /**
-        * Get the list of script-only modules to load on this page.
-        *
-        * @param bool $filter
-        * @param string|null $position Unused
-        * @return array Array of module names
-        */
-       public function getModuleScripts( $filter = false, $position = null ) {
-               return $this->getModules( $filter, null, 'mModuleScripts',
-                       ResourceLoaderModule::TYPE_SCRIPTS
-               );
-       }
-
-       /**
-        * Load the scripts of one or more ResourceLoader modules, on this page.
-        *
-        * This method exists purely to provide the legacy behaviour of loading
-        * a module's scripts in the global scope, and without dependency resolution.
-        * See <https://phabricator.wikimedia.org/T188689>.
-        *
-        * @deprecated since 1.31 Use addModules() instead.
-        * @param string|array $modules Module name (string) or array of module names
+        * @deprecated since 1.33 Use getModules() instead.
+        * @return array
         */
-       public function addModuleScripts( $modules ) {
-               $this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules );
+       public function getModuleScripts() {
+               wfDeprecated( __METHOD__, '1.33' );
+               return [];
        }
 
        /**
@@ -953,6 +932,8 @@ class OutputPage extends ContextSource {
         * good tags like \<i\> will be dropped entirely.
         *
         * @param string|Message $name
+        * @param-taint $name tainted
+        * Phan-taint-check gets very confused by $name being either a string or a Message
         */
        public function setPageTitle( $name ) {
                if ( $name instanceof Message ) {
@@ -966,7 +947,7 @@ class OutputPage extends ContextSource {
 
                # change "<i>foo&amp;bar</i>" to "foo&bar"
                $this->setHTMLTitle(
-                       $this->msg( 'pagetitle' )->rawParams( Sanitizer::stripAllTags( $nameWithTags ) )
+                       $this->msg( 'pagetitle' )->plaintextParams( Sanitizer::stripAllTags( $nameWithTags ) )
                                ->inContentLanguage()
                );
        }
@@ -1164,6 +1145,20 @@ class OutputPage extends ContextSource {
                }
        }
 
+       /**
+        * Return effective list of advertised feed types
+        * @see addFeedLink()
+        *
+        * @return array Array of feed type names ( 'rss', 'atom' )
+        */
+       protected function getAdvertisedFeedTypes() {
+               if ( $this->getConfig()->get( 'Feed' ) ) {
+                       return $this->getConfig()->get( 'AdvertisedFeedTypes' );
+               } else {
+                       return [];
+               }
+       }
+
        /**
         * Add default feeds to the page header
         * This is mainly kept for backward compatibility, see OutputPage::addFeedLink()
@@ -1176,7 +1171,7 @@ class OutputPage extends ContextSource {
        public function setFeedAppendQuery( $val ) {
                $this->mFeedLinks = [];
 
-               foreach ( $this->getConfig()->get( 'AdvertisedFeedTypes' ) as $type ) {
+               foreach ( $this->getAdvertisedFeedTypes() as $type ) {
                        $query = "feed=$type";
                        if ( is_string( $val ) ) {
                                $query .= '&' . $val;
@@ -1192,7 +1187,7 @@ class OutputPage extends ContextSource {
         * @param string $href URL
         */
        public function addFeedLink( $format, $href ) {
-               if ( in_array( $format, $this->getConfig()->get( 'AdvertisedFeedTypes' ) ) ) {
+               if ( in_array( $format, $this->getAdvertisedFeedTypes() ) ) {
                        $this->mFeedLinks[$format] = $href;
                }
        }
@@ -1633,7 +1628,7 @@ class OutputPage extends ContextSource {
                }
 
                if ( !$this->mParserOptions ) {
-                       if ( !$this->getContext()->getUser()->isSafeToLoad() ) {
+                       if ( !$this->getUser()->isSafeToLoad() ) {
                                // $wgUser isn't unstubbable yet, so don't try to get a
                                // ParserOptions for it. And don't cache this ParserOptions
                                // either.
@@ -1970,7 +1965,6 @@ class OutputPage extends ContextSource {
                $this->mNoGallery = $parserOutput->getNoGallery();
                $this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() );
                $this->addModules( $parserOutput->getModules() );
-               $this->addModuleScripts( $parserOutput->getModuleScripts() );
                $this->addModuleStyles( $parserOutput->getModuleStyles() );
                $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
                $this->mPreventClickjacking = $this->mPreventClickjacking
@@ -2037,7 +2031,6 @@ class OutputPage extends ContextSource {
                $this->addParserOutputText( $parserOutput, $poOptions );
 
                $this->addModules( $parserOutput->getModules() );
-               $this->addModuleScripts( $parserOutput->getModuleScripts() );
                $this->addModuleStyles( $parserOutput->getModuleStyles() );
 
                $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
@@ -2194,7 +2187,7 @@ class OutputPage extends ContextSource {
         * Parse wikitext and return the HTML (internal implementation helper)
         *
         * @param string $text
-        * @param Title The title to use
+        * @param Title $title The title to use
         * @param bool $linestart Is this the start of a line?
         * @param bool $tidy Whether the output should be tidied
         * @param bool $interface Use interface language (instead of content language) while parsing
@@ -2685,10 +2678,6 @@ class OutputPage extends ContextSource {
                $response->header( 'Content-language: ' .
                        MediaWikiServices::getInstance()->getContentLanguage()->getHtmlCode() );
 
-               if ( !$this->mArticleBodyOnly ) {
-                       $sk = $this->getSkin();
-               }
-
                $linkHeader = $this->getLinkHeader();
                if ( $linkHeader ) {
                        $response->header( $linkHeader );
@@ -2991,7 +2980,7 @@ class OutputPage extends ContextSource {
         */
        public function showFileRenameError( $old, $new ) {
                wfDeprecated( __METHOD__, '1.32' );
-               $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->escpaed() );
+               $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->escaped() );
        }
 
        /**
@@ -3183,7 +3172,6 @@ class OutputPage extends ContextSource {
                        $rlClient->setConfig( $this->getJSVars() );
                        $rlClient->setModules( $this->getModules( /*filter*/ true ) );
                        $rlClient->setModuleStyles( $moduleStyles );
-                       $rlClient->setModuleScripts( $this->getModuleScripts( /*filter*/ true ) );
                        $rlClient->setExemptStates( $exemptStates );
                        $this->rlClient = $rlClient;
                }
@@ -3231,7 +3219,10 @@ class OutputPage extends ContextSource {
                // Use an IE conditional comment to serve the script only to old IE
                $pieces[] = '<!--[if lt IE 9]>' .
                        ResourceLoaderClientHtml::makeLoad(
-                               ResourceLoaderContext::newDummyContext(),
+                               new ResourceLoaderContext(
+                                       $this->getResourceLoader(),
+                                       new FauxRequest( [] )
+                               ),
                                [ 'html5shiv' ],
                                ResourceLoaderModule::TYPE_SCRIPTS,
                                [ 'sync' => true ],
@@ -3759,8 +3750,9 @@ class OutputPage extends ContextSource {
                        # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined.
                        # If so, use it instead.
                        $sitename = $config->get( 'Sitename' );
-                       if ( $config->get( 'OverrideSiteFeed' ) ) {
-                               foreach ( $config->get( 'OverrideSiteFeed' ) as $type => $feedUrl ) {
+                       $overrideSiteFeed = $config->get( 'OverrideSiteFeed' );
+                       if ( $overrideSiteFeed ) {
+                               foreach ( $overrideSiteFeed as $type => $feedUrl ) {
                                        // Note, this->feedLink escapes the url.
                                        $feedLinks[] = $this->feedLink(
                                                $type,
@@ -3770,7 +3762,7 @@ class OutputPage extends ContextSource {
                                }
                        } elseif ( !$this->getTitle()->isSpecial( 'Recentchanges' ) ) {
                                $rctitle = SpecialPage::getTitleFor( 'Recentchanges' );
-                               foreach ( $config->get( 'AdvertisedFeedTypes' ) as $format ) {
+                               foreach ( $this->getAdvertisedFeedTypes() as $format ) {
                                        $feedLinks[] = $this->feedLink(
                                                $format,
                                                $rctitle->getLocalURL( [ 'feed' => $format ] ),
@@ -3792,26 +3784,24 @@ class OutputPage extends ContextSource {
                if ( $config->get( 'EnableCanonicalServerLink' ) ) {
                        if ( $canonicalUrl !== false ) {
                                $canonicalUrl = wfExpandUrl( $canonicalUrl, PROTO_CANONICAL );
-                       } else {
-                               if ( $this->isArticleRelated() ) {
-                                       // This affects all requests where "setArticleRelated" is true. This is
-                                       // typically all requests that show content (query title, curid, oldid, diff),
-                                       // and all wikipage actions (edit, delete, purge, info, history etc.).
-                                       // It does not apply to File pages and Special pages.
-                                       // 'history' and 'info' actions address page metadata rather than the page
-                                       // content itself, so they may not be canonicalized to the view page url.
-                                       // TODO: this ought to be better encapsulated in the Action class.
-                                       $action = Action::getActionName( $this->getContext() );
-                                       if ( in_array( $action, [ 'history', 'info' ] ) ) {
-                                               $query = "action={$action}";
-                                       } else {
-                                               $query = '';
-                                       }
-                                       $canonicalUrl = $this->getTitle()->getCanonicalURL( $query );
+                       } elseif ( $this->isArticleRelated() ) {
+                               // This affects all requests where "setArticleRelated" is true. This is
+                               // typically all requests that show content (query title, curid, oldid, diff),
+                               // and all wikipage actions (edit, delete, purge, info, history etc.).
+                               // It does not apply to File pages and Special pages.
+                               // 'history' and 'info' actions address page metadata rather than the page
+                               // content itself, so they may not be canonicalized to the view page url.
+                               // TODO: this ought to be better encapsulated in the Action class.
+                               $action = Action::getActionName( $this->getContext() );
+                               if ( in_array( $action, [ 'history', 'info' ] ) ) {
+                                       $query = "action={$action}";
                                } else {
-                                       $reqUrl = $this->getRequest()->getRequestURL();
-                                       $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL );
+                                       $query = '';
                                }
+                               $canonicalUrl = $this->getTitle()->getCanonicalURL( $query );
+                       } else {
+                               $reqUrl = $this->getRequest()->getRequestURL();
+                               $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL );
                        }
                }
                if ( $canonicalUrl !== false ) {
@@ -3955,10 +3945,8 @@ class OutputPage extends ContextSource {
         * @return string HTML fragment
         */
        protected function styleLink( $style, array $options ) {
-               if ( isset( $options['dir'] ) ) {
-                       if ( $this->getLanguage()->getDir() != $options['dir'] ) {
-                               return '';
-                       }
+               if ( isset( $options['dir'] ) && $this->getLanguage()->getDir() != $options['dir'] ) {
+                       return '';
                }
 
                if ( isset( $options['media'] ) ) {
index cbe63a3..2d9216d 100644 (file)
@@ -20,6 +20,7 @@
 
 // phpcs:disable Generic.Arrays.DisallowLongArraySyntax,PSR2.Classes.PropertyDeclaration,MediaWiki.Usage.DirUsage
 // phpcs:disable Squiz.Scope.MemberVarScope.Missing,Squiz.Scope.MethodScope.Missing
+// @phan-file-suppress PhanPluginDuplicateConditionalNullCoalescing
 /**
  * Check PHP Version, as well as for composer dependencies in entry points,
  * and display something vaguely comprehensible in the event of a totally
@@ -35,7 +36,7 @@
  */
 class PHPVersionCheck {
        /* @var string The number of the MediaWiki version used. */
-       var $mwVersion = '1.33';
+       var $mwVersion = '1.34';
 
        /* @var array A mapping of PHP functions to PHP extensions. */
        var $functionsExtensionsMapping = array(
@@ -111,7 +112,7 @@ class PHPVersionCheck {
                        'vendor' => 'the PHP Group',
                        'upstreamSupported' => '5.6.0',
                        'minSupported' => '7.0.13',
-                       'upgradeURL' => 'https://secure.php.net/downloads.php',
+                       'upgradeURL' => 'https://www.php.net/downloads.php',
                );
        }
 
@@ -205,7 +206,7 @@ HTML;
 
                        $missingExtText = '';
                        $missingExtHtml = '';
-                       $baseUrl = 'https://secure.php.net';
+                       $baseUrl = 'https://www.php.net';
                        foreach ( $missingExtensions as $ext ) {
                                $missingExtText .= " * $ext <$baseUrl/$ext>\n";
                                $missingExtHtml .= "<li><b>$ext</b> "
index df2451c..a84370f 100644 (file)
@@ -129,12 +129,10 @@ class PageProps {
                                if ( $propertyValue === false ) {
                                        $queryIDs[] = $pageID;
                                        break;
+                               } elseif ( $gotArray ) {
+                                       $values[$pageID][$propertyName] = $propertyValue;
                                } else {
-                                       if ( $gotArray ) {
-                                               $values[$pageID][$propertyName] = $propertyValue;
-                                       } else {
-                                               $values[$pageID] = $propertyValue;
-                                       }
+                                       $values[$pageID] = $propertyValue;
                                }
                        }
                }
index faf4db4..eb52d7c 100644 (file)
@@ -133,10 +133,8 @@ class PathRouter {
                // Loop over our options and convert any single value $# restrictions
                // into an array so we only have to do in_array tests.
                foreach ( $options as $optionName => $optionData ) {
-                       if ( preg_match( '/^\$\d+$/u', $optionName ) ) {
-                               if ( !is_array( $optionData ) ) {
-                                       $options[$optionName] = [ $optionData ];
-                               }
+                       if ( preg_match( '/^\$\d+$/u', $optionName ) && !is_array( $optionData ) ) {
+                               $options[$optionName] = [ $optionData ];
                        }
                }
 
@@ -252,7 +250,7 @@ class PathRouter {
                // array() (a match with no data) but our WebRequest caller
                // expects array() even when we have no matches so return
                // a array() when we have null
-               return is_null( $matches ) ? [] : $matches;
+               return $matches ?? [];
        }
 
        /**
diff --git a/includes/Permissions/PermissionManager.php b/includes/Permissions/PermissionManager.php
new file mode 100644 (file)
index 0000000..549b7ba
--- /dev/null
@@ -0,0 +1,1051 @@
+<?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
+ */
+namespace MediaWiki\Permissions;
+
+use Action;
+use Exception;
+use FatalError;
+use Hooks;
+use MediaWiki\Linker\LinkTarget;
+use MediaWiki\Special\SpecialPageFactory;
+use MessageSpecifier;
+use MWException;
+use NamespaceInfo;
+use RequestContext;
+use SpecialPage;
+use Title;
+use User;
+use WikiPage;
+
+/**
+ * A service class for checking permissions
+ * To obtain an instance, use MediaWikiServices::getInstance()->getPermissionManager().
+ *
+ * @since 1.33
+ */
+class PermissionManager {
+
+       /** @var string Does cheap permission checks from replica DBs (usable for GUI creation) */
+       const RIGOR_QUICK = 'quick';
+
+       /** @var string Does cheap and expensive checks possibly from a replica DB */
+       const RIGOR_FULL = 'full';
+
+       /** @var string Does cheap and expensive checks, using the master as needed */
+       const RIGOR_SECURE = 'secure';
+
+       /** @var SpecialPageFactory */
+       private $specialPageFactory;
+
+       /** @var string[] List of pages names anonymous user may see */
+       private $whitelistRead;
+
+       /** @var string[] Whitelists publicly readable titles with regular expressions */
+       private $whitelistReadRegexp;
+
+       /** @var bool Require users to confirm email address before they can edit */
+       private $emailConfirmToEdit;
+
+       /** @var bool If set to true, blocked users will no longer be allowed to log in */
+       private $blockDisablesLogin;
+
+       /**
+        * @param SpecialPageFactory $specialPageFactory
+        * @param string[] $whitelistRead
+        * @param string[] $whitelistReadRegexp
+        * @param bool $emailConfirmToEdit
+        * @param bool $blockDisablesLogin
+        */
+       public function __construct(
+               SpecialPageFactory $specialPageFactory,
+               $whitelistRead,
+               $whitelistReadRegexp,
+               $emailConfirmToEdit,
+               $blockDisablesLogin,
+               NamespaceInfo $nsInfo
+       ) {
+               $this->specialPageFactory = $specialPageFactory;
+               $this->whitelistRead = $whitelistRead;
+               $this->whitelistReadRegexp = $whitelistReadRegexp;
+               $this->emailConfirmToEdit = $emailConfirmToEdit;
+               $this->blockDisablesLogin = $blockDisablesLogin;
+               $this->nsInfo = $nsInfo;
+       }
+
+       /**
+        * Can $user perform $action on a page?
+        *
+        * The method is intended to replace Title::userCan()
+        * The $user parameter need to be superseded by UserIdentity value in future
+        * The $title parameter need to be superseded by PageIdentity value in future
+        *
+        * @see Title::userCan()
+        *
+        * @param string $action
+        * @param User $user
+        * @param LinkTarget $page
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        *
+        * @return bool
+        * @throws Exception
+        */
+       public function userCan( $action, User $user, LinkTarget $page, $rigor = self::RIGOR_SECURE ) {
+               return !count( $this->getPermissionErrorsInternal( $action, $user, $page, $rigor, true ) );
+       }
+
+       /**
+        * Can $user perform $action on a page?
+        *
+        * @todo FIXME: This *does not* check throttles (User::pingLimiter()).
+        *
+        * @param string $action Action that permission needs to be checked for
+        * @param User $user User to check
+        * @param LinkTarget $page
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param array $ignoreErrors Array of Strings Set this to a list of message keys
+        *   whose corresponding errors may be ignored.
+        *
+        * @return array Array of arrays of the arguments to wfMessage to explain permissions problems.
+        * @throws Exception
+        */
+       public function getPermissionErrors(
+               $action,
+               User $user,
+               LinkTarget $page,
+               $rigor = self::RIGOR_SECURE,
+               $ignoreErrors = []
+       ) {
+               $errors = $this->getPermissionErrorsInternal( $action, $user, $page, $rigor );
+
+               // Remove the errors being ignored.
+               foreach ( $errors as $index => $error ) {
+                       $errKey = is_array( $error ) ? $error[0] : $error;
+
+                       if ( in_array( $errKey, $ignoreErrors ) ) {
+                               unset( $errors[$index] );
+                       }
+                       if ( $errKey instanceof MessageSpecifier && in_array( $errKey->getKey(), $ignoreErrors ) ) {
+                               unset( $errors[$index] );
+                       }
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Check if user is blocked from editing a particular article
+        *
+        * @param User $user
+        * @param LinkTarget $page Title to check
+        * @param bool $fromReplica Whether to check the replica DB instead of the master
+        *
+        * @return bool
+        * @throws FatalError
+        * @throws MWException
+        */
+       public function isBlockedFrom( User $user, LinkTarget $page, $fromReplica = false ) {
+               $blocked = $user->isHidden();
+
+               // TODO: remove upon further migration to LinkTarget
+               $page = Title::newFromLinkTarget( $page );
+
+               if ( !$blocked ) {
+                       $block = $user->getBlock( $fromReplica );
+                       if ( $block ) {
+                               // Special handling for a user's own talk page. The block is not aware
+                               // of the user, so this must be done here.
+                               if ( $page->equals( $user->getTalkPage() ) ) {
+                                       $blocked = $block->appliesToUsertalk( $page );
+                               } else {
+                                       $blocked = $block->appliesToTitle( $page );
+                               }
+                       }
+               }
+
+               // only for the purpose of the hook. We really don't need this here.
+               $allowUsertalk = $user->isAllowUsertalk();
+
+               Hooks::run( 'UserIsBlockedFrom', [ $user, $page, &$blocked, &$allowUsertalk ] );
+
+               return $blocked;
+       }
+
+       /**
+        * Can $user perform $action on a page? This is an internal function,
+        * with multiple levels of checks depending on performance needs; see $rigor below.
+        * It does not check wfReadOnly().
+        *
+        * @param string $action Action that permission needs to be checked for
+        * @param User $user User to check
+        * @param LinkTarget $page
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Set this to true to stop after the first permission error.
+        *
+        * @return array Array of arrays of the arguments to wfMessage to explain permissions problems.
+        * @throws Exception
+        */
+       private function getPermissionErrorsInternal(
+               $action,
+               User $user,
+               LinkTarget $page,
+               $rigor = self::RIGOR_SECURE,
+               $short = false
+       ) {
+               if ( !in_array( $rigor, [ self::RIGOR_QUICK, self::RIGOR_FULL, self::RIGOR_SECURE ] ) ) {
+                       throw new Exception( "Invalid rigor parameter '$rigor'." );
+               }
+
+               # Read has special handling
+               if ( $action == 'read' ) {
+                       $checks = [
+                               'checkPermissionHooks',
+                               'checkReadPermissions',
+                               'checkUserBlock', // for wgBlockDisablesLogin
+                       ];
+                       # Don't call checkSpecialsAndNSPermissions, checkSiteConfigPermissions
+                       # or checkUserConfigPermissions here as it will lead to duplicate
+                       # error messages. This is okay to do since anywhere that checks for
+                       # create will also check for edit, and those checks are called for edit.
+               } elseif ( $action == 'create' ) {
+                       $checks = [
+                               'checkQuickPermissions',
+                               'checkPermissionHooks',
+                               'checkPageRestrictions',
+                               'checkCascadingSourcesRestrictions',
+                               'checkActionPermissions',
+                               'checkUserBlock'
+                       ];
+               } else {
+                       $checks = [
+                               'checkQuickPermissions',
+                               'checkPermissionHooks',
+                               'checkSpecialsAndNSPermissions',
+                               'checkSiteConfigPermissions',
+                               'checkUserConfigPermissions',
+                               'checkPageRestrictions',
+                               'checkCascadingSourcesRestrictions',
+                               'checkActionPermissions',
+                               'checkUserBlock'
+                       ];
+               }
+
+               $errors = [];
+               foreach ( $checks as $method ) {
+                       $errors = $this->$method( $action, $user, $errors, $rigor, $short, $page );
+
+                       if ( $short && $errors !== [] ) {
+                               break;
+                       }
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Check various permission hooks
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        * @throws FatalError
+        * @throws MWException
+        */
+       private function checkPermissionHooks(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove when LinkTarget usage will expand further
+               $page = Title::newFromLinkTarget( $page );
+               // Use getUserPermissionsErrors instead
+               $result = '';
+               if ( !Hooks::run( 'userCan', [ &$page, &$user, $action, &$result ] ) ) {
+                       return $result ? [] : [ [ 'badaccess-group0' ] ];
+               }
+               // Check getUserPermissionsErrors hook
+               if ( !Hooks::run( 'getUserPermissionsErrors', [ &$page, &$user, $action, &$result ] ) ) {
+                       $errors = $this->resultToError( $errors, $result );
+               }
+               // Check getUserPermissionsErrorsExpensive hook
+               if (
+                       $rigor !== self::RIGOR_QUICK
+                       && !( $short && count( $errors ) > 0 )
+                       && !Hooks::run( 'getUserPermissionsErrorsExpensive', [ &$page, &$user, $action, &$result ] )
+               ) {
+                       $errors = $this->resultToError( $errors, $result );
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Add the resulting error code to the errors array
+        *
+        * @param array $errors List of current errors
+        * @param array $result Result of errors
+        *
+        * @return array List of errors
+        */
+       private function resultToError( $errors, $result ) {
+               if ( is_array( $result ) && count( $result ) && !is_array( $result[0] ) ) {
+                       // A single array representing an error
+                       $errors[] = $result;
+               } elseif ( is_array( $result ) && is_array( $result[0] ) ) {
+                       // A nested array representing multiple errors
+                       $errors = array_merge( $errors, $result );
+               } elseif ( $result !== '' && is_string( $result ) ) {
+                       // A string representing a message-id
+                       $errors[] = [ $result ];
+               } elseif ( $result instanceof MessageSpecifier ) {
+                       // A message specifier representing an error
+                       $errors[] = [ $result ];
+               } elseif ( $result === false ) {
+                       // a generic "We don't want them to do that"
+                       $errors[] = [ 'badaccess-group0' ];
+               }
+               return $errors;
+       }
+
+       /**
+        * Check that the user is allowed to read this page.
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        * @throws FatalError
+        * @throws MWException
+        */
+       private function checkReadPermissions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove when LinkTarget usage will expand further
+               $page = Title::newFromLinkTarget( $page );
+
+               $whitelisted = false;
+               if ( User::isEveryoneAllowed( 'read' ) ) {
+                       # Shortcut for public wikis, allows skipping quite a bit of code
+                       $whitelisted = true;
+               } elseif ( $user->isAllowed( 'read' ) ) {
+                       # If the user is allowed to read pages, he is allowed to read all pages
+                       $whitelisted = true;
+               } elseif ( $this->isSameSpecialPage( 'Userlogin', $page )
+                                  || $this->isSameSpecialPage( 'PasswordReset', $page )
+                                  || $this->isSameSpecialPage( 'Userlogout', $page )
+               ) {
+                       # Always grant access to the login page.
+                       # Even anons need to be able to log in.
+                       $whitelisted = true;
+               } elseif ( is_array( $this->whitelistRead ) && count( $this->whitelistRead ) ) {
+                       # Time to check the whitelist
+                       # Only do these checks is there's something to check against
+                       $name = $page->getPrefixedText();
+                       $dbName = $page->getPrefixedDBkey();
+
+                       // Check for explicit whitelisting with and without underscores
+                       if ( in_array( $name, $this->whitelistRead, true )
+                                || in_array( $dbName, $this->whitelistRead, true ) ) {
+                               $whitelisted = true;
+                       } elseif ( $page->getNamespace() == NS_MAIN ) {
+                               # Old settings might have the title prefixed with
+                               # a colon for main-namespace pages
+                               if ( in_array( ':' . $name, $this->whitelistRead ) ) {
+                                       $whitelisted = true;
+                               }
+                       } elseif ( $page->isSpecialPage() ) {
+                               # If it's a special page, ditch the subpage bit and check again
+                               $name = $page->getDBkey();
+                               list( $name, /* $subpage */ ) =
+                                       $this->specialPageFactory->resolveAlias( $name );
+                               if ( $name ) {
+                                       $pure = SpecialPage::getTitleFor( $name )->getPrefixedText();
+                                       if ( in_array( $pure, $this->whitelistRead, true ) ) {
+                                               $whitelisted = true;
+                                       }
+                               }
+                       }
+               }
+
+               if ( !$whitelisted && is_array( $this->whitelistReadRegexp )
+                        && !empty( $this->whitelistReadRegexp ) ) {
+                       $name = $page->getPrefixedText();
+                       // Check for regex whitelisting
+                       foreach ( $this->whitelistReadRegexp as $listItem ) {
+                               if ( preg_match( $listItem, $name ) ) {
+                                       $whitelisted = true;
+                                       break;
+                               }
+                       }
+               }
+
+               if ( !$whitelisted ) {
+                       # If the title is not whitelisted, give extensions a chance to do so...
+                       Hooks::run( 'TitleReadWhitelist', [ $page, $user, &$whitelisted ] );
+                       if ( !$whitelisted ) {
+                               $errors[] = $this->missingPermissionError( $action, $short );
+                       }
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Get a description array when the user doesn't have the right to perform
+        * $action (i.e. when User::isAllowed() returns false)
+        *
+        * @param string $action The action to check
+        * @param bool $short Short circuit on first error
+        * @return array Array containing an error message key and any parameters
+        */
+       private function missingPermissionError( $action, $short ) {
+               // We avoid expensive display logic for quickUserCan's and such
+               if ( $short ) {
+                       return [ 'badaccess-group0' ];
+               }
+
+               // TODO: it would be a good idea to replace the method below with something else like
+               //  maybe callback injection
+               return User::newFatalPermissionDeniedStatus( $action )->getErrorsArray()[0];
+       }
+
+       /**
+        * Returns true if this title resolves to the named special page
+        *
+        * @param string $name The special page name
+        * @param LinkTarget $page
+        *
+        * @return bool
+        */
+       private function isSameSpecialPage( $name, LinkTarget $page ) {
+               if ( $page->getNamespace() == NS_SPECIAL ) {
+                       list( $thisName, /* $subpage */ ) =
+                               $this->specialPageFactory->resolveAlias( $page->getDBkey() );
+                       if ( $name == $thisName ) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Check that the user isn't blocked from editing.
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        * @throws MWException
+        */
+       private function checkUserBlock(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // Account creation blocks handled at userlogin.
+               // Unblocking handled in SpecialUnblock
+               if ( $rigor === self::RIGOR_QUICK || in_array( $action, [ 'createaccount', 'unblock' ] ) ) {
+                       return $errors;
+               }
+
+               // Optimize for a very common case
+               if ( $action === 'read' && !$this->blockDisablesLogin ) {
+                       return $errors;
+               }
+
+               if ( $this->emailConfirmToEdit
+                        && !$user->isEmailConfirmed()
+                        && $action === 'edit'
+               ) {
+                       $errors[] = [ 'confirmedittext' ];
+               }
+
+               $useReplica = ( $rigor !== self::RIGOR_SECURE );
+               $block = $user->getBlock( $useReplica );
+
+               // If the user does not have a block, or the block they do have explicitly
+               // allows the action (like "read" or "upload").
+               if ( !$block || $block->appliesToRight( $action ) === false ) {
+                       return $errors;
+               }
+
+               // Determine if the user is blocked from this action on this page.
+               // What gets passed into this method is a user right, not an action name.
+               // There is no way to instantiate an action by restriction. However, this
+               // will get the action where the restriction is the same. This may result
+               // in actions being blocked that shouldn't be.
+               $actionObj = null;
+               if ( Action::exists( $action ) ) {
+                       // TODO: this drags a ton of dependencies in, would be good to avoid WikiPage
+                       //  instantiation and decouple it creating an ActionPermissionChecker interface
+                       $wikiPage = WikiPage::factory( Title::newFromLinkTarget( $page, 'clone' ) );
+                       // Creating an action will perform several database queries to ensure that
+                       // the action has not been overridden by the content type.
+                       // FIXME: avoid use of RequestContext since it drags in User and Title dependencies
+                       //  probably we may use fake context object since it's unlikely that Action uses it
+                       //  anyway. It would be nice if we could avoid instantiating the Action at all.
+                       $actionObj = Action::factory( $action, $wikiPage, RequestContext::getMain() );
+                       // Ensure that the retrieved action matches the restriction.
+                       if ( $actionObj && $actionObj->getRestriction() !== $action ) {
+                               $actionObj = null;
+                       }
+               }
+
+               // If no action object is returned, assume that the action requires unblock
+               // which is the default.
+               if ( !$actionObj || $actionObj->requiresUnblock() ) {
+                       if ( $this->isBlockedFrom( $user, $page, $useReplica ) ) {
+                               // @todo FIXME: Pass the relevant context into this function.
+                               $errors[] = $block->getPermissionsError( RequestContext::getMain() );
+                       }
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Permissions checks that fail most often, and which are easiest to test.
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        * @throws FatalError
+        * @throws MWException
+        */
+       private function checkQuickPermissions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove when LinkTarget usage will expand further
+               $page = Title::newFromLinkTarget( $page );
+
+               if ( !Hooks::run( 'TitleQuickPermissions',
+                       [ $page, $user, $action, &$errors, ( $rigor !== self::RIGOR_QUICK ), $short ] )
+               ) {
+                       return $errors;
+               }
+
+               $isSubPage = $this->nsInfo->hasSubpages( $page->getNamespace() ) ?
+                       strpos( $page->getText(), '/' ) !== false : false;
+
+               if ( $action == 'create' ) {
+                       if (
+                               ( $this->nsInfo->isTalk( $page->getNamespace() ) &&
+                                       !$user->isAllowed( 'createtalk' ) ) ||
+                               ( !$this->nsInfo->isTalk( $page->getNamespace() ) &&
+                                       !$user->isAllowed( 'createpage' ) )
+                       ) {
+                               $errors[] = $user->isAnon() ? [ 'nocreatetext' ] : [ 'nocreate-loggedin' ];
+                       }
+               } elseif ( $action == 'move' ) {
+                       if ( !$user->isAllowed( 'move-rootuserpages' )
+                                && $page->getNamespace() == NS_USER && !$isSubPage ) {
+                               // Show user page-specific message only if the user can move other pages
+                               $errors[] = [ 'cant-move-user-page' ];
+                       }
+
+                       // Check if user is allowed to move files if it's a file
+                       if ( $page->getNamespace() == NS_FILE && !$user->isAllowed( 'movefile' ) ) {
+                               $errors[] = [ 'movenotallowedfile' ];
+                       }
+
+                       // Check if user is allowed to move category pages if it's a category page
+                       if ( $page->getNamespace() == NS_CATEGORY && !$user->isAllowed( 'move-categorypages' ) ) {
+                               $errors[] = [ 'cant-move-category-page' ];
+                       }
+
+                       if ( !$user->isAllowed( 'move' ) ) {
+                               // User can't move anything
+                               $userCanMove = User::groupHasPermission( 'user', 'move' );
+                               $autoconfirmedCanMove = User::groupHasPermission( 'autoconfirmed', 'move' );
+                               if ( $user->isAnon() && ( $userCanMove || $autoconfirmedCanMove ) ) {
+                                       // custom message if logged-in users without any special rights can move
+                                       $errors[] = [ 'movenologintext' ];
+                               } else {
+                                       $errors[] = [ 'movenotallowed' ];
+                               }
+                       }
+               } elseif ( $action == 'move-target' ) {
+                       if ( !$user->isAllowed( 'move' ) ) {
+                               // User can't move anything
+                               $errors[] = [ 'movenotallowed' ];
+                       } elseif ( !$user->isAllowed( 'move-rootuserpages' )
+                                          && $page->getNamespace() == NS_USER && !$isSubPage ) {
+                               // Show user page-specific message only if the user can move other pages
+                               $errors[] = [ 'cant-move-to-user-page' ];
+                       } elseif ( !$user->isAllowed( 'move-categorypages' )
+                                          && $page->getNamespace() == NS_CATEGORY ) {
+                               // Show category page-specific message only if the user can move other pages
+                               $errors[] = [ 'cant-move-to-category-page' ];
+                       }
+               } elseif ( !$user->isAllowed( $action ) ) {
+                       $errors[] = $this->missingPermissionError( $action, $short );
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Check against page_restrictions table requirements on this
+        * page. The user must possess all required rights for this
+        * action.
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        */
+       private function checkPageRestrictions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove & rework upon further use of LinkTarget
+               $page = Title::newFromLinkTarget( $page );
+               foreach ( $page->getRestrictions( $action ) as $right ) {
+                       // Backwards compatibility, rewrite sysop -> editprotected
+                       if ( $right == 'sysop' ) {
+                               $right = 'editprotected';
+                       }
+                       // Backwards compatibility, rewrite autoconfirmed -> editsemiprotected
+                       if ( $right == 'autoconfirmed' ) {
+                               $right = 'editsemiprotected';
+                       }
+                       if ( $right == '' ) {
+                               continue;
+                       }
+                       if ( !$user->isAllowed( $right ) ) {
+                               $errors[] = [ 'protectedpagetext', $right, $action ];
+                       } elseif ( $page->areRestrictionsCascading() && !$user->isAllowed( 'protect' ) ) {
+                               $errors[] = [ 'protectedpagetext', 'protect', $action ];
+                       }
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Check restrictions on cascading pages.
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        */
+       private function checkCascadingSourcesRestrictions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove & rework upon further use of LinkTarget
+               $page = Title::newFromLinkTarget( $page );
+               if ( $rigor !== self::RIGOR_QUICK && !$page->isUserConfigPage() ) {
+                       # We /could/ use the protection level on the source page, but it's
+                       # fairly ugly as we have to establish a precedence hierarchy for pages
+                       # included by multiple cascade-protected pages. So just restrict
+                       # it to people with 'protect' permission, as they could remove the
+                       # protection anyway.
+                       list( $cascadingSources, $restrictions ) = $page->getCascadeProtectionSources();
+                       # Cascading protection depends on more than this page...
+                       # Several cascading protected pages may include this page...
+                       # Check each cascading level
+                       # This is only for protection restrictions, not for all actions
+                       if ( isset( $restrictions[$action] ) ) {
+                               foreach ( $restrictions[$action] as $right ) {
+                                       // Backwards compatibility, rewrite sysop -> editprotected
+                                       if ( $right == 'sysop' ) {
+                                               $right = 'editprotected';
+                                       }
+                                       // Backwards compatibility, rewrite autoconfirmed -> editsemiprotected
+                                       if ( $right == 'autoconfirmed' ) {
+                                               $right = 'editsemiprotected';
+                                       }
+                                       if ( $right != '' && !$user->isAllowedAll( 'protect', $right ) ) {
+                                               $wikiPages = '';
+                                               foreach ( $cascadingSources as $wikiPage ) {
+                                                       $wikiPages .= '* [[:' . $wikiPage->getPrefixedText() . "]]\n";
+                                               }
+                                               $errors[] = [ 'cascadeprotected', count( $cascadingSources ), $wikiPages, $action ];
+                                       }
+                               }
+                       }
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Check action permissions not already checked in checkQuickPermissions
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        * @throws Exception
+        */
+       private function checkActionPermissions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               global $wgDeleteRevisionsLimit, $wgLang;
+
+               // TODO: remove & rework upon further use of LinkTarget
+               $page = Title::newFromLinkTarget( $page );
+
+               if ( $action == 'protect' ) {
+                       if ( count( $this->getPermissionErrorsInternal( 'edit', $user, $page, $rigor, true ) ) ) {
+                               // If they can't edit, they shouldn't protect.
+                               $errors[] = [ 'protect-cantedit' ];
+                       }
+               } elseif ( $action == 'create' ) {
+                       $title_protection = $page->getTitleProtection();
+                       if ( $title_protection ) {
+                               if ( $title_protection['permission'] == ''
+                                        || !$user->isAllowed( $title_protection['permission'] )
+                               ) {
+                                       $errors[] = [
+                                               'titleprotected',
+                                               // TODO: get rid of the User dependency
+                                               User::whoIs( $title_protection['user'] ),
+                                               $title_protection['reason']
+                                       ];
+                               }
+                       }
+               } elseif ( $action == 'move' ) {
+                       // Check for immobile pages
+                       if ( !$this->nsInfo->isMovable( $page->getNamespace() ) ) {
+                               // Specific message for this case
+                               $errors[] = [ 'immobile-source-namespace', $page->getNsText() ];
+                       } elseif ( !$page->isMovable() ) {
+                               // Less specific message for rarer cases
+                               $errors[] = [ 'immobile-source-page' ];
+                       }
+               } elseif ( $action == 'move-target' ) {
+                       if ( !$this->nsInfo->isMovable( $page->getNamespace() ) ) {
+                               $errors[] = [ 'immobile-target-namespace', $page->getNsText() ];
+                       } elseif ( !$page->isMovable() ) {
+                               $errors[] = [ 'immobile-target-page' ];
+                       }
+               } elseif ( $action == 'delete' ) {
+                       $tempErrors = $this->checkPageRestrictions( 'edit', $user, [], $rigor, true, $page );
+                       if ( !$tempErrors ) {
+                               $tempErrors = $this->checkCascadingSourcesRestrictions( 'edit',
+                                       $user, $tempErrors, $rigor, true, $page );
+                       }
+                       if ( $tempErrors ) {
+                               // If protection keeps them from editing, they shouldn't be able to delete.
+                               $errors[] = [ 'deleteprotected' ];
+                       }
+                       if ( $rigor !== self::RIGOR_QUICK && $wgDeleteRevisionsLimit
+                                && !$this->userCan( 'bigdelete', $user, $page ) && $page->isBigDeletion()
+                       ) {
+                               $errors[] = [ 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ];
+                       }
+               } elseif ( $action === 'undelete' ) {
+                       if ( count( $this->getPermissionErrorsInternal( 'edit', $user, $page, $rigor, true ) ) ) {
+                               // Undeleting implies editing
+                               $errors[] = [ 'undelete-cantedit' ];
+                       }
+                       if ( !$page->exists()
+                                && count( $this->getPermissionErrorsInternal( 'create', $user, $page, $rigor, true ) )
+                       ) {
+                               // Undeleting where nothing currently exists implies creating
+                               $errors[] = [ 'undelete-cantcreate' ];
+                       }
+               }
+               return $errors;
+       }
+
+       /**
+        * Check permissions on special pages & namespaces
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        */
+       private function checkSpecialsAndNSPermissions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove & rework upon further use of LinkTarget
+               $page = Title::newFromLinkTarget( $page );
+
+               # Only 'createaccount' can be performed on special pages,
+               # which don't actually exist in the DB.
+               if ( $page->getNamespace() == NS_SPECIAL && $action !== 'createaccount' ) {
+                       $errors[] = [ 'ns-specialprotected' ];
+               }
+
+               # Check $wgNamespaceProtection for restricted namespaces
+               if ( $page->isNamespaceProtected( $user ) ) {
+                       $ns = $page->getNamespace() == NS_MAIN ?
+                               wfMessage( 'nstab-main' )->text() : $page->getNsText();
+                       $errors[] = $page->getNamespace() == NS_MEDIAWIKI ?
+                               [ 'protectedinterface', $action ] : [ 'namespaceprotected', $ns, $action ];
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Check sitewide CSS/JSON/JS permissions
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        */
+       private function checkSiteConfigPermissions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove & rework upon further use of LinkTarget
+               $page = Title::newFromLinkTarget( $page );
+
+               if ( $action != 'patrol' ) {
+                       $error = null;
+                       // Sitewide CSS/JSON/JS changes, like all NS_MEDIAWIKI changes, also require the
+                       // editinterface right. That's implemented as a restriction so no check needed here.
+                       if ( $page->isSiteCssConfigPage() && !$user->isAllowed( 'editsitecss' ) ) {
+                               $error = [ 'sitecssprotected', $action ];
+                       } elseif ( $page->isSiteJsonConfigPage() && !$user->isAllowed( 'editsitejson' ) ) {
+                               $error = [ 'sitejsonprotected', $action ];
+                       } elseif ( $page->isSiteJsConfigPage() && !$user->isAllowed( 'editsitejs' ) ) {
+                               $error = [ 'sitejsprotected', $action ];
+                       } elseif ( $page->isRawHtmlMessage() ) {
+                               // Raw HTML can be used to deploy CSS or JS so require rights for both.
+                               if ( !$user->isAllowed( 'editsitejs' ) ) {
+                                       $error = [ 'sitejsprotected', $action ];
+                               } elseif ( !$user->isAllowed( 'editsitecss' ) ) {
+                                       $error = [ 'sitecssprotected', $action ];
+                               }
+                       }
+
+                       if ( $error ) {
+                               if ( $user->isAllowed( 'editinterface' ) ) {
+                                       // Most users / site admins will probably find out about the new, more restrictive
+                                       // permissions by failing to edit something. Give them more info.
+                                       // TODO remove this a few release cycles after 1.32
+                                       $error = [ 'interfaceadmin-info', wfMessage( $error[0], $error[1] ) ];
+                               }
+                               $errors[] = $error;
+                       }
+               }
+
+               return $errors;
+       }
+
+       /**
+        * Check CSS/JSON/JS sub-page permissions
+        *
+        * @param string $action The action to check
+        * @param User $user User to check
+        * @param array $errors List of current errors
+        * @param string $rigor One of PermissionManager::RIGOR_ constants
+        *   - RIGOR_QUICK  : does cheap permission checks from replica DBs (usable for GUI creation)
+        *   - RIGOR_FULL   : does cheap and expensive checks possibly from a replica DB
+        *   - RIGOR_SECURE : does cheap and expensive checks, using the master as needed
+        * @param bool $short Short circuit on first error
+        *
+        * @param LinkTarget $page
+        *
+        * @return array List of errors
+        */
+       private function checkUserConfigPermissions(
+               $action,
+               User $user,
+               $errors,
+               $rigor,
+               $short,
+               LinkTarget $page
+       ) {
+               // TODO: remove & rework upon further use of LinkTarget
+               $page = Title::newFromLinkTarget( $page );
+
+               # Protect css/json/js subpages of user pages
+               # XXX: this might be better using restrictions
+
+               if ( $action === 'patrol' ) {
+                       return $errors;
+               }
+
+               if ( preg_match( '/^' . preg_quote( $user->getName(), '/' ) . '\//', $page->getText() ) ) {
+                       // Users need editmyuser* to edit their own CSS/JSON/JS subpages.
+                       if (
+                               $page->isUserCssConfigPage()
+                               && !$user->isAllowedAny( 'editmyusercss', 'editusercss' )
+                       ) {
+                               $errors[] = [ 'mycustomcssprotected', $action ];
+                       } elseif (
+                               $page->isUserJsonConfigPage()
+                               && !$user->isAllowedAny( 'editmyuserjson', 'edituserjson' )
+                       ) {
+                               $errors[] = [ 'mycustomjsonprotected', $action ];
+                       } elseif (
+                               $page->isUserJsConfigPage()
+                               && !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' )
+                       ) {
+                               $errors[] = [ 'mycustomjsprotected', $action ];
+                       }
+               } else {
+                       // Users need editmyuser* to edit their own CSS/JSON/JS subpages, except for
+                       // deletion/suppression which cannot be used for attacks and we want to avoid the
+                       // situation where an unprivileged user can post abusive content on their subpages
+                       // and only very highly privileged users could remove it.
+                       if ( !in_array( $action, [ 'delete', 'deleterevision', 'suppressrevision' ], true ) ) {
+                               if (
+                                       $page->isUserCssConfigPage()
+                                       && !$user->isAllowed( 'editusercss' )
+                               ) {
+                                       $errors[] = [ 'customcssprotected', $action ];
+                               } elseif (
+                                       $page->isUserJsonConfigPage()
+                                       && !$user->isAllowed( 'edituserjson' )
+                               ) {
+                                       $errors[] = [ 'customjsonprotected', $action ];
+                               } elseif (
+                                       $page->isUserJsConfigPage()
+                                       && !$user->isAllowed( 'edituserjs' )
+                               ) {
+                                       $errors[] = [ 'customjsprotected', $action ];
+                               }
+                       }
+               }
+
+               return $errors;
+       }
+
+}
diff --git a/includes/Preferences.php b/includes/Preferences.php
deleted file mode 100644 (file)
index 70f7060..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-use MediaWiki\Auth\AuthManager;
-use MediaWiki\MediaWikiServices;
-use MediaWiki\Preferences\DefaultPreferencesFactory;
-
-/**
- * This class has been replaced by the PreferencesFactory service.
- *
- * @deprecated since 1.31 use the PreferencesFactory service instead.
- */
-class Preferences {
-
-       /**
-        * A shim to maintain backwards-compatibility of this class, basically replicating the
-        * default behaviour of the PreferencesFactory service but not permitting overriding.
-        * @return DefaultPreferencesFactory
-        */
-       protected static function getDefaultPreferencesFactory() {
-               $services = MediaWikiServices::getInstance();
-               $authManager = AuthManager::singleton();
-               $linkRenderer = $services->getLinkRenderer();
-               $config = $services->getMainConfig();
-               $preferencesFactory = new DefaultPreferencesFactory(
-                       $config, $services->getContentLanguage(), $authManager,
-                       $linkRenderer
-               );
-               return $preferencesFactory;
-       }
-
-       /**
-        * @throws MWException
-        * @param User $user
-        * @param IContextSource $context
-        * @return array|null
-        */
-       public static function getPreferences( $user, IContextSource $context ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $preferencesFactory = self::getDefaultPreferencesFactory();
-               return $preferencesFactory->getFormDescriptor( $user, $context );
-       }
-
-       /**
-        * Loads existing values for a given array of preferences
-        * @throws MWException
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences Array to load values for
-        * @return array|null
-        */
-       public static function loadPreferenceValues( $user, $context, &$defaultPreferences ) {
-               throw new Exception( __METHOD__ . '() is deprecated and does nothing' );
-       }
-
-       /**
-        * Pull option from a user account. Handles stuff like array-type preferences.
-        *
-        * @param string $name
-        * @param array $info
-        * @param User $user
-        * @return array|string
-        */
-       public static function getOptionFromUser( $name, $info, $user ) {
-               throw new Exception( __METHOD__ . '() is deprecated and does nothing' );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        * @return void
-        */
-       public static function profilePreferences(
-               $user, IContextSource $context, &$defaultPreferences
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        * @return void
-        */
-       public static function skinPreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        */
-       public static function filesPreferences(
-               $user, IContextSource $context, &$defaultPreferences
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        * @return void
-        */
-       public static function datetimePreferences(
-               $user, IContextSource $context, &$defaultPreferences
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        */
-       public static function renderingPreferences(
-               $user, IContextSource $context, &$defaultPreferences
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        */
-       public static function editingPreferences(
-               $user, IContextSource $context, &$defaultPreferences
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        */
-       public static function rcPreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        */
-       public static function watchlistPreferences(
-               $user, IContextSource $context, &$defaultPreferences
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        */
-       public static function searchPreferences(
-               $user, IContextSource $context, &$defaultPreferences
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $defaultPreferences = self::getPreferences( $user, $context );
-       }
-
-       /**
-        * Dummy, kept for backwards-compatibility.
-        * @param User $user
-        * @param IContextSource $context
-        * @param array &$defaultPreferences
-        */
-       public static function miscPreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               wfDeprecated( __METHOD__, '1.31' );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @return array Text/links to display as key; $skinkey as value
-        */
-       public static function generateSkinOptions( $user, IContextSource $context ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               return self::getPreferences( $user, $context );
-       }
-
-       /**
-        * @param IContextSource $context
-        * @return array
-        */
-       static function getDateOptions( IContextSource $context ) {
-               throw new Exception( __METHOD__ . '() is deprecated and does nothing' );
-       }
-
-       /**
-        * @param IContextSource $context
-        * @return array
-        */
-       public static function getImageSizes( IContextSource $context ) {
-               throw new Exception( __METHOD__ . '() is deprecated and does nothing' );
-       }
-
-       /**
-        * @param IContextSource $context
-        * @return array
-        */
-       public static function getThumbSizes( IContextSource $context ) {
-               throw new Exception( __METHOD__ . '() is deprecated and does nothing' );
-       }
-
-       /**
-        * @param string $signature
-        * @param array $alldata
-        * @param HTMLForm $form
-        * @return bool|string
-        */
-       public static function validateSignature( $signature, $alldata, $form ) {
-               throw new Exception( __METHOD__ . '() is deprecated and does nothing' );
-       }
-
-       /**
-        * @param string $signature
-        * @param array $alldata
-        * @param HTMLForm $form
-        * @return string
-        */
-       public static function cleanSignature( $signature, $alldata, $form ) {
-               throw new Exception( __METHOD__ . '() is deprecated and does nothing now' );
-       }
-
-       /**
-        * @param User $user
-        * @param IContextSource $context
-        * @param string $formClass
-        * @param array $remove Array of items to remove
-        * @return PreferencesFormLegacy|HTMLForm
-        */
-       public static function getFormObject(
-               $user,
-               IContextSource $context,
-               $formClass = PreferencesFormLegacy::class,
-               array $remove = []
-       ) {
-               wfDeprecated( __METHOD__, '1.31' );
-               $preferencesFactory = self::getDefaultPreferencesFactory();
-               return $preferencesFactory->getForm( $user, $context, $formClass, $remove );
-       }
-}
diff --git a/includes/PrefixSearch.php b/includes/PrefixSearch.php
deleted file mode 100644 (file)
index 7bc7a08..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-<?php
-/**
- * Prefix search of page names.
- *
- * 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;
-
-/**
- * Handles searching prefixes of titles and finding any page
- * names that match. Used largely by the OpenSearch implementation.
- * @deprecated Since 1.27, Use SearchEngine::defaultPrefixSearch or SearchEngine::completionSearch
- *
- * @ingroup Search
- */
-abstract class PrefixSearch {
-       /**
-        * Do a prefix search of titles and return a list of matching page names.
-        * @deprecated Since 1.23, use TitlePrefixSearch or StringPrefixSearch classes
-        *
-        * @param string $search
-        * @param int $limit
-        * @param array $namespaces Used if query is not explicitly prefixed
-        * @param int $offset How many results to offset from the beginning
-        * @return array Array of strings
-        */
-       public static function titleSearch( $search, $limit, $namespaces = [], $offset = 0 ) {
-               $prefixSearch = new StringPrefixSearch;
-               return $prefixSearch->search( $search, $limit, $namespaces, $offset );
-       }
-
-       /**
-        * Do a prefix search of titles and return a list of matching page names.
-        *
-        * @param string $search
-        * @param int $limit
-        * @param array $namespaces Used if query is not explicitly prefixed
-        * @param int $offset How many results to offset from the beginning
-        * @return array Array of strings or Title objects
-        */
-       public function search( $search, $limit, $namespaces = [], $offset = 0 ) {
-               $search = trim( $search );
-               if ( $search == '' ) {
-                       return []; // Return empty result
-               }
-
-               $hasNamespace = SearchEngine::parseNamespacePrefixes( $search, false, true );
-               if ( $hasNamespace !== false ) {
-                       list( $search, $namespaces ) = $hasNamespace;
-               }
-
-               return $this->searchBackend( $namespaces, $search, $limit, $offset );
-       }
-
-       /**
-        * Do a prefix search for all possible variants of the prefix
-        * @param string $search
-        * @param int $limit
-        * @param array $namespaces
-        * @param int $offset How many results to offset from the beginning
-        *
-        * @return array
-        */
-       public function searchWithVariants( $search, $limit, array $namespaces, $offset = 0 ) {
-               $searches = $this->search( $search, $limit, $namespaces, $offset );
-
-               // if the content language has variants, try to retrieve fallback results
-               $fallbackLimit = $limit - count( $searches );
-               if ( $fallbackLimit > 0 ) {
-                       $fallbackSearches = MediaWikiServices::getInstance()->getContentLanguage()->
-                               autoConvertToAllVariants( $search );
-                       $fallbackSearches = array_diff( array_unique( $fallbackSearches ), [ $search ] );
-
-                       foreach ( $fallbackSearches as $fbs ) {
-                               $fallbackSearchResult = $this->search( $fbs, $fallbackLimit, $namespaces );
-                               $searches = array_merge( $searches, $fallbackSearchResult );
-                               $fallbackLimit -= count( $fallbackSearchResult );
-
-                               if ( $fallbackLimit == 0 ) {
-                                       break;
-                               }
-                       }
-               }
-               return $searches;
-       }
-
-       /**
-        * When implemented in a descendant class, receives an array of Title objects and returns
-        * either an unmodified array or an array of strings corresponding to titles passed to it.
-        *
-        * @param array $titles
-        * @return array
-        */
-       abstract protected function titles( array $titles );
-
-       /**
-        * When implemented in a descendant class, receives an array of titles as strings and returns
-        * either an unmodified array or an array of Title objects corresponding to strings received.
-        *
-        * @param array $strings
-        *
-        * @return array
-        */
-       abstract protected function strings( array $strings );
-
-       /**
-        * Do a prefix search of titles and return a list of matching page names.
-        * @param array $namespaces
-        * @param string $search
-        * @param int $limit
-        * @param int $offset How many results to offset from the beginning
-        * @return array Array of strings
-        */
-       protected function searchBackend( $namespaces, $search, $limit, $offset ) {
-               if ( count( $namespaces ) == 1 ) {
-                       $ns = $namespaces[0];
-                       if ( $ns == NS_MEDIA ) {
-                               $namespaces = [ NS_FILE ];
-                       } elseif ( $ns == NS_SPECIAL ) {
-                               return $this->titles( $this->specialSearch( $search, $limit, $offset ) );
-                       }
-               }
-               $srchres = [];
-               if ( Hooks::run(
-                       'PrefixSearchBackend',
-                       [ $namespaces, $search, $limit, &$srchres, $offset ]
-               ) ) {
-                       return $this->titles( $this->defaultSearchBackend( $namespaces, $search, $limit, $offset ) );
-               }
-               return $this->strings(
-                       $this->handleResultFromHook( $srchres, $namespaces, $search, $limit, $offset ) );
-       }
-
-       private function handleResultFromHook( $srchres, $namespaces, $search, $limit, $offset ) {
-               if ( $offset === 0 ) {
-                       // Only perform exact db match if offset === 0
-                       // This is still far from perfect but at least we avoid returning the
-                       // same title afain and again when the user is scrolling with a query
-                       // that matches a title in the db.
-                       $rescorer = new SearchExactMatchRescorer();
-                       $srchres = $rescorer->rescore( $search, $namespaces, $srchres, $limit );
-               }
-               return $srchres;
-       }
-
-       /**
-        * Prefix search special-case for Special: namespace.
-        *
-        * @param string $search Term
-        * @param int $limit Max number of items to return
-        * @param int $offset Number of items to offset
-        * @return array
-        */
-       protected function specialSearch( $search, $limit, $offset ) {
-               $searchParts = explode( '/', $search, 2 );
-               $searchKey = $searchParts[0];
-               $subpageSearch = $searchParts[1] ?? null;
-
-               // Handle subpage search separately.
-               $spFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
-               if ( $subpageSearch !== null ) {
-                       // Try matching the full search string as a page name
-                       $specialTitle = Title::makeTitleSafe( NS_SPECIAL, $searchKey );
-                       if ( !$specialTitle ) {
-                               return [];
-                       }
-                       $special = $spFactory->getPage( $specialTitle->getText() );
-                       if ( $special ) {
-                               $subpages = $special->prefixSearchSubpages( $subpageSearch, $limit, $offset );
-                               return array_map( function ( $sub ) use ( $specialTitle ) {
-                                       return $specialTitle->getSubpage( $sub );
-                               }, $subpages );
-                       } else {
-                               return [];
-                       }
-               }
-
-               # normalize searchKey, so aliases with spaces can be found - T27675
-               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-               $searchKey = str_replace( ' ', '_', $searchKey );
-               $searchKey = $contLang->caseFold( $searchKey );
-
-               // Unlike SpecialPage itself, we want the canonical forms of both
-               // canonical and alias title forms...
-               $keys = [];
-               foreach ( $spFactory->getNames() as $page ) {
-                       $keys[$contLang->caseFold( $page )] = [ 'page' => $page, 'rank' => 0 ];
-               }
-
-               foreach ( $contLang->getSpecialPageAliases() as $page => $aliases ) {
-                       if ( !in_array( $page, $spFactory->getNames() ) ) {# T22885
-                               continue;
-                       }
-
-                       foreach ( $aliases as $key => $alias ) {
-                               $keys[$contLang->caseFold( $alias )] = [ 'page' => $alias, 'rank' => $key ];
-                       }
-               }
-               ksort( $keys );
-
-               $matches = [];
-               foreach ( $keys as $pageKey => $page ) {
-                       if ( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
-                               // 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'
-                               $matches[$page['rank']][] = Title::makeTitleSafe( NS_SPECIAL, $page['page'] );
-
-                               if ( isset( $matches[0] ) && count( $matches[0] ) >= $limit + $offset ) {
-                                       // We have enough items in primary rank, no use to continue
-                                       break;
-                               }
-                       }
-
-               }
-
-               // Ensure keys are in order
-               ksort( $matches );
-               // Flatten the array
-               $matches = array_reduce( $matches, 'array_merge', [] );
-
-               return array_slice( $matches, $offset, $limit );
-       }
-
-       /**
-        * Unless overridden by PrefixSearchBackend hook...
-        * This is case-sensitive (First character may
-        * be automatically capitalized by Title::secureAndSpit()
-        * later on depending on $wgCapitalLinks)
-        *
-        * @param array|null $namespaces Namespaces to search in
-        * @param string $search Term
-        * @param int $limit Max number of items to return
-        * @param int $offset Number of items to skip
-        * @return Title[] Array of Title objects
-        */
-       public function defaultSearchBackend( $namespaces, $search, $limit, $offset ) {
-               // Backwards compatability with old code. Default to NS_MAIN if no namespaces provided.
-               if ( $namespaces === null ) {
-                       $namespaces = [];
-               }
-               if ( !$namespaces ) {
-                       $namespaces[] = NS_MAIN;
-               }
-
-               // Construct suitable prefix for each namespace. They differ in cases where
-               // some namespaces always capitalize and some don't.
-               $prefixes = [];
-               foreach ( $namespaces as $namespace ) {
-                       // For now, if special is included, ignore the other namespaces
-                       if ( $namespace == NS_SPECIAL ) {
-                               return $this->specialSearch( $search, $limit, $offset );
-                       }
-
-                       $title = Title::makeTitleSafe( $namespace, $search );
-                       // Why does the prefix default to empty?
-                       $prefix = $title ? $title->getDBkey() : '';
-                       $prefixes[$prefix][] = $namespace;
-               }
-
-               $dbr = wfGetDB( DB_REPLICA );
-               // Often there is only one prefix that applies to all requested namespaces,
-               // but sometimes there are two if some namespaces do not always capitalize.
-               $conds = [];
-               foreach ( $prefixes as $prefix => $namespaces ) {
-                       $condition = [
-                               'page_namespace' => $namespaces,
-                               'page_title' . $dbr->buildLike( $prefix, $dbr->anyString() ),
-                       ];
-                       $conds[] = $dbr->makeList( $condition, LIST_AND );
-               }
-
-               $table = 'page';
-               $fields = [ 'page_id', 'page_namespace', 'page_title' ];
-               $conds = $dbr->makeList( $conds, LIST_OR );
-               $options = [
-                       'LIMIT' => $limit,
-                       'ORDER BY' => [ 'page_title', 'page_namespace' ],
-                       'OFFSET' => $offset
-               ];
-
-               $res = $dbr->select( $table, $fields, $conds, __METHOD__, $options );
-
-               return iterator_to_array( TitleArray::newFromResult( $res ) );
-       }
-
-       /**
-        * Validate an array of numerical namespace indexes
-        *
-        * @param array $namespaces
-        * @return array (default: contains only NS_MAIN)
-        */
-       protected function validateNamespaces( $namespaces ) {
-               // We will look at each given namespace against content language namespaces
-               $validNamespaces = MediaWikiServices::getInstance()->getContentLanguage()->getNamespaces();
-               if ( is_array( $namespaces ) && count( $namespaces ) > 0 ) {
-                       $valid = [];
-                       foreach ( $namespaces as $ns ) {
-                               if ( is_numeric( $ns ) && array_key_exists( $ns, $validNamespaces ) ) {
-                                       $valid[] = $ns;
-                               }
-                       }
-                       if ( count( $valid ) > 0 ) {
-                               return $valid;
-                       }
-               }
-
-               return [ NS_MAIN ];
-       }
-}
-
-/**
- * Performs prefix search, returning Title objects
- * @deprecated Since 1.27, Use SearchEngine::defaultPrefixSearch or SearchEngine::completionSearch
- * @ingroup Search
- */
-class TitlePrefixSearch extends PrefixSearch {
-
-       protected function titles( array $titles ) {
-               return $titles;
-       }
-
-       protected function strings( array $strings ) {
-               $titles = array_map( 'Title::newFromText', $strings );
-               $lb = new LinkBatch( $titles );
-               $lb->setCaller( __METHOD__ );
-               $lb->execute();
-               return $titles;
-       }
-}
-
-/**
- * Performs prefix search, returning strings
- * @deprecated Since 1.27, Use SearchEngine::prefixSearchSubpages or SearchEngine::completionSearch
- * @ingroup Search
- */
-class StringPrefixSearch extends PrefixSearch {
-
-       protected function titles( array $titles ) {
-               return array_map( function ( Title $t ) {
-                       return $t->getPrefixedText();
-               }, $titles );
-       }
-
-       protected function strings( array $strings ) {
-               return $strings;
-       }
-}
index 6ce7ef4..7972a1e 100644 (file)
@@ -622,10 +622,9 @@ class ProtectionForm {
        /**
         * Show protection long extracts for this page
         *
-        * @param OutputPage &$out
-        * @private
+        * @param OutputPage $out
         */
-       function showLogExtract( &$out ) {
+       private function showLogExtract( OutputPage $out ) {
                # Show relevant lines from the protection log:
                $protectLogPage = new LogPage( 'protect' );
                $out->addHTML( Xml::element( 'h2', null, $protectLogPage->getName()->text() ) );
index 547c2d5..1a09290 100644 (file)
@@ -4,7 +4,7 @@ use Wikimedia\Rdbms\LoadBalancer;
 
 /**
  * A service class for fetching the wiki's current read-only mode.
- * To obtain an instance, use MediaWikiServices::getReadOnlyMode().
+ * To obtain an instance, use MediaWikiServices::getInstance()->getReadOnlyMode().
  *
  * @since 1.29
  */
@@ -58,11 +58,4 @@ class ReadOnlyMode {
        public function setReason( $msg ) {
                $this->configuredReadOnly->setReason( $msg );
        }
-
-       /**
-        * Clear the cache of the read only file
-        */
-       public function clearCache() {
-               $this->configuredReadOnly->clearCache();
-       }
 }
index f2ca79a..cbaff90 100644 (file)
@@ -330,7 +330,7 @@ class Revision implements IDBAccessObject {
         */
        public static function pageJoinCond() {
                wfDeprecated( __METHOD__, '1.31' );
-               return [ 'INNER JOIN', [ 'page_id = rev_page' ] ];
+               return [ 'JOIN', [ 'page_id = rev_page' ] ];
        }
 
        /**
index 6c6fdd6..0139103 100644 (file)
@@ -86,10 +86,8 @@ class MainSlotRoleHandler extends SlotRoleHandler {
 
                // Hook can determine default model
                $title = Title::newFromLinkTarget( $page );
-               if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) ) {
-                       if ( !is_null( $model ) ) {
-                               return $model;
-                       }
+               if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) && !is_null( $model ) ) {
+                       return $model;
                }
 
                // Could this page contain code based on the title?
@@ -120,7 +118,7 @@ class MainSlotRoleHandler extends SlotRoleHandler {
                                case 'json':
                                        return CONTENT_MODEL_JSON;
                                default:
-                                       return is_null( $model ) ? CONTENT_MODEL_TEXT : $model;
+                                       return $model ?? CONTENT_MODEL_TEXT;
                        }
                }
 
index cf19ffb..0329bd1 100644 (file)
@@ -827,11 +827,11 @@ class RevisionStore
                                        // And we have to use raw SQL to bypass the "aggregation used with a locking SELECT" warning
                                        // that's for non-MySQL DBs.
                                        $row1 = $dbw->query(
-                                               $dbw->selectSqlText( 'archive', [ 'v' => "MAX(ar_rev_id)" ], '', __METHOD__ ) . ' FOR UPDATE'
+                                               $dbw->selectSQLText( 'archive', [ 'v' => "MAX(ar_rev_id)" ], '', __METHOD__ ) . ' FOR UPDATE'
                                        )->fetchObject();
                                        if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_NEW ) ) {
                                                $row2 = $dbw->query(
-                                                       $dbw->selectSqlText( 'slots', [ 'v' => "MAX(slot_revision_id)" ], '', __METHOD__ )
+                                                       $dbw->selectSQLText( 'slots', [ 'v' => "MAX(slot_revision_id)" ], '', __METHOD__ )
                                                                . ' FOR UPDATE'
                                                )->fetchObject();
                                        } else {
@@ -1508,9 +1508,11 @@ class RevisionStore
         * @return RevisionRecord|null
         */
        public function getRevisionByTitle( LinkTarget $linkTarget, $revId = 0, $flags = 0 ) {
+               // TODO should not require Title in future (T206498)
+               $title = Title::newFromLinkTarget( $linkTarget );
                $conds = [
-                       'page_namespace' => $linkTarget->getNamespace(),
-                       'page_title' => $linkTarget->getDBkey()
+                       'page_namespace' => $title->getNamespace(),
+                       'page_title' => $title->getDBkey()
                ];
                if ( $revId ) {
                        // Use the specified revision ID.
@@ -1519,7 +1521,7 @@ class RevisionStore
                        // Since the caller supplied a revision ID, we are pretty sure the revision is
                        // supposed to exist, so we should try hard to find it.
                        $conds['rev_id'] = $revId;
-                       return $this->newRevisionFromConds( $conds, $flags );
+                       return $this->newRevisionFromConds( $conds, $flags, $title );
                } else {
                        // Use a join to get the latest revision.
                        // Note that we don't use newRevisionFromConds here because we don't want to retry
@@ -1529,7 +1531,7 @@ class RevisionStore
                        $db = $this->getDBConnectionRefForQueryFlags( $flags );
 
                        $conds[] = 'rev_id=page_latest';
-                       $rev = $this->loadRevisionFromConds( $db, $conds, $flags );
+                       $rev = $this->loadRevisionFromConds( $db, $conds, $flags, $title );
 
                        return $rev;
                }
@@ -1668,6 +1670,7 @@ class RevisionStore
        ) {
                if ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_NEW ) ) {
                        $mainSlot = $this->emulateMainSlot_1_29( $revisionRow, $queryFlags, $title );
+                       // @phan-suppress-next-line PhanTypeInvalidCallableArraySize false positive
                        $slots = new RevisionSlots( [ SlotRecord::MAIN => $mainSlot ] );
                } else {
                        // XXX: do we need the same kind of caching here
@@ -1760,10 +1763,16 @@ class RevisionStore
         * @param object $row
         * @param int $queryFlags
         * @param Title|null $title
-        *
+        * @param bool $fromCache if true, the returned RevisionRecord will ensure that no stale
+        *   data is returned from getters, by querying the database as needed
         * @return RevisionRecord
         */
-       public function newRevisionFromRow( $row, $queryFlags = 0, Title $title = null ) {
+       public function newRevisionFromRow(
+               $row,
+               $queryFlags = 0,
+               Title $title = null,
+               $fromCache = false
+       ) {
                Assert::parameterType( 'object', $row, '$row' );
 
                if ( !$title ) {
@@ -1797,7 +1806,23 @@ class RevisionStore
 
                $slots = $this->newRevisionSlots( $row->rev_id, $row, $queryFlags, $title );
 
-               return new RevisionStoreRecord( $title, $user, $comment, $row, $slots, $this->wikiId );
+               // If this is a cached row, instantiate a cache-aware revision class to avoid stale data.
+               if ( $fromCache ) {
+                       $rev = new RevisionStoreCacheRecord(
+                               function ( $revId ) use ( $queryFlags ) {
+                                       $db = $this->getDBConnectionRefForQueryFlags( $queryFlags );
+                                       return $this->fetchRevisionRowFromConds(
+                                               $db,
+                                               [ 'rev_id' => intval( $revId ) ]
+                                       );
+                               },
+                               $title, $user, $comment, $row, $slots, $this->wikiId
+                       );
+               } else {
+                       $rev = new RevisionStoreRecord(
+                               $title, $user, $comment, $row, $slots, $this->wikiId );
+               }
+               return $rev;
        }
 
        /**
@@ -1839,12 +1864,12 @@ class RevisionStore
                }
 
                // if we have a content object, use it to set the model and type
-               if ( !empty( $fields['content'] ) ) {
-                       if ( !( $fields['content'] instanceof Content ) && !is_array( $fields['content'] ) ) {
-                               throw new MWException(
-                                       'content field must contain a Content object or an array of Content objects.'
-                               );
-                       }
+               if ( !empty( $fields['content'] ) && !( $fields['content'] instanceof Content )
+                       && !is_array( $fields['content'] )
+               ) {
+                       throw new MWException(
+                               'content field must contain a Content object or an array of Content objects.'
+                       );
                }
 
                if ( !empty( $fields['text_id'] ) ) {
@@ -2308,7 +2333,7 @@ class RevisionStore
                                'page_is_redirect',
                                'page_len',
                        ] );
-                       $ret['joins']['page'] = [ 'INNER JOIN', [ 'page_id = rev_page' ] ];
+                       $ret['joins']['page'] = [ 'JOIN', [ 'page_id = rev_page' ] ];
                }
 
                if ( in_array( 'user', $options, true ) ) {
@@ -2337,7 +2362,7 @@ class RevisionStore
                                'old_text',
                                'old_flags'
                        ] );
-                       $ret['joins']['text'] = [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ];
+                       $ret['joins']['text'] = [ 'JOIN', [ 'rev_text_id=old_id' ] ];
                }
 
                return $ret;
@@ -2413,7 +2438,7 @@ class RevisionStore
                                        'content_address',
                                        'content_model',
                                ] );
-                               $ret['joins']['content'] = [ 'INNER JOIN', [ 'slot_content_id = content_id' ] ];
+                               $ret['joins']['content'] = [ 'JOIN', [ 'slot_content_id = content_id' ] ];
 
                                if ( in_array( 'model', $options, true ) ) {
                                        // Use left join to attach model name, so we still find the revision row even
@@ -2773,27 +2798,29 @@ class RevisionStore
                        return false;
                }
 
+               // Load the row from cache if possible.  If not possible, populate the cache.
+               // As a minor optimization, remember if this was a cache hit or miss.
+               // We can sometimes avoid a database query later if this is a cache miss.
+               $fromCache = true;
                $row = $this->cache->getWithSetCallback(
                        // Page/rev IDs passed in from DB to reflect history merges
                        $this->getRevisionRowCacheKey( $db, $pageId, $revId ),
                        WANObjectCache::TTL_WEEK,
-                       function ( $curValue, &$ttl, array &$setOpts ) use ( $db, $pageId, $revId ) {
+                       function ( $curValue, &$ttl, array &$setOpts ) use (
+                               $db, $pageId, $revId, &$fromCache
+                       ) {
                                $setOpts += Database::getCacheSetOptions( $db );
-
-                               $conds = [
-                                       'rev_page' => intval( $pageId ),
-                                       'page_id' => intval( $pageId ),
-                                       'rev_id' => intval( $revId ),
-                               ];
-
-                               $row = $this->fetchRevisionRowFromConds( $db, $conds );
-                               return $row ?: false; // don't cache negatives
+                               $row = $this->fetchRevisionRowFromConds( $db, [ 'rev_id' => intval( $revId ) ] );
+                               if ( $row ) {
+                                       $fromCache = false;
+                               }
+                               return $row; // don't cache negatives
                        }
                );
 
-               // Reflect revision deletion and user renames
+               // Reflect revision deletion and user renames.
                if ( $row ) {
-                       return $this->newRevisionFromRow( $row, 0, $title );
+                       return $this->newRevisionFromRow( $row, 0, $title, $fromCache );
                } else {
                        return false;
                }
diff --git a/includes/Revision/RevisionStoreCacheRecord.php b/includes/Revision/RevisionStoreCacheRecord.php
new file mode 100644 (file)
index 0000000..ef5f10e
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+/**
+ * A RevisionStoreRecord loaded from the cache.
+ *
+ * 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
+ */
+
+namespace MediaWiki\Revision;
+
+use MediaWiki\User\UserIdentity;
+use MediaWiki\User\UserIdentityValue;
+use CommentStoreComment;
+use InvalidArgumentException;
+use Title;
+use User;
+
+/**
+ * A cached RevisionStoreRecord.  Ensures that changes performed "behind the back"
+ * of the cache do not cause the revision record to deliver stale data.
+ *
+ * @since 1.33
+ */
+class RevisionStoreCacheRecord extends RevisionStoreRecord {
+
+       /**
+        * @var callable
+        */
+       private $mCallback;
+
+       /**
+        * @note Avoid calling this constructor directly. Use the appropriate methods
+        * in RevisionStore instead.
+        *
+        * @param callable $callback Callback for loading data.  Signature: function ( $id ): object
+        * @param Title $title The title of the page this Revision is associated with.
+        * @param UserIdentity $user
+        * @param CommentStoreComment $comment
+        * @param object $row A row from the revision table. Use RevisionStore::getQueryInfo() to build
+        *        a query that yields the required fields.
+        * @param RevisionSlots $slots The slots of this revision.
+        * @param bool|string $wikiId the wiki ID of the site this Revision belongs to,
+        *        or false for the local site.
+        */
+       function __construct(
+               $callback,
+               Title $title,
+               UserIdentity $user,
+               CommentStoreComment $comment,
+               $row,
+               RevisionSlots $slots,
+               $wikiId = false
+       ) {
+               parent::__construct( $title, $user, $comment, $row, $slots, $wikiId );
+               $this->mCallback = $callback;
+       }
+
+       /**
+        * Overridden to ensure that we return a fresh value and not a cached one.
+        *
+        * @return int
+        */
+       public function getVisibility() {
+               if ( $this->mCallback ) {
+                       $this->loadFreshRow();
+               }
+               return parent::getVisibility();
+       }
+
+       /**
+        * Overridden to ensure that we return a fresh value and not a cached one.
+        *
+        * @param int $audience
+        * @param User|null $user
+        *
+        * @return UserIdentity The identity of the revision author, null if access is forbidden.
+        */
+       public function getUser( $audience = self::FOR_PUBLIC, User $user = null ) {
+               if ( $this->mCallback ) {
+                       $this->loadFreshRow();
+               }
+               return parent::getUser( $audience, $user );
+       }
+
+       /**
+        * Load a fresh row from the database to ensure we return updated information
+
+        * @throws RevisionAccessException if the row could not be loaded
+        */
+       private function loadFreshRow() {
+               $freshRow = call_user_func( $this->mCallback, $this->mId );
+
+               // Set to null to ensure we do not make unnecessary queries for subsequent getter calls,
+               // and to allow the closure to be freed.
+               $this->mCallback = null;
+
+               if ( $freshRow ) {
+                       $this->mDeleted = intval( $freshRow->rev_deleted );
+
+                       try {
+                               $this->mUser = User::newFromAnyId(
+                                       $freshRow->rev_user ?? null,
+                                       $freshRow->rev_user_text ?? null,
+                                       $freshRow->rev_actor ?? null
+                               );
+                       } catch ( InvalidArgumentException $ex ) {
+                               wfWarn(
+                                       __METHOD__
+                                       . ': '
+                                       . $this->mTitle->getPrefixedDBkey()
+                                       . ': '
+                                       . $ex->getMessage()
+                               );
+                               $this->mUser = new UserIdentityValue( 0, 'Unknown user', 0 );
+                       }
+               } else {
+                       throw new RevisionAccessException(
+                               'Unable to load fresh row for rev_id: ' . $this->mId
+                       );
+               }
+       }
+
+}
diff --git a/includes/RevisionList.php b/includes/RevisionList.php
deleted file mode 100644 (file)
index 5243cc6..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-<?php
-/**
- * Holders of revision list for a single page
- *
- * 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;
-use Wikimedia\Rdbms\IDatabase;
-
-/**
- * List for revision table items for a single page
- */
-abstract class RevisionListBase extends ContextSource implements Iterator {
-       /** @var Title */
-       public $title;
-
-       /** @var array */
-       protected $ids;
-
-       /** @var ResultWrapper|bool */
-       protected $res;
-
-       /** @var bool|Revision */
-       protected $current;
-
-       /**
-        * Construct a revision list for a given title
-        * @param IContextSource $context
-        * @param Title $title
-        */
-       function __construct( IContextSource $context, Title $title ) {
-               $this->setContext( $context );
-               $this->title = $title;
-       }
-
-       /**
-        * Select items only where the ID is any of the specified values
-        * @param array $ids
-        */
-       function filterByIds( array $ids ) {
-               $this->ids = $ids;
-       }
-
-       /**
-        * Get the internal type name of this list. Equal to the table name.
-        * Override this function.
-        * @return null
-        */
-       public function getType() {
-               return null;
-       }
-
-       /**
-        * Initialise the current iteration pointer
-        */
-       protected function initCurrent() {
-               $row = $this->res->current();
-               if ( $row ) {
-                       $this->current = $this->newItem( $row );
-               } else {
-                       $this->current = false;
-               }
-       }
-
-       /**
-        * Start iteration. This must be called before current() or next().
-        * @return Revision First list item
-        */
-       public function reset() {
-               if ( !$this->res ) {
-                       $this->res = $this->doQuery( wfGetDB( DB_REPLICA ) );
-               } else {
-                       $this->res->rewind();
-               }
-               $this->initCurrent();
-               return $this->current;
-       }
-
-       public function rewind() {
-               $this->reset();
-       }
-
-       /**
-        * Get the current list item, or false if we are at the end
-        * @return Revision
-        */
-       public function current() {
-               return $this->current;
-       }
-
-       /**
-        * Move the iteration pointer to the next list item, and return it.
-        * @return Revision
-        */
-       public function next() {
-               $this->res->next();
-               $this->initCurrent();
-               return $this->current;
-       }
-
-       public function key() {
-               return $this->res ? $this->res->key() : 0;
-       }
-
-       public function valid() {
-               return $this->res ? $this->res->valid() : false;
-       }
-
-       /**
-        * Get the number of items in the list.
-        * @return int
-        */
-       public function length() {
-               if ( !$this->res ) {
-                       return 0;
-               } else {
-                       return $this->res->numRows();
-               }
-       }
-
-       /**
-        * Do the DB query to iterate through the objects.
-        * @param IDatabase $db DB object to use for the query
-        */
-       abstract public function doQuery( $db );
-
-       /**
-        * Create an item object from a DB result row
-        * @param object $row
-        */
-       abstract public function newItem( $row );
-}
-
-/**
- * Abstract base class for revision items
- */
-abstract class RevisionItemBase {
-       /** @var RevisionListBase The parent */
-       protected $list;
-
-       /** The database result row */
-       protected $row;
-
-       /**
-        * @param RevisionListBase $list
-        * @param object $row DB result row
-        */
-       public function __construct( $list, $row ) {
-               $this->list = $list;
-               $this->row = $row;
-       }
-
-       /**
-        * Get the DB field name associated with the ID list.
-        * Override this function.
-        * @return null
-        */
-       public function getIdField() {
-               return null;
-       }
-
-       /**
-        * Get the DB field name storing timestamps.
-        * Override this function.
-        * @return bool
-        */
-       public function getTimestampField() {
-               return false;
-       }
-
-       /**
-        * Get the DB field name storing user ids.
-        * Override this function.
-        * @return bool
-        */
-       public function getAuthorIdField() {
-               return false;
-       }
-
-       /**
-        * Get the DB field name storing user names.
-        * Override this function.
-        * @return bool
-        */
-       public function getAuthorNameField() {
-               return false;
-       }
-
-       /**
-        * Get the DB field name storing actor ids.
-        * Override this function.
-        * @since 1.31
-        * @return bool
-        */
-       public function getAuthorActorField() {
-               return false;
-       }
-
-       /**
-        * Get the ID, as it would appear in the ids URL parameter
-        * @return int
-        */
-       public function getId() {
-               $field = $this->getIdField();
-               return $this->row->$field;
-       }
-
-       /**
-        * Get the date, formatted in user's language
-        * @return string
-        */
-       public function formatDate() {
-               return $this->list->getLanguage()->userDate( $this->getTimestamp(),
-                       $this->list->getUser() );
-       }
-
-       /**
-        * Get the time, formatted in user's language
-        * @return string
-        */
-       public function formatTime() {
-               return $this->list->getLanguage()->userTime( $this->getTimestamp(),
-                       $this->list->getUser() );
-       }
-
-       /**
-        * Get the timestamp in MW 14-char form
-        * @return mixed
-        */
-       public function getTimestamp() {
-               $field = $this->getTimestampField();
-               return wfTimestamp( TS_MW, $this->row->$field );
-       }
-
-       /**
-        * Get the author user ID
-        * @return int
-        */
-       public function getAuthorId() {
-               $field = $this->getAuthorIdField();
-               return intval( $this->row->$field );
-       }
-
-       /**
-        * Get the author user name
-        * @return string
-        */
-       public function getAuthorName() {
-               $field = $this->getAuthorNameField();
-               return strval( $this->row->$field );
-       }
-
-       /**
-        * Get the author actor ID
-        * @since 1.31
-        * @return string
-        */
-       public function getAuthorActor() {
-               $field = $this->getAuthorActorField();
-               return strval( $this->row->$field );
-       }
-
-       /**
-        * Returns true if the current user can view the item
-        */
-       abstract public function canView();
-
-       /**
-        * Returns true if the current user can view the item text/file
-        */
-       abstract public function canViewContent();
-
-       /**
-        * Get the HTML of the list item. Should be include "<li></li>" tags.
-        * This is used to show the list in HTML form, by the special page.
-        */
-       abstract public function getHTML();
-
-       /**
-        * Returns an instance of LinkRenderer
-        * @return \MediaWiki\Linker\LinkRenderer
-        */
-       protected function getLinkRenderer() {
-               return MediaWikiServices::getInstance()->getLinkRenderer();
-       }
-}
-
-class RevisionList extends RevisionListBase {
-       public function getType() {
-               return 'revision';
-       }
-
-       /**
-        * @param IDatabase $db
-        * @return mixed
-        */
-       public function doQuery( $db ) {
-               $conds = [ 'rev_page' => $this->title->getArticleID() ];
-               if ( $this->ids !== null ) {
-                       $conds['rev_id'] = array_map( 'intval', $this->ids );
-               }
-               $revQuery = Revision::getQueryInfo( [ 'page', 'user' ] );
-               return $db->select(
-                       $revQuery['tables'],
-                       $revQuery['fields'],
-                       $conds,
-                       __METHOD__,
-                       [ 'ORDER BY' => 'rev_id DESC' ],
-                       $revQuery['joins']
-               );
-       }
-
-       public function newItem( $row ) {
-               return new RevisionItem( $this, $row );
-       }
-}
-
-/**
- * Item class for a live revision table row
- */
-class RevisionItem extends RevisionItemBase {
-       /** @var Revision */
-       protected $revision;
-
-       /** @var RequestContext */
-       protected $context;
-
-       public function __construct( $list, $row ) {
-               parent::__construct( $list, $row );
-               $this->revision = new Revision( $row );
-               $this->context = $list->getContext();
-       }
-
-       public function getIdField() {
-               return 'rev_id';
-       }
-
-       public function getTimestampField() {
-               return 'rev_timestamp';
-       }
-
-       public function getAuthorIdField() {
-               return 'rev_user';
-       }
-
-       public function getAuthorNameField() {
-               return 'rev_user_text';
-       }
-
-       public function canView() {
-               return $this->revision->userCan( Revision::DELETED_RESTRICTED, $this->context->getUser() );
-       }
-
-       public function canViewContent() {
-               return $this->revision->userCan( Revision::DELETED_TEXT, $this->context->getUser() );
-       }
-
-       public function isDeleted() {
-               return $this->revision->isDeleted( Revision::DELETED_TEXT );
-       }
-
-       /**
-        * Get the HTML link to the revision text.
-        * @todo Essentially a copy of RevDelRevisionItem::getRevisionLink. That class
-        * should inherit from this one, and implement an appropriate interface instead
-        * of extending RevDelItem
-        * @return string
-        */
-       protected function getRevisionLink() {
-               $date = $this->list->getLanguage()->userTimeAndDate(
-                       $this->revision->getTimestamp(), $this->list->getUser() );
-
-               if ( $this->isDeleted() && !$this->canViewContent() ) {
-                       return htmlspecialchars( $date );
-               }
-               $linkRenderer = $this->getLinkRenderer();
-               return $linkRenderer->makeKnownLink(
-                       $this->list->title,
-                       $date,
-                       [],
-                       [
-                               'oldid' => $this->revision->getId(),
-                               'unhide' => 1
-                       ]
-               );
-       }
-
-       /**
-        * Get the HTML link to the diff.
-        * @todo Essentially a copy of RevDelRevisionItem::getDiffLink. That class
-        * should inherit from this one, and implement an appropriate interface instead
-        * of extending RevDelItem
-        * @return string
-        */
-       protected function getDiffLink() {
-               if ( $this->isDeleted() && !$this->canViewContent() ) {
-                       return $this->context->msg( 'diff' )->escaped();
-               } else {
-                       $linkRenderer = $this->getLinkRenderer();
-                       return $linkRenderer->makeKnownLink(
-                                       $this->list->title,
-                                       $this->list->msg( 'diff' )->text(),
-                                       [],
-                                       [
-                                               'diff' => $this->revision->getId(),
-                                               'oldid' => 'prev',
-                                               'unhide' => 1
-                                       ]
-                               );
-               }
-       }
-
-       /**
-        * @todo Essentially a copy of RevDelRevisionItem::getHTML. That class
-        * should inherit from this one, and implement an appropriate interface instead
-        * of extending RevDelItem
-        * @return string
-        */
-       public function getHTML() {
-               $difflink = $this->context->msg( 'parentheses' )
-                       ->rawParams( $this->getDiffLink() )->escaped();
-               $revlink = $this->getRevisionLink();
-               $userlink = Linker::revUserLink( $this->revision );
-               $comment = Linker::revComment( $this->revision );
-               if ( $this->isDeleted() ) {
-                       $revlink = "<span class=\"history-deleted\">$revlink</span>";
-               }
-               return "<li>$difflink $revlink $userlink $comment</li>";
-       }
-}
index 46dd913..c55fc68 100644 (file)
@@ -46,6 +46,7 @@ use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Permissions\PermissionManager;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Preferences\DefaultPreferencesFactory;
 use MediaWiki\Revision\MainSlotRoleHandler;
@@ -133,8 +134,8 @@ return [
                return new CryptHKDF( $secret, $config->get( 'HKDFAlgorithm' ), $cache, $context );
        },
 
-       'CryptRand' => function () : CryptRand {
-               return new CryptRand();
+       'DateFormatterFactory' => function () : DateFormatterFactory {
+               return new DateFormatterFactory;
        },
 
        'DBLoadBalancer' => function ( MediaWikiServices $services ) : Wikimedia\Rdbms\LoadBalancer {
@@ -149,7 +150,10 @@ return [
                $lbConf = MWLBFactory::applyDefaultConfig(
                        $mainConfig->get( 'LBFactoryConf' ),
                        $mainConfig,
-                       $services->getConfiguredReadOnlyMode()
+                       $services->getConfiguredReadOnlyMode(),
+                       $services->getLocalServerObjectCache(),
+                       $services->getMainObjectStash(),
+                       $services->getMainWANObjectCache()
                );
                $class = MWLBFactory::getLBFactoryClass( $lbConf );
 
@@ -200,12 +204,12 @@ return [
        },
 
        'LinkRenderer' => function ( MediaWikiServices $services ) : LinkRenderer {
-               global $wgUser;
-
                if ( defined( 'MW_NO_SESSION' ) ) {
                        return $services->getLinkRendererFactory()->create();
                } else {
-                       return $services->getLinkRendererFactory()->createForUser( $wgUser );
+                       return $services->getLinkRendererFactory()->createForUser(
+                               RequestContext::getMain()->getUser()
+                       );
                }
        },
 
@@ -326,6 +330,10 @@ return [
                return new MimeAnalyzer( $params );
        },
 
+       'NamespaceInfo' => function ( MediaWikiServices $services ) : NamespaceInfo {
+               return new NamespaceInfo( $services->getMainConfig() );
+       },
+
        'NameTableStoreFactory' => function ( MediaWikiServices $services ) : NameTableStoreFactory {
                return new NameTableStoreFactory(
                        $services->getDBLoadBalancerFactory(),
@@ -364,7 +372,9 @@ return [
                        $services->getContentLanguage(),
                        wfUrlProtocols(),
                        $services->getSpecialPageFactory(),
-                       $services->getMainConfig()
+                       $services->getMainConfig(),
+                       $services->getLinkRendererFactory(),
+                       $services->getNamespaceInfo()
                );
        },
 
@@ -386,6 +396,18 @@ return [
                );
        },
 
+       'PermissionManager' => function ( MediaWikiServices $services ) : PermissionManager {
+               $config = $services->getMainConfig();
+               return new PermissionManager(
+                       $services->getSpecialPageFactory(),
+                       $config->get( 'WhitelistRead' ),
+                       $config->get( 'WhitelistReadRegexp' ),
+                       $config->get( 'EmailConfirmToEdit' ),
+                       $config->get( 'BlockDisablesLogin' ),
+                       $services->getNamespaceInfo()
+               );
+       },
+
        'PreferencesFactory' => function ( MediaWikiServices $services ) : PreferencesFactory {
                $factory = new DefaultPreferencesFactory(
                        $services->getMainConfig(),
@@ -414,10 +436,17 @@ return [
        },
 
        'ResourceLoader' => function ( MediaWikiServices $services ) : ResourceLoader {
-               return new ResourceLoader(
-                       $services->getMainConfig(),
+               global $IP;
+               $config = $services->getMainConfig();
+
+               $rl = new ResourceLoader(
+                       $config,
                        LoggerFactory::getInstance( 'resourceloader' )
                );
+               $rl->addSource( $config->get( 'ResourceLoaderSources' ) );
+               $rl->register( include "$IP/resources/Resources.php" );
+
+               return $rl;
        },
 
        'RevisionFactory' => function ( MediaWikiServices $services ) : RevisionFactory {
@@ -489,14 +518,10 @@ return [
        },
 
        'SiteLookup' => function ( MediaWikiServices $services ) : SiteLookup {
-               $cacheFile = $services->getMainConfig()->get( 'SitesCacheFile' );
-
-               if ( $cacheFile !== false ) {
-                       return new FileBasedSiteLookup( $cacheFile );
-               } else {
-                       // Use the default SiteStore as the SiteLookup implementation for now
-                       return $services->getSiteStore();
-               }
+               // Use SiteStore as the SiteLookup as well. This was originally separated
+               // to allow for a cacheable read-only interface (using FileBasedSiteLookup),
+               // but this was never used. SiteStore has caching (see below).
+               return $services->getSiteStore();
        },
 
        'SiteStore' => function ( MediaWikiServices $services ) : SiteStore {
@@ -549,8 +574,13 @@ return [
        },
 
        'SpecialPageFactory' => function ( MediaWikiServices $services ) : SpecialPageFactory {
+               $config = $services->getMainConfig();
+               $options = [];
+               foreach ( SpecialPageFactory::$constructorOptions as $key ) {
+                       $options[$key] = $config->get( $key );
+               }
                return new SpecialPageFactory(
-                       $services->getMainConfig(),
+                       $options,
                        $services->getContentLanguage()
                );
        },
@@ -598,13 +628,16 @@ return [
                return new WatchedItemQueryService(
                        $services->getDBLoadBalancer(),
                        $services->getCommentStore(),
-                       $services->getActorMigration()
+                       $services->getActorMigration(),
+                       $services->getWatchedItemStore()
                );
        },
 
        'WatchedItemStore' => function ( MediaWikiServices $services ) : WatchedItemStore {
                $store = new WatchedItemStore(
                        $services->getDBLoadBalancerFactory(),
+                       JobQueueGroup::singleton(),
+                       $services->getMainObjectStash(),
                        new HashBagOStuff( [ 'maxKeys' => 100 ] ),
                        $services->getReadOnlyMode(),
                        $services->getMainConfig()->get( 'UpdateRowsPerQuery' )
index f8b9546..bcdc1d5 100644 (file)
@@ -492,7 +492,7 @@ $wgCanonicalNamespaceNames = [
 
 /// @todo UGLY UGLY
 if ( is_array( $wgExtraNamespaces ) ) {
-       $wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces;
+       $wgCanonicalNamespaceNames += $wgExtraNamespaces;
 }
 
 // Hard-deprecate setting $wgDummyLanguageCodes in LocalSettings.php
@@ -792,22 +792,6 @@ $wgContLang = MediaWikiServices::getInstance()->getContentLanguage();
 // Now that variant lists may be available...
 $wgRequest->interpolateTitle();
 
-if ( !is_object( $wgAuth ) ) {
-       $wgAuth = new MediaWiki\Auth\AuthManagerAuthPlugin;
-       Hooks::run( 'AuthPluginSetup', [ &$wgAuth ] );
-}
-if ( $wgAuth && !$wgAuth instanceof MediaWiki\Auth\AuthManagerAuthPlugin ) {
-       MediaWiki\Auth\AuthManager::singleton()->forcePrimaryAuthenticationProviders( [
-               new MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider( [
-                       'authoritative' => false,
-               ] ),
-               new MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider( $wgAuth ),
-               new MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider( [
-                       'authoritative' => true,
-               ] ),
-       ], '$wgAuth is ' . get_class( $wgAuth ) );
-}
-
 /**
  * @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent
  * session ID (if any) loaded at startup
@@ -897,7 +881,7 @@ $wgOut = RequestContext::getMain()->getOutput(); // BackCompat
 
 /**
  * @var Parser $wgParser
- * @deprecated since 1.32, use MediaWikiServices::getParser() instead
+ * @deprecated since 1.32, use MediaWikiServices::getInstance()->getParser() instead
  */
 $wgParser = new StubObject( 'wgParser', function () {
        return MediaWikiServices::getInstance()->getParser();
index 7af80dc..cab98a7 100644 (file)
@@ -562,7 +562,7 @@ class SiteConfiguration {
                                ->execute();
 
                        $data = trim( $result->getStdout() );
-                       if ( $result->getExitCode() != 0 || !strlen( $data ) ) {
+                       if ( $result->getExitCode() || $data === '' ) {
                                throw new MWException( "Failed to run getConfiguration.php: {$result->getStdout()}" );
                        }
                        $res = unserialize( $data );
@@ -582,14 +582,14 @@ class SiteConfiguration {
         * which is not fun
         *
         * @param array $array1
+        * @param array ...$arrays
         *
         * @return array
         */
-       static function arrayMerge( $array1/* ... */ ) {
+       static function arrayMerge( array $array1, ...$arrays ) {
                $out = $array1;
-               $argsCount = func_num_args();
-               for ( $i = 1; $i < $argsCount; $i++ ) {
-                       foreach ( func_get_arg( $i ) as $key => $value ) {
+               foreach ( $arrays as $array ) {
+                       foreach ( $array as $key => $value ) {
                                if ( isset( $out[$key] ) && is_array( $out[$key] ) && is_array( $value ) ) {
                                        $out[$key] = self::arrayMerge( $out[$key], $value );
                                } elseif ( !isset( $out[$key] ) || !$out[$key] && !is_numeric( $key ) ) {
index f880663..76b905e 100644 (file)
@@ -38,7 +38,7 @@
  * so that a lack of error-handling will be explicit.
  */
 class Status extends StatusValue {
-       /** @var callable */
+       /** @var callable|false */
        public $cleanCallback = false;
 
        /**
@@ -78,7 +78,8 @@ class Status extends StatusValue {
        function __get( $name ) {
                if ( $name === 'ok' ) {
                        return $this->isOK();
-               } elseif ( $name === 'errors' ) {
+               }
+               if ( $name === 'errors' ) {
                        return $this->getErrors();
                }
 
@@ -109,7 +110,7 @@ class Status extends StatusValue {
         * the error messages, and one that contains the warnings, only. The returned array is
         * defined as:
         * [
-        *     0 => object(Status) # the Status with error messages, only
+        *     0 => object(Status) # The Status with error messages, only
         *     1 => object(Status) # The Status with warning messages, only
         * ]
         *
@@ -148,21 +149,18 @@ class Status extends StatusValue {
        }
 
        /**
-        * @param string|Language|null $lang Language to use for processing
+        * @param string|Language|null|StubUserLang $lang Language to use for processing
         *  messages, or null to default to the user language.
-        * @return Language
+        * @return Language|StubUserLang
         */
        protected function languageFromParam( $lang ) {
-               global $wgLang;
-
                if ( $lang === null ) {
-                       // @todo: Use RequestContext::getMain()->getLanguage() instead
-                       return $wgLang;
-               } elseif ( $lang instanceof Language || $lang instanceof StubUserLang ) {
+                       return RequestContext::getMain()->getLanguage();
+               }
+               if ( $lang instanceof Language || $lang instanceof StubUserLang ) {
                        return $lang;
-               } else {
-                       return Language::factory( $lang );
                }
+               return Language::factory( $lang );
        }
 
        /**
@@ -171,14 +169,14 @@ class Status extends StatusValue {
         * @param string|bool $shortContext A short enclosing context message name, to
         *        be used when there is a single error
         * @param string|bool $longContext A long enclosing context message name, for a list
-        * @param string|Language|null $lang Language to use for processing messages
+        * @param string|Language|null|StubUserLang $lang Language to use for processing messages
         * @return string
         */
        public function getWikiText( $shortContext = false, $longContext = false, $lang = null ) {
                $lang = $this->languageFromParam( $lang );
 
                $rawErrors = $this->getErrors();
-               if ( count( $rawErrors ) == 0 ) {
+               if ( count( $rawErrors ) === 0 ) {
                        if ( $this->isOK() ) {
                                $this->fatal( 'internalerror_info',
                                        __METHOD__ . " called for a good result, this is incorrect\n" );
@@ -188,7 +186,7 @@ class Status extends StatusValue {
                        }
                        $rawErrors = $this->getErrors(); // just added a fatal
                }
-               if ( count( $rawErrors ) == 1 ) {
+               if ( count( $rawErrors ) === 1 ) {
                        $s = $this->getErrorMessage( $rawErrors[0], $lang )->plain();
                        if ( $shortContext ) {
                                $s = wfMessage( $shortContext, $s )->inLanguage( $lang )->plain();
@@ -234,7 +232,7 @@ class Status extends StatusValue {
                $lang = $this->languageFromParam( $lang );
 
                $rawErrors = $this->getErrors();
-               if ( count( $rawErrors ) == 0 ) {
+               if ( count( $rawErrors ) === 0 ) {
                        if ( $this->isOK() ) {
                                $this->fatal( 'internalerror_info',
                                        __METHOD__ . " called for a good result, this is incorrect\n" );
@@ -244,7 +242,7 @@ class Status extends StatusValue {
                        }
                        $rawErrors = $this->getErrors(); // just added a fatal
                }
-               if ( count( $rawErrors ) == 1 ) {
+               if ( count( $rawErrors ) === 1 ) {
                        $s = $this->getErrorMessage( $rawErrors[0], $lang );
                        if ( $shortContext ) {
                                $s = wfMessage( $shortContext, $s )->inLanguage( $lang );
@@ -297,7 +295,7 @@ class Status extends StatusValue {
                } elseif ( is_string( $error ) ) {
                        $msg = wfMessage( $error );
                } else {
-                       throw new UnexpectedValueException( "Got " . get_class( $error ) . " for key." );
+                       throw new UnexpectedValueException( 'Got ' . get_class( $error ) . ' for key.' );
                }
 
                $msg->inLanguage( $this->languageFromParam( $lang ) );
index 9ce12b4..d5c1656 100644 (file)
@@ -1590,8 +1590,9 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                                $update->setRevision( $legacyRevision );
                                $update->setTriggeringUser( $triggeringUser );
                        }
+
                        if ( $options['defer'] === false ) {
-                               if ( $options['transactionTicket'] !== null ) {
+                               if ( $update instanceof DataUpdate && $options['transactionTicket'] !== null ) {
                                        $update->setTransactionTicket( $options['transactionTicket'] );
                                }
                                $update->doUpdate();
index 27194ab..bf88b20 100644 (file)
@@ -47,7 +47,7 @@ class NameTableStore {
        private $tableCache = null;
 
        /** @var bool|string */
-       private $wikiId = false;
+       private $domain = false;
 
        /** @var int */
        private $cacheTTL;
@@ -77,7 +77,7 @@ class NameTableStore {
         * @param string $nameField
         * @param callable|null $normalizationCallback Normalization to be applied to names before being
         * saved or queried. This should be a callback that accepts and returns a single string.
-        * @param bool|string $wikiId The ID of the target wiki database. Use false for the local wiki.
+        * @param bool|string $dbDomain Database domain ID. Use false for the local database domain.
         * @param callable|null $insertCallback Callback to change insert fields accordingly.
         * This parameter was introduced in 1.32
         */
@@ -89,7 +89,7 @@ class NameTableStore {
                $idField,
                $nameField,
                callable $normalizationCallback = null,
-               $wikiId = false,
+               $dbDomain = false,
                callable $insertCallback = null
        ) {
                $this->loadBalancer = $dbLoadBalancer;
@@ -99,7 +99,7 @@ class NameTableStore {
                $this->idField = $idField;
                $this->nameField = $nameField;
                $this->normalizationCallback = $normalizationCallback;
-               $this->wikiId = $wikiId;
+               $this->domain = $dbDomain;
                $this->cacheTTL = IExpiringStore::TTL_MONTH;
                $this->insertCallback = $insertCallback;
        }
@@ -111,7 +111,7 @@ class NameTableStore {
         * @return IDatabase
         */
        private function getDBConnection( $index, $flags = 0 ) {
-               return $this->loadBalancer->getConnection( $index, [], $this->wikiId, $flags );
+               return $this->loadBalancer->getConnection( $index, [], $this->domain, $flags );
        }
 
        /**
@@ -126,7 +126,7 @@ class NameTableStore {
                return $this->cache->makeGlobalKey(
                        'NameTableSqlStore',
                        $this->table,
-                       $this->loadBalancer->resolveDomainID( $this->wikiId )
+                       $this->loadBalancer->resolveDomainID( $this->domain )
                );
        }
 
@@ -345,10 +345,10 @@ class NameTableStore {
        /**
         * Reap the WANCache entry for this table.
         *
-        * @param callable $purgeCallback callback to 'purge' the WAN cache
+        * @param callable $purgeCallback Callback to 'purge' the WAN cache
         */
        private function purgeWANCache( $purgeCallback ) {
-               // If the LB has no DB changes don't both with onTransactionPreCommitOrIdle
+               // If the LB has no DB changes don't bother with onTransactionPreCommitOrIdle
                if ( !$this->loadBalancer->hasOrMadeRecentMasterChanges() ) {
                        $purgeCallback();
                        return;
index d7216c5..82410cc 100644 (file)
@@ -35,7 +35,6 @@ use Language;
 use MWException;
 use WANObjectCache;
 use Wikimedia\Assert\Assert;
-use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
 
@@ -275,9 +274,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                        $this->getCacheKey( $blobAddress ),
                        $this->getCacheTTL(),
                        function ( $unused, &$ttl, &$setOpts ) use ( $blobAddress, $queryFlags ) {
-                               list( $index ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
-                               $setOpts += Database::getCacheSetOptions( $this->getDBConnection( $index ) );
-
+                               // Ignore $setOpts; blobs are immutable and negatives are not cached
                                return $this->fetchBlob( $blobAddress, $queryFlags );
                        },
                        [ 'pcGroup' => self::TEXT_CACHE_GROUP, 'pcTTL' => IExpiringStore::TTL_PROC_LONG ]
@@ -417,7 +414,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                                        $this->getCacheKey( $cacheKey ),
                                        $this->getCacheTTL(),
                                        function () use ( $url, $flags ) {
-                                               // No negative caching per BlobStore::getBlob()
+                                               // Ignore $setOpts; blobs are immutable and negatives are not cached
                                                $blob = ExternalStore::fetchFromURL( $url, [ 'wiki' => $this->wikiId ] );
 
                                                return $blob === false ? false : $this->decompressData( $blob, $flags );
@@ -609,12 +606,14 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
        /**
         * Splits a blob address into three parts: the schema, the ID, and parameters/flags.
         *
+        * @since 1.33
+        *
         * @param string $address
         *
         * @throws InvalidArgumentException
         * @return array [ $schema, $id, $parameters ], with $parameters being an assoc array.
         */
-       private static function splitBlobAddress( $address ) {
+       public static function splitBlobAddress( $address ) {
                if ( !preg_match( '/^(\w+):(\w+)(\?(.*))?$/', $address, $m ) ) {
                        throw new InvalidArgumentException( "Bad blob address: $address" );
                }
index 75494b1..fd856be 100644 (file)
@@ -62,9 +62,9 @@ class TemplateParser {
         */
        public function enableRecursivePartials( $enable ) {
                if ( $enable ) {
-                       $this->compileFlags = $this->compileFlags | LightnCandy::FLAG_RUNTIMEPARTIAL;
+                       $this->compileFlags |= LightnCandy::FLAG_RUNTIMEPARTIAL;
                } else {
-                       $this->compileFlags = $this->compileFlags & ~LightnCandy::FLAG_RUNTIMEPARTIAL;
+                       $this->compileFlags &= ~LightnCandy::FLAG_RUNTIMEPARTIAL;
                }
        }
 
@@ -220,6 +220,6 @@ class TemplateParser {
         */
        public function processTemplate( $templateName, $args, array $scopes = [] ) {
                $template = $this->getTemplate( $templateName );
-               return call_user_func( $template, $args, $scopes );
+               return $template( $args, $scopes );
        }
 }
index 494c7bf..bca1ef6 100644 (file)
@@ -66,11 +66,7 @@ class TemplatesOnThisPageFormatter {
                }
 
                # Do a batch existence check
-               $batch = new LinkBatch;
-               foreach ( $templates as $title ) {
-                       $batch->addObj( $title );
-               }
-               $batch->execute();
+               ( new LinkBatch( $templates ) )->execute();
 
                # Construct the HTML
                $outText = '<div class="mw-templatesUsedExplanation">';
index 4075bd5..3891c82 100644 (file)
@@ -22,6 +22,7 @@
  * @file
  */
 
+use MediaWiki\Permissions\PermissionManager;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
@@ -37,7 +38,7 @@ use MediaWiki\MediaWikiServices;
  *       and does not rely on global state or the database.
  */
 class Title implements LinkTarget, IDBAccessObject {
-       /** @var MapCacheLRU */
+       /** @var MapCacheLRU|null */
        private static $titleCache = null;
 
        /**
@@ -53,6 +54,15 @@ class Title implements LinkTarget, IDBAccessObject {
         */
        const GAID_FOR_UPDATE = 1;
 
+       /**
+        * Flag for use with factory methods like newFromLinkTarget() that have
+        * a $forceClone parameter. If set, the method must return a new instance.
+        * Without this flag, some factory methods may return existing instances.
+        *
+        * @since 1.33
+        */
+       const NEW_CLONE = 'clone';
+
        /**
         * @name Private member variables
         * Please use the accessor functions instead.
@@ -140,7 +150,7 @@ class Title implements LinkTarget, IDBAccessObject {
         * Only public to share cache with TitleFormatter
         *
         * @private
-        * @var string
+        * @var string|null
         */
        public $prefixedText = null;
 
@@ -173,10 +183,10 @@ class Title implements LinkTarget, IDBAccessObject {
         * the database or false if not loaded, yet. */
        private $mDbPageLanguage = false;
 
-       /** @var TitleValue A corresponding TitleValue object */
+       /** @var TitleValue|null A corresponding TitleValue object */
        private $mTitleValue = null;
 
-       /** @var bool Would deleting this page be a big deletion? */
+       /** @var bool|null Would deleting this page be a big deletion? */
        private $mIsBigDeletion = null;
        // @}
 
@@ -219,7 +229,7 @@ class Title implements LinkTarget, IDBAccessObject {
         * @return Title|null Title, or null on an error
         */
        public static function newFromDBkey( $key ) {
-               $t = new Title();
+               $t = new self();
                $t->mDbkeyform = $key;
 
                try {
@@ -231,27 +241,39 @@ class Title implements LinkTarget, IDBAccessObject {
        }
 
        /**
-        * Create a new Title from a TitleValue
+        * Returns a Title given a TitleValue.
+        * If the given TitleValue is already a Title instance, that instance is returned,
+        * unless $forceClone is "clone". If $forceClone is "clone" and the given TitleValue
+        * is already a Title instance, that instance is copied using the clone operator.
         *
         * @param TitleValue $titleValue Assumed to be safe.
+        * @param string $forceClone set to NEW_CLONE to ensure a fresh instance is returned.
         *
         * @return Title
         */
-       public static function newFromTitleValue( TitleValue $titleValue ) {
-               return self::newFromLinkTarget( $titleValue );
+       public static function newFromTitleValue( TitleValue $titleValue, $forceClone = '' ) {
+               return self::newFromLinkTarget( $titleValue, $forceClone );
        }
 
        /**
-        * Create a new Title from a LinkTarget
+        * Returns a Title given a LinkTarget.
+        * If the given LinkTarget is already a Title instance, that instance is returned,
+        * unless $forceClone is "clone". If $forceClone is "clone" and the given LinkTarget
+        * is already a Title instance, that instance is copied using the clone operator.
         *
         * @param LinkTarget $linkTarget Assumed to be safe.
+        * @param string $forceClone set to NEW_CLONE to ensure a fresh instance is returned.
         *
         * @return Title
         */
-       public static function newFromLinkTarget( LinkTarget $linkTarget ) {
+       public static function newFromLinkTarget( LinkTarget $linkTarget, $forceClone = '' ) {
                if ( $linkTarget instanceof Title ) {
                        // Special case if it's already a Title object
-                       return $linkTarget;
+                       if ( $forceClone === self::NEW_CLONE ) {
+                               return clone $linkTarget;
+                       } else {
+                               return $linkTarget;
+                       }
                }
                return self::makeTitle(
                        $linkTarget->getNamespace(),
@@ -268,6 +290,10 @@ class Title implements LinkTarget, IDBAccessObject {
         * Title objects returned by this method are guaranteed to be valid, and
         * thus return true from the isValid() method.
         *
+        * @note The Title instance returned by this method is not guaranteed to be a fresh instance.
+        * It may instead be a cached instance created previously, with references to it remaining
+        * elsewhere.
+        *
         * @param string|int|null $text The link text; spaces, prefixes, and an
         *   initial ':' indicating the main namespace are accepted.
         * @param int $defaultNamespace The namespace to use if none is specified
@@ -287,7 +313,7 @@ class Title implements LinkTarget, IDBAccessObject {
                }
 
                try {
-                       return self::newFromTextThrow( strval( $text ), $defaultNamespace );
+                       return self::newFromTextThrow( (string)$text, $defaultNamespace );
                } catch ( MalformedTitleException $ex ) {
                        return null;
                }
@@ -302,6 +328,10 @@ class Title implements LinkTarget, IDBAccessObject {
         * Title objects returned by this method are guaranteed to be valid, and
         * thus return true from the isValid() method.
         *
+        * @note The Title instance returned by this method is not guaranteed to be a fresh instance.
+        * It may instead be a cached instance created previously, with references to it remaining
+        * elsewhere.
+        *
         * @see Title::newFromText
         *
         * @since 1.25
@@ -337,7 +367,7 @@ class Title implements LinkTarget, IDBAccessObject {
 
                $t = new Title();
                $t->mDbkeyform = strtr( $filteredText, ' ', '_' );
-               $t->mDefaultNamespace = intval( $defaultNamespace );
+               $t->mDefaultNamespace = (int)$defaultNamespace;
 
                $t->secureAndSplit();
                if ( $defaultNamespace == NS_MAIN ) {
@@ -385,7 +415,7 @@ class Title implements LinkTarget, IDBAccessObject {
         * @return MapCacheLRU
         */
        private static function getTitleCache() {
-               if ( self::$titleCache == null ) {
+               if ( self::$titleCache === null ) {
                        self::$titleCache = new MapCacheLRU( self::CACHE_MAX );
                }
                return self::$titleCache;
@@ -437,6 +467,7 @@ class Title implements LinkTarget, IDBAccessObject {
                } else {
                        $title = null;
                }
+
                return $title;
        }
 
@@ -499,7 +530,7 @@ class Title implements LinkTarget, IDBAccessObject {
                                $this->mLatestID = (int)$row->page_latest;
                        }
                        if ( !$this->mForcedContentModel && isset( $row->page_content_model ) ) {
-                               $this->mContentModel = strval( $row->page_content_model );
+                               $this->mContentModel = (string)$row->page_content_model;
                        } elseif ( !$this->mForcedContentModel ) {
                                $this->mContentModel = false; # initialized lazily in getContentModel()
                        }
@@ -546,7 +577,7 @@ class Title implements LinkTarget, IDBAccessObject {
                $t = new Title();
                $t->mInterwiki = $interwiki;
                $t->mFragment = $fragment;
-               $t->mNamespace = $ns = intval( $ns );
+               $t->mNamespace = $ns = (int)$ns;
                $t->mDbkeyform = strtr( $title, ' ', '_' );
                $t->mArticleID = ( $ns >= 0 ) ? -1 : 0;
                $t->mUrlform = wfUrlencode( $t->mDbkeyform );
@@ -592,6 +623,10 @@ class Title implements LinkTarget, IDBAccessObject {
        /**
         * Create a new Title for the Main Page
         *
+        * @note The Title instance returned by this method is not guaranteed to be a fresh instance.
+        * It may instead be a cached instance created previously, with references to it remaining
+        * elsewhere.
+        *
         * @return Title The new object
         */
        public static function newMainPage() {
@@ -698,6 +733,7 @@ class Title implements LinkTarget, IDBAccessObject {
                                // Allow unicode if a single high-bit character appears
                                $r0 = sprintf( '\x%02x', $ord0 );
                                $allowUnicode = true;
+                               // @phan-suppress-next-line PhanParamSuspiciousOrder false positive
                        } elseif ( strpos( '-\\[]^', $d0 ) !== false ) {
                                $r0 = '\\' . $d0;
                        } else {
@@ -1701,16 +1737,18 @@ class Title implements LinkTarget, IDBAccessObject {
         * @return string Base name
         */
        public function getBaseText() {
+               $text = $this->getText();
                if ( !MWNamespace::hasSubpages( $this->mNamespace ) ) {
-                       return $this->getText();
+                       return $text;
                }
 
-               $parts = explode( '/', $this->getText() );
-               # Don't discard the real title if there's no subpage involved
-               if ( count( $parts ) > 1 ) {
-                       unset( $parts[count( $parts ) - 1] );
+               $lastSlashPos = strrpos( $text, '/' );
+               // Don't discard the real title if there's no subpage involved
+               if ( $lastSlashPos === false ) {
+                       return $text;
                }
-               return implode( '/', $parts );
+
+               return substr( $text, 0, $lastSlashPos );
        }
 
        /**
@@ -2027,8 +2065,8 @@ class Title implements LinkTarget, IDBAccessObject {
         * protocol-relative, the URL will be expanded to http://
         *
         * @see self::getLocalURL for the arguments.
-        * @param string $query
-        * @param string|bool $query2
+        * @param string|string[] $query
+        * @param string|bool $query2 Deprecated
         * @return string The URL
         */
        public function getInternalURL( $query = '', $query2 = false ) {
@@ -2050,8 +2088,8 @@ class Title implements LinkTarget, IDBAccessObject {
         * NOTE: Unlike getInternalURL(), the canonical URL includes the fragment
         *
         * @see self::getLocalURL for the arguments.
-        * @param string $query
-        * @param string|bool $query2
+        * @param string|string[] $query
+        * @param string|bool $query2 Deprecated
         * @return string The URL
         * @since 1.18
         */
@@ -2090,7 +2128,13 @@ class Title implements LinkTarget, IDBAccessObject {
         *
         * @param string $action Action that permission needs to be checked for
         * @param User|null $user User to check (since 1.19); $wgUser will be used if not provided.
+        *
         * @return bool
+        * @throws Exception
+        *
+        * @deprecated since 1.33,
+        * use MediaWikiServices::getInstance()->getPermissionManager()->quickUserCan(..) instead
+        *
         */
        public function quickUserCan( $action, $user = null ) {
                return $this->userCan( $action, $user, false );
@@ -2103,15 +2147,29 @@ class Title implements LinkTarget, IDBAccessObject {
         * @param User|null $user User to check (since 1.19); $wgUser will be used if not
         *   provided.
         * @param string $rigor Same format as Title::getUserPermissionsErrors()
+        *
         * @return bool
+        * @throws Exception
+        *
+        * @deprecated since 1.33,
+        * use MediaWikiServices::getInstance()->getPermissionManager()->userCan(..) instead
+        *
         */
-       public function userCan( $action, $user = null, $rigor = 'secure' ) {
+       public function userCan( $action, $user = null, $rigor = PermissionManager::RIGOR_SECURE ) {
                if ( !$user instanceof User ) {
                        global $wgUser;
                        $user = $wgUser;
                }
 
-               return !count( $this->getUserPermissionsErrorsInternal( $action, $user, $rigor, true ) );
+               // TODO: this is for b/c, eventually will be removed
+               if ( $rigor === true ) {
+                       $rigor = PermissionManager::RIGOR_SECURE; // b/c
+               } elseif ( $rigor === false ) {
+                       $rigor = PermissionManager::RIGOR_QUICK; // b/c
+               }
+
+               return MediaWikiServices::getInstance()->getPermissionManager()
+                       ->userCan( $action, $user, $this, $rigor );
        }
 
        /**
@@ -2127,99 +2185,26 @@ class Title implements LinkTarget, IDBAccessObject {
         *   - secure : does cheap and expensive checks, using the master as needed
         * @param array $ignoreErrors Array of Strings Set this to a list of message keys
         *   whose corresponding errors may be ignored.
+        *
         * @return array Array of arrays of the arguments to wfMessage to explain permissions problems.
-        */
-       public function getUserPermissionsErrors(
-               $action, $user, $rigor = 'secure', $ignoreErrors = []
-       ) {
-               $errors = $this->getUserPermissionsErrorsInternal( $action, $user, $rigor );
-
-               // Remove the errors being ignored.
-               foreach ( $errors as $index => $error ) {
-                       $errKey = is_array( $error ) ? $error[0] : $error;
-
-                       if ( in_array( $errKey, $ignoreErrors ) ) {
-                               unset( $errors[$index] );
-                       }
-                       if ( $errKey instanceof MessageSpecifier && in_array( $errKey->getKey(), $ignoreErrors ) ) {
-                               unset( $errors[$index] );
-                       }
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Permissions checks that fail most often, and which are easiest to test.
+        * @throws Exception
         *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
+        * @deprecated since 1.33,
+        * use MediaWikiServices::getInstance()->getPermissionManager()->getUserPermissionsErrors()
         *
-        * @return array List of errors
         */
-       private function checkQuickPermissions( $action, $user, $errors, $rigor, $short ) {
-               if ( !Hooks::run( 'TitleQuickPermissions',
-                       [ $this, $user, $action, &$errors, ( $rigor !== 'quick' ), $short ] )
-               ) {
-                       return $errors;
-               }
-
-               if ( $action == 'create' ) {
-                       if (
-                               ( $this->isTalkPage() && !$user->isAllowed( 'createtalk' ) ) ||
-                               ( !$this->isTalkPage() && !$user->isAllowed( 'createpage' ) )
-                       ) {
-                               $errors[] = $user->isAnon() ? [ 'nocreatetext' ] : [ 'nocreate-loggedin' ];
-                       }
-               } elseif ( $action == 'move' ) {
-                       if ( !$user->isAllowed( 'move-rootuserpages' )
-                                       && $this->mNamespace == NS_USER && !$this->isSubpage() ) {
-                               // Show user page-specific message only if the user can move other pages
-                               $errors[] = [ 'cant-move-user-page' ];
-                       }
-
-                       // Check if user is allowed to move files if it's a file
-                       if ( $this->mNamespace == NS_FILE && !$user->isAllowed( 'movefile' ) ) {
-                               $errors[] = [ 'movenotallowedfile' ];
-                       }
-
-                       // Check if user is allowed to move category pages if it's a category page
-                       if ( $this->mNamespace == NS_CATEGORY && !$user->isAllowed( 'move-categorypages' ) ) {
-                               $errors[] = [ 'cant-move-category-page' ];
-                       }
-
-                       if ( !$user->isAllowed( 'move' ) ) {
-                               // User can't move anything
-                               $userCanMove = User::groupHasPermission( 'user', 'move' );
-                               $autoconfirmedCanMove = User::groupHasPermission( 'autoconfirmed', 'move' );
-                               if ( $user->isAnon() && ( $userCanMove || $autoconfirmedCanMove ) ) {
-                                       // custom message if logged-in users without any special rights can move
-                                       $errors[] = [ 'movenologintext' ];
-                               } else {
-                                       $errors[] = [ 'movenotallowed' ];
-                               }
-                       }
-               } elseif ( $action == 'move-target' ) {
-                       if ( !$user->isAllowed( 'move' ) ) {
-                               // User can't move anything
-                               $errors[] = [ 'movenotallowed' ];
-                       } elseif ( !$user->isAllowed( 'move-rootuserpages' )
-                                       && $this->mNamespace == NS_USER && !$this->isSubpage() ) {
-                               // Show user page-specific message only if the user can move other pages
-                               $errors[] = [ 'cant-move-to-user-page' ];
-                       } elseif ( !$user->isAllowed( 'move-categorypages' )
-                                       && $this->mNamespace == NS_CATEGORY ) {
-                               // Show category page-specific message only if the user can move other pages
-                               $errors[] = [ 'cant-move-to-category-page' ];
-                       }
-               } elseif ( !$user->isAllowed( $action ) ) {
-                       $errors[] = $this->missingPermissionError( $action, $short );
+       public function getUserPermissionsErrors(
+               $action, $user, $rigor = PermissionManager::RIGOR_SECURE, $ignoreErrors = []
+       ) {
+               // TODO: this is for b/c, eventually will be removed
+               if ( $rigor === true ) {
+                       $rigor = PermissionManager::RIGOR_SECURE; // b/c
+               } elseif ( $rigor === false ) {
+                       $rigor = PermissionManager::RIGOR_QUICK; // b/c
                }
 
-               return $errors;
+               return MediaWikiServices::getInstance()->getPermissionManager()
+                       ->getPermissionErrors( $action, $user, $this, $rigor, $ignoreErrors );
        }
 
        /**
@@ -2250,582 +2235,6 @@ class Title implements LinkTarget, IDBAccessObject {
                return $errors;
        }
 
-       /**
-        * Check various permission hooks
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkPermissionHooks( $action, $user, $errors, $rigor, $short ) {
-               // Use getUserPermissionsErrors instead
-               $result = '';
-               // Avoid PHP 7.1 warning from passing $this by reference
-               $titleRef = $this;
-               if ( !Hooks::run( 'userCan', [ &$titleRef, &$user, $action, &$result ] ) ) {
-                       return $result ? [] : [ [ 'badaccess-group0' ] ];
-               }
-               // Check getUserPermissionsErrors hook
-               // Avoid PHP 7.1 warning from passing $this by reference
-               $titleRef = $this;
-               if ( !Hooks::run( 'getUserPermissionsErrors', [ &$titleRef, &$user, $action, &$result ] ) ) {
-                       $errors = $this->resultToError( $errors, $result );
-               }
-               // Check getUserPermissionsErrorsExpensive hook
-               if (
-                       $rigor !== 'quick'
-                       && !( $short && count( $errors ) > 0 )
-                       && !Hooks::run( 'getUserPermissionsErrorsExpensive', [ &$titleRef, &$user, $action, &$result ] )
-               ) {
-                       $errors = $this->resultToError( $errors, $result );
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Check permissions on special pages & namespaces
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkSpecialsAndNSPermissions( $action, $user, $errors, $rigor, $short ) {
-               # Only 'createaccount' can be performed on special pages,
-               # which don't actually exist in the DB.
-               if ( $this->isSpecialPage() && $action !== 'createaccount' ) {
-                       $errors[] = [ 'ns-specialprotected' ];
-               }
-
-               # Check $wgNamespaceProtection for restricted namespaces
-               if ( $this->isNamespaceProtected( $user ) ) {
-                       $ns = $this->mNamespace == NS_MAIN ?
-                               wfMessage( 'nstab-main' )->text() : $this->getNsText();
-                       $errors[] = $this->mNamespace == NS_MEDIAWIKI ?
-                               [ 'protectedinterface', $action ] : [ 'namespaceprotected', $ns, $action ];
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Check sitewide CSS/JSON/JS permissions
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkSiteConfigPermissions( $action, $user, $errors, $rigor, $short ) {
-               if ( $action != 'patrol' ) {
-                       $error = null;
-                       // Sitewide CSS/JSON/JS changes, like all NS_MEDIAWIKI changes, also require the
-                       // editinterface right. That's implemented as a restriction so no check needed here.
-                       if ( $this->isSiteCssConfigPage() && !$user->isAllowed( 'editsitecss' ) ) {
-                               $error = [ 'sitecssprotected', $action ];
-                       } elseif ( $this->isSiteJsonConfigPage() && !$user->isAllowed( 'editsitejson' ) ) {
-                               $error = [ 'sitejsonprotected', $action ];
-                       } elseif ( $this->isSiteJsConfigPage() && !$user->isAllowed( 'editsitejs' ) ) {
-                               $error = [ 'sitejsprotected', $action ];
-                       } elseif ( $this->isRawHtmlMessage() ) {
-                               // Raw HTML can be used to deploy CSS or JS so require rights for both.
-                               if ( !$user->isAllowed( 'editsitejs' ) ) {
-                                       $error = [ 'sitejsprotected', $action ];
-                               } elseif ( !$user->isAllowed( 'editsitecss' ) ) {
-                                       $error = [ 'sitecssprotected', $action ];
-                               }
-                       }
-
-                       if ( $error ) {
-                               if ( $user->isAllowed( 'editinterface' ) ) {
-                                       // Most users / site admins will probably find out about the new, more restrictive
-                                       // permissions by failing to edit something. Give them more info.
-                                       // TODO remove this a few release cycles after 1.32
-                                       $error = [ 'interfaceadmin-info', wfMessage( $error[0], $error[1] ) ];
-                               }
-                               $errors[] = $error;
-                       }
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Check CSS/JSON/JS sub-page permissions
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkUserConfigPermissions( $action, $user, $errors, $rigor, $short ) {
-               # Protect css/json/js subpages of user pages
-               # XXX: this might be better using restrictions
-
-               if ( $action === 'patrol' ) {
-                       return $errors;
-               }
-
-               if ( preg_match( '/^' . preg_quote( $user->getName(), '/' ) . '\//', $this->mTextform ) ) {
-                       // Users need editmyuser* to edit their own CSS/JSON/JS subpages.
-                       if (
-                               $this->isUserCssConfigPage()
-                               && !$user->isAllowedAny( 'editmyusercss', 'editusercss' )
-                       ) {
-                               $errors[] = [ 'mycustomcssprotected', $action ];
-                       } elseif (
-                               $this->isUserJsonConfigPage()
-                               && !$user->isAllowedAny( 'editmyuserjson', 'edituserjson' )
-                       ) {
-                               $errors[] = [ 'mycustomjsonprotected', $action ];
-                       } elseif (
-                               $this->isUserJsConfigPage()
-                               && !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' )
-                       ) {
-                               $errors[] = [ 'mycustomjsprotected', $action ];
-                       }
-               } else {
-                       // Users need editmyuser* to edit their own CSS/JSON/JS subpages, except for
-                       // deletion/suppression which cannot be used for attacks and we want to avoid the
-                       // situation where an unprivileged user can post abusive content on their subpages
-                       // and only very highly privileged users could remove it.
-                       if ( !in_array( $action, [ 'delete', 'deleterevision', 'suppressrevision' ], true ) ) {
-                               if (
-                                       $this->isUserCssConfigPage()
-                                       && !$user->isAllowed( 'editusercss' )
-                               ) {
-                                       $errors[] = [ 'customcssprotected', $action ];
-                               } elseif (
-                                       $this->isUserJsonConfigPage()
-                                       && !$user->isAllowed( 'edituserjson' )
-                               ) {
-                                       $errors[] = [ 'customjsonprotected', $action ];
-                               } elseif (
-                                       $this->isUserJsConfigPage()
-                                       && !$user->isAllowed( 'edituserjs' )
-                               ) {
-                                       $errors[] = [ 'customjsprotected', $action ];
-                               }
-                       }
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Check against page_restrictions table requirements on this
-        * page. The user must possess all required rights for this
-        * action.
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkPageRestrictions( $action, $user, $errors, $rigor, $short ) {
-               foreach ( $this->getRestrictions( $action ) as $right ) {
-                       // Backwards compatibility, rewrite sysop -> editprotected
-                       if ( $right == 'sysop' ) {
-                               $right = 'editprotected';
-                       }
-                       // Backwards compatibility, rewrite autoconfirmed -> editsemiprotected
-                       if ( $right == 'autoconfirmed' ) {
-                               $right = 'editsemiprotected';
-                       }
-                       if ( $right == '' ) {
-                               continue;
-                       }
-                       if ( !$user->isAllowed( $right ) ) {
-                               $errors[] = [ 'protectedpagetext', $right, $action ];
-                       } elseif ( $this->mCascadeRestriction && !$user->isAllowed( 'protect' ) ) {
-                               $errors[] = [ 'protectedpagetext', 'protect', $action ];
-                       }
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Check restrictions on cascading pages.
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkCascadingSourcesRestrictions( $action, $user, $errors, $rigor, $short ) {
-               if ( $rigor !== 'quick' && !$this->isUserConfigPage() ) {
-                       # We /could/ use the protection level on the source page, but it's
-                       # fairly ugly as we have to establish a precedence hierarchy for pages
-                       # included by multiple cascade-protected pages. So just restrict
-                       # it to people with 'protect' permission, as they could remove the
-                       # protection anyway.
-                       list( $cascadingSources, $restrictions ) = $this->getCascadeProtectionSources();
-                       # Cascading protection depends on more than this page...
-                       # Several cascading protected pages may include this page...
-                       # Check each cascading level
-                       # This is only for protection restrictions, not for all actions
-                       if ( isset( $restrictions[$action] ) ) {
-                               foreach ( $restrictions[$action] as $right ) {
-                                       // Backwards compatibility, rewrite sysop -> editprotected
-                                       if ( $right == 'sysop' ) {
-                                               $right = 'editprotected';
-                                       }
-                                       // Backwards compatibility, rewrite autoconfirmed -> editsemiprotected
-                                       if ( $right == 'autoconfirmed' ) {
-                                               $right = 'editsemiprotected';
-                                       }
-                                       if ( $right != '' && !$user->isAllowedAll( 'protect', $right ) ) {
-                                               $pages = '';
-                                               foreach ( $cascadingSources as $page ) {
-                                                       $pages .= '* [[:' . $page->getPrefixedText() . "]]\n";
-                                               }
-                                               $errors[] = [ 'cascadeprotected', count( $cascadingSources ), $pages, $action ];
-                                       }
-                               }
-                       }
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Check action permissions not already checked in checkQuickPermissions
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkActionPermissions( $action, $user, $errors, $rigor, $short ) {
-               global $wgDeleteRevisionsLimit, $wgLang;
-
-               if ( $action == 'protect' ) {
-                       if ( count( $this->getUserPermissionsErrorsInternal( 'edit', $user, $rigor, true ) ) ) {
-                               // If they can't edit, they shouldn't protect.
-                               $errors[] = [ 'protect-cantedit' ];
-                       }
-               } elseif ( $action == 'create' ) {
-                       $title_protection = $this->getTitleProtection();
-                       if ( $title_protection ) {
-                               if ( $title_protection['permission'] == ''
-                                       || !$user->isAllowed( $title_protection['permission'] )
-                               ) {
-                                       $errors[] = [
-                                               'titleprotected',
-                                               User::whoIs( $title_protection['user'] ),
-                                               $title_protection['reason']
-                                       ];
-                               }
-                       }
-               } elseif ( $action == 'move' ) {
-                       // Check for immobile pages
-                       if ( !MWNamespace::isMovable( $this->mNamespace ) ) {
-                               // Specific message for this case
-                               $errors[] = [ 'immobile-source-namespace', $this->getNsText() ];
-                       } elseif ( !$this->isMovable() ) {
-                               // Less specific message for rarer cases
-                               $errors[] = [ 'immobile-source-page' ];
-                       }
-               } elseif ( $action == 'move-target' ) {
-                       if ( !MWNamespace::isMovable( $this->mNamespace ) ) {
-                               $errors[] = [ 'immobile-target-namespace', $this->getNsText() ];
-                       } elseif ( !$this->isMovable() ) {
-                               $errors[] = [ 'immobile-target-page' ];
-                       }
-               } elseif ( $action == 'delete' ) {
-                       $tempErrors = $this->checkPageRestrictions( 'edit', $user, [], $rigor, true );
-                       if ( !$tempErrors ) {
-                               $tempErrors = $this->checkCascadingSourcesRestrictions( 'edit',
-                                       $user, $tempErrors, $rigor, true );
-                       }
-                       if ( $tempErrors ) {
-                               // If protection keeps them from editing, they shouldn't be able to delete.
-                               $errors[] = [ 'deleteprotected' ];
-                       }
-                       if ( $rigor !== 'quick' && $wgDeleteRevisionsLimit
-                               && !$this->userCan( 'bigdelete', $user ) && $this->isBigDeletion()
-                       ) {
-                               $errors[] = [ 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ];
-                       }
-               } elseif ( $action === 'undelete' ) {
-                       if ( count( $this->getUserPermissionsErrorsInternal( 'edit', $user, $rigor, true ) ) ) {
-                               // Undeleting implies editing
-                               $errors[] = [ 'undelete-cantedit' ];
-                       }
-                       if ( !$this->exists()
-                               && count( $this->getUserPermissionsErrorsInternal( 'create', $user, $rigor, true ) )
-                       ) {
-                               // Undeleting where nothing currently exists implies creating
-                               $errors[] = [ 'undelete-cantcreate' ];
-                       }
-               }
-               return $errors;
-       }
-
-       /**
-        * Check that the user isn't blocked from editing.
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkUserBlock( $action, $user, $errors, $rigor, $short ) {
-               global $wgEmailConfirmToEdit, $wgBlockDisablesLogin;
-               // Account creation blocks handled at userlogin.
-               // Unblocking handled in SpecialUnblock
-               if ( $rigor === 'quick' || in_array( $action, [ 'createaccount', 'unblock' ] ) ) {
-                       return $errors;
-               }
-
-               // Optimize for a very common case
-               if ( $action === 'read' && !$wgBlockDisablesLogin ) {
-                       return $errors;
-               }
-
-               if ( $wgEmailConfirmToEdit
-                       && !$user->isEmailConfirmed()
-                       && $action === 'edit'
-               ) {
-                       $errors[] = [ 'confirmedittext' ];
-               }
-
-               $useReplica = ( $rigor !== 'secure' );
-               $block = $user->getBlock( $useReplica );
-
-               // If the user does not have a block, or the block they do have explicitly
-               // allows the action (like "read" or "upload").
-               if ( !$block || $block->appliesToRight( $action ) === false ) {
-                       return $errors;
-               }
-
-               // Determine if the user is blocked from this action on this page.
-               // What gets passed into this method is a user right, not an action name.
-               // There is no way to instantiate an action by restriction. However, this
-               // will get the action where the restriction is the same. This may result
-               // in actions being blocked that shouldn't be.
-               $actionObj = null;
-               if ( Action::exists( $action ) ) {
-                       // Clone the title to prevent mutations to this object which is done
-                       // by Title::loadFromRow() in WikiPage::loadFromRow().
-                       $page = WikiPage::factory( clone $this );
-                       // Creating an action will perform several database queries to ensure that
-                       // the action has not been overridden by the content type.
-                       // @todo FIXME: Pass the relevant context into this function.
-                       $actionObj = Action::factory( $action, $page, RequestContext::getMain() );
-                       // Ensure that the retrieved action matches the restriction.
-                       if ( $actionObj && $actionObj->getRestriction() !== $action ) {
-                               $actionObj = null;
-                       }
-               }
-
-               // If no action object is returned, assume that the action requires unblock
-               // which is the default.
-               if ( !$actionObj || $actionObj->requiresUnblock() ) {
-                       if ( $user->isBlockedFrom( $this, $useReplica ) ) {
-                               // @todo FIXME: Pass the relevant context into this function.
-                               $errors[] = $block->getPermissionsError( RequestContext::getMain() );
-                       }
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Check that the user is allowed to read this page.
-        *
-        * @param string $action The action to check
-        * @param User $user User to check
-        * @param array $errors List of current errors
-        * @param string $rigor Same format as Title::getUserPermissionsErrors()
-        * @param bool $short Short circuit on first error
-        *
-        * @return array List of errors
-        */
-       private function checkReadPermissions( $action, $user, $errors, $rigor, $short ) {
-               global $wgWhitelistRead, $wgWhitelistReadRegexp;
-
-               $whitelisted = false;
-               if ( User::isEveryoneAllowed( 'read' ) ) {
-                       # Shortcut for public wikis, allows skipping quite a bit of code
-                       $whitelisted = true;
-               } elseif ( $user->isAllowed( 'read' ) ) {
-                       # If the user is allowed to read pages, he is allowed to read all pages
-                       $whitelisted = true;
-               } elseif ( $this->isSpecial( 'Userlogin' )
-                       || $this->isSpecial( 'PasswordReset' )
-                       || $this->isSpecial( 'Userlogout' )
-               ) {
-                       # Always grant access to the login page.
-                       # Even anons need to be able to log in.
-                       $whitelisted = true;
-               } elseif ( is_array( $wgWhitelistRead ) && count( $wgWhitelistRead ) ) {
-                       # Time to check the whitelist
-                       # Only do these checks is there's something to check against
-                       $name = $this->getPrefixedText();
-                       $dbName = $this->getPrefixedDBkey();
-
-                       // Check for explicit whitelisting with and without underscores
-                       if ( in_array( $name, $wgWhitelistRead, true ) || in_array( $dbName, $wgWhitelistRead, true ) ) {
-                               $whitelisted = true;
-                       } elseif ( $this->mNamespace == NS_MAIN ) {
-                               # Old settings might have the title prefixed with
-                               # a colon for main-namespace pages
-                               if ( in_array( ':' . $name, $wgWhitelistRead ) ) {
-                                       $whitelisted = true;
-                               }
-                       } elseif ( $this->isSpecialPage() ) {
-                               # If it's a special page, ditch the subpage bit and check again
-                               $name = $this->mDbkeyform;
-                               list( $name, /* $subpage */ ) =
-                                       MediaWikiServices::getInstance()->getSpecialPageFactory()->
-                                               resolveAlias( $name );
-                               if ( $name ) {
-                                       $pure = SpecialPage::getTitleFor( $name )->getPrefixedText();
-                                       if ( in_array( $pure, $wgWhitelistRead, true ) ) {
-                                               $whitelisted = true;
-                                       }
-                               }
-                       }
-               }
-
-               if ( !$whitelisted && is_array( $wgWhitelistReadRegexp ) && !empty( $wgWhitelistReadRegexp ) ) {
-                       $name = $this->getPrefixedText();
-                       // Check for regex whitelisting
-                       foreach ( $wgWhitelistReadRegexp as $listItem ) {
-                               if ( preg_match( $listItem, $name ) ) {
-                                       $whitelisted = true;
-                                       break;
-                               }
-                       }
-               }
-
-               if ( !$whitelisted ) {
-                       # If the title is not whitelisted, give extensions a chance to do so...
-                       Hooks::run( 'TitleReadWhitelist', [ $this, $user, &$whitelisted ] );
-                       if ( !$whitelisted ) {
-                               $errors[] = $this->missingPermissionError( $action, $short );
-                       }
-               }
-
-               return $errors;
-       }
-
-       /**
-        * Get a description array when the user doesn't have the right to perform
-        * $action (i.e. when User::isAllowed() returns false)
-        *
-        * @param string $action The action to check
-        * @param bool $short Short circuit on first error
-        * @return array Array containing an error message key and any parameters
-        */
-       private function missingPermissionError( $action, $short ) {
-               // We avoid expensive display logic for quickUserCan's and such
-               if ( $short ) {
-                       return [ 'badaccess-group0' ];
-               }
-
-               return User::newFatalPermissionDeniedStatus( $action )->getErrorsArray()[0];
-       }
-
-       /**
-        * Can $user perform $action on this page? This is an internal function,
-        * with multiple levels of checks depending on performance needs; see $rigor below.
-        * It does not check wfReadOnly().
-        *
-        * @param string $action Action that permission needs to be checked for
-        * @param User $user User to check
-        * @param string $rigor One of (quick,full,secure)
-        *   - quick  : does cheap permission checks from replica DBs (usable for GUI creation)
-        *   - full   : does cheap and expensive checks possibly from a replica DB
-        *   - secure : does cheap and expensive checks, using the master as needed
-        * @param bool $short Set this to true to stop after the first permission error.
-        * @return array Array of arrays of the arguments to wfMessage to explain permissions problems.
-        */
-       protected function getUserPermissionsErrorsInternal(
-               $action, $user, $rigor = 'secure', $short = false
-       ) {
-               if ( $rigor === true ) {
-                       $rigor = 'secure'; // b/c
-               } elseif ( $rigor === false ) {
-                       $rigor = 'quick'; // b/c
-               } elseif ( !in_array( $rigor, [ 'quick', 'full', 'secure' ] ) ) {
-                       throw new Exception( "Invalid rigor parameter '$rigor'." );
-               }
-
-               # Read has special handling
-               if ( $action == 'read' ) {
-                       $checks = [
-                               'checkPermissionHooks',
-                               'checkReadPermissions',
-                               'checkUserBlock', // for wgBlockDisablesLogin
-                       ];
-               # Don't call checkSpecialsAndNSPermissions, checkSiteConfigPermissions
-               # or checkUserConfigPermissions here as it will lead to duplicate
-               # error messages. This is okay to do since anywhere that checks for
-               # create will also check for edit, and those checks are called for edit.
-               } elseif ( $action == 'create' ) {
-                       $checks = [
-                               'checkQuickPermissions',
-                               'checkPermissionHooks',
-                               'checkPageRestrictions',
-                               'checkCascadingSourcesRestrictions',
-                               'checkActionPermissions',
-                               'checkUserBlock'
-                       ];
-               } else {
-                       $checks = [
-                               'checkQuickPermissions',
-                               'checkPermissionHooks',
-                               'checkSpecialsAndNSPermissions',
-                               'checkSiteConfigPermissions',
-                               'checkUserConfigPermissions',
-                               'checkPageRestrictions',
-                               'checkCascadingSourcesRestrictions',
-                               'checkActionPermissions',
-                               'checkUserBlock'
-                       ];
-               }
-
-               $errors = [];
-               foreach ( $checks as $method ) {
-                       $errors = $this->$method( $action, $user, $errors, $rigor, $short );
-
-                       if ( $short && $errors !== [] ) {
-                               break;
-                       }
-               }
-
-               return $errors;
-       }
-
        /**
         * Get a filtered list of all restriction types supported by this wiki.
         * @param bool $exists True to get all restriction types that apply to
@@ -3254,8 +2663,9 @@ class Title implements LinkTarget, IDBAccessObject {
                }
 
                if ( $this->mOldRestrictions === false ) {
-                       $this->mOldRestrictions = $dbr->selectField( 'page', 'page_restrictions',
-                               [ 'page_id' => $this->getArticleID() ], __METHOD__ );
+                       $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+                       $linkCache->addLinkObj( $this ); # in case we already had an article ID
+                       $this->mOldRestrictions = $linkCache->getGoodLinkFieldObj( $this, 'restrictions' );
                }
 
                if ( $this->mOldRestrictions != '' ) {
@@ -3322,7 +2732,7 @@ class Title implements LinkTarget, IDBAccessObject {
                $id = $this->getArticleID();
                if ( $id ) {
                        $fname = __METHOD__;
-                       $loadRestrictionsFromDb = function ( Database $dbr ) use ( $fname, $id ) {
+                       $loadRestrictionsFromDb = function ( IDatabase $dbr ) use ( $fname, $id ) {
                                return iterator_to_array(
                                        $dbr->select(
                                                'page_restrictions',
@@ -3337,15 +2747,20 @@ class Title implements LinkTarget, IDBAccessObject {
                                $dbr = wfGetDB( DB_MASTER );
                                $rows = $loadRestrictionsFromDb( $dbr );
                        } else {
-                               $cache = ObjectCache::getMainWANInstance();
+                               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                                $rows = $cache->getWithSetCallback(
                                        // Page protections always leave a new null revision
-                                       $cache->makeKey( 'page-restrictions', $id, $this->getLatestRevID() ),
+                                       $cache->makeKey( 'page-restrictions', 'v1', $id, $this->getLatestRevID() ),
                                        $cache::TTL_DAY,
                                        function ( $curValue, &$ttl, array &$setOpts ) use ( $loadRestrictionsFromDb ) {
                                                $dbr = wfGetDB( DB_REPLICA );
 
                                                $setOpts += Database::getCacheSetOptions( $dbr );
+                                               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+                                               if ( $lb->hasOrMadeRecentMasterChanges() ) {
+                                                       // @TODO: cleanup Title cache and caller assumption mess in general
+                                                       $ttl = WANObjectCache::TTL_UNCACHEABLE;
+                                               }
 
                                                return $loadRestrictionsFromDb( $dbr );
                                        }
@@ -3547,10 +2962,8 @@ class Title implements LinkTarget, IDBAccessObject {
                        $linkCache->clearLink( $this );
                        $this->mArticleID = $linkCache->addLinkObj( $this );
                        $linkCache->forUpdate( $oldUpdate );
-               } else {
-                       if ( $this->mArticleID == -1 ) {
-                               $this->mArticleID = $linkCache->addLinkObj( $this );
-                       }
+               } elseif ( $this->mArticleID == -1 ) {
+                       $this->mArticleID = $linkCache->addLinkObj( $this );
                }
                return $this->mArticleID;
        }
@@ -3720,6 +3133,7 @@ class Title implements LinkTarget, IDBAccessObject {
                // @todo: get rid of secureAndSplit, refactor parsing code.
                // @note: getTitleParser() returns a TitleParser implementation which does not have a
                //        splitTitleString method, but the only implementation (MediaWikiTitleCodec) does
+               /** @var MediaWikiTitleCodec $titleCodec */
                $titleCodec = MediaWikiServices::getInstance()->getTitleParser();
                // MalformedTitleException can be thrown here
                $parts = $titleCodec->splitTitleString( $this->mDbkeyform, $this->mDefaultNamespace );
@@ -3983,28 +3397,6 @@ class Title implements LinkTarget, IDBAccessObject {
                return $errors ?: true;
        }
 
-       /**
-        * Check if the requested move target is a valid file move target
-        * @todo move this to MovePage
-        * @param Title $nt Target title
-        * @return array List of errors
-        */
-       protected function validateFileMoveOperation( $nt ) {
-               global $wgUser;
-
-               $errors = [];
-
-               $destFile = wfLocalFile( $nt );
-               $destFile->load( File::READ_LATEST );
-               if ( !$wgUser->isAllowed( 'reupload-shared' )
-                       && !$destFile->exists() && wfFindFile( $nt )
-               ) {
-                       $errors[] = [ 'file-exists-sharedrepo' ];
-               }
-
-               return $errors;
-       }
-
        /**
         * Move a title to a new location
         *
@@ -4818,7 +4210,7 @@ class Title implements LinkTarget, IDBAccessObject {
                $dbw->onTransactionPreCommitOrIdle(
                        function () use ( $dbw ) {
                                ResourceLoaderWikiModule::invalidateModuleCache(
-                                       $this, null, null, $dbw->getDomainId() );
+                                       $this, null, null, $dbw->getDomainID() );
                        },
                        __METHOD__
                );
@@ -5017,9 +4409,7 @@ class Title implements LinkTarget, IDBAccessObject {
        public function canUseNoindex() {
                global $wgExemptFromUserRobotsControl;
 
-               $bannedNamespaces = is_null( $wgExemptFromUserRobotsControl )
-                       ? MWNamespace::getContentNamespaces()
-                       : $wgExemptFromUserRobotsControl;
+               $bannedNamespaces = $wgExemptFromUserRobotsControl ?? MWNamespace::getContentNamespaces();
 
                return !in_array( $this->mNamespace, $bannedNamespaces );
        }
index ed10615..2a03d2d 100644 (file)
@@ -382,17 +382,15 @@ class WebRequest {
         */
        private function getGPCVal( $arr, $name, $default ) {
                # PHP is so nice to not touch input data, except sometimes:
-               # https://secure.php.net/variables.external#language.variables.external.dot-in-names
+               # https://www.php.net/variables.external#language.variables.external.dot-in-names
                # Work around PHP *feature* to avoid *bugs* elsewhere.
                $name = strtr( $name, '.', '_' );
                if ( isset( $arr[$name] ) ) {
                        $data = $arr[$name];
-                       if ( isset( $_GET[$name] ) && !is_array( $data ) ) {
+                       if ( isset( $_GET[$name] ) && is_string( $data ) ) {
                                # Check for alternate/legacy character encoding.
                                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-                               if ( $contLang ) {
-                                       $data = $contLang->checkTitleEncoding( $data );
-                               }
+                               $data = $contLang->checkTitleEncoding( $data );
                        }
                        $data = $this->normalizeUnicode( $data );
                        return $data;
@@ -1309,7 +1307,7 @@ HTML;
         *
         * This means that the client is not requesting any state changes and that database writes
         * are not inherently required. Ideally, no visible updates would happen at all. If they
-        * must, then they should not be publically attributed to the end user.
+        * must, then they should not be publicly attributed to the end user.
         *
         * In more detail:
         *   - Cache populations and refreshes MAY occur.
index 34c6062..c2d08b8 100644 (file)
@@ -103,7 +103,7 @@ class WebRequestUpload {
 
        /**
         * Return the upload error. See link for explanation
-        * https://secure.php.net/manual/en/features.file-upload.errors.php
+        * https://www.php.net/manual/en/features.file-upload.errors.php
         *
         * @return int One of the UPLOAD_ constants, 0 if non-existent
         */
index 3a4faf0..45cc7df 100644 (file)
@@ -205,7 +205,7 @@ class WebResponse {
                                wfDebugLog( 'cookie', 'already set ' . $func . ': "' . implode( '", "', $data ) . '"' );
                        } else {
                                wfDebugLog( 'cookie', $func . ': "' . implode( '", "', $data ) . '"' );
-                               if ( call_user_func_array( $func, array_values( $data ) ) ) {
+                               if ( $func( ...array_values( $data ) ) ) {
                                        self::$setCookies[$key] = $deleting ? null : [ $func, $data ];
                                }
                        }
@@ -235,132 +235,3 @@ class WebResponse {
                return (bool)self::$setCookies;
        }
 }
-
-/**
- * @ingroup HTTP
- */
-class FauxResponse extends WebResponse {
-       private $headers;
-       private $cookies = [];
-       private $code;
-
-       /**
-        * Stores a HTTP header
-        * @param string $string Header to output
-        * @param bool $replace Replace current similar header
-        * @param null|int $http_response_code Forces the HTTP response code to the specified value.
-        */
-       public function header( $string, $replace = true, $http_response_code = null ) {
-               if ( substr( $string, 0, 5 ) == 'HTTP/' ) {
-                       $parts = explode( ' ', $string, 3 );
-                       $this->code = intval( $parts[1] );
-               } else {
-                       list( $key, $val ) = array_map( 'trim', explode( ":", $string, 2 ) );
-
-                       $key = strtoupper( $key );
-
-                       if ( $replace || !isset( $this->headers[$key] ) ) {
-                               $this->headers[$key] = $val;
-                       }
-               }
-
-               if ( $http_response_code !== null ) {
-                       $this->code = intval( $http_response_code );
-               }
-       }
-
-       /**
-        * @since 1.26
-        * @param int $code Status code
-        */
-       public function statusHeader( $code ) {
-               $this->code = intval( $code );
-       }
-
-       public function headersSent() {
-               return false;
-       }
-
-       /**
-        * @param string $key The name of the header to get (case insensitive).
-        * @return string|null The header value (if set); null otherwise.
-        */
-       public function getHeader( $key ) {
-               $key = strtoupper( $key );
-
-               return $this->headers[$key] ?? null;
-       }
-
-       /**
-        * Get the HTTP response code, null if not set
-        *
-        * @return int|null
-        */
-       public function getStatusCode() {
-               return $this->code;
-       }
-
-       /**
-        * @param string $name The name of the cookie.
-        * @param string $value The value to be stored in the cookie.
-        * @param int|null $expire Ignored in this faux subclass.
-        * @param array $options Ignored in this faux subclass.
-        */
-       public function setCookie( $name, $value, $expire = 0, $options = [] ) {
-               global $wgCookiePath, $wgCookiePrefix, $wgCookieDomain;
-               global $wgCookieSecure, $wgCookieExpiration, $wgCookieHttpOnly;
-
-               $options = array_filter( $options, function ( $a ) {
-                       return $a !== null;
-               } ) + [
-                       'prefix' => $wgCookiePrefix,
-                       'domain' => $wgCookieDomain,
-                       'path' => $wgCookiePath,
-                       'secure' => $wgCookieSecure,
-                       'httpOnly' => $wgCookieHttpOnly,
-                       'raw' => false,
-               ];
-
-               if ( $expire === null ) {
-                       $expire = 0; // Session cookie
-               } elseif ( $expire == 0 && $wgCookieExpiration != 0 ) {
-                       $expire = time() + $wgCookieExpiration;
-               }
-
-               $this->cookies[$options['prefix'] . $name] = [
-                       'value' => (string)$value,
-                       'expire' => (int)$expire,
-                       'path' => (string)$options['path'],
-                       'domain' => (string)$options['domain'],
-                       'secure' => (bool)$options['secure'],
-                       'httpOnly' => (bool)$options['httpOnly'],
-                       'raw' => (bool)$options['raw'],
-               ];
-       }
-
-       /**
-        * @param string $name
-        * @return string|null
-        */
-       public function getCookie( $name ) {
-               if ( isset( $this->cookies[$name] ) ) {
-                       return $this->cookies[$name]['value'];
-               }
-               return null;
-       }
-
-       /**
-        * @param string $name
-        * @return array|null
-        */
-       public function getCookieData( $name ) {
-               return $this->cookies[$name] ?? null;
-       }
-
-       /**
-        * @return array
-        */
-       public function getCookies() {
-               return $this->cookies;
-       }
-}
index 628fbc0..8b000f2 100644 (file)
@@ -245,8 +245,12 @@ class WikiMap {
        /**
         * Get the wiki ID of a database domain
         *
-        * This is like DatabaseDomain::getId() without encoding (for legacy reasons)
-        * and without the schema if it merely set to the generic value "mediawiki"
+        * This is like DatabaseDomain::getId() without encoding (for legacy reasons) and
+        * without the schema if it is the generic installer default of "mediawiki"/"dbo"
+        *
+        * @see $wgDBmwschema
+        * @see PostgresInstaller
+        * @see MssqlInstaller
         *
         * @param string|DatabaseDomain $domain
         * @return string
@@ -254,15 +258,17 @@ class WikiMap {
         */
        public static function getWikiIdFromDbDomain( $domain ) {
                $domain = DatabaseDomain::newFromId( $domain );
-
-               if ( !in_array( $domain->getSchema(), [ null, 'mediawiki' ], true ) ) {
-                       // Include the schema if it is set and is not the default placeholder.
+               // Since the schema was not always part of the wiki ID, try to maintain backwards
+               // compatibility with some common cases. Assume that if the DB domain schema is just
+               // the installer default then it is probably the case that the schema is the same for
+               // all wikis in the farm. Historically, any wiki farm had to make the database/prefix
+               // combination unique per wiki. Ommit the schema if it does not seem wiki specific.
+               if ( !in_array( $domain->getSchema(), [ null, 'mediawiki', 'dbo' ], true ) ) {
                        // This means a site admin may have specifically taylored the schemas.
-                       // Domain IDs might use the form <DB>-<project>-<language>, meaning that
-                       // the schema portion must be accounted for to disambiguate wikis.
+                       // Domain IDs might use the form <DB>-<project>- or <DB>-<project>-<language>_,
+                       // meaning that the schema portion must be accounted for to disambiguate wikis.
                        return "{$domain->getDatabase()}-{$domain->getSchema()}-{$domain->getTablePrefix()}";
                }
-
                // Note that if this wiki ID is passed a a domain ID to LoadBalancer, then it can
                // handle the schema by assuming the generic "mediawiki" schema if needed.
                return strlen( $domain->getTablePrefix() )
@@ -291,30 +297,16 @@ class WikiMap {
 
        /**
         * @param DatabaseDomain|string $domain
-        * @return bool Whether $domain has the same DB/prefix as the current wiki
+        * @return bool Whether $domain matches the DB domain of the current wiki
         * @since 1.33
         */
        public static function isCurrentWikiDbDomain( $domain ) {
-               $domain = DatabaseDomain::newFromId( $domain );
-               $curDomain = self::getCurrentWikiDbDomain();
-
-               if ( !in_array( $curDomain->getSchema(), [ null, 'mediawiki' ], true ) ) {
-                       // Include the schema if it is set and is not the default placeholder.
-                       // This means a site admin may have specifically taylored the schemas.
-                       // Domain IDs might use the form <DB>-<project>-<language>, meaning that
-                       // the schema portion must be accounted for to disambiguate wikis.
-                       return $curDomain->equals( $domain );
-               }
-
-               return (
-                       $curDomain->getDatabase() === $domain->getDatabase() &&
-                       $curDomain->getTablePrefix() === $domain->getTablePrefix()
-               );
+               return self::getCurrentWikiDbDomain()->equals( DatabaseDomain::newFromId( $domain ) );
        }
 
        /**
         * @param string $wikiId
-        * @return bool Whether $wikiId has the same DB/prefix as the current wiki
+        * @return bool Whether $wikiId matches the wiki ID of the current wiki
         * @since 1.33
         */
        public static function isCurrentWikiId( $wikiId ) {
index d1a56bf..febf03e 100644 (file)
@@ -47,12 +47,10 @@ class Xml {
                }
                if ( is_null( $contents ) ) {
                        $out .= '>';
+               } elseif ( $allowShortTag && $contents === '' ) {
+                       $out .= ' />';
                } else {
-                       if ( $allowShortTag && $contents === '' ) {
-                               $out .= ' />';
-                       } else {
-                               $out .= '>' . htmlspecialchars( $contents, ENT_NOQUOTES ) . "</$element>";
-                       }
+                       $out .= '>' . htmlspecialchars( $contents, ENT_NOQUOTES ) . "</$element>";
                }
                return $out;
        }
index ed58686..4cb7dda 100644 (file)
@@ -222,12 +222,10 @@ class CreditsAction extends FormlessAction {
                $link = $this->link( $user );
                if ( $user->isAnon() ) {
                        return $this->msg( 'anonuser' )->rawParams( $link )->parse();
+               } elseif ( $this->canShowRealUserName() && $user->getRealName() ) {
+                       return $link;
                } else {
-                       if ( $this->canShowRealUserName() && $user->getRealName() ) {
-                               return $link;
-                       } else {
-                               return $this->msg( 'siteuser' )->rawParams( $link )->params( $user->getName() )->escaped();
-                       }
+                       return $this->msg( 'siteuser' )->rawParams( $link )->params( $user->getName() )->escaped();
                }
        }
 
index 39bc830..bc1d351 100644 (file)
@@ -2,8 +2,6 @@
 /**
  * Page history
  *
- * Split off from Article.php and Skin.php, 2003-12-22
- *
  * 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
@@ -80,7 +78,7 @@ class HistoryAction extends FormlessAction {
                                        ->rawParams( $this->getLanguage()->pipeList( $links ) )
                                        ->escaped();
                }
-               return $subtitle;
+               return Html::rawElement( 'div', [ 'class' => 'mw-history-subtitle' ], $subtitle );
        }
 
        /**
@@ -104,6 +102,43 @@ class HistoryAction extends FormlessAction {
                }
        }
 
+       /**
+        * @param WebRequest $request
+        * @return string
+        */
+       private function getTimestampFromRequest( WebRequest $request ) {
+               // Backwards compatibility checks for URIs with only year and/or month.
+               $year = $request->getInt( 'year' );
+               $month = $request->getInt( 'month' );
+               $day = null;
+               if ( $year !== 0 || $month !== 0 ) {
+                       if ( $year === 0 ) {
+                               $year = MWTimestamp::getLocalInstance()->format( 'Y' );
+                       }
+                       if ( $month < 1 || $month > 12 ) {
+                               // month is invalid so treat as December (all months)
+                               $month = 12;
+                       }
+                       // month is valid so check day
+                       $day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
+
+                       // Left pad the months and days
+                       $month = str_pad( $month, 2, "0", STR_PAD_LEFT );
+                       $day = str_pad( $day, 2, "0", STR_PAD_LEFT );
+               }
+
+               $before = $request->getVal( 'date-range-to' );
+               if ( $before ) {
+                       $parts = explode( '-', $before );
+                       $year = $parts[0];
+                       // check date input is valid
+                       if ( count( $parts ) === 3 ) {
+                               $month = $parts[1];
+                               $day = $parts[2];
+                       }
+               }
+               return $year && $month && $day ? $year . '-' . $month . '-' . $day : '';
+       }
        /**
         * Print the history page for an article.
         */
@@ -181,13 +216,8 @@ class HistoryAction extends FormlessAction {
                        return;
                }
 
-               /**
-                * Add date selector to quickly get to a certain time
-                */
-               $year = $request->getInt( 'year' );
-               $month = $request->getInt( 'month' );
+               $ts = $this->getTimestampFromRequest( $request );
                $tagFilter = $request->getVal( 'tagfilter' );
-               $tagSelector = ChangeTags::buildTagFilterSelector( $tagFilter, false, $this->getContext() );
 
                /**
                 * Option to show only revisions that have been (partially) hidden via RevisionDelete
@@ -197,41 +227,70 @@ class HistoryAction extends FormlessAction {
                } else {
                        $conds = [];
                }
-               if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
-                       $checkDeleted = Xml::checkLabel( $this->msg( 'history-show-deleted' )->text(),
-                               'deleted', 'mw-show-deleted-only', $request->getBool( 'deleted' ) ) . "\n";
-               } else {
-                       $checkDeleted = '';
-               }
 
-               // Add the general form
-               $action = htmlspecialchars( wfScript() );
-               $content = Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n";
-               $content .= Html::hidden( 'action', 'history' ) . "\n";
-               $content .= Xml::dateMenu(
-                       ( $year == null ? MWTimestamp::getLocalInstance()->format( 'Y' ) : $year ),
-                       $month
-               ) . "\u{00A0}";
-               $content .= $tagSelector ? ( implode( "\u{00A0}", $tagSelector ) . "\u{00A0}" ) : '';
-               $content .= $checkDeleted . Html::submitButton(
-                       $this->msg( 'historyaction-submit' )->text(),
-                       [],
-                       [ 'mw-ui-progressive' ]
-               );
-               $out->addHTML(
-                       "<form action=\"$action\" method=\"get\" id=\"mw-history-searchform\">" .
-                       Xml::fieldset(
-                               $this->msg( 'history-fieldset-title' )->text(),
-                               $content,
-                               [ 'id' => 'mw-history-search' ]
-                       ) .
-                       '</form>'
-               );
+               // Add the general form.
+               $fields = [
+                       [
+                               'name' => 'title',
+                               'type' => 'hidden',
+                               'default' => $this->getTitle()->getPrefixedDBkey(),
+                       ],
+                       [
+                               'name' => 'action',
+                               'type' => 'hidden',
+                               'default' => 'history',
+                       ],
+                       [
+                               'type' => 'date',
+                               'default' => $ts,
+                               'label' => $this->msg( 'date-range-to' )->text(),
+                               'name' => 'date-range-to',
+                       ],
+                       [
+                               'label-raw' => $this->msg( 'tag-filter' )->parse(),
+                               'type' => 'tagfilter',
+                               'id' => 'tagfilter',
+                               'name' => 'tagfilter',
+                               'value' => $tagFilter,
+                       ]
+               ];
+               if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
+                       $fields[] = [
+                               'type' => 'check',
+                               'label' => $this->msg( 'history-show-deleted' )->text(),
+                               'default' => $request->getBool( 'deleted' ),
+                               'name' => 'deleted',
+                       ];
+               }
+
+               $out->enableOOUI();
+               $htmlForm = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
+               $htmlForm
+                       ->setMethod( 'get' )
+                       ->setAction( wfScript() )
+                       ->setCollapsible( true )
+                       ->setId( 'mw-history-searchform' )
+                       ->setSubmitText( $this->msg( 'historyaction-submit' )->text() )
+                       ->setWrapperAttributes( [ 'id' => 'mw-history-search' ] )
+                       ->setWrapperLegend( $this->msg( 'history-fieldset-title' )->text() );
+               $htmlForm->loadData();
+
+               $out->addHTML( $htmlForm->getHTML( false ) );
 
                Hooks::run( 'PageHistoryBeforeList', [ &$this->page, $this->getContext() ] );
 
                // Create and output the list.
-               $pager = new HistoryPager( $this, $year, $month, $tagFilter, $conds );
+               $dateComponents = explode( '-', $ts );
+               if ( count( $dateComponents ) > 1 ) {
+                       $y = $dateComponents[0];
+                       $m = $dateComponents[1];
+                       $d = $dateComponents[2];
+               } else {
+                       $y = '';
+                       $m = '';
+                       $d = '';
+               }
+               $pager = new HistoryPager( $this, $y, $m, $tagFilter, $conds, $d );
                $out->addHTML(
                        $pager->getNavigationBar() .
                        $pager->getBody() .
@@ -382,607 +441,3 @@ class HistoryAction extends FormlessAction {
                );
        }
 }
-
-/**
- * @ingroup Pager
- * @ingroup Actions
- */
-class HistoryPager extends ReverseChronologicalPager {
-       /**
-        * @var bool|stdClass
-        */
-       public $lastRow = false;
-
-       public $counter, $historyPage, $buttons, $conds;
-
-       protected $oldIdChecked;
-
-       protected $preventClickjacking = false;
-       /**
-        * @var array
-        */
-       protected $parentLens;
-
-       /** @var bool Whether to show the tag editing UI */
-       protected $showTagEditUI;
-
-       /** @var string */
-       private $tagFilter;
-
-       /**
-        * @param HistoryAction $historyPage
-        * @param string $year
-        * @param string $month
-        * @param string $tagFilter
-        * @param array $conds
-        */
-       public function __construct(
-               HistoryAction $historyPage,
-               $year = '',
-               $month = '',
-               $tagFilter = '',
-               array $conds = []
-       ) {
-               parent::__construct( $historyPage->getContext() );
-               $this->historyPage = $historyPage;
-               $this->tagFilter = $tagFilter;
-               $this->getDateCond( $year, $month );
-               $this->conds = $conds;
-               $this->showTagEditUI = ChangeTags::showTagEditingUI( $this->getUser() );
-       }
-
-       // For hook compatibility...
-       function getArticle() {
-               return $this->historyPage->getArticle();
-       }
-
-       function getSqlComment() {
-               if ( $this->conds ) {
-                       return 'history page filtered'; // potentially slow, see CR r58153
-               } else {
-                       return 'history page unfiltered';
-               }
-       }
-
-       function getQueryInfo() {
-               $revQuery = Revision::getQueryInfo( [ 'user' ] );
-               $queryInfo = [
-                       'tables' => $revQuery['tables'],
-                       'fields' => $revQuery['fields'],
-                       'conds' => array_merge(
-                               [ 'rev_page' => $this->getWikiPage()->getId() ],
-                               $this->conds ),
-                       'options' => [ 'USE INDEX' => [ 'revision' => 'page_timestamp' ] ],
-                       'join_conds' => $revQuery['joins'],
-               ];
-               ChangeTags::modifyDisplayQuery(
-                       $queryInfo['tables'],
-                       $queryInfo['fields'],
-                       $queryInfo['conds'],
-                       $queryInfo['join_conds'],
-                       $queryInfo['options'],
-                       $this->tagFilter
-               );
-
-               // Avoid PHP 7.1 warning of passing $this by reference
-               $historyPager = $this;
-               Hooks::run( 'PageHistoryPager::getQueryInfo', [ &$historyPager, &$queryInfo ] );
-
-               return $queryInfo;
-       }
-
-       function getIndexField() {
-               return 'rev_timestamp';
-       }
-
-       /**
-        * @param stdClass $row
-        * @return string
-        */
-       function formatRow( $row ) {
-               if ( $this->lastRow ) {
-                       $latest = ( $this->counter == 1 && $this->mIsFirst );
-                       $firstInList = $this->counter == 1;
-                       $this->counter++;
-
-                       $notifTimestamp = $this->getConfig()->get( 'ShowUpdatedMarker' )
-                               ? $this->getTitle()->getNotificationTimestamp( $this->getUser() )
-                               : false;
-
-                       $s = $this->historyLine(
-                               $this->lastRow, $row, $notifTimestamp, $latest, $firstInList );
-               } else {
-                       $s = '';
-               }
-               $this->lastRow = $row;
-
-               return $s;
-       }
-
-       protected function doBatchLookups() {
-               if ( !Hooks::run( 'PageHistoryPager::doBatchLookups', [ $this, $this->mResult ] ) ) {
-                       return;
-               }
-
-               # Do a link batch query
-               $this->mResult->seek( 0 );
-               $batch = new LinkBatch();
-               $revIds = [];
-               foreach ( $this->mResult as $row ) {
-                       if ( $row->rev_parent_id ) {
-                               $revIds[] = $row->rev_parent_id;
-                       }
-                       if ( $row->user_name !== null ) {
-                               $batch->add( NS_USER, $row->user_name );
-                               $batch->add( NS_USER_TALK, $row->user_name );
-                       } else { # for anons or usernames of imported revisions
-                               $batch->add( NS_USER, $row->rev_user_text );
-                               $batch->add( NS_USER_TALK, $row->rev_user_text );
-                       }
-               }
-               $this->parentLens = Revision::getParentLengths( $this->mDb, $revIds );
-               $batch->execute();
-               $this->mResult->seek( 0 );
-       }
-
-       /**
-        * Creates begin of history list with a submit button
-        *
-        * @return string HTML output
-        */
-       protected function getStartBody() {
-               $this->lastRow = false;
-               $this->counter = 1;
-               $this->oldIdChecked = 0;
-
-               $this->getOutput()->wrapWikiMsg( "<div class='mw-history-legend'>\n$1\n</div>", 'histlegend' );
-               $s = Html::openElement( 'form', [ 'action' => wfScript(),
-                       'id' => 'mw-history-compare' ] ) . "\n";
-               $s .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n";
-               $s .= Html::hidden( 'action', 'historysubmit' ) . "\n";
-               $s .= Html::hidden( 'type', 'revision' ) . "\n";
-
-               // Button container stored in $this->buttons for re-use in getEndBody()
-               $this->buttons = '<div>';
-               $className = 'historysubmit mw-history-compareselectedversions-button';
-               $attrs = [ 'class' => $className ]
-                       + Linker::tooltipAndAccesskeyAttribs( 'compareselectedversions' );
-               $this->buttons .= $this->submitButton( $this->msg( 'compareselectedversions' )->text(),
-                       $attrs
-               ) . "\n";
-
-               $user = $this->getUser();
-               $actionButtons = '';
-               if ( $user->isAllowed( 'deleterevision' ) ) {
-                       $actionButtons .= $this->getRevisionButton( 'revisiondelete', 'showhideselectedversions' );
-               }
-               if ( $this->showTagEditUI ) {
-                       $actionButtons .= $this->getRevisionButton( 'editchangetags', 'history-edit-tags' );
-               }
-               if ( $actionButtons ) {
-                       $this->buttons .= Xml::tags( 'div', [ 'class' =>
-                               'mw-history-revisionactions' ], $actionButtons );
-               }
-
-               if ( $user->isAllowed( 'deleterevision' ) || $this->showTagEditUI ) {
-                       $this->buttons .= ( new ListToggle( $this->getOutput() ) )->getHTML();
-               }
-
-               $this->buttons .= '</div>';
-
-               $s .= $this->buttons;
-               $s .= '<ul id="pagehistory">' . "\n";
-
-               return $s;
-       }
-
-       private function getRevisionButton( $name, $msg ) {
-               $this->preventClickjacking();
-               # Note T22966, <button> is non-standard in IE<8
-               $element = Html::element(
-                       'button',
-                       [
-                               'type' => 'submit',
-                               'name' => $name,
-                               'value' => '1',
-                               'class' => "historysubmit mw-history-$name-button",
-                       ],
-                       $this->msg( $msg )->text()
-               ) . "\n";
-               return $element;
-       }
-
-       protected function getEndBody() {
-               if ( $this->lastRow ) {
-                       $latest = $this->counter == 1 && $this->mIsFirst;
-                       $firstInList = $this->counter == 1;
-                       if ( $this->mIsBackwards ) {
-                               # Next row is unknown, but for UI reasons, probably exists if an offset has been specified
-                               if ( $this->mOffset == '' ) {
-                                       $next = null;
-                               } else {
-                                       $next = 'unknown';
-                               }
-                       } else {
-                               # The next row is the past-the-end row
-                               $next = $this->mPastTheEndRow;
-                       }
-                       $this->counter++;
-
-                       $notifTimestamp = $this->getConfig()->get( 'ShowUpdatedMarker' )
-                               ? $this->getTitle()->getNotificationTimestamp( $this->getUser() )
-                               : false;
-
-                       $s = $this->historyLine(
-                               $this->lastRow, $next, $notifTimestamp, $latest, $firstInList );
-               } else {
-                       $s = '';
-               }
-               $s .= "</ul>\n";
-               # Add second buttons only if there is more than one rev
-               if ( $this->getNumRows() > 2 ) {
-                       $s .= $this->buttons;
-               }
-               $s .= '</form>';
-
-               return $s;
-       }
-
-       /**
-        * Creates a submit button
-        *
-        * @param string $message Text of the submit button, will be escaped
-        * @param array $attributes
-        * @return string HTML output for the submit button
-        */
-       function submitButton( $message, $attributes = [] ) {
-               # Disable submit button if history has 1 revision only
-               if ( $this->getNumRows() > 1 ) {
-                       return Html::submitButton( $message, $attributes );
-               } else {
-                       return '';
-               }
-       }
-
-       /**
-        * Returns a row from the history printout.
-        *
-        * @todo document some more, and maybe clean up the code (some params redundant?)
-        *
-        * @param stdClass $row The database row corresponding to the previous line.
-        * @param mixed $next The database row corresponding to the next line
-        *   (chronologically previous)
-        * @param bool|string $notificationtimestamp
-        * @param bool $latest Whether this row corresponds to the page's latest revision.
-        * @param bool $firstInList Whether this row corresponds to the first
-        *   displayed on this history page.
-        * @return string HTML output for the row
-        */
-       function historyLine( $row, $next, $notificationtimestamp = false,
-               $latest = false, $firstInList = false ) {
-               $rev = new Revision( $row, 0, $this->getTitle() );
-
-               if ( is_object( $next ) ) {
-                       $prevRev = new Revision( $next, 0, $this->getTitle() );
-               } else {
-                       $prevRev = null;
-               }
-
-               $curlink = $this->curLink( $rev, $latest );
-               $lastlink = $this->lastLink( $rev, $next );
-               $curLastlinks = $curlink . $this->historyPage->message['pipe-separator'] . $lastlink;
-               $histLinks = Html::rawElement(
-                       'span',
-                       [ 'class' => 'mw-history-histlinks' ],
-                       $this->msg( 'parentheses' )->rawParams( $curLastlinks )->escaped()
-               );
-
-               $diffButtons = $this->diffButtons( $rev, $firstInList );
-               $s = $histLinks . $diffButtons;
-
-               $link = $this->revLink( $rev );
-               $classes = [];
-
-               $del = '';
-               $user = $this->getUser();
-               $canRevDelete = $user->isAllowed( 'deleterevision' );
-               // Show checkboxes for each revision, to allow for revision deletion and
-               // change tags
-               if ( $canRevDelete || $this->showTagEditUI ) {
-                       $this->preventClickjacking();
-                       // If revision was hidden from sysops and we don't need the checkbox
-                       // for anything else, disable it
-                       if ( !$this->showTagEditUI && !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
-                               $del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
-                       // Otherwise, enable the checkbox...
-                       } else {
-                               $del = Xml::check( 'showhiderevisions', false,
-                                       [ 'name' => 'ids[' . $rev->getId() . ']' ] );
-                       }
-               // User can only view deleted revisions...
-               } elseif ( $rev->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) {
-                       // If revision was hidden from sysops, disable the link
-                       if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
-                               $del = Linker::revDeleteLinkDisabled( false );
-                       // Otherwise, show the link...
-                       } else {
-                               $query = [ 'type' => 'revision',
-                                       'target' => $this->getTitle()->getPrefixedDBkey(), 'ids' => $rev->getId() ];
-                               $del .= Linker::revDeleteLink( $query,
-                                       $rev->isDeleted( Revision::DELETED_RESTRICTED ), false );
-                       }
-               }
-               if ( $del ) {
-                       $s .= " $del ";
-               }
-
-               $lang = $this->getLanguage();
-               $dirmark = $lang->getDirMark();
-
-               $s .= " $link";
-               $s .= $dirmark;
-               $s .= " <span class='history-user'>" .
-                       Linker::revUserTools( $rev, true ) . "</span>";
-               $s .= $dirmark;
-
-               if ( $rev->isMinor() ) {
-                       $s .= ' ' . ChangesList::flag( 'minor', $this->getContext() );
-               }
-
-               # Sometimes rev_len isn't populated
-               if ( $rev->getSize() !== null ) {
-                       # Size is always public data
-                       $prevSize = $this->parentLens[$row->rev_parent_id] ?? 0;
-                       $sDiff = ChangesList::showCharacterDifference( $prevSize, $rev->getSize() );
-                       $fSize = Linker::formatRevisionSize( $rev->getSize() );
-                       $s .= ' <span class="mw-changeslist-separator">. .</span> ' . "$fSize $sDiff";
-               }
-
-               # Text following the character difference is added just before running hooks
-               $s2 = Linker::revComment( $rev, false, true );
-
-               if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
-                       $s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>';
-                       $classes[] = 'mw-history-line-updated';
-               }
-
-               $tools = [];
-
-               # Rollback and undo links
-               if ( $prevRev && $this->getTitle()->quickUserCan( 'edit', $user ) ) {
-                       if ( $latest && $this->getTitle()->quickUserCan( 'rollback', $user ) ) {
-                               // Get a rollback link without the brackets
-                               $rollbackLink = Linker::generateRollback(
-                                       $rev,
-                                       $this->getContext(),
-                                       [ 'verify', 'noBrackets' ]
-                               );
-                               if ( $rollbackLink ) {
-                                       $this->preventClickjacking();
-                                       $tools[] = $rollbackLink;
-                               }
-                       }
-
-                       if ( !$rev->isDeleted( Revision::DELETED_TEXT )
-                               && !$prevRev->isDeleted( Revision::DELETED_TEXT )
-                       ) {
-                               # Create undo tooltip for the first (=latest) line only
-                               $undoTooltip = $latest
-                                       ? [ 'title' => $this->msg( 'tooltip-undo' )->text() ]
-                                       : [];
-                               $undolink = MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
-                                       $this->getTitle(),
-                                       $this->msg( 'editundo' )->text(),
-                                       $undoTooltip,
-                                       [
-                                               'action' => 'edit',
-                                               'undoafter' => $prevRev->getId(),
-                                               'undo' => $rev->getId()
-                                       ]
-                               );
-                               $tools[] = "<span class=\"mw-history-undo\">{$undolink}</span>";
-                       }
-               }
-               // Allow extension to add their own links here
-               Hooks::run( 'HistoryRevisionTools', [ $rev, &$tools, $prevRev, $user ] );
-
-               if ( $tools ) {
-                       $s2 .= ' ' . $this->msg( 'parentheses' )->rawParams( $lang->pipeList( $tools ) )->escaped();
-               }
-
-               # Tags
-               list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow(
-                       $row->ts_tags,
-                       'history',
-                       $this->getContext()
-               );
-               $classes = array_merge( $classes, $newClasses );
-               if ( $tagSummary !== '' ) {
-                       $s2 .= " $tagSummary";
-               }
-
-               # Include separator between character difference and following text
-               if ( $s2 !== '' ) {
-                       $s .= ' <span class="mw-changeslist-separator">. .</span> ' . $s2;
-               }
-
-               $attribs = [ 'data-mw-revid' => $rev->getId() ];
-
-               Hooks::run( 'PageHistoryLineEnding', [ $this, &$row, &$s, &$classes, &$attribs ] );
-               $attribs = array_filter( $attribs,
-                       [ Sanitizer::class, 'isReservedDataAttribute' ],
-                       ARRAY_FILTER_USE_KEY
-               );
-
-               if ( $classes ) {
-                       $attribs['class'] = implode( ' ', $classes );
-               }
-
-               return Xml::tags( 'li', $attribs, $s ) . "\n";
-       }
-
-       /**
-        * Create a link to view this revision of the page
-        *
-        * @param Revision $rev
-        * @return string
-        */
-       function revLink( $rev ) {
-               $date = $this->getLanguage()->userTimeAndDate( $rev->getTimestamp(), $this->getUser() );
-               if ( $rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
-                       $link = MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
-                               $this->getTitle(),
-                               $date,
-                               [ 'class' => 'mw-changeslist-date' ],
-                               [ 'oldid' => $rev->getId() ]
-                       );
-               } else {
-                       $link = htmlspecialchars( $date );
-               }
-               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
-                       $link = "<span class=\"history-deleted\">$link</span>";
-               }
-
-               return $link;
-       }
-
-       /**
-        * Create a diff-to-current link for this revision for this page
-        *
-        * @param Revision $rev
-        * @param bool $latest This is the latest revision of the page?
-        * @return string
-        */
-       function curLink( $rev, $latest ) {
-               $cur = $this->historyPage->message['cur'];
-               if ( $latest || !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
-                       return $cur;
-               } else {
-                       return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
-                               $this->getTitle(),
-                               new HtmlArmor( $cur ),
-                               [],
-                               [
-                                       'diff' => $this->getWikiPage()->getLatest(),
-                                       'oldid' => $rev->getId()
-                               ]
-                       );
-               }
-       }
-
-       /**
-        * Create a diff-to-previous link for this revision for this page.
-        *
-        * @param Revision $prevRev The revision being displayed
-        * @param stdClass|string|null $next The next revision in list (that is
-        *        the previous one in chronological order).
-        *        May either be a row, "unknown" or null.
-        * @return string
-        */
-       function lastLink( $prevRev, $next ) {
-               $last = $this->historyPage->message['last'];
-
-               if ( $next === null ) {
-                       # Probably no next row
-                       return $last;
-               }
-
-               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
-               if ( $next === 'unknown' ) {
-                       # Next row probably exists but is unknown, use an oldid=prev link
-                       return $linkRenderer->makeKnownLink(
-                               $this->getTitle(),
-                               new HtmlArmor( $last ),
-                               [],
-                               [
-                                       'diff' => $prevRev->getId(),
-                                       'oldid' => 'prev'
-                               ]
-                       );
-               }
-
-               $nextRev = new Revision( $next );
-
-               if ( !$prevRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
-                       || !$nextRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
-               ) {
-                       return $last;
-               }
-
-               return $linkRenderer->makeKnownLink(
-                       $this->getTitle(),
-                       new HtmlArmor( $last ),
-                       [],
-                       [
-                               'diff' => $prevRev->getId(),
-                               'oldid' => $next->rev_id
-                       ]
-               );
-       }
-
-       /**
-        * Create radio buttons for page history
-        *
-        * @param Revision $rev
-        * @param bool $firstInList Is this version the first one?
-        *
-        * @return string HTML output for the radio buttons
-        */
-       function diffButtons( $rev, $firstInList ) {
-               if ( $this->getNumRows() > 1 ) {
-                       $id = $rev->getId();
-                       $radio = [ 'type' => 'radio', 'value' => $id ];
-                       /** @todo Move title texts to javascript */
-                       if ( $firstInList ) {
-                               $first = Xml::element( 'input',
-                                       array_merge( $radio, [
-                                               'style' => 'visibility:hidden',
-                                               'name' => 'oldid',
-                                               'id' => 'mw-oldid-null' ] )
-                               );
-                               $checkmark = [ 'checked' => 'checked' ];
-                       } else {
-                               # Check visibility of old revisions
-                               if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
-                                       $radio['disabled'] = 'disabled';
-                                       $checkmark = []; // We will check the next possible one
-                               } elseif ( !$this->oldIdChecked ) {
-                                       $checkmark = [ 'checked' => 'checked' ];
-                                       $this->oldIdChecked = $id;
-                               } else {
-                                       $checkmark = [];
-                               }
-                               $first = Xml::element( 'input',
-                                       array_merge( $radio, $checkmark, [
-                                               'name' => 'oldid',
-                                               'id' => "mw-oldid-$id" ] ) );
-                               $checkmark = [];
-                       }
-                       $second = Xml::element( 'input',
-                               array_merge( $radio, $checkmark, [
-                                       'name' => 'diff',
-                                       'id' => "mw-diff-$id" ] ) );
-
-                       return $first . $second;
-               } else {
-                       return '';
-               }
-       }
-
-       /**
-        * This is called if a write operation is possible from the generated HTML
-        * @param bool $enable
-        */
-       function preventClickjacking( $enable = true ) {
-               $this->preventClickjacking = $enable;
-       }
-
-       /**
-        * Get the "prevent clickjacking" flag
-        * @return bool
-        */
-       function getPreventClickjacking() {
-               return $this->preventClickjacking;
-       }
-
-}
index 47bbdc0..e9de846 100644 (file)
@@ -30,7 +30,7 @@ class McrUndoAction extends FormAction {
 
        protected $undo = 0, $undoafter = 0, $cur = 0;
 
-       /** @param RevisionRecord|null */
+       /** @var RevisionRecord|null */
        protected $curRev = null;
 
        public function getName() {
@@ -298,7 +298,7 @@ class McrUndoAction extends FormAction {
                        'class' => 'mw-content-' . $pageViewLang->getDir() ];
                $previewHTML = Html::rawElement( 'div', $attribs, $previewHTML );
 
-               $out->addHtml( $previewhead . $previewHTML );
+               $out->addHTML( $previewhead . $previewHTML );
        }
 
        public function onSubmit( $data ) {
index 73594bc..c9d0ae9 100644 (file)
@@ -116,10 +116,10 @@ class RawAction extends FormlessAction {
                                $elevatedText = $elevated ? 'by elevated ' : '';
                                $log = LoggerFactory::getInstance( "security" );
                                $log->warning(
-                                       "Unsafe JS/CSS/Json $elevatedText" . "load - {user} loaded {title} with {ctype}",
+                                       "Unsafe JS/CSS/Json {$elevatedText}load - {user} loaded {title} with {ctype}",
                                        [
                                                'user' => $this->getUser()->getName(),
-                                               'title' => $title->getPrefixedDBKey(),
+                                               'title' => $title->getPrefixedDBkey(),
                                                'ctype' => $contentType,
                                                'elevated' => $elevated
                                        ]
@@ -147,7 +147,7 @@ class RawAction extends FormlessAction {
                        $log->info( "Blocked loading unprotected JS {title} for {user}",
                                [
                                        'user' => $this->getUser()->getName(),
-                                       'title' => $title->getPrefixedDBKey(),
+                                       'title' => $title->getPrefixedDBkey(),
                                ]
                        );
                        throw new HttpError( 403, wfMessage( 'unprotected-js' ) );
index 68a0325..8a5d7c9 100644 (file)
@@ -136,7 +136,10 @@ class RevertAction extends FormAction {
                        0,
                        false,
                        false,
-                       $this->getUser()
+                       $this->getUser(),
+                       [],
+                       true,
+                       true
                );
        }
 
index 03a5bc8..e2fc265 100644 (file)
@@ -25,7 +25,7 @@
  *
  * @ingroup Actions
  */
-class RollbackAction extends FormlessAction {
+class RollbackAction extends FormAction {
 
        public function getName() {
                return 'rollback';
@@ -35,21 +35,59 @@ class RollbackAction extends FormlessAction {
                return 'rollback';
        }
 
-       /**
-        * Temporarily unused message keys due to T88044/T136375:
-        * - confirm-rollback-top
-        * - confirm-rollback-button
-        * - rollbackfailed
-        * - rollback-missingparam
-        * - rollback-success-notify
-        */
+       protected function usesOOUI() {
+               return true;
+       }
+
+       protected function getDescription() {
+               return '';
+       }
+
+       public function doesWrites() {
+               return true;
+       }
+
+       public function onSuccess() {
+               return false;
+       }
+
+       public function onSubmit( $data ) {
+               return false;
+       }
+
+       protected function alterForm( HTMLForm $form ) {
+               $form->setWrapperLegendMsg( 'confirm-rollback-top' );
+               $form->setSubmitTextMsg( 'confirm-rollback-button' );
+               $form->setTokenSalt( 'rollback' );
+
+               $from = $this->getRequest()->getVal( 'from' );
+               if ( $from === null ) {
+                       throw new BadRequestError( 'rollbackfailed', 'rollback-missingparam' );
+               }
+               foreach ( [ 'from', 'bot', 'hidediff', 'summary', 'token' ] as $param ) {
+                       $val = $this->getRequest()->getVal( $param );
+                       if ( $val !== null ) {
+                               $form->addHiddenField( $param, $val );
+                       }
+               }
+       }
 
        /**
         * @throws ErrorPageError
+        * @throws ReadOnlyError
+        * @throws ThrottledError
         */
-       public function onView() {
-               // TODO: use $this->useTransactionalTimeLimit(); when POST only
-               wfTransactionalTimeLimit();
+       public function show() {
+               if ( $this->getUser()->getOption( 'showrollbackconfirmation' ) == false ||
+                        $this->getRequest()->wasPosted() ) {
+                       $this->handleRollbackRequest();
+               } else {
+                       $this->showRollbackConfirmationForm();
+               }
+       }
+
+       public function handleRollbackRequest() {
+               $this->enableTransactionalTimelimit();
 
                $request = $this->getRequest();
                $user = $this->getUser();
@@ -69,15 +107,6 @@ class RollbackAction extends FormlessAction {
                        ] );
                }
 
-               // @TODO: remove this hack once rollback uses POST (T88044)
-               $fname = __METHOD__;
-               $trxLimits = $this->context->getConfig()->get( 'TrxProfilerLimits' );
-               $trxProfiler = Profiler::instance()->getTransactionProfiler();
-               $trxProfiler->redefineExpectations( $trxLimits['POST'], $fname );
-               DeferredUpdates::addCallableUpdate( function () use ( $trxProfiler, $trxLimits, $fname ) {
-                       $trxProfiler->redefineExpectations( $trxLimits['PostSend-POST'], $fname );
-               } );
-
                $data = null;
                $errors = $this->page->doRollback(
                        $from,
@@ -92,9 +121,7 @@ class RollbackAction extends FormlessAction {
                        throw new ThrottledError;
                }
 
-               if ( isset( $errors[0][0] ) &&
-                       ( $errors[0][0] == 'alreadyrolled' || $errors[0][0] == 'cantrollback' )
-               ) {
+               if ( $this->hasRollbackRelatedErrors( $errors ) ) {
                        $this->getOutput()->setPageTitle( $this->msg( 'rollbackfailed' ) );
                        $errArray = $errors[0];
                        $errMsg = array_shift( $errArray );
@@ -166,11 +193,51 @@ class RollbackAction extends FormlessAction {
                }
        }
 
-       protected function getDescription() {
-               return '';
+       /**
+        * Enables transactional time limit for POST and GET requests to RollbackAction
+        * @throws ConfigException
+        */
+       private function enableTransactionalTimelimit() {
+               // If Rollbacks are made POST-only, use $this->useTransactionalTimeLimit()
+               wfTransactionalTimeLimit();
+               if ( !$this->getRequest()->wasPosted() ) {
+                       /**
+                        * We apply the higher POST limits on GET requests
+                        * to prevent logstash.wikimedia.org from being spammed
+                        */
+                       $fname = __METHOD__;
+                       $trxLimits = $this->context->getConfig()->get( 'TrxProfilerLimits' );
+                       $trxProfiler = Profiler::instance()->getTransactionProfiler();
+                       $trxProfiler->redefineExpectations( $trxLimits['POST'], $fname );
+                       DeferredUpdates::addCallableUpdate( function () use ( $trxProfiler, $trxLimits, $fname
+                       ) {
+                               $trxProfiler->redefineExpectations( $trxLimits['PostSend-POST'], $fname );
+                       } );
+               }
        }
 
-       public function doesWrites() {
-               return true;
+       private function showRollbackConfirmationForm() {
+               $form = $this->getForm();
+               if ( $form->show() ) {
+                       $this->onSuccess();
+               }
+       }
+
+       protected function getFormFields() {
+               return [
+                       'intro' => [
+                               'type' => 'info',
+                               'vertical-label' => true,
+                               'raw' => true,
+                               'default' => $this->msg( 'confirm-rollback-bottom' )->parse()
+                       ]
+               ];
+       }
+
+       private function hasRollbackRelatedErrors( array $errors ) {
+               return isset( $errors[0][0] ) &&
+                       ( $errors[0][0] == 'alreadyrolled' ||
+                               $errors[0][0] == 'cantrollback'
+                       );
        }
 }
diff --git a/includes/actions/pagers/HistoryPager.php b/includes/actions/pagers/HistoryPager.php
new file mode 100644 (file)
index 0000000..c9c1b51
--- /dev/null
@@ -0,0 +1,630 @@
+<?php
+/**
+ * Page history pager
+ *
+ * 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 Actions
+ */
+
+use MediaWiki\MediaWikiServices;
+
+/**
+ * @ingroup Pager
+ * @ingroup Actions
+ */
+class HistoryPager extends ReverseChronologicalPager {
+       /**
+        * @var bool|stdClass
+        */
+       public $lastRow = false;
+
+       public $counter, $historyPage, $buttons, $conds;
+
+       protected $oldIdChecked;
+
+       protected $preventClickjacking = false;
+       /**
+        * @var array
+        */
+       protected $parentLens;
+
+       /** @var bool Whether to show the tag editing UI */
+       protected $showTagEditUI;
+
+       /** @var string */
+       private $tagFilter;
+
+       /**
+        * @param HistoryAction $historyPage
+        * @param string $year
+        * @param string $month
+        * @param string $tagFilter
+        * @param array $conds
+        * @param string $day
+        */
+       public function __construct(
+               HistoryAction $historyPage,
+               $year = '',
+               $month = '',
+               $tagFilter = '',
+               array $conds = [],
+               $day = ''
+       ) {
+               parent::__construct( $historyPage->getContext() );
+               $this->historyPage = $historyPage;
+               $this->tagFilter = $tagFilter;
+               $this->getDateCond( $year, $month, $day );
+               $this->conds = $conds;
+               $this->showTagEditUI = ChangeTags::showTagEditingUI( $this->getUser() );
+       }
+
+       // For hook compatibility...
+       function getArticle() {
+               return $this->historyPage->getArticle();
+       }
+
+       function getSqlComment() {
+               if ( $this->conds ) {
+                       return 'history page filtered'; // potentially slow, see CR r58153
+               } else {
+                       return 'history page unfiltered';
+               }
+       }
+
+       function getQueryInfo() {
+               $revQuery = Revision::getQueryInfo( [ 'user' ] );
+               $queryInfo = [
+                       'tables' => $revQuery['tables'],
+                       'fields' => $revQuery['fields'],
+                       'conds' => array_merge(
+                               [ 'rev_page' => $this->getWikiPage()->getId() ],
+                               $this->conds ),
+                       'options' => [ 'USE INDEX' => [ 'revision' => 'page_timestamp' ] ],
+                       'join_conds' => $revQuery['joins'],
+               ];
+               ChangeTags::modifyDisplayQuery(
+                       $queryInfo['tables'],
+                       $queryInfo['fields'],
+                       $queryInfo['conds'],
+                       $queryInfo['join_conds'],
+                       $queryInfo['options'],
+                       $this->tagFilter
+               );
+
+               // Avoid PHP 7.1 warning of passing $this by reference
+               $historyPager = $this;
+               Hooks::run( 'PageHistoryPager::getQueryInfo', [ &$historyPager, &$queryInfo ] );
+
+               return $queryInfo;
+       }
+
+       function getIndexField() {
+               return 'rev_timestamp';
+       }
+
+       /**
+        * @param stdClass $row
+        * @return string
+        */
+       function formatRow( $row ) {
+               if ( $this->lastRow ) {
+                       $latest = ( $this->counter == 1 && $this->mIsFirst );
+                       $firstInList = $this->counter == 1;
+                       $this->counter++;
+
+                       $notifTimestamp = $this->getConfig()->get( 'ShowUpdatedMarker' )
+                               ? $this->getTitle()->getNotificationTimestamp( $this->getUser() )
+                               : false;
+
+                       $s = $this->historyLine(
+                               $this->lastRow, $row, $notifTimestamp, $latest, $firstInList );
+               } else {
+                       $s = '';
+               }
+               $this->lastRow = $row;
+
+               return $s;
+       }
+
+       protected function doBatchLookups() {
+               if ( !Hooks::run( 'PageHistoryPager::doBatchLookups', [ $this, $this->mResult ] ) ) {
+                       return;
+               }
+
+               # Do a link batch query
+               $this->mResult->seek( 0 );
+               $batch = new LinkBatch();
+               $revIds = [];
+               foreach ( $this->mResult as $row ) {
+                       if ( $row->rev_parent_id ) {
+                               $revIds[] = $row->rev_parent_id;
+                       }
+                       if ( $row->user_name !== null ) {
+                               $batch->add( NS_USER, $row->user_name );
+                               $batch->add( NS_USER_TALK, $row->user_name );
+                       } else { # for anons or usernames of imported revisions
+                               $batch->add( NS_USER, $row->rev_user_text );
+                               $batch->add( NS_USER_TALK, $row->rev_user_text );
+                       }
+               }
+               $this->parentLens = Revision::getParentLengths( $this->mDb, $revIds );
+               $batch->execute();
+               $this->mResult->seek( 0 );
+       }
+
+       /**
+        * Creates begin of history list with a submit button
+        *
+        * @return string HTML output
+        */
+       protected function getStartBody() {
+               $this->lastRow = false;
+               $this->counter = 1;
+               $this->oldIdChecked = 0;
+
+               $this->getOutput()->wrapWikiMsg( "<div class='mw-history-legend'>\n$1\n</div>", 'histlegend' );
+               $s = Html::openElement( 'form', [ 'action' => wfScript(),
+                       'id' => 'mw-history-compare' ] ) . "\n";
+               $s .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n";
+               $s .= Html::hidden( 'action', 'historysubmit' ) . "\n";
+               $s .= Html::hidden( 'type', 'revision' ) . "\n";
+
+               // Button container stored in $this->buttons for re-use in getEndBody()
+               $this->buttons = Html::openElement( 'div', [ 'class' => 'mw-history-compareselectedversions' ] );
+               $className = 'historysubmit mw-history-compareselectedversions-button';
+               $attrs = [ 'class' => $className ]
+                       + Linker::tooltipAndAccesskeyAttribs( 'compareselectedversions' );
+               $this->buttons .= $this->submitButton( $this->msg( 'compareselectedversions' )->text(),
+                       $attrs
+               ) . "\n";
+
+               $user = $this->getUser();
+               $actionButtons = '';
+               if ( $user->isAllowed( 'deleterevision' ) ) {
+                       $actionButtons .= $this->getRevisionButton( 'revisiondelete', 'showhideselectedversions' );
+               }
+               if ( $this->showTagEditUI ) {
+                       $actionButtons .= $this->getRevisionButton( 'editchangetags', 'history-edit-tags' );
+               }
+               if ( $actionButtons ) {
+                       $this->buttons .= Xml::tags( 'div', [ 'class' =>
+                               'mw-history-revisionactions' ], $actionButtons );
+               }
+
+               if ( $user->isAllowed( 'deleterevision' ) || $this->showTagEditUI ) {
+                       $this->buttons .= ( new ListToggle( $this->getOutput() ) )->getHTML();
+               }
+
+               $this->buttons .= '</div>';
+
+               $s .= $this->buttons;
+               $s .= '<ul id="pagehistory">' . "\n";
+
+               return $s;
+       }
+
+       private function getRevisionButton( $name, $msg ) {
+               $this->preventClickjacking();
+               # Note T22966, <button> is non-standard in IE<8
+               $element = Html::element(
+                       'button',
+                       [
+                               'type' => 'submit',
+                               'name' => $name,
+                               'value' => '1',
+                               'class' => "historysubmit mw-history-$name-button",
+                       ],
+                       $this->msg( $msg )->text()
+               ) . "\n";
+               return $element;
+       }
+
+       protected function getEndBody() {
+               if ( $this->lastRow ) {
+                       $latest = $this->counter == 1 && $this->mIsFirst;
+                       $firstInList = $this->counter == 1;
+                       if ( $this->mIsBackwards ) {
+                               # Next row is unknown, but for UI reasons, probably exists if an offset has been specified
+                               if ( $this->mOffset == '' ) {
+                                       $next = null;
+                               } else {
+                                       $next = 'unknown';
+                               }
+                       } else {
+                               # The next row is the past-the-end row
+                               $next = $this->mPastTheEndRow;
+                       }
+                       $this->counter++;
+
+                       $notifTimestamp = $this->getConfig()->get( 'ShowUpdatedMarker' )
+                               ? $this->getTitle()->getNotificationTimestamp( $this->getUser() )
+                               : false;
+
+                       $s = $this->historyLine(
+                               $this->lastRow, $next, $notifTimestamp, $latest, $firstInList );
+               } else {
+                       $s = '';
+               }
+               $s .= "</ul>\n";
+               # Add second buttons only if there is more than one rev
+               if ( $this->getNumRows() > 2 ) {
+                       $s .= $this->buttons;
+               }
+               $s .= '</form>';
+
+               return $s;
+       }
+
+       /**
+        * Creates a submit button
+        *
+        * @param string $message Text of the submit button, will be escaped
+        * @param array $attributes
+        * @return string HTML output for the submit button
+        */
+       function submitButton( $message, $attributes = [] ) {
+               # Disable submit button if history has 1 revision only
+               if ( $this->getNumRows() > 1 ) {
+                       return Html::submitButton( $message, $attributes );
+               } else {
+                       return '';
+               }
+       }
+
+       /**
+        * Returns a row from the history printout.
+        *
+        * @todo document some more, and maybe clean up the code (some params redundant?)
+        *
+        * @param stdClass $row The database row corresponding to the previous line.
+        * @param mixed $next The database row corresponding to the next line
+        *   (chronologically previous)
+        * @param bool|string $notificationtimestamp
+        * @param bool $latest Whether this row corresponds to the page's latest revision.
+        * @param bool $firstInList Whether this row corresponds to the first
+        *   displayed on this history page.
+        * @return string HTML output for the row
+        */
+       function historyLine( $row, $next, $notificationtimestamp = false,
+               $latest = false, $firstInList = false ) {
+               $rev = new Revision( $row, 0, $this->getTitle() );
+
+               if ( is_object( $next ) ) {
+                       $prevRev = new Revision( $next, 0, $this->getTitle() );
+               } else {
+                       $prevRev = null;
+               }
+
+               $curlink = $this->curLink( $rev, $latest );
+               $lastlink = $this->lastLink( $rev, $next );
+               $curLastlinks = Html::rawElement( 'span', [], $curlink ) .
+                       Html::rawElement( 'span', [], $lastlink );
+               $histLinks = Html::rawElement(
+                       'span',
+                       [ 'class' => 'mw-history-histlinks mw-changeslist-links' ],
+                       $curLastlinks
+               );
+
+               $diffButtons = $this->diffButtons( $rev, $firstInList );
+               $s = $histLinks . $diffButtons;
+
+               $link = $this->revLink( $rev );
+               $classes = [];
+
+               $del = '';
+               $user = $this->getUser();
+               $canRevDelete = $user->isAllowed( 'deleterevision' );
+               // Show checkboxes for each revision, to allow for revision deletion and
+               // change tags
+               if ( $canRevDelete || $this->showTagEditUI ) {
+                       $this->preventClickjacking();
+                       // If revision was hidden from sysops and we don't need the checkbox
+                       // for anything else, disable it
+                       if ( !$this->showTagEditUI && !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
+                               $del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
+                       // Otherwise, enable the checkbox...
+                       } else {
+                               $del = Xml::check( 'showhiderevisions', false,
+                                       [ 'name' => 'ids[' . $rev->getId() . ']' ] );
+                       }
+               // User can only view deleted revisions...
+               } elseif ( $rev->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) {
+                       // If revision was hidden from sysops, disable the link
+                       if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
+                               $del = Linker::revDeleteLinkDisabled( false );
+                       // Otherwise, show the link...
+                       } else {
+                               $query = [ 'type' => 'revision',
+                                       'target' => $this->getTitle()->getPrefixedDBkey(), 'ids' => $rev->getId() ];
+                               $del .= Linker::revDeleteLink( $query,
+                                       $rev->isDeleted( Revision::DELETED_RESTRICTED ), false );
+                       }
+               }
+               if ( $del ) {
+                       $s .= " $del ";
+               }
+
+               $lang = $this->getLanguage();
+               $dirmark = $lang->getDirMark();
+
+               $s .= " $link";
+               $s .= $dirmark;
+               $s .= " <span class='history-user'>" .
+                       Linker::revUserTools( $rev, true, false ) . "</span>";
+               $s .= $dirmark;
+
+               if ( $rev->isMinor() ) {
+                       $s .= ' ' . ChangesList::flag( 'minor', $this->getContext() );
+               }
+
+               # Sometimes rev_len isn't populated
+               if ( $rev->getSize() !== null ) {
+                       # Size is always public data
+                       $prevSize = $this->parentLens[$row->rev_parent_id] ?? 0;
+                       $sDiff = ChangesList::showCharacterDifference( $prevSize, $rev->getSize() );
+                       $fSize = Linker::formatRevisionSize( $rev->getSize(), false );
+                       $s .= ' <span class="mw-changeslist-separator"></span> ' . "$fSize $sDiff";
+               }
+
+               # Text following the character difference is added just before running hooks
+               $s2 = Linker::revComment( $rev, false, true, false );
+
+               if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
+                       $s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>';
+                       $classes[] = 'mw-history-line-updated';
+               }
+
+               $tools = [];
+
+               # Rollback and undo links
+               if ( $prevRev && $this->getTitle()->quickUserCan( 'edit', $user ) ) {
+                       if ( $latest && $this->getTitle()->quickUserCan( 'rollback', $user ) ) {
+                               // Get a rollback link without the brackets
+                               $rollbackLink = Linker::generateRollback(
+                                       $rev,
+                                       $this->getContext(),
+                                       [ 'verify', 'noBrackets' ]
+                               );
+                               if ( $rollbackLink ) {
+                                       $this->preventClickjacking();
+                                       $tools[] = $rollbackLink;
+                               }
+                       }
+
+                       if ( !$rev->isDeleted( Revision::DELETED_TEXT )
+                               && !$prevRev->isDeleted( Revision::DELETED_TEXT )
+                       ) {
+                               # Create undo tooltip for the first (=latest) line only
+                               $undoTooltip = $latest
+                                       ? [ 'title' => $this->msg( 'tooltip-undo' )->text() ]
+                                       : [];
+                               $undolink = MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
+                                       $this->getTitle(),
+                                       $this->msg( 'editundo' )->text(),
+                                       $undoTooltip,
+                                       [
+                                               'action' => 'edit',
+                                               'undoafter' => $prevRev->getId(),
+                                               'undo' => $rev->getId()
+                                       ]
+                               );
+                               $tools[] = "<span class=\"mw-history-undo\">{$undolink}</span>";
+                       }
+               }
+               // Allow extension to add their own links here
+               Hooks::run( 'HistoryRevisionTools', [ $rev, &$tools, $prevRev, $user ] );
+
+               if ( $tools ) {
+                       $s2 .= ' ' . Html::openElement( 'span', [ 'class' => 'mw-changeslist-links' ] );
+                       foreach ( $tools as $tool ) {
+                               $s2 .= Html::rawElement( 'span', [], $tool );
+                       }
+                       $s2 .= Html::closeElement( 'span' );
+               }
+
+               # Tags
+               list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow(
+                       $row->ts_tags,
+                       'history',
+                       $this->getContext()
+               );
+               $classes = array_merge( $classes, $newClasses );
+               if ( $tagSummary !== '' ) {
+                       $s2 .= " $tagSummary";
+               }
+
+               # Include separator between character difference and following text
+               if ( $s2 !== '' ) {
+                       $s .= ' <span class="mw-changeslist-separator"></span> ' . $s2;
+               }
+
+               $attribs = [ 'data-mw-revid' => $rev->getId() ];
+
+               Hooks::run( 'PageHistoryLineEnding', [ $this, &$row, &$s, &$classes, &$attribs ] );
+               $attribs = array_filter( $attribs,
+                       [ Sanitizer::class, 'isReservedDataAttribute' ],
+                       ARRAY_FILTER_USE_KEY
+               );
+
+               if ( $classes ) {
+                       $attribs['class'] = implode( ' ', $classes );
+               }
+
+               return Xml::tags( 'li', $attribs, $s ) . "\n";
+       }
+
+       /**
+        * Create a link to view this revision of the page
+        *
+        * @param Revision $rev
+        * @return string
+        */
+       function revLink( $rev ) {
+               return ChangesList::revDateLink( $rev, $this->getUser(), $this->getLanguage(),
+                       $this->getTitle() );
+       }
+
+       /**
+        * Create a diff-to-current link for this revision for this page
+        *
+        * @param Revision $rev
+        * @param bool $latest This is the latest revision of the page?
+        * @return string
+        */
+       function curLink( $rev, $latest ) {
+               $cur = $this->historyPage->message['cur'];
+               if ( $latest || !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+                       return $cur;
+               } else {
+                       return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
+                               $this->getTitle(),
+                               new HtmlArmor( $cur ),
+                               [],
+                               [
+                                       'diff' => $this->getWikiPage()->getLatest(),
+                                       'oldid' => $rev->getId()
+                               ]
+                       );
+               }
+       }
+
+       /**
+        * Create a diff-to-previous link for this revision for this page.
+        *
+        * @param Revision $prevRev The revision being displayed
+        * @param stdClass|string|null $next The next revision in list (that is
+        *        the previous one in chronological order).
+        *        May either be a row, "unknown" or null.
+        * @return string
+        */
+       function lastLink( $prevRev, $next ) {
+               $last = $this->historyPage->message['last'];
+
+               if ( $next === null ) {
+                       # Probably no next row
+                       return $last;
+               }
+
+               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+               if ( $next === 'unknown' ) {
+                       # Next row probably exists but is unknown, use an oldid=prev link
+                       return $linkRenderer->makeKnownLink(
+                               $this->getTitle(),
+                               new HtmlArmor( $last ),
+                               [],
+                               [
+                                       'diff' => $prevRev->getId(),
+                                       'oldid' => 'prev'
+                               ]
+                       );
+               }
+
+               $nextRev = new Revision( $next, 0, $this->getTitle() );
+
+               if ( !$prevRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
+                       || !$nextRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
+               ) {
+                       return $last;
+               }
+
+               return $linkRenderer->makeKnownLink(
+                       $this->getTitle(),
+                       new HtmlArmor( $last ),
+                       [],
+                       [
+                               'diff' => $prevRev->getId(),
+                               'oldid' => $next->rev_id
+                       ]
+               );
+       }
+
+       /**
+        * Create radio buttons for page history
+        *
+        * @param Revision $rev
+        * @param bool $firstInList Is this version the first one?
+        *
+        * @return string HTML output for the radio buttons
+        */
+       function diffButtons( $rev, $firstInList ) {
+               if ( $this->getNumRows() > 1 ) {
+                       $id = $rev->getId();
+                       $radio = [ 'type' => 'radio', 'value' => $id ];
+                       /** @todo Move title texts to javascript */
+                       if ( $firstInList ) {
+                               $first = Xml::element( 'input',
+                                       array_merge( $radio, [
+                                               'style' => 'visibility:hidden',
+                                               'name' => 'oldid',
+                                               'id' => 'mw-oldid-null' ] )
+                               );
+                               $checkmark = [ 'checked' => 'checked' ];
+                       } else {
+                               # Check visibility of old revisions
+                               if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+                                       $radio['disabled'] = 'disabled';
+                                       $checkmark = []; // We will check the next possible one
+                               } elseif ( !$this->oldIdChecked ) {
+                                       $checkmark = [ 'checked' => 'checked' ];
+                                       $this->oldIdChecked = $id;
+                               } else {
+                                       $checkmark = [];
+                               }
+                               $first = Xml::element( 'input',
+                                       array_merge( $radio, $checkmark, [
+                                               'name' => 'oldid',
+                                               'id' => "mw-oldid-$id" ] ) );
+                               $checkmark = [];
+                       }
+                       $second = Xml::element( 'input',
+                               array_merge( $radio, $checkmark, [
+                                       'name' => 'diff',
+                                       'id' => "mw-diff-$id" ] ) );
+
+                       return $first . $second;
+               } else {
+                       return '';
+               }
+       }
+
+       /**
+        * @inheritDoc
+        */
+       function getDefaultQuery() {
+               parent::getDefaultQuery();
+               unset( $this->mDefaultQuery['date-range-to'] );
+               return $this->mDefaultQuery;
+       }
+
+       /**
+        * This is called if a write operation is possible from the generated HTML
+        * @param bool $enable
+        */
+       function preventClickjacking( $enable = true ) {
+               $this->preventClickjacking = $enable;
+       }
+
+       /**
+        * Get the "prevent clickjacking" flag
+        * @return bool
+        */
+       function getPreventClickjacking() {
+               return $this->preventClickjacking;
+       }
+
+}
index e37b4d4..2f66277 100644 (file)
@@ -345,10 +345,10 @@ class ApiAuthManagerHelper {
        /**
         * Fetch the standard parameters this helper recognizes
         * @param string $action AuthManager action
-        * @param string $param,... Parameters to use
+        * @param string ...$wantedParams Parameters to use
         * @return array
         */
-       public static function getStandardParams( $action, $param /* ... */ ) {
+       public static function getStandardParams( $action, ...$wantedParams ) {
                $params = [
                        'requests' => [
                                ApiBase::PARAM_TYPE => 'string',
@@ -384,8 +384,6 @@ class ApiAuthManagerHelper {
                ];
 
                $ret = [];
-               $wantedParams = func_get_args();
-               array_shift( $wantedParams );
                foreach ( $wantedParams as $name ) {
                        if ( isset( $params[$name] ) ) {
                                $ret[$name] = $params[$name];
index 4898385..528ced8 100644 (file)
@@ -800,6 +800,7 @@ abstract class ApiBase extends ContextSource {
                                        // $results if all are done.
                                        unset( $targets[$placeholder] );
                                        $placeholder = '{' . $placeholder . '}';
+                                       // @phan-suppress-next-line PhanTypeNoAccessiblePropertiesForeach
                                        foreach ( $results[$target] as $value ) {
                                                if ( !preg_match( '/^[^{}]*$/', $value ) ) {
                                                        // Skip values that make invalid parameter names.
@@ -1805,13 +1806,16 @@ abstract class ApiBase extends ContextSource {
 
                $status = Status::newGood();
                foreach ( $errors as $error ) {
-                       if ( is_array( $error ) && isset( self::$blockMsgMap[$error[0]] ) && $user->getBlock() ) {
+                       if ( !is_array( $error ) ) {
+                               $error = [ $error ];
+                       }
+                       if ( is_string( $error[0] ) && isset( self::$blockMsgMap[$error[0]] ) && $user->getBlock() ) {
                                list( $msg, $code ) = self::$blockMsgMap[$error[0]];
                                $status->fatal( ApiMessage::create( $msg, $code,
                                        [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ]
                                ) );
                        } else {
-                               $status->fatal( ...(array)$error );
+                               $status->fatal( ...$error );
                        }
                }
                return $status;
@@ -2222,13 +2226,33 @@ abstract class ApiBase extends ContextSource {
         * @param string $feature Feature being used.
         */
        public function logFeatureUsage( $feature ) {
+               static $loggedFeatures = [];
+
+               // Only log each feature once per request. We can get multiple calls from calls to
+               // extractRequestParams() with different values for 'parseLimit', for example.
+               if ( isset( $loggedFeatures[$feature] ) ) {
+                       return;
+               }
+               $loggedFeatures[$feature] = true;
+
                $request = $this->getRequest();
-               $s = '"' . addslashes( $feature ) . '"' .
-                       ' "' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) . '"' .
-                       ' "' . $request->getIP() . '"' .
-                       ' "' . addslashes( $request->getHeader( 'Referer' ) ) . '"' .
-                       ' "' . addslashes( $this->getMain()->getUserAgent() ) . '"';
-               wfDebugLog( 'api-feature-usage', $s, 'private' );
+               $ctx = [
+                       'feature' => $feature,
+                       // Spaces to underscores in 'username' for historical reasons.
+                       'username' => str_replace( ' ', '_', $this->getUser()->getName() ),
+                       'ip' => $request->getIP(),
+                       'referer' => (string)$request->getHeader( 'Referer' ),
+                       'agent' => $this->getMain()->getUserAgent(),
+               ];
+
+               // Text string is deprecated. Remove (or replace with just $feature) in MW 1.34.
+               $s = '"' . addslashes( $ctx['feature'] ) . '"' .
+                       ' "' . wfUrlencode( $ctx['username'] ) . '"' .
+                       ' "' . $ctx['ip'] . '"' .
+                       ' "' . addslashes( $ctx['referer'] ) . '"' .
+                       ' "' . addslashes( $ctx['agent'] ) . '"';
+
+               wfDebugLog( 'api-feature-usage', $s, 'private', $ctx );
        }
 
        /**@}*/
index 14177ed..673fc6b 100644 (file)
@@ -135,7 +135,7 @@ class ApiBlock extends ApiBase {
 
                $block = Block::newFromTarget( $target, null, true );
                if ( $block instanceof Block ) {
-                       $res['expiry'] = ApiResult::formatExpiry( $block->mExpiry, 'infinite' );
+                       $res['expiry'] = ApiResult::formatExpiry( $block->getExpiry(), 'infinite' );
                        $res['id'] = $block->getId();
                } else {
                        # should be unreachable
index 4ba30ab..1eb5e8d 100644 (file)
@@ -307,10 +307,8 @@ class ApiComparePages extends ApiBase {
                foreach ( [ 'from', 'to' ] as $prefix ) {
                        if ( $params["{$prefix}rev"] !== null ) {
                                $rev = $this->getRevisionById( $params["{$prefix}rev"] );
-                               if ( $rev ) {
-                                       if ( $rev->hasSlot( $role ) ) {
-                                               return $rev->getSlot( $role, RevisionRecord::RAW )->getModel();
-                                       }
+                               if ( $rev && $rev->hasSlot( $role ) ) {
+                                       return $rev->getSlot( $role, RevisionRecord::RAW )->getModel();
                                }
                        }
                }
index 7da8ed9..e4c52dd 100644 (file)
@@ -217,6 +217,8 @@ class ApiContinuationManager {
                        // Some modules are unfinished: include those params, and copy
                        // the generator params.
                        foreach ( $continuationData as $module => $kvp ) {
+                               // XXX: Not sure why phan is complaining here...
+                               // @phan-suppress-next-line PhanTypeInvalidLeftOperand
                                $data += $kvp;
                        }
                        $generatorParams = [];
index 7e8041d..0e13d70 100644 (file)
@@ -75,7 +75,7 @@ class ApiDelete extends ApiBase {
                        $status = self::delete( $pageObj, $user, $reason, $params['tags'] );
                }
 
-               if ( !$status->isOk() ) {
+               if ( !$status->isOK() ) {
                        $this->dieStatus( $status );
                }
                $this->addMessagesFromStatus( $status, [ 'warning' ], [ 'delete-scheduled' ] );
index 562bcdf..22f5235 100644 (file)
@@ -162,7 +162,8 @@ class ApiExpandTemplates extends ApiBase {
                                }
                                if ( isset( $prop['modules'] ) ) {
                                        $retval['modules'] = array_values( array_unique( $p_output->getModules() ) );
-                                       $retval['modulescripts'] = array_values( array_unique( $p_output->getModuleScripts() ) );
+                                       // Deprecated since 1.32 (T188689)
+                                       $retval['modulescripts'] = [];
                                        $retval['modulestyles'] = array_values( array_unique( $p_output->getModuleStyles() ) );
                                }
                                if ( isset( $prop['jsconfigvars'] ) ) {
index 935bb09..11b5d91 100644 (file)
@@ -102,10 +102,8 @@ class ApiFeedWatchlist extends ApiBase {
                                $fauxReqArr['wlallrev'] = '';
                        }
 
-                       // Create the request
                        $fauxReq = new FauxRequest( $fauxReqArr );
 
-                       // Execute
                        $module = new ApiMain( $fauxReq );
                        $module->execute();
 
index 9d69145..bff9fd0 100644 (file)
@@ -158,11 +158,9 @@ abstract class ApiFormatBase extends ApiBase {
 
                if ( !is_array( $paramSettings ) ) {
                        return $paramSettings;
-               } elseif ( isset( $paramSettings[self::PARAM_DFLT] ) ) {
-                       return $paramSettings[self::PARAM_DFLT];
-               } else {
-                       return null;
                }
+
+               return $paramSettings[self::PARAM_DFLT] ?? null;
        }
 
        /**
@@ -307,7 +305,6 @@ abstract class ApiFormatBase extends ApiBase {
                                                'html' => $out->getHTML(),
                                                'modules' => array_values( array_unique( array_merge(
                                                        $out->getModules(),
-                                                       $out->getModuleScripts(),
                                                        $out->getModuleStyles()
                                                ) ) ),
                                                'continue' => $this->getResult()->getResultData( 'continue' ),
index 45bdb6d..616b341 100644 (file)
@@ -30,6 +30,9 @@ class ApiFormatPhp extends ApiFormatBase {
                return 'application/vnd.php.serialized';
        }
 
+       /**
+        * @suppress SecurityCheck-XSS Output type is not text/html
+        */
        public function execute() {
                $params = $this->extractRequestParams();
 
index 886dbcc..1656e7c 100644 (file)
@@ -559,11 +559,9 @@ class ApiHelp extends ApiBase {
                                                                                $arr = &$submodules;
                                                                                try {
                                                                                        $submod = $module->getModuleFromPath( $m );
-                                                                                       if ( $submod ) {
-                                                                                               if ( $submod->isDeprecated() ) {
-                                                                                                       $arr = &$deprecatedSubmodules;
-                                                                                                       $attrs['class'] = 'apihelp-deprecated-value';
-                                                                                               }
+                                                                                       if ( $submod && $submod->isDeprecated() ) {
+                                                                                               $arr = &$deprecatedSubmodules;
+                                                                                               $attrs['class'] = 'apihelp-deprecated-value';
                                                                                        }
                                                                                } catch ( ApiUsageException $ex ) {
                                                                                        // Ignore
index 21e2694..7045138 100644 (file)
@@ -33,8 +33,6 @@ class ApiImageRotate extends ApiBase {
                $pageSet = $this->getPageSet();
                $pageSet->execute();
 
-               $result = [];
-
                $result = $pageSet->getInvalidTitlesAndRevisions( [
                        'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'interwikiTitles',
                ] );
index 133f0ce..d7b3332 100644 (file)
@@ -107,7 +107,6 @@ class ApiLogin extends ApiBase {
                }
 
                $authRes = false;
-               $context = new DerivativeContext( $this->getContext() );
                $loginType = 'N/A';
 
                // Check login token
index 634ebd1..588e31a 100644 (file)
@@ -218,7 +218,7 @@ class ApiMain extends ApiBase {
                                                'cookies' => $sessionCookies,
                                                'ip' => $request->getIP(),
                                                'userAgent' => $this->getUserAgent(),
-                                               'wiki' => wfWikiID(),
+                                               'wiki' => WikiMap::getCurrentWikiDbDomain()->getId(),
                                        ]
                                );
                        }
@@ -321,7 +321,7 @@ class ApiMain extends ApiBase {
                $request = $this->getRequest();
 
                // JSONP mode
-               if ( $request->getVal( 'callback' ) !== null ) {
+               if ( $request->getCheck( 'callback' ) ) {
                        $this->lacksSameOriginSecurity = true;
                        return true;
                }
@@ -1117,19 +1117,17 @@ class ApiMain extends ApiBase {
                                        . $this->msg( 'api-usage-mailinglist-ref' )->inLanguage( $formatter->getLanguage() )->text()
                                )
                        );
-               } else {
-                       if ( $config->get( 'ShowExceptionDetails' ) ) {
-                               $result->addContentValue(
-                                       $path,
-                                       'trace',
-                                       $this->msg( 'api-exception-trace',
-                                               get_class( $e ),
-                                               $e->getFile(),
-                                               $e->getLine(),
-                                               MWExceptionHandler::getRedactedTraceAsString( $e )
-                                       )->inLanguage( $formatter->getLanguage() )->text()
-                               );
-                       }
+               } elseif ( $config->get( 'ShowExceptionDetails' ) ) {
+                       $result->addContentValue(
+                               $path,
+                               'trace',
+                               $this->msg( 'api-exception-trace',
+                                       get_class( $e ),
+                                       $e->getFile(),
+                                       $e->getLine(),
+                                       MWExceptionHandler::getRedactedTraceAsString( $e )
+                               )->inLanguage( $formatter->getLanguage() )->text()
+                       );
                }
 
                // Add the id and such
@@ -1592,17 +1590,14 @@ class ApiMain extends ApiBase {
                        $this->setupExternalResponse( $module, $params );
                }
 
-               // Execute
                $module->execute();
                Hooks::run( 'APIAfterExecute', [ &$module ] );
 
                $this->reportUnusedParams();
 
                if ( !$this->mInternalMode ) {
-                       // append Debug information
                        MWDebug::appendDebugInfoToApiResult( $this->getContext(), $this->getResult() );
 
-                       // Print result data
                        $this->printResult();
                }
        }
@@ -1632,28 +1627,56 @@ class ApiMain extends ApiBase {
         */
        protected function logRequest( $time, $e = null ) {
                $request = $this->getRequest();
-               $logCtx = [
+               $legacyLogCtx = [
                        'ts' => time(),
                        'ip' => $request->getIP(),
                        'userAgent' => $this->getUserAgent(),
-                       'wiki' => wfWikiID(),
+                       'wiki' => WikiMap::getCurrentWikiDbDomain()->getId(),
                        'timeSpentBackend' => (int)round( $time * 1000 ),
                        'hadError' => $e !== null,
                        'errorCodes' => [],
                        'params' => [],
                ];
 
+               $logCtx = [
+                       '$schema' => '/mediawiki/api/request/0.0.1',
+                       'meta' => [
+                               'request_id' => WebRequest::getRequestId(),
+                               'id' => UIDGenerator::newUUIDv1(),
+                               'dt' => wfTimestamp( TS_ISO_8601 ),
+                               'domain' => $this->getConfig()->get( 'ServerName' ),
+                               'stream' => 'mediawiki.api-request'
+                       ],
+                       'http' => [
+                               'method' => $request->getMethod(),
+                               'client_ip' => $request->getIP()
+                       ],
+                       'database' => WikiMap::getCurrentWikiDbDomain()->getId(),
+                       'backend_time_ms' => (int)round( $time * 1000 ),
+               ];
+
+               // If set, these headers will be logged in http.request_headers.
+               $httpRequestHeadersToLog = [ 'accept-language', 'referer', 'user-agent' ];
+               foreach ( $httpRequestHeadersToLog as $header ) {
+                       if ( $request->getHeader( $header ) ) {
+                               // Set the header in http.request_headers
+                               $logCtx['http']['request_headers'][$header] = $request->getHeader( $header );
+                       }
+               }
+
                if ( $e ) {
+                       $logCtx['api_error_codes'] = [];
                        foreach ( $this->errorMessagesFromException( $e ) as $msg ) {
-                               $logCtx['errorCodes'][] = $msg->getApiCode();
+                               $legacyLogCtx['errorCodes'][] = $msg->getApiCode();
+                               $logCtx['api_error_codes'][] = $msg->getApiCode();
                        }
                }
 
                // Construct space separated message for 'api' log channel
                $msg = "API {$request->getMethod()} " .
                        wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) .
-                       " {$logCtx['ip']} " .
-                       "T={$logCtx['timeSpentBackend']}ms";
+                       " {$legacyLogCtx['ip']} " .
+                       "T={$legacyLogCtx['timeSpentBackend']}ms";
 
                $sensitive = array_flip( $this->getSensitiveParams() );
                foreach ( $this->getParamsUsed() as $name ) {
@@ -1672,13 +1695,17 @@ class ApiMain extends ApiBase {
                                $encValue = $this->encodeRequestLogValue( $value );
                        }
 
+                       $legacyLogCtx['params'][$name] = $value;
                        $logCtx['params'][$name] = $value;
                        $msg .= " {$name}={$encValue}";
                }
 
                wfDebugLog( 'api', $msg, 'private' );
-               // ApiAction channel is for structured data consumers
-               wfDebugLog( 'ApiAction', '', 'private', $logCtx );
+               // ApiAction channel is for structured data consumers.
+               // The ApiAction was using logging channel is deprecated and is replaced
+               // by the api-request channel.
+               wfDebugLog( 'ApiAction', '', 'private', $legacyLogCtx );
+               wfDebugLog( 'api-request', '', 'private', $logCtx );
        }
 
        /**
index 450ebb6..b321c7d 100644 (file)
@@ -1398,10 +1398,10 @@ class ApiPageSet extends ApiBase {
                                                $data[$toPageId],
                                                $this->mGeneratorData[$fromNs][$fromDBkey]
                                        );
-                                       if ( $result instanceof ApiResult ) {
-                                               if ( !$result->addValue( $path, $toPageId, $data[$toPageId], ApiResult::OVERRIDE ) ) {
-                                                       return false;
-                                               }
+                                       if ( $result instanceof ApiResult &&
+                                               !$result->addValue( $path, $toPageId, $data[$toPageId], ApiResult::OVERRIDE )
+                                       ) {
+                                               return false;
                                        }
                                }
                        }
index 855b73d..5e4639d 100644 (file)
@@ -417,11 +417,13 @@ class ApiParse extends ApiBase {
                if ( isset( $prop['modules'] ) ) {
                        if ( $skin ) {
                                $result_array['modules'] = $outputPage->getModules();
-                               $result_array['modulescripts'] = $outputPage->getModuleScripts();
+                               // Deprecated since 1.32 (T188689)
+                               $result_array['modulescripts'] = [];
                                $result_array['modulestyles'] = $outputPage->getModuleStyles();
                        } else {
                                $result_array['modules'] = array_values( array_unique( $p_result->getModules() ) );
-                               $result_array['modulescripts'] = array_values( array_unique( $p_result->getModuleScripts() ) );
+                               // Deprecated since 1.32 (T188689)
+                               $result_array['modulescripts'] = [];
                                $result_array['modulestyles'] = array_values( array_unique( $p_result->getModuleStyles() ) );
                        }
                }
@@ -630,8 +632,8 @@ class ApiParse extends ApiBase {
         */
        private function formatSummary( $title, $params ) {
                global $wgParser;
-               $summary = !is_null( $params['summary'] ) ? $params['summary'] : '';
-               $sectionTitle = !is_null( $params['sectiontitle'] ) ? $params['sectiontitle'] : '';
+               $summary = $params['summary'] ?? '';
+               $sectionTitle = $params['sectiontitle'] ?? '';
 
                if ( $this->section === 'new' && ( $sectionTitle === '' || $summary === '' ) ) {
                        if ( $sectionTitle !== '' ) {
index c68ec2b..ae6b1a1 100644 (file)
@@ -287,7 +287,7 @@ class ApiQuery extends ApiBase {
                        }
                } elseif ( $modCacheMode === 'public' ) {
                        // do nothing, if it's public already it will stay public
-               } else { // private
+               } else {
                        $cacheMode = 'private';
                }
 
index 8855615..bb50185 100644 (file)
@@ -131,7 +131,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
+                               [ 'change_tag' => [ 'JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
                        );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
index 5343c33..75d75ec 100644 (file)
@@ -105,7 +105,7 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
 
                        if ( $needPageTable ) {
                                $revQuery['tables'][] = 'page';
-                               $revQuery['joins']['page'] = [ 'INNER JOIN', [ "$pageField = page_id" ] ];
+                               $revQuery['joins']['page'] = [ 'JOIN', [ "$pageField = page_id" ] ];
                                if ( (bool)$miser_ns ) {
                                        $revQuery['fields'][] = 'page_namespace';
                                }
index a540661..8b3d864 100644 (file)
@@ -117,7 +117,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        $this->addTables( 'user_groups', 'ug1' );
                        $this->addJoinConds( [
                                'ug1' => [
-                                       'INNER JOIN',
+                                       'JOIN',
                                        [
                                                'ug1.ug_user=user_id',
                                                'ug1.ug_group' => $params['group'],
@@ -141,7 +141,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                        LIST_OR
                                ) ];
                        }
-                       $this->addJoinConds( [ 'ug1' => [ 'LEFT OUTER JOIN',
+                       $this->addJoinConds( [ 'ug1' => [ 'LEFT JOIN',
                                array_merge( [
                                        'ug1.ug_user=user_id',
                                        'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
@@ -172,7 +172,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        // There shouldn't be any duplicate rows in querycachetwo here.
                        $this->addTables( 'querycachetwo' );
                        $this->addJoinConds( [ 'querycachetwo' => [
-                               'INNER JOIN', [
+                               'JOIN', [
                                        'qcc_type' => 'activeusers',
                                        'qcc_namespace' => NS_USER,
                                        'qcc_title=user_name',
index 3070665..d955b56 100644 (file)
@@ -157,16 +157,14 @@ abstract class ApiQueryBase extends ApiBase {
         */
        protected function addTables( $tables, $alias = null ) {
                if ( is_array( $tables ) ) {
-                       if ( !is_null( $alias ) ) {
+                       if ( $alias !== null ) {
                                ApiBase::dieDebug( __METHOD__, 'Multiple table aliases not supported' );
                        }
                        $this->tables = array_merge( $this->tables, $tables );
+               } elseif ( $alias !== null ) {
+                       $this->tables[$alias] = $tables;
                } else {
-                       if ( !is_null( $alias ) ) {
-                               $this->tables[$alias] = $tables;
-                       } else {
-                               $this->tables[] = $tables;
-                       }
+                       $this->tables[] = $tables;
                }
        }
 
index a8f970e..9057f10 100644 (file)
@@ -176,7 +176,7 @@ class ApiQueryContributors extends ApiQueryBase {
                        $limitGroups = array_unique( $limitGroups );
                        $this->addTables( 'user_groups' );
                        $this->addJoinConds( [ 'user_groups' => [
-                               $excludeGroups ? 'LEFT OUTER JOIN' : 'INNER JOIN',
+                               $excludeGroups ? 'LEFT JOIN' : 'JOIN',
                                [
                                        'ug_user=' . $revQuery['fields']['rev_user'],
                                        'ug_group' => $limitGroups,
index c156341..b266ecf 100644 (file)
@@ -83,7 +83,7 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
+                               [ 'change_tag' => [ 'JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
                        );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
index 3ee75f5..370a3fb 100644 (file)
@@ -137,7 +137,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
+                               [ 'change_tag' => [ 'JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
                        );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
index 333b769..051e127 100644 (file)
@@ -249,13 +249,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        // Don't set $scale['width']; this signals mergeThumbParams() to fill it with the image's width
                        $scale = [];
                        $scale['height'] = $params['urlheight'];
+               } elseif ( $params['urlparam'] ) {
+                       // Audio files might not have a width/height.
+                       $scale = [];
                } else {
-                       if ( $params['urlparam'] ) {
-                               // Audio files might not have a width/height.
-                               $scale = [];
-                       } else {
-                               $scale = null;
-                       }
+                       $scale = null;
                }
 
                return $scale;
index 3d358b9..a5437ba 100644 (file)
@@ -515,10 +515,8 @@ class ApiQueryInfo extends ApiQueryBase {
                        }
                }
 
-               if ( $this->fld_varianttitles ) {
-                       if ( isset( $this->variantTitles[$pageid] ) ) {
-                               $pageInfo['varianttitles'] = $this->variantTitles[$pageid];
-                       }
+               if ( $this->fld_varianttitles && isset( $this->variantTitles[$pageid] ) ) {
+                       $pageInfo['varianttitles'] = $this->variantTitles[$pageid];
                }
 
                if ( $this->params['testactions'] ) {
index 0934ab3..7798688 100644 (file)
@@ -112,7 +112,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
 
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
-                       $this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN',
+                       $this->addJoinConds( [ 'change_tag' => [ 'JOIN',
                                [ 'log_id=ct_log_id' ] ] ] );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
@@ -183,6 +183,10 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                $db, 'log_user', User::newFromName( $params['user'], false )
                        );
                        $this->addWhere( $q['conds'] );
+
+                       // T71222: MariaDB's optimizer, at least 10.1.37 and .38, likes to choose a wildly bad plan for
+                       // some reason for this code path. Tell it not to use the wrong index it wants to pick.
+                       $this->addOption( 'IGNORE INDEX', [ 'logging' => [ 'times' ] ] );
                }
 
                $title = $params['title'];
index 2d5c987..4b1bf2e 100644 (file)
@@ -360,7 +360,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
-                       $this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN', [ 'rc_id=ct_rc_id' ] ] ] );
+                       $this->addJoinConds( [ 'change_tag' => [ 'JOIN', [ 'rc_id=ct_rc_id' ] ] ] );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
                                $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
index 9301f81..7e46c1a 100644 (file)
@@ -177,7 +177,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                        // Always join 'page' so orphaned revisions are filtered out
                        $this->addTables( [ 'revision', 'page' ] );
                        $this->addJoinConds(
-                               [ 'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ] ]
+                               [ 'page' => [ 'JOIN', [ 'page_id = rev_page' ] ] ]
                        );
                        $this->addFields( [
                                'rev_id' => $idField, 'rev_timestamp' => $tsField, 'rev_page' => $pageField
@@ -191,7 +191,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                if ( $params['tag'] !== null ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ 'rev_id=ct_rev_id' ] ] ]
+                               [ 'change_tag' => [ 'JOIN', [ 'rev_id=ct_rev_id' ] ] ]
                        );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
@@ -268,7 +268,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                                                [ 'ar_rev_id' => $revids ],
                                                __METHOD__
                                        ),
-                               ], false );
+                               ], $db::UNION_DISTINCT );
                                $res = $db->query( $sql, __METHOD__ );
                                foreach ( $res as $row ) {
                                        if ( (int)$row->id === (int)$params['startid'] ) {
index 51f4d41..565e615 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 
+use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\Revision\RevisionAccessException;
 use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\Revision\SlotRecord;
@@ -292,69 +293,27 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                        }
                }
 
-               if ( $this->fld_roles ) {
-                       $vals['roles'] = $revision->getSlotRoles();
-               }
-
-               if ( $this->needSlots ) {
-                       $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT );
-                       if ( ( $this->fld_slotsha1 || $this->fetchContent ) && ( $revDel & self::IS_DELETED ) ) {
-                               $anyHidden = true;
+               try {
+                       if ( $this->fld_roles ) {
+                               $vals['roles'] = $revision->getSlotRoles();
                        }
-                       if ( $this->slotRoles === null ) {
-                               try {
-                                       $slot = $revision->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
-                               } catch ( RevisionAccessException $e ) {
-                                       // Back compat: If there's no slot, there's no content, so set 'textmissing'
-                                       // @todo: Gergő says to mention T198099 as a "todo" here.
-                                       $vals['textmissing'] = true;
-                                       $slot = null;
-                               }
 
-                               if ( $slot ) {
-                                       $content = null;
-                                       $vals += $this->extractSlotInfo( $slot, $revDel, $content );
-                                       if ( !empty( $vals['nosuchsection'] ) ) {
-                                               $this->dieWithError(
-                                                       [
-                                                               'apierror-nosuchsection-what',
-                                                               wfEscapeWikiText( $this->section ),
-                                                               $this->msg( 'revid', $revision->getId() )
-                                                       ],
-                                                       'nosuchsection'
-                                               );
-                                       }
-                                       if ( $content ) {
-                                               $vals += $this->extractDeprecatedContent( $content, $revision );
-                                       }
-                               }
-                       } else {
-                               $roles = array_intersect( $this->slotRoles, $revision->getSlotRoles() );
-                               $vals['slots'] = [
-                                       ApiResult::META_KVP_MERGE => true,
-                               ];
-                               foreach ( $roles as $role ) {
-                                       try {
-                                               $slot = $revision->getSlot( $role, RevisionRecord::RAW );
-                                       } catch ( RevisionAccessException $e ) {
-                                               // Don't error out here so the client can still process other slots/revisions.
-                                               // @todo: Gergő says to mention T198099 as a "todo" here.
-                                               $vals['slots'][$role]['missing'] = true;
-                                               continue;
-                                       }
-                                       $content = null;
-                                       $vals['slots'][$role] = $this->extractSlotInfo( $slot, $revDel, $content );
-                                       // @todo Move this into extractSlotInfo() (and remove its $content parameter)
-                                       // when extractDeprecatedContent() is no more.
-                                       if ( $content ) {
-                                               $vals['slots'][$role]['contentmodel'] = $content->getModel();
-                                               $vals['slots'][$role]['contentformat'] = $content->getDefaultFormat();
-                                               ApiResult::setContentValue( $vals['slots'][$role], 'content', $content->serialize() );
-                                       }
+                       if ( $this->needSlots ) {
+                               $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT );
+                               if ( ( $this->fld_slotsha1 || $this->fetchContent ) && ( $revDel & self::IS_DELETED ) ) {
+                                       $anyHidden = true;
                                }
-                               ApiResult::setArrayType( $vals['slots'], 'kvp', 'role' );
-                               ApiResult::setIndexedTagName( $vals['slots'], 'slot' );
+                               $vals = array_merge( $vals, $this->extractAllSlotInfo( $revision, $revDel ) );
                        }
+               } catch ( RevisionAccessException $ex ) {
+                       // This is here so T212428 doesn't spam the log.
+                       // TODO: find out why T212428 happens in the first place!
+                       $vals['slotsmissing'] = true;
+
+                       LoggerFactory::getInstance( 'api-warning' )->error(
+                               'Failed to access revision slots',
+                               [ 'revision' => $revision->getId(), 'exception' => $ex, ]
+                       );
                }
 
                if ( $this->fld_comment || $this->fld_parsedcomment ) {
@@ -396,6 +355,79 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                return $vals;
        }
 
+       /**
+        * Extracts information about all relevant slots.
+        *
+        * @param RevisionRecord $revision
+        * @param int $revDel
+        *
+        * @return array
+        * @throws ApiUsageException
+        */
+       private function extractAllSlotInfo( RevisionRecord $revision, $revDel ): array {
+               $vals = [];
+
+               if ( $this->slotRoles === null ) {
+                       try {
+                               $slot = $revision->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
+                       } catch ( RevisionAccessException $e ) {
+                               // Back compat: If there's no slot, there's no content, so set 'textmissing'
+                               // @todo: Gergő says to mention T198099 as a "todo" here.
+                               $vals['textmissing'] = true;
+                               $slot = null;
+                       }
+
+                       if ( $slot ) {
+                               $content = null;
+                               $vals += $this->extractSlotInfo( $slot, $revDel, $content );
+                               if ( !empty( $vals['nosuchsection'] ) ) {
+                                       $this->dieWithError(
+                                               [
+                                                       'apierror-nosuchsection-what',
+                                                       wfEscapeWikiText( $this->section ),
+                                                       $this->msg( 'revid', $revision->getId() )
+                                               ],
+                                               'nosuchsection'
+                                       );
+                               }
+                               if ( $content ) {
+                                       $vals += $this->extractDeprecatedContent( $content, $revision );
+                               }
+                       }
+               } else {
+                       $roles = array_intersect( $this->slotRoles, $revision->getSlotRoles() );
+                       $vals['slots'] = [
+                               ApiResult::META_KVP_MERGE => true,
+                       ];
+                       foreach ( $roles as $role ) {
+                               try {
+                                       $slot = $revision->getSlot( $role, RevisionRecord::RAW );
+                               } catch ( RevisionAccessException $e ) {
+                                       // Don't error out here so the client can still process other slots/revisions.
+                                       // @todo: Gergő says to mention T198099 as a "todo" here.
+                                       $vals['slots'][$role]['missing'] = true;
+                                       continue;
+                               }
+                               $content = null;
+                               $vals['slots'][$role] = $this->extractSlotInfo( $slot, $revDel, $content );
+                               // @todo Move this into extractSlotInfo() (and remove its $content parameter)
+                               // when extractDeprecatedContent() is no more.
+                               if ( $content ) {
+                                       $vals['slots'][$role]['contentmodel'] = $content->getModel();
+                                       $vals['slots'][$role]['contentformat'] = $content->getDefaultFormat();
+                                       ApiResult::setContentValue(
+                                               $vals['slots'][$role],
+                                               'content',
+                                               $content->serialize()
+                                       );
+                               }
+                       }
+                       ApiResult::setArrayType( $vals['slots'], 'kvp', 'role' );
+                       ApiResult::setIndexedTagName( $vals['slots'], 'slot' );
+               }
+               return $vals;
+       }
+
        /**
         * Extract information from the SlotRecord
         *
index b90dd5d..e6403f3 100644 (file)
@@ -157,7 +157,6 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                        convertForSearchResult( $matches->termMatches() );
                $titles = [];
                $count = 0;
-               $limit = $params['limit'];
 
                if ( $matches->hasMoreResults() ) {
                        $this->setContinueEnumParameter( 'offset', $params['offset'] + $params['limit'] );
index 96fa8a1..ea2f31b 100644 (file)
@@ -236,7 +236,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                $data[ApiResult::META_BC_BOOLS][] = 'variantarticlepath';
                $data['server'] = $config->get( 'Server' );
                $data['servername'] = $config->get( 'ServerName' );
-               $data['wikiid'] = wfWikiID();
+               $data['wikiid'] = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
                $data['time'] = wfTimestamp( TS_ISO_8601, time() );
 
                $data['misermode'] = (bool)$config->get( 'MiserMode' );
@@ -664,8 +664,8 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                }
 
                $data = [
-                       'url' => strlen( $url ) ? $url : '',
-                       'text' => strlen( $text ) ? $text : '',
+                       'url' => (string)$url,
+                       'text' => (string)$text,
                ];
 
                return $this->getResult()->addValue( 'query', $property, $data );
index 0ca0b20..5b178b7 100644 (file)
@@ -488,7 +488,7 @@ class ApiQueryUserContribs extends ApiQueryBase {
                if ( isset( $this->params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
+                               [ 'change_tag' => [ 'JOIN', [ $idField . ' = ct_rev_id' ] ] ]
                        );
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        try {
@@ -525,7 +525,6 @@ class ApiQueryUserContribs extends ApiQueryBase {
                if ( $this->fld_ids ) {
                        $vals['pageid'] = (int)$row->rev_page;
                        $vals['revid'] = (int)$row->rev_id;
-                       // $vals['textid'] = (int)$row->rev_text_id; // todo: Should this field be exposed?
 
                        if ( !is_null( $row->rev_parent_id ) ) {
                                $vals['parentid'] = (int)$row->rev_parent_id;
index a38d877..59e0524 100644 (file)
@@ -67,8 +67,8 @@ class ApiQueryUserInfo extends ApiQueryBase {
                $vals['blockid'] = $block->getId();
                $vals['blockedby'] = $block->getByName();
                $vals['blockedbyid'] = $block->getBy();
-               $vals['blockreason'] = $block->mReason;
-               $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->mTimestamp );
+               $vals['blockreason'] = $block->getReason();
+               $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->getTimestamp() );
                $vals['blockexpiry'] = ApiResult::formatExpiry( $block->getExpiry(), 'infinite' );
                $vals['blockpartial'] = !$block->isSitewide();
                if ( $block->getSystemBlockType() !== null ) {
@@ -202,13 +202,11 @@ class ApiQueryUserInfo extends ApiQueryBase {
                        $vals['realname'] = $user->getRealName();
                }
 
-               if ( $user->isAllowed( 'viewmyprivateinfo' ) ) {
-                       if ( isset( $this->prop['email'] ) ) {
-                               $vals['email'] = $user->getEmail();
-                               $auth = $user->getEmailAuthenticationTimestamp();
-                               if ( !is_null( $auth ) ) {
-                                       $vals['emailauthenticated'] = wfTimestamp( TS_ISO_8601, $auth );
-                               }
+               if ( $user->isAllowed( 'viewmyprivateinfo' ) && isset( $this->prop['email'] ) ) {
+                       $vals['email'] = $user->getEmail();
+                       $auth = $user->getEmailAuthenticationTimestamp();
+                       if ( $auth !== null ) {
+                               $vals['emailauthenticated'] = wfTimestamp( TS_ISO_8601, $auth );
                        }
                }
 
@@ -251,6 +249,13 @@ class ApiQueryUserInfo extends ApiQueryBase {
                        );
                }
 
+               if ( isset( $this->prop['latestcontrib'] ) ) {
+                       $ts = $this->getLatestContributionTime();
+                       if ( $ts !== null ) {
+                               $vals['latestcontrib'] = $ts;
+                       }
+               }
+
                return $vals;
        }
 
@@ -293,6 +298,40 @@ class ApiQueryUserInfo extends ApiQueryBase {
                return $retval;
        }
 
+       /**
+        * @return string|null ISO 8601 timestamp of current user's last contribution or null if none
+        */
+       protected function getLatestContributionTime() {
+               global $wgActorTableSchemaMigrationStage;
+
+               $user = $this->getUser();
+               $dbr = $this->getDB();
+
+               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
+                       if ( $user->getActorId() === null ) {
+                               return null;
+                       }
+                       $res = $dbr->selectField( 'revision_actor_temp',
+                               'MAX(revactor_timestamp)',
+                               [ 'revactor_actor' => $user->getActorId() ],
+                               __METHOD__
+                       );
+               } else {
+                       if ( $user->isLoggedIn() ) {
+                               $conds = [ 'rev_user' => $user->getId() ];
+                       } else {
+                               $conds = [ 'rev_user_text' => $user->getName() ];
+                       }
+                       $res = $dbr->selectField( 'revision',
+                               'MAX(rev_timestamp)',
+                               $conds,
+                               __METHOD__
+                       );
+               }
+
+               return $res ? wfTimestamp( TS_ISO_8601, $res ) : null;
+       }
+
        public function getAllowedParams() {
                return [
                        'prop' => [
@@ -315,6 +354,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
                                        'unreadcount',
                                        'centralids',
                                        'preferencestoken',
+                                       'latestcontrib',
                                ],
                                ApiBase::PARAM_HELP_MSG_PER_VALUE => [
                                        'unreadcount' => [
index 824c4d5..66d8db4 100644 (file)
@@ -168,7 +168,7 @@ class ApiQueryUsers extends ApiQueryBase {
                                }
 
                                $this->addTables( 'user_groups' );
-                               $this->addJoinConds( [ 'user_groups' => [ 'INNER JOIN', 'ug_user=user_id' ] ] );
+                               $this->addJoinConds( [ 'user_groups' => [ 'JOIN', 'ug_user=user_id' ] ] );
                                $this->addFields( [ 'user_name' ] );
                                $this->addFields( UserGroupMembership::selectFields() );
                                $this->addWhere( 'ug_expiry IS NULL OR ug_expiry >= ' .
index 236f6e0..578a908 100644 (file)
@@ -81,10 +81,8 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        $this->fld_loginfo = isset( $prop['loginfo'] );
                        $this->fld_tags = isset( $prop['tags'] );
 
-                       if ( $this->fld_patrol ) {
-                               if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
-                                       $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'patrol' );
-                               }
+                       if ( $this->fld_patrol && !$user->useRCPatrol() && !$user->useNPPatrol() ) {
+                               $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'patrol' );
                        }
 
                        if ( $this->fld_comment || $this->fld_parsedcomment ) {
@@ -180,7 +178,6 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                ] );
 
                $ids = [];
-               $count = 0;
                $watchedItemQuery = MediaWikiServices::getInstance()->getWatchedItemQueryService();
                $items = $watchedItemQuery->getWatchedItemsWithRecentChangeInfo( $wlowner, $options, $startFrom );
 
@@ -193,12 +190,10 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                                        $startFrom = [ $recentChangeInfo['rc_timestamp'], $recentChangeInfo['rc_id'] ];
                                        break;
                                }
+                       } elseif ( $params['allrev'] ) {
+                               $ids[] = (int)$recentChangeInfo['rc_this_oldid'];
                        } else {
-                               if ( $params['allrev'] ) {
-                                       $ids[] = (int)$recentChangeInfo['rc_this_oldid'];
-                               } else {
-                                       $ids[] = (int)$recentChangeInfo['rc_cur_id'];
-                               }
+                               $ids[] = (int)$recentChangeInfo['rc_cur_id'];
                        }
                }
 
index c4a31c7..c27b10e 100644 (file)
@@ -498,7 +498,7 @@ class ApiResult implements ApiSerializable {
                        throw new InvalidArgumentException( 'Content value must be named' );
                }
                $this->addContentField( $path, $name, $flags );
-               $this->addValue( $path, $name, $value, $flags );
+               return $this->addValue( $path, $name, $value, $flags );
        }
 
        /**
index c9ebfa8..ba4c6e8 100644 (file)
@@ -108,14 +108,7 @@ class ApiSetNotificationTimestamp extends ApiBase {
                $result = [];
                if ( $params['entirewatchlist'] ) {
                        // Entire watchlist mode: Just update the thing and return a success indicator
-                       if ( is_null( $timestamp ) ) {
-                               $watchedItemStore->resetAllNotificationTimestampsForUser( $user );
-                       } else {
-                               $watchedItemStore->setNotificationTimestampsForUser(
-                                       $user,
-                                       $timestamp
-                               );
-                       }
+                       $watchedItemStore->resetAllNotificationTimestampsForUser( $user, $timestamp );
 
                        $result['notificationtimestamp'] = is_null( $timestamp )
                                ? ''
index 17c8040..5184562 100644 (file)
@@ -46,6 +46,8 @@ class ApiStashEdit extends ApiBase {
        const MAX_CACHE_TTL = 300; // 5 minutes
        const MAX_SIGNATURE_TTL = 60;
 
+       const MAX_CACHE_RECENT = 2;
+
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
@@ -169,7 +171,6 @@ class ApiStashEdit extends ApiBase {
         * @since 1.25
         */
        public static function parseAndStash( WikiPage $page, Content $content, User $user, $summary ) {
-               $cache = ObjectCache::getLocalClusterInstance();
                $logger = LoggerFactory::getInstance( 'StashEdit' );
 
                $title = $page->getTitle();
@@ -195,7 +196,7 @@ class ApiStashEdit extends ApiBase {
                $cutoffTime = time() - self::PRESUME_FRESH_TTL_SEC;
 
                // Reuse any freshly build matching edit stash cache
-               $editInfo = $cache->get( $key );
+               $editInfo = self::getStashValue( $key );
                if ( $editInfo && wfTimestamp( TS_UNIX, $editInfo->timestamp ) >= $cutoffTime ) {
                        $alreadyCached = true;
                } else {
@@ -216,29 +217,27 @@ class ApiStashEdit extends ApiBase {
                                return self::ERROR_NONE;
                        }
 
-                       list( $stashInfo, $ttl, $code ) = self::buildStashValue(
+                       $code = self::storeStashValue(
+                               $key,
                                $editInfo->pstContent,
                                $editInfo->output,
                                $editInfo->timestamp,
                                $user
                        );
 
-                       if ( $stashInfo ) {
-                               $ok = $cache->set( $key, $stashInfo, $ttl );
-                               if ( $ok ) {
-                                       $logger->debug( "Cached parser output for key '{cachekey}' ('{title}').",
-                                               [ 'cachekey' => $key, 'title' => $titleStr ] );
-                                       return self::ERROR_NONE;
-                               } else {
-                                       $logger->error( "Failed to cache parser output for key '{cachekey}' ('{title}').",
-                                               [ 'cachekey' => $key, 'title' => $titleStr ] );
-                                       return self::ERROR_CACHE;
-                               }
-                       } else {
-                               // @todo Doesn't seem reachable, see @todo in buildStashValue
-                               $logger->info( "Uncacheable parser output for key '{cachekey}' ('{title}') [{code}].",
+                       if ( $code === true ) {
+                               $logger->debug( "Cached parser output for key '{cachekey}' ('{title}').",
+                                       [ 'cachekey' => $key, 'title' => $titleStr ] );
+                               return self::ERROR_NONE;
+                       } elseif ( $code === 'uncacheable' ) {
+                               $logger->info(
+                                       "Uncacheable parser output for key '{cachekey}' ('{title}') [{code}].",
                                        [ 'cachekey' => $key, 'title' => $titleStr, 'code' => $code ] );
                                return self::ERROR_UNCACHEABLE;
+                       } else {
+                               $logger->error( "Failed to cache parser output for key '{cachekey}' ('{title}').",
+                                       [ 'cachekey' => $key, 'title' => $titleStr, 'code' => $code ] );
+                               return self::ERROR_CACHE;
                        }
                }
 
@@ -267,12 +266,11 @@ class ApiStashEdit extends ApiBase {
                        return false; // bots never stash - don't pollute stats
                }
 
-               $cache = ObjectCache::getLocalClusterInstance();
                $logger = LoggerFactory::getInstance( 'StashEdit' );
                $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
 
                $key = self::getStashKey( $title, self::getContentHash( $content ), $user );
-               $editInfo = $cache->get( $key );
+               $editInfo = self::getStashValue( $key );
                if ( !is_object( $editInfo ) ) {
                        $start = microtime( true );
                        // We ignore user aborts and keep parsing. Block on any prior parsing
@@ -282,7 +280,7 @@ class ApiStashEdit extends ApiBase {
                        $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
                        $dbw = $lb->getAnyOpenConnection( $lb->getWriterIndex() );
                        if ( $dbw && $dbw->lock( $key, __METHOD__, 30 ) ) {
-                               $editInfo = $cache->get( $key );
+                               $editInfo = self::getStashValue( $key );
                                $dbw->unlock( $key, __METHOD__ );
                        }
 
@@ -378,7 +376,7 @@ class ApiStashEdit extends ApiBase {
         */
        private static function getStashKey( Title $title, $contentHash, User $user ) {
                return ObjectCache::getLocalClusterInstance()->makeKey(
-                       'prepared-edit',
+                       'stashed-edit-info',
                        md5( $title->getPrefixedDBkey() ),
                        // Account for the edit model/text
                        $contentHash,
@@ -387,46 +385,108 @@ class ApiStashEdit extends ApiBase {
                );
        }
 
+       /**
+        * @param string $uuid
+        * @return string
+        */
+       private static function getStashParserOutputKey( $uuid ) {
+               return ObjectCache::getLocalClusterInstance()->makeKey( 'stashed-edit-output', $uuid );
+       }
+
+       /**
+        * @param string $key
+        * @return stdClass|bool Object map (pstContent,output,outputID,timestamp,edits) or false
+        */
+       private static function getStashValue( $key ) {
+               $cache = ObjectCache::getLocalClusterInstance();
+
+               $stashInfo = $cache->get( $key );
+               if ( !is_object( $stashInfo ) ) {
+                       return false;
+               }
+
+               $parserOutputKey = self::getStashParserOutputKey( $stashInfo->outputID );
+               $parserOutput = $cache->get( $parserOutputKey );
+               if ( $parserOutput instanceof ParserOutput ) {
+                       $stashInfo->output = $parserOutput;
+
+                       return $stashInfo;
+               }
+
+               return false;
+       }
+
        /**
         * Build a value to store in memcached based on the PST content and parser output
         *
         * This makes a simple version of WikiPage::prepareContentForEdit() as stash info
         *
+        * @param string $key
         * @param Content $pstContent Pre-Save transformed content
         * @param ParserOutput $parserOutput
         * @param string $timestamp TS_MW
         * @param User $user
-        * @return array (stash info array, TTL in seconds, info code) or (null, 0, info code)
+        * @return string|bool True or an error code
         */
-       private static function buildStashValue(
-               Content $pstContent, ParserOutput $parserOutput, $timestamp, User $user
+       private static function storeStashValue(
+               $key, Content $pstContent, ParserOutput $parserOutput, $timestamp, User $user
        ) {
                // If an item is renewed, mind the cache TTL determined by config and parser functions.
                // Put an upper limit on the TTL for sanity to avoid extreme template/file staleness.
-               $since = time() - wfTimestamp( TS_UNIX, $parserOutput->getCacheTime() );
-               $ttl = min( $parserOutput->getCacheExpiry() - $since, self::MAX_CACHE_TTL );
-
+               $age = time() - wfTimestamp( TS_UNIX, $parserOutput->getCacheTime() );
+               $ttl = min( $parserOutput->getCacheExpiry() - $age, self::MAX_CACHE_TTL );
                // Avoid extremely stale user signature timestamps (T84843)
                if ( $parserOutput->getFlag( 'user-signature' ) ) {
                        $ttl = min( $ttl, self::MAX_SIGNATURE_TTL );
                }
 
                if ( $ttl <= 0 ) {
-                       // @todo It doesn't seem like this can occur, because it would mean an entry older than
-                       // getCacheExpiry() seconds, which is much longer than PRESUME_FRESH_TTL_SEC, and
-                       // anything older than PRESUME_FRESH_TTL_SEC will have been thrown out already.
-                       return [ null, 0, 'no_ttl' ];
+                       return 'uncacheable'; // low TTL due to a tag, magic word, or signature?
                }
 
-               // Only store what is actually needed
+               // Store what is actually needed and split the output into another key (T204742)
+               $parseroutputID = md5( $key );
                $stashInfo = (object)[
                        'pstContent' => $pstContent,
-                       'output'     => $parserOutput,
+                       'outputID'   => $parseroutputID,
                        'timestamp'  => $timestamp,
                        'edits'      => $user->getEditCount()
                ];
 
-               return [ $stashInfo, $ttl, 'ok' ];
+               $cache = ObjectCache::getLocalClusterInstance();
+               $ok = $cache->set( $key, $stashInfo, $ttl );
+               if ( $ok ) {
+                       $ok = $cache->set(
+                               self::getStashParserOutputKey( $parseroutputID ),
+                               $parserOutput,
+                               $ttl
+                       );
+               }
+
+               if ( $ok ) {
+                       // These blobs can waste slots in low cardinality memcached slabs
+                       self::pruneExcessStashedEntries( $cache, $user, $key );
+               }
+
+               return $ok ? true : 'store_error';
+       }
+
+       /**
+        * @param BagOStuff $cache
+        * @param User $user
+        * @param string $newKey
+        */
+       private static function pruneExcessStashedEntries( BagOStuff $cache, User $user, $newKey ) {
+               $key = $cache->makeKey( 'stash-edit-recent', sha1( $user->getName() ) );
+
+               $keyList = $cache->get( $key ) ?: [];
+               if ( count( $keyList ) >= self::MAX_CACHE_RECENT ) {
+                       $oldestKey = array_shift( $keyList );
+                       $cache->delete( $oldestKey );
+               }
+
+               $keyList[] = $newKey;
+               $cache->set( $key, $keyList, 2 * self::MAX_CACHE_TTL );
        }
 
        public function getAllowedParams() {
index 07a6aae..5f9b97c 100644 (file)
@@ -31,7 +31,8 @@ class ApiUndelete extends ApiBase {
                $params = $this->extractRequestParams();
 
                $user = $this->getUser();
-               if ( $user->isBlocked() ) {
+               $block = $user->getBlock();
+               if ( $block && $block->isSitewide() ) {
                        $this->dieBlocked( $user->getBlock() );
                }
 
index 2c5b583..fc41e4e 100644 (file)
@@ -417,7 +417,7 @@ class ApiUpload extends ApiBase {
                if ( $this->mParams['filekey'] && $this->mParams['checkstatus'] ) {
                        $progress = UploadBase::getSessionStatus( $this->getUser(), $this->mParams['filekey'] );
                        if ( !$progress ) {
-                               $this->dieWithError( 'api-upload-missingresult', 'missingresult' );
+                               $this->dieWithError( 'apierror-upload-missingresult', 'missingresult' );
                        } elseif ( !$progress['status']->isGood() ) {
                                $this->dieStatusWithCode( $progress['status'], 'stashfailed' );
                        }
@@ -542,7 +542,7 @@ class ApiUpload extends ApiBase {
                }
 
                // Check blocks
-               if ( $user->isBlocked() ) {
+               if ( $user->isBlockedFromUpload() ) {
                        $this->dieBlocked( $user->getBlock() );
                }
 
index 0912dc0..cf9785e 100644 (file)
        "apihelp-parse-paramvalue-prop-revid": "يضيف معرِف المراجعة للصفحة التي تم تحليلها.",
        "apihelp-parse-paramvalue-prop-displaytitle": "يضيف العنوان في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-headitems": "يعطي عناصر لوضعها في <code>&lt;head&gt;</code> الصفحة.",
-       "apihelp-parse-paramvalue-prop-headhtml": "يعطي تحليل <code>&lt;head&gt;</code> الصفحة.",
+       "apihelp-parse-paramvalue-prop-headhtml": "يمنح نوع مستند محلولا، ويفتح عنصر <code>&lt;html&gt;</code>، <code>&lt;head&gt;</code> ويفتح <code>&lt;body&gt;</code> الصفحة.",
        "apihelp-parse-paramvalue-prop-modules": "يعطي وحدات ResourceLoader المستخدمة في الصفحة، للتحميل; استخدم <code>mw.loader.using()</code>، يجب طلب <kbd>jsconfigvars</kbd> أو <kbd>encodedjsconfigvars</kbd> بشكل مشترك مع <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة. للتطبيق; استخدم <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة كسلسلة JSON.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "يضيف تاريخ تسجيل المستخدم.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "يضيف عدد الصفحات غير المقروءة في قائمة مراقبة المستخدم (بحد أقصى $1; ترجع <samp>$2</samp> إذا كان أكثر).",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "يضيف المعرفات المركزية وحالة المرفقات للمستخدم.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "يضيف تاريخ آخر مساهمة للمستخدم.",
        "apihelp-query+userinfo-param-attachedwiki": "باستخدام <kbd>$1prop=centralids</kbd>، حدد ما إذا كان المستخدم مرتبطا بالويكي المحدد بواسطة هذا المعرف.",
        "apihelp-query+userinfo-example-simple": "الحصول على معلومات حول المستخدم الحالي.",
        "apihelp-query+userinfo-example-data": "الحصول على معلومات حول المستخدم الحالي.",
index dd69004..75fa8e3 100644 (file)
@@ -12,7 +12,8 @@
                        "LordMsz",
                        "Dvorapa",
                        "Matěj Suchánek",
-                       "Ilimanaq29"
+                       "Ilimanaq29",
+                       "Patriccck"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentace]]\n* [[mw:Special:MyLanguage/API:FAQ|Otázky a odpovědi]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-mailová konference]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Oznámení k API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Chyby a požadavky]\n</div>\n<strong>Stav:</strong> Všechny funkce uvedené na této stránce by měly fungovat, ale API se stále aktivně vyvíjí a může se kdykoli změnit. Upozornění na změny získáte přihlášením se k [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-mailové konferenci mediawiki-api-announce].\n\n<strong>Chybné požadavky:</strong> Pokud jsou do API zaslány chybné požadavky, bude vrácena HTTP hlavička s klíčem „MediaWiki-API-Error“ a hodnota této hlavičky a chybový kód budou nastaveny na stejnou hodnotu. Více informací najdete [[mw:Special:MyLanguage/API:Errors_and_warnings|v dokumentaci]].\n\n<p class=\"mw-apisandbox-link\"><strong>Testování:</strong> Pro jednoduché testování požadavků na API zkuste [[Special:ApiSandbox]].</p>",
        "api-help-flag-generator": "Tento modul lze využívat jako generátor.",
        "api-help-source": "Zdroj: $1",
        "api-help-license": "Licence: [[$1|$2]]",
-       "api-help-license-noname": "Licence: [[$1|Vizte odkaz]]",
+       "api-help-license-noname": "Licence: [[$1|Viz odkaz]]",
        "api-help-license-unknown": "Licence: <span class=\"apihelp-unknown\">neznámá</span>",
        "api-help-parameters": "{{PLURAL:$1|Parametr|Parametry}}:",
        "api-help-param-deprecated": "Zastaralý.",
        "apierror-blocked": "Byla vám zablokována možnost editace.",
        "apierror-mustbeloggedin": "Abyste mohli $1, musíte být přihlášeni.",
        "apierror-nosuchsection-what": "$2 neobsahuje sekci $1.",
+       "apierror-readonly": "Wiki je právě v módu pro čtení a nelze ji editovat.",
        "apierror-sectionsnotsupported-what": "$1 nepodporuje sekce.",
        "apierror-timeout": "Server neodpověděl v očekávaném čase.",
        "api-credits-header": "Zásluhy",
index 4cad07f..54d6cc5 100644 (file)
@@ -20,7 +20,8 @@
                        "Eddie",
                        "Zenith",
                        "Tacsipacsi",
-                       "FF11"
+                       "FF11",
+                       "DerHexer"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentation]]\n* [[mw:Special:MyLanguage/API:FAQ|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Die MediaWiki-API ist eine ausgereifte und stabile Schnittstelle, die aktiv unterstützt und verbessert wird. Während wir versuchen, dies zu vermeiden, können wir gelegentlich Breaking Changes erforderlich machen. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste] für Mitteilungen zu Aktualisierungen.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Fehler und Warnungen]].\n\n<p class=\"mw-apisandbox-link\"><strong>Testen:</strong> Zum einfachen Testen von API-Anfragen, siehe [[Special:ApiSandbox]].</p>",
        "apihelp-compare-param-fromtitle": "Erster zu vergleichender Titel.",
        "apihelp-compare-param-fromid": "Erste zu vergleichende Seitennummer.",
        "apihelp-compare-param-fromrev": "Erste zu vergleichende Version.",
+       "apihelp-compare-param-frompst": "Führt eine Vorspeicherungsumwandlung für <var>fromtext-&#x7B;slot}</var> aus.",
+       "apihelp-compare-param-fromsection": "Nur den angegebenen Abschnitt des angegebenen „from“-Inhalts verwenden.",
        "apihelp-compare-param-totitle": "Zweiter zu vergleichender Titel.",
        "apihelp-compare-param-toid": "Zweite zu vergleichende Seitennummer.",
        "apihelp-compare-param-torev": "Zweite zu vergleichende Version.",
+       "apihelp-compare-param-topst": "Führt eine Vorspeicherungsumwandlung für <var>totext</var> aus.",
+       "apihelp-compare-param-prop": "Welche Informationen abgerufen werden sollen.",
        "apihelp-compare-paramvalue-prop-diff": "Das Unterschieds-HTML.",
        "apihelp-compare-paramvalue-prop-diffsize": "Die Größe des Unterschieds-HTML in Bytes.",
        "apihelp-compare-paramvalue-prop-title": "Die Seitentitel der Versionen „Von“ und „Nach“.",
+       "apihelp-compare-paramvalue-prop-user": "Der Benutzername und die -kennung der „from“- und „to“-Versionen.",
+       "apihelp-compare-paramvalue-prop-comment": "Der Kommentar zu den „from“- und „to“-Versionen.",
+       "apihelp-compare-paramvalue-prop-parsedcomment": "Der geparste Kommentar zu den „from“- und „to“-Versionen.",
        "apihelp-compare-paramvalue-prop-size": "Die Größe der Versionen „from“ und „to“.",
        "apihelp-compare-example-1": "Unterschied zwischen Version 1 und 2 abrufen",
        "apihelp-createaccount-summary": "Erstellt ein neues Benutzerkonto.",
        "apihelp-createaccount-param-preservestate": "Falls <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> für <samp>hasprimarypreservedstate</samp> wahr ausgegeben hat, sollten Anfragen, die als <samp>primary-required</samp> markiert wurden, ausgelassen werden. Falls ein nicht-leerer Wert für <samp>preservedusername</samp> zurückgegeben wurde, muss dieser Benutzername für den Parameter <var>username</var> verwendet werden.",
+       "apihelp-cspreport-param-source": "Was der CSP-Header erzeugt hat, der diesen Bericht ausgelöst hat.",
        "apihelp-delete-summary": "Löscht eine Seite.",
        "apihelp-delete-param-title": "Titel der Seite, die gelöscht werden soll. Kann nicht zusammen mit <var>$1pageid</var> verwendet werden.",
        "apihelp-delete-param-pageid": "Seitennummer der Seite, die gelöscht werden soll. Kann nicht zusammen mit <var>$1title</var> verwendet werden.",
        "apihelp-parse-paramvalue-prop-sections": "Gibt die Abschnitte im geparsten Wikitext zurück.",
        "apihelp-parse-paramvalue-prop-revid": "Ergänzt die Versionskennung der geparsten Seite.",
        "apihelp-parse-paramvalue-prop-displaytitle": "Ergänzt den Titel des geparsten Wikitextes.",
-       "apihelp-parse-paramvalue-prop-headhtml": "Gibt geparsten <code>&lt;head&gt;</code> der Seite zurück.",
+       "apihelp-parse-paramvalue-prop-headhtml": "Gibt geparsten doctype, offenes <code>&lt;html&gt;</code>, das Element <code>&lt;head&gt;</code> und offenes <code>&lt;body&gt;</code> der Seite aus.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "Gibt die JavaScript-Konfigurationsvariablen speziell für die Seite aus. Zur Anwendung verwende <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Gibt die JavaScript-Konfigurationsvariablen speziell für die Seite als JSON-Zeichenfolge aus.",
        "apihelp-parse-paramvalue-prop-indicators": "Gibt das HTML der Seitenstatusindikatoren zurück, die auf der Seite verwendet werden.",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Fügt den Dateinamen der Archivversion für die nicht-neuesten Versionen hinzu.",
        "apihelp-query+filearchive-example-simple": "Eine Liste aller gelöschten Dateien auflisten",
        "apihelp-query+filerepoinfo-summary": "Gebe Metainformationen über Bild-Repositorien zurück, die im Wiki eingerichtet sind.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL zur Repositoriums-API. Nützlich zum Abruf von Bildinformationen vom Host.",
        "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "Der menschenlesbare Name des Repositoriumwikis.",
        "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "Ob Dateinamen implizit mit einem Großbuchstaben beginnen.",
        "apihelp-query+filerepoinfo-paramvalue-prop-local": "Ob dieses Repositorium das lokale ist oder nicht.",
        "apihelp-query+recentchanges-paramvalue-prop-title": "Ergänzt den Seitentitel der Bearbeitung.",
        "apihelp-query+recentchanges-paramvalue-prop-autopatrolled": "Markiert kontrollierbare Bearbeitungen als automatisch kontrolliert oder nicht.",
        "apihelp-query+recentchanges-paramvalue-prop-tags": "Listet Markierungen für den Eintrag auf.",
+       "apihelp-query+recentchanges-param-limit": "Wie viele Änderungen insgesamt zurückgegeben werden sollen.",
+       "apihelp-query+recentchanges-param-type": "Welche Typen von Änderungen angezeigt werden sollen.",
        "apihelp-query+recentchanges-example-simple": "Listet die letzten Änderungen auf.",
        "apihelp-query+redirects-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+redirects-paramvalue-prop-pageid": "Seitenkennung einer jeden Weiterleitung.",
        "apihelp-query+redirects-paramvalue-prop-title": "Titel einer jeden Weiterleitung.",
+       "apihelp-query+redirects-paramvalue-prop-fragment": "Teil einer jeden Weiterleitung, falls vorhanden.",
        "apihelp-query+redirects-param-namespace": "Schließt nur Seiten in diesen Namensräumen ein.",
        "apihelp-query+redirects-param-limit": "Wie viele Weiterleitungen zurückgegeben werden sollen.",
        "apihelp-query+revisions-summary": "Ruft Informationen zur Version ab.",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "SHA-1-Prüfsumme (Basis 16) der Version.",
        "apihelp-query+revisions+base-paramvalue-prop-slotsha1": "SHA-1 (Basis 16) eines jeden Versionsschlitzes.",
        "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "Inhaltsmodell-Kennung eines jeden Versionsschlitzes.",
+       "apihelp-query+revisions+base-paramvalue-prop-comment": "Kommentar des Benutzers für die Version.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "Inhalt eines jeden Versionsschlitzes.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Markierungen für die Version.",
        "apihelp-query+revisions+base-paramvalue-prop-roles": "Die Liste enthält Schlitzregeln, die in der Version vorhanden sind.",
        "apihelp-query+search-param-qiprofile": "Zu verwendendes anfrageunabhängiges Profil (wirkt sich auf den Ranking-Algorithmus aus).",
        "apihelp-query+search-paramvalue-prop-wordcount": "Ergänzt den Wortzähler der Seite.",
        "apihelp-query+search-paramvalue-prop-extensiondata": "Ergänzt zusätzliche von Erweiterungen erzeugte Daten.",
+       "apihelp-query+search-paramvalue-prop-score": "Ignoriert.",
        "apihelp-query+search-paramvalue-prop-hasrelated": "Ignoriert.",
        "apihelp-query+search-param-limit": "Wie viele Seiten insgesamt zurückgegeben werden sollen.",
        "apihelp-query+search-param-sort": "Legt die Sortierreihenfolge der zurückgegebenen Ergebnisse fest.",
        "apihelp-query+tokens-param-type": "Typen der Token, die abgerufen werden sollen.",
        "apihelp-query+transcludedin-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+transcludedin-paramvalue-prop-pageid": "Seitenkennung jeder Seite.",
+       "apihelp-query+transcludedin-paramvalue-prop-title": "Titel jeder Seite.",
        "apihelp-query+usercontribs-summary": "Alle Bearbeitungen von einem Benutzer abrufen.",
        "apihelp-query+usercontribs-param-limit": "Die maximale Anzahl der zurückzugebenden Beiträge.",
        "apihelp-query+usercontribs-param-start": "Der zurückzugebende Start-Zeitstempel.",
        "apihelp-query+userinfo-paramvalue-prop-options": "Listet alle Einstellungen auf, die der aktuelle Benutzer festgelegt hat.",
        "apihelp-query+userinfo-paramvalue-prop-editcount": "Ergänzt den Bearbeitungszähler des aktuellen Benutzers.",
        "apihelp-query+userinfo-paramvalue-prop-realname": "Fügt den bürgerlichen Namen des Benutzers hinzu.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "Ergänzt das Datum des letzten Benutzerbeitrags.",
        "apihelp-query+userinfo-example-simple": "Informationen über den aktuellen Benutzer abrufen",
        "apihelp-query+userinfo-example-data": "Ruft zusätzliche Informationen über den aktuellen Benutzer ab.",
        "apihelp-query+users-summary": "Informationen über eine Liste von Benutzern abrufen.",
        "apihelp-setpagelanguage-param-tags": "Auf den Logbucheintrag anzuwendende Änderungsmarkierungen, die sich aus dieser Aktion ergeben.",
        "apihelp-setpagelanguage-example-language": "Ändert die Sprache von <kbd>Hauptseite</kbd> auf Baskisch.",
        "apihelp-setpagelanguage-example-default": "Ändert die Sprache der Seite mit der Kennung 123 auf die Standardinhaltssprache des Wikis.",
+       "apihelp-stashedit-param-title": "Titel der Seite, die bearbeitet werden soll.",
        "apihelp-stashedit-param-sectiontitle": "Der Titel für einen neuen Abschnitt.",
        "apihelp-stashedit-param-text": "Seiteninhalt.",
        "apihelp-stashedit-param-stashedtexthash": "Stattdessen zu verwendende Prüfsumme des Seiteninhalts von einem vorherigen Speicher.",
        "apierror-maxbytes": "Der Parameter <var>$1</var> kann nicht länger sein als {{PLURAL:$2|ein Byte|$2 Bytes}}",
        "apierror-maxchars": "Der Parameter <var>$1</var> kann nicht länger sein als {{PLURAL:$2|ein|$2}} Zeichen",
        "apierror-missingcontent-revid-role": "Fehlender Inhalt für die Versionskennung $1 für die Rolle $2.",
+       "apierror-mustbeloggedin": "Du musst eingeloggt sein, um $1.",
        "apierror-nosuchsection": "Es gibt keinen Abschnitt $1.",
        "apierror-nosuchuserid": "Es gibt keinen Benutzer mit der Kennung $1.",
        "apierror-offline": "Aufgrund von Problemen bei der Netzwerkverbindung kannst du nicht weitermachen. Stelle sicher, dass du eine funktionierende Internetverbindung hast und versuche es erneut.",
index 25df749..0d4874c 100644 (file)
        "apihelp-parse-paramvalue-prop-revid": "Adds the revision ID of the parsed page.",
        "apihelp-parse-paramvalue-prop-displaytitle": "Adds the title of the parsed wikitext.",
        "apihelp-parse-paramvalue-prop-headitems": "Gives items to put in the <code>&lt;head&gt;</code> of the page.",
-       "apihelp-parse-paramvalue-prop-headhtml": "Gives parsed <code>&lt;head&gt;</code> of the page.",
+       "apihelp-parse-paramvalue-prop-headhtml": "Gives parsed doctype, opening <code>&lt;html&gt;</code>, <code>&lt;head&gt;</code> element and opening <code>&lt;body&gt;</code> of the page.",
        "apihelp-parse-paramvalue-prop-modules": "Gives the ResourceLoader modules used on the page. To load, use <code>mw.loader.using()</code>. Either <kbd>jsconfigvars</kbd> or <kbd>encodedjsconfigvars</kbd> must be requested jointly with <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "Gives the JavaScript configuration variables specific to the page. To apply, use <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Gives the JavaScript configuration variables specific to the page as a JSON string.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Adds the user's registration date.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Adds the count of unread pages on the user's watchlist (maximum $1; returns <samp>$2</samp> if more).",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "Adds the central IDs and attachment status for the user.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "Adds the date of user's latest contribution.",
        "apihelp-query+userinfo-param-attachedwiki": "With <kbd>$1prop=centralids</kbd>, indicate whether the user is attached with the wiki identified by this ID.",
        "apihelp-query+userinfo-example-simple": "Get information about the current user.",
        "apihelp-query+userinfo-example-data": "Get additional information about the current user.",
index 6862e63..4b336c3 100644 (file)
@@ -40,7 +40,7 @@
        "apihelp-main-param-action": "Qué acción se realizará.",
        "apihelp-main-param-format": "El formato de la salida.",
        "apihelp-main-param-maxlag": "Se puede usar el retardo máximo cuando se instala MediaWiki en un clúster replicado de base de datos. Para evitar acciones que causen más retardo en la replicación del sitio, este parámetro puede hacer que el cliente espere hasta que el retardo en la replicación sea menor que el valor especificado. En caso de retardo excesivo, se devuelve el código de error <samp>maxlag</samp> con un mensaje como <samp>Esperando a $host: $lag segundos de retardo</samp>.<br />Consulta [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: parámetro Maxlag]] para más información.",
-       "apihelp-main-param-smaxage": "Establece la cabecera HTTP <code>s-maxage</code> de control de antememoria a esta cantidad de segundos. Los errores nunca se almacenan en la antememoria.",
+       "apihelp-main-param-smaxage": "Establece la cabecera HTTP <code>s-maxage</code> de control de caché a esta cantidad de segundos. Los errores nunca se almacenan en caché.",
        "apihelp-main-param-maxage": "Establece la cabecera HTTP <code>max-age</code> de control de antememoria a esta cantidad de segundos. Los errores nunca se almacenan en la antememoria.",
        "apihelp-main-param-assert": "Comprobar que el usuario haya iniciado sesión si el valor es <kbd>user</kbd> o si tiene el permiso de bot si es <kbd>bot</kbd>.",
        "apihelp-main-param-assertuser": "Verificar el usuario actual es el usuario nombrado.",
index 64107fc..30c73ce 100644 (file)
@@ -4,6 +4,135 @@
                        "Pikne"
                ]
        },
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentatsioon]]\n* [[mw:Special:MyLanguage/API:FAQ|KKK]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Postiloend]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API teadaanded]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Vead ja taotlused]\n</div>\n<strong>Olek:</strong> MediaWiki API on kasutusküps ja stabiilne liides, millel on olemas tugi ja mida täiustatakse aktiivselt. Püüame seda küll vältida, aga mõnikord võib olla vajalik teha muudatusi, mille järel liides ei toimi enam varasemal kujul. Telli postiloend [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce], et saada teavitusi uuenduste kohta.\n\n<strong>Vigased päringud:</strong> Kui API-le saadetakse vigane päring, saadetakse HTTP päis võtmega \"MediaWiki-API-Error\" ning päisele ja tagastatavale veakoodile määratakse sama väärtus. Täpsemalt loe dokumentatsioonist: [[mw:Special:MyLanguage/API:Errors_and_warnings|API: veateated ja hoiatused]].\n\n<p class=\"mw-apisandbox-link\"><strong>Katsetamine:</strong> Et API päringuid lihtsamini katsetada, saad kasutada lehekülge [[Special:ApiSandbox]].</p>",
+       "apihelp-main-param-action": "Sooritatav toiming.",
+       "apihelp-main-param-format": "Väljundi vorming.",
+       "apihelp-compare-param-prop": "Millised teabe elemendid hankida.",
+       "apihelp-edit-param-bot": "Märgi see muudatus robotimuudatuseks.",
+       "apihelp-expandtemplates-param-prop": "Millised teabe elemendid hankida.\n\nPane tähele, et kui väärtusi pole valitud, siis sisaldab tulemus vikiteksti, aga väljund on ebasoovitatavas vormingus.",
+       "apihelp-feedcontributions-param-feedformat": "Voo väljund.",
+       "apihelp-feedcontributions-param-user": "Milliste kasutajate kaastöö hankida.",
+       "apihelp-feedcontributions-param-namespace": "Millise nimeruumi järgi kaastöö filtreerida.",
+       "apihelp-feedrecentchanges-param-feedformat": "Voo väljund.",
+       "apihelp-feedwatchlist-param-feedformat": "Voo väljund.",
+       "apihelp-help-param-helpformat": "Abiväljundi vorming.",
+       "apihelp-help-example-main": "Põhimooduli abi.",
+       "apihelp-opensearch-param-format": "Väljundi vorming.",
+       "apihelp-parse-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query-param-prop": "Millised atribuudid päritavate lehekülgede kohta hankida.",
+       "apihelp-query-param-list": "Millised loendid hankida.",
+       "apihelp-query-param-meta": "Millised metaandmed hankida.",
+       "apihelp-query+allcategories-summary": "Loetle kõik kategooriad.",
+       "apihelp-query+allcategories-param-from": "Kategooria, millest alates loetleda.",
+       "apihelp-query+allcategories-param-to": "Kategooria, milleni loetleda.",
+       "apihelp-query+allcategories-param-dir": "Järjestuse suund.",
+       "apihelp-query+allcategories-param-limit": "Kui palju kategooriaid tagastada.",
+       "apihelp-query+allcategories-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+alldeletedrevisions-param-start": "Ajatempel, millest alates loetleda.",
+       "apihelp-query+alldeletedrevisions-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+alldeletedrevisions-param-tag": "Loetle ainult redaktsioonid, mille küljes on see märgis.",
+       "apihelp-query+alldeletedrevisions-param-excludeuser": "Ära loetle selle kasutaja redaktsioone.",
+       "apihelp-query+alldeletedrevisions-param-namespace": "Loetle ainult leheküljed selles nimeruumis.",
+       "apihelp-query+allfileusages-param-from": "Faili pealkiri, millest alates loetleda.",
+       "apihelp-query+allfileusages-param-to": "Faili pealkiri, milleni loetleda.",
+       "apihelp-query+allfileusages-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+allfileusages-param-limit": "Kui palju üksusi kokku tagastada.",
+       "apihelp-query+allfileusages-param-dir": "Järjestuse suund.",
+       "apihelp-query+allimages-summary": "Loetle kõik pildid järjestatult.",
+       "apihelp-query+allimages-param-dir": "Järjestuse suund.",
+       "apihelp-query+allimages-param-from": "Pildi pealkiri, millest alates loetleda. Saab kasutada ainult parameetriga $1sort=name.",
+       "apihelp-query+allimages-param-to": "Pildi pealkiri, milleni loetleda. Saab kasutada ainult parameetriga $1sort=name.",
+       "apihelp-query+allimages-param-start": "Ajatempel, millest alates loetleda. Saab kasutada ainult parameetriga $1sort=timestamp.",
+       "apihelp-query+allimages-param-end": "Ajatempel, milleni loetleda. Saab kasutada ainult parameetriga $1sort=timestamp.",
+       "apihelp-query+allimages-param-limit": "Kui palju pilte kokku tagastada.",
+       "apihelp-query+alllinks-summary": "Loetle kõik lingid, mis viitavad teatud nimeruumi.",
+       "apihelp-query+alllinks-param-from": "Lingi pealkiri, millest alates loetleda.",
+       "apihelp-query+alllinks-param-to": "Lingi pealkiri, milleni loetleda.",
+       "apihelp-query+alllinks-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+alllinks-param-namespace": "Loetlemise nimeruum.",
+       "apihelp-query+alllinks-param-limit": "Kui palju üksusi kokku tagastada.",
+       "apihelp-query+alllinks-param-dir": "Järjestuse suund.",
+       "apihelp-query+allmessages-param-prop": "Millised atribuudid hankida.",
+       "apihelp-query+allpages-summary": "Loetle kõik leheküljed järjestatult teatud nimeruumis.",
+       "apihelp-query+allpages-param-from": "Lehekülje pealkiri, millest alates loetleda.",
+       "apihelp-query+allpages-param-to": "Lehekülje pealkiri, milleni loetleda.",
+       "apihelp-query+allpages-param-namespace": "Loetlemise nimeruum.",
+       "apihelp-query+allpages-param-filterredir": "Millised leheküljed loetleda.",
+       "apihelp-query+allpages-param-limit": "Kui palju lehekülgi kokku tagastada.",
+       "apihelp-query+allpages-param-dir": "Järjestuse suund.",
+       "apihelp-query+allredirects-param-from": "Ümbersuunamise pealkiri, millest alates loetleda.",
+       "apihelp-query+allredirects-param-to": "Ümbersuunamise pealkiri, milleni loetleda.",
+       "apihelp-query+allredirects-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+allredirects-param-namespace": "Loetlemise nimeruum.",
+       "apihelp-query+allredirects-param-limit": "Kui palju üksusi kokku tagastada.",
+       "apihelp-query+allredirects-param-dir": "Järjestuse suund.",
+       "apihelp-query+allrevisions-param-start": "Ajatempel, millest alates loetleda.",
+       "apihelp-query+allrevisions-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+allrevisions-param-user": "Loetle ainult selle kasutaja redaktsioonid.",
+       "apihelp-query+allrevisions-param-excludeuser": "Ära loetle selle kasutaja redaktsioone.",
+       "apihelp-query+allrevisions-param-namespace": "Loetle ainult leheküljed selles nimeruumis.",
+       "apihelp-query+mystashedfiles-param-prop": "Millised atribuudid failide kohta hankida.",
+       "apihelp-query+mystashedfiles-param-limit": "Kui palju faile hankida.",
+       "apihelp-query+alltransclusions-param-from": "Mallina kasutatava lehekülje pealkiri, millest alates loetleda.",
+       "apihelp-query+alltransclusions-param-to": "Mallina kasutatava lehekülje pealkiri, milleni loetleda.",
+       "apihelp-query+alltransclusions-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+alltransclusions-param-namespace": "Loetlemise nimeruum.",
+       "apihelp-query+alltransclusions-param-limit": "Kui palju üksusi kokku tagastada.",
+       "apihelp-query+alltransclusions-param-dir": "Järjestuse suund.",
+       "apihelp-query+allusers-summary": "Loetle kõik registreeritud kasutajad.",
+       "apihelp-query+allusers-param-from": "Kasutajanimi, millest alates loetleda.",
+       "apihelp-query+allusers-param-to": "Kasutajanimi, milleni loetleda.",
+       "apihelp-query+allusers-param-dir": "Järjestuse suund.",
+       "apihelp-query+allusers-param-excludegroup": "Välja arvatud kasutajad, kes on neis rühmades.",
+       "apihelp-query+allusers-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+allusers-param-limit": "Kui palju kasutajanimesid kokku tagastada.",
+       "apihelp-query+allusers-param-witheditsonly": "Loetle ainult kasutajad, kes on teinud muudatusi.",
+       "apihelp-query+backlinks-param-namespace": "Loetlemise nimeruum.",
+       "apihelp-query+backlinks-param-dir": "Järjestuse suund.",
+       "apihelp-query+backlinks-param-limit": "Kui palju lehekülgi kokku tagastada. Kui <var>$1redirect</var> on lubatud, siis rakendub piirang mõlemal tasemel eraldi (see tähendab, et tagastada võidakse kuni 2 × <var>$1limit</var> tulemust).",
+       "apihelp-query+blocks-param-start": "Ajatempel, millest alates loetleda.",
+       "apihelp-query+blocks-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+blocks-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+blocks-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele.\nNäiteks, et näidata ainult IP-aadresside suhtes rakendatud tähtajatuid blokeeringuid, määra <kbd>$1show=ip|!temp</kbd>.",
+       "apihelp-query+categories-param-prop": "Millised lisaatribuudid iga kategooria kohta hankida:",
+       "apihelp-query+categories-param-show": "Milliseid kategooriaid näidata.",
+       "apihelp-query+categories-param-limit": "Kui palju kategooriaid tagastada.",
+       "apihelp-query+categories-param-categories": "Loetle ainult need kategooriad. Kasulik, kui vaja kontrollida, kas teatud lehekülg on teatud kategoorias.",
+       "apihelp-query+categories-param-dir": "Järjestuse suund.",
+       "apihelp-query+categorymembers-param-title": "Loetlemise kategooria (nõutav). Peab sisaldama eesliidet <kbd>{{ns:category}}:</kbd>. Ei saa kasutada parameetriga <var>$1pageid</var>.",
+       "apihelp-query+categorymembers-param-pageid": "Loetlemise kategooria lehekülje identifikaator. Ei saa kasutada parameetriga <var>$1title</var>.",
+       "apihelp-query+categorymembers-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+categorymembers-param-type": "Mis tüüpi liikmed kategooriatest hankida. Eiratakse, kui määratud on <kbd>$1sort=timestamp</kbd>.",
+       "apihelp-query+categorymembers-param-dir": "Järjestuse suund.",
+       "apihelp-query+contributors-param-limit": "Kui palju kaastöölisi tagastada.",
+       "apihelp-query+deletedrevisions-param-start": "Ajatempel, millest alates loetleda. Eiratakse, kui töötlusel on redaktsioonide identifikaatorite loend.",
+       "apihelp-query+deletedrevisions-param-end": "Ajatempel, milleni loetleda. Eiratakse, kui töötlusel on redaktsioonide identifikaatorite loend.",
+       "apihelp-query+deletedrevisions-param-tag": "Loetle ainult redaktsioonid, mille küljes on see märgis.",
+       "apihelp-query+deletedrevisions-param-excludeuser": "Ära loetle selle kasutaja redaktsioone.",
+       "apihelp-query+deletedrevs-param-start": "Ajatempel, millest alates loetleda.",
+       "apihelp-query+deletedrevs-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+deletedrevs-param-tag": "Loetle ainult redaktsioonid, mille küljes on see märgis.",
+       "apihelp-query+deletedrevs-param-excludeuser": "Ära loetle selle kasutaja redaktsioone.",
+       "apihelp-query+deletedrevs-param-namespace": "Loetle ainult leheküljed selles nimeruumis.",
+       "apihelp-query+duplicatefiles-param-limit": "Kui palju duplikaatfaile tagastada.",
+       "apihelp-query+duplicatefiles-param-dir": "Järjestuse suund.",
+       "apihelp-query+embeddedin-param-namespace": "Loetlemise nimeruum.",
+       "apihelp-query+embeddedin-param-dir": "Järjestuse suund.",
+       "apihelp-query+embeddedin-param-limit": "Kui palju lehekülgi kokku tagastada.",
+       "apihelp-query+extlinks-param-limit": "Kui palju linke tagastada.",
+       "apihelp-query+exturlusage-summary": "Loetle leheküljed, mis sisaldavad teatud internetiaadressi.",
+       "apihelp-query+exturlusage-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+exturlusage-param-namespace": "Lehekülgede loetlemise nimeruumid.",
+       "apihelp-query+exturlusage-param-limit": "Kui palju lehekülgi tagastada.",
+       "apihelp-query+filearchive-summary": "Loetle kõik kustutatud failid järjestatult.",
+       "apihelp-query+filearchive-param-from": "Pildi pealkiri, millest alates loetleda.",
+       "apihelp-query+filearchive-param-to": "Pildi pealkiri, milleni loetleda.",
+       "apihelp-query+filearchive-param-limit": "Kui palju pilte kokku tagastada.",
+       "apihelp-query+filearchive-param-dir": "Järjestuse suund.",
+       "apihelp-query+filearchive-param-prop": "Milline pilditeave hankida:",
+       "apihelp-query+fileusage-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+fileusage-param-limit": "Kui palju tagastada.",
+       "apihelp-query+fileusage-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele:\n;redirect:Näita ainult ümbersuunamisi.\n;!redirect:Näita ainult üksusi, mis pole ümbersuunamised.",
        "apihelp-query+imageinfo-summary": "Tagastab failiteabe ja üleslaadimisajaloo.",
        "apihelp-query+imageinfo-param-prop": "Millist teavet faili kohta hankida:",
        "apihelp-query+imageinfo-paramvalue-prop-timestamp": "Lisab üles laaditud versiooni ajatempli.",
        "apihelp-query+imageinfo-param-localonly": "Kaasa päringusse ainult kohaliku hoidla failid.",
        "apihelp-query+imageinfo-example-simple": "Faili [[:File:Albert Einstein Head.jpg|Albert Einstein Head.jpg]] praeguse versiooni teabe väljavõtt.",
        "apihelp-query+imageinfo-example-dated": "Faili [[:File:Test.jpg|Test.jpg]] teabe väljavõtt alates 2008. aasta versioonidest.",
-       "api-help-param-continue": "Kui saadaval on rohkem tulemusi, kasuta seda jätkamiseks."
+       "apihelp-query+images-param-limit": "Kui palju faile tagastada.",
+       "apihelp-query+images-param-images": "Loetle ainult need failid. Kasulik, kui vaja kontrollida, kas teatud leheküljel on teatud fail.",
+       "apihelp-query+images-param-dir": "Järjestuse suund.",
+       "apihelp-query+imageusage-param-namespace": "Loetlemise nimeruum.",
+       "apihelp-query+imageusage-param-dir": "Järjestuse suund.",
+       "apihelp-query+imageusage-param-limit": "Kui palju lehekülgi kokku tagastada. Kui <var>$1redirect</var> on lubatud, siis rakendub piirang mõlemal tasemel eraldi (see tähendab, et tagastada võidakse kuni 2 × <var>$1limit</var> tulemust).",
+       "apihelp-query+info-param-prop": "Millised lisaatribuudid hankida:",
+       "apihelp-query+iwbacklinks-param-limit": "Kui palju lehekülgi kokku tagastada.",
+       "apihelp-query+iwbacklinks-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+iwbacklinks-param-dir": "Järjestuse suund.",
+       "apihelp-query+iwlinks-param-prop": "Millised lisaatribuudid iga intervikilingi kohta hankida:",
+       "apihelp-query+iwlinks-param-limit": "Kui palju intervikilinke tagastada.",
+       "apihelp-query+iwlinks-param-dir": "Järjestuse suund.",
+       "apihelp-query+langbacklinks-param-limit": "Kui palju lehekülgi kokku tagastada.",
+       "apihelp-query+langbacklinks-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+langbacklinks-param-dir": "Järjestuse suund.",
+       "apihelp-query+langlinks-param-limit": "Kui palju keelelinke tagastada.",
+       "apihelp-query+langlinks-param-prop": "Millised lisaatribuudid iga intervikilingi kohta hankida:",
+       "apihelp-query+langlinks-param-dir": "Järjestuse suund.",
+       "apihelp-query+links-param-limit": "Kui palju linke tagastada.",
+       "apihelp-query+links-param-titles": "Loetle ainult lingid, mis viitavad neile pealkirjadele. Kasulik, kui vaja kontrollida, kas teatud lehekülg lingib teatud leheküljele.",
+       "apihelp-query+links-param-dir": "Järjestuse suund.",
+       "apihelp-query+linkshere-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+linkshere-param-limit": "Kui palju tagastada.",
+       "apihelp-query+linkshere-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele:\n;redirect:Näita ainult ümbersuunamisi.\n;!redirect:Näita ainult üksusi, mis pole ümbersuunamised.",
+       "apihelp-query+logevents-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+logevents-param-type": "Loetle ainult seda tüüpi logisündmused.",
+       "apihelp-query+logevents-param-action": "Loetle ainult logisündmused selle toimingu kohta. Kirjutab üle parameetri <var>$1type</var>. Väärtused, milles on võimalike väärtuste loetelus metamärk asterisk (<kbd>toiming/*</kbd>), võib kaldkriipsu (/) järel olla erinev sõne.",
+       "apihelp-query+logevents-param-start": "Ajatempel, millest alates loetleda.",
+       "apihelp-query+logevents-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+logevents-param-user": "Loetle ainult selle kasutaja sissekanded.",
+       "apihelp-query+logevents-param-namespace": "Loetle ainult sissekanded, mis on selles nimeruumis.",
+       "apihelp-query+logevents-param-tag": "Loetle ainult logisündmused, mille küljes on see märgis.",
+       "apihelp-query+logevents-param-limit": "Kui palju logisündmusi kokku tagastada.",
+       "apihelp-query+pagepropnames-example-simple": "Hangi esimese 10 atribuudi nimi.",
+       "apihelp-query+pageprops-param-prop": "Loetle ainult need leheatribuudid (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> tagastab kasutatavate atribuutide nimed). Kasulik, kui vaja kontrollida, kas leheküljed kasutavad teatud leheatribuuti.",
+       "apihelp-query+pageswithprop-summary": "Loetle kõik leheküljed, mis kasutavad teatud leheatribuuti.",
+       "apihelp-query+pageswithprop-param-propname": "Leheatribuut, mille kohta lehekülgi loetleda (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> tagastab kasutatavate atribuutide nimed).",
+       "apihelp-query+pageswithprop-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+pageswithprop-paramvalue-prop-value": "Lisab leheatribuudi väärtuse.",
+       "apihelp-query+pageswithprop-param-dir": "Järjestuse suund.",
+       "apihelp-query+protectedtitles-param-namespace": "Loetle ainult pealkirjad nendes nimeruumides.",
+       "apihelp-query+protectedtitles-param-limit": "Kui palju lehekülgi kokku tagastada.",
+       "apihelp-query+protectedtitles-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+random-param-limit": "Kui palju juhuslikke lehekülgi tagastada.",
+       "apihelp-query+recentchanges-summary": "Loetle viimased muudatused.",
+       "apihelp-query+recentchanges-param-start": "Ajatempel, millest alates loetleda.",
+       "apihelp-query+recentchanges-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+recentchanges-param-namespace": "Loetle muudatusi ainult neist nimeruumidest.",
+       "apihelp-query+recentchanges-param-user": "Loetle ainult selle kasutaja muudatused.",
+       "apihelp-query+recentchanges-param-excludeuser": "Ära loetle selle kasutaja muudatusi.",
+       "apihelp-query+recentchanges-param-tag": "Loetle ainult muudatused, mille küljes on see märgis.",
+       "apihelp-query+recentchanges-param-prop": "Hangi teabe lisaelemendid:",
+       "apihelp-query+recentchanges-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele. Näiteks, et näha ainult pisimuudatusi, mille on teinud sisseloginud kasutajad, määra $1show=minor|!anon.",
+       "apihelp-query+recentchanges-param-limit": "Kui palju muudatusi kokku tagastada.",
+       "apihelp-query+recentchanges-param-type": "Mis tüüpi muudatusi näidata.",
+       "apihelp-query+recentchanges-param-toponly": "Loetle ainult muudatused, millele vastab viimane redaktsioon.",
+       "apihelp-query+recentchanges-param-title": "Loetle ainult sissekanded, mis on seotud leheküljega.",
+       "apihelp-query+redirects-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+redirects-param-limit": "Kui palju ümbersuunamisi tagastada.",
+       "apihelp-query+redirects-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele:\n;redirect:Näita ainult fragmendiga ümbersuunamisi.\n;!redirect:Näita ainult ümbersuunamisi, millel pole fragmenti.",
+       "apihelp-query+revisions-param-startid": "Redaktsioon, mille ajatemplist alates loetleda. Redaktsioon peab olemas olema, aga ei pea kuuluma selle lehekülje juurde.",
+       "apihelp-query+revisions-param-endid": "Redaktsioon, mille ajatemplini loetleda. Redaktsioon peab olemas olema, aga ei pea kuuluma selle lehekülje juurde.",
+       "apihelp-query+revisions-param-start": "Redaktsiooni ajatempel, millest alates loetleda.",
+       "apihelp-query+revisions-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+revisions-param-tag": "Loetle ainult redaktsioonid, mille küljes on see märgis.",
+       "apihelp-query+revisions+base-param-prop": "Millised atribuudid iga redaktsiooni kohta hankida:",
+       "apihelp-query+revisions+base-param-limit": "Kui palju redaktsioone tagastada.",
+       "apihelp-query+search-summary": "Soorita täisteksti otsing.",
+       "apihelp-query+search-param-search": "Otsi lehekülgede pealkirju või sisu, mis vastab sellele väärtusele. Saad otsisõnes kasutada neid erifunktsioone, mida otsing selles vikis võimaldab.",
+       "apihelp-query+search-param-namespace": "Otsi ainult neist nimeruumidest.",
+       "apihelp-query+search-param-what": "Mis tüüpi otsing sooritada.",
+       "apihelp-query+search-param-info": "Millised metaandmed tagastada.",
+       "apihelp-query+search-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+search-param-limit": "Kui palju lehekülgi kokku tagastada.",
+       "apihelp-query+siteinfo-param-prop": "Milline teave hankida:",
+       "apihelp-query+tags-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+templates-param-limit": "Kui palju malle tagastada.",
+       "apihelp-query+templates-param-templates": "Loetle ainult need mallid. Kasulik, kui vaja kontrollida, kas teatud lehekülg kasutab teatud malli.",
+       "apihelp-query+templates-param-dir": "Järjestuse suund.",
+       "apihelp-query+transcludedin-param-prop": "Millised atribuudid hankida:",
+       "apihelp-query+transcludedin-param-limit": "Kui palju tagastada.",
+       "apihelp-query+transcludedin-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele:\n;redirect:Näita ainult ümbersuunamisi.\n;!redirect:Näita ainult üksusi, mis pole ümbersuunamised.",
+       "apihelp-query+usercontribs-param-namespace": "Loetle ainult kaastöö nendes nimeruumides.",
+       "apihelp-query+usercontribs-param-prop": "Hangi teabe lisaelemendid:",
+       "apihelp-query+usercontribs-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele. Näiteks ainult muudatused, mis pole pisimuudatused: <kbd>$2show=!minor</kbd>.\n\nKui määratud on <kbd>$2show=patrolled</kbd> või <kbd>$2show=!patrolled</kbd>, siis ei näidata muudatusi, mis on vanemad kui <var>[[mw:Special:MyLanguage/Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|sekund|sekundit}}).",
+       "apihelp-query+usercontribs-param-tag": "Loetle ainult redaktsioonid, mille küljes on see märgis.",
+       "apihelp-query+usercontribs-param-toponly": "Loetle ainult muudatused, millele vastab viimane redaktsioon.",
+       "apihelp-query+userinfo-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+users-param-prop": "Millised teabe elemendid hankida:",
+       "apihelp-query+watchlist-param-start": "Ajatempel, millest alates loetleda.",
+       "apihelp-query+watchlist-param-end": "Ajatempel, milleni loetleda.",
+       "apihelp-query+watchlist-param-namespace": "Loetle ainult muudatused neis nimeruumides.",
+       "apihelp-query+watchlist-param-user": "Loetle ainult selle kasutaja muudatused.",
+       "apihelp-query+watchlist-param-excludeuser": "Ära loetle selle kasutaja muudatusi.",
+       "apihelp-query+watchlist-param-limit": "Kui palju tulemusi päringu kohta kokku tagastada.",
+       "apihelp-query+watchlist-param-prop": "Millised lisaatribuudid hankida:",
+       "apihelp-query+watchlist-param-show": "Näita ainult üksusi, mis vastavad neile kriteeriumitele. Näiteks, et näha ainult pisimuudatusi, mille on teinud sisseloginud kasutajad, määra $1show=minor|!anon.",
+       "apihelp-query+watchlist-param-type": "Mis tüüpi muudatusi näidata:",
+       "apihelp-query+watchlistraw-param-namespace": "Loetle ainult leheküljed nendes nimeruumides.",
+       "apihelp-query+watchlistraw-param-limit": "Kui palju tulemusi päringu kohta kokku tagastada.",
+       "apihelp-query+watchlistraw-param-prop": "Millised lisaatribuudid hankida:",
+       "apihelp-query+watchlistraw-param-show": "Loetle ainult üksused, mis vastavad neile kriteeriumitele.",
+       "apihelp-query+watchlistraw-param-dir": "Järjestuse suund.",
+       "apihelp-query+watchlistraw-param-fromtitle": "Pealkiri (nimeruumi eesliitega), millest alates loetleda.",
+       "apihelp-query+watchlistraw-param-totitle": "Pealkiri (nimeruumi eesliitega), milleni loetleda.",
+       "api-help-main-header": "Põhimoodul.",
+       "api-help-param-limit": "Lubatud pole üle $1.",
+       "api-help-param-limit2": "Lubatud pole üle $1 (robotitele $2).",
+       "api-help-param-direction": "Loetlemise suund:\n;newer:Vanemad enne. Märkus: element $1start peab olema enne elementi $1end.\n;older:Uuemad enne (vaikimisi). Märkus: element $1start peab olema pärast elementi $1end.",
+       "api-help-param-continue": "Kui saadaval on rohkem tulemusi, kasuta seda jätkamiseks.",
+       "apierror-mustbeloggedin": "Pead olema sisse logitud, et $1.",
+       "apierror-timeout": "Server ei vastanud oodatud aja sees."
 }
index 73eb145..9ae584b 100644 (file)
        "apihelp-parse-paramvalue-prop-revid": "Ajoute l’ID de révision de la page analysée.",
        "apihelp-parse-paramvalue-prop-displaytitle": "Ajoute le titre du wikitexte analysé.",
        "apihelp-parse-paramvalue-prop-headitems": "Fournit les éléments à mettre dans le <code>&lt;head&gt;</code> de la page.",
-       "apihelp-parse-paramvalue-prop-headhtml": "Fournit le <code>&lt;head&gt;</code> analysé de la page.",
+       "apihelp-parse-paramvalue-prop-headhtml": "Fournit le type de document, à partir de l'analyse des éléments <code>&lt;html&gt;</code>, <code>&lt;head&gt;</code> et <code>&lt;body&gt;</code> de la page.",
        "apihelp-parse-paramvalue-prop-modules": "Fournit les modules ResourceLoader utilisés sur la page. Pour les charger, utiliser <code>mw.loader.using()</code>. Soit <kbd>jsconfigvars</kbd> soit <kbd>encodedjsconfigvars</kbd> doit être demandé avec <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "Fournit les variables de configuration JavaScript spécifiques à la page. Pour les appliquer, utiliser <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Fournit les variables de configuration JavaScript spécifiques à la page comme chaîne JSON.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Ajoute la date d’inscription de l’utilisateur.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Ajoute le compteur de pages non lues de la liste de suivi de l’utilisateur (au maximum $1 ; renvoie <samp>$2</samp> s’il y en a plus).",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "Ajoute les IDs centraux et l’état d’attachement de l’utilisateur.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "Ajoute la date de la dernière contribution de l'utilisateur.",
        "apihelp-query+userinfo-param-attachedwiki": "Avec <kbd>$1prop=centralids</kbd>, indiquer si l’utilisateur est attaché au wiki identifié par cet ID.",
        "apihelp-query+userinfo-example-simple": "Obtenir des informations sur l’utilisateur actuel.",
        "apihelp-query+userinfo-example-data": "Obtenir des informations supplémentaires sur l’utilisateur actuel.",
index 04efe36..5992590 100644 (file)
        "apihelp-parse-paramvalue-prop-revid": "הוספת מזהה הגרסה של הדף המפוענח.",
        "apihelp-parse-paramvalue-prop-displaytitle": "הוספת הכותרת של קוד הוויקי המפוענח.",
        "apihelp-parse-paramvalue-prop-headitems": "נותן פריטים לשים ב־<code>&lt;head&gt;</code> של הדף.",
-       "apihelp-parse-paramvalue-prop-headhtml": "נותן את ה־<code>&lt;head&gt;</code> המפוענח של הדף.",
+       "apihelp-parse-paramvalue-prop-headhtml": "נותן doctype מפוענח, תג <code>&lt;html&gt;</code> פותח, רכיב <code>&lt;head&gt;</code>, ותג <code>&lt;body&gt;</code> פותח של הדף.",
        "apihelp-parse-paramvalue-prop-modules": "מתן יחידות ResourceLoader שמשמשות בדף. כדי לטעון, יש להשתמש ב<code dir=\"ltr\">mw.loader.using()</code>. יש לבקש את <kbd>jsconfigvars</kbd> או את <kbd>encodedjsconfigvars</kbd> יחד עם <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "נותן משתני הגדרות של JavaScript שייחודיים לדף הזה. כדי להחיל, יש להשתמש ב<code dir=\"ltr\">mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "נותן משתני הגדרות של JavaScript שייחודיים לדף הזה בתור מחרוזת JSON.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "הוספת תאריך הרישום של המשתמש.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "הוספת מניין הדפים שלא נקראו ברשימת המעקב של המשתמש (לכל היותר $1; מחזיר <samp>$2</samp> אם יש יותר).",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "הוספת המזהה המרכזי ומצב השיוך למשתמש.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "הוספת התאריך של התרומה האחרונה של המשתמש.",
        "apihelp-query+userinfo-param-attachedwiki": "עם <kbd>$1prop=centralids</kbd>, לציין האם המשתמש משויך לוויקי עם המזהה הזה.",
        "apihelp-query+userinfo-example-simple": "קבלת מידע על המשתמש הנוכחי.",
        "apihelp-query+userinfo-example-data": "קבלת מידע נוסף על המשתמש הנוכחי.",
index 4e22405..9e28c39 100644 (file)
@@ -38,7 +38,7 @@
        "apihelp-block-param-anononly": "匿名利用者のみブロックします(つまり、このIPアドレスからの匿名での編集を不可能にします)。",
        "apihelp-block-param-nocreate": "アカウントの作成を禁止します。",
        "apihelp-block-param-autoblock": "その利用者が最後に使用したIPアドレスと、ブロック後に編集を試みた際のIPアドレスを自動的にブロックします。",
-       "apihelp-block-param-noemail": "Wikiを通して電子メールを送信することを禁止します。(<code>blockemail</code> 権限が必要です)",
+       "apihelp-block-param-noemail": "ウィキを通してメールを送信することを禁止します。(<code>blockemail</code> 権限が必要です)",
        "apihelp-block-param-hidename": "ブロック記録から利用者名を秘匿します。(<code>hideuser</code> 権限が必要です)",
        "apihelp-block-param-allowusertalk": "自身のトークページの編集を許可する (<var>[[mw:Special:MyLanguage/Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> に依存)。",
        "apihelp-block-param-reblock": "その利用者がすでにブロックされている場合、ブロックを上書きします。",
        "apihelp-edit-example-edit": "ページを編集",
        "apihelp-edit-example-prepend": "<kbd>_&#95;NOTOC_&#95;</kbd> をページの先頭に挿入する。",
        "apihelp-edit-example-undo": "版 13579 から 13585 まで要約を自動入力して取り消す。",
-       "apihelp-emailuser-summary": "利用者に電子メールを送信します。",
+       "apihelp-emailuser-summary": "利用者にメールを送信します。",
        "apihelp-emailuser-param-target": "送信先の利用者名。",
        "apihelp-emailuser-param-subject": "題名。",
-       "apihelp-emailuser-param-text": "電子メールの本文。",
-       "apihelp-emailuser-param-ccme": "電子メールの複製を自分にも送信します。",
-       "apihelp-emailuser-example-email": "利用者 <kbd>WikiSysop</kbd> に <kbd>Content</kbd> という本文の電子メールを送信。",
+       "apihelp-emailuser-param-text": "メールの本文。",
+       "apihelp-emailuser-param-ccme": "メールの複製を自分にも送信します。",
+       "apihelp-emailuser-example-email": "利用者 <kbd>WikiSysop</kbd> に <kbd>Content</kbd> という本文のメールを送信。",
        "apihelp-expandtemplates-summary": "ウィキテキストに含まれるすべてのテンプレートを展開します。",
        "apihelp-expandtemplates-param-title": "ページの名前です。",
        "apihelp-expandtemplates-param-text": "変換するウィキテキストです。",
        "apihelp-query+embeddedin-param-filterredir": "転送ページを絞り込む方法。",
        "apihelp-query+embeddedin-param-limit": "返すページの総数。",
        "apihelp-query+embeddedin-example-simple": "<kbd>Template:Stub</kbd> を参照読み込みしているページを表示する。",
-       "apihelp-query+embeddedin-example-generator": "<kbd>Template:Stub</kbd> をトランスクルードしているページに関する情報を取得する。",
+       "apihelp-query+embeddedin-example-generator": "<kbd>Template:Stub</kbd> を参照読み込みしているページに関する情報を取得する。",
        "apihelp-query+extlinks-summary": "与えられたページにあるすべての外部URL (インターウィキを除く) を返します。",
        "apihelp-query+extlinks-param-limit": "返すリンクの数。",
        "apihelp-query+extlinks-param-protocol": "URLのプロトコル。このパラメータが空であり、かつ<var>$1query</var> が設定されている場合, protocol は <kbd>http</kbd> となります。すべての外部リンクを一覧表示するためにはこのパラメータと <var>$1query</var> の両方を空にしてください。",
        "apihelp-query+transcludedin-param-namespace": "この名前空間に含まれるページのみを一覧表示します。",
        "apihelp-query+transcludedin-param-limit": "返す数。",
        "apihelp-query+transcludedin-example-simple": "<kbd>Main Page</kbd> をトランスクルードしているページの一覧を取得する。",
-       "apihelp-query+transcludedin-example-generator": "<kbd>Main Page</kbd> をトランスクルードしているページに関する情報を取得する。",
+       "apihelp-query+transcludedin-example-generator": "<kbd>Main Page</kbd> を参照読み込みしているページに関する情報を取得する。",
        "apihelp-query+usercontribs-summary": "利用者によるすべての編集を取得します。",
        "apihelp-query+usercontribs-param-limit": "返す投稿記録の最大数。",
        "apihelp-query+usercontribs-param-user": "投稿記録を取得する利用者。<var>$1userids</var> または <var>$1userprefix</var> とは同時に使用できません。",
        "apihelp-query+watchlistraw-param-prop": "追加で取得するプロパティ:",
        "apihelp-query+watchlistraw-param-dir": "昇順・降順の別。",
        "apihelp-query+watchlistraw-example-generator": "現在の利用者のウォッチリスト上のページに関する情報を取得する。",
-       "apihelp-resetpassword-example-user": "利用者 <kbd>Example</kbd> にパスワード再設定の電子メールを送信する。",
+       "apihelp-resetpassword-example-user": "利用者 <kbd>Example</kbd> にパスワード再設定のメールを送信する。",
        "apihelp-revisiondelete-summary": "版の削除および復元を行います。",
        "apihelp-revisiondelete-param-reason": "削除または復元の理由。",
        "apihelp-revisiondelete-example-revision": "<kbd>Main Page</kbd> の版 <kbd>12345</kbd> の本文を隠す。",
        "apierror-mustbeloggedin": "$1にログインしている必要があります。",
        "apierror-noimageredirect": "画像のリダイレクトを作成する権限がありません。",
        "apierror-nosuchpageid": "ID $1のページはありません。",
+       "apierror-pagelang-disabled": "このウィキではページの言語は変更できません。",
        "apierror-permissiondenied": "$1に必要な権限がありません。",
        "apierror-permissiondenied-generic": "アクセスが拒否されました。",
        "apierror-readonly": "ウィキは現在読み取り専用モードです。",
index 4b0f603..27b4d79 100644 (file)
        "apihelp-parse-paramvalue-prop-revid": "Adiciona o ID da revisão da página analisada.",
        "apihelp-parse-paramvalue-prop-displaytitle": "Adiciona o título do texto wiki analisado.",
        "apihelp-parse-paramvalue-prop-headitems": "Fornece itens para colocar no <code>&lt;head&gt;</code> da página.",
-       "apihelp-parse-paramvalue-prop-headhtml": "Fornece <code>&lt;head&gt;</code> analisado da página.",
+       "apihelp-parse-paramvalue-prop-headhtml": "Fornece o tipo analisado do documento, abrindo <code>&lt;html&gt;</code>, o elemento <code>&lt;head&gt;</code> e o <code>&lt;body&gt;</code> da página.",
        "apihelp-parse-paramvalue-prop-modules": "Fornece os módulos do ResourceLoader usados na página. Para carregar, use <code>mw.loader.using()</code>. Contudo, <kbd>jsconfigvars</kbd> ou <kbd>encodedjsconfigvars</kbd> deve ser solicitado conjuntamente com <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "Fornece as variáveis de configuração JavaScript específicas da página. Para aplicar, use <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Fornece as variáveis de configuração JavaScript específicas da página como uma string JSON.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Adiciona a data de registro do usuário.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Adiciona a contagem de páginas não lidas na lista de páginas vigiadas do usuário (máximo $1; retorna <samp>$2</samp> se mais).",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "Adiciona os IDs centrais e o status do anexo do usuário.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "Adiciona a data da última contribuição do usuário.",
        "apihelp-query+userinfo-param-attachedwiki": "Com <kbd>$1prop=centralids</kbd>, indique se o usuário está conectado com a wiki identificada por este ID.",
        "apihelp-query+userinfo-example-simple": "Ober informações sobre o usuário atual.",
        "apihelp-query+userinfo-example-data": "Obter informações adicionais sobre o usuário atual.",
index fc38b40..67465e2 100644 (file)
        "apihelp-parse-paramvalue-prop-revid": "Adiciona o identificador de revisão da página analisada.",
        "apihelp-parse-paramvalue-prop-displaytitle": "Adiciona o título do texto wiki analisado.",
        "apihelp-parse-paramvalue-prop-headitems": "Fornece os elementos a colocar no <code>&lt;head&gt;</code> da página.",
-       "apihelp-parse-paramvalue-prop-headhtml": "Fornece o <code>&lt;head&gt;</code> analisado da página.",
+       "apihelp-parse-paramvalue-prop-headhtml": "Fornece o tipo analisado do documento, abrindo <code>&lt;html&gt;</code>, o elemento <code>&lt;head&gt;</code> e o <code>&lt;body&gt;</code> da página.",
        "apihelp-parse-paramvalue-prop-modules": "Fornece os módulos ResourceLoader usados na página. Para carregá-los, usar <code>mw.loader.using()</code>. Uma das variáveis <kbd>jsconfigvars</kbd> ou <kbd>encodedjsconfigvars</kbd> tem de ser pedida em conjunto com <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "Fornece as variáveis de configuração JavaScript específicas da página. Para aplicá-las, usar <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Fornece as variáveis de configuração JavaScript específicas da página, no formato de uma ''string'' JSON.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Adiciona a data de registo do utilizador.",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Adiciona a contagem de páginas não lidas da lista de páginas vigiadas do utilizador (máximo $1; devolve <samp>$2</samp> se forem mais).",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "Adiciona os identificadores centrais e o estado de ligação central (''attachment'') do utilizador.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "Adiciona a data da última contribuição do utilizador.",
        "apihelp-query+userinfo-param-attachedwiki": "Com <kbd>$1prop=centralids</kbd>, indicar se o utilizador tem ligação com a wiki designada por este identificador.",
        "apihelp-query+userinfo-example-simple": "Obter informações sobre o utilizador atual.",
        "apihelp-query+userinfo-example-data": "Obter informações adicionais sobre o utilizador atual.",
index 9abcfe2..0b5eb39 100644 (file)
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "{{doc-apihelp-paramvalue|query+userinfo|prop|registrationdate}}",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "{{doc-apihelp-paramvalue|query+userinfo|prop|unreadcount|params=* $1 - Maximum value for the \"unreadcount\" property.\n* $2 - Return value when there are more unread pages.|paramstart=3}}",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "{{doc-apihelp-paramvalue|query+userinfo|prop|centralids}}",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "{{doc-apihelp-paramvalue|query+userinfo|prop|latestcontrib}}",
        "apihelp-query+userinfo-param-attachedwiki": "{{doc-apihelp-param|query+userinfo|attachedwiki}}",
        "apihelp-query+userinfo-example-simple": "{{doc-apihelp-example|query+userinfo}}",
        "apihelp-query+userinfo-example-data": "{{doc-apihelp-example|query+userinfo}}",
index 1b30d00..892cba8 100644 (file)
@@ -35,7 +35,8 @@
                        "Movses",
                        "Stjn",
                        "Edward Chernenko",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "Diralik"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Документация]]\n* [[mw:Special:MyLanguage/API:FAQ|ЧаВО]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Почтовая рассылка]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Новости API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Ошибки и запросы]\n</div>\n<strong>Статус:</strong> MediaWiki API — зрелый и стабильный интерфейс, активно поддерживаемый и улучшаемый. Мы стараемся избегать ломающих изменений, однако изредка они могут быть необходимы. Подпишитесь на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ почтовую рассылку mediawiki-api-announce], чтобы быть в курсе обновлений.\n\n<strong>Ошибочные запросы:</strong> Если API получает запрос с ошибкой, вернётся заголовок HTTP с ключом «MediaWiki-API-Error», после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Ошибки и предупреждения]].\n\n<p class=\"mw-apisandbox-link\"><strong>Тестирование:</strong> для удобства тестирования API-запросов, см. [[Special:ApiSandbox]].</p>",
        "apihelp-purge-param-forcelinkupdate": "Обновить таблицы ссылок.",
        "apihelp-purge-param-forcerecursivelinkupdate": "Обновить таблицу ссылок для данной страницы, а также всех страниц, использующих данную как шаблон.",
        "apihelp-purge-example-simple": "Очистить кэш для страниц <kbd>Main Page</kbd> и <kbd>API</kbd>.",
-       "apihelp-purge-example-generator": "Очистить кэш первых 10 страниц в основном пространстве имен.",
+       "apihelp-purge-example-generator": "Очистить кэш первых 10 страниц в основном пространстве имён.",
        "apihelp-query-summary": "Запросить данные с и о MediaWiki.",
        "apihelp-query-extended-description": "Все модификации данных сначала должны запросить соответствующий токен для предотвращения злоупотреблений с вредоносных сайтов.",
        "apihelp-query-param-prop": "Какие использовать свойства для запрашиваемых страниц.",
        "apihelp-query+protectedtitles-paramvalue-prop-parsedcomment": "Добавляет распарсенное описание защиты.",
        "apihelp-query+protectedtitles-paramvalue-prop-expiry": "Добавляет метку времени снятия защиты.",
        "apihelp-query+protectedtitles-paramvalue-prop-level": "Добавляет уровень защиты.",
-       "apihelp-query+protectedtitles-example-simple": "Список защищенных заголовков",
+       "apihelp-query+protectedtitles-example-simple": "Список защищённых заголовков",
        "apihelp-query+protectedtitles-example-generator": "Поиск ссылок на защищённые заголовки в основном пространстве имён.",
        "apihelp-query+querypage-summary": "Получение списка, предоставляемого служебной страницей, основанной на QueryPage.",
        "apihelp-query+querypage-param-page": "Название служебной страницы. Обратите внимание: чувствительно к регистру.",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Гарантируется}}: $2",
        "api-help-right-apihighlimits": "Использовать высокие лимиты в запросах API (медленные запросы: $1, быстрые запросы: $2). Лимиты для медленных запросов также применимы к параметрам со множеством значений.",
        "api-help-open-in-apisandbox": "<small>[открыть в песочнице]</small>",
-       "api-help-authmanager-general-usage": "СÑ\82андаÑ\80Ñ\82наÑ\8f Ð¿Ñ\80оÑ\86едÑ\83Ñ\80а Ð¸Ñ\81полÑ\8cзованиÑ\8f Ñ\8dÑ\82ого Ð¼Ð¾Ð´Ñ\83лÑ\8f Ñ\82акова:\n# Ð\97апÑ\80оÑ\81 Ð¿Ð¾Ð»ÐµÐ¹, Ð´Ð¾Ñ\81Ñ\82Ñ\83пнÑ\8bÑ\85 Ð¸Ð· <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> Ñ\81 <kbd>amirequestsfor=$4</kbd>, Ð¸ Ñ\82окена <kbd>$5</kbd> Ð¸Ð· <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.\n# Ð\9fÑ\80едоÑ\81Ñ\82авление Ð¿Ð¾Ð»ÐµÐ¹ Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8e Ð¸ Ð¿Ð¾Ð»Ñ\83Ñ\87ение ÐµÐ³Ð¾ Ð´Ð°Ð½Ð½Ñ\8bÑ\85.\n# Ð\97апÑ\80оÑ\81 Ðº Ñ\8dÑ\82омÑ\83 Ð¼Ð¾Ð´Ñ\83лÑ\8e, Ñ\81одеÑ\80жаÑ\89ий <var>$1returnurl</var> Ð¸Ð»Ð¸ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸Ñ\87ное Ð¿Ð¾Ð»Ðµ.\n# Ð\9fÑ\80овеÑ\80ка Ð¿Ð¾Ð»Ñ\8f <samp>status</samp> Ð¾Ñ\82веÑ\82а.\n#* Ð\95Ñ\81ли Ð²Ñ\8b Ð¿Ð¾Ð»Ñ\83Ñ\87или <samp>PASS</samp> Ð¸Ð»Ð¸ <samp>FAIL</samp>, Ð²Ñ\8b Ð·Ð°ÐºÐ¾Ð½Ñ\87или. Ð\9eпеÑ\80аÑ\86иÑ\8f Ð»Ð¸Ð±Ð¾ Ð·Ð°Ð²ÐµÑ\80Ñ\88илаÑ\81Ñ\8c Ñ\83Ñ\81пеÑ\85ом, Ð»Ð¸Ð±Ð¾ Ð½ÐµÑ\82.\n#* Ð\95Ñ\81ли Ð²Ñ\8b Ð¿Ð¾Ð»Ñ\83Ñ\87или <samp>UI</samp>, Ð¿Ñ\80едоÑ\81Ñ\82авÑ\8cÑ\82е Ð½Ð¾Ð²Ñ\8bе Ð¿Ð¾Ð»Ñ\8f Ð¿Ð¾Ð»Ñ\8cззоваÑ\82елÑ\8e Ð¸ Ð¿Ð¾Ð»Ñ\83Ñ\87иÑ\82е Ð½Ð¾Ð²Ñ\8bе Ð´Ð°Ð½Ð½Ñ\8bе. Ð\97аÑ\82ем Ñ\81овеÑ\80Ñ\88иÑ\82е Ð½Ð¾Ð²Ñ\8bй Ð·Ð°Ð¿Ñ\80оÑ\81 Ñ\81 Ð¿Ð°Ñ\80амеÑ\82Ñ\80ом <var>$1continue</var> Ð¸ Ð½Ð¾Ð²Ñ\8bми Ð¿Ð¾Ð»Ñ\8fми, Ð¿Ð¾Ñ\81ле Ñ\87его Ð¿Ð¾Ð²Ñ\82оÑ\80иÑ\82е Ð¿Ñ\83нкÑ\82 4.\n#* Ð\95Ñ\81ли Ð²Ñ\8b Ð¿Ð¾Ð»Ñ\83Ñ\87или <samp>REDIRECT</samp>, Ð¾Ñ\82пÑ\80авÑ\8cÑ\82е Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f Ð½Ð° <samp>redirecttarget</samp> Ð¸ Ð¿Ð¾Ð´Ð¾Ð¶Ð´Ð¸Ñ\82е Ð²Ð¾Ð·Ð²Ñ\80аÑ\89ениÑ\8f Ð½Ð° <var>$1returnurl</var>. Ð\97аÑ\82ем Ñ\81овеÑ\80Ñ\88иÑ\82е Ð·Ð°Ð¿Ñ\80оÑ\81 Ðº Ñ\8dÑ\82омÑ\83 Ð¼Ð¾Ð´Ñ\83лÑ\8e Ñ\81 Ð¿Ð°Ñ\80амеÑ\82Ñ\80ом <var>$1continue</var> Ð¸ Ð²Ñ\81еми Ð¿Ð¾Ð»Ñ\8fми, Ñ\81одеÑ\80жаÑ\89имиÑ\81Ñ\8f Ð² Ð²Ð¾Ð·Ð²Ñ\80аÑ\89Ñ\91нной Ñ\81Ñ\81Ñ\8bлке, Ð¸ Ð¿Ð¾Ð²Ñ\82оÑ\80иÑ\82е Ð¿Ñ\83нкÑ\82 4.\n#* Ð\95Ñ\81ли Ð²Ñ\8b Ð¿Ð¾Ð»Ñ\83Ñ\87или <samp>RESTART</samp>, Ñ\8dÑ\82о Ð¾Ð·Ð½Ð°Ñ\87аеÑ\82, Ñ\87Ñ\82о Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86иÑ\8f Ñ\80абоÑ\82аеÑ\82, Ð½Ð¾ Ð¼Ñ\8b Ð½Ðµ Ð¿Ñ\80ивÑ\8fзали Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8cÑ\81кий Ð°ÐºÐºÐ°Ñ\83нÑ\82. Ð\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ñ\80аÑ\81Ñ\81маÑ\82Ñ\80иваÑ\82Ñ\8c Ñ\8dÑ\82о ÐºÐ°Ðº <samp>UI</samp> Ð¸Ð»Ð¸ <samp>FAIL</samp>.",
+       "api-help-authmanager-general-usage": "Стандартная процедура использования этого модуля такова:\n# Запрос полей, доступных из <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> с <kbd>amirequestsfor=$4</kbd>, и токена <kbd>$5</kbd> из <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.\n# Предоставление полей пользователю и получение его данных.\n# Запрос к этому модулю, содержащий <var>$1returnurl</var> или аналогичное поле.\n# Проверка поля <samp>status</samp> ответа.\n#* Если вы получили <samp>PASS</samp> или <samp>FAIL</samp>, вы закончили. Операция либо завершилась успехом, либо нет.\n#* Если вы получили <samp>UI</samp>, предоставьте новые поля пользователю и получите новые данные. Затем совершите новый запрос с параметром <var>$1continue</var> и новыми полями, после чего повторите пункт 4.\n#* Если вы получили <samp>REDIRECT</samp>, отправьте пользователя на <samp>redirecttarget</samp> и подождите возвращения на <var>$1returnurl</var>. Затем совершите запрос к этому модулю с параметром <var>$1continue</var> и всеми полями, содержащимися в возвращённой ссылке, и повторите пункт 4.\n#* Если вы получили <samp>RESTART</samp>, это означает, что аутентификация работает, но мы не привязали пользовательский аккаунт. Вы можете рассматривать это как <samp>UI</samp> или <samp>FAIL</samp>.",
        "api-help-authmanagerhelper-requests": "Использовать только эти аутентификационные запросы, с <samp>id</samp>, возвращённом из <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> с <kbd>amirequestsfor=$1</kbd>, или из предыдущего ответа этого модуля.",
        "api-help-authmanagerhelper-request": "Использовать этот аутентификационный запрос, с <samp>id</samp>, возвращённом из <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> с <kbd>amirequestsfor=$1</kbd>.",
        "api-help-authmanagerhelper-messageformat": "Формат, используемый для возвращаемых сообщений.",
        "apierror-maxchars": "Параметр <var>$1</var> не может быть длиннее $2 {{PLURAL:$2|символа|символов}}",
        "apierror-maxlag-generic": "Ожидание сервера базы данных: $1 {{PLURAL:$1|секунда|секунды|секунд}} задержки.",
        "apierror-maxlag": "Ожидание $2: $1 {{PLURAL:$1|секунда|секунды|секунд}} задержки.",
-       "apierror-mimesearchdisabled": "Поиск по MIME отключен в жадном режиме.",
+       "apierror-mimesearchdisabled": "Поиск по MIME отключён в жадном режиме.",
        "apierror-missingcontent-pageid": "Отсутствует содержимое страницы с идентификатором $1.",
        "apierror-missingcontent-revid": "Отсутствует содержимое версии с идентификатором $1.",
        "apierror-missingparam-at-least-one-of": "{{PLURAL:$2|Параметр|Как минимум один из параметров}} $1 обязателен.",
        "apierror-permissiondenied-generic": "Доступ запрещён.",
        "apierror-permissiondenied-patrolflag": "Вам нужно право <code>patrol</code> или <code>patrolmarks</code> для запроса статуса патрулирования.",
        "apierror-permissiondenied-unblock": "У вас нет прав снимать блокировку с участников.",
-       "apierror-prefixsearchdisabled": "Поиск по префиксу отключен в жадном режиме.",
+       "apierror-prefixsearchdisabled": "Поиск по префиксу отключён в жадном режиме.",
        "apierror-promised-nonwrite-api": "Заголовок HTTP <code>Promise-Non-Write-API-Action</code> не может быть передан в записывающие модули API.",
        "apierror-protect-invalidaction": "Недопустимый тип защиты «$1».",
        "apierror-protect-invalidlevel": "Недопустимый уровень защиты «$1».",
        "apiwarn-compare-nocontentmodel": "Модель содержимого не может быть определена, предполагается $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> устарел. Пожалуйста, вместо него используйте <kbd>prop=deletedrevisions</kbd> или <kbd>list=alldeletedrevisions</kbd>.",
        "apiwarn-deprecation-httpsexpected": "Использован HTTP, где ожидался HTTPS.",
-       "apiwarn-deprecation-login-botpw": "Вход в основной аккаунт через <kbd>action=login</kbd> устарел и может быть отключен без предупреждения. Для продолжения авторизации с <kbd>action=login</kbd>, см.\n[[Special:BotPasswords]]. Для безопасного продолжения использования входа в основной аккаунт, см. <kbd>action=clientlogin</kbd>.",
-       "apiwarn-deprecation-login-nobotpw": "Вход в основной аккаунт через <kbd>action=login</kbd> не поддерживается и может быть отключен без предупреждения. Для безопасной авторизации, см. <kbd>action=clientlogin</kbd>.",
+       "apiwarn-deprecation-login-botpw": "Вход в основной аккаунт через <kbd>action=login</kbd> устарел и может быть отключён без предупреждения. Для продолжения авторизации с <kbd>action=login</kbd>, см.\n[[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> устарело с MediaWiki 1.28. Используйте <kbd>prop=headhtml</kbd> при создании новых HTML документов или <kbd>prop=modules|jsconfigvars</kbd> при обновлении документов на стороне клиента.",
index df94ce2..710133e 100644 (file)
        "apihelp-query+usercontribs-summary": "Hämta alla redigeringar av en användare.",
        "apihelp-query+userinfo-summary": "Få information om den aktuella användaren.",
        "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "Hämta en nyckel för att ändra aktuell användares inställningar.",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "Lägg till datumet för användarens senaste bidrag.",
        "apihelp-query+userinfo-example-simple": "Få information om den aktuella användaren.",
        "apihelp-query+userinfo-example-data": "Få ytterligare information om den aktuella användaren.",
        "apihelp-query+users-summary": "Hämta information om en lista över användare.",
index 78f92f1..38f74d6 100644 (file)
        "apihelp-query+categorymembers-paramvalue-prop-sortkeyprefix": "添加用于分类中排序的关键字前缀(关键字的人类可读部分)。",
        "apihelp-query+categorymembers-paramvalue-prop-type": "添加页面被分类的类型(<samp>page</samp>、<samp>subcat</samp>或<samp>file</samp>)。",
        "apihelp-query+categorymembers-paramvalue-prop-timestamp": "添加页面被包括时的时间戳。",
-       "apihelp-query+categorymembers-param-namespace": "仅包含这些名字空间的页面。注意<kbd>$1type=subcat</kbd>或<kbd>$1type=file</kbd>可能被使用,而不是<kbd>$1namespace=14</kbd>或<kbd>6</kbd>。",
+       "apihelp-query+categorymembers-param-namespace": "仅包含这些名字空间的页面。注意可使用<kbd>$1type=subcat</kbd>或<kbd>$1type=file</kbd>替代<kbd>$1namespace=14</kbd>或<kbd>6</kbd>。",
        "apihelp-query+categorymembers-param-type": "包含的分类成员类型。当<kbd>$1sort=timestamp</kbd>被设置时会忽略。",
        "apihelp-query+categorymembers-param-limit": "返回页面的最大数量。",
        "apihelp-query+categorymembers-param-sort": "要作为排序方式的属性。",
index 776c59a..225db87 100644 (file)
@@ -24,8 +24,8 @@
        "apihelp-main-param-action": "要執行的動作。",
        "apihelp-main-param-format": "輸出的格式。",
        "apihelp-main-param-maxlag": "最大延遲可在當 MediaWiki 安裝於資料庫複寫叢集時使用。為了保存引起更多站台複寫延遲的操作,此參數可讓客戶端等待至複寫延遲小於指定值為止。在過渡延遲的情況下,錯誤碼 <samp>maxlag</samp> 會帶有著像是 <samp>Waiting for $host: $lag seconds lagged</samp> 的訊息內容回傳。<br />請查看[[mw:Special:MyLanguage/Manual:Maxlag_parameter|手冊:Maxlag 參數]]來獲取更多資訊。",
-       "apihelp-main-param-smaxage": "將HTTP緩存控制頭欄位設為<code>s-maxage</code>秒。錯誤不會做緩存。",
-       "apihelp-main-param-maxage": "將HTTP緩存控制頭欄位設為<code>max-age</code>秒。錯誤不會做緩存。",
+       "apihelp-main-param-smaxage": "將HTTP暫存控制頭欄位設為<code>s-maxage</code>秒。錯誤不會做暫存。",
+       "apihelp-main-param-maxage": "將HTTP暫存控制頭欄位設為<code>max-age</code>秒。錯誤不會做暫存。",
        "apihelp-main-param-assert": "若設為<kbd>user</kbd>,會確認使用者是否已登入;若設為<kbd>bot</kbd>,會確認是否擁有機械人權限。",
        "apihelp-main-param-assertuser": "確認目前使用者就是指定的使用者。",
        "apihelp-main-param-requestid": "在此處提供的任何值都將包括在響應之中。可用於區分請求。",
        "apihelp-parse-paramvalue-prop-revid": "添加已解析頁面的修訂 ID。",
        "apihelp-parse-paramvalue-prop-displaytitle": "添加已解析 wiki 文字的標題。",
        "apihelp-parse-paramvalue-prop-headitems": "提供放置頁面裡的 <code>&lt;head&gt;</code> 之項目。",
-       "apihelp-parse-paramvalue-prop-headhtml": "取得頁面已解析的 <code>&lt;head&gt;</code>。",
+       "apihelp-parse-paramvalue-prop-headhtml": "給予頁面已解析的 doctype、開啟的 <code>&lt;html&gt;</code>、<code>&lt;head&gt;</code> 元素、以及開啟的 <code>&lt;body&gt;</code>。",
        "apihelp-parse-paramvalue-prop-modules": "在頁面提供使用的 ResourceLoader 模組。要載入請使用 <code>mw.loader.using()</code>。<kbd>jsconfigvars</kbd> 或 <kbd>encodedjsconfigvars</kbd> 其一必須與 <kbd>modules</kbd> 一同被請求。",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "針對頁面提供指定的 JavaScript 設置變數。若要套用,請使用 <code>mw.config.set()</code>。",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "指定頁面的 JavaScript 設置變量為 JSON 字串。",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "添加使用者的註冊日期。",
        "apihelp-query+userinfo-paramvalue-prop-unreadcount": "添加未讀頁面數目在使用者的監視清單(最多 $1,若有更多則回傳 <samp>$2</samp>)。",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "替使用者添加中心 ID 與附加狀態。",
+       "apihelp-query+userinfo-paramvalue-prop-latestcontrib": "添加使用者最新貢獻的日期。",
        "apihelp-query+userinfo-param-attachedwiki": "以 <kbd>$1prop=centralids</kbd> 來表明使用者是否附加於由此 ID 所識別出的 wiki。",
        "apihelp-query+userinfo-example-simple": "取得目前使用者的資訊。",
        "apihelp-query+userinfo-example-data": "取得目前使用者的額外資訊。",
        "apihelp-format-example-generic": "以 $1 格式傳回查詢結果。",
        "apihelp-format-param-wrappedhtml": "回傳作為 JSON 物件的美觀列印 HTML 內容以及關聯 ResourceLoader 模組。",
        "apihelp-json-summary": "使用 JSON 格式輸出資料。",
-       "apihelp-json-param-callback": "若有指定,將輸出包在指定的函式調用。出於安全考量,會限制所有使用者特定資料。",
+       "apihelp-json-param-callback": "若有指定,將輸出包在指定的函式呼叫。出於安全考量,會限制所有使用者特定資料。",
        "apihelp-json-param-utf8": "若有指定的話,將多數(並非全部)非 ASCII 字元編碼成 UTF-8,而不是以十六進位轉義序列來取代掉。預設是當 <var>formatversion</var> 不是 <kbd>1</kbd> 時。",
-       "apihelp-json-param-ascii": "è\8b¥æ\9c\89æ\8c\87å®\9aï¼\8c編碼æ\89\80æ\9c\89使ç\94¨å\8d\81å\85­é\80²ä½\8dè½\89義序列的非 ASCII。預設當 <var>formatversion</var> 為 <kbd>1</kbd> 時。",
-       "apihelp-json-param-formatversion": "輸出格式:\n;1:向下兼容格式(XML 風格布林,用於內容節點的 <samp>*</samp> 鍵、其它)。\n;2:現代格式。\n;latest:使用最新格式(目前為 <kbd>2</kbd>)可能會不帶警告作更改。",
+       "apihelp-json-param-ascii": "è\8b¥æ\9c\89æ\8c\87å®\9aï¼\8c編碼æ\89\80æ\9c\89使ç\94¨å\8d\81å\85­é\80²ä½\8dè·³è\84«序列的非 ASCII。預設當 <var>formatversion</var> 為 <kbd>1</kbd> 時。",
+       "apihelp-json-param-formatversion": "輸出格式:\n;1:向下相容格式(XML 式布林值,用於內容節點的 <samp>*</samp> 鍵、其它)。\n;2:現代格式。\n;latest:使用最新格式(目前為 <kbd>2</kbd>)可能會不帶警告作更改。",
        "apihelp-jsonfm-summary": "使用 JSON 格式輸出資料 (使用 HTML 格式顯示)。",
        "apihelp-none-summary": "不輸出。",
        "apihelp-php-summary": "使用序列化 PHP 格式輸出資料。",
        "api-help-examples": "{{PLURAL:$1|範例}}:",
        "api-help-permissions": "{{PLURAL:$1|權限}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|已授權給}}: $2",
-       "api-help-right-apihighlimits": "在 API 查詢使用較高的限制(慢查詢:$1;快查詢:$2)。慢查詢的限制也適用於多值參數。",
+       "api-help-right-apihighlimits": "在 API 查詢使用較高的限制(慢速查詢:$1;快速查詢:$2)。慢速查詢的限制也適用於多值參數。",
        "api-help-open-in-apisandbox": "<small>[在沙盒中開啟]</small>",
-       "api-help-authmanager-general-usage": "使用此模組的一般程式是:\n# 通過 <kbd>amirequestsfor=$4</kbd> 取得來自 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> 的可用欄位,和來自 <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> 的<kbd>$5</kbd>權杖。\n# 向用戶顯示欄位,並獲得其提交的內容。\n# 提交(POST)至此模組,提供 <var>$1returnurl</var> 及任何相關欄位。\n# 在回應中檢查 <samp>status</samp>。\n#* 如果您收到了 <samp>PASS</samp>(成功)或<samp>FAIL</samp>(失敗),則認為操作結束。成功與否如上句所示。\n#* 如果您收到了 <samp>UI</samp>,向用戶顯示新欄位,並再次獲取其提交的內容。然後再次使用 <var>$1continue</var>,向本模組提交相關欄位,並重復第四步。\n#* 如果您收到了 <samp>REDIRECT</samp>,將使用者指向<samp>redirecttarget</samp> 中的目標,等待其返回<var>$1returnurl</var>。然後再次使用 <var>$1continue</var>,向本模組提交返回 URL 中提供的一切欄位,並重復第四步。\n#* 如果您收到了 <samp>RESTART</samp>,這意味著身份驗證正常運作,但我們沒有連結的使用者帳戶。您可以將此視為 <samp>UI</samp>或<samp>FAIL</samp>。",
+       "api-help-authmanager-general-usage": "使用此模組的一般步驟是:\n# 透過 <kbd>amirequestsfor=$4</kbd> 取得來自 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> 的可用欄位,和來自 <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> 的<kbd>$5</kbd>權杖。\n# 向使用者顯示欄位,並獲得其提交的內容。\n# 提交(POST)至此模組,提供 <var>$1returnurl</var> 及任何相關欄位。\n# 在回應中檢查 <samp>status</samp>。\n#* 如果您收到了 <samp>PASS</samp>(成功)或<samp>FAIL</samp>(失敗),則認為操作結束。成功與否如上句所示。\n#* 如果您收到了 <samp>UI</samp>,向使用者顯示新欄位,並再次獲取其提交的內容。然後再次使用 <var>$1continue</var>,向本模組提交相關欄位,並重復第四步。\n#* 如果您收到了 <samp>REDIRECT</samp>,將使用者指向<samp>redirecttarget</samp> 中的目標,等待其返回<var>$1returnurl</var>。然後再次使用 <var>$1continue</var>,向本模組提交返回 URL 中提供的一切欄位,並重復第四步。\n#* 如果您收到了 <samp>RESTART</samp>,表示身份驗證正常運作,但我們沒有連結的使用者帳戶。您可以將此視為 <samp>UI</samp>或<samp>FAIL</samp>。",
        "api-help-authmanagerhelper-requests": "只使用這些身份驗證請求,透過自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>回傳的<samp>id</samp>與<kbd>amirequestsfor=$1</kbd>,或來自此模組之前的回應。",
        "api-help-authmanagerhelper-request": "使用此身份驗證請求,透過自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>回傳的<samp>id</samp>與<kbd>amirequestsfor=$1</kbd>。",
        "api-help-authmanagerhelper-messageformat": "用於回傳訊息的格式。",
index b6fedcd..cd9eac4 100644 (file)
@@ -122,10 +122,13 @@ abstract class AbstractPasswordPrimaryAuthenticationProvider
 
                if ( !$reset && $this->config->get( 'InvalidPasswordReset' ) && !$status->isGood() ) {
                        $hard = $status->getValue()['forceChange'] ?? false;
-                       $reset = (object)[
-                               'msg' => $status->getMessage( $hard ? 'resetpass-validity' : 'resetpass-validity-soft' ),
-                               'hard' => $hard,
-                       ];
+
+                       if ( $hard || !empty( $status->getValue()['suggestChangeOnLogin'] ) ) {
+                               $reset = (object)[
+                                       'msg' => $status->getMessage( $hard ? 'resetpass-validity' : 'resetpass-validity-soft' ),
+                                       'hard' => $hard,
+                               ];
+                       }
                }
 
                if ( $reset ) {
index f9174a7..3515a70 100644 (file)
@@ -232,7 +232,9 @@ class AuthManager implements LoggerAwareInterface {
        }
 
        /**
-        * Call a legacy AuthPlugin method, if necessary
+        * This used to call a legacy AuthPlugin method, if necessary. Since that code has
+        * been removed, it now just returns the $return parameter.
+        *
         * @codeCoverageIgnore
         * @deprecated For backwards compatibility only, should be avoided in new code
         * @param string $method AuthPlugin method to call
@@ -241,13 +243,8 @@ class AuthManager implements LoggerAwareInterface {
         * @return mixed Return value from the AuthPlugin method, or $return
         */
        public static function callLegacyAuthPlugin( $method, array $params, $return = null ) {
-               global $wgAuth;
-
-               if ( $wgAuth && !$wgAuth instanceof AuthManagerAuthPlugin ) {
-                       return $wgAuth->$method( ...$params );
-               } else {
-                       return $return;
-               }
+               wfDeprecated( __METHOD__, '1.33' );
+               return $return;
        }
 
        /**
@@ -1009,7 +1006,7 @@ class AuthManager implements LoggerAwareInterface {
                if ( $block ) {
                        $errorParams = [
                                $block->getTarget(),
-                               $block->mReason ?: wfMessage( 'blockednoreason' )->text(),
+                               $block->getReason() ?: wfMessage( 'blockednoreason' )->text(),
                                $block->getByName()
                        ];
 
@@ -1426,7 +1423,7 @@ class AuthManager implements LoggerAwareInterface {
                                        // @codeCoverageIgnoreEnd
                                }
                                $this->setDefaultUserOptions( $user, $creator->isAnon() );
-                               \Hooks::run( 'LocalUserCreated', [ $user, false ] );
+                               \Hooks::runWithoutAbort( 'LocalUserCreated', [ $user, false ] );
                                $user->saveSettings();
                                $state['userid'] = $user->getId();
 
@@ -1745,7 +1742,6 @@ class AuthManager implements LoggerAwareInterface {
                // Inform the providers
                $this->callMethodOnProviders( 6, 'autoCreatedAccount', [ $user, $source ] );
 
-               \Hooks::run( 'AuthPluginAutoCreate', [ $user ], '1.27' );
                \Hooks::run( 'LocalUserCreated', [ $user, true ] );
                $user->saveSettings();
 
@@ -2105,10 +2101,8 @@ class AuthManager implements LoggerAwareInterface {
                                $id = $req->getUniqueId();
 
                                // If a required request if from a Primary, mark it as "primary-required" instead
-                               if ( $isPrimary ) {
-                                       if ( $req->required ) {
-                                               $req->required = AuthenticationRequest::PRIMARY_REQUIRED;
-                                       }
+                               if ( $isPrimary && $req->required ) {
+                                       $req->required = AuthenticationRequest::PRIMARY_REQUIRED;
                                }
 
                                if (
diff --git a/includes/auth/AuthManagerAuthPlugin.php b/includes/auth/AuthManagerAuthPlugin.php
deleted file mode 100644 (file)
index 008639c..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-namespace MediaWiki\Auth;
-
-use Psr\Log\LoggerInterface;
-use User;
-
-/**
- * Backwards-compatibility wrapper for AuthManager via $wgAuth
- * @since 1.27
- * @deprecated since 1.27
- */
-class AuthManagerAuthPlugin extends \AuthPlugin {
-       /** @var string|null */
-       protected $domain = null;
-
-       /** @var LoggerInterface */
-       protected $logger = null;
-
-       public function __construct() {
-               $this->logger = \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' );
-       }
-
-       public function userExists( $name ) {
-               return AuthManager::singleton()->userExists( $name );
-       }
-
-       public function authenticate( $username, $password ) {
-               $data = [
-                       'username' => $username,
-                       'password' => $password,
-               ];
-               if ( $this->domain !== null && $this->domain !== '' ) {
-                       $data['domain'] = $this->domain;
-               }
-               $reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_LOGIN );
-               $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
-
-               $res = AuthManager::singleton()->beginAuthentication( $reqs, 'null:' );
-               switch ( $res->status ) {
-                       case AuthenticationResponse::PASS:
-                               return true;
-                       case AuthenticationResponse::FAIL:
-                               // Hope it's not a PreAuthenticationProvider that failed...
-                               $msg = $res->message instanceof \Message ? $res->message : new \Message( $res->message );
-                               $this->logger->info( __METHOD__ . ': Authentication failed: ' . $msg->plain() );
-                               return false;
-                       default:
-                               throw new \BadMethodCallException(
-                                       'AuthManager does not support such simplified authentication'
-                               );
-               }
-       }
-
-       public function modifyUITemplate( &$template, &$type ) {
-               // AuthManager does not support direct UI screwing-around-with
-       }
-
-       public function setDomain( $domain ) {
-               $this->domain = $domain;
-       }
-
-       public function getDomain() {
-               return $this->domain ?? 'invaliddomain';
-       }
-
-       public function validDomain( $domain ) {
-               $domainList = $this->domainList();
-               return $domainList ? in_array( $domain, $domainList, true ) : $domain === '';
-       }
-
-       public function updateUser( &$user ) {
-               \Hooks::run( 'UserLoggedIn', [ $user ] );
-               return true;
-       }
-
-       public function autoCreate() {
-               return true;
-       }
-
-       public function allowPropChange( $prop = '' ) {
-               return AuthManager::singleton()->allowsPropertyChange( $prop );
-       }
-
-       public function allowPasswordChange() {
-               $reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_CHANGE );
-               foreach ( $reqs as $req ) {
-                       if ( $req instanceof PasswordAuthenticationRequest ) {
-                               return true;
-                       }
-               }
-
-               return false;
-       }
-
-       public function allowSetLocalPassword() {
-               // There should be a PrimaryAuthenticationProvider that does this, if necessary
-               return false;
-       }
-
-       public function setPassword( $user, $password ) {
-               $data = [
-                       'username' => $user->getName(),
-                       'password' => $password,
-               ];
-               if ( $this->domain !== null && $this->domain !== '' ) {
-                       $data['domain'] = $this->domain;
-               }
-               $reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_CHANGE );
-               $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
-               foreach ( $reqs as $req ) {
-                       $status = AuthManager::singleton()->allowsAuthenticationDataChange( $req );
-                       if ( !$status->isGood() ) {
-                               $this->logger->info( __METHOD__ . ': Password change rejected: {reason}', [
-                                       'username' => $data['username'],
-                                       'reason' => $status->getWikiText( null, null, 'en' ),
-                               ] );
-                               return false;
-                       }
-               }
-               foreach ( $reqs as $req ) {
-                       AuthManager::singleton()->changeAuthenticationData( $req );
-               }
-               return true;
-       }
-
-       public function updateExternalDB( $user ) {
-               // This fires the necessary hook
-               $user->saveSettings();
-               return true;
-       }
-
-       public function updateExternalDBGroups( $user, $addgroups, $delgroups = [] ) {
-               throw new \BadMethodCallException(
-                       'Update of user groups via AuthPlugin is not supported with AuthManager.'
-               );
-       }
-
-       public function canCreateAccounts() {
-               return AuthManager::singleton()->canCreateAccounts();
-       }
-
-       public function addUser( $user, $password, $email = '', $realname = '' ) {
-               throw new \BadMethodCallException(
-                       'Creation of users via AuthPlugin is not supported with '
-                       . 'AuthManager. Generally, user creation should be left to either '
-                       . 'Special:CreateAccount, auto-creation when triggered by a '
-                       . 'SessionProvider or PrimaryAuthenticationProvider, or '
-                       . 'User::newSystemUser().'
-               );
-       }
-
-       public function strict() {
-               // There should be a PrimaryAuthenticationProvider that does this, if necessary
-               return true;
-       }
-
-       public function strictUserAuth( $username ) {
-               // There should be a PrimaryAuthenticationProvider that does this, if necessary
-               return true;
-       }
-
-       public function initUser( &$user, $autocreate = false ) {
-               \Hooks::run( 'LocalUserCreated', [ $user, $autocreate ] );
-       }
-
-       public function getCanonicalName( $username ) {
-               // AuthManager doesn't support restrictions beyond MediaWiki's
-               return $username;
-       }
-
-       public function getUserInstance( User &$user ) {
-               return new AuthManagerAuthPluginUser( $user );
-       }
-
-       public function domainList() {
-               return [];
-       }
-}
diff --git a/includes/auth/AuthManagerAuthPluginUser.php b/includes/auth/AuthManagerAuthPluginUser.php
deleted file mode 100644 (file)
index e31be60..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-namespace MediaWiki\Auth;
-
-use User;
-
-/**
- * @since 1.27
- * @deprecated since 1.27
- */
-class AuthManagerAuthPluginUser extends \AuthPluginUser {
-       /** @var User */
-       private $user;
-
-       function __construct( $user ) {
-               $this->user = $user;
-       }
-
-       public function getId() {
-               return $this->user->getId();
-       }
-
-       public function isLocked() {
-               return $this->user->isLocked();
-       }
-
-       public function isHidden() {
-               return $this->user->isHidden();
-       }
-
-       public function resetAuthToken() {
-               \MediaWiki\Session\SessionManager::singleton()->invalidateSessionsForUser( $this->user );
-               return true;
-       }
-}
diff --git a/includes/auth/AuthPluginPrimaryAuthenticationProvider.php b/includes/auth/AuthPluginPrimaryAuthenticationProvider.php
deleted file mode 100644 (file)
index cd0734d..0000000
+++ /dev/null
@@ -1,429 +0,0 @@
-<?php
-/**
- * Primary authentication provider wrapper for AuthPlugin
- *
- * 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 Auth
- */
-
-namespace MediaWiki\Auth;
-
-use AuthPlugin;
-use User;
-
-/**
- * Primary authentication provider wrapper for AuthPlugin
- * @warning If anything depends on the wrapped AuthPlugin being $wgAuth, it won't work with this!
- * @ingroup Auth
- * @since 1.27
- * @deprecated since 1.27
- */
-class AuthPluginPrimaryAuthenticationProvider
-       extends AbstractPasswordPrimaryAuthenticationProvider
-{
-       private $auth;
-       private $hasDomain;
-       private $requestType = null;
-
-       /**
-        * @param AuthPlugin $auth AuthPlugin to wrap
-        * @param string|null $requestType Class name of the
-        *  PasswordAuthenticationRequest to use. If $auth->domainList() returns
-        *  more than one domain, this must be a PasswordDomainAuthenticationRequest.
-        */
-       public function __construct( AuthPlugin $auth, $requestType = null ) {
-               parent::__construct();
-
-               if ( $auth instanceof AuthManagerAuthPlugin ) {
-                       throw new \InvalidArgumentException(
-                               'Trying to wrap AuthManagerAuthPlugin in AuthPluginPrimaryAuthenticationProvider ' .
-                                       'makes no sense.'
-                       );
-               }
-
-               $need = count( $auth->domainList() ) > 1
-                       ? PasswordDomainAuthenticationRequest::class
-                       : PasswordAuthenticationRequest::class;
-               if ( $requestType === null ) {
-                       $requestType = $need;
-               } elseif ( $requestType !== $need && !is_subclass_of( $requestType, $need ) ) {
-                       throw new \InvalidArgumentException( "$requestType is not a $need" );
-               }
-
-               $this->auth = $auth;
-               $this->requestType = $requestType;
-               $this->hasDomain = (
-                       $requestType === PasswordDomainAuthenticationRequest::class ||
-                       is_subclass_of( $requestType, PasswordDomainAuthenticationRequest::class )
-               );
-               $this->authoritative = $auth->strict();
-
-               // Registering hooks from core is unusual, but is needed here to be
-               // able to call the AuthPlugin methods those hooks replace.
-               \Hooks::register( 'UserSaveSettings', [ $this, 'onUserSaveSettings' ] );
-               \Hooks::register( 'UserGroupsChanged', [ $this, 'onUserGroupsChanged' ] );
-               \Hooks::register( 'UserLoggedIn', [ $this, 'onUserLoggedIn' ] );
-               \Hooks::register( 'LocalUserCreated', [ $this, 'onLocalUserCreated' ] );
-       }
-
-       /**
-        * Create an appropriate AuthenticationRequest
-        * @return PasswordAuthenticationRequest
-        */
-       protected function makeAuthReq() {
-               $class = $this->requestType;
-               if ( $this->hasDomain ) {
-                       return new $class( $this->auth->domainList() );
-               } else {
-                       return new $class();
-               }
-       }
-
-       /**
-        * Call $this->auth->setDomain()
-        * @param PasswordAuthenticationRequest $req
-        */
-       protected function setDomain( $req ) {
-               if ( $this->hasDomain ) {
-                       $domain = $req->domain;
-               } else {
-                       // Just grab the first one.
-                       $domainList = $this->auth->domainList();
-                       $domain = reset( $domainList );
-               }
-
-               // Special:UserLogin does this. Strange.
-               if ( !$this->auth->validDomain( $domain ) ) {
-                       $domain = $this->auth->getDomain();
-               }
-               $this->auth->setDomain( $domain );
-       }
-
-       /**
-        * Hook function to call AuthPlugin::updateExternalDB()
-        * @param User $user
-        * @codeCoverageIgnore
-        */
-       public function onUserSaveSettings( $user ) {
-               // No way to know the domain, just hope the provider handles that.
-               $this->auth->updateExternalDB( $user );
-       }
-
-       /**
-        * Hook function to call AuthPlugin::updateExternalDBGroups()
-        * @param User $user
-        * @param array $added
-        * @param array $removed
-        */
-       public function onUserGroupsChanged( $user, $added, $removed ) {
-               // No way to know the domain, just hope the provider handles that.
-               $this->auth->updateExternalDBGroups( $user, $added, $removed );
-       }
-
-       /**
-        * Hook function to call AuthPlugin::updateUser()
-        * @param User $user
-        */
-       public function onUserLoggedIn( $user ) {
-               $hookUser = $user;
-               // No way to know the domain, just hope the provider handles that.
-               $this->auth->updateUser( $hookUser );
-               if ( $hookUser !== $user ) {
-                       throw new \UnexpectedValueException(
-                               get_class( $this->auth ) . '::updateUser() tried to replace $user!'
-                       );
-               }
-       }
-
-       /**
-        * Hook function to call AuthPlugin::initUser()
-        * @param User $user
-        * @param bool $autocreated
-        */
-       public function onLocalUserCreated( $user, $autocreated ) {
-               // For $autocreated, see self::autoCreatedAccount()
-               if ( !$autocreated ) {
-                       $hookUser = $user;
-                       // No way to know the domain, just hope the provider handles that.
-                       $this->auth->initUser( $hookUser, $autocreated );
-                       if ( $hookUser !== $user ) {
-                               throw new \UnexpectedValueException(
-                                       get_class( $this->auth ) . '::initUser() tried to replace $user!'
-                               );
-                       }
-               }
-       }
-
-       public function getUniqueId() {
-               return parent::getUniqueId() . ':' . get_class( $this->auth );
-       }
-
-       public function getAuthenticationRequests( $action, array $options ) {
-               switch ( $action ) {
-                       case AuthManager::ACTION_LOGIN:
-                       case AuthManager::ACTION_CREATE:
-                               return [ $this->makeAuthReq() ];
-
-                       case AuthManager::ACTION_CHANGE:
-                       case AuthManager::ACTION_REMOVE:
-                               // No way to know the domain, just hope the provider handles that.
-                               return $this->auth->allowPasswordChange() ? [ $this->makeAuthReq() ] : [];
-
-                       default:
-                               return [];
-               }
-       }
-
-       public function beginPrimaryAuthentication( array $reqs ) {
-               $req = AuthenticationRequest::getRequestByClass( $reqs, $this->requestType );
-               if ( !$req || $req->username === null || $req->password === null ||
-                       ( $this->hasDomain && $req->domain === null )
-               ) {
-                       return AuthenticationResponse::newAbstain();
-               }
-
-               $username = User::getCanonicalName( $req->username, 'usable' );
-               if ( $username === false ) {
-                       return AuthenticationResponse::newAbstain();
-               }
-
-               $this->setDomain( $req );
-               if ( $this->testUserCanAuthenticateInternal( User::newFromName( $username ) ) &&
-                       $this->auth->authenticate( $username, $req->password )
-               ) {
-                       return AuthenticationResponse::newPass( $username );
-               } else {
-                       $this->authoritative = $this->auth->strict() || $this->auth->strictUserAuth( $username );
-                       return $this->failResponse( $req );
-               }
-       }
-
-       public function testUserCanAuthenticate( $username ) {
-               $username = User::getCanonicalName( $username, 'usable' );
-               if ( $username === false ) {
-                       return false;
-               }
-
-               // We have to check every domain, because at least LdapAuthentication
-               // interprets AuthPlugin::userExists() as applying only to the current
-               // domain.
-               $curDomain = $this->auth->getDomain();
-               $domains = $this->auth->domainList() ?: [ '' ];
-               foreach ( $domains as $domain ) {
-                       $this->auth->setDomain( $domain );
-                       if ( $this->testUserCanAuthenticateInternal( User::newFromName( $username ) ) ) {
-                               $this->auth->setDomain( $curDomain );
-                               return true;
-                       }
-               }
-               $this->auth->setDomain( $curDomain );
-               return false;
-       }
-
-       /**
-        * @see self::testUserCanAuthenticate
-        * @note The caller is responsible for calling $this->auth->setDomain()
-        * @param User $user
-        * @return bool
-        */
-       private function testUserCanAuthenticateInternal( $user ) {
-               if ( $this->auth->userExists( $user->getName() ) ) {
-                       return !$this->auth->getUserInstance( $user )->isLocked();
-               } else {
-                       return false;
-               }
-       }
-
-       public function providerRevokeAccessForUser( $username ) {
-               $username = User::getCanonicalName( $username, 'usable' );
-               if ( $username === false ) {
-                       return;
-               }
-               $user = User::newFromName( $username );
-               if ( $user ) {
-                       // Reset the password on every domain.
-                       $curDomain = $this->auth->getDomain();
-                       $domains = $this->auth->domainList() ?: [ '' ];
-                       $failed = [];
-                       foreach ( $domains as $domain ) {
-                               $this->auth->setDomain( $domain );
-                               if ( $this->testUserCanAuthenticateInternal( $user ) &&
-                                       !$this->auth->setPassword( $user, null )
-                               ) {
-                                       $failed[] = $domain === '' ? '(default)' : $domain;
-                               }
-                       }
-                       $this->auth->setDomain( $curDomain );
-                       if ( $failed ) {
-                               throw new \UnexpectedValueException(
-                                       "AuthPlugin failed to reset password for $username in the following domains: "
-                                               . implode( ' ', $failed )
-                               );
-                       }
-               }
-       }
-
-       public function testUserExists( $username, $flags = User::READ_NORMAL ) {
-               $username = User::getCanonicalName( $username, 'usable' );
-               if ( $username === false ) {
-                       return false;
-               }
-
-               // We have to check every domain, because at least LdapAuthentication
-               // interprets AuthPlugin::userExists() as applying only to the current
-               // domain.
-               $curDomain = $this->auth->getDomain();
-               $domains = $this->auth->domainList() ?: [ '' ];
-               foreach ( $domains as $domain ) {
-                       $this->auth->setDomain( $domain );
-                       if ( $this->auth->userExists( $username ) ) {
-                               $this->auth->setDomain( $curDomain );
-                               return true;
-                       }
-               }
-               $this->auth->setDomain( $curDomain );
-               return false;
-       }
-
-       public function providerAllowsPropertyChange( $property ) {
-               // No way to know the domain, just hope the provider handles that.
-               return $this->auth->allowPropChange( $property );
-       }
-
-       public function providerAllowsAuthenticationDataChange(
-               AuthenticationRequest $req, $checkData = true
-       ) {
-               if ( get_class( $req ) !== $this->requestType ) {
-                       return \StatusValue::newGood( 'ignored' );
-               }
-
-               // Hope it works, AuthPlugin gives us no way to do this.
-               $curDomain = $this->auth->getDomain();
-               $this->setDomain( $req );
-               try {
-                       // If !$checkData the domain might be wrong. Nothing we can do about that.
-                       if ( !$this->auth->allowPasswordChange() ) {
-                               return \StatusValue::newFatal( 'authmanager-authplugin-setpass-denied' );
-                       }
-
-                       if ( !$checkData ) {
-                               return \StatusValue::newGood();
-                       }
-
-                       if ( $this->hasDomain ) {
-                               if ( $req->domain === null ) {
-                                       return \StatusValue::newGood( 'ignored' );
-                               }
-                               if ( !$this->auth->validDomain( $req->domain ) ) {
-                                       return \StatusValue::newFatal( 'authmanager-authplugin-setpass-bad-domain' );
-                               }
-                       }
-
-                       $username = User::getCanonicalName( $req->username, 'usable' );
-                       if ( $username !== false ) {
-                               $sv = \StatusValue::newGood();
-                               if ( $req->password !== null ) {
-                                       if ( $req->password !== $req->retype ) {
-                                               $sv->fatal( 'badretype' );
-                                       } else {
-                                               $sv->merge( $this->checkPasswordValidity( $username, $req->password ) );
-                                       }
-                               }
-                               return $sv;
-                       } else {
-                               return \StatusValue::newGood( 'ignored' );
-                       }
-               } finally {
-                       $this->auth->setDomain( $curDomain );
-               }
-       }
-
-       public function providerChangeAuthenticationData( AuthenticationRequest $req ) {
-               if ( get_class( $req ) === $this->requestType ) {
-                       $username = $req->username !== null ? User::getCanonicalName( $req->username, 'usable' ) : false;
-                       if ( $username === false ) {
-                               return;
-                       }
-
-                       if ( $this->hasDomain && $req->domain === null ) {
-                               return;
-                       }
-
-                       $this->setDomain( $req );
-                       $user = User::newFromName( $username );
-                       if ( !$this->auth->setPassword( $user, $req->password ) ) {
-                               // This is totally unfriendly and leaves other
-                               // AuthenticationProviders in an uncertain state, but what else
-                               // can we do?
-                               throw new \ErrorPageError(
-                                       'authmanager-authplugin-setpass-failed-title',
-                                       'authmanager-authplugin-setpass-failed-message'
-                               );
-                       }
-               }
-       }
-
-       public function accountCreationType() {
-               // No way to know the domain, just hope the provider handles that.
-               return $this->auth->canCreateAccounts() ? self::TYPE_CREATE : self::TYPE_NONE;
-       }
-
-       public function testForAccountCreation( $user, $creator, array $reqs ) {
-               return \StatusValue::newGood();
-       }
-
-       public function beginPrimaryAccountCreation( $user, $creator, array $reqs ) {
-               if ( $this->accountCreationType() === self::TYPE_NONE ) {
-                       throw new \BadMethodCallException( 'Shouldn\'t call this when accountCreationType() is NONE' );
-               }
-
-               $req = AuthenticationRequest::getRequestByClass( $reqs, $this->requestType );
-               if ( !$req || $req->username === null || $req->password === null ||
-                       ( $this->hasDomain && $req->domain === null )
-               ) {
-                       return AuthenticationResponse::newAbstain();
-               }
-
-               $username = User::getCanonicalName( $req->username, 'usable' );
-               if ( $username === false ) {
-                       return AuthenticationResponse::newAbstain();
-               }
-
-               $this->setDomain( $req );
-               if ( $this->auth->addUser(
-                       $user, $req->password, $user->getEmail(), $user->getRealName()
-               ) ) {
-                       return AuthenticationResponse::newPass();
-               } else {
-                       return AuthenticationResponse::newFail(
-                               new \Message( 'authmanager-authplugin-create-fail' )
-                       );
-               }
-       }
-
-       public function autoCreatedAccount( $user, $source ) {
-               $hookUser = $user;
-               // No way to know the domain, just hope the provider handles that.
-               $this->auth->initUser( $hookUser, true );
-               if ( $hookUser !== $user ) {
-                       throw new \UnexpectedValueException(
-                               get_class( $this->auth ) . '::initUser() tried to replace $user!'
-                       );
-               }
-       }
-}
index 7fc362a..4744c4d 100644 (file)
@@ -370,6 +370,7 @@ abstract class AuthenticationRequest {
         * @return AuthenticationRequest
         */
        public static function __set_state( $data ) {
+               // @phan-suppress-next-line PhanTypeInstantiateAbstract
                $ret = new static();
                foreach ( $data as $k => $v ) {
                        $ret->$k = $v;
index 7488fba..10925b5 100644 (file)
@@ -77,8 +77,8 @@ class CheckBlocksSecondaryAuthenticationProvider extends AbstractSecondaryAuthen
        public function testUserForCreation( $user, $autocreate, array $options = [] ) {
                $block = $user->isBlockedFromCreateAccount();
                if ( $block ) {
-                       if ( $block->mReason ) {
-                               $reason = $block->mReason;
+                       if ( $block->getReason() ) {
+                               $reason = $block->getReason();
                        } else {
                                $msg = \Message::newFromKey( 'blockednoreason' );
                                if ( !\RequestContext::getMain()->getUser()->isSafeToLoad() ) {
index e9adb7e..b646380 100644 (file)
@@ -46,6 +46,13 @@ class LocalPasswordPrimaryAuthenticationProvider
                $this->loginOnly = !empty( $params['loginOnly'] );
        }
 
+       /**
+        * Check if the password has expired and needs a reset
+        *
+        * @param string $username
+        * @param \stdClass $row A row from the user table
+        * @return \stdClass|null
+        */
        protected function getPasswordResetData( $username, $row ) {
                $now = wfTimestamp();
                $expiration = wfTimestampOrNull( TS_UNIX, $row->user_password_expires );
@@ -296,18 +303,16 @@ class LocalPasswordPrimaryAuthenticationProvider
                }
 
                $req = AuthenticationRequest::getRequestByClass( $reqs, PasswordAuthenticationRequest::class );
-               if ( $req ) {
-                       if ( $req->username !== null && $req->password !== null ) {
-                               // Nothing we can do besides claim it, because the user isn't in
-                               // the DB yet
-                               if ( $req->username !== $user->getName() ) {
-                                       $req = clone $req;
-                                       $req->username = $user->getName();
-                               }
-                               $ret = AuthenticationResponse::newPass( $req->username );
-                               $ret->createRequest = $req;
-                               return $ret;
+               if ( $req && $req->username !== null && $req->password !== null ) {
+                       // Nothing we can do besides claim it, because the user isn't in
+                       // the DB yet
+                       if ( $req->username !== $user->getName() ) {
+                               $req = clone $req;
+                               $req->username = $user->getName();
                        }
+                       $ret = AuthenticationResponse::newPass( $req->username );
+                       $ret->createRequest = $req;
+                       return $ret;
                }
                return AuthenticationResponse::newAbstain();
        }
index 045f791..e129538 100644 (file)
@@ -356,23 +356,21 @@ class TemporaryPasswordPrimaryAuthenticationProvider
                $req = AuthenticationRequest::getRequestByClass(
                        $reqs, TemporaryPasswordAuthenticationRequest::class
                );
-               if ( $req ) {
-                       if ( $req->username !== null && $req->password !== null ) {
-                               // Nothing we can do yet, because the user isn't in the DB yet
-                               if ( $req->username !== $user->getName() ) {
-                                       $req = clone $req;
-                                       $req->username = $user->getName();
-                               }
-
-                               if ( $req->mailpassword ) {
-                                       // prevent EmailNotificationSecondaryAuthenticationProvider from sending another mail
-                                       $this->manager->setAuthenticationSessionData( 'no-email', true );
-                               }
+               if ( $req && $req->username !== null && $req->password !== null ) {
+                       // Nothing we can do yet, because the user isn't in the DB yet
+                       if ( $req->username !== $user->getName() ) {
+                               $req = clone $req;
+                               $req->username = $user->getName();
+                       }
 
-                               $ret = AuthenticationResponse::newPass( $req->username );
-                               $ret->createRequest = $req;
-                               return $ret;
+                       if ( $req->mailpassword ) {
+                               // prevent EmailNotificationSecondaryAuthenticationProvider from sending another mail
+                               $this->manager->setAuthenticationSessionData( 'no-email', true );
                        }
+
+                       $ret = AuthenticationResponse::newPass( $req->username );
+                       $ret->createRequest = $req;
+                       return $ret;
                }
                return AuthenticationResponse::newAbstain();
        }
index 72f6eaa..2e8752e 100644 (file)
@@ -25,6 +25,7 @@ namespace MediaWiki\Block;
 use MediaWiki\Block\Restriction\NamespaceRestriction;
 use MediaWiki\Block\Restriction\PageRestriction;
 use MediaWiki\Block\Restriction\Restriction;
+use MWException;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
 
@@ -51,7 +52,7 @@ class BlockRestriction {
                        return [];
                }
 
-               $db = $db ?: wfGetDb( DB_REPLICA );
+               $db = $db ?: wfGetDB( DB_REPLICA );
 
                $result = $db->select(
                        [ 'ipblocks_restrictions', 'page' ],
@@ -73,7 +74,7 @@ class BlockRestriction {
         * @return bool
         */
        public static function insert( array $restrictions ) {
-               if ( empty( $restrictions ) ) {
+               if ( !$restrictions ) {
                        return false;
                }
 
@@ -85,18 +86,20 @@ class BlockRestriction {
                        $rows[] = $restriction->toRow();
                }
 
-               if ( empty( $rows ) ) {
+               if ( !$rows ) {
                        return false;
                }
 
                $dbw = wfGetDB( DB_MASTER );
 
-               return $dbw->insert(
+               $dbw->insert(
                        'ipblocks_restrictions',
                        $rows,
                        __METHOD__,
                        [ 'IGNORE' ]
                );
+
+               return true;
        }
 
        /**
@@ -180,7 +183,7 @@ class BlockRestriction {
 
                $parentBlockId = (int)$parentBlockId;
 
-               $db = wfGetDb( DB_MASTER );
+               $db = wfGetDB( DB_MASTER );
 
                $db->startAtomic( __METHOD__ );
 
index 9fb7603..a010e83 100644 (file)
@@ -59,28 +59,28 @@ abstract class AbstractRestriction implements Restriction {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public static function getType() {
                return static::TYPE;
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public static function getTypeId() {
                return static::TYPE_ID;
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function getBlockId() {
                return $this->blockId;
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function setBlockId( $blockId ) {
                $this->blockId = (int)$blockId;
@@ -89,21 +89,22 @@ abstract class AbstractRestriction implements Restriction {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function getValue() {
                return $this->value;
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public static function newFromRow( \stdClass $row ) {
+               // @phan-suppress-next-line PhanTypeInstantiateAbstract
                return new static( $row->ir_ipb_id, $row->ir_value );
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function toRow() {
                return [
@@ -114,14 +115,14 @@ abstract class AbstractRestriction implements Restriction {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function equals( Restriction $other ) {
                return $this->getHash() === $other->getHash();
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function getHash() {
                return $this->getType() . '-' . $this->getValue();
index bf9769f..8d86853 100644 (file)
@@ -25,17 +25,17 @@ namespace MediaWiki\Block\Restriction;
 class NamespaceRestriction extends AbstractRestriction {
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        const TYPE = 'ns';
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        const TYPE_ID = 2;
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function matches( \Title $title ) {
                return $this->getValue() === $title->getNamespace();
index 5d3fabb..ea73d19 100644 (file)
@@ -25,12 +25,12 @@ namespace MediaWiki\Block\Restriction;
 class PageRestriction extends AbstractRestriction {
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        const TYPE = 'page';
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        const TYPE_ID = 1;
 
@@ -40,7 +40,7 @@ class PageRestriction extends AbstractRestriction {
        protected $title;
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function matches( \Title $title ) {
                if ( !$this->getTitle() ) {
@@ -84,7 +84,7 @@ class PageRestriction extends AbstractRestriction {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public static function newFromRow( \stdClass $row ) {
                $restriction = parent::newFromRow( $row );
diff --git a/includes/cache/CacheDependency.php b/includes/cache/CacheDependency.php
deleted file mode 100644 (file)
index 11df5bc..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-<?php
-/**
- * Data caching with dependencies.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Cache
- */
-use MediaWiki\MediaWikiServices;
-
-/**
- * This class stores an arbitrary value along with its dependencies.
- * Users should typically only use DependencyWrapper::getValueFromCache(),
- * rather than instantiating one of these objects directly.
- * @ingroup Cache
- */
-class DependencyWrapper {
-       private $value;
-       /** @var CacheDependency[] */
-       private $deps;
-
-       /**
-        * @param mixed $value The user-supplied value
-        * @param CacheDependency|CacheDependency[] $deps A dependency or dependency
-        *   array. All dependencies must be objects implementing CacheDependency.
-        */
-       function __construct( $value = false, $deps = [] ) {
-               $this->value = $value;
-
-               if ( !is_array( $deps ) ) {
-                       $deps = [ $deps ];
-               }
-
-               $this->deps = $deps;
-       }
-
-       /**
-        * Returns true if any of the dependencies have expired
-        *
-        * @return bool
-        */
-       function isExpired() {
-               foreach ( $this->deps as $dep ) {
-                       if ( $dep->isExpired() ) {
-                               return true;
-                       }
-               }
-
-               return false;
-       }
-
-       /**
-        * Initialise dependency values in preparation for storing. This must be
-        * called before serialization.
-        */
-       function initialiseDeps() {
-               foreach ( $this->deps as $dep ) {
-                       $dep->loadDependencyValues();
-               }
-       }
-
-       /**
-        * Get the user-defined value
-        * @return bool|mixed
-        */
-       function getValue() {
-               return $this->value;
-       }
-
-       /**
-        * Store the wrapper to a cache
-        *
-        * @param BagOStuff $cache
-        * @param string $key
-        * @param int $expiry
-        */
-       function storeToCache( $cache, $key, $expiry = 0 ) {
-               $this->initialiseDeps();
-               $cache->set( $key, $this, $expiry );
-       }
-
-       /**
-        * Attempt to get a value from the cache. If the value is expired or missing,
-        * it will be generated with the callback function (if present), and the newly
-        * calculated value will be stored to the cache in a wrapper.
-        *
-        * @param BagOStuff $cache
-        * @param string $key The cache key
-        * @param int $expiry The expiry timestamp or interval in seconds
-        * @param bool|callable $callback The callback for generating the value, or false
-        * @param array $callbackParams The function parameters for the callback
-        * @param array $deps The dependencies to store on a cache miss. Note: these
-        *    are not the dependencies used on a cache hit! Cache hits use the stored
-        *    dependency array.
-        *
-        * @return mixed The value, or null if it was not present in the cache and no
-        *    callback was defined.
-        */
-       static function getValueFromCache( $cache, $key, $expiry = 0, $callback = false,
-               $callbackParams = [], $deps = []
-       ) {
-               $obj = $cache->get( $key );
-
-               if ( is_object( $obj ) && $obj instanceof DependencyWrapper && !$obj->isExpired() ) {
-                       $value = $obj->value;
-               } elseif ( $callback ) {
-                       $value = $callback( ...$callbackParams );
-                       # Cache the newly-generated value
-                       $wrapper = new DependencyWrapper( $value, $deps );
-                       $wrapper->storeToCache( $cache, $key, $expiry );
-               } else {
-                       $value = null;
-               }
-
-               return $value;
-       }
-}
-
-/**
- * @ingroup Cache
- */
-abstract class CacheDependency {
-       /**
-        * Returns true if the dependency is expired, false otherwise
-        */
-       abstract function isExpired();
-
-       /**
-        * Hook to perform any expensive pre-serialize loading of dependency values.
-        */
-       function loadDependencyValues() {
-       }
-}
-
-/**
- * @ingroup Cache
- */
-class FileDependency extends CacheDependency {
-       private $filename;
-       private $timestamp;
-
-       /**
-        * Create a file dependency
-        *
-        * @param string $filename The name of the file, preferably fully qualified
-        * @param null|bool|int $timestamp The unix last modified timestamp, or false if the
-        *        file does not exist. If omitted, the timestamp will be loaded from
-        *        the file.
-        *
-        * A dependency on a nonexistent file will be triggered when the file is
-        * created. A dependency on an existing file will be triggered when the
-        * file is changed.
-        */
-       function __construct( $filename, $timestamp = null ) {
-               $this->filename = $filename;
-               $this->timestamp = $timestamp;
-       }
-
-       /**
-        * @return array
-        */
-       function __sleep() {
-               $this->loadDependencyValues();
-
-               return [ 'filename', 'timestamp' ];
-       }
-
-       function loadDependencyValues() {
-               if ( is_null( $this->timestamp ) ) {
-                       Wikimedia\suppressWarnings();
-                       # Dependency on a non-existent file stores "false"
-                       # This is a valid concept!
-                       $this->timestamp = filemtime( $this->filename );
-                       Wikimedia\restoreWarnings();
-               }
-       }
-
-       /**
-        * @return bool
-        */
-       function isExpired() {
-               Wikimedia\suppressWarnings();
-               $lastmod = filemtime( $this->filename );
-               Wikimedia\restoreWarnings();
-               if ( $lastmod === false ) {
-                       if ( $this->timestamp === false ) {
-                               # Still nonexistent
-                               return false;
-                       } else {
-                               # Deleted
-                               wfDebug( "Dependency triggered: {$this->filename} deleted.\n" );
-
-                               return true;
-                       }
-               } else {
-                       if ( $lastmod > $this->timestamp ) {
-                               # Modified or created
-                               wfDebug( "Dependency triggered: {$this->filename} changed.\n" );
-
-                               return true;
-                       } else {
-                               # Not modified
-                               return false;
-                       }
-               }
-       }
-}
-
-/**
- * @ingroup Cache
- */
-class GlobalDependency extends CacheDependency {
-       private $name;
-       private $value;
-
-       function __construct( $name ) {
-               $this->name = $name;
-               $this->value = $GLOBALS[$name];
-       }
-
-       /**
-        * @return bool
-        */
-       function isExpired() {
-               if ( !isset( $GLOBALS[$this->name] ) ) {
-                       return true;
-               }
-
-               return $GLOBALS[$this->name] != $this->value;
-       }
-}
-
-/**
- * @ingroup Cache
- */
-class MainConfigDependency extends CacheDependency {
-       private $name;
-       private $value;
-
-       function __construct( $name ) {
-               $this->name = $name;
-               $this->value = $this->getConfig()->get( $this->name );
-       }
-
-       private function getConfig() {
-               return MediaWikiServices::getInstance()->getMainConfig();
-       }
-
-       /**
-        * @return bool
-        */
-       function isExpired() {
-               if ( !$this->getConfig()->has( $this->name ) ) {
-                       return true;
-               }
-
-               return $this->getConfig()->get( $this->name ) != $this->value;
-       }
-}
-
-/**
- * @ingroup Cache
- */
-class ConstantDependency extends CacheDependency {
-       private $name;
-       private $value;
-
-       function __construct( $name ) {
-               $this->name = $name;
-               $this->value = constant( $name );
-       }
-
-       /**
-        * @return bool
-        */
-       function isExpired() {
-               return constant( $this->name ) != $this->value;
-       }
-}
index d7669eb..ec6ce04 100644 (file)
@@ -221,13 +221,11 @@ class CacheHelper implements ICacheHelper {
                                } else {
                                        $value = array_shift( $this->cachedChunks );
                                }
+                       } elseif ( array_key_exists( $key, $this->cachedChunks ) ) {
+                               $value = $this->cachedChunks[$key];
+                               unset( $this->cachedChunks[$key] );
                        } else {
-                               if ( array_key_exists( $key, $this->cachedChunks ) ) {
-                                       $value = $this->cachedChunks[$key];
-                                       unset( $this->cachedChunks[$key] );
-                               } else {
-                                       wfWarn( "There is no item with key '$key' in this->cachedChunks in " . __METHOD__ );
-                               }
+                               wfWarn( "There is no item with key '$key' in this->cachedChunks in " . __METHOD__ );
                        }
                } else {
                        if ( !is_array( $args ) ) {
index 3a89066..a0d61b2 100644 (file)
@@ -128,10 +128,8 @@ class HTMLFileCache extends FileCacheBase {
                        return false;
                }
 
-               if ( $mode === self::MODE_NORMAL ) {
-                       if ( $user->getNewtalk() ) {
-                               return false;
-                       }
+               if ( ( $mode === self::MODE_NORMAL ) && $user->getNewtalk() ) {
+                       return false;
                }
 
                // Allow extensions to disable caching
@@ -211,18 +209,14 @@ class HTMLFileCache extends FileCacheBase {
                }
 
                // gzip output to buffer as needed and set headers...
-               if ( $this->useGzip() ) {
-                       // @todo Ugly wfClientAcceptsGzip() function - use context!
-                       if ( wfClientAcceptsGzip() ) {
-                               header( 'Content-Encoding: gzip' );
+               // @todo Ugly wfClientAcceptsGzip() function - use context!
+               if ( $this->useGzip() && wfClientAcceptsGzip() ) {
+                       header( 'Content-Encoding: gzip' );
 
-                               return $compressed;
-                       } else {
-                               return $text;
-                       }
-               } else {
-                       return $text;
+                       return $compressed;
                }
+
+               return $text;
        }
 
        /**
index b3dc004..c13f95e 100644 (file)
@@ -141,6 +141,7 @@ class LinkCache {
                        'revision' => (int)$revision,
                        'model' => $model ? (string)$model : null,
                        'lang' => $lang ? (string)$lang : null,
+                       'restrictions' => null
                ] );
        }
 
@@ -158,8 +159,15 @@ class LinkCache {
                        'length' => intval( $row->page_len ),
                        'redirect' => intval( $row->page_is_redirect ),
                        'revision' => intval( $row->page_latest ),
-                       'model' => !empty( $row->page_content_model ) ? strval( $row->page_content_model ) : null,
-                       'lang' => !empty( $row->page_lang ) ? strval( $row->page_lang ) : null,
+                       'model' => !empty( $row->page_content_model )
+                               ? strval( $row->page_content_model )
+                               : null,
+                       'lang' => !empty( $row->page_lang )
+                               ? strval( $row->page_lang )
+                               : null,
+                       'restrictions' => !empty( $row->page_restrictions )
+                               ? strval( $row->page_restrictions )
+                               : null
                ] );
        }
 
@@ -198,7 +206,13 @@ class LinkCache {
        public static function getSelectFields() {
                global $wgContentHandlerUseDB, $wgPageLanguageUseDB;
 
-               $fields = [ 'page_id', 'page_len', 'page_is_redirect', 'page_latest' ];
+               $fields = [
+                       'page_id',
+                       'page_len',
+                       'page_is_redirect',
+                       'page_latest',
+                       'page_restrictions'
+               ];
                if ( $wgContentHandlerUseDB ) {
                        $fields[] = 'page_content_model';
                }
@@ -281,7 +295,16 @@ class LinkCache {
        }
 
        private function isCacheable( LinkTarget $title ) {
-               return ( $title->inNamespace( NS_TEMPLATE ) || $title->inNamespace( NS_FILE ) );
+               $ns = $title->getNamespace();
+               if ( in_array( $ns, [ NS_TEMPLATE, NS_FILE, NS_CATEGORY ] ) ) {
+                       return true;
+               }
+               // Focus on transcluded pages more than the main content
+               if ( MWNamespace::isContent( $ns ) ) {
+                       return false;
+               }
+               // Non-talk extension namespaces (e.g. NS_MODULE)
+               return ( $ns >= 100 && MWNamespace::isSubject( $ns ) );
        }
 
        private function fetchPageRow( IDatabase $db, LinkTarget $nt ) {
diff --git a/includes/cache/MessageBlobStore.php b/includes/cache/MessageBlobStore.php
deleted file mode 100644 (file)
index ceb51f2..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-<?php
-/**
- * Message blobs storage used by ResourceLoader.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Roan Kattouw
- * @author Trevor Parscal
- * @author Timo Tijhof
- */
-
-use MediaWiki\MediaWikiServices;
-use Psr\Log\LoggerAwareInterface;
-use Psr\Log\LoggerInterface;
-use Psr\Log\NullLogger;
-use Wikimedia\Rdbms\Database;
-
-/**
- * This class generates message blobs for use by ResourceLoader modules.
- *
- * A message blob is a JSON object containing the interface messages for a certain module in
- * a certain language.
- */
-class MessageBlobStore implements LoggerAwareInterface {
-
-       /* @var ResourceLoader */
-       private $resourceloader;
-
-       /**
-        * @var LoggerInterface
-        */
-       protected $logger;
-
-       /**
-        * @var WANObjectCache
-        */
-       protected $wanCache;
-
-       /**
-        * @param ResourceLoader $rl
-        * @param LoggerInterface|null $logger
-        */
-       public function __construct( ResourceLoader $rl, LoggerInterface $logger = null ) {
-               $this->resourceloader = $rl;
-               $this->logger = $logger ?: new NullLogger();
-               $this->wanCache = MediaWikiServices::getInstance()->getMainWANObjectCache();
-       }
-
-       /**
-        * @since 1.27
-        * @param LoggerInterface $logger
-        */
-       public function setLogger( LoggerInterface $logger ) {
-               $this->logger = $logger;
-       }
-
-       /**
-        * Get the message blob for a module
-        *
-        * @since 1.27
-        * @param ResourceLoaderModule $module
-        * @param string $lang Language code
-        * @return string JSON
-        */
-       public function getBlob( ResourceLoaderModule $module, $lang ) {
-               $blobs = $this->getBlobs( [ $module->getName() => $module ], $lang );
-               return $blobs[$module->getName()];
-       }
-
-       /**
-        * Get the message blobs for a set of modules
-        *
-        * @since 1.27
-        * @param ResourceLoaderModule[] $modules Array of module objects keyed by name
-        * @param string $lang Language code
-        * @return array An array mapping module names to message blobs
-        */
-       public function getBlobs( array $modules, $lang ) {
-               // Each cache key for a message blob by module name and language code also has a generic
-               // check key without language code. This is used to invalidate any and all language subkeys
-               // that exist for a module from the updateMessage() method.
-               $cache = $this->wanCache;
-               $checkKeys = [
-                       // Global check key, see clear()
-                       $cache->makeKey( __CLASS__ )
-               ];
-               $cacheKeys = [];
-               foreach ( $modules as $name => $module ) {
-                       $cacheKey = $this->makeCacheKey( $module, $lang );
-                       $cacheKeys[$name] = $cacheKey;
-                       // Per-module check key, see updateMessage()
-                       $checkKeys[$cacheKey][] = $cache->makeKey( __CLASS__, $name );
-               }
-               $curTTLs = [];
-               $result = $cache->getMulti( array_values( $cacheKeys ), $curTTLs, $checkKeys );
-
-               $blobs = [];
-               foreach ( $modules as $name => $module ) {
-                       $key = $cacheKeys[$name];
-                       if ( !isset( $result[$key] ) || $curTTLs[$key] === null || $curTTLs[$key] < 0 ) {
-                               $blobs[$name] = $this->recacheMessageBlob( $key, $module, $lang );
-                       } else {
-                               // Use unexpired cache
-                               $blobs[$name] = $result[$key];
-                       }
-               }
-               return $blobs;
-       }
-
-       /**
-        * @deprecated since 1.27 Use getBlobs() instead
-        * @return array
-        */
-       public function get( ResourceLoader $resourceLoader, $modules, $lang ) {
-               return $this->getBlobs( $modules, $lang );
-       }
-
-       /**
-        * @since 1.27
-        * @param ResourceLoaderModule $module
-        * @param string $lang
-        * @return string Cache key
-        */
-       private function makeCacheKey( ResourceLoaderModule $module, $lang ) {
-               $messages = array_values( array_unique( $module->getMessages() ) );
-               sort( $messages );
-               return $this->wanCache->makeKey( __CLASS__, $module->getName(), $lang,
-                       md5( json_encode( $messages ) )
-               );
-       }
-
-       /**
-        * @since 1.27
-        * @param string $cacheKey
-        * @param ResourceLoaderModule $module
-        * @param string $lang
-        * @return string JSON blob
-        */
-       protected function recacheMessageBlob( $cacheKey, ResourceLoaderModule $module, $lang ) {
-               $blob = $this->generateMessageBlob( $module, $lang );
-               $cache = $this->wanCache;
-               $cache->set( $cacheKey, $blob,
-                       // Add part of a day to TTL to avoid all modules expiring at once
-                       $cache::TTL_WEEK + mt_rand( 0, $cache::TTL_DAY ),
-                       Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) )
-               );
-               return $blob;
-       }
-
-       /**
-        * Invalidate cache keys for modules using this message key.
-        * Called by MessageCache when a message has changed.
-        *
-        * @param string $key Message key
-        */
-       public function updateMessage( $key ) {
-               $moduleNames = $this->getResourceLoader()->getModulesByMessage( $key );
-               foreach ( $moduleNames as $moduleName ) {
-                       // Uses a holdoff to account for database replica DB lag (for MessageCache)
-                       $this->wanCache->touchCheckKey( $this->wanCache->makeKey( __CLASS__, $moduleName ) );
-               }
-       }
-
-       /**
-        * Invalidate cache keys for all known modules.
-        * Called by LocalisationCache after cache is regenerated.
-        */
-       public function clear() {
-               $cache = $this->wanCache;
-               // Disable holdoff because this invalidates all modules and also not needed since
-               // LocalisationCache is stored outside the database and doesn't have lag.
-               $cache->touchCheckKey( $cache->makeKey( __CLASS__ ), $cache::HOLDOFF_NONE );
-       }
-
-       /**
-        * @since 1.27
-        * @return ResourceLoader
-        */
-       protected function getResourceLoader() {
-               return $this->resourceloader;
-       }
-
-       /**
-        * @since 1.27
-        * @param string $key Message key
-        * @param string $lang Language code
-        * @return string
-        */
-       protected function fetchMessage( $key, $lang ) {
-               $message = wfMessage( $key )->inLanguage( $lang );
-               $value = $message->plain();
-               if ( !$message->exists() ) {
-                       $this->logger->warning( 'Failed to find {messageKey} ({lang})', [
-                               'messageKey' => $key,
-                               'lang' => $lang,
-                       ] );
-               }
-               return $value;
-       }
-
-       /**
-        * Generate the message blob for a given module in a given language.
-        *
-        * @param ResourceLoaderModule $module
-        * @param string $lang Language code
-        * @return string JSON blob
-        */
-       private function generateMessageBlob( ResourceLoaderModule $module, $lang ) {
-               $messages = [];
-               foreach ( $module->getMessages() as $key ) {
-                       $messages[$key] = $this->fetchMessage( $key, $lang );
-               }
-
-               $json = FormatJson::encode( (object)$messages );
-               // @codeCoverageIgnoreStart
-               if ( $json === false ) {
-                       $this->logger->warning( 'Failed to encode message blob for {module} ({lang})', [
-                               'module' => $module->getName(),
-                               'lang' => $lang,
-                       ] );
-                       $json = '{}';
-               }
-               // codeCoverageIgnoreEnd
-               return $json;
-       }
-}
index b669fcd..157d88e 100644 (file)
@@ -48,7 +48,7 @@ class MessageCache {
        /**
         * Process cache of loaded messages that are defined in MediaWiki namespace
         *
-        * @var MapCacheLRU Map of (language code => key => " <MESSAGE>" or "!TOO BIG")
+        * @var MapCacheLRU Map of (language code => key => " <MESSAGE>" or "!TOO BIG" or "!ERROR")
         */
        protected $cache;
 
@@ -535,27 +535,33 @@ class MessageCache {
                }
 
                // Set the text for small software-defined messages in the main cache map
+               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+               $revQuery = $revisionStore->getQueryInfo( [ 'page', 'user' ] );
                $res = $dbr->select(
-                       [ 'page', 'revision', 'text' ],
-                       [ 'page_title', 'page_latest', 'old_id', 'old_text', 'old_flags' ],
-                       array_merge( $conds, [ 'page_len <= ' . intval( $wgMaxMsgCacheEntrySize ) ] ),
+                       $revQuery['tables'],
+                       $revQuery['fields'],
+                       array_merge( $conds, [
+                               'page_len <= ' . intval( $wgMaxMsgCacheEntrySize ),
+                               'page_latest = rev_id' // get the latest revision only
+                       ] ),
                        __METHOD__ . "($code)-small",
                        [],
-                       [
-                               'revision' => [ 'JOIN', 'page_latest=rev_id' ],
-                               'text' => [ 'JOIN', 'rev_text_id=old_id' ],
-                       ]
+                       $revQuery['joins']
                );
                foreach ( $res as $row ) {
                        $name = $this->contLang->lcfirst( $row->page_title );
                        // Include entries/stubs for all keys in $mostused in adaptive mode
                        if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) {
-                               $text = Revision::getRevisionText( $row );
-                               if ( $text === false ) {
-                                       // Failed to fetch data; possible ES errors?
-                                       // Store a marker to fetch on-demand as a workaround...
-                                       // TODO Use a differnt marker
-                                       $entry = '!TOO BIG';
+                               try {
+                                       $rev = $revisionStore->newRevisionFromRow( $row );
+                                       $content = $rev->getContent( MediaWiki\Revision\SlotRecord::MAIN );
+                                       $text = $this->getMessageTextFromContent( $content );
+                               } catch ( Exception $ex ) {
+                                       $text = false;
+                               }
+
+                               if ( !is_string( $text ) ) {
+                                       $entry = '!ERROR';
                                        wfDebugLog(
                                                'MessageCache',
                                                __METHOD__
@@ -1049,7 +1055,7 @@ class MessageCache {
                if ( $entry !== null ) {
                        // Message page exists as an override of a software messages
                        if ( substr( $entry, 0, 1 ) === ' ' ) {
-                               // The message exists and is not '!TOO BIG'
+                               // The message exists and is not '!TOO BIG' or '!ERROR'
                                return (string)substr( $entry, 1 );
                        } elseif ( $entry === '!NONEXISTENT' ) {
                                // The text might be '-' or missing due to some data loss
diff --git a/includes/cache/dependency/CacheDependency.php b/includes/cache/dependency/CacheDependency.php
new file mode 100644 (file)
index 0000000..2e4711f
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Data caching with dependencies.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+/**
+ * @ingroup Cache
+ */
+abstract class CacheDependency {
+       /**
+        * Returns true if the dependency is expired, false otherwise
+        */
+       abstract function isExpired();
+
+       /**
+        * Hook to perform any expensive pre-serialize loading of dependency values.
+        */
+       function loadDependencyValues() {
+       }
+}
diff --git a/includes/cache/dependency/ConstantDependency.php b/includes/cache/dependency/ConstantDependency.php
new file mode 100644 (file)
index 0000000..079e99f
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Data caching with dependencies.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+/**
+ * @ingroup Cache
+ */
+class ConstantDependency extends CacheDependency {
+       private $name;
+       private $value;
+
+       function __construct( $name ) {
+               $this->name = $name;
+               $this->value = constant( $name );
+       }
+
+       /**
+        * @return bool
+        */
+       function isExpired() {
+               return constant( $this->name ) != $this->value;
+       }
+}
diff --git a/includes/cache/dependency/DependencyWrapper.php b/includes/cache/dependency/DependencyWrapper.php
new file mode 100644 (file)
index 0000000..43d659c
--- /dev/null
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Data caching with dependencies.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+/**
+ * This class stores an arbitrary value along with its dependencies.
+ * Users should typically only use DependencyWrapper::getValueFromCache(),
+ * rather than instantiating one of these objects directly.
+ * @ingroup Cache
+ */
+class DependencyWrapper {
+       private $value;
+       /** @var CacheDependency[] */
+       private $deps;
+
+       /**
+        * @param mixed $value The user-supplied value
+        * @param CacheDependency|CacheDependency[] $deps A dependency or dependency
+        *   array. All dependencies must be objects implementing CacheDependency.
+        */
+       function __construct( $value = false, $deps = [] ) {
+               $this->value = $value;
+
+               if ( !is_array( $deps ) ) {
+                       $deps = [ $deps ];
+               }
+
+               $this->deps = $deps;
+       }
+
+       /**
+        * Returns true if any of the dependencies have expired
+        *
+        * @return bool
+        */
+       function isExpired() {
+               foreach ( $this->deps as $dep ) {
+                       if ( $dep->isExpired() ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Initialise dependency values in preparation for storing. This must be
+        * called before serialization.
+        */
+       function initialiseDeps() {
+               foreach ( $this->deps as $dep ) {
+                       $dep->loadDependencyValues();
+               }
+       }
+
+       /**
+        * Get the user-defined value
+        * @return bool|mixed
+        */
+       function getValue() {
+               return $this->value;
+       }
+
+       /**
+        * Store the wrapper to a cache
+        *
+        * @param BagOStuff $cache
+        * @param string $key
+        * @param int $expiry
+        */
+       function storeToCache( $cache, $key, $expiry = 0 ) {
+               $this->initialiseDeps();
+               $cache->set( $key, $this, $expiry );
+       }
+
+       /**
+        * Attempt to get a value from the cache. If the value is expired or missing,
+        * it will be generated with the callback function (if present), and the newly
+        * calculated value will be stored to the cache in a wrapper.
+        *
+        * @param BagOStuff $cache
+        * @param string $key The cache key
+        * @param int $expiry The expiry timestamp or interval in seconds
+        * @param bool|callable $callback The callback for generating the value, or false
+        * @param array $callbackParams The function parameters for the callback
+        * @param array $deps The dependencies to store on a cache miss. Note: these
+        *    are not the dependencies used on a cache hit! Cache hits use the stored
+        *    dependency array.
+        *
+        * @return mixed The value, or null if it was not present in the cache and no
+        *    callback was defined.
+        */
+       static function getValueFromCache( $cache, $key, $expiry = 0, $callback = false,
+               $callbackParams = [], $deps = []
+       ) {
+               $obj = $cache->get( $key );
+
+               if ( is_object( $obj ) && $obj instanceof DependencyWrapper && !$obj->isExpired() ) {
+                       $value = $obj->value;
+               } elseif ( $callback ) {
+                       $value = $callback( ...$callbackParams );
+                       # Cache the newly-generated value
+                       $wrapper = new DependencyWrapper( $value, $deps );
+                       $wrapper->storeToCache( $cache, $key, $expiry );
+               } else {
+                       $value = null;
+               }
+
+               return $value;
+       }
+}
diff --git a/includes/cache/dependency/FileDependency.php b/includes/cache/dependency/FileDependency.php
new file mode 100644 (file)
index 0000000..a8f542f
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Data caching with dependencies.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+/**
+ * @ingroup Cache
+ */
+class FileDependency extends CacheDependency {
+       private $filename;
+       private $timestamp;
+
+       /**
+        * Create a file dependency
+        *
+        * @param string $filename The name of the file, preferably fully qualified
+        * @param null|bool|int $timestamp The unix last modified timestamp, or false if the
+        *        file does not exist. If omitted, the timestamp will be loaded from
+        *        the file.
+        *
+        * A dependency on a nonexistent file will be triggered when the file is
+        * created. A dependency on an existing file will be triggered when the
+        * file is changed.
+        */
+       function __construct( $filename, $timestamp = null ) {
+               $this->filename = $filename;
+               $this->timestamp = $timestamp;
+       }
+
+       /**
+        * @return array
+        */
+       function __sleep() {
+               $this->loadDependencyValues();
+
+               return [ 'filename', 'timestamp' ];
+       }
+
+       function loadDependencyValues() {
+               if ( is_null( $this->timestamp ) ) {
+                       Wikimedia\suppressWarnings();
+                       # Dependency on a non-existent file stores "false"
+                       # This is a valid concept!
+                       $this->timestamp = filemtime( $this->filename );
+                       Wikimedia\restoreWarnings();
+               }
+       }
+
+       /**
+        * @return bool
+        */
+       function isExpired() {
+               Wikimedia\suppressWarnings();
+               $lastmod = filemtime( $this->filename );
+               Wikimedia\restoreWarnings();
+               if ( $lastmod === false ) {
+                       if ( $this->timestamp === false ) {
+                               # Still nonexistent
+                               return false;
+                       }
+
+                       # Deleted
+                       wfDebug( "Dependency triggered: {$this->filename} deleted.\n" );
+
+                       return true;
+               }
+
+               if ( $lastmod > $this->timestamp ) {
+                       # Modified or created
+                       wfDebug( "Dependency triggered: {$this->filename} changed.\n" );
+
+                       return true;
+               }
+
+               # Not modified
+               return false;
+       }
+}
diff --git a/includes/cache/dependency/GlobalDependency.php b/includes/cache/dependency/GlobalDependency.php
new file mode 100644 (file)
index 0000000..be1d345
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Data caching with dependencies.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+/**
+ * @ingroup Cache
+ */
+class GlobalDependency extends CacheDependency {
+       private $name;
+       private $value;
+
+       function __construct( $name ) {
+               $this->name = $name;
+               $this->value = $GLOBALS[$name];
+       }
+
+       /**
+        * @return bool
+        */
+       function isExpired() {
+               if ( !isset( $GLOBALS[$this->name] ) ) {
+                       return true;
+               }
+
+               return $GLOBALS[$this->name] != $this->value;
+       }
+}
diff --git a/includes/cache/dependency/MainConfigDependency.php b/includes/cache/dependency/MainConfigDependency.php
new file mode 100644 (file)
index 0000000..dd33a2e
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Data caching with dependencies.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+use MediaWiki\MediaWikiServices;
+
+/**
+ * @ingroup Cache
+ */
+class MainConfigDependency extends CacheDependency {
+       private $name;
+       private $value;
+
+       function __construct( $name ) {
+               $this->name = $name;
+               $this->value = $this->getConfig()->get( $this->name );
+       }
+
+       private function getConfig() {
+               return MediaWikiServices::getInstance()->getMainConfig();
+       }
+
+       /**
+        * @return bool
+        */
+       function isExpired() {
+               if ( !$this->getConfig()->has( $this->name ) ) {
+                       return true;
+               }
+
+               return $this->getConfig()->get( $this->name ) != $this->value;
+       }
+}
index 246a3dd..8814cff 100644 (file)
@@ -86,11 +86,9 @@ class LCStoreCDB implements LCStore {
        }
 
        public function startWrite( $code ) {
-               if ( !file_exists( $this->directory ) ) {
-                       if ( !wfMkdirParents( $this->directory, null, __METHOD__ ) ) {
-                               throw new MWException( "Unable to create the localisation store " .
-                                       "directory \"{$this->directory}\"" );
-                       }
+               if ( !file_exists( $this->directory ) && !wfMkdirParents( $this->directory, null, __METHOD__ ) ) {
+                       throw new MWException( "Unable to create the localisation store " .
+                               "directory \"{$this->directory}\"" );
                }
 
                // Close reader to stop permission errors on write
index 75c8465..d3504a8 100644 (file)
@@ -45,11 +45,9 @@ class LCStoreStaticArray implements LCStore {
        }
 
        public function startWrite( $code ) {
-               if ( !file_exists( $this->directory ) ) {
-                       if ( !wfMkdirParents( $this->directory, null, __METHOD__ ) ) {
-                               throw new MWException( "Unable to create the localisation store " .
-                                       "directory \"{$this->directory}\"" );
-                       }
+               if ( !file_exists( $this->directory ) && !wfMkdirParents( $this->directory, null, __METHOD__ ) ) {
+                       throw new MWException( "Unable to create the localisation store " .
+                               "directory \"{$this->directory}\"" );
                }
 
                $this->currentLang = $code;
@@ -101,8 +99,7 @@ class LCStoreStaticArray implements LCStore {
                        return $encoded;
                }
 
-               $type = $encoded[0];
-               $data = $encoded[1];
+               list( $type, $data ) = $encoded;
 
                switch ( $type ) {
                        case 'a':
index 1d00d19..8df8013 100644 (file)
@@ -536,7 +536,6 @@ class LocalisationCache {
                        }
                } elseif ( $_fileType == 'aliases' ) {
                        if ( isset( $aliases ) ) {
-                               /** @suppress PhanUndeclaredVariable */
                                $data['aliases'] = $aliases;
                        }
                } else {
index 7ac8cd0..50c6826 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Feed to Special:RecentChanges and Special:RecentChangesLiked
@@ -82,7 +83,7 @@ class ChangesFeed {
                        return null;
                }
 
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                $optionsHash = md5( serialize( $opts->getAllValues() ) ) . $wgRenderHashAppend;
                $timekey = $cache->makeKey(
                        $this->type, $this->format, $wgLang->getCode(), $optionsHash, 'timestamp' );
@@ -119,7 +120,7 @@ class ChangesFeed {
         * @param string $key Memcached key of the content
         */
        public function saveToCache( $feed, $timekey, $key ) {
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                $cache->set( $key, $feed, $cache::TTL_DAY );
                $cache->set( $timekey, wfTimestamp( TS_MW ), $cache::TTL_DAY );
        }
@@ -135,7 +136,7 @@ class ChangesFeed {
        public function loadFromCache( $lastmod, $timekey, $key ) {
                global $wgFeedCacheTimeout, $wgOut;
 
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                $feedLastmod = $cache->get( $timekey );
 
                if ( ( $wgFeedCacheTimeout > 0 ) && $feedLastmod ) {
@@ -207,7 +208,7 @@ class ChangesFeed {
 
                foreach ( $sorted as $obj ) {
                        $title = Title::makeTitle( $obj->rc_namespace, $obj->rc_title );
-                       $talkpage = MWNamespace::canTalk( $obj->rc_namespace )
+                       $talkpage = MWNamespace::hasTalkNamespace( $obj->rc_namespace )
                                ? $title->getTalkPage()->getFullURL()
                                : '';
 
index bf275b3..184a2c1 100644 (file)
@@ -395,6 +395,36 @@ class ChangesList extends ContextSource {
                return $out;
        }
 
+       /**
+        * Render the date and time of a revision in the current user language
+        * based on whether the user is able to view this information or not.
+        * @param Revision $rev
+        * @param User $user
+        * @param Language $lang
+        * @param Title|null $title (optional) where Title does not match
+        *   the Title associated with the Revision
+        * @internal For usage by Pager classes only (e.g. HistoryPager and ContribsPager).
+        * @return string HTML
+        */
+       public static function revDateLink( Revision $rev, User $user, Language $lang, $title = null ) {
+               $ts = $rev->getTimestamp();
+               $date = $lang->userTimeAndDate( $ts, $user );
+               if ( $rev->userCan( Revision::DELETED_TEXT, $user ) ) {
+                       $link = MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
+                               $title !== null ? $title : $rev->getTitle(),
+                               $date,
+                               [ 'class' => 'mw-changeslist-date' ],
+                               [ 'oldid' => $rev->getId() ]
+                       );
+               } else {
+                       $link = htmlspecialchars( $date );
+               }
+               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+                       $link = "<span class=\"history-deleted mw-changeslist-date\">$link</span>";
+               }
+               return $link;
+       }
+
        /**
         * @param string &$s HTML to update
         * @param mixed $rc_timestamp
@@ -517,6 +547,7 @@ class ChangesList extends ContextSource {
         * and a separator
         *
         * @param RecentChange $rc
+        * @deprecated use revDateLink instead.
         * @return string HTML fragment
         */
        public function getTimestamp( $rc ) {
@@ -586,7 +617,13 @@ class ChangesList extends ContextSource {
                        return ' <span class="history-deleted">' .
                                $this->msg( 'rev-deleted-comment' )->escaped() . '</span>';
                } else {
-                       return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() );
+                       return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle(),
+                               // Whether section links should refer to local page (using default false)
+                               false,
+                               // wikid to generate links for (using default null) */
+                               null,
+                               // whether parentheses should be rendered as part of the message
+                               false );
                }
        }
 
index 3e98f65..8186059 100644 (file)
@@ -393,7 +393,7 @@ class EnhancedChangesList extends ChangesList {
                }
                $classes = array_merge( $classes, $this->getHTMLClasses( $rcObj, $rcObj->watched ) );
 
-               $separator = ' <span class="mw-changeslist-separator">. .</span> ';
+               $separator = ' <span class="mw-changeslist-separator"></span> ';
 
                $data['recentChangesFlags'] = [
                        'newpage' => $type == RC_NEW,
@@ -556,19 +556,22 @@ class EnhancedChangesList extends ChangesList {
                                $isnew ||
                                $rcObj->mAttribs['rc_type'] == RC_CATEGORIZE
                        ) {
-                               $links['total-changes'] = $nchanges[$n];
+                               $links['total-changes'] = Html::rawElement( 'span', [], $nchanges[$n] );
                        } else {
-                               $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'],
-                                       ]
+                               $links['total-changes'] = Html::rawElement( 'span', [],
+                                       $this->linkRenderer->makeKnownLink(
+                                               $block0->getTitle(),
+                                               new HtmlArmor( $nchanges[$n] ),
+                                               [ 'class' => 'mw-changeslist-groupdiff' ],
+                                               $queryParams + [
+                                                       'diff' => $currentRevision,
+                                                       'oldid' => $last->mAttribs['rc_last_oldid'],
+                                               ]
+                                       )
                                );
                                if ( $sinceLast > 0 && $sinceLast < $n ) {
-                                       $links['total-changes-since-last'] = $this->linkRenderer->makeKnownLink(
+                                       $links['total-changes-since-last'] = Html::rawElement( 'span', [],
+                                               $this->linkRenderer->makeKnownLink(
                                                        $block0->getTitle(),
                                                        new HtmlArmor( $sinceLastVisitMsg[$sinceLast] ),
                                                        [ 'class' => 'mw-changeslist-groupdiff' ],
@@ -576,7 +579,8 @@ class EnhancedChangesList extends ChangesList {
                                                                'diff' => $currentRevision,
                                                                'oldid' => $unvisitedOldid,
                                                        ]
-                                               );
+                                               )
+                                       );
                                }
                        }
                }
@@ -585,17 +589,19 @@ class EnhancedChangesList extends ChangesList {
                if ( $allLogs || $rcObj->mAttribs['rc_type'] == RC_CATEGORIZE ) {
                        // don't show history link for logs
                } elseif ( $namehidden || !$block0->getTitle()->exists() ) {
-                       $links['history'] = $this->message['enhancedrc-history'];
+                       $links['history'] = Html::rawElement( 'span', [], $this->message['enhancedrc-history'] );
                } else {
                        $params = $queryParams;
                        $params['action'] = 'history';
 
-                       $links['history'] = $this->linkRenderer->makeKnownLink(
+                       $links['history'] = Html::rawElement( 'span', [],
+                               $this->linkRenderer->makeKnownLink(
                                        $block0->getTitle(),
                                        new HtmlArmor( $this->message['enhancedrc-history'] ),
                                        [ 'class' => 'mw-changeslist-history' ],
                                        $params
-                               );
+                               )
+                       );
                }
 
                # Allow others to alter, remove or add to these links
@@ -606,8 +612,8 @@ class EnhancedChangesList extends ChangesList {
                        return '';
                }
 
-               $logtext = implode( $this->message['pipe-separator'], $links );
-               $logtext = $this->msg( 'parentheses' )->rawParams( $logtext )->escaped();
+               $logtext = Html::rawElement( 'span', [ 'class' => 'mw-changeslist-links' ],
+                       implode( ' ', $links ) );
                return ' ' . $logtext;
        }
 
@@ -653,10 +659,9 @@ class EnhancedChangesList extends ChangesList {
                        $logPage = new LogPage( $logType );
                        $logTitle = SpecialPage::getTitleFor( 'Log', $logType );
                        $logName = $logPage->getName()->text();
-                       $data['logLink'] = $this->msg( 'parentheses' )
-                               ->rawParams(
-                                       $this->linkRenderer->makeKnownLink( $logTitle, $logName )
-                               )->escaped();
+                       $data['logLink'] = Html::rawElement( 'span', [ 'class' => 'mw-changeslist-links' ],
+                               $this->linkRenderer->makeKnownLink( $logTitle, $logName )
+                       );
                } else {
                        $data['articleLink'] = $this->getArticleLink( $rcObj, $rcObj->unpatrolled, $rcObj->watched );
                }
@@ -664,16 +669,16 @@ class EnhancedChangesList extends ChangesList {
                # Diff and hist links
                if ( $type != RC_LOG && $type != RC_CATEGORIZE ) {
                        $query['action'] = 'history';
-                       $data['historyLink'] = $this->getDiffHistLinks( $rcObj, $query );
+                       $data['historyLink'] = $this->getDiffHistLinks( $rcObj, $query, false );
                }
-               $data['separatorAfterLinks'] = ' <span class="mw-changeslist-separator">. .</span> ';
+               $data['separatorAfterLinks'] = ' <span class="mw-changeslist-separator"></span> ';
 
                # Character diff
                if ( $this->getConfig()->get( 'RCShowChangedSize' ) ) {
                        $cd = $this->formatCharacterDifference( $rcObj );
                        if ( $cd !== '' ) {
                                $data['characterDiff'] = $cd;
-                               $data['separatorAftercharacterDiff'] = ' <span class="mw-changeslist-separator">. .</span> ';
+                               $data['separatorAftercharacterDiff'] = ' <span class="mw-changeslist-separator"></span> ';
                        }
                }
 
@@ -686,7 +691,7 @@ class EnhancedChangesList extends ChangesList {
                        $data['userTalkLink'] = $rcObj->usertalklink;
                        $data['comment'] = $this->insertComment( $rcObj );
                        if ( $type == RC_CATEGORIZE ) {
-                               $data['historyLink'] = $this->getDiffHistLinks( $rcObj, $query );
+                               $data['historyLink'] = $this->getDiffHistLinks( $rcObj, $query, false );
                        }
                        $data['rollback'] = $this->getRollback( $rcObj );
                }
@@ -744,7 +749,11 @@ class EnhancedChangesList extends ChangesList {
                ] );
 
                // everything else: makes it easier for extensions to add or remove data
-               $line .= implode( '', $data );
+               foreach ( $data as $key => $dataItem ) {
+                       $line .= Html::rawElement( 'span', [
+                               'class' => 'mw-changeslist-line-inner-' . $key,
+                       ], $dataItem );
+               }
 
                $line .= "</td></tr></table>\n";
 
@@ -759,9 +768,10 @@ class EnhancedChangesList extends ChangesList {
         *
         * @param RCCacheEntry $rc
         * @param array $query array of key/value pairs to append as a query string
+        * @param bool $useParentheses (optional) Wrap comments in parentheses where needed
         * @return string HTML
         */
-       public function getDiffHistLinks( RCCacheEntry $rc, array $query ) {
+       public function getDiffHistLinks( RCCacheEntry $rc, array $query, $useParentheses = true ) {
                $pageTitle = $rc->getTitle();
                if ( $rc->getAttribute( 'rc_type' ) == RC_CATEGORIZE ) {
                        // For categorizations we must swap the category title with the page title!
@@ -773,15 +783,23 @@ class EnhancedChangesList extends ChangesList {
                        }
                }
 
-               $retVal = ' ' . $this->msg( 'parentheses' )
-                               ->rawParams( $rc->difflink . $this->message['pipe-separator']
-                                       . $this->linkRenderer->makeKnownLink(
-                                               $pageTitle,
-                                               new HtmlArmor( $this->message['hist'] ),
-                                               [ 'class' => 'mw-changeslist-history' ],
-                                               $query
-                                       ) )->escaped();
-               return $retVal;
+               $histLink = $this->linkRenderer->makeKnownLink(
+                       $pageTitle,
+                       new HtmlArmor( $this->message['hist'] ),
+                       [ 'class' => 'mw-changeslist-history' ],
+                       $query
+               );
+               if ( $useParentheses ) {
+                       $retVal = $this->msg( 'parentheses' )
+                       ->rawParams( $rc->difflink . $this->message['pipe-separator']
+                               . $histLink )->escaped();
+               } else {
+                       $retVal = Html::rawElement( 'span', [ 'class' => 'mw-changeslist-links' ],
+                               Html::rawElement( 'span', [], $rc->difflink ) .
+                               Html::rawElement( 'span', [], $histLink )
+                       );
+               }
+               return ' ' . $retVal;
        }
 
        /**
index e8c3a99..2d60ca2 100644 (file)
@@ -82,7 +82,15 @@ class RCCacheEntryFactory {
                if ( !ChangesList::isDeleted( $cacheEntry, Revision::DELETED_USER ) ) {
                        $cacheEntry->usertalklink = Linker::userToolLinks(
                                $cacheEntry->mAttribs['rc_user'],
-                               $cacheEntry->mAttribs['rc_user_text']
+                               $cacheEntry->mAttribs['rc_user_text'],
+                               // Should the contributions link be red if the user has no edits (using default)
+                               false,
+                               // Customisation flags (using default 0)
+                               0,
+                               // User edit count (using default )
+                               null,
+                               // do not wrap the message in parentheses
+                               false
                        );
                }
 
index 7f7d77d..eed159d 100644 (file)
@@ -19,6 +19,7 @@
  *
  * @file
  */
+use MediaWiki\ChangeTags\Taggable;
 
 /**
  * Utility class for creating new RC entries
@@ -65,7 +66,7 @@
  *  we're having to include both rc_comment and rc_comment_text/rc_comment_data
  *  so random crap works right.
  */
-class RecentChange {
+class RecentChange implements Taggable {
        // Constants for the rc_source field.  Extensions may also have
        // their own source constants.
        const SRC_EDIT = 'mw.edit';
@@ -589,6 +590,13 @@ class RecentChange {
        public function doMarkPatrolled( User $user, $auto = false, $tags = null ) {
                global $wgUseRCPatrol, $wgUseNPPatrol, $wgUseFilePatrol;
 
+               // Fix up $tags so that the MarkPatrolled hook below always gets an array
+               if ( $tags === null ) {
+                       $tags = [];
+               } elseif ( is_string( $tags ) ) {
+                       $tags = [ $tags ];
+               }
+
                $errors = [];
                // If recentchanges patrol is disabled, only new pages or new file versions
                // can be patrolled, provided the appropriate config variable is set
@@ -601,7 +609,7 @@ class RecentChange {
                $right = $auto ? 'autopatrol' : 'patrol';
                $errors = array_merge( $errors, $this->getTitle()->getUserPermissionsErrors( $right, $user ) );
                if ( !Hooks::run( 'MarkPatrolled',
-                                       [ $this->getAttribute( 'rc_id' ), &$user, false, $auto ] )
+                                       [ $this->getAttribute( 'rc_id' ), &$user, false, $auto, &$tags ] )
                ) {
                        $errors[] = [ 'hookaborted' ];
                }
@@ -1198,7 +1206,7 @@ class RecentChange {
         *
         * @since 1.28
         *
-        * @param string|array $tags
+        * @param string|string[] $tags
         */
        public function addTags( $tags ) {
                if ( is_string( $tags ) ) {
index 91877f2..3a93e57 100644 (file)
@@ -756,7 +756,7 @@ class ChangeTags {
                        // Add an INNER JOIN on change_tag
 
                        $tables[] = 'change_tag';
-                       $join_conds['change_tag'] = [ 'INNER JOIN', $join_cond ];
+                       $join_conds['change_tag'] = [ 'JOIN', $join_cond ];
                        $filterTagIds = [];
                        $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                        foreach ( (array)$filter_tag as $filterTagName ) {
@@ -766,7 +766,7 @@ class ChangeTags {
                                        // Return nothing.
                                        $conds[] = '0';
                                        break;
-                               };
+                               }
                        }
 
                        if ( $filterTagIds !== [] ) {
@@ -808,7 +808,7 @@ class ChangeTags {
                }
 
                $tagTables = [ 'change_tag', 'change_tag_def' ];
-               $join_cond_ts_tags = [ 'change_tag_def' => [ 'INNER JOIN', 'ct_tag_id=ctd_id' ] ];
+               $join_cond_ts_tags = [ 'change_tag_def' => [ 'JOIN', 'ct_tag_id=ctd_id' ] ];
                $field = 'ctd_name';
 
                return wfGetDB( DB_REPLICA )->buildGroupConcatField(
index a248c6e..75b713e 100644 (file)
@@ -85,7 +85,7 @@ class ChangeTagsLogItem extends RevisionItemBase {
                $loglink = $this->list->msg( 'parentheses' )->rawParams( $loglink )->escaped();
                // User links and action text
                $action = $formatter->getActionText();
-               // Comment
+
                $comment = $this->list->getLanguage()->getDirMark() .
                        $formatter->getComment();
 
diff --git a/includes/changetags/Taggable.php b/includes/changetags/Taggable.php
new file mode 100644 (file)
index 0000000..f624555
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Interface that defines how to tag objects
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Change tagging
+ * @author Piotr Miazga
+ * @license GPL-2.0-or-later
+ */
+namespace MediaWiki\ChangeTags;
+
+/**
+ * Interface that defines how to tag objects
+ *
+ * @since 1.33
+ */
+interface Taggable {
+
+       /**
+        * Append tags to the tagged object
+        *
+        * @since 1.33
+        * @param string|string[] $tags Tags to apply
+        */
+       public function addTags( $tags );
+
+}
index 36d72c2..49d9d1c 100644 (file)
@@ -25,7 +25,7 @@
  * Uses asynchronous I/O, allowing purges to be done in a highly parallel
  * manner.
  *
- * Could be replaced by curl_multi_exec() or some such.
+ * @todo Consider using MultiHttpClient.
  */
 class SquidPurgeClient {
        /** @var string */
@@ -315,7 +315,7 @@ class SquidPurgeClient {
                                }
                                if ( $this->readState == 'status' ) {
                                        $this->processStatusLine( $lines[0] );
-                               } else { // header
+                               } else {
                                        $this->processHeaderLine( $lines[0] );
                                }
                                $this->readBuffer = $lines[1];
index ab3c6fb..312c2d4 100644 (file)
@@ -76,7 +76,7 @@ abstract class Collation {
                                $collationObject = null;
                                Hooks::run( 'Collation::factory', [ $collationName, &$collationObject ] );
 
-                               if ( $collationObject instanceof Collation ) {
+                               if ( $collationObject instanceof self ) {
                                        return $collationObject;
                                }
 
index d45b2ce..9c1c5f8 100644 (file)
@@ -365,16 +365,14 @@ class IcuCollation extends Collation {
                        foreach ( $digits as $digit ) {
                                $letters[] = $this->digitTransformLanguage->formatNum( $digit, true );
                        }
+               } elseif ( $this->locale === 'root' ) {
+                       $letters = require "$IP/includes/collation/data/first-letters-root.php";
                } else {
-                       if ( $this->locale === 'root' ) {
-                               $letters = require "$IP/includes/collation/data/first-letters-root.php";
-                       } else {
-                               // FIXME: Is this still used?
-                               $letters = wfGetPrecompiledData( "first-letters-{$this->locale}.ser" );
-                               if ( $letters === false ) {
-                                       throw new MWException( "MediaWiki does not support ICU locale " .
-                                               "\"{$this->locale}\"" );
-                               }
+                       // FIXME: Is this still used?
+                       $letters = wfGetPrecompiledData( "first-letters-{$this->locale}.ser" );
+                       if ( $letters === false ) {
+                               throw new MWException( "MediaWiki does not support ICU locale " .
+                                       "\"{$this->locale}\"" );
                        }
                }
 
index 52bc0cd..5071fdc 100644 (file)
@@ -55,7 +55,7 @@ class ComposerVersionNormalizer {
                        $version = substr( $version, 0, $dashPosition );
                }
 
-               $version = implode( '.', array_pad( explode( '.', $version ), 4, '0' ) );
+               $version = implode( '.', array_pad( explode( '.', $version, 4 ), 4, '0' ) );
 
                if ( $dashPosition !== false ) {
                        $version .= $suffix;
index 769364f..696bbf4 100644 (file)
@@ -44,7 +44,7 @@ class ConfigFactory implements SalvageableService {
        protected $configs = [];
 
        /**
-        * @deprecated since 1.27, use MediaWikiServices::getConfigFactory() instead.
+        * @deprecated since 1.27, use MediaWikiServices::getInstance()->getConfigFactory() instead.
         *
         * @return ConfigFactory
         */
index 96dc51c..2874c33 100644 (file)
@@ -71,10 +71,8 @@ class ConfigRepository implements SalvageableService {
                if ( !$this->has( $name, true ) ) {
                        throw new \ConfigException( 'The configuration option ' . $name . ' does not exist.' );
                }
-               if ( isset( $this->configItems['public'][$name] ) ) {
-                       return $this->configItems['public'][$name];
-               }
-               return $this->configItems['private'][$name];
+
+               return $this->configItems['public'][$name] ?? $this->configItems['private'][$name];
        }
 
        /**
index 7020159..09d0189 100644 (file)
@@ -326,7 +326,7 @@ class EtcdConfig implements Config, LoggerAwareInterface {
        private function unserialize( $string ) {
                if ( $this->encoding === 'YAML' ) {
                        return yaml_parse( $string );
-               } else { // JSON
+               } else {
                        return json_decode( $string, true );
                }
        }
index 49e3132..decbb0c 100644 (file)
@@ -667,7 +667,7 @@ abstract class ContentHandler {
         * This default implementation just returns the content language (except for pages
         * in the MediaWiki namespace)
         *
-        * Note that the pages language is not cacheable, since it may in some
+        * Note that the page's language is not cacheable, since it may in some
         * cases depend on user settings.
         *
         * Also note that the page language may or may not depend on the actual content of the page,
@@ -684,7 +684,7 @@ abstract class ContentHandler {
                global $wgLang;
                $pageLang = MediaWikiServices::getInstance()->getContentLanguage();
 
-               if ( $title->getNamespace() == NS_MEDIAWIKI ) {
+               if ( $title->inNamespace( NS_MEDIAWIKI ) ) {
                        // Parse mediawiki messages with correct target language
                        list( /* $unused */, $lang ) = MessageCache::singleton()->figureMessage( $title->getText() );
                        $pageLang = Language::factory( $lang );
index 0e03e72..2f3a6f6 100644 (file)
@@ -154,7 +154,7 @@ class WikiTextStructure {
                        'enableSectionEditTokens' => false,
                        'allowTOC' => false,
                ] );
-               if ( strlen( $text ) == 0 ) {
+               if ( $text === '' ) {
                        $this->allText = "";
                        // empty text - nothing to seek here
                        return;
index 9817c3f..d32617e 100644 (file)
@@ -91,11 +91,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return Config
         */
        public function getConfig() {
-               if ( !is_null( $this->config ) ) {
-                       return $this->config;
-               } else {
-                       return $this->getContext()->getConfig();
-               }
+               return $this->config ?: $this->getContext()->getConfig();
        }
 
        /**
@@ -111,11 +107,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return Timing
         */
        public function getTiming() {
-               if ( !is_null( $this->timing ) ) {
-                       return $this->timing;
-               } else {
-                       return $this->getContext()->getTiming();
-               }
+               return $this->timing ?: $this->getContext()->getTiming();
        }
 
        /**
@@ -129,11 +121,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return WebRequest
         */
        public function getRequest() {
-               if ( !is_null( $this->request ) ) {
-                       return $this->request;
-               } else {
-                       return $this->getContext()->getRequest();
-               }
+               return $this->request ?: $this->getContext()->getRequest();
        }
 
        /**
@@ -147,11 +135,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return Title|null
         */
        public function getTitle() {
-               if ( !is_null( $this->title ) ) {
-                       return $this->title;
-               } else {
-                       return $this->getContext()->getTitle();
-               }
+               return $this->title ?: $this->getContext()->getTitle();
        }
 
        /**
@@ -165,11 +149,13 @@ class DerivativeContext extends ContextSource implements MutableContext {
        public function canUseWikiPage() {
                if ( $this->wikipage !== null ) {
                        return true;
-               } elseif ( $this->title !== null ) {
+               }
+
+               if ( $this->title !== null ) {
                        return $this->title->canExist();
-               } else {
-                       return $this->getContext()->canUseWikiPage();
                }
+
+               return $this->getContext()->canUseWikiPage();
        }
 
        /**
@@ -190,11 +176,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return WikiPage
         */
        public function getWikiPage() {
-               if ( !is_null( $this->wikipage ) ) {
-                       return $this->wikipage;
-               } else {
-                       return $this->getContext()->getWikiPage();
-               }
+               return $this->wikipage ?: $this->getContext()->getWikiPage();
        }
 
        /**
@@ -208,11 +190,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return OutputPage
         */
        public function getOutput() {
-               if ( !is_null( $this->output ) ) {
-                       return $this->output;
-               } else {
-                       return $this->getContext()->getOutput();
-               }
+               return $this->output ?: $this->getContext()->getOutput();
        }
 
        /**
@@ -226,11 +204,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return User
         */
        public function getUser() {
-               if ( !is_null( $this->user ) ) {
-                       return $this->user;
-               } else {
-                       return $this->getContext()->getUser();
-               }
+               return $this->user ?: $this->getContext()->getUser();
        }
 
        /**
@@ -255,11 +229,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @since 1.19
         */
        public function getLanguage() {
-               if ( !is_null( $this->lang ) ) {
-                       return $this->lang;
-               } else {
-                       return $this->getContext()->getLanguage();
-               }
+               return $this->lang ?: $this->getContext()->getLanguage();
        }
 
        /**
@@ -274,11 +244,7 @@ class DerivativeContext extends ContextSource implements MutableContext {
         * @return Skin
         */
        public function getSkin() {
-               if ( !is_null( $this->skin ) ) {
-                       return $this->skin;
-               } else {
-                       return $this->getContext()->getSkin();
-               }
+               return $this->skin ?: $this->getContext()->getSkin();
        }
 
        /**
index 2cbe67c..a4225a1 100644 (file)
@@ -345,12 +345,8 @@ class RequestContext implements IContextSource, MutableContext {
                                        $obj = Language::factory( $code );
                                        $this->lang = $obj;
                                }
-
-                               unset( $this->recursion );
-                       }
-                       catch ( Exception $ex ) {
+                       } finally {
                                unset( $this->recursion );
-                               throw $ex;
                        }
                }
 
index 79c0385..e099b38 100644 (file)
@@ -2,7 +2,7 @@
 
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\IDatabase;
-use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\ILoadBalancer;
 
 /**
  * Base class for objects that allow access to other wiki's databases using
@@ -84,11 +84,11 @@ abstract class DBAccessBase implements IDBAccessObject {
        /**
         * Get the database type used for read operations.
         *
-        * @see MediaWikiServices::getDBLoadBalancer
+        * @see MediaWikiServices::getInstance()->getDBLoadBalancer
         *
         * @since 1.21
         *
-        * @return LoadBalancer The database load balancer object
+        * @return ILoadBalancer The database load balancer object
         */
        public function getLoadBalancer() {
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
index d427724..cdf0f79 100644 (file)
@@ -25,16 +25,16 @@ use Wikimedia\Rdbms\IMaintainableDatabase;
 
 class CloneDatabase {
        /** @var string Table prefix for cloning */
-       private $newTablePrefix = '';
+       private $newTablePrefix;
 
        /** @var string Current table prefix */
-       private $oldTablePrefix = '';
+       private $oldTablePrefix;
 
        /** @var array List of tables to be cloned */
-       private $tablesToClone = [];
+       private $tablesToClone;
 
        /** @var bool Should we DROP tables containing the new names? */
-       private $dropCurrentTables = true;
+       private $dropCurrentTables;
 
        /** @var bool Whether to use temporary tables or not */
        private $useTemporaryTables = true;
@@ -128,7 +128,7 @@ class CloneDatabase {
        }
 
        /**
-        * Change the table prefix on all open DB connections/
+        * Change the table prefix on all open DB connections
         *
         * @param string $prefix
         * @return void
index 6af6de5..dedaf21 100644 (file)
@@ -21,7 +21,7 @@
  * @ingroup Database
  */
 
-use MediaWiki\MediaWikiServices;
+use Wikimedia\Timestamp\ConvertibleTimestamp;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\DatabaseDomain;
 use Wikimedia\Rdbms\Blob;
@@ -52,15 +52,18 @@ class DatabaseOracle extends Database {
        /** @var array */
        private $mFieldInfoCache = [];
 
-       function __construct( array $p ) {
-               global $wgDBprefix;
+       /** @var string[] Map of (reserved table name => alternate table name) */
+       private $keywordTableMap = [];
 
-               if ( $p['tablePrefix'] == 'get from global' ) {
-                       $p['tablePrefix'] = $wgDBprefix;
-               }
-               $p['tablePrefix'] = strtoupper( $p['tablePrefix'] );
-               parent::__construct( $p );
-               Hooks::run( 'DatabaseOraclePostInit', [ $this ] );
+       /**
+        * @see Database::__construct()
+        * @param array $params Additional parameters include:
+        *   - keywordTableMap : Map of reserved table names to alternative table names to use
+        */
+       function __construct( array $params ) {
+               $this->keywordTableMap = $params['keywordTableMap'] ?? [];
+               $params['tablePrefix'] = strtoupper( $params['tablePrefix'] );
+               parent::__construct( $params );
        }
 
        function __destruct() {
@@ -84,8 +87,6 @@ class DatabaseOracle extends Database {
        }
 
        protected function open( $server, $user, $password, $dbName, $schema, $tablePrefix ) {
-               global $wgDBOracleDRCP;
-
                if ( !function_exists( 'oci_connect' ) ) {
                        throw new DBConnectionError(
                                $this,
@@ -112,11 +113,7 @@ class DatabaseOracle extends Database {
                        return null;
                }
 
-               if ( $wgDBOracleDRCP ) {
-                       $this->setFlag( DBO_PERSISTENT );
-               }
-
-               $session_mode = $this->flags & DBO_SYSDBA ? OCI_SYSDBA : OCI_DEFAULT;
+               $session_mode = ( $this->flags & DBO_SYSDBA ) ? OCI_SYSDBA : OCI_DEFAULT;
 
                Wikimedia\suppressWarnings();
                if ( $this->flags & DBO_PERSISTENT ) {
@@ -184,10 +181,13 @@ class DatabaseOracle extends Database {
                return $this->trxLevel ? OCI_NO_AUTO_COMMIT : OCI_COMMIT_ON_SUCCESS;
        }
 
+       /**
+        * @param string $sql
+        * @return bool|mixed|ORAResult
+        */
        protected function doQuery( $sql ) {
-               wfDebug( "SQL: [$sql]\n" );
-               if ( !StringUtils::isUtf8( $sql ) ) {
-                       throw new InvalidArgumentException( "SQL encoding is invalid\n$sql" );
+               if ( !mb_check_encoding( (string)$sql, 'UTF-8' ) ) {
+                       throw new DBUnexpectedError( $this, "SQL encoding is invalid\n$sql" );
                }
 
                // handle some oracle specifics
@@ -421,7 +421,11 @@ class DatabaseOracle extends Database {
                }
 
                if ( $val === null ) {
-                       if ( $col_info != false && $col_info->isNullable() == 0 && $col_info->defaultValue() != null ) {
+                       if (
+                               $col_info != false &&
+                               $col_info->isNullable() == 0 &&
+                               $col_info->defaultValue() != null
+                       ) {
                                $bind .= 'DEFAULT';
                        } else {
                                $bind .= 'NULL';
@@ -482,12 +486,14 @@ class DatabaseOracle extends Database {
                                }
 
                                // backward compatibility
-                               if ( preg_match( '/^timestamp.*/i', $col_type ) == 1 && strtolower( $val ) == 'infinity' ) {
+                               if (
+                                       preg_match( '/^timestamp.*/i', $col_type ) == 1 &&
+                                       strtolower( $val ) == 'infinity'
+                               ) {
                                        $val = $this->getInfinity();
                                }
 
-                               $val = MediaWikiServices::getInstance()->getContentLanguage()->
-                                       checkTitleEncoding( $val );
+                               $val = $this->getVerifiedUTF8( $val );
                                if ( oci_bind_by_name( $stmt, ":$col", $val, -1, SQLT_CHR ) === false ) {
                                        $e = oci_error( $stmt );
                                        $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ );
@@ -499,7 +505,10 @@ class DatabaseOracle extends Database {
                                $lob[$col] = oci_new_descriptor( $this->conn, OCI_D_LOB );
                                if ( $lob[$col] === false ) {
                                        $e = oci_error( $stmt );
-                                       throw new DBUnexpectedError( $this, "Cannot create LOB descriptor: " . $e['message'] );
+                                       throw new DBUnexpectedError(
+                                               $this,
+                                               "Cannot create LOB descriptor: " . $e['message']
+                                       );
                                }
 
                                if ( is_object( $val ) ) {
@@ -555,13 +564,15 @@ class DatabaseOracle extends Database {
                if ( $sequenceData !== false &&
                        !isset( $varMap[$sequenceData['column']] )
                ) {
-                       $varMap[$sequenceData['column']] = 'GET_SEQUENCE_VALUE(\'' . $sequenceData['sequence'] . '\')';
+                       $varMap[$sequenceData['column']] =
+                               'GET_SEQUENCE_VALUE(\'' . $sequenceData['sequence'] . '\')';
                }
 
                // count-alias subselect fields to avoid abigious definition errors
                $i = 0;
                foreach ( $varMap as &$val ) {
-                       $val = $val . ' field' . ( $i++ );
+                       $val .= ' field' . $i;
+                       $i++;
                }
 
                $selectSql = $this->selectSQLText(
@@ -573,7 +584,8 @@ class DatabaseOracle extends Database {
                        $selectJoinConds
                );
 
-               $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ') ' . $selectSql;
+               $sql = "INSERT INTO $destTable (" .
+                       implode( ',', array_keys( $varMap ) ) . ') ' . $selectSql;
 
                if ( in_array( 'IGNORE', $insertOptions ) ) {
                        $this->ignoreDupValOnIndex = true;
@@ -586,7 +598,7 @@ class DatabaseOracle extends Database {
                }
        }
 
-       public function upsert( $table, array $rows, array $uniqueIndexes, array $set,
+       public function upsert( $table, array $rows, $uniqueIndexes, array $set,
                $fname = __METHOD__
        ) {
                if ( $rows === [] ) {
@@ -612,24 +624,21 @@ class DatabaseOracle extends Database {
                return parent::upsert( $table, $rows, $uniqueIndexes, $set, $fname );
        }
 
-       function tableName( $name, $format = 'quoted' ) {
-               /*
-               Replace reserved words with better ones
-               Using uppercase because that's the only way Oracle can handle
-               quoted tablenames
-               */
-               switch ( $name ) {
-                       case 'user':
-                               $name = 'MWUSER';
-                               break;
-                       case 'text':
-                               $name = 'PAGECONTENT';
-                               break;
-               }
+       public function tableName( $name, $format = 'quoted' ) {
+               // Replace reserved words with better ones
+               $name = $this->remappedTableName( $name );
 
                return strtoupper( parent::tableName( $name, $format ) );
        }
 
+       /**
+        * @param string $name
+        * @return string Value of $name or remapped name if $name is a reserved keyword
+        */
+       public function remappedTableName( $name ) {
+               return $this->keywordTableMap[$name] ?? $name;
+       }
+
        function tableNameInternal( $name ) {
                $name = $this->tableName( $name );
 
@@ -640,23 +649,31 @@ class DatabaseOracle extends Database {
         * Return sequence_name if table has a sequence
         *
         * @param string $table
-        * @return bool
+        * @return string[]|bool
         */
        private function getSequenceData( $table ) {
                if ( $this->sequenceData == null ) {
-                       $result = $this->doQuery( "SELECT lower(asq.sequence_name),
-                               lower(atc.table_name),
-                               lower(atc.column_name)
-                       FROM all_sequences asq, all_tab_columns atc
-                       WHERE decode(
-                                       atc.table_name,
-                                       '{$this->tablePrefix}MWUSER',
-                                       '{$this->tablePrefix}USER',
-                                       atc.table_name
-                               ) || '_' ||
-                               atc.column_name || '_SEQ' = '{$this->tablePrefix}' || asq.sequence_name
-                               AND asq.sequence_owner = upper('{$this->getDBname()}')
-                               AND atc.owner = upper('{$this->getDBname()}')" );
+                       $dbname = $this->currentDomain->getDatabase();
+                       $prefix = $this->currentDomain->getTablePrefix();
+                       // See https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions040.htm
+                       $decodeArgs = [ 'atc.table_name' ]; // the switch
+                       foreach ( $this->keywordTableMap as $reserved => $alternative ) {
+                               $search = strtoupper( $prefix . $alternative ); // case
+                               $replace = strtoupper( $prefix . $reserved ); // result
+                               $decodeArgs[] = $this->addQuotes( $search );
+                               $decodeArgs[] = $this->addQuotes( $replace );
+                       }
+                       $decodeArgs[] = [ 'atc.table_name' ]; // default
+                       $decodeArgs = implode( ', ', $decodeArgs );
+
+                       $result = $this->doQuery(
+                               "SELECT lower(asq.sequence_name), lower(atc.table_name), lower(atc.column_name)
+                               FROM all_sequences asq, all_tab_columns atc
+                               WHERE decode({$decodeArgs}) || '_' ||
+                               atc.column_name || '_SEQ' = '{$prefix}' || asq.sequence_name
+                               AND asq.sequence_owner = upper('{$dbname}')
+                               AND atc.owner = upper('{$dbname}')"
+                       );
 
                        while ( ( $row = $result->fetchRow() ) !== false ) {
                                $this->sequenceData[$row[1]] = [
@@ -695,14 +712,6 @@ class DatabaseOracle extends Database {
                return new Blob( $b );
        }
 
-       function decodeBlob( $b ) {
-               if ( $b instanceof Blob ) {
-                       $b = $b->fetch();
-               }
-
-               return $b;
-       }
-
        function unionQueries( $sqls, $all ) {
                $glue = ' UNION ALL ';
 
@@ -718,13 +727,14 @@ class DatabaseOracle extends Database {
                $fname = __METHOD__
        ) {
                $temporary = $temporary ? 'TRUE' : 'FALSE';
+               $tablePrefix = $this->currentDomain->getTablePrefix();
 
                $newName = strtoupper( $newName );
                $oldName = strtoupper( $oldName );
 
-               $tabName = substr( $newName, strlen( $this->tablePrefix ) );
+               $tabName = substr( $newName, strlen( $tablePrefix ) );
                $oldPrefix = substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) );
-               $newPrefix = strtoupper( $this->tablePrefix );
+               $newPrefix = strtoupper( $tablePrefix );
 
                return $this->doQuery( "BEGIN DUPLICATE_TABLE( '$tabName', " .
                        "'$oldPrefix', '$newPrefix', $temporary ); END;" );
@@ -764,8 +774,10 @@ class DatabaseOracle extends Database {
                return $this->doQuery( "DROP TABLE $tableName CASCADE CONSTRAINTS PURGE" );
        }
 
-       function timestamp( $ts = 0 ) {
-               return wfTimestamp( TS_ORACLE, $ts );
+       public function timestamp( $ts = 0 ) {
+               $t = new ConvertibleTimestamp( $ts );
+               // Let errors bubble up to avoid putting garbage in the DB
+               return $t->getTimestamp( TS_ORACLE );
        }
 
        /**
@@ -920,7 +932,10 @@ class DatabaseOracle extends Database {
         */
        function fieldInfo( $table, $field ) {
                if ( is_array( $table ) ) {
-                       throw new DBUnexpectedError( $this, 'DatabaseOracle::fieldInfo called with table array!' );
+                       throw new DBUnexpectedError(
+                               $this,
+                               'DatabaseOracle::fieldInfo called with table array!'
+                       );
                }
 
                return $this->fieldInfoMulti( $table, $field );
@@ -964,7 +979,7 @@ class DatabaseOracle extends Database {
                // Defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}';
                while ( !feof( $fp ) ) {
                        if ( $lineCallback ) {
-                               call_user_func( $lineCallback );
+                               $lineCallback();
                        }
                        $line = trim( fgets( $fp, 1024 ) );
                        $sl = strlen( $line ) - 1;
@@ -1010,7 +1025,7 @@ class DatabaseOracle extends Database {
 
                                        $cmd = $this->replaceVars( $cmd );
                                        if ( $inputCallback ) {
-                                               call_user_func( $inputCallback, $cmd );
+                                               $inputCallback( $cmd );
                                        }
                                        $res = $this->doQuery( $cmd );
                                        if ( $resultCallback ) {
@@ -1069,12 +1084,7 @@ class DatabaseOracle extends Database {
        }
 
        function addQuotes( $s ) {
-               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-               if ( isset( $contLang->mLoaded ) && $contLang->mLoaded ) {
-                       $s = $contLang->checkTitleEncoding( $s );
-               }
-
-               return "'" . $this->strencode( $s ) . "'";
+               return "'" . $this->strencode( $this->getVerifiedUTF8( $s ) ) . "'";
        }
 
        public function addIdentifierQuotes( $s ) {
@@ -1098,11 +1108,9 @@ class DatabaseOracle extends Database {
                $col_type = $col_info != false ? $col_info->type() : 'CONSTANT';
                if ( $col_type == 'CLOB' ) {
                        $col = 'TO_CHAR(' . $col . ')';
-                       $val =
-                               MediaWikiServices::getInstance()->getContentLanguage()->checkTitleEncoding( $val );
+                       $val = $this->getVerifiedUTF8( $val );
                } elseif ( $col_type == 'VARCHAR2' ) {
-                       $val =
-                               MediaWikiServices::getInstance()->getContentLanguage()->checkTitleEncoding( $val );
+                       $val = $this->getVerifiedUTF8( $val );
                }
        }
 
@@ -1268,12 +1276,14 @@ class DatabaseOracle extends Database {
                                        $val = $val->getData();
                                }
 
-                               if ( preg_match( '/^timestamp.*/i', $col_type ) == 1 && strtolower( $val ) == 'infinity' ) {
+                               if (
+                                       preg_match( '/^timestamp.*/i', $col_type ) == 1 &&
+                                       strtolower( $val ) == 'infinity'
+                               ) {
                                        $val = '31-12-2030 12:00:00.000000';
                                }
 
-                               $val = MediaWikiServices::getInstance()->getContentLanguage()->
-                                       checkTitleEncoding( $val );
+                               $val = $this->getVerifiedUTF8( $val );
                                if ( oci_bind_by_name( $stmt, ":$col", $val ) === false ) {
                                        $e = oci_error( $stmt );
                                        $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ );
@@ -1285,7 +1295,10 @@ class DatabaseOracle extends Database {
                                $lob[$col] = oci_new_descriptor( $this->conn, OCI_D_LOB );
                                if ( $lob[$col] === false ) {
                                        $e = oci_error( $stmt );
-                                       throw new DBUnexpectedError( $this, "Cannot create LOB descriptor: " . $e['message'] );
+                                       throw new DBUnexpectedError(
+                                               $this,
+                                               "Cannot create LOB descriptor: " . $e['message']
+                                       );
                                }
 
                                if ( is_object( $val ) ) {
@@ -1345,10 +1358,6 @@ class DatabaseOracle extends Database {
                return 'BITOR(' . $fieldLeft . ', ' . $fieldRight . ')';
        }
 
-       function getServer() {
-               return $this->server;
-       }
-
        public function buildGroupConcatField(
                $delim, $table, $field, $conds = '', $join_conds = []
        ) {
@@ -1378,4 +1387,16 @@ class DatabaseOracle extends Database {
        public function getInfinity() {
                return '31-12-2030 12:00:00.000000';
        }
+
+       /**
+        * @param string $s
+        * @return string
+        */
+       private function getVerifiedUTF8( $s ) {
+               if ( mb_check_encoding( (string)$s, 'UTF-8' ) ) {
+                       return $s; // valid
+               }
+
+               throw new DBUnexpectedError( $this, "Non BLOB/CLOB field must be UTF-8." );
+       }
 }
index e50f855..6633fba 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
-use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\LBFactory;
 use Wikimedia\Rdbms\DatabaseDomain;
 
@@ -39,14 +38,22 @@ abstract class MWLBFactory {
         * @param array $lbConf Config for LBFactory::__construct()
         * @param Config $mainConfig Main config object from MediaWikiServices
         * @param ConfiguredReadOnlyMode $readOnlyMode
+        * @param BagOStuff $srvCace
+        * @param BagOStuff $mainStash
+        * @param WANObjectCache $wanCache
         * @return array
         */
-       public static function applyDefaultConfig( array $lbConf, Config $mainConfig,
-               ConfiguredReadOnlyMode $readOnlyMode
+       public static function applyDefaultConfig(
+               array $lbConf,
+               Config $mainConfig,
+               ConfiguredReadOnlyMode $readOnlyMode,
+               BagOStuff $srvCace,
+               BagOStuff $mainStash,
+               WANObjectCache $wanCache
        ) {
                global $wgCommandLineMode;
 
-               static $typesWithSchema = [ 'postgres', 'msssql' ];
+               $typesWithSchema = self::getDbTypesWithSchemas();
 
                $lbConf += [
                        'localDomain' => new DatabaseDomain(
@@ -54,7 +61,9 @@ abstract class MWLBFactory {
                                $mainConfig->get( 'DBmwschema' ),
                                $mainConfig->get( 'DBprefix' )
                        ),
-                       'profiler' => Profiler::instance(),
+                       'profiler' => function ( $section ) {
+                               return Profiler::instance()->scopedProfileIn( $section );
+                       },
                        'trxProfiler' => Profiler::instance()->getTransactionProfiler(),
                        'replLogger' => LoggerFactory::getInstance( 'DBReplication' ),
                        'queryLogger' => LoggerFactory::getInstance( 'DBQuery' ),
@@ -68,99 +77,135 @@ abstract class MWLBFactory {
                        'defaultGroup' => $mainConfig->get( 'DBDefaultGroup' ),
                ];
 
+               $serversCheck = [];
                // When making changes here, remember to also specify MediaWiki-specific options
                // for Database classes in the relevant Installer subclass.
                // Such as MysqlInstaller::openConnection and PostgresInstaller::openConnectionWithParams.
                if ( $lbConf['class'] === Wikimedia\Rdbms\LBFactorySimple::class ) {
                        if ( isset( $lbConf['servers'] ) ) {
-                               // Server array is already explicitly configured; leave alone
+                               // Server array is already explicitly configured
                        } elseif ( is_array( $mainConfig->get( 'DBservers' ) ) ) {
+                               $lbConf['servers'] = [];
                                foreach ( $mainConfig->get( 'DBservers' ) as $i => $server ) {
-                                       if ( $server['type'] === 'sqlite' ) {
-                                               $server += [ 'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ) ];
-                                       } elseif ( $server['type'] === 'postgres' ) {
-                                               $server += [
-                                                       'port' => $mainConfig->get( 'DBport' ),
-                                                       // Work around the reserved word usage in MediaWiki schema
-                                                       'keywordTableMap' => [ 'user' => 'mwuser', 'text' => 'pagecontent' ]
-                                               ];
-                                       } elseif ( $server['type'] === 'mssql' ) {
-                                               $server += [
-                                                       'port' => $mainConfig->get( 'DBport' ),
-                                                       'useWindowsAuth' => $mainConfig->get( 'DBWindowsAuthentication' )
-                                               ];
-                                       }
-
-                                       if ( in_array( $server['type'], $typesWithSchema, true ) ) {
-                                               $server += [ 'schema' => $mainConfig->get( 'DBmwschema' ) ];
-                                       }
-
-                                       $server += [
-                                               'tablePrefix' => $mainConfig->get( 'DBprefix' ),
-                                               'flags' => DBO_DEFAULT,
-                                               'sqlMode' => $mainConfig->get( 'SQLMode' ),
-                                               'utf8Mode' => $mainConfig->get( 'DBmysql5' )
-                                       ];
-
-                                       $lbConf['servers'][$i] = $server;
+                                       $lbConf['servers'][$i] = self::initServerInfo( $server, $mainConfig );
                                }
                        } else {
-                               $flags = DBO_DEFAULT;
-                               $flags |= $mainConfig->get( 'DebugDumpSql' ) ? DBO_DEBUG : 0;
-                               $flags |= $mainConfig->get( 'DBssl' ) ? DBO_SSL : 0;
-                               $flags |= $mainConfig->get( 'DBcompress' ) ? DBO_COMPRESS : 0;
-                               $server = [
-                                       'host' => $mainConfig->get( 'DBserver' ),
-                                       'user' => $mainConfig->get( 'DBuser' ),
-                                       'password' => $mainConfig->get( 'DBpassword' ),
-                                       'dbname' => $mainConfig->get( 'DBname' ),
-                                       'tablePrefix' => $mainConfig->get( 'DBprefix' ),
-                                       'type' => $mainConfig->get( 'DBtype' ),
-                                       'load' => 1,
-                                       'flags' => $flags,
-                                       'sqlMode' => $mainConfig->get( 'SQLMode' ),
-                                       'utf8Mode' => $mainConfig->get( 'DBmysql5' )
-                               ];
-                               if ( in_array( $server['type'], $typesWithSchema, true ) ) {
-                                       $server += [ 'schema' => $mainConfig->get( 'DBmwschema' ) ];
-                               }
-                               if ( $server['type'] === 'sqlite' ) {
-                                       $server[ 'dbDirectory'] = $mainConfig->get( 'SQLiteDataDir' );
-                               } elseif ( $server['type'] === 'postgres' ) {
-                                       $server['port'] = $mainConfig->get( 'DBport' );
-                                       // Work around the reserved word usage in MediaWiki schema
-                                       $server['keywordTableMap'] = [ 'user' => 'mwuser', 'text' => 'pagecontent' ];
-                               } elseif ( $server['type'] === 'mssql' ) {
-                                       $server['port'] = $mainConfig->get( 'DBport' );
-                                       $server['useWindowsAuth'] = $mainConfig->get( 'DBWindowsAuthentication' );
-                               }
+                               $server = self::initServerInfo(
+                                       [
+                                               'host' => $mainConfig->get( 'DBserver' ),
+                                               'user' => $mainConfig->get( 'DBuser' ),
+                                               'password' => $mainConfig->get( 'DBpassword' ),
+                                               'dbname' => $mainConfig->get( 'DBname' ),
+                                               'type' => $mainConfig->get( 'DBtype' ),
+                                               'load' => 1
+                                       ],
+                                       $mainConfig
+                               );
+
+                               $server['flags'] |= $mainConfig->get( 'DBssl' ) ? DBO_SSL : 0;
+                               $server['flags'] |= $mainConfig->get( 'DBcompress' ) ? DBO_COMPRESS : 0;
+
                                $lbConf['servers'] = [ $server ];
                        }
                        if ( !isset( $lbConf['externalClusters'] ) ) {
                                $lbConf['externalClusters'] = $mainConfig->get( 'ExternalServers' );
                        }
+
+                       $serversCheck = $lbConf['servers'];
                } elseif ( $lbConf['class'] === Wikimedia\Rdbms\LBFactoryMulti::class ) {
                        if ( isset( $lbConf['serverTemplate'] ) ) {
                                if ( in_array( $lbConf['serverTemplate']['type'], $typesWithSchema, true ) ) {
                                        $lbConf['serverTemplate']['schema'] = $mainConfig->get( 'DBmwschema' );
                                }
                                $lbConf['serverTemplate']['sqlMode'] = $mainConfig->get( 'SQLMode' );
-                               $lbConf['serverTemplate']['utf8Mode'] = $mainConfig->get( 'DBmysql5' );
                        }
+                       $serversCheck = [ $lbConf['serverTemplate'] ] ?? [];
+               }
+
+               self::assertValidServerConfigs( $serversCheck, $mainConfig );
+
+               $lbConf = self::injectObjectCaches( $lbConf, $srvCace, $mainStash, $wanCache );
+
+               return $lbConf;
+       }
+
+       /**
+        * @return array
+        */
+       private static function getDbTypesWithSchemas() {
+               return [ 'postgres', 'msssql' ];
+       }
+
+       /**
+        * @param array $server
+        * @param Config $mainConfig
+        * @return array
+        */
+       private static function initServerInfo( array $server, Config $mainConfig ) {
+               if ( $server['type'] === 'sqlite' ) {
+                       $httpMethod = $_SERVER['REQUEST_METHOD'] ?? null;
+                       // T93097: hint for how file-based databases (e.g. sqlite) should go about locking.
+                       // See https://www.sqlite.org/lang_transaction.html
+                       // See https://www.sqlite.org/lockingv3.html#shared_lock
+                       $isHttpRead = in_array( $httpMethod, [ 'GET', 'HEAD', 'OPTIONS', 'TRACE' ] );
+                       $server += [
+                               'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ),
+                               'trxMode' => $isHttpRead ? 'DEFERRED' : 'IMMEDIATE'
+                       ];
+               } elseif ( $server['type'] === 'postgres' ) {
+                       $server += [
+                               'port' => $mainConfig->get( 'DBport' ),
+                               // Work around the reserved word usage in MediaWiki schema
+                               'keywordTableMap' => [ 'user' => 'mwuser', 'text' => 'pagecontent' ]
+                       ];
+               } elseif ( $server['type'] === 'oracle' ) {
+                       $server += [
+                               // Work around the reserved word usage in MediaWiki schema
+                               'keywordTableMap' => [ 'user' => 'mwuser', 'text' => 'pagecontent' ]
+                       ];
+               } elseif ( $server['type'] === 'mssql' ) {
+                       $server += [
+                               'port' => $mainConfig->get( 'DBport' ),
+                               'useWindowsAuth' => $mainConfig->get( 'DBWindowsAuthentication' )
+                       ];
+               }
+
+               if ( in_array( $server['type'], self::getDbTypesWithSchemas(), true ) ) {
+                       $server += [ 'schema' => $mainConfig->get( 'DBmwschema' ) ];
+               }
+
+               $flags = DBO_DEFAULT;
+               $flags |= $mainConfig->get( 'DebugDumpSql' ) ? DBO_DEBUG : 0;
+               if ( $server['type'] === 'oracle' ) {
+                       $flags |= $mainConfig->get( 'DBOracleDRCP' ) ? DBO_PERSISTENT : 0;
                }
 
-               $services = MediaWikiServices::getInstance();
+               $server += [
+                       'tablePrefix' => $mainConfig->get( 'DBprefix' ),
+                       'flags' => $flags,
+                       'sqlMode' => $mainConfig->get( 'SQLMode' ),
+               ];
 
+               return $server;
+       }
+
+       /**
+        * @param array $lbConf
+        * @param BagOStuff $sCache
+        * @param BagOStuff $mStash
+        * @param WANObjectCache $wCache
+        * @return array
+        */
+       private static function injectObjectCaches(
+               array $lbConf, BagOStuff $sCache, BagOStuff $mStash, WANObjectCache $wCache
+       ) {
                // Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804)
-               $sCache = $services->getLocalServerObjectCache();
                if ( $sCache->getQoS( $sCache::ATTR_EMULATION ) > $sCache::QOS_EMULATION_SQL ) {
                        $lbConf['srvCache'] = $sCache;
                }
-               $mStash = $services->getMainObjectStash();
                if ( $mStash->getQoS( $mStash::ATTR_EMULATION ) > $mStash::QOS_EMULATION_SQL ) {
                        $lbConf['memStash'] = $mStash;
                }
-               $wCache = $services->getMainWANObjectCache();
                if ( $wCache->getQoS( $wCache::ATTR_EMULATION ) > $wCache::QOS_EMULATION_SQL ) {
                        $lbConf['wanCache'] = $wCache;
                }
@@ -168,6 +213,84 @@ abstract class MWLBFactory {
                return $lbConf;
        }
 
+       /**
+        * @param array $servers
+        * @param Config $mainConfig
+        */
+       private static function assertValidServerConfigs( array $servers, Config $mainConfig ) {
+               $ldDB = $mainConfig->get( 'DBname' ); // local domain DB
+               $ldTP = $mainConfig->get( 'DBprefix' ); // local domain prefix
+
+               foreach ( $servers as $server ) {
+                       $type = $server['type'] ?? null;
+                       $srvDB = $server['dbname'] ?? null; // server DB
+                       $srvTP = $server['tablePrefix'] ?? ''; // server table prefix
+
+                       if ( $type === 'mysql' ) {
+                               // A DB name is not needed to connect to mysql; 'dbname' is useless.
+                               // This field only defines the DB to use for unspecified DB domains.
+                               if ( $srvDB !== null && $srvDB !== $ldDB ) {
+                                       self::reportMismatchedDBs( $srvDB, $ldDB );
+                               }
+                       } elseif ( $type === 'postgres' ) {
+                               if ( $srvTP !== '' ) {
+                                       self::reportIfPrefixSet( $srvTP, $type );
+                               }
+                       }
+
+                       if ( $srvTP !== '' && $srvTP !== $ldTP ) {
+                               self::reportMismatchedPrefixes( $srvTP, $ldTP );
+                       }
+               }
+       }
+
+       /**
+        * @param string $prefix Table prefix
+        * @param string $dbType Database type
+        */
+       private static function reportIfPrefixSet( $prefix, $dbType ) {
+               $e = new UnexpectedValueException(
+                       "\$wgDBprefix is set to '$prefix' but the database type is '$dbType'. " .
+                       "MediaWiki does not support using a table prefix with this RDBMS type."
+               );
+               MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY );
+               exit;
+       }
+
+       /**
+        * @param string $srvDB Server config database
+        * @param string $ldDB Local DB domain database
+        */
+       private static function reportMismatchedDBs( $srvDB, $ldDB ) {
+               $e = new UnexpectedValueException(
+                       "\$wgDBservers has dbname='$srvDB' but \$wgDBname='$ldDB'. " .
+                       "Set \$wgDBname to the database used by this wiki project. " .
+                       "There is rarely a need to set 'dbname' in \$wgDBservers. " .
+                       "Cross-wiki database access, use of WikiMap::getCurrentWikiDbDomain(), " .
+                       "use of Database::getDomainId(), and other features are not reliable when " .
+                       "\$wgDBservers does not match the local wiki database/prefix."
+               );
+               MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY );
+               exit;
+       }
+
+       /**
+        * @param string $srvTP Server config table prefix
+        * @param string $ldTP Local DB domain database
+        */
+       private static function reportMismatchedPrefixes( $srvTP, $ldTP ) {
+               $e = new UnexpectedValueException(
+                       "\$wgDBservers has tablePrefix='$srvTP' but \$wgDBprefix='$ldTP'. " .
+                       "Set \$wgDBprefix to the table prefix used by this wiki project. " .
+                       "There is rarely a need to set 'tablePrefix' in \$wgDBservers. " .
+                       "Cross-wiki database access, use of WikiMap::getCurrentWikiDbDomain(), " .
+                       "use of Database::getDomainId(), and other features are not reliable when " .
+                       "\$wgDBservers does not match the local wiki database/prefix."
+               );
+               MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY );
+               exit;
+       }
+
        /**
         * Returns the LBFactory class to use and the load balancer configuration.
         *
index cd78005..dc73ac9 100644 (file)
@@ -50,7 +50,7 @@ trait DeprecationHelper {
         * the name of the class defining the property, <component> is the MediaWiki component
         * (extension, skin etc.) for use in the deprecation warning) or null if it is MediaWiki.
         * E.g. [ 'mNewRev' => [ '1.32', 'DifferenceEngine', null ]
-        * @var string[]
+        * @var string[][]
         */
        protected $deprecatedPublicProperties = [];
 
@@ -68,7 +68,7 @@ trait DeprecationHelper {
        protected function deprecatePublicProperty(
                $property, $version, $class = null, $component = null
        ) {
-               $this->deprecatedPublicProperties[$property] = [ $version, $class ?: get_class(), $component ];
+               $this->deprecatedPublicProperties[$property] = [ $version, $class ?: __CLASS__, $component ];
        }
 
        public function __get( $name ) {
@@ -79,7 +79,7 @@ trait DeprecationHelper {
                        return $this->$name;
                }
 
-               $qualifiedName = get_class() . '::$' . $name;
+               $qualifiedName = __CLASS__ . '::$' . $name;
                if ( $this->deprecationHelperGetPropertyOwner( $name ) ) {
                        // Someone tried to access a normal non-public property. Try to behave like PHP would.
                        trigger_error( "Cannot access non-public property $qualifiedName", E_USER_ERROR );
@@ -99,7 +99,7 @@ trait DeprecationHelper {
                        return;
                }
 
-               $qualifiedName = get_class() . '::$' . $name;
+               $qualifiedName = __CLASS__ . '::$' . $name;
                if ( $this->deprecationHelperGetPropertyOwner( $name ) ) {
                        // Someone tried to access a normal non-public property. Try to behave like PHP would.
                        trigger_error( "Cannot access non-public property $qualifiedName", E_USER_ERROR );
index ff653ab..d67696a 100644 (file)
@@ -22,6 +22,7 @@ namespace MediaWiki\Logger;
 
 use MediaWiki\Logger\Monolog\BufferHandler;
 use Monolog\Logger;
+use Monolog\Handler\StreamHandler;
 use Wikimedia\ObjectFactory;
 
 /**
@@ -147,6 +148,17 @@ class MonologSpi implements Spi {
                                $this->config[$key] = $value;
                        }
                }
+               if ( !isset( $this->config['loggers']['@default'] ) ) {
+                       $this->config['loggers']['@default'] = [
+                               'handlers' => [ '@default' ],
+                       ];
+                       if ( !isset( $this->config['handlers']['@default'] ) ) {
+                               $this->config['handlers']['@default'] = [
+                                       'class' => StreamHandler::class,
+                                       'args' => [ 'php://stderr', Logger::ERROR ],
+                               ];
+                       }
+               }
                $this->reset();
        }
 
diff --git a/includes/debug/logger/monolog/MwlogHandler.php b/includes/debug/logger/monolog/MwlogHandler.php
new file mode 100644 (file)
index 0000000..e61aada
--- /dev/null
@@ -0,0 +1,102 @@
+<?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
+ */
+
+namespace MediaWiki\Logger\Monolog;
+
+use Monolog\Handler\SyslogUdpHandler;
+use Monolog\Logger;
+
+/**
+ * Log handler that will append the record's channel to a fixed 'application
+ * prefix' given at construction time.
+ *
+ * The use case for this handler is to deprecate udp2log with a localhost
+ * syslog endpoint. The application name is then used to reconstruct the
+ * message's channel.
+ *
+ * @since 1.32
+ * @copyright © 2019 Wikimedia Foundation and contributors
+ */
+class MwlogHandler extends SyslogUdpHandler {
+
+       /**
+        * @var string $appprefix
+        */
+       private $appprefix;
+
+       /**
+        * @var string $hostname
+        */
+       private $hostname;
+
+       /**
+        * @param string $appprefix Application prefix to use, channel will be appended.
+        * @param string $host Syslog host
+        * @param int $port Syslog port
+        * @param int $facility Syslog message facility
+        * @param int $level The minimum logging level at which this handler
+        *   will be triggered
+        * @param bool $bubble Whether the messages that are handled can bubble up
+        *   the stack or not
+        */
+       public function __construct(
+               $appprefix,
+               $host,
+               $port = 514,
+               $facility = LOG_USER,
+               $level = Logger::DEBUG,
+               $bubble = true
+       ) {
+               parent::__construct( $host, $port, $facility, $level, $bubble );
+               $this->appprefix = $appprefix;
+               $this->hostname = php_uname( 'n' );
+       }
+
+       protected function syslogHeader( $severity, $app ) {
+               $pri = $severity + $this->facility;
+
+               // Goofy date format courtesy of RFC 3164 :(
+               // RFC 3164 actually specifies that the day of month should be space
+               // padded rather than unpadded but this seems to work with rsyslog and
+               // Logstash.
+               $timestamp = date( 'M j H:i:s' );
+
+               return "<{$pri}>{$timestamp} {$this->hostname} {$app}: ";
+       }
+
+       private function splitMessageIntoLines( $message ): array {
+               if ( is_array( $message ) ) {
+                       $message = implode( "\n", $message );
+               }
+
+               return preg_split( '/$\R?^/m', (string)$message, -1, PREG_SPLIT_NO_EMPTY );
+       }
+
+       protected function write( array $record ) {
+               $lines = $this->splitMessageIntoLines( $record['formatted'] );
+               $header = $this->syslogHeader(
+                       $this->logLevels[$record['level']],
+                       $this->appprefix . $record['channel'] );
+
+               foreach ( $lines as $line ) {
+                       $this->socket->write( $line, $header );
+               }
+       }
+}
index 8b62989..69f09e3 100644 (file)
@@ -15,18 +15,22 @@ class AtomicSectionUpdate implements DeferrableUpdate, DeferrableCallback {
        private $callback;
 
        /**
-        * @param IDatabase $dbw
+        * @param IDatabase $dbw DB handle; update aborts if a transaction now this rolls back
         * @param string $fname Caller name (usually __METHOD__)
         * @param callable $callback
+        * @param IDatabase[] $conns Abort if a transaction now on one of these rolls back [optional]
         * @see IDatabase::doAtomicSection()
         */
-       public function __construct( IDatabase $dbw, $fname, callable $callback ) {
+       public function __construct( IDatabase $dbw, $fname, callable $callback, array $conns = [] ) {
                $this->dbw = $dbw;
                $this->fname = $fname;
                $this->callback = $callback;
-
-               if ( $this->dbw->trxLevel() ) {
-                       $this->dbw->onTransactionResolution( [ $this, 'cancelOnRollback' ], $fname );
+               // Register DB connections for which uncommitted changes are related to this update
+               $conns[] = $dbw;
+               foreach ( $conns as $conn ) {
+                       if ( $conn->trxLevel() ) {
+                               $conn->onTransactionResolution( [ $this, 'cancelOnRollback' ], $fname );
+                       }
                }
        }
 
@@ -36,6 +40,10 @@ class AtomicSectionUpdate implements DeferrableUpdate, DeferrableCallback {
                }
        }
 
+       /**
+        * @private This method is public so that it works with onTransactionResolution()
+        * @param int $trigger
+        */
        public function cancelOnRollback( $trigger ) {
                if ( $trigger === IDatabase::TRIGGER_ROLLBACK ) {
                        $this->callback = null;
index 8507157..ddfd987 100644 (file)
@@ -15,17 +15,21 @@ class AutoCommitUpdate implements DeferrableUpdate, DeferrableCallback {
        private $callback;
 
        /**
-        * @param IDatabase $dbw
+        * @param IDatabase $dbw DB handle; update aborts if a transaction now this rolls back
         * @param string $fname Caller name (usually __METHOD__)
         * @param callable $callback Callback that takes (IDatabase, method name string)
+        * @param IDatabase[] $conns Abort if a transaction now on one of these rolls back [optional]
         */
-       public function __construct( IDatabase $dbw, $fname, callable $callback ) {
+       public function __construct( IDatabase $dbw, $fname, callable $callback, array $conns = [] ) {
                $this->dbw = $dbw;
                $this->fname = $fname;
                $this->callback = $callback;
-
-               if ( $this->dbw->trxLevel() ) {
-                       $this->dbw->onTransactionResolution( [ $this, 'cancelOnRollback' ], $fname );
+               // Register DB connections for which uncommitted changes are related to this update
+               $conns[] = $dbw;
+               foreach ( $conns as $conn ) {
+                       if ( $conn->trxLevel() ) {
+                               $conn->onTransactionResolution( [ $this, 'cancelOnRollback' ], $fname );
+                       }
                }
        }
 
@@ -50,6 +54,10 @@ class AutoCommitUpdate implements DeferrableUpdate, DeferrableCallback {
                }
        }
 
+       /**
+        * @private This method is public so that it works with onTransactionResolution()
+        * @param int $trigger
+        */
        public function cancelOnRollback( $trigger ) {
                if ( $trigger === IDatabase::TRIGGER_ROLLBACK ) {
                        $this->callback = null;
index 5329ca7..2d07f75 100644 (file)
@@ -62,15 +62,6 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate {
                return new CdnCacheUpdate( $urlArr );
        }
 
-       /**
-        * @param Title $title
-        * @return CdnCacheUpdate
-        * @deprecated since 1.27
-        */
-       public static function newSimplePurge( Title $title ) {
-               return new CdnCacheUpdate( $title->getCdnUrls() );
-       }
-
        /**
         * Purges the list of URLs passed to the constructor.
         */
@@ -80,13 +71,10 @@ class CdnCacheUpdate implements DeferrableUpdate, MergeableUpdate {
                self::purge( $this->urls );
 
                if ( $wgCdnReboundPurgeDelay > 0 ) {
-                       JobQueueGroup::singleton()->lazyPush( new CdnPurgeJob(
-                               Title::makeTitle( NS_SPECIAL, 'Badtitle/' . __CLASS__ ),
-                               [
-                                       'urls' => $this->urls,
-                                       'jobReleaseTimestamp' => time() + $wgCdnReboundPurgeDelay
-                               ]
-                       ) );
+                       JobQueueGroup::singleton()->lazyPush( new CdnPurgeJob( [
+                               'urls' => $this->urls,
+                               'jobReleaseTimestamp' => time() + $wgCdnReboundPurgeDelay
+                       ] ) );
                }
        }
 
index b97bd21..3b7de9d 100644 (file)
@@ -124,6 +124,9 @@ class DeferredUpdates {
        /**
         * Do any deferred updates and clear the list
         *
+        * If $stage is self::ALL then the queue of PRESEND updates will be resolved,
+        * followed by the queue of POSTSEND updates
+        *
         * @param string $mode Use "enqueue" to use the job queue when possible [Default: "run"]
         * @param int $stage DeferredUpdates constant (PRESEND, POSTSEND, or ALL) (since 1.27)
         */
@@ -260,7 +263,8 @@ class DeferredUpdates {
                        if ( $mode === 'enqueue' && $update instanceof EnqueueableDataUpdate ) {
                                // Run only the job enqueue logic to complete the update later
                                $spec = $update->getAsJobSpecification();
-                               JobQueueGroup::singleton( $spec['wiki'] )->push( $spec['job'] );
+                               $domain = $spec['domain'] ?? $spec['wiki'];
+                               JobQueueGroup::singleton( $domain )->push( $spec['job'] );
                        } elseif ( $update instanceof TransactionRoundDefiningUpdate ) {
                                $update->doUpdate();
                        } else {
@@ -332,7 +336,8 @@ class DeferredUpdates {
                foreach ( $updates as $update ) {
                        if ( $update instanceof EnqueueableDataUpdate ) {
                                $spec = $update->getAsJobSpecification();
-                               JobQueueGroup::singleton( $spec['wiki'] )->push( $spec['job'] );
+                               $domain = $spec['domain'] ?? $spec['wiki'];
+                               JobQueueGroup::singleton( $domain )->push( $spec['job'] );
                        } else {
                                $remaining[] = $update;
                        }
index ffeb740..3a77f54 100644 (file)
@@ -9,7 +9,7 @@
  */
 interface EnqueueableDataUpdate {
        /**
-        * @return array (wiki => wiki ID, job => IJobSpecification)
+        * @return array (domain => DB domain ID, job => IJobSpecification)
         */
        public function getAsJobSpecification();
 }
index 0743dbe..0e24134 100644 (file)
  */
 use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
-use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Update object handling the cleanup of links tables after a page was deleted.
  */
-class LinksDeletionUpdate extends DataUpdate implements EnqueueableDataUpdate {
+class LinksDeletionUpdate extends LinksUpdate implements EnqueueableDataUpdate {
        /** @var WikiPage */
        protected $page;
-       /** @var int */
-       protected $pageId;
        /** @var string */
        protected $timestamp;
 
-       /** @var IDatabase */
-       private $db;
-
        /**
         * @param WikiPage $page Page we are updating
         * @param int|null $pageId ID of the page we are updating [optional]
@@ -44,63 +38,37 @@ class LinksDeletionUpdate extends DataUpdate implements EnqueueableDataUpdate {
         * @throws MWException
         */
        function __construct( WikiPage $page, $pageId = null, $timestamp = null ) {
-               parent::__construct();
-
                $this->page = $page;
                if ( $pageId ) {
-                       $this->pageId = $pageId; // page ID at time of deletion
+                       $this->mId = $pageId; // page ID at time of deletion
                } elseif ( $page->exists() ) {
-                       $this->pageId = $page->getId();
+                       $this->mId = $page->getId();
                } else {
                        throw new InvalidArgumentException( "Page ID not known. Page doesn't exist?" );
                }
 
                $this->timestamp = $timestamp ?: wfTimestampNow();
+
+               $fakePO = new ParserOutput();
+               $fakePO->setCacheTime( $timestamp );
+               parent::__construct( $page->getTitle(), $fakePO, false );
        }
 
-       public function doUpdate() {
+       protected function doIncrementalUpdate() {
                $services = MediaWikiServices::getInstance();
                $config = $services->getMainConfig();
                $lbFactory = $services->getDBLoadBalancerFactory();
                $batchSize = $config->get( 'UpdateRowsPerQuery' );
 
-               // Page may already be deleted, so don't just getId()
-               $id = $this->pageId;
-
-               if ( $this->ticket ) {
-                       // Make sure all links update threads see the changes of each other.
-                       // This handles the case when updates have to batched into several COMMITs.
-                       $scopedLock = LinksUpdate::acquirePageLock( $this->getDB(), $id );
-                       if ( !$scopedLock ) {
-                               throw new RuntimeException( "Could not acquire lock for page ID '{$id}'." );
-                       }
-               }
+               $id = $this->mId;
+               $title = $this->mTitle;
 
-               $title = $this->page->getTitle();
                $dbw = $this->getDB(); // convenience
 
-               // Delete restrictions for it
-               $dbw->delete( 'page_restrictions', [ 'pr_page' => $id ], __METHOD__ );
+               parent::doIncrementalUpdate();
 
-               // Fix category table counts
-               $cats = $dbw->selectFieldValues(
-                       'categorylinks',
-                       'cl_to',
-                       [ 'cl_from' => $id ],
-                       __METHOD__
-               );
-               $catBatches = array_chunk( $cats, $batchSize );
-               foreach ( $catBatches as $catBatch ) {
-                       $this->page->updateCategoryCounts( [], $catBatch, $id );
-                       if ( count( $catBatches ) > 1 ) {
-                               // Only sacrifice atomicity if necessary due to size
-                               $lbFactory->commitAndWaitForReplication(
-                                       __METHOD__, $this->ticket, [ 'domain' => $dbw->getDomainID() ]
-                               );
-                       }
-               }
-
-               // Refresh counts on categories that should be empty now
+               // Typically, a category is empty when deleted, so check that we don't leave
+               // spurious row in the category table.
                if ( $title->getNamespace() === NS_CATEGORY ) {
                        // T166757: do the update after the main job DB commit
                        DeferredUpdates::addCallableUpdate( function () use ( $title ) {
@@ -109,52 +77,11 @@ class LinksDeletionUpdate extends DataUpdate implements EnqueueableDataUpdate {
                        } );
                }
 
-               $this->batchDeleteByPK(
-                       'pagelinks',
-                       [ 'pl_from' => $id ],
-                       [ 'pl_from', 'pl_namespace', 'pl_title' ],
-                       $batchSize
-               );
-               $this->batchDeleteByPK(
-                       'imagelinks',
-                       [ 'il_from' => $id ],
-                       [ 'il_from', 'il_to' ],
-                       $batchSize
-               );
-               $this->batchDeleteByPK(
-                       'categorylinks',
-                       [ 'cl_from' => $id ],
-                       [ 'cl_from', 'cl_to' ],
-                       $batchSize
-               );
-               $this->batchDeleteByPK(
-                       'templatelinks',
-                       [ 'tl_from' => $id ],
-                       [ 'tl_from', 'tl_namespace', 'tl_title' ],
-                       $batchSize
-               );
-               $this->batchDeleteByPK(
-                       'externallinks',
-                       [ 'el_from' => $id ],
-                       [ 'el_id' ],
-                       $batchSize
-               );
-               $this->batchDeleteByPK(
-                       'langlinks',
-                       [ 'll_from' => $id ],
-                       [ 'll_from', 'll_lang' ],
-                       $batchSize
-               );
-               $this->batchDeleteByPK(
-                       'iwlinks',
-                       [ 'iwl_from' => $id ],
-                       [ 'iwl_from', 'iwl_prefix', 'iwl_title' ],
-                       $batchSize
-               );
+               // Delete restrictions for the deleted page
+               $dbw->delete( 'page_restrictions', [ 'pr_page' => $id ], __METHOD__ );
 
-               // Delete any redirect entry or page props entries
+               // Delete any redirect entry
                $dbw->delete( 'redirect', [ 'rd_from' => $id ], __METHOD__ );
-               $dbw->delete( 'page_props', [ 'pp_page' => $id ], __METHOD__ );
 
                // Find recentchanges entries to clean up...
                $rcIdsForTitle = $dbw->selectFieldValues(
@@ -191,46 +118,14 @@ class LinksDeletionUpdate extends DataUpdate implements EnqueueableDataUpdate {
                ScopedCallback::consume( $scopedLock );
        }
 
-       private function batchDeleteByPK( $table, array $conds, array $pk, $bSize ) {
-               $services = MediaWikiServices::getInstance();
-               $lbFactory = $services->getDBLoadBalancerFactory();
-               $dbw = $this->getDB(); // convenience
-
-               $res = $dbw->select( $table, $pk, $conds, __METHOD__ );
-
-               $pkDeleteConds = [];
-               foreach ( $res as $row ) {
-                       $pkDeleteConds[] = $dbw->makeList( (array)$row, LIST_AND );
-                       if ( count( $pkDeleteConds ) >= $bSize ) {
-                               $dbw->delete( $table, $dbw->makeList( $pkDeleteConds, LIST_OR ), __METHOD__ );
-                               $lbFactory->commitAndWaitForReplication(
-                                       __METHOD__, $this->ticket, [ 'domain' => $dbw->getDomainID() ]
-                               );
-                               $pkDeleteConds = [];
-                       }
-               }
-
-               if ( $pkDeleteConds ) {
-                       $dbw->delete( $table, $dbw->makeList( $pkDeleteConds, LIST_OR ), __METHOD__ );
-               }
-       }
-
-       protected function getDB() {
-               if ( !$this->db ) {
-                       $this->db = wfGetDB( DB_MASTER );
-               }
-
-               return $this->db;
-       }
-
        public function getAsJobSpecification() {
                return [
-                       'wiki' => WikiMap::getWikiIdFromDbDomain( $this->getDB()->getDomainID() ),
-                       'job'  => new JobSpecification(
+                       'domain' => $this->getDB()->getDomainID(),
+                       'job' => new JobSpecification(
                                'deleteLinks',
-                               [ 'pageId' => $this->pageId, 'timestamp' => $this->timestamp ],
+                               [ 'pageId' => $this->mId, 'timestamp' => $this->timestamp ],
                                [ 'removeDuplicates' => true ],
-                               $this->page->getTitle()
+                               $this->mTitle
                        )
                ];
        }
index 7c7cabd..9d3309b 100644 (file)
@@ -122,7 +122,11 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                parent::__construct();
 
                $this->mTitle = $title;
-               $this->mId = $title->getArticleID( Title::GAID_FOR_UPDATE );
+
+               if ( !$this->mId ) {
+                       // NOTE: subclasses may initialize mId before calling this constructor!
+                       $this->mId = $title->getArticleID( Title::GAID_FOR_UPDATE );
+               }
 
                if ( !$this->mId ) {
                        throw new InvalidArgumentException(
@@ -611,7 +615,8 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                        $nt = Title::makeTitleSafe( NS_CATEGORY, $name );
                        $contLang->findVariantLink( $name, $nt, true );
 
-                       $type = MWNamespace::getCategoryLinkType( $this->mTitle->getNamespace() );
+                       $type = MediaWikiServices::getInstance()->getNamespaceInfo()->
+                               getCategoryLinkType( $this->mTitle->getNamespace() );
 
                        # Treat custom sortkeys as a prefix, so that if multiple
                        # things are forced to sort as '*' or something, they'll
@@ -832,7 +837,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
         * @param array $existing
         * @return array
         */
-       function getPropertyDeletions( $existing ) {
+       private function getPropertyDeletions( $existing ) {
                return array_diff_assoc( $existing, $this->mProperties );
        }
 
@@ -1180,7 +1185,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
        /**
         * @return IDatabase
         */
-       private function getDB() {
+       protected function getDB() {
                if ( !$this->db ) {
                        $this->db = wfGetDB( DB_MASTER );
                }
@@ -1205,7 +1210,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                }
 
                return [
-                       'wiki' => WikiMap::getWikiIdFromDbDomain( $this->getDB()->getDomainID() ),
+                       'domain' => $this->getDB()->getDomainID(),
                        'job'  => new JobSpecification(
                                'refreshLinksPrioritized',
                                [
index 9803b7a..efca406 100644 (file)
@@ -35,6 +35,10 @@ class MWCallableUpdate implements DeferrableUpdate, DeferrableCallback {
                }
        }
 
+       /**
+        * @private This method is public so that it works with onTransactionResolution()
+        * @param int $trigger
+        */
        public function cancelOnRollback( $trigger ) {
                if ( $trigger === IDatabase::TRIGGER_ROLLBACK ) {
                        $this->callback = null;
index 604f205..a218f76 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Linker\LinkTarget;
 use Psr\Log\LoggerInterface;
 use Wikimedia\Rdbms\IDatabase;
@@ -39,7 +40,7 @@ class WANCacheReapUpdate implements DeferrableUpdate {
 
        function doUpdate() {
                $reaper = new WANObjectCacheReaper(
-                       ObjectCache::getMainWANInstance(),
+                       MediaWikiServices::getInstance()->getMainWANObjectCache(),
                        ObjectCache::getLocalClusterInstance(),
                        [ $this, 'getTitleChangeEvents' ],
                        [ $this, 'getEventAffectedKeys' ],
index 142c51d..546a12c 100644 (file)
@@ -456,9 +456,7 @@ class DiffEngine {
 
                // need to store these so we don't lose them when they're
                // overwritten by the recursion
-               $len = $snake[2];
-               $startx = $snake[0];
-               $starty = $snake[1];
+               list( $startx, $starty, $len ) = $snake;
 
                // the middle snake is part of the LCS, store it
                for ( $i = 0; $i < $len; ++$i ) {
@@ -805,40 +803,3 @@ class DiffEngine {
        }
 
 }
-
-/**
- * Alternative representation of a set of changes, by the index
- * ranges that are changed.
- *
- * @ingroup DifferenceEngine
- */
-class RangeDifference {
-
-       /** @var int */
-       public $leftstart;
-
-       /** @var int */
-       public $leftend;
-
-       /** @var int */
-       public $leftlength;
-
-       /** @var int */
-       public $rightstart;
-
-       /** @var int */
-       public $rightend;
-
-       /** @var int */
-       public $rightlength;
-
-       function __construct( $leftstart, $leftend, $rightstart, $rightend ) {
-               $this->leftstart = $leftstart;
-               $this->leftend = $leftend;
-               $this->leftlength = $leftend - $leftstart;
-               $this->rightstart = $rightstart;
-               $this->rightend = $rightend;
-               $this->rightlength = $rightend - $rightstart;
-       }
-
-}
index 8e2b96d..833bc69 100644 (file)
@@ -250,7 +250,7 @@ class DifferenceEngine extends ContextSource {
 
                        $slotContents = $this->getSlotContents();
                        $this->slotDiffRenderers = array_map( function ( $contents ) {
-                               /** @var $content Content */
+                               /** @var Content $content */
                                $content = $contents['new'] ?: $contents['old'];
                                return $content->getContentHandler()->getSlotDiffRenderer( $this->getContext() );
                        }, $slotContents );
@@ -1024,7 +1024,7 @@ class DifferenceEngine extends ContextSource {
 
                // Cacheable?
                $key = false;
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                if ( $this->mOldid && $this->mNewid ) {
                        // Check if subclass is still using the old way
                        // for backwards-compatibility
diff --git a/includes/diff/RangeDifference.php b/includes/diff/RangeDifference.php
new file mode 100644 (file)
index 0000000..e625514
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+/**
+ * New version of the difference engine
+ *
+ * Copyright © 2008 Guy Van den Broeck <guy@guyvdb.eu>
+ *
+ * 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 DifferenceEngine
+ */
+
+/**
+ * Alternative representation of a set of changes, by the index
+ * ranges that are changed.
+ *
+ * @ingroup DifferenceEngine
+ */
+class RangeDifference {
+
+       /** @var int */
+       public $leftstart;
+
+       /** @var int */
+       public $leftend;
+
+       /** @var int */
+       public $leftlength;
+
+       /** @var int */
+       public $rightstart;
+
+       /** @var int */
+       public $rightend;
+
+       /** @var int */
+       public $rightlength;
+
+       function __construct( $leftstart, $leftend, $rightstart, $rightend ) {
+               $this->leftstart = $leftstart;
+               $this->leftend = $leftend;
+               $this->leftlength = $leftend - $leftstart;
+               $this->rightstart = $rightstart;
+               $this->rightend = $rightend;
+               $this->rightlength = $rightend - $rightstart;
+       }
+
+}
index e2cdd82..bb965e1 100644 (file)
@@ -72,7 +72,7 @@ class TextSlotDiffRenderer extends SlotDiffRenderer {
         * @return string
         */
        public static function diff( $oldText, $newText ) {
-               /** @var $slotDiffRenderer TextSlotDiffRenderer */
+               /** @var TextSlotDiffRenderer $slotDiffRenderer */
                $slotDiffRenderer = ContentHandler::getForModelID( CONTENT_MODEL_TEXT )
                        ->getSlotDiffRenderer( RequestContext::getMain() );
                return $slotDiffRenderer->getTextDiff( $oldText, $newText );
@@ -214,12 +214,6 @@ class TextSlotDiffRenderer extends SlotDiffRenderer {
                                        $newText,
                                        2
                                );
-
-                               // Log a warning in case the configuration value is set to not silently ignore it
-                               if ( $this->wikiDiff2MovedParagraphDetectionCutoff > 0 ) {
-                                       wfLogWarning( '$wgWikiDiff2MovedParagraphDetectionCutoff is set but has no
-                                               effect since the used version of WikiDiff2 does not support it.' );
-                               }
                        }
 
                        return $text;
index f7d0945..2471b52 100644 (file)
@@ -166,7 +166,6 @@ class TextConflictHelper {
         * HTML to build the textbox1 on edit conflicts
         *
         * @param array $customAttribs
-        * @return string HTML
         */
        public function getEditConflictMainTextBox( array $customAttribs = [] ) {
                $builder = new TextboxBuilder();
index 7f70c4f..cb7ff19 100644 (file)
@@ -69,23 +69,22 @@ class MWException extends Exception {
         * @param string $key Message name
         * @param string $fallback Default message if the message cache can't be
         *                  called by the exception
-        * The function also has other parameters that are arguments for the message
+        * @param mixed ...$params To pass to wfMessage()
         * @return string Message with arguments replaced
         */
-       public function msg( $key, $fallback /*[, params...] */ ) {
+       public function msg( $key, $fallback, ...$params ) {
                global $wgSitename;
-               $args = array_slice( func_get_args(), 2 );
 
                // FIXME: Keep logic in sync with MWExceptionRenderer::msg.
                $res = false;
                if ( $this->useMessageCache() ) {
                        try {
-                               $res = wfMessage( $key, $args )->text();
+                               $res = wfMessage( $key, $params )->text();
                        } catch ( Exception $e ) {
                        }
                }
                if ( $res === false ) {
-                       $res = wfMsgReplaceArgs( $fallback, $args );
+                       $res = wfMsgReplaceArgs( $fallback, $params );
                        // If an exception happens inside message rendering,
                        // {{SITENAME}} sometimes won't be replaced.
                        $res = strtr( $res, [
@@ -209,12 +208,7 @@ class MWException extends Exception {
                        wfHttpError( 500, 'Internal Server Error', $this->getText() );
                } elseif ( self::isCommandLine() ) {
                        $message = $this->getText();
-                       // T17602: STDERR may not be available
-                       if ( !defined( 'MW_PHPUNIT_TEST' ) && defined( 'STDERR' ) ) {
-                               fwrite( STDERR, $message );
-                       } else {
-                               echo $message;
-                       }
+                       $this->writeToCommandLine( $message );
                } else {
                        self::statusHeader( 500 );
                        self::header( "Content-Type: $wgMimeType; charset=utf-8" );
@@ -223,6 +217,21 @@ class MWException extends Exception {
                }
        }
 
+       /**
+        * Write a message to stderr falling back to stdout if stderr unavailable
+        *
+        * @param string $message
+        * @suppress SecurityCheck-XSS
+        */
+       private function writeToCommandLine( $message ) {
+               // T17602: STDERR may not be available
+               if ( !defined( 'MW_PHPUNIT_TEST' ) && defined( 'STDERR' ) ) {
+                       fwrite( STDERR, $message );
+               } else {
+                       echo $message;
+               }
+       }
+
        /**
         * Check whether we are in command line mode or not to report the exception
         * in the correct format.
index 22be2be..c52a867 100644 (file)
@@ -71,14 +71,12 @@ class MWExceptionRenderer {
                                                self::getShowBacktraceError( $e );
                                }
                                $message .= "\n";
+                       } elseif ( $wgShowExceptionDetails ) {
+                               $message = MWExceptionHandler::getLogMessage( $e ) .
+                                       "\nBacktrace:\n" .
+                                       MWExceptionHandler::getRedactedTraceAsString( $e ) . "\n";
                        } else {
-                               if ( $wgShowExceptionDetails ) {
-                                       $message = MWExceptionHandler::getLogMessage( $e ) .
-                                               "\nBacktrace:\n" .
-                                               MWExceptionHandler::getRedactedTraceAsString( $e ) . "\n";
-                               } else {
-                                       $message = MWExceptionHandler::getPublicLogMessage( $e );
-                               }
+                               $message = MWExceptionHandler::getPublicLogMessage( $e );
                        }
                        echo nl2br( htmlspecialchars( $message ) ) . "\n";
                }
@@ -193,18 +191,17 @@ class MWExceptionRenderer {
         * @param string $key Message name
         * @param string $fallback Default message if the message cache can't be
         *                  called by the exception
-        * The function also has other parameters that are arguments for the message
+        * @param mixed ...$params To pass to wfMessage()
         * @return string Message with arguments replaced
         */
-       private static function msg( $key, $fallback /*[, params...] */ ) {
+       private static function msg( $key, $fallback, ...$params ) {
                global $wgSitename;
-               $args = array_slice( func_get_args(), 2 );
 
                // FIXME: Keep logic in sync with MWException::msg.
                try {
-                       $res = wfMessage( $key, $args )->text();
+                       $res = wfMessage( $key, $params )->text();
                } catch ( Exception $e ) {
-                       $res = wfMsgReplaceArgs( $fallback, $args );
+                       $res = wfMsgReplaceArgs( $fallback, $params );
                        // If an exception happens inside message rendering,
                        // {{SITENAME}} sometimes won't be replaced.
                        $res = strtr( $res, [
@@ -268,6 +265,7 @@ class MWExceptionRenderer {
         * Print a message, if possible to STDERR.
         * Use this in command line mode only (see isCommandLine)
         *
+        * @suppress SecurityCheck-XSS
         * @param string $message Failure text
         */
        private static function printError( $message ) {
index 31c945c..a50150e 100644 (file)
@@ -23,6 +23,8 @@
  * @file
  */
 
+use MediaWiki\Shell\Shell;
+
 /**
  * @ingroup Dump
  */
@@ -49,8 +51,8 @@ class Dump7ZipOutput extends DumpPipeOutput {
         */
        function setup7zCommand( $file ) {
                $command = "7za a -bd -si -mx=";
-               $command .= wfEscapeShellArg( $this->compressionLevel ) . ' ';
-               $command .= wfEscapeShellArg( $file );
+               $command .= Shell::escape( $this->compressionLevel ) . ' ';
+               $command .= Shell::escape( $file );
                // Suppress annoying useless crap from p7zip
                // Unfortunately this could suppress real error messages too
                $command .= ' >' . wfGetNull() . ' 2>&1';
diff --git a/includes/export/DumpLBZip2Output.php b/includes/export/DumpLBZip2Output.php
new file mode 100644 (file)
index 0000000..b923995
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Sends dump output via the lbzip2 compressor.
+ *
+ * Copyright © 2003, 2005, 2006 Brion Vibber <brion@pobox.com>
+ * Copyright © 2019 Wikimedia Foundation Inc.
+ * https://www.mediawiki.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @ingroup Dump
+ * @since 1.33
+ */
+class DumpLBZip2Output extends DumpPipeOutput {
+       /**
+        * @param string $file
+        */
+       function __construct( $file ) {
+               # use only one core
+               parent::__construct( "lbzip2 -n 1", $file );
+       }
+}
index 26010da..a353c44 100644 (file)
@@ -25,6 +25,8 @@
  * @file
  */
 
+use MediaWiki\Shell\Shell;
+
 /**
  * @ingroup Dump
  */
@@ -38,7 +40,7 @@ class DumpPipeOutput extends DumpFileOutput {
         */
        function __construct( $command, $file = null ) {
                if ( !is_null( $file ) ) {
-                       $command .= " > " . wfEscapeShellArg( $file );
+                       $command .= " > " . Shell::escape( $file );
                }
 
                $this->startCommand( $command );
@@ -94,7 +96,7 @@ class DumpPipeOutput extends DumpFileOutput {
                        $this->renameOrException( $newname );
                        if ( $open ) {
                                $command = $this->command;
-                               $command .= " > " . wfEscapeShellArg( $this->filename );
+                               $command .= " > " . Shell::escape( $this->filename );
                                $this->startCommand( $command );
                        }
                }
index e6b9719..e02cd83 100644 (file)
@@ -63,12 +63,16 @@ class WikiExporter {
        /** @var DumpOutput */
        public $sink;
 
+       /** @var XmlDumpWriter */
+       private $writer;
+
        /**
-        * Returns the export schema version.
+        * Returns the default export schema version, as defined by $wgXmlDumpSchemaVersion.
         * @return string
         */
        public static function schemaVersion() {
-               return "0.10";
+               global $wgXmlDumpSchemaVersion;
+               return $wgXmlDumpSchemaVersion;
        }
 
        /**
@@ -83,11 +87,20 @@ class WikiExporter {
        function __construct( $db, $history = self::CURRENT, $text = self::TEXT ) {
                $this->db = $db;
                $this->history = $history;
-               $this->writer = new XmlDumpWriter();
+               $this->writer = new XmlDumpWriter( $text, self::schemaVersion() );
                $this->sink = new DumpOutput();
                $this->text = $text;
        }
 
+       /**
+        * @param string $schemaVersion which schema version the generated XML should comply to.
+        * One of the values from self::$supportedSchemas, using the XML_DUMP_SCHEMA_VERSION_XX
+        * constants.
+        */
+       public function setSchemaVersion( $schemaVersion ) {
+               $this->writer = new XmlDumpWriter( $this->text, $schemaVersion );
+       }
+
        /**
         * Set the DumpOutput or DumpFilter object which will receive
         * various row objects and XML output for filtering. Filters
@@ -233,10 +246,10 @@ class WikiExporter {
                foreach ( $res as $row ) {
                        $this->author_list .= "<contributor>" .
                                "<username>" .
-                               htmlentities( $row->rev_user_text ) .
+                               htmlspecialchars( $row->rev_user_text ) .
                                "</username>" .
                                "<id>" .
-                               $row->rev_user .
+                               ( (int)$row->rev_user ) .
                                "</id>" .
                                "</contributor>";
                }
@@ -322,10 +335,7 @@ class WikiExporter {
                }
 
                $revOpts = [ 'page' ];
-               if ( $this->text != self::STUB ) {
-                       // TODO: remove the text and make XmlDumpWriter use a RevisionStore instead! (T198706)
-                       $revOpts[] = 'text';
-               }
+
                $revQuery = Revision::getQueryInfo( $revOpts );
 
                // We want page primary rather than revision
@@ -335,8 +345,12 @@ class WikiExporter {
                        ];
                unset( $join['page'] );
 
-               // TODO: remove rev_text_id and make XmlDumpWriter use a RevisionStore instead! (T198706)
-               $fields = array_merge( $revQuery['fields'], [ 'page_restrictions, rev_text_id' ] );
+               $fields = $revQuery['fields'];
+               $fields[] = 'page_restrictions';
+
+               if ( $this->text != self::STUB ) {
+                       $fields['_load_content'] = '1';
+               }
 
                $conds = [];
                if ( $cond !== '' ) {
@@ -372,18 +386,18 @@ class WikiExporter {
                                $opts[] = 'STRAIGHT_JOIN';
                                $opts['USE INDEX']['revision'] = 'rev_page_id';
                                unset( $join['revision'] );
-                               $join['page'] = [ 'INNER JOIN', 'rev_page=page_id' ];
+                               $join['page'] = [ 'JOIN', 'rev_page=page_id' ];
                        }
                } elseif ( $this->history & self::CURRENT ) {
                        # Latest revision dumps...
                        if ( $this->list_authors && $cond != '' ) { // List authors, if so desired
                                $this->do_list_authors( $cond );
                        }
-                       $join['revision'] = [ 'INNER JOIN', 'page_id=rev_page AND page_latest=rev_id' ];
+                       $join['revision'] = [ 'JOIN', 'page_id=rev_page AND page_latest=rev_id' ];
                } elseif ( $this->history & self::STABLE ) {
                        # "Stable" revision dumps...
                        # Default JOIN, to be overridden...
-                       $join['revision'] = [ 'INNER JOIN', 'page_id=rev_page AND page_latest=rev_id' ];
+                       $join['revision'] = [ 'JOIN', 'page_id=rev_page AND page_latest=rev_id' ];
                        # One, and only one hook should set this, and return false
                        if ( Hooks::run( 'WikiExporter::dumpStableQuery', [ &$tables, &$opts, &$join ] ) ) {
                                throw new MWException( __METHOD__ . " given invalid history dump type." );
@@ -455,8 +469,8 @@ class WikiExporter {
        protected function outputPageStreamBatch( $results, $lastRow ) {
                foreach ( $results as $row ) {
                        if ( $lastRow === null ||
-                               $lastRow->page_namespace != $row->page_namespace ||
-                               $lastRow->page_title != $row->page_title ) {
+                               $lastRow->page_namespace !== $row->page_namespace ||
+                               $lastRow->page_title !== $row->page_title ) {
                                if ( $lastRow !== null ) {
                                        $output = '';
                                        if ( $this->dumpUploads ) {
index fae8b62..54249a8 100644 (file)
  *
  * @file
  */
-
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Storage\SqlBlobStore;
 
 /**
  * @ingroup Dump
  */
 class XmlDumpWriter {
+       /**
+        * @var string[] the schema versions supported for output
+        * @final
+        */
+       public static $supportedSchemas = [
+               XML_DUMP_SCHEMA_VERSION_10,
+       ];
+
+       /**
+        * Title of the currently processed page
+        *
+        * @var Title|null
+        */
+       private $currentTitle = null;
+
        /**
         * Opens the XML output stream's root "<mediawiki>" element.
         * This does not include an xml directive, so is safe to include
@@ -159,12 +175,13 @@ class XmlDumpWriter {
         */
        public function openPage( $row ) {
                $out = "  <page>\n";
-               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
-               $out .= '    ' . Xml::elementClean( 'title', [], self::canonicalTitle( $title ) ) . "\n";
+               $this->currentTitle = Title::makeTitle( $row->page_namespace, $row->page_title );
+               $canonicalTitle = self::canonicalTitle( $this->currentTitle );
+               $out .= '    ' . Xml::elementClean( 'title', [], $canonicalTitle ) . "\n";
                $out .= '    ' . Xml::element( 'ns', [], strval( $row->page_namespace ) ) . "\n";
                $out .= '    ' . Xml::element( 'id', [], strval( $row->page_id ) ) . "\n";
                if ( $row->page_is_redirect ) {
-                       $page = WikiPage::factory( $title );
+                       $page = WikiPage::factory( $this->currentTitle );
                        $redirect = $page->getRedirectTarget();
                        if ( $redirect instanceof Title && $redirect->isValidRedirectTarget() ) {
                                $out .= '    ';
@@ -178,7 +195,7 @@ class XmlDumpWriter {
                                strval( $row->page_restrictions ) ) . "\n";
                }
 
-               Hooks::run( 'XmlDumpWriterOpenPage', [ $this, &$out, $row, $title ] );
+               Hooks::run( 'XmlDumpWriterOpenPage', [ $this, &$out, $row, $this->currentTitle ] );
 
                return $out;
        }
@@ -190,9 +207,29 @@ class XmlDumpWriter {
         * @return string
         */
        function closePage() {
+               if ( $this->currentTitle !== null ) {
+                       $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+                       // In rare cases, link cache has the same key for some pages which
+                       // might be read as part of the same batch. T220424 and T220316
+                       $linkCache->clearLink( $this->currentTitle );
+               }
                return "  </page>\n";
        }
 
+       /**
+        * @return RevisionStore
+        */
+       private function getRevisionStore() {
+               return MediaWikiServices::getInstance()->getRevisionStore();
+       }
+
+       /**
+        * @return SqlBlobStore
+        */
+       private function getBlobStore() {
+               return MediaWikiServices::getInstance()->getBlobStore();
+       }
+
        /**
         * Dumps a "<revision>" section on the output stream, with
         * data filled in from the given database row.
@@ -228,16 +265,17 @@ class XmlDumpWriter {
                        }
                }
 
+               // TODO: rev_content_model no longer exists with MCR, see T174031
                if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model ) ) {
                        $content_model = strval( $row->rev_content_model );
                } else {
                        // probably using $wgContentHandlerUseDB = false;
-                       $title = Title::makeTitle( $row->page_namespace, $row->page_title );
-                       $content_model = ContentHandler::getDefaultModelFor( $title );
+                       $content_model = ContentHandler::getDefaultModelFor( $this->currentTitle );
                }
 
                $content_handler = ContentHandler::getForModelID( $content_model );
 
+               // TODO: rev_content_format no longer exists with MCR, see T174031
                if ( isset( $row->rev_content_format ) && !is_null( $row->rev_content_format ) ) {
                        $content_format = strval( $row->rev_content_format );
                } else {
@@ -254,15 +292,70 @@ class XmlDumpWriter {
                } elseif ( isset( $row->old_text ) ) {
                        // Raw text from the database may have invalid chars
                        $text = strval( Revision::getRevisionText( $row ) );
-                       $text = $content_handler->exportTransform( $text, $content_format );
+                       try {
+                               $text = $content_handler->exportTransform( $text, $content_format );
+                       }
+                       catch ( Exception $ex ) {
+                               if ( $ex instanceof MWException || $ex instanceof RuntimeException ) {
+                                       // leave text as is; that's the way it goes
+                                       wfLogWarning( 'exportTransform failed on text for revid ' . $row->rev_id . "\n" );
+                               } else {
+                                       throw $ex;
+                               }
+                       }
                        $out .= "      " . Xml::elementClean( 'text',
                                [ 'xml:space' => 'preserve', 'bytes' => intval( $row->rev_len ) ],
                                strval( $text ) ) . "\n";
-               } else {
-                       // Stub output
+               } elseif ( isset( $row->_load_content ) ) {
+                       // TODO: make this fully MCR aware, see T174031
+                       $rev = $this->getRevisionStore()->newRevisionFromRow( $row, 0, $this->currentTitle );
+                       $slot = $rev->getSlot( 'main' );
+                       try {
+                               $content = $slot->getContent();
+
+                               if ( $content instanceof TextContent ) {
+                                       // HACK: For text based models, bypass the serialization step.
+                                       // This allows extensions (like Flow)that use incompatible combinations
+                                       // of serialization format and content model.
+                                       $text = $content->getNativeData();
+                               } else {
+                                       $text = $content->serialize( $content_format );
+                               }
+                               $text = $content_handler->exportTransform( $text, $content_format );
+                               $out .= "      " . Xml::elementClean( 'text',
+                                       [ 'xml:space' => 'preserve', 'bytes' => intval( $slot->getSize() ) ],
+                                       strval( $text ) ) . "\n";
+                       }
+                       catch ( Exception $ex ) {
+                               if ( $ex instanceof MWException || $ex instanceof RuntimeException ) {
+                                       // there's no provsion in the schema for an attribute that will let
+                                       // the user know this element was unavailable due to error; an empty
+                                       // tag is the best we can do
+                                       $out .= "      " . Xml::element( 'text' ) . "\n";
+                                       wfLogWarning( 'failed to load content for revid ' . $row->rev_id . "\n" );
+                               } else {
+                                       throw $ex;
+                               }
+                       }
+               } elseif ( isset( $row->rev_text_id ) ) {
+                       // Stub output for pre-MCR schema
+                       // TODO: MCR: rev_text_id only exists in the pre-MCR schema. Remove this when
+                       // we drop support for the old schema.
                        $out .= "      " . Xml::element( 'text',
                                [ 'id' => $row->rev_text_id, 'bytes' => intval( $row->rev_len ) ],
                                "" ) . "\n";
+               } else {
+                       // Backwards-compatible stub output for MCR aware schema
+                       // TODO: MCR: emit content addresses instead of text ids, see T174031, T199121
+                       $rev = $this->getRevisionStore()->newRevisionFromRow( $row, 0, $this->currentTitle );
+                       $slot = $rev->getSlot( 'main' );
+
+                       // Note that this is currently the ONLY reason we have a BlobStore here at all.
+                       // When removing this line, check whether the BlobStore has become unused.
+                       $textId = $this->getBlobStore()->getTextIdFromAddress( $slot->getAddress() );
+                       $out .= "      " . Xml::element( 'text',
+                                       [ 'id' => $textId, 'bytes' => intval( $slot->getSize() ) ],
+                                       "" ) . "\n";
                }
 
                if ( isset( $row->rev_sha1 )
index de7d1a4..9cf8e15 100644 (file)
@@ -197,7 +197,7 @@ class ExternalStore {
                                        $msg = 'read only';
                                } else {
                                        $url = $store->store( $path, $data );
-                                       if ( strlen( $url ) ) {
+                                       if ( $url !== false ) {
                                                return $url; // a store accepted the write; done!
                                        }
                                        $msg = 'operation failed';
index 1bc2edc..30c742d 100644 (file)
@@ -67,7 +67,7 @@ class ExternalStoreMwstore extends ExternalStoreMedium {
                $blobs = [];
                foreach ( $pathsByBackend as $backendName => $paths ) {
                        $be = FileBackendGroup::singleton()->get( $backendName );
-                       $blobs = $blobs + $be->getFileContentsMulti( [ 'srcs' => $paths ] );
+                       $blobs += $be->getFileContentsMulti( [ 'srcs' => $paths ] );
                }
 
                return $blobs;
index cbf9bff..a5860e2 100644 (file)
@@ -178,9 +178,15 @@ class FileBackendGroup {
 
                $config = $this->backends[$name]['config'];
                $config['class'] = $class;
-               $config += [ // set defaults
+               if ( isset( $config['domainId'] ) ) {
+                       $domain = $config['domainId'];
+               } else {
                        // @FIXME: this does not include the domain for b/c but it ideally should
-                       'wikiId' => wfWikiID(), // e.g. "my_wiki-en_"
+                       $domain = $config['wikiId'] ?? wfWikiID();
+               }
+               // Set default parameter values
+               $config += [
+                       'domainId' => $domain, // e.g. "my_wiki-en_"
                        'mimeCallback' => [ $this, 'guessMimeInternal' ],
                        'obResetFunc' => 'wfResetOutputBuffers',
                        'streamMimeFunc' => [ StreamFile::class, 'contentTypeFromPath' ],
@@ -189,10 +195,12 @@ class FileBackendGroup {
                        'wanCache' => MediaWikiServices::getInstance()->getMainWANObjectCache(),
                        'srvCache' => ObjectCache::getLocalServerInstance( 'hash' ),
                        'logger' => LoggerFactory::getInstance( 'FileOperation' ),
-                       'profiler' => Profiler::instance()
+                       'profiler' => function ( $section ) {
+                               return Profiler::instance()->scopedProfileIn( $section );
+                       }
                ];
                $config['lockManager'] =
-                       LockManagerGroup::singleton( $config['wikiId'] )->get( $config['lockManager'] );
+                       LockManagerGroup::singleton( $domain )->get( $config['lockManager'] );
                $config['fileJournal'] = isset( $config['fileJournal'] )
                        ? FileJournal::factory( $config['fileJournal'], $name )
                        : FileJournal::factory( [ 'class' => NullFileJournal::class ], $name );
index 3dc9f18..17cf8f0 100644 (file)
@@ -32,19 +32,19 @@ use Wikimedia\Rdbms\DBError;
 class DBFileJournal extends FileJournal {
        /** @var IDatabase */
        protected $dbw;
-
-       protected $wiki = false; // string; wiki DB name
+       /** @var string */
+       protected $domain;
 
        /**
         * Construct a new instance from configuration.
         *
         * @param array $config Includes:
-        *     'wiki' : wiki name to use for LoadBalancer
+        *   domain: database domain ID of the wiki
         */
        protected function __construct( array $config ) {
                parent::__construct( $config );
 
-               $this->wiki = $config['wiki'];
+               $this->domain = $config['domain'] ?? $config['wiki']; // b/c
        }
 
        /**
@@ -184,7 +184,7 @@ class DBFileJournal extends FileJournal {
                if ( !$this->dbw ) {
                        // Get a separate connection in autocommit mode
                        $lb = MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->newMainLB();
-                       $this->dbw = $lb->getConnection( DB_MASTER, [], $this->wiki );
+                       $this->dbw = $lb->getConnection( DB_MASTER, [], $this->domain );
                        $this->dbw->clearFlag( DBO_TRX );
                }
 
index aa955d0..43f6010 100644 (file)
@@ -129,6 +129,7 @@ class LockManagerGroup {
                        }
                        $config['logger'] = LoggerFactory::getInstance( 'LockManager' );
 
+                       // @phan-suppress-next-line PhanTypeInstantiateAbstract
                        $this->managers[$name]['instance'] = new $class( $config );
                }
 
index b445487..962cfd9 100644 (file)
@@ -54,7 +54,7 @@ class FileBackendDBRepoWrapper extends FileBackend {
                /** @var FileBackend $backend */
                $backend = $config['backend'];
                $config['name'] = $backend->getName();
-               $config['wikiId'] = $backend->getWikiId();
+               $config['domainId'] = $backend->getDomainId();
                parent::__construct( $config );
                $this->backend = $config['backend'];
                $this->repoName = $config['repoName'];
index 9e4b6df..346ec8e 100644 (file)
@@ -348,14 +348,11 @@ class ForeignAPIRepo extends FileRepo {
                if ( !$knownThumbUrls ) {
                        /* No knownThumbUrls for this file */
                        $knownThumbUrls = [];
-               } else {
-                       if ( isset( $knownThumbUrls[$sizekey] ) ) {
-                               wfDebug( __METHOD__ . ': Got thumburl from local cache: ' .
-                                       "{$knownThumbUrls[$sizekey]} \n" );
+               } elseif ( isset( $knownThumbUrls[$sizekey] ) ) {
+                       wfDebug( __METHOD__ . ': Got thumburl from local cache: ' .
+                               "{$knownThumbUrls[$sizekey]} \n" );
 
-                               return $knownThumbUrls[$sizekey];
-                       }
-                       /* This size is not yet known */
+                       return $knownThumbUrls[$sizekey];
                }
 
                $metadata = null;
index 923484a..7d4f4df 100644 (file)
@@ -29,6 +29,7 @@ use MediaWiki\MediaWikiServices;
  * @ingroup FileAbstraction
  */
 
+// @phan-file-suppress PhanTypeMissingReturn false positives
 /**
  * Implements some public methods and some protected utility functions which
  * are required by multiple child classes. Contains stub functionality for
@@ -207,7 +208,7 @@ abstract class File implements IDBAccessObject {
                if ( !is_callable( $function ) ) {
                        return null;
                } else {
-                       $this->$name = call_user_func( $function );
+                       $this->$name = $function();
 
                        return $this->$name;
                }
@@ -633,20 +634,15 @@ abstract class File implements IDBAccessObject {
                        // one would not expect it to be animated
                        // so true.
                        return true;
-               } else {
-                       if ( $this->allowInlineDisplay()
-                               && $handler->isAnimatedImage( $this )
-                               && !$handler->canAnimateThumbnail( $this )
-                       ) {
-                               // Image is animated, but thumbnail isn't.
-                               // This is unexpected to the user.
-                               return false;
-                       } else {
-                               // Image is not animated, so one would
-                               // not expect thumb to be
-                               return true;
-                       }
                }
+
+               return !$this->allowInlineDisplay()
+                       // Image is not animated, so one would
+                       // not expect thumb to be
+                       || !$handler->isAnimatedImage( $this )
+                       // Image is animated, but thumbnail isn't.
+                       // This is unexpected to the user.
+                       || $handler->canAnimateThumbnail( $this );
        }
 
        /**
index aff0e3f..ab8ef2f 100644 (file)
@@ -154,7 +154,7 @@ class ForeignAPIFile extends File {
 
        /**
         * @param int $page
-        * @return int|number
+        * @return int
         */
        public function getWidth( $page = 1 ) {
                return isset( $this->mInfo['width'] ) ? intval( $this->mInfo['width'] ) : 0;
@@ -184,11 +184,7 @@ class ForeignAPIFile extends File {
         *   null on error
         */
        public function getExtendedMetadata() {
-               if ( isset( $this->mInfo['extmetadata'] ) ) {
-                       return $this->mInfo['extmetadata'];
-               }
-
-               return null;
+               return $this->mInfo['extmetadata'] ?? null;
        }
 
        /**
@@ -318,16 +314,15 @@ class ForeignAPIFile extends File {
         * @return null|string
         */
        function getThumbPath( $suffix = '' ) {
-               if ( $this->repo->canCacheThumbs() ) {
-                       $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
-                       if ( $suffix ) {
-                               $path = $path . $suffix . '/';
-                       }
-
-                       return $path;
-               } else {
+               if ( !$this->repo->canCacheThumbs() ) {
                        return null;
                }
+
+               $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
+               if ( $suffix ) {
+                       $path .= $suffix . '/';
+               }
+               return $path;
        }
 
        /**
index 1869967..3438a63 100644 (file)
@@ -24,6 +24,7 @@
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\DBUnexpectedError;
 
+// @phan-file-suppress PhanTypeMissingReturn false positives
 /**
  * Foreign file with an accessible MediaWiki database
  *
index 789d7c5..aa04fae 100644 (file)
@@ -634,7 +634,6 @@ class LocalFile extends File {
                }
 
                $this->fileExists = true;
-               $this->maybeUpgradeRow();
        }
 
        /**
@@ -659,7 +658,7 @@ class LocalFile extends File {
        /**
         * Upgrade a row if it needs it
         */
-       function maybeUpgradeRow() {
+       protected function maybeUpgradeRow() {
                global $wgUpdateCompatibleMetadata;
 
                if ( wfReadOnly() || $this->upgrading ) {
@@ -797,11 +796,14 @@ class LocalFile extends File {
        /** isVisible inherited */
 
        /**
+        * Checks if this file exists in its parent repo, as referenced by its
+        * virtual URL.
+        *
         * @return bool
         */
        function isMissing() {
                if ( $this->missing === null ) {
-                       list( $fileExists ) = $this->repo->fileExists( $this->getVirtualUrl() );
+                       $fileExists = $this->repo->fileExists( $this->getVirtualUrl() );
                        $this->missing = !$fileExists;
                }
 
@@ -1028,6 +1030,7 @@ class LocalFile extends File {
         */
        function purgeCache( $options = [] ) {
                // Refresh metadata cache
+               $this->maybeUpgradeRow();
                $this->purgeMetadataCache();
 
                // Delete thumbnails
@@ -1303,12 +1306,13 @@ class LocalFile extends File {
         *   (This doesn't check $user's permissions.)
         * @param bool $createNullRevision Set to false to avoid creation of a null revision on file
         *   upload, see T193621
+        * @param bool $revert If this file upload is a revert
         * @return Status On success, the value member contains the
         *     archive name, or an empty string if it was a new file.
         */
        function upload( $src, $comment, $pageText, $flags = 0, $props = false,
                $timestamp = false, $user = null, $tags = [],
-               $createNullRevision = true
+               $createNullRevision = true, $revert = false
        ) {
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
                        return $this->readOnlyFatalStatus();
@@ -1366,7 +1370,8 @@ class LocalFile extends File {
                                $timestamp,
                                $user,
                                $tags,
-                               $createNullRevision
+                               $createNullRevision,
+                               $revert
                        );
                        if ( !$uploadStatus->isOK() ) {
                                if ( $uploadStatus->hasMessage( 'filenotfound' ) ) {
@@ -1425,11 +1430,12 @@ class LocalFile extends File {
         * @param string[] $tags
         * @param bool $createNullRevision Set to false to avoid creation of a null revision on file
         *   upload, see T193621
+        * @param bool $revert If this file upload is a revert
         * @return Status
         */
        function recordUpload2(
                $oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null, $tags = [],
-               $createNullRevision = true
+               $createNullRevision = true, $revert = false
        ) {
                global $wgActorTableSchemaMigrationStage;
 
@@ -1602,8 +1608,16 @@ class LocalFile extends File {
                $wikiPage = new WikiFilePage( $descTitle );
                $wikiPage->setFile( $this );
 
+               // Determine log action. If reupload is done by reverting, use a special log_action.
+               if ( $revert === true ) {
+                       $logAction = 'revert';
+               } elseif ( $reupload === true ) {
+                       $logAction = 'overwrite';
+               } else {
+                       $logAction = 'upload';
+               }
                // Add the log entry...
-               $logEntry = new ManualLogEntry( 'upload', $reupload ? 'overwrite' : 'upload' );
+               $logEntry = new ManualLogEntry( 'upload', $logAction );
                $logEntry->setTimestamp( $this->timestamp );
                $logEntry->setPerformer( $user );
                $logEntry->setComment( $comment );
@@ -1827,8 +1841,13 @@ class LocalFile extends File {
 
                $this->lock();
 
-               $archiveName = wfTimestamp( TS_MW ) . '!' . $this->getName();
-               $archiveRel = $this->getArchiveRel( $archiveName );
+               if ( $this->isOld() ) {
+                       $archiveRel = $dstRel;
+                       $archiveName = basename( $archiveRel );
+               } else {
+                       $archiveName = wfTimestamp( TS_MW ) . '!' . $this->getName();
+                       $archiveRel = $this->getArchiveRel( $archiveName );
+               }
 
                if ( $repo->hasSha1Storage() ) {
                        $sha1 = FileRepo::isVirtualUrl( $srcPath )
index 23ff304..3cdbfc2 100644 (file)
@@ -418,10 +418,10 @@ class OldLocalFile extends LocalFile {
                $dstRel = $this->getArchiveRel( $archiveName );
                $status = $this->publishTo( $srcPath, $dstRel );
 
-               if ( $status->isGood() ) {
-                       if ( !$this->recordOldUpload( $srcPath, $archiveName, $timestamp, $comment, $user ) ) {
-                               $status->fatal( 'filenotfound', $srcPath );
-                       }
+               if ( $status->isGood() &&
+                       !$this->recordOldUpload( $srcPath, $archiveName, $timestamp, $comment, $user )
+               ) {
+                       $status->fatal( 'filenotfound', $srcPath );
                }
 
                $this->unlock();
diff --git a/includes/gallery/PackedHoverImageGallery.php b/includes/gallery/PackedHoverImageGallery.php
new file mode 100644 (file)
index 0000000..2e1ef7d
--- /dev/null
@@ -0,0 +1,28 @@
+<?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
+ */
+
+/**
+ * Same as Packed except different CSS is applied to make the
+ * caption only show up on hover. If a touch screen is detected,
+ * falls back to PackedHoverGallery. Degrades gracefully for
+ * screen readers.
+ */
+class PackedHoverImageGallery extends PackedOverlayImageGallery {
+}
index 0a5a457..4c72f87 100644 (file)
@@ -53,12 +53,3 @@ class PackedOverlayImageGallery extends PackedImageGallery {
                        . "\n\t\t\t</div></div>";
        }
 }
-
-/**
- * Same as Packed except different CSS is applied to make the
- * caption only show up on hover. If a touch screen is detected,
- * falls back to PackedHoverGallery. Degrades gracefully for
- * screen readers.
- */
-class PackedHoverImageGallery extends PackedOverlayImageGallery {
-}
index 5ede631..9de7eb8 100644 (file)
@@ -72,11 +72,9 @@ class TraditionalImageGallery extends ImageGalleryBase {
                $lang = $this->getRenderLang();
                # Output each image...
                foreach ( $this->mImages as $pair ) {
+                       // "text" means "caption" here
                        /** @var Title $nt */
-                       $nt = $pair[0];
-                       $text = $pair[1]; # "text" means "caption" here
-                       $alt = $pair[2];
-                       $link = $pair[3];
+                       list( $nt, $text, $alt, $link ) = $pair;
 
                        $descQuery = false;
                        if ( $nt->getNamespace() === NS_FILE ) {
diff --git a/includes/historyblob/ConcatenatedGzipHistoryBlob.php b/includes/historyblob/ConcatenatedGzipHistoryBlob.php
new file mode 100644 (file)
index 0000000..f6ca2f5
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Efficient concatenated text storage.
+ *
+ * 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
+ */
+
+/**
+ * Concatenated gzip (CGZ) storage
+ * Improves compression ratio by concatenating like objects before gzipping
+ */
+class ConcatenatedGzipHistoryBlob implements HistoryBlob {
+       public $mVersion = 0, $mCompressed = false, $mItems = [], $mDefaultHash = '';
+       public $mSize = 0;
+       public $mMaxSize = 10000000;
+       public $mMaxCount = 100;
+
+       public function __construct() {
+               if ( !function_exists( 'gzdeflate' ) ) {
+                       throw new MWException( "Need zlib support to read or write this "
+                               . "kind of history object (ConcatenatedGzipHistoryBlob)\n" );
+               }
+       }
+
+       /**
+        * @param string $text
+        * @return string
+        */
+       public function addItem( $text ) {
+               $this->uncompress();
+               $hash = md5( $text );
+               if ( !isset( $this->mItems[$hash] ) ) {
+                       $this->mItems[$hash] = $text;
+                       $this->mSize += strlen( $text );
+               }
+               return $hash;
+       }
+
+       /**
+        * @param string $hash
+        * @return array|bool
+        */
+       public function getItem( $hash ) {
+               $this->uncompress();
+               if ( array_key_exists( $hash, $this->mItems ) ) {
+                       return $this->mItems[$hash];
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * @param string $text
+        * @return void
+        */
+       public function setText( $text ) {
+               $this->uncompress();
+               $this->mDefaultHash = $this->addItem( $text );
+       }
+
+       /**
+        * @return array|bool
+        */
+       public function getText() {
+               $this->uncompress();
+               return $this->getItem( $this->mDefaultHash );
+       }
+
+       /**
+        * Remove an item
+        *
+        * @param string $hash
+        */
+       public function removeItem( $hash ) {
+               $this->mSize -= strlen( $this->mItems[$hash] );
+               unset( $this->mItems[$hash] );
+       }
+
+       /**
+        * Compress the bulk data in the object
+        */
+       public function compress() {
+               if ( !$this->mCompressed ) {
+                       $this->mItems = gzdeflate( serialize( $this->mItems ) );
+                       $this->mCompressed = true;
+               }
+       }
+
+       /**
+        * Uncompress bulk data
+        */
+       public function uncompress() {
+               if ( $this->mCompressed ) {
+                       $this->mItems = unserialize( gzinflate( $this->mItems ) );
+                       $this->mCompressed = false;
+               }
+       }
+
+       /**
+        * @return array
+        */
+       function __sleep() {
+               $this->compress();
+               return [ 'mVersion', 'mCompressed', 'mItems', 'mDefaultHash' ];
+       }
+
+       function __wakeup() {
+               $this->uncompress();
+       }
+
+       /**
+        * Helper function for compression jobs
+        * Returns true until the object is "full" and ready to be committed
+        *
+        * @return bool
+        */
+       public function isHappy() {
+               return $this->mSize < $this->mMaxSize
+                       && count( $this->mItems ) < $this->mMaxCount;
+       }
+}
+
+// phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
+if ( false ) {
+       // Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
+       // class name coerced to lowercase. We can improve efficiency by adding
+       // autoload entries for the lowercase variants of these classes (T166759).
+       // The code below is never executed, but it is picked up by the AutoloadGenerator
+       // parser, which scans for class_alias() calls.
+       class_alias( ConcatenatedGzipHistoryBlob::class, 'concatenatedgziphistoryblob' );
+}
diff --git a/includes/historyblob/DiffHistoryBlob.php b/includes/historyblob/DiffHistoryBlob.php
new file mode 100644 (file)
index 0000000..8d92fe5
--- /dev/null
@@ -0,0 +1,377 @@
+<?php
+/**
+ * Efficient concatenated text storage.
+ *
+ * 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
+ */
+
+/**
+ * Diff-based history compression
+ * Requires xdiff 1.5+ and zlib
+ */
+class DiffHistoryBlob implements HistoryBlob {
+       /** @var array Uncompressed item cache */
+       public $mItems = [];
+
+       /** @var int Total uncompressed size */
+       public $mSize = 0;
+
+       /**
+        * @var array Array of diffs. If a diff D from A to B is notated D = B - A,
+        * and Z is an empty string:
+        *
+        *              { item[map[i]] - item[map[i-1]]   where i > 0
+        *    diff[i] = {
+        *              { item[map[i]] - Z                where i = 0
+        */
+       public $mDiffs;
+
+       /** @var array The diff map, see above */
+       public $mDiffMap;
+
+       /** @var int The key for getText()
+        */
+       public $mDefaultKey;
+
+       /** @var string Compressed storage */
+       public $mCompressed;
+
+       /** @var bool True if the object is locked against further writes */
+       public $mFrozen = false;
+
+       /**
+        * @var int The maximum uncompressed size before the object becomes sad
+        * Should be less than max_allowed_packet
+        */
+       public $mMaxSize = 10000000;
+
+       /** @var int The maximum number of text items before the object becomes sad */
+       public $mMaxCount = 100;
+
+       /** Constants from xdiff.h */
+       const XDL_BDOP_INS = 1;
+       const XDL_BDOP_CPY = 2;
+       const XDL_BDOP_INSB = 3;
+
+       function __construct() {
+               if ( !function_exists( 'gzdeflate' ) ) {
+                       throw new MWException( "Need zlib support to read or write DiffHistoryBlob\n" );
+               }
+       }
+
+       /**
+        * @throws MWException
+        * @param string $text
+        * @return int
+        */
+       function addItem( $text ) {
+               if ( $this->mFrozen ) {
+                       throw new MWException( __METHOD__ . ": Cannot add more items after sleep/wakeup" );
+               }
+
+               $this->mItems[] = $text;
+               $this->mSize += strlen( $text );
+               $this->mDiffs = null; // later
+               return count( $this->mItems ) - 1;
+       }
+
+       /**
+        * @param string $key
+        * @return string
+        */
+       function getItem( $key ) {
+               return $this->mItems[$key];
+       }
+
+       /**
+        * @param string $text
+        */
+       function setText( $text ) {
+               $this->mDefaultKey = $this->addItem( $text );
+       }
+
+       /**
+        * @return string
+        */
+       function getText() {
+               return $this->getItem( $this->mDefaultKey );
+       }
+
+       /**
+        * @throws MWException
+        */
+       function compress() {
+               if ( !function_exists( 'xdiff_string_rabdiff' ) ) {
+                       throw new MWException( "Need xdiff 1.5+ support to write DiffHistoryBlob\n" );
+               }
+               if ( isset( $this->mDiffs ) ) {
+                       // Already compressed
+                       return;
+               }
+               if ( $this->mItems === [] ) {
+                       return;
+               }
+
+               // Create two diff sequences: one for main text and one for small text
+               $sequences = [
+                       'small' => [
+                               'tail' => '',
+                               'diffs' => [],
+                               'map' => [],
+                       ],
+                       'main' => [
+                               'tail' => '',
+                               'diffs' => [],
+                               'map' => [],
+                       ],
+               ];
+               $smallFactor = 0.5;
+
+               $mItemsCount = count( $this->mItems );
+               for ( $i = 0; $i < $mItemsCount; $i++ ) {
+                       $text = $this->mItems[$i];
+                       if ( $i == 0 ) {
+                               $seqName = 'main';
+                       } else {
+                               $mainTail = $sequences['main']['tail'];
+                               if ( strlen( $text ) < strlen( $mainTail ) * $smallFactor ) {
+                                       $seqName = 'small';
+                               } else {
+                                       $seqName = 'main';
+                               }
+                       }
+                       $seq =& $sequences[$seqName];
+                       $tail = $seq['tail'];
+                       $diff = $this->diff( $tail, $text );
+                       $seq['diffs'][] = $diff;
+                       $seq['map'][] = $i;
+                       $seq['tail'] = $text;
+               }
+               unset( $seq ); // unlink dangerous alias
+
+               // Knit the sequences together
+               $tail = '';
+               $this->mDiffs = [];
+               $this->mDiffMap = [];
+               foreach ( $sequences as $seq ) {
+                       if ( $seq['diffs'] === [] ) {
+                               continue;
+                       }
+                       if ( $tail === '' ) {
+                               $this->mDiffs[] = $seq['diffs'][0];
+                       } else {
+                               $head = $this->patch( '', $seq['diffs'][0] );
+                               $this->mDiffs[] = $this->diff( $tail, $head );
+                       }
+                       $this->mDiffMap[] = $seq['map'][0];
+                       $diffsCount = count( $seq['diffs'] );
+                       for ( $i = 1; $i < $diffsCount; $i++ ) {
+                               $this->mDiffs[] = $seq['diffs'][$i];
+                               $this->mDiffMap[] = $seq['map'][$i];
+                       }
+                       $tail = $seq['tail'];
+               }
+       }
+
+       /**
+        * @param string $t1
+        * @param string $t2
+        * @return string
+        */
+       function diff( $t1, $t2 ) {
+               # Need to do a null concatenation with warnings off, due to bugs in the current version of xdiff
+               # "String is not zero-terminated"
+               Wikimedia\suppressWarnings();
+               $diff = xdiff_string_rabdiff( $t1, $t2 ) . '';
+               Wikimedia\restoreWarnings();
+               return $diff;
+       }
+
+       /**
+        * @param string $base
+        * @param string $diff
+        * @return bool|string
+        */
+       function patch( $base, $diff ) {
+               if ( function_exists( 'xdiff_string_bpatch' ) ) {
+                       Wikimedia\suppressWarnings();
+                       $text = xdiff_string_bpatch( $base, $diff ) . '';
+                       Wikimedia\restoreWarnings();
+                       return $text;
+               }
+
+               # Pure PHP implementation
+
+               $header = unpack( 'Vofp/Vcsize', substr( $diff, 0, 8 ) );
+
+               # Check the checksum if hash extension is available
+               $ofp = $this->xdiffAdler32( $base );
+               if ( $ofp !== false && $ofp !== substr( $diff, 0, 4 ) ) {
+                       wfDebug( __METHOD__ . ": incorrect base checksum\n" );
+                       return false;
+               }
+               if ( $header['csize'] != strlen( $base ) ) {
+                       wfDebug( __METHOD__ . ": incorrect base length\n" );
+                       return false;
+               }
+
+               $p = 8;
+               $out = '';
+               while ( $p < strlen( $diff ) ) {
+                       $x = unpack( 'Cop', substr( $diff, $p, 1 ) );
+                       $op = $x['op'];
+                       ++$p;
+                       switch ( $op ) {
+                               case self::XDL_BDOP_INS:
+                                       $x = unpack( 'Csize', substr( $diff, $p, 1 ) );
+                                       $p++;
+                                       $out .= substr( $diff, $p, $x['size'] );
+                                       $p += $x['size'];
+                                       break;
+                               case self::XDL_BDOP_INSB:
+                                       $x = unpack( 'Vcsize', substr( $diff, $p, 4 ) );
+                                       $p += 4;
+                                       $out .= substr( $diff, $p, $x['csize'] );
+                                       $p += $x['csize'];
+                                       break;
+                               case self::XDL_BDOP_CPY:
+                                       $x = unpack( 'Voff/Vcsize', substr( $diff, $p, 8 ) );
+                                       $p += 8;
+                                       $out .= substr( $base, $x['off'], $x['csize'] );
+                                       break;
+                               default:
+                                       wfDebug( __METHOD__ . ": invalid op\n" );
+                                       return false;
+                       }
+               }
+               return $out;
+       }
+
+       /**
+        * Compute a binary "Adler-32" checksum as defined by LibXDiff, i.e. with
+        * 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
+        */
+       function xdiffAdler32( $s ) {
+               if ( !function_exists( 'hash' ) ) {
+                       return false;
+               }
+
+               static $init;
+               if ( $init === null ) {
+                       $init = str_repeat( "\xf0", 205 ) . "\xee" . str_repeat( "\xf0", 67 ) . "\x02";
+               }
+
+               // The real Adler-32 checksum of $init is zero, so it initialises the
+               // state to zero, as it is at the start of LibXDiff's checksum
+               // algorithm. Appending the subject string then simulates LibXDiff.
+               return strrev( hash( 'adler32', $init . $s, true ) );
+       }
+
+       function uncompress() {
+               if ( !$this->mDiffs ) {
+                       return;
+               }
+               $tail = '';
+               $mDiffsCount = count( $this->mDiffs );
+               for ( $diffKey = 0; $diffKey < $mDiffsCount; $diffKey++ ) {
+                       $textKey = $this->mDiffMap[$diffKey];
+                       $text = $this->patch( $tail, $this->mDiffs[$diffKey] );
+                       $this->mItems[$textKey] = $text;
+                       $tail = $text;
+               }
+       }
+
+       /**
+        * @return array
+        */
+       function __sleep() {
+               $this->compress();
+               if ( $this->mItems === [] ) {
+                       $info = false;
+               } else {
+                       // Take forward differences to improve the compression ratio for sequences
+                       $map = '';
+                       $prev = 0;
+                       foreach ( $this->mDiffMap as $i ) {
+                               if ( $map !== '' ) {
+                                       $map .= ',';
+                               }
+                               $map .= $i - $prev;
+                               $prev = $i;
+                       }
+                       $info = [
+                               'diffs' => $this->mDiffs,
+                               'map' => $map
+                       ];
+               }
+               if ( isset( $this->mDefaultKey ) ) {
+                       $info['default'] = $this->mDefaultKey;
+               }
+               $this->mCompressed = gzdeflate( serialize( $info ) );
+               return [ 'mCompressed' ];
+       }
+
+       function __wakeup() {
+               // addItem() doesn't work if mItems is partially filled from mDiffs
+               $this->mFrozen = true;
+               $info = unserialize( gzinflate( $this->mCompressed ) );
+               unset( $this->mCompressed );
+
+               if ( !$info ) {
+                       // Empty object
+                       return;
+               }
+
+               if ( isset( $info['default'] ) ) {
+                       $this->mDefaultKey = $info['default'];
+               }
+               $this->mDiffs = $info['diffs'];
+               if ( isset( $info['base'] ) ) {
+                       // Old format
+                       $this->mDiffMap = range( 0, count( $this->mDiffs ) - 1 );
+                       array_unshift( $this->mDiffs,
+                               pack( 'VVCV', 0, 0, self::XDL_BDOP_INSB, strlen( $info['base'] ) ) .
+                               $info['base'] );
+               } else {
+                       // New format
+                       $map = explode( ',', $info['map'] );
+                       $cur = 0;
+                       $this->mDiffMap = [];
+                       foreach ( $map as $i ) {
+                               $cur += $i;
+                               $this->mDiffMap[] = $cur;
+                       }
+               }
+               $this->uncompress();
+       }
+
+       /**
+        * Helper function for compression jobs
+        * Returns true until the object is "full" and ready to be committed
+        *
+        * @return bool
+        */
+       function isHappy() {
+               return $this->mSize < $this->mMaxSize
+                       && count( $this->mItems ) < $this->mMaxCount;
+       }
+
+}
diff --git a/includes/historyblob/HistoryBlob.php b/includes/historyblob/HistoryBlob.php
new file mode 100644 (file)
index 0000000..36c7c8f
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Efficient concatenated text storage.
+ *
+ * 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
+ */
+
+/**
+ * Base class for general text storage via the "object" flag in old_flags, or
+ * two-part external storage URLs. Used for represent efficient concatenated
+ * storage, and migration-related pointer objects.
+ */
+interface HistoryBlob {
+       /**
+        * Adds an item of text, returns a stub object which points to the item.
+        * You must call setLocation() on the stub object before storing it to the
+        * database
+        *
+        * @param string $text
+        *
+        * @return string The key for getItem()
+        */
+       function addItem( $text );
+
+       /**
+        * Get item by key, or false if the key is not present
+        *
+        * @param string $key
+        *
+        * @return string|bool
+        */
+       function getItem( $key );
+
+       /**
+        * Set the "default text"
+        * This concept is an odd property of the current DB schema, whereby each text item has a revision
+        * associated with it. The default text is the text of the associated revision. There may, however,
+        * be other revisions in the same object.
+        *
+        * Default text is not required for two-part external storage URLs.
+        *
+        * @param string $text
+        */
+       function setText( $text );
+
+       /**
+        * Get default text. This is called from Revision::getRevisionText()
+        *
+        * @return string
+        */
+       function getText();
+}
diff --git a/includes/historyblob/HistoryBlobCurStub.php b/includes/historyblob/HistoryBlobCurStub.php
new file mode 100644 (file)
index 0000000..8858c8d
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Efficient concatenated text storage.
+ *
+ * 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
+ */
+
+/**
+ * To speed up conversion from 1.4 to 1.5 schema, text rows can refer to the
+ * leftover cur table as the backend. This avoids expensively copying hundreds
+ * of megabytes of data during the conversion downtime.
+ *
+ * Serialized HistoryBlobCurStub objects will be inserted into the text table
+ * on conversion if $wgLegacySchemaConversion is set to true.
+ */
+class HistoryBlobCurStub {
+       /** @var int */
+       public $mCurId;
+
+       /**
+        * @param int $curid The cur_id pointed to
+        */
+       function __construct( $curid = 0 ) {
+               $this->mCurId = $curid;
+       }
+
+       /**
+        * Sets the location (cur_id) of the main object to which this object
+        * points
+        *
+        * @param int $id
+        */
+       function setLocation( $id ) {
+               $this->mCurId = $id;
+       }
+
+       /**
+        * @return string|bool
+        */
+       function getText() {
+               $dbr = wfGetDB( DB_REPLICA );
+               $row = $dbr->selectRow( 'cur', [ 'cur_text' ], [ 'cur_id' => $this->mCurId ] );
+               if ( !$row ) {
+                       return false;
+               }
+               return $row->cur_text;
+       }
+}
+
+// phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
+if ( false ) {
+       // Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
+       // class name coerced to lowercase. We can improve efficiency by adding
+       // autoload entries for the lowercase variants of these classes (T166759).
+       // The code below is never executed, but it is picked up by the AutoloadGenerator
+       // parser, which scans for class_alias() calls.
+       class_alias( HistoryBlobCurStub::class, 'historyblobcurstub' );
+}
diff --git a/includes/historyblob/HistoryBlobStub.php b/includes/historyblob/HistoryBlobStub.php
new file mode 100644 (file)
index 0000000..4995d3b
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Efficient concatenated text storage.
+ *
+ * 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
+ */
+
+/**
+ * Pointer object for an item within a CGZ blob stored in the text table.
+ */
+class HistoryBlobStub {
+       /**
+        * @var array One-step cache variable to hold base blobs; operations that
+        * pull multiple revisions may often pull multiple times from the same
+        * blob. By keeping the last-used one open, we avoid redundant
+        * unserialization and decompression overhead.
+        */
+       protected static $blobCache = [];
+
+       /** @var int */
+       public $mOldId;
+
+       /** @var string */
+       public $mHash;
+
+       /** @var string */
+       public $mRef;
+
+       /**
+        * @param string $hash The content hash of the text
+        * @param int $oldid The old_id for the CGZ object
+        */
+       function __construct( $hash = '', $oldid = 0 ) {
+               $this->mHash = $hash;
+       }
+
+       /**
+        * Sets the location (old_id) of the main object to which this object
+        * points
+        * @param int $id
+        */
+       function setLocation( $id ) {
+               $this->mOldId = $id;
+       }
+
+       /**
+        * Sets the location (old_id) of the referring object
+        * @param string $id
+        */
+       function setReferrer( $id ) {
+               $this->mRef = $id;
+       }
+
+       /**
+        * Gets the location of the referring object
+        * @return string
+        */
+       function getReferrer() {
+               return $this->mRef;
+       }
+
+       /**
+        * @return string|false
+        */
+       function getText() {
+               if ( isset( self::$blobCache[$this->mOldId] ) ) {
+                       $obj = self::$blobCache[$this->mOldId];
+               } else {
+                       $dbr = wfGetDB( DB_REPLICA );
+                       $row = $dbr->selectRow(
+                               'text',
+                               [ 'old_flags', 'old_text' ],
+                               [ 'old_id' => $this->mOldId ]
+                       );
+
+                       if ( !$row ) {
+                               return false;
+                       }
+
+                       $flags = explode( ',', $row->old_flags );
+                       if ( in_array( 'external', $flags ) ) {
+                               $url = $row->old_text;
+                               $parts = explode( '://', $url, 2 );
+                               if ( !isset( $parts[1] ) || $parts[1] == '' ) {
+                                       return false;
+                               }
+                               $row->old_text = ExternalStore::fetchFromURL( $url );
+
+                       }
+
+                       if ( !in_array( 'object', $flags ) ) {
+                               return false;
+                       }
+
+                       if ( in_array( 'gzip', $flags ) ) {
+                               // This shouldn't happen, but a bug in the compress script
+                               // may at times gzip-compress a HistoryBlob object row.
+                               $obj = unserialize( gzinflate( $row->old_text ) );
+                       } else {
+                               $obj = unserialize( $row->old_text );
+                       }
+
+                       if ( !is_object( $obj ) ) {
+                               // Correct for old double-serialization bug.
+                               $obj = unserialize( $obj );
+                       }
+
+                       // Save this item for reference; if pulling many
+                       // items in a row we'll likely use it again.
+                       $obj->uncompress();
+                       self::$blobCache = [ $this->mOldId => $obj ];
+               }
+
+               return $obj->getItem( $this->mHash );
+       }
+
+       /**
+        * Get the content hash
+        *
+        * @return string
+        */
+       function getHash() {
+               return $this->mHash;
+       }
+}
+
+// phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
+if ( false ) {
+       // Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
+       // class name coerced to lowercase. We can improve efficiency by adding
+       // autoload entries for the lowercase variants of these classes (T166759).
+       // The code below is never executed, but it is picked up by the AutoloadGenerator
+       // parser, which scans for class_alias() calls.
+       class_alias( HistoryBlobStub::class, 'historyblobstub' );
+}
index 82cbb40..aeeb934 100644 (file)
@@ -221,6 +221,20 @@ class HTMLForm extends ContextSource {
         */
        protected $mAction = false;
 
+       /**
+        * Whether the HTML form can be collapsed
+        * @since 1.33
+        * @var bool
+        */
+       protected $mCollapsible = false;
+
+       /**
+        * Whether the HTML form IS collapsed by default
+        * @since 1.33
+        * @var bool
+        */
+       protected $mCollapsed = false;
+
        /**
         * Form attribute autocomplete. A typical value is "off". null does not set the attribute
         * @since 1.27
@@ -233,6 +247,7 @@ class HTMLForm extends ContextSource {
        protected $mButtons = [];
 
        protected $mWrapperLegend = false;
+       protected $mWrapperAttributes = [];
 
        /**
         * Salt for the edit token.
@@ -526,7 +541,6 @@ class HTMLForm extends ContextSource {
        public function tryAuthorizedSubmit() {
                $result = false;
 
-               $identOkay = false;
                if ( $this->mFormIdentifier === null ) {
                        $identOkay = true;
                } else {
@@ -605,7 +619,7 @@ class HTMLForm extends ContextSource {
                $valid = true;
                $hoistedErrors = Status::newGood();
                if ( $this->mValidationErrorMessage ) {
-                       foreach ( (array)$this->mValidationErrorMessage as $error ) {
+                       foreach ( $this->mValidationErrorMessage as $error ) {
                                $hoistedErrors->fatal( ...$error );
                        }
                } else {
@@ -700,8 +714,8 @@ class HTMLForm extends ContextSource {
        /**
         * Set a message to display on a validation error.
         *
-        * @param string|array $msg String or Array of valid inputs to wfMessage()
-        *     (so each entry can be either a String or Array)
+        * @param array $msg Array of valid inputs to wfMessage()
+        *     (so each entry must itself be an array of arguments)
         *
         * @return HTMLForm $this for chaining calls (since 1.20)
         */
@@ -1047,6 +1061,18 @@ class HTMLForm extends ContextSource {
                return '' . $this->mPre . $html . $this->mPost;
        }
 
+       /**
+        * Make the form collapsible
+        * @since 1.33
+        * @param bool $collapsed whether it should be by default
+        * @return HTMLForm $this for chaining calls (since 1.20)
+        */
+       public function setCollapsible( $collapsed = false ) {
+               $this->mCollapsible = true;
+               $this->mCollapsed = $collapsed;
+               return $this;
+       }
+
        /**
         * Get HTML attributes for the `<form>` tag.
         * @return array
@@ -1089,7 +1115,7 @@ class HTMLForm extends ContextSource {
                # Include a <fieldset> wrapper for style, if requested.
                if ( $this->mWrapperLegend !== false ) {
                        $legend = is_string( $this->mWrapperLegend ) ? $this->mWrapperLegend : false;
-                       $html = Xml::fieldset( $legend, $html );
+                       $html = Xml::fieldset( $legend, $html, $this->mWrapperAttributes );
                }
 
                return Html::rawElement(
@@ -1534,6 +1560,19 @@ class HTMLForm extends ContextSource {
                return $this;
        }
 
+       /**
+        * For internal use only. Use is discouraged, and should only be used where
+        * support for gadgets/user scripts is warranted.
+        * @param array $attributes
+        * @internal
+        * @return HTMLForm $this for chaining calls
+        */
+       public function setWrapperAttributes( $attributes ) {
+               $this->mWrapperAttributes = $attributes;
+
+               return $this;
+       }
+
        /**
         * Prompt the whole form to be wrapped in a "<fieldset>", with
         * this message as its "<legend>" element.
index 818474d..0702635 100644 (file)
@@ -77,9 +77,7 @@ abstract class HTMLFormField {
         *
         * @return Message
         */
-       public function msg() {
-               $args = func_get_args();
-
+       public function msg( ...$args ) {
                if ( $this->mParent ) {
                        return $this->mParent->msg( ...$args );
                }
@@ -586,7 +584,7 @@ abstract class HTMLFormField {
                        // It might look weird, but it'll work OK.
                        return $this->getFieldLayoutOOUI(
                                new OOUI\Widget( [ 'content' => new OOUI\HtmlSnippet( $this->getDiv( $value ) ) ] ),
-                               [ 'infusable' => false, 'align' => 'top' ]
+                               [ 'align' => 'top' ]
                        );
                }
 
index 49cbdee..22ece4c 100644 (file)
@@ -145,19 +145,21 @@ class OOUIHTMLForm extends HTMLForm {
                        [ 'class' => 'mw-htmlform-submit-buttons' ], "\n$buttons" ) . "\n";
        }
 
+       /**
+        * @inheritDoc
+        * @return OOUI\PanelLayout
+        */
        protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
                // to get a user visible effect, wrap the fieldset into a framed panel layout
                $layout = new OOUI\PanelLayout( [
                        'expanded' => false,
                        'padded' => true,
                        'framed' => true,
-                       'infusable' => false,
                ] );
 
                $layout->appendContent(
                        new OOUI\FieldsetLayout( [
                                'label' => $legend,
-                               'infusable' => false,
                                'items' => [
                                        new OOUI\Widget( [
                                                'content' => new OOUI\HtmlSnippet( $section )
@@ -279,20 +281,30 @@ class OOUIHTMLForm extends HTMLForm {
 
        public function wrapForm( $html ) {
                if ( is_string( $this->mWrapperLegend ) ) {
+                       $classes = $this->mCollapsible ? [ 'mw-collapsible' ] : [];
+                       if ( $this->mCollapsed ) {
+                               $classes[] = 'mw-collapsed';
+                       }
                        $content = new OOUI\FieldsetLayout( [
                                'label' => $this->mWrapperLegend,
-                               'items' => [
-                                       new OOUI\Widget( [
-                                               'content' => new OOUI\HtmlSnippet( $html )
-                                       ] ),
-                               ],
-                       ] );
+                               'classes' => $classes,
+                               'group' => new OOUI\StackLayout( [
+                                       'expanded' => false,
+                                       'classes' => [ 'oo-ui-fieldsetLayout-group mw-collapsible-content' ],
+                                       'items' => [
+                                               new OOUI\Widget( [
+                                                       'content' => new OOUI\HtmlSnippet( $html )
+                                               ] ),
+                                       ],
+                               ] ),
+                       ] + OOUI\Element::configFromHtmlAttributes( $this->mWrapperAttributes ) );
                } else {
                        $content = new OOUI\HtmlSnippet( $html );
                }
 
+               $classes = [ 'mw-htmlform', 'mw-htmlform-ooui' ];
                $form = new OOUI\FormLayout( $this->getFormAttributes() + [
-                       'classes' => [ 'mw-htmlform', 'mw-htmlform-ooui' ],
+                       'classes' => $classes,
                        'content' => $content,
                ] );
 
index aad9f6e..0a1024c 100644 (file)
@@ -119,7 +119,7 @@ class HTMLCheckField extends HTMLFormField {
                // Fetch the value in either one of the two following case:
                // - we have a valid submit attempt (form was just submitted)
                // - we have a value (an URL manually built by the user, or GET form with no wpFormIdentifier)
-               if ( $this->isSubmitAttempt( $request ) || $request->getVal( $this->mName ) !== null ) {
+               if ( $this->isSubmitAttempt( $request ) || $request->getCheck( $this->mName ) ) {
                        return $invert
                                ? !$request->getBool( $this->mName )
                                : $request->getBool( $this->mName );
index 7b59a1d..d1f3c44 100644 (file)
@@ -171,11 +171,20 @@ class HTMLDateTimeField extends HTMLTextField {
                        }
                }
 
-               return new MediaWiki\Widget\DateTimeInputWidget( $params );
+               if ( $this->mType === 'date' ) {
+                       $this->mParent->getOutput()->addModuleStyles( 'mediawiki.widgets.DateInputWidget.styles' );
+                       return new MediaWiki\Widget\DateInputWidget( $params );
+               } else {
+                       return new MediaWiki\Widget\DateTimeInputWidget( $params );
+               }
        }
 
        protected function getOOUIModules() {
-               return [ 'mediawiki.widgets.datetime' ];
+               if ( $this->mType === 'date' ) {
+                       return [ 'mediawiki.widgets.DateInputWidget' ];
+               } else {
+                       return [ 'mediawiki.widgets.datetime' ];
+               }
        }
 
        protected function shouldInfuseOOUI() {
index fb0ca77..5866d97 100644 (file)
@@ -25,7 +25,7 @@ class HTMLExpiryField extends HTMLFormField {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         *
         * Use whatever the relative field is as the standard HTML input.
         */
@@ -38,7 +38,7 @@ class HTMLExpiryField extends HTMLFormField {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        protected function getOOUIModules() {
                return array_merge(
@@ -50,7 +50,7 @@ class HTMLExpiryField extends HTMLFormField {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function getInputOOUI( $value ) {
                return new ExpiryInputWidget(
@@ -63,7 +63,7 @@ class HTMLExpiryField extends HTMLFormField {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function loadDataFromRequest( $request ) {
                return $this->relativeField->loadDataFromRequest( $request );
index 03e479b..93f5363 100644 (file)
@@ -59,6 +59,7 @@ class HTMLFormFieldWithButton extends HTMLFormField {
                        'type' => $this->mButtonType,
                        'label' => $this->mButtonValue,
                        'flags' => $this->mButtonFlags,
+                       'id' => $this->mButtonId,
                ] + OOUI\Element::configFromHtmlAttributes(
                        $this->getAttributes( [ 'disabled', 'tabindex' ] )
                ) );
index c0dbf50..b4aab4a 100644 (file)
@@ -22,7 +22,7 @@ class HTMLInfoField extends HTMLFormField {
        public function getDefault() {
                $default = parent::getDefault();
                if ( $default instanceof Closure ) {
-                       $default = call_user_func( $default, $this->mParams );
+                       $default = $default( $this->mParams );
                }
                return $default;
        }
index 5ad1a4d..5eab605 100644 (file)
@@ -38,13 +38,15 @@ class HTMLNamespacesMultiselectField extends HTMLSelectNamespace {
                // $value is a string, because HTMLForm fields store their values as strings
                $namespaces = explode( "\n", $value );
 
-               if ( isset( $this->mParams['max'] ) ) {
-                       if ( count( $namespaces ) > $this->mParams['max'] ) {
-                               return $this->msg( 'htmlform-int-toohigh', $this->mParams['max'] );
-                       }
+               if ( isset( $this->mParams['max'] ) && ( count( $namespaces ) > $this->mParams['max'] ) ) {
+                       return $this->msg( 'htmlform-int-toohigh', $this->mParams['max'] );
                }
 
                foreach ( $namespaces as $namespace ) {
+                       if ( $namespace < 0 ) {
+                               return $this->msg( 'htmlform-select-badoption' );
+                       }
+
                        $result = parent::validate( $namespace, $alldata );
                        if ( $result !== true ) {
                                return $result;
index 4e64e9d..f137bf1 100644 (file)
@@ -144,7 +144,7 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
        /**
         * @param WebRequest $request
         *
-        * @return array("<overall message>","<select value>","<text field value>")
+        * @return array ["<overall message>","<select value>","<text field value>"]
         */
        public function loadDataFromRequest( $request ) {
                if ( $request->getCheck( $this->mName ) ) {
index 60c63d6..56589b0 100644 (file)
@@ -131,6 +131,9 @@ class HTMLTextField extends HTMLFormField {
                                case 'url':
                                        $type = $this->mParams['type'];
                                        break;
+                               case 'textwithbutton':
+                                       $type = $this->mParams['inputtype'] ?? 'text';
+                                       break;
                        }
                }
 
index dd9f793..1eda33c 100644 (file)
@@ -66,7 +66,7 @@ class HTMLTitleTextField extends HTMLTextField {
                if ( $this->mParams['namespace'] !== false &&
                        !$title->inNamespace( $this->mParams['namespace'] )
                ) {
-                       return $this->msg( 'htmlform-title-badnamespace', $this->mParams['namespace'], $text );
+                       return $this->msg( 'htmlform-title-badnamespace', $text, $this->mParams['namespace'] );
                }
 
                if ( $this->mParams['creatable'] && !$title->canExist() ) {
index 1cfbd5f..bd1d2d3 100644 (file)
@@ -53,10 +53,8 @@ class HTMLTitlesMultiselectField extends HTMLTitleTextField {
                // $value is a string, because HTMLForm fields store their values as strings
                $titlesArray = explode( "\n", $value );
 
-               if ( isset( $this->mParams['max'] ) ) {
-                       if ( count( $titlesArray ) > $this->mParams['max'] ) {
-                               return $this->msg( 'htmlform-int-toohigh', $this->mParams['max'] );
-                       }
+               if ( isset( $this->mParams['max'] ) && ( count( $titlesArray ) > $this->mParams['max'] ) ) {
+                       return $this->msg( 'htmlform-int-toohigh', $this->mParams['max'] );
                }
 
                foreach ( $titlesArray as $title ) {
index c29f199..f0972dc 100644 (file)
@@ -132,11 +132,14 @@ class Http {
        }
 
        /**
-        * Checks that the given URI is a valid one. Hardcoding the
-        * protocols, because we only want protocols that both cURL
-        * and php support.
+        * Check that the given URI is a valid one.
         *
-        * file:// should not be allowed here for security purpose (r67684)
+        * This hardcodes a small set of protocols only, because we want to
+        * deterministically reject protocols not supported by all HTTP-transport
+        * methods.
+        *
+        * "file://" specifically must not be allowed, for security purpose
+        * (see <https://www.mediawiki.org/wiki/Special:Code/MediaWiki/r67684>).
         *
         * @todo FIXME this is wildly inaccurate and fails to actually check most stuff
         *
index a3a14d0..f155348 100644 (file)
@@ -46,7 +46,7 @@ class HttpRequestFactory {
                if ( !Http::$httpEngine ) {
                        Http::$httpEngine = 'guzzle';
                } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
-                       throw new DomainException( __METHOD__ . ': curl (https://secure.php.net/curl) is not ' .
+                       throw new DomainException( __METHOD__ . ': curl (https://www.php.net/curl) is not ' .
                           'installed, but Http::$httpEngine is set to "curl"' );
                }
 
@@ -64,7 +64,7 @@ class HttpRequestFactory {
                                        throw new DomainException( __METHOD__ . ': allow_url_fopen ' .
                                           'needs to be enabled for pure PHP http requests to ' .
                                           'work. If possible, curl should be used instead. See ' .
-                                          'https://secure.php.net/curl.'
+                                          'https://www.php.net/curl.'
                                        );
                                }
                                return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
index 30ab181..d2af8c8 100644 (file)
@@ -217,7 +217,7 @@ class PhpHttpRequest extends MWHttpRequest {
                                        break;
                                }
 
-                               if ( strlen( $buf ) ) {
+                               if ( $buf !== '' ) {
                                        call_user_func( $this->callback, $fh, $buf );
                                }
                        }
index ccacbe4..7ac895c 100644 (file)
@@ -32,7 +32,7 @@ class UploadSourceAdapter {
        /** @var array */
        public static $sourceRegistrations = [];
 
-       /** @var string */
+       /** @var ImportSource */
        private $mSource;
 
        /** @var string */
index 4d72102..466e3d8 100644 (file)
@@ -120,10 +120,7 @@ class WikiImporter {
                wfDebug( "IMPORT: $data\n" );
        }
 
-       public function notice( $msg /*, $param, ...*/ ) {
-               $params = func_get_args();
-               array_shift( $params );
-
+       public function notice( $msg, ...$params ) {
                if ( is_callable( $this->mNoticeCallback ) ) {
                        call_user_func( $this->mNoticeCallback, $msg, $params );
                } else { # No ImportReporter -> CLI
@@ -286,18 +283,16 @@ class WikiImporter {
 
                        if ( !$title || $title->isExternal() ) {
                                $status->fatal( 'import-rootpage-invalid' );
+                       } elseif ( !MWNamespace::hasSubpages( $title->getNamespace() ) ) {
+                               $displayNSText = $title->getNamespace() == NS_MAIN
+                                       ? wfMessage( 'blanknamespace' )->text()
+                                       : MediaWikiServices::getInstance()->getContentLanguage()->
+                                               getNsText( $title->getNamespace() );
+                               $status->fatal( 'import-rootpage-nosubpage', $displayNSText );
                        } else {
-                               if ( !MWNamespace::hasSubpages( $title->getNamespace() ) ) {
-                                       $displayNSText = $title->getNamespace() == NS_MAIN
-                                               ? wfMessage( 'blanknamespace' )->text()
-                                               : MediaWikiServices::getInstance()->getContentLanguage()->
-                                                       getNsText( $title->getNamespace() );
-                                       $status->fatal( 'import-rootpage-nosubpage', $displayNSText );
-                               } else {
-                                       // set namespace to 'all', so the namespace check in processTitle() can pass
-                                       $this->setTargetNamespace( null );
-                                       $this->setImportTitleFactory( new SubpageImportTitleFactory( $title ) );
-                               }
+                               // set namespace to 'all', so the namespace check in processTitle() can pass
+                               $this->setTargetNamespace( null );
+                               $this->setImportTitleFactory( new SubpageImportTitleFactory( $title ) );
                        }
                }
                return $status;
@@ -432,8 +427,7 @@ class WikiImporter {
                        }
                }
 
-               $args = func_get_args();
-               return Hooks::run( 'AfterImportPage', $args );
+               return Hooks::run( 'AfterImportPage', func_get_args() );
        }
 
        /**
@@ -488,8 +482,7 @@ class WikiImporter {
        private function pageOutCallback( $title, $foreignTitle, $revCount,
                        $sucCount, $pageInfo ) {
                if ( isset( $this->mPageOutCallback ) ) {
-                       $args = func_get_args();
-                       call_user_func_array( $this->mPageOutCallback, $args );
+                       call_user_func_array( $this->mPageOutCallback, func_get_args() );
                }
        }
 
@@ -893,6 +886,7 @@ class WikiImporter {
                                ) . " exceeds the maximum allowable size ($wgMaxArticleSize KB)" );
                }
 
+               // FIXME: process schema version 11!
                $revision = new WikiRevision( $this->config );
 
                if ( isset( $revisionInfo['id'] ) ) {
index 7267ddd..c008333 100644 (file)
@@ -200,24 +200,23 @@ class CliInstaller extends Installer {
                $this->showMessage( 'config-install-step-done' );
        }
 
-       public function showMessage( $msg /*, ... */ ) {
-               echo $this->getMessageText( func_get_args() ) . "\n";
+       public function showMessage( $msg, ...$params ) {
+               echo $this->getMessageText( $msg, $params ) . "\n";
                flush();
        }
 
-       public function showError( $msg /*, ... */ ) {
-               echo "***{$this->getMessageText( func_get_args() )}***\n";
+       public function showError( $msg, ...$params ) {
+               echo "***{$this->getMessageText( $msg, $params )}***\n";
                flush();
        }
 
        /**
+        * @param string $msg
         * @param array $params
         *
         * @return string
         */
-       protected function getMessageText( $params ) {
-               $msg = array_shift( $params );
-
+       protected function getMessageText( $msg, $params ) {
                $text = wfMessage( $msg, $params )->parse();
 
                $text = preg_replace( '/<a href="(.*?)".*?>(.*?)<\/a>/', '$2 &lt;$1&gt;', $text );
index 7a92807..b32be39 100644 (file)
@@ -20,8 +20,8 @@
  * @file
  * @ingroup Deployment
  */
-use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\IMaintainableDatabase;
 use MediaWiki\MediaWikiServices;
 
 require_once __DIR__ . '/../../maintenance/Maintenance.php';
@@ -59,7 +59,7 @@ abstract class DatabaseUpdater {
        /**
         * Handle to the database subclass
         *
-        * @var Database
+        * @var IMaintainableDatabase
         */
        protected $db;
 
@@ -110,11 +110,15 @@ abstract class DatabaseUpdater {
        protected $holdContentHandlerUseDB = true;
 
        /**
-        * @param Database &$db To perform updates on
+        * @param IMaintainableDatabase &$db To perform updates on
         * @param bool $shared Whether to perform updates on shared tables
         * @param Maintenance|null $maintenance Maintenance object which created us
         */
-       protected function __construct( Database &$db, $shared, Maintenance $maintenance = null ) {
+       protected function __construct(
+               IMaintainableDatabase &$db,
+               $shared,
+               Maintenance $maintenance = null
+       ) {
                $this->db = $db;
                $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
                $this->shared = $shared;
@@ -177,14 +181,18 @@ abstract class DatabaseUpdater {
        }
 
        /**
-        * @param Database $db
+        * @param IMaintainableDatabase $db
         * @param bool $shared
         * @param Maintenance|null $maintenance
         *
         * @throws MWException
         * @return DatabaseUpdater
         */
-       public static function newForDB( Database $db, $shared = false, Maintenance $maintenance = null ) {
+       public static function newForDB(
+               IMaintainableDatabase $db,
+               $shared = false,
+               Maintenance $maintenance = null
+       ) {
                $type = $db->getType();
                if ( in_array( $type, Installer::getDBTypes() ) ) {
                        $class = ucfirst( $type ) . 'Updater';
@@ -198,7 +206,7 @@ abstract class DatabaseUpdater {
        /**
         * Get a database connection to run updates
         *
-        * @return Database
+        * @return IMaintainableDatabase
         */
        public function getDB() {
                return $this->db;
@@ -410,9 +418,7 @@ abstract class DatabaseUpdater {
                $this->updatesSkipped = [];
 
                foreach ( $updates as $funcList ) {
-                       $func = $funcList[0];
-                       $args = $funcList[1];
-                       $origParams = $funcList[2];
+                       list( $func, $args, $origParams ) = $funcList;
                        $func( ...$args );
                        flush();
                        $this->updatesSkipped[] = $origParams;
@@ -1221,7 +1227,7 @@ abstract class DatabaseUpdater {
         */
        protected function rebuildLocalisationCache() {
                /**
-                * @var $cl RebuildLocalisationCache
+                * @var RebuildLocalisationCache $cl
                 */
                $cl = $this->maintenance->runChild(
                        RebuildLocalisationCache::class, 'rebuildLocalisationCache.php'
index 20661f2..9053f8d 100644 (file)
@@ -336,14 +336,16 @@ abstract class Installer {
         * The messages will be in wikitext format, which will be converted to an
         * output format such as HTML or text before being sent to the user.
         * @param string $msg
+        * @param mixed ...$params
         */
-       abstract public function showMessage( $msg /*, ... */ );
+       abstract public function showMessage( $msg, ...$params );
 
        /**
         * Same as showMessage(), but for displaying errors
         * @param string $msg
+        * @param mixed ...$params
         */
-       abstract public function showError( $msg /*, ... */ );
+       abstract public function showError( $msg, ...$params );
 
        /**
         * Show a message to the installing user by using a Status object
@@ -686,10 +688,10 @@ abstract class Installer {
         * @return string
         */
        public function parse( $text, $lineStart = false ) {
-               global $wgParser;
+               $parser = MediaWikiServices::getInstance()->getParser();
 
                try {
-                       $out = $wgParser->parse( $text, $this->parserTitle, $this->parserOptions, $lineStart );
+                       $out = $parser->parse( $text, $this->parserTitle, $this->parserOptions, $lineStart );
                        $html = $out->getText( [
                                'enableSectionEditLinks' => false,
                                'unwrap' => true,
@@ -866,8 +868,7 @@ abstract class Installer {
                }
 
                if ( !$caches ) {
-                       $key = 'config-no-cache-apcu';
-                       $this->showMessage( $key );
+                       $this->showMessage( 'config-no-cache-apcu' );
                }
 
                $this->setVar( '_Caches', $caches );
@@ -1184,8 +1185,8 @@ abstract class Installer {
        public function dirIsExecutable( $dir, $url ) {
                $scriptTypes = [
                        'php' => [
-                               "<?php echo 'ex' . 'ec';",
-                               "#!/var/env php\n<?php echo 'ex' . 'ec';",
+                               "<?php echo 'exec';",
+                               "#!/var/env php\n<?php echo 'exec';",
                        ],
                ];
 
@@ -1502,7 +1503,7 @@ abstract class Installer {
                $data = $registry->readFromQueue( $queue );
                $wgAutoloadClasses += $data['autoload'];
 
-               /** @suppress PhanUndeclaredVariable $wgHooks is set by DefaultSettings */
+               // @phan-suppress-next-line PhanUndeclaredVariable $wgHooks is set by DefaultSettings
                $hooksWeWant = $wgHooks['LoadExtensionSchemaUpdates'] ?? [];
 
                if ( isset( $data['globals']['wgHooks']['LoadExtensionSchemaUpdates'] ) ) {
@@ -1608,9 +1609,7 @@ abstract class Installer {
                }
                if ( $status->isOk() ) {
                        $this->showMessage(
-                               'config-install-success',
-                               $this->getVar( 'wgServer' ),
-                               $this->getVar( 'wgScriptPath' )
+                               'config-install-db-success'
                        );
                        $this->setVar( '_InstallDone', true );
                }
@@ -1633,8 +1632,7 @@ abstract class Installer {
        }
 
        /**
-        * Generate a secret value for variables using our CryptRand generator.
-        * Produce a warning if the random source was insecure.
+        * Generate a secret value for variables using a secure generator.
         *
         * @param array $keys
         * @return Status
index 6d70338..a2179c6 100644 (file)
@@ -390,7 +390,7 @@ ${serverSetting}
 
 ## Set \$wgCacheDirectory to a writable directory on the web server
 ## to make your wiki go slightly faster. The directory should not
-## be publically accessible from the web.
+## be publicly accessible from the web.
 #\$wgCacheDirectory = \"\$IP/cache\";
 
 # Site language code, should be one of the list in ./languages/data/Names.php
index e462220..6d62c43 100644 (file)
@@ -187,7 +187,7 @@ class MssqlInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
 
@@ -241,7 +241,7 @@ class MssqlInstaller extends DatabaseInstaller {
                        return;
                }
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
                $conn->selectDB( $this->getVar( 'wgDBname' ) );
index 75f3894..b8dc5ff 100644 (file)
@@ -166,6 +166,7 @@ class MssqlUpdater extends DatabaseUpdater {
                parent::applyPatch( $path, $isFullPath, $msg );
                $this->db->scrollableCursor( $prevScroll );
                $this->db->prepareStatements( $prevPrep );
+               return true;
        }
 
        /**
index e9a2d03..74924d0 100644 (file)
@@ -128,7 +128,7 @@ class MysqlInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
 
@@ -167,7 +167,7 @@ class MysqlInstaller extends DatabaseInstaller {
                        return;
                }
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
                $conn->selectDB( $this->getVar( 'wgDBname' ) );
@@ -232,7 +232,7 @@ class MysqlInstaller extends DatabaseInstaller {
                $status = $this->getConnection();
 
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
 
index 2e3fdba..c33d3dd 100644 (file)
@@ -375,6 +375,7 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'dropTable', 'valid_tag' ],
                        [ 'dropTable', 'tag_summary' ],
                        [ 'dropField', 'protected_titles', 'pt_reason', 'patch-drop-comment-fields.sql' ],
+                       [ 'modifyTable', 'job', 'patch-job-params-mediumblob.sql' ],
                ];
        }
 
index 16b47e2..21b6f39 100644 (file)
@@ -119,13 +119,13 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
 
                // Check version
                $version = $conn->getServerVersion();
-               $status = static::meetsMinimumRequirement( $conn->getServerVersion() );
+               $status = static::meetsMinimumRequirement( $version );
                if ( !$status->isOK() ) {
                        return $status;
                }
@@ -190,7 +190,7 @@ class PostgresInstaller extends DatabaseInstaller {
 
                if ( $status->isOK() ) {
                        /**
-                        * @var $conn Database
+                        * @var Database $conn
                         */
                        $conn = $status->value;
                        $conn->clearFlag( DBO_TRX );
@@ -242,7 +242,7 @@ class PostgresInstaller extends DatabaseInstaller {
                                $status = $this->openPgConnection( 'create-schema' );
                                if ( $status->isOK() ) {
                                        /**
-                                        * @var $conn Database
+                                        * @var Database $conn
                                         */
                                        $conn = $status->value;
                                        $safeRole = $conn->addIdentifierQuotes( $this->getVar( 'wgDBuser' ) );
@@ -296,7 +296,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return false;
                }
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
                $superuser = $this->getVar( '_InstallUser' );
@@ -443,11 +443,11 @@ class PostgresInstaller extends DatabaseInstaller {
                        }
                        // Recursively search each member of the group to see if the target
                        // is a member of it, up to the given maximum depth.
-                       if ( $maxDepth > 0 ) {
-                               if ( $this->isRoleMember( $conn, $targetMember, $row->member, $maxDepth - 1 ) ) {
-                                       // Found member of member
-                                       return true;
-                               }
+                       if ( $maxDepth > 0 &&
+                               $this->isRoleMember( $conn, $targetMember, $row->member, $maxDepth - 1 )
+                       ) {
+                               // Found member of member
+                               return true;
                        }
                }
 
@@ -645,7 +645,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn Database
+                * @var Database $conn
                 */
                $conn = $status->value;
 
index 75877a1..008240a 100644 (file)
@@ -839,7 +839,7 @@ END;
                if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
                        $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
 
-                       return;
+                       return true;
                }
 
                // Second requirement: the new index must be missing
@@ -853,17 +853,18 @@ END;
                                        "            $old should be manually removed if not needed anymore.\n" );
                        }
 
-                       return;
+                       return true;
                }
 
                // Third requirement: the old index must exist
                if ( !$this->db->indexExists( $table, $old, __METHOD__ ) ) {
                        $this->output( "...skipping: index $old doesn't exist.\n" );
 
-                       return;
+                       return true;
                }
 
                $this->db->query( "ALTER INDEX $old RENAME TO $new" );
+               return true;
        }
 
        protected function dropPgField( $table, $field ) {
@@ -1007,13 +1008,11 @@ END;
        public function addPgExtIndex( $table, $index, $type ) {
                if ( $this->db->indexExists( $table, $index ) ) {
                        $this->output( "...index '$index' on table '$table' already exists\n" );
+               } elseif ( preg_match( '/^\(/', $type ) ) {
+                       $this->output( "Creating index '$index' on table '$table'\n" );
+                       $this->db->query( "CREATE INDEX $index ON $table $type" );
                } else {
-                       if ( preg_match( '/^\(/', $type ) ) {
-                               $this->output( "Creating index '$index' on table '$table'\n" );
-                               $this->db->query( "CREATE INDEX $index ON $table $type" );
-                       } else {
-                               $this->applyPatch( $type, true, "Creating index '$index' on table '$table'" );
-                       }
+                       $this->applyPatch( $type, true, "Creating index '$index' on table '$table'" );
                }
        }
 
index aa95438..7d2898c 100644 (file)
@@ -33,7 +33,7 @@ use Wikimedia\Rdbms\DBConnectionError;
  */
 class SqliteInstaller extends DatabaseInstaller {
 
-       public static $minimumVersion = '3.3.7';
+       public static $minimumVersion = '3.8.0';
        protected static $notMiniumumVerisonMessage = 'config-outdated-sqlite';
 
        /**
@@ -231,6 +231,7 @@ class SqliteInstaller extends DatabaseInstaller {
                $status->merge( $this->makeStubDBFile( $dir, $db ) );
                $status->merge( $this->makeStubDBFile( $dir, "wikicache" ) );
                $status->merge( $this->makeStubDBFile( $dir, "{$db}_l10n_cache" ) );
+               $status->merge( $this->makeStubDBFile( $dir, "{$db}_jobqueue" ) );
                if ( !$status->isOK() ) {
                        return $status;
                }
@@ -283,6 +284,39 @@ EOT;
                        return Status::newFatal( 'config-sqlite-connection-error', $e->getMessage() );
                }
 
+               # Create the job queue DB
+               try {
+                       $conn = Database::factory(
+                               'sqlite', [ 'dbname' => "{$db}_jobqueue", 'dbDirectory' => $dir ] );
+                       # @todo: don't duplicate job definition, though it's very static
+                       $sql =
+<<<EOT
+       CREATE TABLE job (
+               job_id INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
+               job_cmd BLOB NOT NULL default '',
+               job_namespace INTEGER NOT NULL,
+               job_title TEXT  NOT NULL,
+               job_timestamp BLOB NULL default NULL,
+               job_params BLOB NOT NULL,
+               job_random integer  NOT NULL default 0,
+               job_attempts integer  NOT NULL default 0,
+               job_token BLOB NOT NULL default '',
+               job_token_timestamp BLOB NULL default NULL,
+               job_sha1 BLOB NOT NULL default ''
+       );
+       CREATE INDEX job_sha1 ON job (job_sha1);
+       CREATE INDEX job_cmd_token ON job (job_cmd,job_token,job_random);
+       CREATE INDEX job_cmd_token_id ON job (job_cmd,job_token,job_id);
+       CREATE INDEX job_cmd ON job (job_cmd, job_namespace, job_title, job_params);
+       CREATE INDEX job_timestamp ON job (job_timestamp);
+EOT;
+                       $conn->query( $sql );
+                       $conn->query( "PRAGMA journal_mode=WAL" ); // this is permanent
+                       $conn->close();
+               } catch ( DBConnectionError $e ) {
+                       return Status::newFatal( 'config-sqlite-connection-error', $e->getMessage() );
+               }
+
                # Open the main DB
                return $this->getConnection();
        }
@@ -298,10 +332,8 @@ EOT;
                        if ( !is_writable( $file ) ) {
                                return Status::newFatal( 'config-sqlite-readonly', $file );
                        }
-               } else {
-                       if ( file_put_contents( $file, '' ) === false ) {
-                               return Status::newFatal( 'config-sqlite-cant-create-db', $file );
-                       }
+               } elseif ( file_put_contents( $file, '' ) === false ) {
+                       return Status::newFatal( 'config-sqlite-cant-create-db', $file );
                }
 
                return Status::newGood();
@@ -340,7 +372,9 @@ EOT;
         */
        public function getLocalSettings() {
                $dir = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgSQLiteDataDir' ) );
-
+               // These tables have frequent writes and are thus split off from the main one.
+               // Since the code using these tables only uses transactions for writes then set
+               // them to using BEGIN IMMEDIATE. This avoids frequent lock errors on first write.
                return "# SQLite-specific settings
 \$wgSQLiteDataDir = \"{$dir}\";
 \$wgObjectCaches[CACHE_DB] = [
@@ -350,7 +384,9 @@ EOT;
                'type' => 'sqlite',
                'dbname' => 'wikicache',
                'tablePrefix' => '',
+               'variables' => [ 'synchronous' => 'NORMAL' ],
                'dbDirectory' => \$wgSQLiteDataDir,
+               'trxMode' => 'IMMEDIATE',
                'flags' => 0
        ]
 ];
@@ -358,8 +394,22 @@ EOT;
        'type' => 'sqlite',
        'dbname' => \"{\$wgDBname}_l10n_cache\",
        'tablePrefix' => '',
+       'variables' => [ 'synchronous' => 'NORMAL' ],
        'dbDirectory' => \$wgSQLiteDataDir,
+       'trxMode' => 'IMMEDIATE',
        'flags' => 0
+];
+\$wgJobTypeConf['default'] = [
+       'class' => 'JobQueueDB',
+       'claimTTL' => 3600,
+       'server' => [
+               'type' => 'sqlite',
+               'dbname' => \"{\$wgDBname}_jobqueue\",
+               'tablePrefix' => '',
+               'dbDirectory' => \$wgSQLiteDataDir,
+               'trxMode' => 'IMMEDIATE',
+               'flags' => 0
+       ]
 ];";
        }
 }
index cda8612..0a6be86 100644 (file)
@@ -140,9 +140,9 @@ class WebInstaller extends Installer {
                $this->request = $request;
 
                // Add parser hooks
-               global $wgParser;
-               $wgParser->setHook( 'downloadlink', [ $this, 'downloadLinkHook' ] );
-               $wgParser->setHook( 'doclink', [ $this, 'docLink' ] );
+               $parser = MediaWikiServices::getInstance()->getParser();
+               $parser->setHook( 'downloadlink', [ $this, 'downloadLinkHook' ] );
+               $parser->setHook( 'doclink', [ $this, 'docLink' ] );
        }
 
        /**
@@ -374,13 +374,14 @@ class WebInstaller extends Installer {
         * Show an error message in a box. Parameters are like wfMessage(), or
         * alternatively, pass a Message object in.
         * @param string|Message $msg
+        * @param mixed ...$params
         */
-       public function showError( $msg /*...*/ ) {
+       public function showError( $msg, ...$params ) {
                if ( !( $msg instanceof Message ) ) {
-                       $args = func_get_args();
-                       array_shift( $args );
-                       $args = array_map( 'htmlspecialchars', $args );
-                       $msg = wfMessage( $msg, $args );
+                       $msg = wfMessage(
+                               $msg,
+                               array_map( 'htmlspecialchars', $params )
+                       );
                }
                $text = $msg->useDatabase( false )->plain();
                $this->output->addHTML( $this->getErrorBox( $text ) );
@@ -675,9 +676,7 @@ class WebInstaller extends Installer {
         * @param string $msg
         * @return string
         */
-       public function getHelpBox( $msg /*, ... */ ) {
-               $args = func_get_args();
-               array_shift( $args );
+       public function getHelpBox( $msg, ...$args ) {
                $args = array_map( 'htmlspecialchars', $args );
                $text = wfMessage( $msg, $args )->useDatabase( false )->plain();
                $html = $this->parse( $text, true );
@@ -693,10 +692,10 @@ class WebInstaller extends Installer {
        /**
         * Output a help box.
         * @param string $msg Key for wfMessage()
+        * @param mixed ...$params
         */
-       public function showHelpBox( $msg /*, ... */ ) {
-               $args = func_get_args();
-               $html = $this->getHelpBox( ...$args );
+       public function showHelpBox( $msg, ...$params ) {
+               $html = $this->getHelpBox( $msg, ...$params );
                $this->output->addHTML( $html );
        }
 
@@ -705,12 +704,11 @@ class WebInstaller extends Installer {
         * Output looks like a list.
         *
         * @param string $msg
+        * @param mixed ...$params
         */
-       public function showMessage( $msg /*, ... */ ) {
-               $args = func_get_args();
-               array_shift( $args );
+       public function showMessage( $msg, ...$params ) {
                $html = '<div class="config-message">' .
-                       $this->parse( wfMessage( $msg, $args )->useDatabase( false )->plain() ) .
+                       $this->parse( wfMessage( $msg, $params )->useDatabase( false )->plain() ) .
                        "</div>\n";
                $this->output->addHTML( $html );
        }
@@ -1072,12 +1070,10 @@ class WebInstaller extends Installer {
                        if ( $value === null ) {
                                // Checkbox?
                                $this->setVar( $name, false );
+                       } elseif ( stripos( $name, 'password' ) !== false ) {
+                               $this->setPassword( $name, $value );
                        } else {
-                               if ( stripos( $name, 'password' ) !== false ) {
-                                       $this->setPassword( $name, $value );
-                               } else {
-                                       $this->setVar( $name, $value );
-                               }
+                               $this->setVar( $name, $value );
                        }
                }
 
index 456058e..9f80489 100644 (file)
@@ -59,6 +59,7 @@ class WebInstallerComplete extends WebInstallerPage {
 
                $this->parent->restoreLinkPopups();
                $this->endForm( false, false );
+               return '';
        }
 
 }
index f79d272..5241b3c 100644 (file)
@@ -32,6 +32,7 @@ abstract class WebInstallerDocument extends WebInstallerPage {
                $this->parent->output->addWikiTextAsInterface( $text );
                $this->startForm();
                $this->endForm( false );
+               return '';
        }
 
        /**
index 8314fd2..1222ac2 100644 (file)
@@ -28,10 +28,8 @@ class WebInstallerName extends WebInstallerPage {
         */
        public function execute() {
                $r = $this->parent->request;
-               if ( $r->wasPosted() ) {
-                       if ( $this->submit() ) {
-                               return 'continue';
-                       }
+               if ( $r->wasPosted() && $this->submit() ) {
+                       return 'continue';
                }
 
                $this->startForm();
index 4794712..bc25179 100644 (file)
@@ -31,10 +31,8 @@ class WebInstallerOptions extends WebInstallerPage {
                        $this->submitSkins();
                        return 'skip';
                }
-               if ( $this->parent->request->wasPosted() ) {
-                       if ( $this->submit() ) {
-                               return 'continue';
-                       }
+               if ( $this->parent->request->wasPosted() && $this->submit() ) {
+                       return 'continue';
                }
 
                $emailwrapperStyle = $this->getVar( 'wgEnableEmail' ) ? '' : 'display: none';
index a4f031c..28e8784 100644 (file)
@@ -25,10 +25,8 @@ class WebInstallerWelcome extends WebInstallerPage {
         * @return string
         */
        public function execute() {
-               if ( $this->parent->request->wasPosted() ) {
-                       if ( $this->getVar( '_Environment' ) ) {
-                               return 'continue';
-                       }
+               if ( $this->parent->request->wasPosted() && $this->getVar( '_Environment' ) ) {
+                       return 'continue';
                }
                $this->parent->output->addWikiTextAsInterface( wfMessage( 'config-welcome' )->plain() );
                $status = $this->parent->doEnvironmentChecks();
index 73a2525..989d4ba 100644 (file)
        "config-install-done": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في مجلد التثبيت الخاص بالويكي (نفس المجلد المحتوي على <code>index.php</code>). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <strong>[$2 دخول الويكي]</strong>.",
        "config-install-done-path": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في <code>$4</code> (نفس المجلد المحتوي على index.php). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <code>[$2 دخول الويكي]</strong>.",
        "config-install-success": "لقد تم تثبيت ميدياويكي بنجاح; يمكنك الآن \nزيارة <$1$2> لعرض الويكي الخاص بك; \nإذا كانت لديك أسئلة، فاطلع على قائمة الأسئلة الشائعة: \n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ>> أو استخدم أحد \nمنتديات الدعم المرتبطة بهذه الصفحة.",
+       "config-install-db-success": "تم إعداد قاعدة البيانات بنجاح",
        "config-download-localsettings": "تنزيل <code>LocalSettings.php</code>",
        "config-help": "مساعدة",
        "config-help-tooltip": "اضغط للتوسيع",
index 73929dd..9b4ff9c 100644 (file)
@@ -7,47 +7,47 @@
                        "Crucifunked"
                ]
        },
-       "config-desc": "L'instalador pa MediaWiki",
+       "config-desc": "L'instalador de MediaWiki",
        "config-title": "Instalación de MediaWiki $1",
        "config-information": "Información",
-       "config-localsettings-upgrade": "Detectose un ficheru <code>LocalSettings.php</code>.\nP'anovar esta instalación, escriba'l valor de\n<code>$wgUpgradeKey</code> nel cuadru d'abaxo.\nAlcontraralu en <code>LocalSettings.php</code>.",
-       "config-localsettings-cli-upgrade": "Deteutose un ficheru <code>LocalSettings.php</code>.\nP'anovar esta instalación, execute <code>update.php</code>",
+       "config-localsettings-upgrade": "Deteutóse un ficheru <code>LocalSettings.php</code>.\nP'anovar esta instalación, introduz el valor de <code>$wgUpgradeKey</code> na caxa d'embaxo.\nVas alcontralu en <code>LocalSettings.php</code>.",
+       "config-localsettings-cli-upgrade": "Deteutóse un ficheru <code>LocalSettings.php</code>.\nP'anovar esta instalación, executa <code>update.php</code>",
        "config-localsettings-key": "Clave d'anovamientu:",
        "config-localsettings-badkey": "La clave d'anovamientu que disti ye incorreuta.",
-       "config-upgrade-key-missing": "Deteutose una instalación esistente de MediaWiki.\nP'anovar esta instalación, ponga la llinia siguiente al final del ficheru <code>LocalSettings.php</code>:\n\n$1",
+       "config-upgrade-key-missing": "Deteutóse una instalación esistente de MediaWiki.\nP'anovar esta instalación, pon la llinia de darréu no baxero del ficheru <code>LocalSettings.php</code>:\n\n$1",
        "config-localsettings-incomplete": "Paez que'l ficheru <code>LocalSettings.php</code> esistente ta incompletu.\nLa variable $1 nun ta definida.\nCamude'l ficheru <code>LocalSettings.php</code> pa qu'esta variable quede definida y calque \"{{int:Config-continue}}\".",
        "config-localsettings-connection-error": "Alcontróse un error al conectar cola base de datos usando la configuración especificada en <code>LocalSettings.php</code>. Corrixa esta configuración y vuelva a intentalo.\n\n$1",
-       "config-session-error": "Error al aniciar sesión: $1",
+       "config-session-error": "Fallu al aniciar sesión: $1",
        "config-session-expired": "Paez que caducaron los sos datos de sesión.\nLes sesiones tan configuraes pa tener una duración de $1.\nPue incrementar esto configurando <code>session.gc_maxlifetime</code> en php.ini.\nReanicie'l procesu d'instalación.",
        "config-no-session": "¡Perdiéronse los sos datos de sesión!\nCompruebe php.ini y asegúrese de qu'en <code>session.save_path</code> ta definíu un direutoriu correutu.",
        "config-your-language": "La so llingua:",
-       "config-your-language-help": "Seleicione la llingua a emplegar nel procesu d'instalación.",
+       "config-your-language-help": "Esbilla la llingua a usar nel procesu d'instalación.",
        "config-wiki-language": "Llingua de la wiki:",
        "config-wiki-language-help": "Seleicione la llingua que s'usará preferentemente na wiki.",
        "config-back": "← Atrás",
        "config-continue": "Siguir →",
        "config-page-language": "Llingua",
-       "config-page-welcome": "¡Bienveníu a MediaWiki!",
+       "config-page-welcome": "¡Afáyate en MediaWiki!",
        "config-page-dbconnect": "Conectar cola base de datos",
        "config-page-upgrade": "Anovar instalación esistente",
        "config-page-dbsettings": "Configuración de la base de datos",
        "config-page-name": "Nome",
        "config-page-options": "Opciones",
        "config-page-install": "Instalar",
-       "config-page-complete": "¡Completo!",
+       "config-page-complete": "¡Completóse!",
        "config-page-restart": "Reaniciar la instalación",
        "config-page-readme": "Llei-me",
        "config-page-releasenotes": "Notes de la versión",
        "config-page-copying": "Copiar",
        "config-page-upgradedoc": "Anovando",
        "config-page-existingwiki": "Wiki esistente",
-       "config-help-restart": "¿Quier llimpiar tolos datos guardaos qu'escribió y reaniciar el procesu d'instalación?",
+       "config-help-restart": "¿Quies llimpiar tolos datos guardaos qu'introduxesti y reaniciar el procesu d'instalación?",
        "config-restart": "Sí, reanicialu",
        "config-welcome": "=== Comprobaciones del entornu ===\nAgora van facese unes comprobaciones básiques para ver si l'entornu ye afayadizu pa la instalación de MediaWiki.\nAlcuérdese d'incluir esta información si necesita encontu pa completar la instalación.",
        "config-copyright": "=== Drechos d'autor y condiciones d'usu ===\n\n$1\n\nEsti programa ye software llibre; puedes redistribuilu y/o camudalu baxo les condiciones de la llicencia pública xeneral GNU tal como la publica la Free Software Foundation; versión 2 o (como prefieras) cualquier versión posterior.\n\nEsti programa distribúese cola esperanza de que pueda ser útil, pero <strong>ensin garantía denguna</strong>; nin siquiera la garantía implícita de <strong>comercialidá</strong> o \n<strong>adautación a un fin determináu</strong>.\nVer la Llicencia pública xeneral GNU pa más detalles.\n\nHabríes de tener recibío <doclink href=Copying>una copia de la llicencia pública xeneral GNU</doclink> xunto con esti programa; sinón, escribi a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, o [https://www.gnu.org/copyleft/gpl.html lléila en llinia].",
        "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/gl Páxina principal de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guía del usuariu]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Guía del alministrador]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Entrugues frecuentes]\n----\n* <doclink href=Readme>Lléame</doclink>\n* <doclink href=ReleaseNotes>Notes de llanzamientu</doclink>\n* <doclink href=Copying>Copia</doclink>\n* <doclink href=UpgradeDoc>Anovamientu</doclink>",
-       "config-env-good": "Comprobóse l'entornu.\nPue instalar MediaWiki.",
-       "config-env-bad": "Comprobóse l'entornu.\nNun pue instalar MediaWiki.",
+       "config-env-good": "Comprobóse l'entornu.\nPues instalar MediaWiki.",
+       "config-env-bad": "Comprobóse l'entornu.\nNun pues instalar MediaWiki.",
        "config-env-php": "PHP $1 ta instaláu.",
        "config-env-hhvm": "HHVM $1 ta instaláu.",
        "config-unicode-using-intl": "Usando la [https://pecl.php.net/intl estensión intl PECL] pa la normalización Unicode.",
@@ -65,9 +65,9 @@
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] ta instaláu",
        "config-no-cache-apcu": "<strong>Atención:</strong> Nun pudo alcontrase [https://secure.php.net/apcu APCu] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nLa caché d'oxetos nun ta activada.",
        "config-mod-security": "<strong>Alvertencia:</strong> El to servidor web tien activáu [https://modsecurity.org/mod_security]/mod_security2 .Munches de les sos configuraciones comunes pueden causar problemes a MediaWiki o otru software que dexe a los usuarios publicar conteníu arbitrario. De ser posible, tendríes de desactivalo. Si non, consulta la  [https://modsecurity.org/documentation/ mod_security documentation] o contacta col alministrador del to servidor si atopes erros aleatorios.",
-       "config-diff3-bad": "Nun s'alcontró GNU diff3.",
+       "config-diff3-bad": "Nun s'alcontró la utilidá de comparanza de testos GNU diff3. Pues inorar esto pel momentu pero podríes tener problemes d'edición davezu.",
        "config-git": "Alcontróse'l software de control de versiones Git: <code>$1</code>.",
-       "config-git-bad": "Nun s'alcontró el software de control de versiones Git.",
+       "config-git-bad": "Nun s'alcontró el software de control de versiones Git. Pues inorar esto pel momentu. Decátate que Special:Version nun va amosase nos hashes de los unvios.",
        "config-imagemagick": "ImageMagick atopáu: <code>$1</code>.\nLa miniaturización d'imaxes habilitaráse si habilites les cargues.",
        "config-gd": "Atopóse una biblioteca de gráficos GD integrada.\nLa miniaturización d'imaxes habilitaráse si habilites les xubíes.",
        "config-no-scaling": "Nun s'atopó la biblioteca GD o ImageMagik.\nVa desactivase la miniaturización d'imaxes.",
        "config-using-32bit": "<strong>Atención:</strong> paez que'l sistema funciona con enteros de 32 bits. Esto ta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit desaconseyáu].",
        "config-db-type": "Tipu de base de datos:",
        "config-db-host": "Servidor de la base de datos:",
-       "config-db-host-help": "Si'l to servidor de base de datos ta n'otru servidor, escribe'l nome del equipu o la so dirección IP equí.\n\nSi tas utilizando alojamiento web compartíu, el to provisor tendría de date'l nome correctu del servidor na so documentación.\n\nSi vas instalar nun servidor Windows y a utilizar MySQL, l'usu de \"localhost\" como nome del servidor puede nun #funcionar. Si ye asina, intenta poner \"127.0.0.1\" como dirección IP local.\n\nSi utilices PostgreSQL, dexa esti campu vacío pa conectase al traviés d'un socket de Unix.",
+       "config-db-host-help": "Si'l sirvidor de bases de datos ta nun sirvidor diferente, introduz equí la IP o'l nome del agospiu.\n\nSi tas usando un agospiu web compartíu, el so fornidor debió especificar el nome del agospiu na so documentación.\n\nSi tas usando MySQL, usar «localhost» pue nun funcionar pal nome del sirvidor. Si non, prueba «120.0.0.1» pa la direición IP llocal.\n\nSi tas usando PostgreSQL, dexa esti campu baleru pa coneutate per una ralura d'Unix.",
        "config-db-host-oracle": "TNS de la base de datos:",
        "config-db-host-oracle-help": "Escribe un [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm nome de conexón local] válidu; un archivu tnsnames.ora ten de ser visible pa esta instalación.<br />Si tas utilizando biblioteques de veceru 10g o más recién tamién puedes utilizar el métodu de asignación de nomes [http://download.oracle.com/docs/cd/Y11882_01/network.112/y10836/naming.htm Easy Connect].",
        "config-db-wiki-settings": "Identifica esta wiki",
-       "config-db-name": "Nome de base de datos:",
+       "config-db-name": "Nome de la base de datos (ensin guiones):",
        "config-db-name-help": "Escueye un nome qu'identifique la to wiki. Nun tien de contener espacios. \nSi tas utilizando agospiamientu web compartíu, el to provisor va date un nome específicu de base de datos por que lu utilices, o bien va dexate crear bases de datos al traviés d'un panel de control.",
        "config-db-name-oracle": "Esquema de la base de datos:",
        "config-db-account-oracle-warn": "Hai tres escenarios compatibles pa la instalación de Oracle como motor de base de datos:\n\nSi desees crear una cuenta de base de datos como parte del procesu d'instalación, por favor apurre una cuenta con rol SYSDBA como cuenta de base de datos pa la instalación y especifica les credenciales que quies tener pal accesu a la web a la cuenta; d'otra miente, puedes crear manualmente la cuenta d'accesu a la web y suministrar namái esa cuenta (si tien los permisos necesarios pa crear los oxetos d'esquema) o dar dos cuentes distintos, una con privilexos de creación y otra con accesu acutáu a la web\n\nLa secuencia de comandos (script) pa crear una cuenta colos privilexos necesarios puede atopase nel direutoriu \"maintenance/oracle/\" d'esta instalación. Ten en cuenta qu'utilizar una cuenta acutada va desactivar toles capacidaes de caltenimientu cola cuenta predeterminada.",
@@ -99,7 +99,7 @@
        "config-db-account-lock": "Usar el mesmu nome d'usuariu y contraseña demientres la operación normal",
        "config-db-wiki-account": "Cuenta d'usuariu pa operar normalmente",
        "config-db-wiki-help": "Escribe'l nome d'usuariu y la contraseña que se van utilizar p'aportar a la base de datos mientres la operación normal de la wiki.\nSi esta cuenta nun esiste y la cuenta d'instalación tien permisos bastante, va crease esta cuenta d'usuariu colos mínimos permisos necesarios pa operar normalmente la wiki.",
-       "config-db-prefix": "Prefixu de tables de la base de datos:",
+       "config-db-prefix": "Prefixu de tables de la base de datos (ensin guiones):",
        "config-db-prefix-help": "Si precises compartir una base de datos ente múltiples wikis, o ente MediaWiki y otra aplicación web, puedes optar por amestar un prefixu a tolos nomes de tabla pa evitar conflictos.\nNun utilices espacios.\n\nDe normal déxase esti campu vacío.",
        "config-mysql-old": "Precísase MySQL $1 o posterior. Tienes $2.",
        "config-db-port": "Puertu de la base de datos:",
        "config-oracle-def-ts": "Espaciu de tables predetermináu:",
        "config-oracle-temp-ts": "Espaciu de tables temporal:",
        "config-type-mysql": "MariaDB, MySQL o compatible",
+       "config-type-postgres": "PostgreSQL",
+       "config-type-sqlite": "SQLite",
+       "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki ye compatible colos siguientes sistemes de bases de datos:\n\n$1\n\nSi nun atopes na llista el sistema de base de datos que tas intentando utilizar, sigue les instrucciones enllazaes enriba p'activar la compatibilidá.",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
-       "config-header-mysql": "Configuración de MariaDB/MySQL",
-       "config-header-postgres": "Configuración de PostgreSQL",
-       "config-header-sqlite": "Configuración de SQLite",
-       "config-header-oracle": "Configuración d'Oracle",
-       "config-header-mssql": "Configuración de Microsoft SQL Server",
+       "config-header-mysql": "Axustes de MariaDB/MySQL",
+       "config-header-postgres": "Axustes de PostgreSQL",
+       "config-header-sqlite": "Axustes de SQLite",
+       "config-header-oracle": "Axustes d'Oracle",
+       "config-header-mssql": "Axustes de Microsoft SQL Server",
        "config-invalid-db-type": "Triba non válida de base de datos.",
-       "config-missing-db-name": "Tienes d'introducir un valor pa «{{int:config-db-name}}».",
-       "config-missing-db-host": "Tienes d'escribir un valor pa «{{int:config-db-host}}».",
-       "config-missing-db-server-oracle": "Tienes d'escribir un valor pa «{{int:config-db-host-oracle}}».",
+       "config-missing-db-name": "Has introducir un valor pa «{{int:config-db-name}}».",
+       "config-missing-db-host": "Has introducir un valor pa «{{int:config-db-host}}».",
+       "config-missing-db-server-oracle": "Has introducir un valor pa «{{int:config-db-host-oracle}}».",
        "config-invalid-db-server-oracle": "TNS inválidu pa la base de datos «$1».\nUsa una cadena «TNS Name» o «Easy Connect» ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Métodos de nomenclatura d'Oracle]).",
        "config-invalid-db-name": "Nome inválidu de la base de datos «$1».\nUsa sólo lletres ASCII (a-z, A-Z), númberos (0-9), guiones baxos (_) y guiones (-).",
        "config-invalid-db-prefix": "Prefixu inválidu pa la base de datos «$1».\nUsa sólo lletres ASCII (a-z, A-Z), númberos (0-9), guiones baxos (_) y guiones (-).",
        "config-connection-error": "$1.\n\nComprueba'l sirvidor, el nome d'usuariu y la contraseña, y tenta nuevamente.",
        "config-invalid-schema": "Esquema inválidu «$1» pa MediaWiki.\nUsa sólo lletres ASCII (a-z, A-Z), númberos (0-9) y guiones baxos (_).",
-       "config-db-sys-create-oracle": "L'instalador sólo almite l'emplegu d'una cuenta SYSDBA pa crear una cuenta nueva.",
+       "config-db-sys-create-oracle": "L'instalador namái sofita l'usu d'una cuenta SYSDBA pa la creación d'otra cuenta nueva.",
        "config-db-sys-user-exists-oracle": "La cuenta d'usuariu «$1» yá esiste. ¡SYSDBA sólo puede utilizase pa crear una nueva cuenta!",
        "config-postgres-old": "Ríquese PostgreSQL $1 o posterior. Tienes la versión $2.",
        "config-mssql-old": "Ríquese Microsoft SQL Server $1 o posterior. Tienes la versión $2.",
        "config-db-web-create": "Crear la cuenta si nun esiste yá",
        "config-db-web-no-create-privs": "La cuenta qu'especificasti pa la instalación nun tien permisos abondo pa crear una cuenta.\nLa cuenta qu'especifiques equí yá tien d'esistir.",
        "config-mysql-engine": "Motor d'almacenamientu:",
-       "config-mysql-innodb": "InnoDB (recomendao)",
+       "config-mysql-innodb": "InnoDB (aconséyase)",
        "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Triba d'autenticación:",
        "config-mssql-sqlauth": "Autenticación de SQL Server",
        "config-admin-password-confirm": "Repiti la contraseña:",
        "config-admin-help": "Escribe equí'l nome d'usuariu que desees, como por casu \"Nel Bloggs\".\nEsti ye'l nome que vas usar pa entrar na wiki.",
        "config-admin-name-blank": "Escribe'l nome d'usuariu d'un alministrador.",
+       "config-admin-password-mismatch": "Les dos contraseñes qu'introduxesti nun concasen.",
        "config-optional-skip": "Yá toi aburríu, namái instala la wiki.",
        "config-profile-wiki": "Wiki públicu",
        "config-profile-no-anon": "Ríquese crear una cuenta",
        "config-email-user": "Activar el corréu electrónicu ente usuarios",
        "config-logo": "URL del logo:",
        "config-instantcommons": "Activar Instant Commons",
+       "config-advanced-settings": "Configuración avanzada",
        "config-extensions": "Estensiones",
-       "config-skins": "Apariencies",
+       "config-skins": "Estilos",
        "config-skins-help": "Deteutáronse les apariencies de la llista anterior nel direutoriu <code>./skins</code>. Tienes d'activar siquier una, y escoyer la predeterminada.",
        "config-skins-use-as-default": "Utilizar esta apariencia como predeterminada",
        "config-skins-missing": "Nun s'atopó nenguna apariencia; MediaWiki utilizará una apariencia de respaldu hasta qu'instales delles apariencies afayadices.",
-       "config-skins-must-enable-some": "Tienes d'escoyer polo meno una apariencia p'activar.",
+       "config-skins-must-enable-some": "Has escoyer polo menos un estilu p'activar.",
        "config-skins-must-enable-default": "L'apariencia escoyida como predeterminada tien de tar activada.",
        "config-install-step-done": "fecho",
        "config-install-step-failed": "falló",
        "config-install-interwiki": "Enllenando la tabla d'interwiki predeterminada",
        "config-install-interwiki-list": "Nun pudo lleese'l ficheru <code>interwiki.list</code>.",
        "config-download-localsettings": "Descargar <code>LocalSettings.php</code>",
-       "config-help": "Ayuda",
+       "config-help": "ayuda",
        "config-nofile": "Nun pudo atopase'l ficheru \"$1\". ¿Desaniciose?",
        "config-skins-screenshots": "$1 (imaxes de pantalla: $2)",
+       "config-skins-screenshot": "$1 ($2)",
+       "config-extensions-requires": "$1 (rique $2)",
        "config-screenshot": "imaxe de pantalla",
        "mainpagetext": "<strong>Instalóse MediaWiki.</strong>",
        "mainpagedocfooter": "Consulta la [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guía del usuariu] pa saber cómo usar el software wiki.\n\n== Primeros pasos ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Llista de les opciones de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ EMF de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de llanzamientos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Llocaliza MediaWiki na to llingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Depriende como combatir la puxarra na to wiki]"
index 0e83199..ecc7211 100644 (file)
        "config-install-done": "<strong>Віншуем!</strong>\nВы ўсталявалі MediaWiki.\n\nПраграма ўсталяваньня стварыла файл <code>LocalSettings.php</code>.\nЁн утрымлівае ўсе Вашыя налады.\n\nВам неабходна загрузіць яго і захаваць у карэнную дырэкторыю Вашай вікі (у тую ж самую дырэкторыю, дзе знаходзіцца index.php). Загрузка павінна пачацца аўтаматычна.\n\nКалі загрузка не пачалася, ці Вы яе адмянілі, Вы можаце перазапусьціць яе націснуўшы на спасылку ніжэй:\n\n$3\n\n<strong>Заўвага</strong>: калі Вы гэтага ня зробіце зараз, то створаны файл ня будзе даступны Вам потым, калі Вы выйдзеце з праграмы ўсталяваньня безь яго загрузкі.\n\nКалі Вы гэта зробіце, Вы можаце <strong>[$2 ўвайсьці ў Вашую вікі]</strong>.",
        "config-install-done-path": "<strong>Віншуем!</strong>\nВы ўсталявалі MediaWiki.\n\nПраграма ўсталёўкі стварыла файл <code>LocalSettings.php</code>. Ён утрымлівае ўсе вашыя налады.\n\nВам трэба спампаваць яго і пакласьці ў <code>$4</code>. Спампоўка павінна пачацца аўтаматычна.\n\nКалі спампоўка не пачалася або вы адмянілі яе, вы можаце пачаць яе наноў, калі націсьніце на наступную спасылку:\n\n$3\n\n<strong>Заўвага:</strong> Калі вы ня зробіце гэта зараз, то створаны файл ня будзе даступны вам па выхадзе з праграмы безь яго спампоўкі.\n\nКалі вы зробіце гэта, вы можаце <strong>[$2 ўвайсьці ў вашую вікі]</strong>.",
        "config-install-success": "MediaWiki была пасьпяхова ўсталяваная. Цяпер вы можаце наведаць <$1$2>, каб пабачыць вашую вікі. Калі вы маеце пытаньні, сьпярша паглядзіце сьпіс адказаў на частыя пытаньні: <https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> ці скарыстайцеся адным з форумаў падтрымкі, пазначаных на гэтай старонцы.",
+       "config-install-db-success": "База зьвестак была пасьпяхова наладжаная",
        "config-download-localsettings": "Загрузіць <code>LocalSettings.php</code>",
        "config-help": "дапамога",
        "config-help-tooltip": "націсьніце, каб разгарнуць",
index 7fb9851..21d7cbb 100644 (file)
@@ -28,7 +28,7 @@
        "config-wiki-language": "Език на уикито:",
        "config-wiki-language-help": "Избор на език, на който ще е основното съдържание на уикито.",
        "config-back": "← Връщане",
-       "config-continue": "Ð\9fÑ\80одÑ\8aлжаване →",
+       "config-continue": "Ð\9dапÑ\80ед →",
        "config-page-language": "Език",
        "config-page-welcome": "Добре дошли в МедияУики!",
        "config-page-dbconnect": "Свързване с базата от данни",
@@ -68,9 +68,9 @@
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] е инсталиран",
        "config-no-cache-apcu": "<strong>Внимание:</strong> [https://secure.php.net/apcu APCu] и [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] не могат да бъдат открити.\nКеширането на обекти не е активирано.",
        "config-mod-security": "<strong>Предупреждение:</strong> [https://modsecurity.org/ mod_security]/mod_security2 е включено на вашия уеб сървър. Много от обичайните му конфигурации пораждат проблеми с МедияУики и друг софтуер, който позволява публикуване на произволно съдържание.\nАко е възможно, моля изключете го. В противен случай се обърнете към [https://modsecurity.org/documentation/ документацията на mod_security] или се свържете с поддръжката на хостинга си, ако се сблъскате със случайни грешки.",
-       "config-diff3-bad": "Ð\9dе Ðµ Ð½Ð°Ð¼ÐµÑ\80ен Ñ\81Ñ\80авниÑ\82елÑ\8fÑ\82 Ð·Ð° Ñ\82екÑ\81Ñ\82 Ð\93Ð\9dУ Ñ\80азл3 (GNU diff3). Ð\97аÑ\81ега Ñ\82ова Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð³Ð¾ Ð¸Ð³Ð½Ð¾Ñ\80иÑ\80аÑ\82е, Ð½Ð¾ Ð·Ð°Ñ\82ова ÐºÐ¾Ð½Ñ\84ликÑ\82иÑ\82е Ð½Ð° Ñ\80едакÑ\86ииÑ\82е Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð·Ð°Ñ\87еÑ\81Ñ\82аÑ\82.",
+       "config-diff3-bad": "Ð\98нÑ\81Ñ\82Ñ\80Ñ\83менÑ\82Ñ\8aÑ\82 Ð·Ð° Ñ\81Ñ\80авнÑ\8fване Ð½Ð° Ñ\82екÑ\81Ñ\82 GNU diff3 Ð½Ðµ Ð±ÐµÑ\88е Ð½Ð°Ð¼ÐµÑ\80ен. Ð\9cожеÑ\82е Ð´Ð° Ð¸Ð³Ð½Ð¾Ñ\80иÑ\80аÑ\82е Ñ\82ова Ð·Ð° Ñ\81ега, Ð½Ð¾ ÐºÐ¾Ð½Ñ\84ликÑ\82иÑ\82е Ð¿Ñ\80и Ñ\80едакÑ\82иÑ\80ане Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aдаÑ\82 Ð¿Ð¾-Ñ\87еÑ\81Ñ\82и.",
        "config-git": "Налична е системата за контрол на версиите Git: <code>$1</code>.",
-       "config-git-bad": "Не е намерен софтуер за контрол на версиите Git.",
+       "config-git-bad": "Не е намерен софтуер за контрол на версиите Git. Може да игнорирате това. Забележете, че Специални:Версия няма да покаже хешове на къмит.",
        "config-imagemagick": "Открит е ImageMagick: <code>$1</code>.\nПреоразмеряването на картинки ще бъде включено ако качването на файлове бъде разрешено.",
        "config-gd": "Открита е вградена графичната библиотека GD.\nАко качването на файлове бъде включено, ще бъде включена възможността за преоразмеряване на картинки.",
        "config-no-scaling": "Не са открити библиотеките GD или ImageMagick.\nПреоразмеряването на картинки ще бъде изключено.",
@@ -85,9 +85,9 @@
        "config-using-32bit": "<strong>Внимание:</strong> изглежда, че системата Ви работи с 32-битови числа. Това [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit не се препоръчва].",
        "config-db-type": "Тип на базата от данни:",
        "config-db-host": "Сървър на базата от данни:",
-       "config-db-host-help": "Ако базата от данни е на друг сървър, в кутията се въвежда името на хоста или IP адреса.\n\nАко се използва споделен уеб хостинг, доставчикът на услугата би трябвало да е предоставил в документацията си коректния хост.\n\nАко инсталацията протича на Windows-сървър и се използва MySQL, използването на \"localhost\" може да е неприемливо. В такива случаи се използва \"127.0.0.1\" за локален IP адрес.\n\nПри използване на PostgreSQL, това поле се оставя празно, за свързване чрез Unix socket.",
+       "config-db-host-help": "Ако базата от данни е на друг сървър, в кутията се въвежда името на хоста или IP адреса.\n\nАко се използва споделен уеб хостинг, доставчикът на услугата би трябвало да е предоставил в документацията си коректния хост.\n\nАко се използва MySQL, използването на „localhost“ може да е неприемливо. В такива случаи се използва „127.0.0.1“ за локален IP адрес.\n\nПри използване на PostgreSQL, това поле се оставя празно, за свързване чрез Unix socket.",
        "config-db-host-oracle": "TNS на базата от данни:",
-       "config-db-host-oracle-help": "Ð\92Ñ\8aведеÑ\82е Ð²Ð°Ð»Ð¸Ð´Ð½Ð¾ [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Local Connect Name]. Ð\9dа Ð¸Ð½Ñ\81Ñ\82алаÑ\86иÑ\8fÑ\82а Ñ\82Ñ\80Ñ\8fбва Ð´Ð° Ð±Ñ\8aде Ð²Ð¸Ð´Ð¸Ð¼ Ñ\84айлÑ\8aÑ\82 tnsnames.ora.<br />Ако използвате клиентска библиотека версия 10g или по-нова можете да използвате метода [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect].",
+       "config-db-host-oracle-help": "Ð\92Ñ\8aведеÑ\82е Ð²Ð°Ð»Ð¸Ð´Ð½Ð¾ [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Local Connect Name]. Ð¤Ð°Ð¹Ð»Ñ\8aÑ\82 tnsnames.ora Ñ\82Ñ\80Ñ\8fбва Ð´Ð° Ð±Ñ\8aде Ð²Ð¸Ð´Ð¸Ð¼ Ð·Ð° Ð¸Ð½Ñ\81Ñ\82алаÑ\86иÑ\8fÑ\82а.<br />Ако използвате клиентска библиотека версия 10g или по-нова можете да използвате метода [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect].",
        "config-db-wiki-settings": "Идентифициране на това уики",
        "config-db-name": "Име на базата от данни (без тирета):",
        "config-db-name-help": "Избира се име, което да идентифицира уикито.\nТо не трябва да съдържа интервали.\n\nАко се използва споделен хостинг, доставчикът на услугата би трябвало да е предоставил или име на базата от данни, която да бъде използвана, или да позволява създаването на бази от данни чрез контролния панел.",
        "config-invalid-db-server-oracle": "Невалиден TNS на базата от данни „$1“.\nИзползвайте „TNS Name“ или „Easy Connect“ ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Методи за именуване на Oracle])",
        "config-invalid-db-name": "Невалидно име на базата от данни „$1“.\nИзползват се само ASCII букви (a-z, A-Z), цифри (0-9), долни черти (_) и тирета (-).",
        "config-invalid-db-prefix": "Невалидна представка за базата от данни „$1“.\nПозволени са само ASCII букви (a-z, A-Z), цифри (0-9), долни черти (_) и тирета (-).",
-       "config-connection-error": "$1.\n\nНеобходимо е да се проверят хостът, потребителското име и паролата, след което да се опита отново.",
+       "config-connection-error": "$1.\n\nНеобходимо е да се проверят хостът, потребителското име и паролата, след което да се опита отново. Ако използвате „localhost“ като хост на базата от данни, опитайте с „127.0.0.1“ вместо него (и обратно).",
        "config-invalid-schema": "Невалидна схема за МедияУики „$1“.\nДопустими са само ASCII букви (a-z, A-Z), цифри (0-9) и долни черти (_).",
        "config-db-sys-create-oracle": "Инсталаторът поддържа само сметка SYSDBA за създаване на нова сметка.",
        "config-db-sys-user-exists-oracle": "Потребителската сметка „$1“ вече съществува. SYSDBA може да се използва само за създаване на нова сметка!",
index b618f7a..f1d06ce 100644 (file)
@@ -11,7 +11,8 @@
                        "LordMsz",
                        "Seb35",
                        "Ilimanaq29",
-                       "Dvorapa"
+                       "Dvorapa",
+                       "Patriccck"
                ]
        },
        "config-desc": "Instalační program pro MediaWiki",
        "config-missing-db-name": "Musíte zadat hodnotu pro „{{int:config-db-name}}“.",
        "config-missing-db-host": "Musíte zadat hodnotu pro „{{int:config-db-host}}“.",
        "config-missing-db-server-oracle": "Musíte zadat hodnotu pro „{{int:config-db-host-oracle}}“.",
-       "config-invalid-db-server-oracle": "Chybné databázové TNS „$1“.\nPoužívejte buď „TNS Name“ nebo „Easy Connect“ (vizte [http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle Naming Methods]).",
+       "config-invalid-db-server-oracle": "Chybné databázové TNS „$1“.\nPoužívejte buď „TNS Name“ nebo „Easy Connect“ (viz [http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle Naming Methods]).",
        "config-invalid-db-name": "Chybné jméno databáze „$1“.\nPoužívejte pouze ASCII písmena (a-z, A-Z), čísla (0-9), podtržítko (_) a spojovník (-).",
        "config-invalid-db-prefix": "Chybný databázový prefix „$1“.\nPoužívejte pouze ASCII písmena (a-z, A-Z), čísla (0-9), podtržítko (_) a spojovník (-).",
-       "config-connection-error": "$1.\n\nZkontrolujte server, uživatelské jméno a heslo a zkuste to znovu.",
+       "config-connection-error": "$1.\n\nZkontrolujte server, uživatelské jméno a heslo a zkuste to znovu. Pokud jako adresu databázového serveru používáte „localhost“, zkuste použít „127.0.0.1“ (a naopak).",
        "config-invalid-schema": "Neplatné schéma pro MediaWiki „$1“.\nPoužívejte pouze ASCII písmena (a-z, A-Z), čísla (0-9) a podtržítko (_).",
        "config-db-sys-create-oracle": "Instalátor podporuje zakládání nového účtu pouze prostřednictvím účtu SYSDBA.",
        "config-db-sys-user-exists-oracle": "Uživatelský účet „$1“ již existuje. SYSDBA lze použít pouze pro založení nového účtu!",
        "config-profile-no-anon": "Vyžadována registrace uživatelů",
        "config-profile-fishbowl": "Editace jen pro vybrané",
        "config-profile-private": "Soukromá wiki",
-       "config-profile-help": "Wiki fungují nejlépe, když je necháte editovat co největším možným počtem lidí.\nV MediaWiki můžete snadno kontrolovat poslední změny a vracet zpět libovolnou škodu způsobenou hloupými nebo zlými uživateli.\n\nMnoho lidí však zjistilo, že je MediaWiki užitečné v širokém spektru rolí a někdy není snadné všechny přesvědčit o výhodách wikizvyklostí.\nTakže si můžete vybrat.\n\nModel '''{{int:config-profile-wiki}}''' dovoluje editovat všem, aniž by se museli přihlašovat.\nNa wiki, kde je '''{{int:config-profile-no-anon}}''', se lépe řídí zodpovědnost, ale může to odradit náhodné přispěvatele.\n\nProfil '''{{int:config-profile-fishbowl}}''' umožňuje schváleným uživatelům editovat, ale veřejnost si může stránky prohlížet včetně jejich historie.\n'''{{int:config-profile-private}}''' dovoluje stránky prohlížet jen schváleným uživatelům, kteří je i mohou editovat.\n\nPo instalaci je možná komplexní konfigurace uživatelských práv; vizte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights odpovídající stránku příručky].",
+       "config-profile-help": "Wiki fungují nejlépe, když je necháte editovat co největším možným počtem lidí.\nV MediaWiki můžete snadno kontrolovat poslední změny a vracet zpět libovolnou škodu způsobenou hloupými nebo zlými uživateli.\n\nMnoho lidí však zjistilo, že je MediaWiki užitečné v širokém spektru rolí a někdy není snadné všechny přesvědčit o výhodách wikizvyklostí.\nTakže si můžete vybrat.\n\nModel '''{{int:config-profile-wiki}}''' dovoluje editovat všem, aniž by se museli přihlašovat.\nNa wiki, kde je '''{{int:config-profile-no-anon}}''', se lépe řídí zodpovědnost, ale může to odradit náhodné přispěvatele.\n\nProfil '''{{int:config-profile-fishbowl}}''' umožňuje schváleným uživatelům editovat, ale veřejnost si může stránky prohlížet včetně jejich historie.\n'''{{int:config-profile-private}}''' dovoluje stránky prohlížet jen schváleným uživatelům, kteří je i mohou editovat.\n\nPo instalaci je možná komplexní konfigurace uživatelských práv; viz [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights odpovídající stránku příručky].",
        "config-license": "Autorská práva a licence:",
        "config-license-none": "Bez patičky s licencí",
        "config-license-cc-by-sa": "Creative Commons Uveďte autora-Zachovejte licenci",
        "config-install-done": "<strong>Gratulujeme!</strong>\nNainstalovali jste MediaWiki.\n\nInstalátor vytvořil soubor <code>LocalSettings.php</code>.\nTen obsahuje veškerou vaši konfiguraci.\n\nBudete si ho muset stáhnout a uložit do základního adresáře vaší instalace wiki (do stejného adresáře jako soubor index.php). Stažení souboru se mělo spustit automaticky.\n\nPokud se vám stažení nenabídlo nebo jste ho zrušili, můžete ho spustit znovu kliknutím na následující odkaz:\n\n$3\n\n<strong>Poznámka</strong>: Pokud to neuděláte hned, tento vygenerovaný konfigurační soubor nebude později dostupný, pokud instalaci opustíte, aniž byste si ho stáhli.\n\nAž to dokončíte, můžete <strong>[$2 vstoupit do své wiki]</strong>.",
        "config-install-done-path": "<strong>Gratulujeme!</strong>\nNainstalovali jste MediaWiki.\n\nInstalátor vytvořil soubor <code>LocalSettings.php</code>.\nTen obsahuje veškerou vaši konfiguraci.\n\nBudete si ho muset stáhnout a uložit do <code>$4</code>. Stažení souboru se mělo spustit automaticky.\n\nPokud se vám stažení nenabídlo nebo jste ho zrušili, můžete ho spustit znovu kliknutím na následující odkaz:\n\n$3\n\n<strong>Poznámka:</strong> Pokud to neuděláte hned, tento vygenerovaný konfigurační soubor nebude později dostupný, pokud instalaci opustíte, aniž byste si ho stáhli.\n\nAž to dokončíte, můžete <strong>[$2 vstoupit do své wiki]</strong>.",
        "config-install-success": "MediaWiki byla úspěšně nainstalována. Nyní můžete navštívit <$1$2>, abyste si prohlédli svou novou wiki.\nPokud máte dotazy, podívejte se do našeho seznamu často kladených otázek:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> nebo použijte jedno\nz tam odkazovaných diskusních fór.",
+       "config-install-db-success": "Databáze byla úspěšně nastavena",
        "config-download-localsettings": "Stáhnout <code>LocalSettings.php</code>",
        "config-help": "nápověda",
        "config-help-tooltip": "rozbalíte kliknutím",
index 2a6aa23..c144ce7 100644 (file)
        "config-install-done": "'''Herzlichen Glückwunsch!'''\nMediaWiki wurde erfolgreich installiert.\n\nDas Installationsprogramm hat die Datei <code>LocalSettings.php</code> erzeugt.\nSie enthält alle vorgenommenen Konfigurationseinstellungen.\n\nDiese Datei muss nun heruntergeladen und anschließend in das Stammverzeichnis der MediaWiki-Installation hochgeladen werden. Dies ist dasselbe Verzeichnis, in dem sich auch die Datei <code>index.php</code> befindet. Das Herunterladen sollte inzwischen automatisch gestartet worden sein.\n\nSofern dies nicht der Fall war, oder das Herunterladen unterbrochen wurde, kann der Vorgang durch einen Klick auf den folgenden Link erneut gestartet werden:\n\n$3\n\n'''Hinweis:''' Die Konfigurationsdatei sollte jetzt unbedingt heruntergeladen werden. Sie wird nach Beenden des Installationsprogramms, nicht mehr zur Verfügung stehen.\n\nSobald alles erledigt wurde, kann auf das '''[$2 Wiki zugegriffen werden]'''. Wir wünschen viel Spaß und Erfolg mit dem Wiki.",
        "config-install-done-path": "<strong>Herzlichen Glückwunsch!</strong>\nDu hast MediaWiki installiert.\n\nDas Installationsprogramm hat eine Datei „<code>LocalSettings.php</code>“ erzeugt.\nSie enthält deine gesamte Konfiguration.\n\nDu musst sie herunterladen und unter <code>$4</code> ablegen. Der Download sollte automatisch gestartet sein.\n\nFalls der Download nicht angeboten wird oder du ihn abgebrochen hast, kannst du ihn durch Anklicken des folgenden Links neu starten:\n\n$3\n\n<strong>Hinweis:</strong> Falls du dies jetzt nicht tust, wird die erzeugte Konfigurationsdatei später nicht verfügbar sein, wenn du die Installation ohne Herunterladen verlässt.\n\nBei Fertigstellung kannst du <strong>[$2 dein Wiki aufrufen]</strong>.",
        "config-install-success": "MediaWiki wurde erfolgreich installiert. Du kannst jetzt\n<$1$2> aufrufen, um dein Wiki anzusehen.\nFalls du Fragen hast, lies unsere Liste der häufig gestellten Fragen:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> oder benutze eines der\nSupport-Foren, die auf dieser Seite verlinkt sind.",
+       "config-install-db-success": "Die Datenbank wurde erfolgreich aufgesetzt",
        "config-download-localsettings": "<code>LocalSettings.php</code> herunterladen",
        "config-help": "Hilfe",
        "config-help-tooltip": "Zum Expandieren klicken",
index c248468..4852380 100644 (file)
        "config-pcre-no-utf8": "<strong>Fatal:</strong> PHP's PCRE module seems to be compiled without PCRE_UTF8 support.\nMediaWiki requires UTF-8 support to function correctly.",
        "config-memory-raised": "PHP's <code>memory_limit</code> is $1, raised to $2.",
        "config-memory-bad": "<strong>Warning:</strong> PHP's <code>memory_limit</code> is $1.\nThis is probably too low.\nThe installation may fail!",
-       "config-apc": "[https://secure.php.net/apc APC] is installed",
-       "config-apcu": "[https://secure.php.net/apcu APCu] is installed",
+       "config-apc": "[https://www.php.net/apc APC] is installed",
+       "config-apcu": "[https://www.php.net/apcu APCu] is installed",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] is installed",
-       "config-no-cache-apcu": "<strong>Warning:</strong> Could not find [https://secure.php.net/apcu APCu] or [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObject caching is not enabled.",
+       "config-no-cache-apcu": "<strong>Warning:</strong> Could not find [https://www.php.net/apcu APCu] or [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObject caching is not enabled.",
        "config-mod-security": "<strong>Warning:</strong> Your web server has [https://modsecurity.org/ mod_security]/mod_security2 enabled. Many common configurations of this will cause problems for MediaWiki and other software that allows users to post arbitrary content.\nIf possible, this should be disabled. Otherwise, refer to [https://modsecurity.org/documentation/ mod_security documentation] or contact your host's support if you encounter random errors.",
 
        "config-diff3-bad": "GNU diff3 text comparison utility not found. You can ignore this for now, but might run into edit conflicts more frequently.",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supports the following database systems:\n\n$1\n\nIf you do not see the database system you are trying to use listed below, then follow the instructions linked above to enable support.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] is the primary target for MediaWiki and is best supported. MediaWiki also works with [{{int:version-db-mysql-url}} MySQL] and [{{int:version-db-percona-url}} Percona Server], which are MariaDB compatible. ([https://secure.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([https://secure.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([https://secure.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is a commercial enterprise database for Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] is the primary target for MediaWiki and is best supported. MediaWiki also works with [{{int:version-db-mysql-url}} MySQL] and [{{int:version-db-percona-url}} Percona Server], which are MariaDB compatible. ([https://www.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. ([https://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([https://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([https://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is a commercial enterprise database for Windows. ([https://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "MariaDB/MySQL settings",
        "config-header-postgres": "PostgreSQL settings",
        "config-header-sqlite": "SQLite settings",
        "config-license-help": "Many public wikis put all contributions under a [https://freedomdefined.org/Definition free license].\nThis helps to create a sense of community ownership and encourages long-term contribution.\nIt is not generally necessary for a private or corporate wiki.\n\nIf you want to be able to use text from Wikipedia, and you want Wikipedia to be able to accept text copied from your wiki, you should choose <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia previously used the GNU Free Documentation License.\nThe GFDL is a valid license, but it is difficult to understand.\nIt is also difficult to reuse content licensed under the GFDL.",
        "config-email-settings": "Email settings",
        "config-enable-email": "Enable outbound email",
-       "config-enable-email-help": "If you want email to work, [https://secure.php.net/manual/en/mail.configuration.php PHP's mail settings] need to be configured correctly.\nIf you do not want any email features, you can disable them here.",
+       "config-enable-email-help": "If you want email to work, [https://www.php.net/manual/en/mail.configuration.php PHP's mail settings] need to be configured correctly.\nIf you do not want any email features, you can disable them here.",
        "config-email-user": "Enable user-to-user email",
        "config-email-user-help": "Allow all users to send each other email if they have enabled it in their preferences.",
        "config-email-usertalk": "Enable user talk page notification",
        "config-install-done": "<strong>Congratulations!</strong>\nYou have installed MediaWiki.\n\nThe installer has generated a <code>LocalSettings.php</code> file.\nIt contains all your configuration.\n\nYou will need to download it and put it in the base of your wiki installation (the same directory as index.php). The download should have started automatically.\n\nIf the download was not offered, or if you cancelled it, you can restart the download by clicking the link below:\n\n$3\n\n<strong>Note:</strong> If you do not do this now, this generated configuration file will not be available to you later if you exit the installation without downloading it.\n\nWhen that has been done, you can <strong>[$2 enter your wiki]</strong>.",
        "config-install-done-path": "<strong>Congratulations!</strong>\nYou have installed MediaWiki.\n\nThe installer has generated a <code>LocalSettings.php</code> file.\nIt contains all your configuration.\n\nYou will need to download it and put it at <code>$4</code>. The download should have started automatically.\n\nIf the download was not offered, or if you cancelled it, you can restart the download by clicking the link below:\n\n$3\n\n<strong>Note:</strong> If you do not do this now, this generated configuration file will not be available to you later if you exit the installation without downloading it.\n\nWhen that has been done, you can <strong>[$2 enter your wiki]</strong>.",
        "config-install-success": "MediaWiki has been successfully installed. You can now visit <$1$2> to view your wiki.\nIf you have questions, check out our frequently asked questions list:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> or use one of the\nsupport forums linked on that page.",
+       "config-install-db-success": "Database was successfully set up",
        "config-download-localsettings": "Download <code>LocalSettings.php</code>",
        "config-help": "help",
        "config-help-tooltip": "click to expand",
index 8048a26..1942957 100644 (file)
        "config-cc-again": "Elegir otra vez...",
        "config-cc-not-chosen": "Elige la licencia Creative Commons que desees y haz clic en \"proceed\".",
        "config-advanced-settings": "Configuración avanzada",
-       "config-cache-options": "Configuración de la antememoria de objetos:",
+       "config-cache-options": "Configuración de la caché de objetos:",
        "config-cache-help": "El almacenamiento en caché de objetos se utiliza para mejorar la velocidad de MediaWiki mediante el almacenamiento en caché los datos usados más frecuentemente.\nA los sitios medianos y grandes se les recomienda que permitirlo. También es beneficioso para los sitios pequeños.",
        "config-cache-none": "Sin almacenamiento en caché (no se pierde ninguna funcionalidad, pero la velocidad puede resentirse en sitios grandes)",
-       "config-cache-accel": "Almacenamiento en antememoria de objetos PHP (APC, APCu o WinCache)",
+       "config-cache-accel": "Almacenamiento en caché de objetos PHP (APC, APCu o WinCache)",
        "config-cache-memcached": "Utilizar Memcached (necesita ser instalado y configurado aparte)",
        "config-memcached-servers": "Servidores Memcached:",
        "config-memcached-help": "Lista de direcciones IP que serán usadas por Memcached.\nDeben especificarse una por cada línea y especificar el puerto a utilizar. Por ejemplo:\n127.0.0.1:11211\n192.168.1.25:1234",
        "config-install-done": "<strong>¡Felicidades!</strong>\nHas instalado MediaWiki.\n\nEl instalador ha generado un archivo <code>LocalSettings.php</code>.\nEste contiene toda su configuración.\n\nDeberás descargarlo y ponerlo en la base de la instalación de wiki (el mismo directorio que index.php). La descarga debería haber comenzado automáticamente.\n\nSi no comenzó la descarga, o si se ha cancelado, puedes reiniciar la descarga haciendo clic en el siguiente enlace:\n\n$3\n\n<strong>Nota</strong>: si no haces esto ahora, este archivo de configuración generado no estará disponible más tarde si sales de la instalación sin descargarlo.\n\nCuando lo hayas hecho, podrás <strong>[$2 entrar en tu wiki]</strong>.",
        "config-install-done-path": "<strong>¡Felicidades!</strong>\nHas instalado MediaWiki.\n\nEl instalador ha generado un archivo <code>LocalSettings.php</code>.\nEste contiene toda su configuración.\n\nDeberás descargarlo y ponerlo en <code>$4</code>. La descarga debería haber comenzado automáticamente.\n\nSi no comenzó la descarga, o si se ha cancelado, puedes reiniciar la descarga haciendo clic en el siguiente enlace:\n\n$3\n\n<strong>Nota</strong>: si no haces esto ahora, este archivo de configuración generado no estará disponible más tarde si sales de la instalación sin descargarlo.\n\nCuando lo hayas hecho, podrás <strong>[$2 entrar en tu wiki]</strong>.",
        "config-install-success": "Se instaló MediaWiki correctamente. Ahora puedes visitar\n<$1$2> para ver el wiki.\nSi tienes dudas, echa un vistazo a la lista de preguntas frecuentes:\n<https://www.mediawiki.org/wiki/Manual:FAQ>, o bien, utiliza uno de\nlos foros de asistencia que se enumeran en esa página.",
+       "config-install-db-success": "Se configuró la base de datos correctamente",
        "config-download-localsettings": "Descargar <code>LocalSettings.php</code>",
        "config-help": "ayuda",
        "config-help-tooltip": "pulsa para ampliar",
index 3102bfb..bef363d 100644 (file)
                        "درفش کاویانی",
                        "Hamisun",
                        "Alifakoor",
-                       "Seb35"
+                       "Seb35",
+                       "Ahmad252",
+                       "FarsiNevis"
                ]
        },
-       "config-desc": "نصب کنندهٔ مدیاویکی",
+       "config-desc": "نصبکنندهٔ مدیاویکی",
        "config-title": "نصب مدیاویکی $1",
        "config-information": "اطلاعات",
        "config-localsettings-upgrade": "یک پرونده <code>LocalSettings.php</code> شناسایی شده‌است.\nبرای ارتقاء این نصب لطفاً مقدار <code>$wgUpgradeKey</code> در جعبه زیر وارد کنید.\nشما می‌توانید آن را در <code>LocalSettings.php</code> پیدا کنید.",
@@ -76,9 +78,9 @@
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] نصب شده‌است.",
        "config-no-cache-apcu": "<strong>هشدار:</strong> پیوند [https://secure.php.net/apcu APCu] یا [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] یافت نشد. ذخیره شی فعال نیست.",
        "config-mod-security": "'''هشدار:''' وب سرور شما [https://modsecurity.org/ mod_security] فعال است.اگر اشتباه پیکربندی شده‌‌ باشد،می تواند باعث ایجاد مشکلاتی برای مدیاویکی یا دیگر نرم‌افزاری شود که به کاربران اجازه می‌دهد پیام دلخواه ارسال کنند.\nبه [https://modsecurity.org/documentation/ mod_security documentation] مراجعه کنید یا اگر با خطاهای اتفاقی مواجه شدید با پشتیبانی میزبان خود در تماس باشید.",
-       "config-diff3-bad": "جÛ\8câ\80\8cاÙ\86â\80\8cÛ\8cÙ\88 Ø¯Û\8cÙ\81Û³ Ù¾Û\8cدا Ù\86Ø´د.",
+       "config-diff3-bad": "ابزار Ù\85Ù\82اÛ\8cسÙ\87 Ù\85تÙ\86 ØªÙ\81اÙ\88ت۳ Ú¯Ù\86Ù\88 Ù¾Û\8cدا Ù\86شد. Ù\85Û\8câ\80\8cتÙ\88اÙ\86Û\8cد Ù\81عÙ\84اÙ\8b Ø§Û\8cÙ\86 Ù¾Û\8cاÙ\85 Ø±Ø§ Ù\86ادÛ\8cدÙ\87 Ø¨Ú¯Û\8cرÛ\8cدØ\8c Ø§Ù\85ا Ù\85Ù\85Ú©Ù\86 Ø§Ø³Øª Ø¨Ù\87 Ø¯Ù\81عات Ø¨Û\8cشترÛ\8c Ø¯Ú\86ار ØªØ¹Ø§Ø±Ø¶ Ù\88Û\8cراÛ\8cØ´Û\8c Ø´Ù\88Û\8cد.",
        "config-git": "کنترل نسخهٔ نرم‌افزار گیت پیدا شد: <code>$1</code>.",
-       "config-git-bad": "کنترل نسخهٔ نرم‌افزار گیت پیدا نشد.",
+       "config-git-bad": "کنترل نسخهٔ نرم‌افزار گیت پیدا نشد. فعلاً می‌توانید این پیام را نادیده بگیرید. در نظر داشته باشید که ویژه:نسخه، توابع درهم‌سازی‌شده را نمایش نخواهد داد.",
        "config-imagemagick": "ایمیج‌مجیک پیدا شد: <code>$1</code>.\nاگر ارسال‌ها را فعال کنید،تصویر کوچک فعال خواهد‌شد.",
        "config-gd": "گرافیک‌های جی‌دی ساخته‌‌ شده در کتابخانه پیدا شد.\nاگر ارسال‌ها را فعال کنید تصویر کوچک فعال خواهد‌شد.",
        "config-no-scaling": "کتابخانهٔ جی‌دی یا ایمیج‌مجیک نتوانست پیدا شود.\nتصویر کوچک غیر‌فعال خواهد‌شد.",
        "config-using-32bit": "<strong>هشدار:</strong> سیستم شما به‌نظر می‌آید با اعداد صحیح ۳۲ بیت اجرا شده باشد. [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit توصیه نمی‌شود].",
        "config-db-type": "نوع پایگاه اطلاعات:",
        "config-db-host": "میزبان پایگاه اطلاعات:",
-       "config-db-host-help": "اگر سرور پایگاه اطلاعاتی شما در سرور دیگری است، نام گروه و آدرس آی‌پی را اینجا وارد کنید.\nاگر از گروه شبکهٔ اشتراک گذاری استفاده می‌کنید، تهیه‌کنندهٔ گروه‌تان باید نام گروه صحیح در اسنادومدارک را به شما بدهد.\nاگر در حال نصب یک سرور ویندوز هستید و از مای‌اس‌کیو‌ال استفاده می‌کنید، ممکن است استفاده از \"گروه داخلی\" برای نام سرور کار نکند.اگر کار نکرد، \"۱۲۷.۰.۰.۱\" را برای آدرس آی‌پی داخلی امتحان کنید.\nاگر از پستگِرِاس‌کیوال استفاده می‌کنید،برای اتصال از طریق یک سوکت یونیکس این زمینه را خالی رها کنید.",
+       "config-db-host-help": "اگر سرور پایگاه اطلاعاتی شما در سرور دیگری است، نام گروه و آدرس آی‌پی را اینجا وارد کنید.\nاگر از میزبان شبکهٔ به اشتراک گذاشته‌شده استفاده می‌کنید، تهیه‌کنندهٔ خدمات میزبانی شما باید نام میزبان صحیح در اسناد و مدارک را به شما بدهد.\nاگر از مای‌اس‌کیو‌ال استفاده می‌کنید، ممکن است استفاده از «میزبان‌محلی» برای نام سرور کار نکند.اگر کار نکرد، «۱۲۷.۰.۰.۱» را برای آدرس آی‌پی محلی امتحان کنید.\nاگر از پستگرس‌کیوال استفاده می‌کنید، برای اتصال از طریق یک سوکت یونیکس این قسمت را خالی رها کنید.",
        "config-db-host-oracle": "پایگاه اطلاعاتی تی‌ان‌اس:",
        "config-db-host-oracle-help": "یک [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Local Connect Name] معتبر وارد کنید؛ پوشهٔ tnsnames.ora باید برای این نصب نمایان باشد.<br /> اگر از کتابخانه‌های پردازشگر ۱۰جی یا جدیدتر استفاده می‌کنید،همچنین می‌توانید از روش نامبردهٔ [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect] استفاده کنید.",
        "config-db-wiki-settings": "این ویکی را شناسایی کنید.",
-       "config-db-name": "Ù\86اÙ\85 Ù¾Ø§Û\8cگاÙ\87 Ø§Ø·Ù\84اعاتÛ\8c:",
+       "config-db-name": "Ù\86اÙ\85 Ù¾Ø§Û\8cگاÙ\87 Ø¯Ø§Ø¯Ù\87 (بدÙ\88Ù\86 Ø®Ø· Ù¾Û\8cÙ\88Ù\86د):",
        "config-db-name-help": "نامی را انتخاب کنید که ویکی شما را شناسایی کند.\nنباید شامل فاصله باشد.\nاگر از گروه شبکهٔ اشتراک‌گذاری استفاده می‌کنید، تهیه‌کنندهٔ گروهتان یا باید به شما نام یک پایگاه اطلاعاتی مشخص برای استفاده بدهد یا برای ایجاد پایگاه‌های اطلاعاتی از طریق یک کنترل پنل به شما اجازه بدهد.",
        "config-db-name-oracle": "طرح کلی پایگاه اطلاعاتی:",
        "config-db-account-oracle-warn": "برای نصب برنامهٔ اوراکل به عنوان پایگاه اطلاعاتی در بخش گذشته،سه سناریو پشتیبانی شده است:\nاگر مایل به ایجاد حساب پایگاه اطلاعاتی به عنوان بخشی از روند نصب هستید، لطفاً یک حساب با نقش اس‌وای‌اس‌دی‌بی‌ای به عنوان حساب پایگاه اطلاعاتی برای نصب تهیه کنید و اعتبارنامه‌های مطلوبی را برای حساب دردسترس شبکه تعیین کنید، به عبارتی دیگر یا می‌توانید حساب دردسترس شبکه را به طور دستی ایجاد کنید و تنها آن حساب را تهیه کنید (اگر مستلزم مجوزهایی برای ایجاد موضوعات طرح کلی باشد) یا دو حساب دیگر تهیه کنید،یکی با ایجاد مزایا و یک حساب محدود برای دسترسی شبکه.\nمتنی برای ایجاد یک حساب با مزایای لازم بنویسید که می‌تواند در فهرست\"نگهداری/برنامهٔ اوراکل\" این نصب یافت شود. به یاد داشته باشید که استفاده از یک حساب محدود،همهٔ قابلیت‌های نگهداری با حساب پیش‌فرض را غیرفعال خواهد کرد.",
        "config-db-account-lock": "در طی عملیات عادی از نام کاربری و رمز عبور یکسان استفاده کنید",
        "config-db-wiki-account": "حساب کاربری برای عملیات عادی",
        "config-db-wiki-help": "نام کاربری و رمز عبوری را وارد کنید که برای اتصال به پایگاه اطلاعاتی در طی عملیات عادی ویکی استفاده خواهید‌کرد.\nاگر حساب وجود ندارد، و نصب حساب مزایای کافی را داراست، این حساب کاربر با حداقل مزایای مورد نیاز برای عمل کردن ویکی به‌وجود خواهد‌آمد.",
-       "config-db-prefix": "جدÙ\88Ù\84 Ù¾Û\8cØ´Ù\88Ù\86د Ù¾Ø§Û\8cگاÙ\87 Ø§Ø·Ù\84اعاتÛ\8c",
+       "config-db-prefix": "جدÙ\88Ù\84 Ù¾Û\8cØ´Ù\88Ù\86د Ù¾Ø§Û\8cگاÙ\87 Ø¯Ø§Ø¯Ù\87 (بدÙ\88Ù\86 Ø®Ø· Ù¾Û\8cÙ\88Ù\86د):",
        "config-db-prefix-help": "اگر نیاز دارید یک اطلاعات پایگاهی را بین چندین ویکی یا بین مدیاویکی و برنامهٔ کاربردی وب دیگری به اشتراک بگذارید،مجاز به انتخاب برای اضافه کردن یک پیشوند به همهٔ  نام‌های جدول برای جلوگیری از اختلاف‌ها هستید.\nاز فاصله‌ها استفاده نکنید.\nاغلب این زمینه خالی مانده‌است.",
        "config-mysql-old": "مای‌اس‌کیو‌ال نسخهٔ $1 و یا بالاتر نیاز است، شما نسخهٔ $2 را دارید.",
        "config-db-port": "درگاه پایگاه‌داده:",
-       "config-db-schema": "طرح کلی برای مدیاویکی:",
+       "config-db-schema": "طرح کلی برای مدیاویکی (بدون خط پیوند):",
        "config-db-schema-help": "طرح کلی اغلب بی‌نقص خواهد بود.\nاگر می‌دانید نیاز دارید که تغییرش دهید،آن را تغییر دهید.",
        "config-pg-test-error": "نمی‌توان به پایگاه اطلاعاتی '''$1''' وصل شد: $2",
        "config-sqlite-dir": "فهرست اطلاعات اس‌کیو‌لایت:",
        "config-invalid-db-server-oracle": "تی‌ان‌اس پایگاه اطلاعاتی $1 نامعتبر.\nیا از \"نام تی‌ان‌اس\" یا یک سلسله \"ارتباط آسان\" ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle Naming Methods]) استفاده کنید.",
        "config-invalid-db-name": "نام پایگاه اطلاعاتی نامعتبر \"$1\".\nفقط حروف اِی‌اس‌سی‌آی‌آی بزرگ (اِی-زدکوچک،اِی-زد بزرگ)،اعداد (۰-۹)،آندرلاین (_) و خط تیره کوتاه (-) استفاده کنید.",
        "config-invalid-db-prefix": "پیشوند پایگاه اطلاعاتی نامعتبر \"$1\".\nفقط حروف اِی‌اس‌سی‌آی‌آی بزرگ (اِی-زدکوچک،اِی-زد بزرگ)،اعداد (۰-۹)،آندرلاین (_) و خط تیره کوتاه (-) استفاده کنید.",
-       "config-connection-error": "$1.\n\nمیزبان، نام کاربری و گذرواژه را بررسی کنید و دوباره امتحان کنید.",
+       "config-connection-error": "$1.\n\nمیزبان، نام کاربری و گذرواژه را بررسی کرده و دوباره امتحان کنید. اگر از «میزبان محلی» به عنوان میزبان پایگاه داده استفاده می‌کنید، استفاده از «۱۲۷.۰.۰.۱» را امتحان کنید (یا برعکس).",
        "config-invalid-schema": "طرح‌کلی برای مدیاویکی نامعتبر \"$1\".\nفقط حروف اِی‌اس‌سی‌آی‌آی بزرگ (اِی-زدکوچک،اِی-زد بزرگ)،اعداد (۰-۹)،آندرلاین (_) و خط تیره کوتاه (-) استفاده کنید.",
        "config-db-sys-create-oracle": "نصب‌کننده تنها از استفادهٔ یک حساب اس‌وای‌اس‌دی‌بی‌اِی برای ایجاد یک حساب جدید حمایت می‌کند.",
        "config-db-sys-user-exists-oracle": "حساب کاربری \"$1\" در‌حال‌حاضر وجود دارد.تنها اس‌وای‌اس‌دی‌بی‌اِی می‌تواند برای ایجاد یک حساب جدید استفاده شود!",
        "config-sqlite-cant-create-db": "پوشه‌ٔ پایگاه اطلا‌عاتی <code>$1</code>نتوانست ایجاد شود.",
        "config-sqlite-fts3-downgrade": "پی‌اچ‌پی، پشتیبانی اف‌تی‌اس۳ کار نمی‌کند، کاهش جدول‌ها",
        "config-can-upgrade": "جدول‌های مدیاویکی در این پایگاه اطلاعاتی وجود دارند.\nبرای ارتقاء دادن آنها به مدیاویکی $1، '''ادامه''' را کلیک کنید.",
+       "config-upgrade-error": "در به‌روزرسانی جدول‌های مدیاویکی در پایگاه داده شما خطایی پیش آمد.\n\nبرای اطلاعات بیشتر به سیاهۀ بالا نگاه کنید. برای تلاش دوباره، روی <strong>ادامه</strong> کلیک کنید.",
        "config-upgrade-done": "تکمیل ارتقاء.\nاکنون شما می‌توانید [$1 start using your wiki].\nاگر می‌خواهید پوشهٔ <code>LocalSettings.php</code> را احیا کنید،دکمهٔ زیر را کلیک کنید.\nاین ''' توصیه نمی‌شود ''' مگر اینکه با ویکی خود مشکل داشته باشید.",
        "config-upgrade-done-no-regenerate": "ارتقاء کامل شد.\nاکنون شما می‌توانید [$1 start using your wiki].",
        "config-regenerate": "بازسازی LocalSettings.php ←",
        "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-install-done-path": "<strong>تبریک!</strong>\nمدیاویکی با موفقیت نصب گردید.\nبرنامه نصب‌کننده یک پرونده <code>LocalSettings.php</code> ایجاد کرده است که شامل تمام تنظیمات می‌باشد.\n\nلازم است شما آن را دریافت کرده و در <code>$4</code> قرار دهید. اِن دریافت می باِست به صورت خودکار شروع شده‌باشد.\n\nاگر دریافت شروع نشده بود و یا آن را لغو کرده اید با کلیک روی پیوند زیر می‌توانید آن را دریافت کنید:\n\n$3\n\n<strong>توجه:</strong> اگر این کار را هم اکنون انجام ندهید و بدون دریافت آن از برنامه نصب خارج شويد، این پرونده تنظیمات تولیدشده در آینده در اختیار شما قرار نخواهد داشت.\n\nوقتی که آن کار را انجام داديد، می‌توانید <strong>[$2 وارد ويکی خودتان شويد]</strong>.",
-       "config-install-success": "مدیاویکی به صورت موفقیت‌آمیز نصب شد. شما می‌توانید\nاز <$1$2> برای دیدن ویکی‌تان بازدید کنید.\nاگر پرسشی داشتید، فهرست سوال‌های متداول ما را مطالعه کنید:\n<https://www.mediawiki.org/wiki/Manual:FAQ> یا از یکی از انجمن‌های پشیبانی ما که در آن صفحه فهرست شده‌اند استفاده کنید.",
+       "config-install-success": "نصب مدیاویکی موفق بود. شما می‌توانید برای دیدن ویکی‌تان از <$1$2> بازدید کنید.\nاگر پرسشی داشتید، فهرست پرسش‌های متداول ما را مطالعه کنید:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> یا از یکی از انجمن‌های پشیبانی که در آن صفحه فهرست شده‌اند استفاده کنید.",
+       "config-install-db-success": "دادگان با موفقیت نصب شد",
        "config-download-localsettings": "دریافت <code>LocalSettings.php</code>",
        "config-help": "راهنما",
        "config-help-tooltip": "برای گسترش کلیک کنید",
        "config-nofile": "پروندهٔ «$1» یافت نشد. آیا حذف شده‌است؟",
-       "config-extension-link": "آیا می‌دانستید که ویکی شما [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensions] را پشتیبانی می‌کند؟\nشما می‌توانید [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensions by category]",
+       "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] را مرور کنید.",
        "config-skins-screenshots": "$1 (تصاویر: $2)",
        "config-extensions-requires": "$1 (نیازمند $2)",
        "config-screenshot": "تصویر",
+       "config-extension-not-found": "پرونده ثبت افزونه «$1» پیدا نشد.",
+       "config-extension-dependency": "خطای وابسته در حین نصب افزونه «$1» رخ داد: $2",
        "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 یادگیری روش‌های مقابله با هرزنگاری در ویکی]"
 }
index a134db8..cbb0312 100644 (file)
@@ -74,6 +74,7 @@
        "config-outdated-sqlite": "<strong>Varoitus:</strong> sinulla on käytössä SQLite $1, joke on vanhempi kuin vähintään vaadittava versio $2. SQLite ei ole saatavilla.",
        "config-no-fts3": "<strong>Varoitus:</strong> SQLite on koostettu ilman [//sqlite.org/fts3.html FTS3-moduulia], hakuominaisuudet eivät ole käytössä tässä taustajärjestelmässä.",
        "config-pcre-old": "<strong>Tärkeää:</strong> PCRE $1 tai uudempi versio tarvitaan.\nPHP-binäärisi on linkitetty versiolla PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Lisätietoja].",
+       "config-pcre-no-utf8": "<strong>Vakava virhe:</strong> PHP:n PCRE-moduuli näyttää olevan koottu ilman PCRE_UTF8 tukea.\nMediaWiki edellyttää UTF-8 tukea toimiakseen oikein.",
        "config-memory-raised": "PHP:n <code>memory_limit</code> on $1, nostetaan arvoon $2.",
        "config-memory-bad": "'''Varoitus:''' PHP:n <code>memory_limit</code> on $1.\nTämä on luultavasti liian alhainen.\nAsennus saattaa epäonnistua!",
        "config-apc": "[https://secure.php.net/apc APC] on asennettu",
        "config-install-done": "<strong>Onnittelut!</strong>\nOlet asentanut MediaWikin.\n\nAsennusohjelma on luonut <code>LocalSettings.php</code> -tiedoston.\nSiinä on kaikki MediaWikin asetukset.\n\nLataa tiedosto ja laita se MediaWikin asennushakemistoon (sama kuin missä on index.php). Lataamisen olisi pitänyt alkaa automaattisesti.\n\nMikäli latausta ei tarjottu tai keskeytit latauksen, käynnistä se uudestaan tästä linkistä:\n\n$3\n\n<strong>Huom:</strong> Mikäli et nyt lataa tiedostoa, luotu tiedosto ei ole saatavissa myöhemmin, jos poistut asennuksesta lataamatta sitä.\n\nKun olet laittanut tiedoston oikeaan paikkaan, voit <strong>[$2 mennä wikiisi]</strong>.",
        "config-install-done-path": "<strong>Onnittelut!</strong>\nOlet asentanut MediaWikin.\n\nAsennusohjelma on luonut <code>LocalSettings.php</code> -tiedoston.\nSiinä on kaikki MediaWikin asetukset.\n\nLataa tiedosto ja laita se sijaintiin <code>$4</code>. Lataamisen olisi pitänyt alkaa automaattisesti.\n\nMikäli latausta ei tarjottu tai keskeytit latauksen, käynnistä se uudestaan tästä linkistä:\n\n$3\n\n<strong>Huom:</strong> Mikäli et nyt lataa tiedostoa, luotu tiedosto ei ole saatavissa myöhemmin, jos poistut asennuksesta lataamatta sitä.\n\nKun olet laittanut tiedoston oikeaan paikkaan, voit <strong>[$2 mennä wikiisi]</strong>.",
        "config-install-success": "MediaWiki on asennettu onnistuneesti. Voit nyt vierailla <$1$2> katsellaksesi wikiäsi. Jos sinulla on kysyttävää, tutustu usein kysyttyjen kysymysten luetteloon: <https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> tai käytä jotakin sivulla linkitettyä tukifoorumia.",
+       "config-install-db-success": "Tietokanta asennettiin onnistuneesti",
        "config-download-localsettings": "Lataa <code>LocalSettings.php</code>",
        "config-help": "ohje",
        "config-help-tooltip": "Klikkaa laajentaaksesi",
index 79a1ebb..2c154e7 100644 (file)
@@ -90,7 +90,7 @@
        "config-apcu": "[https://secure.php.net/apcu APCu] est installé",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] est installé",
        "config-no-cache-apcu": "<strong>Attention :</strong> impossible de trouver [https://secure.php.net/apcu APCu] ou [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nLa mise en cache d’objets n’est pas activée.",
-       "config-mod-security": "<strong>Attention :</strong> votre serveur web a [https://modsecurity.org/ mod_security] activé. S’il est mal configuré, cela peut poser des problèmes à MediaWiki ou à d’autres applications qui permettent aux utilisateurs de publier un contenu quelconque. Si possible, ceci devrait être désactivé. Sinon, reportez-vous à [https://modsecurity.org/documentation/ la documentation de mod_security] ou contactez l’assistance de votre hébergeur si vous rencontrez des erreurs aléatoires.",
+       "config-mod-security": "<strong>Attention :</strong> votre serveur web a activé [https://modsecurity.org/ mod_security]/mod_security2 . Dans plusieurs configurations communes cela pose des problèmes à MediaWiki ou à d’autres applications qui permettent aux utilisateurs de publier un contenu quelconque. \nSi possible, ceci devrait être désactivé. Sinon, reportez-vous à [https://modsecurity.org/documentation/ la documentation de mod_security] ou contactez l’assistance de votre hébergeur si vous rencontrez des erreurs aléatoires.",
        "config-diff3-bad": "L’utilitaire de comparaison de texte GNU diff3 est introuvable. Vous pouvez l’ignorer pour le moment, mais cela peut provoquer des conflits de modification plus souvent.",
        "config-git": "Logiciel de contrôle de version Git trouvé : <code>$1</code>.",
        "config-git-bad": "Logiciel de contrôle de version Git non trouvé. Vous pouvez l’ignorer pour le moment. Notez que Special:Version n’affichera pas les hachages de validation.",
        "config-install-done": "<strong>Félicitations!</strong>\nVous avez installé MediaWiki.\n\nLe programme d'installation a généré un fichier <code>LocalSettings.php</code>. Il contient tous les paramètres de votre configuration.\n\nVous devrez le télécharger et le mettre à la racine de votre installation wiki (dans le même répertoire que index.php). Le téléchargement devrait démarrer automatiquement.\n\nSi le téléchargement n'a pas été proposé, ou que vous l'avez annulé, vous pouvez redémarrer le téléchargement en cliquant ce lien :\n\n$3\n\n<strong>Note :</strong> Si vous ne le faites pas maintenant, ce fichier de configuration généré ne sera pas disponible plus tard si vous quittez l'installation sans le télécharger.\n\nLorsque c'est fait, vous pouvez <strong>[$2 accéder à votre wiki]</strong> .",
        "config-install-done-path": "<strong>Félicitations !</strong>\nVous avez installé MédiaWiki.\n\nL’installeur a généré un fichier <code>LocalSettings.php</code>.\nIl contient toute votre configuration.\n\nVous devez le télécharger et le mettre dans <code>$4</code>. Le téléchargement devrait avoir démarré automatiquement.\n\nSi le téléchargement n’a pas été proposé ou si vous l’avez annulé, vous pouvez le redémarrer en cliquant sur le lien ci-dessous :\n\n$3\n\n<strong>Note :</strong> Si vous ne le faites pas maintenant, ce fichier de configuration généré ne sera plus disponible ultérieurement si vous quittez l’installation sans le télécharger.\n\nUne fois ceci fait, vous pouvez <strong>[$2 entrer dans votre wiki]</strong>.",
        "config-install-success": "MédiaWiki a été installé correctement. Vous pouvez maintenant visiter <$1$2> pour voir votre wiki.\nSi vous avez des questions, consultez notre foire aux questions :\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> ou utilisez un des\nforums de support liés sur cette page.",
+       "config-install-db-success": "La base de données a été bien installée",
        "config-download-localsettings": "Télécharger <code>LocalSettings.php</code>",
        "config-help": "aide",
        "config-help-tooltip": "cliquer pour agrandir",
index 01dc661..86cddd6 100644 (file)
        "config-sqlite-cant-create-db": "Non poteva crear le file de base de datos <code>$1</code>.",
        "config-sqlite-fts3-downgrade": "PHP non ha supporto pro FTS3. Le tabellas es retrogradate.",
        "config-can-upgrade": "Il ha tabellas MediaWiki in iste base de datos.\nPro actualisar los a MediaWiki $1, clicca super '''Continuar'''.",
+       "config-upgrade-error": "Un error ha occurrite durante le actualisation del tabellas MediaWiki in tu base de datos.\n\nPro plus information, examina le registro supra. Pro tentar lo de novo, clicca sur <strong>Continuar</strong>.",
        "config-upgrade-done": "Actualisation complete.\n\nTu pote ora [$1 comenciar a usar tu wiki].\n\nSi tu vole regenerar tu file <code>LocalSettings.php</code>, clicca super le button hic infra.\nIsto '''non es recommendate''' si tu non ha problemas con tu wiki.",
        "config-upgrade-done-no-regenerate": "Actualisation complete.\n\nTu pote ora [$1 comenciar a usar tu wiki].",
        "config-regenerate": "Regenerar LocalSettings.php →",
        "config-install-done": "<strong>Felicitationes!</strong>\nTu ha installate MediaWiki.\n\nLe installator ha generate un file <code>LocalSettings.php</code>.\nIste contine tote le configuration.\n\nEs necessari discargar lo e poner lo in le base del installation wiki (le mesme directorio que index.php).\nLe discargamento debe haber comenciate automaticamente.\n\nSi le discargamento non ha comenciate, o si illo esseva cancellate, recomencia le discargamento con un clic sur le ligamine sequente:\n\n$3\n\n<strong>Nota:</strong> Si tu non discarga iste file de configuration ora, illo non essera disponibile plus tarde.\n\nPost facer isto, tu pote <strong>[$2 entrar in tu wiki]</strong>.",
        "config-install-done-path": "<strong>Felicitationes!</strong>\nTu ha installate MediaWiki.\n\nLe installator ha generate un file <code>LocalSettings.php</code>.\nIste contine tote le configuration.\n\nEs necessari discargar lo e poner lo in <code>$4</code>.\nLe discargamento debe haber comenciate automaticamente.\n\nSi le discargamento non ha comenciate, o si illo esseva cancellate, recomencia le discargamento con un clic sur le ligamine sequente:\n\n$3\n\n<strong>Nota:</strong> Si tu non discarga iste file de configuration ora, illo non essera disponibile plus tarde.\n\nPost facer isto, tu pote <strong>[$2 entrar in tu wiki]</strong>.",
        "config-install-success": "MediaWiki ha essite installate con successo. Tu pote ora\nvisitar <$1$2> pro vider tu wiki.\nSi tu ha questiones, consulta nostre lista de questiones frequentemente ponite:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> o usa un del\nforos de supporto indicate sur ille pagina.",
+       "config-install-db-success": "Le installation del base de datos ha succedite",
        "config-download-localsettings": "Discargar <code>LocalSettings.php</code>",
        "config-help": "adjuta",
        "config-help-tooltip": "clicca pro displicar",
        "config-skins-screenshots": "$1 (capturas de schermo: $2)",
        "config-extensions-requires": "$1 (require $2)",
        "config-screenshot": "captura de schermo",
+       "config-extension-not-found": "Impossibile trovar le file de registration pro le extension \"$1\"",
+       "config-extension-dependency": "Un error de dependentia se ha producite durante le installation del extension \"$1\": $2",
        "mainpagetext": "<strong>MediaWiki ha essite installate.</strong>",
        "mainpagedocfooter": "Consulta le [https://meta.wikimedia.org/wiki/Help:Contents Guida del usator] pro information sur le uso del software wiki.\n\n== Pro initiar ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de configurationes]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ a proposito de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de diffusion pro annuncios de nove versiones de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Traducer MediaWiki in tu lingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Como combatter le spam in tu wiki]"
 }
index 87fc27b..7d8ce34 100644 (file)
@@ -71,7 +71,8 @@
        "config-pcre-no-utf8": "'''Fatal''': Modul PCRE PHP tampaknya dikompilasi tanpa dukungan PCRE_UTF8.\nMediaWiki memerlukan dukungan UTF-8 untuk berfungsi dengan benar.",
        "config-memory-raised": "<code>memory_limit</code> PHP adalah $1, dinaikkan ke $2.",
        "config-memory-bad": "'''Peringatan:''' <code>memory_limit</code> PHP adalah $1.\nIni terlalu rendah.\nInstalasi terancam gagal!",
-       "config-apc": "[https://secure.php.net/apc APC] telah diinstal",
+       "config-apc": "[https://secure.php.net/apc APC] telah dipasang",
+       "config-apcu": "[https://secure.php.net/apcu APCu] telah dipasang",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] telah diinstal",
        "config-no-cache-apcu": "<strong>Peringatan:</strong> Tidak dapat menemukan [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] atau [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]. Singgahan obyek tidak diaktifkan.",
        "config-mod-security": "<strong>Peringatan:</strong> Server web Anda memiliki [https://modsecurity.org/ mod_security] yang diaktifkan. Jika salah dalam mengkonfigurasi, ini dapat menyebabkan masalah untuk MediaWiki atau perangkat lunak lain yang memungkinkan pengguna untuk mengirim sembarang konten.\nLihat [https://modsecurity.org/documentation/ dokumentasi mod_security] atau hubungi layanan host Anda jika Anda mengalami kesalahan acak.",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] adalah sistem basis data yang ringan yang sangat baik dukungannya. ([http://www.php.net/manual/en/pdo.installation.php cara mengompilasi PHP dengan dukungan SQLite], menggunakan PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] adalah basis data komersial untuk perusahaan. ([http://www.php.net/manual/en/oci8.installation.php cara mengompilasi PHP dengan dukungan OCI8])",
        "config-dbsupport-mssql": "[{{int:version-db-mssql-url}} Microsoft SQL Server] adalah database perusahaan komersial untuk Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Bagaimana cara mengkompilasi PHP dengan dukungan SQLSRV])",
-       "config-header-mysql": "Pengaturan MySQL",
+       "config-header-mysql": "Pengaturan MariaDB/MySQL",
        "config-header-postgres": "Pengaturan PostgreSQL",
        "config-header-sqlite": "Pengaturan SQLite",
        "config-header-oracle": "Pengaturan Oracle",
        "config-help-tooltip": "klik untuk memperluas",
        "config-nofile": "Berkas \"$1\" tidak dapat ditemukan. Mungkin sudah dihapus?",
        "config-extension-link": "Tahukah Anda bahwa wiki Anda mendukung [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions ekstensi]?\n\nAnda dapat menjelajahi [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category ekstensi menurut kategori] atau [https://www.mediawiki.org/wiki/Extension_Matrix Ekstensi Matriks] untuk melihat daftar lengkap ekstensi.",
+       "config-skins-screenshots": "$1 (tangkapan layar: $2)",
+       "config-extensions-requires": "$1 (memerlukan $2)",
+       "config-screenshot": "tangkapan layar",
        "mainpagetext": "<strong>MediaWiki telah terpasang dengan sukses.</strong>",
        "mainpagedocfooter": "Konsultasikan [https://www.mediawiki.org/wiki/Help:Contents Panduan Pengguna] untuk cara penggunaan perangkat lunak wiki ini.\n\n== Memulai ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Daftar pengaturan konfigurasi]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Pertanyaan yang sering diajukan mengenai MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Milis rilis MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Pelokalan MediaWiki untuk bahasa Anda]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Belajar bagaimana menghadapi spam di wiki lokal]"
 }
index 5be6e03..c1eabf2 100644 (file)
        "config-sqlite-cant-create-db": "Impossibile creare il file di database <code>$1</code> .",
        "config-sqlite-fts3-downgrade": "Il PHP è mancante del supporto FTS3, declassamento tabelle in corso",
        "config-can-upgrade": "Ci sono tabelle di MediaWiki in questo database.\nPer aggiornarle a MediaWiki $1, fai clic su '''continua'''.",
+       "config-upgrade-error": "Si è verificato un errore durante l'aggiornamento delle tabelle MediaWiki nel tuo database.\n\nPer ulteriori informazioni guarda nel registro qui sopra, per riprovare clicca su <strong>Continua</strong>.",
        "config-upgrade-done": "Aggiornamento completo.\n\nPuoi [$1 iniziare ad usare il tuo wiki].\n\nSe vuoi rigenerare il tuo file <code>LocalSettings.php</code>, clicca sul pulsante sotto. Questa operazione '''non è raccomandata''', a meno che non hai problemi con il tuo wiki.",
        "config-upgrade-done-no-regenerate": "Aggiornamento completo.\n\nPuoi [$1 iniziare ad usare il tuo wiki].",
        "config-regenerate": "Rigenera LocalSettings.php →",
        "config-install-mainpage-failed": "Impossibile inserire la pagina principale: $1",
        "config-install-done": "<strong>Complimenti!</strong>\nHai installato MediaWiki.\n\nIl programma di installazione ha generato un file <code>LocalSettings.php</code> che contiene tutte le impostazioni.\n\nDevi scaricarlo ed inserirlo nella directory base del tuo wiki (la stessa dove è presente index.php). Il download dovrebbe partire automaticamente.\n\nSe il download non si avvia, o se è stato annullato, puoi riavviarlo cliccando sul collegamento di seguito:\n\n$3\n\n<strong>Nota:</strong> se esci ora dall'installazione senza scaricare il file di configurazione che è stato generato, questo poi non sarà più disponibile in seguito.\n\nQuando hai fatto, puoi <strong>[$2 entrare nel tuo wiki]</strong>.",
        "config-install-done-path": "<strong>Complimenti!</strong>\nHai installato MediaWiki.\n\nIl programma di installazione ha generato un file <code>LocalSettings.php</code> che contiene tutte le impostazioni.\n\nDevi scaricarlo ed inserirlo in <code>$4</code>. Il download dovrebbe partire automaticamente.\n\nSe il download non si avvia, o se è stato annullato, puoi riavviarlo cliccando sul collegamento seguente:\n\n$3\n\n<strong>Nota:</strong> se esci ora dall'installazione senza scaricare il file di configurazione che è stato generato, questo poi non sarà più disponibile in seguito.\n\nQuando hai fatto, puoi <strong>[$2 entrare nel tuo wiki]</strong>.",
+       "config-install-success": "MediaWiki è stato installato corretamente. Ora puoi visitare <$1$2> per vedere il tuo wiki.\nSe hai domande, controlla la nostra lista di domande frequenti:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> o usa usa uno dei forum di supporto riepilogati su quella pagina.",
+       "config-install-db-success": "Il database è stato configurato correttamente",
        "config-download-localsettings": "Scarica <code>LocalSettings.php</code>",
        "config-help": "aiuto",
        "config-help-tooltip": "fai clic per espandere",
index c91f0a9..cc2efd4 100644 (file)
        "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> 이 생성한 설정 파일을 다운로드하지 않고 설치를 끝내면 이 파일은 나중에 사용할 수 없습니다.\n\n완료되었으면 <strong>[$2 위키에 들어갈 수 있습니다]</strong>.",
        "config-install-done-path": "<strong>축하합니다!</strong>\n미디어위키가 설치되었습니다.\n\n설치 관리자가 <code>LocalSettings.php</code> 파일을 생성했습니다.\n이 파일에 모든 설정이 포함되어 있습니다.\n\n이 파일을 다운로드하여 <code>$4</code> 위치에 넣으세요. 다운로드가 자동으로 시작되었을 것입니다.\n\n다운로드가 시작되지 않았거나 취소했다면, 아래 링크를 클릭하여 다운로드를 재시작할 수 있습니다.\n\n$3\n\n<strong>알림:</strong> 지금 다운로드하지 않는다면, 이후에는 이 설정 파일을 다운로드할 수 없습니다.\n\n모든 작업이 완료되었다면, <strong>[$2 위키에 들어갈 수 있습니다]</strong>.",
        "config-install-success": "미디어위키가 성공적으로 설치되었습니다. 이제 <$1$2>에 방문하여 위키를 볼 수 있습니다.\n질문이 있으시다면 자주 묻는 질문 목록을 살펴보십시오:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> 아니면\n해당 문서에 연결된 지원 포럼 중 한곳을 이용하십시오.",
+       "config-install-db-success": "데이터베이스가 성공적으로 구축되었습니다",
        "config-download-localsettings": "<code>LocalSettings.php</code> 다운로드",
        "config-help": "도움말",
        "config-help-tooltip": "확장하려면 클릭",
index 73ab2ba..3df5d6b 100644 (file)
        "config-db-schema-help": "Оваа шема обично по правило ќе работи нормално.\nСменете ја само ако знаете дека треба да се смени.",
        "config-pg-test-error": "Не можам да се поврзам со базата <strong>$1</strong>: $2",
        "config-sqlite-dir": "Папка на SQLite-податоци:",
-       "config-sqlite-dir-help": "SQLite ги складира сите податоци во една податотека.\n\nПапката што ќе ја наведете мора да е запислива од мрежниот опслужувач во текот на воспоставката.\n\nТаа '''не''' смее да биде достапна преку семрежјето, и затоа не ја ставаме кајшто ви се наоѓаат PHP-податотеките.\n\nВоспоставувачот воедно ќе создаде податотека <code>.htaccess</code>, но ако таа не функционира како што треба, тогаш некој ќе може да ви влезе во вашата необработена (сирова) база на податоци.\nТука спаѓаат необработени кориснички податоци (е-поштенски адреси, хеширани лозинки) како и избришани преработки и други податоци за викито до кои се има ограничен пристап.\n\nСе препорачува целата база да ја сместите некаде, како на пр. <code>/var/lib/mediawiki/вашетовики</code>.",
+       "config-sqlite-dir-help": "SQLite ги складира сите податоци во една податотека.\n\nПапката што ќе ја наведете мора да е запислива од мрежниот опслужувач во текот на воспоставката.\n\nТаа '''не''' смее да биде достапна преку семрежјето, и затоа не ја ставаме кајшто ви се наоѓаат PHP-податотеките.\n\nВоспоставувачот воедно ќе создаде податотека <code>.htaccess</code>, но ако таа не функционира како што треба, тогаш некој ќе може да ви влезе во вашата необработена (сирова) база на податоци.\nТука спаѓаат необработени кориснички податоци (е-поштенски адреси, хеширани лозинки) како и избришани преработки и други податоци за викито до кои се има ограничен пристап.\n\nСе препорачува целата база да ја сместите некаде, како на пр. <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Стандарден таблеарен простор:",
        "config-oracle-temp-ts": "Привремен табеларен простор:",
        "config-type-mysql": "MariaDB, MySQL или складно",
        "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>: Ако ова не го направите сега, податотеката со поставки повеќе нема да биде на достапна.\n\nОткога ќе завршите со тоа, можете да <strong>[$2 влезете на вашето вики]</strong>.",
        "config-install-done-path": "<strong>Честитаме!</strong>\nГо воспоставивте МедијаВики.\n\nВоспоставувачот создаде податотека <code>LocalSettings.php</code>.\nТаму се содржат сите ваши нагодувања.\n\nЌе треба да ја преземете и да ја ставите во <code>$4</code>. Преземањето треба да е започнато автоматски.\n\nАко не ви е понудено преземање, или пак ако сте го откажале, можете да го почнете одново стискајќи на следнава врска:\n\n$3\n\n<strong>Напомена</strong>: Ако ова не го направите сега, создадената податотека со поставки повеќе нема да биде на достапна, освен ако не ја преземете пред да излезете.\n\nОткога ќе завршите со тоа, можете да <strong>[$2 влезете на вашето вики]</strong>.",
        "config-install-success": "МедијаВики е успешно воспоставен. Сега можете да појдете на <$1$2> за да го погледате вашето вики.\nАко имате било какви прашања, погледајте го списокот на често поставувани прашања:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> или појдете на еден од форумите за поддршка наведени на таа страница.",
+       "config-install-db-success": "Базата е успешно поставена",
        "config-download-localsettings": "Преземи го <code>LocalSettings.php</code>",
        "config-help": "помош",
        "config-help-tooltip": "стиснете да расклопите",
index 54f743d..c79aa63 100644 (file)
        "config-install-done": "<strong>Gefeliciteerd!</strong>\nU hebt MediaWiki geïnstalleerd.\n\nHet installatieprogramma heeft het bestand <code>LocalSettings.php</code> aangemaakt.\nDit bevat al uw instellingen.\n\nU moet het bestand downloaden en in de hoofdmap van uw wiki-installatie plaatsen, in dezelfde map als index.php.\nDe download zou automatisch moeten zijn gestart.\n\nAls de download niet is gestart of als u de download hebt geannuleerd, dan kunt u de download opnieuw starten door op de onderstaande koppeling te klikken:\n\n$3\n\n<strong>Let op:</strong> als u dit niet nu doet, dan is het bestand als u later de installatieprocedure afsluit zonder het bestand te downloaden niet meer beschikbaar.\n\nNa het plaatsen van het bestand met instellingen kunt u <strong>[$2 uw wiki gebruiken]</strong>.",
        "config-install-done-path": "<strong>Gefeliciteerd!</strong>\nU hebt MediaWiki geïnstalleerd.\n\nHet installatieprogramma heeft het bestand <code>LocalSettings.php</code> aangemaakt.\nDit bevat al uw instellingen.\n\nU moet het bestand downloaden en in <code>$4</code> plaatsen. De download zou automatisch moeten zijn gestart.\n\nAls de download niet is gestart of als u de download hebt geannuleerd, dan kunt u de download opnieuw starten door op de onderstaande koppeling te klikken:\n\n$3\n\n<strong>Let op:</strong> Als u dit niet nu doet, dan is het bestand als u later de installatieprocedure afsluit zonder het bestand te downloaden niet meer beschikbaar.\n\nNa het plaatsen van het bestand met instellingen kunt u <strong>[$2 uw wiki gebruiken]</strong>.",
        "config-install-success": "MediaWiki is geïnstalleerd. U kunt nu\n<$1$2> bezoeken om uw wiki te bekijken.\nAls u vragen hebt, bekijk dan onze lijst met veelgestelde vragen:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ>, of gebruik een van de hulpforums vermeld op die pagina.",
+       "config-install-db-success": "Het installeren van de database is geslaagd",
        "config-download-localsettings": "<code>LocalSettings.php</code> downloaden",
        "config-help": "hulp",
        "config-help-tooltip": "klik om uit te vouwen",
index 131e06f..9d41768 100644 (file)
@@ -7,7 +7,8 @@
                        "아라",
                        "Amire80",
                        "Macofe",
-                       "Seb35"
+                       "Seb35",
+                       "MaxSem"
                ]
        },
        "config-desc": "L'instalador për mediaWiki",
@@ -76,7 +77,7 @@
        "config-uploads-not-safe": "'''Avis:''' Sò dossié stàndard për carié <code>$1</code> a l'é vulneràbil a l'esecussion ëd qualsëssìa senari.\nBele che MediaWiki a contròla j'aspet ëd sicurëssa ëd tùit j'archivi carià, a l'é motobin arcomandà ëd [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security saré ës përtus ëd sicurëssa] prima d'abilité ij cariament.",
        "config-no-cli-uploads-check": "'''Avis:''' Toa cartela predefinìa për j-amportassion (<code>$1</code>) a l'é nen controlà a propòsit ëd la vulnerabilità\nd'esecussion ëd senari arbitrari durant l'istalassion CLI.",
        "config-brokenlibxml": "Sò sistema a l'ha na combinassion ëd version PHP e libxml2 che a l'ha dij bigat e a peul provoché la corussion ëd dat ëstërmà an MediaWiki e d'àutre aplicassion për l'aragnà.\nCh'a agiorna a PHP 5.2.9 o pi neuv e libxml2 2.7.3 o pi neuv ([https://bugs.php.net/bug.php?id=45996 bigat archivià con PHP]).\nAnstalassion abortìa.",
-       "config-suhosin-max-value-length": "Suhosin a l'é instalà e a lìmita la longheur dël paràmetr GET a $1 byte. Ël component ResourceLoader ëd MediaWiki a travajerà an rispetand ës lìmit, ma sòn a degraderà le prestassion. Se possìbil, a dovrìa amposté suhosin.get.max_value_lenght a 1024 o pi àut an <code>php.ini</code>, e amposté <code>$wgResourceLoaderMaxQueryLength</code> al midem valor an LocalSettings.php .",
+       "config-suhosin-max-value-length": "Suhosin a l'é instalà e a lìmita la <code>longheur</code> dël paràmetr GET a $1 byte. Ël component ResourceLoader ëd MediaWiki a travajerà an rispetand ës lìmit, ma sòn a degraderà le prestassion. Se possìbil, a dovrìa amposté <code>suhosin.get.max_value_length</code> a 1024 o pi àut an <code>php.ini</code>, e amposté <code>$wgResourceLoaderMaxQueryLength</code> al midem valor an <code>LocalSettings.php</code>.",
        "config-db-type": "Sòrt ëd base ëd dàit:",
        "config-db-host": "Ospitant ëd la base ëd dàit:",
        "config-db-host-help": "Se sò servent ëd base ëd dàit a l'é su un servent diferent, ch'a anserissa ambelessì ël nòm dl'ospitant o l'adrëssa IP.\n\nS'a deuvra n'ospitalità partagià, sò fornidor d'ospitalità a dovrìa deje ël nòm dl'ospitant giust ant soa documentassion.\n\nSe a anstala su un servent Windows e a deuvra MySQL, dovré «localhost» a podrìa funsioné nen com nòm dël servent. S'a marcia nen, ch'a preuva «127.0.0.1» com adrëssa IP local.\n\nS'a deuvra PostgresSQL, ch'a lassa sto camp bianch për coleghesse a travers un socket UNIX.",
index 8c53ed1..872e67b 100644 (file)
        "config-install-done": "<strong>Parabéns!</strong>\nVocê instalou o MediaWiki.\n\nO instalador gerou um arquivo <code>LocalSettings.php</code>.\nEste arquivo contém todas as suas configurações.\n\nVocê precisa fazer o download desse arquivo e colocá-lo na raiz da sua instalação (o mesmo diretório onde está o arquivo index.php). O download deve iniciar automaticamente.\n\nSe o download não foi iniciado ou se ele foi cancelado, você pode recomeçá-lo clicando no link abaixo:\n\n$3\n\n<strong>Nota:</strong> Se você não fizer isso agora, o arquivo de configuração que foi gerado não estará mais disponível se você sair da instalação sem fazer o download.\n\nQuando isso tiver sido feito, você pode <strong>[$2 entrar na sua wiki]</strong>.",
        "config-install-done-path": "<strong>Parabéns!</strong>\nVocê instalou o MediaWiki.\n\nO instalador gerou um arquivo <code>LocalSettings.php</code>.\nEste arquivo contém todas as suas configurações.\n\nVocê precisa fazer o download desse arquivo e colocá-lo em <code>$4</code>. O download deve iniciar automaticamente.\n\nSe o download não foi iniciado ou se ele foi cancelado, você pode recomeçá-lo clicando no link abaixo:\n\n$3\n\n<strong>Nota:</strong> Se você não fizer isso agora, o arquivo de configuração que foi gerado não estará mais disponível se você sair da instalação sem fazer o download.\n\nQuando isso tiver sido feito, você pode <strong>[$2 entrar na sua wiki]</strong>.",
        "config-install-success": "O MediaWiki foi instalado. Já pode visitar <$1$2> para ver a sua wiki.\nSe tiver dúvidas, veja a nossa lista de perguntas frequentes,\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ>, ou utilize um dos fóruns de suporte indicados nessa página.",
+       "config-install-db-success": "Banco de dados foi configurado com sucesso",
        "config-download-localsettings": "Baixar <code>LocalSettings.php</code>",
        "config-help": "ajuda",
        "config-help-tooltip": "clique para expandir",
index e712fe5..f493ef3 100644 (file)
@@ -20,7 +20,8 @@
                        "Ruila",
                        "Seb35",
                        "MokaAkashiyaPT",
-                       "Athena in Wonderland"
+                       "Athena in Wonderland",
+                       "CaiusSPQR"
                ]
        },
        "config-desc": "O instalador do MediaWiki",
@@ -98,7 +99,7 @@
        "config-using-32bit": "<strong>Aviso:</strong> o seu sistema parece estar a funcionar com inteiros de 32 bits. Isto  [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit não é recomendado].",
        "config-db-type": "Tipo da base de dados:",
        "config-db-host": "Servidor da base de dados:",
-       "config-db-host-help": "Se a base de dados estiver num servidor separado, introduza aqui o nome ou o endereço IP desse servidor.\n\nSe estiver a usar um servidor partilhado, o fornecedor do alojamento deve fornecer o nome do servidor na documentação.\n\nSe está a fazer a instalação num servidor Windows com MySQL, usar como nome do servidor \"localhost\" poderá não funcionar. Se não funcionar, tente usar \"127.0.0.1\" como endereço IP local.\n\nSe estiver a usar PostgreSQL, deixe este campo em branco para fazer a ligação através de um socket Unix.",
+       "config-db-host-help": "Se a base de dados estiver num servidor separado, introduza aqui o nome ou o endereço IP desse servidor.\n\nSe estiver a usar um servidor partilhado, o fornecedor do alojamento deve fornecer o nome do servidor na documentação.\n\nSe estiver a usar MySQL, usar como nome do servidor \"localhost\" poderá não funcionar. Se não funcionar, tente usar \"127.0.0.1\" como endereço IP local.\n\nSe estiver a usar PostgreSQL, deixe este campo em branco para fazer a ligação através de um socket Unix.",
        "config-db-host-oracle": "TNS (Transparent Network Substrate) da base de dados:",
        "config-db-host-oracle-help": "Introduza um [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Nome Local de Ligação] válido; tem de estar visível para esta instalação um ficheiro tnsnames.ora.<br />Se está a usar bibliotecas cliente versão 10g ou posterior, também pode usar o método [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Ligação Fácil] de atribuição do nome.",
        "config-db-wiki-settings": "Identifique esta wiki",
        "config-invalid-db-server-oracle": "O TNS da base de dados, \"$1\", é inválido.\nUse \"TNS Name\" ou o método \"Easy Connect\" ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Métodos de Configuração da Conectividade em Oracle])",
        "config-invalid-db-name": "O nome da base de dados, \"$1\",  é inválido.\nUse só letras (a-z, A-Z), algarismos (0-9), sublinhados (_) e hífens (-) dos caracteres ASCII.",
        "config-invalid-db-prefix": "O prefixo da base de dados, \"$1\",  é inválido.\nUse só letras (a-z, A-Z), algarismos (0-9), sublinhados (_) e hífens (-) dos caracteres ASCII.",
-       "config-connection-error": "$1.\n\nVerifique o servidor, o nome do utilizador e a palavra-passe e tente novamente.",
+       "config-connection-error": "$1.\n\nVerifique o servidor, o nome do utilizador e a palavra-passe e tente novamente. Se estiver a usar \"localhost\" como servidor da base de dados, tente antes usar \"127.0.0.1\" (ou vice-versa).",
        "config-invalid-schema": "O esquema ''(schema)'' do MediaWiki, \"$1\", é inválido.\nUse só letras (a-z, A-Z), algarismos (0-9) e sublinhados (_) dos caracteres ASCII.",
        "config-db-sys-create-oracle": "O instalador só permite criar uma conta nova usando uma conta SYSDBA.",
        "config-db-sys-user-exists-oracle": "A conta \"$1\" já existe. A conta SYSDBA só pode criar uma conta nova!",
        "config-install-done": "<strong>Parabéns!</strong>\nTerminou a instalação do MediaWiki.\n\nO instalador gerou um ficheiro <code>LocalSettings.php</code>.\nEste ficheiro contém todas as configurações.\n\nPrecisa de descarregar o ficheiro e colocá-lo no diretório de raiz da sua instalação (o mesmo diretório onde está o ficheiro index.php). Este descarregamento deverá ter sido iniciado automaticamente.\n\nSe o descarregamento não foi iniciado, ou se o cancelou, pode recomeçá-lo clicando na hiperligação abaixo:\n\n$3\n\n<strong>Nota</strong>: Se não o descarregar agora, o ficheiro que foi gerado deixará de estar disponível quando sair do processo de instalação.\n\nDepois de terminar o passo anterior, pode <strong>[$2 entrar na wiki]</strong>.",
        "config-install-done-path": "<strong>Parabéns!</strong>\nTerminou a instalação do MediaWiki.\n\nO instalador gerou um ficheiro <code>LocalSettings.php</code>.\nEste ficheiro contém todas as configurações.\n\nPrecisa de descarregar o ficheiro e colocá-lo no diretório <code>$4</code>. Este descarregamento deverá ter sido iniciado automaticamente.\n\nSe o descarregamento não foi iniciado, ou se o cancelou, pode recomeçá-lo clicando a hiperligação abaixo:\n\n$3\n\n<strong>Nota</strong>: Se não fizer o descarregamento agora, o ficheiro que foi gerado deixará de estar disponível quando sair do processo de instalação.\n\nDepois de terminar o passo anterior, pode <strong>[$2 entrar na wiki]</strong>.",
        "config-install-success": "O MediaWiki foi instalado. Já pode visitar <$1$2> para ver a sua wiki.\nSe tiver dúvidas, veja a nossa lista de perguntas frequentes,\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ>, ou utilize um dos fóruns de suporte indicados nessa página.",
+       "config-install-db-success": "A base de dados foi configurada",
        "config-download-localsettings": "Descarregar <code>LocalSettings.php</code>",
        "config-help": "ajuda",
        "config-help-tooltip": "clique para expandir",
index bf19769..91f07c3 100644 (file)
        "config-install-mainpage-failed": "Used as error message. Parameters:\n* $1 - detailed error message",
        "config-install-done": "Parameters:\n* $1 is the URL to LocalSettings download\n* $2 is a link to the wiki.\n* $3 is a download link with attached download icon. The config-download-localsettings message will be used as the link text.",
        "config-install-done-path": "Parameters:\n* $1 is the URL to LocalSettings download\n* $2 is a link to the wiki.\n* $3 is a download link with attached download icon. The config-download-localsettings message will be used as the link text.\n* $4 is the filesystem location of where the LocalSettings.php file should be saved to.",
-       "config-install-success": "Gives user information that installation was successful. Parameters:\n* $1 - server name\n* $2 - script path",
+       "config-install-success": "Gives user information that installation was successful. Only shown in command line installer. Parameters:\n* $1 - server name\n* $2 - script path",
+       "config-install-db-success": "Shown after DB is set up. In web installer this is step prior to downloading LocalSettings.php",
        "config-download-localsettings": "The link text used in the download link in config-install-done.",
        "config-help": "This is used in help boxes.\n{{Identical|Help}}",
        "config-help-tooltip": "Tooltip for the 'help' links ({{msg-mw|config-help}}), to make it clear they'll expand in place rather than open a new page",
index de6d731..ccadc13 100644 (file)
@@ -27,7 +27,8 @@
                        "Facenapalm",
                        "Movses",
                        "Vlad5250",
-                       "Athena Atterdag"
+                       "Athena Atterdag",
+                       "Diralik"
                ]
        },
        "config-desc": "Инсталлятор MediaWiki",
        "config-cc-not-chosen": "Выберите, какую лицензию Creative Commons Вы хотите использовать, и нажмите кнопку \"proceed\".",
        "config-advanced-settings": "Дополнительные настройки",
        "config-cache-options": "Параметры кэширования объектов:",
-       "config-cache-help": "Кэширование объектов используется для повышения скорости MediaWiki путем кэширования часто используемых данных.\nДля средних и больших сайтов кеширование настоятельно рекомендуется включать, а для небольших сайтов кеширование может показать преимущество.",
+       "config-cache-help": "Кэширование объектов используется для повышения скорости MediaWiki путём кэширования часто используемых данных.\nДля средних и больших сайтов кеширование настоятельно рекомендуется включать, а для небольших сайтов кеширование может показать преимущество.",
        "config-cache-none": "Без кэширования (никакой функционал не теряется, но крупные вики-сайты могут работать медленнее)",
        "config-cache-accel": "Кэширование PHP-объектов (APC, APCu или WinCache)",
        "config-cache-memcached": "Использовать Memcached (требует дополнительной настройки)",
        "config-download-localsettings": "Загрузить <code>LocalSettings.php</code>",
        "config-help": "справка",
        "config-help-tooltip": "нажмите, чтобы развернуть",
-       "config-nofile": "Файл \"$1\" не удается найти. Он был удален?",
+       "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 расширения по категориям]",
        "config-skins-screenshots": "$1 (скриншоты: $2)",
        "config-extensions-requires": "$1 (требуется $2)",
index f6850a4..37ea7bb 100644 (file)
@@ -3,9 +3,165 @@
                "authors": [
                        "OC Ripper",
                        "Seb35",
-                       "Conquistador"
+                       "Conquistador",
+                       "Vlad5250"
                ]
        },
+       "config-desc": "Uspostavljač MediaWikija",
+       "config-title": "Uspostava MediaWikija $1",
+       "config-information": "Informacije",
+       "config-localsettings-upgrade": "Otkrivena je datoteka <code>LocalSettings.php</code>.\nDa biste nadogradili instalaciju, unesite vrijednost <code>$wgUpgradeKey</code> u okvir ispod.\nNaći ćete ga u <code>LocalSettings.php</code>.",
+       "config-localsettings-cli-upgrade": "Određuje se prisutnost datoteke \"<code>LocalSettings.php</code>\".\nDa biste nadogradili uspostavu, pokrenite je \"<code>update.php</code>\" umjesto gore navedenoj.",
+       "config-localsettings-key": "Ključ za nadogradnju:",
+       "config-localsettings-badkey": "Ključ za nadogradnju koji ste naveli je pogrešan.",
+       "config-upgrade-key-missing": "Otkrivena je postojeća uspostava MediaWikija.\nDa biste je nadogradili, umetnite sljedeći red na dno vaše stranice <code>LocalSettings.php</code>:\n\n$1",
+       "config-localsettings-incomplete": "Postojeća stranica <code>LocalSettings.php</code> je nepotpuna.\nNije postavljena varijabla $1.\nIzmijenite stranicu <code>LocalSettings.php</code> tako što ćete zadati vrijednost varijabli, pa kliknite na \"{{int:Config-continue}}\".",
+       "config-localsettings-connection-error": "Došlo je do pogreške prilikom povezivanja s bazom podataka korišćenjem postavki navedenih u <code>LocalSettings.php</code>. Ispravite ove postavke i pokušajte ponovo.\n\n$1",
+       "config-session-error": "Greška pri započinjanju sesije: $1",
+       "config-session-expired": "Vaši podaci o sesiji su istekle.\nPostavke za sesije traju $1.\nNjihovo trajanje možete povećati zadavanjem na <code>session.gc_maxlifetime</code> u php.ini.\nPonovo pokrenite uspostavu.",
+       "config-no-session": "Podaci sesije su izgubljeni!\nPogledajte u php.ini ako je <code>session.save_path</code> postavljen u pravilni direktorijum.",
+       "config-your-language": "Vaš jezik:",
+       "config-your-language-help": "Odaberite na kojem jeziku će se odviva uspostava.",
+       "config-wiki-language": "Jezik wikija:",
+       "config-wiki-language-help": "Odaberite na kojem jeziku će biti sadržaje wikija.",
+       "config-back": "← Nazad",
+       "config-continue": "Nastavi →",
+       "config-page-language": "Jezik",
+       "config-page-welcome": "Dobro došli na MediaWiki!",
+       "config-page-dbconnect": "Povezivanje s bazom podataka",
+       "config-page-upgrade": "Nadogradnja postojeće uspostave",
+       "config-page-dbsettings": "Podešavanja baze podataka",
+       "config-page-name": "Naziv",
+       "config-page-options": "Postavke",
+       "config-page-install": "Uspostavi",
+       "config-page-complete": "Završeno!",
+       "config-page-restart": "Pokreni uspostavu ponovno",
+       "config-page-readme": "Pročitaj me",
+       "config-page-releasenotes": "Bilješke o izdanju",
+       "config-page-copying": "Kopiranje",
+       "config-page-upgradedoc": "Nadogradnja",
+       "config-page-existingwiki": "Postojeći wiki",
+       "config-help-restart": "Želite li obrisati sve sačuvane podatke koje ste unijeli i ponovo pokrenuti uspostavu?",
+       "config-restart": "Da, pokreni ponovo",
+       "config-welcome": "=== Provjere okoline ===\nSada ćemo obaviti osnovne provjere kako bismo utvrdili je li okruženje prikladno za uspostavu MediaWikija. Ne zaboravite navesti ove informacije ako tražite pomoć s dovršavanjem uspostave.",
+       "config-copyright": "=== Autorska prava i uvjeti ===\n\n$1\n\nTo je slobodni softver (free software); možete ga redistribuirati i/ili mijenjati pod uvjetima GNU-ove opće javne licence (GNU General Public License) Zaklade za slobodni softver (Free Software Foundation); verzija 2 ili bilo koja kasnija verzija licence (po vašem izboru).\n\nOvaj se program nudi u nadi da će biti koristan, ali '''bez ikakvog jamstva'''; čak i implicirano jamstvo '''sposobnosti prodaje''' ili '''prikladnosti za određenu svrhu'''.\nViše informacija ćete naći u tekstu GNU-ove opće javne licence.\n\nTrebali ste primiti <doclink href=Copying>primjerak GNU-ove opće javne licence</doclink> zajedno s programima; ako ga ne primite, pišite nam na Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ili [https://www.gnu.org/copyleft/gpl.html pročitajte je ovdje].",
+       "config-sidebar": "* [https://www.mediawiki.org Početna strana MediaWikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodič za korisnike]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Vodič za administratore]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ČPP]\n----\n* <doclink href=Readme>Pročitaj me</doclink>\n* <doclink href=ReleaseNotes>Bilješke o izdanju</doclink>\n* <doclink href=Copying>Kopiranje</doclink>\n* <doclink href=UpgradeDoc>Nadograđivanje</doclink>",
+       "config-env-good": "Okruženje je provjereno.\nMožete uspostaviti MediaWiki.",
+       "config-env-bad": "Okruženje je provjereno.\nNe možete uspostaviti MediaWiki.",
+       "config-env-php": "PHP $1 je uspostavljen.",
+       "config-env-hhvm": "HHVM $1 je uspostavljen.",
+       "config-unicode-using-intl": "Uz dodatak [https://pecl.php.net/intl intL PECL] za Unicode normalizaciju.",
+       "config-unicode-pure-php-warning": "'''Upozorenje''': Dodatak [https://pecl.php.net/intl intl PECL] nije dostupan za normalizaciju Unicode, vraćajući se na sporu primjenu čistog PHP-a.\n\nAko imate web-lokaciju s visokim prometom, morat ćete pročitati više o [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalizacije].",
+       "config-unicode-update-warning": "'''Upozorenje:''' Uspostavljena verzija omotnice Unicode normalizacije koristi stariju verziju biblioteke [http://site.icu-project.org/ projekta ICU].\nDa biste koristili Unicode, trebate napraviti [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations nadogradnju].",
+       "config-no-db": "Nisam mogao pronaći odgovarajući upravljački program za bazu podataka! Morat ćete uspostaviti upravljački program za PHP-bazu.\n{{PLURAL:$2|Podržana je sljedeća vrsta|Podržane su sljedeće vrste}} baze: $1.\n\nAko ste sami kompilirali PHP, omogućite bazni klijent u postavkama - npr. s <code>./configure --with-mysqli</code>.\nAko ovaj PHP uspostavite iz Debian ili Ubuntu paketa, tada ćete ga morati uspostaviti, npr., paket <code>php-mysql</code>.",
+       "config-outdated-sqlite": "'''Upozorenje''': imate SQLite $1. Najstarija dopuštena verzija je $2. Stoga će SQLite biti nedostupan.",
+       "config-no-fts3": "'''Upozorenje''': SQLite se kompilira bez modula [//sqlite.org/fts3.html FTS3] - za tu bazu podataka neće biti mogućnosti pretrage.",
+       "config-pcre-old": "'''Kobno:''' Potreban je PCRE $1 ili novija verzija.\nVaš PHP-binarni je svezan s PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Više informacija].",
+       "config-pcre-no-utf8": "<strong>Kobno</strong>: PCRE modul PHP-a je hitan bez podrške za PCRE_UTF8.\nMediaWiki zahtijeva podršku za UTF-8 kako bi ispravno funkcionirao.",
+       "config-memory-raised": "<code>memory_limit</code> za PHP iznosi $1, povišen na $2.",
+       "config-memory-bad": "<strong>Upozorenje:</strong> <code>memory_limit</code> za PHP iznosi $1.\nOvo je vjerovatno premalo.\nUspostava možda neće uspjeti!",
+       "config-apc": "[https://secure.php.net/apc APC] je uspostavljen",
+       "config-apcu": "[https://secure.php.net/apcu APCu] je uspostavljen",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] je uspostavljen",
+       "config-no-cache-apcu": "<strong>Upozorenje:</strong> Nisam mogao naći [https://secure.php.net/apcu APCu] ili [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].",
+       "config-mod-security": "'''Upozorenje''': na vašem poslužitelju ima omogućeno [https://modsecurity.org/ mod_security]. Ako nije postavljeno kako treba, to može uzrokovati probleme s programom MediaWikija i drugim programima koji korisnicima omogućuju objavljivanje proizvoljnog sadržaja.\nPogledajte [https://modsecurity.org/documentation/ mod_security dokumentaciju] ili kontaktirajte domaćin ako naiđete na slučajne greške.",
+       "config-diff3-bad": "Nisam pronašao usporednik za tekst GNU razl3 (GNU diff3). Za sada ovo možete zanemariti, ali kontradikcije u uređivanju mogu postati češće.",
+       "config-git": "Pronašao sam Git program za kontrolu verzija: <code>$1</code>.",
+       "config-git-bad": "Nisam pronašao Git-program za kontrolu verzija. Za sada ovo možete zanemariti. Imajte na umu da Posebna:Verzije ne prikazuju krpe u primjenama.",
+       "config-imagemagick": "Pronađen je ImageMagick: <code>$1</code>.\nAko omogućite otpremanje, bit će omogućena minijaturizacija slika.",
+       "config-gd": "Utvrdio sam da ima ugrađenu GD grafička biblioteka.\nAko omogućite otpremanje, bit će omogućena minijaturizacija slika.",
+       "config-no-scaling": "Nisam mogao pronaći GD-biblioteku ili ImageMagick.\nMinijaturizacija slika bit će onemogućena.",
+       "config-no-uri": "<strong>Greška:</strong> Nisam mogao utvrditi trenutni URI.\nUspostava je otkazana.",
+       "config-no-cli-uri": "'''Upozorenje''': Nema navedenog <code>--scriptpath</code>. Će se koristiti podrazumevani: <code>$1</code>.",
+       "config-using-server": "Koristite server pod imenom \"<nowiki>$1</nowiki>\".",
+       "config-using-uri": "Koristite server s URL adresom \"<nowiki>$1$2</nowiki>\".",
+       "config-uploads-not-safe": "'''Upozorenje:''' Vaš matični direktorijum za otpremanja <code>$1</code> podliježe izvršavanju (pokretanju) proizvoljnih skripta.\nIako MediaWiki provodi sigurnosne provjere svih prenesenih datoteka, savjetujemo vam da [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security zatvorite ovu sigurnosnu rupu] prije omogućavanja otpremanja.",
+       "config-no-cli-uploads-check": "'''Upozorenje:'''  Vaš podrazumevani direktorijum za otpremanje (<code>$1</code>) nije provjeren ako je podložna\nslučajno izvršavanje skripti tijekom uspostavke posrednika na razini pozivatelja (CLI).",
+       "config-brokenlibxml": "Vaš sistem ima kombinaciju verzija PHP i libxml2 te stoga ima pogreške i može uzrokovati oštećenje skrivenih podataka u MediaWiki i drugim mrežnim programima.\nNadogradite ga na libxml2 2.7.3 ili njihove kasnije verzije! ([https://bugs.php.net/bug.php?id=45996 pogreška je zabilježena u PHP-u]). Uspostava je otkazana.",
+       "config-suhosin-max-value-length": "Suhosin je uspostavljen i ograničava duljinu GET parametra na $1 bajta. Sekcija ResourceLoader MediaWikija će zaobići ovu granicu, ali to će pogoršati učinkovitost. Ako je ikako moguće, na <code>suhosin.get.max_value_length</code> treba ga namjestiti na 1024 ili više u <code>php.ini</code>, i dati istu vrijednost <code>$wgResourceLoaderMaxQueryLength</code> u <code>LocalSettings.php</code>.",
+       "config-using-32bit": "<strong>Upozorenje:</strong> vaš sistem radi na 32-bitnim celim brojevima. Ovo se [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit ne preporučuje].",
+       "config-db-type": "Tip baze podataka:",
+       "config-db-host": "Domaćin baze podataka:",
+       "config-db-host-help": "Ako je vaša baza podataka na drugom serveru, tada ovdje unesite ime domaćina ili IP adresu.\n\nAko koristite zajednički (deljen) hosting, tada će vaš vjerovnik navesti ispravno ime domaćina u njegovoj dokumentaciji.\n\nAko koristite MySQL, mogućnost \"localhost\" možda neće raditi za serversko ime. U tom slučaju, pokušajte unijeti \"127.0.0.1\" kao lokalnu IP adresu.\n\nAko koristite PostgreSQL, ostavite polje prazno za povezivanje putem Unix priključka.",
+       "config-db-host-oracle": "TNS baze podataka:",
+       "config-db-host-oracle-help": "Unesite valjano [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm lokalno ime za povezivanje]. Ovoj uspostavi mora biti vidljiva datotekata tnsnames.ora.<br />Ako koristite klijentske biblioteke 10g ili novije, tada možete koristiti i metodu imenovanja [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect].",
+       "config-db-wiki-settings": "Identifikuj ovaj wiki",
+       "config-db-name": "Ime baze podataka (bez crtica):",
+       "config-db-name-help": "Odaberite ime koje će predstavljati vaš wiki.\nIme ne smije sadržavati razmake.\n\nAko koristite zajednički (deljen) hosting, tada vaš će vam poslodavac dati određeno ime baze podataka za korištenje, ili pak će vas pustiti da pravite baze podataka putem upravljačnice.",
+       "config-db-name-oracle": "Šema baze podataka:",
+       "config-db-account-oracle-warn": "Postoje tri podržana scenarija za uspostavu Oraclea kao bazni davatelja usluga:\n\nAko želite stvoriti račun baze podataka kao dio postupka uspostave, navedite račun s SYSDBA-ulogom kao račun za bazu koja se uspostavlja i navedite željene podatke za račun mrežnog pristupa. U drugom slučaju, možete izraditi račun za pristup mreži ručno i navesti samo taj račun (ako postoje dozvole za izradu shematskih objekata) ili pak navesti dva različita računa, jedan s povlasticama izrade, a drugi (ograničeno) za mrežni pristup.\n\nSkriptu za izradu računa s obveznim ovlastima naći ćete u direktorijumu „maintenance/oracle/“ ove uspostave. Imajte na umu da ćete, ako koristite ograničeni račun, onemogućiti sve funkcije održavanja s primarnim računom.",
+       "config-db-install-account": "Korisnički račun za uspostavu",
+       "config-db-username": "Korisničko ime baze podataka:",
+       "config-db-password": "Lozinka baze podataka:",
+       "config-db-install-username": "Unesite korisničko ime koje će se koristiti za povezivanje s bazom podataka tijekom uspostave. Ovo nije korisničko ime s računa MediaWiki, već posebno korisničko ime za vašu bazu podataka.",
+       "config-db-install-password": "Unesite lozinku koja će se koristiti za povezivanje s bazom podataka tijekom uspostave. Ovo nije lozinka s računa MediaWiki, već zasebna lozinka za vašu bazu podataka.",
+       "config-db-install-help": "Unesite korisničko ime i lozinku koja će se koristiti za povezivanje s bazom podataka tijekom uspostave.",
+       "config-db-account-lock": "Koristi isto korisničko ime i lozinku za redoviti rad",
+       "config-db-wiki-account": "Korisnički račun za redovan rad",
+       "config-db-wiki-help": "Unesite korisničko ime i lozinku koje će se koristiti za povezivanje s bazom podataka tijekom redovnog rada s wikijem.\nAko račun ne postoji, a instalacijski račun ima dovoljno povlastica, tada će ovaj korisnički račun biti izrađen s najmanjim privilegijama potrebnim za rad s wikijem.",
+       "config-db-prefix": "Prefiks tabele baze podataka (bez crtica):",
+       "config-db-prefix-help": "Ako trebate dijeliti bazu podataka s više wikijama, ili s MediaWikijom i drugim mrežnim programom, tada možete dodati prefiks svim nazivima tablica kako biste spriječili problematične situacije.\nNemojte koristiti prazna mjesta.\n\nOvo polje obično ostaje prazno.",
+       "config-mysql-old": "Zahtijeva se MySQL $1 ili noviji. Vi imate $2.",
+       "config-db-port": "Porta baze podataka:",
+       "config-db-schema": "Šema za MediaWiki (bez crtica):",
+       "config-db-schema-help": "Ova shema obično će po pravilu raditi normalno.\nSmijenite je samo ako znate da se mora smijeniti.",
+       "config-pg-test-error": "Nije moguće povezati se sa bazom podataka <strong>$1</strong>: $2",
+       "config-sqlite-dir": "Direktorijum za SQLite-podatke:",
+       "config-sqlite-dir-help": "SQLite pohranjuje sve podatke u jednu datoteku.\n\nDirektorijum što navedete mora biti zapisljiv iz mrežnog servera tijekom uspostave.\n\nTaj je '''ne''' mora biti dostupno putem svemrežja, tako da ne stavljamo gdje su vaše PHP datoteke.\n\nUspostavljač će također stvoriti datoteku <code>.htaccess</code>, ali ako ta ne radi kako treba, tada netko može unijeti vašu neobrađenu (sirovu) bazu podataka.\nTo uključuje neobrađene korisničke podatke (adrese e-pošte, hash lozinke) kao i izbrisane revizije i druge podatke za wiki koji ima ograničen pristup.\n\nPreporučuje se da cijelu bazu smjestite negdje, primjerice <code>/var/lib/mediawiki/yourwiki</code>.",
+       "config-oracle-def-ts": "Podrazumevani tablearni prostor:",
+       "config-oracle-temp-ts": "Privremeni tabelarni prostor:",
+       "config-type-mysql": "MariaDB, MySQL ili kompatibilan",
+       "config-type-mssql": "Microsoft SQL Server",
+       "config-support-info": "MediaWiki podržava sljedeće sustave baza podataka:\n\n$1\n\nAko sustav koji želite koristiti nije naveden u nastavku, slijedite vezu gore navedenih uputa kako biste omogućili podršku za taj sustav.",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] je glavna meta MediaWikija i najbolje je podržan. MediaWiki također radi sa [{{int:version-db-mysql-url}} MySQL-om] i [{{int:version-db-percona-url}} Percona], koji su skladni sa MariaDB-om. ([https://secure.php.net/manual/en/mysqli.installation.php Kako kompajlirati PHP sa podrškom MySQL-a])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularan sistem baza podataka otvorenog koda koji predstavlja alternativu MySQL-u. ([https://secure.php.net/manual/en/pgsql.installation.php Kako kompajlirati PHP sa podrškom PostgreSQL-a])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] je lagan sistem baze podataka koji je veoma dobro podržan. ([https://secure.php.net/manual/en/pdo.installation.php Kako kompajlirati PHP sa podrškom SQLite-a], koristi PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je baza podataka komercijalnih preduzeća. ([https://secure.php.net/manual/en/oci8.installation.php Kako kompajlirati PHP sa podrškom OCI8-a])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je baza podataka komercijalnih preduzeća za Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Kako kompajlirati PHP sa podrškom SQLSRV-a])",
+       "config-header-mysql": "Podešavanja MariaDB/MySQL-a",
+       "config-header-postgres": "Podešavanja PostgreSQL-a",
+       "config-header-sqlite": "Podešavanja SQLite-a",
+       "config-header-oracle": "Podešavanja Oracle-a",
+       "config-header-mssql": "Podešavanja za Microsoft SQL Server",
+       "config-invalid-db-type": "Nevažeći tip baze",
+       "config-missing-db-name": "Morate unijeti vrijednost za \"{{int:config-db-name}}\".",
+       "config-missing-db-host": "Morate unijeti vrijednost za \"{{int:config-db-host}}\".",
+       "config-missing-db-server-oracle": "Morate unijeti vrijednost za \"{{int:config-db-host-oracle}}\".",
+       "config-invalid-db-server-oracle": "Nevažeći TNS „$1”.\nKoristite ili „TNS Name” ili nisku „Easy Connect”.\n([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle metodi imenovanja]).",
+       "config-invalid-db-name": "Ime baze podataka „$1” nije važeće.\nKoristite samo ASCII-slova (a-z, A-Z), brojeve (0-9) i podvlake (_).",
+       "config-invalid-db-prefix": "Prefiks baze podataka „$1” nije važeći.\nKoristite samo ASCII-slova (a-z, A-Z), brojeve (0-9), podvlake (_) i crtice (-).",
+       "config-connection-error": "$1.\n\nProvjerite host, korisničko ime i lozinku i pokušajte ponovno. Ako kao host baze podataka koristite \"localhost\", zamijenite ga \"127.0.0.1\" (ili obrnuto).",
+       "config-invalid-schema": "Šema za MediaWiki „$1” nije važeća.\nKoristite samo ASCII slova (a-z, A-Z), brojeve (0-9) i podvlake (_).",
+       "config-db-sys-create-oracle": "Uspostavljač podržava samo upotrebu SYSDBA-računa za pravljenje novih računa.",
+       "config-db-sys-user-exists-oracle": "Korisnički račun \"$1\" već postoji. SYSDBA samo služi za stvaranje novog računa!",
+       "config-postgres-old": "Zahtijeva se PostgreSQL $1 ili noviji. Vi imate $2.",
+       "config-mssql-old": "Zahtijeva se Microsoft SQL Server $1 ili novija verzija. Vi imate $2.",
+       "config-sqlite-name-help": "Odaberite ime koje će predstavljati vaš wiki.\nNe koristite razmake i crte.\nOvo će se koristiti za ime datoteke SQLite-podataka.",
+       "config-sqlite-parent-unwritable-group": "Nije moguće izraditi direktorijum <code><nowiki>$1</nowiki></code> \njer mrežni poslužitelj ne može pisati u matični direktorijum <code><nowiki>$2</nowiki></code>.\n\nIdentificiran je korisnik pod kojim radi vaš mrežni poslužitelj.\nDa biste nastavili, namjestite da može zapisivati u direktorijum <code><nowiki>$3</nowiki></code>.\nNa Unix/Linux sistemu učinite sljedeće:\n\n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
+       "config-sqlite-parent-unwritable-nogroup": "Nije moguće izraditi direktorijum <code><nowiki>$1</nowiki></code> \njer mrežni poslužitelj ne može pisati u matični direktorijum <code><nowiki>$2</nowiki></code>.\n\nUspostavljač nije mogao odrediti korisnika pod kojim radi vaš mrežni poslužitelj.\nDa biste nastavili, postavite toga (i druge!) da biste se globalno zapisivati u direktorijum <code><nowiki>$3</nowiki></code>.\nNa Unix/Linux sistemu učinite sljedeće:\n\n<pre>cd $2\nmkdir $3\nchmod a+w $3</pre>",
+       "config-sqlite-mkdir-error": "Greška pri pravljenju podatkovnog direktorijuma \"$1\".\nProvjerite gdje se nalazi i pokušajte ponovo.",
+       "config-sqlite-dir-unwritable": "Nije moguće upisati u direktorijum \"$1\".\nU dopuštenjima za nju, omogućite mrežnom poslužitelju da upisuje u njemu i pokušajte ponovo.",
+       "config-sqlite-connection-error": "$1.\n\nProverite podatkovni direktorijum i ime baze podataka, i pokušajte ponovo.",
+       "config-sqlite-readonly": "Datoteka <code>$1</code> je nezapisiva.",
+       "config-sqlite-cant-create-db": "Nisam mogao stvoriti datoteku <code>$1</code> za bazu podataka.",
+       "config-sqlite-fts3-downgrade": "PHP-u nedostaje FTS3 podrška — poništavam nadogradnju tabela",
+       "config-can-upgrade": "U ovoj bazi podataka ima tabele MediaWikija.\nDa biste ih nadogradili na MediaWiki $1, kliknite na <strong>Nastavi</strong>.",
+       "config-upgrade-error": "Došlo je do greške pri obnovi MediaWiki tabela u bazi podataka.\n\nZa više informacija, pogledajte evidenciju iznad. Da biste pokušali ponovo, kliknite na <strong>Nastavi</strong>.",
+       "config-upgrade-done": "Nadogradnja završena.\n\nSada možete [$1 početi koristiti Vaš wiki].\n\nAko želite prestvoriti Vašu datoteku <code>LocalSettings.php</code>, tada kliknite na dugme ispod.\nOvo <strong>nije preporučeno</strong> osim u slučaju problema s wikijem.",
+       "config-upgrade-done-no-regenerate": "Nadogradnja završena.\n\nSad možete [$1 početi da koristite wiki].",
+       "config-regenerate": "Prestvori LocalSettings.php →",
+       "config-show-table-status": "Upit <code>SHOW TABLE STATUS</code> nije uspeo!",
+       "config-unknown-collation": "<strong>Upozorenje:</strong> Baza podataka koristi neprepoznatu uputnu poredbu.",
+       "config-db-web-account": "Račun baze podataka za mrežni pristup",
+       "config-db-web-help": "Odaberite korisničko ime i lozinku koje će koristiti mrežni poslužitelj za povezivanje s poslužiteljem baze podataka tijekom redovitog rada s wikijem.",
+       "config-db-web-account-same": "Koristi isti račun iz uspostave",
+       "config-db-web-create": "Napravi račun ako već ne postoji",
+       "config-db-web-no-create-privs": "Račun koji ste naveli za uspostavu nema dovoljne privilegije za da stvori račun.\nOvdje morate navesti postojeći račun.",
+       "config-mysql-engine": "Skladišni pogon:",
+       "config-mysql-innodb": "InnoDB (preporučeno)",
+       "config-mysql-myisam": "MyISAM",
+       "config-mysql-myisam-dep": "<strong>Upozorenje:</strong> Odabrali ste MyISAM kao skladišni pogon za MySQL. Ali ne preporučuje se za MediaWiki jer:\n* jedva podržava istovremenost iz zaključavanja tabela\n* vjerojatnije je da će ih druge biljke pokvariti\n* kodna baza MediaWikija ne može uvijek ispravno raditi s MyISAM-om\n\nAko vaša uspostava MySQL-a podržava InnoDB, tada seriozno preporučujemo da je koristite umjesto MyISAM.\nAko vaša uspostava MySQL-a ne podržava InnoDB, vjerojatno je vrijeme za nadogradnju.",
+       "config-mysql-only-myisam-dep": "<strong>Upozorenje:</strong> MyISAM je jedini dostupan skladišni pogon za MySQL na ovom stroju, a ovo se ne preporučuje za uporabu s MediaWiki, jer:\n* skoro ne podržava istovremeno izvršavanje zadataka zbog zaključavanja tablica\n* više osjetljiv na kvarenje od drugih pogona \n* kodna baza MediaWIkija ne radi uvijek ispravno s MyISAM-om\nVaša MySQL uspostava ne podržava InnoDB. Možda je vrijeme da ga nadogradimo.",
        "config-admin-password": "Lozinka:",
        "mainpagetext": "<strong>MediaWiki je uspješno instaliran.</strong>",
        "mainpagedocfooter": "Za informacije o korištenju wiki softvera konzultirajte [https://meta.wikimedia.org/wiki/Help:Contents Vodič za korisnike].\n\n== Uvod u rad ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista konfiguracije postavki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista primatelja izdanja MediaWikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokalizirajte MediaWiki za svoj jezik]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Saznajte kako se boriti protiv spama na svojem wikiju]"
index a313371..d0b5e14 100644 (file)
@@ -87,7 +87,7 @@
        "config-using-32bit": "<strong>Varning:</strong> ditt system verkar vara en 32-bitarsversion. Detta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit rekommenderas inte].",
        "config-db-type": "Databastyp:",
        "config-db-host": "Databasvärd:",
-       "config-db-host-help": "Om din databasserver är på en annan server, ange då värdnamnet eller IP-adressen här.\n\nOm du använder ett delat webbhotell, bör din leverantör ge dig rätt värdnamn i deras dokumentation.\n\nOm du installerar på en Windowsserver och använder MySQL, kanske \"localhost\" inte fungerar för servernamnet. Om det inte gör det försök med \"127.0.0.1\" som den lokala IP-adressen.\n\nOm du använder PostgreSQL, lämna detta fält blankt för att ansluta via en Unix-socket.",
+       "config-db-host-help": "Om din databasserver är på en annan server, ange då värdnamnet eller IP-adressen här.\n\nOm du använder ett delat webbhotell, bör din leverantör ge dig rätt värdnamn i deras dokumentation.\n\nOm du använder MySQL, kanske \"localhost\" inte fungerar för servernamnet. Om det inte gör det försök med \"127.0.0.1\" som den lokala IP-adressen.\n\nOm du använder PostgreSQL, lämna detta fält blankt för att ansluta via en Unix-socket.",
        "config-db-host-oracle": "Databas TNS:",
        "config-db-host-oracle-help": "Ange ett giltigt [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Local Connect Name]; en tnsnames.ora-fil måste vara synlig för denna installation.<br />Om du använder klientbibliotek 10g eller nyare kan du också använda [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect] namngivningsmetoden.",
        "config-db-wiki-settings": "Identifiera denna wiki",
        "config-invalid-db-server-oracle": "Ogiltig databas-TNS \"$1\".\nAnvända antingen \"TNS Name\" eller en \"Easy Connect\"-sträng ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracles namngivningsmetoder]).",
        "config-invalid-db-name": "\"$1\" är ett ogiltigt databasnamn.\nAnvänd bara ASCII-bokstäver (a-z, A-Z), siffror (0-9), understreck (_) och bindestreck (-).",
        "config-invalid-db-prefix": "\"$1\" är ett ogiltigt databasprefix.\nAnvänd bara ASCII-bokstäver (a-z, A-Z), siffror (0-9), understreck (_) och bindestreck (-).",
-       "config-connection-error": "$1.\n\nKontrollera värd, användarnamn och lösenord och försök igen.",
+       "config-connection-error": "$1.\n\nKontrollera värd, användarnamn och lösenord och försök igen. Om du använder \"localhost\" som databasvärden, försök använda \"127.0.0.1\" istället (eller tvärtom).",
        "config-invalid-schema": "\"$1\" är ett ogiltigt schema för MediaWiki.\nAnvänd bara ASCII-bokstäver (a-z, A-Z), siffror (0-9), understreck (_) och bindestreck (-).",
        "config-db-sys-create-oracle": "Installationsprogrammet stöder endast användningen av ett SYSDBA-konto för att skapa ett nytt konto.",
        "config-db-sys-user-exists-oracle": "Användarkontot \"$1\" finns redan. SYSDBA kan endast användas för att skapa ett nytt konto!",
        "config-install-done": "<strong>Grattis!</strong>\nDu har installerat MediaWiki.\n\nInstallationsprogrammet har genererat filen <code>LocalSettings.php</code>.\nDet innehåller alla dina konfigurationer.\n\nDu kommer att behöva ladda ner den och placera den i roten för din wiki-installation (samma katalog som index.php). Nedladdningen borde ha startats automatiskt.\n\nOm ingen nedladdning erbjöds, eller om du har avbrutit det kan du starta om nedladdningen genom att klicka på länken nedan:\n\n$3\n\n<strong>OBS</strong>: Om du inte gör detta nu, kommer denna genererade konfigurationsfil inte vara tillgänglig för dig senare om du avslutar installationen utan att ladda ned den.\n\nNär det är klart, kan du <strong>[$2 gå in på din wiki]</strong>",
        "config-install-done-path": "<strong>Grattis!</strong>\nDu har installerat MediaWiki.\n\nInstallationsprogrammet har genererat filen <code>LocalSettings.php</code>.\nDet innehåller alla dina konfigurationer.\n\nDu kommer att behöva ladda ner den och placera den i <code>$4</code>. Nedladdningen borde ha startats automatiskt.\n\nOm ingen nedladdning erbjöds, eller om du har avbrutit det kan du starta om nedladdningen genom att klicka på länken nedan:\n\n$3\n\n<strong>OBS</strong>: Om du inte gör detta nu, kommer denna genererade konfigurationsfil inte vara tillgänglig för dig senare om du avslutar installationen utan att ladda ned den.\n\nNär det är klart, kan du <strong>[$2 gå in på din wiki]</strong>",
        "config-install-success": "MediaWiki har installerats. Du kan nu besöka <$1$2> för att se din wiki.\nOm du undrar någonting, kolla in vår lista över vanliga ställda frågor:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> eller använda något supportforum som länkas på sidan.",
+       "config-install-db-success": "Databasen har konfigurerats",
        "config-download-localsettings": "Ladda ner <code>LocalSettings.php</code>",
        "config-help": "hjälp",
        "config-help-tooltip": "klicka för att expandera",
index b67adb2..54bae6e 100644 (file)
@@ -14,7 +14,8 @@
                        "Piramidion",
                        "Macofe",
                        "Movses",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "Gzhegozh"
                ]
        },
        "config-desc": "Інсталятор MediaWiki",
@@ -92,7 +93,7 @@
        "config-using-32bit": "<strong>Попередження:</strong> схоже, що Ваша система працює з 32-бітними цілими числами. Таке [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit не рекомендується].",
        "config-db-type": "Тип бази даних:",
        "config-db-host": "Хост бази даних:",
-       "config-db-host-help": "Якщо сервер бази даних знаходиться на іншому сервері, введіть тут ім'я хосту і IP адресу.\n\nЯкщо Ви використовуєте віртуальний хостинг, Ваш хостинг-провайдер має надати Вам правильне ім'я хосту у його документації.\n\nЯкщо у Вас сервер із Windows Ви використовуєте MySQL, параметр \"localhost\" може не працювати для імені сервера. Якщо не працює, використайте \"127.0.0.1\" як локальну IP-адресу.\n\nЯкщо Ви використовуєте PostgreSQL, залиште це поле пустим, щоб під'єднатись через сокет Unix.",
+       "config-db-host-help": "Якщо сервер бази даних знаходиться на іншому сервері, введіть тут ім'я хосту і IP-адресу.\n\nЯкщо Ви використовуєте спільний веб-хостинг, Ваш хостинг-провайдер має надати Вам правильне ім'я хосту у його документації.\n\nЯкщо Ви використовуєте MySQL, можливість «localhost» може не працювати для серверного імені. Якщо не працює, використайте «127.0.0.1» як локальну IP-адресу.\n\nЯкщо Ви використовуєте PostgreSQL, залиште це поле пустим, щоб під'єднатись через сокет Unix.",
        "config-db-host-oracle": "TNS бази даних:",
        "config-db-host-oracle-help": "Введіть допустиме [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Local Connect Name]; файл tnsnames.ora має бути видимим для цієї інсталяції. <br />Якщо Ви використовуєте бібліотеки 10g чи новіші, можна також використовувати метод іменування [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect].",
        "config-db-wiki-settings": "Ідентифікувати цю вікі",
        "config-invalid-db-server-oracle": "Неприпустиме TNS бази даних \"$1\".\nВикористовуйте \"TNS Name\" або рядок \"Easy Connect\"  ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Методи найменування Oracle])",
        "config-invalid-db-name": "Неприпустима назва бази даних \"$1\".\nВикористовуйте тільки ASCII букви (a-z, A-Z), цифри (0-9), знаки підкреслення (_) і дефіси (-).",
        "config-invalid-db-prefix": "Неприпустимий префікс бази даних \"$1\".\nВикористовуйте тільки ASCII букви (a-z, A-Z), цифри (0-9), знаки підкреслення (_) і дефіси (-).",
-       "config-connection-error": "$1.\n\nПеревірте хост, ім'я користувача та пароль і спробуйте ще раз.",
+       "config-connection-error": "$1.\n\nПеревірте нижченаведений хост, ім'я користувача та пароль і спробуйте ще раз. Якщо Ви використовуєте «localhost» як хост бази даних, замініть його на «127.0.0.1» (або навпаки)",
        "config-invalid-schema": "Неприпустима схема для MediaWiki \"$1\".\nВикористовуйте тільки ASCII букви (a-z, A-Z), цифри (0-9) і знаки підкреслення(_).",
        "config-db-sys-create-oracle": "Інсталятор підтримує лише використання облікового запису SYSDBA для створення нового облікового запису.",
        "config-db-sys-user-exists-oracle": "Обліковий запис користувача \"$1\" уже існує. SYSDBA використовується лише для створення новий облікових записів!",
        "config-install-begin": "Натискаючи \"{{int:config-continue}}\", Ви розпочинаєте встановлення MediaWiki.\nЯкщо Ви все ще хочете внести зміни, натисніть \"{{int:config-back}}\".",
        "config-install-step-done": "виконано",
        "config-install-step-failed": "не вдалося",
-       "config-install-extensions": "У Ñ\82омÑ\83 Ñ\87иÑ\81лÑ\96 розширення",
+       "config-install-extensions": "Ð\97окÑ\80ема розширення",
        "config-install-database": "Налаштування бази даних",
        "config-install-schema": "Створення схеми",
        "config-install-pg-schema-not-exist": "Схеми PostgreSQL не існує.",
        "config-install-done": "<strong>Вітаємо!</strong>\nВи успішно встановили MediaWiki.\n\nІнсталятор згенерував файл <code>LocalSettings.php</code>, який містить усі Ваші налаштування.\n\nВам необхідно завантажити його і помістити у кореневу папку Вашої вікі (туди ж, де index.php). Завантаження мало початись автоматично.\n\nЯкщо завантаження не почалось або Ви його скасували, можете заново його почати, натиснувши на посилання внизу:\n\n$3\n\n<strong>Примітка</strong>: Якщо Ви не зробите цього зараз, цей файл не буде доступним пізніше, коли Ви вийдете з встановлення, не скачавши його.\n\nПісля виконання дій, описаних вище, Ви зможете <strong>[$2 увійти у свою вікі]</strong>.",
        "config-install-done-path": "<strong>Вітаємо!</strong>\nВи встановили Медіавікі.\n\nІнсталятор створив файл <code>LocalSettings.php</code>.\nУ ньому містяться всі Ваші налаштування.\n\nВам потрібно завантажити його й помістити в <code>$4</code>. Завантаження повинно було автоматично розпочатись.\n\nЯкщо завантаження не було запропоновано, або Ви його скасували, Ви можете перезапустити завантаження натиснувши на посилання нижче:\n\n$3\n\n<strong>Зверніть увагу:</strong> Якщо Ви не зробите це зараз, цей згенерований файл налаштувань не буде доступним для Вас пізніше якщо Ви вийдете зі встановлення не завантаживши його.\n\nКоли це було зроблено Ви можете <strong>[$2 зайти до своєї вікі]</strong>.",
        "config-install-success": "Mediawiki успішно встановлено. Зараз Ви можете перейти до <$1$2>, щоб переглянути свою вікі. Якщо у Вас є питання, ознайомтеся з нашим FAQ: <https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> або використовуйте один з форумів підтримки, які вказано на цій сторінці.",
+       "config-install-db-success": "База даних була успішно сформована",
        "config-download-localsettings": "Завантажити <code>LocalSettings.php</code>",
        "config-help": "допомога",
        "config-help-tooltip": "натисніть, щоб розгорнути",
index f9e918b..4f4a6a6 100644 (file)
@@ -24,7 +24,8 @@
                        "Fengchao",
                        "Duolaimi",
                        "A Chinese Wikipedian",
-                       "水獭很懒"
+                       "水獭很懒",
+                       "Zazzzz"
                ]
        },
        "config-desc": "MediaWiki安装程序",
@@ -85,9 +86,9 @@
        "config-wincache": "已安装[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
        "config-no-cache-apcu": "<strong>警告:</strong>找不到[https://secure.php.net/apcu APCu]或[https://www.iis.net/downloads/microsoft/wincache-extension WinCache]。对象缓存未启用。",
        "config-mod-security": "<strong>警告:</strong>您的web服务器已启用[https://modsecurity.org/ mod_security]/mod_security2。它的很多常见配置可能导致MediaWiki及其他软件允许用户发布任意内容的问题。如果可能,这应当被禁用。否则,当您遭遇随机错误时,请参考[https://modsecurity.org/documentation/ mod_security 文档]或联络您的主机支持。",
-       "config-diff3-bad": "找不到GNU diff3。",
+       "config-diff3-bad": "找不到GNU diff3文字对比工具程序,您可以暂时忽略它,但可能会更频繁遇到编辑冲突。",
        "config-git": "发现Git版本控制软件:<code>$1</code>",
-       "config-git-bad": "Git版本控制软件未找到。",
+       "config-git-bad": "Git版本控制软件未找到,您可以暂时忽略他,另请注意Special:Version不会显示提交散列。",
        "config-imagemagick": "已找到ImageMagick:<code>$1</code>。如果您启用了上传功能,缩略图功能也将被启用。",
        "config-gd": "已找到内建的GD图形库。如果你启用了上传功能,缩略图功能也将被启用。",
        "config-no-scaling": "找不到GD库或ImageMagick。缩略图功能将不可用。",
        "config-db-host-oracle": "数据库透明网络底层(TNS):",
        "config-db-host-oracle-help": "请输入合法的[http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm 本地连接名],并确保tnsnames.ora文件对本安装程序可见。<br />如果您使用的客户端库为10g或更新的版本,您还可以使用[http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm 简单连接名方法](easy connect naming method)。",
        "config-db-wiki-settings": "标识本wiki",
-       "config-db-name": "数据库名称:",
+       "config-db-name": "æ\95°æ\8d®åº\93å\90\8d称ï¼\88ä¸\8d带è¿\9eå­\97å\8f·ï¼\89ï¼\9a",
        "config-db-name-help": "请输入一个可以标识您的wiki的名称。请勿使用空格。\n\n如果您正在使用共享web主机,您的主机提供商或会给您指定一个数据库名称,或会让您通过控制面板创建数据库。",
        "config-db-name-oracle": "数据库模式:",
        "config-db-account-oracle-warn": "现有三种已支持方案可以将Oracle设置为后端数据库:\n\n如果您希望在安装过程中创建数据库帐户,请为安装程序提供具有SYSDBA角色的数据库帐户,并为web访问帐户指定所需身份证明;否则您可以手动创建web访问的账户并仅须提供该帐户(确保帐户已有创建方案对象(schema object)的所需权限);或提供两个不同的帐户,其一具有创建权限,另一则被限制为web访问。\n\n具有所需权限账户的创建脚本存放于本程序的“maintenance/oracle/”目录下。请注意,使用受限制的帐户将禁用默认帐户的所有维护性功能。",
        "config-db-account-lock": "在普通操作中使用相同的用户名和密码",
        "config-db-wiki-account": "用于普通操作的用户帐号",
        "config-db-wiki-help": "输入在普通的wiki操作中(安装完成后)将用于连接数据库的用户名和密码。如果该帐号并不存在,而安装帐号具有足够的权限,该用户帐号会被自动创建,并被赋予足以运行此wiki的最低权限。",
-       "config-db-prefix": "数据库表前缀:",
+       "config-db-prefix": "æ\95°æ\8d®åº\93表å\89\8dç¼\80ï¼\88ä¸\8d带è¿\9eå­\97å\8f·ï¼\89ï¼\9a",
        "config-db-prefix-help": "如果您需要在多个wiki之间(或在MediaWiki与其他web应用程序之间)共享一个数据库,您可以通过添加前缀的方式来避免出现表名称的冲突。请勿使用空格。\n\n此字段通常可留空。",
        "config-mysql-old": "需要MySQL $1或更新的版本,您的版本为$2。",
        "config-db-port": "数据库端口:",
-       "config-db-schema": "MediaWiki的数据库模式",
+       "config-db-schema": "MediaWiki的数据库模式(不带连字号)",
        "config-db-schema-help": "此数据库模式通常是正确的,请在有明确需求时才改动之。",
        "config-pg-test-error": "无法连接到数据库<strong>$1</strong>:$2",
        "config-sqlite-dir": "SQLite数据目录:",
index 52c78c8..5bf0020 100644 (file)
        "config-install-done": "<strong>恭喜!</strong>\n您已經成功安裝MediaWiki。\n\n安裝程式已自動產生<code>LocalSettings.php</code>檔案,\n該檔案中包含了您所有的設定項目。\n\n您需要下載該檔案,並將其放置在您的Wiki的根目錄(index.php所在的目錄)中,下載應已自動開始。\n\n若瀏覽器沒有提示您下載,或者您取消了下載,您可以點選下方連結重新下載:\n\n$3\n\n<strong>注意:</strong>如果您現在不下載此檔案,稍後結束安裝程式之後將無法再下載設定檔。\n\n當您完成本步驟後,您可以<strong>[$2 進入您的Wiki]</strong>。",
        "config-install-done-path": "<strong>恭喜!</strong>\n您已經成功安裝MediaWiki。\n\n安裝程式已自動產生<code>LocalSettings.php</code>檔案,\n該檔案中包含了您所有的設定項目。\n\n您需要下載該檔案,並將其放置在<code>$4</code>中,下載應已自動開始。\n\n若瀏覽器沒有提示您下載,或者您取消了下載,您可以點選下方連結重新下載:\n\n$3\n\n<strong>注意:</strong>如果您現在不下載此檔案,稍後結束安裝程式之後將無法再下載設定檔。\n\n當您完成本步驟後,您可以<strong>[$2 進入您的Wiki]</strong>。",
        "config-install-success": "MediaWiki 已安裝成功。您現在可以在 <$1$2> 上檢視您的 wiki。若您有任何問題,請閱讀常見問題清單:<https://www.mediawiki.org/wiki/Manual:FAQ/zh>,或是利用在頁面上所連結的支援論壇之一。",
+       "config-install-db-success": "資料庫設定成功",
        "config-download-localsettings": "下載 <code>LocalSettings.php</code>",
        "config-help": "說明",
        "config-help-tooltip": "點選以展開",
index 832883b..30826d4 100644 (file)
@@ -36,7 +36,7 @@ class Interwiki {
        protected $mAPI;
 
        /** @var string The name of the database (for a connection to be established
-        *    with LBFactory::getMainLB( 'wikiid' ))
+        *    with LBFactory::getMainLB( 'domainId' ))
         */
        protected $mWikiID;
 
diff --git a/includes/jobqueue/GenericParameterJob.php b/includes/jobqueue/GenericParameterJob.php
new file mode 100644 (file)
index 0000000..f7da42b
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Interface for generic jobs only uses the parameters field.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Interface for generic jobs only uses the parameters field and are JSON serializable
+ *
+ * @ingroup JobQueue
+ * @since 1.33
+ */
+interface GenericParameterJob extends IJobSpecification {
+       /**
+        * @param array $params JSON-serializable map of parameters
+        */
+       public function __construct( array $params );
+}
index 8bc1bc3..2b3caa2 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Job queue task description base code.
+ * Job queue task description interface
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  */
 
 /**
- * Job queue task description interface
+ * Interface for serializable objects that describe a job queue task
+ *
+ * A job specification can be inserted into a queue via JobQueue::push().
+ * The specification parameters should be JSON serializable (e.g. no PHP classes).
+ * Whatever queue the job specification is pushed into is assumed to have job runners
+ * that will eventually pop the job specification from the queue, construct a RunnableJob
+ * instance from the specification, and then execute that instance via RunnableJob::run().
  *
  * @ingroup JobQueue
  * @since 1.23
  */
 interface IJobSpecification {
        /**
-        * @return string Job type
+        * @return string Job type that defines what sort of changes this job makes
         */
        public function getType();
 
        /**
-        * @return array
+        * @return array Parameters that specify sources, targets, and options for execution
         */
        public function getParams();
 
@@ -76,9 +82,4 @@ interface IJobSpecification {
         * @return bool Whether this is job is a root job
         */
        public function isRootJob();
-
-       /**
-        * @return Title Descriptive title (this can simply be informative)
-        */
-       public function getTitle();
 }
index d624acf..6054e35 100644 (file)
@@ -27,7 +27,7 @@
  *
  * @ingroup JobQueue
  */
-abstract class Job implements IJobSpecification {
+abstract class Job implements RunnableJob {
        /** @var string */
        public $command;
 
@@ -41,7 +41,7 @@ abstract class Job implements IJobSpecification {
        protected $title;
 
        /** @var bool Expensive jobs may set this to true */
-       protected $removeDuplicates;
+       protected $removeDuplicates = false;
 
        /** @var string Text for error that occurred last */
        protected $error;
@@ -55,40 +55,50 @@ abstract class Job implements IJobSpecification {
        /** @var int Job must not be wrapped in the usual explicit LBFactory transaction round */
        const JOB_NO_EXPLICIT_TRX_ROUND = 1;
 
-       /**
-        * Run the job
-        * @return bool Success
-        */
-       abstract public function run();
-
        /**
         * Create the appropriate object to handle a specific job
         *
         * @param string $command Job command
-        * @param Title $title Associated title
-        * @param array $params Job parameters
+        * @param array|Title $params Job parameters
         * @throws InvalidArgumentException
         * @return Job
         */
-       public static function factory( $command, Title $title, $params = [] ) {
+       public static function factory( $command, $params = [] ) {
                global $wgJobClasses;
 
+               if ( $params instanceof Title ) {
+                       // Backwards compatibility for old signature ($command, $title, $params)
+                       $title = $params;
+                       $params = func_num_args() >= 3 ? func_get_arg( 2 ) : [];
+               } else {
+                       $title = ( isset( $params['namespace'] ) && isset( $params['title'] ) )
+                               ? Title::makeTitle( $params['namespace'], $params['title'] )
+                               : Title::makeTitle( NS_SPECIAL, '' );
+               }
+
+               $params = is_array( $params ) ? $params : []; // sanity
+
                if ( isset( $wgJobClasses[$command] ) ) {
                        $handler = $wgJobClasses[$command];
 
                        if ( is_callable( $handler ) ) {
                                $job = call_user_func( $handler, $title, $params );
                        } elseif ( class_exists( $handler ) ) {
-                               $job = new $handler( $title, $params );
+                               if ( is_subclass_of( $handler, GenericParameterJob::class ) ) {
+                                       $job = new $handler( $params );
+                               } else {
+                                       $job = new $handler( $title, $params );
+                               }
                        } else {
                                $job = null;
                        }
 
                        if ( $job instanceof Job ) {
                                $job->command = $command;
+
                                return $job;
                        } else {
-                               throw new InvalidArgumentException( "Cannot instantiate job '$command': bad spec!" );
+                               throw new InvalidArgumentException( "Could instantiate job '$command': bad spec!" );
                        }
                }
 
@@ -97,19 +107,33 @@ abstract class Job implements IJobSpecification {
 
        /**
         * @param string $command
-        * @param Title $title
-        * @param array|bool $params Can not be === true
+        * @param array|Title|null $params
         */
-       public function __construct( $command, $title, $params = false ) {
-               $this->command = $command;
-               $this->title = $title;
-               $this->params = is_array( $params ) ? $params : []; // sanity
-
-               // expensive jobs may set this to true
-               $this->removeDuplicates = false;
+       public function __construct( $command, $params = null ) {
+               if ( $params instanceof Title ) {
+                       // Backwards compatibility for old signature ($command, $title, $params)
+                       $title = $params;
+                       $params = func_num_args() >= 3 ? func_get_arg( 2 ) : [];
+                       $params = is_array( $params ) ? $params : []; // sanity
+                       // Set namespace/title params if both are missing and this is not a dummy title
+                       if (
+                               $title->getDBkey() !== '' &&
+                               !isset( $params['namespace'] ) &&
+                               !isset( $params['title'] )
+                       ) {
+                               $params['namespace'] = $title->getNamespace();
+                               $params['title'] = $title->getDBKey();
+                               // Note that JobQueue classes will prefer the parameters over getTitle()
+                               $this->title = $title;
+                       }
+               }
 
-               if ( !isset( $this->params['requestId'] ) ) {
-                       $this->params['requestId'] = WebRequest::getRequestId();
+               $this->command = $command;
+               $this->params = $params + [ 'requestId' => WebRequest::getRequestId() ];
+               if ( $this->title === null ) {
+                       $this->title = ( isset( $params['namespace'] ) && isset( $params['title'] ) )
+                               ? Title::makeTitle( $params['namespace'], $params['title'] )
+                               : Title::makeTitle( NS_SPECIAL, '' );
                }
        }
 
@@ -119,7 +143,7 @@ abstract class Job implements IJobSpecification {
         * @since 1.31
         */
        public function hasExecutionFlag( $flag ) {
-               return ( $this->executionFlags && $flag ) === $flag;
+               return ( $this->executionFlags & $flag ) === $flag;
        }
 
        /**
@@ -132,7 +156,7 @@ abstract class Job implements IJobSpecification {
        /**
         * @return Title
         */
-       public function getTitle() {
+       final public function getTitle() {
                return $this->title;
        }
 
@@ -143,6 +167,36 @@ abstract class Job implements IJobSpecification {
                return $this->params;
        }
 
+       /**
+        * @param string|null $field Metadata field or null to get all the metadata
+        * @return mixed|null Value; null if missing
+        * @since 1.33
+        */
+       public function getMetadata( $field = null ) {
+               if ( $field === null ) {
+                       return $this->metadata;
+               }
+
+               return $this->metadata[$field] ?? null;
+       }
+
+       /**
+        * @param string $field Key name to set the value for
+        * @param mixed $value The value to set the field for
+        * @return mixed|null The prior field value; null if missing
+        * @since 1.33
+        */
+       public function setMetadata( $field, $value ) {
+               $old = $this->getMetadata( $field );
+               if ( $value === null ) {
+                       unset( $this->metadata[$field] );
+               } else {
+                       $this->metadata[$field] = $value;
+               }
+
+               return $old;
+       }
+
        /**
         * @return int|null UNIX timestamp to delay running this job until, otherwise null
         * @since 1.22
@@ -225,8 +279,6 @@ abstract class Job implements IJobSpecification {
        public function getDeduplicationInfo() {
                $info = [
                        'type' => $this->getType(),
-                       'namespace' => $this->getTitle()->getNamespace(),
-                       'title' => $this->getTitle()->getDBkey(),
                        'params' => $this->getParams()
                ];
                if ( is_array( $info['params'] ) ) {
index 660352a..f5ed7b9 100644 (file)
@@ -20,7 +20,7 @@
  * @file
  * @defgroup JobQueue JobQueue
  */
-use MediaWiki\MediaWikiServices;
+use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 
 /**
  * Class to handle enqueueing and running of background jobs
@@ -29,7 +29,7 @@ use MediaWiki\MediaWikiServices;
  * @since 1.21
  */
 abstract class JobQueue {
-       /** @var string Wiki ID */
+       /** @var string DB domain ID */
        protected $domain;
        /** @var string Job type */
        protected $type;
@@ -41,11 +41,11 @@ abstract class JobQueue {
        protected $maxTries;
        /** @var string|bool Read only rationale (or false if r/w) */
        protected $readOnlyReason;
+       /** @var StatsdDataFactoryInterface */
+       protected $stats;
 
        /** @var BagOStuff */
        protected $dupCache;
-       /** @var JobQueueAggregator */
-       protected $aggr;
 
        const QOS_ATOMIC = 1; // integer; "all-or-nothing" job insertions
 
@@ -53,7 +53,7 @@ abstract class JobQueue {
 
        /**
         * @param array $params
-        * @throws MWException
+        * @throws JobQueueError
         */
        protected function __construct( array $params ) {
                $this->domain = $params['domain'] ?? $params['wiki']; // b/c
@@ -66,18 +66,18 @@ abstract class JobQueue {
                        $this->order = $this->optimalOrder();
                }
                if ( !in_array( $this->order, $this->supportedOrders() ) ) {
-                       throw new MWException( __CLASS__ . " does not support '{$this->order}' order." );
+                       throw new JobQueueError( __CLASS__ . " does not support '{$this->order}' order." );
                }
-               $this->dupCache = wfGetCache( CACHE_ANYTHING );
-               $this->aggr = $params['aggregator'] ?? new JobQueueAggregatorNull( [] );
                $this->readOnlyReason = $params['readOnlyReason'] ?? false;
+               $this->stats = $params['stats'] ?? new NullStatsdDataFactory();
+               $this->dupCache = $params['stash'] ?? new EmptyBagOStuff();
        }
 
        /**
         * Get a job queue object of the specified type.
         * $params includes:
         *   - class      : What job class to use (determines job type)
-        *   - wiki       : wiki ID of the wiki the jobs are for (defaults to current wiki)
+        *   - domain     : Database domain ID of the wiki the jobs are for (defaults to current wiki)
         *   - type       : The name of the job types this queue handles
         *   - order      : Order that pop() selects jobs, one of "fifo", "timestamp" or "random".
         *                  If "fifo" is used, the queue will effectively be FIFO. Note that job
@@ -94,28 +94,30 @@ abstract class JobQueue {
         *                  of jobs simply means re-inserting them into the queue. Jobs can be
         *                  attempted up to three times before being discarded.
         *   - readOnlyReason : Set this to a string to make the queue read-only.
+        *   - stash      : A BagOStuff instance that can be used for root job deduplication
+        *   - stats      : A StatsdDataFactoryInterface [optional]
         *
         * Queue classes should throw an exception if they do not support the options given.
         *
         * @param array $params
         * @return JobQueue
-        * @throws MWException
+        * @throws JobQueueError
         */
        final public static function factory( array $params ) {
                $class = $params['class'];
                if ( !class_exists( $class ) ) {
-                       throw new MWException( "Invalid job queue class '$class'." );
+                       throw new JobQueueError( "Invalid job queue class '$class'." );
                }
                $obj = new $class( $params );
                if ( !( $obj instanceof self ) ) {
-                       throw new MWException( "Class '$class' is not a " . __CLASS__ . " class." );
+                       throw new JobQueueError( "Class '$class' is not a " . __CLASS__ . " class." );
                }
 
                return $obj;
        }
 
        /**
-        * @return string Wiki ID
+        * @return string Database domain ID
         */
        final public function getDomain() {
                return $this->domain;
@@ -126,7 +128,7 @@ abstract class JobQueue {
         * @deprecated 1.33
         */
        final public function getWiki() {
-               return $this->domain;
+               return WikiMap::getWikiIdFromDbDomain( $this->domain );
        }
 
        /**
@@ -318,7 +320,7 @@ abstract class JobQueue {
         * @param IJobSpecification[] $jobs
         * @param int $flags Bitfield (supports JobQueue::QOS_ATOMIC)
         * @return void
-        * @throws MWException
+        * @throws JobQueueError
         */
        final public function batchPush( array $jobs, $flags = 0 ) {
                $this->assertNotReadOnly();
@@ -329,16 +331,15 @@ abstract class JobQueue {
 
                foreach ( $jobs as $job ) {
                        if ( $job->getType() !== $this->type ) {
-                               throw new MWException(
+                               throw new JobQueueError(
                                        "Got '{$job->getType()}' job; expected a '{$this->type}' job." );
                        } elseif ( $job->getReleaseTimestamp() && !$this->supportsDelayedJobs() ) {
-                               throw new MWException(
+                               throw new JobQueueError(
                                        "Got delayed '{$job->getType()}' job; delays are not supported." );
                        }
                }
 
                $this->doBatchPush( $jobs, $flags );
-               $this->aggr->notifyQueueNonEmpty( $this->domain, $this->type );
 
                foreach ( $jobs as $job ) {
                        if ( $job->isRootJob() ) {
@@ -359,31 +360,18 @@ abstract class JobQueue {
         * This requires $wgJobClasses to be set for the given job type.
         * Outside callers should use JobQueueGroup::pop() instead of this function.
         *
-        * @throws MWException
-        * @return Job|bool Returns false if there are no jobs
+        * @throws JobQueueError
+        * @return RunnableJob|bool Returns false if there are no jobs
         */
        final public function pop() {
-               global $wgJobClasses;
-
                $this->assertNotReadOnly();
-               if ( !WikiMap::isCurrentWikiDbDomain( $this->domain ) ) {
-                       throw new MWException(
-                               "Cannot pop '{$this->type}' job off foreign '{$this->domain}' wiki queue." );
-               } elseif ( !isset( $wgJobClasses[$this->type] ) ) {
-                       // Do not pop jobs if there is no class for the queue type
-                       throw new MWException( "Unrecognized job type '{$this->type}'." );
-               }
 
                $job = $this->doPop();
 
-               if ( !$job ) {
-                       $this->aggr->notifyQueueEmpty( $this->domain, $this->type );
-               }
-
                // Flag this job as an old duplicate based on its "root" job...
                try {
                        if ( $job && $this->isRootJobOldDuplicate( $job ) ) {
-                               self::incrStats( 'dupe_pops', $this->type );
+                               $this->incrStats( 'dupe_pops', $this->type );
                                $job = DuplicateJob::newFromJob( $job ); // convert to a no-op
                        }
                } catch ( Exception $e ) {
@@ -395,7 +383,7 @@ abstract class JobQueue {
 
        /**
         * @see JobQueue::pop()
-        * @return Job|bool
+        * @return RunnableJob|bool
         */
        abstract protected function doPop();
 
@@ -405,14 +393,14 @@ abstract class JobQueue {
         * This does nothing for certain queue classes or if "claimTTL" is not set.
         * Outside callers should use JobQueueGroup::ack() instead of this function.
         *
-        * @param Job $job
+        * @param RunnableJob $job
         * @return void
-        * @throws MWException
+        * @throws JobQueueError
         */
-       final public function ack( Job $job ) {
+       final public function ack( RunnableJob $job ) {
                $this->assertNotReadOnly();
                if ( $job->getType() !== $this->type ) {
-                       throw new MWException( "Got '{$job->getType()}' job; expected '{$this->type}'." );
+                       throw new JobQueueError( "Got '{$job->getType()}' job; expected '{$this->type}'." );
                }
 
                $this->doAck( $job );
@@ -420,9 +408,9 @@ abstract class JobQueue {
 
        /**
         * @see JobQueue::ack()
-        * @param Job $job
+        * @param RunnableJob $job
         */
-       abstract protected function doAck( Job $job );
+       abstract protected function doAck( RunnableJob $job );
 
        /**
         * Register the "root job" of a given job into the queue for de-duplication.
@@ -452,13 +440,13 @@ abstract class JobQueue {
         * This does nothing for certain queue classes.
         *
         * @param IJobSpecification $job
-        * @throws MWException
+        * @throws JobQueueError
         * @return bool
         */
        final public function deduplicateRootJob( IJobSpecification $job ) {
                $this->assertNotReadOnly();
                if ( $job->getType() !== $this->type ) {
-                       throw new MWException( "Got '{$job->getType()}' job; expected '{$this->type}'." );
+                       throw new JobQueueError( "Got '{$job->getType()}' job; expected '{$this->type}'." );
                }
 
                return $this->doDeduplicateRootJob( $job );
@@ -467,12 +455,12 @@ abstract class JobQueue {
        /**
         * @see JobQueue::deduplicateRootJob()
         * @param IJobSpecification $job
-        * @throws MWException
+        * @throws JobQueueError
         * @return bool
         */
        protected function doDeduplicateRootJob( IJobSpecification $job ) {
                if ( !$job->hasRootJobParams() ) {
-                       throw new MWException( "Cannot register root job; missing parameters." );
+                       throw new JobQueueError( "Cannot register root job; missing parameters." );
                }
                $params = $job->getRootJobParams();
 
@@ -488,19 +476,19 @@ abstract class JobQueue {
                }
 
                // Update the timestamp of the last root job started at the location...
-               return $this->dupCache->set( $key, $params['rootJobTimestamp'], JobQueueDB::ROOTJOB_TTL );
+               return $this->dupCache->set( $key, $params['rootJobTimestamp'], self::ROOTJOB_TTL );
        }
 
        /**
         * Check if the "root" job of a given job has been superseded by a newer one
         *
-        * @param Job $job
-        * @throws MWException
+        * @param IJobSpecification $job
+        * @throws JobQueueError
         * @return bool
         */
-       final protected function isRootJobOldDuplicate( Job $job ) {
+       final protected function isRootJobOldDuplicate( IJobSpecification $job ) {
                if ( $job->getType() !== $this->type ) {
-                       throw new MWException( "Got '{$job->getType()}' job; expected '{$this->type}'." );
+                       throw new JobQueueError( "Got '{$job->getType()}' job; expected '{$this->type}'." );
                }
                $isDuplicate = $this->doIsRootJobOldDuplicate( $job );
 
@@ -509,10 +497,10 @@ abstract class JobQueue {
 
        /**
         * @see JobQueue::isRootJobOldDuplicate()
-        * @param Job $job
+        * @param IJobSpecification $job
         * @return bool
         */
-       protected function doIsRootJobOldDuplicate( Job $job ) {
+       protected function doIsRootJobOldDuplicate( IJobSpecification $job ) {
                if ( !$job->hasRootJobParams() ) {
                        return false; // job has no de-deplication info
                }
@@ -555,10 +543,10 @@ abstract class JobQueue {
 
        /**
         * @see JobQueue::delete()
-        * @throws MWException
+        * @throws JobQueueError
         */
        protected function doDelete() {
-               throw new MWException( "This method is not implemented." );
+               throw new JobQueueError( "This method is not implemented." );
        }
 
        /**
@@ -659,7 +647,7 @@ abstract class JobQueue {
         *
         * @param array $types List of queues types
         * @return array|null (list of non-empty queue types) or null if unsupported
-        * @throws MWException
+        * @throws JobQueueError
         * @since 1.22
         */
        final public function getSiblingQueuesWithJobs( array $types ) {
@@ -682,7 +670,7 @@ abstract class JobQueue {
         *
         * @param array $types List of queues types
         * @return array|null (job type => whether queue is empty) or null if unsupported
-        * @throws MWException
+        * @throws JobQueueError
         * @since 1.22
         */
        final public function getSiblingQueueSizes( array $types ) {
@@ -698,6 +686,16 @@ abstract class JobQueue {
                return null; // not supported
        }
 
+       /**
+        * @param string $command
+        * @param array $params
+        * @return Job
+        */
+       protected function factoryJob( $command, $params ) {
+               // @TODO: dependency inject this as a callback
+               return Job::factory( $command, $params );
+       }
+
        /**
         * @throws JobQueueReadOnlyError
         */
@@ -715,12 +713,8 @@ abstract class JobQueue {
         * @param int $delta
         * @since 1.22
         */
-       public static function incrStats( $key, $type, $delta = 1 ) {
-               static $stats;
-               if ( !$stats ) {
-                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
-               }
-               $stats->updateCount( "jobqueue.{$key}.all", $delta );
-               $stats->updateCount( "jobqueue.{$key}.{$type}", $delta );
+       protected function incrStats( $key, $type, $delta = 1 ) {
+               $this->stats->updateCount( "jobqueue.{$key}.all", $delta );
+               $this->stats->updateCount( "jobqueue.{$key}.{$type}", $delta );
        }
 }
index cda0636..47ee588 100644 (file)
@@ -20,7 +20,7 @@
  * @file
  */
 use Wikimedia\Rdbms\IDatabase;
-use Wikimedia\Rdbms\DBConnRef;
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\DBConnectionError;
 use Wikimedia\Rdbms\DBError;
 use MediaWiki\MediaWikiServices;
@@ -40,23 +40,34 @@ class JobQueueDB extends JobQueue {
 
        /** @var WANObjectCache */
        protected $cache;
+       /** @var IDatabase|DBError|null */
+       protected $conn;
 
-       /** @var bool|string Name of an external DB cluster. False if not set */
-       protected $cluster = false;
+       /** @var array|null Server configuration array */
+       protected $server;
+       /** @var string|null Name of an external DB cluster or null for the local DB cluster */
+       protected $cluster;
 
        /**
         * Additional parameters include:
+        *   - server  : Server configuration array for Database::factory. Overrides "cluster".
         *   - cluster : The name of an external cluster registered via LBFactory.
         *               If not specified, the primary DB cluster for the wiki will be used.
         *               This can be overridden with a custom cluster so that DB handles will
         *               be retrieved via LBFactory::getExternalLB() and getConnection().
+        *   - wanCache : An instance of WANObjectCache to use for caching.
         * @param array $params
         */
        protected function __construct( array $params ) {
                parent::__construct( $params );
 
-               $this->cluster = $params['cluster'] ?? false;
-               $this->cache = ObjectCache::getMainWANInstance();
+               if ( isset( $params['server'] ) ) {
+                       $this->server = $params['server'];
+               } elseif ( isset( $params['cluster'] ) && is_string( $params['cluster'] ) ) {
+                       $this->cluster = $params['cluster'];
+               }
+
+               $this->cache = $params['wanCache'] ?? WANObjectCache::newEmpty();
        }
 
        protected function supportedOrders() {
@@ -73,6 +84,8 @@ class JobQueueDB extends JobQueue {
         */
        protected function doIsEmpty() {
                $dbr = $this->getReplicaDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbr );
                try {
                        $found = $dbr->selectField( // unclaimed job
                                'job', '1', [ 'job_cmd' => $this->type, 'job_token' => '' ], __METHOD__
@@ -96,8 +109,10 @@ class JobQueueDB extends JobQueue {
                        return $size;
                }
 
+               $dbr = $this->getReplicaDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbr );
                try {
-                       $dbr = $this->getReplicaDB();
                        $size = (int)$dbr->selectField( 'job', 'COUNT(*)',
                                [ 'job_cmd' => $this->type, 'job_token' => '' ],
                                __METHOD__
@@ -127,6 +142,8 @@ class JobQueueDB extends JobQueue {
                }
 
                $dbr = $this->getReplicaDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbr );
                try {
                        $count = (int)$dbr->selectField( 'job', 'COUNT(*)',
                                [ 'job_cmd' => $this->type, "job_token != {$dbr->addQuotes( '' )}" ],
@@ -158,6 +175,8 @@ class JobQueueDB extends JobQueue {
                }
 
                $dbr = $this->getReplicaDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbr );
                try {
                        $count = (int)$dbr->selectField( 'job', 'COUNT(*)',
                                [
@@ -185,6 +204,8 @@ class JobQueueDB extends JobQueue {
         */
        protected function doBatchPush( array $jobs, $flags ) {
                $dbw = $this->getMasterDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
                // In general, there will be two cases here:
                // a) sqlite; DB connection is probably a regular round-aware handle.
                // If the connection is busy with a transaction, then defer the job writes
@@ -255,8 +276,8 @@ class JobQueueDB extends JobQueue {
                        foreach ( array_chunk( $rows, 50 ) as $rowBatch ) {
                                $dbw->insert( 'job', $rowBatch, $method );
                        }
-                       JobQueue::incrStats( 'inserts', $this->type, count( $rows ) );
-                       JobQueue::incrStats( 'dupe_inserts', $this->type,
+                       $this->incrStats( 'inserts', $this->type, count( $rows ) );
+                       $this->incrStats( 'dupe_inserts', $this->type,
                                count( $rowSet ) + count( $rowList ) - count( $rows )
                        );
                } catch ( DBError $e ) {
@@ -269,19 +290,16 @@ class JobQueueDB extends JobQueue {
 
        /**
         * @see JobQueue::doPop()
-        * @return Job|bool
+        * @return RunnableJob|bool
         */
        protected function doPop() {
                $dbw = $this->getMasterDB();
-               try {
-                       $autoTrx = $dbw->getFlag( DBO_TRX ); // get current setting
-                       $dbw->clearFlag( DBO_TRX ); // make each query its own transaction
-                       $scopedReset = new ScopedCallback( function () use ( $dbw, $autoTrx ) {
-                               $dbw->setFlag( $autoTrx ? DBO_TRX : 0 ); // restore old setting
-                       } );
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
 
+               $job = false; // job popped off
+               try {
                        $uuid = wfRandomString( 32 ); // pop attempt
-                       $job = false; // job popped off
                        do { // retry when our row is invalid or deleted as a duplicate
                                // Try to reserve a row in the DB...
                                if ( in_array( $this->order, [ 'fifo', 'timestamp' ] ) ) {
@@ -295,13 +313,15 @@ class JobQueueDB extends JobQueue {
                                if ( !$row ) {
                                        break; // nothing to do
                                }
-                               JobQueue::incrStats( 'pops', $this->type );
+                               $this->incrStats( 'pops', $this->type );
+
                                // Get the job object from the row...
-                               $title = Title::makeTitle( $row->job_namespace, $row->job_title );
-                               $job = Job::factory( $row->job_cmd, $title,
-                                       self::extractBlob( $row->job_params ) );
-                               $job->metadata['id'] = $row->job_id;
-                               $job->metadata['timestamp'] = $row->job_timestamp;
+                               $params = self::extractBlob( $row->job_params );
+                               $params = is_array( $params ) ? $params : []; // sanity
+                               $params += [ 'namespace' => $row->job_namespace, 'title' => $row->job_title ];
+                               $job = $this->factoryJob( $row->job_cmd, $params );
+                               $job->setMetadata( 'id', $row->job_id );
+                               $job->setMetadata( 'timestamp', $row->job_timestamp );
                                break; // done
                        } while ( true );
 
@@ -327,6 +347,8 @@ class JobQueueDB extends JobQueue {
         */
        protected function claimRandom( $uuid, $rand, $gte ) {
                $dbw = $this->getMasterDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
                // Check cache to see if the queue has <= OFFSET items
                $tinyQueue = $this->cache->get( $this->getCacheKey( 'small' ) );
 
@@ -404,6 +426,8 @@ class JobQueueDB extends JobQueue {
         */
        protected function claimOldest( $uuid ) {
                $dbw = $this->getMasterDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
 
                $row = false; // the row acquired
                do {
@@ -459,27 +483,27 @@ class JobQueueDB extends JobQueue {
 
        /**
         * @see JobQueue::doAck()
-        * @param Job $job
+        * @param RunnableJob $job
         * @throws MWException
         */
-       protected function doAck( Job $job ) {
-               if ( !isset( $job->metadata['id'] ) ) {
+       protected function doAck( RunnableJob $job ) {
+               $id = $job->getMetadata( 'id' );
+               if ( $id === null ) {
                        throw new MWException( "Job of type '{$job->getType()}' has no ID." );
                }
 
                $dbw = $this->getMasterDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
                try {
-                       $autoTrx = $dbw->getFlag( DBO_TRX ); // get current setting
-                       $dbw->clearFlag( DBO_TRX ); // make each query its own transaction
-                       $scopedReset = new ScopedCallback( function () use ( $dbw, $autoTrx ) {
-                               $dbw->setFlag( $autoTrx ? DBO_TRX : 0 ); // restore old setting
-                       } );
-
                        // Delete a row with a single DELETE without holding row locks over RTTs...
-                       $dbw->delete( 'job',
-                               [ 'job_cmd' => $this->type, 'job_id' => $job->metadata['id'] ], __METHOD__ );
+                       $dbw->delete(
+                               'job',
+                               [ 'job_cmd' => $this->type, 'job_id' => $id ],
+                               __METHOD__
+                       );
 
-                       JobQueue::incrStats( 'acks', $this->type );
+                       $this->incrStats( 'acks', $this->type );
                } catch ( DBError $e ) {
                        $this->throwDBException( $e );
                }
@@ -505,6 +529,9 @@ class JobQueueDB extends JobQueue {
                // maintained. Having only the de-duplication registration succeed would cause
                // jobs to become no-ops without any actual jobs that made them redundant.
                $dbw = $this->getMasterDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
+
                $cache = $this->dupCache;
                $dbw->onTransactionCommitOrIdle(
                        function () use ( $cache, $params, $key ) {
@@ -528,6 +555,8 @@ class JobQueueDB extends JobQueue {
         */
        protected function doDelete() {
                $dbw = $this->getMasterDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
                try {
                        $dbw->delete( 'job', [ 'job_cmd' => $this->type ] );
                } catch ( DBError $e ) {
@@ -542,9 +571,15 @@ class JobQueueDB extends JobQueue {
         * @return void
         */
        protected function doWaitForBackups() {
+               if ( $this->server ) {
+                       return; // not using LBFactory instance
+               }
+
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               $lbFactory->waitForReplication(
-                       [ 'domain' => $this->domain, 'cluster' => $this->cluster ] );
+               $lbFactory->waitForReplication( [
+                       'domain' => $this->domain,
+                       'cluster' => is_string( $this->cluster ) ? $this->cluster : false
+               ] );
        }
 
        /**
@@ -578,17 +613,22 @@ class JobQueueDB extends JobQueue {
         */
        protected function getJobIterator( array $conds ) {
                $dbr = $this->getReplicaDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbr );
                try {
                        return new MappedIterator(
                                $dbr->select( 'job', self::selectFields(), $conds ),
                                function ( $row ) {
-                                       $job = Job::factory(
-                                               $row->job_cmd,
-                                               Title::makeTitle( $row->job_namespace, $row->job_title ),
-                                               strlen( $row->job_params ) ? unserialize( $row->job_params ) : []
-                                       );
-                                       $job->metadata['id'] = $row->job_id;
-                                       $job->metadata['timestamp'] = $row->job_timestamp;
+                                       $params = strlen( $row->job_params ) ? unserialize( $row->job_params ) : [];
+                                       $params = is_array( $params ) ? $params : []; // sanity
+                                       $params += [
+                                               'namespace' => $row->job_namespace,
+                                               'title' => $row->job_title
+                                       ];
+
+                                       $job = $this->factoryJob( $row->job_cmd, $params );
+                                       $job->setMetadata( 'id', $row->job_id );
+                                       $job->setMetadata( 'timestamp', $row->job_timestamp );
 
                                        return $job;
                                }
@@ -599,13 +639,19 @@ class JobQueueDB extends JobQueue {
        }
 
        public function getCoalesceLocationInternal() {
-               return $this->cluster
+               if ( $this->server ) {
+                       return null; // not using the LBFactory instance
+               }
+
+               return is_string( $this->cluster )
                        ? "DBCluster:{$this->cluster}:{$this->domain}"
                        : "LBFactory:{$this->domain}";
        }
 
        protected function doGetSiblingQueuesWithJobs( array $types ) {
                $dbr = $this->getReplicaDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbr );
                // @note: this does not check whether the jobs are claimed or not.
                // This is useful so JobQueueGroup::pop() also sees queues that only
                // have stale jobs. This lets recycleAndDeleteStaleJobs() re-enqueue
@@ -623,6 +669,9 @@ class JobQueueDB extends JobQueue {
 
        protected function doGetSiblingQueueSizes( array $types ) {
                $dbr = $this->getReplicaDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbr );
+
                $res = $dbr->select( 'job', [ 'job_cmd', 'COUNT(*) AS count' ],
                        [ 'job_cmd' => $types ], __METHOD__, [ 'GROUP BY' => 'job_cmd' ] );
 
@@ -643,6 +692,8 @@ class JobQueueDB extends JobQueue {
                $now = time();
                $count = 0; // affected rows
                $dbw = $this->getMasterDB();
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedNoTrxFlag( $dbw );
 
                try {
                        if ( !$dbw->lock( "jobqueue-recycle-{$this->type}", __METHOD__, 1 ) ) {
@@ -682,8 +733,7 @@ class JobQueueDB extends JobQueue {
                                        );
                                        $affected = $dbw->affectedRows();
                                        $count += $affected;
-                                       JobQueue::incrStats( 'recycles', $this->type, $affected );
-                                       $this->aggr->notifyQueueNonEmpty( $this->domain, $this->type );
+                                       $this->incrStats( 'recycles', $this->type, $affected );
                                }
                        }
 
@@ -709,7 +759,7 @@ class JobQueueDB extends JobQueue {
                                $dbw->delete( 'job', [ 'job_id' => $ids ], __METHOD__ );
                                $affected = $dbw->affectedRows();
                                $count += $affected;
-                               JobQueue::incrStats( 'abandons', $this->type, $affected );
+                               $this->incrStats( 'abandons', $this->type, $affected );
                        }
 
                        $dbw->unlock( "jobqueue-recycle-{$this->type}", __METHOD__ );
@@ -729,8 +779,8 @@ class JobQueueDB extends JobQueue {
                return [
                        // Fields that describe the nature of the job
                        'job_cmd' => $job->getType(),
-                       'job_namespace' => $job->getTitle()->getNamespace(),
-                       'job_title' => $job->getTitle()->getDBkey(),
+                       'job_namespace' => $job->getParams()['namespace'] ?? NS_SPECIAL,
+                       'job_title' => $job->getParams()['title'] ?? '',
                        'job_params' => self::makeBlob( $job->getParams() ),
                        // Additional job metadata
                        'job_timestamp' => $db->timestamp(),
@@ -744,7 +794,7 @@ class JobQueueDB extends JobQueue {
 
        /**
         * @throws JobQueueConnectionError
-        * @return DBConnRef
+        * @return IDatabase
         */
        protected function getReplicaDB() {
                try {
@@ -756,7 +806,7 @@ class JobQueueDB extends JobQueue {
 
        /**
         * @throws JobQueueConnectionError
-        * @return DBConnRef
+        * @return IDatabase
         */
        protected function getMasterDB() {
                try {
@@ -768,20 +818,52 @@ class JobQueueDB extends JobQueue {
 
        /**
         * @param int $index (DB_REPLICA/DB_MASTER)
-        * @return DBConnRef
+        * @return IDatabase
         */
        protected function getDB( $index ) {
-               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               $lb = ( $this->cluster !== false )
-                       ? $lbFactory->getExternalLB( $this->cluster )
-                       : $lbFactory->getMainLB( $this->domain );
-
-               return ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' )
-                       // Keep a separate connection to avoid contention and deadlocks;
-                       // However, SQLite has the opposite behavior due to DB-level locking.
-                       ? $lb->getConnectionRef( $index, [], $this->domain, $lb::CONN_TRX_AUTOCOMMIT )
-                       // Jobs insertion will be defered until the PRESEND stage to reduce contention.
-                       : $lb->getConnectionRef( $index, [], $this->domain );
+               if ( $this->server ) {
+                       if ( $this->conn instanceof IDatabase ) {
+                               return $this->conn;
+                       } elseif ( $this->conn instanceof DBError ) {
+                               throw $this->conn;
+                       }
+
+                       try {
+                               $this->conn = Database::factory( $this->server['type'], $this->server );
+                       } catch ( DBError $e ) {
+                               $this->conn = $e;
+                               throw $e;
+                       }
+
+                       return $this->conn;
+               } else {
+                       $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+                       $lb = is_string( $this->cluster )
+                               ? $lbFactory->getExternalLB( $this->cluster )
+                               : $lbFactory->getMainLB( $this->domain );
+
+                       return ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' )
+                               // Keep a separate connection to avoid contention and deadlocks;
+                               // However, SQLite has the opposite behavior due to DB-level locking.
+                               ? $lb->getConnectionRef( $index, [], $this->domain, $lb::CONN_TRX_AUTOCOMMIT )
+                               // Jobs insertion will be defered until the PRESEND stage to reduce contention.
+                               : $lb->getConnectionRef( $index, [], $this->domain );
+               }
+       }
+
+       /**
+        * @param IDatabase $db
+        * @return ScopedCallback
+        */
+       private function getScopedNoTrxFlag( IDatabase $db ) {
+               $autoTrx = $db->getFlag( DBO_TRX ); // get current setting
+               $db->clearFlag( DBO_TRX ); // make each query its own transaction
+
+               return new ScopedCallback( function () use ( $db, $autoTrx ) {
+                       if ( $autoTrx ) {
+                               $db->setFlag( DBO_TRX ); // restore old setting
+                       }
+               } );
        }
 
        /**
index 2025bf7..8b5a62e 100644 (file)
@@ -199,7 +199,7 @@ class JobQueueFederated extends JobQueue {
         * @param HashRing &$partitionRing
         * @param int $flags
         * @throws JobQueueError
-        * @return array List of Job object that could not be inserted
+        * @return IJobSpecification[] List of Job object that could not be inserted
         */
        protected function tryJobInsertions( array $jobs, HashRing &$partitionRing, $flags ) {
                $jobsLeft = [];
@@ -287,7 +287,7 @@ class JobQueueFederated extends JobQueue {
                                $job = false;
                        }
                        if ( $job ) {
-                               $job->metadata['QueuePartition'] = $partition;
+                               $job->setMetadata( 'QueuePartition', $partition );
 
                                return $job;
                        } else {
@@ -299,15 +299,16 @@ class JobQueueFederated extends JobQueue {
                return false;
        }
 
-       protected function doAck( Job $job ) {
-               if ( !isset( $job->metadata['QueuePartition'] ) ) {
+       protected function doAck( RunnableJob $job ) {
+               $partition = $job->getMetadata( 'QueuePartition' );
+               if ( $partition === null ) {
                        throw new MWException( "The given job has no defined partition name." );
                }
 
-               $this->partitionQueues[$job->metadata['QueuePartition']]->ack( $job );
+               $this->partitionQueues[$partition]->ack( $job );
        }
 
-       protected function doIsRootJobOldDuplicate( Job $job ) {
+       protected function doIsRootJobOldDuplicate( IJobSpecification $job ) {
                $signature = $job->getRootJobParams()['rootJobSignature'];
                $partition = $this->partitionRing->getLiveLocation( $signature );
                try {
index 328f298..83e5fb2 100644 (file)
@@ -114,11 +114,15 @@ class JobQueueGroup {
                } else {
                        $conf = $conf + $wgJobTypeConf['default'];
                }
-               $conf['aggregator'] = JobQueueAggregator::singleton();
                if ( !isset( $conf['readOnlyReason'] ) ) {
                        $conf['readOnlyReason'] = $this->readOnlyReason;
                }
 
+               $services = MediaWikiServices::getInstance();
+               $conf['stats'] = $services->getStatsdDataFactory();
+               $conf['wanCache'] = $services->getMainWANObjectCache();
+               $conf['stash'] = $services->getMainObjectStash();
+
                return JobQueue::factory( $conf );
        }
 
@@ -230,11 +234,21 @@ class JobQueueGroup {
         * @param int|string $qtype JobQueueGroup::TYPE_* constant or job type string
         * @param int $flags Bitfield of JobQueueGroup::USE_* constants
         * @param array $blacklist List of job types to ignore
-        * @return Job|bool Returns false on failure
+        * @return RunnableJob|bool Returns false on failure
         */
        public function pop( $qtype = self::TYPE_DEFAULT, $flags = 0, array $blacklist = [] ) {
+               global $wgJobClasses;
+
                $job = false;
 
+               if ( !WikiMap::isCurrentWikiDbDomain( $this->domain ) ) {
+                       throw new JobQueueError(
+                               "Cannot pop '{$qtype}' job off foreign '{$this->domain}' wiki queue." );
+               } elseif ( is_string( $qtype ) && !isset( $wgJobClasses[$qtype] ) ) {
+                       // Do not pop jobs if there is no class for the queue type
+                       throw new JobQueueError( "Unrecognized job type '$qtype'." );
+               }
+
                if ( is_string( $qtype ) ) { // specific job type
                        if ( !in_array( $qtype, $blacklist ) ) {
                                $job = $this->get( $qtype )->pop();
@@ -353,12 +367,14 @@ class JobQueueGroup {
        /**
         * Get the list of job types that have non-empty queues
         *
-        * @return array List of job types that have non-empty queues
+        * @return string[] List of job types that have non-empty queues
         */
        public function getQueuesWithJobs() {
                $types = [];
                foreach ( $this->getCoalescedQueues() as $info ) {
-                       $nonEmpty = $info['queue']->getSiblingQueuesWithJobs( $this->getQueueTypes() );
+                       /** @var JobQueue $queue */
+                       $queue = $info['queue'];
+                       $nonEmpty = $queue->getSiblingQueuesWithJobs( $this->getQueueTypes() );
                        if ( is_array( $nonEmpty ) ) { // batching features supported
                                $types = array_merge( $types, $nonEmpty );
                        } else { // we have to go through the queues in the bucket one-by-one
@@ -376,12 +392,14 @@ class JobQueueGroup {
        /**
         * Get the size of the queus for a list of job types
         *
-        * @return array Map of (job type => size)
+        * @return int[] Map of (job type => size)
         */
        public function getQueueSizes() {
                $sizeMap = [];
                foreach ( $this->getCoalescedQueues() as $info ) {
-                       $sizes = $info['queue']->getSiblingQueueSizes( $this->getQueueTypes() );
+                       /** @var JobQueue $queue */
+                       $queue = $info['queue'];
+                       $sizes = $queue->getSiblingQueueSizes( $this->getQueueTypes() );
                        if ( is_array( $sizes ) ) { // batching features supported
                                $sizeMap = $sizeMap + $sizes;
                        } else { // we have to go through the queues in the bucket one-by-one
@@ -395,7 +413,7 @@ class JobQueueGroup {
        }
 
        /**
-        * @return array
+        * @return JobQueue[]
         */
        protected function getCoalescedQueues() {
                global $wgJobTypeConf;
@@ -404,7 +422,7 @@ class JobQueueGroup {
                        $this->coalescedQueues = [];
                        foreach ( $wgJobTypeConf as $type => $conf ) {
                                $queue = JobQueue::factory(
-                                       [ 'wiki' => $this->domain, 'type' => 'null' ] + $conf );
+                                       [ 'domain' => $this->domain, 'type' => 'null' ] + $conf );
                                $loc = $queue->getCoalesceLocationInternal();
                                if ( !isset( $this->coalescedQueues[$loc] ) ) {
                                        $this->coalescedQueues[$loc]['queue'] = $queue;
index 9b1fbdf..cb20a76 100644 (file)
@@ -32,6 +32,12 @@ class JobQueueMemory extends JobQueue {
        /** @var array[] */
        protected static $data = [];
 
+       public function __construct( array $params ) {
+               parent::__construct( $params );
+
+               $this->dupCache = new HashBagOStuff();
+       }
+
        /**
         * @see JobQueue::doBatchPush
         *
@@ -43,10 +49,7 @@ class JobQueueMemory extends JobQueue {
 
                foreach ( $jobs as $job ) {
                        if ( $job->ignoreDuplicates() ) {
-                               $sha1 = Wikimedia\base_convert(
-                                       sha1( serialize( $job->getDeduplicationInfo() ) ),
-                                       16, 36, 31
-                               );
+                               $sha1 = sha1( serialize( $job->getDeduplicationInfo() ) );
                                if ( !isset( $unclaimed[$sha1] ) ) {
                                        $unclaimed[$sha1] = $job;
                                }
@@ -108,7 +111,7 @@ class JobQueueMemory extends JobQueue {
        /**
         * @see JobQueue::doPop
         *
-        * @return Job|bool
+        * @return RunnableJob|bool
         */
        protected function doPop() {
                if ( $this->doGetSize() == 0 ) {
@@ -132,7 +135,7 @@ class JobQueueMemory extends JobQueue {
                $job = $this->jobFromSpecInternal( $spec );
 
                end( $claimed );
-               $job->metadata['claimId'] = key( $claimed );
+               $job->setMetadata( 'claimId', key( $claimed ) );
 
                return $job;
        }
@@ -140,15 +143,15 @@ class JobQueueMemory extends JobQueue {
        /**
         * @see JobQueue::doAck
         *
-        * @param Job $job
+        * @param RunnableJob $job
         */
-       protected function doAck( Job $job ) {
+       protected function doAck( RunnableJob $job ) {
                if ( $this->getAcquiredCount() == 0 ) {
                        return;
                }
 
                $claimed =& $this->getQueueData( 'claimed' );
-               unset( $claimed[$job->metadata['claimId']] );
+               unset( $claimed[$job->getMetadata( 'claimId' )] );
        }
 
        /**
@@ -203,11 +206,10 @@ class JobQueueMemory extends JobQueue {
 
        /**
         * @param IJobSpecification $spec
-        *
-        * @return Job
+        * @return RunnableJob
         */
        public function jobFromSpecInternal( IJobSpecification $spec ) {
-               return Job::factory( $spec->getType(), $spec->getTitle(), $spec->getParams() );
+               return $this->factoryJob( $spec->getType(), $spec->getParams() );
        }
 
        /**
index 5e7a115..8864688 100644 (file)
@@ -225,9 +225,9 @@ class JobQueueRedis extends JobQueue {
                                        $failed += count( $itemBatch );
                                }
                        }
-                       JobQueue::incrStats( 'inserts', $this->type, count( $items ) );
-                       JobQueue::incrStats( 'inserts_actual', $this->type, $pushed );
-                       JobQueue::incrStats( 'dupe_inserts', $this->type,
+                       $this->incrStats( 'inserts', $this->type, count( $items ) );
+                       $this->incrStats( 'inserts_actual', $this->type, $pushed );
+                       $this->incrStats( 'dupe_inserts', $this->type,
                                count( $items ) - $failed - $pushed );
                        if ( $failed > 0 ) {
                                $err = "Could not insert {$failed} {$this->type} job(s).";
@@ -307,7 +307,7 @@ LUA;
 
        /**
         * @see JobQueue::doPop()
-        * @return Job|bool
+        * @return RunnableJob|bool
         * @throws JobQueueError
         */
        protected function doPop() {
@@ -321,7 +321,7 @@ LUA;
                                        break; // no jobs; nothing to do
                                }
 
-                               JobQueue::incrStats( 'pops', $this->type );
+                               $this->incrStats( 'pops', $this->type );
                                $item = $this->unserialize( $blob );
                                if ( $item === false ) {
                                        wfDebugLog( 'JobQueueRedis', "Could not unserialize {$this->type} job." );
@@ -379,17 +379,17 @@ LUA;
 
        /**
         * @see JobQueue::doAck()
-        * @param Job $job
-        * @return Job|bool
+        * @param RunnableJob $job
+        * @return RunnableJob|bool
         * @throws UnexpectedValueException
         * @throws JobQueueError
         */
-       protected function doAck( Job $job ) {
-               if ( !isset( $job->metadata['uuid'] ) ) {
+       protected function doAck( RunnableJob $job ) {
+               $uuid = $job->getMetadata( 'uuid' );
+               if ( $uuid === null ) {
                        throw new UnexpectedValueException( "Job of type '{$job->getType()}' has no UUID." );
                }
 
-               $uuid = $job->metadata['uuid'];
                $conn = $this->getConnection();
                try {
                        static $script =
@@ -424,7 +424,7 @@ LUA;
                                return false;
                        }
 
-                       JobQueue::incrStats( 'acks', $this->type );
+                       $this->incrStats( 'acks', $this->type );
                } catch ( RedisException $e ) {
                        $this->throwRedisException( $conn, $e );
                }
@@ -463,11 +463,11 @@ LUA;
 
        /**
         * @see JobQueue::doIsRootJobOldDuplicate()
-        * @param Job $job
+        * @param IJobSpecification $job
         * @return bool
         * @throws JobQueueError
         */
-       protected function doIsRootJobOldDuplicate( Job $job ) {
+       protected function doIsRootJobOldDuplicate( IJobSpecification $job ) {
                if ( !$job->hasRootJobParams() ) {
                        return false; // job has no de-deplication info
                }
@@ -627,7 +627,7 @@ LUA;
         *
         * @param string $uid
         * @param RedisConnRef $conn
-        * @return Job|bool Returns false if the job does not exist
+        * @return RunnableJob|bool Returns false if the job does not exist
         * @throws JobQueueError
         * @throws UnexpectedValueException
         */
@@ -641,12 +641,15 @@ LUA;
                        if ( !is_array( $item ) ) { // this shouldn't happen
                                throw new UnexpectedValueException( "Could not find job with ID '$uid'." );
                        }
-                       $title = Title::makeTitle( $item['namespace'], $item['title'] );
-                       $job = Job::factory( $item['type'], $title, $item['params'] );
-                       $job->metadata['uuid'] = $item['uuid'];
-                       $job->metadata['timestamp'] = $item['timestamp'];
+
+                       $params = $item['params'];
+                       $params += [ 'namespace' => $item['namespace'], 'title' => $item['title'] ];
+                       $job = $this->factoryJob( $item['type'], $params );
+                       $job->setMetadata( 'uuid', $item['uuid'] );
+                       $job->setMetadata( 'timestamp', $item['timestamp'] );
                        // Add in attempt count for debugging at showJobs.php
-                       $job->metadata['attempts'] = $conn->hGet( $this->getQueueKey( 'h-attempts' ), $uid );
+                       $job->setMetadata( 'attempts',
+                               $conn->hGet( $this->getQueueKey( 'h-attempts' ), $uid ) );
 
                        return $job;
                } catch ( RedisException $e ) {
@@ -683,8 +686,8 @@ LUA;
                return [
                        // Fields that describe the nature of the job
                        'type' => $job->getType(),
-                       'namespace' => $job->getTitle()->getNamespace(),
-                       'title' => $job->getTitle()->getDBkey(),
+                       'namespace' => $job->getParams()['namespace'] ?? NS_SPECIAL,
+                       'title' => $job->getParams()['title'] ?? '',
                        'params' => $job->getParams(),
                        // Some jobs cannot run until a "release timestamp"
                        'rtimestamp' => $job->getReleaseTimestamp() ?: 0,
@@ -699,13 +702,15 @@ LUA;
 
        /**
         * @param array $fields
-        * @return Job|bool
+        * @return RunnableJob|bool
         */
        protected function getJobFromFields( array $fields ) {
-               $title = Title::makeTitle( $fields['namespace'], $fields['title'] );
-               $job = Job::factory( $fields['type'], $title, $fields['params'] );
-               $job->metadata['uuid'] = $fields['uuid'];
-               $job->metadata['timestamp'] = $fields['timestamp'];
+               $params = $fields['params'];
+               $params += [ 'namespace' => $fields['namespace'], 'title' => $fields['title'] ];
+
+               $job = $this->factoryJob( $fields['type'], $params );
+               $job->setMetadata( 'uuid', $fields['uuid'] );
+               $job->setMetadata( 'timestamp', $fields['timestamp'] );
 
                return $job;
        }
index 4abbc6d..80a46d0 100644 (file)
@@ -28,8 +28,7 @@
  * $job = new JobSpecification(
  *             'null',
  *             array( 'lives' => 1, 'usleep' => 100, 'pi' => 3.141569 ),
- *             array( 'removeDuplicates' => 1 ),
- *             Title::makeTitle( NS_SPECIAL, 'nullity' )
+ *             array( 'removeDuplicates' => 1 )
  * );
  * JobQueueGroup::singleton()->push( $job )
  * @endcode
@@ -63,8 +62,19 @@ class JobSpecification implements IJobSpecification {
                $this->validateParams( $opts );
 
                $this->type = $type;
+               if ( $title instanceof Title ) {
+                       // Make sure JobQueue classes can pull the title from parameters alone
+                       if ( $title->getDBkey() !== '' ) {
+                               $params += [
+                                       'namespace' => $title->getNamespace(),
+                                       'title' => $title->getDBkey()
+                               ];
+                       }
+               } else {
+                       $title = Title::makeTitle( NS_SPECIAL, '' );
+               }
                $this->params = $params;
-               $this->title = $title ?: Title::makeTitle( NS_SPECIAL, 'Badtitle/' . static::class );
+               $this->title = $title;
                $this->opts = $opts;
        }
 
diff --git a/includes/jobqueue/RunnableJob.php b/includes/jobqueue/RunnableJob.php
new file mode 100644 (file)
index 0000000..e477b12
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Job queue task instance that can be executed via a run() method
+ *
+ * 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
+ */
+
+/**
+ * Job that has a run() method and metadata accessors for JobQueue::pop() and JobQueue::ack()
+ *
+ * Instances are not only enqueueable via JobQueue::push(), but they can also be executed by
+ * by calling their run() method. When constructing a job to be enqueued via JobQueue::push(),
+ * it will not be possible to construct a RunnableJob instance if the class for that job is not
+ * loaded by the application for the local DB domain. In that case, the general-purpose
+ * JobSpecification class can be used instead.
+ *
+ * @ingroup JobQueue
+ * @since 1.33
+ */
+interface RunnableJob extends IJobSpecification {
+       /**
+        * Run the job
+        * @return bool Success
+        */
+       public function run();
+
+       /**
+        * @param string|null $field Metadata field or null to get all the metadata
+        * @return mixed|null Value; null if missing
+        */
+       public function getMetadata( $field = null );
+
+       /**
+        * @param string $field Key name to set the value for
+        * @param mixed $value The value to set the field for
+        * @return mixed|null The prior field value; null if missing
+        */
+       public function setMetadata( $field, $value );
+}
diff --git a/includes/jobqueue/aggregator/JobQueueAggregator.php b/includes/jobqueue/aggregator/JobQueueAggregator.php
deleted file mode 100644 (file)
index 27ad88e..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-/**
- * Job queue aggregator code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Class to handle tracking information about all queues
- *
- * @ingroup JobQueue
- * @since 1.21
- */
-abstract class JobQueueAggregator {
-       /** @var JobQueueAggregator */
-       protected static $instance = null;
-
-       /**
-        * @param array $params
-        */
-       public function __construct( array $params ) {
-       }
-
-       /**
-        * @throws MWException
-        * @return JobQueueAggregator
-        */
-       final public static function singleton() {
-               global $wgJobQueueAggregator;
-
-               if ( !isset( self::$instance ) ) {
-                       $class = $wgJobQueueAggregator['class'];
-                       $obj = new $class( $wgJobQueueAggregator );
-                       if ( !( $obj instanceof JobQueueAggregator ) ) {
-                               throw new MWException( "Class '$class' is not a JobQueueAggregator class." );
-                       }
-                       self::$instance = $obj;
-               }
-
-               return self::$instance;
-       }
-
-       /**
-        * Destroy the singleton instance
-        *
-        * @return void
-        */
-       final public static function destroySingleton() {
-               self::$instance = null;
-       }
-
-       /**
-        * Mark a queue as being empty
-        *
-        * @param string $wiki
-        * @param string $type
-        * @return bool Success
-        */
-       final public function notifyQueueEmpty( $wiki, $type ) {
-               $ok = $this->doNotifyQueueEmpty( $wiki, $type );
-
-               return $ok;
-       }
-
-       /**
-        * @see JobQueueAggregator::notifyQueueEmpty()
-        * @param string $wiki
-        * @param string $type
-        * @return bool
-        */
-       abstract protected function doNotifyQueueEmpty( $wiki, $type );
-
-       /**
-        * Mark a queue as being non-empty
-        *
-        * @param string $wiki
-        * @param string $type
-        * @return bool Success
-        */
-       final public function notifyQueueNonEmpty( $wiki, $type ) {
-               $ok = $this->doNotifyQueueNonEmpty( $wiki, $type );
-
-               return $ok;
-       }
-
-       /**
-        * @see JobQueueAggregator::notifyQueueNonEmpty()
-        * @param string $wiki
-        * @param string $type
-        * @return bool
-        */
-       abstract protected function doNotifyQueueNonEmpty( $wiki, $type );
-
-       /**
-        * Get the list of all of the queues with jobs
-        *
-        * @return array (job type => (list of wiki IDs))
-        */
-       final public function getAllReadyWikiQueues() {
-               $res = $this->doGetAllReadyWikiQueues();
-
-               return $res;
-       }
-
-       /**
-        * @see JobQueueAggregator::getAllReadyWikiQueues()
-        */
-       abstract protected function doGetAllReadyWikiQueues();
-
-       /**
-        * Purge all of the aggregator information
-        *
-        * @return bool Success
-        */
-       final public function purge() {
-               $res = $this->doPurge();
-
-               return $res;
-       }
-
-       /**
-        * @see JobQueueAggregator::purge()
-        */
-       abstract protected function doPurge();
-
-       /**
-        * Get all databases that have a pending job.
-        * This poll all the queues and is this expensive.
-        *
-        * @return array (job type => (list of wiki IDs))
-        */
-       protected function findPendingWikiQueues() {
-               global $wgLocalDatabases;
-
-               $pendingDBs = []; // (job type => (db list))
-               foreach ( $wgLocalDatabases as $wikiId ) {
-                       foreach ( JobQueueGroup::singleton( $wikiId )->getQueuesWithJobs() as $type ) {
-                               $pendingDBs[$type][] = $wikiId;
-                       }
-               }
-
-               return $pendingDBs;
-       }
-}
-
-/**
- * @ingroup JobQueue
- */
-class JobQueueAggregatorNull extends JobQueueAggregator {
-       protected function doNotifyQueueEmpty( $wiki, $type ) {
-               return true;
-       }
-
-       protected function doNotifyQueueNonEmpty( $wiki, $type ) {
-               return true;
-       }
-
-       protected function doGetAllReadyWikiQueues() {
-               return [];
-       }
-
-       protected function doPurge() {
-               return true;
-       }
-}
diff --git a/includes/jobqueue/aggregator/JobQueueAggregatorRedis.php b/includes/jobqueue/aggregator/JobQueueAggregatorRedis.php
deleted file mode 100644 (file)
index 7d0e1e6..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-/**
- * Job queue aggregator code that uses PhpRedis.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-use Psr\Log\LoggerInterface;
-
-/**
- * Class to handle tracking information about all queues using PhpRedis
- *
- * The mediawiki/services/jobrunner background service must be set up and running.
- *
- * @ingroup JobQueue
- * @ingroup Redis
- * @since 1.21
- */
-class JobQueueAggregatorRedis extends JobQueueAggregator {
-       /** @var RedisConnectionPool */
-       protected $redisPool;
-       /** @var LoggerInterface */
-       protected $logger;
-       /** @var array List of Redis server addresses */
-       protected $servers;
-
-       /**
-        * @param array $params Possible keys:
-        *   - redisConfig  : An array of parameters to RedisConnectionPool::__construct().
-        *   - redisServers : Array of server entries, the first being the primary and the
-        *                    others being fallback servers. Each entry is either a hostname/port
-        *                    combination or the absolute path of a UNIX socket.
-        *                    If a hostname is specified but no port, the standard port number
-        *                    6379 will be used. Required.
-        */
-       public function __construct( array $params ) {
-               parent::__construct( $params );
-               $this->servers = $params['redisServers'] ?? [ $params['redisServer'] ]; // b/c
-               $params['redisConfig']['serializer'] = 'none';
-               $this->redisPool = RedisConnectionPool::singleton( $params['redisConfig'] );
-               $this->logger = \MediaWiki\Logger\LoggerFactory::getInstance( 'redis' );
-       }
-
-       protected function doNotifyQueueEmpty( $wiki, $type ) {
-               return true; // managed by the service
-       }
-
-       protected function doNotifyQueueNonEmpty( $wiki, $type ) {
-               return true; // managed by the service
-       }
-
-       protected function doGetAllReadyWikiQueues() {
-               $conn = $this->getConnection();
-               if ( !$conn ) {
-                       return [];
-               }
-               try {
-                       $map = $conn->hGetAll( $this->getReadyQueueKey() );
-
-                       if ( is_array( $map ) && isset( $map['_epoch'] ) ) {
-                               unset( $map['_epoch'] ); // ignore
-                               $pendingDBs = []; // (type => list of wikis)
-                               foreach ( $map as $key => $time ) {
-                                       list( $type, $wiki ) = $this->decodeQueueName( $key );
-                                       $pendingDBs[$type][] = $wiki;
-                               }
-                       } else {
-                               throw new UnexpectedValueException(
-                                       "No queue listing found; make sure redisJobChronService is running."
-                               );
-                       }
-
-                       return $pendingDBs;
-               } catch ( RedisException $e ) {
-                       $this->redisPool->handleError( $conn, $e );
-
-                       return [];
-               }
-       }
-
-       protected function doPurge() {
-               return true; // fully and only refreshed by the service
-       }
-
-       /**
-        * Get a connection to the server that handles all sub-queues for this queue
-        *
-        * @return RedisConnRef|bool Returns false on failure
-        * @throws MWException
-        */
-       protected function getConnection() {
-               $conn = false;
-               foreach ( $this->servers as $server ) {
-                       $conn = $this->redisPool->getConnection( $server, $this->logger );
-                       if ( $conn ) {
-                               break;
-                       }
-               }
-
-               return $conn;
-       }
-
-       /**
-        * @return string
-        */
-       private function getReadyQueueKey() {
-               return "jobqueue:aggregator:h-ready-queues:v2"; // global
-       }
-
-       /**
-        * @param string $name
-        * @return string[]
-        */
-       private function decodeQueueName( $name ) {
-               list( $type, $wiki ) = explode( '/', $name, 2 );
-
-               return [ rawurldecode( $type ), rawurldecode( $wiki ) ];
-       }
-}
index b64c87a..3aedc38 100644 (file)
@@ -195,7 +195,7 @@ class CategoryMembershipChangeJob extends Job {
                // Get the prior revision (the same for null edits)
                if ( $newRev->getParentId() ) {
                        $oldRev = Revision::newFromId( $newRev->getParentId(), Revision::READ_LATEST );
-                       if ( !$oldRev->getContent() ) {
+                       if ( !$oldRev || !$oldRev->getContent() ) {
                                return; // deleted?
                        }
                } else {
index 356eeba..d8cbf75 100644 (file)
  * @ingroup JobQueue
  * @since 1.27
  */
-class CdnPurgeJob extends Job {
-       /**
-        * @param Title $title
-        * @param array $params Job parameters (urls)
-        */
-       function __construct( Title $title, array $params ) {
-               parent::__construct( 'cdnPurge', $title, $params );
+class CdnPurgeJob extends Job implements GenericParameterJob {
+       function __construct( array $params ) {
+               parent::__construct( 'cdnPurge', $params );
                $this->removeDuplicates = false; // delay semantics are critical
        }
 
index 77adfa1..01fa46c 100644 (file)
@@ -10,7 +10,17 @@ use MediaWiki\MediaWikiServices;
  * @ingroup JobQueue
  * @since 1.31
  */
-class ClearUserWatchlistJob extends Job {
+class ClearUserWatchlistJob extends Job implements GenericParameterJob {
+       /**
+        * @param array $params
+        *  - userId,         The ID for the user whose watchlist is being cleared.
+        *  - maxWatchlistId, The maximum wl_id at the time the job was first created,
+        */
+       public function __construct( array $params ) {
+               parent::__construct( 'clearUserWatchlist', $params );
+
+               $this->removeDuplicates = true;
+       }
 
        /**
         * @param User $user User to clear the watchlist for.
@@ -19,26 +29,7 @@ class ClearUserWatchlistJob extends Job {
         * @return ClearUserWatchlistJob
         */
        public static function newForUser( User $user, $maxWatchlistId ) {
-               return new self(
-                       null,
-                       [ 'userId' => $user->getId(), 'maxWatchlistId' => $maxWatchlistId ]
-               );
-       }
-
-       /**
-        * @param Title|null $title Not used by this job.
-        * @param array $params
-        *  - userId,         The ID for the user whose watchlist is being cleared.
-        *  - maxWatchlistId, The maximum wl_id at the time the job was first created,
-        */
-       public function __construct( Title $title = null, array $params ) {
-               parent::__construct(
-                       'clearUserWatchlist',
-                       SpecialPage::getTitleFor( 'EditWatchlist', 'clear' ),
-                       $params
-               );
-
-               $this->removeDuplicates = true;
+               return new self( [ 'userId' => $user->getId(), 'maxWatchlistId' => $maxWatchlistId ] );
        }
 
        public function run() {
@@ -101,7 +92,7 @@ class ClearUserWatchlistJob extends Job {
                if ( count( $watchlistIds ) === (int)$batchSize ) {
                        // Until we get less results than the limit, recursively push
                        // the same job again.
-                       JobQueueGroup::singleton()->push( new self( $this->getTitle(), $this->getParams() ) );
+                       JobQueueGroup::singleton()->push( new self( $this->getParams() ) );
                }
 
                return true;
index 94c1351..f53174a 100644 (file)
 use MediaWiki\MediaWikiServices;
 
 /**
- * Job for clearing all of the "last viewed" timestamps for a user's watchlist
+ * Job for clearing all of the "last viewed" timestamps for a user's watchlist, or setting them all
+ * to the same value.
  *
  * Job parameters include:
  *   - userId: affected user ID [required]
  *   - casTime: UNIX timestamp of the event that triggered this job [required]
+ *   - timestamp: value to set all of the "last viewed" timestamps to [optional, defaults to null]
  *
  * @ingroup JobQueue
  * @since 1.31
  */
-class ClearWatchlistNotificationsJob extends Job {
-       function __construct( Title $title, array $params ) {
-               parent::__construct( 'clearWatchlistNotifications', $title, $params );
+class ClearWatchlistNotificationsJob extends Job implements GenericParameterJob {
+       function __construct( array $params ) {
+               parent::__construct( 'clearWatchlistNotifications', $params );
 
                static $required = [ 'userId', 'casTime' ];
                $missing = implode( ', ', array_diff( $required, array_keys( $this->params ) ) );
                if ( $missing != '' ) {
-                       throw new InvalidArgumentException( "Missing paramter(s) $missing" );
+                       throw new InvalidArgumentException( "Missing parameter(s) $missing" );
                }
 
                $this->removeDuplicates = true;
@@ -51,29 +53,49 @@ class ClearWatchlistNotificationsJob extends Job {
 
                $dbw = $lbFactory->getMainLB()->getConnection( DB_MASTER );
                $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
+               $timestamp = $this->params['timestamp'] ?? null;
+               if ( $timestamp === null ) {
+                       $timestampCond = 'wl_notificationtimestamp IS NOT NULL';
+               } else {
+                       $timestamp = $dbw->timestamp( $timestamp );
+                       $timestampCond = 'wl_notificationtimestamp != ' . $dbw->addQuotes( $timestamp ) .
+                               ' OR wl_notificationtimestamp IS NULL';
+               }
+               // New notifications since the reset should not be cleared
+               $casTimeCond = 'wl_notificationtimestamp < ' .
+                       $dbw->addQuotes( $dbw->timestamp( $this->params['casTime'] ) ) .
+                       ' OR wl_notificationtimestamp IS NULL';
 
-               $asOfTimes = array_unique( $dbw->selectFieldValues(
-                       'watchlist',
-                       'wl_notificationtimestamp',
-                       [ 'wl_user' => $this->params['userId'], 'wl_notificationtimestamp IS NOT NULL' ],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'wl_notificationtimestamp DESC' ]
-               ) );
-
-               foreach ( array_chunk( $asOfTimes, $rowsPerQuery ) as $asOfTimeBatch ) {
-                       $dbw->update(
+               $firstBatch = true;
+               do {
+                       $idsToUpdate = $dbw->selectFieldValues(
                                'watchlist',
-                               [ 'wl_notificationtimestamp' => null ],
+                               'wl_id',
                                [
                                        'wl_user' => $this->params['userId'],
-                                       'wl_notificationtimestamp' => $asOfTimeBatch,
-                                       // New notifications since the reset should not be cleared
-                                       'wl_notificationtimestamp < ' .
-                                               $dbw->addQuotes( $dbw->timestamp( $this->params['casTime'] ) )
+                                       $timestampCond,
+                                       $casTimeCond,
                                ],
-                               __METHOD__
+                               __METHOD__,
+                               [ 'LIMIT' => $rowsPerQuery ]
                        );
-                       $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
-               }
+                       if ( $idsToUpdate ) {
+                               $dbw->update(
+                                       'watchlist',
+                                       [ 'wl_notificationtimestamp' => $timestamp ],
+                                       [
+                                               'wl_id' => $idsToUpdate,
+                                               // For paranoia, enforce the CAS time condition here too
+                                               $casTimeCond
+                                       ],
+                                       __METHOD__
+                               );
+                               if ( !$firstBatch ) {
+                                       $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
+                               }
+                               $firstBatch = false;
+                       }
+               } while ( $idsToUpdate );
+               return true;
        }
 }
index 9b5cef4..b0ce6a5 100644 (file)
@@ -3,16 +3,13 @@
 /**
  * Class DeletePageJob
  */
-class DeletePageJob extends Job {
-       public function __construct( $title, $params ) {
-               parent::__construct( 'deletePage', $title, $params );
+class DeletePageJob extends Job implements GenericParameterJob {
+       public function __construct( array $params ) {
+               parent::__construct( 'deletePage', $params );
+
+               $this->title = Title::makeTitle( $params['namespace'], $params['title'] );
        }
 
-       /**
-        * Execute the job
-        *
-        * @return bool
-        */
        public function run() {
                // Failure to load the page is not job failure.
                // A parallel deletion operation may have already completed the page deletion.
index c005a29..4231e15 100644 (file)
  *
  * @ingroup JobQueue
  */
-final class DuplicateJob extends Job {
+final class DuplicateJob extends Job implements GenericParameterJob {
        /**
         * Callers should use DuplicateJob::newFromJob() instead
         *
-        * @param Title $title
         * @param array $params Job parameters
         */
-       function __construct( Title $title, array $params ) {
-               parent::__construct( 'duplicate', $title, $params );
+       function __construct( array $params ) {
+               parent::__construct( 'duplicate', $params );
        }
 
        /**
         * Get a duplicate no-op version of a job
         *
-        * @param Job $job
+        * @param RunnableJob $job
         * @return Job
         */
-       public static function newFromJob( Job $job ) {
-               $djob = new self( $job->getTitle(), $job->getParams() );
+       public static function newFromJob( RunnableJob $job ) {
+               $djob = new self( $job->getParams() );
                $djob->command = $job->getType();
                $djob->params = is_array( $djob->params ) ? $djob->params : [];
                $djob->params = [ 'isDuplicate' => true ] + $djob->params;
-               $djob->metadata = $job->metadata;
+               $djob->metadata = $job->getMetadata();
 
                return $djob;
        }
index ea7a8d7..f9735d5 100644 (file)
  * @ingroup JobQueue
  * @since 1.25
  */
-final class EnqueueJob extends Job {
+final class EnqueueJob extends Job implements GenericParameterJob {
        /**
         * Callers should use the factory methods instead
         *
-        * @param Title $title
         * @param array $params Job parameters
         */
-       function __construct( Title $title, array $params ) {
-               parent::__construct( 'enqueue', $title, $params );
+       public function __construct( array $params ) {
+               parent::__construct( 'enqueue', $params );
        }
 
        /**
@@ -50,22 +49,24 @@ final class EnqueueJob extends Job {
        public static function newFromLocalJobs( $jobs ) {
                $jobs = is_array( $jobs ) ? $jobs : [ $jobs ];
 
-               return self::newFromJobsByWiki( [ wfWikiID() => $jobs ] );
+               return self::newFromJobsByDomain( [
+                       WikiMap::getCurrentWikiDbDomain()->getId() => $jobs
+               ] );
        }
 
        /**
-        * @param array $jobsByWiki Map of (wiki => JobSpecification list)
+        * @param array $jobsByDomain Map of (wiki => JobSpecification list)
         * @return EnqueueJob
         */
-       public static function newFromJobsByWiki( array $jobsByWiki ) {
+       public static function newFromJobsByDomain( array $jobsByDomain ) {
                $deduplicate = true;
 
-               $jobMapsByWiki = [];
-               foreach ( $jobsByWiki as $wiki => $jobs ) {
-                       $jobMapsByWiki[$wiki] = [];
+               $jobMapsByDomain = [];
+               foreach ( $jobsByDomain as $domain => $jobs ) {
+                       $jobMapsByDomain[$domain] = [];
                        foreach ( $jobs as $job ) {
                                if ( $job instanceof JobSpecification ) {
-                                       $jobMapsByWiki[$wiki][] = $job->toSerializableArray();
+                                       $jobMapsByDomain[$domain][] = $job->toSerializableArray();
                                } else {
                                        throw new InvalidArgumentException( "Jobs must be of type JobSpecification." );
                                }
@@ -73,10 +74,7 @@ final class EnqueueJob extends Job {
                        }
                }
 
-               $eJob = new self(
-                       Title::makeTitle( NS_SPECIAL, 'Badtitle/' . __CLASS__ ),
-                       [ 'jobsByWiki' => $jobMapsByWiki ]
-               );
+               $eJob = new self( [ 'jobsByDomain' => $jobMapsByDomain ] );
                // If *all* jobs to be pushed are to be de-duplicated (a common case), then
                // de-duplicate this whole job itself to avoid build up in high traffic cases
                $eJob->removeDuplicates = $deduplicate;
@@ -84,13 +82,24 @@ final class EnqueueJob extends Job {
                return $eJob;
        }
 
+       /**
+        * @param array $jobsByWiki
+        * @return EnqueueJob
+        * @deprecated Since 1.33; use newFromJobsByDomain()
+        */
+       public static function newFromJobsByWiki( array $jobsByWiki ) {
+               return self::newFromJobsByDomain( $jobsByWiki );
+       }
+
        public function run() {
-               foreach ( $this->params['jobsByWiki'] as $wiki => $jobMaps ) {
+               $jobsByDomain = $this->params['jobsByDomain'] ?? $this->params['jobsByWiki']; // b/c
+
+               foreach ( $jobsByDomain as $domain => $jobMaps ) {
                        $jobSpecs = [];
                        foreach ( $jobMaps as $jobMap ) {
                                $jobSpecs[] = JobSpecification::newFromArray( $jobMap );
                        }
-                       JobQueueGroup::singleton( $wiki )->push( $jobSpecs );
+                       JobQueueGroup::singleton( $domain )->push( $jobSpecs );
                }
 
                return true;
index 7d0ada5..73fa947 100644 (file)
@@ -135,9 +135,8 @@ class HTMLCacheUpdateJob extends Job {
                $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
                // Update page_touched (skipping pages already touched since the root job).
                // Check $wgUpdateRowsPerQuery for sanity; batch jobs are sized by that already.
-               foreach ( array_chunk( $pageIds, $wgUpdateRowsPerQuery ) as $batch ) {
-                       $factory->commitAndWaitForReplication( __METHOD__, $ticket );
-
+               $batches = array_chunk( $pageIds, $wgUpdateRowsPerQuery );
+               foreach ( $batches as $batch ) {
                        $dbw->update( 'page',
                                [ 'page_touched' => $dbw->timestamp( $touchTimestamp ) ],
                                [ 'page_id' => $batch,
@@ -146,6 +145,9 @@ class HTMLCacheUpdateJob extends Job {
                                ],
                                __METHOD__
                        );
+                       if ( count( $batches ) > 1 ) {
+                               $factory->commitAndWaitForReplication( __METHOD__, $ticket );
+                       }
                }
                // Get the list of affected pages (races only mean something else did the purge)
                $titleArray = TitleArray::newFromResult( $dbw->select(
index 80826fe..01afe6f 100644 (file)
@@ -31,7 +31,7 @@
  * @code
  * $ php maintenance/eval.php
  * > $queue = JobQueueGroup::singleton();
- * > $job = new NullJob( Title::newMainPage(), [ 'lives' => 10 ] );
+ * > $job = new NullJob( [ 'lives' => 10 ] );
  * > $queue->push( $job );
  * @endcode
  * You can then confirm the job has been enqueued by using the showJobs.php
  *
  * @ingroup JobQueue
  */
-class NullJob extends Job {
+class NullJob extends Job implements GenericParameterJob {
        /**
-        * @param Title $title
         * @param array $params Job parameters (lives, usleep)
         */
-       function __construct( Title $title, array $params ) {
-               parent::__construct( 'null', $title, $params );
+       function __construct( array $params ) {
+               parent::__construct( 'null', $params );
                if ( !isset( $this->params['lives'] ) ) {
                        $this->params['lives'] = 1;
                }
@@ -67,7 +66,7 @@ class NullJob extends Job {
                if ( $this->params['lives'] > 1 ) {
                        $params = $this->params;
                        $params['lives']--;
-                       $job = new self( $this->title, $params );
+                       $job = new self( $params );
                        JobQueueGroup::singleton()->push( $job );
                }
 
index 7f9b2a3..b1c805b 100644 (file)
@@ -54,6 +54,8 @@ class RefreshLinksJob extends Job {
                        !( isset( $params['pages'] ) && count( $params['pages'] ) != 1 )
                );
                $this->params += [ 'causeAction' => 'unknown', 'causeAgent' => 'unknown' ];
+               // This will control transaction rounds in order to run DataUpdates
+               $this->executionFlags |= self::JOB_NO_EXPLICIT_TRX_ROUND;
        }
 
        /**
@@ -145,6 +147,8 @@ class RefreshLinksJob extends Job {
                $renderer = $services->getRevisionRenderer();
                $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
 
+               $lbFactory->beginMasterChanges( __METHOD__ );
+
                $page = WikiPage::factory( $title );
                $page->loadPageData( WikiPage::READ_LATEST );
 
@@ -153,6 +157,7 @@ class RefreshLinksJob extends Job {
                /** @noinspection PhpUnusedLocalVariableInspection */
                $scopedLock = LinksUpdate::acquirePageLock( $dbw, $page->getId(), 'job' );
                if ( $scopedLock === null ) {
+                       $lbFactory->commitMasterChanges( __METHOD__ );
                        // Another job is already updating the page, likely for an older revision (T170596).
                        $this->setLastError( 'LinksUpdate already running for this page, try again later.' );
                        return false;
@@ -175,10 +180,12 @@ class RefreshLinksJob extends Job {
                }
 
                if ( !$revision ) {
+                       $lbFactory->commitMasterChanges( __METHOD__ );
                        $stats->increment( 'refreshlinks.rev_not_found' );
                        $this->setLastError( "Revision not found for {$title->getPrefixedDBkey()}" );
                        return false; // just deleted?
                } elseif ( $revision->getId() != $latest || $revision->getPageId() !== $page->getId() ) {
+                       $lbFactory->commitMasterChanges( __METHOD__ );
                        // Do not clobber over newer updates with older ones. If all jobs where FIFO and
                        // serialized, it would be OK to update links based on older revisions since it
                        // would eventually get to the latest. Since that is not the case (by design),
@@ -208,6 +215,7 @@ class RefreshLinksJob extends Job {
                        }
 
                        if ( $page->getLinksTimestamp() > $skewedTimestamp ) {
+                               $lbFactory->commitMasterChanges( __METHOD__ );
                                // Something already updated the backlinks since this job was made
                                $stats->increment( 'refreshlinks.update_skipped' );
                                return true;
@@ -284,6 +292,9 @@ class RefreshLinksJob extends Job {
                                $options['triggeringUser'] = User::newFromName( $userInfo['userName'], false );
                        }
                }
+
+               $lbFactory->commitMasterChanges( __METHOD__ );
+
                $page->doSecondaryDataUpdates( $options );
 
                InfoAction::invalidateCache( $title );
index 63575eb..eb8b1a2 100644 (file)
@@ -93,7 +93,7 @@ class ThumbnailRenderJob extends Job {
                if ( $wgUploadThumbnailRenderHttpCustomDomain ) {
                        $parsedUrl = wfParseUrl( $thumbUrl );
 
-                       if ( !$parsedUrl || !isset( $parsedUrl['path'] ) || !strlen( $parsedUrl['path'] ) ) {
+                       if ( !isset( $parsedUrl['path'] ) || $parsedUrl['path'] === '' ) {
                                $this->setLastError( __METHOD__ . ": invalid thumb URL: $thumbUrl" );
                                return false;
                        }
index 0945e58..ac8f94a 100644 (file)
@@ -21,9 +21,9 @@
  * @ingroup JobQueue
  */
 
-class UserGroupExpiryJob extends Job {
-       public function __construct( $params = false ) {
-               parent::__construct( 'userGroupExpiry', Title::newMainPage(), $params );
+class UserGroupExpiryJob extends Job implements GenericParameterJob {
+       public function __construct( array $params = [] ) {
+               parent::__construct( 'userGroupExpiry', $params );
                $this->removeDuplicates = true;
        }
 
index ef364b5..1e40eb4 100644 (file)
@@ -65,7 +65,8 @@ class PurgeJobUtils {
 
                                $batchSize = $services->getMainConfig()->get( 'UpdateRowsPerQuery' );
                                $ticket = $lbFactory->getEmptyTransactionTicket( $fname );
-                               foreach ( array_chunk( $ids, $batchSize ) as $idBatch ) {
+                               $idBatches = array_chunk( $ids, $batchSize );
+                               foreach ( $idBatches as $idBatch ) {
                                        $dbw->update(
                                                'page',
                                                [ 'page_touched' => $now ],
@@ -75,7 +76,9 @@ class PurgeJobUtils {
                                                ],
                                                $fname
                                        );
-                                       $lbFactory->commitAndWaitForReplication( $fname, $ticket );
+                                       if ( count( $idBatches ) > 1 ) {
+                                               $lbFactory->commitAndWaitForReplication( $fname, $ticket );
+                                       }
                                }
                        }
                ) );
index e238887..ccc76bb 100644 (file)
@@ -151,13 +151,11 @@ class ArrayUtils {
         * @since 1.23
         *
         * @param array $array1 The array to compare from
-        * @param array $array2,... More arrays to compare against
+        * @param array ...$arrays More arrays to compare against
         * @return array An array containing all the values from array1
         *               that are not present in any of the other arrays.
         */
-       public static function arrayDiffAssocRecursive( $array1 ) {
-               $arrays = func_get_args();
-               array_shift( $arrays );
+       public static function arrayDiffAssocRecursive( $array1, ...$arrays ) {
                $ret = [];
 
                foreach ( $array1 as $key => $value ) {
index 3129c5b..7a90082 100644 (file)
@@ -407,14 +407,14 @@ class CSSMin {
                        // FIXME: Simplify now we only support PHP 7.0.0+
                        // Note: PCRE doesn't support multiple capture groups with the same name by default.
                        // - PCRE 6.7 introduced the "J" modifier (PCRE_INFO_JCHANGED for PCRE_DUPNAMES).
-                       //   https://secure.php.net/manual/en/reference.pcre.pattern.modifiers.php
+                       //   https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
                        //   However this isn't useful since it just ignores all but the first one.
                        //   Also, while the modifier was introduced in PCRE 6.7 (PHP 5.2+) it was
                        //   not exposed to public preg_* functions until PHP 5.6.0.
                        // - PCRE 8.36 fixed this to work as expected (e.g. merge conceptually to
                        //   only return the one matched in the part that actually matched).
                        //   However MediaWiki supports 5.5.9, which has PCRE 8.32
-                       //   Per https://secure.php.net/manual/en/pcre.installation.php:
+                       //   Per https://www.php.net/manual/en/pcre.installation.php:
                        //   - PCRE 8.32 (PHP 5.5.0)
                        //   - PCRE 8.34 (PHP 5.5.10, PHP 5.6.0)
                        //   - PCRE 8.37 (PHP 5.5.26, PHP 5.6.9, PHP 7.0.0)
diff --git a/includes/libs/CryptRand.php b/includes/libs/CryptRand.php
deleted file mode 100644 (file)
index da0cae2..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-/**
- * A cryptographic random generator class used for generating secret keys
- *
- * This is based in part on Drupal code as well as what we used in our own code
- * prior to introduction of this class.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @author Daniel Friesen
- * @file
- */
-
-/**
- * @deprecated since 1.32, use random_bytes()/random_int()
- */
-class CryptRand {
-       /**
-        * @deprecated since 1.32, unused
-        */
-       const MIN_ITERATIONS = 1000;
-
-       /**
-        * @deprecated since 1.32, unused
-        */
-       const MSEC_PER_BYTE = 0.5;
-
-       /**
-        * Initialize an initial random state based off of whatever we can find
-        *
-        * @deprecated since 1.32, unused and does nothing
-        *
-        * @return string
-        */
-       protected function initialRandomState() {
-               wfDeprecated( __METHOD__, '1.32' );
-               return '';
-       }
-
-       /**
-        * Randomly hash data while mixing in clock drift data for randomness
-        *
-        * @deprecated since 1.32, unused and does nothing
-        *
-        * @param string $data The data to randomly hash.
-        * @return string The hashed bytes
-        * @author Tim Starling
-        */
-       protected function driftHash( $data ) {
-               wfDeprecated( __METHOD__, '1.32' );
-               return '';
-       }
-
-       /**
-        * Return a rolling random state initially build using data from unstable sources
-        *
-        * @deprecated since 1.32, unused and does nothing
-        *
-        * @return string A new weak random state
-        */
-       protected function randomState() {
-               wfDeprecated( __METHOD__, '1.32' );
-               return '';
-       }
-
-       /**
-        * Return a boolean indicating whether or not the source used for cryptographic
-        * random bytes generation in the previously run generate* call
-        * was cryptographically strong.
-        *
-        * @deprecated since 1.32, always returns true
-        *
-        * @return bool Always true
-        */
-       public function wasStrong() {
-               wfDeprecated( __METHOD__, '1.32' );
-               return true;
-       }
-
-       /**
-        * Generate a run of cryptographically random data and return
-        * it in raw binary form.
-        * You can use CryptRand::wasStrong() if you wish to know if the source used
-        * was cryptographically strong.
-        *
-        * @param int $bytes The number of bytes of random data to generate
-        * @return string Raw binary random data
-        */
-       public function generate( $bytes ) {
-               wfDeprecated( __METHOD__, '1.32' );
-               $bytes = floor( $bytes );
-               return random_bytes( $bytes );
-       }
-
-       /**
-        * Generate a run of cryptographically random data and return
-        * it in hexadecimal string format.
-        *
-        * @param int $chars The number of hex chars of random data to generate
-        * @return string Hexadecimal random data
-        */
-       public function generateHex( $chars ) {
-               wfDeprecated( __METHOD__, '1.32' );
-               return MWCryptRand::generateHex( $chars );
-       }
-}
index 9470413..7de60b1 100644 (file)
@@ -36,12 +36,11 @@ class DeferredStringifier {
 
        /**
         * @param callable $callback Callback that gets called by __toString
-        * @param mixed $param,... Parameters to the callback
+        * @param mixed ...$params Parameters to the callback
         */
-       public function __construct( $callback /*...*/ ) {
-               $this->params = func_get_args();
-               array_shift( $this->params );
+       public function __construct( $callback, ...$params ) {
                $this->callback = $callback;
+               $this->params = $params;
        }
 
        /**
index 8efcd15..da525e7 100644 (file)
@@ -467,7 +467,7 @@ class IP {
         * to an integer network and a number of bits
         *
         * @param string $range IP with CIDR prefix
-        * @return array(int or string, int)
+        * @return array [int or string, int]
         */
        public static function parseCIDR( $range ) {
                if ( self::isIPv6( $range ) ) {
@@ -557,7 +557,7 @@ class IP {
         *
         * @param string $range
         *
-        * @return array(string, int)
+        * @return array [string, int]
         */
        private static function parseCIDR6( $range ) {
                # Explode into <expanded IP,range>
@@ -598,7 +598,7 @@ class IP {
         *
         * @param string $range
         *
-        * @return array(string, string)
+        * @return array [string, string]
         */
        private static function parseRange6( $range ) {
                # Expand any IPv6 IP
index e9d1fc1..5e7485c 100644 (file)
@@ -135,11 +135,11 @@ class MemoizedCallable {
         *
         * Like MemoizedCallable::invokeArgs(), but variadic.
         *
-        * @param mixed $params,... Parameters for memoized function or method.
+        * @param mixed ...$params Parameters for memoized function or method.
         * @return mixed The memoized callable's return value.
         */
-       public function invoke() {
-               return $this->invokeArgs( func_get_args() );
+       public function invoke( ...$params ) {
+               return $this->invokeArgs( $params );
        }
 
        /**
index 536177e..a6135ae 100644 (file)
@@ -237,11 +237,9 @@ class MultiHttpClient implements LoggerAwareInterface {
                                        }
                                } while ( $mrc == CURLM_CALL_MULTI_PERFORM );
                                // Wait (if possible) for available work...
-                               if ( $active > 0 && $mrc == CURLM_OK ) {
-                                       if ( curl_multi_select( $chm, $selectTimeout ) == -1 ) {
-                                               // PHP bug 63411; https://curl.haxx.se/libcurl/c/curl_multi_fdset.html
-                                               usleep( 5000 ); // 5ms
-                                       }
+                               if ( $active > 0 && $mrc == CURLM_OK && curl_multi_select( $chm, $selectTimeout ) == -1 ) {
+                                       // PHP bug 63411; https://curl.haxx.se/libcurl/c/curl_multi_fdset.html
+                                       usleep( 5000 ); // 5ms
                                }
                        } while ( $active > 0 && $mrc == CURLM_OK );
                }
index f3c1f01..b8aa951 100644 (file)
@@ -101,7 +101,7 @@ class FSFileBackend extends FileBackendStore {
        public function getFeatures() {
                if ( $this->isWindows && version_compare( PHP_VERSION, '7.1', 'lt' ) ) {
                        // PHP before 7.1 used 8-bit code page for filesystem paths on Windows;
-                       // See https://secure.php.net/manual/en/migration71.windows-support.php
+                       // See https://www.php.net/manual/en/migration71.windows-support.php
                        return 0;
                } else {
                        return FileBackend::ATTR_UNICODE_PATHS;
index 06a155a..53a0ca0 100644 (file)
@@ -114,7 +114,7 @@ abstract class FileBackend implements LoggerAwareInterface {
        protected $fileJournal;
        /** @var LoggerInterface */
        protected $logger;
-       /** @var object|string Class name or object With profileIn/profileOut methods */
+       /** @var callable|null */
        protected $profiler;
 
        /** @var callable */
@@ -156,14 +156,14 @@ abstract class FileBackend implements LoggerAwareInterface {
         *   - obResetFunc : alternative callback to clear the output buffer
         *   - streamMimeFunc : alternative method to determine the content type from the path
         *   - logger : Optional PSR logger object.
-        *   - profiler : Optional class name or object With profileIn/profileOut methods.
+        *   - profiler : Optional callback that takes a section name argument and returns
+        *      a ScopedCallback instance that ends the profile section in its destructor.
         * @throws InvalidArgumentException
         */
        public function __construct( array $config ) {
                $this->name = $config['name'];
-               $this->domainId = isset( $config['domainId'] )
-                       ? $config['domainId'] // e.g. "my_wiki-en_"
-                       : $config['wikiId']; // b/c alias
+               $this->domainId = $config['domainId'] // e.g. "my_wiki-en_"
+                       ?? $config['wikiId']; // b/c alias
                if ( !preg_match( '!^[a-zA-Z0-9-_]{1,255}$!', $this->name ) ) {
                        throw new InvalidArgumentException( "Backend name '{$this->name}' is invalid." );
                } elseif ( !is_string( $this->domainId ) ) {
@@ -187,6 +187,9 @@ abstract class FileBackend implements LoggerAwareInterface {
                $this->statusWrapper = $config['statusWrapper'] ?? null;
 
                $this->profiler = $config['profiler'] ?? null;
+               if ( !is_callable( $this->profiler ) ) {
+                       $this->profiler = null;
+               }
                $this->logger = $config['logger'] ?? new \Psr\Log\NullLogger();
                $this->statusWrapper = $config['statusWrapper'] ?? null;
                $this->tmpDirectory = $config['tmpDirectory'] ?? null;
@@ -831,7 +834,7 @@ abstract class FileBackend implements LoggerAwareInterface {
         * files whereas key/value store backends might revoke container
         * access to the storage user representing end-users in web requests.
         *
-        * This is not guaranteed to actually make files or listings publically hidden.
+        * This is not guaranteed to actually make files or listings publicly hidden.
         * Additional server configuration may be needed to achieve the desired effect.
         *
         * @param array $params Parameters include:
@@ -864,7 +867,7 @@ abstract class FileBackend implements LoggerAwareInterface {
         * access to the storage user representing end-users in web requests.
         * This essentially can undo the result of secure() calls.
         *
-        * This is not guaranteed to actually make files or listings publically viewable.
+        * This is not guaranteed to actually make files or listings publicly viewable.
         * Additional server configuration may be needed to achieve the desired effect.
         *
         * @param array $params Parameters include:
@@ -1572,11 +1575,10 @@ abstract class FileBackend implements LoggerAwareInterface {
         *   - StatusValue::newGood() if this method is called without parameters
         *   - StatusValue::newFatal() with all parameters to this method if passed in
         *
-        * @param string $args,...
+        * @param string ...$args
         * @return StatusValue
         */
-       final protected function newStatus() {
-               $args = func_get_args();
+       final protected function newStatus( ...$args ) {
                if ( count( $args ) ) {
                        $sv = StatusValue::newFatal( ...$args );
                } else {
@@ -1599,12 +1601,7 @@ abstract class FileBackend implements LoggerAwareInterface {
         * @return ScopedCallback|null
         */
        protected function scopedProfileSection( $section ) {
-               if ( $this->profiler ) {
-                       call_user_func( [ $this->profiler, 'profileIn' ], $section );
-                       return new ScopedCallback( [ $this->profiler, 'profileOut' ], [ $section ] );
-               }
-
-               return null;
+               return $this->profiler ? ( $this->profiler )( $section ) : null;
        }
 
        protected function resetOutputBuffer() {
index 655a710..f92d5fa 100644 (file)
@@ -87,9 +87,6 @@ class FileBackendMultiWrite extends FileBackend {
         *                      This will apply such updates post-send for web requests. Note that
         *                      any checks from "syncChecks" are still synchronous.
         *
-        * Bogus warning
-        * @suppress PhanAccessMethodProtected
-        *
         * @param array $config
         * @throws FileBackendError
         */
@@ -260,11 +257,11 @@ class FileBackendMultiWrite extends FileBackend {
                                                $status->fatal( 'backend-fail-synced', $path );
                                                continue;
                                        }
-                                       if ( $this->syncChecks & self::CHECK_SIZE ) {
-                                               if ( $cStat['size'] != $mStat['size'] ) { // wrong size
-                                                       $status->fatal( 'backend-fail-synced', $path );
-                                                       continue;
-                                               }
+                                       if ( ( $this->syncChecks & self::CHECK_SIZE )
+                                               && $cStat['size'] != $mStat['size']
+                                       ) { // wrong size
+                                               $status->fatal( 'backend-fail-synced', $path );
+                                               continue;
                                        }
                                        if ( $this->syncChecks & self::CHECK_TIME ) {
                                                $mTs = wfTimestamp( TS_UNIX, $mStat['mtime'] );
@@ -274,16 +271,12 @@ class FileBackendMultiWrite extends FileBackend {
                                                        continue;
                                                }
                                        }
-                                       if ( $this->syncChecks & self::CHECK_SHA1 ) {
-                                               if ( $cBackend->getFileSha1Base36( $cParams ) !== $mSha1 ) { // wrong SHA1
-                                                       $status->fatal( 'backend-fail-synced', $path );
-                                                       continue;
-                                               }
-                                       }
-                               } else { // file is not in master
-                                       if ( $cStat ) { // file should not exist
+                                       if ( ( $this->syncChecks & self::CHECK_SHA1 ) && $cBackend->getFileSha1Base36( $cParams ) !== $mSha1 ) { // wrong SHA1
                                                $status->fatal( 'backend-fail-synced', $path );
+                                               continue;
                                        }
+                               } elseif ( $cStat ) { // file is not in master; file should not exist
+                                       $status->fatal( 'backend-fail-synced', $path );
                                }
                        }
                }
index 28a293f..97da557 100644 (file)
@@ -1009,7 +1009,7 @@ abstract class FileBackendStore extends FileBackend {
         * @param string $container Resolved container name
         * @param string $dir Resolved path relative to container
         * @param array $params
-        * @return Traversable|array|null Returns null on failure
+        * @return Traversable|string[]|null Returns null on failure
         */
        abstract public function getFileListInternal( $container, $dir, array $params );
 
index 3134e50..0eab860 100644 (file)
@@ -1700,7 +1700,7 @@ class JSNode
        public $funDecls = array();
        public $varDecls = array();
 
-       public function __construct($t, $type=0)
+       public function __construct($t, $type=0, ...$nodes)
        {
                if ($token = $t->currentToken())
                {
@@ -1716,11 +1716,9 @@ class JSNode
                        $this->lineno = $t->lineno;
                }
 
-               if (($numargs = func_num_args()) > 2)
+               foreach($nodes as $node)
                {
-                       $args = func_get_args();
-                       for ($i = 2; $i < $numargs; $i++)
-                               $this->addNode($args[$i]);
+                       $this->addNode($node);
                }
        }
 
index e08da61..413fb2a 100644 (file)
@@ -806,6 +806,8 @@ EOT;
                if ( $eocdrPos !== false ) {
                        $this->logger->info( __METHOD__ . ": ZIP signature present in $file\n" );
                        // Check if it really is a ZIP file, make sure the EOCDR is at the end (T40432)
+                       // FIXME: unpack()'s third argument was added in PHP 7.1
+                       // @phan-suppress-next-line PhanParamTooManyInternal
                        $commentLength = unpack( "n", $tail, $eocdrPos + 20 )[0];
                        if ( $eocdrPos + 22 + $commentLength !== strlen( $tail ) ) {
                                $this->logger->info( __METHOD__ . ": ZIP EOCDR not at end. Not a ZIP file." );
index 993eea9..0b52391 100644 (file)
@@ -72,7 +72,7 @@ class XmlTypeCheck {
         * Additional parsing options
         */
        private $parserOptions = [
-               'processing_instruction_handler' => '',
+               'processing_instruction_handler' => null,
                'external_dtd_handler' => '',
                'dtd_handler' => '',
                'require_safe_dtd' => true
@@ -406,10 +406,10 @@ class XmlTypeCheck {
                        $callbackReturn = false;
                }
 
-               if ( $checkIfSafe && isset( $parsedDTD['internal'] ) ) {
-                       if ( !$this->checkDTDIsSafe( $parsedDTD['internal'] ) ) {
-                               $this->wellFormed = false;
-                       }
+               if ( $checkIfSafe && isset( $parsedDTD['internal'] ) &&
+                       !$this->checkDTDIsSafe( $parsedDTD['internal'] )
+               ) {
+                       $this->wellFormed = false;
                }
        }
 
index e41c3a2..9a5a433 100644 (file)
 /**
  * This is a wrapper for APC's shared memory functions
  *
+ * Use PHP serialization to avoid bugs and easily create CAS tokens.
+ * APCu has a memory corruption bug when the serializer is set to 'default'.
+ * See T120267, and upstream bug reports:
+ *  - https://github.com/krakjoe/apcu/issues/38
+ *  - https://github.com/krakjoe/apcu/issues/35
+ *  - https://github.com/krakjoe/apcu/issues/111
+ *
  * @ingroup Cache
  */
 class APCBagOStuff extends BagOStuff {
-
-       /**
-        * @var bool If true, trust the APC implementation to serialize and
-        * deserialize objects correctly. If false, (de-)serialize in PHP.
-        */
-       protected $nativeSerialize;
-
        /**
         * @var string String to append to each APC key. This may be changed
         *  whenever the handling of values is changed, to prevent existing code
         *  from encountering older values which it cannot handle.
         */
-       const KEY_SUFFIX = ':2';
+       const KEY_SUFFIX = ':3';
 
-       /**
-        * Available parameters are:
-        *   - nativeSerialize:     If true, pass objects to apc_store(), and trust it
-        *                          to serialize them correctly. If false, serialize
-        *                          all values in PHP.
-        *
-        * @param array $params
-        */
-       public function __construct( array $params = [] ) {
-               parent::__construct( $params );
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               $casToken = null;
 
-               if ( isset( $params['nativeSerialize'] ) ) {
-                       $this->nativeSerialize = $params['nativeSerialize'];
-               } elseif ( extension_loaded( 'apcu' ) && ini_get( 'apc.serializer' ) === 'default' ) {
-                       // APCu has a memory corruption bug when the serializer is set to 'default'.
-                       // See T120267, and upstream bug reports:
-                       //  - https://github.com/krakjoe/apcu/issues/38
-                       //  - https://github.com/krakjoe/apcu/issues/35
-                       //  - https://github.com/krakjoe/apcu/issues/111
-                       $this->logger->warning(
-                               'The APCu extension is loaded and the apc.serializer INI setting ' .
-                               'is set to "default". This can cause memory corruption! ' .
-                               'You should change apc.serializer to "php" instead. ' .
-                               'See <https://github.com/krakjoe/apcu/issues/38>.'
-                       );
-                       $this->nativeSerialize = false;
-               } else {
-                       $this->nativeSerialize = true;
+               $blob = apc_fetch( $key . self::KEY_SUFFIX );
+               $value = $this->unserialize( $blob );
+               if ( $value !== false ) {
+                       $casToken = $blob; // don't bother hashing this
                }
-       }
-
-       protected function doGet( $key, $flags = 0 ) {
-               return $this->getUnserialize(
-                       apc_fetch( $key . self::KEY_SUFFIX )
-               );
-       }
 
-       protected function getUnserialize( $value ) {
-               if ( is_string( $value ) && !$this->nativeSerialize ) {
-                       $value = $this->isInteger( $value )
-                               ? intval( $value )
-                               : unserialize( $value );
-               }
                return $value;
        }
 
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
                apc_store(
                        $key . self::KEY_SUFFIX,
-                       $this->setSerialize( $value ),
+                       $this->serialize( $value ),
                        $exptime
                );
 
                return true;
        }
 
-       protected function setSerialize( $value ) {
-               if ( !$this->nativeSerialize && !$this->isInteger( $value ) ) {
-                       $value = serialize( $value );
-               }
-               return $value;
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               return apc_add(
+                       $key . self::KEY_SUFFIX,
+                       $this->serialize( $value ),
+                       $exptime
+               );
        }
 
-       public function delete( $key ) {
+       public function delete( $key, $flags = 0 ) {
                apc_delete( $key . self::KEY_SUFFIX );
 
                return true;
@@ -117,4 +84,12 @@ class APCBagOStuff extends BagOStuff {
        public function decr( $key, $value = 1 ) {
                return apc_dec( $key . self::KEY_SUFFIX, $value );
        }
+
+       protected function serialize( $value ) {
+               return $this->isInteger( $value ) ? (int)$value : serialize( $value );
+       }
+
+       protected function unserialize( $value ) {
+               return $this->isInteger( $value ) ? (int)$value : unserialize( $value );
+       }
 }
index a26e560..0483ee7 100644 (file)
 /**
  * This is a wrapper for APCU's shared memory functions
  *
+ * Use PHP serialization to avoid bugs and easily create CAS tokens.
+ * APCu has a memory corruption bug when the serializer is set to 'default'.
+ * See T120267, and upstream bug reports:
+ *  - https://github.com/krakjoe/apcu/issues/38
+ *  - https://github.com/krakjoe/apcu/issues/35
+ *  - https://github.com/krakjoe/apcu/issues/111
+ *
  * @ingroup Cache
  */
-class APCUBagOStuff extends APCBagOStuff {
+class APCUBagOStuff extends BagOStuff {
        /**
-        * Available parameters are:
-        *   - nativeSerialize:     If true, pass objects to apcu_store(), and trust it
-        *                          to serialize them correctly. If false, serialize
-        *                          all values in PHP.
-        *
-        * @param array $params
+        * @var string String to append to each APC key. This may be changed
+        *  whenever the handling of values is changed, to prevent existing code
+        *  from encountering older values which it cannot handle.
         */
-       public function __construct( array $params = [] ) {
-               parent::__construct( $params );
-       }
+       const KEY_SUFFIX = ':3';
 
-       protected function doGet( $key, $flags = 0 ) {
-               return $this->getUnserialize(
-                       apcu_fetch( $key . self::KEY_SUFFIX )
-               );
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               $casToken = null;
+
+               $blob = apcu_fetch( $key . self::KEY_SUFFIX );
+               $value = $this->unserialize( $blob );
+               if ( $value !== false ) {
+                       $casToken = $blob; // don't bother hashing this
+               }
+
+               return $value;
        }
 
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
                apcu_store(
                        $key . self::KEY_SUFFIX,
-                       $this->setSerialize( $value ),
+                       $this->serialize( $value ),
                        $exptime
                );
 
                return true;
        }
 
-       public function delete( $key ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               return apcu_add(
+                       $key . self::KEY_SUFFIX,
+                       $this->serialize( $value ),
+                       $exptime
+               );
+       }
+
+       public function delete( $key, $flags = 0 ) {
                apcu_delete( $key . self::KEY_SUFFIX );
 
                return true;
@@ -86,4 +102,12 @@ class APCUBagOStuff extends APCBagOStuff {
                        return false;
                }
        }
+
+       protected function serialize( $value ) {
+               return $this->isInteger( $value ) ? (int)$value : serialize( $value );
+       }
+
+       protected function unserialize( $value ) {
+               return $this->isInteger( $value ) ? (int)$value : unserialize( $value );
+       }
 }
index a7ef3d5..0dd7b57 100644 (file)
@@ -87,18 +87,12 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        /** @var int[] Map of (ATTR_* class constant => QOS_* class constant) */
        protected $attrMap = [];
 
-       /** Possible values for getLastError() */
-       const ERR_NONE = 0; // no error
-       const ERR_NO_RESPONSE = 1; // no response
-       const ERR_UNREACHABLE = 2; // can't connect
-       const ERR_UNEXPECTED = 3; // response gave some error
-
        /** Bitfield constants for get()/getMulti() */
        const READ_LATEST = 1; // use latest data for replicated stores
        const READ_VERIFIED = 2; // promise that caller can tell when keys are stale
        /** Bitfield constants for set()/merge() */
-       const WRITE_SYNC = 1; // synchronously write to all locations for replicated stores
-       const WRITE_CACHE_ONLY = 2; // Only change state of the in-memory cache
+       const WRITE_SYNC = 4; // synchronously write to all locations for replicated stores
+       const WRITE_CACHE_ONLY = 8; // Only change state of the in-memory cache
 
        /**
         * $params include:
@@ -145,12 +139,12 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        /**
         * Get an item with the given key, regenerating and setting it if not found
         *
-        * If the callback returns false, then nothing is stored.
+        * Nothing is stored nor deleted if the callback returns false
         *
         * @param string $key
         * @param int $ttl Time-to-live (seconds)
         * @param callable $callback Callback that derives the new value
-        * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
+        * @param int $flags Bitfield of BagOStuff::READ_* or BagOStuff::WRITE_* constants [optional]
         * @return mixed The cached value if found or the result of $callback otherwise
         * @since 1.27
         */
@@ -163,7 +157,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                        }
                        $value = call_user_func( $callback );
                        if ( $value !== false ) {
-                               $this->set( $key, $value, $ttl );
+                               $this->set( $key, $value, $ttl, $flags );
                        }
                }
 
@@ -181,13 +175,9 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         *
         * @param string $key
         * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
-        * @param int|null $oldFlags [unused]
-        * @return mixed Returns false on failure and if the item does not exist
+        * @return mixed Returns false on failure or if the item does not exist
         */
-       public function get( $key, $flags = 0, $oldFlags = null ) {
-               // B/C for ( $key, &$casToken = null, $flags = 0 )
-               $flags = is_int( $oldFlags ) ? $oldFlags : $flags;
-
+       public function get( $key, $flags = 0 ) {
                $this->trackDuplicateKeys( $key );
 
                return $this->doGet( $key, $flags );
@@ -229,22 +219,10 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        /**
         * @param string $key
         * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
-        * @return mixed Returns false on failure and if the item does not exist
-        */
-       abstract protected function doGet( $key, $flags = 0 );
-
-       /**
-        * @note This method is only needed if merge() uses mergeViaCas()
-        *
-        * @param string $key
-        * @param mixed &$casToken
-        * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
-        * @return mixed Returns false on failure and if the item does not exist
-        * @throws Exception
+        * @param mixed|null &$casToken Token to use for check-and-set comparisons
+        * @return mixed Returns false on failure or if the item does not exist
         */
-       protected function getWithToken( $key, &$casToken, $flags = 0 ) {
-               throw new Exception( __METHOD__ . ' not implemented.' );
-       }
+       abstract protected function doGet( $key, $flags = 0, &$casToken = null );
 
        /**
         * Set an item
@@ -262,8 +240,20 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         *
         * @param string $key
         * @return bool True if the item was deleted or not found, false on failure
+        * @param int $flags Bitfield of BagOStuff::WRITE_* constants
         */
-       abstract public function delete( $key );
+       abstract public function delete( $key, $flags = 0 );
+
+       /**
+        * Insert an item if it does not already exist
+        *
+        * @param string $key
+        * @param mixed $value
+        * @param int $exptime
+        * @param int $flags Bitfield of BagOStuff::WRITE_* constants (since 1.33)
+        * @return bool Success
+        */
+       abstract public function add( $key, $value, $exptime = 0, $flags = 0 );
 
        /**
         * Merge changes into the existing cache value (possibly creating a new one)
@@ -272,6 +262,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * (which will be false if not present), and takes the arguments:
         * (this BagOStuff, cache key, current value, TTL).
         * The TTL parameter is reference set to $exptime. It can be overriden in the callback.
+        * Nothing is stored nor deleted if the callback returns false.
         *
         * @param string $key
         * @param callable $callback Callback method to be executed
@@ -282,7 +273,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @throws InvalidArgumentException
         */
        public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               return $this->mergeViaLock( $key, $callback, $exptime, $attempts, $flags );
+               return $this->mergeViaCas( $key, $callback, $exptime, $attempts, $flags );
        }
 
        /**
@@ -292,17 +283,15 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
+        * @param int $flags Bitfield of BagOStuff::WRITE_* constants
         * @return bool Success
         */
-       protected function mergeViaCas( $key, $callback, $exptime = 0, $attempts = 10 ) {
+       protected function mergeViaCas( $key, $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
                do {
-                       $this->clearLastError();
-                       $reportDupes = $this->reportDupes;
-                       $this->reportDupes = false;
                        $casToken = null; // passed by reference
-                       $currentValue = $this->getWithToken( $key, $casToken, self::READ_LATEST );
-                       $this->reportDupes = $reportDupes;
-
+                       // Get the old value and CAS token from cache
+                       $this->clearLastError();
+                       $currentValue = $this->doGet( $key, self::READ_LATEST, $casToken );
                        if ( $this->getLastError() ) {
                                $this->logger->warning(
                                        __METHOD__ . ' failed due to I/O error on get() for {key}.',
@@ -314,16 +303,18 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
 
                        // Derive the new value from the old value
                        $value = call_user_func( $callback, $this, $key, $currentValue, $exptime );
+                       $hadNoCurrentValue = ( $currentValue === false );
+                       unset( $currentValue ); // free RAM in case the value is large
 
                        $this->clearLastError();
                        if ( $value === false ) {
                                $success = true; // do nothing
-                       } elseif ( $currentValue === false ) {
+                       } elseif ( $hadNoCurrentValue ) {
                                // Try to create the key, failing if it gets created in the meantime
-                               $success = $this->add( $key, $value, $exptime );
+                               $success = $this->add( $key, $value, $exptime, $flags );
                        } else {
                                // Try to update the key, failing if it gets changed in the meantime
-                               $success = $this->cas( $casToken, $key, $value, $exptime );
+                               $success = $this->cas( $casToken, $key, $value, $exptime, $flags );
                        }
                        if ( $this->getLastError() ) {
                                $this->logger->warning(
@@ -345,18 +336,19 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @param string $key
         * @param mixed $value
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
+        * @param int $flags Bitfield of BagOStuff::WRITE_* constants
         * @return bool Success
         * @throws Exception
         */
-       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
                if ( !$this->lock( $key, 0 ) ) {
                        return false; // non-blocking
                }
 
                $curCasToken = null; // passed by reference
-               $this->getWithToken( $key, $curCasToken, self::READ_LATEST );
+               $this->doGet( $key, self::READ_LATEST, $curCasToken );
                if ( $casToken === $curCasToken ) {
-                       $success = $this->set( $key, $value, $exptime );
+                       $success = $this->set( $key, $value, $exptime, $flags );
                } else {
                        $this->logger->info(
                                __METHOD__ . ' failed due to race condition for {key}.',
@@ -372,69 +364,32 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        }
 
        /**
-        * @see BagOStuff::merge()
+        * Change the expiration on a key if it exists
         *
-        * @param string $key
-        * @param callable $callback Callback method to be executed
-        * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
-        * @param int $attempts The amount of times to attempt a merge in case of failure
-        * @param int $flags Bitfield of BagOStuff::WRITE_* constants
-        * @return bool Success
-        */
-       protected function mergeViaLock( $key, $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               if ( $attempts <= 1 ) {
-                       $timeout = 0; // clearly intended to be "non-blocking"
-               } else {
-                       $timeout = 3;
-               }
-
-               if ( !$this->lock( $key, $timeout ) ) {
-                       return false;
-               }
-
-               $this->clearLastError();
-               $reportDupes = $this->reportDupes;
-               $this->reportDupes = false;
-               $currentValue = $this->get( $key, self::READ_LATEST );
-               $this->reportDupes = $reportDupes;
-
-               if ( $this->getLastError() ) {
-                       $this->logger->warning(
-                               __METHOD__ . ' failed due to I/O error on get() for {key}.',
-                               [ 'key' => $key ]
-                       );
-
-                       $success = false;
-               } else {
-                       // Derive the new value from the old value
-                       $value = call_user_func( $callback, $this, $key, $currentValue, $exptime );
-                       if ( $value === false ) {
-                               $success = true; // do nothing
-                       } else {
-                               $success = $this->set( $key, $value, $exptime, $flags ); // set the new value
-                       }
-               }
-
-               if ( !$this->unlock( $key ) ) {
-                       // this should never happen
-                       trigger_error( "Could not release lock for key '$key'." );
-               }
-
-               return $success;
-       }
-
-       /**
-        * Reset the TTL on a key if it exists
+        * If an expiry in the past is given then the key will immediately be expired
         *
         * @param string $key
-        * @param int $expiry
-        * @return bool Success Returns false if there is no key
+        * @param int $expiry TTL or UNIX timestamp
+        * @param int $flags Bitfield of BagOStuff::WRITE_* constants (since 1.33)
+        * @return bool Success Returns false on failure or if the item does not exist
         * @since 1.28
         */
-       public function changeTTL( $key, $expiry = 0 ) {
-               $value = $this->get( $key );
+       public function changeTTL( $key, $expiry = 0, $flags = 0 ) {
+               $found = false;
 
-               return ( $value === false ) ? false : $this->set( $key, $value, $expiry );
+               $ok = $this->merge(
+                       $key,
+                       function ( $cache, $ttl, $currentValue ) use ( &$found ) {
+                               $found = ( $currentValue !== false );
+
+                               return $currentValue; // nothing is written if this is false
+                       },
+                       $expiry,
+                       1, // 1 attempt
+                       $flags
+               );
+
+               return ( $ok && $found );
        }
 
        /**
@@ -465,7 +420,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                        function () use ( $key, $expiry, $fname ) {
                                $this->clearLastError();
                                if ( $this->add( "{$key}:lock", 1, $expiry ) ) {
-                                       return true; // locked!
+                                       return WaitConditionLoop::CONDITION_REACHED; // locked!
                                } elseif ( $this->getLastError() ) {
                                        $this->logger->warning(
                                                $fname . ' failed due to I/O error for {key}.',
@@ -573,78 +528,69 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
 
        /**
         * Get an associative array containing the item for each of the keys that have items.
-        * @param array $keys List of strings
+        * @param string[] $keys List of keys
         * @param int $flags Bitfield; supports READ_LATEST [optional]
         * @return array
         */
        public function getMulti( array $keys, $flags = 0 ) {
                $res = [];
                foreach ( $keys as $key ) {
-                       $val = $this->get( $key );
+                       $val = $this->get( $key, $flags );
                        if ( $val !== false ) {
                                $res[$key] = $val;
                        }
                }
+
                return $res;
        }
 
        /**
-        * Batch insertion
-        * @param array $data $key => $value assoc array
+        * Batch insertion/replace
+        * @param mixed[] $data Map of (key => value)
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
+        * @param int $flags Bitfield of BagOStuff::WRITE_* constants (since 1.33)
         * @return bool Success
         * @since 1.24
         */
-       public function setMulti( array $data, $exptime = 0 ) {
+       public function setMulti( array $data, $exptime = 0, $flags = 0 ) {
                $res = true;
                foreach ( $data as $key => $value ) {
-                       if ( !$this->set( $key, $value, $exptime ) ) {
+                       if ( !$this->set( $key, $value, $exptime, $flags ) ) {
                                $res = false;
                        }
                }
+
                return $res;
        }
 
        /**
-        * @param string $key
-        * @param mixed $value
-        * @param int $exptime
+        * Batch deletion
+        * @param string[] $keys List of keys
+        * @param int $flags Bitfield of BagOStuff::WRITE_* constants
         * @return bool Success
+        * @since 1.33
         */
-       public function add( $key, $value, $exptime = 0 ) {
-               // @note: avoid lock() here since that method uses *this* method by default
-               if ( $this->get( $key ) === false ) {
-                       return $this->set( $key, $value, $exptime );
+       public function deleteMulti( array $keys, $flags = 0 ) {
+               $res = true;
+               foreach ( $keys as $key ) {
+                       $res = $this->delete( $key, $flags ) && $res;
                }
-               return false; // key already set
+
+               return $res;
        }
 
        /**
         * Increase stored value of $key by $value while preserving its TTL
         * @param string $key Key to increase
-        * @param int $value Value to add to $key (Default 1)
+        * @param int $value Value to add to $key (default: 1) [optional]
         * @return int|bool New value or false on failure
         */
-       public function incr( $key, $value = 1 ) {
-               if ( !$this->lock( $key, 1 ) ) {
-                       return false;
-               }
-               $n = $this->get( $key );
-               if ( $this->isInteger( $n ) ) { // key exists?
-                       $n += intval( $value );
-                       $this->set( $key, max( 0, $n ) ); // exptime?
-               } else {
-                       $n = false;
-               }
-               $this->unlock( $key );
-
-               return $n;
-       }
+       abstract public function incr( $key, $value = 1 );
 
        /**
         * Decrease stored value of $key by $value while preserving its TTL
         * @param string $key
-        * @param int $value
+        * @param int $value Value to subtract from $key (default: 1) [optional]
         * @return int|bool New value or false on failure
         */
        public function decr( $key, $value = 1 ) {
@@ -710,7 +656,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * The callbacks may or may not be called ever, in any particular order.
         * They are likely to be invoked when something WRITE_SYNC is used used.
         * They should follow a caching pattern as shown below, so that any code
-        * using the word will get it's result no matter what happens.
+        * using the work will get it's result no matter what happens.
         * @code
         *     $result = null;
         *     $workCallback = function () use ( &$result ) {
@@ -728,24 +674,6 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                $this->busyCallbacks[] = $workCallback;
        }
 
-       /**
-        * Modify a cache update operation array for EventRelayer::notify()
-        *
-        * This is used for relayed writes, e.g. for broadcasting a change
-        * to multiple data-centers. If the array contains a 'val' field
-        * then the command involves setting a key to that value. Note that
-        * for simplicity, 'val' is always a simple scalar value. This method
-        * is used to possibly serialize the value and add any cache-specific
-        * key/values needed for the relayer daemon (e.g. memcached flags).
-        *
-        * @param array $event
-        * @return array
-        * @since 1.26
-        */
-       public function modifySimpleRelayEvent( array $event ) {
-               return $event;
-       }
-
        /**
         * @param string $text
         */
@@ -757,13 +685,21 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                }
        }
 
+       /**
+        * @param int $exptime
+        * @return bool
+        */
+       protected function expiryIsRelative( $exptime ) {
+               return ( $exptime != 0 && $exptime < ( 10 * self::TTL_YEAR ) );
+       }
+
        /**
         * Convert an optionally relative time to an absolute time
         * @param int $exptime
         * @return int
         */
-       protected function convertExpiry( $exptime ) {
-               if ( $exptime != 0 && $exptime < ( 10 * self::TTL_YEAR ) ) {
+       protected function convertToExpiry( $exptime ) {
+               if ( $this->expiryIsRelative( $exptime ) ) {
                        return (int)$this->getCurrentTime() + $exptime;
                } else {
                        return $exptime;
@@ -810,8 +746,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        public function makeKeyInternal( $keyspace, $args ) {
                $key = $keyspace;
                foreach ( $args as $arg ) {
-                       $arg = str_replace( ':', '%3A', $arg );
-                       $key = $key . ':' . $arg;
+                       $key .= ':' . str_replace( ':', '%3A', $arg );
                }
                return strtr( $key, ' ', '_' );
        }
index 726836e..8892f73 100644 (file)
@@ -32,6 +32,7 @@
  *   up going to the HashBagOStuff used for the in-memory cache).
  *
  * @ingroup Cache
+ * @TODO: Make this class use composition instead of calling super
  */
 class CachedBagOStuff extends HashBagOStuff {
        /** @var BagOStuff */
@@ -50,10 +51,10 @@ class CachedBagOStuff extends HashBagOStuff {
                $this->attrMap = $backend->attrMap;
        }
 
-       protected function doGet( $key, $flags = 0 ) {
-               $ret = parent::doGet( $key, $flags );
+       public function get( $key, $flags = 0 ) {
+               $ret = parent::get( $key, $flags );
                if ( $ret === false && !$this->hasKey( $key ) ) {
-                       $ret = $this->backend->doGet( $key, $flags );
+                       $ret = $this->backend->get( $key, $flags );
                        $this->set( $key, $ret, 0, self::WRITE_CACHE_ONLY );
                }
                return $ret;
@@ -68,7 +69,7 @@ class CachedBagOStuff extends HashBagOStuff {
        }
 
        public function delete( $key, $flags = 0 ) {
-               parent::delete( $key );
+               parent::delete( $key, $flags );
                if ( !( $flags & self::WRITE_CACHE_ONLY ) ) {
                        $this->backend->delete( $key );
                }
@@ -101,6 +102,21 @@ class CachedBagOStuff extends HashBagOStuff {
        // These just call the backend (tested elsewhere)
        // @codeCoverageIgnoreStart
 
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               if ( $this->get( $key ) === false ) {
+                       return $this->set( $key, $value, $exptime, $flags );
+               }
+
+               return false; // key already set
+       }
+
+       public function incr( $key, $value = 1 ) {
+               $n = $this->backend->incr( $key, $value );
+               parent::delete( $key );
+
+               return $n;
+       }
+
        public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' ) {
                return $this->backend->lock( $key, $timeout, $expiry, $rclass );
        }
@@ -117,9 +133,5 @@ class CachedBagOStuff extends HashBagOStuff {
                return $this->backend->clearLastError();
        }
 
-       public function modifySimpleRelayEvent( array $event ) {
-               return $this->backend->modifySimpleRelayEvent( $event );
-       }
-
        // @codeCoverageIgnoreEnd
 }
index 3f66c06..ffe3a4c 100644 (file)
  * @ingroup Cache
  */
 class EmptyBagOStuff extends BagOStuff {
-       protected function doGet( $key, $flags = 0 ) {
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               $casToken = null;
+
                return false;
        }
 
-       public function add( $key, $value, $exp = 0 ) {
+       public function add( $key, $value, $exp = 0, $flags = 0 ) {
                return true;
        }
 
@@ -39,10 +41,14 @@ class EmptyBagOStuff extends BagOStuff {
                return true;
        }
 
-       public function delete( $key ) {
+       public function delete( $key, $flags = 0 ) {
                return true;
        }
 
+       public function incr( $key, $value = 1 ) {
+               return false;
+       }
+
        public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
                return true; // faster
        }
index ec66492..d24f408 100644 (file)
@@ -34,8 +34,15 @@ class HashBagOStuff extends BagOStuff {
        /** @var int Max entries allowed */
        protected $maxCacheKeys;
 
+       /** @var string CAS token prefix for this instance */
+       private $token;
+
+       /** @var int CAS token counter */
+       private static $casCounter = 0;
+
        const KEY_VAL = 0;
        const KEY_EXP = 1;
+       const KEY_CAS = 2;
 
        /**
         * @param array $params Additional parameters include:
@@ -44,40 +51,17 @@ class HashBagOStuff extends BagOStuff {
        function __construct( $params = [] ) {
                parent::__construct( $params );
 
+               $this->token = microtime( true ) . ':' . mt_rand();
                $this->maxCacheKeys = $params['maxKeys'] ?? INF;
                if ( $this->maxCacheKeys <= 0 ) {
                        throw new InvalidArgumentException( '$maxKeys parameter must be above zero' );
                }
        }
 
-       protected function expire( $key ) {
-               $et = $this->bag[$key][self::KEY_EXP];
-               if ( $et == self::TTL_INDEFINITE || $et > $this->getCurrentTime() ) {
-                       return false;
-               }
-
-               $this->delete( $key );
-
-               return true;
-       }
-
-       /**
-        * Does this bag have a non-null value for the given key?
-        *
-        * @param string $key
-        * @return bool
-        * @since 1.27
-        */
-       protected function hasKey( $key ) {
-               return isset( $this->bag[$key] );
-       }
-
-       protected function doGet( $key, $flags = 0 ) {
-               if ( !$this->hasKey( $key ) ) {
-                       return false;
-               }
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               $casToken = null;
 
-               if ( $this->expire( $key ) ) {
+               if ( !$this->hasKey( $key ) || $this->expire( $key ) ) {
                        return false;
                }
 
@@ -86,6 +70,8 @@ class HashBagOStuff extends BagOStuff {
                unset( $this->bag[$key] );
                $this->bag[$key] = $temp;
 
+               $casToken = $this->bag[$key][self::KEY_CAS];
+
                return $this->bag[$key][self::KEY_VAL];
        }
 
@@ -94,7 +80,8 @@ class HashBagOStuff extends BagOStuff {
                unset( $this->bag[$key] );
                $this->bag[$key] = [
                        self::KEY_VAL => $value,
-                       self::KEY_EXP => $this->convertExpiry( $exptime )
+                       self::KEY_EXP => $this->convertToExpiry( $exptime ),
+                       self::KEY_CAS => $this->token . ':' . ++self::$casCounter
                ];
 
                if ( count( $this->bag ) > $this->maxCacheKeys ) {
@@ -106,13 +93,62 @@ class HashBagOStuff extends BagOStuff {
                return true;
        }
 
-       public function delete( $key ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               if ( $this->get( $key ) === false ) {
+                       return $this->set( $key, $value, $exptime, $flags );
+               }
+
+               return false; // key already set
+       }
+
+       public function delete( $key, $flags = 0 ) {
                unset( $this->bag[$key] );
 
                return true;
        }
 
+       public function incr( $key, $value = 1 ) {
+               $n = $this->get( $key );
+               if ( $this->isInteger( $n ) ) {
+                       $n = max( $n + intval( $value ), 0 );
+                       $this->bag[$key][self::KEY_VAL] = $n;
+
+                       return $n;
+               }
+
+               return false;
+       }
+
+       /**
+        * Clear all values in cache
+        */
        public function clear() {
                $this->bag = [];
        }
+
+       /**
+        * @param string $key
+        * @return bool
+        */
+       protected function expire( $key ) {
+               $et = $this->bag[$key][self::KEY_EXP];
+               if ( $et == self::TTL_INDEFINITE || $et > $this->getCurrentTime() ) {
+                       return false;
+               }
+
+               $this->delete( $key );
+
+               return true;
+       }
+
+       /**
+        * Does this bag have a non-null value for the given key?
+        *
+        * @param string $key
+        * @return bool
+        * @since 1.27
+        */
+       protected function hasKey( $key ) {
+               return isset( $this->bag[$key] );
+       }
 }
index 7bab20a..61a4c61 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 /**
- * Generic base class for storage interfaces.
+ * Generic interface for lightweight expiring object stores.
  *
  * Provides convenient TTL constants.
  *
@@ -44,16 +44,24 @@ interface IExpiringStore {
 
        const TTL_INDEFINITE = 0;
 
-       // Attribute and QoS constants; higher QOS values with the same prefix rank higher...
-       // Medium attributes constants related to emulation or media type
+       // Emulation/fallback medium attribute (e.g. SQLBagOStuff)
        const ATTR_EMULATION = 1;
+       // Quality of service constants for ATTR_EMULATION (higher means faster)
        const QOS_EMULATION_SQL = 1;
-       // Medium attributes constants related to replica consistency
-       const ATTR_SYNCWRITES = 2; // SYNC_WRITES flag support
+
+       // Replica synchronization/consistency attribute of medium when SYNC_WRITES is used
+       const ATTR_SYNCWRITES = 2;
+       // Quality of service constants for ATTR_SYNCWRITES (higher means more consistent)
        const QOS_SYNCWRITES_NONE = 1; // replication only supports eventual consistency or less
        const QOS_SYNCWRITES_BE = 2; // best effort synchronous with limited retries
        const QOS_SYNCWRITES_QC = 3; // write quorum applied directly to state machines where R+W > N
        const QOS_SYNCWRITES_SS = 4; // strict-serializable, nodes refuse reads if possible stale
+
        // Generic "unknown" value that is useful for comparisons (e.g. always good enough)
        const QOS_UNKNOWN = INF;
+
+       const ERR_NONE = 0; // no error
+       const ERR_NO_RESPONSE = 1; // no response
+       const ERR_UNREACHABLE = 2; // can't connect
+       const ERR_UNEXPECTED = 3; // response gave some error
 }
index f7bf86b..71e3331 100644 (file)
@@ -50,13 +50,7 @@ class MemcachedBagOStuff extends BagOStuff {
                ];
        }
 
-       protected function doGet( $key, $flags = 0 ) {
-               $casToken = null;
-
-               return $this->getWithToken( $key, $casToken, $flags );
-       }
-
-       protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
                return $this->client->get( $this->validateKeyEncoding( $key ), $casToken );
        }
 
@@ -65,25 +59,33 @@ class MemcachedBagOStuff extends BagOStuff {
                        $this->fixExpiry( $exptime ) );
        }
 
-       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
                return $this->client->cas( $casToken, $this->validateKeyEncoding( $key ),
                        $value, $this->fixExpiry( $exptime ) );
        }
 
-       public function delete( $key ) {
+       public function delete( $key, $flags = 0 ) {
                return $this->client->delete( $this->validateKeyEncoding( $key ) );
        }
 
-       public function add( $key, $value, $exptime = 0 ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
                return $this->client->add( $this->validateKeyEncoding( $key ), $value,
                        $this->fixExpiry( $exptime ) );
        }
 
-       public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               return $this->mergeViaCas( $key, $callback, $exptime, $attempts );
+       public function incr( $key, $value = 1 ) {
+               $n = $this->client->incr( $this->validateKeyEncoding( $key ), $value );
+
+               return ( $n !== false && $n !== null ) ? $n : false;
        }
 
-       public function changeTTL( $key, $exptime = 0 ) {
+       public function decr( $key, $value = 1 ) {
+               $n = $this->client->decr( $this->validateKeyEncoding( $key ), $value );
+
+               return ( $n !== false && $n !== null ) ? $n : false;
+       }
+
+       public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
                return $this->client->touch( $this->validateKeyEncoding( $key ),
                        $this->fixExpiry( $exptime ) );
        }
@@ -181,12 +183,4 @@ class MemcachedBagOStuff extends BagOStuff {
        protected function debugLog( $text ) {
                $this->logger->debug( $text );
        }
-
-       public function modifySimpleRelayEvent( array $event ) {
-               if ( array_key_exists( 'val', $event ) ) {
-                       $event['flg'] = 0; // data is not serialized nor gzipped (for memcached driver)
-               }
-
-               return $event;
-       }
 }
index 1cc07b7..937ca55 100644 (file)
@@ -255,8 +255,6 @@ class MemcachedClient {
         * Memcache initializer
         *
         * @param array $args Associative array of settings
-        *
-        * @return mixed
         */
        public function __construct( $args ) {
                $this->set_servers( $args['servers'] ?? array() );
index fe31c25..692771d 100644 (file)
@@ -138,7 +138,10 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                return $params;
        }
 
-       protected function getWithToken( $key, &$casToken, $flags = 0 ) {
+       /**
+        * @suppress PhanTypeNonVarPassByRef
+        */
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
                $this->debugLog( "get($key)" );
                if ( defined( Memcached::class . '::GET_EXTENDED' ) ) { // v3.0.0
                        $flags = Memcached::GET_EXTENDED;
@@ -159,7 +162,7 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
 
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
                $this->debugLog( "set($key)" );
-               $result = parent::set( $key, $value, $exptime );
+               $result = parent::set( $key, $value, $exptime, $flags = 0 );
                if ( $result === false && $this->client->getResultCode() === Memcached::RES_NOTSTORED ) {
                        // "Not stored" is always used as the mcrouter response with AllAsyncRoute
                        return true;
@@ -167,12 +170,12 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                return $this->checkResult( $key, $result );
        }
 
-       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
                $this->debugLog( "cas($key)" );
-               return $this->checkResult( $key, parent::cas( $casToken, $key, $value, $exptime ) );
+               return $this->checkResult( $key, parent::cas( $casToken, $key, $value, $exptime, $flags ) );
        }
 
-       public function delete( $key ) {
+       public function delete( $key, $flags = 0 ) {
                $this->debugLog( "delete($key)" );
                $result = parent::delete( $key );
                if ( $result === false && $this->client->getResultCode() === Memcached::RES_NOTFOUND ) {
@@ -182,7 +185,7 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                return $this->checkResult( $key, $result );
        }
 
-       public function add( $key, $value, $exptime = 0 ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
                $this->debugLog( "add($key)" );
                return $this->checkResult( $key, parent::add( $key, $value, $exptime ) );
        }
@@ -248,12 +251,7 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                return $this->checkResult( false, $result );
        }
 
-       /**
-        * @param array $data
-        * @param int $exptime
-        * @return bool
-        */
-       public function setMulti( array $data, $exptime = 0 ) {
+       public function setMulti( array $data, $exptime = 0, $flags = 0 ) {
                $this->debugLog( 'setMulti(' . implode( ', ', array_keys( $data ) ) . ')' );
                foreach ( array_keys( $data ) as $key ) {
                        $this->validateKeyEncoding( $key );
@@ -262,7 +260,7 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                return $this->checkResult( false, $result );
        }
 
-       public function changeTTL( $key, $expiry = 0 ) {
+       public function changeTTL( $key, $expiry = 0, $flags = 0 ) {
                $this->debugLog( "touch($key)" );
                $result = $this->client->touch( $key, $expiry );
                return $this->checkResult( $key, $result );
index 3ff390b..8f190c3 100644 (file)
@@ -58,16 +58,4 @@ class MemcachedPhpBagOStuff extends MemcachedBagOStuff {
 
                return $this->client->get_multi( $keys );
        }
-
-       public function incr( $key, $value = 1 ) {
-               $this->validateKeyEncoding( $key );
-
-               return $this->client->incr( $key, $value ) ?? false;
-       }
-
-       public function decr( $key, $value = 1 ) {
-               $this->validateKeyEncoding( $key );
-
-               return $this->client->decr( $key, $value ) ?? false;
-       }
 }
index 043f8cb..adb9bb8 100644 (file)
@@ -27,6 +27,9 @@ use Wikimedia\ObjectFactory;
  * are implemented by reading from the caches in the order they are given in
  * the configuration until a cache gives a positive result.
  *
+ * Note that cache key construction will use the first cache backend in the list,
+ * so make sure that the other backends can handle such keys (e.g. via encoding).
+ *
  * @ingroup Cache
  */
 class MultiWriteBagOStuff extends BagOStuff {
@@ -100,11 +103,11 @@ class MultiWriteBagOStuff extends BagOStuff {
                }
        }
 
-       protected function doGet( $key, $flags = 0 ) {
+       public function get( $key, $flags = 0 ) {
                if ( ( $flags & self::READ_LATEST ) == self::READ_LATEST ) {
                        // If the latest write was a delete(), we do NOT want to fallback
                        // to the other tiers and possibly see the old value. Also, this
-                       // is used by mergeViaLock(), which only needs to hit the primary.
+                       // is used by merge(), which only needs to hit the primary.
                        return $this->caches[0]->get( $key, $flags );
                }
 
@@ -124,67 +127,72 @@ class MultiWriteBagOStuff extends BagOStuff {
                ) {
                        // Backfill the value to the higher (and often faster/smaller) cache tiers
                        $this->doWrite(
-                               $missIndexes, $this->asyncWrites, 'set', $key, $value, self::UPGRADE_TTL
+                               $missIndexes,
+                               $this->asyncWrites,
+                               'set',
+                               [ $key, $value, self::UPGRADE_TTL ]
                        );
                }
 
                return $value;
        }
-
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
-               $asyncWrites = ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC )
-                       ? false
-                       : $this->asyncWrites;
-
-               return $this->doWrite( $this->cacheIndexes, $asyncWrites, 'set', $key, $value, $exptime );
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->usesAsyncWritesGivenFlags( $flags ),
+                       __FUNCTION__,
+                       func_get_args()
+               );
        }
 
-       public function delete( $key ) {
-               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'delete', $key );
+       public function delete( $key, $flags = 0 ) {
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->usesAsyncWritesGivenFlags( $flags ),
+                       __FUNCTION__,
+                       func_get_args()
+               );
        }
 
-       public function add( $key, $value, $exptime = 0 ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
                // Try the write to the top-tier cache
-               $ok = $this->doWrite( [ 0 ], $this->asyncWrites, 'add', $key, $value, $exptime );
+               $ok = $this->doWrite(
+                       [ 0 ],
+                       $this->usesAsyncWritesGivenFlags( $flags ),
+                       __FUNCTION__,
+                       func_get_args()
+               );
+
                if ( $ok ) {
                        // Relay the add() using set() if it succeeded. This is meant to handle certain
                        // migration scenarios where the same store might get written to twice for certain
                        // keys. In that case, it does not make sense to return false due to "self-conflicts".
                        return $this->doWrite(
                                array_slice( $this->cacheIndexes, 1 ),
-                               $this->asyncWrites,
+                               $this->usesAsyncWritesGivenFlags( $flags ),
                                'set',
-                               $key,
-                               $value,
-                               $exptime
+                               [ $key, $value, $exptime, $flags ]
                        );
                }
 
                return false;
        }
 
-       public function incr( $key, $value = 1 ) {
-               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'incr', $key, $value );
-       }
-
-       public function decr( $key, $value = 1 ) {
-               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'decr', $key, $value );
-       }
-
        public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               $asyncWrites = ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC )
-                       ? false
-                       : $this->asyncWrites;
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->usesAsyncWritesGivenFlags( $flags ),
+                       __FUNCTION__,
+                       func_get_args()
+               );
+       }
 
+       public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
                return $this->doWrite(
                        $this->cacheIndexes,
-                       $asyncWrites,
-                       'merge',
-                       $key,
-                       $callback,
-                       $exptime,
-                       $attempts,
-                       $flags
+                       $this->usesAsyncWritesGivenFlags( $flags ),
+                       __FUNCTION__,
+                       func_get_args()
                );
        }
 
@@ -197,6 +205,82 @@ class MultiWriteBagOStuff extends BagOStuff {
                // Only the first cache is locked
                return $this->caches[0]->unlock( $key );
        }
+       /**
+        * Delete objects expiring before a certain date.
+        *
+        * Succeed if any of the child caches succeed.
+        * @param string $date
+        * @param bool|callable $progressCallback
+        * @return bool
+        */
+       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
+               $ret = false;
+               foreach ( $this->caches as $cache ) {
+                       if ( $cache->deleteObjectsExpiringBefore( $date, $progressCallback ) ) {
+                               $ret = true;
+                       }
+               }
+
+               return $ret;
+       }
+
+       public function getMulti( array $keys, $flags = 0 ) {
+               // Just iterate over each key in order to handle all the backfill logic
+               $res = [];
+               foreach ( $keys as $key ) {
+                       $val = $this->get( $key, $flags );
+                       if ( $val !== false ) {
+                               $res[$key] = $val;
+                       }
+               }
+
+               return $res;
+       }
+
+       public function setMulti( array $data, $exptime = 0, $flags = 0 ) {
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->usesAsyncWritesGivenFlags( $flags ),
+                       __FUNCTION__,
+                       func_get_args()
+               );
+       }
+
+       public function deleteMulti( array $data, $flags = 0 ) {
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->usesAsyncWritesGivenFlags( $flags ),
+                       __FUNCTION__,
+                       func_get_args()
+               );
+       }
+
+       public function incr( $key, $value = 1 ) {
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->asyncWrites,
+                       __FUNCTION__,
+                       func_get_args()
+               );
+       }
+
+       public function decr( $key, $value = 1 ) {
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->asyncWrites,
+                       __FUNCTION__,
+                       func_get_args()
+               );
+       }
+
+       public function incrWithInit( $key, $ttl, $value = 1, $init = 1 ) {
+               return $this->doWrite(
+                       $this->cacheIndexes,
+                       $this->asyncWrites,
+                       __FUNCTION__,
+                       func_get_args()
+               );
+       }
 
        public function getLastError() {
                return $this->caches[0]->getLastError();
@@ -205,19 +289,17 @@ class MultiWriteBagOStuff extends BagOStuff {
        public function clearLastError() {
                $this->caches[0]->clearLastError();
        }
-
        /**
         * Apply a write method to the backing caches specified by $indexes (in order)
         *
         * @param int[] $indexes List of backing cache indexes
         * @param bool $asyncWrites
-        * @param string $method
-        * @param mixed $args,...
+        * @param string $method Method name of backing caches
+        * @param array[] $args Arguments to the method of backing caches
         * @return bool
         */
-       protected function doWrite( $indexes, $asyncWrites, $method /*, ... */ ) {
+       protected function doWrite( $indexes, $asyncWrites, $method, array $args ) {
                $ret = true;
-               $args = array_slice( func_get_args(), 3 );
 
                if ( array_diff( $indexes, [ 0 ] ) && $asyncWrites && $method !== 'merge' ) {
                        // Deep-clone $args to prevent misbehavior when something writes an
@@ -249,22 +331,11 @@ class MultiWriteBagOStuff extends BagOStuff {
        }
 
        /**
-        * Delete objects expiring before a certain date.
-        *
-        * Succeed if any of the child caches succeed.
-        * @param string $date
-        * @param bool|callable $progressCallback
+        * @param int $flags
         * @return bool
         */
-       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
-               $ret = false;
-               foreach ( $this->caches as $cache ) {
-                       if ( $cache->deleteObjectsExpiringBefore( $date, $progressCallback ) ) {
-                               $ret = true;
-                       }
-               }
-
-               return $ret;
+       protected function usesAsyncWritesGivenFlags( $flags ) {
+               return ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) ? false : $this->asyncWrites;
        }
 
        public function makeKeyInternal( $keyspace, $args ) {
@@ -278,4 +349,8 @@ class MultiWriteBagOStuff extends BagOStuff {
        public function makeGlobalKey( $class, $component = null ) {
                return $this->caches[0]->makeGlobalKey( ...func_get_args() );
        }
+
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               throw new LogicException( __METHOD__ . ': proxy class does not need this method.' );
+       }
 }
index fc3d575..4d8ae59 100644 (file)
@@ -84,12 +84,9 @@ class RESTBagOStuff extends BagOStuff {
                $this->client->setLogger( $logger );
        }
 
-       /**
-        * @param string $key
-        * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
-        * @return mixed Returns false on failure and if the item does not exist
-        */
-       protected function doGet( $key, $flags = 0 ) {
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               $casToken = null;
+
                $req = [
                        'method' => 'GET',
                        'url' => $this->url . rawurlencode( $key ),
@@ -98,7 +95,11 @@ class RESTBagOStuff extends BagOStuff {
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req );
                if ( $rcode === 200 ) {
                        if ( is_string( $rbody ) ) {
-                               return unserialize( $rbody );
+                               $value = unserialize( $rbody );
+                               /// @FIXME: use some kind of hash or UUID header as CAS token
+                               $casToken = ( $value !== false ) ? $rbody : null;
+
+                               return $value;
                        }
                        return false;
                }
@@ -108,32 +109,9 @@ class RESTBagOStuff extends BagOStuff {
                return false;
        }
 
-       /**
-        * Handle storage error
-        * @param string $msg Error message
-        * @param int $rcode Error code from client
-        * @param string $rerr Error message from client
-        * @return false
-        */
-       protected function handleError( $msg, $rcode, $rerr ) {
-               $this->logger->error( "$msg : ({code}) {error}", [
-                       'code' => $rcode,
-                       'error' => $rerr
-               ] );
-               $this->setLastError( $rcode === 0 ? self::ERR_UNREACHABLE : self::ERR_UNEXPECTED );
-               return false;
-       }
-
-       /**
-        * Set an item
-        *
-        * @param string $key
-        * @param mixed $value
-        * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
-        * @param int $flags Bitfield of BagOStuff::WRITE_* constants
-        * @return bool Success
-        */
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
+               // @TODO: respect WRITE_SYNC (e.g. EACH_QUORUM)
+               // @TODO: respect $exptime
                $req = [
                        'method' => 'PUT',
                        'url' => $this->url . rawurlencode( $key ),
@@ -146,13 +124,17 @@ class RESTBagOStuff extends BagOStuff {
                return $this->handleError( "Failed to store $key", $rcode, $rerr );
        }
 
-       /**
-        * Delete an item.
-        *
-        * @param string $key
-        * @return bool True if the item was deleted or not found, false on failure
-        */
-       public function delete( $key ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               // @TODO: make this atomic
+               if ( $this->get( $key ) === false ) {
+                       return $this->set( $key, $value, $exptime, $flags );
+               }
+
+               return false; // key already set
+       }
+
+       public function delete( $key, $flags = 0 ) {
+               // @TODO: respect WRITE_SYNC (e.g. EACH_QUORUM)
                $req = [
                        'method' => 'DELETE',
                        'url' => $this->url . rawurlencode( $key ),
@@ -163,4 +145,32 @@ class RESTBagOStuff extends BagOStuff {
                }
                return $this->handleError( "Failed to delete $key", $rcode, $rerr );
        }
+
+       public function incr( $key, $value = 1 ) {
+               // @TODO: make this atomic
+               $n = $this->get( $key, self::READ_LATEST );
+               if ( $this->isInteger( $n ) ) { // key exists?
+                       $n = max( $n + intval( $value ), 0 );
+                       // @TODO: respect $exptime
+                       return $this->set( $key, $n ) ? $n : false;
+               }
+
+               return false;
+       }
+
+       /**
+        * Handle storage error
+        * @param string $msg Error message
+        * @param int $rcode Error code from client
+        * @param string $rerr Error message from client
+        * @return false
+        */
+       protected function handleError( $msg, $rcode, $rerr ) {
+               $this->logger->error( "$msg : ({code}) {error}", [
+                       'code' => $rcode,
+                       'error' => $rerr
+               ] );
+               $this->setLastError( $rcode === 0 ? self::ERR_UNREACHABLE : self::ERR_UNEXPECTED );
+               return false;
+       }
 }
index abf9e8b..2c74d45 100644 (file)
@@ -86,13 +86,9 @@ class RedisBagOStuff extends BagOStuff {
                $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_NONE;
        }
 
-       protected function doGet( $key, $flags = 0 ) {
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
                $casToken = null;
 
-               return $this->getWithToken( $key, $casToken, $flags );
-       }
-
-       protected function getWithToken( $key, &$casToken, $flags = 0 ) {
                list( $server, $conn ) = $this->getConnection( $key );
                if ( !$conn ) {
                        return false;
@@ -132,7 +128,7 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       public function delete( $key ) {
+       public function delete( $key, $flags = 0 ) {
                list( $server, $conn ) = $this->getConnection( $key );
                if ( !$conn ) {
                        return false;
@@ -189,12 +185,7 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       /**
-        * @param array $data
-        * @param int $expiry
-        * @return bool
-        */
-       public function setMulti( array $data, $expiry = 0 ) {
+       public function setMulti( array $data, $expiry = 0, $flags = 0 ) {
                $batches = [];
                $conns = [];
                foreach ( $data as $key => $value ) {
@@ -238,7 +229,46 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       public function add( $key, $value, $expiry = 0 ) {
+       public function deleteMulti( array $keys, $flags = 0 ) {
+               $batches = [];
+               $conns = [];
+               foreach ( $keys as $key ) {
+                       list( $server, $conn ) = $this->getConnection( $key );
+                       if ( !$conn ) {
+                               continue;
+                       }
+                       $conns[$server] = $conn;
+                       $batches[$server][] = $key;
+               }
+
+               $result = true;
+               foreach ( $batches as $server => $batchKeys ) {
+                       $conn = $conns[$server];
+                       try {
+                               $conn->multi( Redis::PIPELINE );
+                               foreach ( $batchKeys as $key ) {
+                                       $conn->delete( $key );
+                               }
+                               $batchResult = $conn->exec();
+                               if ( $batchResult === false ) {
+                                       $this->debug( "deleteMulti request to $server failed" );
+                                       continue;
+                               }
+                               foreach ( $batchResult as $value ) {
+                                       if ( $value === false ) {
+                                               $result = false;
+                                       }
+                               }
+                       } catch ( RedisException $e ) {
+                               $this->handleException( $conn, $e );
+                               $result = false;
+                       }
+               }
+
+               return $result;
+       }
+
+       public function add( $key, $value, $expiry = 0, $flags = 0 ) {
                list( $server, $conn ) = $this->getConnection( $key );
                if ( !$conn ) {
                        return false;
@@ -263,10 +293,6 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               return $this->mergeViaCas( $key, $callback, $exptime, $attempts );
-       }
-
        /**
         * Non-atomic implementation of incr().
         *
@@ -299,32 +325,32 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       public function changeTTL( $key, $expiry = 0 ) {
+       public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
                list( $server, $conn ) = $this->getConnection( $key );
                if ( !$conn ) {
                        return false;
                }
 
-               $expiry = $this->convertToRelative( $expiry );
+               $relative = $this->expiryIsRelative( $exptime );
                try {
-                       $result = $conn->expire( $key, $expiry );
+                       if ( $exptime == 0 ) {
+                               $result = $conn->persist( $key );
+                               $this->logRequest( 'persist', $key, $server, $result );
+                       } elseif ( $relative ) {
+                               $result = $conn->expire( $key, $this->convertToRelative( $exptime ) );
+                               $this->logRequest( 'expire', $key, $server, $result );
+                       } else {
+                               $result = $conn->expireAt( $key, $this->convertToExpiry( $exptime ) );
+                               $this->logRequest( 'expireAt', $key, $server, $result );
+                       }
                } catch ( RedisException $e ) {
                        $result = false;
                        $this->handleException( $conn, $e );
                }
 
-               $this->logRequest( 'expire', $key, $server, $result );
                return $result;
        }
 
-       public function modifySimpleRelayEvent( array $event ) {
-               if ( array_key_exists( 'val', $event ) ) {
-                       $event['val'] = serialize( $event['val'] ); // this class uses PHP serialization
-               }
-
-               return $event;
-       }
-
        /**
         * @param mixed $data
         * @return string
index f2c3732..70f9096 100644 (file)
@@ -74,36 +74,30 @@ class ReplicatedBagOStuff extends BagOStuff {
                $this->readStore->setDebug( $debug );
        }
 
-       protected function doGet( $key, $flags = 0 ) {
+       public function get( $key, $flags = 0 ) {
                return ( $flags & self::READ_LATEST )
                        ? $this->writeStore->get( $key, $flags )
                        : $this->readStore->get( $key, $flags );
        }
 
-       public function getMulti( array $keys, $flags = 0 ) {
-               return ( $flags & self::READ_LATEST )
-                       ? $this->writeStore->getMulti( $keys, $flags )
-                       : $this->readStore->getMulti( $keys, $flags );
-       }
-
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
                return $this->writeStore->set( $key, $value, $exptime, $flags );
        }
 
-       public function delete( $key ) {
-               return $this->writeStore->delete( $key );
+       public function delete( $key, $flags = 0 ) {
+               return $this->writeStore->delete( $key, $flags );
        }
 
-       public function add( $key, $value, $exptime = 0 ) {
-               return $this->writeStore->add( $key, $value, $exptime );
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               return $this->writeStore->add( $key, $value, $exptime, $flags );
        }
 
-       public function incr( $key, $value = 1 ) {
-               return $this->writeStore->incr( $key, $value );
+       public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
+               return $this->writeStore->merge( $key, $callback, $exptime, $attempts, $flags );
        }
 
-       public function decr( $key, $value = 1 ) {
-               return $this->writeStore->decr( $key, $value );
+       public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
+               return $this->writeStore->changeTTL( $key, $exptime, $flags );
        }
 
        public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' ) {
@@ -114,8 +108,34 @@ class ReplicatedBagOStuff extends BagOStuff {
                return $this->writeStore->unlock( $key );
        }
 
-       public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               return $this->writeStore->merge( $key, $callback, $exptime, $attempts, $flags );
+       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
+               return $this->writeStore->deleteObjectsExpiringBefore( $date, $progressCallback );
+       }
+
+       public function getMulti( array $keys, $flags = 0 ) {
+               return ( ( $flags & self::READ_LATEST ) == self::READ_LATEST )
+                       ? $this->writeStore->getMulti( $keys, $flags )
+                       : $this->readStore->getMulti( $keys, $flags );
+       }
+
+       public function setMulti( array $data, $exptime = 0, $flags = 0 ) {
+               return $this->writeStore->setMulti( $data, $exptime, $flags );
+       }
+
+       public function deleteMulti( array $keys, $flags = 0 ) {
+               return $this->writeStore->deleteMulti( $keys, $flags );
+       }
+
+       public function incr( $key, $value = 1 ) {
+               return $this->writeStore->incr( $key, $value );
+       }
+
+       public function decr( $key, $value = 1 ) {
+               return $this->writeStore->decr( $key, $value );
+       }
+
+       public function incrWithInit( $key, $ttl, $value = 1, $init = 1 ) {
+               return $this->writeStore->incrWithInit( $key, $ttl, $value, $init );
        }
 
        public function getLastError() {
@@ -140,4 +160,8 @@ class ReplicatedBagOStuff extends BagOStuff {
        public function makeGlobalKey( $class, $component = null ) {
                return $this->writeStore->makeGlobalKey( ...func_get_args() );
        }
+
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               throw new LogicException( __METHOD__ . ': proxy class does not need this method.' );
+       }
 }
index 86e193b..8f0b539 100644 (file)
@@ -94,8 +94,8 @@ use Psr\Log\NullLogger;
  *        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.
+ * Broadcasted operations like delete() and touchCheckKey() are intended to run
+ * immediately in the local datacenter and asynchronously in remote datacenters.
  *
  * This means that callers in all datacenters may see older values for however many
  * milliseconds that the purge took to reach that datacenter. As with any cache, this
@@ -191,9 +191,18 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
        /** Tiny negative float to use when CTL comes up >= 0 due to clock skew */
        const TINY_NEGATIVE = -0.000001;
+       /** Tiny positive float to use when using "minTime" to assert an inequality */
+       const TINY_POSTIVE = 0.000001;
 
-       /** Seconds of delay after get() where set() storms are a consideration with 'lockTSE' */
-       const SET_DELAY_HIGH_SEC = 0.1;
+       /** Milliseconds of delay after get() where set() storms are a consideration with 'lockTSE' */
+       const SET_DELAY_HIGH_MS = 50;
+       /** Min millisecond set() backoff for keys in hold-off (far less than INTERIM_KEY_TTL) */
+       const RECENT_SET_LOW_MS = 50;
+       /** Max millisecond set() backoff for keys in hold-off (far less than INTERIM_KEY_TTL) */
+       const RECENT_SET_HIGH_MS = 100;
+
+       /** Parameter to get()/getMulti() to return extra information by reference */
+       const PASS_BY_REF = -1;
 
        /** Cache format version number */
        const VERSION = 1;
@@ -202,18 +211,9 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        const FLD_VALUE = 1; // key to the cached value
        const FLD_TTL = 2; // key to the original TTL
        const FLD_TIME = 3; // key to the cache time
-       const FLD_FLAGS = 4; // key to the flags bitfield
+       const FLD_FLAGS = 4; // key to the flags bitfield (reserved number)
        const FLD_HOLDOFF = 5; // key to any hold-off TTL
 
-       /** @var int Treat this value as expired-on-arrival */
-       const FLG_STALE = 1;
-
-       const ERR_NONE = 0; // no error
-       const ERR_NO_RESPONSE = 1; // no response
-       const ERR_UNREACHABLE = 2; // can't connect
-       const ERR_UNEXPECTED = 3; // response gave some error
-       const ERR_RELAY = 4; // relay broadcast failed
-
        const VALUE_KEY_PREFIX = 'WANCache:v:';
        const INTERIM_KEY_PREFIX = 'WANCache:i:';
        const TIME_KEY_PREFIX = 'WANCache:t:';
@@ -231,7 +231,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @param array $params
         *   - cache    : BagOStuff object for a persistent cache
         *   - logger   : LoggerInterface object
-        *   - stats    : LoggerInterface object
+        *   - stats    : StatsdDataFactoryInterface object
         *   - asyncHandler : A function that takes a callback and runs it later. If supplied,
         *       whenever a preemptive refresh would be triggered in getWithSetCallback(), the
         *       current cache value is still used instead. However, the async-handler function
@@ -276,9 +276,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @return WANObjectCache
         */
        public static function newEmpty() {
-               return new static( [
-                       'cache'   => new EmptyBagOStuff()
-               ] );
+               return new static( [ 'cache' => new EmptyBagOStuff() ] );
        }
 
        /**
@@ -316,18 +314,36 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * Consider using getWithSetCallback() instead of get() and set() cycles.
         * That method has cache slam avoiding features for hot/expensive keys.
         *
+        * Pass $info as WANObjectCache::PASS_BY_REF to transform it into a cache key info map.
+        * This map includes the following metadata:
+        *   - asOf: UNIX timestamp of the value or null if the key is nonexistant
+        *   - tombAsOf: UNIX timestamp of the tombstone or null if the key is not tombstoned
+        *   - lastCKPurge: UNIX timestamp of the highest check key or null if none provided
+        *
+        * Otherwise, $info will transform into the cached value timestamp.
+        *
         * @param string $key Cache key made from makeKey() or makeGlobalKey()
         * @param mixed|null &$curTTL Approximate TTL left on the key if present/tombstoned [returned]
         * @param array $checkKeys List of "check" keys
-        * @param float|null &$asOf UNIX timestamp of cached value; null on failure [returned]
+        * @param mixed|null &$info Key info if WANObjectCache::PASS_BY_REF [returned]
         * @return mixed Value of cache key or false on failure
         */
-       final public function get( $key, &$curTTL = null, array $checkKeys = [], &$asOf = null ) {
-               $curTTLs = [];
-               $asOfs = [];
-               $values = $this->getMulti( [ $key ], $curTTLs, $checkKeys, $asOfs );
+       final public function get(
+               $key, &$curTTL = null, array $checkKeys = [], &$info = null
+       ) {
+               $curTTLs = self::PASS_BY_REF;
+               $infoByKey = self::PASS_BY_REF;
+               $values = $this->getMulti( [ $key ], $curTTLs, $checkKeys, $infoByKey );
                $curTTL = $curTTLs[$key] ?? null;
-               $asOf = $asOfs[$key] ?? null;
+               if ( $info === self::PASS_BY_REF ) {
+                       $info = [
+                               'asOf' => $infoByKey[$key]['asOf'] ?? null,
+                               'tombAsOf' => $infoByKey[$key]['tombAsOf'] ?? null,
+                               'lastCKPurge' => $infoByKey[$key]['lastCKPurge'] ?? null
+                       ];
+               } else {
+                       $info = $infoByKey[$key]['asOf'] ?? null; // b/c
+               }
 
                return $values[$key] ?? false;
        }
@@ -335,21 +351,31 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /**
         * Fetch the value of several keys from cache
         *
+        * Pass $info as WANObjectCache::PASS_BY_REF to transform it into a map of cache keys
+        * to cache key info maps, each having the same style as those of WANObjectCache::get().
+        * All the cache keys listed in $keys will have an entry.
+        *
+        * Othwerwise, $info will transform into a map of (cache key => cached value timestamp).
+        * Only the cache keys listed in $keys that exists or are tombstoned will have an entry.
+        *
         * @see WANObjectCache::get()
         *
         * @param array $keys List of cache keys made from makeKey() or makeGlobalKey()
-        * @param array &$curTTLs Map of (key => approximate TTL left) for existing keys [returned]
+        * @param mixed|null &$curTTLs Map of (key => TTL left) for existing/tombstoned keys [returned]
         * @param array $checkKeys List of check keys to apply to all $keys. May also apply "check"
         *  keys to specific cache keys only by using cache keys as keys in the $checkKeys array.
-        * @param float[] &$asOfs Map of (key =>  UNIX timestamp of cached value; null on failure)
+        * @param mixed|null &$info Map of (key => info) if WANObjectCache::PASS_BY_REF [returned]
         * @return array Map of (key => value) for keys that exist and are not tombstoned
         */
        final public function getMulti(
-               array $keys, &$curTTLs = [], array $checkKeys = [], array &$asOfs = []
+               array $keys,
+               &$curTTLs = [],
+               array $checkKeys = [],
+               &$info = null
        ) {
                $result = [];
                $curTTLs = [];
-               $asOfs = [];
+               $infoByKey = [];
 
                $vPrefixLen = strlen( self::VALUE_KEY_PREFIX );
                $valueKeys = self::prefixCacheKeys( $keys, self::VALUE_KEY_PREFIX );
@@ -360,13 +386,11 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                foreach ( $checkKeys as $i => $checkKeyGroup ) {
                        $prefixed = self::prefixCacheKeys( (array)$checkKeyGroup, self::TIME_KEY_PREFIX );
                        $checkKeysFlat = array_merge( $checkKeysFlat, $prefixed );
-                       // Is this check keys for a specific cache key, or for all keys being fetched?
+                       // Are these check keys for a specific cache key, or for all keys being fetched?
                        if ( is_int( $i ) ) {
                                $checkKeysForAll = array_merge( $checkKeysForAll, $prefixed );
                        } else {
-                               $checkKeysByKey[$i] = isset( $checkKeysByKey[$i] )
-                                       ? array_merge( $checkKeysByKey[$i], $prefixed )
-                                       : $prefixed;
+                               $checkKeysByKey[$i] = $prefixed;
                        }
                }
 
@@ -395,35 +419,43 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                // Get the main cache value for each key and validate them
                foreach ( $valueKeys as $vKey ) {
-                       if ( !isset( $wrappedValues[$vKey] ) ) {
-                               continue; // not found
+                       $key = substr( $vKey, $vPrefixLen ); // unprefix
+                       list( $value, $curTTL, $asOf, $tombAsOf ) = isset( $wrappedValues[$vKey] )
+                               ? $this->unwrap( $wrappedValues[$vKey], $now )
+                               : [ false, null, null, null ]; // not found
+                       // Force dependent keys to be seen as stale for a while after purging
+                       // to reduce race conditions involving stale data getting cached
+                       $purgeValues = $purgeValuesForAll;
+                       if ( isset( $purgeValuesByKey[$key] ) ) {
+                               $purgeValues = array_merge( $purgeValues, $purgeValuesByKey[$key] );
                        }
 
-                       $key = substr( $vKey, $vPrefixLen ); // unprefix
+                       $lastCKPurge = null; // timestamp of the highest check key
+                       foreach ( $purgeValues as $purge ) {
+                               $lastCKPurge = max( $purge[self::FLD_TIME], $lastCKPurge );
+                               $safeTimestamp = $purge[self::FLD_TIME] + $purge[self::FLD_HOLDOFF];
+                               if ( $value !== false && $safeTimestamp >= $asOf ) {
+                                       // How long ago this value was invalidated by *this* check key
+                                       $ago = min( $purge[self::FLD_TIME] - $now, self::TINY_NEGATIVE );
+                                       // How long ago this value was invalidated by *any* known check key
+                                       $curTTL = min( $curTTL, $ago );
+                               }
+                       }
 
-                       list( $value, $curTTL ) = $this->unwrap( $wrappedValues[$vKey], $now );
                        if ( $value !== false ) {
                                $result[$key] = $value;
-                               // Force dependent keys to be seen as stale for a while after purging
-                               // to reduce race conditions involving stale data getting cached
-                               $purgeValues = $purgeValuesForAll;
-                               if ( isset( $purgeValuesByKey[$key] ) ) {
-                                       $purgeValues = array_merge( $purgeValues, $purgeValuesByKey[$key] );
-                               }
-                               foreach ( $purgeValues as $purge ) {
-                                       $safeTimestamp = $purge[self::FLD_TIME] + $purge[self::FLD_HOLDOFF];
-                                       if ( $safeTimestamp >= $wrappedValues[$vKey][self::FLD_TIME] ) {
-                                               // How long ago this value was invalidated by *this* check key
-                                               $ago = min( $purge[self::FLD_TIME] - $now, self::TINY_NEGATIVE );
-                                               // How long ago this value was invalidated by *any* known check key
-                                               $curTTL = min( $curTTL, $ago );
-                                       }
-                               }
                        }
-                       $curTTLs[$key] = $curTTL;
-                       $asOfs[$key] = ( $value !== false ) ? $wrappedValues[$vKey][self::FLD_TIME] : null;
+                       if ( $curTTL !== null ) {
+                               $curTTLs[$key] = $curTTL;
+                       }
+
+                       $infoByKey[$key] = ( $info === self::PASS_BY_REF )
+                               ? [ 'asOf' => $asOf, 'tombAsOf' => $tombAsOf, 'lastCKPurge' => $lastCKPurge ]
+                               : $asOf; // b/c
                }
 
+               $info = $infoByKey;
+
                return $result;
        }
 
@@ -487,87 +519,124 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @param string $key Cache key
         * @param mixed $value
         * @param int $ttl Seconds to live. Special values are:
-        *   - WANObjectCache::TTL_INDEFINITE: Cache forever
+        *   - WANObjectCache::TTL_INDEFINITE: Cache forever (default)
         * @param array $opts Options map:
-        *   - lag : Seconds of replica DB lag. Typically, this is either the replica DB lag
+        *   - lag: seconds of replica DB lag. Typically, this is either the replica DB lag
         *      before the data was read or, if applicable, the replica DB lag before
         *      the snapshot-isolated transaction the data was read from started.
         *      Use false to indicate that replication is not running.
         *      Default: 0 seconds
-        *   - since : UNIX timestamp of the data in $value. Typically, this is either
+        *   - since: UNIX timestamp of the data in $value. Typically, this is either
         *      the current time the data was read or (if applicable) the time when
         *      the snapshot-isolated transaction the data was read from started.
         *      Default: 0 seconds
-        *   - pending : Whether this data is possibly from an uncommitted write transaction.
+        *   - pending: whether this data is possibly from an uncommitted write transaction.
         *      Generally, other threads should not see values from the future and
         *      they certainly should not see ones that ended up getting rolled back.
         *      Default: false
-        *   - lockTSE : if excessive replication/snapshot lag is detected, then store the value
+        *   - lockTSE: if excessive replication/snapshot lag is detected, then store the value
         *      with this TTL and flag it as stale. This is only useful if the reads for this key
         *      use getWithSetCallback() with "lockTSE" set. Note that if "staleTTL" is set
         *      then it will still add on to this TTL in the excessive lag scenario.
         *      Default: WANObjectCache::TSE_NONE
-        *   - staleTTL : Seconds to keep the key around if it is stale. The get()/getMulti()
+        *   - staleTTL: seconds to keep the key around if it is stale. The get()/getMulti()
         *      methods return such stale values with a $curTTL of 0, and getWithSetCallback()
         *      will call the regeneration callback in such cases, passing in the old value
         *      and its as-of time to the callback. This is useful if adaptiveTTL() is used
         *      on the old value's as-of time when it is verified as still being correct.
         *      Default: WANObjectCache::STALE_TTL_NONE.
+        *   - creating: optimize for the case where the key does not already exist.
+        *      Default: false
         * @note Options added in 1.28: staleTTL
+        * @note Options added in 1.33: creating
         * @return bool Success
         */
-       final public function set( $key, $value, $ttl = 0, array $opts = [] ) {
+       final public function set( $key, $value, $ttl = self::TTL_INDEFINITE, array $opts = [] ) {
                $now = $this->getCurrentTime();
                $lockTSE = $opts['lockTSE'] ?? self::TSE_NONE;
                $staleTTL = $opts['staleTTL'] ?? self::STALE_TTL_NONE;
                $age = isset( $opts['since'] ) ? max( 0, $now - $opts['since'] ) : 0;
+               $creating = $opts['creating'] ?? false;
                $lag = $opts['lag'] ?? 0;
 
                // Do not cache potentially uncommitted data as it might get rolled back
                if ( !empty( $opts['pending'] ) ) {
-                       $this->logger->info( 'Rejected set() for {cachekey} due to pending writes.',
-                               [ 'cachekey' => $key ] );
+                       $this->logger->info(
+                               'Rejected set() for {cachekey} due to pending writes.',
+                               [ 'cachekey' => $key ]
+                       );
 
                        return true; // no-op the write for being unsafe
                }
 
-               $wrapExtra = []; // additional wrapped value fields
+               $logicalTTL = null; // logical TTL override
                // Check if there's a risk of writing stale data after the purge tombstone expired
                if ( $lag === false || ( $lag + $age ) > self::MAX_READ_LAG ) {
-                       // Case A: read lag with "lockTSE"; save but record value as stale
-                       if ( $lockTSE >= 0 ) {
-                               $ttl = max( 1, (int)$lockTSE ); // set() expects seconds
-                               $wrapExtra[self::FLD_FLAGS] = self::FLG_STALE; // mark as stale
-                       // Case B: any long-running transaction; ignore this set()
-                       } elseif ( $age > self::MAX_READ_LAG ) {
-                               $this->logger->info( 'Rejected set() for {cachekey} due to snapshot lag.',
-                                       [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ] );
+                       // Case A: any long-running transaction
+                       if ( $age > self::MAX_READ_LAG ) {
+                               if ( $lockTSE >= 0 ) {
+                                       // Store value as *almost* stale to avoid cache and mutex stampedes
+                                       $logicalTTL = self::TTL_SECOND;
+                                       $this->logger->info(
+                                               'Lowered set() TTL for {cachekey} due to snapshot lag.',
+                                               [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ]
+                                       );
+                               } else {
+                                       $this->logger->info(
+                                               'Rejected set() for {cachekey} due to snapshot lag.',
+                                               [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ]
+                                       );
 
-                               return true; // no-op the write for being unsafe
-                       // Case C: high replication lag; lower TTL instead of ignoring all set()s
+                                       return true; // no-op the write for being unsafe
+                               }
+                       // Case B: high replication lag; lower TTL instead of ignoring all set()s
                        } elseif ( $lag === false || $lag > self::MAX_READ_LAG ) {
-                               $ttl = $ttl ? min( $ttl, self::TTL_LAGGED ) : self::TTL_LAGGED;
-                               $this->logger->warning( 'Lowered set() TTL for {cachekey} due to replication lag.',
-                                       [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ] );
-                       // Case D: medium length request with medium replication lag; ignore this set()
+                               if ( $lockTSE >= 0 ) {
+                                       $logicalTTL = min( $ttl ?: INF, self::TTL_LAGGED );
+                               } else {
+                                       $ttl = min( $ttl ?: INF, self::TTL_LAGGED );
+                               }
+                               $this->logger->warning(
+                                       'Lowered set() TTL for {cachekey} due to replication lag.',
+                                       [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ]
+                               );
+                       // Case C: medium length request with medium replication lag
+                       } elseif ( $lockTSE >= 0 ) {
+                               // Store value as *almost* stale to avoid cache and mutex stampedes
+                               $logicalTTL = self::TTL_SECOND;
+                               $this->logger->info(
+                                       'Lowered set() TTL for {cachekey} due to high read lag.',
+                                       [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ]
+                               );
                        } else {
-                               $this->logger->info( 'Rejected set() for {cachekey} due to high read lag.',
-                                       [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ] );
+                               $this->logger->info(
+                                       'Rejected set() for {cachekey} due to high read lag.',
+                                       [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ]
+                               );
 
                                return true; // no-op the write for being unsafe
                        }
                }
 
                // Wrap that value with time/TTL/version metadata
-               $wrapped = $this->wrap( $value, $ttl, $now ) + $wrapExtra;
+               $wrapped = $this->wrap( $value, $logicalTTL ?: $ttl, $now );
+               $storeTTL = $ttl + $staleTTL;
 
-               $func = function ( $cache, $key, $cWrapped ) use ( $wrapped ) {
-                       return ( is_string( $cWrapped ) )
-                               ? false // key is tombstoned; do nothing
-                               : $wrapped;
-               };
+               if ( $creating ) {
+                       $ok = $this->cache->add( self::VALUE_KEY_PREFIX . $key, $wrapped, $storeTTL );
+               } else {
+                       $ok = $this->cache->merge(
+                               self::VALUE_KEY_PREFIX . $key,
+                               function ( $cache, $key, $cWrapped ) use ( $wrapped ) {
+                                       // A string value means that it is a tombstone; do nothing in that case
+                                       return ( is_string( $cWrapped ) ) ? false : $wrapped;
+                               },
+                               $storeTTL,
+                               1 // 1 attempt
+                       );
+               }
 
-               return $this->cache->merge( self::VALUE_KEY_PREFIX . $key, $func, $ttl + $staleTTL, 1 );
+               return $ok;
        }
 
        /**
@@ -632,16 +701,17 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @return bool True if the item was purged or not found, false on failure
         */
        final public function delete( $key, $ttl = self::HOLDOFF_TTL ) {
-               $key = self::VALUE_KEY_PREFIX . $key;
-
                if ( $ttl <= 0 ) {
                        // Publish the purge to all datacenters
-                       $ok = $this->relayDelete( $key );
+                       $ok = $this->relayDelete( self::VALUE_KEY_PREFIX . $key );
                } else {
                        // Publish the purge to all datacenters
-                       $ok = $this->relayPurge( $key, $ttl, self::HOLDOFF_NONE );
+                       $ok = $this->relayPurge( self::VALUE_KEY_PREFIX . $key, $ttl, self::HOLDOFF_NONE );
                }
 
+               $kClass = $this->determineKeyClassForStats( $key );
+               $this->stats->increment( "wanobjectcache.$kClass.delete." . ( $ok ? 'ok' : 'error' ) );
+
                return $ok;
        }
 
@@ -796,7 +866,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         */
        final public function touchCheckKey( $key, $holdoff = self::HOLDOFF_TTL ) {
                // Publish the purge to all datacenters
-               return $this->relayPurge( self::TIME_KEY_PREFIX . $key, self::CHECK_KEY_TTL, $holdoff );
+               $ok = $this->relayPurge( self::TIME_KEY_PREFIX . $key, self::CHECK_KEY_TTL, $holdoff );
+
+               $kClass = $this->determineKeyClassForStats( $key );
+               $this->stats->increment( "wanobjectcache.$kClass.ck_touch." . ( $ok ? 'ok' : 'error' ) );
+
+               return $ok;
        }
 
        /**
@@ -828,7 +903,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         */
        final public function resetCheckKey( $key ) {
                // Publish the purge to all datacenters
-               return $this->relayDelete( self::TIME_KEY_PREFIX . $key );
+               $ok = $this->relayDelete( self::TIME_KEY_PREFIX . $key );
+
+               $kClass = $this->determineKeyClassForStats( $key );
+               $this->stats->increment( "wanobjectcache.$kClass.ck_reset." . ( $ok ? 'ok' : 'error' ) );
+
+               return $ok;
        }
 
        /**
@@ -1055,7 +1135,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *      stampede is worth avoiding. Note that if the key falls out of cache then concurrent
         *      threads will all run the callback on cache miss until the value is saved in cache.
         *      The only stampede protection in that case is from duplicate cache sets when the
-        *      callback takes longer than WANObjectCache::SET_DELAY_HIGH_SEC seconds; consider
+        *      callback takes longer than WANObjectCache::SET_DELAY_HIGH_MS milliseconds; consider
         *      using "busyValue" if such stampedes are a problem. Note that the higher "lockTSE" is
         *      set, the higher the worst-case staleness of returned values can be. Also note that
         *      this option does not by itself handle the case of the key simply expiring on account
@@ -1081,10 +1161,17 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *      It is generally preferable to use a class constant when setting this value.
         *      This has no effect unless pcTTL is used.
         *      Default: WANObjectCache::PC_PRIMARY.
-        *   - version: Integer version number. This allows for callers to make breaking changes to
-        *      how values are stored while maintaining compatability and correct cache purges. New
-        *      versions are stored alongside older versions concurrently. Avoid storing class objects
-        *      however, as this reduces compatibility (due to serialization).
+        *   - version: Integer version number. This lets callers make breaking changes to the format
+        *      of cached values without causing problems for sites that use non-instantaneous code
+        *      deployments. Old and new code will recognize incompatible versions and purges from
+        *      both old and new code will been seen by each other. When this method encounters an
+        *      incompatibly versioned value at the provided key, a "variant key" will be used for
+        *      reading from and saving to cache. The variant key is specific to the key and version
+        *      number provided to this method. If the variant key value is older than that of the
+        *      provided key, or the provided key is non-existant, then the variant key will be seen
+        *      as non-existant. Therefore, delete() calls invalidate the provided key's variant keys.
+        *      The "checkKeys" and "touchedCallback" options still apply to variant keys as usual.
+        *      Avoid storing class objects, as this reduces compatibility (due to serialization).
         *      Default: null.
         *   - minAsOf: Reject values if they were generated before this UNIX timestamp.
         *      This is useful if the source of a key is suspected of having possibly changed
@@ -1220,23 +1307,25 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                $popWindow = $opts['hotTTR'] ?? self::HOT_TTR;
                $ageNew = $opts['ageNew'] ?? self::AGE_NEW;
                $minTime = $opts['minAsOf'] ?? self::MIN_TIMESTAMP_NONE;
-               $versioned = isset( $opts['version'] );
-               $touchedCallback = $opts['touchedCallback'] ?? null;
+               $needsVersion = isset( $opts['version'] );
+               $touchedCb = $opts['touchedCallback'] ?? null;
                $initialTime = $this->getCurrentTime();
 
-               // Get a collection name to describe this class of key
-               $kClass = $this->determineKeyClass( $key );
+               $kClass = $this->determineKeyClassForStats( $key );
 
-               // Get the current key value and populate $curTTL and $asOf accordingly
-               $curTTL = null;
-               $cValue = $this->get( $key, $curTTL, $checkKeys, $asOf ); // current value
-               $value = $cValue; // return value
-               // Apply additional dynamic expiration logic if supplied
-               $curTTL = $this->applyTouchedCallback( $value, $asOf, $curTTL, $touchedCallback );
+               // Get the current key value
+               $curTTL = self::PASS_BY_REF;
+               $curInfo = self::PASS_BY_REF; /** @var array $curInfo */
+               $curValue = $this->get( $key, $curTTL, $checkKeys, $curInfo );
+               // Apply any $touchedCb invalidation timestamp to get the "last purge timestamp"
+               list( $curTTL, $LPT ) = $this->resolveCTL( $curValue, $curTTL, $curInfo, $touchedCb );
+               // Keep track of the best candidate value and its timestamp
+               $value = $curValue; // return value
+               $asOf = $curInfo['asOf']; // return value timestamp
 
                // Determine if a cached value regeneration is needed or desired
                if (
-                       $this->isValid( $value, $versioned, $asOf, $minTime ) &&
+                       $this->isValid( $value, $needsVersion, $asOf, $minTime ) &&
                        $this->isAliveOrInGracePeriod( $curTTL, $graceTTL )
                ) {
                        $preemptiveRefresh = (
@@ -1248,32 +1337,43 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                                $this->stats->increment( "wanobjectcache.$kClass.hit.good" );
 
                                return $value;
-                       } elseif ( $this->asyncHandler ) {
-                               // Update the cache value later, such during post-send of an HTTP request
-                               $func = $this->asyncHandler;
-                               $func( function () use ( $key, $ttl, $callback, $opts, $asOf ) {
-                                       $opts['minAsOf'] = INF; // force a refresh
-                                       $this->doGetWithSetCallback( $key, $ttl, $callback, $opts, $asOf );
-                               } );
+                       } elseif ( $this->scheduleAsyncRefresh( $key, $ttl, $callback, $opts ) ) {
                                $this->stats->increment( "wanobjectcache.$kClass.hit.refresh" );
 
                                return $value;
                        }
                }
 
-               // Only a tombstoned key yields no value yet has a (negative) "current time left"
-               $isKeyTombstoned = ( $curTTL !== null && $value === false );
+               $isKeyTombstoned = ( $curInfo['tombAsOf'] !== null );
+               if ( $isKeyTombstoned ) {
+                       // Get the interim key value since the key is tombstoned (write-holed)
+                       list( $value, $asOf ) = $this->getInterimValue( $key, $needsVersion, $minTime );
+                       // Update the "last purge time" since the $touchedCb timestamp depends on $value
+                       $LPT = $this->resolveTouched( $value, $LPT, $touchedCb );
+               }
+
+               // Reduce mutex and cache set spam while keys are in the tombstone/holdoff period by
+               // checking if $value was genereated by a recent thread much less than a second ago.
+               if (
+                       $this->isValid( $value, $needsVersion, $asOf, $minTime, $LPT ) &&
+                       $this->isVolatileValueAgeNegligible( $initialTime - $asOf )
+               ) {
+                       $this->stats->increment( "wanobjectcache.$kClass.hit.volatile" );
+
+                       return $value;
+               }
+
                // Decide if only one thread should handle regeneration at a time
                $useMutex =
                        // Note that since tombstones no-op set(), $lockTSE and $curTTL cannot be used to
-                       // deduce the key hotness because $curTTL will always keep increasing until the
+                       // deduce the key hotness because |$curTTL| will always keep increasing until the
                        // tombstone expires or is overwritten by a new tombstone. Also, even if $lockTSE
                        // is not set, constant regeneration of a key for the tombstone lifetime might be
                        // very expensive. Assume tombstoned keys are possibly hot in order to reduce
                        // the risk of high regeneration load after the delete() method is called.
                        $isKeyTombstoned ||
                        // Assume a key is hot if requested soon ($lockTSE seconds) after invalidation.
-                       // This avoids stampedes when timestamps from $checkKeys/$touchedCallback bump.
+                       // This avoids stampedes when timestamps from $checkKeys/$touchedCb bump.
                        ( $curTTL !== null && $curTTL <= 0 && abs( $curTTL ) <= $lockTSE ) ||
                        // Assume a key is hot if there is no value and a busy fallback is given.
                        // This avoids stampedes on eviction or preemptive regeneration taking too long.
@@ -1285,23 +1385,13 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        if ( $this->cache->add( self::MUTEX_KEY_PREFIX . $key, 1, self::LOCK_TTL ) ) {
                                // Lock acquired; this thread will recompute the value and update cache
                                $hasLock = true;
-                       } elseif ( $this->isValid( $value, $versioned, $asOf, $minTime ) ) {
+                       } elseif ( $this->isValid( $value, $needsVersion, $asOf, $minTime ) ) {
                                // Lock not acquired and a stale value exists; use the stale value
                                $this->stats->increment( "wanobjectcache.$kClass.hit.stale" );
 
                                return $value;
                        } else {
                                // Lock not acquired and no stale value exists
-                               if ( $isKeyTombstoned ) {
-                                       // Use the INTERIM value from the last thread that regenerated it if possible
-                                       $value = $this->getInterimValue( $key, $versioned, $minTime, $asOf );
-                                       if ( $value !== false ) {
-                                               $this->stats->increment( "wanobjectcache.$kClass.hit.volatile" );
-
-                                               return $value;
-                                       }
-                               }
-
                                if ( $busyValue !== null ) {
                                        // Use the busy fallback value if nothing else
                                        $miss = is_infinite( $minTime ) ? 'renew' : 'miss';
@@ -1321,7 +1411,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                $setOpts = [];
                ++$this->callbackDepth;
                try {
-                       $value = call_user_func_array( $callback, [ $cValue, &$ttl, &$setOpts, $asOf ] );
+                       $value = call_user_func_array( $callback, [ $curValue, &$ttl, &$setOpts, $asOf ] );
                } finally {
                        --$this->callbackDepth;
                }
@@ -1333,16 +1423,13 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                        if ( $isKeyTombstoned ) {
                                if ( $this->checkAndSetCooloff( $key, $kClass, $ago, $lockTSE, $hasLock ) ) {
-                                       // When delete() is called, writes are write-holed by the tombstone,
-                                       // so use a special INTERIM key to pass the new value among threads.
-                                       $tempTTL = max( self::INTERIM_KEY_TTL, (int)$lockTSE ); // set() expects seconds
-                                       $newAsOf = $this->getCurrentTime();
-                                       $wrapped = $this->wrap( $value, $tempTTL, $newAsOf );
-                                       // Avoid using set() to avoid pointless mcrouter broadcasting
-                                       $this->setInterimValue( $key, $wrapped, $tempTTL );
+                                       // Use the interim key value since the key is tombstoned (write-holed)
+                                       $tempTTL = max( self::INTERIM_KEY_TTL, (int)$lockTSE );
+                                       $this->setInterimValue( $key, $value, $tempTTL, $this->getCurrentTime() );
                                }
                        } elseif ( !$useMutex || $hasLock ) {
                                if ( $this->checkAndSetCooloff( $key, $kClass, $ago, $lockTSE, $hasLock ) ) {
+                                       $setOpts['creating'] = ( $curValue === false );
                                        // Save the value unless a lock-winning thread is already expected to do that
                                        $setOpts['lockTSE'] = $lockTSE;
                                        $setOpts['staleTTL'] = $staleTTL;
@@ -1355,7 +1442,6 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                }
 
                if ( $hasLock ) {
-                       // Avoid using delete() to avoid pointless mcrouter broadcasting
                        $this->cache->changeTTL( self::MUTEX_KEY_PREFIX . $key, (int)$initialTime - 60 );
                }
 
@@ -1365,6 +1451,14 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                return $value;
        }
 
+       /**
+        * @param float $age Age of volatile/interim key in seconds
+        * @return bool Whether the age of a volatile value is negligible
+        */
+       private function isVolatileValueAgeNegligible( $age ) {
+               return ( $age < mt_rand( self::RECENT_SET_LOW_MS, self::RECENT_SET_HIGH_MS ) / 1e3 );
+       }
+
        /**
         * @param string $key
         * @param string $kClass
@@ -1382,7 +1476,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                // consistent hashing).
                if ( $lockTSE < 0 || $hasLock ) {
                        return true; // either not a priori hot or thread has the lock
-               } elseif ( $elapsed <= self::SET_DELAY_HIGH_SEC ) {
+               } elseif ( $elapsed <= self::SET_DELAY_HIGH_MS * 1e3 ) {
                        return true; // not enough time for threads to pile up
                }
 
@@ -1402,59 +1496,78 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
        /**
         * @param mixed $value
-        * @param float $asOf
-        * @param float $curTTL
-        * @param callable|null $callback
-        * @return float
+        * @param float|null $curTTL
+        * @param array $curInfo
+        * @param callable|null $touchedCallback
+        * @return array (current time left or null, UNIX timestamp of last purge or null)
+        * @note Callable type hints are not used to avoid class-autoloading
         */
-       protected function applyTouchedCallback( $value, $asOf, $curTTL, $callback ) {
-               if ( $callback === null ) {
-                       return $curTTL;
+       protected function resolveCTL( $value, $curTTL, $curInfo, $touchedCallback ) {
+               if ( $touchedCallback === null || $value === false ) {
+                       return [ $curTTL, max( $curInfo['tombAsOf'], $curInfo['lastCKPurge'] ) ];
                }
 
-               if ( !is_callable( $callback ) ) {
+               if ( !is_callable( $touchedCallback ) ) {
                        throw new InvalidArgumentException( "Invalid expiration callback provided." );
                }
 
-               if ( $value !== false ) {
-                       $touched = $callback( $value );
-                       if ( $touched !== null && $touched >= $asOf ) {
-                               $curTTL = min( $curTTL, self::TINY_NEGATIVE, $asOf - $touched );
-                       }
+               $touched = $touchedCallback( $value );
+               if ( $touched !== null && $touched >= $curInfo['asOf'] ) {
+                       $curTTL = min( $curTTL, self::TINY_NEGATIVE, $curInfo['asOf'] - $touched );
+               }
+
+               return [ $curTTL, max( $curInfo['tombAsOf'], $curInfo['lastCKPurge'], $touched ) ];
+       }
+
+       /**
+        * @param mixed $value
+        * @param float|null $lastPurge
+        * @param callable|null $touchedCallback
+        * @return float|null UNIX timestamp of last purge or null
+        * @note Callable type hints are not used to avoid class-autoloading
+        */
+       protected function resolveTouched( $value, $lastPurge, $touchedCallback ) {
+               if ( $touchedCallback === null || $value === false ) {
+                       return $lastPurge;
+               }
+
+               if ( !is_callable( $touchedCallback ) ) {
+                       throw new InvalidArgumentException( "Invalid expiration callback provided." );
                }
 
-               return $curTTL;
+               return max( $touchedCallback( $value ), $lastPurge );
        }
 
        /**
         * @param string $key
         * @param bool $versioned
         * @param float $minTime
-        * @param mixed &$asOf
-        * @return mixed
+        * @return array (cached value or false, cached value timestamp or null)
         */
-       protected function getInterimValue( $key, $versioned, $minTime, &$asOf ) {
+       protected function getInterimValue( $key, $versioned, $minTime ) {
                if ( !$this->useInterimHoldOffCaching ) {
-                       return false; // disabled
+                       return [ false, null ]; // disabled
                }
 
                $wrapped = $this->cache->get( self::INTERIM_KEY_PREFIX . $key );
                list( $value ) = $this->unwrap( $wrapped, $this->getCurrentTime() );
-               if ( $this->isValid( $value, $versioned, $asOf, $minTime ) ) {
-                       $asOf = $wrapped[self::FLD_TIME];
-
-                       return $value;
+               $valueAsOf = $wrapped[self::FLD_TIME] ?? null;
+               if ( $this->isValid( $value, $versioned, $valueAsOf, $minTime ) ) {
+                       return [ $value, $valueAsOf ];
                }
 
-               return false;
+               return [ false, null ];
        }
 
        /**
         * @param string $key
-        * @param array $wrapped
+        * @param mixed $value
         * @param int $tempTTL
+        * @param float $newAsOf
         */
-       protected function setInterimValue( $key, $wrapped, $tempTTL ) {
+       protected function setInterimValue( $key, $value, $tempTTL, $newAsOf ) {
+               $wrapped = $this->wrap( $value, $tempTTL, $newAsOf );
+
                $this->cache->merge(
                        self::INTERIM_KEY_PREFIX . $key,
                        function () use ( $wrapped ) {
@@ -1989,6 +2102,28 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                return $ok;
        }
 
+       /**
+        * @param string $key
+        * @param int $ttl
+        * @param callable $callback
+        * @param array $opts
+        * @return bool Success
+        */
+       private function scheduleAsyncRefresh( $key, $ttl, $callback, $opts ) {
+               if ( !$this->asyncHandler ) {
+                       return false;
+               }
+               // Update the cache value later, such during post-send of an HTTP request
+               $func = $this->asyncHandler;
+               $func( function () use ( $key, $ttl, $callback, $opts ) {
+                       $asOf = null; // unused
+                       $opts['minAsOf'] = INF; // force a refresh
+                       $this->doGetWithSetCallback( $key, $ttl, $callback, $opts, $asOf );
+               } );
+
+               return true;
+       }
+
        /**
         * Check if a key is fresh or in the grace window and thus due for randomized reuse
         *
@@ -2094,14 +2229,18 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @param bool $versioned
         * @param float $asOf The time $value was generated
         * @param float $minTime The last time the main value was generated (0.0 if unknown)
+        * @param float|null $purgeTime The last time the value was invalidated
         * @return bool
         */
-       protected function isValid( $value, $versioned, $asOf, $minTime ) {
+       protected function isValid( $value, $versioned, $asOf, $minTime, $purgeTime = null ) {
+               // Avoid reading any key not generated after the latest delete() or touch
+               $safeMinTime = max( $minTime, $purgeTime + self::TINY_POSTIVE );
+
                if ( $value === false ) {
                        return false;
                } elseif ( $versioned && !isset( $value[self::VFLD_VERSION] ) ) {
                        return false;
-               } elseif ( $minTime > 0 && $asOf < $minTime ) {
+               } elseif ( $safeMinTime > 0 && $asOf < $minTime ) {
                        return false;
                }
 
@@ -2128,9 +2267,11 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /**
         * Do not use this method outside WANObjectCache
         *
+        * The cached value will be false if absent/tombstoned/malformed
+        *
         * @param array|string|bool $wrapped
         * @param float $now Unix Current timestamp (preferrably pre-query)
-        * @return array (mixed; false if absent/tombstoned/malformed, current time left)
+        * @return array (cached value or false, current TTL, value timestamp, tombstone timestamp)
         */
        protected function unwrap( $wrapped, $now ) {
                // Check if the value is a tombstone
@@ -2138,22 +2279,17 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                if ( $purge !== false ) {
                        // Purged values should always have a negative current $ttl
                        $curTTL = min( $purge[self::FLD_TIME] - $now, self::TINY_NEGATIVE );
-                       return [ false, $curTTL ];
+                       return [ false, $curTTL, null, $purge[self::FLD_TIME] ];
                }
 
                if ( !is_array( $wrapped ) // not found
                        || !isset( $wrapped[self::FLD_VERSION] ) // wrong format
                        || $wrapped[self::FLD_VERSION] !== self::VERSION // wrong version
                ) {
-                       return [ false, null ];
+                       return [ false, null, null, null ];
                }
 
-               $flags = $wrapped[self::FLD_FLAGS] ?? 0;
-               if ( ( $flags & self::FLG_STALE ) == self::FLG_STALE ) {
-                       // Treat as expired, with the cache time as the expiration
-                       $age = $now - $wrapped[self::FLD_TIME];
-                       $curTTL = min( -$age, self::TINY_NEGATIVE );
-               } elseif ( $wrapped[self::FLD_TTL] > 0 ) {
+               if ( $wrapped[self::FLD_TTL] > 0 ) {
                        // Get the approximate time left on the key
                        $age = $now - $wrapped[self::FLD_TIME];
                        $curTTL = max( $wrapped[self::FLD_TTL] - $age, 0.0 );
@@ -2164,10 +2300,10 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                if ( $wrapped[self::FLD_TIME] < $this->epoch ) {
                        // Values this old are ignored
-                       return [ false, null ];
+                       return [ false, null, null, null ];
                }
 
-               return [ $wrapped[self::FLD_VALUE], $curTTL ];
+               return [ $wrapped[self::FLD_VALUE], $curTTL, $wrapped[self::FLD_TIME], null ];
        }
 
        /**
@@ -2186,9 +2322,9 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
        /**
         * @param string $key String of the format <scope>:<class>[:<class or variable>]...
-        * @return string
+        * @return string A collection name to describe this class of key
         */
-       protected function determineKeyClass( $key ) {
+       protected function determineKeyClassForStats( $key ) {
                $parts = explode( ':', $key );
 
                return $parts[1] ?? $parts[0]; // sanity
index 764230b..8c419b2 100644 (file)
  * @ingroup Cache
  */
 class WinCacheBagOStuff extends BagOStuff {
-       protected function doGet( $key, $flags = 0 ) {
-               $val = wincache_ucache_get( $key );
-               if ( is_string( $val ) ) {
-                       $val = unserialize( $val );
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
+               $casToken = null;
+
+               $blob = wincache_ucache_get( $key );
+               if ( !is_string( $blob ) ) {
+                       return false;
+               }
+
+               $value = unserialize( $blob );
+               if ( $value !== false ) {
+                       $casToken = (string)$blob; // don't bother hashing this
+               }
+
+               return $value;
+       }
+
+       protected function cas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
+               if ( !wincache_lock( $key ) ) { // optimize with FIFO lock
+                       return false;
+               }
+
+               $curCasToken = null; // passed by reference
+               $this->doGet( $key, self::READ_LATEST, $curCasToken );
+               if ( $casToken === $curCasToken ) {
+                       $success = $this->set( $key, $value, $exptime, $flags );
+               } else {
+                       $this->logger->info(
+                               __METHOD__ . ' failed due to race condition for {key}.',
+                               [ 'key' => $key ]
+                       );
+
+                       $success = false; // mismatched or failed
                }
 
-               return $val;
+               wincache_unlock( $key );
+
+               return $success;
        }
 
        public function set( $key, $value, $expire = 0, $flags = 0 ) {
                $result = wincache_ucache_set( $key, serialize( $value ), $expire );
 
-               /* wincache_ucache_set returns an empty array on success if $value
-                * was an array, bool otherwise */
-               return ( is_array( $result ) && $result === [] ) || $result;
+               // false positive, wincache_ucache_set returns an empty array
+               // in some circumstances.
+               // @phan-suppress-next-line PhanTypeComparisonToArray
+               return ( $result === [] || $result === true );
        }
 
-       public function delete( $key ) {
-               wincache_ucache_delete( $key );
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               $result = wincache_ucache_add( $key, serialize( $value ), $exptime );
 
-               return true;
+               // false positive, wincache_ucache_add returns an empty array
+               // in some circumstances.
+               // @phan-suppress-next-line PhanTypeComparisonToArray
+               return ( $result === [] || $result === true );
        }
 
-       public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               if ( wincache_lock( $key ) ) { // optimize with FIFO lock
-                       $ok = $this->mergeViaLock( $key, $callback, $exptime, $attempts, $flags );
-                       wincache_unlock( $key );
-               } else {
-                       $ok = false;
-               }
+       public function delete( $key, $flags = 0 ) {
+               wincache_ucache_delete( $key );
 
-               return $ok;
+               return true;
        }
 
        /**
@@ -105,18 +134,20 @@ class WinCacheBagOStuff extends BagOStuff {
         * @return int|bool New value or false on failure
         */
        public function incr( $key, $value = 1 ) {
-               if ( !$this->lock( $key ) ) {
+               if ( !wincache_lock( $key ) ) { // optimize with FIFO lock
                        return false;
                }
-               $n = $this->get( $key );
-               if ( $this->isInteger( $n ) ) { // key exists?
-                       $n += intval( $value );
+
+               $n = $this->doGet( $key );
+               if ( $this->isInteger( $n ) ) {
+                       $n = max( $n + (int)$value, 0 );
                        $oldTTL = wincache_ucache_info( false, $key )["ucache_entries"][1]["ttl_seconds"];
-                       $this->set( $key, max( 0, $n ), $oldTTL );
+                       $this->set( $key, $n, $oldTTL );
                } else {
                        $n = false;
                }
-               $this->unlock( $key );
+
+               wincache_unlock( $key );
 
                return $n;
        }
index 3e71e36..62a2968 100644 (file)
@@ -72,7 +72,7 @@ class ChronologyProtector implements LoggerAwareInterface {
 
        /**
         * @param BagOStuff $store
-        * @param array[] $client Map of (ip: <IP>, agent: <user-agent> [, clientId: <hash>] )
+        * @param array $client Map of (ip: <IP>, agent: <user-agent> [, clientId: <hash>] )
         * @param int|null $posIndex Write counter index [optional]
         * @since 1.27
         */
diff --git a/includes/libs/rdbms/database/AtomicSectionIdentifier.php b/includes/libs/rdbms/database/AtomicSectionIdentifier.php
deleted file mode 100644 (file)
index c6e3d44..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-namespace Wikimedia\Rdbms;
-
-/**
- * Class used for token representing identifiers for atomic sections from IDatabase instances
- */
-class AtomicSectionIdentifier {
-}
index f693dd5..b216892 100644 (file)
@@ -8,7 +8,6 @@ use InvalidArgumentException;
  * Helper class to handle automatically marking connections as reusable (via RAII pattern)
  * as well handling deferring the actual network connection until the handle is used
  *
- * @note: proxy methods are defined explicitly to avoid interface errors
  * @ingroup Database
  * @since 1.22
  */
@@ -19,6 +18,8 @@ class DBConnRef implements IDatabase {
        private $conn;
        /** @var array|null N-tuple of (server index, group, DatabaseDomain|string) */
        private $params;
+       /** @var int One of DB_MASTER/DB_REPLICA */
+       private $role;
 
        const FLD_INDEX = 0;
        const FLD_GROUP = 1;
@@ -27,10 +28,13 @@ class DBConnRef implements IDatabase {
 
        /**
         * @param ILoadBalancer $lb Connection manager for $conn
-        * @param Database|array $conn Database handle or (server index, query groups, domain, flags)
+        * @param Database|array $conn Database or (server index, query groups, domain, flags)
+        * @param int $role The type of connection asked for; one of DB_MASTER/DB_REPLICA
+        * @internal This method should not be called outside of LoadBalancer
         */
-       public function __construct( ILoadBalancer $lb, $conn ) {
+       public function __construct( ILoadBalancer $lb, $conn, $role ) {
                $this->lb = $lb;
+               $this->role = $role;
                if ( $conn instanceof Database ) {
                        $this->conn = $conn; // live handle
                } elseif ( is_array( $conn ) && count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
@@ -42,13 +46,21 @@ class DBConnRef implements IDatabase {
 
        function __call( $name, array $arguments ) {
                if ( $this->conn === null ) {
-                       list( $db, $groups, $wiki, $flags ) = $this->params;
-                       $this->conn = $this->lb->getConnection( $db, $groups, $wiki, $flags );
+                       list( $index, $groups, $wiki, $flags ) = $this->params;
+                       $this->conn = $this->lb->getConnection( $index, $groups, $wiki, $flags );
                }
 
                return $this->conn->$name( ...$arguments );
        }
 
+       /**
+        * @return int DB_MASTER when this *requires* the master DB, otherwise DB_REPLICA
+        * @since 1.33
+        */
+       public function getReferenceRole() {
+               return $this->role;
+       }
+
        public function getServerInfo() {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -74,11 +86,29 @@ class DBConnRef implements IDatabase {
        }
 
        public function tablePrefix( $prefix = null ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
+               if ( $this->conn === null && $prefix === null ) {
+                       $domain = DatabaseDomain::newFromId( $this->params[self::FLD_DOMAIN] );
+                       // Avoid triggering a database connection
+                       return $domain->getTablePrefix();
+               } elseif ( $this->conn !== null && $prefix === null ) {
+                       // This will just return the prefix
+                       return $this->__call( __FUNCTION__, func_get_args() );
+               }
+               // Disallow things that might confuse the LoadBalancer tracking
+               throw new DBUnexpectedError( $this, "Database selection is disallowed to enable reuse." );
        }
 
        public function dbSchema( $schema = null ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
+               if ( $this->conn === null && $schema === null ) {
+                       $domain = DatabaseDomain::newFromId( $this->params[self::FLD_DOMAIN] );
+                       // Avoid triggering a database connection
+                       return $domain->getSchema();
+               } elseif ( $this->conn !== null && $schema === null ) {
+                       // This will just return the schema
+                       return $this->__call( __FUNCTION__, func_get_args() );
+               }
+               // Disallow things that might confuse the LoadBalancer tracking
+               throw new DBUnexpectedError( $this, "Database selection is disallowed to enable reuse." );
        }
 
        public function getLBInfo( $name = null ) {
@@ -86,11 +116,13 @@ class DBConnRef implements IDatabase {
        }
 
        public function setLBInfo( $name, $value = null ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
+               // Disallow things that might confuse the LoadBalancer tracking
+               throw new DBUnexpectedError( $this, "Changing LB info is disallowed to enable reuse." );
        }
 
        public function setLazyMasterHandle( IDatabase $conn ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
+               // Disallow things that might confuse the LoadBalancer tracking
+               throw new DBUnexpectedError( $this, "Database injection is disallowed to enable reuse." );
        }
 
        public function implicitGroupby() {
@@ -179,6 +211,19 @@ class DBConnRef implements IDatabase {
        }
 
        public function getType() {
+               if ( $this->conn === null ) {
+                       // Avoid triggering a database connection
+                       if ( $this->params[self::FLD_INDEX] === ILoadBalancer::DB_MASTER ) {
+                               $index = $this->lb->getWriterIndex();
+                       } else {
+                               $index = $this->params[self::FLD_INDEX];
+                       }
+                       if ( $index >= 0 ) {
+                               // In theory, if $index is DB_REPLICA, the type could vary
+                               return $this->lb->getServerType( $index );
+                       }
+               }
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -231,11 +276,15 @@ class DBConnRef implements IDatabase {
        }
 
        public function close() {
-               return $this->__call( __FUNCTION__, func_get_args() );
+               throw new DBUnexpectedError( $this->conn, 'Cannot close shared connection.' );
        }
 
-       public function query( $sql, $fname = __METHOD__, $tempIgnore = false ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
+       public function query( $sql, $fname = __METHOD__, $flags = 0 ) {
+               if ( $this->role !== ILoadBalancer::DB_MASTER ) {
+                       $flags |= IDatabase::QUERY_REPLICA_ROLE;
+               }
+
+               return $this->__call( __FUNCTION__, [ $sql, $fname, $flags ] );
        }
 
        public function freeResult( $res ) {
@@ -268,6 +317,10 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       public function limitResult( $sql, $limit, $offset = false ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
        public function selectRow(
                $table, $vars, $conds, $fname = __METHOD__,
                $options = [], $join_conds = []
@@ -290,6 +343,8 @@ class DBConnRef implements IDatabase {
        public function lockForUpdate(
                $table, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
        ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -306,10 +361,14 @@ class DBConnRef implements IDatabase {
        }
 
        public function insert( $table, $a, $fname = __METHOD__, $options = [] ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function update( $table, $values, $conds, $fname = __METHOD__, $options = [] ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -381,6 +440,12 @@ class DBConnRef implements IDatabase {
        }
 
        public function getDBname() {
+               if ( $this->conn === null ) {
+                       $domain = DatabaseDomain::newFromId( $this->params[self::FLD_DOMAIN] );
+                       // Avoid triggering a database connection
+                       return $domain->getDatabase();
+               }
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -392,6 +457,10 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       public function addIdentifierQuotes( $s ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
        public function buildLike() {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -405,26 +474,36 @@ class DBConnRef implements IDatabase {
        }
 
        public function nextSequenceValue( $seqName ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function upsert(
-               $table, array $rows, array $uniqueIndexes, array $set, $fname = __METHOD__
+               $table, array $rows, $uniqueIndexes, array $set, $fname = __METHOD__
        ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function deleteJoin(
                $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = __METHOD__
        ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function delete( $table, $conds, $fname = __METHOD__ ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -432,6 +511,8 @@ class DBConnRef implements IDatabase {
                $destTable, $srcTable, $varMap, $conds,
                $fname = __METHOD__, $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -499,18 +580,21 @@ class DBConnRef implements IDatabase {
        }
 
        public function onTransactionResolution( callable $callback, $fname = __METHOD__ ) {
+               // DB_REPLICA role: caller might want to refresh cache after a REPEATABLE-READ snapshot
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function onTransactionCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
+               // DB_REPLICA role: caller might want to refresh cache after a REPEATABLE-READ snapshot
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
+               return $this->onTransactionCommitOrIdle( $callback, $fname );
        }
 
        public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
+               // DB_REPLICA role: caller might want to refresh cache after a cache mutex is released
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -521,20 +605,24 @@ class DBConnRef implements IDatabase {
        public function startAtomic(
                $fname = __METHOD__, $cancelable = IDatabase::ATOMIC_NOT_CANCELABLE
        ) {
+               // Don't call assertRoleAllowsWrites(); caller might want a REPEATABLE-READ snapshot
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function endAtomic( $fname = __METHOD__ ) {
+               // Don't call assertRoleAllowsWrites(); caller might want a REPEATABLE-READ snapshot
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function cancelAtomic( $fname = __METHOD__, AtomicSectionIdentifier $sectionId = null ) {
+               // Don't call assertRoleAllowsWrites(); caller might want a REPEATABLE-READ snapshot
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function doAtomicSection(
                $fname, callable $callback, $cancelable = self::ATOMIC_NOT_CANCELABLE
        ) {
+               // Don't call assertRoleAllowsWrites(); caller might want a REPEATABLE-READ snapshot
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -597,18 +685,26 @@ class DBConnRef implements IDatabase {
        }
 
        public function lockIsFree( $lockName, $method ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function lock( $lockName, $method, $timeout = 5 ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function unlock( $lockName, $method ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function getScopedLockAndFlush( $lockKey, $fname, $timeout ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -644,6 +740,26 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       /**
+        * Error out if the role is not DB_MASTER
+        *
+        * Note that the underlying connection may or may not itself be read-only.
+        * It could even be to a writable master (both server-side and to the application).
+        * This error is meant for the case when a DB_REPLICA handle was requested but a
+        * a write was attempted on that handle regardless.
+        *
+        * In configurations where the master DB has some generic read load or is the only server,
+        * DB_MASTER/DB_REPLICA will sometimes (or always) use the same connection to the master DB.
+        * This does not effect the role of DBConnRef instances.
+        * @throws DBReadOnlyRoleError
+        */
+       protected function assertRoleAllowsWrites() {
+               // DB_MASTER is "prima facie" writable
+               if ( $this->role !== ILoadBalancer::DB_MASTER ) {
+                       throw new DBReadOnlyRoleError( $this->conn, "Cannot write with role DB_REPLICA" );
+               }
+       }
+
        /**
         * Clean up the connection when out of scope
         */
index b3597df..beca663 100644 (file)
@@ -61,8 +61,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        const SLOW_WRITE_SEC = 0.500;
        const SMALL_WRITE_ROWS = 100;
 
-       /** @var string Whether lock granularity is on the level of the entire database */
+       /** @var string Lock granularity is on the level of the entire database */
        const ATTR_DB_LEVEL_LOCKING = 'db-level-locking';
+       /** @var string The SCHEMA keyword refers to a grouping of tables in a database */
+       const ATTR_SCHEMAS_AS_TABLE_GROUPS = 'supports-schemas';
 
        /** @var int New Database instance will not be connected yet when returned */
        const NEW_UNCONNECTED = 0;
@@ -102,7 +104,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /** @var callable Deprecation logging callback */
        protected $deprecationLogger;
 
-       /** @var resource|null Database connection */
+       /** @var object|resource|null Database connection */
        protected $conn = null;
        /** @var bool */
        protected $opened = false;
@@ -260,7 +262,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /** @var int[] Prior flags member variable values */
        private $priorFlags = [];
 
-       /** @var mixed Class name or object With profileIn/profileOut methods */
+       /** @var callable|null */
        protected $profiler;
        /** @var TransactionProfiler */
        protected $trxProfiler;
@@ -280,6 +282,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /** @var int No transaction is active */
        const STATUS_TRX_NONE = 3;
 
+       /** @var int Writes to this temporary table do not affect lastDoneWrites() */
+       const TEMP_NORMAL = 1;
+       /** @var int Writes to this temporary table effect lastDoneWrites() */
+       const TEMP_PSEUDO_PERMANENT = 2;
+
        /**
         * @note exceptions for missing libraries/drivers should be thrown in initConnection()
         * @param array $params Parameters passed from Database::factory()
@@ -308,7 +315,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                $this->srvCache = $params['srvCache'] ?? new HashBagOStuff();
 
-               $this->profiler = $params['profiler'];
+               $this->profiler = is_callable( $params['profiler'] ) ? $params['profiler'] : null;
                $this->trxProfiler = $params['trxProfiler'];
                $this->connLogger = $params['connLogger'];
                $this->queryLogger = $params['queryLogger'];
@@ -408,9 +415,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *      used to adjust lock timeouts or encoding modes and the like.
         *   - connLogger: Optional PSR-3 logger interface instance.
         *   - queryLogger: Optional PSR-3 logger interface instance.
-        *   - profiler: Optional class name or object with profileIn()/profileOut() methods.
-        *      These will be called in query(), using a simplified version of the SQL that also
-        *      includes the agent as a SQL comment.
+        *   - profiler : Optional callback that takes a section name argument and returns
+        *      a ScopedCallback instance that ends the profile section in its destructor.
+        *      These will be called in query(), using a simplified version of the SQL that
+        *      also includes the agent as a SQL comment.
         *   - trxProfiler: Optional TransactionProfiler instance.
         *   - errorLogger: Optional callback that takes an Exception and logs it.
         *   - deprecationLogger: Optional callback that takes a string and logs it.
@@ -474,12 +482,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /**
         * @param string $dbType A possible DB type (sqlite, mysql, postgres,...)
         * @param string|null $driver Optional name of a specific DB client driver
-        * @return array Map of (Database::ATTRIBUTE_* constant => value) for all such constants
+        * @return array Map of (Database::ATTR_* constant => value) for all such constants
         * @throws InvalidArgumentException
         * @since 1.31
         */
        final public static function attributesFromType( $dbType, $driver = null ) {
-               static $defaults = [ self::ATTR_DB_LEVEL_LOCKING => false ];
+               static $defaults = [
+                       self::ATTR_DB_LEVEL_LOCKING => false,
+                       self::ATTR_SCHEMAS_AS_TABLE_GROUPS => false
+               ];
 
                $class = self::getClass( $dbType, $driver );
 
@@ -513,20 +524,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $possibleDrivers = $builtinTypes[$dbType];
                        if ( is_string( $possibleDrivers ) ) {
                                $class = $possibleDrivers;
+                       } elseif ( (string)$driver !== '' ) {
+                               if ( !isset( $possibleDrivers[$driver] ) ) {
+                                       throw new InvalidArgumentException( __METHOD__ .
+                                               " type '$dbType' does not support driver '{$driver}'" );
+                               }
+
+                               $class = $possibleDrivers[$driver];
                        } else {
-                               if ( (string)$driver !== '' ) {
-                                       if ( !isset( $possibleDrivers[$driver] ) ) {
-                                               throw new InvalidArgumentException( __METHOD__ .
-                                                       " type '$dbType' does not support driver '{$driver}'" );
-                                       } else {
-                                               $class = $possibleDrivers[$driver];
-                                       }
-                               } else {
-                                       foreach ( $possibleDrivers as $posDriver => $possibleClass ) {
-                                               if ( extension_loaded( $posDriver ) ) {
-                                                       $class = $possibleClass;
-                                                       break;
-                                               }
+                               foreach ( $possibleDrivers as $posDriver => $possibleClass ) {
+                                       if ( extension_loaded( $posDriver ) ) {
+                                               $class = $possibleClass;
+                                               break;
                                        }
                                }
                        }
@@ -543,7 +552,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * @return array Map of (Database::ATTRIBUTE_* constant => value
+        * @return array Map of (Database::ATTR_* constant => value
         * @since 1.31
         */
        protected static function getAttributes() {
@@ -606,6 +615,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function dbSchema( $schema = null ) {
+               if ( strlen( $schema ) && $this->getDBname() === null ) {
+                       throw new DBUnexpectedError( $this, "Cannot set schema to '$schema'; no database set." );
+               }
+
                $old = $this->currentDomain->getSchema();
                if ( $schema !== null ) {
                        $this->currentDomain = new DatabaseDomain(
@@ -629,13 +642,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        public function getLBInfo( $name = null ) {
                if ( is_null( $name ) ) {
                        return $this->lbInfo;
-               } else {
-                       if ( array_key_exists( $name, $this->lbInfo ) ) {
-                               return $this->lbInfo[$name];
-                       } else {
-                               return null;
-                       }
                }
+
+               if ( array_key_exists( $name, $this->lbInfo ) ) {
+                       return $this->lbInfo[$name];
+               }
+
+               return null;
        }
 
        public function setLBInfo( $name, $value = null ) {
@@ -925,6 +938,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        final public function close() {
                $exception = null; // error to throw after disconnecting
 
+               $wasOpen = $this->opened;
+               // This should mostly do nothing if the connection is already closed
                if ( $this->conn ) {
                        // Roll back any dangling transaction first
                        if ( $this->trxLevel ) {
@@ -967,11 +982,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                        // Close the actual connection in the binding handle
                        $closed = $this->closeConnection();
-                       $this->conn = false;
                } else {
                        $closed = true; // already closed; nothing to do
                }
 
+               $this->conn = false;
                $this->opened = false;
 
                // Throw any unexpected errors after having disconnected
@@ -979,28 +994,55 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        throw $exception;
                }
 
-               // Sanity check that no callbacks are dangling
-               $fnames = $this->pendingWriteAndCallbackCallers();
-               if ( $fnames ) {
-                       throw new RuntimeException(
-                               "Transaction callbacks are still pending:\n" . implode( ', ', $fnames )
-                       );
+               // Note that various subclasses call close() at the start of open(), which itself is
+               // called by replaceLostConnection(). In that case, just because onTransactionResolution()
+               // callbacks are pending does not mean that an exception should be thrown. Rather, they
+               // will be executed after the reconnection step.
+               if ( $wasOpen ) {
+                       // Sanity check that no callbacks are dangling
+                       $fnames = $this->pendingWriteAndCallbackCallers();
+                       if ( $fnames ) {
+                               throw new RuntimeException(
+                                       "Transaction callbacks are still pending:\n" . implode( ', ', $fnames )
+                               );
+                       }
                }
 
                return $closed;
        }
 
        /**
-        * Make sure isOpen() returns true as a sanity check
+        * Make sure there is an open connection handle (alive or not) as a sanity check
+        *
+        * This guards against fatal errors to the binding handle not being defined
+        * in cases where open() was never called or close() was already called
         *
         * @throws DBUnexpectedError
         */
-       protected function assertOpen() {
+       protected function assertHasConnectionHandle() {
                if ( !$this->isOpen() ) {
                        throw new DBUnexpectedError( $this, "DB connection was already closed." );
                }
        }
 
+       /**
+        * Make sure that this server is not marked as a replica nor read-only as a sanity check
+        *
+        * @throws DBUnexpectedError
+        */
+       protected function assertIsWritableMaster() {
+               if ( $this->getLBInfo( 'replica' ) === true ) {
+                       throw new DBReadOnlyRoleError(
+                               $this,
+                               'Write operations are not allowed on replica database connections.'
+                       );
+               }
+               $reason = $this->getReadOnlyReason();
+               if ( $reason !== false ) {
+                       throw new DBReadOnlyError( $this, "Database is read-only: $reason" );
+               }
+       }
+
        /**
         * Closes underlying database connection
         * @since 1.20
@@ -1019,13 +1061,22 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * Run a query and return a DBMS-dependent wrapper (that has all IResultWrapper methods)
+        * Run a query and return a DBMS-dependent wrapper or boolean
         *
-        * This might return things, such as mysqli_result, that do not formally implement
-        * IResultWrapper, but nonetheless implement all of its methods correctly
+        * For SELECT queries, this returns either:
+        *   - a) A driver-specific value/resource, only on success. This can be iterated
+        *        over by calling fetchObject()/fetchRow() until there are no more rows.
+        *        Alternatively, the result can be passed to resultObject() to obtain a
+        *        ResultWrapper instance which can then be iterated over via "foreach".
+        *   - b) False, on any query failure
         *
-        * @param string $sql SQL query.
-        * @return IResultWrapper|bool Iterator to feed to fetchObject/fetchRow; false on failure
+        * For non-SELECT queries, this returns either:
+        *   - a) A driver-specific value/resource, only on success
+        *   - b) True, only on success (e.g. no meaningful result other than "OK")
+        *   - c) False, on any query failure
+        *
+        * @param string $sql SQL query
+        * @return mixed|bool An object, resource, or true on success; false on failure
         */
        abstract protected function doQuery( $sql );
 
@@ -1096,144 +1147,131 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        /**
         * @param string $sql A SQL query
-        * @return bool Whether $sql is SQL for TEMPORARY table operation
+        * @param bool $pseudoPermanent Treat any table from CREATE TEMPORARY as pseudo-permanent
+        * @return int|null A self::TEMP_* constant for temp table operations or null otherwise
         */
-       protected function registerTempTableOperation( $sql ) {
+       protected function registerTempTableWrite( $sql, $pseudoPermanent ) {
+               static $qt = '[`"\']?(\w+)[`"\']?'; // quoted table
+
                if ( preg_match(
-                       '/^CREATE\s+TEMPORARY\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"\']?(\w+)[`"\']?/i',
+                       '/^CREATE\s+TEMPORARY\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?' . $qt . '/i',
                        $sql,
                        $matches
                ) ) {
-                       $this->sessionTempTables[$matches[1]] = 1;
+                       $type = $pseudoPermanent ? self::TEMP_PSEUDO_PERMANENT : self::TEMP_NORMAL;
+                       $this->sessionTempTables[$matches[1]] = $type;
 
-                       return true;
+                       return $type;
                } elseif ( preg_match(
-                       '/^DROP\s+(?:TEMPORARY\s+)?TABLE\s+(?:IF\s+EXISTS\s+)?[`"\']?(\w+)[`"\']?/i',
+                       '/^DROP\s+(?:TEMPORARY\s+)?TABLE\s+(?:IF\s+EXISTS\s+)?' . $qt . '/i',
                        $sql,
                        $matches
                ) ) {
-                       $isTemp = isset( $this->sessionTempTables[$matches[1]] );
+                       $type = $this->sessionTempTables[$matches[1]] ?? null;
                        unset( $this->sessionTempTables[$matches[1]] );
 
-                       return $isTemp;
+                       return $type;
                } elseif ( preg_match(
-                       '/^TRUNCATE\s+(?:TEMPORARY\s+)?TABLE\s+(?:IF\s+EXISTS\s+)?[`"\']?(\w+)[`"\']?/i',
+                       '/^TRUNCATE\s+(?:TEMPORARY\s+)?TABLE\s+(?:IF\s+EXISTS\s+)?' . $qt . '/i',
                        $sql,
                        $matches
                ) ) {
-                       return isset( $this->sessionTempTables[$matches[1]] );
+                       return $this->sessionTempTables[$matches[1]] ?? null;
                } elseif ( preg_match(
-                       '/^(?:INSERT\s+(?:\w+\s+)?INTO|UPDATE|DELETE\s+FROM)\s+[`"\']?(\w+)[`"\']?/i',
+                       '/^(?:(?:INSERT|REPLACE)\s+(?:\w+\s+)?INTO|UPDATE|DELETE\s+FROM)\s+' . $qt . '/i',
                        $sql,
                        $matches
                ) ) {
-                       return isset( $this->sessionTempTables[$matches[1]] );
+                       return $this->sessionTempTables[$matches[1]] ?? null;
                }
 
-               return false;
+               return null;
        }
 
-       public function query( $sql, $fname = __METHOD__, $tempIgnore = false ) {
+       public function query( $sql, $fname = __METHOD__, $flags = 0 ) {
                $this->assertTransactionStatus( $sql, $fname );
+               $this->assertHasConnectionHandle();
 
-               # Avoid fatals if close() was called
-               $this->assertOpen();
+               $flags = (int)$flags; // b/c; this field used to be a bool
+               $ignoreErrors = $this->hasFlags( $flags, self::QUERY_SILENCE_ERRORS );
 
+               $priorTransaction = $this->trxLevel;
                $priorWritesPending = $this->writesOrCallbacksPending();
                $this->lastQuery = $sql;
 
-               $isWrite = $this->isWriteQuery( $sql );
-               if ( $isWrite ) {
-                       $isNonTempWrite = !$this->registerTempTableOperation( $sql );
-               } else {
-                       $isNonTempWrite = false;
-               }
-
-               if ( $isWrite ) {
-                       if ( $this->getLBInfo( 'replica' ) === true ) {
-                               throw new DBError(
-                                       $this,
-                                       'Write operations are not allowed on replica database connections.'
-                               );
-                       }
+               if ( $this->isWriteQuery( $sql ) ) {
                        # In theory, non-persistent writes are allowed in read-only mode, but due to things
                        # like https://bugs.mysql.com/bug.php?id=33669 that might not work anyway...
-                       $reason = $this->getReadOnlyReason();
-                       if ( $reason !== false ) {
-                               throw new DBReadOnlyError( $this, "Database is read-only: $reason" );
+                       $this->assertIsWritableMaster();
+                       # Do not treat temporary table writes as "meaningful writes" that need committing.
+                       # Profile them as reads. Integration tests can override this behavior via $flags.
+                       $pseudoPermanent = $this->hasFlags( $flags, self::QUERY_PSEUDO_PERMANENT );
+                       $tableType = $this->registerTempTableWrite( $sql, $pseudoPermanent );
+                       $isEffectiveWrite = ( $tableType !== self::TEMP_NORMAL );
+                       # DBConnRef uses QUERY_REPLICA_ROLE to enforce the replica role for raw SQL queries
+                       if ( $isEffectiveWrite && $this->hasFlags( $flags, self::QUERY_REPLICA_ROLE ) ) {
+                               throw new DBReadOnlyRoleError( $this, "Cannot write; target role is DB_REPLICA" );
                        }
-                       # Set a flag indicating that writes have been done
-                       $this->lastWriteTime = microtime( true );
+               } else {
+                       $isEffectiveWrite = false;
                }
 
                # 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 (T44598)
                $commentedSql = preg_replace( '/\s|$/', " /* $fname {$this->agent} */ ", $sql, 1 );
 
-               # Start implicit transactions that wrap the request if DBO_TRX is enabled
-               if ( !$this->trxLevel && $this->getFlag( self::DBO_TRX )
-                       && $this->isTransactableQuery( $sql )
-               ) {
-                       $this->begin( __METHOD__ . " ($fname)", self::TRANSACTION_INTERNAL );
-                       $this->trxAutomatic = true;
-               }
-
-               # Keep track of whether the transaction has write queries pending
-               if ( $this->trxLevel && !$this->trxDoneWrites && $isWrite ) {
-                       $this->trxDoneWrites = true;
-                       $this->trxProfiler->transactionWritingIn(
-                               $this->server, $this->getDomainID(), $this->trxShortId );
-               }
-
-               if ( $this->getFlag( self::DBO_DEBUG ) ) {
-                       $this->queryLogger->debug( "{$this->getDomainID()} {$commentedSql}" );
-               }
-
                # Send the query to the server and fetch any corresponding errors
-               $ret = $this->doProfiledQuery( $sql, $commentedSql, $isNonTempWrite, $fname );
+               $ret = $this->attemptQuery( $sql, $commentedSql, $isEffectiveWrite, $fname );
                $lastError = $this->lastError();
                $lastErrno = $this->lastErrno();
 
-               # Try reconnecting if the connection was lost
+               $recoverableSR = false; // recoverable statement rollback?
+               $recoverableCL = false; // recoverable connection loss?
+
                if ( $ret === false && $this->wasConnectionLoss() ) {
-                       # Check if any meaningful session state was lost
-                       $recoverable = $this->canRecoverFromDisconnect( $sql, $priorWritesPending );
+                       # Check if no meaningful session state was lost
+                       $recoverableCL = $this->canRecoverFromDisconnect( $sql, $priorWritesPending );
                        # Update session state tracking and try to restore the connection
                        $reconnected = $this->replaceLostConnection( __METHOD__ );
                        # Silently resend the query to the server if it is safe and possible
-                       if ( $reconnected && $recoverable ) {
-                               $ret = $this->doProfiledQuery( $sql, $commentedSql, $isNonTempWrite, $fname );
+                       if ( $recoverableCL && $reconnected ) {
+                               $ret = $this->attemptQuery( $sql, $commentedSql, $isEffectiveWrite, $fname );
                                $lastError = $this->lastError();
                                $lastErrno = $this->lastErrno();
 
                                if ( $ret === false && $this->wasConnectionLoss() ) {
                                        # Query probably causes disconnects; reconnect and do not re-run it
                                        $this->replaceLostConnection( __METHOD__ );
+                               } else {
+                                       $recoverableCL = false; // connection does not need recovering
+                                       $recoverableSR = $this->wasKnownStatementRollbackError();
                                }
                        }
+               } else {
+                       $recoverableSR = $this->wasKnownStatementRollbackError();
                }
 
                if ( $ret === false ) {
-                       if ( $this->trxLevel ) {
-                               if ( $this->wasKnownStatementRollbackError() ) {
+                       if ( $priorTransaction ) {
+                               if ( $recoverableSR ) {
                                        # We're ignoring an error that caused just the current query to be aborted.
                                        # But log the cause so we can log a deprecation notice if a caller actually
                                        # does ignore it.
                                        $this->trxStatusIgnoredCause = [ $lastError, $lastErrno, $fname ];
-                               } else {
+                               } elseif ( !$recoverableCL ) {
                                        # Either the query was aborted or all queries after BEGIN where aborted.
                                        # In the first case, the only options going forward are (a) ROLLBACK, or
                                        # (b) ROLLBACK TO SAVEPOINT (if one was set). If the later case, the only
                                        # option is ROLLBACK, since the snapshots would have been released.
                                        $this->trxStatus = self::STATUS_TRX_ERROR;
                                        $this->trxStatusCause =
-                                               $this->makeQueryException( $lastError, $lastErrno, $sql, $fname );
-                                       $tempIgnore = false; // cannot recover
+                                               $this->getQueryExceptionAndLog( $lastError, $lastErrno, $sql, $fname );
+                                       $ignoreErrors = false; // cannot recover
                                        $this->trxStatusIgnoredCause = null;
                                }
                        }
 
-                       $this->reportQueryError( $lastError, $lastErrno, $sql, $fname, $tempIgnore );
+                       $this->reportQueryError( $lastError, $lastErrno, $sql, $fname, $ignoreErrors );
                }
 
                return $this->resultObject( $ret );
@@ -1244,12 +1282,28 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *
         * @param string $sql Original SQL query
         * @param string $commentedSql SQL query with debugging/trace comment
-        * @param bool $isWrite Whether the query is a (non-temporary) write operation
+        * @param bool $isEffectiveWrite Whether the query is a (non-temporary table) write
         * @param string $fname Name of the calling function
         * @return bool|ResultWrapper True for a successful write query, ResultWrapper
         *     object for a successful read query, or false on failure
         */
-       private function doProfiledQuery( $sql, $commentedSql, $isWrite, $fname ) {
+       private function attemptQuery( $sql, $commentedSql, $isEffectiveWrite, $fname ) {
+               $this->beginIfImplied( $sql, $fname );
+
+               # Keep track of whether the transaction has write queries pending
+               if ( $isEffectiveWrite ) {
+                       $this->lastWriteTime = microtime( true );
+                       if ( $this->trxLevel && !$this->trxDoneWrites ) {
+                               $this->trxDoneWrites = true;
+                               $this->trxProfiler->transactionWritingIn(
+                                       $this->server, $this->getDomainID(), $this->trxShortId );
+                       }
+               }
+
+               if ( $this->getFlag( self::DBO_DEBUG ) ) {
+                       $this->queryLogger->debug( "{$this->getDomainID()} {$commentedSql}" );
+               }
+
                $isMaster = !is_null( $this->getLBInfo( 'master' ) );
                # generalizeSQL() will probably cut down the query to reasonable
                # logging size most of the time. The substr is really just a sanity check.
@@ -1263,22 +1317,16 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $queryProf .= $this->trxShortId ? " [TRX#{$this->trxShortId}]" : "";
 
                $startTime = microtime( true );
-               if ( $this->profiler ) {
-                       $this->profiler->profileIn( $queryProf );
-               }
+               $ps = $this->profiler ? ( $this->profiler )( $queryProf ) : null;
                $this->affectedRowCount = null;
                $ret = $this->doQuery( $commentedSql );
                $this->affectedRowCount = $this->affectedRows();
-               if ( $this->profiler ) {
-                       $this->profiler->profileOut( $queryProf );
-               }
+               unset( $ps ); // profile out (if set)
                $queryRuntime = max( microtime( true ) - $startTime, 0.0 );
 
-               unset( $queryProfSection ); // profile out (if set)
-
                if ( $ret !== false ) {
                        $this->lastPing = $startTime;
-                       if ( $isWrite && $this->trxLevel ) {
+                       if ( $isEffectiveWrite && $this->trxLevel ) {
                                $this->updateTrxWriteQueryTime( $sql, $queryRuntime, $this->affectedRows() );
                                $this->trxWriteCallers[] = $fname;
                        }
@@ -1291,8 +1339,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->trxProfiler->recordQueryCompletion(
                        $queryProf,
                        $startTime,
-                       $isWrite,
-                       $isWrite ? $this->affectedRows() : $this->numRows( $ret )
+                       $isEffectiveWrite,
+                       $isEffectiveWrite ? $this->affectedRows() : $this->numRows( $ret )
                );
                $this->queryLogger->debug( $sql, [
                        'method' => $fname,
@@ -1303,6 +1351,23 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return $ret;
        }
 
+       /**
+        * Start an implicit transaction if DBO_TRX is enabled and no transaction is active
+        *
+        * @param string $sql
+        * @param string $fname
+        */
+       private function beginIfImplied( $sql, $fname ) {
+               if (
+                       !$this->trxLevel &&
+                       $this->getFlag( self::DBO_TRX ) &&
+                       $this->isTransactableQuery( $sql )
+               ) {
+                       $this->begin( __METHOD__ . " ($fname)", self::TRANSACTION_INTERNAL );
+                       $this->trxAutomatic = true;
+               }
+       }
+
        /**
         * Update the estimated run-time of a query, not counting large row lock times
         *
@@ -1338,12 +1403,19 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
+        * Error out if the DB is not in a valid state for a query via query()
+        *
         * @param string $sql
         * @param string $fname
         * @throws DBTransactionStateError
         */
        private function assertTransactionStatus( $sql, $fname ) {
-               if ( $this->getQueryVerb( $sql ) === 'ROLLBACK' ) { // transaction/savepoint
+               $verb = $this->getQueryVerb( $sql );
+               if ( $verb === 'USE' ) {
+                       throw new DBUnexpectedError( $this, "Got USE query; use selectDomain() instead." );
+               }
+
+               if ( $verb === 'ROLLBACK' ) { // transaction/savepoint
                        return;
                }
 
@@ -1375,8 +1447,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * Determine whether or not it is safe to retry queries after a database
-        * connection is lost
+        * Determine whether it is safe to retry queries after a database connection is lost
         *
         * @param string $sql SQL query
         * @param bool $priorWritesPending Whether there is a transaction open with
@@ -1407,9 +1478,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * Clean things up after session (and thus transaction) loss
+        * Clean things up after session (and thus transaction) loss before reconnect
         */
-       private function handleSessionLoss() {
+       private function handleSessionLossPreconnect() {
                // Clean up tracking of session-level things...
                // https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
                // https://www.postgresql.org/docs/9.2/static/sql-createtable.html (ignoring ON COMMIT)
@@ -1418,17 +1489,26 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                // https://www.postgresql.org/docs/9.4/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
                $this->namedLocksHeld = [];
                // Session loss implies transaction loss
-               $this->handleTransactionLoss();
-       }
-
-       /**
-        * Clean things up after transaction loss
-        */
-       private function handleTransactionLoss() {
                $this->trxLevel = 0;
                $this->trxAtomicCounter = 0;
                $this->trxIdleCallbacks = []; // T67263; transaction already lost
                $this->trxPreCommitCallbacks = []; // T67263; transaction already lost
+               // @note: leave trxRecurringCallbacks in place
+               if ( $this->trxDoneWrites ) {
+                       $this->trxProfiler->transactionWritingOut(
+                               $this->server,
+                               $this->getDomainID(),
+                               $this->trxShortId,
+                               $this->pendingWriteQueryDuration( self::ESTIMATE_TOTAL ),
+                               $this->trxWriteAffectedRows
+                       );
+               }
+       }
+
+       /**
+        * Clean things up after session (and thus transaction) loss after reconnect
+        */
+       private function handleSessionLossPostconnect() {
                try {
                        // Handle callbacks in trxEndCallbacks, e.g. onTransactionResolution().
                        // If callback suppression is set then the array will remain unhandled.
@@ -1460,20 +1540,20 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        /**
         * Report a query error. Log the error, and if neither the object ignore
-        * flag nor the $tempIgnore flag is set, throw a DBQueryError.
+        * flag nor the $ignoreErrors flag is set, throw a DBQueryError.
         *
         * @param string $error
         * @param int $errno
         * @param string $sql
         * @param string $fname
-        * @param bool $tempIgnore
+        * @param bool $ignoreErrors
         * @throws DBQueryError
         */
-       public function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
-               if ( $tempIgnore ) {
+       public function reportQueryError( $error, $errno, $sql, $fname, $ignoreErrors = false ) {
+               if ( $ignoreErrors ) {
                        $this->queryLogger->debug( "SQL ERROR (ignored): $error\n" );
                } else {
-                       $exception = $this->makeQueryException( $error, $errno, $sql, $fname );
+                       $exception = $this->getQueryExceptionAndLog( $error, $errno, $sql, $fname );
 
                        throw $exception;
                }
@@ -1486,7 +1566,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param string $fname
         * @return DBError
         */
-       private function makeQueryException( $error, $errno, $sql, $fname ) {
+       private function getQueryExceptionAndLog( $error, $errno, $sql, $fname ) {
                $sql1line = mb_substr( str_replace( "\n", "\\n", $sql ), 0, 5 * 1024 );
                $this->queryLogger->error(
                        "{fname}\t{db_server}\t{errno}\t{error}\t{sql1line}",
@@ -1496,6 +1576,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                'error' => $error,
                                'sql1line' => $sql1line,
                                'fname' => $fname,
+                               'trace' => ( new RuntimeException() )->getTraceAsString()
                        ] )
                );
                $this->queryLogger->debug( "SQL ERROR: " . $error . "\n" );
@@ -2477,7 +2558,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        throw new InvalidArgumentException( "Table must be a string or Subquery." );
                }
 
-               if ( !strlen( $alias ) || $alias === $table ) {
+               if ( $alias === false || $alias === $table ) {
                        if ( $table instanceof Subquery ) {
                                throw new InvalidArgumentException( "Subquery table missing alias." );
                        }
@@ -2666,15 +2747,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
        }
 
-       /**
-        * Quotes an identifier using `backticks` or "double quotes" depending on the database type.
-        * MySQL uses `backticks` while basically everything else uses double quotes.
-        * Since MySQL is the odd one out here the double quotes are our generic
-        * and we implement backticks in DatabaseMysqlBase.
-        *
-        * @param string $s
-        * @return string
-        */
        public function addIdentifierQuotes( $s ) {
                return '"' . str_replace( '"', '""', $s ) . '"';
        }
@@ -2775,6 +2847,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        return;
                }
 
+               $uniqueIndexes = (array)$uniqueIndexes;
                // Single row case
                if ( !is_array( reset( $rows ) ) ) {
                        $rows = [ $rows ];
@@ -2854,13 +2927,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->query( $sql, $fname );
        }
 
-       public function upsert( $table, array $rows, array $uniqueIndexes, array $set,
+       public function upsert( $table, array $rows, $uniqueIndexes, array $set,
                $fname = __METHOD__
        ) {
                if ( $rows === [] ) {
                        return true; // nothing to do
                }
 
+               $uniqueIndexes = (array)$uniqueIndexes;
                if ( !is_array( reset( $rows ) ) ) {
                        $rows = [ $rows ];
                }
@@ -3117,34 +3191,16 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->query( $sql, $fname );
        }
 
-       /**
-        * Construct a LIMIT query with optional offset. This is used for query
-        * pages. The SQL should be adjusted so that only the first $limit rows
-        * are returned. If $offset is provided as well, then the first $offset
-        * rows should be discarded, and the next $limit rows should be returned.
-        * If the result of the query is not ordered, then the rows to be returned
-        * are theoretically arbitrary.
-        *
-        * $sql is expected to be a SELECT, if that makes a difference.
-        *
-        * The version provided by default works in MySQL and SQLite. It will very
-        * likely need to be overridden for most other DBMSes.
-        *
-        * @param string $sql SQL query we will append the limit too
-        * @param int $limit The SQL limit
-        * @param int|bool $offset The SQL offset (default false)
-        * @throws DBUnexpectedError
-        * @return string
-        */
        public function limitResult( $sql, $limit, $offset = false ) {
                if ( !is_numeric( $limit ) ) {
                        throw new DBUnexpectedError( $this,
                                "Invalid non-numeric limit passed to limitResult()\n" );
                }
-
+               // This version works in MySQL and SQLite. It will very likely need to be
+               // overridden for most other RDBMS subclasses.
                return "$sql LIMIT "
-               . ( ( is_numeric( $offset ) && $offset != 0 ) ? "{$offset}," : "" )
-               . "{$limit} ";
+                       . ( ( is_numeric( $offset ) && $offset != 0 ) ? "{$offset}," : "" )
+                       . "{$limit} ";
        }
 
        public function unionSupportsOrderAndLimit() {
@@ -3279,7 +3335,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * @return bool Whether it is safe to assume the given error only caused statement rollback
+        * @return bool Whether it is known that the last query error only caused statement rollback
         * @note This is for backwards compatibility for callers catching DBError exceptions in
         *   order to ignore problems like duplicate key errors or foriegn key violations
         * @since 1.31
@@ -3510,6 +3566,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                list( $phpCallback ) = $callback;
                                $this->clearFlag( self::DBO_TRX ); // make each query its own transaction
                                try {
+                                       // @phan-suppress-next-line PhanParamTooManyCallable
                                        call_user_func( $phpCallback, $trigger, $this );
                                } catch ( Exception $ex ) {
                                        call_user_func( $this->errorLogger, $ex );
@@ -3840,8 +3897,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        throw new DBUnexpectedError( $this, $msg );
                }
 
-               // Avoid fatals if close() was called
-               $this->assertOpen();
+               $this->assertHasConnectionHandle();
 
                $this->doBegin( $fname );
                $this->trxStatus = self::STATUS_TRX_OK;
@@ -3904,21 +3960,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                        "$fname: Flushing an explicit transaction, getting out of sync."
                                );
                        }
-               } else {
-                       if ( !$this->trxLevel ) {
-                               $this->queryLogger->error(
-                                       "$fname: No transaction to commit, something got out of sync." );
-                               return; // nothing to do
-                       } elseif ( $this->trxAutomatic ) {
-                               throw new DBUnexpectedError(
-                                       $this,
-                                       "$fname: Expected mass commit of all peer transactions (DBO_TRX set)."
-                               );
-                       }
+               } elseif ( !$this->trxLevel ) {
+                       $this->queryLogger->error(
+                               "$fname: No transaction to commit, something got out of sync." );
+                       return; // nothing to do
+               } elseif ( $this->trxAutomatic ) {
+                       throw new DBUnexpectedError(
+                               $this,
+                               "$fname: Expected mass commit of all peer transactions (DBO_TRX set)."
+                       );
                }
 
-               // Avoid fatals if close() was called
-               $this->assertOpen();
+               $this->assertHasConnectionHandle();
 
                $this->runOnTransactionPreCommitCallbacks();
 
@@ -3960,18 +4013,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        final public function rollback( $fname = __METHOD__, $flush = '' ) {
                $trxActive = $this->trxLevel;
 
-               if ( $flush !== self::FLUSHING_INTERNAL && $flush !== self::FLUSHING_ALL_PEERS ) {
-                       if ( $this->getFlag( self::DBO_TRX ) ) {
-                               throw new DBUnexpectedError(
-                                       $this,
-                                       "$fname: Expected mass rollback of all peer transactions (DBO_TRX set)."
-                               );
-                       }
+               if ( $flush !== self::FLUSHING_INTERNAL
+                       && $flush !== self::FLUSHING_ALL_PEERS
+                       && $this->getFlag( self::DBO_TRX )
+               ) {
+                       throw new DBUnexpectedError(
+                               $this,
+                               "$fname: Expected mass rollback of all peer transactions (DBO_TRX set)."
+                       );
                }
 
                if ( $trxActive ) {
-                       // Avoid fatals if close() was called
-                       $this->assertOpen();
+                       $this->assertHasConnectionHandle();
 
                        $this->doRollback( $fname );
                        $this->trxStatus = self::STATUS_TRX_NONE;
@@ -4140,6 +4193,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->closeConnection();
                $this->opened = false;
                $this->conn = false;
+
+               $this->handleSessionLossPreconnect();
+
                try {
                        $this->open(
                                $this->server,
@@ -4168,7 +4224,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        );
                }
 
-               $this->handleSessionLoss();
+               $this->handleSessionLossPostconnect();
 
                return $ok;
        }
@@ -4636,6 +4692,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->indexAliases = $aliases;
        }
 
+       /**
+        * @param int $field
+        * @param int $flags
+        * @return bool
+        */
+       protected function hasFlags( $field, $flags ) {
+               return ( ( $field & $flags ) === $flags );
+       }
+
        /**
         * Get the underlying binding connection handle
         *
@@ -4681,7 +4746,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $this->opened = false;
                        $this->conn = false;
                        $this->trxEndCallbacks = []; // don't copy
-                       $this->handleSessionLoss(); // no trx or locks anymore
+                       $this->handleSessionLossPreconnect(); // no trx or locks anymore
                        $this->open(
                                $this->server,
                                $this->user,
diff --git a/includes/libs/rdbms/database/DatabaseDomain.php b/includes/libs/rdbms/database/DatabaseDomain.php
deleted file mode 100644 (file)
index 7559b06..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-namespace Wikimedia\Rdbms;
-
-use InvalidArgumentException;
-
-/**
- * Class to handle database/prefix specification for IDatabase domains
- */
-class DatabaseDomain {
-       /** @var string|null */
-       private $database;
-       /** @var string|null */
-       private $schema;
-       /** @var string */
-       private $prefix;
-
-       /** @var string Cache of convertToString() */
-       private $equivalentString;
-
-       /**
-        * @param string|null $database Database name
-        * @param string|null $schema Schema name
-        * @param string $prefix Table prefix
-        */
-       public function __construct( $database, $schema, $prefix ) {
-               if ( $database !== null && ( !is_string( $database ) || !strlen( $database ) ) ) {
-                       throw new InvalidArgumentException( "Database must be null or a non-empty string." );
-               }
-               $this->database = $database;
-               if ( $schema !== null && ( !is_string( $schema ) || !strlen( $schema ) ) ) {
-                       throw new InvalidArgumentException( "Schema must be null or a non-empty string." );
-               }
-               $this->schema = $schema;
-               if ( !is_string( $prefix ) ) {
-                       throw new InvalidArgumentException( "Prefix must be a string." );
-               }
-               $this->prefix = $prefix;
-       }
-
-       /**
-        * @param DatabaseDomain|string $domain Result of DatabaseDomain::toString()
-        * @return DatabaseDomain
-        */
-       public static function newFromId( $domain ) {
-               if ( $domain instanceof self ) {
-                       return $domain;
-               }
-
-               $parts = array_map( [ __CLASS__, 'decode' ], explode( '-', $domain ) );
-
-               $schema = null;
-               $prefix = '';
-
-               if ( count( $parts ) == 1 ) {
-                       $database = $parts[0];
-               } elseif ( count( $parts ) == 2 ) {
-                       list( $database, $prefix ) = $parts;
-               } elseif ( count( $parts ) == 3 ) {
-                       list( $database, $schema, $prefix ) = $parts;
-               } else {
-                       throw new InvalidArgumentException( "Domain '$domain' has too few or too many parts." );
-               }
-
-               if ( $database === '' ) {
-                       $database = null;
-               }
-
-               if ( $schema === '' ) {
-                       $schema = null;
-               }
-
-               return new self( $database, $schema, $prefix );
-       }
-
-       /**
-        * @return DatabaseDomain
-        */
-       public static function newUnspecified() {
-               return new self( null, null, '' );
-       }
-
-       /**
-        * @param DatabaseDomain|string $other
-        * @return bool Whether the domain instances are the same by value
-        */
-       public function equals( $other ) {
-               if ( $other instanceof self ) {
-                       return (
-                               $this->database === $other->database &&
-                               $this->schema === $other->schema &&
-                               $this->prefix === $other->prefix
-                       );
-               }
-
-               return ( $this->getId() === $other );
-       }
-
-       /**
-        * Check whether the domain $other meets the specifications of this domain
-        *
-        * If this instance has a null database specifier, then $other can have any database
-        * specified, including the null, and likewise if the schema specifier is null. This
-        * is not transitive like equals() since a domain that explicitly wants a certain
-        * database or schema cannot be satisfied by one of another (nor null). If the prefix
-        * is empty and the DB and schema are both null, then the entire domain is considered
-        * unspecified, and any prefix of $other is considered compatible.
-        *
-        * @param DatabaseDomain|string $other
-        * @return bool
-        * @since 1.32
-        */
-       public function isCompatible( $other ) {
-               if ( $this->isUnspecified() ) {
-                       return true; // even the prefix doesn't matter
-               }
-
-               $other = ( $other instanceof self ) ? $other : self::newFromId( $other );
-
-               return (
-                       ( $this->database === $other->database || $this->database === null ) &&
-                       ( $this->schema === $other->schema || $this->schema === null ) &&
-                       $this->prefix === $other->prefix
-               );
-       }
-
-       /**
-        * @return bool
-        * @since 1.32
-        */
-       public function isUnspecified() {
-               return (
-                       $this->database === null && $this->schema === null && $this->prefix === ''
-               );
-       }
-
-       /**
-        * @return string|null Database name
-        */
-       public function getDatabase() {
-               return $this->database;
-       }
-
-       /**
-        * @return string|null Database schema
-        */
-       public function getSchema() {
-               return $this->schema;
-       }
-
-       /**
-        * @return string Table prefix
-        */
-       public function getTablePrefix() {
-               return $this->prefix;
-       }
-
-       /**
-        * @return string
-        */
-       public function getId() {
-               if ( $this->equivalentString === null ) {
-                       $this->equivalentString = $this->convertToString();
-               }
-
-               return $this->equivalentString;
-       }
-
-       /**
-        * @return string
-        */
-       private function convertToString() {
-               $parts = [ $this->database ];
-               if ( $this->schema !== null ) {
-                       $parts[] = $this->schema;
-               }
-               if ( $this->prefix != '' || $this->schema !== null ) {
-                       // If there is a schema, then we need the prefix to disambiguate.
-                       // For engines like Postgres that use schemas, this awkwardness is hopefully
-                       // avoided since it is easy to have one DB per server (to avoid having many users)
-                       // and use schema/prefix to have wiki farms. For example, a domain schemes could be
-                       // wiki-<project>-<language>, e.g. "wiki-fitness-es"/"wiki-sports-fr"/"wiki-news-en".
-                       $parts[] = $this->prefix;
-               }
-
-               return implode( '-', array_map( [ __CLASS__, 'encode' ], $parts ) );
-       }
-
-       private static function encode( $decoded ) {
-               $encoded = '';
-
-               $length = strlen( $decoded );
-               for ( $i = 0; $i < $length; ++$i ) {
-                       $char = $decoded[$i];
-                       if ( $char === '-' ) {
-                               $encoded .= '?h';
-                       } elseif ( $char === '?' ) {
-                               $encoded .= '??';
-                       } else {
-                               $encoded .= $char;
-                       }
-               }
-
-               return $encoded;
-       }
-
-       private static function decode( $encoded ) {
-               $decoded = '';
-
-               $length = strlen( $encoded );
-               for ( $i = 0; $i < $length; ++$i ) {
-                       $char = $encoded[$i];
-                       if ( $char === '?' ) {
-                               $nextChar = $encoded[$i + 1] ?? null;
-                               if ( $nextChar === 'h' ) {
-                                       $decoded .= '-';
-                                       ++$i;
-                               } elseif ( $nextChar === '?' ) {
-                                       $decoded .= '?';
-                                       ++$i;
-                               } else {
-                                       $decoded .= $char;
-                               }
-                       } else {
-                               $decoded .= $char;
-                       }
-               }
-
-               return $decoded;
-       }
-
-       /**
-        * @return string
-        */
-       function __toString() {
-               return $this->getId();
-       }
-}
index a6027e6..6d266ae 100644 (file)
@@ -157,7 +157,6 @@ class DatabaseMssql extends Database {
        /**
         * @param string $sql
         * @return bool|MssqlResultWrapper|resource
-        * @throws DBUnexpectedError
         */
        protected function doQuery( $sql ) {
                // several extensions seem to think that all databases support limits
@@ -703,12 +702,6 @@ class DatabaseMssql extends Database {
                                }
                                if ( is_null( $value ) ) {
                                        $sql .= 'null';
-                               } elseif ( is_array( $value ) || is_object( $value ) ) {
-                                       if ( is_object( $value ) && $value instanceof Blob ) {
-                                               $sql .= $this->addQuotes( $value );
-                                       } else {
-                                               $sql .= $this->addQuotes( serialize( $value ) );
-                                       }
                                } else {
                                        $sql .= $this->addQuotes( $value );
                                }
@@ -1168,8 +1161,18 @@ class DatabaseMssql extends Database {
        }
 
        protected function doSelectDomain( DatabaseDomain $domain ) {
-               $encDatabase = $this->addIdentifierQuotes( $domain->getDatabase() );
-               $this->query( "USE $encDatabase" );
+               if ( $domain->getSchema() !== null ) {
+                       throw new DBExpectedError( $this, __CLASS__ . ": domain schemas are not supported." );
+               }
+
+               $database = $domain->getDatabase();
+               if ( $database !== $this->getDBname() ) {
+                       $encDatabase = $this->addIdentifierQuotes( $database );
+                       $res = $this->doQuery( "USE $encDatabase" );
+                       if ( !$res ) {
+                               throw new DBExpectedError( $this, "Could not select database '$database'." );
+                       }
+               }
                // Update that domain fields on success (no exception thrown)
                $this->currentDomain = $domain;
 
@@ -1319,8 +1322,9 @@ class DatabaseMssql extends Database {
 
        /**
         * @param string $name
-        * @param string $format
-        * @return string
+        * @param string $format One of "quoted" (default), "raw", or "split".
+        * @return string|array When the requested $format is "split", a list of database, schema, and
+        *  table name is returned. Database and schema can be `false`.
         */
        function tableName( $name, $format = 'quoted' ) {
                # Replace reserved words with better ones
@@ -1335,18 +1339,17 @@ class DatabaseMssql extends Database {
        /**
         * call this instead of tableName() in the updater when renaming tables
         * @param string $name
-        * @param string $format One of quoted, raw, or split
-        * @return string
+        * @param string $format One of "quoted" (default), "raw", or "split".
+        * @return string|array When the requested $format is "split", a list of database, schema, and
+        *  table name is returned. Database and schema can be `false`.
+        * @private
         */
        function realTableName( $name, $format = 'quoted' ) {
                $table = parent::tableName( $name, $format );
                if ( $format == 'split' ) {
                        // Used internally, we want the schema split off from the table name and returned
                        // as a list with 3 elements (database, schema, table)
-                       $table = explode( '.', $table );
-                       while ( count( $table ) < 3 ) {
-                               array_unshift( $table, false );
-                       }
+                       return array_pad( explode( '.', $table, 3 ), -3, false );
                }
                return $table;
        }
@@ -1403,6 +1406,9 @@ class DatabaseMssql extends Database {
                return "CAST( $field AS NVARCHAR )";
        }
 
+       public static function getAttributes() {
+               return [ self::ATTR_SCHEMAS_AS_TABLE_GROUPS => true ];
+       }
 }
 
 /**
index 62110ef..36c947f 100644 (file)
@@ -106,7 +106,7 @@ abstract class DatabaseMysqlBase extends Database {
                                $this->$var = $params[$var];
                        }
                }
-               $this->sqlMode = $params['sqlMode'] ?? '';
+               $this->sqlMode = $params['sqlMode'] ?? null;
                $this->utf8Mode = !empty( $params['utf8Mode'] );
                $this->insertSelectIsSafe = isset( $params['insertSelectIsSafe'] )
                        ? (bool)$params['insertSelectIsSafe'] : null;
@@ -225,6 +225,39 @@ abstract class DatabaseMysqlBase extends Database {
                }
        }
 
+       protected function doSelectDomain( DatabaseDomain $domain ) {
+               if ( $domain->getSchema() !== null ) {
+                       throw new DBExpectedError( $this, __CLASS__ . ": domain schemas are not supported." );
+               }
+
+               $database = $domain->getDatabase();
+               // A null database means "don't care" so leave it as is and update the table prefix
+               if ( $database === null ) {
+                       $this->currentDomain = new DatabaseDomain(
+                               $this->currentDomain->getDatabase(),
+                               null,
+                               $domain->getTablePrefix()
+                       );
+
+                       return true;
+               }
+
+               if ( $database !== $this->getDBname() ) {
+                       $sql = 'USE ' . $this->addIdentifierQuotes( $database );
+                       $ret = $this->doQuery( $sql );
+                       if ( $ret === false ) {
+                               $error = $this->lastError();
+                               $errno = $this->lastErrno();
+                               $this->reportQueryError( $error, $errno, $sql, __METHOD__ );
+                       }
+               }
+
+               // Update that domain fields on success (no exception thrown)
+               $this->currentDomain = $domain;
+
+               return true;
+       }
+
        /**
         * Open a connection to a MySQL server
         *
@@ -486,15 +519,11 @@ abstract class DatabaseMysqlBase extends Database {
        abstract protected function mysqlError( $conn = null );
 
        protected function wasQueryTimeout( $error, $errno ) {
-               return $errno == 2062;
+               // https://dev.mysql.com/doc/refman/8.0/en/client-error-reference.html
+               // https://phabricator.wikimedia.org/T170638
+               return in_array( $errno, [ 2062, 3024 ] );
        }
 
-       /**
-        * @param string $table
-        * @param array $uniqueIndexes
-        * @param array $rows
-        * @param string $fname
-        */
        public function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
                $this->nativeReplace( $table, $rows, $fname );
        }
@@ -1326,16 +1355,8 @@ abstract class DatabaseMysqlBase extends Database {
                $this->query( $sql, $fname );
        }
 
-       /**
-        * @param string $table
-        * @param array $rows
-        * @param array $uniqueIndexes
-        * @param array $set
-        * @param string $fname
-        * @return bool
-        */
-       public function upsert( $table, array $rows, array $uniqueIndexes,
-               array $set, $fname = __METHOD__
+       public function upsert(
+               $table, array $rows, $uniqueIndexes, array $set, $fname = __METHOD__
        ) {
                if ( $rows === [] ) {
                        return true; // nothing to do
@@ -1421,7 +1442,7 @@ abstract class DatabaseMysqlBase extends Database {
                }
 
                // See https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
-               return in_array( $errno, [ 1022, 1216, 1217, 1137 ], true );
+               return in_array( $errno, [ 1022, 1062, 1216, 1217, 1137, 1146, 1051, 1054 ], true );
        }
 
        /**
@@ -1439,7 +1460,7 @@ abstract class DatabaseMysqlBase extends Database {
                $oldName = $this->addIdentifierQuotes( $oldName );
                $query = "CREATE $tmp TABLE $newName (LIKE $oldName)";
 
-               return $this->query( $query, $fname );
+               return $this->query( $query, $fname, $this::QUERY_PSEUDO_PERMANENT );
        }
 
        /**
index ad9b0a4..1a5cdab 100644 (file)
@@ -37,7 +37,7 @@ use stdClass;
 class DatabaseMysqli extends DatabaseMysqlBase {
        /**
         * @param string $sql
-        * @return mysqli_result
+        * @return mysqli_result|bool
         */
        protected function doQuery( $sql ) {
                $conn = $this->getBindingHandle();
@@ -78,9 +78,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                } elseif ( substr_count( $realServer, ':' ) == 1 ) {
                        // If we have a colon and something that's not a port number
                        // inside the hostname, assume it's the socket location
-                       $hostAndSocket = explode( ':', $realServer, 2 );
-                       $realServer = $hostAndSocket[0];
-                       $socket = $hostAndSocket[1];
+                       list( $realServer, $socket ) = explode( ':', $realServer, 2 );
                }
 
                $mysqli = mysqli_init();
@@ -139,11 +137,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        protected function mysqlSetCharset( $charset ) {
                $conn = $this->getBindingHandle();
 
-               if ( method_exists( $conn, 'set_charset' ) ) {
-                       return $conn->set_charset( $charset );
-               } else {
-                       return $this->query( 'SET NAMES ' . $charset, __METHOD__ );
-               }
+               return $conn->set_charset( $charset );
        }
 
        /**
@@ -184,24 +178,6 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                return $conn->affected_rows;
        }
 
-       function doSelectDomain( DatabaseDomain $domain ) {
-               $conn = $this->getBindingHandle();
-
-               if ( $domain->getSchema() !== null ) {
-                       throw new DBExpectedError( $this, __CLASS__ . ": domain schemas are not supported." );
-               }
-
-               $database = $domain->getDatabase();
-               if ( !$conn->select_db( $database ) ) {
-                       throw new DBExpectedError( $this, "Could not select database '$database'." );
-               }
-
-               // Update that domain fields on success (no exception thrown)
-               $this->currentDomain = $domain;
-
-               return true;
-       }
-
        /**
         * @param mysqli_result $res
         * @return bool
index 381b1fd..d8be62f 100644 (file)
@@ -116,7 +116,7 @@ class DatabasePostgres extends Database {
                        $connectVars['port'] = (int)$this->port;
                }
                if ( $this->flags & self::DBO_SSL ) {
-                       $connectVars['sslmode'] = 1;
+                       $connectVars['sslmode'] = 'require';
                }
 
                $this->connectString = $this->makeConnectionString( $connectVars );
@@ -216,6 +216,10 @@ class DatabasePostgres extends Database {
                        !preg_match( '/^SELECT\s+pg_(try_|)advisory_\w+\(/', $sql );
        }
 
+       /**
+        * @param string $sql
+        * @return bool|mixed|resource
+        */
        public function doQuery( $sql ) {
                $conn = $this->getBindingHandle();
 
@@ -815,8 +819,12 @@ __INDEXATTR__;
 
                $temporary = $temporary ? 'TEMPORARY' : '';
 
-               $ret = $this->query( "CREATE $temporary TABLE $newNameE " .
-                       "(LIKE $oldNameE INCLUDING DEFAULTS INCLUDING INDEXES)", $fname );
+               $ret = $this->query(
+                       "CREATE $temporary TABLE $newNameE " .
+                               "(LIKE $oldNameE INCLUDING DEFAULTS INCLUDING INDEXES)",
+                       $fname,
+                       $this::QUERY_PSEUDO_PERMANENT
+               );
                if ( !$ret ) {
                        return $ret;
                }
@@ -838,7 +846,10 @@ __INDEXATTR__;
                        $fieldE = $this->addIdentifierQuotes( $field );
                        $newSeqE = $this->addIdentifierQuotes( $newSeq );
                        $newSeqQ = $this->addQuotes( $newSeq );
-                       $this->query( "CREATE $temporary SEQUENCE $newSeqE OWNED BY $newNameE.$fieldE", $fname );
+                       $this->query(
+                               "CREATE $temporary SEQUENCE $newSeqE OWNED BY $newNameE.$fieldE",
+                               $fname
+                       );
                        $this->query(
                                "ALTER TABLE $newNameE ALTER COLUMN $fieldE SET DEFAULT nextval({$newSeqQ}::regclass)",
                                $fname
@@ -911,7 +922,7 @@ __INDEXATTR__;
 
        /**
         * Posted by cc[plus]php[at]c2se[dot]com on 25-Mar-2009 09:12
-        * to https://secure.php.net/manual/en/ref.pgsql.php
+        * to https://www.php.net/manual/en/ref.pgsql.php
         *
         * Parsing a postgres array can be a tricky problem, he's my
         * take on this, it handles multi-dimensional arrays plus
@@ -1342,10 +1353,6 @@ SQL;
                return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ];
        }
 
-       public function getServer() {
-               return $this->server;
-       }
-
        public function buildConcat( $stringList ) {
                return implode( ' || ', $stringList );
        }
@@ -1458,6 +1465,10 @@ SQL;
                return $row ? ( strtolower( $row->default_transaction_read_only ) === 'on' ) : false;
        }
 
+       public static function getAttributes() {
+               return [ self::ATTR_SCHEMAS_AS_TABLE_GROUPS => true ];
+       }
+
        /**
         * @param string $lockName
         * @return string Integer
index 7049df5..c9942a5 100644 (file)
@@ -216,6 +216,11 @@ class DatabaseSqlite extends Database {
                        # Enforce LIKE to be case sensitive, just like MySQL
                        $this->query( 'PRAGMA case_sensitive_like = 1' );
 
+                       $sync = $this->sessionVars['synchronous'] ?? null;
+                       if ( in_array( $sync, [ 'EXTRA', 'FULL', 'NORMAL' ], true ) ) {
+                               $this->query( "PRAGMA synchronous = $sync" );
+                       }
+
                        return $this->conn;
                }
 
@@ -254,7 +259,7 @@ class DatabaseSqlite extends Database {
         * Check if the searchindext table is FTS enabled.
         * @return bool False if not enabled.
         */
-       function checkForEnabledSearch() {
+       public function checkForEnabledSearch() {
                if ( self::$fulltextEnabled === null ) {
                        self::$fulltextEnabled = false;
                        $table = $this->tableName( 'searchindex' );
@@ -1013,7 +1018,7 @@ class DatabaseSqlite extends Database {
                        }
                }
 
-               $res = $this->query( $sql, $fname );
+               $res = $this->query( $sql, $fname, self::QUERY_PSEUDO_PERMANENT );
 
                // Take over indexes
                $indexList = $this->query( 'PRAGMA INDEX_LIST(' . $this->addQuotes( $oldName ) . ')' );
index 2795883..05f787c 100644 (file)
@@ -106,6 +106,21 @@ interface IDatabase {
        /** @var int Enable compression in connection protocol */
        const DBO_COMPRESS = 512;
 
+       /** @var int Ignore query errors and return false when they happen */
+       const QUERY_SILENCE_ERRORS = 1; // b/c for 1.32 query() argument; note that (int)true = 1
+       /**
+        * @var int Treat the TEMPORARY table from the given CREATE query as if it is
+        *   permanent as far as write tracking is concerned. This is useful for testing.
+        */
+       const QUERY_PSEUDO_PERMANENT = 2;
+       /** @var int Enforce that a query does not make effective writes */
+       const QUERY_REPLICA_ROLE = 4;
+
+       /** @var bool Parameter to unionQueries() for UNION ALL */
+       const UNION_ALL = true;
+       /** @var bool Parameter to unionQueries() for UNION DISTINCT */
+       const UNION_DISTINCT = false;
+
        /**
         * A string describing the current software version, and possibly
         * other details in a user-friendly way. Will be listed on Special:Version, etc.
@@ -416,7 +431,7 @@ interface IDatabase {
 
        /**
         * Get the number of fields in a result object
-        * @see https://secure.php.net/mysql_num_fields
+        * @see https://www.php.net/mysql_num_fields
         *
         * @param mixed $res A SQL result
         * @return int
@@ -425,7 +440,7 @@ interface IDatabase {
 
        /**
         * Get a field name in a result object
-        * @see https://secure.php.net/mysql_field_name
+        * @see https://www.php.net/mysql_field_name
         *
         * @param mixed $res A SQL result
         * @param int $n
@@ -446,7 +461,7 @@ interface IDatabase {
 
        /**
         * Change the position of the cursor in a result object
-        * @see https://secure.php.net/mysql_data_seek
+        * @see https://www.php.net/mysql_data_seek
         *
         * @param mixed $res A SQL result
         * @param int $row
@@ -455,7 +470,7 @@ interface IDatabase {
 
        /**
         * Get the last error number
-        * @see https://secure.php.net/mysql_errno
+        * @see https://www.php.net/mysql_errno
         *
         * @return int
         */
@@ -463,7 +478,7 @@ interface IDatabase {
 
        /**
         * Get a description of the last error
-        * @see https://secure.php.net/mysql_error
+        * @see https://www.php.net/mysql_error
         *
         * @return string
         */
@@ -471,7 +486,7 @@ interface IDatabase {
 
        /**
         * Get the number of rows affected by the last write query
-        * @see https://secure.php.net/mysql_affected_rows
+        * @see https://www.php.net/mysql_affected_rows
         *
         * @return int
         */
@@ -527,13 +542,13 @@ interface IDatabase {
         * @param string $sql SQL query
         * @param string $fname Name of the calling function, for profiling/SHOW PROCESSLIST
         *     comment (you can use __METHOD__ or add some extra info)
-        * @param bool $tempIgnore Whether to avoid throwing an exception on errors...
-        *     maybe best to catch the exception instead?
+        * @param int $flags Bitfield of IDatabase::QUERY_* constants. Note that suppression
+        *     of errors is best handled by try/catch rather than using one of these flags.
         * @return bool|IResultWrapper True for a successful write query, IResultWrapper object
-        *     for a successful read query, or false on failure if $tempIgnore set
+        *     for a successful read query, or false on failure if QUERY_SILENCE_ERRORS is set.
         * @throws DBError
         */
-       public function query( $sql, $fname = __METHOD__, $tempIgnore = false );
+       public function query( $sql, $fname = __METHOD__, $flags = 0 );
 
        /**
         * Free a result object returned by query() or select(). It's usually not
@@ -583,7 +598,7 @@ interface IDatabase {
         * @param string|array $options The query options. See IDatabase::select() for details.
         * @param string|array $join_conds The query join conditions. See IDatabase::select() for details.
         *
-        * @return array The values from the field
+        * @return array The values from the field in the order they were returned from the DB
         * @throws DBError
         * @since 1.25
         */
@@ -998,6 +1013,7 @@ interface IDatabase {
         * @param string $valuename
         *
         * @return string
+        * @deprecated Since 1.33
         */
        public function aggregateValue( $valuedata, $valuename = 'value' );
 
@@ -1096,6 +1112,25 @@ interface IDatabase {
                $options = [], $join_conds = []
        );
 
+       /**
+        * Construct a LIMIT query with optional offset. This is used for query
+        * pages. The SQL should be adjusted so that only the first $limit rows
+        * are returned. If $offset is provided as well, then the first $offset
+        * rows should be discarded, and the next $limit rows should be returned.
+        * If the result of the query is not ordered, then the rows to be returned
+        * are theoretically arbitrary.
+        *
+        * $sql is expected to be a SELECT, if that makes a difference.
+        *
+        * @param string $sql SQL query we will append the limit too
+        * @param int $limit The SQL limit
+        * @param int|bool $offset The SQL offset (default false)
+        * @throws DBUnexpectedError
+        * @return string
+        * @since 1.34
+        */
+       public function limitResult( $sql, $limit, $offset = false );
+
        /**
         * Returns true if DBs are assumed to be on potentially different servers
         *
@@ -1155,6 +1190,17 @@ interface IDatabase {
         */
        public function addQuotes( $s );
 
+       /**
+        * Quotes an identifier, in order to make user controlled input safe
+        *
+        * Depending on the database this will either be `backticks` or "double quotes"
+        *
+        * @param string $s
+        * @return string
+        * @since 1.33
+        */
+       public function addIdentifierQuotes( $s );
+
        /**
         * LIKE statement wrapper, receives a variable-length argument list with
         * parts of pattern to match containing either string literals that will be
@@ -1221,8 +1267,10 @@ interface IDatabase {
         * errors which wouldn't have occurred in MySQL.
         *
         * @param string $table The table to replace the row(s) in.
-        * @param array $uniqueIndexes Either a list of fields that define a unique index or
-        *   an array of such lists if there are multiple unique indexes defined in the schema
+        * @param array[]|string[]|string $uniqueIndexes All unique indexes. One of the following:
+        *   a) the one unique field in the table (when no composite unique key exist)
+        *   b) a list of all unique fields in the table (when no composite unique key exist)
+        *   c) a list of all unique indexes in the table (each as a list of the indexed fields)
         * @param array $rows Can be either a single row to insert, or multiple rows,
         *   in the same format as for IDatabase::insert()
         * @param string $fname Calling function name (use __METHOD__) for logs/profiling
@@ -1256,8 +1304,10 @@ interface IDatabase {
         *
         * @param string $table Table name. This will be passed through Database::tableName().
         * @param array $rows A single row or list of rows to insert
-        * @param array $uniqueIndexes Either a list of fields that define a unique index or
-        *   an array of such lists if there are multiple unique indexes defined in the schema
+        * @param array[]|string[]|string $uniqueIndexes All unique indexes. One of the following:
+        *   a) the one unique field in the table (when no composite unique key exist)
+        *   b) a list of all unique fields in the table (when no composite unique key exist)
+        *   c) a list of all unique indexes in the table (each as a list of the indexed fields)
         * @param array $set An array of values to SET. For each array element, the
         *   key gives the field name, and the value gives the data to set that
         *   field to. The data will be quoted by IDatabase::addQuotes().
@@ -1268,7 +1318,7 @@ interface IDatabase {
         * @return bool Return true if no exception was thrown (deprecated since 1.33)
         */
        public function upsert(
-               $table, array $rows, array $uniqueIndexes, array $set, $fname = __METHOD__
+               $table, array $rows, $uniqueIndexes, array $set, $fname = __METHOD__
        );
 
        /**
@@ -1361,7 +1411,7 @@ interface IDatabase {
         * This is used for providing overload point for other DB abstractions
         * not compatible with the MySQL syntax.
         * @param array $sqls SQL statements to combine
-        * @param bool $all Use UNION ALL
+        * @param bool $all Either IDatabase::UNION_ALL or IDatabase::UNION_DISTINCT
         * @return string SQL fragment
         */
        public function unionQueries( $sqls, $all );
@@ -1526,7 +1576,6 @@ interface IDatabase {
         *
         * @param callable $callback
         * @param string $fname Caller name
-        * @return mixed
         * @since 1.28
         */
        public function onTransactionResolution( callable $callback, $fname = __METHOD__ );
@@ -1570,7 +1619,6 @@ interface IDatabase {
         *
         * @param callable $callback
         * @param string $fname
-        * @return mixed
         * @since 1.20
         * @deprecated Since 1.32
         */
@@ -1616,7 +1664,6 @@ interface IDatabase {
         *
         * @param string $name Callback name
         * @param callable|null $callback Use null to unset a listener
-        * @return mixed
         * @since 1.28
         */
        public function setTransactionListener( $name, callable $callback = null );
@@ -2144,7 +2191,6 @@ interface IDatabase {
         * the aliases can be removed, and then the old X-named indexes dropped.
         *
         * @param string[] $aliases
-        * @return mixed
         * @since 1.31
         */
        public function setIndexAliases( array $aliases );
index 8a2c795..10a0897 100644 (file)
@@ -30,6 +30,8 @@ class MaintainableDBConnRef extends DBConnRef implements IMaintainableDatabase {
                $fname = false,
                callable $inputCallback = null
        ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -40,14 +42,20 @@ class MaintainableDBConnRef extends DBConnRef implements IMaintainableDatabase {
                $fname = __METHOD__,
                callable $inputCallback = null
        ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function dropTable( $tableName, $fName = __METHOD__ ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function deadlockLoop() {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -66,6 +74,8 @@ class MaintainableDBConnRef extends DBConnRef implements IMaintainableDatabase {
        public function duplicateTableStructure(
                $oldName, $newName, $temporary = false, $fname = __METHOD__
        ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -74,10 +84,14 @@ class MaintainableDBConnRef extends DBConnRef implements IMaintainableDatabase {
        }
 
        public function lockTables( array $read, array $write, $method ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function unlockTables( $method ) {
+               $this->assertRoleAllowsWrites();
+
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
diff --git a/includes/libs/rdbms/database/domain/DatabaseDomain.php b/includes/libs/rdbms/database/domain/DatabaseDomain.php
new file mode 100644 (file)
index 0000000..5dd4b49
--- /dev/null
@@ -0,0 +1,260 @@
+<?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 Database
+ */
+namespace Wikimedia\Rdbms;
+
+use InvalidArgumentException;
+
+/**
+ * Class to handle database/prefix specification for IDatabase domains
+ */
+class DatabaseDomain {
+       /** @var string|null */
+       private $database;
+       /** @var string|null */
+       private $schema;
+       /** @var string */
+       private $prefix;
+
+       /** @var string Cache of convertToString() */
+       private $equivalentString;
+
+       /**
+        * @param string|null $database Database name
+        * @param string|null $schema Schema name
+        * @param string $prefix Table prefix
+        */
+       public function __construct( $database, $schema, $prefix ) {
+               if ( $database !== null && ( !is_string( $database ) || $database === '' ) ) {
+                       throw new InvalidArgumentException( 'Database must be null or a non-empty string.' );
+               }
+               $this->database = $database;
+               if ( $schema !== null && ( !is_string( $schema ) || $schema === '' ) ) {
+                       throw new InvalidArgumentException( 'Schema must be null or a non-empty string.' );
+               } elseif ( $database === null && $schema !== null ) {
+                       throw new InvalidArgumentException( 'Schema must be null if database is null.' );
+               }
+               $this->schema = $schema;
+               if ( !is_string( $prefix ) ) {
+                       throw new InvalidArgumentException( 'Prefix must be a string.' );
+               } elseif ( $prefix !== '' && substr( $prefix, -1, 1 ) !== '_' ) {
+                       throw new InvalidArgumentException( 'A non-empty prefix must end with "_".' );
+               }
+               $this->prefix = $prefix;
+       }
+
+       /**
+        * @param DatabaseDomain|string $domain Result of DatabaseDomain::toString()
+        * @return DatabaseDomain
+        */
+       public static function newFromId( $domain ) {
+               if ( $domain instanceof self ) {
+                       return $domain;
+               }
+
+               $parts = array_map( [ __CLASS__, 'decode' ], explode( '-', $domain ) );
+
+               $schema = null;
+               $prefix = '';
+
+               if ( count( $parts ) == 1 ) {
+                       $database = $parts[0];
+               } elseif ( count( $parts ) == 2 ) {
+                       list( $database, $prefix ) = $parts;
+               } elseif ( count( $parts ) == 3 ) {
+                       list( $database, $schema, $prefix ) = $parts;
+               } else {
+                       throw new InvalidArgumentException( "Domain '$domain' has too few or too many parts." );
+               }
+
+               if ( $database === '' ) {
+                       $database = null;
+               }
+
+               if ( $schema === '' ) {
+                       $schema = null;
+               }
+
+               return new self( $database, $schema, $prefix );
+       }
+
+       /**
+        * @return DatabaseDomain
+        */
+       public static function newUnspecified() {
+               return new self( null, null, '' );
+       }
+
+       /**
+        * @param DatabaseDomain|string $other
+        * @return bool Whether the domain instances are the same by value
+        */
+       public function equals( $other ) {
+               if ( $other instanceof self ) {
+                       return (
+                               $this->database === $other->database &&
+                               $this->schema === $other->schema &&
+                               $this->prefix === $other->prefix
+                       );
+               }
+
+               return ( $this->getId() === $other );
+       }
+
+       /**
+        * Check whether the domain $other meets the specifications of this domain
+        *
+        * If this instance has a null database specifier, then $other can have any database
+        * specifier, including null. This is likewise true if the schema specifier is null.
+        * This is not transitive like equals() since a domain that explicitly wants a certain
+        * database or schema cannot be satisfied by one of another (nor null). If the prefix
+        * is empty and the DB and schema are both null, then the entire domain is considered
+        * unspecified, and any prefix of $other is considered compatible.
+        *
+        * @param DatabaseDomain|string $other
+        * @return bool
+        * @since 1.32
+        */
+       public function isCompatible( $other ) {
+               if ( $this->isUnspecified() ) {
+                       return true; // even the prefix doesn't matter
+               }
+
+               $other = self::newFromId( $other );
+
+               return (
+                       ( $this->database === $other->database || $this->database === null ) &&
+                       ( $this->schema === $other->schema || $this->schema === null ) &&
+                       $this->prefix === $other->prefix
+               );
+       }
+
+       /**
+        * @return bool
+        * @since 1.32
+        */
+       public function isUnspecified() {
+               return (
+                       $this->database === null && $this->schema === null && $this->prefix === ''
+               );
+       }
+
+       /**
+        * @return string|null Database name
+        */
+       public function getDatabase() {
+               return $this->database;
+       }
+
+       /**
+        * @return string|null Database schema
+        */
+       public function getSchema() {
+               return $this->schema;
+       }
+
+       /**
+        * @return string Table prefix
+        */
+       public function getTablePrefix() {
+               return $this->prefix;
+       }
+
+       /**
+        * @return string
+        */
+       public function getId() {
+               if ( $this->equivalentString === null ) {
+                       $this->equivalentString = $this->convertToString();
+               }
+
+               return $this->equivalentString;
+       }
+
+       /**
+        * @return string
+        */
+       private function convertToString() {
+               $parts = [ (string)$this->database ];
+               if ( $this->schema !== null ) {
+                       $parts[] = $this->schema;
+               }
+               if ( $this->prefix != '' || $this->schema !== null ) {
+                       // If there is a schema, then we need the prefix to disambiguate.
+                       // For engines like Postgres that use schemas, this awkwardness is hopefully
+                       // avoided since it is easy to have one DB per server (to avoid having many users)
+                       // and use schema/prefix to have wiki farms. For example, a domain schemes could be
+                       // wiki-<project>-<language>, e.g. "wiki-fitness-es"/"wiki-sports-fr"/"wiki-news-en".
+                       $parts[] = $this->prefix;
+               }
+
+               return implode( '-', array_map( [ __CLASS__, 'encode' ], $parts ) );
+       }
+
+       private static function encode( $decoded ) {
+               $encoded = '';
+
+               $length = strlen( $decoded );
+               for ( $i = 0; $i < $length; ++$i ) {
+                       $char = $decoded[$i];
+                       if ( $char === '-' ) {
+                               $encoded .= '?h';
+                       } elseif ( $char === '?' ) {
+                               $encoded .= '??';
+                       } else {
+                               $encoded .= $char;
+                       }
+               }
+
+               return $encoded;
+       }
+
+       private static function decode( $encoded ) {
+               $decoded = '';
+
+               $length = strlen( $encoded );
+               for ( $i = 0; $i < $length; ++$i ) {
+                       $char = $encoded[$i];
+                       if ( $char === '?' ) {
+                               $nextChar = $encoded[$i + 1] ?? null;
+                               if ( $nextChar === 'h' ) {
+                                       $decoded .= '-';
+                                       ++$i;
+                               } elseif ( $nextChar === '?' ) {
+                                       $decoded .= '?';
+                                       ++$i;
+                               } else {
+                                       $decoded .= $char;
+                               }
+                       } else {
+                               $decoded .= $char;
+                       }
+               }
+
+               return $decoded;
+       }
+
+       /**
+        * @return string
+        */
+       function __toString() {
+               return $this->getId();
+       }
+}
index 1355e22..a9befc2 100644 (file)
@@ -69,7 +69,6 @@ class ResultWrapper implements IResultWrapper {
 
        public function free() {
                if ( $this->db ) {
-                       $this->db->freeResult( $this );
                        $this->db = null;
                }
                $this->result = null;
diff --git a/includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php b/includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php
new file mode 100644 (file)
index 0000000..c6e3d44
--- /dev/null
@@ -0,0 +1,27 @@
+<?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 Database
+ */
+namespace Wikimedia\Rdbms;
+
+/**
+ * Class used for token representing identifiers for atomic sections from IDatabase instances
+ */
+class AtomicSectionIdentifier {
+}
index 8e68aba..1819a9a 100644 (file)
@@ -6,15 +6,13 @@ class MssqlBlob extends Blob {
        /** @noinspection PhpMissingParentConstructorInspection */
 
        /**
-        * @param string $data
+        * @param Blob|string $data
         */
        public function __construct( $data ) {
                if ( $data instanceof MssqlBlob ) {
-                       return $data;
+                       $this->data = $data->data;
                } elseif ( $data instanceof Blob ) {
                        $this->data = $data->fetch();
-               } elseif ( is_array( $data ) && is_object( $data ) ) {
-                       $this->data = serialize( $data );
                } else {
                        $this->data = $data;
                }
index b1353b7..9b664fc 100644 (file)
@@ -45,7 +45,7 @@ class DBQueryError extends DBExpectedError {
        public function __construct( IDatabase $db, $error, $errno, $sql, $fname, $message = null ) {
                if ( $message === null ) {
                        if ( $db instanceof Database && $db->wasConnectionError( $errno ) ) {
-                               $message = "A connection error occurred. \n" .
+                               $message = "A connection error occurred during a query. \n" .
                                         "Query: $sql\n" .
                                         "Function: $fname\n" .
                                         "Error: $errno $error\n";
diff --git a/includes/libs/rdbms/exception/DBReadOnlyRoleError.php b/includes/libs/rdbms/exception/DBReadOnlyRoleError.php
new file mode 100644 (file)
index 0000000..4d565ba
--- /dev/null
@@ -0,0 +1,30 @@
+<?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 Database
+ */
+
+namespace Wikimedia\Rdbms;
+
+/**
+ * Exception class for attempted DB write access to a DBConnRef with the DB_REPLICA role
+ *
+ * @ingroup Database
+ */
+class DBReadOnlyRoleError extends DBUnexpectedError {
+}
index 74abace..87cc2bd 100644 (file)
@@ -22,8 +22,7 @@
 namespace Wikimedia\Rdbms;
 
 /**
- * Exception class for replica DB wait timeouts
- * @deprecated since 1.32
+ * Exception class for replica DB wait errors
  * @ingroup Database
  */
 class DBReplicationWaitError extends DBExpectedError {
index 98c06ad..cb8be21 100644 (file)
@@ -390,7 +390,6 @@ interface ILBFactory {
         * the aliases can be removed, and then the old X-named indexes dropped.
         *
         * @param string[] $aliases
-        * @return mixed
         * @since 1.31
         */
        public function setIndexAliases( array $aliases );
index 9ec1ce1..3a8f2e1 100644 (file)
@@ -634,7 +634,7 @@ abstract class LBFactory implements ILBFactory {
        public function setLocalDomainPrefix( $prefix ) {
                $this->localDomain = new DatabaseDomain(
                        $this->localDomain->getDatabase(),
-                       null,
+                       $this->localDomain->getSchema(),
                        $prefix
                );
 
@@ -654,7 +654,7 @@ abstract class LBFactory implements ILBFactory {
        }
 
        public function closeAll() {
-               $this->forEachLBCallMethod( 'closeAll', [] );
+               $this->forEachLBCallMethod( 'closeAll' );
        }
 
        public function setAgentName( $agent ) {
index 189ceee..aec99f4 100644 (file)
@@ -89,9 +89,6 @@ class LBFactoryMulti extends LBFactory {
         */
        private $readOnlyBySection = [];
 
-       /** @var array Load balancer factory configuration */
-       private $conf;
-
        /** @var LoadBalancer[] */
        private $mainLBs = [];
 
@@ -166,7 +163,6 @@ class LBFactoryMulti extends LBFactory {
        public function __construct( array $conf ) {
                parent::__construct( $conf );
 
-               $this->conf = $conf;
                $required = [ 'sectionsByDB', 'sectionLoads', 'serverTemplate' ];
                $optional = [ 'groupLoadsBySection', 'groupLoadsByDB', 'hostsByName',
                        'externalLoads', 'externalTemplateOverrides', 'templateOverridesByServer',
index b20bf04..52d8370 100644 (file)
@@ -291,13 +291,13 @@ interface ILoadBalancer {
         *
         * @see ILoadBalancer::getConnection() for parameter information
         *
-        * @param int $db Server index or DB_MASTER/DB_REPLICA
+        * @param int $i Server index or DB_MASTER/DB_REPLICA
         * @param array|string|bool $groups Query group(s), or false for the generic reader
         * @param string|bool $domain Domain ID, or false for the current domain
         * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return MaintainableDBConnRef
         */
-       public function getMaintenanceConnectionRef( $db, $groups = [], $domain = false, $flags = 0 );
+       public function getMaintenanceConnectionRef( $i, $groups = [], $domain = false, $flags = 0 );
 
        /**
         * Open a connection to the server given by the specified index
@@ -680,7 +680,6 @@ interface ILoadBalancer {
         * the aliases can be removed, and then the old X-named indexes dropped.
         *
         * @param string[] $aliases
-        * @return mixed
         * @since 1.31
         */
        public function setIndexAliases( array $aliases );
index f2e4e3d..da5382a 100644 (file)
@@ -487,10 +487,8 @@ class LoadBalancer implements ILoadBalancer {
                        $this->waitForPos = $pos;
                        // If a generic reader connection was already established, then wait now
                        $i = $this->readIndex;
-                       if ( $i > 0 ) {
-                               if ( !$this->doWait( $i ) ) {
-                                       $this->laggedReplicaMode = true;
-                               }
+                       if ( ( $i > 0 ) && !$this->doWait( $i ) ) {
+                               $this->laggedReplicaMode = true;
                        }
                } finally {
                        // Restore the older position if it was higher since this is used for lag-protection
@@ -566,15 +564,24 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function getAnyOpenConnection( $i, $flags = 0 ) {
+               $i = ( $i === self::DB_MASTER ) ? $this->getWriterIndex() : $i;
                $autocommit = ( ( $flags & self::CONN_TRX_AUTOCOMMIT ) == self::CONN_TRX_AUTOCOMMIT );
+
                foreach ( $this->conns as $connsByServer ) {
-                       if ( !isset( $connsByServer[$i] ) ) {
-                               continue;
+                       if ( $i === self::DB_REPLICA ) {
+                               $indexes = array_keys( $connsByServer );
+                       } else {
+                               $indexes = isset( $connsByServer[$i] ) ? [ $i ] : [];
                        }
 
-                       foreach ( $connsByServer[$i] as $conn ) {
-                               if ( !$autocommit || $conn->getLBInfo( 'autoCommitOnly' ) ) {
-                                       return $conn;
+                       foreach ( $indexes as $index ) {
+                               foreach ( $connsByServer[$index] as $conn ) {
+                                       if ( !$conn->isOpen() ) {
+                                               continue; // some sort of error occured?
+                                       }
+                                       if ( !$autocommit || $conn->getLBInfo( 'autoCommitOnly' ) ) {
+                                               return $conn;
+                                       }
                                }
                        }
                }
@@ -827,23 +834,36 @@ class LoadBalancer implements ILoadBalancer {
                }
        }
 
-       public function getConnectionRef( $db, $groups = [], $domain = false, $flags = 0 ) {
+       public function getConnectionRef( $i, $groups = [], $domain = false, $flags = 0 ) {
                $domain = $this->resolveDomainID( $domain );
+               $role = $this->getRoleFromIndex( $i );
 
-               return new DBConnRef( $this, $this->getConnection( $db, $groups, $domain, $flags ) );
+               return new DBConnRef( $this, $this->getConnection( $i, $groups, $domain, $flags ), $role );
        }
 
-       public function getLazyConnectionRef( $db, $groups = [], $domain = false, $flags = 0 ) {
+       public function getLazyConnectionRef( $i, $groups = [], $domain = false, $flags = 0 ) {
                $domain = $this->resolveDomainID( $domain );
+               $role = $this->getRoleFromIndex( $i );
 
-               return new DBConnRef( $this, [ $db, $groups, $domain, $flags ] );
+               return new DBConnRef( $this, [ $i, $groups, $domain, $flags ], $role );
        }
 
-       public function getMaintenanceConnectionRef( $db, $groups = [], $domain = false, $flags = 0 ) {
+       public function getMaintenanceConnectionRef( $i, $groups = [], $domain = false, $flags = 0 ) {
                $domain = $this->resolveDomainID( $domain );
+               $role = $this->getRoleFromIndex( $i );
 
                return new MaintainableDBConnRef(
-                       $this, $this->getConnection( $db, $groups, $domain, $flags ) );
+                       $this, $this->getConnection( $i, $groups, $domain, $flags ), $role );
+       }
+
+       /**
+        * @param int $i Server index or DB_MASTER/DB_REPLICA
+        * @return int One of DB_MASTER/DB_REPLICA
+        */
+       private function getRoleFromIndex( $i ) {
+               return ( $i === self::DB_MASTER || $i === $this->getWriterIndex() )
+                       ? self::DB_MASTER
+                       : self::DB_REPLICA;
        }
 
        public function openConnection( $i, $domain = false, $flags = 0 ) {
@@ -1018,7 +1038,7 @@ class LoadBalancer implements ILoadBalancer {
                                }
                                unset( $this->conns[$connFreeKey][$i][$oldDomain] );
                                // Note that if $domain is an empty string, getDomainID() might not match it
-                               $this->conns[$connInUseKey][$i][$conn->getDomainId()] = $conn;
+                               $this->conns[$connInUseKey][$i][$conn->getDomainID()] = $conn;
                                $this->connLogger->debug( __METHOD__ .
                                        ": reusing free connection from $oldDomain for $domain" );
                                break;
@@ -1842,12 +1862,6 @@ class LoadBalancer implements ILoadBalancer {
                }
        }
 
-       /**
-        * @param IDatabase $conn
-        * @param DBMasterPos|bool $pos
-        * @param int|null $timeout
-        * @return bool
-        */
        public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = null ) {
                $timeout = max( 1, $timeout ?: $this->waitTimeout );
 
@@ -1862,6 +1876,12 @@ class LoadBalancer implements ILoadBalancer {
                                $pos = $masterConn->getMasterPos();
                        } else {
                                $masterConn = $this->openConnection( $this->getWriterIndex(), self::DOMAIN_ANY );
+                               if ( !$masterConn ) {
+                                       throw new DBReplicationWaitError(
+                                               null,
+                                               "Could not obtain a master database connection to get the position"
+                                       );
+                               }
                                $pos = $masterConn->getMasterPos();
                                $this->closeConnection( $masterConn );
                        }
index 2161b66..fcddfcf 100644 (file)
@@ -26,7 +26,12 @@ namespace Wikimedia\Rdbms;
 use InvalidArgumentException;
 
 /**
- * Trivial LoadBalancer that always returns an injected connection handle
+ * Trivial LoadBalancer that always returns an injected connection handle.
+ *
+ * Note that, while this LoadBalancer does not open any connections itself,
+ * it still closes the injected connection at times, including during destruction.
+ * It is therefore unsuitable for use in tests unless you have a Database instance
+ * separate from the main test database (which is expected to stay open).
  */
 class LoadBalancerSingle extends LoadBalancer {
        /** @var IDatabase */
@@ -55,7 +60,8 @@ class LoadBalancerSingle extends LoadBalancer {
                        'trxProfiler' => $params['trxProfiler'] ?? null,
                        'srvCache' => $params['srvCache'] ?? null,
                        'wanCache' => $params['wanCache'] ?? null,
-                       'localDomain' => $params['localDomain'] ?? $this->db->getDomainID()
+                       'localDomain' => $params['localDomain'] ?? $this->db->getDomainID(),
+                       'readOnlyReason' => $params['readOnlyReason'] ?? false,
                ] );
 
                if ( isset( $params['readOnlyReason'] ) ) {
index 01834ee..180baed 100644 (file)
@@ -191,7 +191,7 @@ class LoadMonitor implements ILoadMonitor {
                                                [ 'db_server' => $host ]
                                        );
                                } elseif ( $lagTimes[$i] > $this->lagWarnThreshold ) {
-                                       $this->replLogger->error(
+                                       $this->replLogger->warning(
                                                "Server {host} has {lag} seconds of lag (>= {maxlag})",
                                                [
                                                        'host' => $host,
index d09620b..db29760 100644 (file)
@@ -33,9 +33,10 @@ class RedisConnRef implements LoggerAwareInterface {
        protected $pool;
        /** @var Redis */
        protected $conn;
-
-       protected $server; // string
-       protected $lastError; // string
+       /** @var string */
+       protected $server;
+       /** @var string|null */
+       protected $lastError;
 
        /**
         * @var LoggerInterface
index aa60242..9a8086f 100644 (file)
@@ -245,13 +245,11 @@ class RedisConnectionPool implements LoggerAwareInterface {
 
                                return false;
                        }
-                       if ( $this->password !== null ) {
-                               if ( !$conn->auth( $this->password ) ) {
-                                       $logger->error(
-                                               'Authentication error connecting to "{redis_server}"',
-                                               [ 'redis_server' => $server ]
-                                       );
-                               }
+                       if ( ( $this->password !== null ) && !$conn->auth( $this->password ) ) {
+                               $logger->error(
+                                       'Authentication error connecting to "{redis_server}"',
+                                       [ 'redis_server' => $server ]
+                               );
                        }
                } catch ( RedisException $e ) {
                        $this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
@@ -364,15 +362,13 @@ class RedisConnectionPool implements LoggerAwareInterface {
         * @return bool Success
         */
        public function reauthenticateConnection( $server, Redis $conn ) {
-               if ( $this->password !== null ) {
-                       if ( !$conn->auth( $this->password ) ) {
-                               $this->logger->error(
-                                       'Authentication error connecting to "{redis_server}"',
-                                       [ 'redis_server' => $server ]
-                               );
+               if ( $this->password !== null && !$conn->auth( $this->password ) ) {
+                       $this->logger->error(
+                               'Authentication error connecting to "{redis_server}"',
+                               [ 'redis_server' => $server ]
+                       );
 
-                               return false;
-                       }
+                       return false;
                }
 
                return true;
index 61efba0..c90cea9 100644 (file)
@@ -43,28 +43,19 @@ class PageDataRequestHandler {
         */
        public function canHandleRequest( $subPage, WebRequest $request ) {
                if ( $subPage === '' || $subPage === null ) {
-                       if ( $request->getText( 'target', '' ) === '' ) {
-                               return false;
-                       } else {
-                               return true;
-                       }
+                       return $request->getText( 'target' ) !== '';
                }
 
                $parts = explode( '/', $subPage, 2 );
-               if ( $parts !== 2 ) {
-                       $slot = $parts[0];
-                       if ( $slot === 'main' || $slot === '' ) {
-                               return true;
-                       }
-               }
-
-               return false;
+               $slot = $parts[0];
+               $title = $parts[1] ?? '';
+               return ( $slot === 'main' || $slot === '' ) && $title !== '';
        }
 
        /**
         * Main method for handling requests.
         *
-        * @param string $subPage
+        * @param string|null $subPage
         * @param WebRequest $request The request parameters. Known parameters are:
         *        - title: the page title
         *        - format: the format
@@ -86,11 +77,11 @@ class PageDataRequestHandler {
 
                $revision = 0;
 
-               $parts = explode( '/', $subPage, 2 );
                if ( $subPage !== '' ) {
-                       $title = $parts[1];
+                       $parts = explode( '/', $subPage, 2 );
+                       $title = $parts[1] ?? '';
                } else {
-                       $title = $request->getText( 'target', '' );
+                       $title = $request->getText( 'target' );
                }
 
                $revision = $request->getInt( 'oldid', $revision );
@@ -145,7 +136,7 @@ class PageDataRequestHandler {
                }
 
                $negotiator = new HttpAcceptNegotiator( $mimeTypes );
-               $format = $negotiator->getBestSupportedKey( $accept, null );
+               $format = $negotiator->getBestSupportedKey( $accept );
 
                if ( $format === null ) {
                        $format = isset( $accept['text/html'] ) ? 'text/html' : null;
index 5706f2d..c5e4a92 100644 (file)
  * @since 1.19
  */
 
+use MediaWiki\ChangeTags\Taggable;
+use MediaWiki\Linker\LinkTarget;
+use MediaWiki\User\UserIdentity;
 use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Assert\Assert;
 
 /**
  * Interface for log entries. Every log entry has these methods.
@@ -96,7 +100,7 @@ interface LogEntry {
        /**
         * Get the access restriction.
         *
-        * @return string
+        * @return int
         */
        public function getDeleted();
 
@@ -434,7 +438,7 @@ class RCDatabaseLogEntry extends DatabaseLogEntry {
  *
  * @since 1.19
  */
-class ManualLogEntry extends LogEntryBase {
+class ManualLogEntry extends LogEntryBase implements Taggable {
        /** @var string Type of log entry */
        protected $type;
 
@@ -462,8 +466,8 @@ class ManualLogEntry extends LogEntryBase {
        /** @var int A rev id associated to the log entry */
        protected $revId = 0;
 
-       /** @var array Change tags add to the log entry */
-       protected $tags = null;
+       /** @var string[] Change tags add to the log entry */
+       protected $tags = [];
 
        /** @var int Deletion state of the log entry */
        protected $deleted;
@@ -527,20 +531,20 @@ class ManualLogEntry extends LogEntryBase {
         * Set the user that performed the action being logged.
         *
         * @since 1.19
-        * @param User $performer
+        * @param UserIdentity $performer
         */
-       public function setPerformer( User $performer ) {
-               $this->performer = $performer;
+       public function setPerformer( UserIdentity $performer ) {
+               $this->performer = User::newFromIdentity( $performer );
        }
 
        /**
         * Set the title of the object changed.
         *
         * @since 1.19
-        * @param Title $target
+        * @param LinkTarget $target
         */
-       public function setTarget( Title $target ) {
-               $this->target = $target;
+       public function setTarget( LinkTarget $target ) {
+               $this->target = Title::newFromLinkTarget( $target );
        }
 
        /**
@@ -579,14 +583,35 @@ class ManualLogEntry extends LogEntryBase {
        /**
         * Set change tags for the log entry.
         *
+        * Passing `null` means the same as empty array,
+        * for compatibility with WikiPage::doUpdateRestrictions().
+        *
         * @since 1.27
-        * @param string|string[] $tags
+        * @param string|string[]|null $tags
+        * @deprecated since 1.33 Please use addTags() instead
         */
        public function setTags( $tags ) {
+               if ( $this->tags ) {
+                       wfDebug( 'Overwriting existing ManualLogEntry tags' );
+               }
+               $this->tags = [];
+               if ( $tags !== null ) {
+                       $this->addTags( $tags );
+               }
+       }
+
+       /**
+        * Add change tags for the log entry
+        *
+        * @since 1.33
+        * @param string|string[] $tags Tags to apply
+        */
+       public function addTags( $tags ) {
                if ( is_string( $tags ) ) {
                        $tags = [ $tags ];
                }
-               $this->tags = $tags;
+               Assert::parameterElementType( 'string', $tags, 'tags' );
+               $this->tags = array_unique( array_merge( $this->tags, $tags ) );
        }
 
        /**
@@ -768,20 +793,44 @@ class ManualLogEntry extends LogEntryBase {
         * @param string $to One of: rcandudp (default), rc, udp
         */
        public function publish( $newId, $to = 'rcandudp' ) {
+               $canAddTags = true;
+               // FIXME: this code should be removed once all callers properly call publish()
+               if ( $to === 'udp' && !$newId && !$this->getAssociatedRevId() ) {
+                       \MediaWiki\Logger\LoggerFactory::getInstance( 'logging' )->warning(
+                               'newId and/or revId must be set when calling ManualLogEntry::publish()',
+                               [
+                                       'newId' => $newId,
+                                       'to' => $to,
+                                       'revId' => $this->getAssociatedRevId(),
+                                       // pass a new exception to register the stack trace
+                                       'exception' => new RuntimeException()
+                               ]
+                       );
+                       $canAddTags = false;
+               }
+
                DeferredUpdates::addCallableUpdate(
-                       function () use ( $newId, $to ) {
+                       function () use ( $newId, $to, $canAddTags ) {
                                $log = new LogPage( $this->getType() );
                                if ( !$log->isRestricted() ) {
+                                       Hooks::runWithoutAbort( 'ManualLogEntryBeforePublish', [ $this ] );
                                        $rc = $this->getRecentChange( $newId );
 
                                        if ( $to === 'rc' || $to === 'rcandudp' ) {
                                                // save RC, passing tags so they are applied there
+                                               $rc->addTags( $this->getTags() );
+                                               $rc->save( $rc::SEND_NONE );
+                                       } else {
                                                $tags = $this->getTags();
-                                               if ( is_null( $tags ) ) {
-                                                       $tags = [];
+                                               if ( $tags && $canAddTags ) {
+                                                       $revId = $this->getAssociatedRevId();
+                                                       ChangeTags::addTags(
+                                                               $tags,
+                                                               null,
+                                                               $revId > 0 ? $revId : null,
+                                                               $newId > 0 ? $newId : null
+                                                       );
                                                }
-                                               $rc->addTags( $tags );
-                                               $rc->save( $rc::SEND_NONE );
                                        }
 
                                        if ( $to === 'udp' || $to === 'rcandudp' ) {
@@ -840,7 +889,7 @@ class ManualLogEntry extends LogEntryBase {
 
        /**
         * @since 1.27
-        * @return array
+        * @return string[]
         */
        public function getTags() {
                return $this->tags;
index c66aa59..3fd52af 100644 (file)
@@ -692,6 +692,8 @@ class LogEventsList extends ContextSource {
                        $s .= $loglist->beginLogEventsList() .
                                $logBody .
                                $loglist->endLogEventsList();
+                       // add styles for change tags
+                       $context->getOutput()->addModuleStyles( 'mediawiki.interface.helpers.styles' );
                } elseif ( $showIfEmpty ) {
                        $s = Html::rawElement( 'div', [ 'class' => 'mw-warning-logempty' ],
                                $context->msg( 'logempty' )->parse() );
index b07f20e..b9bb70c 100644 (file)
@@ -329,6 +329,7 @@ class LogFormatter {
                                                        ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
                                        case 'overwrite':
+                                       case 'revert':
                                                $text = wfMessage( 'overwroteimage' )
                                                        ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
@@ -761,7 +762,9 @@ class LogFormatter {
                                        $user->getName(),
                                        true, // redContribsWhenNoEdits
                                        $toolFlags,
-                                       $user->getEditCount()
+                                       $user->getEditCount(),
+                                       // do not render parenthesises in the HTML markup (CSS will provide)
+                                       false
                                );
                        }
                }
@@ -814,6 +817,11 @@ class LogFormatter {
                foreach ( $this->getParametersForApi() as $key => $value ) {
                        $vals = explode( ':', $key, 3 );
                        if ( count( $vals ) !== 3 ) {
+                               if ( $value instanceof __PHP_Incomplete_Class ) {
+                                       wfLogWarning( 'Log entry of type ' . $this->entry->getFullType() .
+                                               ' contains unrecoverable extra parameters.' );
+                                       continue;
+                               }
                                $logParams[$key] = $value;
                                continue;
                        }
index 32afa37..801c474 100644 (file)
@@ -333,7 +333,7 @@ class LogPager extends ReverseChronologicalPager {
                        }
                }
                # Don't show duplicate rows when using log_search
-               $joins['log_search'] = [ 'INNER JOIN', 'ls_log_id=log_id' ];
+               $joins['log_search'] = [ 'JOIN', 'ls_log_id=log_id' ];
 
                $info = [
                        'tables' => $tables,
index 4d1b855..acf2c2e 100644 (file)
@@ -225,10 +225,9 @@ class EmailNotification {
                                                && $watchingUser->getId() != $userTalkId
                                                && !in_array( $watchingUser->getName(), $wgUsersNotifiedOnAllChanges )
                                                && !( $wgBlockDisablesLogin && $watchingUser->isBlocked() )
+                                               && Hooks::run( 'SendWatchlistEmailNotification', [ $watchingUser, $title, $this ] )
                                        ) {
-                                               if ( Hooks::run( 'SendWatchlistEmailNotification', [ $watchingUser, $title, $this ] ) ) {
-                                                       $this->compose( $watchingUser, self::WATCHLIST );
-                                               }
+                                               $this->compose( $watchingUser, self::WATCHLIST );
                                        }
                                }
                        }
@@ -328,8 +327,9 @@ class EmailNotification {
 
                $keys['$PAGETITLE'] = $this->title->getPrefixedText();
                $keys['$PAGETITLE_URL'] = $this->title->getCanonicalURL();
-               $keys['$PAGEMINOREDIT'] = "\n" . ( $this->minorEdit ?
-                       wfMessage( 'enotif_minoredit' )->inContentLanguage()->text() : '' );
+               $keys['$PAGEMINOREDIT'] = $this->minorEdit ?
+                       "\n\n" . wfMessage( 'enotif_minoredit' )->inContentLanguage()->text() :
+                       '';
                $keys['$UNWATCHURL'] = $this->title->getCanonicalURL( 'action=unwatch' );
 
                if ( $this->editor->isAnon() ) {
index b8b706d..2d1c3b2 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Media
  */
 
+use MediaWiki\Shell\Shell;
+
 /**
  * Generic handler for bitmap images
  *
@@ -228,7 +230,7 @@ class BitmapHandler extends TransformationalImageHandler {
                $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
                list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
 
-               $cmd = wfEscapeShellArg( ...array_merge(
+               $cmd = Shell::escape( ...array_merge(
                        [ $wgImageMagickConvertCommand ],
                        $quality,
                        // Specify white background color, will be used for transparent images
@@ -338,10 +340,8 @@ class BitmapHandler extends TransformationalImageHandler {
                        }
                        $im->setImageDepth( 8 );
 
-                       if ( $rotation ) {
-                               if ( !$im->rotateImage( new ImagickPixel( 'white' ), 360 - $rotation ) ) {
-                                       return $this->getMediaTransformError( $params, "Error rotating $rotation degrees" );
-                               }
+                       if ( $rotation && !$im->rotateImage( new ImagickPixel( 'white' ), 360 - $rotation ) ) {
+                               return $this->getMediaTransformError( $params, "Error rotating $rotation degrees" );
                        }
 
                        if ( $this->isAnimatedImage( $image ) ) {
@@ -375,12 +375,12 @@ class BitmapHandler extends TransformationalImageHandler {
                global $wgCustomConvertCommand;
 
                # Variables: %s %d %w %h
-               $src = wfEscapeShellArg( $params['srcPath'] );
-               $dst = wfEscapeShellArg( $params['dstPath'] );
+               $src = Shell::escape( $params['srcPath'] );
+               $dst = Shell::escape( $params['dstPath'] );
                $cmd = $wgCustomConvertCommand;
                $cmd = str_replace( '%s', $src, str_replace( '%d', $dst, $cmd ) ); # Filenames
-               $cmd = str_replace( '%h', wfEscapeShellArg( $params['physicalHeight'] ),
-                       str_replace( '%w', wfEscapeShellArg( $params['physicalWidth'] ), $cmd ) ); # Size
+               $cmd = str_replace( '%h', Shell::escape( $params['physicalHeight'] ),
+                       str_replace( '%w', Shell::escape( $params['physicalWidth'] ), $cmd ) ); # Size
                wfDebug( __METHOD__ . ": Running custom convert command $cmd\n" );
                $retval = 0;
                $err = wfShellExecWithStderr( $cmd, $retval );
@@ -571,10 +571,10 @@ class BitmapHandler extends TransformationalImageHandler {
                $scaler = $this->getScalerType( null, false );
                switch ( $scaler ) {
                        case 'im':
-                               $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . " " .
-                                       wfEscapeShellArg( $this->escapeMagickInput( $params['srcPath'], $scene ) ) .
-                                       " -rotate " . wfEscapeShellArg( "-$rotation" ) . " " .
-                                       wfEscapeShellArg( $this->escapeMagickOutput( $params['dstPath'] ) );
+                               $cmd = Shell::escape( $wgImageMagickConvertCommand ) . " " .
+                                       Shell::escape( $this->escapeMagickInput( $params['srcPath'], $scene ) ) .
+                                       " -rotate " . Shell::escape( "-$rotation" ) . " " .
+                                       Shell::escape( $this->escapeMagickOutput( $params['dstPath'] ) );
                                wfDebug( __METHOD__ . ": running ImageMagick: $cmd\n" );
                                $retval = 0;
                                $err = wfShellExecWithStderr( $cmd, $retval );
index 81c63db..9617692 100644 (file)
@@ -132,13 +132,13 @@ class BitmapMetadataHandler {
                                        // Do some special casing for multilingual values.
                                        // Don't discard translations if also as a simple value.
                                        foreach ( $this->metadata[$type] as $itemName => $item ) {
-                                               if ( is_array( $item ) && isset( $item['_type'] ) && $item['_type'] === 'lang' ) {
-                                                       if ( isset( $temp[$itemName] ) && !is_array( $temp[$itemName] ) ) {
-                                                               $default = $temp[$itemName];
-                                                               $temp[$itemName] = $item;
-                                                               $temp[$itemName]['x-default'] = $default;
-                                                               unset( $this->metadata[$type][$itemName] );
-                                                       }
+                                               if ( is_array( $item ) && isset( $item['_type'] ) && $item['_type'] === 'lang' &&
+                                                       isset( $temp[$itemName] ) && !is_array( $temp[$itemName] )
+                                               ) {
+                                                       $default = $temp[$itemName];
+                                                       $temp[$itemName] = $item;
+                                                       $temp[$itemName]['x-default'] = $default;
+                                                       unset( $this->metadata[$type][$itemName] );
                                                }
                                        }
 
index ed62ba1..3b904e8 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  * @ingroup Media
  */
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Shell\Shell;
 
 /**
  * Handler for DjVu images
@@ -203,7 +205,7 @@ class DjVuHandler extends ImageHandler {
 
                # Use a subshell (brackets) to aggregate stderr from both pipeline commands
                # before redirecting it to the overall stdout. This works in both Linux and Windows XP.
-               $cmd = '(' . wfEscapeShellArg(
+               $cmd = '(' . Shell::escape(
                        $wgDjvuRenderer,
                        "-format=ppm",
                        "-page={$page}",
@@ -212,7 +214,7 @@ class DjVuHandler extends ImageHandler {
                if ( $wgDjvuPostProcessor ) {
                        $cmd .= " | {$wgDjvuPostProcessor}";
                }
-               $cmd .= ' > ' . wfEscapeShellArg( $dstPath ) . ') 2>&1';
+               $cmd .= ' > ' . Shell::escape( $dstPath ) . ') 2>&1';
                wfDebug( __METHOD__ . ": $cmd\n" );
                $retval = '';
                $err = wfShellExec( $cmd, $retval );
@@ -402,7 +404,7 @@ class DjVuHandler extends ImageHandler {
        }
 
        protected function getDimensionInfo( File $file ) {
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                return $cache->getWithSetCallback(
                        $cache->makeKey( 'file-djvu', 'dimensions', $file->getSha1() ),
                        $cache::TTL_INDEFINITE,
index 9aa1d53..fde43f4 100644 (file)
@@ -24,6 +24,8 @@
  * @ingroup Media
  */
 
+use MediaWiki\Shell\Shell;
+
 /**
  * Support for detecting/validating DjVu image files and getting
  * some basic file metadata (resolution etc)
@@ -109,7 +111,7 @@ class DjVuImage {
                                $this->dumpForm( $file, $chunkLength, $indent + 1 );
                        } else {
                                fseek( $file, $chunkLength, SEEK_CUR );
-                               if ( $chunkLength & 1 == 1 ) {
+                               if ( ( $chunkLength & 1 ) == 1 ) {
                                        // Padding byte between chunks
                                        fseek( $file, 1, SEEK_CUR );
                                }
@@ -167,7 +169,7 @@ class DjVuImage {
        private function skipChunk( $file, $chunkLength ) {
                fseek( $file, $chunkLength, SEEK_CUR );
 
-               if ( $chunkLength & 0x01 == 1 && !feof( $file ) ) {
+               if ( ( $chunkLength & 0x01 ) == 1 && !feof( $file ) ) {
                        // padding byte
                        fseek( $file, 1, SEEK_CUR );
                }
@@ -254,19 +256,19 @@ class DjVuImage {
                if ( isset( $wgDjvuDump ) ) {
                        # djvudump is faster as of version 3.5
                        # https://sourceforge.net/p/djvu/bugs/71/
-                       $cmd = wfEscapeShellArg( $wgDjvuDump ) . ' ' . wfEscapeShellArg( $this->mFilename );
+                       $cmd = Shell::escape( $wgDjvuDump ) . ' ' . Shell::escape( $this->mFilename );
                        $dump = wfShellExec( $cmd );
                        $xml = $this->convertDumpToXML( $dump );
                } elseif ( isset( $wgDjvuToXML ) ) {
-                       $cmd = wfEscapeShellArg( $wgDjvuToXML ) . ' --without-anno --without-text ' .
-                               wfEscapeShellArg( $this->mFilename );
+                       $cmd = Shell::escape( $wgDjvuToXML ) . ' --without-anno --without-text ' .
+                               Shell::escape( $this->mFilename );
                        $xml = wfShellExec( $cmd );
                } else {
                        $xml = null;
                }
                # Text layer
                if ( isset( $wgDjvuTxt ) ) {
-                       $cmd = wfEscapeShellArg( $wgDjvuTxt ) . ' --detail=page ' . wfEscapeShellArg( $this->mFilename );
+                       $cmd = Shell::escape( $wgDjvuTxt ) . ' --detail=page ' . Shell::escape( $this->mFilename );
                        wfDebug( __METHOD__ . ": $cmd\n" );
                        $retval = '';
                        $txt = wfShellExec( $cmd, $retval, [], [ 'memory' => self::DJVUTXT_MEMORY_LIMIT ] );
@@ -286,8 +288,9 @@ class DjVuImage {
 EOR;
                                $txt = preg_replace_callback( $reg, [ $this, 'pageTextCallback' ], $txt );
                                $txt = "<DjVuTxt>\n<HEAD></HEAD>\n<BODY>\n" . $txt . "</BODY>\n</DjVuTxt>\n";
-                               $xml = preg_replace( "/<DjVuXML>/", "<mw-djvu><DjVuXML>", $xml, 1 );
-                               $xml = $xml . $txt . '</mw-djvu>';
+                               $xml = preg_replace( "/<DjVuXML>/", "<mw-djvu><DjVuXML>", $xml, 1 ) .
+                                       $txt .
+                                       '</mw-djvu>';
                        }
                }
 
index c32a720..0fde386 100644 (file)
@@ -455,8 +455,7 @@ class Exif {
                        $val = substr( $this->mFilteredExifData[$prop], 8 );
 
                        switch ( $charCode ) {
-                               case "\x4A\x49\x53\x00\x00\x00\x00\x00":
-                                       // JIS
+                               case "JIS\x00\x00\x00\x00\x00":
                                        $charset = "Shift-JIS";
                                        break;
                                case "UNICODE\x00":
index 556e83c..9ef37fb 100644 (file)
@@ -86,8 +86,11 @@ class GIFHandler extends BitmapHandler {
                $ser = $image->getMetadata();
                if ( $ser ) {
                        $metadata = unserialize( $ser );
-
-                       return $image->getWidth() * $image->getHeight() * $metadata['frameCount'];
+                       if ( isset( $metadata['frameCount'] ) && $metadata['frameCount'] > 0 ) {
+                               return $image->getWidth() * $image->getHeight() * $metadata['frameCount'];
+                       } else {
+                               return $image->getWidth() * $image->getHeight();
+                       }
                } else {
                        return $image->getWidth() * $image->getHeight();
                }
@@ -101,7 +104,7 @@ class GIFHandler extends BitmapHandler {
                $ser = $image->getMetadata();
                if ( $ser ) {
                        $metadata = unserialize( $ser );
-                       if ( $metadata['frameCount'] > 1 ) {
+                       if ( isset( $metadata['frameCount'] ) && $metadata['frameCount'] > 1 ) {
                                return true;
                        }
                }
index 4bcb53d..4aca5b3 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Media
  */
 
+use MediaWiki\Shell\Shell;
+
 /**
  * JPEG specific handler.
  * Inherits most stuff from BitmapHandler, just here to do the metadata handler differently.
@@ -140,17 +142,23 @@ class JpegHandler extends ExifBitmapHandler {
                $rotation = ( $params['rotation'] + $this->getRotation( $file ) ) % 360;
 
                if ( $wgJpegTran && is_executable( $wgJpegTran ) ) {
-                       $cmd = wfEscapeShellArg( $wgJpegTran ) .
-                               " -rotate " . wfEscapeShellArg( $rotation ) .
-                               " -outfile " . wfEscapeShellArg( $params['dstPath'] ) .
-                               " " . wfEscapeShellArg( $params['srcPath'] );
-                       wfDebug( __METHOD__ . ": running jpgtran: $cmd\n" );
-                       $retval = 0;
-                       $err = wfShellExecWithStderr( $cmd, $retval );
-                       if ( $retval !== 0 ) {
-                               $this->logErrorForExternalProcess( $retval, $err, $cmd );
-
-                               return new MediaTransformError( 'thumbnail_error', 0, 0, $err );
+                       $command = Shell::command( $wgJpegTran,
+                               '-rotate',
+                               $rotation,
+                               '-outfile',
+                               $params['dstPath'],
+                               $params['srcPath']
+                       );
+                       $result = $command
+                               ->includeStderr()
+                               ->execute();
+                       if ( $result->getExitCode() !== 0 ) {
+                               $this->logErrorForExternalProcess( $result->getExitCode(),
+                                       $result->getStdout(),
+                                       $command
+                               );
+
+                               return new MediaTransformError( 'thumbnail_error', 0, 0, $result->getStdout() );
                        }
 
                        return false;
@@ -240,20 +248,21 @@ class JpegHandler extends ExifBitmapHandler {
                        return false;
                }
 
-               $cmd = wfEscapeShellArg( $wgExiftool,
+               $result = Shell::command(
+                       $wgExiftool,
                        '-EXIF:ColorSpace',
                        '-ICC_Profile:ProfileDescription',
                        '-S',
                        '-T',
                        $filepath
-               );
-
-               $output = wfShellExecWithStderr( $cmd, $retval );
+               )
+                       ->includeStderr()
+                       ->execute();
 
                // Explode EXIF data into an array with [0 => Color Space, 1 => Device Model Desc]
-               $data = explode( "\t", trim( $output ) );
+               $data = explode( "\t", trim( $result->getStdout() ) );
 
-               if ( $retval !== 0 ) {
+               if ( $result->getExitCode() !== 0 ) {
                        return false;
                }
 
@@ -271,16 +280,20 @@ class JpegHandler extends ExifBitmapHandler {
                        return false;
                }
 
-               $cmd = wfEscapeShellArg( $wgExiftool,
+               $command = Shell::command( $wgExiftool,
                        '-overwrite_original',
                        '-icc_profile<=' . $profileFilepath,
                        $filepath
                );
-
-               $output = wfShellExecWithStderr( $cmd, $retval );
-
-               if ( $retval !== 0 ) {
-                       $this->logErrorForExternalProcess( $retval, $output, $cmd );
+               $result = $command
+                       ->includeStderr()
+                       ->execute();
+
+               if ( $result->getExitCode() !== 0 ) {
+                       $this->logErrorForExternalProcess( $result->getExitCode(),
+                               $result->getStdout(),
+                               $command
+                       );
 
                        return false;
                }
index a54da7d..1a96c1d 100644 (file)
@@ -104,7 +104,7 @@ abstract class MediaHandler {
         *   Warning, FSFile::getPropsFromPath might pass an FSFile instead of File (!)
         * @param string $path The filename
         * @return array|bool Follow the format of PHP getimagesize() internal function.
-        *   See https://secure.php.net/getimagesize. MediaWiki will only ever use the
+        *   See https://www.php.net/getimagesize. MediaWiki will only ever use the
         *   first two array keys (the width and height), and the 'bits' associative
         *   key. All other array keys are ignored. Returning a 'bits' key is optional
         *   as not all formats have a notion of "bitdepth". Returns false on failure.
index 543dc80..82e8d1f 100644 (file)
@@ -66,11 +66,7 @@ class MediaHandlerFactory {
        }
 
        protected function getHandlerClass( $type ) {
-               if ( isset( $this->registry[$type] ) ) {
-                       return $this->registry[$type];
-               } else {
-                       return false;
-               }
+               return $this->registry[$type] ?? false;
        }
 
        /**
diff --git a/includes/media/MediaTransformError.php b/includes/media/MediaTransformError.php
new file mode 100644 (file)
index 0000000..fb1b015
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Base class for the output of file transformation methods.
+ *
+ * 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 Media
+ */
+
+/**
+ * Basic media transform error class
+ *
+ * @ingroup Media
+ */
+class MediaTransformError extends MediaTransformOutput {
+       /** @var Message */
+       private $msg;
+
+       function __construct( $msg, $width, $height, ...$args ) {
+               $this->msg = wfMessage( $msg )->params( $args );
+               $this->width = intval( $width );
+               $this->height = intval( $height );
+               $this->url = false;
+               $this->path = false;
+       }
+
+       function toHtml( $options = [] ) {
+               return "<div class=\"MediaTransformError\" style=\"" .
+                       "width: {$this->width}px; height: {$this->height}px; display:inline-block;\">" .
+                       $this->getHtmlMsg() .
+                       "</div>";
+       }
+
+       function toText() {
+               return $this->msg->text();
+       }
+
+       function getHtmlMsg() {
+               return $this->msg->escaped();
+       }
+
+       function getMsg() {
+               return $this->msg;
+       }
+
+       function isError() {
+               return true;
+       }
+
+       function getHttpStatusCode() {
+               return 500;
+       }
+}
index 34f7e8c..9c06ef4 100644 (file)
@@ -268,270 +268,3 @@ abstract class MediaTransformOutput {
                return $attribs;
        }
 }
-
-/**
- * Media transform output for images
- *
- * @ingroup Media
- */
-class ThumbnailImage extends MediaTransformOutput {
-       private static $firstNonIconImageRendered = false;
-
-       /**
-        * Get a thumbnail object from a file and parameters.
-        * If $path is set to null, the output file is treated as a source copy.
-        * If $path is set to false, no output file will be created.
-        * $parameters should include, as a minimum, (file) 'width' and 'height'.
-        * It may also include a 'page' parameter for multipage files.
-        *
-        * @param File $file
-        * @param string $url URL path to the thumb
-        * @param string|bool $path Filesystem path to the thumb
-        * @param array $parameters Associative array of parameters
-        */
-       function __construct( $file, $url, $path = false, $parameters = [] ) {
-               # Previous parameters:
-               #   $file, $url, $width, $height, $path = false, $page = false
-
-               $defaults = [
-                       'page' => false,
-                       'lang' => false
-               ];
-
-               if ( is_array( $parameters ) ) {
-                       $actualParams = $parameters + $defaults;
-               } else {
-                       # Using old format, should convert. Later a warning could be added here.
-                       $numArgs = func_num_args();
-                       $actualParams = [
-                               'width' => $path,
-                               'height' => $parameters,
-                               'page' => ( $numArgs > 5 ) ? func_get_arg( 5 ) : false
-                       ] + $defaults;
-                       $path = ( $numArgs > 4 ) ? func_get_arg( 4 ) : false;
-               }
-
-               $this->file = $file;
-               $this->url = $url;
-               $this->path = $path;
-
-               # These should be integers when they get here.
-               # If not, there's a bug somewhere.  But let's at
-               # least produce valid HTML code regardless.
-               $this->width = round( $actualParams['width'] );
-               $this->height = round( $actualParams['height'] );
-
-               $this->page = $actualParams['page'];
-               $this->lang = $actualParams['lang'];
-       }
-
-       /**
-        * Return HTML <img ... /> tag for the thumbnail, will include
-        * width and height attributes and a blank alt text (as required).
-        *
-        * @param array $options Associative array of options. Boolean options
-        *     should be indicated with a value of true for true, and false or
-        *     absent for false.
-        *
-        *     alt          HTML alt attribute
-        *     title        HTML title attribute
-        *     desc-link    Boolean, show a description link
-        *     file-link    Boolean, show a file download link
-        *     valign       vertical-align property, if the output is an inline element
-        *     img-class    Class applied to the \<img\> tag, if there is such a tag
-        *     desc-query   String, description link query params
-        *     override-width     Override width attribute. Should generally not set
-        *     override-height    Override height attribute. Should generally not set
-        *     no-dimensions      Boolean, skip width and height attributes (useful if
-        *                        set in CSS)
-        *     custom-url-link    Custom URL to link to
-        *     custom-title-link  Custom Title object to link to
-        *     custom target-link Value of the target attribute, for custom-target-link
-        *     parser-extlink-*   Attributes added by parser for external links:
-        *          parser-extlink-rel: add rel="nofollow"
-        *          parser-extlink-target: link target, but overridden by custom-target-link
-        *
-        * For images, desc-link and file-link are implemented as a click-through. For
-        * sounds and videos, they may be displayed in other ways.
-        *
-        * @throws MWException
-        * @return string
-        */
-       function toHtml( $options = [] ) {
-               global $wgPriorityHints;
-
-               if ( count( func_get_args() ) == 2 ) {
-                       throw new MWException( __METHOD__ . ' called in the old style' );
-               }
-
-               $alt = $options['alt'] ?? '';
-
-               $query = $options['desc-query'] ?? '';
-
-               $attribs = [
-                       'alt' => $alt,
-                       'src' => $this->url,
-                       'decoding' => 'async',
-               ];
-
-               if ( $wgPriorityHints
-                       && !self::$firstNonIconImageRendered
-                       && $this->width * $this->height > 100 * 100 ) {
-                       self::$firstBigImageRendered = true;
-
-                       $attribs['importance'] = 'high';
-               }
-
-               if ( !empty( $options['custom-url-link'] ) ) {
-                       $linkAttribs = [ 'href' => $options['custom-url-link'] ];
-                       if ( !empty( $options['title'] ) ) {
-                               $linkAttribs['title'] = $options['title'];
-                       }
-                       if ( !empty( $options['custom-target-link'] ) ) {
-                               $linkAttribs['target'] = $options['custom-target-link'];
-                       } elseif ( !empty( $options['parser-extlink-target'] ) ) {
-                               $linkAttribs['target'] = $options['parser-extlink-target'];
-                       }
-                       if ( !empty( $options['parser-extlink-rel'] ) ) {
-                               $linkAttribs['rel'] = $options['parser-extlink-rel'];
-                       }
-               } elseif ( !empty( $options['custom-title-link'] ) ) {
-                       /** @var Title $title */
-                       $title = $options['custom-title-link'];
-                       $linkAttribs = [
-                               'href' => $title->getLinkURL(),
-                               'title' => empty( $options['title'] ) ? $title->getFullText() : $options['title']
-                       ];
-               } elseif ( !empty( $options['desc-link'] ) ) {
-                       $linkAttribs = $this->getDescLinkAttribs(
-                               empty( $options['title'] ) ? null : $options['title'],
-                               $query
-                       );
-               } elseif ( !empty( $options['file-link'] ) ) {
-                       $linkAttribs = [ 'href' => $this->file->getUrl() ];
-               } else {
-                       $linkAttribs = false;
-                       if ( !empty( $options['title'] ) ) {
-                               $attribs['title'] = $options['title'];
-                       }
-               }
-
-               if ( empty( $options['no-dimensions'] ) ) {
-                       $attribs['width'] = $this->width;
-                       $attribs['height'] = $this->height;
-               }
-               if ( !empty( $options['valign'] ) ) {
-                       $attribs['style'] = "vertical-align: {$options['valign']}";
-               }
-               if ( !empty( $options['img-class'] ) ) {
-                       $attribs['class'] = $options['img-class'];
-               }
-               if ( isset( $options['override-height'] ) ) {
-                       $attribs['height'] = $options['override-height'];
-               }
-               if ( isset( $options['override-width'] ) ) {
-                       $attribs['width'] = $options['override-width'];
-               }
-
-               // Additional densities for responsive images, if specified.
-               // If any of these urls is the same as src url, it'll be excluded.
-               $responsiveUrls = array_diff( $this->responsiveUrls, [ $this->url ] );
-               if ( !empty( $responsiveUrls ) ) {
-                       $attribs['srcset'] = Html::srcSet( $responsiveUrls );
-               }
-
-               Hooks::run( 'ThumbnailBeforeProduceHTML', [ $this, &$attribs, &$linkAttribs ] );
-
-               return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
-       }
-}
-
-/**
- * Basic media transform error class
- *
- * @ingroup Media
- */
-class MediaTransformError extends MediaTransformOutput {
-       /** @var Message */
-       private $msg;
-
-       function __construct( $msg, $width, $height /*, ... */ ) {
-               $args = array_slice( func_get_args(), 3 );
-               $this->msg = wfMessage( $msg )->params( $args );
-               $this->width = intval( $width );
-               $this->height = intval( $height );
-               $this->url = false;
-               $this->path = false;
-       }
-
-       function toHtml( $options = [] ) {
-               return "<div class=\"MediaTransformError\" style=\"" .
-                       "width: {$this->width}px; height: {$this->height}px; display:inline-block;\">" .
-                       $this->getHtmlMsg() .
-                       "</div>";
-       }
-
-       function toText() {
-               return $this->msg->text();
-       }
-
-       function getHtmlMsg() {
-               return $this->msg->escaped();
-       }
-
-       function getMsg() {
-               return $this->msg;
-       }
-
-       function isError() {
-               return true;
-       }
-
-       function getHttpStatusCode() {
-               return 500;
-       }
-}
-
-/**
- * Shortcut class for parameter validation errors
- *
- * @ingroup Media
- */
-class TransformParameterError extends MediaTransformError {
-       function __construct( $params ) {
-               parent::__construct( 'thumbnail_error',
-                       max( $params['width'] ?? 0, 120 ),
-                       max( $params['height'] ?? 0, 120 ),
-                       wfMessage( 'thumbnail_invalid_params' )
-               );
-       }
-
-       function getHttpStatusCode() {
-               return 400;
-       }
-}
-
-/**
- * Shortcut class for parameter file size errors
- *
- * @ingroup Media
- * @since 1.25
- */
-class TransformTooBigImageAreaError extends MediaTransformError {
-       function __construct( $params, $maxImageArea ) {
-               $msg = wfMessage( 'thumbnail_toobigimagearea' );
-               $msg->params(
-                       $msg->getLanguage()->formatComputingNumbers( $maxImageArea, 1000, "size-$1pixel" )
-               );
-
-               parent::__construct( 'thumbnail_error',
-                       max( $params['width'] ?? 0, 120 ),
-                       max( $params['height'] ?? 0, 120 ),
-                       $msg
-               );
-       }
-
-       function getHttpStatusCode() {
-               return 400;
-       }
-}
index f8b0c3c..bc5eb09 100644 (file)
@@ -226,13 +226,8 @@ class SVGReader {
                        return;
                }
                // @todo Find and store type of xml snippet. metadata['metadataType'] = "rdf"
-               if ( method_exists( $this->reader, 'readInnerXML' ) ) {
-                       $this->metadata[$metafield] = trim( $this->reader->readInnerXml() );
-               } else {
-                       throw new MWException( "The PHP XMLReader extension does not come " .
-                               "with readInnerXML() method. Your libxml is probably out of " .
-                               "date (need 2.6.20 or later)." );
-               }
+               $this->metadata[$metafield] = trim( $this->reader->readInnerXml() );
+
                $this->reader->next();
        }
 
index b7745df..bdda674 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  * @ingroup Media
  */
+
+use MediaWiki\Shell\Shell;
 use Wikimedia\ScopedCallback;
 
 /**
@@ -199,20 +201,16 @@ class SvgHandler extends ImageHandler {
                                $params['physicalWidth'] = $wgSVGMaxSize;
                                $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight, $wgSVGMaxSize );
                        }
-               } else {
-                       if ( $params['physicalHeight'] > $wgSVGMaxSize ) {
-                               $srcWidth = $image->getWidth( $params['page'] );
-                               $srcHeight = $image->getHeight( $params['page'] );
-                               $params['physicalWidth'] = File::scaleHeight( $srcHeight, $srcWidth, $wgSVGMaxSize );
-                               $params['physicalHeight'] = $wgSVGMaxSize;
-                       }
+               } elseif ( $params['physicalHeight'] > $wgSVGMaxSize ) {
+                       $srcWidth = $image->getWidth( $params['page'] );
+                       $srcHeight = $image->getHeight( $params['page'] );
+                       $params['physicalWidth'] = File::scaleHeight( $srcHeight, $srcWidth, $wgSVGMaxSize );
+                       $params['physicalHeight'] = $wgSVGMaxSize;
                }
                // To prevent the proliferation of thumbnails in languages not present in SVGs, unless
                // explicitly forced by user.
-               if ( isset( $params['targetlang'] ) ) {
-                       if ( !$image->getMatchedLanguage( $params['targetlang'] ) ) {
-                               unset( $params['targetlang'] );
-                       }
+               if ( isset( $params['targetlang'] ) && !$image->getMatchedLanguage( $params['targetlang'] ) ) {
+                       unset( $params['targetlang'] );
                }
 
                return $params;
@@ -339,11 +337,11 @@ class SvgHandler extends ImageHandler {
                                // External command
                                $cmd = str_replace(
                                        [ '$path/', '$width', '$height', '$input', '$output' ],
-                                       [ $wgSVGConverterPath ? wfEscapeShellArg( "$wgSVGConverterPath/" ) : "",
+                                       [ $wgSVGConverterPath ? Shell::escape( "$wgSVGConverterPath/" ) : "",
                                                intval( $width ),
                                                intval( $height ),
-                                               wfEscapeShellArg( $srcPath ),
-                                               wfEscapeShellArg( $dstPath ) ],
+                                               Shell::escape( $srcPath ),
+                                               Shell::escape( $dstPath ) ],
                                        $wgSVGConverters[$wgSVGConverter]
                                );
 
diff --git a/includes/media/ThumbnailImage.php b/includes/media/ThumbnailImage.php
new file mode 100644 (file)
index 0000000..36cf422
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+/**
+ * Base class for the output of file transformation methods.
+ *
+ * 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 Media
+ */
+
+/**
+ * Media transform output for images
+ *
+ * @ingroup Media
+ */
+class ThumbnailImage extends MediaTransformOutput {
+       private static $firstNonIconImageRendered = false;
+
+       /**
+        * Get a thumbnail object from a file and parameters.
+        * If $path is set to null, the output file is treated as a source copy.
+        * If $path is set to false, no output file will be created.
+        * $parameters should include, as a minimum, (file) 'width' and 'height'.
+        * It may also include a 'page' parameter for multipage files.
+        *
+        * @param File $file
+        * @param string $url URL path to the thumb
+        * @param string|bool $path Filesystem path to the thumb
+        * @param array $parameters Associative array of parameters
+        */
+       function __construct( $file, $url, $path = false, $parameters = [] ) {
+               # Previous parameters:
+               #   $file, $url, $width, $height, $path = false, $page = false
+
+               $defaults = [
+                       'page' => false,
+                       'lang' => false
+               ];
+
+               if ( is_array( $parameters ) ) {
+                       $actualParams = $parameters + $defaults;
+               } else {
+                       # Using old format, should convert. Later a warning could be added here.
+                       $numArgs = func_num_args();
+                       $actualParams = [
+                               'width' => $path,
+                               'height' => $parameters,
+                               'page' => ( $numArgs > 5 ) ? func_get_arg( 5 ) : false
+                       ] + $defaults;
+                       $path = ( $numArgs > 4 ) ? func_get_arg( 4 ) : false;
+               }
+
+               $this->file = $file;
+               $this->url = $url;
+               $this->path = $path;
+
+               # These should be integers when they get here.
+               # If not, there's a bug somewhere.  But let's at
+               # least produce valid HTML code regardless.
+               $this->width = round( $actualParams['width'] );
+               $this->height = round( $actualParams['height'] );
+
+               $this->page = $actualParams['page'];
+               $this->lang = $actualParams['lang'];
+       }
+
+       /**
+        * Return HTML <img ... /> tag for the thumbnail, will include
+        * width and height attributes and a blank alt text (as required).
+        *
+        * @param array $options Associative array of options. Boolean options
+        *     should be indicated with a value of true for true, and false or
+        *     absent for false.
+        *
+        *     alt          HTML alt attribute
+        *     title        HTML title attribute
+        *     desc-link    Boolean, show a description link
+        *     file-link    Boolean, show a file download link
+        *     valign       vertical-align property, if the output is an inline element
+        *     img-class    Class applied to the \<img\> tag, if there is such a tag
+        *     desc-query   String, description link query params
+        *     override-width     Override width attribute. Should generally not set
+        *     override-height    Override height attribute. Should generally not set
+        *     no-dimensions      Boolean, skip width and height attributes (useful if
+        *                        set in CSS)
+        *     custom-url-link    Custom URL to link to
+        *     custom-title-link  Custom Title object to link to
+        *     custom target-link Value of the target attribute, for custom-target-link
+        *     parser-extlink-*   Attributes added by parser for external links:
+        *          parser-extlink-rel: add rel="nofollow"
+        *          parser-extlink-target: link target, but overridden by custom-target-link
+        *
+        * For images, desc-link and file-link are implemented as a click-through. For
+        * sounds and videos, they may be displayed in other ways.
+        *
+        * @throws MWException
+        * @return string
+        */
+       function toHtml( $options = [] ) {
+               global $wgPriorityHints, $wgElementTiming;
+
+               if ( func_num_args() == 2 ) {
+                       throw new MWException( __METHOD__ . ' called in the old style' );
+               }
+
+               $alt = $options['alt'] ?? '';
+
+               $query = $options['desc-query'] ?? '';
+
+               $attribs = [
+                       'alt' => $alt,
+                       'src' => $this->url,
+                       'decoding' => 'async',
+               ];
+
+               $elementTimingName = 'thumbnail';
+
+               if ( $wgPriorityHints
+                       && !self::$firstNonIconImageRendered
+                       && $this->width * $this->height > 100 * 100 ) {
+                       self::$firstNonIconImageRendered = true;
+
+                       $attribs['importance'] = 'high';
+                       $elementTimingName = 'thumbnail-high';
+               }
+
+               if ( $wgElementTiming ) {
+                       $attribs['elementtiming'] = $elementTimingName;
+               }
+
+               if ( !empty( $options['custom-url-link'] ) ) {
+                       $linkAttribs = [ 'href' => $options['custom-url-link'] ];
+                       if ( !empty( $options['title'] ) ) {
+                               $linkAttribs['title'] = $options['title'];
+                       }
+                       if ( !empty( $options['custom-target-link'] ) ) {
+                               $linkAttribs['target'] = $options['custom-target-link'];
+                       } elseif ( !empty( $options['parser-extlink-target'] ) ) {
+                               $linkAttribs['target'] = $options['parser-extlink-target'];
+                       }
+                       if ( !empty( $options['parser-extlink-rel'] ) ) {
+                               $linkAttribs['rel'] = $options['parser-extlink-rel'];
+                       }
+               } elseif ( !empty( $options['custom-title-link'] ) ) {
+                       /** @var Title $title */
+                       $title = $options['custom-title-link'];
+                       $linkAttribs = [
+                               'href' => $title->getLinkURL(),
+                               'title' => empty( $options['title'] ) ? $title->getFullText() : $options['title']
+                       ];
+               } elseif ( !empty( $options['desc-link'] ) ) {
+                       $linkAttribs = $this->getDescLinkAttribs(
+                               empty( $options['title'] ) ? null : $options['title'],
+                               $query
+                       );
+               } elseif ( !empty( $options['file-link'] ) ) {
+                       $linkAttribs = [ 'href' => $this->file->getUrl() ];
+               } else {
+                       $linkAttribs = false;
+                       if ( !empty( $options['title'] ) ) {
+                               $attribs['title'] = $options['title'];
+                       }
+               }
+
+               if ( empty( $options['no-dimensions'] ) ) {
+                       $attribs['width'] = $this->width;
+                       $attribs['height'] = $this->height;
+               }
+               if ( !empty( $options['valign'] ) ) {
+                       $attribs['style'] = "vertical-align: {$options['valign']}";
+               }
+               if ( !empty( $options['img-class'] ) ) {
+                       $attribs['class'] = $options['img-class'];
+               }
+               if ( isset( $options['override-height'] ) ) {
+                       $attribs['height'] = $options['override-height'];
+               }
+               if ( isset( $options['override-width'] ) ) {
+                       $attribs['width'] = $options['override-width'];
+               }
+
+               // Additional densities for responsive images, if specified.
+               // If any of these urls is the same as src url, it'll be excluded.
+               $responsiveUrls = array_diff( $this->responsiveUrls, [ $this->url ] );
+               if ( !empty( $responsiveUrls ) ) {
+                       $attribs['srcset'] = Html::srcSet( $responsiveUrls );
+               }
+
+               Hooks::run( 'ThumbnailBeforeProduceHTML', [ $this, &$attribs, &$linkAttribs ] );
+
+               return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
+       }
+}
diff --git a/includes/media/TransformParameterError.php b/includes/media/TransformParameterError.php
new file mode 100644 (file)
index 0000000..0f26239
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Base class for the output of file transformation methods.
+ *
+ * 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 Media
+ */
+
+/**
+ * Shortcut class for parameter validation errors
+ *
+ * @ingroup Media
+ */
+class TransformParameterError extends MediaTransformError {
+       function __construct( $params ) {
+               parent::__construct( 'thumbnail_error',
+                       max( $params['width'] ?? 0, 120 ),
+                       max( $params['height'] ?? 0, 120 ),
+                       wfMessage( 'thumbnail_invalid_params' )
+               );
+       }
+
+       function getHttpStatusCode() {
+               return 400;
+       }
+}
diff --git a/includes/media/TransformTooBigImageAreaError.php b/includes/media/TransformTooBigImageAreaError.php
new file mode 100644 (file)
index 0000000..0a58ef3
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Base class for the output of file transformation methods.
+ *
+ * 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 Media
+ */
+
+/**
+ * Shortcut class for parameter file size errors
+ *
+ * @ingroup Media
+ * @since 1.25
+ */
+class TransformTooBigImageAreaError extends MediaTransformError {
+       function __construct( $params, $maxImageArea ) {
+               $msg = wfMessage( 'thumbnail_toobigimagearea' );
+               $msg->params(
+                       $msg->getLanguage()->formatComputingNumbers( $maxImageArea, 1000, "size-$1pixel" )
+               );
+
+               parent::__construct( 'thumbnail_error',
+                       max( $params['width'] ?? 0, 120 ),
+                       max( $params['height'] ?? 0, 120 ),
+                       $msg
+               );
+       }
+
+       function getHttpStatusCode() {
+               return 400;
+       }
+}
index 38dc390..dbeca0b 100644 (file)
@@ -26,6 +26,7 @@
  * @ingroup Media
  */
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Shell\Shell;
 
 /**
  * Handler for images that need to be transformed
@@ -517,7 +518,7 @@ abstract class TransformationalImageHandler extends ImageHandler {
                        function () use ( $method ) {
                                global $wgImageMagickConvertCommand;
 
-                               $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version';
+                               $cmd = Shell::escape( $wgImageMagickConvertCommand ) . ' -version';
                                wfDebug( $method . ": Running convert -version\n" );
                                $retval = '';
                                $return = wfShellExecWithStderr( $cmd, $retval );
index 33f33bd..e47cc37 100644 (file)
@@ -67,7 +67,7 @@ class XCFHandler extends BitmapHandler {
                }
 
                # Forge a return array containing metadata information just like getimagesize()
-               # See PHP documentation at: https://secure.php.net/getimagesize
+               # See PHP documentation at: https://www.php.net/getimagesize
                return [
                        0 => $header['width'],
                        1 => $header['height'],
index 14d63a1..fed0854 100644 (file)
@@ -238,7 +238,6 @@ class ObjectCache {
                global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType;
                $candidates = [ $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType ];
                foreach ( $candidates as $candidate ) {
-                       $cache = false;
                        if ( $candidate !== CACHE_NONE && $candidate !== CACHE_ANYTHING ) {
                                $cache = self::getInstance( $candidate );
                                // CACHE_ACCEL might default to nothing if no APCu
@@ -365,7 +364,7 @@ class ObjectCache {
         *
         * @since 1.26
         * @return WANObjectCache
-        * @deprecated Since 1.28 Use MediaWikiServices::getMainWANObjectCache()
+        * @deprecated Since 1.28 Use MediaWikiServices::getInstance()->getMainWANObjectCache()
         */
        public static function getMainWANInstance() {
                return MediaWikiServices::getInstance()->getMainWANObjectCache();
@@ -388,7 +387,7 @@ class ObjectCache {
         *
         * @return BagOStuff
         * @since 1.26
-        * @deprecated Since 1.28 Use MediaWikiServices::getMainObjectStash
+        * @deprecated Since 1.28 Use MediaWikiServices::getInstance()->getMainObjectStash()
         */
        public static function getMainStashInstance() {
                return MediaWikiServices::getInstance()->getMainObjectStash();
index 2866a6c..088f94e 100644 (file)
@@ -234,22 +234,34 @@ class SqlBagOStuff extends BagOStuff {
                }
        }
 
-       protected function doGet( $key, $flags = 0 ) {
+       protected function doGet( $key, $flags = 0, &$casToken = null ) {
                $casToken = null;
 
-               return $this->getWithToken( $key, $casToken, $flags );
-       }
+               $blobs = $this->fetchBlobMulti( [ $key ] );
+               if ( array_key_exists( $key, $blobs ) ) {
+                       $blob = $blobs[$key];
+                       $value = $this->unserialize( $blob );
+
+                       $casToken = ( $value !== false ) ? $blob : null;
 
-       protected function getWithToken( $key, &$casToken, $flags = 0 ) {
-               $values = $this->getMulti( [ $key ] );
-               if ( array_key_exists( $key, $values ) ) {
-                       $casToken = $values[$key];
-                       return $values[$key];
+                       return $value;
                }
+
                return false;
        }
 
        public function getMulti( array $keys, $flags = 0 ) {
+               $values = [];
+
+               $blobs = $this->fetchBlobMulti( $keys );
+               foreach ( $blobs as $key => $blob ) {
+                       $values[$key] = $this->unserialize( $blob );
+               }
+
+               return $values;
+       }
+
+       public function fetchBlobMulti( array $keys, $flags = 0 ) {
                $values = []; // array of (key => value)
 
                $keysByTable = [];
@@ -298,7 +310,7 @@ class SqlBagOStuff extends BagOStuff {
                                        if ( $this->isExpired( $db, $row->exptime ) ) { // MISS
                                                $this->debug( "get: key has expired" );
                                        } else { // HIT
-                                               $values[$key] = $this->unserialize( $db->decodeBlob( $row->value ) );
+                                               $values[$key] = $db->decodeBlob( $row->value );
                                        }
                                } catch ( DBQueryError $e ) {
                                        $this->handleWriteError( $e, $db, $row->serverIndex );
@@ -311,7 +323,11 @@ class SqlBagOStuff extends BagOStuff {
                return $values;
        }
 
-       public function setMulti( array $data, $expiry = 0 ) {
+       public function setMulti( array $data, $expiry = 0, $flags = 0 ) {
+               return $this->insertMulti( $data, $expiry, $flags, true );
+       }
+
+       private function insertMulti( array $data, $expiry, $flags, $replace ) {
                $keysByTable = [];
                foreach ( $data as $key => $value ) {
                        list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
@@ -340,7 +356,7 @@ class SqlBagOStuff extends BagOStuff {
                        if ( $exptime == 0 ) {
                                $encExpiry = $this->getMaxDateTime( $db );
                        } else {
-                               $exptime = $this->convertExpiry( $exptime );
+                               $exptime = $this->convertToExpiry( $exptime );
                                $encExpiry = $db->timestamp( $exptime );
                        }
                        foreach ( $serverKeys as $tableName => $tableKeys ) {
@@ -354,19 +370,22 @@ class SqlBagOStuff extends BagOStuff {
                                }
 
                                try {
-                                       $db->replace(
-                                               $tableName,
-                                               [ 'keyname' ],
-                                               $rows,
-                                               __METHOD__
-                                       );
+                                       if ( $replace ) {
+                                               $db->replace( $tableName, [ 'keyname' ], $rows, __METHOD__ );
+                                       } else {
+                                               $db->insert( $tableName, $rows, __METHOD__, [ 'IGNORE' ] );
+                                               $result = ( $db->affectedRows() > 0 && $result );
+                                       }
                                } catch ( DBError $e ) {
                                        $this->handleWriteError( $e, $db, $serverIndex );
                                        $result = false;
                                }
 
                        }
+               }
 
+               if ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) {
+                       $result = $this->waitForReplication() && $result;
                }
 
                return $result;
@@ -374,14 +393,17 @@ class SqlBagOStuff extends BagOStuff {
 
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
                $ok = $this->setMulti( [ $key => $value ], $exptime );
-               if ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) {
-                       $ok = $this->waitForReplication() && $ok;
-               }
 
                return $ok;
        }
 
-       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
+       public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+               $added = $this->insertMulti( [ $key => $value ], $exptime, $flags, false );
+
+               return $added;
+       }
+
+       protected function cas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
                list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
                $db = null;
                $silenceScope = $this->silenceTransactionProfiler();
@@ -396,7 +418,7 @@ class SqlBagOStuff extends BagOStuff {
                        if ( $exptime == 0 ) {
                                $encExpiry = $this->getMaxDateTime( $db );
                        } else {
-                               $exptime = $this->convertExpiry( $exptime );
+                               $exptime = $this->convertToExpiry( $exptime );
                                $encExpiry = $db->timestamp( $exptime );
                        }
                        // (T26425) use a replace if the db supports it instead of
@@ -410,7 +432,7 @@ class SqlBagOStuff extends BagOStuff {
                                ],
                                [
                                        'keyname' => $key,
-                                       'value' => $db->encodeBlob( $this->serialize( $casToken ) )
+                                       'value' => $db->encodeBlob( $casToken )
                                ],
                                __METHOD__
                        );
@@ -423,22 +445,47 @@ class SqlBagOStuff extends BagOStuff {
                return (bool)$db->affectedRows();
        }
 
-       public function delete( $key ) {
-               list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
-               $db = null;
+       public function deleteMulti( array $keys, $flags = 0 ) {
+               $keysByTable = [];
+               foreach ( $keys as $key ) {
+                       list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
+                       $keysByTable[$serverIndex][$tableName][] = $key;
+               }
+
+               $result = true;
                $silenceScope = $this->silenceTransactionProfiler();
-               try {
-                       $db = $this->getDB( $serverIndex );
-                       $db->delete(
-                               $tableName,
-                               [ 'keyname' => $key ],
-                               __METHOD__ );
-               } catch ( DBError $e ) {
-                       $this->handleWriteError( $e, $db, $serverIndex );
-                       return false;
+               foreach ( $keysByTable as $serverIndex => $serverKeys ) {
+                       $db = null;
+                       try {
+                               $db = $this->getDB( $serverIndex );
+                       } catch ( DBError $e ) {
+                               $this->handleWriteError( $e, $db, $serverIndex );
+                               $result = false;
+                               continue;
+                       }
+
+                       foreach ( $serverKeys as $tableName => $tableKeys ) {
+                               try {
+                                       $db->delete( $tableName, [ 'keyname' => $tableKeys ], __METHOD__ );
+                               } catch ( DBError $e ) {
+                                       $this->handleWriteError( $e, $db, $serverIndex );
+                                       $result = false;
+                               }
+
+                       }
                }
 
-               return true;
+               if ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) {
+                       $result = $this->waitForReplication() && $result;
+               }
+
+               return $result;
+       }
+
+       public function delete( $key, $flags = 0 ) {
+               $ok = $this->deleteMulti( [ $key ], $flags );
+
+               return $ok;
        }
 
        public function incr( $key, $step = 1 ) {
@@ -453,42 +500,45 @@ class SqlBagOStuff extends BagOStuff {
                                [ 'value', 'exptime' ],
                                [ 'keyname' => $key ],
                                __METHOD__,
-                               [ 'FOR UPDATE' ] );
+                               [ 'FOR UPDATE' ]
+                       );
                        if ( $row === false ) {
                                // Missing
-
-                               return null;
+                               return false;
                        }
                        $db->delete( $tableName, [ 'keyname' => $key ], __METHOD__ );
                        if ( $this->isExpired( $db, $row->exptime ) ) {
                                // Expired, do not reinsert
-
-                               return null;
+                               return false;
                        }
 
                        $oldValue = intval( $this->unserialize( $db->decodeBlob( $row->value ) ) );
                        $newValue = $oldValue + $step;
-                       $db->insert( $tableName,
+                       $db->insert(
+                               $tableName,
                                [
                                        'keyname' => $key,
                                        'value' => $db->encodeBlob( $this->serialize( $newValue ) ),
                                        'exptime' => $row->exptime
-                               ], __METHOD__, 'IGNORE' );
+                               ],
+                               __METHOD__,
+                               'IGNORE'
+                       );
 
                        if ( $db->affectedRows() == 0 ) {
                                // Race condition. See T30611
-                               $newValue = null;
+                               $newValue = false;
                        }
                } catch ( DBError $e ) {
                        $this->handleWriteError( $e, $db, $serverIndex );
-                       return null;
+                       return false;
                }
 
                return $newValue;
        }
 
        public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               $ok = $this->mergeViaCas( $key, $callback, $exptime, $attempts );
+               $ok = $this->mergeViaCas( $key, $callback, $exptime, $attempts, $flags );
                if ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) {
                        $ok = $this->waitForReplication() && $ok;
                }
@@ -496,20 +546,33 @@ class SqlBagOStuff extends BagOStuff {
                return $ok;
        }
 
-       public function changeTTL( $key, $expiry = 0 ) {
+       public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
                list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
                $db = null;
                $silenceScope = $this->silenceTransactionProfiler();
                try {
                        $db = $this->getDB( $serverIndex );
+                       if ( $exptime == 0 ) {
+                               $timestamp = $this->getMaxDateTime( $db );
+                       } else {
+                               $timestamp = $db->timestamp( $this->convertToExpiry( $exptime ) );
+                       }
                        $db->update(
                                $tableName,
-                               [ 'exptime' => $db->timestamp( $this->convertExpiry( $expiry ) ) ],
+                               [ 'exptime' => $timestamp ],
                                [ 'keyname' => $key, 'exptime > ' . $db->addQuotes( $db->timestamp( time() ) ) ],
                                __METHOD__
                        );
                        if ( $db->affectedRows() == 0 ) {
-                               return false;
+                               $exists = (bool)$db->selectField(
+                                       $tableName,
+                                       1,
+                                       [ 'keyname' => $key, 'exptime' => $timestamp ],
+                                       __METHOD__,
+                                       [ 'FOR UPDATE' ]
+                               );
+
+                               return $exists;
                        }
                } catch ( DBError $e ) {
                        $this->handleWriteError( $e, $db, $serverIndex );
@@ -711,14 +774,8 @@ class SqlBagOStuff extends BagOStuff {
                if ( $exception instanceof DBConnectionError ) {
                        $this->markServerDown( $exception, $serverIndex );
                }
-               $this->logger->error( "DBError: {$exception->getMessage()}" );
-               if ( $exception instanceof DBConnectionError ) {
-                       $this->setLastError( BagOStuff::ERR_UNREACHABLE );
-                       $this->logger->debug( __METHOD__ . ": ignoring connection error" );
-               } else {
-                       $this->setLastError( BagOStuff::ERR_UNEXPECTED );
-                       $this->logger->debug( __METHOD__ . ": ignoring query error" );
-               }
+
+               $this->setAndLogDBError( $exception );
        }
 
        /**
@@ -732,15 +789,15 @@ class SqlBagOStuff extends BagOStuff {
        protected function handleWriteError( DBError $exception, IDatabase $db = null, $serverIndex ) {
                if ( !$db ) {
                        $this->markServerDown( $exception, $serverIndex );
-               } elseif ( $db->wasReadOnlyError() ) {
-                       if ( $db->trxLevel() && $this->usesMainDB() ) {
-                               // Errors like deadlocks and connection drops already cause rollback.
-                               // For consistency, we have no choice but to throw an error and trigger
-                               // complete rollback if the main DB is also being used as the cache DB.
-                               throw $exception;
-                       }
                }
 
+               $this->setAndLogDBError( $exception );
+       }
+
+       /**
+        * @param DBError $exception
+        */
+       private function setAndLogDBError( DBError $exception ) {
                $this->logger->error( "DBError: {$exception->getMessage()}" );
                if ( $exception instanceof DBConnectionError ) {
                        $this->setLastError( BagOStuff::ERR_UNREACHABLE );
@@ -813,20 +870,26 @@ class SqlBagOStuff extends BagOStuff {
                }
 
                // Main LB is used; wait for any replica DBs to catch up
-               $masterPos = $lb->getMasterPos();
-               if ( !$masterPos ) {
-                       return true; // not applicable
-               }
+               try {
+                       $masterPos = $lb->getMasterPos();
+                       if ( !$masterPos ) {
+                               return true; // not applicable
+                       }
+
+                       $loop = new WaitConditionLoop(
+                               function () use ( $lb, $masterPos ) {
+                                       return $lb->waitForAll( $masterPos, 1 );
+                               },
+                               $this->syncTimeout,
+                               $this->busyCallbacks
+                       );
 
-               $loop = new WaitConditionLoop(
-                       function () use ( $lb, $masterPos ) {
-                               return $lb->waitForAll( $masterPos, 1 );
-                       },
-                       $this->syncTimeout,
-                       $this->busyCallbacks
-               );
+                       return ( $loop->invoke() === $loop::CONDITION_REACHED );
+               } catch ( DBError $e ) {
+                       $this->setAndLogDBError( $e );
 
-               return ( $loop->invoke() === $loop::CONDITION_REACHED );
+                       return false;
+               }
        }
 
        /**
index 983f069..124437e 100644 (file)
@@ -31,7 +31,6 @@ use MediaWiki\Revision\SlotRecord;
  *
  * @todo Move and rewrite code to an Action class
  *
- * See design.txt for an overview.
  * Note: edit user interface and cache support functions have been
  * moved to separate EditPage and HTMLFileCache classes.
  */
@@ -1132,13 +1131,11 @@ class Article implements Page {
         * [[MediaWiki:Talkpagetext]]. For Article::view().
         */
        public function showNamespaceHeader() {
-               if ( $this->getTitle()->isTalkPage() ) {
-                       if ( !wfMessage( 'talkpageheader' )->isDisabled() ) {
-                               $this->getContext()->getOutput()->wrapWikiMsg(
-                                       "<div class=\"mw-talkpageheader\">\n$1\n</div>",
-                                       [ 'talkpageheader' ]
-                               );
-                       }
+               if ( $this->getTitle()->isTalkPage() && !wfMessage( 'talkpageheader' )->isDisabled() ) {
+                       $this->getContext()->getOutput()->wrapWikiMsg(
+                               "<div class=\"mw-talkpageheader\">\n$1\n</div>",
+                               [ 'talkpageheader' ]
+                       );
                }
        }
 
@@ -2734,7 +2731,7 @@ class Article implements Page {
         * @see WikiPage::setTimestamp
         */
        public function setTimestamp( $ts ) {
-               return $this->mPage->setTimestamp( $ts );
+               $this->mPage->setTimestamp( $ts );
        }
 
        /**
@@ -2858,7 +2855,10 @@ class Article implements Page {
         * @return array
         */
        public function doRollback( $fromP, $summary, $token, $bot, &$resultDetails, User $user = null ) {
-               $user = is_null( $user ) ? $this->getContext()->getUser() : $user;
+               if ( !$user ) {
+                       $user = $this->getContext()->getUser();
+               }
+
                return $this->mPage->doRollback( $fromP, $summary, $token, $bot, $resultDetails, $user );
        }
 
@@ -2871,7 +2871,10 @@ class Article implements Page {
         * @return array
         */
        public function commitRollback( $fromP, $summary, $bot, &$resultDetails, User $guser = null ) {
-               $guser = is_null( $guser ) ? $this->getContext()->getUser() : $guser;
+               if ( !$guser ) {
+                       $guser = $this->getContext()->getUser();
+               }
+
                return $this->mPage->commitRollback( $fromP, $summary, $bot, $resultDetails, $guser );
        }
 
index 5313334..e488b6c 100644 (file)
@@ -194,16 +194,18 @@ class ImageHistoryList extends ContextSource {
                $row .= "<td $selected style='white-space: nowrap;'>";
                if ( !$file->userCan( File::DELETED_FILE, $user ) ) {
                        # Don't link to unviewable files
-                       $row .= '<span class="history-deleted">'
-                               . $lang->userTimeAndDate( $timestamp, $user ) . '</span>';
+                       $row .= Html::element( 'span', [ 'class' => 'history-deleted' ],
+                               $lang->userTimeAndDate( $timestamp, $user )
+                       );
                } elseif ( $file->isDeleted( File::DELETED_FILE ) ) {
+                       $timeAndDate = htmlspecialchars( $lang->userTimeAndDate( $timestamp, $user ) );
                        if ( $local ) {
                                $this->preventClickjacking();
                                $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
                                # Make a link to review the image
                                $url = Linker::linkKnown(
                                        $revdel,
-                                       $lang->userTimeAndDate( $timestamp, $user ),
+                                       $timeAndDate,
                                        [],
                                        [
                                                'target' => $this->title->getPrefixedText(),
@@ -212,12 +214,13 @@ class ImageHistoryList extends ContextSource {
                                        ]
                                );
                        } else {
-                               $url = $lang->userTimeAndDate( $timestamp, $user );
+                               $url = $timeAndDate;
                        }
                        $row .= '<span class="history-deleted">' . $url . '</span>';
                } elseif ( !$file->exists() ) {
-                       $row .= '<span class="mw-file-missing">'
-                               . $lang->userTimeAndDate( $timestamp, $user ) . '</span>';
+                       $row .= Html::element( 'span', [ 'class' => 'mw-file-missing' ],
+                               $lang->userTimeAndDate( $timestamp, $user )
+                       );
                } else {
                        $url = $iscur ? $this->current->getUrl() : $this->current->getArchiveUrl( $img );
                        $row .= Xml::element(
@@ -265,9 +268,12 @@ class ImageHistoryList extends ContextSource {
                        $row .= '<td><span class="history-deleted">' .
                                $this->msg( 'rev-deleted-comment' )->escaped() . '</span></td>';
                } else {
-                       $row .=
-                               '<td dir="' . MediaWikiServices::getInstance()->getContentLanguage()->getDir() .
-                               '">' . Linker::formatComment( $description, $this->title ) . '</td>';
+                       $contLang = MediaWikiServices::getInstance()->getContentLanguage();
+                       $row .= Html::rawElement(
+                               'td',
+                               [ 'dir' => $contLang->getDir() ],
+                               Linker::formatComment( $description, $this->title )
+                       );
                }
 
                $rowClass = null;
index 66804bc..86c59ad 100644 (file)
@@ -321,9 +321,7 @@ class ImagePage extends Article {
                $dirmark = $lang->getDirMarkEntity();
                $request = $this->getContext()->getRequest();
 
-               $max = $this->getImageLimitsFromOption( $user, 'imagesize' );
-               $maxWidth = $max[0];
-               $maxHeight = $max[1];
+               list( $maxWidth, $maxHeight ) = $this->getImageLimitsFromOption( $user, 'imagesize' );
 
                if ( $this->displayImg->exists() ) {
                        # image
@@ -963,7 +961,7 @@ EOT
                $out->addHTML( "<ul class='mw-imagepage-duplicates'>\n" );
 
                /**
-                * @var $file File
+                * @var File $file
                 */
                foreach ( $dupes as $file ) {
                        $fromSrc = '';
@@ -1029,7 +1027,7 @@ EOT
         *
         * @param User $user
         * @param string $optionName Name of a option to check, typically imagesize or thumbsize
-        * @return array
+        * @return int[]
         * @since 1.21
         */
        public function getImageLimitsFromOption( $user, $optionName ) {
@@ -1224,7 +1222,7 @@ EOT
         * @return TitleArray|Title[]
         */
        public function getForeignCategories() {
-               $this->mPage->getForeignCategories();
+               return $this->mPage->getForeignCategories();
        }
 
 }
index 4c2ebdc..c457a34 100644 (file)
@@ -235,7 +235,7 @@ class WikiFilePage extends WikiPage {
                        ],
                        __METHOD__,
                        [],
-                       [ 'categorylinks' => [ 'INNER JOIN', 'page_id = cl_from' ] ]
+                       [ 'categorylinks' => [ 'JOIN', 'page_id = cl_from' ] ]
                );
 
                return TitleArray::newFromResult( $res );
index df9259b..931740c 100644 (file)
@@ -50,13 +50,23 @@ class WikiPage implements Page, IDBAccessObject {
         */
        public $mTitle = null;
 
-       /**@{{
+       /**
+        * @var bool
+        * @protected
+        */
+       public $mDataLoaded = false;
+
+       /**
+        * @var bool
         * @protected
         */
-       public $mDataLoaded = false;         // !< Boolean
-       public $mIsRedirect = false;         // !< Boolean
-       public $mLatest = false;             // !< Integer (false means "not loaded")
-       /**@}}*/
+       public $mIsRedirect = false;
+
+       /**
+        * @var int|false False means "not loaded"
+        * @protected
+        */
+       public $mLatest = false;
 
        /** @var PreparedEdit Map of cache fields (text, parser output, ect) for a proposed/new edit */
        public $mPreparedEdit = false;
@@ -637,7 +647,7 @@ class WikiPage implements Page, IDBAccessObject {
         */
        public function getContentModel() {
                if ( $this->exists() ) {
-                       $cache = ObjectCache::getMainWANInstance();
+                       $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
 
                        return $cache->getWithSetCallback(
                                $cache->makeKey( 'page-content-model', $this->getLatest() ),
@@ -2626,7 +2636,9 @@ class WikiPage implements Page, IDBAccessObject {
                // Avoid PHP 7.1 warning of passing $this by reference
                $wikiPage = $this;
 
-               $deleter = is_null( $deleter ) ? $wgUser : $deleter;
+               if ( !$deleter ) {
+                       $deleter = $wgUser;
+               }
                if ( !Hooks::run( 'ArticleDelete',
                        [ &$wikiPage, &$deleter, &$reason, &$error, &$status, $suppress ]
                ) ) {
@@ -2724,6 +2736,8 @@ class WikiPage implements Page, IDBAccessObject {
                        $dbw->endAtomic( __METHOD__ );
 
                        $jobParams = [
+                               'namespace' => $this->getTitle()->getNamespace(),
+                               'title' => $this->getTitle()->getDBkey(),
                                'wikiPageId' => $id,
                                'requestId' => $webRequestId ?? WebRequest::getRequestId(),
                                'reason' => $reason,
@@ -2733,7 +2747,7 @@ class WikiPage implements Page, IDBAccessObject {
                                'logsubtype' => $logsubtype,
                        ];
 
-                       $job = new DeletePageJob( $this->getTitle(), $jobParams );
+                       $job = new DeletePageJob( $jobParams );
                        JobQueueGroup::singleton()->push( $job );
 
                        $status->warning( 'delete-scheduled',
@@ -2985,7 +2999,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @param Content|null $content Page content to be used when determining
         *   the required updates. This may be needed because $this->getContent()
         *   may already return null when the page proper was deleted.
-        * @param RevisionRecord|Revision|null $revision The current page revision at the time of
+        * @param Revision|null $revision The current page revision at the time of
         *   deletion, used when determining the required updates. This may be needed because
         *   $this->getRevision() may already return null when the page proper was deleted.
         * @param User|null $user The user that caused the deletion
@@ -3590,7 +3604,8 @@ class WikiPage implements Page, IDBAccessObject {
         */
        public function updateCategoryCounts( array $added, array $deleted, $id = 0 ) {
                $id = $id ?: $this->getId();
-               $type = MWNamespace::getCategoryLinkType( $this->getTitle()->getNamespace() );
+               $type = MediaWikiServices::getInstance()->getNamespaceInfo()->
+                       getCategoryLinkType( $this->getTitle()->getNamespace() );
 
                $addFields = [ 'cat_pages = cat_pages + 1' ];
                $removeFields = [ 'cat_pages = cat_pages - 1' ];
index e9cadf3..64dbb22 100644 (file)
@@ -67,58 +67,84 @@ use Wikimedia\Rdbms\IDatabase;
  * @ingroup Pager
  */
 abstract class IndexPager extends ContextSource implements Pager {
-       /**
-        * Constants for the $mDefaultDirection field.
-        *
-        * These are boolean for historical reasons and should stay boolean for backwards-compatibility.
-        */
+       /** Backwards-compatible constant for $mDefaultDirection field (do not change) */
        const DIR_ASCENDING = false;
+       /** Backwards-compatible constant for $mDefaultDirection field (do not change) */
        const DIR_DESCENDING = true;
 
+       /** Backwards-compatible constant for reallyDoQuery() (do not change) */
+       const QUERY_ASCENDING = true;
+       /** Backwards-compatible constant for reallyDoQuery() (do not change) */
+       const QUERY_DESCENDING = false;
+
+       /** @var WebRequest */
        public $mRequest;
+       /** @var int[] List of default entry limit options to be presented to clients */
        public $mLimitsShown = [ 20, 50, 100, 250, 500 ];
+       /** @var int The default entry limit choosen for clients */
        public $mDefaultLimit = 50;
-       public $mOffset, $mLimit;
+       /** @var mixed The starting point to enumerate entries */
+       public $mOffset;
+       /** @var int The maximum number of entries to show */
+       public $mLimit;
+       /** @var bool Whether the listing query completed */
        public $mQueryDone = false;
        /** @var IDatabase */
        public $mDb;
+       /** @var stdClass|bool|null Extra row fetched at the end to see if the end was reached */
        public $mPastTheEndRow;
 
        /**
         * The index to actually be used for ordering. This is a single column,
         * for one ordering, even if multiple orderings are supported.
+        * @var string
         */
        protected $mIndexField;
        /**
         * An array of secondary columns to order by. These fields are not part of the offset.
         * This is a column list for one ordering, even if multiple orderings are supported.
+        * @var string[]
         */
        protected $mExtraSortFields;
        /** For pages that support multiple types of ordering, which one to use.
+        * @var string|null
         */
        protected $mOrderType;
        /**
         * $mDefaultDirection gives the direction to use when sorting results:
-        * DIR_ASCENDING or DIR_DESCENDING.  If $mIsBackwards is set, we
-        * start from the opposite end, but we still sort the page itself according
-        * to $mDefaultDirection.  E.g., if $mDefaultDirection is false but we're
-        * going backwards, we'll display the last page of results, but the last
-        * result will be at the bottom, not the top.
+        * DIR_ASCENDING or DIR_DESCENDING. If $mIsBackwards is set, we start from
+        * the opposite end, but we still sort the page itself according to
+        * $mDefaultDirection. For example, if $mDefaultDirection is DIR_ASCENDING
+        * but we're going backwards, we'll display the last page of results, but
+        * the last result will be at the bottom, not the top.
         *
         * Like $mIndexField, $mDefaultDirection will be a single value even if the
         * class supports multiple default directions for different order types.
+        * @var bool
         */
        public $mDefaultDirection;
+       /** @var bool */
        public $mIsBackwards;
 
-       /** True if the current result set is the first one */
+       /** @var bool True if the current result set is the first one */
        public $mIsFirst;
+       /** @var bool */
        public $mIsLast;
 
-       protected $mLastShown, $mFirstShown, $mPastTheEndIndex, $mDefaultQuery, $mNavigationBar;
+       /** @var mixed */
+       protected $mLastShown;
+       /** @var mixed */
+       protected $mFirstShown;
+       /** @var mixed */
+       protected $mPastTheEndIndex;
+       /** @var array */
+       protected $mDefaultQuery;
+       /** @var string */
+       protected $mNavigationBar;
 
        /**
         * Whether to include the offset in the query
+        * @var bool
         */
        protected $mIncludeOffset = false;
 
@@ -200,10 +226,14 @@ abstract class IndexPager extends ContextSource implements Pager {
        public function doQuery() {
                # Use the child class name for profiling
                $fname = __METHOD__ . ' (' . static::class . ')';
+               /** @noinspection PhpUnusedLocalVariableInspection */
                $section = Profiler::instance()->scopedProfileIn( $fname );
 
-               // @todo This should probably compare to DIR_DESCENDING and DIR_ASCENDING constants
-               $descending = ( $this->mIsBackwards == $this->mDefaultDirection );
+               $defaultOrder = ( $this->mDefaultDirection === self::DIR_ASCENDING )
+                       ? self::QUERY_ASCENDING
+                       : self::QUERY_DESCENDING;
+               $order = $this->mIsBackwards ? self::oppositeOrder( $defaultOrder ) : $defaultOrder;
+
                # Plus an extra row so that we can tell the "next" link should be shown
                $queryLimit = $this->mLimit + 1;
 
@@ -215,14 +245,15 @@ abstract class IndexPager extends ContextSource implements Pager {
                        // direction see if we get a row.
                        $oldIncludeOffset = $this->mIncludeOffset;
                        $this->mIncludeOffset = !$this->mIncludeOffset;
-                       $isFirst = !$this->reallyDoQuery( $this->mOffset, 1, !$descending )->numRows();
+                       $oppositeOrder = self::oppositeOrder( $order );
+                       $isFirst = !$this->reallyDoQuery( $this->mOffset, 1, $oppositeOrder )->numRows();
                        $this->mIncludeOffset = $oldIncludeOffset;
                }
 
                $this->mResult = $this->reallyDoQuery(
                        $this->mOffset,
                        $queryLimit,
-                       $descending
+                       $order
                );
 
                $this->extractResultInfo( $isFirst, $queryLimit, $this->mResult );
@@ -232,6 +263,16 @@ abstract class IndexPager extends ContextSource implements Pager {
                $this->mResult->rewind(); // Paranoia
        }
 
+       /**
+        * @param bool $order One of the IndexPager::QUERY_* class constants
+        * @return bool The opposite query order as an IndexPager::QUERY_ constant
+        */
+       final protected static function oppositeOrder( $order ) {
+               return ( $order === self::QUERY_ASCENDING )
+                       ? self::QUERY_DESCENDING
+                       : self::QUERY_ASCENDING;
+       }
+
        /**
         * @return IResultWrapper The result wrapper.
         */
@@ -354,17 +395,18 @@ abstract class IndexPager extends ContextSource implements Pager {
        }
 
        /**
-        * Do a query with specified parameters, rather than using the object
-        * context
+        * Do a query with specified parameters, rather than using the object context
+        *
+        * @note For b/c, query direction is true for ascending and false for descending
         *
         * @param string $offset Index offset, inclusive
         * @param int $limit Exact query limit
-        * @param bool $descending Query direction, false for ascending, true for descending
+        * @param bool $order IndexPager::QUERY_ASCENDING or IndexPager::QUERY_DESCENDING
         * @return IResultWrapper
         */
-       public function reallyDoQuery( $offset, $limit, $descending ) {
+       public function reallyDoQuery( $offset, $limit, $order ) {
                list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
-                       $this->buildQueryInfo( $offset, $limit, $descending );
+                       $this->buildQueryInfo( $offset, $limit, $order );
 
                return $this->mDb->select( $tables, $fields, $conds, $fname, $options, $join_conds );
        }
@@ -372,12 +414,14 @@ abstract class IndexPager extends ContextSource implements Pager {
        /**
         * Build variables to use by the database wrapper.
         *
+        * @note For b/c, query direction is true for ascending and false for descending
+        *
         * @param string $offset Index offset, inclusive
         * @param int $limit Exact query limit
-        * @param bool $descending Query direction, false for ascending, true for descending
+        * @param bool $order IndexPager::QUERY_ASCENDING or IndexPager::QUERY_DESCENDING
         * @return array
         */
-       protected function buildQueryInfo( $offset, $limit, $descending ) {
+       protected function buildQueryInfo( $offset, $limit, $order ) {
                $fname = __METHOD__ . ' (' . $this->getSqlComment() . ')';
                $info = $this->getQueryInfo();
                $tables = $info['tables'];
@@ -386,7 +430,7 @@ abstract class IndexPager extends ContextSource implements Pager {
                $options = $info['options'] ?? [];
                $join_conds = $info['join_conds'] ?? [];
                $sortColumns = array_merge( [ $this->mIndexField ], $this->mExtraSortFields );
-               if ( $descending ) {
+               if ( $order === self::QUERY_ASCENDING ) {
                        $options['ORDER BY'] = $sortColumns;
                        $operator = $this->mIncludeOffset ? '>=' : '>';
                } else {
index bf36983..5caf1f4 100644 (file)
@@ -26,6 +26,7 @@ use Wikimedia\Timestamp\TimestampException;
  */
 abstract class RangeChronologicalPager extends ReverseChronologicalPager {
 
+       /** @var string[] */
        protected $rangeConds = [];
 
        /**
@@ -93,14 +94,14 @@ abstract class RangeChronologicalPager extends ReverseChronologicalPager {
         *
         * @param string $offset Index offset, inclusive
         * @param int $limit Exact query limit
-        * @param bool $descending Query direction, false for ascending, true for descending
+        * @param bool $order IndexPager::QUERY_ASCENDING or IndexPager::QUERY_DESCENDING
         * @return array
         */
-       protected function buildQueryInfo( $offset, $limit, $descending ) {
+       protected function buildQueryInfo( $offset, $limit, $order ) {
                list( $tables, $fields, $conds, $fname, $options, $join_conds ) = parent::buildQueryInfo(
                        $offset,
                        $limit,
-                       $descending
+                       $order
                );
 
                if ( $this->rangeConds ) {
index 51824d2..e8f3f40 100644 (file)
@@ -26,9 +26,13 @@ use Wikimedia\Timestamp\TimestampException;
  * @ingroup Pager
  */
 abstract class ReverseChronologicalPager extends IndexPager {
+       /** @var bool */
        public $mDefaultDirection = IndexPager::DIR_DESCENDING;
+       /** @var int */
        public $mYear;
+       /** @var int */
        public $mMonth;
+       /** @var int */
        public $mDay;
 
        public function getNavigationBar() {
index 8934fc2..d94104b 100644 (file)
  * @ingroup Pager
  */
 abstract class TablePager extends IndexPager {
+       /** @var string */
        protected $mSort;
 
+       /** @var stdClass */
        protected $mCurrentRow;
 
        public function __construct( IContextSource $context = null ) {
@@ -130,12 +132,12 @@ abstract class TablePager extends IndexPager {
                                        // We don't actually know in which direction other fields will be sorted by default…
                                        if ( $this->mDefaultDirection == IndexPager::DIR_DESCENDING ) {
                                                $linkType = 'asc';
-                                               $class = "$sortClass TablePager_sort-descending";
+                                               $class = "$sortClass mw-datatable-is-sorted mw-datatable-is-descending";
                                                $query['asc'] = '1';
                                                $query['desc'] = '';
                                        } else {
                                                $linkType = 'desc';
-                                               $class = "$sortClass TablePager_sort-ascending";
+                                               $class = "$sortClass mw-datatable-is-sorted mw-datatable-is-ascending";
                                                $query['asc'] = '';
                                                $query['desc'] = '1';
                                        }
@@ -150,7 +152,7 @@ abstract class TablePager extends IndexPager {
 
                $tableClass = $this->getTableClass();
                $ret = Html::openElement( 'table', [
-                       'class' => "mw-datatable $tableClass" ]
+                       'class' => " $tableClass" ]
                );
                $ret .= Html::rawElement( 'thead', [], Html::rawElement( 'tr', [], "\n" . $s . "\n" ) );
                $ret .= Html::openElement( 'tbody' ) . "\n";
@@ -264,10 +266,11 @@ abstract class TablePager extends IndexPager {
        }
 
        /**
+        * TablePager relies on `mw-datatable` for styling, see T214208
         * @return string
         */
        protected function getTableClass() {
-               return 'TablePager';
+               return 'mw-datatable';
        }
 
        /**
index a69b3d2..50c7e23 100644 (file)
@@ -25,7 +25,7 @@
 class BlockLevelPass {
        private $DTopen = false;
        private $inPre = false;
-       private $lastSection = '';
+       private $lastParagraph = '';
        private $lineStart;
        private $text;
 
@@ -61,18 +61,29 @@ class BlockLevelPass {
                $this->lineStart = $lineStart;
        }
 
+       /**
+        * @return bool
+        */
+       private function hasOpenParagraph() {
+               return $this->lastParagraph !== '';
+       }
+
        /**
         * If a pre or p is open, return the corresponding close tag and update
         * the state. If no tag is open, return an empty string.
+        * @param bool $atTheEnd Omit trailing newline if we've reached the end.
         * @return string
         */
-       private function closeParagraph() {
+       private function closeParagraph( $atTheEnd = false ) {
                $result = '';
-               if ( $this->lastSection !== '' ) {
-                       $result = '</' . $this->lastSection . ">\n";
+               if ( $this->hasOpenParagraph() ) {
+                       $result = '</' . $this->lastParagraph . '>';
+                       if ( !$atTheEnd ) {
+                               $result .= "\n";
+                       }
                }
                $this->inPre = false;
-               $this->lastSection = '';
+               $this->lastParagraph = '';
                return $result;
        }
 
@@ -188,7 +199,11 @@ class BlockLevelPass {
                $pendingPTag = false;
                $inBlockquote = false;
 
-               foreach ( $textLines as $inputLine ) {
+               for ( $textLines->rewind(); $textLines->valid(); ) {
+                       $inputLine = $textLines->current();
+                       $textLines->next();
+                       $notLastLine = $textLines->valid();
+
                        # Fix up $lineStart
                        if ( !$this->lineStart ) {
                                $output .= $inputLine;
@@ -341,14 +356,14 @@ class BlockLevelPass {
                                        $inBlockElem = !$closeMatch;
                                } elseif ( !$inBlockElem && !$this->inPre ) {
                                        if ( substr( $t, 0, 1 ) == ' '
-                                               && ( $this->lastSection === 'pre' || trim( $t ) != '' )
+                                               && ( $this->lastParagraph === 'pre' || trim( $t ) != '' )
                                                && !$inBlockquote
                                        ) {
                                                # pre
-                                               if ( $this->lastSection !== 'pre' ) {
+                                               if ( $this->lastParagraph !== 'pre' ) {
                                                        $pendingPTag = false;
                                                        $output .= $this->closeParagraph() . '<pre>';
-                                                       $this->lastSection = 'pre';
+                                                       $this->lastParagraph = 'pre';
                                                }
                                                $t = substr( $t, 1 );
                                        } elseif ( preg_match( '/^(?:<style\\b[^>]*>.*?<\\/style>\s*|<link\\b[^>]*>\s*)+$/iS', $t ) ) {
@@ -357,7 +372,6 @@ class BlockLevelPass {
                                                if ( $pendingPTag ) {
                                                        $output .= $this->closeParagraph();
                                                        $pendingPTag = false;
-                                                       $this->lastSection = '';
                                                }
                                        } else {
                                                # paragraph
@@ -365,25 +379,20 @@ class BlockLevelPass {
                                                        if ( $pendingPTag ) {
                                                                $output .= $pendingPTag . '<br />';
                                                                $pendingPTag = false;
-                                                               $this->lastSection = 'p';
+                                                               $this->lastParagraph = 'p';
+                                                       } elseif ( $this->lastParagraph !== 'p' ) {
+                                                               $output .= $this->closeParagraph();
+                                                               $pendingPTag = '<p>';
                                                        } else {
-                                                               if ( $this->lastSection !== 'p' ) {
-                                                                       $output .= $this->closeParagraph();
-                                                                       $this->lastSection = '';
-                                                                       $pendingPTag = '<p>';
-                                                               } else {
-                                                                       $pendingPTag = '</p><p>';
-                                                               }
-                                                       }
-                                               } else {
-                                                       if ( $pendingPTag ) {
-                                                               $output .= $pendingPTag;
-                                                               $pendingPTag = false;
-                                                               $this->lastSection = 'p';
-                                                       } elseif ( $this->lastSection !== 'p' ) {
-                                                               $output .= $this->closeParagraph() . '<p>';
-                                                               $this->lastSection = 'p';
+                                                               $pendingPTag = '</p><p>';
                                                        }
+                                               } elseif ( $pendingPTag ) {
+                                                       $output .= $pendingPTag;
+                                                       $pendingPTag = false;
+                                                       $this->lastParagraph = 'p';
+                                               } elseif ( $this->lastParagraph !== 'p' ) {
+                                                       $output .= $this->closeParagraph() . '<p>';
+                                                       $this->lastParagraph = 'p';
                                                }
                                        }
                                }
@@ -395,7 +404,11 @@ class BlockLevelPass {
                        if ( $pendingPTag === false ) {
                                if ( $prefixLength === 0 ) {
                                        $output .= $t;
-                                       $output .= "\n";
+                                       // Add a newline if there's an open paragraph
+                                       // or we've yet to reach the last line.
+                                       if ( $notLastLine || $this->hasOpenParagraph() ) {
+                                               $output .= "\n";
+                                       }
                                } else {
                                        // Trim whitespace in list items
                                        $output .= trim( $t );
@@ -405,15 +418,13 @@ class BlockLevelPass {
                while ( $prefixLength ) {
                        $output .= $this->closeList( $prefix2[$prefixLength - 1] );
                        --$prefixLength;
-                       if ( !$prefixLength ) {
+                       // Note that a paragraph is only ever opened when `prefixLength`
+                       // is zero, but we'll choose to be overly cautious.
+                       if ( !$prefixLength && $this->hasOpenParagraph() ) {
                                $output .= "\n";
                        }
                }
-               if ( $this->lastSection !== '' ) {
-                       $output .= '</' . $this->lastSection . '>';
-                       $this->lastSection = '';
-               }
-
+               $output .= $this->closeParagraph( true );
                return $output;
        }
 
index 8ab5c31..7ce96be 100644 (file)
@@ -90,13 +90,13 @@ class CoreParserFunctions {
 
        /**
         * @param Parser $parser
-        * @param string $part1
+        * @param string $part1 Message key
+        * @param mixed ...$params To pass to wfMessage()
         * @return array
         */
-       public static function intFunction( $parser, $part1 = '' /*, ... */ ) {
+       public static function intFunction( $parser, $part1 = '', ...$params ) {
                if ( strval( $part1 ) !== '' ) {
-                       $args = array_slice( func_get_args(), 2 );
-                       $message = wfMessage( $part1, $args )
+                       $message = wfMessage( $part1, $params )
                                ->inLanguage( $parser->getOptions()->getUserLangObj() );
                        return [ $message->plain(), 'noparse' => false ];
                } else {
@@ -113,7 +113,7 @@ class CoreParserFunctions {
         */
        public static function formatDate( $parser, $date, $defaultPref = null ) {
                $lang = $parser->getFunctionLang();
-               $df = DateFormatter::getInstance( $lang );
+               $df = MediaWikiServices::getInstance()->getDateFormatterFactory()->get( $lang );
 
                $date = trim( $date );
 
@@ -313,11 +313,10 @@ class CoreParserFunctions {
        /**
         * @param Parser $parser
         * @param string $username
+        * @param string ...$forms What to output for each gender
         * @return string
         */
-       public static function gender( $parser, $username ) {
-               $forms = array_slice( func_get_args(), 2 );
-
+       public static function gender( $parser, $username, ...$forms ) {
                // Some shortcuts to avoid loading user data unnecessarily
                if ( count( $forms ) === 0 ) {
                        return '';
@@ -327,7 +326,6 @@ class CoreParserFunctions {
 
                $username = trim( $username );
 
-               // default
                $gender = User::getDefaultOption( 'gender' );
 
                // allow prefix and normalize (e.g. "&#42;foo" -> "*foo" ).
@@ -352,10 +350,10 @@ class CoreParserFunctions {
        /**
         * @param Parser $parser
         * @param string $text
+        * @param string ...$forms What to output for each number (singular, dual, plural, etc.)
         * @return string
         */
-       public static function plural( $parser, $text = '' ) {
-               $forms = array_slice( func_get_args(), 2 );
+       public static function plural( $parser, $text = '', ...$forms ) {
                $text = $parser->getFunctionLang()->parseFormattedNumber( $text );
                settype( $text, ctype_digit( $text ) ? 'int' : 'float' );
                return $parser->getFunctionLang()->convertPlural( $text, $forms );
index fb79442..b0c41d9 100644 (file)
 use MediaWiki\MediaWikiServices;
 
 /**
- * Date formatter, recognises dates in plain text and formats them according to user preferences.
- * @todo preferences, OutputPage
+ * Date formatter. Recognises dates and formats them according to a specified preference.
+ *
+ * This class was originally introduced to detect and transform dates in free text. It is now
+ * only used by the {{#dateformat}} parser function. This is a very rudimentary date formatter;
+ * Language::sprintfDate() has many more features and is the correct choice for most new code.
+ * The main advantage of this date formatter is that it is able to format incomplete dates with an
+ * unspecified year.
+ *
  * @ingroup Parser
  */
 class DateFormatter {
-       private $mSource, $mTarget;
-       private $monthNames = '';
-
+       /** @var string[] Date format regexes indexed the class constants */
        private $regexes;
-       private $rules, $xMonths, $preferences;
 
-       private $lang, $mLinked;
+       /**
+        * @var int[][] Array of special rules. The first key is the preference ID
+        * (one of the class constants), the second key is the detected source
+        * format, and the value is the ID of the target format that will be used
+        * in that case.
+        */
+       private $rules = [];
 
-       /** @var string[] */
-       private $keys;
+       /**
+        * @var int[] Month numbers by lowercase name
+        */
+       private $xMonths = [];
 
-       /** @var string[] */
-       private $targets;
+       /**
+        * @var string[] Month names by number
+        */
+       private $monthNames = [];
 
+       /**
+        * @var int[] A map of descriptive preference text to internal format ID
+        */
+       private $preferenceIDs;
+
+       /** @var string[] Format strings similar to those used by date(), indexed by ID */
+       private $targetFormats;
+
+       /** Used as a preference ID for rules that apply regardless of preference */
        const ALL = -1;
+
+       /** No preference: the date may be left in the same format as the input */
        const NONE = 0;
+
+       /** e.g. January 15, 2001 */
        const MDY = 1;
+
+       /** e.g. 15 January 2001 */
        const DMY = 2;
+
+       /** e.g. 2001 January 15 */
        const YMD = 3;
-       const ISO1 = 4;
+
+       /** e.g. 2001-01-15 */
+       const ISO = 4;
+
+       /** The highest ID that is a valid user preference */
        const LASTPREF = 4;
-       const ISO2 = 5;
-       const YDM = 6;
-       const DM = 7;
-       const MD = 8;
-       const LAST = 8;
+
+       /** e.g. 2001, 15 January */
+       const YDM = 5;
+
+       /** e.g. 15 January */
+       const DM = 6;
+
+       /** e.g. January 15 */
+       const MD = 7;
+
+       /** The highest ID that is a valid target format */
+       const LAST = 7;
 
        /**
         * @param Language $lang In which language to format the date
         */
        public function __construct( Language $lang ) {
-               $this->lang = $lang;
-
-               $this->monthNames = $this->getMonthRegex();
+               $monthRegexParts = [];
                for ( $i = 1; $i <= 12; $i++ ) {
-                       $this->xMonths[$this->lang->lc( $this->lang->getMonthName( $i ) )] = $i;
-                       $this->xMonths[$this->lang->lc( $this->lang->getMonthAbbreviation( $i ) )] = $i;
+                       $monthName = $lang->getMonthName( $i );
+                       $monthAbbrev = $lang->getMonthAbbreviation( $i );
+                       $this->monthNames[$i] = $monthName;
+                       $monthRegexParts[] = preg_quote( $monthName, '/' );
+                       $monthRegexParts[] = preg_quote( $monthAbbrev, '/' );
+                       $this->xMonths[mb_strtolower( $monthName )] = $i;
+                       $this->xMonths[mb_strtolower( $monthAbbrev )] = $i;
                }
 
-               $this->regexTrail = '(?![a-z])/iu';
-
-               # Partial regular expressions
-               $this->prxDM = '\[\[(\d{1,2})[ _](' . $this->monthNames . ')\]\]';
-               $this->prxMD = '\[\[(' . $this->monthNames . ')[ _](\d{1,2})\]\]';
-               $this->prxY = '\[\[(\d{1,4}([ _]BC|))\]\]';
-               $this->prxISO1 = '\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})\]\]';
-               $this->prxISO2 = '\[\[(-?\d{4})-(\d{2})-(\d{2})\]\]';
-
-               # Real regular expressions
-               $this->regexes[self::DMY] = "/{$this->prxDM}(?: *, *| +){$this->prxY}{$this->regexTrail}";
-               $this->regexes[self::YDM] = "/{$this->prxY}(?: *, *| +){$this->prxDM}{$this->regexTrail}";
-               $this->regexes[self::MDY] = "/{$this->prxMD}(?: *, *| +){$this->prxY}{$this->regexTrail}";
-               $this->regexes[self::YMD] = "/{$this->prxY}(?: *, *| +){$this->prxMD}{$this->regexTrail}";
-               $this->regexes[self::DM] = "/{$this->prxDM}{$this->regexTrail}";
-               $this->regexes[self::MD] = "/{$this->prxMD}{$this->regexTrail}";
-               $this->regexes[self::ISO1] = "/{$this->prxISO1}{$this->regexTrail}";
-               $this->regexes[self::ISO2] = "/{$this->prxISO2}{$this->regexTrail}";
-
-               # Extraction keys
-               # See the comments in replace() for the meaning of the letters
-               $this->keys[self::DMY] = 'jFY';
-               $this->keys[self::YDM] = 'Y jF';
-               $this->keys[self::MDY] = 'FjY';
-               $this->keys[self::YMD] = 'Y Fj';
-               $this->keys[self::DM] = 'jF';
-               $this->keys[self::MD] = 'Fj';
-               $this->keys[self::ISO1] = 'ymd'; # y means ISO year
-               $this->keys[self::ISO2] = 'ymd';
-
-               # Target date formats
-               $this->targets[self::DMY] = '[[F j|j F]] [[Y]]';
-               $this->targets[self::YDM] = '[[Y]], [[F j|j F]]';
-               $this->targets[self::MDY] = '[[F j]], [[Y]]';
-               $this->targets[self::YMD] = '[[Y]] [[F j]]';
-               $this->targets[self::DM] = '[[F j|j F]]';
-               $this->targets[self::MD] = '[[F j]]';
-               $this->targets[self::ISO1] = '[[Y|y]]-[[F j|m-d]]';
-               $this->targets[self::ISO2] = '[[y-m-d]]';
-
-               # Rules
-               #            pref       source      target
+               // Partial regular expressions
+               $monthNames = implode( '|', $monthRegexParts );
+               $dm = "(?<day>\d{1,2})[ _](?<monthName>{$monthNames})";
+               $md = "(?<monthName>{$monthNames})[ _](?<day>\d{1,2})";
+               $y = '(?<year>\d{1,4}([ _]BC|))';
+               $iso = '(?<isoYear>-?\d{4})-(?<isoMonth>\d{2})-(?<isoDay>\d{2})';
+
+               $this->regexes = [
+                       self::DMY => "/^{$dm}(?: *, *| +){$y}$/iu",
+                       self::YDM => "/^{$y}(?: *, *| +){$dm}$/iu",
+                       self::MDY => "/^{$md}(?: *, *| +){$y}$/iu",
+                       self::YMD => "/^{$y}(?: *, *| +){$md}$/iu",
+                       self::DM => "/^{$dm}$/iu",
+                       self::MD => "/^{$md}$/iu",
+                       self::ISO => "/^{$iso}$/iu",
+               ];
+
+               // Target date formats
+               $this->targetFormats = [
+                       self::DMY => 'j F Y',
+                       self::YDM => 'Y, j F',
+                       self::MDY => 'F j, Y',
+                       self::YMD => 'Y F j',
+                       self::DM => 'j F',
+                       self::MD => 'F j',
+                       self::ISO => 'y-m-d',
+               ];
+
+               // Rules
+               //           pref       source      target
                $this->rules[self::DMY][self::MD] = self::DM;
                $this->rules[self::ALL][self::MD] = self::MD;
                $this->rules[self::MDY][self::DM] = self::MD;
                $this->rules[self::ALL][self::DM] = self::DM;
-               $this->rules[self::NONE][self::ISO2] = self::ISO1;
+               $this->rules[self::NONE][self::ISO] = self::ISO;
 
-               $this->preferences = [
+               $this->preferenceIDs = [
                        'default' => self::NONE,
                        'dmy' => self::DMY,
                        'mdy' => self::MDY,
                        'ymd' => self::YMD,
-                       'ISO 8601' => self::ISO1,
+                       'ISO 8601' => self::ISO,
                ];
        }
 
        /**
         * Get a DateFormatter object
         *
+        * @deprecated since 1.33 use MediaWikiServices::getDateFormatterFactory()
+        *
         * @param Language|null $lang In which language to format the date
         *     Defaults to the site content language
         * @return DateFormatter
         */
        public static function getInstance( Language $lang = null ) {
-               global $wgMainCacheType;
-
                $lang = $lang ?? MediaWikiServices::getInstance()->getContentLanguage();
-               $cache = ObjectCache::getLocalServerInstance( $wgMainCacheType );
-
-               static $dateFormatter = false;
-               if ( !$dateFormatter ) {
-                       $dateFormatter = $cache->getWithSetCallback(
-                               $cache->makeKey( 'dateformatter', $lang->getCode() ),
-                               $cache::TTL_HOUR,
-                               function () use ( $lang ) {
-                                       return new DateFormatter( $lang );
-                               }
-                       );
-               }
-
-               return $dateFormatter;
+               return MediaWikiServices::getInstance()->getDateFormatterFactory()->get( $lang );
        }
 
        /**
-        * @param string $preference User preference
+        * @param string $preference User preference, must be one of "default",
+        *   "dmy", "mdy", "ymd" or "ISO 8601".
         * @param string $text Text to reformat
-        * @param array $options Array can contain 'linked' and/or 'match-whole'
+        * @param array $options Ignored. Since 1.33, 'match-whole' is implied, and
+        *  'linked' has been removed.
         *
         * @return string
         */
-       public function reformat( $preference, $text, $options = [ 'linked' ] ) {
-               $linked = in_array( 'linked', $options );
-               $match_whole = in_array( 'match-whole', $options );
-
-               if ( isset( $this->preferences[$preference] ) ) {
-                       $preference = $this->preferences[$preference];
+       public function reformat( $preference, $text, $options = [] ) {
+               if ( isset( $this->preferenceIDs[$preference] ) ) {
+                       $preference = $this->preferenceIDs[$preference];
                } else {
                        $preference = self::NONE;
                }
-               for ( $i = 1; $i <= self::LAST; $i++ ) {
-                       $this->mSource = $i;
-                       if ( isset( $this->rules[$preference][$i] ) ) {
+               for ( $source = 1; $source <= self::LAST; $source++ ) {
+                       if ( isset( $this->rules[$preference][$source] ) ) {
                                # Specific rules
-                               $this->mTarget = $this->rules[$preference][$i];
-                       } elseif ( isset( $this->rules[self::ALL][$i] ) ) {
+                               $target = $this->rules[$preference][$source];
+                       } elseif ( isset( $this->rules[self::ALL][$source] ) ) {
                                # General rules
-                               $this->mTarget = $this->rules[self::ALL][$i];
+                               $target = $this->rules[self::ALL][$source];
                        } elseif ( $preference ) {
                                # User preference
-                               $this->mTarget = $preference;
+                               $target = $preference;
                        } else {
                                # Default
-                               $this->mTarget = $i;
-                       }
-                       $regex = $this->regexes[$i];
-
-                       // Horrible hack
-                       if ( !$linked ) {
-                               $regex = str_replace( [ '\[\[', '\]\]' ], '', $regex );
-                       }
-
-                       if ( $match_whole ) {
-                               // Let's hope this works
-                               $regex = preg_replace( '!^/!', '/^', $regex );
-                               $regex = str_replace( $this->regexTrail,
-                                       '$' . $this->regexTrail, $regex );
-                       }
-
-                       // Another horrible hack
-                       $this->mLinked = $linked;
-                       $text = preg_replace_callback( $regex, [ $this, 'replace' ], $text );
-                       unset( $this->mLinked );
-               }
-               return $text;
-       }
-
-       /**
-        * Regexp replacement callback
-        *
-        * @param array $matches
-        * @return string
-        */
-       private function replace( $matches ) {
-               # Extract information from $matches
-               $linked = $this->mLinked ?? true;
-
-               $bits = [];
-               $key = $this->keys[$this->mSource];
-               $keyLength = strlen( $key );
-               for ( $p = 0; $p < $keyLength; $p++ ) {
-                       if ( $key[$p] != ' ' ) {
-                               $bits[$key[$p]] = $matches[$p + 1];
+                               $target = $source;
                        }
-               }
-
-               return $this->formatDate( $bits, $matches[0], $linked );
-       }
+                       $regex = $this->regexes[$source];
 
-       /**
-        * @param array $bits
-        * @param string $orig Original input string, to be returned
-        *  on formatting failure.
-        * @param bool $link
-        * @return string
-        */
-       private function formatDate( $bits, $orig, $link = true ) {
-               $format = $this->targets[$this->mTarget];
-
-               if ( !$link ) {
-                       // strip piped links
-                       $format = preg_replace( '/\[\[[^|]+\|([^\]]+)\]\]/', '$1', $format );
-                       // strip remaining links
-                       $format = str_replace( [ '[[', ']]' ], '', $format );
-               }
-
-               # Construct new date
-               $text = '';
-               $fail = false;
-
-               // Pre-generate y/Y stuff because we need the year for the <span> title.
-               if ( !isset( $bits['y'] ) && isset( $bits['Y'] ) ) {
-                       $bits['y'] = $this->makeIsoYear( $bits['Y'] );
-               }
-               if ( !isset( $bits['Y'] ) && isset( $bits['y'] ) ) {
-                       $bits['Y'] = $this->makeNormalYear( $bits['y'] );
-               }
-
-               if ( !isset( $bits['m'] ) ) {
-                       $m = $this->makeIsoMonth( $bits['F'] );
-                       if ( !$m || $m == '00' ) {
-                               $fail = true;
-                       } else {
-                               $bits['m'] = $m;
-                       }
-               }
+                       $text = preg_replace_callback( $regex,
+                               function ( $match ) use ( $target ) {
+                                       $format = $this->targetFormats[$target];
 
-               if ( !isset( $bits['d'] ) ) {
-                       $bits['d'] = sprintf( '%02d', $bits['j'] );
-               }
+                                       $text = '';
 
-               $formatLength = strlen( $format );
-               for ( $p = 0; $p < $formatLength; $p++ ) {
-                       $char = $format[$p];
-                       switch ( $char ) {
-                               case 'd': # ISO day of month
-                                       $text .= $bits['d'];
-                                       break;
-                               case 'm': # ISO month
-                                       $text .= $bits['m'];
-                                       break;
-                               case 'y': # ISO year
-                                       $text .= $bits['y'];
-                                       break;
-                               case 'j': # ordinary day of month
-                                       if ( !isset( $bits['j'] ) ) {
-                                               $text .= intval( $bits['d'] );
-                                       } else {
-                                               $text .= $bits['j'];
+                                       // Pre-generate y/Y stuff because we need the year for the <span> title.
+                                       if ( !isset( $match['isoYear'] ) && isset( $match['year'] ) ) {
+                                               $match['isoYear'] = $this->makeIsoYear( $match['year'] );
+                                       }
+                                       if ( !isset( $match['year'] ) && isset( $match['isoYear'] ) ) {
+                                               $match['year'] = $this->makeNormalYear( $match['isoYear'] );
                                        }
-                                       break;
-                               case 'F': # long month
-                                       if ( !isset( $bits['F'] ) ) {
-                                               $m = intval( $bits['m'] );
-                                               if ( $m > 12 || $m < 1 ) {
-                                                       $fail = true;
+
+                                       if ( !isset( $match['isoMonth'] ) ) {
+                                               $m = $this->makeIsoMonth( $match['monthName'] );
+                                               if ( $m === false ) {
+                                                       // Fail
+                                                       return $match[0];
                                                } else {
-                                                       $text .= $this->lang->getMonthName( $m );
+                                                       $match['isoMonth'] = $m;
                                                }
-                                       } else {
-                                               $text .= ucfirst( $bits['F'] );
                                        }
-                                       break;
-                               case 'Y': # ordinary (optional BC) year
-                                       $text .= $bits['Y'];
-                                       break;
-                               default:
-                                       $text .= $char;
-                       }
-               }
-               if ( $fail ) {
-                       // This occurs when parsing a date with day or month outside the bounds
-                       // of possibilities.
-                       $text = $orig;
-               }
 
-               $isoBits = [];
-               if ( isset( $bits['y'] ) ) {
-                       $isoBits[] = $bits['y'];
-               }
-               $isoBits[] = $bits['m'];
-               $isoBits[] = $bits['d'];
-               $isoDate = implode( '-', $isoBits );
+                                       if ( !isset( $match['isoDay'] ) ) {
+                                               $match['isoDay'] = sprintf( '%02d', $match['day'] );
+                                       }
 
-               // Output is not strictly HTML (it's wikitext), but <span> is whitelisted.
-               $text = Html::rawElement( 'span',
-                                       [ 'class' => 'mw-formatted-date', 'title' => $isoDate ], $text );
+                                       $formatLength = strlen( $format );
+                                       for ( $p = 0; $p < $formatLength; $p++ ) {
+                                               $char = $format[$p];
+                                               switch ( $char ) {
+                                                       case 'd': // ISO day of month
+                                                               $text .= $match['isoDay'];
+                                                               break;
+                                                       case 'm': // ISO month
+                                                               $text .= $match['isoMonth'];
+                                                               break;
+                                                       case 'y': // ISO year
+                                                               $text .= $match['isoYear'];
+                                                               break;
+                                                       case 'j': // ordinary day of month
+                                                               if ( !isset( $match['day'] ) ) {
+                                                                       $text .= intval( $match['isoDay'] );
+                                                               } else {
+                                                                       $text .= $match['day'];
+                                                               }
+                                                               break;
+                                                       case 'F': // long month
+                                                               $m = intval( $match['isoMonth'] );
+                                                               if ( $m > 12 || $m < 1 ) {
+                                                                       // Fail
+                                                                       return $match[0];
+                                                               } else {
+                                                                       $text .= $this->monthNames[$m];
+                                                               }
+                                                               break;
+                                                       case 'Y': // ordinary (optional BC) year
+                                                               $text .= $match['year'];
+                                                               break;
+                                                       default:
+                                                               $text .= $char;
+                                               }
+                                       }
 
-               return $text;
-       }
+                                       $isoBits = [];
+                                       if ( isset( $match['isoYear'] ) ) {
+                                               $isoBits[] = $match['isoYear'];
+                                       }
+                                       $isoBits[] = $match['isoMonth'];
+                                       $isoBits[] = $match['isoDay'];
+                                       $isoDate = implode( '-', $isoBits );
 
-       /**
-        * Return a regex that can be used to find month names in string
-        * @return string regex to find the months with
-        */
-       private function getMonthRegex() {
-               $names = [];
-               for ( $i = 1; $i <= 12; $i++ ) {
-                       $names[] = $this->lang->getMonthName( $i );
-                       $names[] = $this->lang->getMonthAbbreviation( $i );
+                                       // Output is not strictly HTML (it's wikitext), but <span> is whitelisted.
+                                       $text = Html::rawElement( 'span',
+                                               [ 'class' => 'mw-formatted-date', 'title' => $isoDate ], $text );
+
+                                       return $text;
+                               }, $text
+                       );
                }
-               return implode( '|', $names );
+               return $text;
        }
 
        /**
         * Makes an ISO month, e.g. 02, from a month name
         * @param string $monthName Month name
-        * @return string ISO month name
+        * @return string|false ISO month name, or false if the input was invalid
         */
        private function makeIsoMonth( $monthName ) {
-               $n = $this->xMonths[$this->lang->lc( $monthName )];
-               return sprintf( '%02d', $n );
+               $isoMonth = $this->xMonths[mb_strtolower( $monthName )] ?? false;
+               if ( $isoMonth === false ) {
+                       return false;
+               }
+               return sprintf( '%02d', $isoMonth );
        }
 
        /**
@@ -358,12 +305,11 @@ class DateFormatter {
         * @return string ISO year name
         */
        private function makeIsoYear( $year ) {
-               # Assumes the year is in a nice format, as enforced by the regex
+               // Assumes the year is in a nice format, as enforced by the regex
                if ( substr( $year, -2 ) == 'BC' ) {
                        $num = intval( substr( $year, 0, -3 ) ) - 1;
-                       # PHP bug note: sprintf( "%04d", -1 ) fails poorly
+                       // PHP bug note: sprintf( "%04d", -1 ) fails poorly
                        $text = sprintf( '-%04d', $num );
-
                } else {
                        $text = sprintf( '%04d', $year );
                }
@@ -371,7 +317,7 @@ class DateFormatter {
        }
 
        /**
-        * Make a year one from an ISO year, for instance: '400 BC' from '-0399'.
+        * Make a year from an ISO year, for instance: '400 BC' from '-0399'.
         * @param string $iso ISO year
         * @return int|string int representing year number in case of AD dates, or string containing
         *   year number and 'BC' at the end otherwise.
diff --git a/includes/parser/DateFormatterFactory.php b/includes/parser/DateFormatterFactory.php
new file mode 100644 (file)
index 0000000..d18ecf4
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+class DateFormatterFactory {
+       /** @var DateFormatter[] */
+       private $instances;
+
+       /**
+        * @param Language $lang
+        * @return DateFormatter
+        */
+       public function get( Language $lang ) {
+               $code = $lang->getCode();
+               if ( !isset( $this->instances[$code] ) ) {
+                       $this->instances[$code] = new DateFormatter( $lang );
+               }
+               return $this->instances[$code];
+       }
+}
index 078c819..6416449 100644 (file)
@@ -632,8 +632,7 @@ class LinkHolderArray {
         * @private
         */
        public function replaceTextCallback( $matches ) {
-               $type = $matches[1];
-               $key = $matches[2];
+               list( , $type, $key ) = $matches;
                if ( $type == 'LINK' ) {
                        list( $ns, $index ) = explode( ':', $key, 2 );
                        if ( isset( $this->internals[$ns][$index]['text'] ) ) {
index 0fe456d..9ff731d 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Parser
  */
 use MediaWiki\Linker\LinkRenderer;
+use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Special\SpecialPageFactory;
 use Wikimedia\ScopedCallback;
@@ -276,6 +277,12 @@ class Parser {
        /** @var Config */
        private $siteConfig;
 
+       /** @var LinkRendererFactory */
+       private $linkRendererFactory;
+
+       /** @var NamespaceInfo */
+       private $nsInfo;
+
        /**
         * @param array $parserConf See $wgParserConf documentation
         * @param MagicWordFactory|null $magicWordFactory
@@ -284,11 +291,15 @@ class Parser {
         * @param string|null $urlProtocols As returned from wfUrlProtocols()
         * @param SpecialPageFactory|null $spFactory
         * @param Config|null $siteConfig
+        * @param LinkRendererFactory|null $linkRendererFactory
+        * @param NamespaceInfo|null $nsInfo
         */
        public function __construct(
                array $parserConf = [], MagicWordFactory $magicWordFactory = null,
                Language $contLang = null, ParserFactory $factory = null, $urlProtocols = null,
-               SpecialPageFactory $spFactory = null, Config $siteConfig = null
+               SpecialPageFactory $spFactory = null, Config $siteConfig = null,
+               LinkRendererFactory $linkRendererFactory = null,
+               NamespaceInfo $nsInfo = null
        ) {
                $this->mConf = $parserConf;
                $this->mUrlProtocols = $urlProtocols ?? wfUrlProtocols();
@@ -319,7 +330,10 @@ class Parser {
 
                $this->factory = $factory ?? $services->getParserFactory();
                $this->specialPageFactory = $spFactory ?? $services->getSpecialPageFactory();
-               $this->siteConfig = $siteConfig ?? MediaWikiServices::getInstance()->getMainConfig();
+               $this->siteConfig = $siteConfig ?? $services->getMainConfig();
+               $this->linkRendererFactory =
+                       $linkRendererFactory ?? $services->getLinkRendererFactory();
+               $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
        }
 
        /**
@@ -973,9 +987,9 @@ class Parser {
         * @return LinkRenderer
         */
        public function getLinkRenderer() {
+               // XXX We make the LinkRenderer with current options and then cache it forever
                if ( !$this->mLinkRenderer ) {
-                       $this->mLinkRenderer = MediaWikiServices::getInstance()
-                               ->getLinkRendererFactory()->create();
+                       $this->mLinkRenderer = $this->linkRendererFactory->create();
                        $this->mLinkRenderer->setStubThreshold(
                                $this->getOptions()->getStubThreshold()
                        );
@@ -1029,7 +1043,7 @@ class Parser {
                $matches = [];
 
                $taglist = implode( '|', $elements );
-               $start = "/<($taglist)(\\s+[^>]*?|\\s*?)(\/?" . ">)|<(!--)/i";
+               $start = "/<($taglist)(\\s+[^>]*?|\\s*?)(\/?>)|<(!--)/i";
 
                while ( $text != '' ) {
                        $p = preg_split( $start, $text, 2, PREG_SPLIT_DELIM_CAPTURE );
@@ -1045,10 +1059,7 @@ class Parser {
                                $inside = $p[5];
                        } else {
                                # tag
-                               $element = $p[1];
-                               $attributes = $p[2];
-                               $close = $p[3];
-                               $inside = $p[4];
+                               list( , $element, $attributes, $close, $inside ) = $p;
                        }
 
                        $marker = self::MARKER_PREFIX . "-$element-" . sprintf( '%08X', $n++ ) . self::MARKER_SUFFIX;
@@ -1072,8 +1083,7 @@ class Parser {
                                        $tail = '';
                                        $text = '';
                                } else {
-                                       $tail = $q[1];
-                                       $text = $q[2];
+                                       list( , $tail, $text ) = $q;
                                }
                        }
 
@@ -1425,13 +1435,12 @@ class Parser {
                 */
                if ( !( $this->mOptions->getDisableContentConversion()
                        || isset( $this->mDoubleUnderscores['nocontentconvert'] ) )
+                       && !$this->mOptions->getInterfaceMessage()
                ) {
-                       if ( !$this->mOptions->getInterfaceMessage() ) {
-                               # The position of the convert() call should not be changed. it
-                               # assumes that the links are all replaced and the only thing left
-                               # is the <nowiki> mark.
-                               $text = $this->getTargetLanguage()->convert( $text );
-                       }
+                       # The position of the convert() call should not be changed. it
+                       # assumes that the links are all replaced and the only thing left
+                       # is the <nowiki> mark.
+                       $text = $this->getTargetLanguage()->convert( $text );
                }
 
                $text = $this->mStripState->unstripNoWiki( $text );
@@ -1771,10 +1780,8 @@ class Parser {
                                                // if $firstsingleletterword is set, we don't
                                                // look at the other options, so we can bail early.
                                                break;
-                                       } else {
-                                               if ( $firstmultiletterword == -1 ) {
-                                                       $firstmultiletterword = $i;
-                                               }
+                                       } elseif ( $firstmultiletterword == -1 ) {
+                                               $firstmultiletterword = $i;
                                        }
                                }
                        }
@@ -2240,8 +2247,7 @@ class Parser {
 
                        if ( $useLinkPrefixExtension ) {
                                if ( preg_match( $e2, $s, $m ) ) {
-                                       $prefix = $m[2];
-                                       $s = $m[1];
+                                       list( , $s, $prefix ) = $m;
                                } else {
                                        $prefix = '';
                                }
@@ -2528,7 +2534,7 @@ class Parser {
         */
        public function areSubpagesAllowed() {
                # Some namespaces don't allow subpages
-               return MWNamespace::hasSubpages( $this->mTitle->getNamespace() );
+               return $this->nsInfo->hasSubpages( $this->mTitle->getNamespace() );
        }
 
        /**
@@ -2583,15 +2589,27 @@ class Parser {
                 * Some of these require message or data lookups and can be
                 * expensive to check many times.
                 */
-               if ( Hooks::run( 'ParserGetVariableValueVarCache', [ &$parser, &$this->mVarCache ] ) ) {
-                       if ( isset( $this->mVarCache[$index] ) ) {
-                               return $this->mVarCache[$index];
-                       }
+               if ( Hooks::run( 'ParserGetVariableValueVarCache', [ &$parser, &$this->mVarCache ] )
+                       && isset( $this->mVarCache[$index] )
+               ) {
+                       return $this->mVarCache[$index];
                }
 
                $ts = wfTimestamp( TS_UNIX, $this->mOptions->getTimestamp() );
                Hooks::run( 'ParserGetVariableValueTs', [ &$parser, &$ts ] );
 
+               // In miser mode, disable words that always cause double-parses on page save (T137900)
+               static $slowRevWords = [ 'revisionid' => true ]; // @TODO: 'revisiontimestamp'
+               if (
+                       isset( $slowRevWords[$index] ) &&
+                       $this->siteConfig->get( 'MiserMode' ) &&
+                       !$this->mOptions->getInterfaceMessage() &&
+                       // @TODO: disallow this word on all namespaces
+                       $this->nsInfo->isContent( $this->mTitle->getNamespace() )
+               ) {
+                       return $this->mRevisionId ? '-' : '';
+               };
+
                $pageLang = $this->getFunctionLang();
 
                switch ( $index ) {
@@ -3326,7 +3344,7 @@ class Parser {
                                                        );
                                                }
                                        }
-                               } elseif ( MWNamespace::isNonincludable( $title->getNamespace() ) ) {
+                               } elseif ( $this->nsInfo->isNonincludable( $title->getNamespace() ) ) {
                                        $found = false; # access denied
                                        wfDebug( __METHOD__ . ": template inclusion denied for " .
                                                $title->getPrefixedDBkey() . "\n" );
@@ -3979,7 +3997,7 @@ class Parser {
                        $name = strtolower( $name );
                        $attributes = Sanitizer::decodeTagAttributes( $attrText );
                        if ( isset( $params['attributes'] ) ) {
-                               $attributes = $attributes + $params['attributes'];
+                               $attributes += $params['attributes'];
                        }
 
                        if ( isset( $this->mTagHooks[$name] ) ) {
@@ -4522,7 +4540,7 @@ class Parser {
                if ( $enoughToc && $isMain && !$this->mForceTocPosition ) {
                        // append the TOC at the beginning
                        // Top anchor now in skin
-                       $sections[0] = $sections[0] . $toc . "\n";
+                       $sections[0] .= $toc . "\n";
                }
 
                $full .= implode( '', $sections );
@@ -5122,7 +5140,7 @@ class Parser {
                                'img_link' => 'gallery-internal-link',
                        ];
                        if ( $handler ) {
-                               $paramMap = $paramMap + $handler->getParamMap();
+                               $paramMap += $handler->getParamMap();
                                // We don't want people to specify per-image widths.
                                // Additionally the width parameter would need special casing anyhow.
                                unset( $paramMap['img_width'] );
@@ -5282,8 +5300,6 @@ class Parser {
                #  * bottom
                #  * text-bottom
 
-               global $wgMediaInTargetLanguage;
-
                # Protect LanguageConverter markup when splitting into parts
                $parts = StringUtils::delimiterExplode(
                        '-{', '}-', '|', $options, true /* allow nesting */
@@ -5362,10 +5378,8 @@ class Parser {
                                                                        if ( $paramName === 'no-link' ) {
                                                                                $value = true;
                                                                        }
-                                                                       if ( $paramName === 'link-url' ) {
-                                                                               if ( $this->mOptions->getExternalLinkTarget() ) {
-                                                                                       $params[$type]['link-target'] = $this->mOptions->getExternalLinkTarget();
-                                                                               }
+                                                                       if ( ( $paramName === 'link-url' ) && $this->mOptions->getExternalLinkTarget() ) {
+                                                                               $params[$type]['link-target'] = $this->mOptions->getExternalLinkTarget();
                                                                        }
                                                                }
                                                                break;
@@ -5444,9 +5458,7 @@ class Parser {
                        # Use the "caption" for the tooltip text
                        $params['frame']['title'] = $this->stripAltText( $caption, $holders );
                }
-               if ( $wgMediaInTargetLanguage ) {
-                       $params['handler']['targetlang'] = $this->getTargetLanguage()->getCode();
-               }
+               $params['handler']['targetlang'] = $this->getTargetLanguage()->getCode();
 
                Hooks::run( 'ParserMakeImageParams', [ $title, $file, &$params, $this ] );
 
@@ -5708,15 +5720,15 @@ class Parser {
                        if ( $sectionIndex == 0 ) {
                                if ( $mode === 'get' ) {
                                        return '';
-                               } else {
-                                       return $newText;
                                }
+
+                               return $newText;
                        } else {
                                if ( $mode === 'get' ) {
                                        return $newText;
-                               } else {
-                                       return $text;
                                }
+
+                               return $text;
                        }
                }
 
@@ -6331,10 +6343,8 @@ class Parser {
         */
        public static function stripOuterParagraph( $html ) {
                $m = [];
-               if ( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $html, $m ) ) {
-                       if ( strpos( $m[1], '</p>' ) === false ) {
-                               $html = $m[1];
-                       }
+               if ( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $html, $m ) && strpos( $m[1], '</p>' ) === false ) {
+                       $html = $m[1];
                }
 
                return $html;
index ce7ae13..8e8cd98 100644 (file)
@@ -189,9 +189,8 @@ class ParserCache {
                }
 
                // Determine the options which affect this article
-               $casToken = null;
                $optionsKey = $this->mMemc->get(
-                       $this->getOptionsKey( $article ), $casToken, BagOStuff::READ_VERIFIED );
+                       $this->getOptionsKey( $article ), BagOStuff::READ_VERIFIED );
                if ( $optionsKey instanceof CacheTime ) {
                        if ( $useOutdated < self::USE_EXPIRED && $optionsKey->expired( $article->getTouched() ) ) {
                                $this->incrementStats( $article, "miss.expired" );
@@ -257,7 +256,7 @@ class ParserCache {
 
                $casToken = null;
                /** @var ParserOutput $value */
-               $value = $this->mMemc->get( $parserOutputKey, $casToken, BagOStuff::READ_VERIFIED );
+               $value = $this->mMemc->get( $parserOutputKey, BagOStuff::READ_VERIFIED );
                if ( !$value ) {
                        wfDebug( "ParserOutput cache miss.\n" );
                        $this->incrementStats( $article, "miss.absent" );
index eb05ace..cddacf4 100644 (file)
@@ -18,7 +18,8 @@
  * @file
  * @ingroup Parser
  */
-
+use MediaWiki\Linker\LinkRendererFactory;
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Special\SpecialPageFactory;
 
 /**
@@ -43,6 +44,12 @@ class ParserFactory {
        /** @var Config */
        private $siteConfig;
 
+       /** @var LinkRendererFactory */
+       private $linkRendererFactory;
+
+       /** @var NamespaceInfo */
+       private $nsInfo;
+
        /**
         * @param array $parserConf See $wgParserConf documentation
         * @param MagicWordFactory $magicWordFactory
@@ -50,18 +57,27 @@ class ParserFactory {
         * @param string $urlProtocols As returned from wfUrlProtocols()
         * @param SpecialPageFactory $spFactory
         * @param Config $siteConfig
+        * @param LinkRendererFactory $linkRendererFactory
+        * @param NamespaceInfo|null $nsInfo
         * @since 1.32
         */
        public function __construct(
                array $parserConf, MagicWordFactory $magicWordFactory, Language $contLang, $urlProtocols,
-               SpecialPageFactory $spFactory, Config $siteConfig
+               SpecialPageFactory $spFactory, Config $siteConfig,
+               LinkRendererFactory $linkRendererFactory, NamespaceInfo $nsInfo = null
        ) {
+               if ( !$nsInfo ) {
+                       wfDeprecated( __METHOD__ . ' with no NamespaceInfo argument', '1.34' );
+                       $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
+               }
                $this->parserConf = $parserConf;
                $this->magicWordFactory = $magicWordFactory;
                $this->contLang = $contLang;
                $this->urlProtocols = $urlProtocols;
                $this->specialPageFactory = $spFactory;
                $this->siteConfig = $siteConfig;
+               $this->linkRendererFactory = $linkRendererFactory;
+               $this->nsInfo = $nsInfo;
        }
 
        /**
@@ -70,6 +86,7 @@ class ParserFactory {
         */
        public function create() : Parser {
                return new Parser( $this->parserConf, $this->magicWordFactory, $this->contLang, $this,
-                       $this->urlProtocols, $this->specialPageFactory, $this->siteConfig );
+                       $this->urlProtocols, $this->specialPageFactory, $this->siteConfig,
+                       $this->linkRendererFactory, $this->nsInfo );
        }
 }
index a69e805..bdca848 100644 (file)
@@ -1261,25 +1261,6 @@ class ParserOptions {
                }
        }
 
-       /**
-        * Returns the full array of options that would have been used by
-        * in 1.16.
-        * Used to get the old parser cache entries when available.
-        * @deprecated since 1.30. You probably want self::allCacheVaryingOptions() instead.
-        * @return string[]
-        */
-       public static function legacyOptions() {
-               wfDeprecated( __METHOD__, '1.30' );
-               return [
-                       'stubthreshold',
-                       'numberheadings',
-                       'userlang',
-                       'thumbsize',
-                       'editsection',
-                       'printable'
-               ];
-       }
-
        /**
         * Return all option keys that vary the options hash
         * @since 1.30
index 6260de6..f2aaeed 100644 (file)
@@ -120,11 +120,6 @@ class ParserOutput extends CacheTime {
         */
        public $mModules = [];
 
-       /**
-        * @var array $mModuleScripts Modules of which only the JS will be loaded by ResourceLoader.
-        */
-       public $mModuleScripts = [];
-
        /**
         * @var array $mModuleStyles Modules of which only the CSSS will be loaded by ResourceLoader.
         */
@@ -524,7 +519,8 @@ class ParserOutput extends CacheTime {
        }
 
        public function getModuleScripts() {
-               return $this->mModuleScripts;
+               wfDeprecated( __METHOD__, '1.33' );
+               return [];
        }
 
        public function getModuleStyles() {
@@ -817,14 +813,6 @@ class ParserOutput extends CacheTime {
                $this->mModules = array_merge( $this->mModules, (array)$modules );
        }
 
-       /**
-        * @deprecated since 1.31 Use addModules() instead.
-        * @see OutputPage::addModuleScripts
-        */
-       public function addModuleScripts( $modules ) {
-               $this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules );
-       }
-
        /**
         * @see OutputPage::addModuleStyles
         */
@@ -857,7 +845,6 @@ class ParserOutput extends CacheTime {
         */
        public function addOutputPageMetadata( OutputPage $out ) {
                $this->addModules( $out->getModules() );
-               $this->addModuleScripts( $out->getModuleScripts() );
                $this->addModuleStyles( $out->getModuleStyles() );
                $this->addJsConfigVars( $out->getJsConfigVars() );
 
@@ -1338,7 +1325,6 @@ class ParserOutput extends CacheTime {
                // HTML and HTTP
                $this->mHeadItems = self::mergeMixedList( $this->mHeadItems, $source->getHeadItems() );
                $this->mModules = self::mergeList( $this->mModules, $source->getModules() );
-               $this->mModuleScripts = self::mergeList( $this->mModuleScripts, $source->getModuleScripts() );
                $this->mModuleStyles = self::mergeList( $this->mModuleStyles, $source->getModuleStyles() );
                $this->mJsConfigVars = self::mergeMap( $this->mJsConfigVars, $source->getJsConfigVars() );
                $this->mMaxAdaptiveExpiry = min( $this->mMaxAdaptiveExpiry, $source->mMaxAdaptiveExpiry );
@@ -1359,7 +1345,7 @@ class ParserOutput extends CacheTime {
 
                // TODO: we'll have to be smarter about this!
                $this->mSections = array_merge( $this->mSections, $source->getSections() );
-               $this->mTOCHTML = $this->mTOCHTML . $source->mTOCHTML;
+               $this->mTOCHTML .= $source->mTOCHTML;
 
                // XXX: we don't want to concatenate title text, so first write wins.
                // We should use the first *modified* title text, but we don't have the original to check.
index b6084d8..bdfedd6 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 
 /**
  * @ingroup Parser
@@ -73,10 +74,12 @@ abstract class Preprocessor {
                        return;
                }
 
-               $cache = ObjectCache::getLocalClusterInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                $key = $cache->makeKey(
                        defined( 'static::CACHE_PREFIX' ) ? static::CACHE_PREFIX : static::class,
-                       md5( $text ), $flags );
+                       md5( $text ),
+                       $flags
+               );
                $value = sprintf( "%08d", static::CACHE_VERSION ) . $tree;
 
                $cache->set( $key, $value, 86400 );
@@ -102,11 +105,13 @@ abstract class Preprocessor {
                        return false;
                }
 
-               $cache = ObjectCache::getLocalClusterInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
 
                $key = $cache->makeKey(
                        defined( 'static::CACHE_PREFIX' ) ? static::CACHE_PREFIX : static::class,
-                       md5( $text ), $flags );
+                       md5( $text ),
+                       $flags
+               );
 
                $value = $cache->get( $key );
                if ( !$value ) {
index 3bcd012..c27a635 100644 (file)
@@ -858,6 +858,9 @@ class PPDStack {
                return $this->accum;
        }
 
+       /**
+        * @return bool|PPDPart
+        */
        public function getCurrentPart() {
                if ( $this->top === false ) {
                        return false;
@@ -970,6 +973,9 @@ class PPDStackElement {
                $this->parts[] = new $class( $s );
        }
 
+       /**
+        * @return PPDPart
+        */
        public function getCurrentPart() {
                return $this->parts[count( $this->parts ) - 1];
        }
@@ -1415,12 +1421,10 @@ class PPFrame_DOM implements PPFrame {
        /**
         * @param string $sep
         * @param int $flags
-        * @param string|PPNode_DOM|DOMDocument $args,...
+        * @param string|PPNode_DOM|DOMDocument ...$args
         * @return string
         */
-       public function implodeWithFlags( $sep, $flags /*, ... */ ) {
-               $args = array_slice( func_get_args(), 2 );
-
+       public function implodeWithFlags( $sep, $flags, ...$args ) {
                $first = true;
                $s = '';
                foreach ( $args as $root ) {
@@ -1447,12 +1451,10 @@ class PPFrame_DOM implements PPFrame {
         * This previously called implodeWithFlags but has now been inlined to reduce stack depth
         *
         * @param string $sep
-        * @param string|PPNode_DOM|DOMDocument $args,...
+        * @param string|PPNode_DOM|DOMDocument ...$args
         * @return string
         */
-       public function implode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
-
+       public function implode( $sep, ...$args ) {
                $first = true;
                $s = '';
                foreach ( $args as $root ) {
@@ -1479,11 +1481,10 @@ class PPFrame_DOM implements PPFrame {
         * with implode()
         *
         * @param string $sep
-        * @param string|PPNode_DOM|DOMDocument $args,...
+        * @param string|PPNode_DOM|DOMDocument ...$args
         * @return array
         */
-       public function virtualImplode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
+       public function virtualImplode( $sep, ...$args ) {
                $out = [];
                $first = true;
 
@@ -1511,11 +1512,10 @@ class PPFrame_DOM implements PPFrame {
         * @param string $start
         * @param string $sep
         * @param string $end
-        * @param string|PPNode_DOM|DOMDocument $args,...
+        * @param string|PPNode_DOM|DOMDocument ...$args
         * @return array
         */
-       public function virtualBracketedImplode( $start, $sep, $end /*, ... */ ) {
-               $args = array_slice( func_get_args(), 3 );
+       public function virtualBracketedImplode( $start, $sep, $end, ...$args ) {
                $out = [ $start ];
                $first = true;
 
index eb869e2..dfce0a0 100644 (file)
@@ -1232,12 +1232,10 @@ class PPFrame_Hash implements PPFrame {
        /**
         * @param string $sep
         * @param int $flags
-        * @param string|PPNode $args,...
+        * @param string|PPNode ...$args
         * @return string
         */
-       public function implodeWithFlags( $sep, $flags /*, ... */ ) {
-               $args = array_slice( func_get_args(), 2 );
-
+       public function implodeWithFlags( $sep, $flags, ...$args ) {
                $first = true;
                $s = '';
                foreach ( $args as $root ) {
@@ -1263,12 +1261,10 @@ class PPFrame_Hash implements PPFrame {
         * Implode with no flags specified
         * This previously called implodeWithFlags but has now been inlined to reduce stack depth
         * @param string $sep
-        * @param string|PPNode $args,...
+        * @param string|PPNode ...$args
         * @return string
         */
-       public function implode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
-
+       public function implode( $sep, ...$args ) {
                $first = true;
                $s = '';
                foreach ( $args as $root ) {
@@ -1295,11 +1291,10 @@ class PPFrame_Hash implements PPFrame {
         * with implode()
         *
         * @param string $sep
-        * @param string|PPNode $args,...
+        * @param string|PPNode ...$args
         * @return PPNode_Hash_Array
         */
-       public function virtualImplode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
+       public function virtualImplode( $sep, ...$args ) {
                $out = [];
                $first = true;
 
@@ -1328,11 +1323,10 @@ class PPFrame_Hash implements PPFrame {
         * @param string $start
         * @param string $sep
         * @param string $end
-        * @param string|PPNode $args,...
+        * @param string|PPNode ...$args
         * @return PPNode_Hash_Array
         */
-       public function virtualBracketedImplode( $start, $sep, $end /*, ... */ ) {
-               $args = array_slice( func_get_args(), 3 );
+       public function virtualBracketedImplode( $start, $sep, $end, ...$args ) {
                $out = [ $start ];
                $first = true;
 
index bf4c098..2d75c86 100644 (file)
@@ -87,7 +87,10 @@ class RemexStripTagHandler implements TokenHandler {
                'pre' => true,
                'section' => true,
                'table' => true,
+               'td' => true,
                'tfoot' => true,
+               'th' => true,
+               'tr' => true,
                'ul' => true,
                'video' => true,
        ];
index 0aa58c1..518846c 100644 (file)
@@ -578,10 +578,8 @@ class Sanitizer {
                                                                        $badtag = true;
                                                                }
                                                        }
-                                               } else {
-                                                       if ( $t == 'table' ) {
-                                                               $tagstack = array_pop( $tablestack );
-                                                       }
+                                               } elseif ( $t == 'table' ) {
+                                                       $tagstack = array_pop( $tablestack );
                                                }
                                                $newparams = '';
                                        } else {
index 8f6cb3e..4caff8e 100644 (file)
@@ -33,14 +33,6 @@ use Wikimedia\Assert\Assert;
  * to be fulfilled:
  *  * If Password::toString() is called on an object, and the result is passed back in
  *    to PasswordFactory::newFromCiphertext(), the result will be identical to the original.
- *  * The string representations of two Password objects are equal only if
- *    the original plaintext passwords match. In other words, if the toString() result of
- *    two objects match, the passwords are the same, and the user will be logged in.
- *    Since the string representation of a hash includes its type name (@see Password::toString),
- *    this property is preserved across all classes that inherit Password.
- *    If a hashing scheme does not fulfill this expectation, it must make sure to override the
- *    Password::equals() function and use custom comparison logic. However, this is not
- *    recommended unless absolutely required by the hashing mechanism.
  * With these two points in mind, when creating a new Password sub-class, there are some functions
  * you have to override (because they are abstract) and others that you may want to override.
  *
@@ -56,8 +48,9 @@ use Wikimedia\Assert\Assert;
  *  * Password::toString(), which can be useful if the hash was changed in the constructor and
  *    needs to be re-assembled before being returned as a string. This function is expected to add
  *    the type back on to the hash, so make sure to do that if you override the function.
- *  * Password::equals() - This function compares two Password objects to see if they are equal.
- *    The default is to just do a timing-safe string comparison on the $this->hash values.
+ *  * Password::verify() - This function checks if $this->hash was generated with the given
+ *    password. The default is to just hash the password and do a timing-safe string comparison with
+ *    $this->hash.
  *
  * After creating a new password hash type, it can be registered using the static
  * Password::register() method. The default type is set using the Password::setDefaultType() type.
index f7b283b..96cc3fe 100644 (file)
@@ -47,7 +47,8 @@ final class PasswordFactory {
 
        /**
         * Construct a new password factory.
-        * Most of the time you'll want to use MediaWikiServices::getPasswordFactory instead.
+        * Most of the time you'll want to use MediaWikiServices::getInstance()->getPasswordFactory
+        * instead.
         * @param array $config Mapping of password type => config
         * @param string $default Default password type
         * @see PasswordFactory::register
index c61c795..79a5539 100644 (file)
@@ -71,6 +71,7 @@ class UserPasswordPolicy {
         *   indicate the user shouldn't be allowed to login. The status value will be an array,
         *   potentially with the following keys:
         *   - forceChange: do not allow the user to login without changing the password if invalid.
+        *   - suggestChangeOnLogin: prompt for a password change on login if the password is invalid.
         */
        public function checkUserPassword( User $user, $password ) {
                $effectivePolicy = $this->getPoliciesForUser( $user );
@@ -93,6 +94,7 @@ class UserPasswordPolicy {
         *   indicate the user shouldn't be allowed to login. The status value will be an array,
         *   potentially with the following keys:
         *   - forceChange: do not allow the user to login without changing the password if invalid.
+        *   - suggestChangeOnLogin: prompt for a password change on login if the password is invalid.
         */
        public function checkUserPasswordForGroups( User $user, $password, array $groups ) {
                $effectivePolicy = self::getPoliciesForGroups(
@@ -118,6 +120,7 @@ class UserPasswordPolicy {
        private function checkPolicies( User $user, $password, $policies, $policyCheckFunctions ) {
                $status = Status::newGood( [] );
                $forceChange = false;
+               $suggestChangeOnLogin = false;
                foreach ( $policies as $policy => $settings ) {
                        if ( !isset( $policyCheckFunctions[$policy] ) ) {
                                throw new DomainException( "Invalid password policy config. No check defined for '$policy'." );
@@ -137,14 +140,27 @@ class UserPasswordPolicy {
                                $user,
                                $password
                        );
-                       if ( !$policyStatus->isGood() && !empty( $settings['forceChange'] ) ) {
-                               $forceChange = true;
+
+                       if ( !$policyStatus->isGood() ) {
+                               if ( !empty( $settings['forceChange'] ) ) {
+                                       $forceChange = true;
+                               }
+
+                               if ( !empty( $settings['suggestChangeOnLogin'] ) ) {
+                                       $suggestChangeOnLogin = true;
+                               }
                        }
                        $status->merge( $policyStatus );
                }
-               if ( $status->isOK() && $forceChange ) {
-                       $status->value['forceChange'] = true;
+
+               if ( $status->isOK() ) {
+                       if ( $forceChange ) {
+                               $status->value['forceChange'] = true;
+                       } elseif ( $suggestChangeOnLogin ) {
+                               $status->value['suggestChangeOnLogin'] = true;
+                       }
                }
+
                return $status;
        }
 
index ba0b4cb..060faec 100644 (file)
@@ -39,7 +39,7 @@
  * that start with "nowait:". However, only 0 timeouts (non-blocking requests)
  * can be used with "nowait:" keys.
  *
- * By default PoolCounter_Stub is used, which provides no locking. You
+ * By default PoolCounterNull is used, which provides no locking. You
  * can get a useful one in the PoolCounter extension.
  */
 abstract class PoolCounter {
@@ -111,7 +111,7 @@ abstract class PoolCounter {
        public static function factory( $type, $key ) {
                global $wgPoolCounterConf;
                if ( !isset( $wgPoolCounterConf[$type] ) ) {
-                       return new PoolCounter_Stub;
+                       return new PoolCounterNull;
                }
                $conf = $wgPoolCounterConf[$type];
                $class = $conf['class'];
@@ -208,23 +208,3 @@ abstract class PoolCounter {
                return $type . ':' . ( hexdec( substr( sha1( $key ), 0, 4 ) ) % $slots );
        }
 }
-
-// phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
-class PoolCounter_Stub extends PoolCounter {
-
-       public function __construct() {
-               /* No parameters needed */
-       }
-
-       public function acquireForMe() {
-               return Status::newGood( PoolCounter::LOCKED );
-       }
-
-       public function acquireForAnyone() {
-               return Status::newGood( PoolCounter::LOCKED );
-       }
-
-       public function release() {
-               return Status::newGood( PoolCounter::RELEASED );
-       }
-}
diff --git a/includes/poolcounter/PoolCounterNull.php b/includes/poolcounter/PoolCounterNull.php
new file mode 100644 (file)
index 0000000..95a5057
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Provides of semaphore semantics for restricting the number
+ * of workers that may be concurrently performing the same task.
+ *
+ * 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
+ */
+
+/**
+ * A default PoolCounter, which provides no locking.
+ */
+class PoolCounterNull extends PoolCounter {
+
+       public function __construct() {
+               /* No parameters needed */
+       }
+
+       public function acquireForMe() {
+               return Status::newGood( PoolCounter::LOCKED );
+       }
+
+       public function acquireForAnyone() {
+               return Status::newGood( PoolCounter::LOCKED );
+       }
+
+       public function release() {
+               return Status::newGood( PoolCounter::RELEASED );
+       }
+}
index 512a6b3..be2bf08 100644 (file)
@@ -121,7 +121,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                $this->skinPreferences( $user, $context, $preferences );
                $this->datetimePreferences( $user, $context, $preferences );
                $this->filesPreferences( $context, $preferences );
-               $this->renderingPreferences( $context, $preferences );
+               $this->renderingPreferences( $user, $context, $preferences );
                $this->editingPreferences( $user, $context, $preferences );
                $this->rcPreferences( $user, $context, $preferences );
                $this->watchlistPreferences( $user, $context, $preferences );
@@ -373,7 +373,6 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        ];
                }
 
-               // Language
                $languages = Language::fetchLanguageNames( null, 'mwfile' );
                $languageCode = $this->config->get( 'LanguageCode' );
                if ( !array_key_exists( $languageCode, $languages ) ) {
@@ -801,10 +800,15 @@ class DefaultPreferencesFactory implements PreferencesFactory {
        }
 
        /**
+        * @param User $user
         * @param MessageLocalizer $l10n
         * @param array &$defaultPreferences
         */
-       protected function renderingPreferences( MessageLocalizer $l10n, &$defaultPreferences ) {
+       protected function renderingPreferences(
+               User $user,
+               MessageLocalizer $l10n,
+               &$defaultPreferences
+       ) {
                # # Diffs ####################################
                $defaultPreferences['diffonly'] = [
                        'type' => 'toggle',
@@ -843,7 +847,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        'options' => $stubThresholdOptions,
                        // This is not a raw HTML message; label-raw is needed for the manual <a></a>
                        'label-raw' => $l10n->msg( 'stub-threshold' )->rawParams(
-                               '<a href="#" class="stub">' .
+                               '<a class="stub">' .
                                $l10n->msg( 'stub-threshold-sample-link' )->parse() .
                                '</a>' )->parse(),
                ];
@@ -859,6 +863,14 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        'section' => 'rendering/advancedrendering',
                        'label-message' => 'tog-numberheadings',
                ];
+
+               if ( $user->isAllowed( 'rollback' ) ) {
+                       $defaultPreferences['showrollbackconfirmation'] = [
+                               'type' => 'toggle',
+                               'section' => 'rendering/advancedrendering',
+                               'label-message' => 'tog-showrollbackconfirmation',
+                       ];
+               }
        }
 
        /**
@@ -1040,7 +1052,6 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                # # Watchlist #####################################
                if ( $user->isAllowed( 'editmywatchlist' ) ) {
                        $editWatchlistLinks = '';
-                       $editWatchlistLinksOld = [];
                        $editWatchlistModes = [
                                'edit' => [ 'subpage' => false, 'flags' => [] ],
                                'raw' => [ 'subpage' => 'raw', 'flags' => [] ],
@@ -1439,7 +1450,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                }
 
                /**
-                * @var $htmlForm HTMLForm
+                * @var HTMLForm $htmlForm
                 */
                $htmlForm = new $formClass( $formDescriptor, $context, 'prefs' );
 
@@ -1572,7 +1583,6 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        );
                }
 
-               AuthManager::callLegacyAuthPlugin( 'updateExternalDB', [ $user ] );
                $user->saveSettings();
 
                return $result;
index 455130c..554ca08 100644 (file)
@@ -147,11 +147,12 @@ abstract class Profiler {
                }
        }
 
-       // Kept BC for now, remove when possible
        public function profileIn( $functionname ) {
+               wfDeprecated( __METHOD__, '1.33' );
        }
 
        public function profileOut( $functionname ) {
+               wfDeprecated( __METHOD__, '1.33' );
        }
 
        /**
@@ -212,7 +213,7 @@ abstract class Profiler {
        }
 
        /**
-        * Log the data to some store or even the page output
+        * Log the data to the backing store for all ProfilerOutput instances that have one
         *
         * @since 1.25
         */
@@ -225,27 +226,38 @@ abstract class Profiler {
                        return;
                }
 
-               $outputs = $this->getOutputs();
-               if ( !$outputs ) {
-                       return;
+               $outputs = [];
+               foreach ( $this->getOutputs() as $output ) {
+                       if ( !$output->logsToOutput() ) {
+                               $outputs[] = $output;
+                       }
                }
 
-               $stats = $this->getFunctionStats();
-               foreach ( $outputs as $output ) {
-                       $output->log( $stats );
+               if ( $outputs ) {
+                       $stats = $this->getFunctionStats();
+                       foreach ( $outputs as $output ) {
+                               $output->log( $stats );
+                       }
                }
        }
 
        /**
-        * Output current data to the page output if configured to do so
+        * Log the data to the script/request output for all ProfilerOutput instances that do so
         *
         * @throws MWException
         * @since 1.26
         */
        public function logDataPageOutputOnly() {
+               $outputs = [];
                foreach ( $this->getOutputs() as $output ) {
-                       if ( $output instanceof ProfilerOutputText ) {
-                               $stats = $this->getFunctionStats();
+                       if ( $output->logsToOutput() ) {
+                               $outputs[] = $output;
+                       }
+               }
+
+               if ( $outputs ) {
+                       $stats = $this->getFunctionStats();
+                       foreach ( $outputs as $output ) {
                                $output->log( $stats );
                        }
                }
index 1017e44..fe46798 100644 (file)
@@ -32,9 +32,11 @@ class ProfilerStub extends Profiler {
        }
 
        public function getFunctionStats() {
+               return [];
        }
 
        public function getOutput() {
+               return '';
        }
 
        public function close() {
index 20b0780..fe27c04 100644 (file)
@@ -47,6 +47,15 @@ abstract class ProfilerOutput {
                return true;
        }
 
+       /**
+        * Does log() just send the data to the request/script output?
+        * @return bool
+        * @since 1.33
+        */
+       public function logsToOutput() {
+               return false;
+       }
+
        /**
         * Log MediaWiki-style profiling data
         *
index e3184db..95b5ff9 100644 (file)
@@ -35,6 +35,11 @@ class ProfilerOutputText extends ProfilerOutput {
                parent::__construct( $collector, $params );
                $this->thresholdMs = $params['thresholdMs'] ?? 1.0;
        }
+
+       public function logsToOutput() {
+               return true;
+       }
+
        public function log( array $stats ) {
                if ( $this->collector->getTemplated() ) {
                        $out = '';
index 8a3aa0c..c954df1 100644 (file)
@@ -37,7 +37,7 @@
  *
  * @since 1.22
  */
-class RedisPubSubFeedEngine extends RCFeedEngine {
+class RedisPubSubFeedEngine extends FormattedRCFeed {
 
        /**
         * @see FormattedRCFeed::send
@@ -68,8 +68,8 @@ class RedisPubSubFeedEngine extends RCFeedEngine {
                if ( $conn !== false ) {
                        $conn->publish( $channel, $line );
                        return true;
-               } else {
-                       return false;
                }
+
+               return false;
        }
 }
index f76d771..7e69a02 100644 (file)
@@ -32,5 +32,6 @@ class UDPRCFeedEngine extends RCFeedEngine {
        public function send( array $feed, $line ) {
                $transport = UDPTransport::newFromString( $feed['uri'] );
                $transport->emit( $line );
+               return true;
        }
 }
index 9d6c1a5..ba5df52 100644 (file)
@@ -60,12 +60,16 @@ class ExtensionJsonValidator {
                                'The JsonSchema library cannot be found, please install it through composer.'
                        );
                        return false;
-               } elseif ( !class_exists( SpdxLicenses::class ) ) {
+               }
+
+               if ( !class_exists( SpdxLicenses::class ) ) {
                        call_user_func( $this->missingDepCallback,
                                'The spdx-licenses library cannot be found, please install it through composer.'
                        );
                        return false;
-               } elseif ( !class_exists( JsonParser::class ) ) {
+               }
+
+               if ( !class_exists( JsonParser::class ) ) {
                        call_user_func( $this->missingDepCallback,
                                'The JSON lint library cannot be found, please install it through composer.'
                        );
@@ -104,7 +108,9 @@ class ExtensionJsonValidator {
                        throw new ExtensionJsonValidationError(
                                "$path is using a non-supported schema version"
                        );
-               } elseif ( $version > ExtensionRegistry::MANIFEST_VERSION ) {
+               }
+
+               if ( $version > ExtensionRegistry::MANIFEST_VERSION ) {
                        throw new ExtensionJsonValidationError(
                                "$path is using a non-supported schema version"
                        );
@@ -140,15 +146,15 @@ class ExtensionJsonValidator {
                if ( $validator->isValid() && !$extraErrors ) {
                        // All good.
                        return true;
-               } else {
-                       $out = "$path did not pass validation.\n";
-                       foreach ( $validator->getErrors() as $error ) {
-                               $out .= "[{$error['property']}] {$error['message']}\n";
-                       }
-                       if ( $extraErrors ) {
-                               $out .= implode( "\n", $extraErrors ) . "\n";
-                       }
-                       throw new ExtensionJsonValidationError( $out );
                }
+
+               $out = "$path did not pass validation.\n";
+               foreach ( $validator->getErrors() as $error ) {
+                       $out .= "[{$error['property']}] {$error['message']}\n";
+               }
+               if ( $extraErrors ) {
+                       $out .= implode( "\n", $extraErrors ) . "\n";
+               }
+               throw new ExtensionJsonValidationError( $out );
        }
 }
index 1d3fd86..b474ddc 100644 (file)
@@ -189,7 +189,6 @@ class ExtensionProcessor implements Processor {
         * @param string $path
         * @param array $info
         * @param int $version manifest_version for info
-        * @return array
         */
        public function extractInfo( $path, array $info, $version ) {
                $dir = dirname( $path );
index 88d9fd3..e3df499 100644 (file)
@@ -374,7 +374,7 @@ class ExtensionRegistry {
                                }
                                throw new UnexpectedValueException( "callback '$cb' is not callable" );
                        }
-                       call_user_func( $cb, $info['credits'][$name] );
+                       $cb( $info['credits'][$name] );
                }
        }
 
index 636d3b3..68ba413 100644 (file)
@@ -17,7 +17,6 @@ interface Processor {
         * @param string $path Absolute path of JSON file
         * @param array $info
         * @param int $version manifest_version for info
-        * @return array "credits" information to store
         */
        public function extractInfo( $path, array $info, $version );
 
diff --git a/includes/resourceloader/MessageBlobStore.php b/includes/resourceloader/MessageBlobStore.php
new file mode 100644 (file)
index 0000000..b7c1904
--- /dev/null
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Message blobs storage used by ResourceLoader.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Roan Kattouw
+ * @author Trevor Parscal
+ * @author Timo Tijhof
+ */
+
+use MediaWiki\MediaWikiServices;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+use Wikimedia\Rdbms\Database;
+
+/**
+ * This class generates message blobs for use by ResourceLoader modules.
+ *
+ * A message blob is a JSON object containing the interface messages for a certain module in
+ * a certain language.
+ */
+class MessageBlobStore implements LoggerAwareInterface {
+
+       /* @var ResourceLoader */
+       private $resourceloader;
+
+       /**
+        * @var LoggerInterface
+        */
+       protected $logger;
+
+       /**
+        * @var WANObjectCache
+        */
+       protected $wanCache;
+
+       /**
+        * @param ResourceLoader $rl
+        * @param LoggerInterface|null $logger
+        */
+       public function __construct( ResourceLoader $rl, LoggerInterface $logger = null ) {
+               $this->resourceloader = $rl;
+               $this->logger = $logger ?: new NullLogger();
+               $this->wanCache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+       }
+
+       /**
+        * @since 1.27
+        * @param LoggerInterface $logger
+        */
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
+       /**
+        * Get the message blob for a module
+        *
+        * @since 1.27
+        * @param ResourceLoaderModule $module
+        * @param string $lang Language code
+        * @return string JSON
+        */
+       public function getBlob( ResourceLoaderModule $module, $lang ) {
+               $blobs = $this->getBlobs( [ $module->getName() => $module ], $lang );
+               return $blobs[$module->getName()];
+       }
+
+       /**
+        * Get the message blobs for a set of modules
+        *
+        * @since 1.27
+        * @param ResourceLoaderModule[] $modules Array of module objects keyed by name
+        * @param string $lang Language code
+        * @return array An array mapping module names to message blobs
+        */
+       public function getBlobs( array $modules, $lang ) {
+               // Each cache key for a message blob by module name and language code also has a generic
+               // check key without language code. This is used to invalidate any and all language subkeys
+               // that exist for a module from the updateMessage() method.
+               $cache = $this->wanCache;
+               $checkKeys = [
+                       // Global check key, see clear()
+                       $cache->makeKey( __CLASS__ )
+               ];
+               $cacheKeys = [];
+               foreach ( $modules as $name => $module ) {
+                       $cacheKey = $this->makeCacheKey( $module, $lang );
+                       $cacheKeys[$name] = $cacheKey;
+                       // Per-module check key, see updateMessage()
+                       $checkKeys[$cacheKey][] = $cache->makeKey( __CLASS__, $name );
+               }
+               $curTTLs = [];
+               $result = $cache->getMulti( array_values( $cacheKeys ), $curTTLs, $checkKeys );
+
+               $blobs = [];
+               foreach ( $modules as $name => $module ) {
+                       $key = $cacheKeys[$name];
+                       if ( !isset( $result[$key] ) || $curTTLs[$key] === null || $curTTLs[$key] < 0 ) {
+                               $blobs[$name] = $this->recacheMessageBlob( $key, $module, $lang );
+                       } else {
+                               // Use unexpired cache
+                               $blobs[$name] = $result[$key];
+                       }
+               }
+               return $blobs;
+       }
+
+       /**
+        * @since 1.27
+        * @param ResourceLoaderModule $module
+        * @param string $lang
+        * @return string Cache key
+        */
+       private function makeCacheKey( ResourceLoaderModule $module, $lang ) {
+               $messages = array_values( array_unique( $module->getMessages() ) );
+               sort( $messages );
+               return $this->wanCache->makeKey( __CLASS__, $module->getName(), $lang,
+                       md5( json_encode( $messages ) )
+               );
+       }
+
+       /**
+        * @since 1.27
+        * @param string $cacheKey
+        * @param ResourceLoaderModule $module
+        * @param string $lang
+        * @return string JSON blob
+        */
+       protected function recacheMessageBlob( $cacheKey, ResourceLoaderModule $module, $lang ) {
+               $blob = $this->generateMessageBlob( $module, $lang );
+               $cache = $this->wanCache;
+               $cache->set( $cacheKey, $blob,
+                       // Add part of a day to TTL to avoid all modules expiring at once
+                       $cache::TTL_WEEK + mt_rand( 0, $cache::TTL_DAY ),
+                       Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) )
+               );
+               return $blob;
+       }
+
+       /**
+        * Invalidate cache keys for modules using this message key.
+        * Called by MessageCache when a message has changed.
+        *
+        * @param string $key Message key
+        */
+       public function updateMessage( $key ) {
+               $moduleNames = $this->getResourceLoader()->getModulesByMessage( $key );
+               foreach ( $moduleNames as $moduleName ) {
+                       // Uses a holdoff to account for database replica DB lag (for MessageCache)
+                       $this->wanCache->touchCheckKey( $this->wanCache->makeKey( __CLASS__, $moduleName ) );
+               }
+       }
+
+       /**
+        * Invalidate cache keys for all known modules.
+        * Called by LocalisationCache after cache is regenerated.
+        */
+       public function clear() {
+               $cache = $this->wanCache;
+               // Disable holdoff because this invalidates all modules and also not needed since
+               // LocalisationCache is stored outside the database and doesn't have lag.
+               $cache->touchCheckKey( $cache->makeKey( __CLASS__ ), $cache::HOLDOFF_NONE );
+       }
+
+       /**
+        * @since 1.27
+        * @return ResourceLoader
+        */
+       protected function getResourceLoader() {
+               return $this->resourceloader;
+       }
+
+       /**
+        * @since 1.27
+        * @param string $key Message key
+        * @param string $lang Language code
+        * @return string
+        */
+       protected function fetchMessage( $key, $lang ) {
+               $message = wfMessage( $key )->inLanguage( $lang );
+               $value = $message->plain();
+               if ( !$message->exists() ) {
+                       $this->logger->warning( 'Failed to find {messageKey} ({lang})', [
+                               'messageKey' => $key,
+                               'lang' => $lang,
+                       ] );
+               }
+               return $value;
+       }
+
+       /**
+        * Generate the message blob for a given module in a given language.
+        *
+        * @param ResourceLoaderModule $module
+        * @param string $lang Language code
+        * @return string JSON blob
+        */
+       private function generateMessageBlob( ResourceLoaderModule $module, $lang ) {
+               $messages = [];
+               foreach ( $module->getMessages() as $key ) {
+                       $messages[$key] = $this->fetchMessage( $key, $lang );
+               }
+
+               $json = FormatJson::encode( (object)$messages );
+               // @codeCoverageIgnoreStart
+               if ( $json === false ) {
+                       $this->logger->warning( 'Failed to encode message blob for {module} ({lang})', [
+                               'module' => $module->getName(),
+                               'lang' => $lang,
+                       ] );
+                       $json = '{}';
+               }
+               // codeCoverageIgnoreEnd
+               return $json;
+       }
+}
index 4158082..7fb2df2 100644 (file)
@@ -240,8 +240,6 @@ class ResourceLoader implements LoggerAwareInterface {
         * @param LoggerInterface|null $logger [optional]
         */
        public function __construct( Config $config = null, LoggerInterface $logger = null ) {
-               global $IP;
-
                $this->logger = $logger ?: new NullLogger();
 
                if ( !$config ) {
@@ -254,11 +252,9 @@ class ResourceLoader implements LoggerAwareInterface {
                // Add 'local' source first
                $this->addSource( 'local', $config->get( 'LoadScript' ) );
 
-               // Add other sources
-               $this->addSource( $config->get( 'ResourceLoaderSources' ) );
+               // Special module that always exists
+               $this->register( 'startup', [ 'class' => ResourceLoaderStartUpModule::class ] );
 
-               // Register core modules
-               $this->register( include "$IP/resources/Resources.php" );
                // Register extension modules
                $this->register( $config->get( 'ResourceModules' ) );
 
@@ -322,8 +318,6 @@ class ResourceLoader implements LoggerAwareInterface {
         * @throws MWException If a duplicate module registration is attempted
         * @throws MWException If a module name contains illegal characters (pipes or commas)
         * @throws MWException If something other than a ResourceLoaderModule is being registered
-        * @return bool False if there were any errors, in which case one or more modules were
-        *   not registered
         */
        public function register( $name, $info = null ) {
                $moduleSkinStyles = $this->config->get( 'ResourceModuleSkinStyles' );
@@ -424,7 +418,7 @@ class ResourceLoader implements LoggerAwareInterface {
                // Add the QUnit testrunner as implicit dependency to extension test suites.
                foreach ( $testModules['qunit'] as &$module ) {
                        // Shuck any single-module dependency as an array
-                       if ( is_string( $module['dependencies'] ) ) {
+                       if ( isset( $module['dependencies'] ) && is_string( $module['dependencies'] ) ) {
                                $module['dependencies'] = [ $module['dependencies'] ];
                        }
 
@@ -1106,7 +1100,7 @@ MESSAGE;
                                                                // mw.loader.implement will use globalEval if scripts is a string.
                                                                // Minify manually here, because general response minification is
                                                                // not effective due it being a string literal, not a function.
-                                                               if ( !self::inDebugMode() ) {
+                                                               if ( !$context->getDebug() ) {
                                                                        $scripts = self::filter( 'minify-js', $scripts ); // T107377
                                                                }
                                                        } else {
@@ -1163,11 +1157,9 @@ MESSAGE;
                                // Use a linebreak between module script and state script (T162719)
                                $out = $this->ensureNewline( $out ) . $stateScript;
                        }
-               } else {
-                       if ( $states ) {
-                               $this->errors[] = 'Problematic modules: '
-                                       . self::encodeJsonForScript( $states );
-                       }
+               } elseif ( $states ) {
+                       $this->errors[] = 'Problematic modules: '
+                               . self::encodeJsonForScript( $states );
                }
 
                return $out;
@@ -1180,7 +1172,7 @@ MESSAGE;
         */
        private function ensureNewline( $str ) {
                $end = substr( $str, -1 );
-               if ( $end === false || $end === "\n" ) {
+               if ( $end === false || $end === '' || $end === "\n" ) {
                        return $str;
                }
                return $str . "\n";
@@ -1452,7 +1444,7 @@ MESSAGE;
                        }
                }
 
-               array_walk( $modules, [ 'self', 'trimArray' ] );
+               array_walk( $modules, [ self::class, 'trimArray' ] );
 
                return Xml::encodeJsCall(
                        'mw.loader.register',
@@ -1575,7 +1567,7 @@ MESSAGE;
         * For example, `[ 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ]`
         * becomes `'foo.bar,baz|bar.baz,quux'`.
         *
-        * This process is reversed by ResourceLoaderContext::expandModuleNames().
+        * This process is reversed by ResourceLoader::expandModuleNames().
         * See also mw.loader#buildModulesString() which is a port of this, used
         * on the client-side.
         *
@@ -1599,6 +1591,44 @@ MESSAGE;
                return implode( '|', $arr );
        }
 
+       /**
+        * Expand a string of the form `jquery.foo,bar|jquery.ui.baz,quux` to
+        * an array of module names like `[ 'jquery.foo', 'jquery.bar',
+        * 'jquery.ui.baz', 'jquery.ui.quux' ]`.
+        *
+        * This process is reversed by ResourceLoader::makePackedModulesString().
+        *
+        * @since 1.33
+        * @param string $modules Packed module name list
+        * @return array Array of module names
+        */
+       public static function expandModuleNames( $modules ) {
+               $retval = [];
+               $exploded = explode( '|', $modules );
+               foreach ( $exploded as $group ) {
+                       if ( strpos( $group, ',' ) === false ) {
+                               // This is not a set of modules in foo.bar,baz notation
+                               // but a single module
+                               $retval[] = $group;
+                       } else {
+                               // This is a set of modules in foo.bar,baz notation
+                               $pos = strrpos( $group, '.' );
+                               if ( $pos === false ) {
+                                       // Prefixless modules, i.e. without dots
+                                       $retval = array_merge( $retval, explode( ',', $group ) );
+                               } else {
+                                       // We have a prefix and a bunch of suffixes
+                                       $prefix = substr( $group, 0, $pos ); // 'foo'
+                                       $suffixes = explode( ',', substr( $group, $pos + 1 ) ); // [ 'bar', 'baz' ]
+                                       foreach ( $suffixes as $suffix ) {
+                                               $retval[] = "$prefix.$suffix";
+                                       }
+                               }
+                       }
+               }
+               return $retval;
+       }
+
        /**
         * Determine whether debug mode was requested
         * Order of priority is 1) request param, 2) cookie, 3) $wg setting
@@ -1695,8 +1725,10 @@ MESSAGE;
                        'modules' => self::makePackedModulesString( $modules ),
                        'lang' => $lang,
                        'skin' => $skin,
-                       'debug' => $debug ? 'true' : 'false',
                ];
+               if ( $debug === true ) {
+                       $query['debug'] = 'true';
+               }
                if ( $user !== null ) {
                        $query['user'] = $user;
                }
index 5c072bf..ec408c7 100644 (file)
@@ -22,7 +22,7 @@ use Wikimedia\WrappedString;
 use Wikimedia\WrappedStringList;
 
 /**
- * Bootstrap a ResourceLoader client on an HTML page.
+ * Load and configure a ResourceLoader client on an HTML page.
  *
  * @since 1.28
  */
@@ -46,9 +46,6 @@ class ResourceLoaderClientHtml {
        /** @var array */
        private $moduleStyles = [];
 
-       /** @var array */
-       private $moduleScripts = [];
-
        /** @var array */
        private $exemptStates = [];
 
@@ -101,16 +98,6 @@ class ResourceLoaderClientHtml {
                $this->moduleStyles = $modules;
        }
 
-       /**
-        * Ensure the scripts of one or more modules are loaded.
-        *
-        * @deprecated since 1.28
-        * @param array $modules Array of module names
-        */
-       public function setModuleScripts( array $modules ) {
-               $this->moduleScripts = $modules;
-       }
-
        /**
         * Set state of special modules that are handled by the caller manually.
         *
@@ -139,7 +126,6 @@ class ResourceLoaderClientHtml {
                        ],
                        'general' => [],
                        'styles' => [],
-                       'scripts' => [],
                        // Embedding for private modules
                        'embed' => [
                                'styles' => [],
@@ -217,26 +203,6 @@ class ResourceLoaderClientHtml {
                        }
                }
 
-               foreach ( $this->moduleScripts as $name ) {
-                       $module = $rl->getModule( $name );
-                       if ( !$module ) {
-                               continue;
-                       }
-
-                       $group = $module->getGroup();
-                       $context = $this->getContext( $group, ResourceLoaderModule::TYPE_SCRIPTS );
-                       if ( $module->isKnownEmpty( $context ) ) {
-                               // Avoid needless request for empty module
-                               $data['states'][$name] = 'ready';
-                       } else {
-                               // Load from load.php?only=scripts via <script src></script>
-                               $data['scripts'][] = $name;
-
-                               // Avoid duplicate request from mw.loader
-                               $data['states'][$name] = 'loading';
-                       }
-               }
-
                return $data;
        }
 
@@ -312,15 +278,6 @@ class ResourceLoaderClientHtml {
                        );
                }
 
-               // Inline RLQ: Load only=scripts
-               if ( $data['scripts'] ) {
-                       $chunks[] = $this->getLoad(
-                               $data['scripts'],
-                               ResourceLoaderModule::TYPE_SCRIPTS,
-                               $nonce
-                       );
-               }
-
                // External stylesheets (only=styles)
                if ( $data['styles'] ) {
                        $chunks[] = $this->getLoad(
@@ -493,19 +450,17 @@ class ResourceLoaderClientHtml {
                                                // Decide whether to use 'style' or 'script' element
                                                if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
                                                        $chunk = Html::linkedStyle( $url );
+                                               } elseif ( $context->getRaw() || $isRaw ) {
+                                                       $chunk = Html::element( 'script', [
+                                                               // In SpecialJavaScriptTest, QUnit must load synchronous
+                                                               'async' => !isset( $extraQuery['sync'] ),
+                                                               'src' => $url
+                                                       ] );
                                                } else {
-                                                       if ( $context->getRaw() || $isRaw ) {
-                                                               $chunk = Html::element( 'script', [
-                                                                       // In SpecialJavaScriptTest, QUnit must load synchronous
-                                                                       'async' => !isset( $extraQuery['sync'] ),
-                                                                       'src' => $url
-                                                               ] );
-                                                       } else {
-                                                               $chunk = ResourceLoader::makeInlineScript(
-                                                                       Xml::encodeJsCall( 'mw.loader.load', [ $url ] ),
-                                                                       $nonce
-                                                               );
-                                                       }
+                                                       $chunk = ResourceLoader::makeInlineScript(
+                                                               Xml::encodeJsCall( 'mw.loader.load', [ $url ] ),
+                                                               $nonce
+                                                       );
                                                }
 
                                                if ( $group == 'noscript' ) {
index 67de192..7afbfb2 100644 (file)
@@ -63,19 +63,16 @@ class ResourceLoaderContext implements MessageLocalizer {
                $this->request = $request;
                $this->logger = $resourceLoader->getLogger();
 
-               // Future developers: Use WebRequest::getRawVal() instead getVal().
+               // Future developers: Use WebRequest::getRawVal() instead of getVal().
                // The getVal() method performs slow Language+UTF logic. (f303bb9360)
 
                // List of modules
                $modules = $request->getRawVal( 'modules' );
-               $this->modules = $modules ? self::expandModuleNames( $modules ) : [];
+               $this->modules = $modules ? ResourceLoader::expandModuleNames( $modules ) : [];
 
                // Various parameters
                $this->user = $request->getRawVal( 'user' );
-               $this->debug = $request->getFuzzyBool(
-                       'debug',
-                       $this->getConfig()->get( 'ResourceLoaderDebug' )
-               );
+               $this->debug = $request->getRawVal( 'debug' ) === 'true';
                $this->only = $request->getRawVal( 'only', null );
                $this->version = $request->getRawVal( 'version', null );
                $this->raw = $request->getFuzzyBool( 'raw' );
@@ -94,40 +91,16 @@ class ResourceLoaderContext implements MessageLocalizer {
        }
 
        /**
-        * Expand a string of the form `jquery.foo,bar|jquery.ui.baz,quux` to
-        * an array of module names like `[ 'jquery.foo', 'jquery.bar',
-        * 'jquery.ui.baz', 'jquery.ui.quux' ]`.
-        *
-        * This process is reversed by ResourceLoader::makePackedModulesString().
+        * Reverse the process done by ResourceLoader::makePackedModulesString().
         *
+        * @deprecated since 1.33 Use ResourceLoader::expandModuleNames instead.
         * @param string $modules Packed module name list
         * @return array Array of module names
+        * @codeCoverageIgnore
         */
        public static function expandModuleNames( $modules ) {
-               $retval = [];
-               $exploded = explode( '|', $modules );
-               foreach ( $exploded as $group ) {
-                       if ( strpos( $group, ',' ) === false ) {
-                               // This is not a set of modules in foo.bar,baz notation
-                               // but a single module
-                               $retval[] = $group;
-                       } else {
-                               // This is a set of modules in foo.bar,baz notation
-                               $pos = strrpos( $group, '.' );
-                               if ( $pos === false ) {
-                                       // Prefixless modules, i.e. without dots
-                                       $retval = array_merge( $retval, explode( ',', $group ) );
-                               } else {
-                                       // We have a prefix and a bunch of suffixes
-                                       $prefix = substr( $group, 0, $pos ); // 'foo'
-                                       $suffixes = explode( ',', substr( $group, $pos + 1 ) ); // [ 'bar', 'baz' ]
-                                       foreach ( $suffixes as $suffix ) {
-                                               $retval[] = "$prefix.$suffix";
-                                       }
-                               }
-                       }
-               }
-               return $retval;
+               wfDeprecated( __METHOD__, '1.33' );
+               return ResourceLoader::expandModuleNames( $modules );
        }
 
        /**
@@ -135,7 +108,6 @@ class ResourceLoaderContext implements MessageLocalizer {
         * things that don't "really" need a context.
         *
         * Use cases:
-        * - Creating html5shiv script tag in OutputPage.
         * - Unit tests (deprecated, create empty instance directly or use RLTestCase).
         *
         * @return ResourceLoaderContext
index 2848871..031541b 100644 (file)
@@ -198,10 +198,11 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *         ],
         *         // Scripts to include in debug contexts
         *         'debugScripts' => [file path string or array of file path strings],
-        *         // For package modules: files to make available for internal require() use
-        *         // 'type' is optional, and will be inferred from the file name extension if omitted
-        *         // 'config' can only be used when 'type' is 'data'; vars are resolved with Config::get()
-        *         // If 'packageFiles' is set, 'scripts' cannot also be set
+        *         // For package modules: files to be made available for internal require() do not
+        *         // need to have 'type' defined; it will be inferred from the file name extension
+        *         // if omitted. 'config' can only be used when 'type' is 'data'; the variables are
+        *         // resolved with Config::get(). The first entry in 'packageFiles' is always the
+        *         // module entry point. If 'packageFiles' is set, 'scripts' cannot also be set.
         *         'packageFiles' => [
         *             [file path string], // or:
         *             [ 'name' => [file name], 'file' => [file path], 'type' => 'script'|'data' ], // or:
@@ -384,7 +385,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                if ( $this->packageFiles !== null ) {
                        $packageFiles = $this->getPackageFiles( $context );
                        if ( $deprecationScript ) {
-                               $mainFile =& $packageFiles['files'][ $packageFiles['main'] ];
+                               $mainFile =& $packageFiles['files'][$packageFiles['main']];
                                $mainFile['content'] = $deprecationScript . $mainFile['content'];
                        }
                        return $packageFiles;
index 8cd5b19..27fa5ad 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\Shell\Shell;
+
 /**
  * Class encapsulating an image used in a ResourceLoaderImageModule.
  *
@@ -73,7 +75,7 @@ class ResourceLoaderImage {
                }
                // Remove 'deprecated' key
                if ( is_array( $this->descriptor ) ) {
-                       unset( $this->descriptor[ 'deprecated' ] );
+                       unset( $this->descriptor['deprecated'] );
                }
 
                // Ensure that all files have common extension.
@@ -373,7 +375,7 @@ class ResourceLoaderImage {
                if ( strpos( $wgSVGConverter, 'rsvg' ) === 0 ) {
                        $command = 'rsvg-convert';
                        if ( $wgSVGConverterPath ) {
-                               $command = wfEscapeShellArg( "$wgSVGConverterPath/" ) . $command;
+                               $command = Shell::escape( "$wgSVGConverterPath/" ) . $command;
                        }
 
                        $process = proc_open(
index b711cbd..9b50d80 100644 (file)
@@ -28,6 +28,7 @@
  */
 class ResourceLoaderImageModule extends ResourceLoaderModule {
 
+       /** @var array|null */
        protected $definition = null;
 
        /**
@@ -38,10 +39,18 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
 
        protected $origin = self::ORIGIN_CORE_SITEWIDE;
 
+       /** @var ResourceLoaderImage[]|null */
+       protected $imageObjects = null;
+       /** @var array */
        protected $images = [];
+       /** @var string|null */
        protected $defaultColor = null;
        protected $useDataURI = true;
+       /** @var array|null */
+       protected $globalVariants = null;
+       /** @var array */
        protected $variants = [];
+       /** @var string|null */
        protected $prefix = null;
        protected $selectorWithoutVariant = '.{prefix}-{name}';
        protected $selectorWithVariant = '.{prefix}-{name}-{variant}';
@@ -175,9 +184,9 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                                                $option = [ 'default' => $option ];
                                        }
                                        foreach ( $option as $skin => $data ) {
-                                               if ( !is_array( $option ) ) {
+                                               if ( !is_array( $data ) ) {
                                                        throw new InvalidArgumentException(
-                                                               "Invalid list error. '$option' given, array expected."
+                                                               "Invalid list error. '$data' given, array expected."
                                                        );
                                                }
                                        }
@@ -211,7 +220,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
 
        /**
         * Get CSS selector templates used by this module.
-        * @return string
+        * @return string[]
         */
        public function getSelectors() {
                $this->loadFromDefinition();
@@ -240,7 +249,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
         */
        public function getImages( ResourceLoaderContext $context ) {
                $skin = $context->getSkin();
-               if ( !isset( $this->imageObjects ) ) {
+               if ( $this->imageObjects === null ) {
                        $this->loadFromDefinition();
                        $this->imageObjects = [];
                }
@@ -288,7 +297,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
         */
        public function getGlobalVariants( ResourceLoaderContext $context ) {
                $skin = $context->getSkin();
-               if ( !isset( $this->globalVariants ) ) {
+               if ( $this->globalVariants === null ) {
                        $this->loadFromDefinition();
                        $this->globalVariants = [];
                }
@@ -419,7 +428,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                        'selectorWithVariant',
                ] as $member ) {
                        $options[$member] = $this->{$member};
-               };
+               }
 
                $summary[] = [
                        'options' => $options,
index b392625..aca5c73 100644 (file)
@@ -476,44 +476,51 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                        $localFileRefs = array_values( array_unique( $localFileRefs ) );
                        sort( $localFileRefs );
                        $localPaths = self::getRelativePaths( $localFileRefs );
-
                        $storedPaths = self::getRelativePaths( $this->getFileDependencies( $context ) );
-                       // If the list has been modified since last time we cached it, update the cache
-                       if ( $localPaths !== $storedPaths ) {
-                               $vary = $context->getSkin() . '|' . $context->getLanguage();
-                               $cache = ObjectCache::getLocalClusterInstance();
-                               $key = $cache->makeKey( __METHOD__, $this->getName(), $vary );
-                               $scopeLock = $cache->getScopedLock( $key, 0 );
-                               if ( !$scopeLock ) {
-                                       return; // T124649; avoid write slams
-                               }
 
-                               // No needless escaping as this isn't HTML output.
-                               // Only stored in the database and parsed in PHP.
-                               $deps = json_encode( $localPaths, JSON_UNESCAPED_SLASHES );
-                               $dbw = wfGetDB( DB_MASTER );
-                               $dbw->upsert( 'module_deps',
-                                       [
-                                               'md_module' => $this->getName(),
-                                               'md_skin' => $vary,
-                                               'md_deps' => $deps,
-                                       ],
-                                       [ 'md_module', 'md_skin' ],
-                                       [
-                                               'md_deps' => $deps,
-                                       ]
-                               );
+                       if ( $localPaths === $storedPaths ) {
+                               // Unchanged. Avoid needless database query (especially master conn!).
+                               return;
+                       }
 
-                               if ( $dbw->trxLevel() ) {
-                                       $dbw->onTransactionResolution(
-                                               function () use ( &$scopeLock ) {
-                                                       ScopedCallback::consume( $scopeLock ); // release after commit
-                                               },
-                                               __METHOD__
-                                       );
-                               }
+                       // The file deps list has changed, we want to update it.
+                       $vary = $context->getSkin() . '|' . $context->getLanguage();
+                       $cache = ObjectCache::getLocalClusterInstance();
+                       $key = $cache->makeKey( __METHOD__, $this->getName(), $vary );
+                       $scopeLock = $cache->getScopedLock( $key, 0 );
+                       if ( !$scopeLock ) {
+                               // Another request appears to be doing this update already.
+                               // Avoid write slams (T124649).
+                               return;
+                       }
+
+                       // No needless escaping as this isn't HTML output.
+                       // Only stored in the database and parsed in PHP.
+                       $deps = json_encode( $localPaths, JSON_UNESCAPED_SLASHES );
+                       $dbw = wfGetDB( DB_MASTER );
+                       $dbw->upsert( 'module_deps',
+                               [
+                                       'md_module' => $this->getName(),
+                                       'md_skin' => $vary,
+                                       'md_deps' => $deps,
+                               ],
+                               [ 'md_module', 'md_skin' ],
+                               [
+                                       'md_deps' => $deps,
+                               ]
+                       );
+
+                       if ( $dbw->trxLevel() ) {
+                               $dbw->onTransactionResolution(
+                                       function () use ( &$scopeLock ) {
+                                               ScopedCallback::consume( $scopeLock ); // release after commit
+                                       },
+                                       __METHOD__
+                               );
                        }
                } catch ( Exception $e ) {
+                       // Probably a DB failure. Either the read query from getFileDependencies(),
+                       // or the write query above.
                        wfDebugLog( 'resourceloader', __METHOD__ . ": failed to update DB: $e" );
                }
        }
@@ -734,7 +741,6 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                }
                $content['scripts'] = $scripts;
 
-               // Styles
                $styles = [];
                // Don't create empty stylesheets like [ '' => '' ] for modules
                // that don't *have* any stylesheets (T40024).
@@ -944,7 +950,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                if ( !$this->getConfig()->get( 'ResourceLoaderValidateJS' ) ) {
                        return $contents;
                }
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                return $cache->getWithSetCallback(
                        $cache->makeGlobalKey(
                                'resourceloader',
index e97e074..7d39a58 100644 (file)
@@ -28,15 +28,15 @@ class ResourceLoaderOOUIFileModule extends ResourceLoaderFileModule {
        use ResourceLoaderOOUIModule;
 
        public function __construct( $options = [] ) {
-               if ( isset( $options[ 'themeScripts' ] ) ) {
-                       $skinScripts = $this->getSkinSpecific( $options[ 'themeScripts' ], 'scripts' );
+               if ( isset( $options['themeScripts'] ) ) {
+                       $skinScripts = $this->getSkinSpecific( $options['themeScripts'], 'scripts' );
                        if ( !isset( $options['skinScripts'] ) ) {
                                $options['skinScripts'] = [];
                        }
                        $this->extendSkinSpecific( $options['skinScripts'], $skinScripts );
                }
-               if ( isset( $options[ 'themeStyles' ] ) ) {
-                       $skinStyles = $this->getSkinSpecific( $options[ 'themeStyles' ], 'styles' );
+               if ( isset( $options['themeStyles'] ) ) {
+                       $skinStyles = $this->getSkinSpecific( $options['themeStyles'], 'styles' );
                        if ( !isset( $options['skinStyles'] ) ) {
                                $options['skinStyles'] = [];
                        }
index 0a4e94e..0395127 100644 (file)
@@ -104,7 +104,7 @@ trait ResourceLoaderOOUIModule {
         */
        protected function getThemePath( $theme, $kind, $module ) {
                $paths = self::getThemePaths();
-               $path = $paths[ $theme ][ $kind ];
+               $path = $paths[$theme][$kind];
                $path = str_replace( '{module}', $module, $path );
                return $path;
        }
index e0fbeee..2dd6c17 100644 (file)
@@ -91,7 +91,6 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
        private function getLogoPreloadlinks() {
                $logo = $this->getLogoData( $this->getConfig() );
 
-               $tags = [];
                $logosPerDppx = [];
                $logos = [];
 
@@ -99,14 +98,14 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
 
                if ( !is_array( $logo ) ) {
                        // No media queries required if we only have one variant
-                       $preloadLinks[ $logo ] = [ 'as' => 'image' ];
+                       $preloadLinks[$logo] = [ 'as' => 'image' ];
                        return $preloadLinks;
                }
 
                if ( isset( $logo['svg'] ) ) {
                        // No media queries required if we only have a 1x and svg variant
                        // because all preload-capable browsers support SVGs
-                       $preloadLinks [ $logo['svg'] ] = [ 'as' => 'image' ];
+                       $preloadLinks[$logo['svg']] = [ 'as' => 'image' ];
                        return $preloadLinks;
                }
 
@@ -125,7 +124,10 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
                } );
 
                foreach ( $logosPerDppx as $dppx => $src ) {
-                       $logos[] = [ 'dppx' => $dppx, 'src' => $src ];
+                       $logos[] = [
+                               'dppx' => $dppx,
+                               'src' => $src
+                       ];
                }
 
                $logosCount = count( $logos );
@@ -139,21 +141,24 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
                                // Smallest dppx
                                // min-resolution is ">=" (larger than or equal to)
                                // "not min-resolution" is essentially "<"
-                               $media_query = 'not all and (min-resolution: ' . $logos[ 1 ]['dppx'] . 'dppx)';
+                               $media_query = 'not all and (min-resolution: ' . $logos[1]['dppx'] . 'dppx)';
                        } elseif ( $i !== $logosCount - 1 ) {
                                // In between
                                // Media query expressions can only apply "not" to the entire expression
                                // (e.g. can't express ">= 1.5 and not >= 2).
                                // Workaround: Use <= 1.9999 in place of < 2.
-                               $upper_bound = floatval( $logos[ $i + 1 ]['dppx'] ) - 0.000001;
-                               $media_query = '(min-resolution: ' . $logos[ $i ]['dppx'] .
+                               $upper_bound = floatval( $logos[$i + 1]['dppx'] ) - 0.000001;
+                               $media_query = '(min-resolution: ' . $logos[$i]['dppx'] .
                                        'dppx) and (max-resolution: ' . $upper_bound . 'dppx)';
                        } else {
                                // Largest dppx
-                               $media_query = '(min-resolution: ' . $logos[ $i ]['dppx'] . 'dppx)';
+                               $media_query = '(min-resolution: ' . $logos[$i]['dppx'] . 'dppx)';
                        }
 
-                       $preloadLinks[ $logos[$i]['src'] ] = [ 'as' => 'image', 'media' => $media_query ];
+                       $preloadLinks[$logos[$i]['src']] = [
+                               'as' => 'image',
+                               'media' => $media_query
+                       ];
                }
 
                return $preloadLinks;
index 334fc73..acc2503 100644 (file)
@@ -107,14 +107,12 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        'wgSiteName' => $conf->get( 'Sitename' ),
                        'wgDBname' => $conf->get( 'DBname' ),
                        'wgExtraSignatureNamespaces' => $conf->get( 'ExtraSignatureNamespaces' ),
-                       'wgAvailableSkins' => Skin::getSkinNames(),
                        'wgExtensionAssetsPath' => $conf->get( 'ExtensionAssetsPath' ),
                        // MediaWiki sets cookies to have this prefix by default
                        'wgCookiePrefix' => $conf->get( 'CookiePrefix' ),
                        'wgCookieDomain' => $conf->get( 'CookieDomain' ),
                        'wgCookiePath' => $conf->get( 'CookiePath' ),
                        'wgCookieExpiration' => $conf->get( 'CookieExpiration' ),
-                       'wgResourceLoaderMaxQueryLength' => $conf->get( 'ResourceLoaderMaxQueryLength' ),
                        'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces,
                        'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass( Title::legalChars() ),
                        'wgIllegalFileChars' => Title::convertByteClassToUnicodeClass( $illegalFileChars ),
@@ -387,6 +385,8 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         */
        public function getScript( ResourceLoaderContext $context ) {
                global $IP;
+               $conf = $this->getConfig();
+
                if ( $context->getOnly() !== 'scripts' ) {
                        return '/* Requires only=script */';
                }
@@ -400,13 +400,16 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                if ( $context->getDebug() ) {
                        $mwLoaderCode .= file_get_contents( "$IP/resources/src/startup/mediawiki.log.js" );
                }
-               if ( $this->getConfig()->get( 'ResourceLoaderEnableJSProfiler' ) ) {
+               if ( $conf->get( 'ResourceLoaderEnableJSProfiler' ) ) {
                        $mwLoaderCode .= file_get_contents( "$IP/resources/src/startup/profiler.js" );
                }
 
                // Perform replacements for mediawiki.js
                $mwLoaderPairs = [
                        '$VARS.baseModules' => ResourceLoader::encodeJsonForScript( $this->getBaseModules() ),
+                       '$VARS.maxQueryLength' => ResourceLoader::encodeJsonForScript(
+                               $conf->get( 'ResourceLoaderMaxQueryLength' )
+                       ),
                ];
                $profilerStubs = [
                        '$CODE.profileExecuteStart();' => 'mw.loader.profiler.onExecuteStart( module );',
@@ -414,7 +417,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        '$CODE.profileScriptStart();' => 'mw.loader.profiler.onScriptStart( module );',
                        '$CODE.profileScriptEnd();' => 'mw.loader.profiler.onScriptEnd( module );',
                ];
-               if ( $this->getConfig()->get( 'ResourceLoaderEnableJSProfiler' ) ) {
+               if ( $conf->get( 'ResourceLoaderEnableJSProfiler' ) ) {
                        // When profiling is enabled, insert the calls.
                        $mwLoaderPairs += $profilerStubs;
                } else {
@@ -426,7 +429,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                // Perform string replacements for startup.js
                $pairs = [
                        '$VARS.wgLegacyJavaScriptGlobals' => ResourceLoader::encodeJsonForScript(
-                               $this->getConfig()->get( 'LegacyJavaScriptGlobals' )
+                               $conf->get( 'LegacyJavaScriptGlobals' )
                        ),
                        '$VARS.configuration' => ResourceLoader::encodeJsonForScript(
                                $this->getConfigSettings( $context )
index ecb1a09..9fad348 100644 (file)
@@ -26,6 +26,7 @@ use MediaWiki\Linker\LinkTarget;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Abstraction for ResourceLoader modules which pull from wiki pages
@@ -432,7 +433,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                                // Avoid including ids or timestamps of revision/page tables so
                                // that versions are not wasted
                                $title = new TitleValue( (int)$row->page_namespace, $row->page_title );
-                               $titleInfo[ self::makeTitleKey( $title ) ] = [
+                               $titleInfo[self::makeTitleKey( $title )] = [
                                        'page_len' => $row->page_len,
                                        'page_latest' => $row->page_latest,
                                        'page_touched' => $row->page_touched,
@@ -482,7 +483,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                $func = [ static::class, 'fetchTitleInfo' ];
                $fname = __METHOD__;
 
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                $allInfo = $cache->getWithSetCallback(
                        $cache->makeGlobalKey( 'resourceloader', 'titleinfo', $db->getDomainID(), $hash ),
                        $cache::TTL_HOUR,
@@ -549,7 +550,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                }
 
                if ( $purge ) {
-                       $cache = ObjectCache::getMainWANInstance();
+                       $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                        $key = $cache->makeGlobalKey( 'resourceloader', 'titleinfo', $domain );
                        $cache->touchCheckKey( $key );
                }
index 7ddf587..221359d 100644 (file)
@@ -224,8 +224,21 @@ abstract class RevDelList extends RevisionListBase {
                                        } elseif ( IP::isIPAddress( $item->getAuthorName() ) ) {
                                                $authorIPs[] = $item->getAuthorName();
                                        }
-                               }
-                               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
+                                       if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
+                                               $actorId = $item->getAuthorActor();
+                                               // During migration, the actor field might be empty. If so, populate
+                                               // it here.
+                                               if ( !$actorId ) {
+                                                       if ( $item->getAuthorId() > 0 ) {
+                                                               $user = User::newFromId( $item->getAuthorId() );
+                                                       } else {
+                                                               $user = User::newFromName( $item->getAuthorName(), false );
+                                                       }
+                                                       $actorId = $user->getActorId( $dbw );
+                                               }
+                                               $authorActors[] = $actorId;
+                                       }
+                               } elseif ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
                                        $authorActors[] = $item->getAuthorActor();
                                }
 
index bf28f60..54a715d 100644 (file)
@@ -105,7 +105,7 @@ class RevDelLogItem extends RevDelItem {
                $loglink = $this->list->msg( 'parentheses' )->rawParams( $loglink )->escaped();
                // User links and action text
                $action = $formatter->getActionText();
-               // Comment
+
                $comment = CommentStore::getStore()->getComment( 'log_comment', $this->row )->text;
                $comment = $this->list->getLanguage()->getDirMark()
                        . Linker::commentBlock( $comment );
diff --git a/includes/revisionlist/RevisionItem.php b/includes/revisionlist/RevisionItem.php
new file mode 100644 (file)
index 0000000..faf8d82
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Holders of revision list for a single page
+ *
+ * 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
+ */
+
+/**
+ * Item class for a live revision table row
+ */
+class RevisionItem extends RevisionItemBase {
+       /** @var Revision */
+       protected $revision;
+
+       /** @var RequestContext */
+       protected $context;
+
+       public function __construct( $list, $row ) {
+               parent::__construct( $list, $row );
+               $this->revision = new Revision( $row );
+               $this->context = $list->getContext();
+       }
+
+       public function getIdField() {
+               return 'rev_id';
+       }
+
+       public function getTimestampField() {
+               return 'rev_timestamp';
+       }
+
+       public function getAuthorIdField() {
+               return 'rev_user';
+       }
+
+       public function getAuthorNameField() {
+               return 'rev_user_text';
+       }
+
+       public function canView() {
+               return $this->revision->userCan( Revision::DELETED_RESTRICTED, $this->context->getUser() );
+       }
+
+       public function canViewContent() {
+               return $this->revision->userCan( Revision::DELETED_TEXT, $this->context->getUser() );
+       }
+
+       public function isDeleted() {
+               return $this->revision->isDeleted( Revision::DELETED_TEXT );
+       }
+
+       /**
+        * Get the HTML link to the revision text.
+        * @todo Essentially a copy of RevDelRevisionItem::getRevisionLink. That class
+        * should inherit from this one, and implement an appropriate interface instead
+        * of extending RevDelItem
+        * @return string
+        */
+       protected function getRevisionLink() {
+               $date = $this->list->getLanguage()->userTimeAndDate(
+                       $this->revision->getTimestamp(), $this->list->getUser() );
+
+               if ( $this->isDeleted() && !$this->canViewContent() ) {
+                       return htmlspecialchars( $date );
+               }
+               $linkRenderer = $this->getLinkRenderer();
+               return $linkRenderer->makeKnownLink(
+                       $this->list->title,
+                       $date,
+                       [],
+                       [
+                               'oldid' => $this->revision->getId(),
+                               'unhide' => 1
+                       ]
+               );
+       }
+
+       /**
+        * Get the HTML link to the diff.
+        * @todo Essentially a copy of RevDelRevisionItem::getDiffLink. That class
+        * should inherit from this one, and implement an appropriate interface instead
+        * of extending RevDelItem
+        * @return string
+        */
+       protected function getDiffLink() {
+               if ( $this->isDeleted() && !$this->canViewContent() ) {
+                       return $this->context->msg( 'diff' )->escaped();
+               } else {
+                       $linkRenderer = $this->getLinkRenderer();
+                       return $linkRenderer->makeKnownLink(
+                                       $this->list->title,
+                                       $this->list->msg( 'diff' )->text(),
+                                       [],
+                                       [
+                                               'diff' => $this->revision->getId(),
+                                               'oldid' => 'prev',
+                                               'unhide' => 1
+                                       ]
+                               );
+               }
+       }
+
+       /**
+        * @todo Essentially a copy of RevDelRevisionItem::getHTML. That class
+        * should inherit from this one, and implement an appropriate interface instead
+        * of extending RevDelItem
+        * @return string
+        */
+       public function getHTML() {
+               $difflink = $this->context->msg( 'parentheses' )
+                       ->rawParams( $this->getDiffLink() )->escaped();
+               $revlink = $this->getRevisionLink();
+               $userlink = Linker::revUserLink( $this->revision );
+               $comment = Linker::revComment( $this->revision );
+               if ( $this->isDeleted() ) {
+                       $revlink = "<span class=\"history-deleted\">$revlink</span>";
+               }
+               return "<li>$difflink $revlink $userlink $comment</li>";
+       }
+}
diff --git a/includes/revisionlist/RevisionItemBase.php b/includes/revisionlist/RevisionItemBase.php
new file mode 100644 (file)
index 0000000..dcb2f39
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Holders of revision list for a single page
+ *
+ * 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;
+
+/**
+ * Abstract base class for revision items
+ */
+abstract class RevisionItemBase {
+       /** @var RevisionListBase The parent */
+       protected $list;
+
+       /** The database result row */
+       protected $row;
+
+       /**
+        * @param RevisionListBase $list
+        * @param object $row DB result row
+        */
+       public function __construct( $list, $row ) {
+               $this->list = $list;
+               $this->row = $row;
+       }
+
+       /**
+        * Get the DB field name associated with the ID list.
+        * Override this function.
+        * @return null
+        */
+       public function getIdField() {
+               return null;
+       }
+
+       /**
+        * Get the DB field name storing timestamps.
+        * Override this function.
+        * @return bool
+        */
+       public function getTimestampField() {
+               return false;
+       }
+
+       /**
+        * Get the DB field name storing user ids.
+        * Override this function.
+        * @return bool
+        */
+       public function getAuthorIdField() {
+               return false;
+       }
+
+       /**
+        * Get the DB field name storing user names.
+        * Override this function.
+        * @return bool
+        */
+       public function getAuthorNameField() {
+               return false;
+       }
+
+       /**
+        * Get the DB field name storing actor ids.
+        * Override this function.
+        * @since 1.31
+        * @return bool
+        */
+       public function getAuthorActorField() {
+               return false;
+       }
+
+       /**
+        * Get the ID, as it would appear in the ids URL parameter
+        * @return int
+        */
+       public function getId() {
+               $field = $this->getIdField();
+               return $this->row->$field;
+       }
+
+       /**
+        * Get the date, formatted in user's language
+        * @return string
+        */
+       public function formatDate() {
+               return $this->list->getLanguage()->userDate( $this->getTimestamp(),
+                       $this->list->getUser() );
+       }
+
+       /**
+        * Get the time, formatted in user's language
+        * @return string
+        */
+       public function formatTime() {
+               return $this->list->getLanguage()->userTime( $this->getTimestamp(),
+                       $this->list->getUser() );
+       }
+
+       /**
+        * Get the timestamp in MW 14-char form
+        * @return mixed
+        */
+       public function getTimestamp() {
+               $field = $this->getTimestampField();
+               return wfTimestamp( TS_MW, $this->row->$field );
+       }
+
+       /**
+        * Get the author user ID
+        * @return int
+        */
+       public function getAuthorId() {
+               $field = $this->getAuthorIdField();
+               return intval( $this->row->$field );
+       }
+
+       /**
+        * Get the author user name
+        * @return string
+        */
+       public function getAuthorName() {
+               $field = $this->getAuthorNameField();
+               return strval( $this->row->$field );
+       }
+
+       /**
+        * Get the author actor ID
+        * @since 1.31
+        * @return string
+        */
+       public function getAuthorActor() {
+               $field = $this->getAuthorActorField();
+               return strval( $this->row->$field );
+       }
+
+       /**
+        * Returns true if the current user can view the item
+        */
+       abstract public function canView();
+
+       /**
+        * Returns true if the current user can view the item text/file
+        */
+       abstract public function canViewContent();
+
+       /**
+        * Get the HTML of the list item. Should be include "<li></li>" tags.
+        * This is used to show the list in HTML form, by the special page.
+        */
+       abstract public function getHTML();
+
+       /**
+        * Returns an instance of LinkRenderer
+        * @return \MediaWiki\Linker\LinkRenderer
+        */
+       protected function getLinkRenderer() {
+               return MediaWikiServices::getInstance()->getLinkRenderer();
+       }
+}
diff --git a/includes/revisionlist/RevisionList.php b/includes/revisionlist/RevisionList.php
new file mode 100644 (file)
index 0000000..e7fab9b
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Holders of revision list for a single page
+ *
+ * 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 Wikimedia\Rdbms\IDatabase;
+
+class RevisionList extends RevisionListBase {
+       public function getType() {
+               return 'revision';
+       }
+
+       /**
+        * @param IDatabase $db
+        * @return mixed
+        */
+       public function doQuery( $db ) {
+               $conds = [ 'rev_page' => $this->title->getArticleID() ];
+               if ( $this->ids !== null ) {
+                       $conds['rev_id'] = array_map( 'intval', $this->ids );
+               }
+               $revQuery = Revision::getQueryInfo( [ 'page', 'user' ] );
+               return $db->select(
+                       $revQuery['tables'],
+                       $revQuery['fields'],
+                       $conds,
+                       __METHOD__,
+                       [ 'ORDER BY' => 'rev_id DESC' ],
+                       $revQuery['joins']
+               );
+       }
+
+       public function newItem( $row ) {
+               return new RevisionItem( $this, $row );
+       }
+}
diff --git a/includes/revisionlist/RevisionListBase.php b/includes/revisionlist/RevisionListBase.php
new file mode 100644 (file)
index 0000000..fb379c9
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Holders of revision list for a single page
+ *
+ * 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 Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
+
+/**
+ * List for revision table items for a single page
+ */
+abstract class RevisionListBase extends ContextSource implements Iterator {
+       /** @var Title */
+       public $title;
+
+       /** @var array */
+       protected $ids;
+
+       /** @var ResultWrapper|bool */
+       protected $res;
+
+       /** @var bool|Revision */
+       protected $current;
+
+       /**
+        * Construct a revision list for a given title
+        * @param IContextSource $context
+        * @param Title $title
+        */
+       function __construct( IContextSource $context, Title $title ) {
+               $this->setContext( $context );
+               $this->title = $title;
+       }
+
+       /**
+        * Select items only where the ID is any of the specified values
+        * @param array $ids
+        */
+       function filterByIds( array $ids ) {
+               $this->ids = $ids;
+       }
+
+       /**
+        * Get the internal type name of this list. Equal to the table name.
+        * Override this function.
+        * @return null
+        */
+       public function getType() {
+               return null;
+       }
+
+       /**
+        * Initialise the current iteration pointer
+        */
+       protected function initCurrent() {
+               $row = $this->res->current();
+               if ( $row ) {
+                       $this->current = $this->newItem( $row );
+               } else {
+                       $this->current = false;
+               }
+       }
+
+       /**
+        * Start iteration. This must be called before current() or next().
+        * @return Revision First list item
+        */
+       public function reset() {
+               if ( !$this->res ) {
+                       $this->res = $this->doQuery( wfGetDB( DB_REPLICA ) );
+               } else {
+                       $this->res->rewind();
+               }
+               $this->initCurrent();
+               return $this->current;
+       }
+
+       public function rewind() {
+               $this->reset();
+       }
+
+       /**
+        * Get the current list item, or false if we are at the end
+        * @return Revision
+        */
+       public function current() {
+               return $this->current;
+       }
+
+       /**
+        * Move the iteration pointer to the next list item, and return it.
+        * @return Revision
+        */
+       public function next() {
+               $this->res->next();
+               $this->initCurrent();
+               return $this->current;
+       }
+
+       public function key() {
+               return $this->res ? $this->res->key() : 0;
+       }
+
+       public function valid() {
+               return $this->res ? $this->res->valid() : false;
+       }
+
+       /**
+        * Get the number of items in the list.
+        * @return int
+        */
+       public function length() {
+               if ( !$this->res ) {
+                       return 0;
+               } else {
+                       return $this->res->numRows();
+               }
+       }
+
+       /**
+        * Do the DB query to iterate through the objects.
+        * @param IDatabase $db DB object to use for the query
+        */
+       abstract public function doQuery( $db );
+
+       /**
+        * Create an item object from a DB result row
+        * @param object $row
+        */
+       abstract public function newItem( $row );
+}
index ff1e8cb..22f5998 100644 (file)
@@ -22,6 +22,7 @@ class NullIndexField implements SearchIndexField {
         * @return $this
         */
        public function setFlag( $flag, $unset = false ) {
+               return $this;
        }
 
        /**
diff --git a/includes/search/PrefixSearch.php b/includes/search/PrefixSearch.php
new file mode 100644 (file)
index 0000000..aa429b2
--- /dev/null
@@ -0,0 +1,327 @@
+<?php
+/**
+ * Prefix search of page names.
+ *
+ * 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;
+
+/**
+ * Handles searching prefixes of titles and finding any page
+ * names that match. Used largely by the OpenSearch implementation.
+ * @deprecated Since 1.27, Use SearchEngine::defaultPrefixSearch or SearchEngine::completionSearch
+ *
+ * @ingroup Search
+ */
+abstract class PrefixSearch {
+       /**
+        * Do a prefix search of titles and return a list of matching page names.
+        * @deprecated Since 1.23, use TitlePrefixSearch or StringPrefixSearch classes
+        *
+        * @param string $search
+        * @param int $limit
+        * @param array $namespaces Used if query is not explicitly prefixed
+        * @param int $offset How many results to offset from the beginning
+        * @return array Array of strings
+        */
+       public static function titleSearch( $search, $limit, $namespaces = [], $offset = 0 ) {
+               $prefixSearch = new StringPrefixSearch;
+               return $prefixSearch->search( $search, $limit, $namespaces, $offset );
+       }
+
+       /**
+        * Do a prefix search of titles and return a list of matching page names.
+        *
+        * @param string $search
+        * @param int $limit
+        * @param array $namespaces Used if query is not explicitly prefixed
+        * @param int $offset How many results to offset from the beginning
+        * @return array Array of strings or Title objects
+        */
+       public function search( $search, $limit, $namespaces = [], $offset = 0 ) {
+               $search = trim( $search );
+               if ( $search == '' ) {
+                       return []; // Return empty result
+               }
+
+               $hasNamespace = SearchEngine::parseNamespacePrefixes( $search, false, true );
+               if ( $hasNamespace !== false ) {
+                       list( $search, $namespaces ) = $hasNamespace;
+               }
+
+               return $this->searchBackend( $namespaces, $search, $limit, $offset );
+       }
+
+       /**
+        * Do a prefix search for all possible variants of the prefix
+        * @param string $search
+        * @param int $limit
+        * @param array $namespaces
+        * @param int $offset How many results to offset from the beginning
+        *
+        * @return array
+        */
+       public function searchWithVariants( $search, $limit, array $namespaces, $offset = 0 ) {
+               $searches = $this->search( $search, $limit, $namespaces, $offset );
+
+               // if the content language has variants, try to retrieve fallback results
+               $fallbackLimit = $limit - count( $searches );
+               if ( $fallbackLimit > 0 ) {
+                       $fallbackSearches = MediaWikiServices::getInstance()->getContentLanguage()->
+                               autoConvertToAllVariants( $search );
+                       $fallbackSearches = array_diff( array_unique( $fallbackSearches ), [ $search ] );
+
+                       foreach ( $fallbackSearches as $fbs ) {
+                               $fallbackSearchResult = $this->search( $fbs, $fallbackLimit, $namespaces );
+                               $searches = array_merge( $searches, $fallbackSearchResult );
+                               $fallbackLimit -= count( $fallbackSearchResult );
+
+                               if ( $fallbackLimit == 0 ) {
+                                       break;
+                               }
+                       }
+               }
+               return $searches;
+       }
+
+       /**
+        * When implemented in a descendant class, receives an array of Title objects and returns
+        * either an unmodified array or an array of strings corresponding to titles passed to it.
+        *
+        * @param array $titles
+        * @return array
+        */
+       abstract protected function titles( array $titles );
+
+       /**
+        * When implemented in a descendant class, receives an array of titles as strings and returns
+        * either an unmodified array or an array of Title objects corresponding to strings received.
+        *
+        * @param array $strings
+        *
+        * @return array
+        */
+       abstract protected function strings( array $strings );
+
+       /**
+        * Do a prefix search of titles and return a list of matching page names.
+        * @param array $namespaces
+        * @param string $search
+        * @param int $limit
+        * @param int $offset How many results to offset from the beginning
+        * @return array Array of strings
+        */
+       protected function searchBackend( $namespaces, $search, $limit, $offset ) {
+               if ( count( $namespaces ) == 1 ) {
+                       $ns = $namespaces[0];
+                       if ( $ns == NS_MEDIA ) {
+                               $namespaces = [ NS_FILE ];
+                       } elseif ( $ns == NS_SPECIAL ) {
+                               return $this->titles( $this->specialSearch( $search, $limit, $offset ) );
+                       }
+               }
+               $srchres = [];
+               if ( Hooks::run(
+                       'PrefixSearchBackend',
+                       [ $namespaces, $search, $limit, &$srchres, $offset ]
+               ) ) {
+                       return $this->titles( $this->defaultSearchBackend( $namespaces, $search, $limit, $offset ) );
+               }
+               return $this->strings(
+                       $this->handleResultFromHook( $srchres, $namespaces, $search, $limit, $offset ) );
+       }
+
+       private function handleResultFromHook( $srchres, $namespaces, $search, $limit, $offset ) {
+               if ( $offset === 0 ) {
+                       // Only perform exact db match if offset === 0
+                       // This is still far from perfect but at least we avoid returning the
+                       // same title afain and again when the user is scrolling with a query
+                       // that matches a title in the db.
+                       $rescorer = new SearchExactMatchRescorer();
+                       $srchres = $rescorer->rescore( $search, $namespaces, $srchres, $limit );
+               }
+               return $srchres;
+       }
+
+       /**
+        * Prefix search special-case for Special: namespace.
+        *
+        * @param string $search Term
+        * @param int $limit Max number of items to return
+        * @param int $offset Number of items to offset
+        * @return array
+        */
+       protected function specialSearch( $search, $limit, $offset ) {
+               $searchParts = explode( '/', $search, 2 );
+               $searchKey = $searchParts[0];
+               $subpageSearch = $searchParts[1] ?? null;
+
+               // Handle subpage search separately.
+               $spFactory = MediaWikiServices::getInstance()->getSpecialPageFactory();
+               if ( $subpageSearch !== null ) {
+                       // Try matching the full search string as a page name
+                       $specialTitle = Title::makeTitleSafe( NS_SPECIAL, $searchKey );
+                       if ( !$specialTitle ) {
+                               return [];
+                       }
+                       $special = $spFactory->getPage( $specialTitle->getText() );
+                       if ( $special ) {
+                               $subpages = $special->prefixSearchSubpages( $subpageSearch, $limit, $offset );
+                               return array_map( function ( $sub ) use ( $specialTitle ) {
+                                       return $specialTitle->getSubpage( $sub );
+                               }, $subpages );
+                       } else {
+                               return [];
+                       }
+               }
+
+               # normalize searchKey, so aliases with spaces can be found - T27675
+               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
+               $searchKey = str_replace( ' ', '_', $searchKey );
+               $searchKey = $contLang->caseFold( $searchKey );
+
+               // Unlike SpecialPage itself, we want the canonical forms of both
+               // canonical and alias title forms...
+               $keys = [];
+               foreach ( $spFactory->getNames() as $page ) {
+                       $keys[$contLang->caseFold( $page )] = [ 'page' => $page, 'rank' => 0 ];
+               }
+
+               foreach ( $contLang->getSpecialPageAliases() as $page => $aliases ) {
+                       if ( !in_array( $page, $spFactory->getNames() ) ) {# T22885
+                               continue;
+                       }
+
+                       foreach ( $aliases as $key => $alias ) {
+                               $keys[$contLang->caseFold( $alias )] = [ 'page' => $alias, 'rank' => $key ];
+                       }
+               }
+               ksort( $keys );
+
+               $matches = [];
+               foreach ( $keys as $pageKey => $page ) {
+                       if ( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
+                               // 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'
+                               $matches[$page['rank']][] = Title::makeTitleSafe( NS_SPECIAL, $page['page'] );
+
+                               if ( isset( $matches[0] ) && count( $matches[0] ) >= $limit + $offset ) {
+                                       // We have enough items in primary rank, no use to continue
+                                       break;
+                               }
+                       }
+
+               }
+
+               // Ensure keys are in order
+               ksort( $matches );
+               // Flatten the array
+               $matches = array_reduce( $matches, 'array_merge', [] );
+
+               return array_slice( $matches, $offset, $limit );
+       }
+
+       /**
+        * Unless overridden by PrefixSearchBackend hook...
+        * This is case-sensitive (First character may
+        * be automatically capitalized by Title::secureAndSpit()
+        * later on depending on $wgCapitalLinks)
+        *
+        * @param array|null $namespaces Namespaces to search in
+        * @param string $search Term
+        * @param int $limit Max number of items to return
+        * @param int $offset Number of items to skip
+        * @return Title[] Array of Title objects
+        */
+       public function defaultSearchBackend( $namespaces, $search, $limit, $offset ) {
+               // Backwards compatability with old code. Default to NS_MAIN if no namespaces provided.
+               if ( $namespaces === null ) {
+                       $namespaces = [];
+               }
+               if ( !$namespaces ) {
+                       $namespaces[] = NS_MAIN;
+               }
+
+               // Construct suitable prefix for each namespace. They differ in cases where
+               // some namespaces always capitalize and some don't.
+               $prefixes = [];
+               foreach ( $namespaces as $namespace ) {
+                       // For now, if special is included, ignore the other namespaces
+                       if ( $namespace == NS_SPECIAL ) {
+                               return $this->specialSearch( $search, $limit, $offset );
+                       }
+
+                       $title = Title::makeTitleSafe( $namespace, $search );
+                       // Why does the prefix default to empty?
+                       $prefix = $title ? $title->getDBkey() : '';
+                       $prefixes[$prefix][] = $namespace;
+               }
+
+               $dbr = wfGetDB( DB_REPLICA );
+               // Often there is only one prefix that applies to all requested namespaces,
+               // but sometimes there are two if some namespaces do not always capitalize.
+               $conds = [];
+               foreach ( $prefixes as $prefix => $namespaces ) {
+                       $condition = [
+                               'page_namespace' => $namespaces,
+                               'page_title' . $dbr->buildLike( $prefix, $dbr->anyString() ),
+                       ];
+                       $conds[] = $dbr->makeList( $condition, LIST_AND );
+               }
+
+               $table = 'page';
+               $fields = [ 'page_id', 'page_namespace', 'page_title' ];
+               $conds = $dbr->makeList( $conds, LIST_OR );
+               $options = [
+                       'LIMIT' => $limit,
+                       'ORDER BY' => [ 'page_title', 'page_namespace' ],
+                       'OFFSET' => $offset
+               ];
+
+               $res = $dbr->select( $table, $fields, $conds, __METHOD__, $options );
+
+               return iterator_to_array( TitleArray::newFromResult( $res ) );
+       }
+
+       /**
+        * Validate an array of numerical namespace indexes
+        *
+        * @param array $namespaces
+        * @return array (default: contains only NS_MAIN)
+        */
+       protected function validateNamespaces( $namespaces ) {
+               // We will look at each given namespace against content language namespaces
+               $validNamespaces = MediaWikiServices::getInstance()->getContentLanguage()->getNamespaces();
+               if ( is_array( $namespaces ) && count( $namespaces ) > 0 ) {
+                       $valid = [];
+                       foreach ( $namespaces as $ns ) {
+                               if ( is_numeric( $ns ) && array_key_exists( $ns, $validNamespaces ) ) {
+                                       $valid[] = $ns;
+                               }
+                       }
+                       if ( count( $valid ) > 0 ) {
+                               return $valid;
+                       }
+               }
+
+               return [ NS_MAIN ];
+       }
+}
index 405db44..a3a8abe 100644 (file)
@@ -281,12 +281,11 @@ abstract class SearchEngine {
 
        /**
         * Get chars legal for search
-        * NOTE: usage as static is deprecated and preserved only as BC measure
         * @param int $type type of search chars (see self::CHARS_ALL
         * and self::CHARS_NO_SYNTAX). Defaults to CHARS_ALL
         * @return string
         */
-       public static function legalSearchChars( $type = self::CHARS_ALL ) {
+       public function legalSearchChars( $type = self::CHARS_ALL ) {
                return "A-Za-z_'.0-9\\x80-\\xFF\\-";
        }
 
@@ -894,13 +893,3 @@ abstract class SearchEngine {
                }
        }
 }
-
-/**
- * Dummy class to be used when non-supported Database engine is present.
- * @todo FIXME: Dummy class should probably try something at least mildly useful,
- * such as a LIKE search through titles.
- * @ingroup Search
- */
-class SearchEngineDummy extends SearchEngine {
-       // no-op
-}
diff --git a/includes/search/SearchEngineDummy.php b/includes/search/SearchEngineDummy.php
new file mode 100644 (file)
index 0000000..b3db28b
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Dummy search engine
+ *
+ * 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 Search
+ */
+
+/**
+ * Dummy class to be used when non-supported Database engine is present.
+ * @todo FIXME: Dummy class should probably try something at least mildly useful,
+ * such as a LIKE search through titles.
+ * @ingroup Search
+ */
+class SearchEngineDummy extends SearchEngine {
+       // no-op
+}
index 9f10697..cae3426 100644 (file)
@@ -149,7 +149,7 @@ class SearchMySQL extends SearchDatabase {
                return $regex;
        }
 
-       public static function legalSearchChars( $type = self::CHARS_ALL ) {
+       public function legalSearchChars( $type = self::CHARS_ALL ) {
                $searchChars = parent::legalSearchChars( $type );
                if ( $type === self::CHARS_ALL ) {
                        // " for phrase, * for wildcard
index 0cbb41c..6b2b403 100644 (file)
@@ -267,7 +267,7 @@ class SearchOracle extends SearchDatabase {
                        [] );
        }
 
-       public static function legalSearchChars( $type = self::CHARS_ALL ) {
+       public function legalSearchChars( $type = self::CHARS_ALL ) {
                $searchChars = parent::legalSearchChars( $type );
                if ( $type === self::CHARS_ALL ) {
                        $searchChars = "\"" . $searchChars;
index 6d5f117..74ee552 100644 (file)
@@ -23,6 +23,8 @@
  * @file
  * @ingroup Search
  */
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\SlotRecord;
 
 /**
  * Search engine hook base class for Postgres
@@ -137,10 +139,16 @@ class SearchPostgres extends SearchDatabase {
                $top = $res->fetchRow()[0];
 
                $this->searchTerms = [];
+               $slotRoleStore = MediaWikiServices::getInstance()->getSlotRoleStore();
                if ( $top === "" ) { # # e.g. if only stopwords are used XXX return something better
                        $query = "SELECT page_id, page_namespace, page_title, 0 AS score " .
-                               "FROM page p, revision r, pagecontent c WHERE p.page_latest = r.rev_id " .
-                               "AND r.rev_text_id = c.old_id AND 1=0";
+                               "FROM page p, revision r, slots s, content c, pagecontent pc " .
+                               "WHERE p.page_latest = r.rev_id " .
+                               "AND s.slot_revision_id = r.rev_id " .
+                               "AND s.slot_role_id = " . $slotRoleStore->getId( SlotRecord::MAIN ) . " " .
+                               "AND c.content_id = s.slot_content_id " .
+                               "AND pc.old_id = substring( c.content_address from '^tt:([0-9]+)$' )::int " .
+                               "AND 1=0";
                } else {
                        $m = [];
                        if ( preg_match_all( "/'([^']+)'/", $top, $m, PREG_SET_ORDER ) ) {
@@ -151,10 +159,14 @@ class SearchPostgres extends SearchDatabase {
 
                        $query = "SELECT page_id, page_namespace, page_title, " .
                                "ts_rank($fulltext, to_tsquery($searchstring), 5) AS score " .
-                               "FROM page p, revision r, pagecontent c WHERE p.page_latest = r.rev_id " .
-                               "AND r.rev_text_id = c.old_id AND $fulltext @@ to_tsquery($searchstring)";
+                               "FROM page p, revision r, slots s, content c, pagecontent pc " .
+                               "WHERE p.page_latest = r.rev_id " .
+                               "AND s.slot_revision_id = r.rev_id " .
+                               "AND s.slot_role_id = " . $slotRoleStore->getId( SlotRecord::MAIN ) . " " .
+                               "AND c.content_id = s.slot_content_id " .
+                               "AND pc.old_id = substring( c.content_address from '^tt:([0-9]+)$' )::int " .
+                               "AND $fulltext @@ to_tsquery($searchstring)";
                }
-
                # # Namespaces - defaults to 0
                if ( !is_null( $this->namespaces ) ) { // null -> search all
                        if ( count( $this->namespaces ) < 1 ) {
@@ -178,9 +190,17 @@ class SearchPostgres extends SearchDatabase {
 
        function update( $pageid, $title, $text ) {
                # # We don't want to index older revisions
-               $sql = "UPDATE pagecontent SET textvector = NULL WHERE textvector IS NOT NULL and old_id IN " .
-                               "(SELECT DISTINCT rev_text_id FROM revision WHERE rev_page = " . intval( $pageid ) .
-                               " ORDER BY rev_text_id DESC OFFSET 1)";
+               $slotRoleStore = MediaWikiServices::getInstance()->getSlotRoleStore();
+               $sql = "UPDATE pagecontent SET textvector = NULL " .
+                       "WHERE textvector IS NOT NULL " .
+                       "AND old_id IN " .
+                       "(SELECT DISTINCT substring( c.content_address from '^tt:([0-9]+)$' )::int AS old_rev_text_id " .
+                       " FROM content c, slots s, revision r " .
+                       " WHERE r.rev_page = $pageid " .
+                       " AND s.slot_revision_id = r.rev_id " .
+                       " AND s.slot_role_id = " . $slotRoleStore->getId( SlotRecord::MAIN ) . " " .
+                       " AND c.content_id = s.slot_content_id " .
+                       " ORDER BY old_rev_text_id DESC OFFSET 1)";
                $this->db->query( $sql );
                return true;
        }
index f653796..c304797 100644 (file)
@@ -142,7 +142,7 @@ class SearchSqlite extends SearchDatabase {
                return $regex;
        }
 
-       public static function legalSearchChars( $type = self::CHARS_ALL ) {
+       public function legalSearchChars( $type = self::CHARS_ALL ) {
                $searchChars = parent::legalSearchChars( $type );
                if ( $type === self::CHARS_ALL ) {
                        // " for phrase, * for wildcard
diff --git a/includes/search/StringPrefixSearch.php b/includes/search/StringPrefixSearch.php
new file mode 100644 (file)
index 0000000..517518e
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Prefix search of page names.
+ *
+ * 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
+ */
+
+/**
+ * Performs prefix search, returning strings
+ * @deprecated Since 1.27, Use SearchEngine::prefixSearchSubpages or SearchEngine::completionSearch
+ * @ingroup Search
+ */
+class StringPrefixSearch extends PrefixSearch {
+
+       protected function titles( array $titles ) {
+               return array_map( function ( Title $t ) {
+                       return $t->getPrefixedText();
+               }, $titles );
+       }
+
+       protected function strings( array $strings ) {
+               return $strings;
+       }
+}
diff --git a/includes/search/TitlePrefixSearch.php b/includes/search/TitlePrefixSearch.php
new file mode 100644 (file)
index 0000000..a548dbf
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Prefix search of page names.
+ *
+ * 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
+ */
+
+/**
+ * Performs prefix search, returning Title objects
+ * @deprecated Since 1.27, Use SearchEngine::defaultPrefixSearch or SearchEngine::completionSearch
+ * @ingroup Search
+ */
+class TitlePrefixSearch extends PrefixSearch {
+
+       protected function titles( array $titles ) {
+               return $titles;
+       }
+
+       protected function strings( array $strings ) {
+               $titles = array_map( 'Title::newFromText', $strings );
+               $lb = new LinkBatch( $titles );
+               $lb->setCaller( __METHOD__ );
+               $lb->execute();
+               return $titles;
+       }
+}
index aaa522a..6ad00ea 100644 (file)
@@ -35,7 +35,10 @@ use WebRequest;
  */
 class CookieSessionProvider extends SessionProvider {
 
+       /** @var mixed[] */
        protected $params = [];
+
+       /** @var mixed[] */
        protected $cookieOptions = [];
 
        /**
index 200b913..149bb80 100644 (file)
@@ -41,6 +41,7 @@ abstract class ImmutableSessionProviderWithCookie extends SessionProvider {
 
        /** @var string|null */
        protected $sessionCookieName = null;
+       /** @var mixed[] */
        protected $sessionCookieOptions = [];
 
        /**
index 157cc52..f14e0eb 100644 (file)
@@ -37,6 +37,8 @@ class PHPSessionHandler implements \SessionHandlerInterface {
 
        /** @var bool Whether PHP session handling is enabled */
        protected $enable = false;
+
+       /** @var bool */
        protected $warn = true;
 
        /** @var SessionManager|null */
index 3dc8299..328958c 100644 (file)
@@ -537,7 +537,7 @@ final class Session implements \Countable, \Iterator, \ArrayAccess {
                // Extension::OATHAuth.
 
                // Unseal and check
-               $pieces = explode( '.', $encrypted );
+               $pieces = explode( '.', $encrypted, 4 );
                if ( count( $pieces ) !== 3 ) {
                        $ex = new \Exception( 'Invalid sealed-secret format' );
                        $this->logger->warning( $ex->getMessage(), [ 'exception' => $ex ] );
index f3bfb2b..0ea13e2 100644 (file)
@@ -50,15 +50,25 @@ final class SessionBackend {
        /** @var SessionId */
        private $id;
 
+       /** @var bool */
        private $persist = false;
+
+       /** @var bool */
        private $remember = false;
+
+       /** @var bool */
        private $forceHTTPS = false;
 
        /** @var array|null */
        private $data = null;
 
+       /** @var bool */
        private $forcePersist = false;
+
+       /** @var bool */
        private $metaDirty = false;
+
+       /** @var bool */
        private $dataDirty = false;
 
        /** @var string Used to detect subarray modifications */
@@ -76,6 +86,7 @@ final class SessionBackend {
        /** @var User */
        private $user;
 
+       /** @var int */
        private $curIndex = 0;
 
        /** @var WebRequest[] Session requests */
@@ -87,13 +98,21 @@ final class SessionBackend {
        /** @var array|null provider-specified metadata */
        private $providerMetadata = null;
 
+       /** @var int */
        private $expires = 0;
+
+       /** @var int */
        private $loggedOut = 0;
+
+       /** @var int */
        private $delaySave = 0;
 
+       /** @var bool */
        private $usePhpSessionHandling = true;
+       /** @var bool */
        private $checkPHPSessionRecursionGuard = false;
 
+       /** @var bool */
        private $shutdown = false;
 
        /**
@@ -251,6 +270,8 @@ final class SessionBackend {
                        // Delete the data for the old session ID now
                        $this->store->delete( $this->store->makeKey( 'MWSession', $oldId ) );
                }
+
+               return $this->id;
        }
 
        /**
index 577e03a..a7bbcce 100644 (file)
@@ -50,10 +50,19 @@ class SessionInfo {
        /** @var UserInfo|null */
        private $userInfo = null;
 
+       /** @var bool */
        private $persisted = false;
+
+       /** @var bool */
        private $remembered = false;
+
+       /** @var bool */
        private $forceHTTPS = false;
+
+       /** @var bool */
        private $idIsSafe = false;
+
+       /** @var bool */
        private $forceUse = false;
 
        /** @var array|null */
index 385cc35..98c0499 100644 (file)
@@ -314,11 +314,6 @@ final class SessionManager implements SessionManagerInterface {
                $user->setToken();
                $user->saveSettings();
 
-               $authUser = \MediaWiki\Auth\AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$user ] );
-               if ( $authUser ) {
-                       $authUser->resetAuthToken();
-               }
-
                foreach ( $this->getProviders() as $provider ) {
                        $provider->invalidateSessionsForUser( $user );
                }
index 1f015b5..781fc33 100644 (file)
@@ -374,7 +374,7 @@ abstract class SessionProvider implements SessionProviderInterface, LoggerAwareI
        public function preventSessionsForUser( $username ) {
                if ( !$this->canChangeUser() ) {
                        throw new \BadMethodCallException(
-                               __METHOD__ . ' must be implmented when canChangeUser() is false'
+                               __METHOD__ . ' must be implemented when canChangeUser() is false'
                        );
                }
        }
index 14d239d..5165506 100644 (file)
@@ -34,8 +34,13 @@ class Token {
         * editing from certain broken proxies. */
        const SUFFIX = '+\\';
 
+       /** @var string */
        private $secret = '';
+
+       /** @var string */
        private $salt = '';
+
+       /** @var bool */
        private $new = false;
 
        /**
index c01b9ec..f5145a3 100644 (file)
@@ -49,6 +49,7 @@ use User;
  * @since 1.27
  */
 final class UserInfo {
+       /** @var bool */
        private $verified = false;
 
        /** @var User|null */
index 1936d00..ba8133f 100644 (file)
@@ -111,11 +111,10 @@ class Command {
         * Adds parameters to the command. All parameters are sanitized via Shell::escape().
         * Null values are ignored.
         *
-        * @param string|string[] $args,...
+        * @param string|string[] ...$args
         * @return $this
         */
-       public function params( /* ... */ ) {
-               $args = func_get_args();
+       public function params( ...$args ) {
                if ( count( $args ) === 1 && is_array( reset( $args ) ) ) {
                        // If only one argument has been passed, and that argument is an array,
                        // treat it as a list of arguments
@@ -130,11 +129,10 @@ class Command {
         * Adds unsafe parameters to the command. These parameters are NOT sanitized in any way.
         * Null values are ignored.
         *
-        * @param string|string[] $args,...
+        * @param string|string[] ...$args
         * @return $this
         */
-       public function unsafeParams( /* ... */ ) {
-               $args = func_get_args();
+       public function unsafeParams( ...$args ) {
                if ( count( $args ) === 1 && is_array( reset( $args ) ) ) {
                        // If only one argument has been passed, and that argument is an array,
                        // treat it as a list of arguments
@@ -429,7 +427,7 @@ class Command {
                        }
 
                        // clear get_last_error without actually raising an error
-                       // from https://secure.php.net/manual/en/function.error-get-last.php#113518
+                       // from https://www.php.net/manual/en/function.error-get-last.php#113518
                        // TODO replace with clear_last_error when requirements are bumped to PHP7
                        set_error_handler( function () {
                        }, 0 );
index c168a47..174d667 100644 (file)
  */
 
 /**
- * Provides a file-based cache of a SiteStore. The sites are stored in
- * a json file. (see docs/sitescache.txt regarding format)
- *
- * The cache can be built with the rebuildSitesCache.php maintenance script,
- * and a MediaWiki instance can be setup to use this by setting the
- * 'wgSitesCacheFile' configuration to the cache file location.
+ * Provides a file-based cache of a SiteStore, using a json file.
  *
  * @since 1.25
+ * @deprecated since 1.33 Use CachingSiteStore instead.
  */
 class FileBasedSiteLookup implements SiteLookup {
 
@@ -46,6 +42,7 @@ class FileBasedSiteLookup implements SiteLookup {
         * @param string $cacheFile
         */
        public function __construct( $cacheFile ) {
+               wfDeprecated( __CLASS__, '1.33' );
                $this->cacheFile = $cacheFile;
        }
 
index 01b2a3c..ec13765 100644 (file)
@@ -460,10 +460,10 @@ class Site implements Serializable {
         *
         * @since 1.21
         *
-        * @param string $languageCode
+        * @param string|null $languageCode
         */
        public function setLanguageCode( $languageCode ) {
-               if ( !Language::isValidCode( $languageCode ) ) {
+               if ( $languageCode !== null && !Language::isValidCode( $languageCode ) ) {
                        throw new InvalidArgumentException( "$languageCode is not a valid language code." );
                }
                $this->languageCode = $languageCode;
diff --git a/includes/site/SitesCacheFileBuilder.php b/includes/site/SitesCacheFileBuilder.php
deleted file mode 100644 (file)
index f0d6ce1..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.25
- *
- * @file
- *
- * @license GPL-2.0-or-later
- */
-class SitesCacheFileBuilder {
-
-       /**
-        * @var SiteLookup
-        */
-       private $siteLookup;
-
-       /**
-        * @var string
-        */
-       private $cacheFile;
-
-       /**
-        * @param SiteLookup $siteLookup
-        * @param string $cacheFile
-        */
-       public function __construct( SiteLookup $siteLookup, $cacheFile ) {
-               $this->siteLookup = $siteLookup;
-               $this->cacheFile = $cacheFile;
-       }
-
-       public function build() {
-               $this->sites = $this->siteLookup->getSites();
-               $this->cacheSites( $this->sites->getArrayCopy() );
-       }
-
-       /**
-        * @param Site[] $sites
-        *
-        * @throws MWException if in manualRecache mode
-        * @return bool
-        */
-       private function cacheSites( array $sites ) {
-               $sitesArray = [];
-
-               foreach ( $sites as $site ) {
-                       $globalId = $site->getGlobalId();
-                       $sitesArray[$globalId] = $this->getSiteAsArray( $site );
-               }
-
-               $json = json_encode( [
-                       'sites' => $sitesArray
-               ] );
-
-               $result = file_put_contents( $this->cacheFile, $json );
-
-               return $result !== false;
-       }
-
-       /**
-        * @param Site $site
-        *
-        * @return array
-        */
-       private function getSiteAsArray( Site $site ) {
-               $siteEntry = unserialize( $site->serialize() );
-               $siteIdentifiers = $this->buildLocalIdentifiers( $site );
-               $identifiersArray = [];
-
-               foreach ( $siteIdentifiers as $identifier ) {
-                       $identifiersArray[] = $identifier;
-               }
-
-               $siteEntry['identifiers'] = $identifiersArray;
-
-               return $siteEntry;
-       }
-
-       /**
-        * @param Site $site
-        *
-        * @return array Site local identifiers
-        */
-       private function buildLocalIdentifiers( Site $site ) {
-               $localIds = [];
-
-               foreach ( $site->getLocalIds() as $idType => $ids ) {
-                       foreach ( $ids as $id ) {
-                               $localIds[] = [
-                                       'type' => $idType,
-                                       'key' => $id
-                               ];
-                       }
-               }
-
-               return $localIds;
-       }
-
-}
index 02247bd..8fe35f0 100644 (file)
@@ -264,28 +264,26 @@ abstract class BaseTemplate extends QuickTemplate {
                                        $boxes[$boxName]['content'] = $content;
                                }
                        }
-               } else {
-                       if ( $hookContents ) {
-                               $boxes['TOOLBOXEND'] = [
-                                       'id' => 'p-toolboxend',
-                                       'header' => $boxes['TOOLBOX']['header'],
-                                       'generated' => false,
-                                       'content' => "<ul>{$hookContents}</ul>",
-                               ];
-                               // HACK: Make sure that TOOLBOXEND is sorted next to TOOLBOX
-                               $boxes2 = [];
-                               foreach ( $boxes as $key => $box ) {
-                                       if ( $key === 'TOOLBOXEND' ) {
-                                               continue;
-                                       }
-                                       $boxes2[$key] = $box;
-                                       if ( $key === 'TOOLBOX' ) {
-                                               $boxes2['TOOLBOXEND'] = $boxes['TOOLBOXEND'];
-                                       }
+               } elseif ( $hookContents ) {
+                       $boxes['TOOLBOXEND'] = [
+                               'id' => 'p-toolboxend',
+                               'header' => $boxes['TOOLBOX']['header'],
+                               'generated' => false,
+                               'content' => "<ul>{$hookContents}</ul>",
+                       ];
+                       // HACK: Make sure that TOOLBOXEND is sorted next to TOOLBOX
+                       $boxes2 = [];
+                       foreach ( $boxes as $key => $box ) {
+                               if ( $key === 'TOOLBOXEND' ) {
+                                       continue;
+                               }
+                               $boxes2[$key] = $box;
+                               if ( $key === 'TOOLBOX' ) {
+                                       $boxes2['TOOLBOXEND'] = $boxes['TOOLBOXEND'];
                                }
-                               $boxes = $boxes2;
-                               // END hack
                        }
+                       $boxes = $boxes2;
+                       // END hack
                }
 
                return $boxes;
index 1e688eb..5044301 100644 (file)
@@ -63,7 +63,7 @@ abstract class QuickTemplate {
         */
        public function extend( $name, $value ) {
                if ( $this->haveData( $name ) ) {
-                       $this->data[$name] = $this->data[$name] . $value;
+                       $this->data[$name] .= $value;
                } else {
                        $this->data[$name] = $value;
                }
index 54dfff3..ac41c46 100644 (file)
@@ -175,7 +175,6 @@ abstract class Skin extends ContextSource {
         */
        public function getDefaultModules() {
                $out = $this->getOutput();
-               $config = $this->getConfig();
                $user = $this->getUser();
 
                // Modules declared in the $modules literal are loaded
@@ -530,14 +529,14 @@ abstract class Skin extends ContextSource {
                $colon = $this->msg( 'colon-separator' )->escaped();
 
                if ( !empty( $allCats['normal'] ) ) {
-                       $t = $embed . implode( "{$pop}{$embed}", $allCats['normal'] ) . $pop;
+                       $t = $embed . implode( $pop . $embed, $allCats['normal'] ) . $pop;
 
                        $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
                        $linkPage = $this->msg( 'pagecategorieslink' )->inContentLanguage()->text();
                        $title = Title::newFromText( $linkPage );
                        $link = $title ? Linker::link( $title, $msg ) : $msg;
                        $s .= '<div id="mw-normal-catlinks" class="mw-normal-catlinks">' .
-                               $link . $colon . '<ul>' . $t . '</ul>' . '</div>';
+                               $link . $colon . '<ul>' . $t . '</ul></div>';
                }
 
                # Hidden categories
@@ -552,7 +551,7 @@ abstract class Skin extends ContextSource {
 
                        $s .= "<div id=\"mw-hidden-catlinks\" class=\"mw-hidden-catlinks$class\">" .
                                $this->msg( 'hidden-categories' )->numParams( count( $allCats['hidden'] ) )->escaped() .
-                               $colon . '<ul>' . $embed . implode( "{$pop}{$embed}", $allCats['hidden'] ) . $pop . '</ul>' .
+                               $colon . '<ul>' . $embed . implode( $pop . $embed, $allCats['hidden'] ) . $pop . '</ul>' .
                                '</div>';
                }
 
@@ -1525,7 +1524,6 @@ abstract class Skin extends ContextSource {
         *   should fall back to the next notice in its sequence
         */
        private function getCachedNotice( $name ) {
-               $needParse = false;
                $config = $this->getConfig();
 
                if ( $name === 'default' ) {
index c29c996..8f45f28 100644 (file)
@@ -171,6 +171,9 @@ class SkinTemplate extends Skin {
                return $languageLinks;
        }
 
+       /**
+        * @return QuickTemplate
+        */
        protected function setupTemplateForOutput() {
                $request = $this->getRequest();
                $user = $this->getUser();
@@ -386,14 +389,15 @@ class SkinTemplate extends Skin {
                $tpl->set( 'credits', false );
                $tpl->set( 'numberofwatchingusers', false );
                if ( $title->exists() ) {
-                       if ( $out->isArticle() ) {
-                               if ( $this->isRevisionCurrent() ) {
-                                       if ( $wgMaxCredits != 0 ) {
-                                               $tpl->set( 'credits', Action::factory( 'credits', $this->getWikiPage(),
-                                                       $this->getContext() )->getCredits( $wgMaxCredits, $wgShowCreditsIfMax ) );
-                                       } else {
-                                               $tpl->set( 'lastmod', $this->lastModified() );
-                                       }
+                       if ( $out->isArticle() && $this->isRevisionCurrent() ) {
+                               if ( $wgMaxCredits != 0 ) {
+                                       /** @var CreditsAction $action */
+                                       $action = Action::factory(
+                                               'credits', $this->getWikiPage(), $this->getContext() );
+                                       $tpl->set( 'credits',
+                                               $action->getCredits( $wgMaxCredits, $wgShowCreditsIfMax ) );
+                               } else {
+                                       $tpl->set( 'lastmod', $this->lastModified() );
                                }
                        }
                        if ( $out->showsCopyright() ) {
@@ -526,7 +530,9 @@ class SkinTemplate extends Skin {
                $html = '';
 
                if ( $personalTools === null ) {
-                       $personalTools = $tpl->getPersonalTools();
+                       $personalTools = ( $tpl instanceof BaseTemplate )
+                               ? $tpl->getPersonalTools()
+                               : [];
                }
 
                foreach ( $personalTools as $key => $item ) {
@@ -547,7 +553,7 @@ class SkinTemplate extends Skin {
                $tpl = $this->setupTemplateForOutput();
                $tpl->set( 'personal_urls', $this->buildPersonalUrls() );
 
-               return $tpl->getPersonalTools();
+               return ( $tpl instanceof BaseTemplate ) ? $tpl->getPersonalTools() : [];
        }
 
        /**
index c56cc65..101570f 100644 (file)
@@ -157,7 +157,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
                                if ( $request->wasPosted() ) {
                                        // unique ID in case the same special page is open in multiple browser tabs
                                        $uniqueId = MWCryptRand::generateHex( 6 );
-                                       $key = $key . ':' . $uniqueId;
+                                       $key .= ':' . $uniqueId;
 
                                        $queryParams = [ 'authUniqueId' => $uniqueId ] + $queryParams;
                                        $authData = array_diff_key( $request->getValues(),
@@ -181,7 +181,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
 
                $uniqueId = $request->getVal( 'authUniqueId' );
                if ( $uniqueId ) {
-                       $key = $key . ':' . $uniqueId;
+                       $key .= ':' . $uniqueId;
                        $authData = $authManager->getAuthenticationSessionData( $key );
                        if ( $authData ) {
                                $authManager->removeAuthenticationSessionData( $key );
@@ -710,7 +710,6 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
         * are shown closer to the bottom; weight defaults to 0. Negative weight is allowed.)
         * Keep order if weights are equal.
         * @param array &$formDescriptor
-        * @return array
         */
        protected static function sortFormDescriptorFields( array &$formDescriptor ) {
                $i = 0;
index c96cf8e..1b43a42 100644 (file)
@@ -25,6 +25,7 @@ use Wikimedia\Rdbms\DBQueryTimeoutError;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Special page which uses a ChangesList to show query results.
@@ -615,9 +616,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
        }
 
        /**
-        * Main execution point
-        *
-        * @param string $subpage
+        * @param string|null $subpage
         */
        public function execute( $subpage ) {
                $this->rcSubpage = $subpage;
@@ -845,7 +844,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
         * @return array Tag data
         */
        protected static function getChangeTagList( ResourceLoaderContext $context ) {
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                return $cache->getWithSetCallback(
                        $cache->makeKey( 'changeslistspecialpage-changetags', $context->getLanguage() ),
                        $cache::TTL_MINUTE * 10,
@@ -1053,6 +1052,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
         *
         * There is light processing to simplify core maintenance.
         * @param array $definition
+        * @phan-param array<int,array{class:string}> $definition
         */
        protected function registerFiltersFromDefinitions( array $definition ) {
                $autoFillPriority = -1;
index 81a0036..939460f 100644 (file)
@@ -31,7 +31,7 @@
 abstract class FormSpecialPage extends SpecialPage {
        /**
         * The sub-page of the special page.
-        * @var string
+        * @var string|null
         */
        protected $par = null;
 
@@ -166,7 +166,7 @@ abstract class FormSpecialPage extends SpecialPage {
        /**
         * Basic SpecialPage workflow: get a form, send it to the user; get some data back,
         *
-        * @param string $par Subpage string if one was specified
+        * @param string|null $par Subpage string if one was specified
         */
        public function execute( $par ) {
                $this->setParameter( $par );
@@ -188,7 +188,7 @@ abstract class FormSpecialPage extends SpecialPage {
 
        /**
         * Maybe do something interesting with the subpage parameter
-        * @param string $par
+        * @param string|null $par
         */
        protected function setParameter( $par ) {
                $this->par = $par;
@@ -203,9 +203,11 @@ abstract class FormSpecialPage extends SpecialPage {
        protected function checkExecutePermissions( User $user ) {
                $this->checkPermissions();
 
-               if ( $this->requiresUnblock() && $user->isBlocked() ) {
+               if ( $this->requiresUnblock() ) {
                        $block = $user->getBlock();
-                       throw new UserBlockedError( $block );
+                       if ( $block && $block->isSitewide() ) {
+                               throw new UserBlockedError( $block );
+                       }
                }
 
                if ( $this->requiresWrite() ) {
index 8df6493..722251d 100644 (file)
@@ -68,6 +68,7 @@ abstract class ImageQueryPage extends QueryPage {
 
        // Gotta override this since it's abstract
        function formatResult( $skin, $result ) {
+               return false;
        }
 
        /**
index 579ca19..46873b1 100644 (file)
@@ -46,13 +46,18 @@ abstract class QueryPage extends SpecialPage {
         * The number of rows returned by the query. Reading this variable
         * only makes sense in functions that are run after the query has been
         * done, such as preprocessResults() and formatRow().
+        *
+        * @var int
         */
        protected $numRows;
 
+       /**
+        * @var string|null
+        */
        protected $cachedTimestamp = null;
 
        /**
-        * Whether to show prev/next links
+        * @var bool Whether to show prev/next links
         */
        protected $shownavigation = true;
 
@@ -62,7 +67,8 @@ abstract class QueryPage extends SpecialPage {
         *
         * DO NOT CHANGE THIS LIST without testing that
         * maintenance/updateSpecialPages.php still works.
-        * @return array
+        *
+        * @return string[][]
         */
        public static function getPages() {
                static $qp = null;
@@ -166,7 +172,7 @@ abstract class QueryPage extends SpecialPage {
         * Subclasses return an array of fields to order by here. Don't append
         * DESC to the field names, that'll be done automatically if
         * sortDescending() returns true.
-        * @return array
+        * @return string[]
         * @since 1.18
         */
        function getOrderFields() {
@@ -378,7 +384,7 @@ abstract class QueryPage extends SpecialPage {
 
        /**
         * Get a DB connection to be used for slow recache queries
-        * @return IDatabase
+        * @return \Wikimedia\Rdbms\Database
         */
        function getRecacheDB() {
                return wfGetDB( DB_REPLICA, [ $this->getName(), 'QueryPage::recache', 'vslow' ] );
@@ -500,6 +506,9 @@ abstract class QueryPage extends SpecialPage {
                return [ 'value' ];
        }
 
+       /**
+        * @return string
+        */
        public function getCachedTimestamp() {
                if ( is_null( $this->cachedTimestamp ) ) {
                        $dbr = wfGetDB( DB_REPLICA );
@@ -569,7 +578,7 @@ abstract class QueryPage extends SpecialPage {
        /**
         * This is the actual workhorse. It does everything needed to make a
         * real, honest-to-gosh query page.
-        * @param string $par
+        * @param string|null $par
         */
        public function execute( $par ) {
                $user = $this->getUser();
@@ -649,8 +658,8 @@ abstract class QueryPage extends SpecialPage {
                                $miserMaxResults = $this->getConfig()->get( 'MiserMode' )
                                        && ( $this->offset + $this->limit >= $this->getMaxResults() );
                                $atEnd = ( $this->numRows <= $this->limit ) || $miserMaxResults;
-                               $paging = $this->getLanguage()->viewPrevNext( $this->getPageTitle( $par ), $this->offset,
-                                       $this->limit, $this->linkParameters(), $atEnd );
+                               $paging = $this->buildPrevNextNavigation( $this->offset,
+                                       $this->limit, $this->linkParameters(), $atEnd, $par );
                                $out->addHTML( '<p>' . $paging . '</p>' );
                        } else {
                                # No results to show, so don't bother with "showing X of Y" etc.
@@ -754,98 +763,6 @@ abstract class QueryPage extends SpecialPage {
        function preprocessResults( $db, $res ) {
        }
 
-       /**
-        * Similar to above, but packaging in a syndicated feed instead of a web page
-        * @param string $class
-        * @param int $limit
-        * @return bool
-        */
-       function doFeed( $class = '', $limit = 50 ) {
-               if ( !$this->getConfig()->get( 'Feed' ) ) {
-                       $this->getOutput()->addWikiMsg( 'feed-unavailable' );
-                       return false;
-               }
-
-               $limit = min( $limit, $this->getConfig()->get( 'FeedLimit' ) );
-
-               $feedClasses = $this->getConfig()->get( 'FeedClasses' );
-               if ( isset( $feedClasses[$class] ) ) {
-                       /** @var RSSFeed|AtomFeed $feed */
-                       $feed = new $feedClasses[$class](
-                               $this->feedTitle(),
-                               $this->feedDesc(),
-                               $this->feedUrl() );
-                       $feed->outHeader();
-
-                       $res = $this->reallyDoQuery( $limit, 0 );
-                       foreach ( $res as $obj ) {
-                               $item = $this->feedResult( $obj );
-                               if ( $item ) {
-                                       $feed->outItem( $item );
-                               }
-                       }
-
-                       $feed->outFooter();
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Override for custom handling. If the titles/links are ok, just do
-        * feedItemDesc()
-        * @param object $row
-        * @return FeedItem|null
-        */
-       function feedResult( $row ) {
-               if ( !isset( $row->title ) ) {
-                       return null;
-               }
-               $title = Title::makeTitle( intval( $row->namespace ), $row->title );
-               if ( $title ) {
-                       $date = $row->timestamp ?? '';
-                       $comments = '';
-                       if ( $title ) {
-                               $talkpage = $title->getTalkPage();
-                               $comments = $talkpage->getFullURL();
-                       }
-
-                       return new FeedItem(
-                               $title->getPrefixedText(),
-                               $this->feedItemDesc( $row ),
-                               $title->getFullURL(),
-                               $date,
-                               $this->feedItemAuthor( $row ),
-                               $comments );
-               } else {
-                       return null;
-               }
-       }
-
-       function feedItemDesc( $row ) {
-               return isset( $row->comment ) ? htmlspecialchars( $row->comment ) : '';
-       }
-
-       function feedItemAuthor( $row ) {
-               return $row->user_text ?? '';
-       }
-
-       function feedTitle() {
-               $desc = $this->getDescription();
-               $code = $this->getConfig()->get( 'LanguageCode' );
-               $sitename = $this->getConfig()->get( 'Sitename' );
-               return "$sitename - $desc [$code]";
-       }
-
-       function feedDesc() {
-               return $this->msg( 'tagline' )->text();
-       }
-
-       function feedUrl() {
-               return $this->getPageTitle()->getFullURL();
-       }
-
        /**
         * Creates a new LinkBatch object, adds all pages from the passed ResultWrapper (MUST include
         * title and optional the namespace field) and executes the batch. This operation will pre-cache
diff --git a/includes/specialpage/RedirectSpecialArticle.php b/includes/specialpage/RedirectSpecialArticle.php
new file mode 100644 (file)
index 0000000..b8dce3f
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Shortcuts to construct a special page alias.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Superclass for any RedirectSpecialPage which redirects the user
+ * to a particular article (as opposed to user contributions, logs, etc.).
+ *
+ * For security reasons these special pages are restricted to pass on
+ * the following subset of GET parameters to the target page while
+ * removing all others:
+ *
+ * - useskin, uselang, printable: to alter the appearance of the resulting page
+ *
+ * - redirect: allows viewing one's user page or talk page even if it is a
+ * redirect.
+ *
+ * - rdfrom: allows redirecting to one's user page or talk page from an
+ * external wiki with the "Redirect from..." notice.
+ *
+ * - limit, offset: Useful for linking to history of one's own user page or
+ * user talk page. For example, this would be a link to "the last edit to your
+ * user talk page in the year 2010":
+ * https://en.wikipedia.org/wiki/Special:MyPage?offset=20110000000000&limit=1&action=history
+ *
+ * - feed: would allow linking to the current user's RSS feed for their user
+ * talk page:
+ * https://en.wikipedia.org/w/index.php?title=Special:MyTalk&action=history&feed=rss
+ *
+ * - preloadtitle: Can be used to provide a default section title for a
+ * preloaded new comment on one's own talk page.
+ *
+ * - summary : Can be used to provide a default edit summary for a preloaded
+ * edit to one's own user page or talk page.
+ *
+ * - preview: Allows showing/hiding preview on first edit regardless of user
+ * preference, useful for preloaded edits where you know preview wouldn't be
+ * useful.
+ *
+ * - redlink: Affects the message the user sees if their talk page/user talk
+ * page does not currently exist. Avoids confusion for newbies with no user
+ * pages over why they got a "permission error" following this link:
+ * https://en.wikipedia.org/w/index.php?title=Special:MyPage&redlink=1
+ *
+ * - debug: determines whether the debug parameter is passed to load.php,
+ * which disables reformatting and allows scripts to be debugged. Useful
+ * when debugging scripts that manipulate one's own user page or talk page.
+ *
+ * @par Hook extension:
+ * Extensions can add to the redirect parameters list by using the hook
+ * RedirectSpecialArticleRedirectParams
+ *
+ * This hook allows extensions which add GET parameters like FlaggedRevs to
+ * retain those parameters when redirecting using special pages.
+ *
+ * @par Hook extension example:
+ * @code
+ *    $wgHooks['RedirectSpecialArticleRedirectParams'][] =
+ *        'MyExtensionHooks::onRedirectSpecialArticleRedirectParams';
+ *    public static function onRedirectSpecialArticleRedirectParams( &$redirectParams ) {
+ *        $redirectParams[] = 'stable';
+ *        return true;
+ *    }
+ * @endcode
+ *
+ * @ingroup SpecialPage
+ */
+abstract class RedirectSpecialArticle extends RedirectSpecialPage {
+       function __construct( $name ) {
+               parent::__construct( $name );
+               $redirectParams = [
+                       'action',
+                       'redirect', 'rdfrom',
+                       # Options for preloaded edits
+                       'preload', 'preloadparams', 'editintro', 'preloadtitle', 'summary', 'nosummary',
+                       # Options for overriding user settings
+                       'preview', 'minor', 'watchthis',
+                       # Options for history/diffs
+                       'section', 'oldid', 'diff', 'dir',
+                       'limit', 'offset', 'feed',
+                       # Misc options
+                       'redlink',
+                       # Options for action=raw; missing ctype can break JS or CSS in some browsers
+                       'ctype', 'maxage', 'smaxage',
+               ];
+
+               Hooks::run( "RedirectSpecialArticleRedirectParams", [ &$redirectParams ] );
+               $this->mAllowedRedirectParams = $redirectParams;
+       }
+}
index 8d39c99..01a88f4 100644 (file)
@@ -112,124 +112,3 @@ abstract class RedirectSpecialPage extends UnlistedSpecialPage {
                throw new MWException( "RedirectSpecialPage $class doesn't redirect!" );
        }
 }
-
-/**
- * @ingroup SpecialPage
- */
-abstract class SpecialRedirectToSpecial extends RedirectSpecialPage {
-       /** @var string Name of redirect target */
-       protected $redirName;
-
-       /** @var string Name of subpage of redirect target */
-       protected $redirSubpage;
-
-       function __construct(
-               $name, $redirName, $redirSubpage = false,
-               $allowedRedirectParams = [], $addedRedirectParams = []
-       ) {
-               parent::__construct( $name );
-               $this->redirName = $redirName;
-               $this->redirSubpage = $redirSubpage;
-               $this->mAllowedRedirectParams = $allowedRedirectParams;
-               $this->mAddedRedirectParams = $addedRedirectParams;
-       }
-
-       /**
-        * @param string|null $subpage
-        * @return Title|bool
-        */
-       public function getRedirect( $subpage ) {
-               if ( $this->redirSubpage === false ) {
-                       return SpecialPage::getTitleFor( $this->redirName, $subpage );
-               }
-
-               return SpecialPage::getTitleFor( $this->redirName, $this->redirSubpage );
-       }
-}
-
-/**
- * Superclass for any RedirectSpecialPage which redirects the user
- * to a particular article (as opposed to user contributions, logs, etc.).
- *
- * For security reasons these special pages are restricted to pass on
- * the following subset of GET parameters to the target page while
- * removing all others:
- *
- * - useskin, uselang, printable: to alter the appearance of the resulting page
- *
- * - redirect: allows viewing one's user page or talk page even if it is a
- * redirect.
- *
- * - rdfrom: allows redirecting to one's user page or talk page from an
- * external wiki with the "Redirect from..." notice.
- *
- * - limit, offset: Useful for linking to history of one's own user page or
- * user talk page. For example, this would be a link to "the last edit to your
- * user talk page in the year 2010":
- * https://en.wikipedia.org/wiki/Special:MyPage?offset=20110000000000&limit=1&action=history
- *
- * - feed: would allow linking to the current user's RSS feed for their user
- * talk page:
- * https://en.wikipedia.org/w/index.php?title=Special:MyTalk&action=history&feed=rss
- *
- * - preloadtitle: Can be used to provide a default section title for a
- * preloaded new comment on one's own talk page.
- *
- * - summary : Can be used to provide a default edit summary for a preloaded
- * edit to one's own user page or talk page.
- *
- * - preview: Allows showing/hiding preview on first edit regardless of user
- * preference, useful for preloaded edits where you know preview wouldn't be
- * useful.
- *
- * - redlink: Affects the message the user sees if their talk page/user talk
- * page does not currently exist. Avoids confusion for newbies with no user
- * pages over why they got a "permission error" following this link:
- * https://en.wikipedia.org/w/index.php?title=Special:MyPage&redlink=1
- *
- * - debug: determines whether the debug parameter is passed to load.php,
- * which disables reformatting and allows scripts to be debugged. Useful
- * when debugging scripts that manipulate one's own user page or talk page.
- *
- * @par Hook extension:
- * Extensions can add to the redirect parameters list by using the hook
- * RedirectSpecialArticleRedirectParams
- *
- * This hook allows extensions which add GET parameters like FlaggedRevs to
- * retain those parameters when redirecting using special pages.
- *
- * @par Hook extension example:
- * @code
- *    $wgHooks['RedirectSpecialArticleRedirectParams'][] =
- *        'MyExtensionHooks::onRedirectSpecialArticleRedirectParams';
- *    public static function onRedirectSpecialArticleRedirectParams( &$redirectParams ) {
- *        $redirectParams[] = 'stable';
- *        return true;
- *    }
- * @endcode
- *
- * @ingroup SpecialPage
- */
-abstract class RedirectSpecialArticle extends RedirectSpecialPage {
-       function __construct( $name ) {
-               parent::__construct( $name );
-               $redirectParams = [
-                       'action',
-                       'redirect', 'rdfrom',
-                       # Options for preloaded edits
-                       'preload', 'preloadparams', 'editintro', 'preloadtitle', 'summary', 'nosummary',
-                       # Options for overriding user settings
-                       'preview', 'minor', 'watchthis',
-                       # Options for history/diffs
-                       'section', 'oldid', 'diff', 'dir',
-                       'limit', 'offset', 'feed',
-                       # Misc options
-                       'redlink',
-                       # Options for action=raw; missing ctype can break JS or CSS in some browsers
-                       'ctype', 'maxage', 'smaxage',
-               ];
-
-               Hooks::run( "RedirectSpecialArticleRedirectParams", [ &$redirectParams ] );
-               $this->mAllowedRedirectParams = $redirectParams;
-       }
-}
index e18eacc..bd0e24f 100644 (file)
@@ -406,7 +406,7 @@ class SpecialPage implements MessageLocalizer {
                if ( $securityStatus === AuthManager::SEC_OK ) {
                        $uniqueId = $request->getVal( 'postUniqueId' );
                        if ( $uniqueId ) {
-                               $key = $key . ':' . $uniqueId;
+                               $key .= ':' . $uniqueId;
                                $session = $request->getSession();
                                $data = $session->getSecret( $key );
                                if ( $data ) {
@@ -424,7 +424,7 @@ class SpecialPage implements MessageLocalizer {
                                if ( $data ) {
                                        // unique ID in case the same special page is open in multiple browser tabs
                                        $uniqueId = MWCryptRand::generateHex( 6 );
-                                       $key = $key . ':' . $uniqueId;
+                                       $key .= ':' . $uniqueId;
                                        $queryParams['postUniqueId'] = $uniqueId;
                                        $session = $request->getSession();
                                        $session->persist(); // Just in case
@@ -920,4 +920,70 @@ class SpecialPage implements MessageLocalizer {
        public function setLinkRenderer( LinkRenderer $linkRenderer ) {
                $this->linkRenderer = $linkRenderer;
        }
+
+       /**
+        * Generate (prev x| next x) (20|50|100...) type links for paging
+        *
+        * @param int $offset
+        * @param int $limit
+        * @param array $query Optional URL query parameter string
+        * @param bool $atend Optional param for specified if this is the last page
+        * @param string|bool $subpage Optional param for specifying subpage
+        * @return string
+        */
+       protected function buildPrevNextNavigation( $offset, $limit,
+               array $query = [], $atend = false, $subpage = false
+       ) {
+               $lang = $this->getLanguage();
+
+               # Make 'previous' link
+               $prev = $this->msg( 'prevn' )->numParams( $limit )->text();
+               if ( $offset > 0 ) {
+                       $plink = $this->numLink( max( $offset - $limit, 0 ), $limit, $query,
+                               $prev, 'prevn-title', 'mw-prevlink', $subpage );
+               } else {
+                       $plink = htmlspecialchars( $prev );
+               }
+
+               # Make 'next' link
+               $next = $this->msg( 'nextn' )->numParams( $limit )->text();
+               if ( $atend ) {
+                       $nlink = htmlspecialchars( $next );
+               } else {
+                       $nlink = $this->numLink( $offset + $limit, $limit,
+                               $query, $next, 'nextn-title', 'mw-nextlink', $subpage );
+               }
+
+               # Make links to set number of items per page
+               $numLinks = [];
+               foreach ( [ 20, 50, 100, 250, 500 ] as $num ) {
+                       $numLinks[] = $this->numLink( $offset, $num, $query,
+                               $lang->formatNum( $num ), 'shown-title', 'mw-numlink', $subpage );
+               }
+
+               return $this->msg( 'viewprevnext' )->rawParams( $plink, $nlink, $lang->pipeList( $numLinks ) )->
+                       escaped();
+       }
+
+       /**
+        * Helper function for buildPrevNextNavigation() that generates links
+        *
+        * @param int $offset
+        * @param int $limit
+        * @param array $query Extra query parameters
+        * @param string $link Text to use for the link; will be escaped
+        * @param string $tooltipMsg Name of the message to use as tooltip
+        * @param string $class Value of the "class" attribute of the link
+        * @param string|bool $subpage Optional param for specifying subpage
+        * @return string HTML fragment
+        */
+       private function numLink( $offset, $limit, array $query, $link,
+               $tooltipMsg, $class, $subpage = false
+       ) {
+               $query = [ 'limit' => $limit, 'offset' => $offset ] + $query;
+               $tooltip = $this->msg( $tooltipMsg )->numParams( $limit )->text();
+               $href = $this->getPageTitle( $subpage )->getLocalURL( $query );
+               return Html::element( 'a', [ 'href' => $href,
+                       'title' => $tooltip, 'class' => $class ], $link );
+       }
 }
index 58212dd..a3b7296 100644 (file)
@@ -34,6 +34,7 @@ use RequestContext;
 use SpecialPage;
 use Title;
 use User;
+use Wikimedia\Assert\Assert;
 
 /**
  * Factory for handling the special page list and generating SpecialPage objects.
@@ -215,17 +216,36 @@ class SpecialPageFactory {
        private $aliases;
 
        /** @var Config */
-       private $config;
+       private $options;
 
        /** @var Language */
        private $contLang;
 
        /**
-        * @param Config $config
+        * TODO Make this a const when HHVM support is dropped (T192166)
+        *
+        * @var array
+        * @since 1.33
+        * */
+       public static $constructorOptions = [
+               'ContentHandlerUseDB',
+               'DisableInternalSearch',
+               'EmailAuthentication',
+               'EnableEmail',
+               'EnableJavaScriptTest',
+               'PageLanguageUseDB',
+               'SpecialPages',
+       ];
+
+       /**
+        * @param array $options
         * @param Language $contLang
         */
-       public function __construct( Config $config, Language $contLang ) {
-               $this->config = $config;
+       public function __construct( array $options, Language $contLang ) {
+               Assert::parameter( count( $options ) === count( self::$constructorOptions ) &&
+                       !array_diff( self::$constructorOptions, array_keys( $options ) ),
+                       '$options', 'Wrong set of options present' );
+               $this->options = $options;
                $this->contLang = $contLang;
        }
 
@@ -248,32 +268,32 @@ class SpecialPageFactory {
                if ( !is_array( $this->list ) ) {
                        $this->list = self::$coreList;
 
-                       if ( !$this->config->get( 'DisableInternalSearch' ) ) {
+                       if ( !$this->options['DisableInternalSearch'] ) {
                                $this->list['Search'] = \SpecialSearch::class;
                        }
 
-                       if ( $this->config->get( 'EmailAuthentication' ) ) {
+                       if ( $this->options['EmailAuthentication'] ) {
                                $this->list['Confirmemail'] = \EmailConfirmation::class;
                                $this->list['Invalidateemail'] = \EmailInvalidation::class;
                        }
 
-                       if ( $this->config->get( 'EnableEmail' ) ) {
+                       if ( $this->options['EnableEmail'] ) {
                                $this->list['ChangeEmail'] = \SpecialChangeEmail::class;
                        }
 
-                       if ( $this->config->get( 'EnableJavaScriptTest' ) ) {
+                       if ( $this->options['EnableJavaScriptTest'] ) {
                                $this->list['JavaScriptTest'] = \SpecialJavaScriptTest::class;
                        }
 
-                       if ( $this->config->get( 'PageLanguageUseDB' ) ) {
+                       if ( $this->options['PageLanguageUseDB'] ) {
                                $this->list['PageLanguage'] = \SpecialPageLanguage::class;
                        }
-                       if ( $this->config->get( 'ContentHandlerUseDB' ) ) {
+                       if ( $this->options['ContentHandlerUseDB'] ) {
                                $this->list['ChangeContentModel'] = \SpecialChangeContentModel::class;
                        }
 
                        // Add extension special pages
-                       $this->list = array_merge( $this->list, $this->config->get( 'SpecialPages' ) );
+                       $this->list = array_merge( $this->list, $this->options['SpecialPages'] );
 
                        // This hook can be used to disable unwanted core special pages
                        // or conditionally register special pages.
diff --git a/includes/specialpage/SpecialRedirectToSpecial.php b/includes/specialpage/SpecialRedirectToSpecial.php
new file mode 100644 (file)
index 0000000..e30278e
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Shortcuts to construct a special page alias.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * @ingroup SpecialPage
+ */
+abstract class SpecialRedirectToSpecial extends RedirectSpecialPage {
+       /** @var string Name of redirect target */
+       protected $redirName;
+
+       /** @var string Name of subpage of redirect target */
+       protected $redirSubpage;
+
+       function __construct(
+               $name, $redirName, $redirSubpage = false,
+               $allowedRedirectParams = [], $addedRedirectParams = []
+       ) {
+               parent::__construct( $name );
+               $this->redirName = $redirName;
+               $this->redirSubpage = $redirSubpage;
+               $this->mAllowedRedirectParams = $allowedRedirectParams;
+               $this->mAddedRedirectParams = $addedRedirectParams;
+       }
+
+       /**
+        * @param string|null $subpage
+        * @return Title|bool
+        */
+       public function getRedirect( $subpage ) {
+               if ( $this->redirSubpage === false ) {
+                       return SpecialPage::getTitleFor( $this->redirName, $subpage );
+               }
+
+               return SpecialPage::getTitleFor( $this->redirName, $this->redirSubpage );
+       }
+}
index 0c709af..f52a6f3 100644 (file)
@@ -33,9 +33,7 @@ class SpecialActiveUsers extends SpecialPage {
        }
 
        /**
-        * Show the special page
-        *
-        * @param string $par Parameter passed to the page or null
+        * @param string|null $par Parameter passed to the page or null
         */
        public function execute( $par ) {
                $out = $this->getOutput();
index 2482d74..878440d 100644 (file)
@@ -35,9 +35,7 @@ class SpecialAllMessages extends SpecialPage {
        }
 
        /**
-        * Show the special page
-        *
-        * @param string $par Parameter passed to the page or null
+        * @param string|null $par Parameter passed to the page or null
         */
        public function execute( $par ) {
                $out = $this->getOutput();
index 4f691cb..cea6d37 100644 (file)
@@ -50,7 +50,7 @@ class AncientPagesPage extends QueryPage {
                ];
                $joinConds = [
                        'revision' => [
-                               'INNER JOIN', [
+                               'JOIN', [
                                        'page_latest = rev_id'
                                ]
                        ],
index cab5a2e..34c3371 100644 (file)
@@ -34,9 +34,7 @@ class SpecialAutoblockList extends SpecialPage {
        }
 
        /**
-        * Main execution point
-        *
-        * @param string $par Title fragment
+        * @param string|null $par Title fragment
         */
        public function execute( $par ) {
                $this->setHeaders();
index a816edc..7d86663 100644 (file)
@@ -141,15 +141,16 @@ class SpecialBlock extends FormSpecialPage {
         * @return array
         */
        protected function getFormFields() {
-               global $wgBlockAllowsUTEdit;
+               $conf = $this->getConfig();
+               $enablePartialBlocks = $conf->get( 'EnablePartialBlocks' );
+               $blockAllowsUTEdit = $conf->get( 'BlockAllowsUTEdit' );
+
+               $this->getOutput()->enableOOUI();
 
                $user = $this->getUser();
 
                $suggestedDurations = self::getSuggestedDurations();
 
-               $conf = $this->getConfig();
-               $enablePartialBlocks = $conf->get( 'EnablePartialBlocks' );
-
                $a = [];
 
                $a['Target'] = [
@@ -177,8 +178,16 @@ class SpecialBlock extends FormSpecialPage {
                                'type' => 'radio',
                                'cssclass' => 'mw-block-editing-restriction',
                                'options' => [
-                                       $this->msg( 'ipb-sitewide' )->escaped() => 'sitewide',
-                                       $this->msg( 'ipb-partial' )->escaped() => 'partial',
+                                       $this->msg( 'ipb-sitewide' )->escaped() .
+                                               new \OOUI\LabelWidget( [
+                                                       'classes' => [ 'oo-ui-inline-help' ],
+                                                       'label' => $this->msg( 'ipb-sitewide-help' )->text(),
+                                               ] ) => 'sitewide',
+                                       $this->msg( 'ipb-partial' )->escaped() .
+                                               new \OOUI\LabelWidget( [
+                                                       'classes' => [ 'oo-ui-inline-help' ],
+                                                       'label' => $this->msg( 'ipb-partial-help' )->text(),
+                                               ] ) => 'partial',
                                ],
                                'section' => 'actions',
                        ];
@@ -222,7 +231,7 @@ class SpecialBlock extends FormSpecialPage {
                        ];
                }
 
-               if ( $wgBlockAllowsUTEdit ) {
+               if ( $blockAllowsUTEdit ) {
                        $a['DisableUTEdit'] = [
                                'type' => 'check',
                                'label-message' => 'ipb-disableusertalk',
@@ -328,9 +337,11 @@ class SpecialBlock extends FormSpecialPage {
 
                $block = Block::newFromTarget( $this->target );
 
-               if ( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
-                       && ( $this->type != Block::TYPE_RANGE # The block isn't a rangeblock
-                               || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
+               // Populate fields if there is a block that is not an autoblock; if it is a range
+               // block, only populate the fields if the range is the same as $this->target
+               if ( $block instanceof Block && $block->getType() !== Block::TYPE_AUTO
+                       && ( $this->type != Block::TYPE_RANGE
+                               || $block->getTarget() == $this->target )
                ) {
                        $fields['HardBlock']['default'] = $block->isHardblock();
                        $fields['CreateAccount']['default'] = $block->isCreateAccountBlocked();
@@ -341,7 +352,7 @@ class SpecialBlock extends FormSpecialPage {
                        }
 
                        if ( isset( $fields['HideUser'] ) ) {
-                               $fields['HideUser']['default'] = $block->mHideName;
+                               $fields['HideUser']['default'] = $block->getHideName();
                        }
 
                        if ( isset( $fields['DisableUTEdit'] ) ) {
@@ -350,8 +361,8 @@ 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: T37839
-                       if ( !$block->mHideName || $this->getUser()->isAllowed( 'hideuser' ) ) {
-                               $fields['Reason']['default'] = $block->mReason;
+                       if ( !$block->getHideName() || $this->getUser()->isAllowed( 'hideuser' ) ) {
+                               $fields['Reason']['default'] = $block->getReason();
                        } else {
                                $fields['Reason']['default'] = '';
                        }
@@ -367,16 +378,22 @@ class SpecialBlock extends FormSpecialPage {
                                $fields['Confirm']['default'] = 1;
                        }
 
-                       if ( $block->mExpiry == 'infinity' ) {
+                       if ( $block->getExpiry() == 'infinity' ) {
                                $fields['Expiry']['default'] = 'infinite';
                        } else {
-                               $fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->mExpiry );
+                               $fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->getExpiry() );
                        }
 
                        $this->alreadyBlocked = true;
                        $this->preErrors[] = [ 'ipb-needreblock', wfEscapeWikiText( (string)$block->getTarget() ) ];
                }
 
+               if ( $this->alreadyBlocked || $this->getRequest()->wasPosted()
+                       || $this->getRequest()->getCheck( 'wpCreateAccount' )
+               ) {
+                       $this->getOutput()->addJsConfigVars( 'wgCreateAccountDirty', true );
+               }
+
                # We always need confirmation to do HideUser
                if ( $this->requestedHideUser ) {
                        $fields['Confirm']['type'] = 'check';
@@ -602,6 +619,7 @@ class SpecialBlock extends FormSpecialPage {
         *     the HTMLForm
         * @param WebRequest|null $request Optionally try and get data from a request too
         * @return array [ User|string|null, Block::TYPE_ constant|null ]
+        * @phan-return array{0:User|string|null,1:int|null}
         */
        public static function getTargetAndType( $par, WebRequest $request = null ) {
                $i = 0;
@@ -845,14 +863,14 @@ class SpecialBlock extends FormSpecialPage {
                $block = new Block();
                $block->setTarget( $target );
                $block->setBlocker( $performer );
-               $block->mReason = $data['Reason'][0];
-               $block->mExpiry = $expiryTime;
+               $block->setReason( $data['Reason'][0] );
+               $block->setExpiry( $expiryTime );
                $block->isCreateAccountBlocked( $data['CreateAccount'] );
                $block->isUsertalkEditAllowed( !$wgBlockAllowsUTEdit || !$data['DisableUTEdit'] );
                $block->isEmailBlocked( $data['DisableEmail'] );
                $block->isHardblock( $data['HardBlock'] );
                $block->isAutoblocking( $data['AutoBlock'] );
-               $block->mHideName = $data['HideUser'];
+               $block->setHideName( $data['HideUser'] );
 
                if ( $isPartialBlock ) {
                        $block->isSitewide( false );
@@ -911,19 +929,19 @@ class SpecialBlock extends FormSpecialPage {
                                }
                                # If the name was hidden and the blocking user cannot hide
                                # names, then don't allow any block changes...
-                               if ( $currentBlock->mHideName && !$performer->isAllowed( 'hideuser' ) ) {
+                               if ( $currentBlock->getHideName() && !$performer->isAllowed( 'hideuser' ) ) {
                                        return [ 'cant-see-hidden-user' ];
                                }
 
                                $priorBlock = clone $currentBlock;
                                $currentBlock->isHardblock( $block->isHardblock() );
                                $currentBlock->isCreateAccountBlocked( $block->isCreateAccountBlocked() );
-                               $currentBlock->mExpiry = $block->mExpiry;
+                               $currentBlock->setExpiry( $block->getExpiry() );
                                $currentBlock->isAutoblocking( $block->isAutoblocking() );
-                               $currentBlock->mHideName = $block->mHideName;
+                               $currentBlock->setHideName( $block->getHideName() );
                                $currentBlock->isEmailBlocked( $block->isEmailBlocked() );
                                $currentBlock->isUsertalkEditAllowed( $block->isUsertalkEditAllowed() );
-                               $currentBlock->mReason = $block->mReason;
+                               $currentBlock->setReason( $block->getReason() );
 
                                if ( $enablePartialBlocks ) {
                                        // Maintain the sitewide status. If partial blocks is not enabled,
@@ -942,12 +960,12 @@ class SpecialBlock extends FormSpecialPage {
                                $logaction = 'reblock';
 
                                # Unset _deleted fields if requested
-                               if ( $currentBlock->mHideName && !$data['HideUser'] ) {
+                               if ( $currentBlock->getHideName() && !$data['HideUser'] ) {
                                        RevisionDeleteUser::unsuppressUserName( $target, $userId );
                                }
 
                                # If hiding/unhiding a name, this should go in the private logs
-                               if ( (bool)$currentBlock->mHideName ) {
+                               if ( (bool)$currentBlock->getHideName() ) {
                                        $data['HideUser'] = true;
                                }
 
@@ -1057,7 +1075,7 @@ class SpecialBlock extends FormSpecialPage {
         *
         * @todo strtotime() only accepts English strings. This means the expiry input
         *       can only be specified in English.
-        * @see https://secure.php.net/manual/en/function.strtotime.php
+        * @see https://www.php.net/manual/en/function.strtotime.php
         *
         * @param string $expiry Whatever was typed into the form
         * @return string|bool Timestamp or 'infinity' or false on error.
index 186e5ad..fd27fdc 100644 (file)
@@ -36,9 +36,7 @@ class SpecialBlockList extends SpecialPage {
        }
 
        /**
-        * Main execution point
-        *
-        * @param string $par Title fragment
+        * @param string|null $par Title fragment
         */
        public function execute( $par ) {
                $this->setHeaders();
index 2fe38ed..ea9ddaf 100644 (file)
@@ -36,9 +36,7 @@ class SpecialBookSources extends SpecialPage {
        }
 
        /**
-        * Show the special page
-        *
-        * @param string $isbn ISBN passed as a subpage parameter
+        * @param string|null $isbn ISBN passed as a subpage parameter
         */
        public function execute( $isbn ) {
                $out = $this->getOutput();
index 8cf64b1..8d5cf85 100644 (file)
@@ -177,7 +177,6 @@ class SpecialChangeEmail extends FormSpecialPage {
                Hooks::run( 'PrefsEmailAudit', [ $user, $oldaddr, $newaddr ] );
 
                $user->saveSettings();
-               MediaWiki\Auth\AuthManager::callLegacyAuthPlugin( 'updateExternalDB', [ $user ] );
 
                return $status;
        }
index d6fb10f..36928ca 100644 (file)
@@ -43,8 +43,7 @@ class SpecialComparePages extends SpecialPage {
        /**
         * Show a form for filtering namespace and username
         *
-        * @param string $par
-        * @return string
+        * @param string|null $par
         */
        public function execute( $par ) {
                $this->setHeaders();
index b51f92f..99e6dde 100644 (file)
@@ -148,7 +148,7 @@ class EmailConfirmation extends UnlistedSpecialPage {
         * @param string $code Confirmation code
         */
        private function attemptConfirm( $code ) {
-               $user = User::newFromConfirmationCode( $code, User::READ_LATEST );
+               $user = User::newFromConfirmationCode( $code, User::READ_EXCLUSIVE );
                if ( !is_object( $user ) ) {
                        $this->getOutput()->addWikiMsg( 'confirmemail_invalid' );
 
index 8a48aa6..08a7fde 100644 (file)
@@ -21,7 +21,6 @@
  * @ingroup SpecialPage
  */
 
-use MediaWiki\MediaWikiServices;
 use MediaWiki\Widget\DateInputWidget;
 
 /**
@@ -46,6 +45,7 @@ class SpecialContributions extends IncludableSpecialPage {
                        'mediawiki.special',
                        'mediawiki.special.changeslist',
                ] );
+               $out->addModules( 'mediawiki.special.recentchanges' );
                $this->addHelpLink( 'Help:User contributions' );
 
                $this->opts = [];
@@ -237,17 +237,16 @@ class SpecialContributions extends IncludableSpecialPage {
                                $out->addWikiMsg( 'nocontribs', $target );
                        } else {
                                # Show a message about replica DB lag, if applicable
-                               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-                               $lag = $lb->safeGetLag( $pager->getDatabase() );
+                               $lag = $pager->getDatabase()->getSessionLagStatus()['lag'];
                                if ( $lag > 0 ) {
                                        $out->showLagWarning( $lag );
                                }
 
                                $output = $pager->getBody();
                                if ( !$this->including() ) {
-                                       $output = '<p>' . $pager->getNavigationBar() . '</p>' .
+                                       $output = $pager->getNavigationBar() .
                                                $output .
-                                               '<p>' . $pager->getNavigationBar() . '</p>';
+                                               $pager->getNavigationBar();
                                }
                                $out->addHTML( $output );
                        }
@@ -268,14 +267,10 @@ class SpecialContributions extends IncludableSpecialPage {
                                $message = 'sp-contributions-footer';
                        }
 
-                       if ( $message ) {
-                               if ( !$this->including() ) {
-                                       if ( !$this->msg( $message, $target )->isDisabled() ) {
-                                               $out->wrapWikiMsg(
-                                                       "<div class='mw-contributions-footer'>\n$1\n</div>",
-                                                       [ $message, $target ] );
-                                       }
-                               }
+                       if ( $message && !$this->including() && !$this->msg( $message, $target )->isDisabled() ) {
+                               $out->wrapWikiMsg(
+                                       "<div class='mw-contributions-footer'>\n$1\n</div>",
+                                       [ $message, $target ] );
                        }
                }
        }
@@ -314,7 +309,11 @@ class SpecialContributions extends IncludableSpecialPage {
                $links = '';
                if ( $talk ) {
                        $tools = self::getUserLinks( $this, $userObj );
-                       $links = $this->getLanguage()->pipeList( $tools );
+                       $links = Html::openElement( 'span', [ 'class' => 'mw-changeslist-links' ] );
+                       foreach ( $tools as $tool ) {
+                               $links .= Html::rawElement( 'span', [], $tool ) . ' ';
+                       }
+                       $links = trim( $links ) . Html::closeElement( 'span' );
 
                        // Show a note if the user is blocked and display the last block log entry.
                        // Do not expose the autoblocks, since that may lead to a leak of accounts' IPs,
@@ -354,7 +353,10 @@ class SpecialContributions extends IncludableSpecialPage {
                        }
                }
 
-               return $this->msg( 'contribsub2' )->rawParams( $user, $links )->params( $userObj->getName() );
+               return Html::rawElement( 'div', [ 'class' => 'mw-contributions-user-tools' ],
+                       $this->msg( 'contributions-subtitle' )->rawParams( $user )->params( $userObj->getName() )
+                       . ' ' . $links
+               );
        }
 
        /**
@@ -589,6 +591,7 @@ class SpecialContributions extends IncludableSpecialPage {
                        $this->opts['target'],
                        'text',
                        [
+                               'id' => 'mw-target-user-or-ip',
                                'size' => '40',
                                'class' => [
                                        'mw-input',
@@ -608,6 +611,7 @@ class SpecialContributions extends IncludableSpecialPage {
                        $labelNewbies . '<br>' . $labelUsername . ' ' . $input . ' '
                );
 
+               $hidden = $this->opts['namespace'] === '' ? ' mw-input-hidden' : '';
                $namespaceSelection = Xml::tags(
                        'div',
                        [],
@@ -626,11 +630,11 @@ class SpecialContributions extends IncludableSpecialPage {
                        ) . "\u{00A0}" .
                                Html::rawElement(
                                        'span',
-                                       [ 'class' => 'mw-input-with-label' ],
+                                       [ 'class' => 'mw-input-with-label' . $hidden ],
                                        Xml::checkLabel(
                                                $this->msg( 'invert' )->text(),
                                                'nsInvert',
-                                               'nsInvert',
+                                               'nsinvert',
                                                $this->opts['nsInvert'],
                                                [
                                                        'title' => $this->msg( 'tooltip-invert' )->text(),
@@ -638,11 +642,11 @@ class SpecialContributions extends IncludableSpecialPage {
                                                ]
                                        ) . "\u{00A0}"
                                ) .
-                               Html::rawElement( 'span', [ 'class' => 'mw-input-with-label' ],
+                               Html::rawElement( 'span', [ 'class' => 'mw-input-with-label' . $hidden ],
                                        Xml::checkLabel(
                                                $this->msg( 'namespace_association' )->text(),
                                                'associated',
-                                               'associated',
+                                               'nsassociated',
                                                $this->opts['associated'],
                                                [
                                                        'title' => $this->msg( 'tooltip-namespace_association' )->text(),
index 6022ff4..65cf79e 100644 (file)
@@ -21,8 +21,6 @@
  * @ingroup SpecialPage
  */
 
-use MediaWiki\MediaWikiServices;
-
 /**
  * Implements Special:DeletedContributions to display archived revisions
  * @ingroup SpecialPage
@@ -46,8 +44,6 @@ class DeletedContributionsPage extends SpecialPage {
                $this->outputHeader();
                $this->checkPermissions();
 
-               $user = $this->getUser();
-
                $out = $this->getOutput();
                $out->setPageTitle( $this->msg( 'deletedcontributions-title' ) );
 
@@ -101,8 +97,7 @@ class DeletedContributionsPage extends SpecialPage {
                }
 
                # Show a message about replica DB lag, if applicable
-               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-               $lag = $lb->safeGetLag( $pager->getDatabase() );
+               $lag = $pager->getDatabase()->getSessionLagStatus()['lag'];
                if ( $lag > 0 ) {
                        $out->showLagWarning( $lag );
                }
index bcc81c7..5203807 100644 (file)
@@ -75,8 +75,11 @@ class SpecialEditTags extends UnlistedSpecialPage {
                $this->setHeaders();
                $this->outputHeader();
 
-               $this->getOutput()->addModules( [ 'mediawiki.special.edittags',
-                       'mediawiki.special' ] );
+               $output->addModules( [ 'mediawiki.special.edittags' ] );
+               $output->addModuleStyles( [
+                       'mediawiki.interface.helpers.styles',
+                       'mediawiki.special'
+               ] );
 
                $this->submitClicked = $request->wasPosted() && $request->getBool( 'wpSubmit' );
 
@@ -206,8 +209,6 @@ class SpecialEditTags extends UnlistedSpecialPage {
         * the user to modify the tags applied to those items.
         */
        protected function showForm() {
-               $userAllowed = true;
-
                $out = $this->getOutput();
                // Messages: tags-edit-revision-selected, tags-edit-logentry-selected
                $out->wrapWikiMsg( "<strong>$1</strong>", [
index 10a9e96..5f80215 100644 (file)
@@ -108,9 +108,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                $request = $this->getRequest();
                $out->addModuleStyles( 'mediawiki.special' );
 
-               $this->mTarget = is_null( $par )
-                       ? $request->getVal( 'wpTarget', $request->getVal( 'target', '' ) )
-                       : $par;
+               $this->mTarget = $par ?? $request->getVal( 'wpTarget', $request->getVal( 'target', '' ) );
 
                // Make sure, that HTMLForm uses the correct target.
                $request->setVal( 'wpTarget', $this->mTarget );
@@ -250,7 +248,8 @@ class SpecialEmailUser extends UnlistedSpecialPage {
         * @param User $user
         * @param string $editToken Edit token
         * @param Config|null $config optional for backwards compatibility
-        * @return string|null Null on success or string on error
+        * @return null|string|array Null on success, string on error, or array on
+        *  hook error
         */
        public static function getPermissionsError( $user, $editToken, Config $config = null ) {
                if ( $config === null ) {
@@ -300,7 +299,6 @@ class SpecialEmailUser extends UnlistedSpecialPage {
         * Form to ask for target user name.
         *
         * @param string $name User name submitted.
-        * @return string Form asking for user name.
         */
        protected function userForm( $name ) {
                $htmlForm = HTMLForm::factory( 'ooui', [
index 619665b..9ea5e08 100644 (file)
@@ -154,7 +154,6 @@ class SpecialExpandTemplates extends SpecialPage {
         *
         * @param string $title Value for context title field
         * @param string $input Value for input textbox
-        * @return string
         */
        private function makeForm( $title, $input ) {
                $fields = [
index a985bcc..aaa405a 100644 (file)
@@ -391,10 +391,8 @@ class SpecialImport extends SpecialPage {
                                        Xml::closeElement( 'form' ) .
                                        Xml::closeElement( 'fieldset' )
                        );
-               } else {
-                       if ( empty( $this->importSources ) ) {
-                               $out->addWikiMsg( 'importnosources' );
-                       }
+               } elseif ( empty( $this->importSources ) ) {
+                       $out->addWikiMsg( 'importnosources' );
                }
 
                if ( $user->isAllowed( 'import' ) && !empty( $this->importSources ) ) {
index dee2968..7aef4ae 100644 (file)
@@ -35,9 +35,7 @@ class SpecialListUsers extends IncludableSpecialPage {
        }
 
        /**
-        * Show the special page
-        *
-        * @param string $par (optional) A group to list users from
+        * @param string|null $par (optional) A group to list users from
         */
        public function execute( $par ) {
                $this->setHeaders();
@@ -77,25 +75,3 @@ class SpecialListUsers extends IncludableSpecialPage {
                return 'users';
        }
 }
-
-/**
- * Redirect page: Special:ListAdmins --> Special:ListUsers/sysop.
- *
- * @ingroup SpecialPage
- */
-class SpecialListAdmins extends SpecialRedirectToSpecial {
-       function __construct() {
-               parent::__construct( 'Listadmins', 'Listusers', 'sysop' );
-       }
-}
-
-/**
- * Redirect page: Special:ListBots --> Special:ListUsers/bot.
- *
- * @ingroup SpecialPage
- */
-class SpecialListBots extends SpecialRedirectToSpecial {
-       function __construct() {
-               parent::__construct( 'Listbots', 'Listusers', 'bot' );
-       }
-}
index 4d50642..21c166c 100644 (file)
@@ -38,7 +38,9 @@ class SpecialLog extends SpecialPage {
 
                $this->setHeaders();
                $this->outputHeader();
-               $this->getOutput()->addModules( 'mediawiki.userSuggest' );
+               $out = $this->getOutput();
+               $out->addModules( 'mediawiki.userSuggest' );
+               $out->addModuleStyles( 'mediawiki.interface.helpers.styles' );
                $this->addHelpLink( 'Help:Log' );
 
                $opts = new FormOptions;
index 2599b16..e8e5ea0 100644 (file)
@@ -132,6 +132,7 @@ class MIMEsearchPage extends QueryPage {
                        ->setMethod( 'get' )
                        ->prepareForm()
                        ->displayForm( false );
+               return '';
        }
 
        protected function getSuggestionsForTypes() {
index 0234507..8b5562f 100644 (file)
@@ -75,7 +75,7 @@ class MovePageForm extends UnlistedSpecialPage {
                $this->outputHeader();
 
                $request = $this->getRequest();
-               $target = !is_null( $par ) ? $par : $request->getVal( 'target' );
+               $target = $par ?? $request->getVal( 'target' );
 
                // Yes, the use of getVal() and getText() is wanted, see T22365
 
diff --git a/includes/specials/SpecialMyRedirectPages.php b/includes/specials/SpecialMyRedirectPages.php
deleted file mode 100644 (file)
index 077fbf1..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-<?php
-/**
- * Special pages that are used to get user independent links pointing to
- * current user's pages (user page, talk page, contributions, etc.).
- * This can let us cache a single copy of some generated content for all
- * users or be linked in wikitext help pages.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup SpecialPage
- */
-
-/**
- * Special page pointing to current user's user page.
- *
- * @ingroup SpecialPage
- */
-class SpecialMypage extends RedirectSpecialArticle {
-       public function __construct() {
-               parent::__construct( 'Mypage' );
-       }
-
-       /**
-        * @param string|null $subpage
-        * @return Title
-        */
-       public function getRedirect( $subpage ) {
-               if ( $subpage === null || $subpage === '' ) {
-                       return Title::makeTitle( NS_USER, $this->getUser()->getName() );
-               }
-
-               return Title::makeTitle( NS_USER, $this->getUser()->getName() . '/' . $subpage );
-       }
-
-       /**
-        * Target identifies a specific User. See T109724.
-        *
-        * @since 1.27
-        * @return bool
-        */
-       public function personallyIdentifiableTarget() {
-               return true;
-       }
-}
-
-/**
- * Special page pointing to current user's talk page.
- *
- * @ingroup SpecialPage
- */
-class SpecialMytalk extends RedirectSpecialArticle {
-       public function __construct() {
-               parent::__construct( 'Mytalk' );
-       }
-
-       /**
-        * @param string|null $subpage
-        * @return Title
-        */
-       public function getRedirect( $subpage ) {
-               if ( $subpage === null || $subpage === '' ) {
-                       return Title::makeTitle( NS_USER_TALK, $this->getUser()->getName() );
-               }
-
-               return Title::makeTitle( NS_USER_TALK, $this->getUser()->getName() . '/' . $subpage );
-       }
-
-       /**
-        * Target identifies a specific User. See T109724.
-        *
-        * @since 1.27
-        * @return bool
-        */
-       public function personallyIdentifiableTarget() {
-               return true;
-       }
-}
-
-/**
- * Special page pointing to current user's contributions.
- *
- * @ingroup SpecialPage
- */
-class SpecialMycontributions extends RedirectSpecialPage {
-       public function __construct() {
-               parent::__construct( 'Mycontributions' );
-               $this->mAllowedRedirectParams = [ 'limit', 'namespace', 'tagfilter',
-                       'offset', 'dir', 'year', 'month', 'feed', 'deletedOnly',
-                       'nsInvert', 'associated', 'newOnly', 'topOnly', 'start', 'end' ];
-       }
-
-       /**
-        * @param string|null $subpage
-        * @return Title
-        */
-       public function getRedirect( $subpage ) {
-               return SpecialPage::getTitleFor( 'Contributions', $this->getUser()->getName() );
-       }
-
-       /**
-        * Target identifies a specific User. See T109724.
-        *
-        * @since 1.27
-        * @return bool
-        */
-       public function personallyIdentifiableTarget() {
-               return true;
-       }
-}
-
-/**
- * Special page pointing to current user's uploaded files.
- *
- * @ingroup SpecialPage
- */
-class SpecialMyuploads extends RedirectSpecialPage {
-       public function __construct() {
-               parent::__construct( 'Myuploads' );
-               $this->mAllowedRedirectParams = [ 'limit', 'ilshowall', 'ilsearch' ];
-       }
-
-       /**
-        * @param string|null $subpage
-        * @return Title
-        */
-       public function getRedirect( $subpage ) {
-               return SpecialPage::getTitleFor( 'Listfiles', $this->getUser()->getName() );
-       }
-
-       /**
-        * Target identifies a specific User. See T109724.
-        *
-        * @since 1.27
-        * @return bool
-        */
-       public function personallyIdentifiableTarget() {
-               return true;
-       }
-}
-
-/**
- * Special page pointing to current user's uploaded files (including old versions).
- *
- * @ingroup SpecialPage
- */
-class SpecialAllMyUploads extends RedirectSpecialPage {
-       public function __construct() {
-               parent::__construct( 'AllMyUploads' );
-               $this->mAllowedRedirectParams = [ 'limit', 'ilsearch' ];
-       }
-
-       /**
-        * @param string|null $subpage
-        * @return Title
-        */
-       public function getRedirect( $subpage ) {
-               $this->mAddedRedirectParams['ilshowall'] = 1;
-
-               return SpecialPage::getTitleFor( 'Listfiles', $this->getUser()->getName() );
-       }
-
-       /**
-        * Target identifies a specific User. See T109724.
-        *
-        * @since 1.27
-        * @return bool
-        */
-       public function personallyIdentifiableTarget() {
-               return true;
-       }
-}
index 2bbc0bf..1b8ba85 100644 (file)
@@ -39,8 +39,10 @@ class SpecialNewpages extends IncludableSpecialPage {
                parent::__construct( 'Newpages' );
        }
 
+       /**
+        * @param string|null $par
+        */
        protected function setup( $par ) {
-               // Options
                $opts = new FormOptions();
                $this->opts = $opts; // bind
                $opts->add( 'hideliu', false );
@@ -63,16 +65,17 @@ class SpecialNewpages extends IncludableSpecialPage {
                        $opts->add( $key, $params['default'] );
                }
 
-               // Set values
                $opts->fetchValuesFromRequest( $this->getRequest() );
                if ( $par ) {
                        $this->parseParams( $par );
                }
 
-               // Validate
                $opts->validateIntBounds( 'limit', 0, 5000 );
        }
 
+       /**
+        * @param string $par
+        */
        protected function parseParams( $par ) {
                $bits = preg_split( '/\s*,\s*/', trim( $par ) );
                foreach ( $bits as $bit ) {
@@ -118,7 +121,7 @@ class SpecialNewpages extends IncludableSpecialPage {
        /**
         * Show a form for filtering namespace and username
         *
-        * @param string $par
+        * @param string|null $par
         */
        public function execute( $par ) {
                $out = $this->getOutput();
index 52db060..7e41305 100644 (file)
@@ -44,6 +44,7 @@ class SpecialPageLanguage extends FormSpecialPage {
 
        protected function preText() {
                $this->getOutput()->addModules( 'mediawiki.special.pageLanguage' );
+               return parent::preText();
        }
 
        protected function getFormFields() {
index 46ad31c..3c009c3 100644 (file)
@@ -149,7 +149,7 @@ class SpecialPagesWithProp extends QueryPage {
                                'pp_propname' => $this->propName,
                        ],
                        'join_conds' => [
-                               'page' => [ 'INNER JOIN', 'page_id = pp_page' ]
+                               'page' => [ 'JOIN', 'page_id = pp_page' ]
                        ],
                        'options' => []
                ];
index 573dcb5..d09deab 100644 (file)
@@ -136,20 +136,37 @@ class SpecialPasswordPolicies extends SpecialPage {
                );
 
                $ret = [];
-               foreach ( $groupPolicies as $gp => $val ) {
-                       if ( $val === false ) {
-                               // Policy isn't enabled, so no need to dislpay it
+               foreach ( $groupPolicies as $gp => $settings ) {
+                       if ( !is_array( $settings ) ) {
+                               $settings = [ 'value' => $settings ];
+                       }
+                       $val = $settings['value'];
+                       $flags = array_diff_key( $settings, [ 'value' => true ] );
+                       if ( !$val ) {
+                               // Policy isn't enabled, so no need to display it
                                continue;
-                       } elseif ( $val === true ) {
-                               $msg = $this->msg( 'passwordpolicies-policy-' . strtolower( $gp ) );
+                       }
+                       $msg = $this->msg( 'passwordpolicies-policy-' . strtolower( $gp ) )->numParams( $val );
+                       $flagMsgs = [];
+                       foreach ( array_filter( $flags ) as $flag => $value ) {
+                               $flagMsg = $this->msg( 'passwordpolicies-policyflag-' . strtolower( $flag ) );
+                               $flagMsg->params( $value );
+                               $flagMsgs[] = $flagMsg;
+                       }
+                       if ( $flagMsgs ) {
+                               $ret[] = $this->msg(
+                                       'passwordpolicies-policy-displaywithflags',
+                                       $msg,
+                                       '<span class="mw-passwordpolicies-policy-name">' . $gp . '</span>',
+                                       $this->getLanguage()->commaList( $flagMsgs )
+                               )->parse();
                        } else {
-                               $msg = $this->msg( 'passwordpolicies-policy-' . strtolower( $gp ) )->numParams( $val );
+                               $ret[] = $this->msg(
+                                       'passwordpolicies-policy-display',
+                                       $msg,
+                                       '<span class="mw-passwordpolicies-policy-name">' . $gp . '</span>'
+                               )->parse();
                        }
-                       $ret[] = $this->msg(
-                               'passwordpolicies-policy-display',
-                               $msg,
-                               '<span class="mw-passwordpolicies-policy-name">' . $gp . '</span>'
-                       )->parse();
                }
                if ( $ret === [] ) {
                        return '';
index d99de1e..e9dca35 100644 (file)
@@ -46,8 +46,7 @@ class SpecialProtectedpages extends SpecialPage {
                $size = $request->getIntOrNull( 'size' );
                $ns = $request->getIntOrNull( 'namespace' );
 
-               $filters = $request->getArray( 'wpfilters' );
-               $filters = is_null( $filters ) ? [] : $filters;
+               $filters = $request->getArray( 'wpfilters', [] );
                $indefOnly = in_array( 'indefonly', $filters );
                $cascadeOnly = in_array( 'cascadeonly', $filters );
                $noRedirect = in_array( 'noredirect', $filters );
index d781e16..855f799 100644 (file)
@@ -219,7 +219,7 @@ class SpecialRandomInCategory extends FormSpecialPage {
                                'OFFSET' => $offset
                        ],
                        'join_conds' => [
-                               'page' => [ 'INNER JOIN', 'cl_from = page_id' ]
+                               'page' => [ 'JOIN', 'cl_from = page_id' ]
                        ]
                ];
 
index 1e016a5..c8f65c1 100644 (file)
@@ -136,9 +136,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
        }
 
        /**
-        * Main execution point
-        *
-        * @param string $subpage
+        * @param string|null $subpage
         */
        public function execute( $subpage ) {
                // Backwards-compatibility: redirect to new feed URLs
@@ -682,16 +680,21 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        [ 'name' => 'namespace', 'id' => 'namespace' ]
                );
                $nsLabel = Xml::label( $this->msg( 'namespace' )->text(), 'namespace' );
-               $invert = Xml::checkLabel(
+               $attribs = [ 'class' => [ 'mw-input-with-label' ] ];
+               // Hide the checkboxes when the namespace filter is set to 'all'.
+               if ( $opts['namespace'] === '' ) {
+                       $attribs['class'][] = 'mw-input-hidden';
+               }
+               $invert = Html::rawElement( 'span', $attribs, Xml::checkLabel(
                        $this->msg( 'invert' )->text(), 'invert', 'nsinvert',
                        $opts['invert'],
                        [ 'title' => $this->msg( 'tooltip-invert' )->text() ]
-               );
-               $associated = Xml::checkLabel(
+               ) );
+               $associated = Html::rawElement( 'span', $attribs, Xml::checkLabel(
                        $this->msg( 'namespace_association' )->text(), 'associated', 'nsassociated',
                        $opts['associated'],
                        [ 'title' => $this->msg( 'tooltip-namespace_association' )->text() ]
-               );
+               ) );
 
                return [ $nsLabel, "$nsSelect $invert $associated" ];
        }
@@ -912,7 +915,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        'span',
                        [ 'class' => 'rclistfrom' ],
                        $this->makeOptionsLink(
-                               $this->msg( 'rclistfrom' )->rawParams( $now, $timenow, $datenow )->parse(),
+                               $this->msg( 'rclistfrom' )->plaintextParams( $now, $timenow, $datenow )->parse(),
                                [ 'from' => $timestamp ],
                                $nondefaults
                        )
index e42cc70..8865654 100644 (file)
@@ -207,7 +207,7 @@ class SpecialRecentChangesLinked extends SpecialRecentChanges {
                                $conds + $subconds,
                                __METHOD__,
                                $order + $query_options,
-                               $join_conds + [ $link_table => [ 'INNER JOIN', $subjoin ] ]
+                               $join_conds + [ $link_table => [ 'JOIN', $subjoin ] ]
                        );
 
                        if ( $dbr->unionSupportsOrderAndLimit() ) {
@@ -224,7 +224,8 @@ class SpecialRecentChangesLinked extends SpecialRecentChanges {
                        $sql = $subsql[0];
                } else {
                        // need to resort and relimit after union
-                       $sql = $dbr->unionQueries( $subsql, false ) . ' ORDER BY rc_timestamp DESC';
+                       $sql = $dbr->unionQueries( $subsql, $dbr::UNION_DISTINCT ) .
+                               ' ORDER BY rc_timestamp DESC';
                        $sql = $dbr->limitResult( $sql, $limit, false );
                }
 
index b462ce5..f0bac45 100644 (file)
@@ -418,7 +418,8 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                // Show form if the user can submit
                if ( $this->mIsAllowed ) {
                        $out->addModules( [ 'mediawiki.special.revisionDelete' ] );
-                       $out->addModuleStyles( 'mediawiki.special' );
+                       $out->addModuleStyles( [ 'mediawiki.special',
+                               'mediawiki.interface.helpers.styles' ] );
 
                        $form = Xml::openElement( 'form', [ 'method' => 'post',
                                        'action' => $this->getPageTitle()->getLocalURL( [ 'action' => 'submit' ] ),
index ec6c5b9..f27a736 100644 (file)
@@ -102,7 +102,7 @@ class SpecialSearch extends SpecialPage {
        /**
         * Entry point
         *
-        * @param string $par
+        * @param string|null $par
         */
        public function execute( $par ) {
                $request = $this->getRequest();
@@ -115,7 +115,7 @@ class SpecialSearch extends SpecialPage {
                // parameter, but also as part of the primary url. This can have PII implications
                // in releasing page view data. As such issue a 301 redirect to the correct
                // URL.
-               if ( strlen( $par ) && !strlen( $term ) ) {
+               if ( $par !== null && $par !== '' && $term === '' ) {
                        $query = $request->getValues();
                        unset( $query['title'] );
                        // Strip underscores from title parameter; most of the time we'll want
@@ -129,7 +129,7 @@ class SpecialSearch extends SpecialPage {
                $this->load();
                // TODO: This performs database actions on GET request, which is going to
                // be a problem for our multi-datacenter work.
-               if ( !is_null( $request->getVal( 'nsRemember' ) ) ) {
+               if ( $request->getCheck( 'nsRemember' ) ) {
                        $this->saveNamespaces();
                        // Remove the token from the URL to prevent the user from inadvertently
                        // exposing it (e.g. by pasting it into a public wiki page) or undoing
@@ -141,10 +141,7 @@ class SpecialSearch extends SpecialPage {
                }
 
                $this->searchEngineType = $request->getVal( 'srbackend' );
-               if (
-                       !$request->getVal( 'fulltext' ) &&
-                       $request->getVal( 'offset' ) === null
-               ) {
+               if ( !$request->getVal( 'fulltext' ) && !$request->getCheck( 'offset' ) ) {
                        $url = $this->goResult( $term );
                        if ( $url !== null ) {
                                // successful 'go'
@@ -167,21 +164,7 @@ class SpecialSearch extends SpecialPage {
                                $url = str_replace( '$1', urlencode( $term ), $searchForwardUrl );
                                $out->redirect( $url );
                        } else {
-                               $out->addHTML(
-                                       "<fieldset>" .
-                                               "<legend>" .
-                                                       $this->msg( 'search-external' )->escaped() .
-                                               "</legend>" .
-                                               "<p class='mw-searchdisabled'>" .
-                                                       $this->msg( 'searchdisabled' )->escaped() .
-                                               "</p>" .
-                                               $this->msg( 'googlesearch' )->rawParams(
-                                                       htmlspecialchars( $term ),
-                                                       'UTF-8',
-                                                       $this->msg( 'searchbutton' )->escaped()
-                                               )->text() .
-                                       "</fieldset>"
-                               );
+                               $this->showGoogleSearch( $term );
                        }
 
                        return;
@@ -190,6 +173,31 @@ class SpecialSearch extends SpecialPage {
                $this->showResults( $term );
        }
 
+       /**
+        * Output a google search form if search is disabled
+        *
+        * @param string $term Search term
+        * @todo FIXME Maybe we should get rid of this raw html message at some future time
+        * @suppress SecurityCheck-XSS
+        */
+       private function showGoogleSearch( $term ) {
+               $this->getOutput()->addHTML(
+                       "<fieldset>" .
+                               "<legend>" .
+                                       $this->msg( 'search-external' )->escaped() .
+                               "</legend>" .
+                               "<p class='mw-searchdisabled'>" .
+                                       $this->msg( 'searchdisabled' )->escaped() .
+                               "</p>" .
+                               $this->msg( 'googlesearch' )->rawParams(
+                                       htmlspecialchars( $term ),
+                                       'UTF-8',
+                                       $this->msg( 'searchbutton' )->escaped()
+                               )->text() .
+                       "</fieldset>"
+               );
+       }
+
        /**
         * Set up basic search parameters from the request and user settings.
         *
@@ -235,14 +243,12 @@ class SpecialSearch extends SpecialPage {
                        $this->namespaces = $nslist;
                } elseif ( $profile === 'advanced' ) {
                        $this->namespaces = $nslist;
+               } elseif ( isset( $profiles[$profile]['namespaces'] ) ) {
+                       $this->namespaces = $profiles[$profile]['namespaces'];
                } else {
-                       if ( isset( $profiles[$profile]['namespaces'] ) ) {
-                               $this->namespaces = $profiles[$profile]['namespaces'];
-                       } else {
-                               // Unknown profile requested
-                               $profile = 'default';
-                               $this->namespaces = $profiles['default']['namespaces'];
-                       }
+                       // Unknown profile requested
+                       $profile = 'default';
+                       $this->namespaces = $profiles['default']['namespaces'];
                }
 
                $this->fulltext = $request->getVal( 'fulltext' );
@@ -463,8 +469,7 @@ class SpecialSearch extends SpecialPage {
                                $offset = $this->offset;
                        }
 
-                       $prevnext = $this->getLanguage()->viewPrevNext(
-                               $this->getPageTitle(),
+                       $prevnext = $this->buildPrevNextNavigation(
                                $offset,
                                $this->limit,
                                $this->powerSearchOptions() + [ 'search' => $term ],
index 9de31da..ee174ac 100644 (file)
@@ -99,10 +99,18 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
                $includesCachedPages = false;
 
                foreach ( $groups as $group => $sortedPages ) {
-                       $out->wrapWikiMsg(
-                               "<h2 class=\"mw-specialpagesgroup\" id=\"mw-specialpagesgroup-$group\">$1</h2>\n",
-                               "specialpages-group-$group"
-                       );
+                       if ( strpos( $group, '/' ) !== false ) {
+                               list( $group, $subGroup ) = explode( '/', $group, 2 );
+                               $out->wrapWikiMsg(
+                                       "<h3 class=\"mw-specialpagessubgroup\">$1</h3>\n",
+                                       "specialpages-group-$group-$subGroup"
+                               );
+                       } else {
+                               $out->wrapWikiMsg(
+                                       "<h2 class=\"mw-specialpagesgroup\" id=\"mw-specialpagesgroup-$group\">$1</h2>\n",
+                                       "specialpages-group-$group"
+                               );
+                       }
                        $out->addHTML(
                                Html::openElement( 'div', [ 'class' => 'mw-specialpages-list' ] )
                                . '<ul>'
index 0c74e76..110fb1f 100644 (file)
@@ -237,10 +237,8 @@ class SpecialTags extends SpecialPage {
                // add raw $hitcount for sorting, because tags-hitcount contains numbers and letters
                $newRow .= Xml::tags( 'td', [ 'data-sort-value' => $hitcount ], $hitcountLabel );
 
-               // actions
                $actionLinks = [];
 
-               // delete
                if ( $showDeleteActions && ChangeTags::canDeleteTag( $tag )->isOK() ) {
                        $actionLinks[] = $linkRenderer->makeKnownLink(
                                $this->getPageTitle( 'delete' ),
@@ -250,7 +248,6 @@ class SpecialTags extends SpecialPage {
                }
 
                if ( $showManageActions ) { // we've already checked that the user had the requisite userright
-                       // activate
                        if ( ChangeTags::canActivateTag( $tag )->isOK() ) {
                                $actionLinks[] = $linkRenderer->makeKnownLink(
                                        $this->getPageTitle( 'activate' ),
@@ -259,7 +256,6 @@ class SpecialTags extends SpecialPage {
                                        [ 'tag' => $tag ] );
                        }
 
-                       // deactivate
                        if ( ChangeTags::canDeactivateTag( $tag )->isOK() ) {
                                $actionLinks[] = $linkRenderer->makeKnownLink(
                                        $this->getPageTitle( 'deactivate' ),
index 632415c..a04fe4e 100644 (file)
@@ -205,7 +205,7 @@ class SpecialUnblock extends SpecialPage {
 
                # If the name was hidden and the blocking user cannot hide
                # names, then don't allow any block removals...
-               if ( !$performer->isAllowed( 'hideuser' ) && $block->mHideName ) {
+               if ( !$performer->isAllowed( 'hideuser' ) && $block->getHideName() ) {
                        return [ 'unblock-hideuser' ];
                }
 
@@ -222,7 +222,7 @@ class SpecialUnblock extends SpecialPage {
                Hooks::run( 'UnblockUserComplete', [ $block, $performer ] );
 
                # Unset _deleted fields as needed
-               if ( $block->mHideName ) {
+               if ( $block->getHideName() ) {
                        # Something is deeply FUBAR if this is not a User object, but who knows?
                        $id = $block->getTarget() instanceof User
                                ? $block->getTarget()->getId()
index 3e560ad..5f69426 100644 (file)
@@ -95,7 +95,8 @@ class SpecialUndelete extends SpecialPage {
                $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && $user->isAllowed( 'suppressrevision' );
                $this->mToken = $request->getVal( 'token' );
 
-               if ( $this->isAllowed( 'undelete' ) && !$user->isBlocked() ) {
+               $block = $user->getBlock();
+               if ( $this->isAllowed( 'undelete' ) && !( $block && $block->isSitewide() ) ) {
                        $this->mAllowed = true; // user can restore
                        $this->mCanView = true; // user can view content
                } elseif ( $this->isAllowed( 'deletedtext' ) ) {
@@ -199,7 +200,7 @@ class SpecialUndelete extends SpecialPage {
                        } else {
                                $this->showFile( $this->mFilename );
                        }
-               } elseif ( $this->mAction === "submit" ) {
+               } elseif ( $this->mAction === 'submit' ) {
                        if ( $this->mRestore ) {
                                $this->undelete();
                        } elseif ( $this->mRevdel ) {
@@ -223,13 +224,14 @@ class SpecialUndelete extends SpecialPage {
                foreach ( $this->getRequest()->getValues() as $key => $val ) {
                        $matches = [];
                        if ( preg_match( "/^ts(\d{14})$/", $key, $matches ) ) {
-                               $revisions[ $archive->getRevision( $matches[1] )->getId() ] = 1;
+                               $revisions[$archive->getRevision( $matches[1] )->getId()] = 1;
                        }
                }
+
                $query = [
-                       "type" => "revision",
-                       "ids" => $revisions,
-                       "target" => $this->mTargetObj->getPrefixedText()
+                       'type' => 'revision',
+                       'ids' => $revisions,
+                       'target' => $this->mTargetObj->getPrefixedText()
                ];
                $url = SpecialPage::getTitleFor( 'Revisiondelete' )->getFullURL( $query );
                $this->getOutput()->redirect( $url );
@@ -455,7 +457,7 @@ class SpecialUndelete extends SpecialPage {
                        Message::rawParam( $link ), $time,
                        Message::rawParam( $userLink ), $d, $t
                );
-               $out->addHtml( '</div>' );
+               $out->addHTML( '</div>' );
 
                if ( !Hooks::run( 'UndeleteShowRevision', [ $this->mTargetObj, $rev ] ) ) {
                        return;
@@ -502,7 +504,6 @@ class SpecialUndelete extends SpecialPage {
                        ] );
                } else {
                        $sourceView = '';
-                       $previewButton = '';
                }
 
                $buttonFields[] = new OOUI\ButtonInputWidget( [
@@ -548,7 +549,6 @@ class SpecialUndelete extends SpecialPage {
         *
         * @param Revision $previousRev
         * @param Revision $currentRev
-        * @return string HTML
         */
        function showDiff( $previousRev, $currentRev ) {
                $diffContext = clone $this->getContext();
index dbb1481..dcc35fc 100644 (file)
@@ -146,8 +146,7 @@ class SpecialUpload extends SpecialPage {
        }
 
        /**
-        * Special page entry point
-        * @param string $par
+        * @param string|null $par
         * @throws ErrorPageError
         * @throws Exception
         * @throws FatalError
@@ -192,11 +191,9 @@ class SpecialUpload extends SpecialPage {
                $this->loadRequest();
 
                # Unsave the temporary file in case this was a cancelled upload
-               if ( $this->mCancelUpload ) {
-                       if ( !$this->unsaveUploadedFile() ) {
-                               # Something went wrong, so unsaveUploadedFile showed a warning
-                               return;
-                       }
+               if ( $this->mCancelUpload && !$this->unsaveUploadedFile() ) {
+                       # Something went wrong, so unsaveUploadedFile showed a warning
+                       return;
                }
 
                # Process upload or show a form
index abd3e07..24d58c8 100644 (file)
@@ -60,7 +60,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
        /**
         * Execute page -- can output a file directly or show a listing of them.
         *
-        * @param string $subPage Subpage, e.g. in
+        * @param string|null $subPage Subpage, e.g. in
         *   https://example.com/wiki/Special:UploadStash/foo.jpg, the "foo.jpg" part
         * @return bool Success
         */
@@ -261,12 +261,30 @@ class SpecialUploadStash extends UnlistedSpecialPage {
                $scalerThumbUrl = $scalerBaseUrl . '/' . $file->getUrlRel() .
                        '/' . rawurlencode( $scalerThumbName );
 
-               // make a curl call to the scaler to create a thumbnail
+               // If a thumb proxy is set up for the repo, we favor that, as that will
+               // keep the request internal
+               $thumbProxyUrl = $file->getRepo()->getThumbProxyUrl();
+
+               if ( strlen( $thumbProxyUrl ) ) {
+                       $scalerThumbUrl = $thumbProxyUrl . 'temp/' . $file->getUrlRel() .
+                       '/' . rawurlencode( $scalerThumbName );
+               }
+
+               // make an http request based on wgUploadStashScalerBaseUrl to lazy-create
+               // a thumbnail
                $httpOptions = [
                        'method' => 'GET',
                        'timeout' => 5 // T90599 attempt to time out cleanly
                ];
                $req = MWHttpRequest::factory( $scalerThumbUrl, $httpOptions, __METHOD__ );
+
+               $secret = $file->getRepo()->getThumbProxySecret();
+
+               // Pass a secret key shared with the proxied service if any
+               if ( strlen( $secret ) ) {
+                       $req->setHeader( 'X-Swift-Secret', $secret );
+               }
+
                $status = $req->execute();
                if ( !$status->isOK() ) {
                        $errors = $status->getErrorsArray();
index 6e6d905..540754f 100644 (file)
@@ -387,9 +387,6 @@ class UserrightsPage extends SpecialPage {
                // update groups in external authentication database
                Hooks::run( 'UserGroupsChanged', [ $user, $add, $remove, $this->getUser(),
                        $reason, $oldUGMs, $newUGMs ] );
-               MediaWiki\Auth\AuthManager::callLegacyAuthPlugin(
-                       'updateExternalDBGroups', [ $user, $add, $remove ]
-               );
 
                wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) . "\n" );
                wfDebug( 'newGroups: ' . print_r( $newGroups, true ) . "\n" );
index 2ad0def..2632092 100644 (file)
@@ -206,6 +206,7 @@ class SpecialVersion extends SpecialPage {
                        'Victor Vasiliev', 'Rotem Liss', 'Platonides', 'Antoine Musso',
                        'Timo Tijhof', 'Daniel Kinzler', 'Jeroen De Dauw', 'Brad Jorsch',
                        'Bartosz Dziewoński', 'Ed Sanders', 'Moriel Schottlender',
+                       'Kunal Mehta', 'James D. Forrester', 'Brian Wolff', 'Adam Shorland',
                        $othersLink, $translatorsLink
                ];
 
@@ -703,7 +704,7 @@ class SpecialVersion extends SpecialPage {
                                [ 'class' => 'mw-version-ext-name' ]
                        );
                } else {
-                       $extensionNameLink = $extensionName;
+                       $extensionNameLink = htmlspecialchars( $extensionName );
                }
 
                // ... and the version information
index 971aa43..6defc9d 100644 (file)
@@ -37,12 +37,16 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        protected static $limitPreferenceName = 'wllimit';
        protected static $collapsedPreferenceName = 'rcfilters-wl-collapsed';
 
+       /** @var float|int */
        private $maxDays;
+       /** WatchedItemStore */
+       private $watchStore;
 
        public function __construct( $page = 'Watchlist', $restriction = 'viewmywatchlist' ) {
                parent::__construct( $page, $restriction );
 
                $this->maxDays = $this->getConfig()->get( 'RCMaxAge' ) / ( 3600 * 24 );
+               $this->watchStore = MediaWikiServices::getInstance()->getWatchedItemStore();
        }
 
        public function doesWrites() {
@@ -63,6 +67,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $this->addHelpLink( 'Help:Watching pages' );
                $output->addModuleStyles( [ 'mediawiki.special' ] );
                $output->addModules( [
+                       'mediawiki.special.recentchanges',
                        'mediawiki.special.watchlist',
                ] );
 
@@ -186,9 +191,13 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                                        'label' => 'rcfilters-filter-watchlistactivity-unseen-label',
                                        'description' => 'rcfilters-filter-watchlistactivity-unseen-description',
                                        'cssClassSuffix' => 'watchedunseen',
-                                       'isRowApplicableCallable' => function ( $ctx, $rc ) {
+                                       'isRowApplicableCallable' => function ( $ctx, RecentChange $rc ) {
                                                $changeTs = $rc->getAttribute( 'rc_timestamp' );
-                                               $lastVisitTs = $rc->getAttribute( 'wl_notificationtimestamp' );
+                                               $lastVisitTs = $this->watchStore->getLatestNotificationTimestamp(
+                                                       $rc->getAttribute( 'wl_notificationtimestamp' ),
+                                                       $rc->getPerformer(),
+                                                       $rc->getTitle()
+                                               );
                                                return $lastVisitTs !== null && $changeTs >= $lastVisitTs;
                                        },
                                ],
@@ -343,7 +352,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $join_conds = array_merge(
                        [
                                'watchlist' => [
-                                       'INNER JOIN',
+                                       'JOIN',
                                        [
                                                'wl_user' => $user->getId(),
                                                'wl_namespace=rc_namespace',
@@ -458,7 +467,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $services = MediaWikiServices::getInstance();
 
                # Show a message about replica DB lag, if applicable
-               $lag = $services->getDBLoadBalancer()->safeGetLag( $dbr );
+               $lag = $dbr->getSessionLagStatus()['lag'];
                if ( $lag > 0 ) {
                        $output->showLagWarning( $lag );
                }
@@ -655,14 +664,15 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                                'class' => 'namespaceselector',
                        ]
                ) . "\n";
-               $namespaceForm .= '<span class="mw-input-with-label">' . Xml::checkLabel(
+               $hidden = $opts['namespace'] === '' ? ' mw-input-hidden' : '';
+               $namespaceForm .= '<span class="mw-input-with-label' . $hidden . '">' . Xml::checkLabel(
                        $this->msg( 'invert' )->text(),
                        'invert',
                        'nsinvert',
                        $opts['invert'],
                        [ 'title' => $this->msg( 'tooltip-invert' )->text() ]
                ) . "</span>\n";
-               $namespaceForm .= '<span class="mw-input-with-label">' . Xml::checkLabel(
+               $namespaceForm .= '<span class="mw-input-with-label' . $hidden . '">' . Xml::checkLabel(
                        $this->msg( 'namespace_association' )->text(),
                        'associated',
                        'nsassociated',
index 766e190..18c10bf 100644 (file)
@@ -170,7 +170,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                                // Force JOIN order per T106682 to avoid large filesorts
                                [ 'ORDER BY' => $fromCol, 'LIMIT' => 2 * $queryLimit, 'STRAIGHT_JOIN' ],
                                [
-                                       'page' => [ 'INNER JOIN', "$fromCol = page_id" ],
+                                       'page' => [ 'JOIN', "$fromCol = page_id" ],
                                        'redirect' => [ 'LEFT JOIN', $on ]
                                ]
                        );
@@ -180,7 +180,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                                [],
                                __CLASS__ . '::showIndirectLinks',
                                [ 'ORDER BY' => 'page_id', 'LIMIT' => $queryLimit ],
-                               [ 'page' => [ 'INNER JOIN', "$fromCol = page_id" ] ]
+                               [ 'page' => [ 'JOIN', "$fromCol = page_id" ] ]
                        );
                };
 
@@ -200,29 +200,27 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                        && ( $hidetrans || !$tlRes->numRows() )
                        && ( $hideimages || !$ilRes->numRows() )
                ) {
-                       if ( $level == 0 ) {
-                               if ( !$this->including() ) {
-                                       $out->addHTML( $this->whatlinkshereForm() );
-
-                                       // Show filters only if there are links
-                                       if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) {
-                                               $out->addHTML( $this->getFilterPanel() );
-                                       }
-                                       $msgKey = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
-                                       $link = $this->getLinkRenderer()->makeLink(
-                                               $this->target,
-                                               null,
-                                               [],
-                                               $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
-                                       );
-
-                                       $errMsg = $this->msg( $msgKey )
-                                               ->params( $this->target->getPrefixedText() )
-                                               ->rawParams( $link )
-                                               ->parseAsBlock();
-                                       $out->addHTML( $errMsg );
-                                       $out->setStatusCode( 404 );
+                       if ( $level == 0 && !$this->including() ) {
+                               $out->addHTML( $this->whatlinkshereForm() );
+
+                               // Show filters only if there are links
+                               if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) {
+                                       $out->addHTML( $this->getFilterPanel() );
                                }
+                               $msgKey = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
+                               $link = $this->getLinkRenderer()->makeLink(
+                                       $this->target,
+                                       null,
+                                       [],
+                                       $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
+                               );
+
+                               $errMsg = $this->msg( $msgKey )
+                                       ->params( $this->target->getPrefixedText() )
+                                       ->rawParams( $link )
+                                       ->parseAsBlock();
+                               $out->addHTML( $errMsg );
+                               $out->setStatusCode( 404 );
                        }
 
                        return;
@@ -280,27 +278,25 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                }
                $lb->execute();
 
-               if ( $level == 0 ) {
-                       if ( !$this->including() ) {
-                               $out->addHTML( $this->whatlinkshereForm() );
-                               $out->addHTML( $this->getFilterPanel() );
+               if ( $level == 0 && !$this->including() ) {
+                       $out->addHTML( $this->whatlinkshereForm() );
+                       $out->addHTML( $this->getFilterPanel() );
 
-                               $link = $this->getLinkRenderer()->makeLink(
-                                       $this->target,
-                                       null,
-                                       [],
-                                       $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
-                               );
+                       $link = $this->getLinkRenderer()->makeLink(
+                               $this->target,
+                               null,
+                               [],
+                               $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
+                       );
 
-                               $msg = $this->msg( 'linkshere' )
-                                       ->params( $this->target->getPrefixedText() )
-                                       ->rawParams( $link )
-                                       ->parseAsBlock();
-                               $out->addHTML( $msg );
+                       $msg = $this->msg( 'linkshere' )
+                               ->params( $this->target->getPrefixedText() )
+                               ->rawParams( $link )
+                               ->parseAsBlock();
+                       $out->addHTML( $msg );
 
-                               $prevnext = $this->getPrevNext( $prevId, $nextId );
-                               $out->addHTML( $prevnext );
-                       }
+                       $prevnext = $this->getPrevNext( $prevId, $nextId );
+                       $out->addHTML( $prevnext );
                }
                $out->addHTML( $this->listStart( $level ) );
                foreach ( $rows as $row ) {
@@ -321,10 +317,8 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
 
                $out->addHTML( $this->listEnd() );
 
-               if ( $level == 0 ) {
-                       if ( !$this->including() ) {
-                               $out->addHTML( $prevnext );
-                       }
+               if ( $level == 0 && !$this->including() ) {
+                       $out->addHTML( $prevnext );
                }
        }
 
index 51e63d9..204b033 100644 (file)
@@ -214,7 +214,7 @@ class Licenses extends HTMLFormField {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function getInputHTML( $value ) {
                $this->selected = $value;
index 81abf1c..8358cd2 100644 (file)
@@ -117,45 +117,12 @@ class PreferencesFormOOUI extends OOUIHTMLForm {
        }
 
        protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) {
-               // to get a user visible effect, wrap the fieldset into a framed panel layout
-               if ( $isRoot ) {
-                       // Mimic TabPanelLayout
-                       $wrapper = new OOUI\PanelLayout( [
-                               'expanded' => false,
-                               'scrollable' => true,
-                               // Framed and padded for no-JS, frame hidden with CSS
-                               'framed' => true,
-                               'infusable' => false,
-                               'classes' => [ 'oo-ui-stackLayout oo-ui-indexLayout-stackLayout' ]
-                       ] );
-                       $layout = new OOUI\PanelLayout( [
-                               'expanded' => false,
-                               'scrollable' => true,
-                               'infusable' => false,
-                               'classes' => [ 'oo-ui-tabPanelLayout' ]
-                       ] );
-                       $wrapper->appendContent( $layout );
-               } else {
-                       $wrapper = $layout = new OOUI\PanelLayout( [
-                               'expanded' => false,
-                               'padded' => true,
-                               'framed' => true,
-                               'infusable' => false,
-                       ] );
-               }
+               $layout = parent::wrapFieldSetSection( $legend, $section, $attributes, $isRoot );
+
+               $layout->addClasses( [ 'mw-prefs-fieldset-wrapper' ] );
+               $layout->removeClasses( [ 'oo-ui-panelLayout-framed' ] );
 
-               $layout->appendContent(
-                       new OOUI\FieldsetLayout( [
-                               'label' => $legend,
-                               'infusable' => false,
-                               'items' => [
-                                       new OOUI\Widget( [
-                                               'content' => new OOUI\HtmlSnippet( $section )
-                                       ] ),
-                               ],
-                       ] + $attributes )
-               );
-               return $wrapper;
+               return $layout;
        }
 
        /**
@@ -163,61 +130,55 @@ class PreferencesFormOOUI extends OOUIHTMLForm {
         * @return string
         */
        function getBody() {
-               // Construct fake tabs to avoid FOUC. The structure mimics OOUI's tabPanelLayout.
-               // TODO: Consider creating an infusable TabPanelLayout in OOUI-PHP.
-               $fakeTabs = [];
-               foreach ( $this->getPreferenceSections() as $i => $key ) {
-                       $fakeTabs[] =
-                               Html::rawElement(
-                                       'div',
-                                       [
-                                               'class' =>
-                                                       'oo-ui-widget oo-ui-widget-enabled oo-ui-optionWidget ' .
-                                                       'oo-ui-tabOptionWidget oo-ui-labelElement' .
-                                                       ( $i === 0 ? ' oo-ui-optionWidget-selected' : '' )
+               $tabPanels = [];
+               foreach ( $this->mFieldTree as $key => $val ) {
+                       if ( !is_array( $val ) ) {
+                               wfDebug( __METHOD__ . " encountered a field not attached to a section: '$key'" );
+                               continue;
+                       }
+                       $label = $this->getLegend( $key );
+                       $content =
+                               $this->getHeaderText( $key ) .
+                               $this->displaySection(
+                                       $this->mFieldTree[$key],
+                                       "",
+                                       "mw-prefsection-$key-"
+                               ) .
+                               $this->getFooterText( $key );
+
+                       $tabPanels[] = new OOUI\TabPanelLayout( [
+                               'classes' => [ 'mw-htmlform-autoinfuse-lazy' ],
+                               'name' => 'mw-prefsection-' . $key,
+                               'label' => $label,
+                               'content' => new OOUI\FieldsetLayout( [
+                                       'classes' => [ 'mw-prefs-section-fieldset' ],
+                                       'id' => "mw-prefsection-$key",
+                                       'label' => $label,
+                                       'items' => [
+                                               new OOUI\Widget( [
+                                                       'content' => new OOUI\HtmlSnippet( $content )
+                                               ] ),
                                        ],
-                                       Html::element(
-                                               'a',
-                                               [
-                                                       'class' => 'oo-ui-labelElement-label',
-                                                       // Make this a usable link instead of a span so the tabs
-                                                       // can be used before JS runs
-                                                       'href' => '#mw-prefsection-' . $key
-                                               ],
-                                               $this->getLegend( $key )
-                                       )
-                               );
+                               ] ),
+                               'expanded' => false,
+                               'framed' => true,
+                       ] );
                }
-               $fakeTabsHtml = Html::rawElement(
-                       'div',
-                       [ 'class' => 'oo-ui-layout oo-ui-panelLayout oo-ui-indexLayout-tabPanel' ],
-                       Html::rawElement(
-                               'div',
-                               [ 'class' => 'oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget ' .
-                                       'oo-ui-selectWidget-depressed oo-ui-tabSelectWidget' ],
-                               implode( $fakeTabs )
-                       )
-               );
-
-               return Html::rawElement(
-                       'div',
-                       [ 'class' => 'oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed mw-prefs-faketabs' ],
-                       Html::rawElement(
-                               'div',
-                               [ 'class' => 'oo-ui-layout oo-ui-menuLayout oo-ui-menuLayout-static ' .
-                                       'oo-ui-menuLayout-top oo-ui-menuLayout-showMenu oo-ui-indexLayout' ],
-                               Html::rawElement(
-                                       'div',
-                                       [ 'class' => 'oo-ui-menuLayout-menu' ],
-                                       $fakeTabsHtml
-                               ) .
-                               Html::rawElement(
-                                       'div',
-                                       [ 'class' => 'oo-ui-menuLayout-content mw-htmlform-autoinfuse-lazy' ],
-                                       $this->displaySection( $this->mFieldTree, '', 'mw-prefsection-' )
-                               )
-                       )
-               );
+
+               $indexLayout = new OOUI\IndexLayout( [
+                       'infusable' => true,
+                       'expanded' => false,
+                       'autoFocus' => false,
+                       'classes' => [ 'mw-prefs-tabs' ],
+               ] );
+               $indexLayout->addTabPanels( $tabPanels );
+
+               return new OOUI\PanelLayout( [
+                       'framed' => true,
+                       'expanded' => false,
+                       'classes' => [ 'mw-prefs-tabs-wrapper' ],
+                       'content' => $indexLayout
+               ] );
        }
 
        /**
index da4398a..7a47edf 100644 (file)
@@ -393,7 +393,7 @@ class UploadForm extends HTMLForm {
         */
        public function show() {
                $this->addUploadJS();
-               parent::show();
+               return parent::show();
        }
 
        /**
index c79e87c..8063804 100644 (file)
@@ -69,10 +69,10 @@ class ImportReporter extends ContextSource {
                );
        }
 
-       function reportLogItem( /* ... */ ) {
+       function reportLogItem( ...$args ) {
                $this->mLogItemCount++;
                if ( is_callable( $this->mOriginalLogCallback ) ) {
-                       call_user_func_array( $this->mOriginalLogCallback, func_get_args() );
+                       call_user_func_array( $this->mOriginalLogCallback, $args );
                }
        }
 
@@ -86,8 +86,7 @@ class ImportReporter extends ContextSource {
         */
        public function reportPage( $title, $foreignTitle, $revisionCount,
                        $successCount, $pageInfo ) {
-               $args = func_get_args();
-               call_user_func_array( $this->mOriginalPageOutCallback, $args );
+               call_user_func_array( $this->mOriginalPageOutCallback, func_get_args() );
 
                if ( $title === null ) {
                        # Invalid or non-importable title; a notice is already displayed
index aedb9e6..39da076 100644 (file)
@@ -138,15 +138,14 @@ class ActiveUsersPager extends UsersPager {
 
                // Outer query to select the recent edit counts for the selected active users
                $tables = [ 'qcc_users' => $subquery, 'recentchanges' ];
-               $jconds = [ 'recentchanges' => [
-                       'JOIN', $useActor ? 'rc_actor = actor_id' : 'rc_user_text = qcc_title',
-               ] ];
-               $conds = [
+               $jconds = [ 'recentchanges' => [ 'LEFT JOIN', [
+                       $useActor ? 'rc_actor = actor_id' : 'rc_user_text = qcc_title',
                        'rc_type != ' . $dbr->addQuotes( RC_EXTERNAL ), // Don't count wikidata.
                        'rc_type != ' . $dbr->addQuotes( RC_CATEGORIZE ), // Don't count categorization changes.
                        'rc_log_type IS NULL OR rc_log_type != ' . $dbr->addQuotes( 'newusers' ),
                        'rc_timestamp >= ' . $dbr->addQuotes( $timestamp ),
-               ];
+               ] ] ];
+               $conds = [];
 
                return [
                        'tables' => $tables,
@@ -154,7 +153,7 @@ class ActiveUsersPager extends UsersPager {
                                'qcc_title',
                                'user_name' => 'qcc_title',
                                'user_id' => 'user_id',
-                               'recentedits' => 'COUNT(*)'
+                               'recentedits' => 'COUNT(rc_id)'
                        ],
                        'options' => [ 'GROUP BY' => [ 'qcc_title' ] ],
                        'conds' => $conds,
@@ -162,14 +161,16 @@ class ActiveUsersPager extends UsersPager {
                ];
        }
 
-       protected function buildQueryInfo( $offset, $limit, $descending ) {
+       protected function buildQueryInfo( $offset, $limit, $order ) {
                $fname = __METHOD__ . ' (' . $this->getSqlComment() . ')';
 
                $sortColumns = array_merge( [ $this->mIndexField ], $this->mExtraSortFields );
-               if ( $descending ) {
+               if ( $order === self::QUERY_ASCENDING ) {
+                       $dir = 'ASC';
                        $orderBy = $sortColumns;
                        $operator = $this->mIncludeOffset ? '>=' : '>';
                } else {
+                       $dir = 'DESC';
                        $orderBy = [];
                        foreach ( $sortColumns as $col ) {
                                $orderBy[] = $col . ' DESC';
@@ -178,7 +179,7 @@ class ActiveUsersPager extends UsersPager {
                }
                $info = $this->getQueryInfo( [
                        'limit' => intval( $limit ),
-                       'order' => $descending ? 'DESC' : 'ASC',
+                       'order' => $dir,
                        'conds' =>
                                $offset != '' ? [ $this->mIndexField . $operator . $this->mDb->addQuotes( $offset ) ] : [],
                ] );
@@ -229,7 +230,6 @@ class ActiveUsersPager extends UsersPager {
                $lang = $this->getLanguage();
 
                $list = [];
-               $user = User::newFromId( $row->user_id );
 
                $ugms = self::getGroupMemberships( intval( $row->user_id ), $this->userGroupCache );
                foreach ( $ugms as $ugm ) {
index f045333..8120417 100644 (file)
@@ -167,24 +167,25 @@ class AllMessagesTablePager extends TablePager {
        }
 
        /**
-        *  This function normally does a database query to get the results; we need
+        * This function normally does a database query to get the results; we need
         * to make a pretend result using a FakeResultWrapper.
         * @param string $offset
         * @param int $limit
-        * @param bool $descending
+        * @param bool $order
         * @return FakeResultWrapper
         */
-       function reallyDoQuery( $offset, $limit, $descending ) {
+       function reallyDoQuery( $offset, $limit, $order ) {
+               $asc = ( $order === self::QUERY_ASCENDING );
                $result = new FakeResultWrapper( [] );
 
-               $messageNames = $this->getAllMessages( $descending );
+               $messageNames = $this->getAllMessages( $order );
                $statuses = self::getCustomisedStatuses( $messageNames, $this->langcode, $this->foreign );
 
                $count = 0;
                foreach ( $messageNames as $key ) {
                        $customised = isset( $statuses['pages'][$key] );
                        if ( $customised !== $this->custom &&
-                               ( $descending && ( $key < $offset || !$offset ) || !$descending && $key > $offset ) &&
+                               ( $asc && ( $key < $offset || !$offset ) || !$asc && $key > $offset ) &&
                                ( ( $this->prefix && preg_match( $this->prefix, $key ) ) || $this->prefix === false )
                        ) {
                                $actual = wfMessage( $key )->inLanguage( $this->lang )->plain();
index 2fc946e..71cf787 100644 (file)
@@ -161,7 +161,7 @@ class BlockListPager extends TablePager {
                                        $formatted .= '<br />' . $this->msg(
                                                'ipb-blocklist-duration-left',
                                                $language->formatDuration(
-                                                       $timestamp->getTimestamp() - time(),
+                                                       $timestamp->getTimestamp() - MWTimestamp::time(),
                                                        // reasonable output
                                                        [
                                                                'minutes',
@@ -191,10 +191,8 @@ class BlockListPager extends TablePager {
                        case 'ipb_params':
                                $properties = [];
 
-                               if ( $this->getConfig()->get( 'EnablePartialBlocks' ) ) {
-                                       if ( $row->ipb_sitewide ) {
-                                               $properties[] = htmlspecialchars( $msg['blocklist-editing-sitewide'] );
-                                       }
+                               if ( $this->getConfig()->get( 'EnablePartialBlocks' ) && $row->ipb_sitewide ) {
+                                       $properties[] = htmlspecialchars( $msg['blocklist-editing-sitewide'] );
                                }
 
                                if ( !$row->ipb_sitewide && $this->restrictions ) {
@@ -261,7 +259,7 @@ class BlockListPager extends TablePager {
                        switch ( $restriction->getType() ) {
                                case PageRestriction::TYPE:
                                        if ( $restriction->getTitle() ) {
-                                               $items[$restriction->getType()][] = HTML::rawElement(
+                                               $items[$restriction->getType()][] = Html::rawElement(
                                                        'li',
                                                        [],
                                                        Linker::link( $restriction->getTitle() )
@@ -274,7 +272,7 @@ class BlockListPager extends TablePager {
                                                : $this->getLanguage()->getFormattedNsText(
                                                        $restriction->getValue()
                                                );
-                                       $items[$restriction->getType()][] = HTML::rawElement(
+                                       $items[$restriction->getType()][] = Html::rawElement(
                                                'li',
                                                [],
                                                Linker::link(
index 1220e86..10fcfc6 100644 (file)
@@ -154,20 +154,33 @@ class ContribsPager extends RangeChronologicalPager {
                return $query;
        }
 
+       /**
+        * Wrap the navigation bar in a p element with identifying class.
+        * In future we may want to change the `p` tag to a `div` and upstream
+        * this to the parent class.
+        *
+        * @return string HTML
+        */
+       function getNavigationBar() {
+               return Html::rawElement( 'p', [ 'class' => 'mw-pager-navigation-bar' ],
+                       parent::getNavigationBar()
+               );
+       }
+
        /**
         * This method basically executes the exact same code as the parent class, though with
         * a hook added, to allow extensions to add additional queries.
         *
         * @param string $offset Index offset, inclusive
         * @param int $limit Exact query limit
-        * @param bool $descending Query direction, false for ascending, true for descending
+        * @param bool $order IndexPager::QUERY_ASCENDING or IndexPager::QUERY_DESCENDING
         * @return IResultWrapper
         */
-       function reallyDoQuery( $offset, $limit, $descending ) {
+       function reallyDoQuery( $offset, $limit, $order ) {
                list( $tables, $fields, $conds, $fname, $options, $join_conds ) = $this->buildQueryInfo(
                        $offset,
                        $limit,
-                       $descending
+                       $order
                );
 
                /*
@@ -193,7 +206,7 @@ class ContribsPager extends RangeChronologicalPager {
                ) ];
                Hooks::run(
                        'ContribsPager::reallyDoQuery',
-                       [ &$data, $this, $offset, $limit, $descending ]
+                       [ &$data, $this, $offset, $limit, $order ]
                );
 
                $result = [];
@@ -207,7 +220,7 @@ class ContribsPager extends RangeChronologicalPager {
                }
 
                // sort results
-               if ( $descending ) {
+               if ( $order === self::QUERY_ASCENDING ) {
                        ksort( $result );
                } else {
                        krsort( $result );
@@ -633,20 +646,7 @@ class ContribsPager extends RangeChronologicalPager {
 
                        $lang = $this->getLanguage();
                        $comment = $lang->getDirMark() . Linker::revComment( $rev, false, true, false );
-                       $date = $lang->userTimeAndDate( $row->rev_timestamp, $user );
-                       if ( $rev->userCan( Revision::DELETED_TEXT, $user ) ) {
-                               $d = $linkRenderer->makeKnownLink(
-                                       $page,
-                                       $date,
-                                       [ 'class' => 'mw-changeslist-date' ],
-                                       [ 'oldid' => intval( $row->rev_id ) ]
-                               );
-                       } else {
-                               $d = htmlspecialchars( $date );
-                       }
-                       if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
-                               $d = '<span class="history-deleted">' . $d . '</span>';
-                       }
+                       $d = ChangesList::revDateLink( $rev, $user, $lang, $page );
 
                        # Show user names for /newbies as there may be different users.
                        # Note that only unprivileged users have rows with hidden user names excluded.
index fa0fbf3..56b799b 100644 (file)
@@ -115,17 +115,17 @@ class DeletedContribsPager extends IndexPager {
         *
         * @param string $offset Index offset, inclusive
         * @param int $limit Exact query limit
-        * @param bool $descending Query direction, false for ascending, true for descending
+        * @param bool $order IndexPager::QUERY_ASCENDING or IndexPager::QUERY_DESCENDING
         * @return IResultWrapper
         */
-       function reallyDoQuery( $offset, $limit, $descending ) {
-               $data = [ parent::reallyDoQuery( $offset, $limit, $descending ) ];
+       function reallyDoQuery( $offset, $limit, $order ) {
+               $data = [ parent::reallyDoQuery( $offset, $limit, $order ) ];
 
                // This hook will allow extensions to add in additional queries, nearly
                // identical to ContribsPager::reallyDoQuery.
                Hooks::run(
                        'DeletedContribsPager::reallyDoQuery',
-                       [ &$data, $this, $offset, $limit, $descending ]
+                       [ &$data, $this, $offset, $limit, $order ]
                );
 
                $result = [];
@@ -139,7 +139,7 @@ class DeletedContribsPager extends IndexPager {
                }
 
                // sort results
-               if ( $descending ) {
+               if ( $order === self::QUERY_ASCENDING ) {
                        ksort( $result );
                } else {
                        krsort( $result );
index 1794362..ea55568 100644 (file)
@@ -269,10 +269,8 @@ class ImageListPager extends TablePager {
                                }
                        }
                        $fields['top'] = $dbr->addQuotes( 'no' );
-               } else {
-                       if ( $this->mShowAll ) {
-                               $fields['top'] = $dbr->addQuotes( 'yes' );
-                       }
+               } elseif ( $this->mShowAll ) {
+                       $fields['top'] = $dbr->addQuotes( 'yes' );
                }
                $fields['thumb'] = $prefix . '_name';
 
@@ -321,15 +319,15 @@ class ImageListPager extends TablePager {
         *   is descending, so I renamed it to $asc here.
         * @param int $offset
         * @param int $limit
-        * @param bool $asc
-        * @return array
+        * @param bool $order IndexPager::QUERY_ASCENDING or IndexPager::QUERY_DESCENDING
+        * @return FakeResultWrapper
         * @throws MWException
         */
-       function reallyDoQuery( $offset, $limit, $asc ) {
+       function reallyDoQuery( $offset, $limit, $order ) {
                $prevTableName = $this->mTableName;
                $this->mTableName = 'image';
                list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
-                       $this->buildQueryInfo( $offset, $limit, $asc );
+                       $this->buildQueryInfo( $offset, $limit, $order );
                $imageRes = $this->mDb->select( $tables, $fields, $conds, $fname, $options, $join_conds );
                $this->mTableName = $prevTableName;
 
@@ -347,13 +345,13 @@ class ImageListPager extends TablePager {
                $this->mIndexField = 'oi_' . substr( $this->mIndexField, 4 );
 
                list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
-                       $this->buildQueryInfo( $offset, $limit, $asc );
+                       $this->buildQueryInfo( $offset, $limit, $order );
                $oldimageRes = $this->mDb->select( $tables, $fields, $conds, $fname, $options, $join_conds );
 
                $this->mTableName = $prevTableName;
                $this->mIndexField = $oldIndex;
 
-               return $this->combineResult( $imageRes, $oldimageRes, $limit, $asc );
+               return $this->combineResult( $imageRes, $oldimageRes, $limit, $order );
        }
 
        /**
@@ -382,14 +380,12 @@ class ImageListPager extends TablePager {
                                        $resultArray[] = $topRes2;
                                        $topRes2 = $res2->next();
                                }
+                       } elseif ( !$ascending ) {
+                               $resultArray[] = $topRes2;
+                               $topRes2 = $res2->next();
                        } else {
-                               if ( !$ascending ) {
-                                       $resultArray[] = $topRes2;
-                                       $topRes2 = $res2->next();
-                               } else {
-                                       $resultArray[] = $topRes1;
-                                       $topRes1 = $res1->next();
-                               }
+                               $resultArray[] = $topRes1;
+                               $topRes1 = $res1->next();
                        }
                }
 
index 8bac2c4..88dff6e 100644 (file)
@@ -122,7 +122,7 @@ class NewFilesPager extends RangeChronologicalPager {
                                $jcond = $rcQuery['fields']['rc_user'] . ' = ' . $imgQuery['fields']['img_user'];
                        }
                        $jconds['recentchanges'] = [
-                               'INNER JOIN',
+                               'JOIN',
                                [
                                        'rc_title = img_name',
                                        $jcond,
@@ -204,5 +204,6 @@ class NewFilesPager extends RangeChronologicalPager {
                        . htmlspecialchars( $time )
                        . "</i><br />\n"
                );
+               return '';
        }
 }
index d03401d..5788bb2 100644 (file)
@@ -102,7 +102,7 @@ class NewPagesPager extends ReverseChronologicalPager {
                $fields = array_merge( $rcQuery['fields'], [
                        'length' => 'page_len', 'rev_id' => 'page_latest', 'page_namespace', 'page_title'
                ] );
-               $join_conds = [ 'page' => [ 'INNER JOIN', 'page_id=rc_cur_id' ] ] + $rcQuery['joins'];
+               $join_conds = [ 'page' => [ 'JOIN', 'page_id=rc_cur_id' ] ] + $rcQuery['joins'];
 
                // Avoid PHP 7.1 warning from passing $this by reference
                $pager = $this;
index bc4202e..5583842 100644 (file)
@@ -49,7 +49,7 @@ class ProtectedPagesPager extends TablePager {
                LinkRenderer $linkRenderer
        ) {
                $this->mConds = $conds;
-               $this->type = ( $type ) ? $type : 'edit';
+               $this->type = $type ?: 'edit';
                $this->level = $level;
                $this->namespace = $namespace;
                $this->sizetype = $sizetype;
diff --git a/includes/specials/redirects/SpecialAllMyUploads.php b/includes/specials/redirects/SpecialAllMyUploads.php
new file mode 100644 (file)
index 0000000..605b61c
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Special pages that are used to get user independent links pointing to
+ * current user's pages (user page, talk page, contributions, etc.).
+ * This can let us cache a single copy of some generated content for all
+ * users or be linked in wikitext help pages.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Special page pointing to current user's uploaded files (including old versions).
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialAllMyUploads extends RedirectSpecialPage {
+       public function __construct() {
+               parent::__construct( 'AllMyUploads' );
+               $this->mAllowedRedirectParams = [ 'limit', 'ilsearch' ];
+       }
+
+       /**
+        * @param string|null $subpage
+        * @return Title
+        */
+       public function getRedirect( $subpage ) {
+               $this->mAddedRedirectParams['ilshowall'] = 1;
+
+               return SpecialPage::getTitleFor( 'Listfiles', $this->getUser()->getName() );
+       }
+
+       /**
+        * Target identifies a specific User. See T109724.
+        *
+        * @since 1.27
+        * @return bool
+        */
+       public function personallyIdentifiableTarget() {
+               return true;
+       }
+}
diff --git a/includes/specials/redirects/SpecialListAdmins.php b/includes/specials/redirects/SpecialListAdmins.php
new file mode 100644 (file)
index 0000000..f648647
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Implements Special:ListAdmins
+ *
+ * Copyright © 2004 Brion Vibber, lcrocker, Tim Starling,
+ * Domas Mituzas, Antoine Musso, Jens Frank, Zhengzhu,
+ * 2006 Rob Church <robchur@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Redirect page: Special:ListAdmins --> Special:ListUsers/sysop.
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialListAdmins extends SpecialRedirectToSpecial {
+       function __construct() {
+               parent::__construct( 'Listadmins', 'Listusers', 'sysop' );
+       }
+}
diff --git a/includes/specials/redirects/SpecialListBots.php b/includes/specials/redirects/SpecialListBots.php
new file mode 100644 (file)
index 0000000..a745d8b
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Implements Special:ListBots
+ *
+ * Copyright © 2004 Brion Vibber, lcrocker, Tim Starling,
+ * Domas Mituzas, Antoine Musso, Jens Frank, Zhengzhu,
+ * 2006 Rob Church <robchur@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Redirect page: Special:ListBots --> Special:ListUsers/bot.
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialListBots extends SpecialRedirectToSpecial {
+       function __construct() {
+               parent::__construct( 'Listbots', 'Listusers', 'bot' );
+       }
+}
diff --git a/includes/specials/redirects/SpecialMycontributions.php b/includes/specials/redirects/SpecialMycontributions.php
new file mode 100644 (file)
index 0000000..5a2c1cb
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Special pages that are used to get user independent links pointing to
+ * current user's pages (user page, talk page, contributions, etc.).
+ * This can let us cache a single copy of some generated content for all
+ * users or be linked in wikitext help pages.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Special page pointing to current user's contributions.
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialMycontributions extends RedirectSpecialPage {
+       public function __construct() {
+               parent::__construct( 'Mycontributions' );
+               $this->mAllowedRedirectParams = [ 'limit', 'namespace', 'tagfilter',
+                       'offset', 'dir', 'year', 'month', 'feed', 'deletedOnly',
+                       'nsInvert', 'associated', 'newOnly', 'topOnly', 'start', 'end' ];
+       }
+
+       /**
+        * @param string|null $subpage
+        * @return Title
+        */
+       public function getRedirect( $subpage ) {
+               return SpecialPage::getTitleFor( 'Contributions', $this->getUser()->getName() );
+       }
+
+       /**
+        * Target identifies a specific User. See T109724.
+        *
+        * @since 1.27
+        * @return bool
+        */
+       public function personallyIdentifiableTarget() {
+               return true;
+       }
+}
diff --git a/includes/specials/redirects/SpecialMypage.php b/includes/specials/redirects/SpecialMypage.php
new file mode 100644 (file)
index 0000000..487fc74
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Special pages that are used to get user independent links pointing to
+ * current user's pages (user page, talk page, contributions, etc.).
+ * This can let us cache a single copy of some generated content for all
+ * users or be linked in wikitext help pages.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Special page pointing to current user's user page.
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialMypage extends RedirectSpecialArticle {
+       public function __construct() {
+               parent::__construct( 'Mypage' );
+       }
+
+       /**
+        * @param string|null $subpage
+        * @return Title
+        */
+       public function getRedirect( $subpage ) {
+               if ( $subpage === null || $subpage === '' ) {
+                       return Title::makeTitle( NS_USER, $this->getUser()->getName() );
+               }
+
+               return Title::makeTitle( NS_USER, $this->getUser()->getName() . '/' . $subpage );
+       }
+
+       /**
+        * Target identifies a specific User. See T109724.
+        *
+        * @since 1.27
+        * @return bool
+        */
+       public function personallyIdentifiableTarget() {
+               return true;
+       }
+}
diff --git a/includes/specials/redirects/SpecialMytalk.php b/includes/specials/redirects/SpecialMytalk.php
new file mode 100644 (file)
index 0000000..d7be71f
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Special pages that are used to get user independent links pointing to
+ * current user's pages (user page, talk page, contributions, etc.).
+ * This can let us cache a single copy of some generated content for all
+ * users or be linked in wikitext help pages.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Special page pointing to current user's talk page.
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialMytalk extends RedirectSpecialArticle {
+       public function __construct() {
+               parent::__construct( 'Mytalk' );
+       }
+
+       /**
+        * @param string|null $subpage
+        * @return Title
+        */
+       public function getRedirect( $subpage ) {
+               if ( $subpage === null || $subpage === '' ) {
+                       return Title::makeTitle( NS_USER_TALK, $this->getUser()->getName() );
+               }
+
+               return Title::makeTitle( NS_USER_TALK, $this->getUser()->getName() . '/' . $subpage );
+       }
+
+       /**
+        * Target identifies a specific User. See T109724.
+        *
+        * @since 1.27
+        * @return bool
+        */
+       public function personallyIdentifiableTarget() {
+               return true;
+       }
+}
diff --git a/includes/specials/redirects/SpecialMyuploads.php b/includes/specials/redirects/SpecialMyuploads.php
new file mode 100644 (file)
index 0000000..1028ef1
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Special pages that are used to get user independent links pointing to
+ * current user's pages (user page, talk page, contributions, etc.).
+ * This can let us cache a single copy of some generated content for all
+ * users or be linked in wikitext help pages.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * Special page pointing to current user's uploaded files.
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialMyuploads extends RedirectSpecialPage {
+       public function __construct() {
+               parent::__construct( 'Myuploads' );
+               $this->mAllowedRedirectParams = [ 'limit', 'ilshowall', 'ilsearch' ];
+       }
+
+       /**
+        * @param string|null $subpage
+        * @return Title
+        */
+       public function getRedirect( $subpage ) {
+               return SpecialPage::getTitleFor( 'Listfiles', $this->getUser()->getName() );
+       }
+
+       /**
+        * Target identifies a specific User. See T109724.
+        *
+        * @since 1.27
+        * @return bool
+        */
+       public function personallyIdentifiableTarget() {
+               return true;
+       }
+}
index 6d9d6b0..f20afdb 100644 (file)
                                <div class="mw-rcfilters-ui-highlights-color-c5" data-color="c5"></div>
                        </div>
                </td>
-               <td><span class="mw-collapsible-toggle mw-collapsible-arrow mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space mw-collapsible-toggle-collapsed"></span></td>
+               <td>{{!
+                       }}<span class="mw-collapsible-toggle mw-collapsible-arrow mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space mw-collapsible-toggle-collapsed"></span>{{!
+               }}</td>
                <td class="mw-changeslist-line-prefix">{{{ prefix }}}</td>
                <td class="mw-enhanced-rc" colspan="2">{{{ collectedRcFlags }}}&#160;{{ timestamp }}&#160;</td>
-               <td class="mw-changeslist-line-inner">
-                       {{# rev-deleted-event }}<span class="history-deleted">{{{ . }}}</span>{{/ rev-deleted-event }}
-                       {{{ articleLink }}}{{{ languageDirMark }}}{{{ logText }}}
-                       <span class="mw-changeslist-separator">. .</span>
-                       {{# charDifference }}{{{ . }}} <span class="mw-changeslist-separator">. .</span>{{/ charDifference }}
-                       <span class="changedby">{{{ users }}}</span>
-                       {{ numberofWatchingusers }}
-               </td>
+               <td class="mw-changeslist-line-inner">{{!
+                       }}{{# rev-deleted-event }}<span class="history-deleted">{{{ . }}}</span>{{/ rev-deleted-event }}{{!
+                       }}{{{ articleLink }}}{{{ languageDirMark }}}{{{ logText }}}{{!
+                       }}<span class="mw-changeslist-separator"></span>{{!
+                       }}{{# charDifference }}{{{ . }}} <span class="mw-changeslist-separator"></span>{{/ charDifference }}{{!
+                       }}<span class="changedby">{{{ users }}}</span>{{!
+                       }}{{ numberofWatchingusers }}{{!
+               }}</td>
        </tr>
        {{# lines }}
        <tr class="mw-rcfilters-ui-highlights-enhanced-nested {{# classes }}{{ . }} {{/ classes }}"{{{ attribs }}}>
                                <div class="mw-rcfilters-ui-highlights-color-c5" data-color="c5"></div>
                        </div>
                </td>
-               <td class="mw-enhanced-rc-nested" data-target-page="{{ targetTitle }}">
-                       {{# timestampLink }}
-                       <span class="mw-enhanced-rc-time">{{{ . }}}</span>
-                       {{/ timestampLink }}
-                       {{# data }}{{{ . }}}{{/ data }}
-               </td>
+               <td class="mw-enhanced-rc-nested" data-target-page="{{ targetTitle }}">{{!
+                       }}{{# timestampLink }}{{!
+                       }}<span class="mw-enhanced-rc-time">{{{ . }}}</span>{{!
+                       }}{{/ timestampLink }}{{!
+                       }}{{# data }}{{{ . }}}{{/ data }}{{!
+               }}</td>
        </tr>
        {{/ lines }}
 </table>
index 4e93382..abc98ba 100644 (file)
@@ -40,10 +40,10 @@ class RemexCompatFormatter extends HtmlFormatter {
 
                $name = $node->name;
                $attrs = $node->attrs;
-               if ( isset( self::$markedEmptyElements[$name] ) && $attrs->count() === 0 ) {
-                       if ( strspn( $contents, "\t\n\f\r " ) === strlen( $contents ) ) {
-                               return "<{$name} class=\"mw-empty-elt\">$contents</{$name}>";
-                       }
+               if ( isset( self::$markedEmptyElements[$name] ) && $attrs->count() === 0
+                       && strspn( $contents, "\t\n\f\r " ) === strlen( $contents )
+               ) {
+                       return "<{$name} class=\"mw-empty-elt\">$contents</{$name}>";
                }
 
                $s = "<$name";
index df9bb96..0cc9905 100644 (file)
@@ -287,7 +287,6 @@ class RemexCompatMunger implements TreeHandler {
                        $newParent = $this->serializer->getParentNode( $parent );
                        $parent = $newParent;
                        $parentData = $parent->snData;
-                       $pElement = $parentData->childPElement;
                        $parentData->childPElement = null;
                        $newRef = $refElement->userData;
                } elseif ( $under && $parentData->isSplittable
index e06bfb5..adbea89 100644 (file)
@@ -421,10 +421,8 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
 
                # Can't make a link to a namespace alone... "empty" local links can only be
                # self-links with a fragment identifier.
-               if ( $dbkey == '' && $parts['interwiki'] === '' ) {
-                       if ( $parts['namespace'] != NS_MAIN ) {
-                               throw new MalformedTitleException( 'title-invalid-empty', $text );
-                       }
+               if ( $dbkey == '' && $parts['interwiki'] === '' && $parts['namespace'] != NS_MAIN ) {
+                       throw new MalformedTitleException( 'title-invalid-empty', $text );
                }
 
                // Allow IPv6 usernames to start with '::' by canonicalizing IPv6 titles.
diff --git a/includes/title/NamespaceInfo.php b/includes/title/NamespaceInfo.php
new file mode 100644 (file)
index 0000000..f9cab24
--- /dev/null
@@ -0,0 +1,526 @@
+<?php
+/**
+ * Provide things related to namespaces.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of
+ * them based on index.  The textual names of the namespaces are handled by Language.php.
+ *
+ * @since 1.34
+ */
+class NamespaceInfo {
+
+       /**
+        * These namespaces should always be first-letter capitalized, now and
+        * forevermore. Historically, they could've probably been lowercased too,
+        * but some things are just too ingrained now. :)
+        */
+       private $alwaysCapitalizedNamespaces = [ NS_SPECIAL, NS_USER, NS_MEDIAWIKI ];
+
+       /** @var string[]|null Canonical namespaces cache */
+       private $canonicalNamespaces = null;
+
+       /** @var array|false Canonical namespaces index cache */
+       private $namespaceIndexes = false;
+
+       /** @var int[]|null Valid namespaces cache */
+       private $validNamespaces = null;
+
+       /** @var Config */
+       private $config;
+
+       /**
+        * @param Config $config
+        */
+       public function __construct( Config $config ) {
+               $this->config = $config;
+       }
+
+       /**
+        * Throw an exception when trying to get the subject or talk page
+        * for a given namespace where it does not make sense.
+        * Special namespaces are defined in includes/Defines.php and have
+        * a value below 0 (ex: NS_SPECIAL = -1 , NS_MEDIA = -2)
+        *
+        * @param int $index
+        * @param string $method
+        *
+        * @throws MWException
+        * @return bool
+        */
+       private function isMethodValidFor( $index, $method ) {
+               if ( $index < NS_MAIN ) {
+                       throw new MWException( "$method does not make any sense for given namespace $index" );
+               }
+               return true;
+       }
+
+       /**
+        * Can pages in the given namespace be moved?
+        *
+        * @param int $index Namespace index
+        * @return bool
+        */
+       public function isMovable( $index ) {
+               $result = !( $index < NS_MAIN ||
+                       ( $index == NS_FILE && !$this->config->get( 'AllowImageMoving' ) ) );
+
+               /**
+                * @since 1.20
+                */
+               Hooks::run( 'NamespaceIsMovable', [ $index, &$result ] );
+
+               return $result;
+       }
+
+       /**
+        * Is the given namespace is a subject (non-talk) namespace?
+        *
+        * @param int $index Namespace index
+        * @return bool
+        */
+       public function isSubject( $index ) {
+               return !$this->isTalk( $index );
+       }
+
+       /**
+        * Is the given namespace a talk namespace?
+        *
+        * @param int $index Namespace index
+        * @return bool
+        */
+       public function isTalk( $index ) {
+               return $index > NS_MAIN
+                       && $index % 2;
+       }
+
+       /**
+        * Get the talk namespace index for a given namespace
+        *
+        * @param int $index Namespace index
+        * @return int
+        */
+       public function getTalk( $index ) {
+               $this->isMethodValidFor( $index, __METHOD__ );
+               return $this->isTalk( $index )
+                       ? $index
+                       : $index + 1;
+       }
+
+       /**
+        * Get the subject namespace index for a given namespace
+        * Special namespaces (NS_MEDIA, NS_SPECIAL) are always the subject.
+        *
+        * @param int $index Namespace index
+        * @return int
+        */
+       public function getSubject( $index ) {
+               # Handle special namespaces
+               if ( $index < NS_MAIN ) {
+                       return $index;
+               }
+
+               return $this->isTalk( $index )
+                       ? $index - 1
+                       : $index;
+       }
+
+       /**
+        * Get the associated namespace.
+        * For talk namespaces, returns the subject (non-talk) namespace
+        * For subject (non-talk) namespaces, returns the talk namespace
+        *
+        * @param int $index Namespace index
+        * @return int|null If no associated namespace could be found
+        */
+       public function getAssociated( $index ) {
+               $this->isMethodValidFor( $index, __METHOD__ );
+
+               if ( $this->isSubject( $index ) ) {
+                       return $this->getTalk( $index );
+               } elseif ( $this->isTalk( $index ) ) {
+                       return $this->getSubject( $index );
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Returns whether the specified namespace exists
+        *
+        * @param int $index
+        *
+        * @return bool
+        */
+       public function exists( $index ) {
+               $nslist = $this->getCanonicalNamespaces();
+               return isset( $nslist[$index] );
+       }
+
+       /**
+        * Returns whether the specified namespaces are the same namespace
+        *
+        * @note It's possible that in the future we may start using something
+        * other than just namespace indexes. Under that circumstance making use
+        * of this function rather than directly doing comparison will make
+        * sure that code will not potentially break.
+        *
+        * @param int $ns1 The first namespace index
+        * @param int $ns2 The second namespace index
+        *
+        * @return bool
+        */
+       public function equals( $ns1, $ns2 ) {
+               return $ns1 == $ns2;
+       }
+
+       /**
+        * Returns whether the specified namespaces share the same subject.
+        * eg: NS_USER and NS_USER wil return true, as well
+        *     NS_USER and NS_USER_TALK will return true.
+        *
+        * @param int $ns1 The first namespace index
+        * @param int $ns2 The second namespace index
+        *
+        * @return bool
+        */
+       public function subjectEquals( $ns1, $ns2 ) {
+               return $this->getSubject( $ns1 ) == $this->getSubject( $ns2 );
+       }
+
+       /**
+        * Returns array of all defined namespaces with their canonical
+        * (English) names.
+        *
+        * @return array
+        */
+       public function getCanonicalNamespaces() {
+               if ( $this->canonicalNamespaces === null ) {
+                       $this->canonicalNamespaces =
+                               [ NS_MAIN => '' ] + $this->config->get( 'CanonicalNamespaceNames' );
+                       $this->canonicalNamespaces +=
+                               ExtensionRegistry::getInstance()->getAttribute( 'ExtensionNamespaces' );
+                       if ( is_array( $this->config->get( 'ExtraNamespaces' ) ) ) {
+                               $this->canonicalNamespaces += $this->config->get( 'ExtraNamespaces' );
+                       }
+                       Hooks::run( 'CanonicalNamespaces', [ &$this->canonicalNamespaces ] );
+               }
+               return $this->canonicalNamespaces;
+       }
+
+       /**
+        * Returns the canonical (English) name for a given index
+        *
+        * @param int $index Namespace index
+        * @return string|bool If no canonical definition.
+        */
+       public function getCanonicalName( $index ) {
+               $nslist = $this->getCanonicalNamespaces();
+               return $nslist[$index] ?? false;
+       }
+
+       /**
+        * Returns the index for a given canonical name, or NULL
+        * The input *must* be converted to lower case first
+        *
+        * @param string $name Namespace name
+        * @return int
+        */
+       public function getCanonicalIndex( $name ) {
+               if ( $this->namespaceIndexes === false ) {
+                       $this->namespaceIndexes = [];
+                       foreach ( $this->getCanonicalNamespaces() as $i => $text ) {
+                               $this->namespaceIndexes[strtolower( $text )] = $i;
+                       }
+               }
+               if ( array_key_exists( $name, $this->namespaceIndexes ) ) {
+                       return $this->namespaceIndexes[$name];
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Returns an array of the namespaces (by integer id) that exist on the
+        * wiki. Used primarily by the api in help documentation.
+        * @return array
+        */
+       public function getValidNamespaces() {
+               if ( is_null( $this->validNamespaces ) ) {
+                       foreach ( array_keys( $this->getCanonicalNamespaces() ) as $ns ) {
+                               if ( $ns >= 0 ) {
+                                       $this->validNamespaces[] = $ns;
+                               }
+                       }
+                       // T109137: sort numerically
+                       sort( $this->validNamespaces, SORT_NUMERIC );
+               }
+
+               return $this->validNamespaces;
+       }
+
+       /*
+
+       /**
+        * Does this namespace ever have a talk namespace?
+        *
+        * @param int $index Namespace ID
+        * @return bool True if this namespace either is or has a corresponding talk namespace.
+        */
+       public function hasTalkNamespace( $index ) {
+               return $index >= NS_MAIN;
+       }
+
+       /**
+        * Does this namespace contain content, for the purposes of calculating
+        * statistics, etc?
+        *
+        * @param int $index Index to check
+        * @return bool
+        */
+       public function isContent( $index ) {
+               return $index == NS_MAIN || in_array( $index, $this->config->get( 'ContentNamespaces' ) );
+       }
+
+       /**
+        * Might pages in this namespace require the use of the Signature button on
+        * the edit toolbar?
+        *
+        * @param int $index Index to check
+        * @return bool
+        */
+       public function wantSignatures( $index ) {
+               return $this->isTalk( $index ) ||
+                       in_array( $index, $this->config->get( 'ExtraSignatureNamespaces' ) );
+       }
+
+       /**
+        * Can pages in a namespace be watched?
+        *
+        * @param int $index
+        * @return bool
+        */
+       public function isWatchable( $index ) {
+               return $index >= NS_MAIN;
+       }
+
+       /**
+        * Does the namespace allow subpages?
+        *
+        * @param int $index Index to check
+        * @return bool
+        */
+       public function hasSubpages( $index ) {
+               return !empty( $this->config->get( 'NamespacesWithSubpages' )[$index] );
+       }
+
+       /**
+        * Get a list of all namespace indices which are considered to contain content
+        * @return array Array of namespace indices
+        */
+       public function getContentNamespaces() {
+               $contentNamespaces = $this->config->get( 'ContentNamespaces' );
+               if ( !is_array( $contentNamespaces ) || $contentNamespaces === [] ) {
+                       return [ NS_MAIN ];
+               } elseif ( !in_array( NS_MAIN, $contentNamespaces ) ) {
+                       // always force NS_MAIN to be part of array (to match the algorithm used by isContent)
+                       return array_merge( [ NS_MAIN ], $contentNamespaces );
+               } else {
+                       return $contentNamespaces;
+               }
+       }
+
+       /**
+        * List all namespace indices which are considered subject, aka not a talk
+        * or special namespace. See also NamespaceInfo::isSubject
+        *
+        * @return array Array of namespace indices
+        */
+       public function getSubjectNamespaces() {
+               return array_filter(
+                       $this->getValidNamespaces(),
+                       [ $this, 'isSubject' ]
+               );
+       }
+
+       /**
+        * List all namespace indices which are considered talks, aka not a subject
+        * or special namespace. See also NamespaceInfo::isTalk
+        *
+        * @return array Array of namespace indices
+        */
+       public function getTalkNamespaces() {
+               return array_filter(
+                       $this->getValidNamespaces(),
+                       [ $this, 'isTalk' ]
+               );
+       }
+
+       /**
+        * Is the namespace first-letter capitalized?
+        *
+        * @param int $index Index to check
+        * @return bool
+        */
+       public function isCapitalized( $index ) {
+               // Turn NS_MEDIA into NS_FILE
+               $index = $index === NS_MEDIA ? NS_FILE : $index;
+
+               // Make sure to get the subject of our namespace
+               $index = $this->getSubject( $index );
+
+               // Some namespaces are special and should always be upper case
+               if ( in_array( $index, $this->alwaysCapitalizedNamespaces ) ) {
+                       return true;
+               }
+               $overrides = $this->config->get( 'CapitalLinkOverrides' );
+               if ( isset( $overrides[$index] ) ) {
+                       // CapitalLinkOverrides is explicitly set
+                       return $overrides[$index];
+               }
+               // Default to the global setting
+               return $this->config->get( 'CapitalLinks' );
+       }
+
+       /**
+        * Does the namespace (potentially) have different aliases for different
+        * genders. Not all languages make a distinction here.
+        *
+        * @param int $index Index to check
+        * @return bool
+        */
+       public function hasGenderDistinction( $index ) {
+               return $index == NS_USER || $index == NS_USER_TALK;
+       }
+
+       /**
+        * It is not possible to use pages from this namespace as template?
+        *
+        * @param int $index Index to check
+        * @return bool
+        */
+       public function isNonincludable( $index ) {
+               $namespaces = $this->config->get( 'NonincludableNamespaces' );
+               return $namespaces && in_array( $index, $namespaces );
+       }
+
+       /**
+        * Get the default content model for a namespace
+        * This does not mean that all pages in that namespace have the model
+        *
+        * @note To determine the default model for a new page's main slot, or any slot in general,
+        * use SlotRoleHandler::getDefaultModel() together with SlotRoleRegistry::getRoleHandler().
+        *
+        * @param int $index Index to check
+        * @return null|string Default model name for the given namespace, if set
+        */
+       public function getNamespaceContentModel( $index ) {
+               return $this->config->get( 'NamespaceContentModels' )[$index] ?? null;
+       }
+
+       /**
+        * Determine which restriction levels it makes sense to use in a namespace,
+        * optionally filtered by a user's rights.
+        *
+        * @param int $index Index to check
+        * @param User|null $user User to check
+        * @return array
+        */
+       public function getRestrictionLevels( $index, User $user = null ) {
+               if ( !isset( $this->config->get( 'NamespaceProtection' )[$index] ) ) {
+                       // All levels are valid if there's no namespace restriction.
+                       // But still filter by user, if necessary
+                       $levels = $this->config->get( 'RestrictionLevels' );
+                       if ( $user ) {
+                               $levels = array_values( array_filter( $levels, function ( $level ) use ( $user ) {
+                                       $right = $level;
+                                       if ( $right == 'sysop' ) {
+                                               $right = 'editprotected'; // BC
+                                       }
+                                       if ( $right == 'autoconfirmed' ) {
+                                               $right = 'editsemiprotected'; // BC
+                                       }
+                                       return ( $right == '' || $user->isAllowed( $right ) );
+                               } ) );
+                       }
+                       return $levels;
+               }
+
+               // First, get the list of groups that can edit this namespace.
+               $namespaceGroups = [];
+               $combine = 'array_merge';
+               foreach ( (array)$this->config->get( 'NamespaceProtection' )[$index] as $right ) {
+                       if ( $right == 'sysop' ) {
+                               $right = 'editprotected'; // BC
+                       }
+                       if ( $right == 'autoconfirmed' ) {
+                               $right = 'editsemiprotected'; // BC
+                       }
+                       if ( $right != '' ) {
+                               $namespaceGroups = call_user_func( $combine, $namespaceGroups,
+                                       User::getGroupsWithPermission( $right ) );
+                               $combine = 'array_intersect';
+                       }
+               }
+
+               // Now, keep only those restriction levels where there is at least one
+               // group that can edit the namespace but would be blocked by the
+               // restriction.
+               $usableLevels = [ '' ];
+               foreach ( $this->config->get( 'RestrictionLevels' ) as $level ) {
+                       $right = $level;
+                       if ( $right == 'sysop' ) {
+                               $right = 'editprotected'; // BC
+                       }
+                       if ( $right == 'autoconfirmed' ) {
+                               $right = 'editsemiprotected'; // BC
+                       }
+                       if ( $right != '' && ( !$user || $user->isAllowed( $right ) ) &&
+                               array_diff( $namespaceGroups, User::getGroupsWithPermission( $right ) )
+                       ) {
+                               $usableLevels[] = $level;
+                       }
+               }
+
+               return $usableLevels;
+       }
+
+       /**
+        * Returns the link type to be used for categories.
+        *
+        * This determines which section of a category page titles
+        * in the namespace will appear within.
+        *
+        * @param int $index Namespace index
+        * @return string One of 'subcat', 'file', 'page'
+        */
+       public function getCategoryLinkType( $index ) {
+               $this->isMethodValidFor( $index, __METHOD__ );
+
+               if ( $index == NS_CATEGORY ) {
+                       return 'subcat';
+               } elseif ( $index == NS_FILE ) {
+                       return 'file';
+               } else {
+                       return 'page';
+               }
+       }
+}
index d9e8e99..2bbe7c3 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Upload
  */
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Shell\Shell;
 
 /**
  * @defgroup Upload Upload related
@@ -947,8 +948,8 @@ abstract class UploadBase {
                 */
                list( $partname, $ext ) = $this->splitExtensions( $this->mFilteredName );
 
-               if ( count( $ext ) ) {
-                       $this->mFinalExtension = trim( $ext[count( $ext ) - 1] );
+               if ( $ext !== [] ) {
+                       $this->mFinalExtension = trim( end( $ext ) );
                } else {
                        $this->mFinalExtension = '';
 
@@ -1078,10 +1079,8 @@ abstract class UploadBase {
                $props = $this->mFileProps;
                $error = null;
                Hooks::run( 'UploadStashFile', [ $this, $user, $props, &$error ] );
-               if ( $error ) {
-                       if ( !is_array( $error ) ) {
-                               $error = [ $error ];
-                       }
+               if ( $error && !is_array( $error ) ) {
+                       $error = [ $error ];
                }
                return $error;
        }
@@ -1169,7 +1168,7 @@ abstract class UploadBase {
         * scripts, so the blacklist needs to check them all.
         *
         * @param string $filename
-        * @return array
+        * @return array [ string, string[] ]
         */
        public static function splitExtensions( $filename ) {
                $bits = explode( '.', $filename );
@@ -1194,8 +1193,8 @@ abstract class UploadBase {
         * Perform case-insensitive match against a list of file extensions.
         * Returns an array of matching extensions.
         *
-        * @param array $ext
-        * @param array $list
+        * @param string[] $ext
+        * @param string[] $list
         * @return bool
         */
        public static function checkFileExtensionList( $ext, $list ) {
@@ -1865,10 +1864,10 @@ abstract class UploadBase {
 
                if ( strpos( $command, "%f" ) === false ) {
                        # simple pattern: append file to scan
-                       $command .= " " . wfEscapeShellArg( $file );
+                       $command .= " " . Shell::escape( $file );
                } else {
                        # complex pattern: replace "%f" with file to scan
-                       $command = str_replace( "%f", wfEscapeShellArg( $file ), $command );
+                       $command = str_replace( "%f", Shell::escape( $file ), $command );
                }
 
                wfDebug( __METHOD__ . ": running virus scan: $command \n" );
@@ -1916,10 +1915,8 @@ abstract class UploadBase {
                                $output = true; # if there's no output, return true
                        } elseif ( $msgPattern ) {
                                $groups = [];
-                               if ( preg_match( $msgPattern, $output, $groups ) ) {
-                                       if ( $groups[1] ) {
-                                               $output = $groups[1];
-                                       }
+                               if ( preg_match( $msgPattern, $output, $groups ) && $groups[1] ) {
+                                       $output = $groups[1];
                                }
                        }
 
index aa31a5b..7d69fe1 100644 (file)
@@ -162,12 +162,10 @@ class UploadStash {
                        );
                }
 
-               if ( !$noAuth ) {
-                       if ( $this->fileMetadata[$key]['us_user'] != $this->userId ) {
-                               throw new UploadStashWrongOwnerException(
-                                       wfMessage( 'uploadstash-wrong-owner', $key )
-                               );
-                       }
+               if ( !$noAuth && $this->fileMetadata[$key]['us_user'] != $this->userId ) {
+                       throw new UploadStashWrongOwnerException(
+                               wfMessage( 'uploadstash-wrong-owner', $key )
+                       );
                }
 
                return $this->files[$key];
index e8cd94a..6db219d 100644 (file)
@@ -473,7 +473,6 @@ class BotPassword implements IDBAccessObject {
                        return Status::newFatal( 'botpasswords-locked' );
                }
 
-               // Throttle
                $throttle = null;
                if ( !empty( $wgPasswordAttemptThrottle ) ) {
                        $throttle = new MediaWiki\Auth\Throttler( $wgPasswordAttemptThrottle, [
index ef104cc..aada319 100644 (file)
@@ -81,9 +81,7 @@ class PasswordReset implements LoggerAwareInterface {
                        $resetRoutes = $this->config->get( 'PasswordResetRoutes' );
                        $status = StatusValue::newGood();
 
-                       if ( !is_array( $resetRoutes ) ||
-                                !in_array( true, array_values( $resetRoutes ), true )
-                       ) {
+                       if ( !is_array( $resetRoutes ) || !in_array( true, $resetRoutes, true ) ) {
                                // Maybe password resets are disabled, or there are no allowable routes
                                $status = StatusValue::newFatal( 'passwordreset-disabled' );
                        } elseif (
@@ -265,23 +263,7 @@ class PasswordReset implements LoggerAwareInterface {
                if ( !$block ) {
                        return false;
                }
-               $type = $block->getSystemBlockType();
-               if ( in_array( $type, [ null, 'global-block' ], true ) ) {
-                       // Normal block. Maybe it was meant for someone else and the user just needs to log in;
-                       // or maybe it was issued specifically to prevent some IP from messing with password
-                       // reset? Go out on a limb and use the registration allowed flag to decide.
-                       return $block->isCreateAccountBlocked();
-               } elseif ( $type === 'proxy' ) {
-                       // we disallow actions through proxy even if the user is logged in
-                       // so it makes sense to disallow password resets as well
-                       return true;
-               } elseif ( in_array( $type, [ 'dnsbl', 'wgSoftBlockRanges' ], true ) ) {
-                       // these are just meant to force login so let's not prevent that
-                       return false;
-               } else {
-                       // some extension - we'll have to guess
-                       return true;
-               }
+               return $block->appliesToPasswordReset();
        }
 
        /**
index 59cea66..981204d 100644 (file)
@@ -28,6 +28,7 @@ use MediaWiki\Auth\AuthenticationResponse;
 use MediaWiki\Auth\AuthenticationRequest;
 use MediaWiki\User\UserIdentity;
 use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Assert\Assert;
 use Wikimedia\IPSet;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\Database;
@@ -1193,6 +1194,8 @@ class User implements IDBAccessObject, UserIdentity {
         * - forceChange (bool): if set to true, the user should not be
         *   allowed to log with this password unless they change it during
         *   the login process (see ResetPasswordSecondaryAuthenticationProvider).
+        * - suggestChangeOnLogin (bool): if set to true, the user should be prompted for
+        *   a password change on login.
         *
         * @param string $password Desired password
         * @return Status
@@ -1260,10 +1263,7 @@ class User implements IDBAccessObject, UserIdentity {
                        return false;
                }
 
-               // Reject various classes of invalid names
-               $name = AuthManager::callLegacyAuthPlugin(
-                       'getCanonicalName', [ $t->getText() ], $t->getText()
-               );
+               $name = $t->getText();
 
                switch ( $validate ) {
                        case false:
@@ -1406,28 +1406,11 @@ class User implements IDBAccessObject, UserIdentity {
         */
        public function trackBlockWithCookie() {
                $block = $this->getBlock();
-               if ( $block && $this->getRequest()->getCookie( 'BlockID' ) === null ) {
-                       $config = RequestContext::getMain()->getConfig();
-                       $shouldSetCookie = false;
-
-                       if ( $this->isAnon() && $config->get( 'CookieSetOnIpBlock' ) ) {
-                               // If user is logged-out, set a cookie to track the Block
-                               $shouldSetCookie = in_array( $block->getType(), [
-                                       Block::TYPE_IP, Block::TYPE_RANGE
-                               ] );
-                               if ( $shouldSetCookie ) {
-                                       $block->setCookie( $this->getRequest()->response() );
 
-                                       // temporary measure the use of cookies on ip blocks
-                                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
-                                       $stats->increment( 'block.ipblock.setCookie.success' );
-                               }
-                       } elseif ( $this->isLoggedIn() && $config->get( 'CookieSetOnAutoblock' ) ) {
-                               $shouldSetCookie = $block->getType() === Block::TYPE_USER && $block->isAutoblocking();
-                               if ( $shouldSetCookie ) {
-                                       $block->setCookie( $this->getRequest()->response() );
-                               }
-                       }
+               if ( $block && $this->getRequest()->getCookie( 'BlockID' ) === null
+                       && $block->shouldTrackWithCookie( $this->isAnon() )
+               ) {
+                       $block->setCookie( $this->getRequest()->response() );
                }
        }
 
@@ -1669,7 +1652,6 @@ class User implements IDBAccessObject, UserIdentity {
 
                // update groups in external authentication database
                Hooks::run( 'UserGroupsChanged', [ $this, $toPromote, [], false, false, $oldUGMs, $newUGMs ] );
-               AuthManager::callLegacyAuthPlugin( 'updateExternalDBGroups', [ $this, $toPromote ] );
 
                $logEntry = new ManualLogEntry( 'rights', 'autopromote' );
                $logEntry->setPerformer( $this );
@@ -1691,11 +1673,11 @@ class User implements IDBAccessObject, UserIdentity {
         * protected against race conditions using a compare-and-set (CAS) mechanism
         * based on comparing $this->mTouched with the user_touched field.
         *
-        * @param Database $db
+        * @param IDatabase $db
         * @param array $conditions WHERE conditions for use with Database::update
         * @return array WHERE conditions for use with Database::update
         */
-       protected function makeUpdateConditions( Database $db, array $conditions ) {
+       protected function makeUpdateConditions( IDatabase $db, array $conditions ) {
                if ( $this->mTouched ) {
                        // CAS check: only update if the row wasn't changed sicne it was loaded.
                        $conditions['user_touched'] = $db->timestamp( $this->mTouched );
@@ -1770,6 +1752,23 @@ class User implements IDBAccessObject, UserIdentity {
                }
        }
 
+       /** @var array|null */
+       private static $defOpt = null;
+       /** @var string|null */
+       private static $defOptLang = null;
+
+       /**
+        * Reset the process cache of default user options. This is only necessary
+        * if the wiki configuration has changed since defaults were calculated,
+        * and as such should only be performed inside the testing suite that
+        * regularly changes wiki configuration.
+        */
+       public static function resetGetDefaultOptionsForTestsOnly() {
+               Assert::invariant( defined( 'MW_PHPUNIT_TEST' ), 'Unit tests only' );
+               self::$defOpt = null;
+               self::$defOptLang = null;
+       }
+
        /**
         * Combine the language default options with any site-specific options
         * and add the default language variants.
@@ -1779,26 +1778,23 @@ class User implements IDBAccessObject, UserIdentity {
        public static function getDefaultOptions() {
                global $wgNamespacesToBeSearchedDefault, $wgDefaultUserOptions, $wgDefaultSkin;
 
-               static $defOpt = null;
-               static $defOptLang = null;
-
                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
-               if ( $defOpt !== null && $defOptLang === $contLang->getCode() ) {
+               if ( self::$defOpt !== null && self::$defOptLang === $contLang->getCode() ) {
                        // The content language does not change (and should not change) mid-request, but the
                        // unit tests change it anyway, and expect this method to return values relevant to the
                        // current content language.
-                       return $defOpt;
+                       return self::$defOpt;
                }
 
-               $defOpt = $wgDefaultUserOptions;
+               self::$defOpt = $wgDefaultUserOptions;
                // Default language setting
-               $defOptLang = $contLang->getCode();
-               $defOpt['language'] = $defOptLang;
+               self::$defOptLang = $contLang->getCode();
+               self::$defOpt['language'] = self::$defOptLang;
                foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
                        if ( $langCode === $contLang->getCode() ) {
-                               $defOpt['variant'] = $langCode;
+                               self::$defOpt['variant'] = $langCode;
                        } else {
-                               $defOpt["variant-$langCode"] = $langCode;
+                               self::$defOpt["variant-$langCode"] = $langCode;
                        }
                }
 
@@ -1806,13 +1802,13 @@ class User implements IDBAccessObject, UserIdentity {
                // since extensions may change the set of searchable namespaces depending
                // on user groups/permissions.
                foreach ( $wgNamespacesToBeSearchedDefault as $nsnum => $val ) {
-                       $defOpt['searchNs' . $nsnum] = (bool)$val;
+                       self::$defOpt['searchNs' . $nsnum] = (bool)$val;
                }
-               $defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
+               self::$defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
 
-               Hooks::run( 'UserGetDefaultOptions', [ &$defOpt ] );
+               Hooks::run( 'UserGetDefaultOptions', [ &self::$defOpt ] );
 
-               return $defOpt;
+               return self::$defOpt;
        }
 
        /**
@@ -1828,12 +1824,12 @@ class User implements IDBAccessObject, UserIdentity {
 
        /**
         * Get blocking information
-        * @param bool $bFromReplica Whether to check the replica DB first.
+        * @param bool $fromReplica Whether to check the replica DB first.
         *   To improve performance, non-critical checks are done against replica DBs.
         *   Check when actually saving should be done against master.
         */
-       private function getBlockedStatus( $bFromReplica = true ) {
-               global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff, $wgSoftBlockRanges;
+       private function getBlockedStatus( $fromReplica = true ) {
+               global $wgProxyWhitelist, $wgApplyIpBlocksToXff, $wgSoftBlockRanges;
 
                if ( $this->mBlockedby != -1 ) {
                        return;
@@ -1852,19 +1848,18 @@ class User implements IDBAccessObject, UserIdentity {
                # user is not immune to autoblocks/hardblocks, and they are the current user so we
                # know which IP address they're actually coming from
                $ip = null;
-               if ( !$this->isAllowed( 'ipblock-exempt' ) ) {
-                       // $wgUser->getName() only works after the end of Setup.php. Until
-                       // then, assume it's a logged-out user.
-                       $globalUserName = $wgUser->isSafeToLoad()
-                               ? $wgUser->getName()
-                               : IP::sanitizeIP( $wgUser->getRequest()->getIP() );
-                       if ( $this->getName() === $globalUserName ) {
-                               $ip = $this->getRequest()->getIP();
-                       }
+               $sessionUser = RequestContext::getMain()->getUser();
+               // the session user is set up towards the end of Setup.php. Until then,
+               // assume it's a logged-out user.
+               $globalUserName = $sessionUser->isSafeToLoad()
+                       ? $sessionUser->getName()
+                       : IP::sanitizeIP( $sessionUser->getRequest()->getIP() );
+               if ( $this->getName() === $globalUserName && !$this->isAllowed( 'ipblock-exempt' ) ) {
+                       $ip = $this->getRequest()->getIP();
                }
 
                // User/IP blocking
-               $block = Block::newFromTarget( $this, $ip, !$bFromReplica );
+               $block = Block::newFromTarget( $this, $ip, !$fromReplica );
 
                // Cookie blocking
                if ( !$block instanceof Block ) {
@@ -1900,12 +1895,12 @@ class User implements IDBAccessObject, UserIdentity {
                        $xff = $this->getRequest()->getHeader( 'X-Forwarded-For' );
                        $xff = array_map( 'trim', explode( ',', $xff ) );
                        $xff = array_diff( $xff, [ $ip ] );
-                       $xffblocks = Block::getBlocksForIPList( $xff, $this->isAnon(), !$bFromReplica );
+                       $xffblocks = Block::getBlocksForIPList( $xff, $this->isAnon(), !$fromReplica );
                        $block = Block::chooseBlock( $xffblocks, $xff );
                        if ( $block instanceof Block ) {
                                # Mangle the reason to alert the user that the block
                                # originated from matching the X-Forwarded-For header.
-                               $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->plain();
+                               $block->setReason( wfMessage( 'xffblockreason', $block->getReason() )->plain() );
                        }
                }
 
@@ -1927,8 +1922,8 @@ class User implements IDBAccessObject, UserIdentity {
                        wfDebug( __METHOD__ . ": Found block.\n" );
                        $this->mBlock = $block;
                        $this->mBlockedby = $block->getByName();
-                       $this->mBlockreason = $block->mReason;
-                       $this->mHideName = $block->mHideName;
+                       $this->mBlockreason = $block->getReason();
+                       $this->mHideName = $block->getHideName();
                        $this->mAllowUsertalk = $block->isUsertalkEditAllowed();
                } else {
                        $this->mBlock = null;
@@ -1939,9 +1934,9 @@ class User implements IDBAccessObject, UserIdentity {
                }
 
                // Avoid PHP 7.1 warning of passing $this by reference
-               $user = $this;
+               $thisUser = $this;
                // Extensions
-               Hooks::run( 'GetBlockedStatus', [ &$user ] );
+               Hooks::run( 'GetBlockedStatus', [ &$thisUser ] );
        }
 
        /**
@@ -2212,6 +2207,9 @@ class User implements IDBAccessObject, UserIdentity {
 
                // Set the user limit key
                if ( $userLimit !== false ) {
+                       // phan is confused because &can-bypass's value is a bool, so it assumes
+                       // that $userLimit is also a bool here.
+                       // @phan-suppress-next-line PhanTypeInvalidExpressionArrayDestructuring
                        list( $max, $period ) = $userLimit;
                        wfDebug( __METHOD__ . ": effective user limit: $max in {$period}s\n" );
                        $keys[$cache->makeKey( 'limiter', $action, 'user', $id )] = $userLimit;
@@ -2243,6 +2241,9 @@ class User implements IDBAccessObject, UserIdentity {
 
                $triggered = false;
                foreach ( $keys as $key => $limit ) {
+                       // phan is confused because &can-bypass's value is a bool, so it assumes
+                       // that $userLimit is also a bool here.
+                       // @phan-suppress-next-line PhanTypeInvalidExpressionArrayDestructuring
                        list( $max, $period ) = $limit;
                        $summary = "(limit $max in {$period}s)";
                        $count = $cache->get( $key );
@@ -2272,23 +2273,23 @@ class User implements IDBAccessObject, UserIdentity {
        /**
         * Check if user is blocked
         *
-        * @param bool $bFromReplica Whether to check the replica DB instead of
+        * @param bool $fromReplica Whether to check the replica DB instead of
         *   the master. Hacked from false due to horrible probs on site.
         * @return bool True if blocked, false otherwise
         */
-       public function isBlocked( $bFromReplica = true ) {
-               return $this->getBlock( $bFromReplica ) instanceof Block &&
+       public function isBlocked( $fromReplica = true ) {
+               return $this->getBlock( $fromReplica ) instanceof Block &&
                        $this->getBlock()->appliesToRight( 'edit' );
        }
 
        /**
         * Get the block affecting the user, or null if the user is not blocked
         *
-        * @param bool $bFromReplica Whether to check the replica DB instead of the master
+        * @param bool $fromReplica Whether to check the replica DB instead of the master
         * @return Block|null
         */
-       public function getBlock( $bFromReplica = true ) {
-               $this->getBlockedStatus( $bFromReplica );
+       public function getBlock( $fromReplica = true ) {
+               $this->getBlockedStatus( $fromReplica );
                return $this->mBlock instanceof Block ? $this->mBlock : null;
        }
 
@@ -2298,29 +2299,15 @@ class User implements IDBAccessObject, UserIdentity {
         * @param Title $title Title to check
         * @param bool $fromReplica Whether to check the replica DB instead of the master
         * @return bool
+        * @throws MWException
+        *
+        * @deprecated since 1.33,
+        * use MediaWikiServices::getInstance()->getPermissionManager()->isBlockedFrom(..)
+        *
         */
        public function isBlockedFrom( $title, $fromReplica = false ) {
-               $blocked = $this->isHidden();
-
-               if ( !$blocked ) {
-                       $block = $this->getBlock( $fromReplica );
-                       if ( $block ) {
-                               // Special handling for a user's own talk page. The block is not aware
-                               // of the user, so this must be done here.
-                               if ( $title->equals( $this->getTalkPage() ) ) {
-                                       $blocked = $block->appliesToUsertalk( $title );
-                               } else {
-                                       $blocked = $block->appliesToTitle( $title );
-                               }
-                       }
-               }
-
-               // only for the purpose of the hook. We really don't need this here.
-               $allowUsertalk = $this->mAllowUsertalk;
-
-               Hooks::run( 'UserIsBlockedFrom', [ $this, $title, &$blocked, &$allowUsertalk ] );
-
-               return $blocked;
+               return MediaWikiServices::getInstance()->getPermissionManager()
+                       ->isBlockedFrom( $this, $title, $fromReplica );
        }
 
        /**
@@ -2409,10 +2396,8 @@ class User implements IDBAccessObject, UserIdentity {
                if ( $this->mLocked !== null ) {
                        return $this->mLocked;
                }
-               // Avoid PHP 7.1 warning of passing $this by reference
-               $user = $this;
-               $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$user ], null );
-               $this->mLocked = $authUser && $authUser->isLocked();
+               // Reset for hook
+               $this->mLocked = false;
                Hooks::run( 'UserIsLocked', [ $this, &$this->mLocked ] );
                return $this->mLocked;
        }
@@ -2428,10 +2413,8 @@ class User implements IDBAccessObject, UserIdentity {
                }
                $this->getBlockedStatus();
                if ( !$this->mHideName ) {
-                       // Avoid PHP 7.1 warning of passing $this by reference
-                       $user = $this;
-                       $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$user ], null );
-                       $this->mHideName = $authUser && $authUser->isHidden();
+                       // Reset for hook
+                       $this->mHideName = false;
                        Hooks::run( 'UserIsHidden', [ $this, &$this->mHideName ] );
                }
                return (bool)$this->mHideName;
@@ -2770,17 +2753,16 @@ class User implements IDBAccessObject, UserIdentity {
        /**
         * Generate a current or new-future timestamp to be stored in the
         * user_touched field when we update things.
+        *
         * @return string Timestamp in TS_MW format
         */
        private function newTouchedTimestamp() {
-               global $wgClockSkewFudge;
-
-               $time = wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
-               if ( $this->mTouched && $time <= $this->mTouched ) {
-                       $time = wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $this->mTouched ) + 1 );
+               $time = time();
+               if ( $this->mTouched ) {
+                       $time = max( $time, wfTimestamp( TS_UNIX, $this->mTouched ) + 1 );
                }
 
-               return $time;
+               return wfTimestamp( TS_MW, $time );
        }
 
        /**
@@ -4276,7 +4258,7 @@ class User implements IDBAccessObject, UserIdentity {
 
                Hooks::run( 'UserSaveSettings', [ $this ] );
                $this->clearSharedCache();
-               $this->getUserPage()->invalidateCache();
+               $this->getUserPage()->purgeSquid();
        }
 
        /**
@@ -4436,10 +4418,8 @@ class User implements IDBAccessObject, UserIdentity {
                                        [ 'LOCK IN SHARE MODE' ]
                                );
                                $loaded = false;
-                               if ( $this->mId ) {
-                                       if ( $this->loadFromDatabase( self::READ_LOCKING ) ) {
-                                               $loaded = true;
-                                       }
+                               if ( $this->mId && $this->loadFromDatabase( self::READ_LOCKING ) ) {
+                                       $loaded = true;
                                }
                                if ( !$loaded ) {
                                        throw new MWException( $fname . ": hit a key conflict attempting " .
@@ -4726,22 +4706,38 @@ class User implements IDBAccessObject, UserIdentity {
 
                if ( $type == 'created' || $type === false ) {
                        $message = 'confirmemail_body';
+                       $type = 'created';
                } elseif ( $type === true ) {
                        $message = 'confirmemail_body_changed';
+                       $type = 'changed';
                } else {
                        // Messages: confirmemail_body_changed, confirmemail_body_set
                        $message = 'confirmemail_body_' . $type;
                }
 
-               return $this->sendMail( wfMessage( 'confirmemail_subject' )->text(),
-                       wfMessage( $message,
+               $mail = [
+                       'subject' => wfMessage( 'confirmemail_subject' )->text(),
+                       'body' => wfMessage( $message,
                                $this->getRequest()->getIP(),
                                $this->getName(),
                                $url,
                                $wgLang->userTimeAndDate( $expiration, $this ),
                                $invalidateURL,
                                $wgLang->userDate( $expiration, $this ),
-                               $wgLang->userTime( $expiration, $this ) )->text() );
+                               $wgLang->userTime( $expiration, $this ) )->text(),
+                       'from' => null,
+                       'replyTo' => null,
+               ];
+               $info = [
+                       'type' => $type,
+                       'ip' => $this->getRequest()->getIP(),
+                       'confirmURL' => $url,
+                       'invalidateURL' => $invalidateURL,
+                       'expiration' => $expiration
+               ];
+
+               Hooks::run( 'UserSendConfirmationMail', [ $this, &$mail, $info ] );
+               return $this->sendMail( $mail['subject'], $mail['body'], $mail['from'], $mail['replyTo'] );
        }
 
        /**
@@ -4752,7 +4748,7 @@ class User implements IDBAccessObject, UserIdentity {
         * @param string $body Message body
         * @param User|null $from Optional sending user; if unspecified, default
         *   $wgPasswordSender will be used.
-        * @param string|null $replyto Reply-To address
+        * @param MailAddress|null $replyto Reply-To address
         * @return Status
         */
        public function sendMail( $subject, $body, $from = null, $replyto = null ) {
@@ -4968,6 +4964,28 @@ class User implements IDBAccessObject, UserIdentity {
         *  non-existent/anonymous user accounts.
         */
        public function getFirstEditTimestamp() {
+               return $this->getEditTimestamp( true );
+       }
+
+       /**
+        * Get the timestamp of the latest edit
+        *
+        * @since 1.33
+        * @return string|bool Timestamp of first edit, or false for
+        *  non-existent/anonymous user accounts.
+        */
+       public function getLatestEditTimestamp() {
+               return $this->getEditTimestamp( false );
+       }
+
+       /**
+        * Get the timestamp of the first or latest edit
+        *
+        * @param bool $first True for the first edit, false for the latest one
+        * @return string|bool Timestamp of first or latest edit, or false for
+        *  non-existent/anonymous user accounts.
+        */
+       private function getEditTimestamp( $first ) {
                if ( $this->getId() == 0 ) {
                        return false; // anons
                }
@@ -4975,12 +4993,13 @@ class User implements IDBAccessObject, UserIdentity {
                $actorWhere = ActorMigration::newMigration()->getWhere( $dbr, 'rev_user', $this );
                $tsField = isset( $actorWhere['tables']['temp_rev_user'] )
                        ? 'revactor_timestamp' : 'rev_timestamp';
+               $sortOrder = $first ? 'ASC' : 'DESC';
                $time = $dbr->selectField(
                        [ 'revision' ] + $actorWhere['tables'],
                        $tsField,
                        [ $actorWhere['conds'] ],
                        __METHOD__,
-                       [ 'ORDER BY' => "$tsField ASC" ],
+                       [ 'ORDER BY' => "$tsField $sortOrder" ],
                        $actorWhere['joins']
                );
                if ( !$time ) {
@@ -5716,4 +5735,14 @@ class User implements IDBAccessObject, UserIdentity {
                // XXX it's not clear whether central ID providers are supposed to obey this
                return $this->getName() === $user->getName();
        }
+
+       /**
+        * Checks if usertalk is allowed
+        *
+        * @return bool
+        */
+       public function isAllowUsertalk() {
+               return $this->mAllowUsertalk;
+       }
+
 }
index f42b5a0..f2bc615 100644 (file)
@@ -77,7 +77,7 @@ class BatchRowUpdate {
                $this->reader = $reader;
                $this->writer = $writer;
                $this->generator = $generator;
-               $this->output = function () {
+               $this->output = function ( $text ) {
                }; // nop
        }
 
index ec8bf5c..673586d 100644 (file)
  * @file
  */
 
-use MediaWiki\MediaWikiServices;
-
 class MWCryptRand {
-       /**
-        * @deprecated since 1.32
-        * @return CryptRand
-        */
-       protected static function singleton() {
-               wfDeprecated( __METHOD__, '1.32' );
-               return MediaWikiServices::getInstance()->getCryptRand();
-       }
-
-       /**
-        * Return a boolean indicating whether or not the source used for cryptographic
-        * random bytes generation in the previously run generate* call
-        * was cryptographically strong.
-        *
-        * @deprecated since 1.32, always returns true
-        *
-        * @return bool Always true
-        */
-       public static function wasStrong() {
-               wfDeprecated( __METHOD__, '1.32' );
-               return true;
-       }
-
-       /**
-        * Generate a run of cryptographically random data and return
-        * it in raw binary form.
-        *
-        * @deprecated since 1.32, use random_bytes()
-        *
-        * @param int $bytes The number of bytes of random data to generate
-        * @return string Raw binary random data
-        */
-       public static function generate( $bytes ) {
-               wfDeprecated( __METHOD__, '1.32' );
-               return random_bytes( floor( $bytes ) );
-       }
 
        /**
         * Generate a run of cryptographically random data and return
index 15c0cf9..fea5404 100644 (file)
@@ -137,8 +137,7 @@ class UIDGenerator {
                        $time = $info['time'];
                        $counter = $info['offsetCounter'];
                } else {
-                       $time = $info[0];
-                       $counter = $info[1];
+                       list( $time, $counter ) = $info;
                }
                // Take the 46 LSBs of "milliseconds since epoch"
                $id_bin = $this->millisecondsSinceEpochBinary( $time );
@@ -192,9 +191,7 @@ class UIDGenerator {
                        $counter = $info['offsetCounter'];
                        $clkSeq = $info['clkSeq'];
                } else {
-                       $time = $info[0];
-                       $counter = $info[1];
-                       $clkSeq = $info[2];
+                       list( $time, $counter, $clkSeq ) = $info;
                }
                // Take the 46 LSBs of "milliseconds since epoch"
                $id_bin = $this->millisecondsSinceEpochBinary( $time );
@@ -577,7 +574,7 @@ class UIDGenerator {
                $start = microtime( true );
                do {
                        $ct = time();
-                       // https://secure.php.net/manual/en/language.operators.comparison.php
+                       // https://www.php.net/manual/en/language.operators.comparison.php
                        if ( $ct >= $time ) {
                                // current time is higher than or equal to than $time
                                return $ct;
index eabdb07..fc95ebc 100644 (file)
@@ -149,4 +149,7 @@ class NoWriteWatchedItemStore implements WatchedItemStoreInterface {
                throw new DBReadOnlyError( null, self::DB_READONLY_ERROR );
        }
 
+       public function getLatestNotificationTimestamp( $timestamp, User $user, LinkTarget $target ) {
+               return wfTimestampOrNull( TS_MW, $timestamp );
+       }
 }
index a85e7e8..6094f41 100644 (file)
@@ -65,14 +65,19 @@ class WatchedItemQueryService {
        /** @var ActorMigration */
        private $actorMigration;
 
+       /** @var WatchedItemStoreInterface */
+       private $watchedItemStore;
+
        public function __construct(
                LoadBalancer $loadBalancer,
                CommentStore $commentStore,
-               ActorMigration $actorMigration
+               ActorMigration $actorMigration,
+               WatchedItemStoreInterface $watchedItemStore
        ) {
                $this->loadBalancer = $loadBalancer;
                $this->commentStore = $commentStore;
                $this->actorMigration = $actorMigration;
+               $this->watchedItemStore = $watchedItemStore;
        }
 
        /**
@@ -228,11 +233,14 @@ class WatchedItemQueryService {
                                break;
                        }
 
+                       $target = new TitleValue( (int)$row->rc_namespace, $row->rc_title );
                        $items[] = [
                                new WatchedItem(
                                        $user,
-                                       new TitleValue( (int)$row->rc_namespace, $row->rc_title ),
-                                       $row->wl_notificationtimestamp
+                                       $target,
+                                       $this->watchedItemStore->getLatestNotificationTimestamp(
+                                               $row->wl_notificationtimestamp, $user, $target
+                                       )
                                ),
                                $this->getRecentChangeFieldsFromRow( $row )
                        ];
@@ -307,11 +315,14 @@ class WatchedItemQueryService {
 
                $watchedItems = [];
                foreach ( $res as $row ) {
+                       $target = new TitleValue( (int)$row->wl_namespace, $row->wl_title );
                        // todo these could all be cached at some point?
                        $watchedItems[] = new WatchedItem(
                                $user,
-                               new TitleValue( (int)$row->wl_namespace, $row->wl_title ),
-                               $row->wl_notificationtimestamp
+                               $target,
+                               $this->watchedItemStore->getLatestNotificationTimestamp(
+                                       $row->wl_notificationtimestamp, $user, $target
+                               )
                        );
                }
 
@@ -434,11 +445,9 @@ class WatchedItemQueryService {
 
                $conds = array_merge( $conds, $this->getStartEndConds( $db, $options ) );
 
-               if ( !isset( $options['start'] ) && !isset( $options['end'] ) ) {
-                       if ( $db->getType() === 'mysql' ) {
-                               // This is an index optimization for mysql
-                               $conds[] = 'rc_timestamp > ' . $db->addQuotes( '' );
-                       }
+               if ( !isset( $options['start'] ) && !isset( $options['end'] ) && $db->getType() === 'mysql' ) {
+                       // This is an index optimization for mysql
+                       $conds[] = 'rc_timestamp > ' . $db->addQuotes( '' );
                }
 
                $conds = array_merge( $conds, $this->getUserRelatedConds( $db, $user, $options ) );
@@ -693,7 +702,7 @@ class WatchedItemQueryService {
 
        private function getWatchedItemsWithRCInfoQueryJoinConds( array $options ) {
                $joinConds = [
-                       'watchlist' => [ 'INNER JOIN',
+                       'watchlist' => [ 'JOIN',
                                [
                                        'wl_namespace=rc_namespace',
                                        'wl_title=rc_title'
index 873ae2d..a0e64c5 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
@@ -45,7 +45,7 @@ interface WatchedItemQueryServiceExtension {
         * @param IDatabase $db Database connection being used for the query
         * @param array &$items array of pairs ( WatchedItem $watchedItem, string[] $recentChangeInfo ).
         *  May be truncated if necessary, in which case $startFrom must be updated.
-        * @param ResultWrapper|bool $res Database query result
+        * @param IResultWrapper|bool $res Database query result
         * @param array|null &$startFrom Continuation value. If you truncate $items, set this to
         *  [ $recentChangeInfo['rc_timestamp'], $recentChangeInfo['rc_id'] ] from the first item
         *  removed.
index 1c33754..e287a35 100644 (file)
@@ -28,6 +28,16 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
         */
        private $loadBalancer;
 
+       /**
+        * @var JobQueueGroup
+        */
+       private $queueGroup;
+
+       /**
+        * @var BagOStuff
+        */
+       private $stash;
+
        /**
         * @var ReadOnlyMode
         */
@@ -38,6 +48,11 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
         */
        private $cache;
 
+       /**
+        * @var HashBagOStuff
+        */
+       private $latestUpdateCache;
+
        /**
         * @var array[] Looks like $cacheIndex[Namespace ID][Target DB Key][User Id] => 'key'
         * The index is needed so that on mass changes all relevant items can be un-cached.
@@ -68,18 +83,24 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
 
        /**
         * @param ILBFactory $lbFactory
+        * @param JobQueueGroup $queueGroup
+        * @param BagOStuff $stash
         * @param HashBagOStuff $cache
         * @param ReadOnlyMode $readOnlyMode
         * @param int $updateRowsPerQuery
         */
        public function __construct(
                ILBFactory $lbFactory,
+               JobQueueGroup $queueGroup,
+               BagOStuff $stash,
                HashBagOStuff $cache,
                ReadOnlyMode $readOnlyMode,
                $updateRowsPerQuery
        ) {
                $this->lbFactory = $lbFactory;
                $this->loadBalancer = $lbFactory->getMainLB();
+               $this->queueGroup = $queueGroup;
+               $this->stash = $stash;
                $this->cache = $cache;
                $this->readOnlyMode = $readOnlyMode;
                $this->stats = new NullStatsdDataFactory();
@@ -88,6 +109,8 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
                $this->revisionGetTimestampFromIdCallback =
                        [ Revision::class, 'getTimestampFromId' ];
                $this->updateRowsPerQuery = $updateRowsPerQuery;
+
+               $this->latestUpdateCache = new HashBagOStuff( [ 'maxKeys' => 3 ] );
        }
 
        /**
@@ -188,6 +211,10 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
                                }
                        }
                }
+
+               $pageSeenKey = $this->getPageSeenTimestampsKey( $user );
+               $this->latestUpdateCache->delete( $pageSeenKey );
+               $this->stash->delete( $pageSeenKey );
        }
 
        /**
@@ -286,8 +313,7 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
         */
        public function clearUserWatchedItemsUsingJobQueue( User $user ) {
                $job = ClearUserWatchlistJob::newForUser( $user, $this->getMaxId() );
-               // TODO inject me.
-               JobQueueGroup::singleton()->push( $job );
+               $this->queueGroup->push( $job );
        }
 
        /**
@@ -568,6 +594,7 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
                }
 
                $dbr = $this->getConnectionRef( DB_REPLICA );
+
                $row = $dbr->selectRow(
                        'watchlist',
                        'wl_notificationtimestamp',
@@ -582,7 +609,7 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
                $item = new WatchedItem(
                        $user,
                        $target,
-                       wfTimestampOrNull( TS_MW, $row->wl_notificationtimestamp )
+                       $this->getLatestNotificationTimestamp( $row->wl_notificationtimestamp, $user, $target )
                );
                $this->cache( $item );
 
@@ -622,11 +649,13 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
 
                $watchedItems = [];
                foreach ( $res as $row ) {
+                       $target = new TitleValue( (int)$row->wl_namespace, $row->wl_title );
                        // @todo: Should we add these to the process cache?
                        $watchedItems[] = new WatchedItem(
                                $user,
                                new TitleValue( (int)$row->wl_namespace, $row->wl_title ),
-                               $row->wl_notificationtimestamp
+                               $this->getLatestNotificationTimestamp(
+                                       $row->wl_notificationtimestamp, $user, $target )
                        );
                }
 
@@ -688,8 +717,10 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
                );
 
                foreach ( $res as $row ) {
+                       $target = new TitleValue( (int)$row->wl_namespace, $row->wl_title );
                        $timestamps[$row->wl_namespace][$row->wl_title] =
-                               wfTimestampOrNull( TS_MW, $row->wl_notificationtimestamp );
+                               $this->getLatestNotificationTimestamp(
+                                       $row->wl_notificationtimestamp, $user, $target );
                }
 
                return $timestamps;
@@ -778,53 +809,104 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
        }
 
        /**
+        * Set the "last viewed" timestamps for certain titles on a user's watchlist.
+        *
+        * If the $targets parameter is omitted or set to [], this method simply wraps
+        * resetAllNotificationTimestampsForUser(), and in that case you should instead call that method
+        * directly; support for omitting $targets is for backwards compatibility.
+        *
+        * If $targets is omitted or set to [], timestamps will be updated for every title on the user's
+        * watchlist, and this will be done through a DeferredUpdate. If $targets is a non-empty array,
+        * only the specified titles will be updated, and this will be done immediately (not deferred).
+        *
         * @since 1.27
         * @param User $user
-        * @param string|int $timestamp
-        * @param LinkTarget[] $targets
+        * @param string|int $timestamp Value to set the "last viewed" timestamp to (null to clear)
+        * @param LinkTarget[] $targets Titles to set the timestamp for; [] means the entire watchlist
         * @return bool
         */
        public function setNotificationTimestampsForUser( User $user, $timestamp, array $targets = [] ) {
                // Only loggedin user can have a watchlist
-               if ( $user->isAnon() ) {
+               if ( $user->isAnon() || $this->readOnlyMode->isReadOnly() ) {
                        return false;
                }
 
-               $dbw = $this->getConnectionRef( DB_MASTER );
-
-               $conds = [ 'wl_user' => $user->getId() ];
-               if ( $targets ) {
-                       $batch = new LinkBatch( $targets );
-                       $conds[] = $batch->constructSet( 'wl', $dbw );
+               if ( !$targets ) {
+                       // Backwards compatibility
+                       $this->resetAllNotificationTimestampsForUser( $user, $timestamp );
+                       return true;
                }
 
+               $rows = $this->getTitleDbKeysGroupedByNamespace( $targets );
+
+               $dbw = $this->getConnectionRef( DB_MASTER );
                if ( $timestamp !== null ) {
                        $timestamp = $dbw->timestamp( $timestamp );
                }
+               $ticket = $this->lbFactory->getEmptyTransactionTicket( __METHOD__ );
+               $affectedSinceWait = 0;
 
-               $success = $dbw->update(
-                       'watchlist',
-                       [ 'wl_notificationtimestamp' => $timestamp ],
-                       $conds,
-                       __METHOD__
-               );
+               // Batch update items per namespace
+               foreach ( $rows as $namespace => $namespaceTitles ) {
+                       $rowBatches = array_chunk( $namespaceTitles, $this->updateRowsPerQuery );
+                       foreach ( $rowBatches as $toUpdate ) {
+                               $dbw->update(
+                                       'watchlist',
+                                       [ 'wl_notificationtimestamp' => $timestamp ],
+                                       [
+                                               'wl_user' => $user->getId(),
+                                               'wl_namespace' => $namespace,
+                                               'wl_title' => $toUpdate
+                                       ]
+                               );
+                               $affectedSinceWait += $dbw->affectedRows();
+                               // Wait for replication every time we've touched updateRowsPerQuery rows
+                               if ( $affectedSinceWait >= $this->updateRowsPerQuery ) {
+                                       $this->lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
+                                       $affectedSinceWait = 0;
+                               }
+                       }
+               }
 
                $this->uncacheUser( $user );
 
-               return $success;
+               return true;
+       }
+
+       public function getLatestNotificationTimestamp( $timestamp, User $user, LinkTarget $target ) {
+               $timestamp = wfTimestampOrNull( TS_MW, $timestamp );
+               if ( $timestamp === null ) {
+                       return null; // no notification
+               }
+
+               $seenTimestamps = $this->getPageSeenTimestamps( $user );
+               if (
+                       $seenTimestamps &&
+                       $seenTimestamps->get( $this->getPageSeenKey( $target ) ) >= $timestamp
+               ) {
+                       // If a reset job did not yet run, then the "seen" timestamp will be higher
+                       return null;
+               }
+
+               return $timestamp;
        }
 
-       public function resetAllNotificationTimestampsForUser( User $user ) {
+       /**
+        * Schedule a DeferredUpdate that sets all of the "last viewed" timestamps for a given user
+        * to the same value.
+        * @param User $user
+        * @param string|int|null $timestamp Value to set all timestamps to, null to clear them
+        */
+       public function resetAllNotificationTimestampsForUser( User $user, $timestamp = null ) {
                // Only loggedin user can have a watchlist
                if ( $user->isAnon() ) {
                        return;
                }
 
                // If the page is watched by the user (or may be watched), update the timestamp
-               $job = new ClearWatchlistNotificationsJob(
-                       $user->getUserPage(),
-                       [ 'userId'  => $user->getId(), 'casTime' => time() ]
-               );
+               $job = new ClearWatchlistNotificationsJob( [
+                       'userId'  => $user->getId(), 'timestamp' => $timestamp, 'casTime' => time()
+               ] );
 
                // Try to run this post-send
                // Calls DeferredUpdates::addCallableUpdate in normal operation
@@ -902,6 +984,8 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
         * @return bool
         */
        public function resetNotificationTimestamp( User $user, Title $title, $force = '', $oldid = 0 ) {
+               $time = time();
+
                // Only loggedin user can have a watchlist
                if ( $this->readOnlyMode->isReadOnly() || $user->isAnon() ) {
                        return false;
@@ -919,6 +1003,37 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
                        }
                }
 
+               // Get the timestamp (TS_MW) of this revision to track the latest one seen
+               $seenTime = call_user_func(
+                       $this->revisionGetTimestampFromIdCallback,
+                       $title,
+                       $oldid ?: $title->getLatestRevID()
+               );
+
+               // Mark the item as read immediately in lightweight storage
+               $this->stash->merge(
+                       $this->getPageSeenTimestampsKey( $user ),
+                       function ( $cache, $key, $current ) use ( $title, $seenTime ) {
+                               $value = $current ?: new MapCacheLRU( 300 );
+                               $subKey = $this->getPageSeenKey( $title );
+
+                               if ( $seenTime > $value->get( $subKey ) ) {
+                                       // Revision is newer than the last one seen
+                                       $value->set( $subKey, $seenTime );
+                                       $this->latestUpdateCache->set( $key, $value, IExpiringStore::TTL_PROC_LONG );
+                               } elseif ( $seenTime === false ) {
+                                       // Revision does not exist
+                                       $value->set( $subKey, wfTimestamp( TS_MW ) );
+                                       $this->latestUpdateCache->set( $key, $value, IExpiringStore::TTL_PROC_LONG );
+                               } else {
+                                       return false; // nothing to update
+                               }
+
+                               return $value;
+                       },
+                       IExpiringStore::TTL_HOUR
+               );
+
                // If the page is watched by the user (or may be watched), update the timestamp
                $job = new ActivityUpdateJob(
                        $title,
@@ -926,22 +1041,51 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
                                'type'      => 'updateWatchlistNotification',
                                'userid'    => $user->getId(),
                                'notifTime' => $this->getNotificationTimestamp( $user, $title, $item, $force, $oldid ),
-                               'curTime'   => time()
+                               'curTime'   => $time
                        ]
                );
+               // Try to enqueue this post-send
+               $this->queueGroup->lazyPush( $job );
 
-               // Try to run this post-send
-               // Calls DeferredUpdates::addCallableUpdate in normal operation
-               call_user_func(
-                       $this->deferredUpdatesAddCallableUpdateCallback,
-                       function () use ( $job ) {
-                               $job->run();
+               $this->uncache( $user, $title );
+
+               return true;
+       }
+
+       /**
+        * @param User $user
+        * @return MapCacheLRU|null The map contains prefixed title keys and TS_MW values
+        */
+       private function getPageSeenTimestamps( User $user ) {
+               $key = $this->getPageSeenTimestampsKey( $user );
+
+               return $this->latestUpdateCache->getWithSetCallback(
+                       $key,
+                       IExpiringStore::TTL_PROC_LONG,
+                       function () use ( $key ) {
+                               return $this->stash->get( $key ) ?: null;
                        }
                );
+       }
 
-               $this->uncache( $user, $title );
+       /**
+        * @param User $user
+        * @return string
+        */
+       private function getPageSeenTimestampsKey( User $user ) {
+               return $this->stash->makeGlobalKey(
+                       'watchlist-recent-updates',
+                       $this->lbFactory->getLocalDomainID(),
+                       $user->getId()
+               );
+       }
 
-               return true;
+       /**
+        * @param LinkTarget $target
+        * @return string
+        */
+       private function getPageSeenKey( LinkTarget $target ) {
+               return "{$target->getNamespace()}:{$target->getDBkey()}";
        }
 
        private function getNotificationTimestamp( User $user, Title $title, $item, $force, $oldid ) {
@@ -998,25 +1142,22 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
         * @return int|bool
         */
        public function countUnreadNotifications( User $user, $unreadLimit = null ) {
+               $dbr = $this->getConnectionRef( DB_REPLICA );
+
                $queryOptions = [];
                if ( $unreadLimit !== null ) {
                        $unreadLimit = (int)$unreadLimit;
                        $queryOptions['LIMIT'] = $unreadLimit;
                }
 
-               $dbr = $this->getConnectionRef( DB_REPLICA );
-               $rowCount = $dbr->selectRowCount(
-                       'watchlist',
-                       '1',
-                       [
-                               'wl_user' => $user->getId(),
-                               'wl_notificationtimestamp IS NOT NULL',
-                       ],
-                       __METHOD__,
-                       $queryOptions
-               );
+               $conds = [
+                       'wl_user' => $user->getId(),
+                       'wl_notificationtimestamp IS NOT NULL'
+               ];
+
+               $rowCount = $dbr->selectRowCount( 'watchlist', '1', $conds, __METHOD__, $queryOptions );
 
-               if ( !isset( $unreadLimit ) ) {
+               if ( $unreadLimit === null ) {
                        return $rowCount;
                }
 
@@ -1087,7 +1228,7 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
        }
 
        /**
-        * @param TitleValue[] $titles
+        * @param LinkTarget[] $titles
         * @return array
         */
        private function getTitleDbKeysGroupedByNamespace( array $titles ) {
index 274d3f4..349d98a 100644 (file)
@@ -326,4 +326,18 @@ interface WatchedItemStoreInterface {
         */
        public function removeWatchBatchForUser( User $user, array $targets );
 
+       /**
+        * Convert $timestamp to TS_MW or return null if the page was visited since then by $user
+        *
+        * Use this only on single-user methods (having higher read-after-write expectations)
+        * and not in places involving arbitrary batches of different users
+        *
+        * Usage of this method should be limited to WatchedItem* classes
+        *
+        * @param string|null $timestamp Value of wl_notificationtimestamp from the DB
+        * @param User $user
+        * @param LinkTarget $target
+        * @return string TS_MW timestamp or null
+        */
+       public function getLatestNotificationTimestamp( $timestamp, User $user, LinkTarget $target );
 }
index 289cc85..02f369a 100644 (file)
@@ -30,8 +30,6 @@ class ExpiryInputWidget extends Widget {
         * @param array $options Configuration options
         */
        public function __construct( Widget $relativeInput, array $options = [] ) {
-               $config = \RequestContext::getMain()->getConfig();
-
                parent::__construct( $options );
 
                $this->required = $options['required'] ?? false;
@@ -54,7 +52,7 @@ class ExpiryInputWidget extends Widget {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        public function getConfig( &$config ) {
                $config['required'] = $this->required;
index c0efd24..48c624c 100644 (file)
@@ -16,17 +16,17 @@ use OOUI;
  * the results are from.
  */
 class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
-       /** @var SpecialSearch */
+       /** @var SpecialSearch $specialSearch */
        protected $specialSearch;
-       /** @var SearchResultWidget */
+       /** @var SearchResultWidget $resultWidget */
        protected $resultWidget;
-       /** @var string[]|null */
+       /** @var string[]|null $customCaptions */
        protected $customCaptions;
-       /** @var LinkRenderer */
+       /** @var LinkRenderer $linkRenderer */
        protected $linkRenderer;
-       /** @var InterwikiLookup */
+       /** @var InterwikiLookup $iwLookup */
        protected $iwLookup;
-       /** @var $output */
+       /** @var \OutputPage $output */
        protected $output;
        /** @var bool $showMultimedia */
        protected $showMultimedia;
index 4eead5e..095c30a 100644 (file)
@@ -30,7 +30,6 @@ class InterwikiSearchResultWidget implements SearchResultWidget {
         */
        public function render( SearchResult $result, $terms, $position ) {
                $title = $result->getTitle();
-               $iwPrefix = $result->getTitle()->getInterwiki();
                $titleSnippet = $result->getTitleSnippet();
                $snippet = $result->getTextSnippet( $terms );
 
index 3362788..fad38e3 100644 (file)
@@ -7,7 +7,7 @@
        "--builtin-classes": true,
        "--processes": "0",
        "--warnings-exit-nonzero": true,
-       "--external": "Blob,File,HTMLDocument,HTMLElement,HTMLIframeElement,HTMLInputElement,KeyboardEvent,MouseEvent,Node,Window,XMLDocument",
+       "--external": "Blob,File,FileList,HTMLDocument,HTMLElement,HTMLIframeElement,HTMLInputElement,KeyboardEvent,MouseEvent,Node,Window,XMLDocument",
        "--output": "docs/js",
        "--exclude": [
                "resources/src/jquery.tablesorter",
index 3dbde01..a9bbc20 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 use CLDRPluralRuleParser\Evaluator;
+use Wikimedia\Assert\Assert;
 
 /**
  * Internationalisation code
@@ -385,6 +386,7 @@ class Language {
         */
        public static function isValidCode( $code ) {
                static $cache = [];
+               Assert::parameterType( 'string', $code, '$code' );
                if ( !isset( $cache[$code] ) ) {
                        // People think language codes are html safe, so enforce it.
                        // Ideally we should only allow a-zA-Z0-9-
@@ -404,20 +406,11 @@ class Language {
         *
         * @param string $code
         *
-        * @throws MWException
         * @since 1.18
         * @return bool
         */
        public static function isValidBuiltInCode( $code ) {
-               if ( !is_string( $code ) ) {
-                       if ( is_object( $code ) ) {
-                               $addmsg = " of class " . get_class( $code );
-                       } else {
-                               $addmsg = '';
-                       }
-                       $type = gettype( $code );
-                       throw new MWException( __METHOD__ . " must be passed a string, $type given$addmsg" );
-               }
+               Assert::parameterType( 'string', $code, '$code' );
 
                return (bool)preg_match( '/^[a-z0-9-]{2,}$/', $code );
        }
@@ -2845,9 +2838,9 @@ class Language {
        }
 
        /**
+        * TODO: $s is not always a string per T218883
         * @param string $s
         * @return string
-        * @throws MWException
         */
        function checkTitleEncoding( $s ) {
                if ( is_array( $s ) ) {
@@ -2861,7 +2854,7 @@ class Language {
        }
 
        /**
-        * @return array
+        * @return string
         */
        function fallback8bitEncoding() {
                return self::$dataCache->getItem( $this->mCode, 'fallback8bitEncoding' );
@@ -3522,8 +3515,8 @@ class Language {
         * Truncate a string to a specified number of characters, appending an optional
         * string (e.g. for ellipsis).
         *
-        * This provides multibyte version of truncate() method of this class, suitable for truncation
-        * based on number of characters, instead of number of bytes.
+        * This provides multibyte version of truncateForDatabase() method of this class,
+        * suitable for truncation based on number of characters, instead of number of bytes.
         *
         * If $length is negative, the string will be truncated from the beginning.
         *
@@ -3563,12 +3556,8 @@ class Language {
         * @return string
         */
        private function truncateInternal(
-               $string, $length, $ellipsis, $adjustLength, $measureLength, $getSubstring
+               $string, $length, $ellipsis, $adjustLength, callable $measureLength, callable $getSubstring
        ) {
-               if ( !is_callable( $measureLength ) || !is_callable( $getSubstring ) ) {
-                       throw new InvalidArgumentException( 'Invalid callback provided' );
-               }
-
                # Check if there is no need to truncate
                if ( $measureLength( $string ) <= abs( $length ) ) {
                        return $string; // no need to truncate
@@ -3593,14 +3582,12 @@ class Language {
                                $length -= $ellipsisLength;
                                $string = $getSubstring( $string, 0, $length ); // xyz...
                                $string = $this->removeBadCharLast( $string );
-                               $string = rtrim( $string );
-                               $string = $string . $ellipsis;
+                               $string = rtrim( $string ) . $ellipsis;
                        } else {
                                $length += $ellipsisLength;
                                $string = $getSubstring( $string, $length ); // ...xyz
                                $string = $this->removeBadCharFirst( $string );
-                               $string = ltrim( $string );
-                               $string = $ellipsis . $string;
+                               $string = $ellipsis . ltrim( $string );
                        }
                }
 
@@ -3710,6 +3697,7 @@ class Language {
                                        }
                                } elseif ( $dispLen > $length && $dispLen > strlen( $ellipsis ) ) {
                                        # String in fact does need truncation, the truncation point was OK.
+                                       // @phan-suppress-next-line PhanTypeInvalidExpressionArrayDestructuring
                                        list( $ret, $openTags ) = $maybeState; // reload state
                                        $ret = $this->removeBadCharLast( $ret ); // multi-byte char fix
                                        $ret .= $ellipsis; // add ellipsis
@@ -4032,15 +4020,12 @@ class Language {
         * Checks that convertPlural was given an array and pads it to requested
         * amount of forms by copying the last one.
         *
-        * @param array $forms Array of forms given to convertPlural
+        * @param array $forms
         * @param int $count How many forms should there be at least
-        * @return array Padded array of forms or an exception if not an array
+        * @return array Padded array of forms
         */
        protected function preConvertPlural( /* Array */ $forms, $count ) {
-               while ( count( $forms ) < $count ) {
-                       $forms[] = $forms[count( $forms ) - 1];
-               }
-               return $forms;
+               return array_pad( $forms, $count, end( $forms ) );
        }
 
        /**
@@ -4331,32 +4316,6 @@ class Language {
                $this->mConverter->updateConversionTable( $title );
        }
 
-       /**
-        * Prepare external link text for conversion. When the text is
-        * a URL, it shouldn't be converted, and it'll be wrapped in
-        * the "raw" tag (-{R| }-) to prevent conversion.
-        *
-        * This function is called "markNoConversion" for historical
-        * reasons *BUT DIFFERS SIGNIFICANTLY* from
-        * LanguageConverter::markNoConversion(), with which it is easily
-        * confused.
-        *
-        * @param string $text Text to be used for external link
-        * @param bool $noParse Wrap it without confirming it's a real URL first
-        * @return string The tagged text
-        * @deprecated since 1.32, use LanguageConverter::markNoConversion()
-        *  instead.
-        */
-       public function markNoConversion( $text, $noParse = false ) {
-               wfDeprecated( __METHOD__, '1.32' );
-               // Excluding protocal-relative URLs may avoid many false positives.
-               if ( $noParse || preg_match( '/^(?:' . wfUrlProtocolsWithoutProtRel() . ')/', $text ) ) {
-                       return $this->mConverter->markNoConversion( $text );
-               } else {
-                       return $text;
-               }
-       }
-
        /**
         * A regular expression to match legal word-trailing characters
         * which should be merged onto a link of the form [[foo]]bar.
@@ -4444,18 +4403,6 @@ class Language {
                return $this->mHtmlCode;
        }
 
-       /**
-        * @param string $code
-        * @deprecated since 1.32, use Language::factory to create a new object instead.
-        */
-       public function setCode( $code ) {
-               wfDeprecated( __METHOD__, '1.32' );
-               $this->mCode = $code;
-               // Ensure we don't leave incorrect cached data lying around
-               $this->mHtmlCode = null;
-               $this->mParentLanguage = false;
-       }
-
        /**
         * Get the language code from a file name. Inverse of getFileName()
         * @param string $filename $prefix . $languageCode . $suffix
@@ -4892,6 +4839,8 @@ class Language {
         * @param array $query Optional URL query parameter string
         * @param bool $atend Optional param for specified if this is the last page
         * @return string
+        * @deprecated since 1.33, use SpecialPage::viewPrevNext()
+        *  instead.
         */
        public function viewPrevNext( Title $title, $offset, $limit,
                array $query = [], $atend = false
index 8aa7c87..c5ff9d6 100644 (file)
@@ -60,7 +60,13 @@ class LanguageConverter {
        public $mVariantFallbacks;
        public $mVariantNames;
        public $mTablesLoaded = false;
+
+       /**
+        * @var ReplacementArray[]
+        * @phan-var array<string,ReplacementArray>
+        */
        public $mTables;
+
        // 'bidirectional' 'unidirectional' 'disable' for each variant
        public $mManualLevel;
 
index b2bae18..f8c3368 100644 (file)
@@ -73,7 +73,7 @@ class LanguageFi extends Language {
                                break;
                        case 'illative':
                                # Double the last letter and add 'n'
-                               $word = $word . mb_substr( $word, -1 ) . 'n';
+                               $word .= mb_substr( $word, -1 ) . 'n';
                                break;
                        case 'inessive':
                                $word .= ( $aou ? 'ssa' : 'ssä' );
index b9da24a..a89dbc2 100644 (file)
@@ -63,9 +63,7 @@ class LanguageKk_cyrl extends Language {
                $secondPerson = [ "з" ]; // 1st plural, 2nd formal
                $thirdPerson = [ "ы", "і" ]; // 3rd
 
-               $lastLetter = $this->lastLetter( $word, $allVowels );
-               $wordEnding =& $lastLetter[0];
-               $wordLastVowel =& $lastLetter[1];
+               list( $wordEnding, $wordLastVowel ) = $this->lastLetter( $word, $allVowels );
 
                // Now convert the word
                switch ( $case ) {
@@ -73,21 +71,21 @@ class LanguageKk_cyrl extends Language {
                        case "genitive": # ilik
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "тің";
+                                               $word .= "тің";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "тың";
+                                               $word .= "тың";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Nasals ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "нің";
+                                               $word .= "нің";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ның";
+                                               $word .= "ның";
                                        }
                                } elseif ( in_array( $wordEnding, $Sonants ) || in_array( $wordEnding, $Sibilants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "дің";
+                                               $word .= "дің";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "дың";
+                                               $word .= "дың";
                                        }
                                }
                                break;
@@ -95,15 +93,15 @@ class LanguageKk_cyrl extends Language {
                        case "dative": # barıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ке";
+                                               $word .= "ке";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "қа";
+                                               $word .= "қа";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ге";
+                                               $word .= "ге";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ға";
+                                               $word .= "ға";
                                        }
                                }
                                break;
@@ -111,21 +109,21 @@ class LanguageKk_cyrl extends Language {
                        case "possessive dative": # täweldık + barıs
                                if ( in_array( $wordEnding, $firstPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "е";
+                                               $word .= "е";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "а";
+                                               $word .= "а";
                                        }
                                } elseif ( in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ге";
+                                               $word .= "ге";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ға";
+                                               $word .= "ға";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "не";
+                                               $word .= "не";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "на";
+                                               $word .= "на";
                                        }
                                }
                                break;
@@ -133,21 +131,21 @@ class LanguageKk_cyrl extends Language {
                        case "accusative": # tabıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ті";
+                                               $word .= "ті";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ты";
+                                               $word .= "ты";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ні";
+                                               $word .= "ні";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ны";
+                                               $word .= "ны";
                                        }
                                } elseif ( in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ді";
+                                               $word .= "ді";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ды";
+                                               $word .= "ды";
                                        }
                                }
                                break;
@@ -155,27 +153,27 @@ class LanguageKk_cyrl extends Language {
                        case "possessive accusative": # täweldık + tabıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ді";
+                                               $word .= "ді";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ды";
+                                               $word .= "ды";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
-                                               $word = $word . "н";
+                                               $word .= "н";
                                }
                                break;
                        case "dc4":
                        case "locative": # jatıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "те";
+                                               $word .= "те";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "та";
+                                               $word .= "та";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "де";
+                                               $word .= "де";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "да";
+                                               $word .= "да";
                                        }
                                }
                                break;
@@ -183,15 +181,15 @@ class LanguageKk_cyrl extends Language {
                        case "possessive locative": # täweldık + jatıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "де";
+                                               $word .= "де";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "да";
+                                               $word .= "да";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "нде";
+                                               $word .= "нде";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "нда";
+                                               $word .= "нда";
                                        }
                                }
                                break;
@@ -199,24 +197,24 @@ class LanguageKk_cyrl extends Language {
                        case "ablative": # şığıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "тен";
+                                               $word .= "тен";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "тан";
+                                               $word .= "тан";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Sonants )
                                        || in_array( $wordEnding, $Sibilants )
                                ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ден";
+                                               $word .= "ден";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "дан";
+                                               $word .= "дан";
                                        }
                                } elseif ( in_array( $wordEnding, $Nasals ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "нен";
+                                               $word .= "нен";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "нан";
+                                               $word .= "нан";
                                        }
                                }
                                break;
@@ -224,42 +222,42 @@ class LanguageKk_cyrl extends Language {
                        case "possessive ablative": # täweldık + şığıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "нен";
+                                               $word .= "нен";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "нан";
+                                               $word .= "нан";
                                        }
                                } elseif ( in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ден";
+                                               $word .= "ден";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "дан";
+                                               $word .= "дан";
                                        }
                                }
                                break;
                        case "dc6":
                        case "comitative": # kömektes
                                if ( in_array( $wordEnding, $Consonants ) ) {
-                                               $word = $word . "пен";
+                                               $word .= "пен";
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Nasals )
                                        || in_array( $wordEnding, $Sonants )
                                ) {
-                                               $word = $word . "мен";
+                                               $word .= "мен";
                                } elseif ( in_array( $wordEnding, $Sibilants ) ) {
-                                               $word = $word . "бен";
+                                               $word .= "бен";
                                }
                                break;
                        case "dc61":
                        case "possessive comitative": # täweldık + kömektes
                                if ( in_array( $wordEnding, $Consonants ) ) {
-                                               $word = $word . "пенен";
+                                               $word .= "пенен";
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Nasals )
                                        || in_array( $wordEnding, $Sonants )
                                ) {
-                                               $word = $word . "менен";
+                                               $word .= "менен";
                                } elseif ( in_array( $wordEnding, $Sibilants ) ) {
-                                               $word = $word . "бенен";
+                                               $word .= "бенен";
                                }
                                break;
                        default: # dc0 #nominative #ataw
@@ -297,9 +295,7 @@ class LanguageKk_cyrl extends Language {
                $secondPerson = [ "z" ]; // 1st plural, 2nd formal
                $thirdPerson = [ "ı", "i" ]; // 3rd
 
-               $lastLetter = $this->lastLetter( $word, $allVowels );
-               $wordEnding =& $lastLetter[0];
-               $wordLastVowel =& $lastLetter[1];
+               list( $wordEnding, $wordLastVowel ) = $this->lastLetter( $word, $allVowels );
 
                // Now convert the word
                switch ( $case ) {
@@ -307,21 +303,21 @@ class LanguageKk_cyrl extends Language {
                        case "genitive": # ilik
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "tiñ";
+                                               $word .= "tiñ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "tıñ";
+                                               $word .= "tıñ";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Nasals ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "niñ";
+                                               $word .= "niñ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "nıñ";
+                                               $word .= "nıñ";
                                        }
                                } elseif ( in_array( $wordEnding, $Sonants ) || in_array( $wordEnding, $Sibilants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "diñ";
+                                               $word .= "diñ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "dıñ";
+                                               $word .= "dıñ";
                                        }
                                }
                                break;
@@ -329,15 +325,15 @@ class LanguageKk_cyrl extends Language {
                        case "dative": # barıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ke";
+                                               $word .= "ke";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "qa";
+                                               $word .= "qa";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ge";
+                                               $word .= "ge";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ğa";
+                                               $word .= "ğa";
                                        }
                                }
                                break;
@@ -345,21 +341,21 @@ class LanguageKk_cyrl extends Language {
                        case "possessive dative": # täweldık + barıs
                                if ( in_array( $wordEnding, $firstPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "e";
+                                               $word .= "e";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "a";
+                                               $word .= "a";
                                        }
                                } elseif ( in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ge";
+                                               $word .= "ge";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ğa";
+                                               $word .= "ğa";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ne";
+                                               $word .= "ne";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "na";
+                                               $word .= "na";
                                        }
                                }
                                break;
@@ -367,21 +363,21 @@ class LanguageKk_cyrl extends Language {
                        case "accusative": # tabıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ti";
+                                               $word .= "ti";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "tı";
+                                               $word .= "tı";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ni";
+                                               $word .= "ni";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "nı";
+                                               $word .= "nı";
                                        }
                                } elseif ( in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "di";
+                                               $word .= "di";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "dı";
+                                               $word .= "dı";
                                        }
                                }
                                break;
@@ -389,27 +385,27 @@ class LanguageKk_cyrl extends Language {
                        case "possessive accusative": # täweldık + tabıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "di";
+                                               $word .= "di";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "dı";
+                                               $word .= "dı";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
-                                               $word = $word . "n";
+                                               $word .= "n";
                                }
                                break;
                        case "dc4":
                        case "locative": # jatıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "te";
+                                               $word .= "te";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ta";
+                                               $word .= "ta";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "de";
+                                               $word .= "de";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "da";
+                                               $word .= "da";
                                        }
                                }
                                break;
@@ -417,15 +413,15 @@ class LanguageKk_cyrl extends Language {
                        case "possessive locative": # täweldık + jatıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "de";
+                                               $word .= "de";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "da";
+                                               $word .= "da";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "nde";
+                                               $word .= "nde";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "nda";
+                                               $word .= "nda";
                                        }
                                }
                                break;
@@ -433,24 +429,24 @@ class LanguageKk_cyrl extends Language {
                        case "ablative": # şığıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ten";
+                                               $word .= "ten";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "tan";
+                                               $word .= "tan";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Sonants )
                                        || in_array( $wordEnding, $Sibilants )
                                ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "den";
+                                               $word .= "den";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "dan";
+                                               $word .= "dan";
                                        }
                                } elseif ( in_array( $wordEnding, $Nasals ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "nen";
+                                               $word .= "nen";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "nan";
+                                               $word .= "nan";
                                        }
                                }
                                break;
@@ -458,42 +454,42 @@ class LanguageKk_cyrl extends Language {
                        case "possessive ablative": # täweldık + şığıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "nen";
+                                               $word .= "nen";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "nan";
+                                               $word .= "nan";
                                        }
                                } elseif ( in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "den";
+                                               $word .= "den";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "dan";
+                                               $word .= "dan";
                                        }
                                }
                                break;
                        case "dc6":
                        case "comitative": # kömektes
                                if ( in_array( $wordEnding, $Consonants ) ) {
-                                               $word = $word . "pen";
+                                               $word .= "pen";
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Nasals )
                                        || in_array( $wordEnding, $Sonants )
                                ) {
-                                               $word = $word . "men";
+                                               $word .= "men";
                                } elseif ( in_array( $wordEnding, $Sibilants ) ) {
-                                               $word = $word . "ben";
+                                               $word .= "ben";
                                }
                                break;
                        case "dc61":
                        case "possessive comitative": # täweldık + kömektes
                                if ( in_array( $wordEnding, $Consonants ) ) {
-                                               $word = $word . "penen";
+                                               $word .= "penen";
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Nasals )
                                        || in_array( $wordEnding, $Sonants )
                                ) {
-                                               $word = $word . "menen";
+                                               $word .= "menen";
                                } elseif ( in_array( $wordEnding, $Sibilants ) ) {
-                                               $word = $word . "benen";
+                                               $word .= "benen";
                                }
                                break;
                        default: # dc0 #nominative #ataw
@@ -531,9 +527,7 @@ class LanguageKk_cyrl extends Language {
                $secondPerson = [ "ز" ]; // 1st plural, 2nd formal
                $thirdPerson = [ "ى", "ٸ" ]; // 3rd
 
-               $lastLetter = $this->lastLetter( $word, $allVowels );
-               $wordEnding = $lastLetter[0];
-               $wordLastVowel = $lastLetter[1];
+               list( $wordEnding, $wordLastVowel ) = $this->lastLetter( $word, $allVowels );
 
                // Now convert the word
                switch ( $case ) {
@@ -541,21 +535,21 @@ class LanguageKk_cyrl extends Language {
                        case "genitive": # ilik
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "تٸڭ";
+                                               $word .= "تٸڭ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "تىڭ";
+                                               $word .= "تىڭ";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Nasals ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "نٸڭ";
+                                               $word .= "نٸڭ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "نىڭ";
+                                               $word .= "نىڭ";
                                        }
                                } elseif ( in_array( $wordEnding, $Sonants ) || in_array( $wordEnding, $Sibilants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "دٸڭ";
+                                               $word .= "دٸڭ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "دىڭ";
+                                               $word .= "دىڭ";
                                        }
                                }
                                break;
@@ -563,15 +557,15 @@ class LanguageKk_cyrl extends Language {
                        case "dative": # barıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "كە";
+                                               $word .= "كە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "قا";
+                                               $word .= "قا";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "گە";
+                                               $word .= "گە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "عا";
+                                               $word .= "عا";
                                        }
                                }
                                break;
@@ -579,21 +573,21 @@ class LanguageKk_cyrl extends Language {
                        case "possessive dative": # täweldık + barıs
                                if ( in_array( $wordEnding, $firstPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ە";
+                                               $word .= "ە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ا";
+                                               $word .= "ا";
                                        }
                                } elseif ( in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "گە";
+                                               $word .= "گە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "عا";
+                                               $word .= "عا";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "نە";
+                                               $word .= "نە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "نا";
+                                               $word .= "نا";
                                        }
                                }
                                break;
@@ -601,21 +595,21 @@ class LanguageKk_cyrl extends Language {
                        case "accusative": # tabıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "تٸ";
+                                               $word .= "تٸ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "تى";
+                                               $word .= "تى";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "نٸ";
+                                               $word .= "نٸ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "نى";
+                                               $word .= "نى";
                                        }
                                } elseif ( in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "دٸ";
+                                               $word .= "دٸ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "دى";
+                                               $word .= "دى";
                                        }
                                }
                                break;
@@ -623,27 +617,27 @@ class LanguageKk_cyrl extends Language {
                        case "possessive accusative": # täweldık + tabıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "دٸ";
+                                               $word .= "دٸ";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "دى";
+                                               $word .= "دى";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
-                                               $word = $word . "ن";
+                                               $word .= "ن";
                                }
                                break;
                        case "dc4":
                        case "locative": # jatıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "تە";
+                                               $word .= "تە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "تا";
+                                               $word .= "تا";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels ) || in_array( $wordEnding, $Sonorants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "دە";
+                                               $word .= "دە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "دا";
+                                               $word .= "دا";
                                        }
                                }
                                break;
@@ -651,15 +645,15 @@ class LanguageKk_cyrl extends Language {
                        case "possessive locative": # täweldık + jatıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "دە";
+                                               $word .= "دە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "دا";
+                                               $word .= "دا";
                                        }
                                } elseif ( in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "ندە";
+                                               $word .= "ندە";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "ندا";
+                                               $word .= "ندا";
                                        }
                                }
                                break;
@@ -667,24 +661,24 @@ class LanguageKk_cyrl extends Language {
                        case "ablative": # şığıs
                                if ( in_array( $wordEnding, $Consonants ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "تەن";
+                                               $word .= "تەن";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "تان";
+                                               $word .= "تان";
                                        }
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Sonants )
                                        || in_array( $wordEnding, $Sibilants )
                                ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "دەن";
+                                               $word .= "دەن";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "دان";
+                                               $word .= "دان";
                                        }
                                } elseif ( in_array( $wordEnding, $Nasals ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "نەن";
+                                               $word .= "نەن";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "نان";
+                                               $word .= "نان";
                                        }
                                }
                                break;
@@ -692,42 +686,42 @@ class LanguageKk_cyrl extends Language {
                        case "possessive ablative": # täweldık + şığıs
                                if ( in_array( $wordEnding, $firstPerson ) || in_array( $wordEnding, $thirdPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "نەن";
+                                               $word .= "نەن";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "نان";
+                                               $word .= "نان";
                                        }
                                } elseif ( in_array( $wordEnding, $secondPerson ) ) {
                                        if ( in_array( $wordLastVowel, $frontVowels ) ) {
-                                               $word = $word . "دەن";
+                                               $word .= "دەن";
                                        } elseif ( in_array( $wordLastVowel, $backVowels ) ) {
-                                               $word = $word . "دان";
+                                               $word .= "دان";
                                        }
                                }
                                break;
                        case "dc6":
                        case "comitative": # kömektes
                                if ( in_array( $wordEnding, $Consonants ) ) {
-                                               $word = $word . "پەن";
+                                               $word .= "پەن";
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Nasals )
                                        || in_array( $wordEnding, $Sonants )
                                ) {
-                                               $word = $word . "مەن";
+                                               $word .= "مەن";
                                } elseif ( in_array( $wordEnding, $Sibilants ) ) {
-                                               $word = $word . "بەن";
+                                               $word .= "بەن";
                                }
                                break;
                        case "dc61":
                        case "possessive comitative": # täweldık + kömektes
                                if ( in_array( $wordEnding, $Consonants ) ) {
-                                               $word = $word . "پەنەن";
+                                               $word .= "پەنەن";
                                } elseif ( in_array( $wordEnding, $allVowels )
                                        || in_array( $wordEnding, $Nasals )
                                        || in_array( $wordEnding, $Sonants )
                                ) {
-                                               $word = $word . "مەنەن";
+                                               $word .= "مەنەن";
                                } elseif ( in_array( $wordEnding, $Sibilants ) ) {
-                                               $word = $word . "بەنەن";
+                                               $word .= "بەنەن";
                                }
                                break;
                        default: # dc0 #nominative #ataw
@@ -737,7 +731,7 @@ class LanguageKk_cyrl extends Language {
 
        /**
         * @param string $word
-        * @param array $allVowels
+        * @param string[] $allVowels
         * @return array
         */
        function lastLetter( $word, $allVowels ) {
index e97e792..946b3ed 100644 (file)
        "sat": "Sab",
        "january": "Buleuen Sa",
        "february": "Buleuen Duwa",
-       "march": "Buleuën Lhèë",
-       "april": "Buleuën Peuët",
-       "may_long": "Buleuën Limöng",
-       "june": "Buleuën Nam",
-       "july": "Buleuën Tujôh",
-       "august": "Buleuën Lapan",
-       "september": "Buleuën Sikureuëng",
-       "october": "Buleuën Siplôh",
-       "november": "Buleuën Siblaih",
+       "march": "Buleuen Lhèe",
+       "april": "Buleuen Peuet",
+       "may_long": "Buleuen Limöng",
+       "june": "Buleuen Nam",
+       "july": "Buleuen Tujôh",
+       "august": "Buleuen Lapan",
+       "september": "Buleuen Sikureueng",
+       "october": "Buleuen Siplôh",
+       "november": "Buleuen Siblaih",
        "december": "Buleuen Duwa Blaih",
-       "january-gen": "Buleuën Sa",
-       "february-gen": "Buleuën Duwa",
-       "march-gen": "Buleuën Lhèë",
-       "april-gen": "Buleuën Peuët",
-       "may-gen": "Buleuën Limöng",
-       "june-gen": "Buleuën Nam",
-       "july-gen": "Buleuën Tujôh",
-       "august-gen": "Buleuën Lapan",
-       "september-gen": "Buleuën Sikureuëng",
-       "october-gen": "Buleuën Siplôh",
-       "november-gen": "Buleuën Siblaih",
-       "december-gen": "Buleuën Duwa Blaih",
+       "january-gen": "Buleuen Sa",
+       "february-gen": "Buleuen Duwa",
+       "march-gen": "Buleuen Lhèe",
+       "april-gen": "Buleuen Peuet",
+       "may-gen": "Buleuen Limöng",
+       "june-gen": "Buleuen Nam",
+       "july-gen": "Buleuen Tujôh",
+       "august-gen": "Buleuen Lapan",
+       "september-gen": "Buleuen Sikureueng",
+       "october-gen": "Buleuen Siplôh",
+       "november-gen": "Buleuen Siblaih",
+       "december-gen": "Buleuen Duwa Blaih",
        "jan": "Sa",
        "feb": "Duwa",
-       "mar": "Lhèë",
-       "apr": "Peuët",
+       "mar": "Lhèe",
+       "apr": "Peuet",
        "may": "Limöng",
        "jun": "Nam",
        "jul": "Tujôh",
        "oct": "Siplôh",
        "nov": "Siblaih",
        "dec": "Duwa Blaih",
-       "january-date": "$1 Buleuën Sa",
-       "february-date": "$1 Buleuën Duwa",
-       "march-date": "$1 Buleuën Lhèë",
-       "april-date": "$1 Buleuën Peuët",
-       "may-date": "$1 Buleuën Limong",
-       "june-date": "$1 Buleuën Nam",
-       "july-date": "$1 Buleuën Tujôh",
-       "august-date": "$1 Buleuën Lapan",
-       "september-date": "$1 Buleuën Sikureuëng",
-       "october-date": "$1 Buleuën Siplôh",
-       "november-date": "$1 Buleuën Siblaih",
-       "december-date": "$1 Buleuën Duwa Blaih",
+       "january-date": "$1 Buleuen Sa",
+       "february-date": "$1 Buleuen Duwa",
+       "march-date": "$1 Buleuen Lhèe",
+       "april-date": "$1 Buleuen Peuet",
+       "may-date": "$1 Buleuen Limöng",
+       "june-date": "$1 Buleuen Nam",
+       "july-date": "$1 Buleuen Tujôh",
+       "august-date": "$1 Buleuen Lapan",
+       "september-date": "$1 Buleuen Sikureueng",
+       "october-date": "$1 Buleuen Siplôh",
+       "november-date": "$1 Buleuen Siblaih",
+       "december-date": "$1 Buleuen Duwa Blaih",
        "pagecategories": "{{PLURAL:$1|Kawan}}",
        "category_header": "Seunurat lam kawan \"$1\"",
        "subcategories": "Aneuk kawan",
        "edithelp": "Bantu peusaneut",
        "helppage-top-gethelp": "Beunantu",
        "mainpage": "Ôn Keue",
-       "mainpage-description": "Ôn Keuë",
+       "mainpage-description": "Ôn Keue",
        "policy-url": "Project:Neuatô",
        "portal": "Meusapat",
        "portal-url": "Project:Meusapat",
        "listfiles-latestversion-no": "Kön",
        "file-anchor-link": "Beureukaih",
        "filehist": "Riwayat beureukaih",
-       "filehist-help": "Neuteugon bak uroë buleuën/watèë keu neu'eu beureukaih nyoë ‘oh watèë nyan.",
+       "filehist-help": "Neuteugon bak uroe buleuen/watèe keu neu-eu beureukaih nyoe ‘oh watèe nyan.",
        "filehist-deleteall": "sampôh ban dum",
        "filehist-deleteone": "sampôh",
        "filehist-revert": "peuriwang",
        "filehist-current": "jinoë hat",
-       "filehist-datetime": "Uroë buleuën/Watèë",
+       "filehist-datetime": "Uroe buleuen/Watèe",
        "filehist-thumb": "Beuntuk ubeut",
        "filehist-thumbtext": "Beuntuk ubeut keu seunalén tiëp $1",
        "filehist-nothumb": "Hana beuntuk ubeut",
        "protect-cascade": "Peulindông ban mandum ôn nyang rôh lam ôn nyoë (lindông meuturôt).",
        "protect-cantedit": "Droëneuh h‘an jeuët neu’ubah tingkat lindông ôn nyoë kareuna Droëneuh hana hak keu neupeulaku nyan.",
        "protect-otherreason": "Alasan laén/teunamah:",
-       "protect-expiry-options": "1 jeum:1 hour,1 uroë:1 day,1 minggu:1 week,2 minggu:2 weeks,1 buleuën:1 month,3 buleuën:3 months,6 buleuën:6 months,1 thôn:1 year,sabé:infinite",
+       "protect-expiry-options": "1 jeum:1 hour,1 uroe:1 day,1 minggu:1 week,2 minggu:2 weeks,1 buleuen:1 month,3 buleuen:3 months,6 buleuen:6 months,1 thôn:1 year,sabé:infinite",
        "restriction-type": "Lindông:",
        "restriction-level": "Tingkat:",
        "restriction-edit": "Peusaneut",
        "anoncontribs": "Beuneuri",
        "contribsub2": "Keu {{GENDER:$3|$1}} ($2)",
        "uctop": "jinoë",
-       "month": "Mula phôn buleuën (ngön sigohlomjih)",
+       "month": "Mula phôn buleuen (ngön sigohlomjih)",
        "year": "Mula phôn thôn (ngön sigohlomjih)",
        "sp-contributions-newbies": "Peuleumah beuneuri atra ureuëng ban dapeuta mantöng",
        "sp-contributions-newbies-sub": "Keu ureuëng nguy barô",
        "whatlinkshere-filters": "Saréng",
        "blockip": "Theun ureuëng ngui",
        "ipbreason": "Alasan:",
-       "ipboptions": "2 jeum:2 hours,1 uroë:1 day,3 uroë:3 days,1 minggu:1 week,2 minggu:2 weeks,1 buleuën:1 month,3 buleuën:3 months,6 buleuën:6 months,1 thôn:1 year,sabé:infinite",
+       "ipboptions": "2 jeum:2 hours,1 uroe:1 day,3 uroe:3 days,1 minggu:1 week,2 minggu:2 weeks,1 buleuen:1 month,3 buleuen:3 months,6 buleuen:6 months,1 thôn:1 year,sabé:infinite",
        "ipbhidename": "Peusom nan ureueng ngui nibak hasé peusaneut ngön dapeuta",
        "ipblocklist": "Ureuëng ngui teutheun",
        "blocklist-reason": "Alasan",
        "tooltip-search": "Mita lam {{SITENAME}}",
        "tooltip-search-go": "Mita saboh ôn ngon nan nyang paih lagèe nyoe meunyo na",
        "tooltip-search-fulltext": "Mita ôn nyang na asoe lagèe nyoe",
-       "tooltip-p-logo": "Saweuë ôn keuë",
-       "tooltip-n-mainpage": "Saweuë ôn keuë",
-       "tooltip-n-mainpage-description": "Saweuë ôn keuë",
+       "tooltip-p-logo": "Saweue ôn keue",
+       "tooltip-n-mainpage": "Saweue ôn keue",
+       "tooltip-n-mainpage-description": "Saweue ôn keue",
        "tooltip-n-portal": "Bhaih buët, peuë nyang jeuët neupubuët, pat keu mita sipeuë hai",
        "tooltip-n-currentevents": "Mita haba barô",
        "tooltip-n-recentchanges": "Dapeuta neuubah barô lam wiki.",
index 7d2a59b..0c06ebf 100644 (file)
        "createacct-yourpasswordagain-ph": "دخّل كلمة السر مرة أخرى",
        "yourdomainname": "نطاقك:",
        "externaldberror": "هناك إما خطأ في دخول قاعدة البيانات الخارجية أو أنه غير مسموح لك بتحديث حسابك الخارجي.",
-       "login": "ادخل",
-       "logout": "اخرج",
+       "login": "دخÙ\88ل",
+       "logout": "خرÙ\88ج",
        "userlogout": "خروج",
        "notloggedin": "غير مسجل الدخول",
        "createaccount": "أنشئ حسابا",
index e725124..fb82b2e 100644 (file)
        "revertpage": "mapatiku tuway [[Special:Contributions/$2|$2]] ([[User talk:$2|sasukamu]]) a mikawaway-kalumyiti sazikuzay nay [[User:$1|$1]] amisumad nu ayaway a baziyong",
        "revertpage-nouser": "mapatiku tu midimut misaungayay ku mikawaway-kalumyiti malasazikuz {{GENDER:$1|[[User:$1|$1]]}} masumad nu ayaway a baziyong",
        "rollback-success": "mapatiku tuway {{GENDER:$3|$1}} mapasanga’ay a mikawaway-kalumyiti;\nmisumad tatiku nay {{GENDER:$4|$2}} masumad nu ayaway sazikuzay a baziyong.",
-       "rollback-success-notify": "mapatiku $1 nikawawan mikawaway-kalumyiti;\nmisumad patiku ta $2 masumad nu ayaway a sazikuz cacay baziyong. [$3 paazih ku masumaday]",
        "sessionfailure-title": "kasasiket mungangaw",
        "sessionfailure": "kisu patalabu kasasiketan mahiza simunday,\nsaka pataayaw-milangat kasasiketan maalaw atu madebung, tina saungay mapalawpes tuway.\npitatiku ayaway a kasabelih, miliyaw maasip kya kasabelih pitaneng aca.",
        "changecontentmodel": "misumad lacul tatudungen misanga’",
        "authmanager-create-no-primary": "nipabeliay a pincen caay pisaungay i canghaw patizeng.",
        "authmanager-link-no-primary": "nipabeliay a pincen caay pisaungay i canghaw masasiket.",
        "authmanager-link-not-in-progress": "canghaw patizeng caay henay miteka saca kasasiketan kalunasulitan mahedaw tuway, piliyaw miteka aca.",
-       "authmanager-authplugin-setpass-failed-title": "misumad mima mungangaw",
-       "authmanager-authplugin-setpass-failed-message": "zencen cait ihekal makai misaimed tu mima.",
-       "authmanager-authplugin-create-fail": "zencen cait ihekal makai patizeng tu canghaw.",
-       "authmanager-authplugin-setpass-denied": "zencen cait ihekal caay mahasa misumad tu mima.",
-       "authmanager-authplugin-setpass-bad-domain": "la’cusay a calay-subal(wangyi).",
        "authmanager-autocreate-noperm": "caay mahasa lunuk canghaw patizeng.",
        "authmanager-autocreate-exception": "lunuk canghaw patizeng zayhan mungangaw sisa nanunuz paedeb.",
        "authmanager-userdoesnotexist": "misaungayay canghaw \"$1\" caay henay pangangan.",
index 6abb565..e26fee0 100644 (file)
        "nstab-template": "Plantilla",
        "nstab-help": "Aduya",
        "nstab-category": "Categoría",
+       "mainpage-nstab": "Pachina principal",
        "nosuchaction": "No se reconoixe ista acción",
        "nosuchactiontext": "L'acción especificata por a URL no ye conforme.\nTalment s'haiga entivocau en escribir a URL, u haiga seguiu un vinclo incorrecto.\nTamién podría marcar un bug en o software emplegato por {{SITENAME}}.",
        "nosuchspecialpage": "No existe ixa pachina especial",
index 7507ac6..e1bb178 100644 (file)
@@ -76,7 +76,8 @@
                        "Azouz.anis",
                        "Elbasyouny",
                        "Omar Ghrida",
-                       "AHmed Khaled"
+                       "AHmed Khaled",
+                       "البراء صالح"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
        "tog-norollbackdiff": "لا تظهر الفروق بعد إجراء استرجاع",
        "tog-useeditwarning": "حذّرني عندما أغادر تحرير صفحة فيها تغييرات لم أحفظها",
        "tog-prefershttps": "استخدم دائما اتصالا آمنا عند تسجيل الدخول",
+       "tog-showrollbackconfirmation": "إظهار رسالة تأكيد عند النقر على رابط الاسترجاع",
        "underline-always": "دائما",
        "underline-never": "أبدا",
        "underline-default": "وفق المظهر أو المتصفح",
        "view": "مطالعة",
        "view-foreign": "اعرض في $1",
        "edit": "عدل",
-       "edit-local": "تعدÙ\8aل الوصف المحلي",
+       "edit-local": "عدل الوصف المحلي",
        "create": "أنشئ",
        "create-local": "أضف وصفا محليا",
        "delete": "حذف",
        "login-security": "توكيد هويتك",
        "nav-login-createaccount": "دخول / إنشاء حساب",
        "logout": "تسجيل الخروج",
-       "userlogout": "اخرج",
+       "userlogout": "خرÙ\88ج",
        "notloggedin": "غير مسجل للدخول",
        "userlogin-noaccount": "ليس لديك حساب؟",
        "userlogin-joinproject": "انضم إلى {{SITENAME}}",
        "badretype": "كلمات السر التي أدخلتها لا تتطابق.",
        "usernameinprogress": "إن عملية إنشاء حساب لاسم المستخدم هذا جارية بالفعل. برجاء الانتظار.",
        "userexists": "اسم المستخدم الذي تم إدخاله مستعمل بالفعل.\nالرجاء اختيار اسم مختلف.",
+       "createacct-normalization": "سيتم تعديل اسم المستخدم الخاص بك إلى \"$2\" بسبب قيود فنية.",
        "loginerror": "خطأ في الدخول",
        "createacct-error": "خطأ في إنشاء حساب",
        "createaccounterror": "تعذر إنشاء حساب المستخدم: $1",
        "page_first": "الأولى",
        "page_last": "الأخيرة",
        "histlegend": "اختيار الفرق: علم على صناديق النسخ للمقارنة واضغط قارن بين النسخ المختارة أو الزر بالأسفل.<br />\nمفتاح: (الحالي) = الفرق مع النسخة الحالية\n(السابق) = الفرق مع النسخة السابقة، ط = تغيير طفيف",
-       "history-fieldset-title": "اÙ\84بحث Ø¹Ù\86 المراجعات",
+       "history-fieldset-title": "تصÙ\81Ù\8aØ© المراجعات",
        "history-show-deleted": "المحذوفة فقط",
        "histfirst": "الأقدم",
        "histlast": "الأحدث",
        "historysize": "({{PLURAL:$1|1 بايت|$1 بايت}})",
-       "historyempty": "(فارغة)",
+       "historyempty": "فارغة",
        "history-feed-title": "تاريخ المراجعة",
        "history-feed-description": "تاريخ التعديل لهذه الصفحة في الويكي",
        "history-feed-item-nocomment": "$1 في $2",
        "history-feed-empty": "الصفحة المطلوبة غير موجودة.\nمن المحتمل أن تكون هذه الصفحة قد حذفت من الويكي، أو نقلت.\nحاول [[Special:Search|البحث في الويكي]] عن صفحات جديدة ذات صلة.",
        "history-edit-tags": "عدل وسوم المراجعات المختارة",
-       "rev-deleted-comment": "(أزيل ملخص التعديل)",
+       "rev-deleted-comment": "(ملخص التعديل تمت إزالته)",
        "rev-deleted-user": "(اسم المستخدم تمت إزالته)",
-       "rev-deleted-event": "(محيت تفاصيل السجل)",
+       "rev-deleted-event": "(تفاصيل السجل تمت إزالتها)",
        "rev-deleted-user-contribs": "[اسم المستخدم أو عنوان الأيبي تمت إزالته - التعديل مخفي من المساهمات]",
        "rev-deleted-text-permission": "'''حُذِفت''' مراجعة هذه الصفحة.\nيمكنك العثور على التفاصيل في [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سجل الحذف].",
        "rev-suppressed-text-permission": "هذه النسخة قد <strong>أخفيت</strong> ([{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} تفاصيل].)",
        "revdelete-legend": "وضع ضوابط رؤية",
        "revdelete-hide-text": "نص المراجعة",
        "revdelete-hide-image": "أخف محتوى الملف",
-       "revdelete-hide-name": "أخف الهدف والمعيار",
+       "revdelete-hide-name": "أخف الهدف والمعاملات",
        "revdelete-hide-comment": "ملخص التعديل",
        "revdelete-hide-user": "اسم المستخدم/عنوان الآيبي",
        "revdelete-hide-restricted": "أخف البيانات عن الإداريين إضافة إلى الآخرين",
        "right-reupload-own": "الكتابة على ملف موجود تم رفعه بواسطة نفس المستخدم",
        "right-reupload-shared": "الرفع على الملفات في مستودع الملفات المشترك محليا",
        "right-upload_by_url": "رفع ملف من عنوان مسار",
-       "right-purge": "تحديث كاش الموقع لصفحة بدون تأكيد",
+       "right-purge": "تحديث كاش الموقع للصفحة",
        "right-autoconfirmed": "غير متأثر بحدود المعدل",
        "right-bot": "تعامل كعملية أوتوماتيكية",
        "right-nominornewtalk": "عدم جعل التعديلات الطفيفة لصفحات النقاش تظهر برواز الرسائل الجديدة",
        "file-anchor-link": "ملف",
        "filehist": "تاريخ الملف",
        "filehist-help": "اضغط على زمن/تاريخ لرؤية الملف كما بدا في هذا الزمن.",
-       "filehist-deleteall": "احذÙ\81 Ø§Ù\84Ù\83Ù\84",
+       "filehist-deleteall": "حذف الكل",
        "filehist-deleteone": "حذف",
        "filehist-revert": "استرجع",
        "filehist-current": "حالي",
        "sharedupload-desc-create": "هذا ملف من $1 وقد يكون مستخدما في مشاريع أخرى.\nيمكن لك أن تعدل وصف الملف في [$2  صفحته] هناك.",
        "filepage-nofile": "لا ملف موجود بهذا الاسم.",
        "filepage-nofile-link": "لا يوجد ملف بهذا الاسم، لكن يمكنك [$1 رفعه].",
-       "uploadnewversion-linktext": "ارÙ\81ع Ù\86سخة Ø¬Ø¯Ù\8aدة Ù\85Ù\86 Ù\87ذا Ø§Ù\84Ù\85Ù\84Ù\81",
+       "uploadnewversion-linktext": "رفع نسخة جديدة من هذا الملف",
        "shared-repo-from": "من $1",
        "shared-repo": "مستودع مشترك",
        "shared-repo-name-wikimediacommons": "ويكيميديا كومنز",
        "filerevert-success": "'''[[Media:$1|$1]]''' تم استرجاعها [$4 للنسخة بتاريخ $3، $2].",
        "filerevert-badversion": "لا توجد نسخة محلية سابقة لهذا الملف بالتاريخ المعطى.",
        "filerevert-identical": "الإصدار الحالي من الملف بالفعل مطابق للإصدار المحدد.",
-       "filedelete": "احذÙ\81 $1",
-       "filedelete-legend": "احذÙ\81 Ø§Ù\84Ù\85Ù\84Ù\81",
-       "filedelete-intro": "أنت على وشك حذف الملف '''[[Media:$1|$1]]''' مع كل تاريخه.",
+       "filedelete": "حذف $1",
+       "filedelete-legend": "حذف الملف",
+       "filedelete-intro": "أنت على وشك حذف الملف <strong>[[Media:$1|$1]]</strong> مع كل تاريخه.",
        "filedelete-intro-old": "أنت تحذف نسخة '''[[Media:$1|$1]]''' بتاريخ [$4 $3، $2].",
        "filedelete-comment": "السبب:",
        "filedelete-submit": "حذف",
        "delete-confirm": "حذف \"$1\"",
        "delete-legend": "حذف",
        "historywarning": "'''تنبيه:''' الصفحة التي تريد حذفها بها {{PLURAL:$1|نسخة|نسخة واحدة|نسختان|$1 نسخ|$1 نسخة}}. انظر",
-       "historyaction-submit": "أظÙ\87ر",
+       "historyaction-submit": "عرض Ø§Ù\84Ù\85راجعات",
        "confirmdeletetext": "أنت على وشك أن تقوم بحذف صفحة بالإضافة إلى كل تاريخها.\nمن فضلك التأكد من عزمك على الحذف، وبأنك مدرك للعواقب، وبأنك تقوم بهذا بالتوافق مع [[{{MediaWiki:Policy-url}}|السياسة]].",
        "actioncomplete": "انتهاء العملية",
        "actionfailed": "الفعل فشل",
        "deleting-backlinks-warning": "<strong>تحذير:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|صفحات أخرى]] تصل إلى أو تضمن الصفحة التي أنت على وشك حذفها.",
        "deleting-subpages-warning": "<strong>تحذير:</strong> الصفحة التي على وشك أن تحذفها لديها [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|صفحة فرعية|$1 صفحات فرعية|51=أكثر من 50 صفحة فرعية}}]].",
        "rollback": "التراجع عن التعديلات",
+       "rollback-confirmation-confirm": "يُرجى التأكيد:",
+       "rollback-confirmation-yes": "استرجاع",
+       "rollback-confirmation-no": "إلغاء",
        "rollbacklink": "استرجع",
        "rollbacklinkcount": "استرجع {{PLURAL:$1|لا تعديلات|تعديلا واحدا|تعديلين|$1 تعديلات|$1 تعديلاً|تعديل}}",
        "rollbacklinkcount-morethan": "استرجاع أكثر من {{PLURAL:$1|تعديل|تعديل|تعديلين|$1 تعديلات|$1 تعديلاً|$1 تعديل}}",
        "revertpage": "استرجع تعديلات [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]]) حتى آخر مراجعة ل[[User:$1|$1]]",
        "revertpage-nouser": "استرجع تعديلات مستخدم مخفي حتى آخر مراجعة ل{{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "تم استرجاع تعديلات {{GENDER:$3|$1}}، حتى آخر نسخة بواسطة {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "تم استرجاع التعديلات بواسطة $1;\nتم التغيير إلى آخر مراجعة بواسطة $2. [$3 عرض التغييرات]",
        "sessionfailure-title": "فشل في الجلسة",
        "sessionfailure": "يبدو أنه هناك مشكلة في جلسة الدخول الخاصة بك؛\nلذلك فقد ألغيت هذه العملية كإجراء احترازي ضد الاختراق.\nمن فضلك أعد إرسال الاستمارة مرة أخرى.",
        "changecontentmodel": "تغيير نموذج المحتوى لصفحة",
        "mycontris": "مساهمات",
        "anoncontribs": "مساهمات",
        "contribsub2": "ل{{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "لـ{{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "حساب المستخدم \"$1\" غير مسجل.",
        "negative-namespace-not-supported": "النطاقات ذات القيم السالبة غير مدعومة.",
        "nocontribs": "لم يتم العثور على تغييرات تطابق هذه المحددات.",
        "whatlinkshere-prev": "{{PLURAL:$1|السابق|ال$1 السابقة}}",
        "whatlinkshere-next": "{{PLURAL:$1|التالية|ال$1 التالية}}",
        "whatlinkshere-links": "وصلات",
-       "whatlinkshere-hideredirs": "$1 تحويلات",
-       "whatlinkshere-hidetrans": "$1 تضمينات",
-       "whatlinkshere-hidelinks": "$1 وصلات",
+       "whatlinkshere-hideredirs": "$1 Ø§Ù\84تحÙ\88Ù\8aÙ\84ات",
+       "whatlinkshere-hidetrans": "$1 Ø§Ù\84تضÙ\85Ù\8aÙ\86ات",
+       "whatlinkshere-hidelinks": "$1 الوصلات",
        "whatlinkshere-hideimages": "$1 وصلات الملفات",
        "whatlinkshere-filters": "مرشحات",
        "whatlinkshere-submit": "اذهب",
        "ipb-disableusertalk": "تعديل صفحة نقاشه",
        "ipb-change-block": "أعد منع المستخدم بهذه الإعدادات",
        "ipb-confirm": "أكّد المنع",
-       "ipb-sitewide": "الموقع بأكمله",
+       "ipb-sitewide": "كامل",
        "ipb-partial": "جزئي",
+       "ipb-sitewide-help": "كل صفحة على الويكي وجميع إجراءات المساهمة الأخرى.",
+       "ipb-partial-help": "صفحات أو نطاقات محددة.",
        "ipb-pages-label": "الصفحات",
-       "ipb-namespaces-label": "النطاقات",
+       "ipb-namespaces-label": "نطاقات",
        "badipaddress": "عنوان أيبي غير صحيح",
        "blockipsuccesssub": "تم المنع بنجاح",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] تم {{GENDER:$1|منعه|منعها}}.<br />\nطالع [[Special:BlockList|قائمة منع الآيبي]] لمراجعة حالات المنع.",
        "databasenotlocked": "قاعدة البيانات ليست مغلقة.",
        "lockedbyandtime": "(من $1 على $2 في $3 )",
        "move-page": "نقل $1",
-       "move-page-legend": "نقل صفحة",
+       "move-page-legend": "Ù\86Ù\82Ù\84 Ø§Ù\84صÙ\81حة",
        "movepagetext": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك أن تترك التحويلات التي تشير إلى العنوان الأصلي كما هي لتقوم البوتات بتحديثها تلقائياً.\nإذا اخترت أن تقوم بالتحديث يدوياً، فتأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]] وقم بتصحيحها.\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه <strong>لن يتم</strong> نقل الصفحة إذا وجدت صفحة في العنوان الجديد، إلا إذا كانت صفحة تحويل، ولا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، ولا يمكنك نسخ هذه الصفحة فوق صفحة موجودة.\n\n<strong>ملاحظة:</strong>\n\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
        "movepagetext-noredirectfixer": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك تحديث التحويلات التي تشير إلى العنوان الأصلي تلقائياً.\nلو اخترت ألا تفعل، تأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]].\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه <strong>لن يتم</strong>  نقل الصفحة إذا كان هناك صفحة بنفس العنوان الجديد، إلا إذا كانت فارغة، أو تحويلة لا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، وأنك لا يمكنك الكتابة على صفحة موجودة.\n\n<strong>ملاحظة</strong> \n\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
        "movepagetalktext": "لو علمت على هذا الصندوق، فصفحة النقاش المرفقة يتم نقلها أوتوماتيكيا للعنوان الجديد، إلا لو كانت صفحة نقاش غير فارغة هناك بالفعل.\n\nفي هذه الحالة، فسيتعين عليك نقل أو دمج الصفحة يدويا لو رغبت في ذلك.",
        "cant-move-to-category-page": "أنت لا تمتلك صلاحية نقل صفحة إلى صفحة تصنيف.",
        "cant-move-subpages": "أنت لا تمتلك الصلاحية لنقل الصفحات الفرعية.",
        "namespace-nosubpages": "النطاق \"$1\" لا يسمح بالصفحات الفرعية.",
-       "newtitle": "عÙ\86Ù\88اÙ\86 جديد:",
-       "move-watch": "راقب هذه الصفحة",
+       "newtitle": "اÙ\84عÙ\86Ù\88اÙ\86 Ø§Ù\84جديد:",
+       "move-watch": "راقب الصفحتين المنقول منها والمنقول إليها",
        "movepagebtn": "انقل الصفحة",
        "pagemovedsub": "تم النقل بنجاح",
        "cannotmove": "تعذر نقل الصفحة; {{PLURAL:$1|للسبب التالي|للأسباب التالية}}:",
        "move-subpages": "انقل الصفحات الفرعية (حتى $1)",
        "move-talk-subpages": "انقل الصفحات الفرعية لصفحة النقاش (حتى $1)",
        "movepage-page-exists": "الصفحة $1 موجودة بالفعل ولا يمكن الكتابة عليها تلقائياً.",
-       "movepage-page-moved": "نقلت صفحة $1 إلى $2.",
+       "movepage-page-moved": "نقلت صفحة $1 إلى $2 بنجاح.",
        "movepage-page-unmoved": "لم يمكن نقل صفحة $1 إلى $2.",
-       "movepage-max-pages": "تم نقل الحد الأقصى وهو {{PLURAL:$1||صفحة واحدة|صفحتان|$1 صفحات|$1 صفحة}} ولن يتم نقل المزيد تلقائياً.",
+       "movepage-max-pages": "تم نقل الحد الأقصى وهو {{PLURAL:$1|صفحة واحدة|صفحتان|$1 صفحات|$1 صفحة}} ولن يتم نقل المزيد تلقائيا.",
        "movelogpage": "سجل النقل",
        "movelogpagetext": "بالأسفل قائمة بالصفحات التي تم نقلها.",
        "movesubpage": "{{PLURAL:$1||الصفحة الفرعية|الصفحتان الفرعيتان|الصفحات الفرعية}}",
        "confirm-unwatch-top": "إزالة هذه الصفحة من قائمة مراقبتك؟",
        "confirm-rollback-button": "موافق",
        "confirm-rollback-top": "استرجاع التعديلات لهذه الصفحة؟",
+       "confirm-rollback-bottom": "هذا الإجراء سيسترجع فورا التغييرات المحددة في هذه الصفحة.",
        "confirm-mcrrestore-title": "استرجاع مراجعة",
        "confirm-mcrundo-title": "الرجوع عن تغيير",
        "mcrundofailed": "الرجوع فشل",
        "logentry-rights-autopromote": "تمَ تلقائياً ترقية {{GENDER:$2|المستخدم|المستخدمة}} $1 من  $4 إلى $5",
        "logentry-upload-upload": " {{GENDER:$2|رفع|رفعت}} $1 $3",
        "logentry-upload-overwrite": "{{GENDER:$2|رفع|رفعت}} $1 نسخة جديدة من  $3",
-       "logentry-upload-revert": "{{GENDER:$2|رفع|رفعت}} $1 $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|استرجع|استرجعت}} $3 لنسخة قديمة",
        "log-name-managetags": "سجل إدارة الوسوم",
        "log-description-managetags": "هذه الصفحة تعرض مهام الإدارة المرتعلقة ب[[Special:Tags|الوسوم]]. السجل يحتوي فقط على الافعال التي تم عملها يدويا بواسطة إداري؛ الوسوم ربما يتم إنشاؤها او حذفها بواسطة برنامج الويكي بدون تسجيل مدخلة في هذا السجل.",
        "logentry-managetags-create": "$1 {{GENDER:$2|أنشأ|أنشأت}} الوسم \"$4\"",
        "log-action-filter-suppress-reblock": "إخفاء المستخدم بواسطة إعادة المنع",
        "log-action-filter-upload-upload": "رفع جديد",
        "log-action-filter-upload-overwrite": "إعادة الرفع",
+       "log-action-filter-upload-revert": "استرجاع",
        "authmanager-authn-not-in-progress": "عملية التحقق ليست جارية أو بينات الجلسة تم فقدها. من فضلك ابدأ مرة ثانية من البداية.",
        "authmanager-authn-no-primary": "الاعتماد الموفر لم يمكن التحقق منه.",
        "authmanager-authn-no-local-user": "الاعتماد الموفر غير مرتبط بأي مستخدم على هذه الويكي.",
        "authmanager-create-no-primary": "الاعتمادات الموفرة لم يمكن استخدامها لإنشاء الحساب.",
        "authmanager-link-no-primary": "الاعتماد الموفر لم يمكن استخدامه لوصل الحسابات.",
        "authmanager-link-not-in-progress": "وصل الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية من البداية.",
-       "authmanager-authplugin-setpass-failed-title": "تغيير كلمة السر فشل",
-       "authmanager-authplugin-setpass-failed-message": "إضافة التحقق رفضت تغيير كلمة السر.",
-       "authmanager-authplugin-create-fail": "إضافة التحقق رفضت إنشاء الحساب.",
-       "authmanager-authplugin-setpass-denied": "إضافة التحقق لا تسمح بتغيير كلمات السر.",
-       "authmanager-authplugin-setpass-bad-domain": "نطاق غير صحيح.",
        "authmanager-autocreate-noperm": "إنشاء الحساب التلقائي غير مسموح به.",
        "authmanager-autocreate-exception": "إنشاء الحسابات التلقائي تم تعطيله مؤقتا نظرا للأخطاء السابقة.",
        "authmanager-userdoesnotexist": "حساب المستخدم \"$1\" غير مسجل.",
        "passwordpolicies-policy-maximalpasswordlength": "يجب أن يكون طول كلمة المرور أقل من $1 {{PLURAL:$1|حرف|أحرف}}",
        "passwordpolicies-policy-passwordcannotbepopular": "لا يمكن أن تكون كلمة المرور {{PLURAL:$1|كلمة المرور الشائعة|في قائمة كلمات المرور الشائعة الـ$1}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "لا يمكن أن تكون كلمة المرور في قائمة كلمات المرور الـ100.000 الأكثر استخداما.",
+       "passwordpolicies-policyflag-forcechange": "يجب أن تتغير عند تسجيل الدخول",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "اقتراح التغيير عند تسجيل الدخول",
        "easydeflate-invaliddeflate": "المحتوى المقدم لا يتم تفريغه بشكل صحيح",
        "unprotected-js": "لأسباب تتعلق بالأمان; لا يمكن تحميل جافا سكريبت من الصفحات غير المحمية; الرجاء إنشاء جافا سكريبت فقط في نطاق ميدياويكي: أو كصفحة فرعية للمستخدم"
 }
index 23536d4..dbb0288 100644 (file)
        "loginlanguagelabel": "اللوغه: $1",
        "suspicious-userlogout": "المطلب تاعك باش تسجّل خارج ما تسجّلش خاطر راه يبان مرسول من عند بحّار معطّل ولا  خزّان تاع وسّاط (proxy cache).",
        "createacct-another-realname-tip": "السميّة الحقّانيّة ماشي ملزومة.\nيلا تستعملها غادي تصلاح باش تنسّب ليك الخدمة الّي غادي تديرها.",
-       "pt-login": "ادخل",
+       "pt-login": "دخÙ\88ل",
        "pt-login-button": "دخول",
        "pt-login-continue-button": "واصل الدخول",
        "pt-createaccount": "اصنع حساب",
index 3030ab4..e2bdb21 100644 (file)
        "version-entrypoints-header-url": "ইউআৰএল",
        "version-libraries-version": "সংস্কৰণ",
        "redirect": "ফাইল, সদস্য, পৃষ্ঠা বা সংশোধন বা লগ আই ডি-ৰে পুনঃনিৰ্দেশ",
-       "redirect-summary": "এই বিশেষ পৃষ্ঠাটোৱে আপোনাক অন্য এটা ফাইললৈ (ফাইলৰ নাম), এটা পৃষ্ঠালৈ (সংশোধন আই ডি বা পৃষ্ঠা আই ডি), অথবা অন্য সদস্যৰ পৃষ্ঠালৈ (সদস্যৰ সাংখ্যিক আই ডি) পুনঃনির্দেশিত কৰিছে।\nব্যৱহাৰ: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], বা [[{{#Special:Redirect}}/user/101]]।",
+       "redirect-summary": "এই বিশেষ পৃষ্ঠাটোৱে আপোনাক অন্য এটা ফাইললৈ (ফাইলৰ নাম), এটা পৃষ্ঠালৈ (সংশোধন আই ডি বা পৃষ্ঠা আই ডি), অথবা অন্য সদস্যৰ পৃষ্ঠালৈ (সদস্যৰ সাংখ্যিক আই ডি), এটা সূচী ভুক্তিলৈ (প্ৰদত্ত সূচী ভুক্তি) পুনঃনির্দেশিত কৰিছে।\nব্যৱহাৰ: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] বা [[{{#Special:Redirect}}/logid/186]]।",
        "redirect-submit": "যাওক",
        "redirect-lookup": "চাওক:",
        "redirect-value": "মূল্য:",
index 98a0c13..77a312a 100644 (file)
        "accmailtext": "Unvióse a $2 una contraseña xenerada al debalu pal usuariu [[User talk:$1|$1]]. Pue camudase na páxina ''[[Special:ChangePassword|camudar contraseña]]'' depués d'aniciar sesión.",
        "newarticle": "(Nuevu)",
        "newarticletext": "Siguisti un enllaz a un artículu qu'inda nun esiste.\nPa crear la páxina, empecipia a escribir nel cuadru d'embaxo (mira la [$1 páxina d'ayuda] pa más información).\nSi llegasti equí por enquivocu, calca nel botón <strong>atrás</strong> del to restolador.",
-       "anontalkpagetext": "----\n''Esta ye la páxina d'alderique pa un usuariu anónimu qu'inda nun creó una cuenta o que nun la usa.''\nPola mor d'ello ha usase la direición numbérica IP pa identificalu/la.\nTala IP pue compartise por varios usuarios.\nSi yes un usuariu anónimu y notes qu'hai comentarios irrelevantes empobinaos pa ti, por favor [[Special:CreateAccount|crea una cuenta]] o [[Special:UserLogin|anicia sesiín]] pa torgar futures confusiones con otros usuarios anónimos.",
+       "anontalkpagetext": "----\n<em>Esta ye la páxina d'alderique pa un usuariu anónimu qu'inda nun creó una cuenta o que nun la usa.</em>\nPola mor d'ello ha usase la direición numbérica IP como identificación.\nTala IP pué compartise por dellos usuarios.\nSi yes un usuariu anónimu y notes qu'hai comentarios ensin relevancia dirixíos pa ti, por favor [[Special:CreateAccount|crea una cuenta]] o [[Special:UserLogin|anicia sesión]] pa torgar futures confusiones con otros usuarios anónimos.",
        "noarticletext": "Nestos momentos nun hai testu nesta páxina.\nPuedes [[Special:Search/{{PAGENAME}}|buscar esti títulu de páxina]] n'otres páxines,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar los rexistros rellacionaos],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} crear esta páxina]</span>.",
        "noarticletext-nopermission": "Nestos momentos nun hai testu nesta páxina.\nPuedes [[Special:Search/{{PAGENAME}}|buscar esti títulu de páxina]] n'otres páxines o <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar los rexistros rellacionaos]</span>, pero nun tienes permisu pa crear esta páxina.",
        "missing-revision": "La revisión #$1 de la páxina llamada \"{{FULLPAGENAME}}\" nun esiste.\n\nDe vezu la causa d'esto ye siguir un enllaz antiguu del historial a una páxina que se desanició.\nSe puen alcontrar más detalles nel [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} rexistru de desanicios].",
        "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 {{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 col aniciu de sesión;\natayóse esta aición por precaución escontra secuestru de sesiones.\nUnvia'l formulariu otra vegada.",
        "changecontentmodel": "Cambiar el modelu de conteníu d'una páxina",
        "authmanager-create-no-primary": "Les credenciales apurríes nun pueden usase pa crear cuentes.",
        "authmanager-link-no-primary": "Les credenciales apurríes nun pueden usase pa enllazar cuentes.",
        "authmanager-link-not-in-progress": "L'enllazáu de la cuenta nun ta progresando, o perdiéronse los datos de la sesión. Por favor, vuelve de nueves al principiu.",
-       "authmanager-authplugin-setpass-failed-title": "Falló'l cambiu de contraseña",
-       "authmanager-authplugin-setpass-failed-message": "El complementu d'autenticación refugó'l cambéu de contraseña.",
-       "authmanager-authplugin-create-fail": "El complementu d'autenticación refugó la creación de la cuenta.",
-       "authmanager-authplugin-setpass-denied": "El complementu de autenticación nun permite cambiar contraseñes.",
-       "authmanager-authplugin-setpass-bad-domain": "Dominiu inválidu.",
        "authmanager-autocreate-noperm": "Nun se permite la creación automática de cuentes.",
        "authmanager-autocreate-exception": "La creación automática de cuentes desactivóse temporalmente por cuenta d'errores previos.",
        "authmanager-userdoesnotexist": "La cuenta d'usuariu «$1» nun ta rexistrada.",
index 061a14e..8cfd032 100644 (file)
@@ -17,6 +17,7 @@
        "tog-hideminor": "Palsera va <i>Noeltaf betakseem</i> mezolonaf",
        "tog-hidepatrolled": "Palsera va fieyen betaks div noeltaf betakseem",
        "tog-newpageshidepatrolled": "Palsera va fieyenu bu mal vexala dem warzafu bu",
+       "tog-hidecategorization": "Palsera va bulomara",
        "tog-extendwatchlist": "Divatcera va suzdasiki ta nedira va kot rorewan betaks",
        "tog-usenewrc": "Noeltaf betakseem tulogijayan (kucilas va Javascript)",
        "tog-numberheadings": "Mivaskafa vergumveltotukara",
@@ -26,6 +27,7 @@
        "tog-watchdefault": "Loplekura va jinon betanu bu iku iyeltak gu suzdaxa",
        "tog-watchmoves": "Kosuzdara va jinon arrundan bueem",
        "tog-watchdeletion": "Kosuzdara va jinon sulan bueem",
+       "tog-watchuploads": "Loplekura va warzaf iyeltak | Kalvajara ko suzdaxa",
        "tog-minordefault": "Jinaf betakseem omavon mezolonon zo torigid",
        "tog-previewontop": "Abdinedira nediwer vamoe sutelaxo",
        "tog-previewonfirst": "Nedira va abdinedira bal taneafa betara",
@@ -49,6 +51,8 @@
        "underline-always": "Kotviele",
        "underline-never": "Meviele",
        "underline-default": "Omavafa exulexa",
+       "editfont-sansserif": "Sans-serif eltayinda",
+       "editfont-serif": "Serif eltayinda",
        "sunday": "Taneaviel",
        "monday": "Toleaviel",
        "tuesday": "Bareaviel",
        "retypenew": "Va warzaf remravlem gruyel",
        "resetpass_submit": "Va beksa bazel nume zo dogluyatal !",
        "changepassword-success": "Rinaf remravlem kiewatcon su zo betar ! Nume rinafa dogluyara tir...",
+       "botpasswords-label-appid": "Stiernaf yolt",
+       "botpasswords-label-create": "Redura",
+       "botpasswords-label-update": "Nuskera",
+       "botpasswords-label-cancel": "Measkira",
+       "botpasswords-label-delete": "Sulara",
+       "botpasswords-label-resetpassword": "Va remravlem gire bazel",
+       "botpasswords-label-grants": "Rorewan rictaks :",
+       "botpasswords-label-grants-column": "Rictan",
+       "botpasswords-bad-appid": "$1 stiernaf yolt me tir enaf.",
+       "botpasswords-created-title": "Remravlem ke stiernik tir reduyun",
+       "botpasswords-updated-title": "Remravlem ke stiernik tir nuskeyen",
+       "botpasswords-deleted-title": "Remravlem ke stiernik tir sulayan",
+       "botpasswords-not-exist": "\"$1\" webesik va stiernik yoltkiraf gu \"$2\" me dadir.",
        "resetpass_forbidden": "Kona beksa tir merobetana",
+       "resetpass_forbidden-reason": "Remravlem tir merobetana : $1",
        "resetpass-submit-loggedin": "Betara va remravlem",
        "resetpass-submit-cancel": "Kuidera",
        "resetpass-temp-password": "Ugaloraf remravlem :",
        "sig_tip": "Rinafa evlakirafa sugdara",
        "hr_tip": "Zidafa gluyaxa ( me faversel )",
        "summary": "Vildeks:",
-       "subject": "Detce/vergumvelt:",
+       "subject": "Detce :",
        "minoredit": "Betamaks.",
        "watchthis": "Va bat teliz suzdá",
        "savearticle": "Giwara",
+       "savechanges": "Giwara va betakseem",
+       "publishpage": "Busanegara",
+       "publishchanges": "Sanegara va betakseem",
+       "savearticle-start": "Bugiwara...",
+       "savechanges-start": "Giwara va betakseem...",
+       "publishpage-start": "Busanegara...",
+       "publishchanges-start": "Sanegara va betakseem...",
        "preview": "Abdinedira",
        "showpreview": "Abdinedira",
        "showdiff": "Nedira va betakseem",
        "anoneditwarning": "'''Obral !''' Rin til medogluyayan. Rinafe IP mane ko bubetarizvot zo stragatar.  Ede <strong>[$1 va int dogluyal]</strong> oke <strong>[$2 pataredul]</strong>, betaks ik aryona belunda pu rinaf webesikyolt di zo gad.",
-       "missingcommenttext": "Va sebuks vlevon bazel, vay !",
-       "summary-preview": "Abdinedira va vildeks:",
-       "subject-preview": "Abdinedira va detce ik kroj:",
+       "missingcommenttext": "Va sebuks valevon bazel, vay !!",
+       "summary-preview": "Abdinedira va vildeks :",
+       "subject-preview": "Abdinedira va detce :",
+       "previewerrortext": "Rokla sokiyir edje va betakseem fu abdinedil.",
        "blockedtitle": "Elekan favesik",
        "blockedtext": "<strong>Rinafa favesikpata oku IP mane tid elekayane.</strong>\n\nElekara skuyuna gan $1.\nLazava tir <em>$2</em>.\n\n* Elekaratoza : $8\n* Eleckaratena : $6\n* Xialana elekara : $7\n\nTa keyaksera va $1 ok konar [[{{MediaWiki:Grouppage-sysop}}|ristusik]] rotuzeral.\nVa '\"e-mail\" staksara pu bat favesik' me rofavel vaxede \"e-mail\" mane tir koe rinaf [[Special:Preferences|lodamaceem]] ise vaon faveson me zo elekayal.\nRinafe tise IP mane tir $3 isen ID elekara tir #$5.\nVa batyona pinta ko kota erura vay di bazel !!",
        "blockednoreason": "Meka bazena lazava",
        "whitelistedittext": "Ta bubetara rin gonaskil ta $1",
        "confirmedittext": "Abdi bubetara va rinafe e-mail mane gogruyel. Kan rinaf [[Special:Preferences|favesiklodamaceem]] va rinafe e-mail mane vay plekul ise tuenal !",
-       "nosuchsectiontitle": "Me man gabot",
-       "nosuchsectiontext": "Rin yawal da va metis gabot betal.",
+       "nosuchsectiontitle": "Me man gabot trasiyin",
+       "nosuchsectiontext": "Va mekruldes gabot labetal.\nBan in zo arrundayar ike zo sulayar edje va bu nediyil.",
        "loginreqtitle": "Kucilan favesikyolt",
        "loginreqlink": "dogluyara",
        "loginreqpagetext": "$1 tir adrafa ta da va aru bu rodisukel.",
        "noarticletext-nopermission": "Dure me krent koe batu bu.\nVanmia yonaru bu [[Special:Search/{{PAGENAME}}|va batu bu rotaneyal]],\noke <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|bu={{FULLPAGENAMEE}}}} va icdef logs rotaneyal]</span>, voxe va batu bu vol ronoredul.",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" favesikpata me tir vuesteyena. Vay stujel ede va batu bu roredul ike robetal.",
        "userpage-userdoesnotexist-view": "$1 favesikpata me zo koverteyer.",
+       "blocked-notice-logextract": "Bat webesik re zo elekar.\nBocaf \"log\" vuesteks valeveon zo bazer :",
        "clearyourcache": "<strong>Note:</strong> After saving, you may have to bypass your browser's cache to see the changes.\n* <strong>Firefox / Safari:</strong> Hold <em>Shift</em> while clicking <em>Reload</em>, or press either <em>Ctrl-F5</em> or <em>Ctrl-R</em> (<em>⌘-R</em> on a Mac)\n* <strong>Google Chrome:</strong> Press <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> on a Mac)\n* <strong>Internet Explorer:</strong> Hold <em>Ctrl</em> while clicking <em>Refresh</em>, or press <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Go to <em>Menu → Settings</em> (<em>Opera → Preferences</em> on a Mac) and then to <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
-       "usercssyoucanpreview": "'''Astuce :''' utilisez le bouton '''Prévisualisation''' pour tester votre nouvelle feuille css/js avant de l'enregistrer.",
-       "userjsyoucanpreview": "'''Astuce :''' utilisez le bouton '''Prévisualisation''' pour tester votre nouvelle feuille css/js avant de l'enregistrer.",
-       "usercsspreview": "'''Rappelez-vous que vous êtes en train de prévisualiser votre propre feuille css et qu'elle n'a pas encore été enregistrée !'''",
+       "usercssyoucanpreview": "<strong>Djasta :</strong> Va \"{{int:showpreview}}\" uzadjo ta weslara va rinaf warzaf CSS abdida giwal.",
+       "userjsonyoucanpreview": "<strong>Djasta :</strong> Va \"{{int:showpreview}}\" uzadjo ta weslara va rinaf warzaf JSON abdida giwal.",
+       "userjsyoucanpreview": "<strong>Djasta :</strong> Va \"{{int:showpreview}}\" uzadjo ta weslara va rinaf warzaf JavaScript abdida giwal.",
+       "usercsspreview": "<strong>Setikel da va rinaf CSS anton abdinedil.\nBan in men zo giwar !</strong>",
+       "userjsonpreview": "<strong>Setikel da va rinaf JSON tazukara anton weslal ike abdinedil.\nBana ina men zo giwar !</strong>",
        "userjspreview": "'''Rappelez-vous que vous êtes en train de visualiser ou de tester votre code javascript et qu'il n'a pas encore été enregistré !'''",
+       "sitecsspreview": "<strong>Setikel da va rinaf CSS anton abdinedil.\nBan in men zo giwar !</strong>",
+       "sitejsonpreview": "<strong>Setikel da va rinaf JSON tazukara anton abdinedil.\nBana ina men zo giwar !</strong>",
+       "sitejspreview": "<strong>Setikel da va rinaf JavaScript beks anton abdinedil.\nBana ina men zo giwar !</strong>",
        "updated": "(Nuskeyen)",
        "note": "'''Straga :'''",
        "previewnote": "'''Obral, bat krent anton tir abdinedik.'''\nRinafa betara men tid giwayan !",
        "recreate-moveddeleted-warn": "'''Obral: Rin va sulayanu bu djutolredul.'''\n\nGokrafial ede tolredura va batu bu tir vodanyaf.\nSulara \"log\" va batu bu krafiason batlize zo nedir :",
        "moveddeleted-notice": "Sulayanu bu.\n\"Log\" sulara va batu bu oku nendara oku arrundara valeveon vuesteson zo nedid.",
        "edit-conflict": "Rupera va koboda.",
+       "postedit-confirmation-created": "Bu su zo redur.",
+       "postedit-confirmation-restored": "Bu su zo dimplekur.",
+       "postedit-confirmation-saved": "Betara zo giwayar.",
+       "postedit-confirmation-published": "Betara zo sanegayar.",
        "edit-already-exists": "Buredura tir merotisa.\nBu ixam krulder.",
+       "defaultmessagetext": "Omavaf krent",
+       "slot-name-main": "Dalaf",
        "content-model-wikitext": "\"wikitext\"",
+       "content-model-text": "Krentack",
+       "content-model-javascript": "JavaScript",
+       "content-json-empty-object": "Nedaca",
+       "content-json-empty-array": "Nedafa wafra",
+       "deprecated-self-close-category": "Bu dem meenafa HTML arttcala",
+       "duplicate-args-warning": "<strong>OBRAL</strong> [[:$1]] va [[:$2]] rozar, kan loa tanoya voda mu \"$3\" dor. Ant bocafa deana voda zo saveter.",
+       "duplicate-args-category": "Bu favesu va jontolayana rustoda ta tezarozara",
        "expensive-parserfunction-category": "Bu dem slika rozara va exulerafli",
        "post-expand-template-inclusion-warning": "'''Obral !:''' Lum ke toefa teza mantarsaf.\nKonaka teza me di zo kodoplekud.",
        "post-expand-template-inclusion-category": "Bu dem lumars ke dofa teza",
        "revdelete-show-file-submit": "En",
        "logdelete-selected": "{{PLURAL:$1|Reban \"log\" bif|Yon reban \"log\" bif}} :",
        "revdelete-legend": "Skus irutareem",
-       "revdelete-hide-text": "Palsera va betaracek",
+       "revdelete-hide-text": "Krentbetara",
        "revdelete-hide-image": "Palsera va iyeltakcek",
-       "revdelete-hide-name": "Palsera va tegira is xala",
-       "revdelete-hide-comment": "Palsera va betarasebusiki",
-       "revdelete-hide-user": "Palsera va sutes favesikyolt iku IP mane",
+       "revdelete-hide-name": "Palsera va xala is doreem",
+       "revdelete-hide-comment": "Betara va vildeks",
+       "revdelete-hide-user": "Favesikyolt ik IP mane",
        "revdelete-hide-restricted": "Rewara va bat irutareem pu kot ristusik az elekara va bati walasiki",
        "revdelete-radio-same": "(videra)",
-       "revdelete-radio-set": "En",
-       "revdelete-radio-unset": "Me",
+       "revdelete-radio-set": "Palsen",
+       "revdelete-radio-unset": "Rowin",
        "revdelete-suppress": "Origsulara mal ristusik lidam artan",
        "revdelete-unsuppress": "Dimirutara va dimplekun betaks yo",
        "revdelete-log": "Lazava :",
-       "revdelete-submit": "Ko reban siatos rewar",
-       "revdelete-success": "'''Kiewaskinon plekuyuna betarafa rowinuca.'''",
+       "revdelete-submit": "Ko reban {{PLURAL:$1|siatos}} rewar",
+       "revdelete-success": "Rowin siatos nuskeyen.",
+       "revdelete-failure": "Rowin siatos me zo ronusker :\n$1",
        "logdelete-success": "'''Kiewaskinon plekuyuna bifafa rowinuca.'''",
        "revdel-restore": "Betara va rowinuca",
        "pagehist": "Buizvot",
        "diff-multi-sameuser": "( {{PLURAL:$1|Tanoya walifa betara|$1 walifa betara}} gan mil menedin favesik )",
        "diff-multi-otherusers": "({{PLURAL:$1|Tanoya walif betaks|$1 walif betaks}} gan {{PLURAL:$2|tanoy ar favesik|$2 favesik}} menedin)",
        "searchresults": "Aneyan trasikseem",
+       "search-filter-title-prefix-reset": "Aneyara va bueem",
        "searchresults-title": "Aneyan trasiks va \"$1\"",
        "titlematches": "Vadjesaceem vanmia vergumvelteem",
        "textmatches": "Vadjesaceem ko krenteem",
        "notextmatches": "Mek krentvergumvelt ruldas va erune",
        "prevn": "{{PLURAL:$1|$1}} daref",
        "nextn": "{{PLURAL:$1|$1}} diref",
+       "prev-page": "darebu",
+       "next-page": "direbu",
        "prevn-title": "Abdif $1 {{PLURAL:$1|trasiks|trasiks}}",
        "nextn-title": "Diref $1 {{PLURAL:$1|trasiks}}",
        "shown-title": "Nedira va $1 {{PLURAL:$1|trasiks}} tanbuon",
        "search-result-category-size": "{{PLURAL:$1|1 bewik|$1 bewik}} ({{PLURAL:$2|1 volveyloma|$2 volveyloma}}, {{PLURAL:$3|1 iyeltak|$3 iyeltak}})",
        "search-redirect": "( graskara male $1 )",
        "search-section": "($1 gabot)",
+       "search-category": "( $1 loma )",
        "search-file-match": "( va cek ke iyeltak aneyar )",
        "search-suggest": "Va $1 sugdalayal ?",
+       "search-rewritten": "Nedira va trasiks va $1. Va $2 ikaon aneyal !!",
        "search-interwiki-caption": "Beraf abdumimakseem",
        "search-interwiki-default": "$1 trasiks :",
        "search-interwiki-more": "(loon)",
+       "search-interwiki-more-results": "Lo trasiks",
        "search-relatedarticle": "Skedaf",
        "searchrelated": "skedaf",
        "searchall": "kot",
        "search-nonefound": "Mek trasiks vas kucilara",
        "powersearch-legend": "Aneyapara",
        "powersearch-ns": "Aneyara koe yoltxo:",
+       "powersearch-togglelabel": "Stujera :",
        "powersearch-toggleall": "Kot",
        "powersearch-togglenone": "Mek",
        "search-external": "Divafa aneyara",
        "searchdisabled": "<p>La fonction de recherche sur l'intégralité du texte a été temporairement désactivée à cause de la grande charge que cela impose au serveur. Nous espérons la rétablir prochainement lorsque nous disposerons d'un serveur plus puissant. En attendant, vous pouvez faire la recherche avec Google:</p>",
+       "search-error": "Rokla bak aneyara va $1 sokiyir",
+       "search-warning": "Walzera bak aneyara va $1 sokiyir",
        "preferences": "Lodamaceem",
        "mypreferences": "Jinaf lodamaceem",
        "prefs-edits": "Ota va betaks :",
        "prefs-skin": "Laviuca",
        "skin-preview": "Abdiwira",
        "datedefault": "Megelukon",
+       "prefs-user-pages": "Favesikbu",
        "prefs-personal": "Ilkagiveem",
        "prefs-rc": "Noeltaf betakseem",
        "prefs-watchlist": "Suzdasiki",
+       "prefs-editwatchlist": "Betara va suzdaxa",
+       "prefs-editwatchlist-label": "Betara va olk ke suzdaxa :",
+       "prefs-editwatchlist-clear": "Tunedara va suzdaxa",
        "prefs-watchlist-days": "Cugafa vielota gonedina koe suzdasiki :",
        "prefs-watchlist-days-max": "Cugon $1 {{PLURAL:$1|viel|viel}}",
-       "prefs-watchlist-edits": "Betaracugota gonedina koe mantafi suzdasiki :",
+       "prefs-watchlist-edits": "Betaksafa cugota gonedina koe suzdaxa :",
        "prefs-watchlist-edits-max": "Cugafa ota : 1000",
        "prefs-misc": "Gedrafa lodamaca yo",
        "prefs-resetpass": "Betara va remravlem",
+       "prefs-changeemail": "Betara va e-mail mane",
+       "prefs-setemail": "Bazera va e-mail mane",
+       "prefs-email": "Ukeyeem ke e-mail mane",
        "prefs-rendering": "Laviuca",
        "saveprefs": "Va lodamaceem tuená",
        "prefs-editing": "Sutelaxo",
        "timezoneregion-indian": "India welfa",
        "timezoneregion-pacific": "Pacifika welfa",
        "allowemail": "Tutegirara va e-mail staksara mal ar favesik",
-       "prefs-searchoptions": "Aneyarikatcura",
+       "prefs-searchoptions": "Aneyara",
        "prefs-namespaces": "Yoltxo",
        "default": "omava",
        "prefs-files": "Iyeltak se",
+       "prefs-custom-css": "Ilkaf CSS",
+       "prefs-custom-json": "Ilkaf JSON",
+       "prefs-custom-js": "Ilkaf JavaScript",
        "youremail": "Jinafe internetmane",
-       "username": "Favesikyolt:",
-       "prefs-memberingroups": "Bewik ke {{PLURAL:$1|lospa|lospa}}:",
+       "username": "{{GENDER:$1|Favesikyolt}} :",
+       "prefs-memberingroups": "{{GENDER:$2|Bewik}} ke {{PLURAL:$1|lospa}} :",
+       "group-membership-link-with-expiry": "$1 ( ik $2 )",
        "yourrealname": "Rinaf ageltaf yolt*",
        "yourlanguage": "Walasikiava",
        "yournick": "Sugdara tori prilara se (do <tt><nowiki>~~~</nowiki></tt>)&nbsp;",
        "prefs-help-email": "E-mail mane tir rotikatcune vox adrafe gu betara va remravlem todon gu vulkura va bat.",
        "prefs-help-email-others": "Dere ronaral da rictal da artan va rin kan e-mail is gluyasiki moe rinafu favesikbu oku prilarabu rotuzerar.\nRinafe e-mail mane me zo razdar viele ar webesik uzerar.",
        "prefs-help-email-required": "E-mail mane zo kucilar.",
+       "prefs-preview": "Abdinedira",
+       "prefs-advancedrc": "Lo ukey",
+       "prefs-advancedrendering": "Lo ukey",
+       "prefs-advancedsearchoptions": "Lo ukey",
+       "prefs-advancedwatchlist": "Lo ukey",
+       "prefs-displayrc": "Fintara va ukey",
+       "prefs-displaywatchlist": "Fintara va ukey",
+       "prefs-changesrc": "Betaks nedin",
+       "prefs-changeswatchlist": "Betaks nedin",
+       "prefs-pageswatchlist": "Wiyinu bu",
+       "prefs-diffs": "Amid-",
        "userrights": "Pofera va favesikrokeem",
-       "userrights-lookup-user": "Pofera va favesikeem",
+       "userrights-lookup-user": "Rebara va favesik",
        "userrights-user-editname": "Va favesikyolt bazel",
-       "editusergroup": "Betara va favesikeem lospa",
+       "editusergroup": "Vajara va favesikafa lospa",
        "editinguser": "Betara va rokeem ke '''[[User:$1|$1]]''' favesik ([[User talk:$1|{{int:talkpagelinktext}}]]{{int:pipe-separator}}[[Special:Contributions/$1|{{int:contribslink}}]])",
        "userrights-editusergroup": "Betara va favesiklospa",
        "saveusergroups": "Giwara va favesiklospa",
        "right-userrights": "Betara va favesikrokeem",
        "right-userrights-interwiki": "Betara va favesikrokeem koe aro 'wiki' xo",
        "right-siteadmin": "Origakelekara is dimelekara",
+       "grant-group-email": "Staksera va e-mail",
+       "grant-editprotected": "Betara va nendanu bu",
        "newuserlogpage": "Buredura \"log\"",
        "rightslog": "\"Log\" bu va favesikrokeem",
        "rightslogtext": "Tir \"log\" va betara va favesikroka.",
index a1f1974..8092ad1 100644 (file)
@@ -33,7 +33,8 @@
                        "Neriman2003",
                        "Fitoschido",
                        "Toghrul Rahimli",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "Hüseynzadə"
                ]
        },
        "tog-underline": "Keçidlərin altını xətlə:",
@@ -50,6 +51,8 @@
        "tog-watchdefault": "Redaktə etdiyim səhifələri və faylları izlədiyim səhifələrə əlavə et",
        "tog-watchmoves": "Adlarını dəyişdiyim səhifələri və faylları izlədiyim səhifələrə əlavə et",
        "tog-watchdeletion": "Sildiyim səhifələri və faylları izlədiyim səhifələrə əlavə et",
+       "tog-watchuploads": "İzləmə siyahısına yüklədiyim yeni faylları əlavə edin",
+       "tog-watchrollback": "İzləmə siyahıma rollback etdiyim səhifələri əlavə edin",
        "tog-minordefault": "Standart olaraq bütün redaktələri kiçik redaktə kimi nişanla",
        "tog-previewontop": "Sınaq göstərişini redaktə pəncərəsindən əvvəl göstər",
        "tog-previewonfirst": "İlkin redaktədə sınaq göstərişi",
@@ -67,7 +70,7 @@
        "tog-watchlisthideminor": "İzləmə səhifəmdə kiçik redaktələri gizlət",
        "tog-watchlisthideliu": "Qeydiyyatlı istifadəçilərin redaktələrini izləmə siyahısında gizlət",
        "tog-watchlistreloadautomatically": "Hər dəfə filtr dəyişəndə, izləmə siyahısını avtomatik yenilə (JavaScript tələb olunur)",
-       "tog-watchlistunwatchlinks": "İzləmə siyahısındakı səhifələrə birbaşa izləmə/izlə keçidləri əlavə et (JavaScript tələb olunur)",
+       "tog-watchlistunwatchlinks": "İzləmə siyahısındakı səhifələrə birbaşa izləmə/izlə keçidləri ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) əlavə et (JavaScript tələb olunur)",
        "tog-watchlisthideanons": "Qeydiyyatdan keçməmiş istifadəçilərin redaktələrini izləmə siyahısında gizlət",
        "tog-watchlisthidepatrolled": "Yoxlanılmış redaktələri izləmə siyahısında gizlət",
        "tog-watchlisthidecategorization": "Səhifələrin kateqoriyalaşdırmasını gizlət",
@@ -77,6 +80,7 @@
        "tog-norollbackdiff": "Geri qaytardıqdan sonra dəyişikliklər arasındakı fərqi göstərmə",
        "tog-useeditwarning": "Qeyd edilməmiş dəyişikliyə sahib bir dəyişiklik səhifəsindən çıxarkən məni xəbərdar et",
        "tog-prefershttps": "Daxil olarkən hər zaman mühafizə edilən bağlantıdan istifadə et.",
+       "tog-showrollbackconfirmation": "Bir rollback linkinə kliklədiyinizdə təsdiq sorğusunu göstərin",
        "underline-always": "Həmişə",
        "underline-never": "Heç vaxt",
        "underline-default": "Susmaya görə brouzer",
        "returnto": "$1 səhifəsinə qayıt.",
        "tagline": "{{SITENAME}} saytından",
        "help": "Kömək",
+       "help-mediawiki": "MediaWiki haqqında kömək",
        "search": "Axtar",
+       "search-ignored-headings": "#<!-- bu xəttə əl vurmayın --> <pre>\n# Axtarışa görə başlıqlara məhəl qoyulmayacaq.\n# Bununla bağlı dəyişiklik başlıqlı səhifənin indeksli olduğu anda qüvvəyə minir.\n# Boş redaktə edərək səhifəni yenidən indeksləşdirə bilərsiniz.\n# Sintaksis belədir:\n# *Hər şey \"#\" simvolundan xəttin sonuna qədər bir şərhdir.\n# *Hər bir boş olmayan sətir, işin və hər şeyin dəqiq başlığıdır.\nİstinadlar\nXarici keçidlər\nHəmçinin bax\n#</pre> <!-- bu xəttə əl vurmayın -->",
        "searchbutton": "Axtar",
        "go": "Keç",
        "searcharticle": "Keç",
        "history": "Səhifənin tarixçəsi",
        "history_short": "Tarixçə",
+       "history_small": "tarixçə",
        "updatedmarker": "son dəfə mən nəzərdən keçirəndən sonra yenilənib",
        "printableversion": "Çap variantı",
        "permalink": "Daimi bağlantı",
        "create": "Yarat",
        "create-local": "Lokal izah əlavə et",
        "delete": "Sil",
-       "undelete_short": "$1 {{PLURAL:$1|dəyişikliyi|dəyişiklikləri}} bərpa et",
+       "undelete_short": "$1 {{PLURAL:$1|dəyişikliyi}} bərpa et",
        "viewdeleted_short": "{{PLURAL:$1|bir silinmiş redaktəyə|$1 silinmiş redaktəyə}}",
        "protect": "Mühafizə et",
        "protect_change": "dəyiş",
        "toolbox": "Alətlər",
        "tool-link-userrights": "{{GENDER:$1|İstifadəçi}} qruplarını dəyişdir",
        "tool-link-userrights-readonly": "{{GENDER:$1|İstifadəçi}} qruplarına bax",
+       "tool-link-emailuser": "Bu {{GENDER:$1|istifadəçiyə}} e-poçt göndər",
        "imagepage": "Fayl səhifəsini göstər",
        "mediawikipage": "Mesaj səhifəsini göstər",
        "templatepage": "Şablon səhifəsini göstər",
        "jumptonavigation": "naviqasiya",
        "jumptosearch": "axtar",
        "view-pool-error": "Üzr istəyirik, hazırda serverlər artıq yüklənməyə məruz qalmışdır.\nBu səhifəyə baxmaq üçün həddən artıq müraciət daxil olmuşdur.\nZəhmət olmasa, bir müddət sonra yenidən cəhd edin.\n\n$1",
+       "generic-pool-error": "Üzr istəyirik, hazırda serverlər artıq yüklənməyə məruz qalmışdır.\nBu səhifəyə baxmaq üçün həddən artıq müraciət daxil olmuşdur.\nZəhmət olmasa, bir müddət sonra yenidən cəhd edin.",
        "pool-timeout": "Blokun gözləmə müddəti bitdi",
        "pool-queuefull": "Çıxarış səhifəsi doludur",
        "pool-errorunknown": "naməlum xəta",
+       "pool-servererror": "Hovuz sayğaç xidməti mövcud deyil ($1).",
        "poolcounter-usage-error": "İstifadədə xəta: $1",
        "aboutsite": "{{SITENAME}} haqqında",
        "aboutpage": "Project:İzah",
        "privacypage": "Project:Gizlilik prinsipi",
        "badaccess": "İcazə xətası",
        "badaccess-group0": "Bu fəaliyyəti icra etmək səlahiyyətiniz yoxdur.",
-       "badaccess-groups": " Bu fəaliyyəti, yalnız $1 {{PLURAL:$2|qrupundakı|qruplarındakı}} istifadəçilər icra edə bilərlər.",
-       "versionrequired": "MediyaViki $1 versiyası lazımdır",
-       "versionrequiredtext": "Bu səhifəni istifadə etmək üçün MediaWikinin $1 versiyası tələb olunur.\nBax: [[Special:Version|Versiyalar]].",
+       "badaccess-groups": "Bu fəaliyyəti, yalnız $1 {{PLURAL:$2|qrupundakı|qruplarından birindəki}} istifadəçilər icra edə bilərlər.",
+       "versionrequired": "MediaViki $1 versiyası lazımdır",
+       "versionrequiredtext": "Bu səhifəni istifadə etmək üçün MediaVikinin $1 versiyası tələb olunur.\nBax: [[Special:Version|Versiyalar]].",
        "ok": "OK",
        "pagetitle": "$1 - {{SITENAME}}",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "databaseerror-query": "Sorğu: $1",
        "databaseerror-function": "Funksiya: $1",
        "databaseerror-error": "Xəta: $1",
+       "transaction-duration-limit-exceeded": "Yüksək replikasiya xətası yaratmamaq üçün əməliyyat ləğv edildi, çünki yazılma müddəti ($1) $2 limitini keçmişdir.\nBir anda bir çox şeyi dəyişdirirsinizsə, bunun yerinə kiçik əməliyyatlar etməyə çalışın.",
        "laggedslavemode": "'''Xəbərdarlıq:''' Səhifə son əlavələri əks etdirməyə bilər.",
        "readonly": "Verilənlər bazası bloklanıb",
        "enterlockreason": "Bloklamanın səbəbini və nəzərdə tutulan müddətini qeyd edin",
        "missingarticle-rev": "(versiya №: $1)",
        "missingarticle-diff": "(fərq: $1, $2)",
        "readonly_lag": "Məlumatlar bazasının ikinci dərəcəli serveri əsas serverlə əlaqə yaradanadək məlumatlar bazası avtomatik olaraq bloklanmışdır",
+       "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' HTTP başlığı göndərildi, ancaq müraciət API moduluna aiddir.",
        "internalerror": "Daxili xəta",
        "internalerror_info": "Daxili xəta: $1",
+       "internalerror-fatal-exception": "\"$1\" tipli istisna",
        "filecopyerror": "\"$1\" faylı \"$2\" faylına kopyalanmır.",
        "filerenameerror": "\"$1\" faylının adını \"$2\"-yə dəyişmək mümkün deyil",
        "filedeleteerror": "\"$1\" fayılını silə bilmədi.",
        "directorycreateerror": "\"$1\" direktoriyasını yaratmaq mümkün deyil",
+       "directoryreadonlyerror": "\"$1\" təlimatçısı yalnız oxuna bilər.",
+       "directorynotreadableerror": "\"$1\" təlimatçısı oxuna bilmir.",
        "filenotfound": "\"$1\" faylını tapa bilmədi.",
        "unexpected": "Uyğunsuzluq: \"$1\"=\"$2\".",
        "formerror": "Xəta: Formanın məlumatlarını əks etdirmək qeydi-mümkündür",
        "badarticleerror": "Yerinə yetirmək istədiyiniz fəaliyyətin icrası bu səhifədə mümkün deyil.",
        "cannotdelete": "İstədiyiniz \"$1\" səhifə və ya faylını silmək mümkün deyil.\nBu səhifə və ya fayl başqa bir istifadəçi tərəfindən silinmiş ola bilər.",
        "cannotdelete-title": "\"$1\" səhifəsinin silinməsi mümkünsüzdür.",
+       "delete-scheduled": "\"$1\" səhifəsinin silinməsi planlaşdırılır.\nXahiş edirik səbrli olun.",
        "delete-hook-aborted": "Silmə əməliyyatı qarmaq tərəfindən dayandırıldı. \nHeç bir açıqlama edilmədi.",
        "no-null-revision": "\"$1\" səhifəsi üçün yeni boş bir versiya yaradıla bilmədi",
        "badtitle": "Səhv başlıq",
        "badtitletext": "Axtarılan səhifə adı səhvdir, boşdur və ya düzgün olmayan dillərarası, yaxud vikilərarası keçid istifadə edilib.\nBaşlıqlarda istifadə edilməsi qadağan olunan bir və ya daha çox simvol istifadə edilmiş ola bilər.",
+       "title-invalid-empty": "Axtarılan səhifə başlığı boşdur və ya yalnız ad boşluğunun adını ehtiva edir.",
+       "title-invalid-utf8": "Axtarılan səhifənin başlığı etibarsız UTF-8 ardıcıllığını ehtiva edir.",
+       "title-invalid-interwiki": "Axtarılan səhifə başlığı başlıqlarda istifadə edilə bilməyən interviki keçidini ehtiva edir.",
+       "title-invalid-talk-namespace": "Axtarılan səhifə başlığı mövcud olmayan müzakirə səhifəsinə istinad edir.",
+       "title-invalid-characters": "Axtarılan səhifənin başlığı etibarsız simvol ehtiva edir: \"$1\".",
+       "title-invalid-relative": "Başlığın nisbi yolu mövcuddur. Nisbi səhifə başlığı (./, ../) etibarsızdır, istifadəçi brauzeri tərəfindən idarə edildikdə tez-tez istifadə edilə bilməyəcək.",
+       "title-invalid-magic-tilde": "Axtarılan səhifə başlığı etibarsız tilda sırası ehtiva edir (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": "Axtarılan səhifə başlığı çox uzundur. UTF-8 kodlaşdırmasında $1 baytdan artıq olmamalıdır.",
+       "title-invalid-leading-colon": "Axtarılan səhifən başlığı başlıqda etibarsız bir sütun ehtiva edir.",
        "perfcached": "Aşağıdakı məlumatlar keş yaddaşdan götürülmüşdür və bu səbəbdən aktual olmaya bilər. A maximum of {{PLURAL:$1|one result is|$1 results are}} available in the cache.",
        "perfcachedts": "Aşağıdakı məlumatlar keş yaddaşdan götürülmüşdür və sonuncu dəfə $1 tarixində yenilənmişdir. A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
        "querypage-no-updates": "Bu an üçün güncəlləmələr sıradan çıxdı. Buradakı məlumat dərhal yenilənməyəcək.",
        "viewyourtext": "Bu səhifəyə <strong>etdiyiniz dəyişikliklərin</strong> mənbəyinə baxa və köçürə bilərsiniz.",
        "protectedinterface": "Bu səhifədə proqram təminatı üçün sistem məlumatları var və sui-istifadənin qarşısını almaq üçün mühafizə olunmalıdır.",
        "editinginterface": "<strong>Diqqət:</strong> Siz proqram təminatı üçün interfeys mətni olan səhifəni redaktə edirsiniz.\nOnun dəyişdirilməsi digər istifadəçilərin interfeysinin xarici görünüşünə təsir göstərəcək.",
+       "translateinterface": "Bütün vikilər üçün tərcümələri əlavə etmək və ya dəyişmək üçün, xahiş edirik MediaWiki lokallaşdırma layihəsi [https://translatewiki.net/ translatewiki.net]-i istifadə edin.",
        "cascadeprotected": "Bu səhifə mühafizə olunub, çünki o, kaskad mühafizə olunan {{PLURAL:$1|aşağıdakı səhifədə|aşağıdakı səhifələrdə}} istifadə edilib:\n$2",
        "namespaceprotected": "Sizin adlarında $1 olan məqalələrdə redaktə etməyə icazəniz yoxdur.",
        "customcssprotected": "Bu səhifəni redaktə etmə izniniz yoxdur, çünki bu səhifə başqa bir istifadəçinin fərdi parametrlərinə sahibdir.",
+       "customjsonprotected": "Bu JSON səhifəsini redaktə etmək icazəniz yoxdur, çünki burada başqa bir istifadəçinin şəxsi parametrləri var.",
        "customjsprotected": "Bu Java Script səhifəsini redaktə etmə izniniz yoxdur, çünki bu səhifə başqa bir istifadəçinin fərdi parametrlərinə sahibdir.",
+       "sitecssprotected": "Bu CSS səhifəsini redaktə etmək icazəniz yoxdur, çünki bu bütün ziyarətçilərə təsir edə bilər.",
+       "sitejsonprotected": "Bu JSON səhifəsini redaktə etmək icazəniz yoxdur, çünki bu bütün ziyarətçilərə təsir edə bilər.",
+       "sitejsprotected": "Bu JavaScript səhifəsini redaktə etmək icazəniz yoxdur, çünki bu bütün ziyarətçilərə təsir edə bilər.",
        "mycustomcssprotected": "Bu CSS ssəhifəsini redaktə etmək səlahiyyətiniz yoxdur.",
+       "mycustomjsonprotected": "Bu JSON səhifəsini redaktə etmək icazəniz yoxdur.",
        "mycustomjsprotected": "Bu JavaScript səhifəsini redaktə etmək səlahiyyətiniz yoxdur.",
        "myprivateinfoprotected": "Sizin şəxsi məlumatlarınızı redaktə etmək səlahiyyətiniz yoxdur.",
        "mypreferencesprotected": "Seçimlərinizi redaktə etmək üçün izniniz yoxdur.",
        "ns-specialprotected": "Xüsusi səhifələr redaktə oluna bilməz.",
        "titleprotected": "Bu adda səhifənin yaradılması istifadəçi [[User:$1|$1]] tərəfindən qadağan edilmişdir.\nGöstərilən səbəb: <em>$2</em>.",
        "filereadonlyerror": "\"$2\" fayl anbarı yalnız oxunula bilən rejimdə olduğuna görə \"$1\" faylını dəyişmək mümkün deyil.\n\nBazanı bloklayan idarəçinin əsaslandırması belədir: \"$3\".",
+       "invalidtitle": "Yanlış başlıq",
        "invalidtitle-knownnamespace": "\"$2\" sahə adı üçün \"$3\" mətni keçərsiz bir başlıq",
        "invalidtitle-unknownnamespace": "Naməlum $1 ad sahəsi miqdarı və keçərsiz \"$2\" başlıq",
        "exception-nologin": "Giriş edilməmişdir",
        "virus-scanfailed": "Yoxlama başa çatmadı (kod $1)",
        "virus-unknownscanner": "naməlum antivirus",
        "logouttext": "<strong>Sistemdən çıxdınız.</strong>\n\nVeb-brauzerin keş yaddaşını təmizləyənədək bəzi səhifələr hələ də sistemdəymişsiniz kimi görünə bilər.",
+       "cannotlogoutnow-title": "Çıxış etmək mümkün olmadı",
+       "cannotlogoutnow-text": "$1 istifadə edərkən çıxış etmək mümkün deyil.",
        "welcomeuser": "Xoş gəldin $1!",
        "welcomecreation-msg": "Hesabınız yaradıldı.\n[[Special:Preferences|{{SITENAME}} nizamlamalarınızı]] dəyişdirməyi unutmayın.",
        "yourname": "İstifadəçi adı",
        "createacct-yourpasswordagain-ph": "Parolu təkrar daxil edin",
        "userlogin-remembermypassword": "Sistemdə qal",
        "userlogin-signwithsecure": "Etibarlı bağlantıdan istifadə edin",
+       "cannotlogin-title": "Daxil olmaq mümkün olmadı",
+       "cannotlogin-text": "Daxil olmaq mümkün deyil.",
+       "cannotloginnow-title": "Hazırda daxil olmaq mümkün deyil",
+       "cannotloginnow-text": "$1 istifadə edərkən daxil olmaq mümkün deyil.",
+       "cannotcreateaccount-title": "Hesablar yaradıla bilmədi",
+       "cannotcreateaccount-text": "Bu vikidə birbaşa hesab yaratma aktiv deyil.",
        "yourdomainname": "Sizin domeniniz:",
        "password-change-forbidden": "Bu vikidə parolunuzu dəyişdirə bilməzsiniz.",
        "externaldberror": "Verilənlər bazasının doğruluğunu yoxlamada xəta baş verib və yaxud sizin xarici istifadəçi qeydiyyatını yeniləmək hüququnuz yoxdur.",
        "login": "Daxil ol",
+       "login-security": "Kimliyinizi təsdiq edin",
        "nav-login-createaccount": "Daxil ol / hesab yarat",
        "logout": "Çıxış",
        "userlogout": "Çıxış",
        "userlogin-resetpassword-link": "Parolunuzu unutmusunuz?",
        "userlogin-helplink2": "Qeydiyyat barədə köməklik",
        "userlogin-loggedin": "Siz artıq {{GENDER:$1|$1}} kimi daxil olmusunuz.\nAşağıdakı formadan istifadə edərək, başqa bir istifadəçi kimi daxil ola bilərsiniz.",
+       "userlogin-reauth": "{{GENDER:$1|$1}} olduğunuzu təsdiqləmək üçün yenidən daxil olmalısınız.",
        "userlogin-createanother": "Başqa bir istifadəçi hesabı yarat",
        "createacct-emailrequired": "E-poçt ünvanı",
        "createacct-emailoptional": "E-poçt ünvanı (məcburi deyil)",
        "createacct-email-ph": "E-poçt ünvanınızı daxil edin",
        "createacct-another-email-ph": "E-poçt ünvanını daxil edin",
        "createaccountmail": "Müvəqqəti təsadüfi bir paroldan istifadə edə bilər və bu parolu göstərilən e-poçt ünvanına göndərə bilərsiniz",
+       "createaccountmail-help": "Parolu öyrənmədən başqa bir şəxs üçün hesab yaratmaq üçün istifadə edilə bilər.",
        "createacct-realname": "Əsl adınız (məcburi deyil)",
        "createacct-reason": "Səbəb",
        "createacct-reason-ph": "Niyə başqa bir hesab yaradırsınız",
+       "createacct-reason-help": "Hesab yaratma qeydlərində göstərilən mesaj",
        "createacct-submit": "İstifadəçi hesabı yarat",
        "createacct-another-submit": "İstifadəçi hesabı yarat",
+       "createacct-continue-submit": "Hesab yaratmağı davam etdirin",
+       "createacct-another-continue-submit": "Hesab yaratmağı davam etdirin",
        "createacct-benefit-heading": "{{SITENAME}} sizin kimi insanlar tərəfindən yaradılır.",
        "createacct-benefit-body1": "{{PLURAL:$1|redaktə}}",
        "createacct-benefit-body2": "{{PLURAL:$1|səhifə|səhifə}}",
-       "createacct-benefit-body3": "nəfər yenicə {{PLURAL:$1|redaktə edən}}",
+       "createacct-benefit-body3": "yeni {{PLURAL:$1|redaktor}}",
        "badretype": "Daxil etdiyiniz parol uyğun gəlmir.",
+       "usernameinprogress": "Bu istifadəçi adı üçün bir hesab yaratma artıq başlamışdır.\nZəhmət olmasa, gözləyin.",
        "userexists": "Daxil edilmiş ad artıq istifadədədir.\nLütfən başqa ad seçin.",
+       "createacct-normalization": "Texniki məhdudiyyətlər səbəbiylə istifadəçi adınız \"$2\" olaraq düzəldiləcək.",
        "loginerror": "Daxil olma xətası",
        "createacct-error": "Hesab yaratma xətası",
        "createaccounterror": "Bu istifadəçi adını yaratmaq mümkün olmadı: $1",
        "nocookieslogin": "{{SITENAME}} istifadəçilərin daxil ola bilməsi üçün \"cookie\"lərdən istifadə edir. Siz \"cookie\"lərin qəbuluna qadağa qoymusunuz. Lütfən, onların qəbuluna icazə verin və bir daha daxil olmağa cəhd edin.",
        "nocookiesfornew": "İstifadəçinin akkauntu yaradılmayıb, ona görə də biz onun mənbəsini təsdiqləyə bilmədik.\nKukların qoşulmasına əmin olduqdan sonra səhifəni yeniləyib bir daha sınayın.",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
+       "createacct-loginerror": "Hesab müvəffəqiyyətlə yaradılıb, lakin avtomatik olaraq daxil olma mümkün olmadə. Zəhmət olmasa, [[Special:UserLogin|daxil olma]] səhifəsinə keçin.",
        "noname": "Siz mövcud olan istifadəçi adı daxil etməmisiniz.",
        "loginsuccesstitle": "Daxil oldunuz",
        "loginsuccess": "'''\"$1\" adı ilə sistemə daxil oldunuz.'''",
        "nosuchusershort": "\"$1\" adlı istifadəçi mövcud deyil. Yazdığınızı yoxlayın.",
        "nouserspecified": "İstifadəçi adı daxil etməlisiniz.",
        "login-userblocked": "Bu istifadəçi bloklanıb. Sistemə giriş üçün icazə verilmir.",
-       "wrongpassword": "Səhv parol. Təkrar yazın.",
+       "wrongpassword": "Yanlış istifadəçi adı və ya şifrə.\nZəhmət olmasa, bir daha cəhd edin.",
        "wrongpasswordempty": "Parol boş. Təkrar yazın.",
        "passwordtooshort": "Parolda ən azı {{PLURAL:$1|1 hərf yaxud simvol|$1 hərf yaxud simvol}} olmalıdır.",
+       "passwordtoolong": "Parolda ən azı {{PLURAL:$1|1 hərf yaxud simvol|$1 hərf yaxud simvol}} olmalıdır.",
+       "passwordtoopopular": "Çox istifadə edilən parollar seçilə bilməz. Xahiş edirik təxmin edilməsi daha çətin olan bir parol seçin.",
+       "passwordinlargeblacklist": "Daxil edilən parol çox istifadə edilən parolların siyahısında mövcuddur. Xahiş edirik daha bənzərsiz parol seçin.",
        "password-name-match": "Parol adınızdan fərqli olmalıdır.",
        "password-login-forbidden": "Bu istifadəçi adından və paroldan istifadə qadağan olunub.",
        "mailmypassword": "E-mail ilə yeni parol göndər",
        "passwordremindertitle": "{{SITENAME}} parol xatırladıcı",
-       "passwordremindertext": "Kimsə (ehtimal ki, siz özünüz, $1 IP ünvanından) {{SITENAME}} ($4) layihəsi \nüçün yeni bir parol göndərilməsini istəyib. \"$2\" adlı istifadəçi üçün müvəqqəti \nolaraq \"$3\" parolu yaradılıb. Əgər bu sizin istəyiniz əsasında olubsa, \nhesabınıza daxil olaraq yeni bir parol yaratmağınız vacibdir. Müvəqqəti parolunuz\n{{PLURAL:$5|1 gün|$5 gün}} ərzində qüvvədə olacaqdır.\n\nParol dəyişdirməni siz istəməmisinizsə və ya parolunuzu xatırladınızsa \nvə artıq parolunuzu dəyişdirmək istəmirsinizsə, bu mesaja əhəmiyyət vermədən \nəvvəlki parolunuzdan istifadə etməyə davam edə bilərsiniz.",
+       "passwordremindertext": "Kimsə ($1 IP ünvanından) {{SITENAME}} ($4) layihəsi \nüçün yeni bir parol göndərilməsini istəyib. \"$2\" adlı istifadəçi üçün müvəqqəti \nolaraq \"$3\" parolu yaradılıb. Əgər bu sizin istəyiniz əsasında olubsa, \nhesabınıza daxil olaraq yeni bir parol yaratmağınız vacibdir. Müvəqqəti parolunuz\n{{PLURAL:$5|1 gün|$5 gün}} ərzində qüvvədə olacaqdır.\n\nParol dəyişdirməni siz istəməmisinizsə və ya parolunuzu xatırladınızsa \nvə artıq parolunuzu dəyişdirmək istəmirsinizsə, bu mesaja əhəmiyyət vermədən \nəvvəlki parolunuzdan istifadə etməyə davam edə bilərsiniz.",
        "noemail": "\"$1\" adlı istifadəçi e-poçt ünvanını qeyd etməmişdir.",
        "noemailcreate": "Düzgün e-poçt ünvanı qeyd etməlisiniz",
        "passwordsent": "Yeni parol \"$1\" üçün qeydiyyata alınan e-poçt ünvanına göndərilmişdir.\nXahiş edirik, e-məktubu aldıqdan sonra yenidən daxil olasınız.",
        "createaccount-text": "Biriləri {{SITENAME}} saytında ($4) sizin e-poçt ünvanınızdan istifadə edərək, parolu \"$3\" olan, \"$2\" adlı bir hesab yaratdı.\n\nSayta daxil olmalı və parolunuzu dəyişdirməlisiniz.\n\nƏgər istifadəçi hesabını səhvən yaratmısınızsa, bu mesajı gözardı edə bilərsiniz.",
        "login-throttled": "Sistemə daxil olmaq üçün həddən artıq cəhd etmisiniz.\nYeni cəhd etməzdən əvvəl $1 gözləyin.",
        "login-abort-generic": "Giriş uğursuz alındı — ləğv olundu",
+       "login-migrated-generic": "Hesabınız köçürüldü və bu vikidə istifadəçi adınız artıq mövcud deyil.",
        "loginlanguagelabel": "Dil: $1",
        "suspicious-userlogout": "Sizin çıxış üçün cəhdiniz uğursuz alındı. Bu, brouzerin yaxud proksi-keşləmənin düzgün işləməməsindən qaynaqlanır.",
        "createacct-another-realname-tip": "Gərçək adınız istəyə bağlıdır.\nƏgər gərçək adınızı göstərsəniz, çalışmalarınıza müraciət etmək üçün istifadə ediləcəkdir.",
        "pt-login": "Daxil ol",
        "pt-login-button": "Daxil ol",
+       "pt-login-continue-button": "Daxil olmağa davam edin",
        "pt-createaccount": "Hesab yarat",
        "pt-userlogout": "Çıxış",
        "php-mail-error-unknown": "PHP-nin mail() funksiyasında naməlum xəta",
        "retypenew": "Yeni parolu təkrar yazın:",
        "resetpass_submit": "Parol yaradın və sistemə daxil olun",
        "changepassword-success": "Parolunuz dəyişdirildi!",
+       "changepassword-throttled": "Sistemə daxil olmaq üçün həddən artıq cəhd etmisiniz.\nYeni cəhd etməzdən əvvəl $1 gözləyin.",
+       "botpasswords": "Bot parolları",
+       "botpasswords-summary": "<em>Bot parolları</em> hesabın əsas giriş etmə məlumatlarını istifadə etmədən API vasitəsilə bir istifadəçi hesabına giriş imkanı verir. Bir bot parol ilə daxil olduqda mövcud istifadəçi hüquqları məhdudlaşdırıla bilər.\n\nNiyə bunu edə biləcəyinizi bilmirsinizsə, bunu etməməlisiniz. Heç kim sizdən bunlardan birini yaratmağı və ona verməyinizi istəməyəcək.",
+       "botpasswords-disabled": "Bot parolları söndürüldü.",
+       "botpasswords-no-central-id": "Bot parollarını istifadə etmək üçün mərkəzləşdirilmiş bir hesaba daxil olmalısınız.",
+       "botpasswords-existing": "Mövcud bot parolları",
+       "botpasswords-createnew": "Yeni bot parolu yarat",
+       "botpasswords-editexisting": "Mövcud bot parolunu redaktə et",
+       "botpasswords-label-needsreset": "(parol sıfırlanmalıdır)",
        "botpasswords-label-appid": "Bot adı:",
        "botpasswords-label-create": "Yarat",
        "botpasswords-label-update": "Yenilə",
        "botpasswords-label-cancel": "Ləğv et",
        "botpasswords-label-delete": "Sil",
+       "botpasswords-label-resetpassword": "Parolu sıfırla",
+       "botpasswords-label-grants": "Tətbiq edilən hüquqlar:",
+       "botpasswords-help-grants": "Hüquqlar, istifadəçi hesabınız tərəfindən artıq saxlanılan hüquqlara giriş imkanı verir. Burada bir hüquq verilərkən, istifadəçi hesabınızın başqa cür olmadığı heç bir haqqı təmin etmir. Daha ətraflı məlumat üçün [[Special:ListGrants| hüquqlar]] səhifəsinə baxın.",
+       "botpasswords-label-grants-column": "Hüquq verildi",
+       "botpasswords-bad-appid": "\"$1\" bot adı etibarlı deyil.",
+       "botpasswords-insert-failed": "Bot adı \"$1\" əlavə etməyib. Artıq əlavə edilsin?",
+       "botpasswords-update-failed": "\"$1\" bot adı yenilənmədi. Silinsin?",
+       "botpasswords-created-title": "Bot parolu yaradıldı",
+       "botpasswords-created-body": "\"$2\" adlı istifadəçinin \"$1\" bot adı üçün bot parolu yaradıldı.",
+       "botpasswords-updated-title": "Bot parolu yeniləndi",
+       "botpasswords-updated-body": "\"$2\" adlı istifadəçinin \"$1\" bot adı üçün bot parolu yeniləndi.",
+       "botpasswords-deleted-title": "Bot parolu silindi",
+       "botpasswords-deleted-body": "\"$2\" adlı istifadəçinin \"$1\" bot adı üçün bot parolu silindi.",
+       "botpasswords-newpassword": "<strong>$1</strong> ilə daxil olmaq üçün yeni parol: <strong>$2</strong>. <em> Gələcək arayış üçün qeyd edin. </em> <br> (Giriş adının nüfuzlu istifadəçi adı ilə eyni olmasını tələb edən köhnə botlara görə <strong>$3</strong> istifadəçi adını və <strong>$4</strong> parolunu da istifadə edə bilərsiniz)",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider mövcud deyil.",
+       "botpasswords-restriction-failed": "Bot parol məhdudiyyətləri bu girişə mane olur.",
+       "botpasswords-invalid-name": "Göstərilən istifadəçi adı bot ayırıcısını (\"$1\") ehtiva etmir.",
+       "botpasswords-not-exist": "\"$1\" adlı istifadəçinin \"$2\" adlı bot şifrəsi yoxdur.",
+       "botpasswords-needs-reset": "\"$1\" adlı istifadəçinin \"$2\" bot adı üçün bot şifrəsi sıfırlanmalıdır.",
+       "botpasswords-locked": "Hesabınız kilidləndiyinə görə bot şifrəsi ilə giriş edə bilməzsiniz.",
        "resetpass_forbidden": "Parolu dəyişmək mümkün deyil",
+       "resetpass_forbidden-reason": "Şifrəni dəyişmək mümkün deyil: $1",
        "resetpass-no-info": "Bu səhifəni birbaşa açmaq üçün sistemə daxil olmalısınız.",
        "resetpass-submit-loggedin": "Parolu dəyiş",
        "resetpass-submit-cancel": "Ləğv et",
        "resetpass-wrong-oldpass": "Müvəqqəti və ya daimi parolda yanlışlıq var.\nOla bilər siz parolu müvəffəqiyyətlə dəyişmisiniz, yaxud yeni müvəqqəti parol üçün müraciət etmisiniz.",
+       "resetpass-recycled": "Şifrənizi mövcud şifrədən başqasına dəyişdirin.",
+       "resetpass-temp-emailed": "Siz müvəqqəti e-poçt kodu ilə daxil oldunuz. \nDaxil olmağı bitirmək üçün bura yeni bir şifrə yazmalısınız:",
        "resetpass-temp-password": "Müvəqqəti parol:",
        "resetpass-abort-generic": "Parol dəyişikliyi bir genişlənmə tərəfindən ləğv edildi.",
+       "resetpass-expired": "Şifrənizin müddəti doldu. Daxil olmaq üçün yeni bir şifrə təyin edin.",
+       "resetpass-expired-soft": "Şifrənizin müddəti başa çatdığı üçün dəyişdirilməlidir. Xahiş edirik, yeni bir şifrə seçin və ya daha sonra dəyişdirmək üçün \"{{int:authprovider-resetpass-skip-label}}\" düyməsinə basın.",
+       "resetpass-validity": "Şifrəniz etibarlı deyil: $1\n\nDaxil olmaq üçün yeni bir şifrə təyin edin.",
+       "resetpass-validity-soft": "Şifrəniz etibarlı deyil: $1\n\nXahiş edirik yeni bir şifrə seçin və ya daha sonra dəyişdirmək üçün \"{{int: authprovider-resetpass-skip-label}}\" düyməsinə basın.",
        "passwordreset": "Parolu yenilə",
        "passwordreset-text-one": "Parolunuzu sıfırlamaq üçün bu formanı doldurun.",
        "passwordreset-text-many": "{{PLURAL:$1|Parolunuzu sıfırlamaq üçün sahələrdən birini doldurun.}}",
        "passwordreset-email": "E-mail ünvanı:",
        "passwordreset-emailtitle": "{{SITENAME}} hesabın yaradılması",
        "passwordreset-emailtext-ip": "Kimsə, (ehtimal ki siz özünüz, $1 IP adresindən) {{SITENAME}} ($4) layihəsindəki hesabınızın \nparolunun yenilənməsini istəyib. Aşağıdakı istifadəçi {{PLURAL:$3|hesabı|hesabları}} bu e-poçt adresinə bağlıdır:\n\n$2\n\nBu müvəqqəti {{PLURAL:$3|parol|parollar}} {{PLURAL:$5|bir gün|$5 gün}} qüvvədə olacaqdır.\nSiz müvəqqəti parolla daxil olub yeni bir parol seçməlisiniz. Əgər parolun dəyişdirilməsini siz istəməmisinizsə və ya parolunuzu xatırladınızsa və artıq onu dəyişmək istəmirsinizsə, bu məktuba əhəmiyyət verməyərək köhnə parolunuzu istifadə etməyə davam edə bilərsiniz.",
+       "passwordreset-emailtext-user": "Kimsə, ($1 IP adresindən) {{SITENAME}} ($4) layihəsindəki hesabınızın \nparolunun sıfırlanmasını istəyib. Aşağıdakı istifadəçi {{PLURAL:$3|hesabı|hesabları}} bu e-poçt adresinə bağlıdır:\n\n$2\n\nBu müvəqqəti {{PLURAL:$3|parol|parollar}} {{PLURAL:$5|bir gün|$5 gün}} qüvvədə olacaqdır.\nSiz müvəqqəti parolla daxil olub yeni bir parol seçməlisiniz. Əgər parolun dəyişdirilməsini siz istəməmisinizsə və ya parolunuzu xatırladınızsa və artıq onu dəyişmək istəmirsinizsə, bu məktuba əhəmiyyət verməyərək köhnə parolunuzu istifadə etməyə davam edə bilərsiniz.",
        "passwordreset-emailelement": "İstifadəçi adı: \n$1\n\nMüvəqqəti parol: \n$2",
        "passwordreset-emailsentemail": "Əgər bu imeyl sizin istifadəçi hesabınıza bağlıdırsa, o halda parol sıfırlama məktubu ora göndəriləcək.",
+       "passwordreset-emailsentusername": "Əgər bu e-poçt sizin istifadəçi hesabınıza bağlıdırsa, o halda parol sıfırlama məktubu ora göndəriləcək.",
+       "passwordreset-nocaller": "Çağırıcı təmin edilməlidir",
+       "passwordreset-nosuchcaller": "Çağırıcı yoxdur: $1",
+       "passwordreset-ignored": "Parolun sıfırlanması işlənməmişdir. Bəlkə heç bir provayder qurulmayıb?",
+       "passwordreset-invalidemail": "Səhv e-poçt",
+       "passwordreset-nodata": "Nə bir istifadəçi adı, nə də bir e-poçt ünvanı verilmədi.",
        "changeemail": "E-məktub ünvanını dəyiş və ya sil",
+       "changeemail-header": "E-poçt ünvanınızı dəyişdirmək üçün bu formanı tamamlayın. Hesabınızdakı hər hansı bir e-poçt ünvanının birləşməsini aradan qaldırmaq istəyirsinizsə, formu təqdim edərkən yeni e-poçt ünvanını boş buraxın.",
+       "changeemail-no-info": "Bu səhifəni birbaşa açmaq üçün sistemə daxil olmalısınız.",
        "changeemail-oldemail": "Hazırkı e-poçt ünvanı:",
        "changeemail-newemail": "Yeni e-poçt ünvanı:",
+       "changeemail-newemail-help": "E-poçt ünvanınızı çıxarmaq istəyirsinizsə, bu sahə boş olmalıdır. Unudulan bir parolu sıfırlaya bilməyəcəksiniz və e-poçt ünvanı çıxarıldıqda bu vikidən e-poçt ala bilməyəcəksiniz.",
        "changeemail-none": "(yoxdur)",
+       "changeemail-password": "Sizin {{SITENAME}} şifrəniz:",
        "changeemail-submit": "E-poçtu dəyiş",
+       "changeemail-throttled": "Sistemə daxil olmaq üçün həddən artıq cəhd etmisiniz.\nYeni cəhd etməzdən əvvəl $1 gözləyin.",
+       "changeemail-nochange": "Fərqli bir yeni e-poçt ünvanı daxil edin.",
+       "resettokens": "Jetonları sıfırla",
+       "resettokens-text": "Hesabınızla əlaqəli müəyyən şəxsi məlumatlara giriş imkanı verən jetonlar sıfırlana bilər.\n\nTəsadüfən kimsə ilə paylaşdığınız təqdirdə və ya hesabınız pozulduğu halda bunu etməlisiniz.",
+       "resettokens-no-tokens": "Sıfırlanacaq heç bir jeton yoxdur.",
+       "resettokens-tokens": "Jetonlar:",
+       "resettokens-token-label": "$1 (cari dəyər: $2)",
+       "resettokens-watchlist-token": "[[Special:Watchlist|İzləmə siyahınızdakı]] səhifələrdə dəyişikliklərin web feed-i (Atom / RSS) üçün jeton",
+       "resettokens-done": "Jetonlar sıfırlandı.",
+       "resettokens-resetbutton": "Seçilmiş jetonları sıfırla",
        "bold_sample": "Qalın mətn",
        "bold_tip": "Qalın mətn",
        "italic_sample": "Kursiv mətn",
        "minoredit": "Kiçik redaktə",
        "watchthis": "Bu səhifəni izlə",
        "savearticle": "Səhifəni dərc et",
+       "savechanges": "Dəyişiklikləri yadda saxla",
        "publishpage": "Səhifəni yayımla",
        "publishchanges": "Dəyişiklikləri yayımla",
+       "savearticle-start": "Səhifəni dərc et...",
+       "savechanges-start": "Dəyişiklikləri yadda saxla...",
+       "publishpage-start": "Səhifəni yayımla...",
+       "publishchanges-start": "Dəyişiklikləri yayımla...",
        "preview": "Sınaq görüntüsü",
        "showpreview": "Sınaq göstərişi",
        "showdiff": "Dəyişiklikləri göstər",
+       "blankarticle": "<strong>Xəbərdarlıq:</strong> Yaratdığınız səhifə boşdur. Əgər bir daha \"$1\" düyməsinə klikləsəniz, səhifə heç bir məzmun olmadan yaradılacaq.",
        "anoneditwarning": "<strong>Diqqət:</strong> Siz sistemə daxil olmamısınız. Hər hansı dəyişiklik etsəniz, sizin IP-ünvanınız hamıya görünəcək. Əgər <strong>[$1 daxil olsanız]</strong> və ya <strong>[$2 hesab yaratsanız]</strong>, redaktələriniz sizin istifadəçi adınıza yazılacaq və digər üstünlüklər də qazanacaqsınız.",
        "anonpreviewwarning": "Sistemə daxil olmamısınız. \"Səhifəni qeyd et\" düyməsini bassanız IP ünvanınız səhifənin tarixçəsində qeyd olunacaq.",
        "missingsummary": "'''Xatırlatma.''' Siz dəyişikliklərin qısa şərhini verməmisiniz. \"Səhifəni qeyd et\" düyməsinə təkrar basandan sonra sizin dəyişiklikləriniz şərhsiz qeyd olunacaq.",
+       "selfredirect": "<strong>Xəbərdarlıq:</strong> Bu səhifəni özünüzə istiqamətləndirirsiniz.\nİstiqamətləndirmə üçün yanlış hədəf göstərə bilərsiniz və ya səhv səhifəni redaktə edə bilərsiniz.\nYenidən \"$1\" düyməsinə bassanız, yenidən istiqamətləndirmə yaradılacaq.",
        "missingcommenttext": "Zəhmət olmasa, şərh yazın.",
+       "missingcommentheader": "<strong>Xatırlatma:</strong> Bu şərh üçün bir mövzu vermədiniz.\nYenidən \"$1\" düyməsinə basarsanız, düzəlişiniz heçnəsiz saxlanacaq.",
        "summary-preview": "Dəyişikliyin izahının görünüşü:",
        "subject-preview": "Sərlövhə belə olacaq:",
+       "previewerrortext": "Redaktələrinizin sınaq görüntüsü göstərilərkən bir səhv baş verdi.",
        "blockedtitle": "İstifadəçi bloklanıb",
+       "blocked-email-user": "<strong>İstifadəçi adınız e-poçt göndərməkdən bloklanmışdır. Siz hələ də bu vikidə redaktə edə bilərsiniz.</strong> Tam blok detallarını [[Special:MyContributions|istifadəçi fəaliyyətləri]] səhifəsində görə bilərsiniz.\n\nBloklayan: $1\nVerilmiş səbəb:<em>$2</em>\n\n*Blokun başlaması: $8\n*Blokun bitməsi: $6\n*Blok məqsədi: $7\n*Blok ID:#$5",
+       "blockedtext-partial": "<strong>İstifadəçi adınız bu səhifəni redaktə etməkdən bloklanmışdır. Siz bu vikidə digər səhifələrdə redaktə edə bilərsiniz.</strong> Tam blok detallarını [[Special:MyContributions|istifadəçi fəaliyyətləri]] səhifəsində görə bilərsiniz.\n\nBloklayan: $1\nVerilmiş səbəb:<em>$2</em>\n\n*Blokun başlaması: $8\n*Blokun bitməsi: $6\n*Blok məqsədi: $7\n*Blok ID:#$5",
+       "blockedtext": "<strong>Sizin istifadəçi adınız və ya IP ünvanınız bloklanmışdır.</strong>\n\nBloklayan: $1\nSəbəb: <em>$2</em>\n\n*Blokun başlaması: $8\n*Blokun bitməsi: $6\n*Blok məqsədi:$7\n\nSiz $1 ilə və ya  [[{{MediaWiki:Grouppage-sysop}}|digər idarəçilərlə]] bloku müzakirə edə bilərsiniz.\n[[Special:Preferences|Nizamlamalarda]] etibarlı bir e-poçt ünvanı göstərilmədikcə və onu istifadə etməmisinizsə, \"{{int: emailuser}}\" funksiyasından istifadə edə bilməzsiniz.\nSizin IP ünvanınız: $3\nBlok ID: #$5\nXahiş etdiyiniz hər hansı bir sorğuda yuxarıda göstərilən məlumatları daxil edin.",
+       "autoblockedtext": "Sizin IP ünvanınız avtomatik olaraq bloklanıb, çünki digər bloklanmış istifadəçi tərəfindən istifadə edilib.\n\nBloklayan: $1\nSəbəb: <em>$2</em>\n\n*Blokun başlaması: $8\n*Blokun bitməsi: $6\n*Blok məqsədi:$7\n\nSiz $1 ilə və ya  [[{{MediaWiki:Grouppage-sysop}}|digər idarəçilərlə]] bloku müzakirə edə bilərsiniz.\n[[Special:Preferences|Nizamlamalarda]] etibarlı bir e-poçt ünvanı göstərilmədikcə və onu istifadə etməmisinizsə, \"{{int: emailuser}}\" funksiyasından istifadə edə bilməzsiniz.\nSizin IP ünvanınız: $3\nBlok ID: #$5\nXahiş etdiyiniz hər hansı bir sorğuda yuxarıda göstərilən məlumatları daxil edin.",
+       "systemblockedtext": "Sizin istifadəçi adınız və ya IP ünvanınız MediaWiki tərəfindən avtomatik olaraq bloklanıb.\n\nSəbəb: <em>$2</em>\n\n*Blokun başlaması: $8\n*Blokun bitməsi: $6\n*Blok məqsədi:$7\n\n\nSizin IP ünvanınız: $3\nXahiş etdiyiniz hər hansı bir sorğuda yuxarıda göstərilən məlumatları daxil edin.",
        "blockednoreason": "səbəb göstərilməyib",
        "whitelistedittext": "Dəyişiklik edə bilmək üçün $1.",
        "confirmedittext": "Siz elektron ünvanınızı səhifədə dəyişiklik etməzdən əvvəl göstərməlisiniz.\nZəhmət olmasa elektron ünvanınızı [[Special:Preferences|istifadəçi nizamlaması]] səhifənizdə göstərib təsdiq ediniz.",
        "accmailtext": "[[User talk:$1|$1]] üçün təsadüfi yolla yaradılmış parol $2 ünvanına göndərildi.\nHesabınıza daxil olduqdan sonra, parolunuzu ''[[Special:ChangePassword|parolu dəyiş]]'' səhifəsində dəyişdirə bilərsiniz.",
        "newarticle": "(Yeni)",
        "newarticletext": "Mövcud olmayan səhifəyə olan keçidi izlədiniz. Aşağıdakı sahəyə məzmununu yazaraq bu səhifəni '''siz''' yarada bilərsiniz. (əlavə məlumat üçün [$1 kömək səhifəsinə] baxın). Əgər bu səhifəyə səhvən gəlmisinizsə sadəcə olaraq brauzerin '''geri''' düyməsinə vurun.",
-       "anontalkpagetext": "----\n<em>Bu səhifə qeydiyyatdan keçməmiş və ya daxil olmamış anonim istifadəçiyə aid müzakirə səhifəsidir.</em>\nOna görə bu istifadəçini rəqəmlərdən ibarət IP ünvanı ilə müəyyən etmək məcburiyyətindəyik.\nBelə IP-ünvan bir neçə fərd tərəfindən istifadədə ola bilər.\nƏgər siz anonim istifadəçisinizsə və bu mesajın sizə aid olmadığını düşünürsünüzsə, onda [[Special:CreateAccount|qeydiyyatdan keçin]] və ya [[Special:UserLogin|daxil olun]] ki, digər anonim istifadəçilərlə qarışıqlıq yaşamayasınız.",
+       "anontalkpagetext": "----\n<em>Bu səhifə qeydiyyatdan keçməmiş və ya daxil olmamış anonim istifadəçiyə aid müzakirə səhifəsidir.</em>\nOna görə bu istifadəçini rəqəmlərdən ibarət IP ünvanı ilə müəyyən etmək məcburiyyətindəyik.\nBelə IP ünvan bir neçə fərd tərəfindən istifadədə ola bilər.\nƏgər siz anonim istifadəçisinizsə və bu mesajın sizə aid olmadığını düşünürsünüzsə, onda [[Special:CreateAccount|qeydiyyatdan keçin]] və ya [[Special:UserLogin|daxil olun]] ki, digər anonim istifadəçilərlə qarışıqlıq yaşamayasınız.",
        "noarticletext": "Hal-hazırda bu səhifə boşdur. Başqa səhifələrdə eyni adda səhifəni [[Special:Search/{{PAGENAME}}|axtara]], əlaqəli qeydlərə\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} baxa] və ya [{{fullurl:{{FULLPAGENAME}}|action=edit}} bu adda səhifəni yarada]</span> bilərsiniz.",
        "noarticletext-nopermission": "Hal-hazırda bu səhifə boşdur. Başqa səhifələrdə eyni adlı səhifəni [[Special:Search/{{PAGENAME}}| axtara]], <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} əlaqəli qeydlərə baxa] və ya səhifəni [{{fullurl:{{FULLPAGENAME}}|action=edit}} redaktə edə bilərsiniz]</span>, lakin sizin bu məqaləni yaratmaq hüququnuz yoxdur.",
+       "missing-revision": "\"{{FULLPAGENAME}}\" adlı səhifənin #$1 versiyası mövcud deyil.\n\nBu adətən silinmiş bir səhifəyə köhnəlmiş keçid bağlantısı ilə bağlıdır. Detallar üçün [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} silmə qeydlərinə] baxın.",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" istifadəçi adı qeydiyyata alınmayıb.\nƏgər siz bu səhifəni yaratmaq/redaktə etmək istəyirsinizsə, xahiş edirik bunu yoxlayın.",
        "userpage-userdoesnotexist-view": "\"$1\" istifadəçi hesabı qeydiyyatda deyil",
        "blocked-notice-logextract": "Bu istifadəçi hal-hazırda bloklanmışdır.\nBloklama qeydlərinin sonuncusu aşağıda göstərilmişdir:",
+       "clearyourcache": "<strong>Qeyd:</strong> Yaddaşa verdikdən sonra dəyişikliklərin görünməsi üçün brauzerinizin keşindən yan keçilməsi lazım ola bilər. \n<strong>Mozilla / Firefox / Safari:</strong>''' <em>Reload</em> düyməsini basarkən eyni vaxtda <em>Shift</em>-i basılı tutun və ya ''Ctrl-Shift-R''-a basın. (Apple Mac-da ''Cmd-Shift-R''). '''İE''': ''Refresh'' düyməsini basarkən eyni vaxtda ''Ctrl''-i basılı tutun və ya ''Ctrl-F5''-ə basın. '''Conqueror:''' Sadəcə ''Reload'' düyməsinə və ya ''F5''-ə basın. '''Opera''' brauzeri istifadəçiləri ''Tools→Preferences''-dən ''cache''-lərini tamamilə təmizləməli ola bilərlər.",
        "usercssyoucanpreview": "'''İpucu:''' Qeyd etmədən əvvəl \"{{int:showpreview}}\"ə klikləyərək yeni CSSinizi yoxlayın.",
+       "userjsonyoucanpreview": "'''İpucu:''' Qeyd etməzdən əvvəl \"{{int:showpreview}}\" düyməsinə klikləyərək yeni JSON-unuzu yoxlayın.",
        "userjsyoucanpreview": "'''İpucu:''' Qeyd etmədən əvvəl \"{{int:showpreview}}\"ə klikləyərək yeni JavaScriptinizi yoxlayın.",
        "usercsspreview": "''Xatırladırıq ki, siz yalnız CSS-də sınaq göstərişi etmisiniz.'''\n'''Bu hələ yaddaşda saxlanılmayıb!'''",
+       "userjsonpreview": "''Xatırladırıq ki, siz yalnız JSON-da sınaq göstərişi etmisiniz.'''\n'''Bu hələ yaddaşda saxlanılmayıb!'''",
        "userjspreview": "''Xatırladırıq ki, siz yalnız JavaScript-də test/sınaq göstərişi etmisiniz.'''\n'''Bu hələ yaddaşda saxlanılmayıb!'''",
        "sitecsspreview": "''Xatırladırıq ki, siz yalnız CSS-də sınaq göstərişi etmisiniz.'''\n'''Bu hələ yaddaşda saxlanılmayıb!'''",
+       "sitejsonpreview": "''Xatırladırıq ki, siz yalnız JSON-da sınaq göstərişi etmisiniz.'''\n'''Bu hələ yaddaşda saxlanılmayıb!'''",
        "sitejspreview": "''Xatırladırıq ki, siz yalnız JavaScript kodunda sınaq göstərişi etmisiniz.'''\n'''Bu hələ yaddaşda saxlanılmayıb!'''",
+       "userinvalidconfigtitle": "<strong>Xəbərdarlıq:</strong> \"$1\" dərisi (skin) yoxdur.\nXüsusi css, .json, və .js səhifələri kiçik hərflə başlayır. Məsələn: {{ns:user}}:Foo/vector.css",
        "updated": "(yeniləndi)",
        "note": "'''Qeyd:'''",
        "previewnote": "<strong>Unutmayın ki, bu yalnız sınaq göstərişidir.</strong> Dəyişiklikləriniz hal-hazırda qeyd edilməmişdir!",
        "continue-editing": "Redaktə sahəsinə qayıt",
        "previewconflict": "Bu sınaq göstərişidir və yaddaşda saxlayacağınız təqdirdə mətnin redaktə səhifəsinin yuxarı hissəsində nəticənin necə olacağını göstərir.",
        "session_fail_preview": "Üzr istəyirik! Sizin redaktəniz saxlanmadı. \n\nOla bilsin ki, profilinizdən çıxmısınız. <strong>Lütfən hesabınıza daxil olmağınızı yoxlayın və təkrar cəhd edin</strong>. Problem həll olunmazsa, [[Special:UserLogout|hesabınızdan çıxın]] və yenidən daxil olun, həmçinin brauzerinizin bu saytdan kukiləri qəbul etdiyini yoxlayın.",
+       "session_fail_preview_html": "Üzr istəyirik! Sessiya məlumatlarının itirilməsi səbəbindən düzəlişiniz yayımlanmadı.\n\n<em> {{SITENAME}} saytında xammal HTML effektiv olduğundan, sınaq görüntüsü JavaScript hücumlarına qarşı tədbir kimi gizlidir.</em>\n\n<strong>Bu qanuni bir redaktə cəhdidirsə, yenidən cəhd edin. </strong>\nƏgər hələ də işləməsə, [[Special:UserLogout|çıxış]] edin və yenidən daxil olun və brauzerinizin bu saytda çərəzlərə (cookies) icazə verdiyini yoxlayın.",
+       "token_suffix_mismatch": "<strong>Redaktəniz rədd edildi, çünki müştəri düzəliş jetonundakı punktuasiya simvollarını qarışdırdı.</strong>\nDüzəliş səhifə mətninin korrupsiyasının qarşısını almaq üçün rədd edildi.\nBu, bir arqument \"web-based anonim proxy\" xidməti istifadə edərkən bəzən olur.",
+       "edit_form_incomplete": "<strong>Düzəliş formasının bir hissəsi serverə çatmadı; Redaktələrinizin sağlam olduğunu və yenidən cəhd etdiyini təkrarlayın.</strong>",
        "editing": "Redaktə $1",
        "creating": "Qurulur $1",
        "editingsection": "Redaktə $1 (bölmə)",
        "yourtext": "Mətniniz",
        "storedversion": "Qeyd edilmiş versiya",
        "editingold": "'''DİQQƏT! Siz bu səhifənin köhnə versiyasını redaktə edirsiniz. Məqaləni yaddaşda saxlayacağınız halda bu versiyadan sonra edilmiş hər bir dəyişiklik itiriləcək.'''",
+       "unicode-support-fail": "Brauzeriniz Unicode-nu dəstəkləmir. Səhifələri redaktə edərkən, redaktəniz saxlanmadı.",
        "yourdiff": "Fərqlər",
        "copyrightwarning": "Xahiş olunur diqqətə alasınız ki, {{SITENAME}}dakı bütün fəaliyyətləriniz $2 lisenziyasına tabe olduğu hesab edilir (təfərrüat üçün bax: $1). Əgər yazdıqlarınızın əsaslı şəkildə redaktə edilməsini və istənildiyi vaxt başqa yerə ötürülməsini istəmirsinizsə, yazılarınızı burada dərc etməyin.\n<br />\nSiz eyni zamanda söz verirsiniz ki, bu yazıları siz özünüz yazmısınız və ya onları hamıya açıq mühitdən ya da buna bənzər mənbədən köçürmüsünüz.\n\n----\n\n<div style=\"font-weight: bold; font-size: 110%; color:red;\">MÜƏLLİF HÜQUQLARI İLƏ QORUNMUŞ HEÇ BİR İŞİ İCAZƏSİZ DƏRC ETMƏYİN!</div>",
-       "semiprotectedpagewarning": "'''Qeyd:''' Bu səhifə mühafizəli olduğu üçün yalnız qeydiyyatdan keçmiş istifadəçilər redaktə edə bilərlər.",
+       "copyrightwarning2": "{{SITENAME}} saytında edilən bütün töhfələr digər istifadəçilər tərəfindən redaktə, dəyişdirilə və ya silinə bilər.\nYazılarınızın redaktə edilməsini istəmirsinizsə, buraya təqdim etməyin. <br />\nSiz də bunu özünüz yazdığınızı və ya ictimai bir domendən və ya digər bir etibarlı mənbədən kopyaladığınızı vəd edirsiniz (ətraflı məlumat üçün $1-ə baxın).",
+       "editpage-cannot-use-custom-model": "Bu səhifənin məzmunu modeli dəyişdirilə bilməz.",
+       "longpageerror": "<strong>Səhv: Siz təqdim etdiyiniz mətn {{PLURAL:$11 kilobayt|$1 kilobayt}} uzundur; bu {{PLURAL: $2 |bir kilobayt | $2 kilobayt}} maksimumdan daha uzundur.</strong>\nSaxlanıla bilməz.",
+       "readonlywarning": "<strong>Xəbərdarlıq: Verilənlər bazası saxlamaq üçün kilidlənib, beləliklə, düzəlişlərinizi hazırda saxlaya bilməyəcəksiniz.</strong>\nMətni mətn faylına kopyalayıp yapışdırılmasını və daha sonra saxlamağınızı tövsiyə edirik.\n\nBunu kilidləyən sistem idarəçisi bu izahatı verdi: $1",
+       "protectedpagewarning": "<strong>Xəbərdarlıq:</strong> Bu səhifə mühafizə edildiyi üçün yalnız idarəçilər redaktə edə bilərlər.\n\nƏn son jurnal qeydi aşağıda verilmişdir:",
+       "semiprotectedpagewarning": "'''Qeyd:''' Bu səhifə mühafizəli olduğu üçün onu yalnız qeydiyyatdan keçmiş istifadəçilər redaktə edə bilərlər.",
+       "cascadeprotectedwarning": "<strong>Xəbərdarlıq:</strong> Bu səhifə yalnız [[Special:ListGroupRights|xüsusi hüquqlara malik]] istifadəçilər tərəfindən redaktə ediləcək şəkildə mühafizə edilir. Çünki bu səhifə aşağıdakı kaskad mühafizə ilə qorunan {{PLURAL:$1|səhifəyə|səhifələrə}} daxildir:",
        "titleprotectedwarning": "'''DİQQƏT! Bu səhifə mühafizəlidir, yalnız [[Special:ListGroupRights|icazəsi olan]] istifadəçilər onu redaktə edə bilərlər.'''",
        "templatesused": "Bu səhifədə istifadə edilmiş {{PLURAL:$1|şablon|şablonlar}}:",
        "templatesusedpreview": "Bu sınaq göstərişində istifadə edilmiş {{PLURAL:$1|şablon|şablonlar}}:",
        "permissionserrors": "İcazə xətası",
        "permissionserrorstext": "Siz, bunu aşağıdakı {{PLURAL:$1|səbəbə|səbəblərə}} görə edə bilməzsiniz:",
        "permissionserrorstext-withaction": "Aşağıdakı {{PLURAL:$1|səbəbə|səbəblərə}} görə, $2 hüququnuz yoxdur:",
+       "contentmodelediterror": "<code>$1</code> <code>$2</code> səhifəsinin mövcud məzmun modelindən fərqləndiyi üçün bu versiyanı redaktə edə bilməzsiniz.",
        "recreate-moveddeleted-warn": "'''Diqqət! Siz əvvəllər silinmiş səhifəni bərpa etmək istəyirsiz.'''\n\nBu səhifəni yenidən yaratmağın nə qədər zəruri olduğunu bir daha yoxlayın.\nBu səhifə üçün silmə qeydləri aşağıda göstərilmişdir:",
        "moveddeleted-notice": "Bu səhifə silinmişdir.\nMəlumat üçün aşağıda bu səhifənin tarixçəsindən müvafiq silmə, mühafizə və köçmə qeydləri göstərilmişdir.",
+       "moveddeleted-notice-recent": "Üzr istəyirik, bu səhifə son vaxtlarda silinib (son 24 saat ərzində)\nBu səhifənin silinməsi, mühafizə edilməsi və yerdəyişmə qeydləri aşağıda verilmişdir.",
        "log-fulllog": "Bütöv məlumatı göstər",
        "edit-hook-aborted": "Düzəlişlər qarmaq-prosedur tərəfindən geri qaytarılıb.\nƏlavə izahat verilməyib.",
        "edit-gone-missing": "Səhifəni yeniləmək mümkün deyil.\nÇox güman ki, səhifə silinmişdir.",
        "postedit-confirmation-saved": "Redaktəniz qeyd edildi.",
        "edit-already-exists": "Yeni səhifəni yaratmaq mümkün deyil.\nBelə ki, bu adda səhifə artıq mövcuddur.",
        "content-not-allowed-here": "\"$1\" tərkibi [[:$2]] səhifəsi üçün icazə verilmir.",
+       "slot-name-main": "Əsas",
        "content-model-wikitext": "vikimətn",
        "content-model-text": "adi mətn",
        "content-model-javascript": "JavaScript",
        "revdelete-suppress": "Məlumatları idarəçilərdən də gizlə",
        "revdelete-unsuppress": "Bərpa olunan versiyalar üzərindən məhdudiyyətləri qaldır",
        "revdelete-log": "Səbəb:",
-       "revdelete-submit": "Seçilmiş {{PLURAL:$1|versiyaya|versiyayalara}} tətbiq et",
+       "revdelete-submit": "Seçilmiş {{PLURAL:$1|versiyaya|versiyalara}} tətbiq et",
        "revdelete-success": "Versiyanın görünəbilərliyi yeniləndi.",
        "revdelete-failure": "'''Versiyanın görünüşü dəyişdirilə bilməz:'''\n$1",
        "logdelete-success": "Qeydin görünəbilərliyi təsdiqləndi.",
        "mergehistory-go": "Birləşdirilə bilən redaktələri göstər",
        "mergehistory-submit": "Qarışıq düzəlişlər",
        "mergehistory-empty": "Birləşdiriləcək redaktələr tapılmamışdır.",
-       "mergehistory-done": "$1 səhifəsinin $3 {{PLURAL:$3|revizyonu|dəyişikliyi}} uğurla [[:$2]] -yə birləşdirildi.",
-       "mergehistory-no-source": "Mənbə $1 yoxdur.",
-       "mergehistory-no-destination": "Mənbə səhifəsi $1 mövcud deyil.",
+       "mergehistory-done": "$1 səhifəsindəki $3 {{PLURAL:$3|dəyişiklik|dəyişiklik}} uğurla [[:$2]] səhifəsinə birləşdirildi.",
+       "mergehistory-no-source": "Mənbə səhifəsi $1 yoxdur.",
+       "mergehistory-no-destination": "Hədəf səhifəsi $1 mövcud deyil.",
        "mergehistory-invalid-source": "Mənbənin düzgün başlığı olmalıdır.",
        "mergehistory-invalid-destination": "Hədəf səhifəsinin düzgün başlığı olmalıdır.",
        "mergehistory-autocomment": "[[:$1]] səhifəsi [[:$2]] səhifəsinə birləşdirildi",
        "showhideselectedversions": "Seçilən versiyaları göstər/gizlə",
        "editundo": "əvvəlki halına qaytar",
        "diff-empty": "(Fərqli deyil)",
-       "diff-multi-sameuser": "(Eyni istifadəçi tərəfindən edilmiş {{PLURAL:$1|bir dəyişiklik|$1 bir neçə dəyişiklik}} göstərilmir)",
+       "diff-multi-sameuser": "(Eyni istifadəçi tərəfindən edilmiş {{PLURAL:$1|bir dəyişiklik|$1 dəyişiklik}} göstərilmir)",
        "diff-multi-manyusers": "({{PLURAL:$2|Bir istifadəçi|$2 istifadəçi}} tərəfindən edilən {{PLURAL:$1|bir ara redaktə|$1 ara redaktə}} göstərilmir)",
-       "difference-missing-revision": "Səhifənin  {{PLURAL:$2|bu versiyasının|$2 versiyalarının}} müqayisəsi ($1) tapılmadı.\nBu xəta adətən, köhnəlmiş səhifələrin müqayisə versiyalarından keçid edildikdə baş verir.\nDaha ətraflı məlumat üçün [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} silmə qeydlərinə] baxın.",
+       "difference-missing-revision": "Səhifənin {{PLURAL:$2|$2 versiyasının}} müqayisəsi tapılmadı ($1).\nBu xəta adətən, köhnəlmiş səhifələrin müqayisə versiyalarından keçid edildikdə baş verir.\nDaha ətraflı məlumat üçün [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} silmə qeydlərinə] baxın.",
        "searchresults": "Axtarış nəticələri",
+       "search-filter-title-prefix-reset": "Bütün səhifələrdə axtar",
        "searchresults-title": "''$1'' üçün axtarış nəticələri",
        "titlematches": "Səhifə adı eynidir",
        "textmatches": "Mətn eynidir",
        "notextmatches": "Məqalələrdə uyğun məzmun tapılmadı",
        "prevn": "əvvəlki {{PLURAL:$1|$1}}",
-       "nextn": "sonrakı {{PLURAL:$1|$1}}",
+       "nextn": "növbəti {{PLURAL:$1|$1}}",
        "prev-page": "əvvəlki səhifə",
        "next-page": "növbəti səhifə",
        "prevn-title": "Əvvəlki bir $1 {{PLURAL:$1|nəticə|nəticə}}",
        "nextn-title": "Əvvəlki bir $1 {{PLURAL:$1|nəticə|nəticə}}",
        "shown-title": "Səhifə üçün $1 {{PLURAL:$1|nəticə|nəticəyə}} bax",
        "viewprevnext": "Göstər ($1 {{int:pipe-separator}} $2) ($3).",
-       "searchmenu-exists": "'''Bu vikidə \"[[:$1]]\" adında səhifə mövcuddur'''",
+       "searchmenu-exists": "</strong>Bu vikidə \"[[:$1]]\" adında səhifə mövcuddur.</strong> {{PLURAL:$2|0=|Həmçinin tapılmış digər axtarış nəticələrinə də baxın.}}",
        "searchmenu-new": "<strong>Bu viki-layihədə \"[[:$1]]\" səhifəsini yaradın!</strong> {{PLURAL:$2|0=|Həmçinin, axtarışınız əsasında çıxan səhifəyə baxın.|Həmçinin, axtarışınız əsasında çıxan nəticələrə baxın.}}",
        "searchprofile-articles": "Məzmun səhifələri",
        "searchprofile-images": "Multimedia",
        "searchprofile-everything-tooltip": "Bütün səhifələrdə axtar (müzakirə səhifələri daxil)",
        "searchprofile-advanced-tooltip": "Ad aralığında axtar",
        "search-result-size": "$1 ({{PLURAL:$2|1 söz|$2 söz}})",
-       "search-result-category-size": "{{PLURAL:$1|$1 element|$1 elementlər}} ({{PLURAL:$2|$2 alt kateqoriya|$2 alt kateqoriyalar}}, {{PLURAL:$3|$3 fayl|$3 fayllar}})",
+       "search-result-category-size": "{{PLURAL:$1|1 element|$1 element}} ({{PLURAL:$2|1 alt kateqoriya|$2 alt kateqoriya}}, {{PLURAL:$3|1 fayl|$3 fayl}})",
        "search-redirect": "($1 səhifəsindən yönləndirmə)",
        "search-section": "(bölmə $1)",
        "search-category": "(kateqoriya $1)",
        "search-interwiki-caption": "Qonşu layihələrdəki nəticələr",
        "search-interwiki-default": "$1 nəticələri:",
        "search-interwiki-more": "(yenə)",
+       "search-interwiki-more-results": "daha çox nəticə",
        "search-relatedarticle": "əlaqədar",
        "searchrelated": "əlaqəli",
        "searchall": "bütün",
        "username": "{{GENDER:$1|İstifadəçi adı}}:",
        "prefs-memberingroups": "{{GENDER:$2|Üzv}} olduğu {{PLURAL:$1|qrup}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 ($2 qədər)",
        "prefs-registration": "Qeydiyyat vaxtı:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Əsl adınız:",
        "rcfilters-other-review-tools": "Digər yoxlama alətləri",
        "rcfilters-group-results-by-page": "Dəyişiklikləri səhifələrə görə qruplaşdır",
        "rcfilters-activefilters": "Aktiv filtrlər",
+       "rcfilters-activefilters-hide": "Gizlət",
+       "rcfilters-activefilters-show": "Göstər",
        "rcfilters-advancedfilters": "Geniş filtr",
        "rcfilters-limit-title": "Göstərilməli dəyişikliklər",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|redaktə|redaktə}}, $2",
        "deadendpages": "Keçid verməyən səhifələr",
        "deadendpagestext": "Aşağıdakı səhifələrdən bu Vikipediyadakı digər səhifələrə heç bir keçid yoxdur.",
        "protectedpages": "Mühafizəli səhifələr",
+       "protectedpages-filters": "Filtrlər:",
        "protectedpages-indef": "Yalnız müddətsiz mühafizələr",
        "protectedpages-cascade": "Yalnız kaskad mühafizələr",
        "protectedpagesempty": "Hal-hazırda bu parametrə uyğun heç bir mühafizəli səhifə yoxdur",
        "pager-newer-n": "{{PLURAL:$1|1 daha yeni|$1 daha yeni}}",
        "pager-older-n": "{{PLURAL:$1|1 daha köhnə|$1 daha köhnə}}",
        "suppress": "Gizlət",
+       "apisandbox-helpurls": "Kömək linkləri",
+       "apisandbox-add-multi": "Əlavə et",
        "apisandbox-results": "Nəticələr",
+       "apisandbox-multivalue-all-namespaces": "$1 (Bütün ad fəzaları)",
        "booksources": "Kitab mənbələri",
        "booksources-search-legend": "Kitab mənbələri axtar",
        "booksources-isbn": "ISBN:",
        "listgrouprights-addgroup-self-all": "Bütün qrupları öz hesabına əlavə edə bilər",
        "listgrouprights-removegroup-self-all": "Bütün qrupları öz hesabından çıxara bilər",
        "listgrouprights-namespaceprotection-namespace": "Adlar fəzası",
+       "listgrants-rights": "Hüquqlar",
+       "trackingcategories-name": "Mesaj adı",
        "restricted-displaytitle-ignored": "İmtina edilmiş görüntü başlıqlarına malik səhifələr",
        "mailnologin": "Ünvan yoxdur",
        "emailuser": "İstifadəçiyə e-məktub göndər",
        "emailuser-title-target": "Bu {{GENDER:$1|istifadəçiyə}} e-məktub göndər",
+       "emailuser-title-notarget": "İstifadəçi e-maili",
        "defemailsubject": "\"$1\" adlı istifadəçidən {{SITENAME}} e-məktubu",
        "usermaildisabled": "İstifadəçi e-maili işləmir",
        "noemailtitle": "E-məktub ünvanı yoxdur",
        "watchlist-submit": "Göstər",
        "wlshowhideminor": "kiçik redaktələr",
        "wlshowhidebots": "botlar",
+       "wlshowhideliu": "qeydiyyatdan keçmiş istifadəçilər",
+       "wlshowhideanons": "anonim istifadəçilər",
        "wlshowhidemine": "mənimn redaktələrim",
        "watchlist-options": "İzləmə siyahısının nizamlamaları",
        "watching": "İzlənilir...",
        "ipb-disableusertalk": "Bu istifadəçi bloklu olarkən öz müzakirə səhifəsində redaktə etməsinə qadağa qoy",
        "ipb-change-block": "Bu səbəblərlə istifadəçini yenidən blokla",
        "ipb-confirm": "Bloku təsdiqlə",
+       "ipb-pages-label": "Səhifələr",
+       "ipb-namespaces-label": "Adlar fəzası",
        "badipaddress": "Səhv IP",
        "blockipsuccesssub": "Bloklandı",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] bloklanıb.<br />\nBlokları yoxlamaq üçün [[Special:BlockList|bloklama siyahısına]] baxın.",
        "ipb-blocklist": "Mövcud blokları göstər",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}} istifadəçi hesabının fəaliyyətləri",
        "block-expiry": "Bitmə müddəti:",
+       "block-reason": "Səbəb:",
        "unblockip": "İstifadəçinin blokunu götür",
        "unblockiptext": "Əvvəlcədən bloklanmış bir IP ünvanına və ya istifadəçi adına yazma geri vermek için aşağıdakı formadan istifadə edin.",
        "ipusubmit": "Bu bloku götür",
        "createaccountblock": "Yeni hesab yaratma bloklanıb",
        "emailblock": "E-mail bloklanıb",
        "blocklist-nousertalk": "Müzakirə səhifəsini redaktə edə bilməz.",
+       "blocklist-editing-page": "səhifələr",
+       "blocklist-editing-ns": "adlar fəzası",
        "ipblocklist-empty": "Blok siyahısı boşdur.",
        "ipblocklist-no-results": "Tələb olunan IP ünvanı və ya istifadəçi bloklanmadı.",
        "blocklink": "blokla",
        "thumbnail_image-missing": "Belə görünür ki, $1 faylı yoxdur",
        "import": "Səhifələri idxal et",
        "importinterwiki": "Başqa vikidən idxal et",
+       "import-interwiki-sourcepage": "Mənbə səhifəsi:",
        "import-interwiki-history": "Səhifənin dəyişmə tarixçələrinin hamısını köçür",
        "import-interwiki-templates": "Bütün şablonlarla birlikdə",
        "import-interwiki-submit": "İdxal",
        "pageinfo-contentpage-yes": "Bəli",
        "pageinfo-protect-cascading": "Kaskad mühafizə burada qoşulub",
        "pageinfo-protect-cascading-yes": "Bəli",
+       "pageinfo-category-info": "Kateqoriya məlumatı",
        "pageinfo-category-pages": "Səhifələrin sayı",
        "pageinfo-category-subcats": "Altkateqoriyaların sayı",
        "pageinfo-category-files": "Faylların sayı",
        "markedaspatrollederror": "Yoxlanmadı",
        "markedaspatrollederror-noautopatrol": "Öz dəyişikliklərinizi yoxlayıb işarələyə bilməzsiniz.",
        "markedaspatrollednotify": "\"$1\" səhifəsindəki bu redaktə patrullanmış kimi işarələndi.",
+       "markedaspatrollederrornotify": "Patrullanma uğursuz oldu.",
        "patrol-log-page": "Patrul gündəliyi",
        "patrol-log-header": "Bu yoxlanmış dəyişikliklərin gündəliyidir.",
        "deletedrevision": "Köhnə versiyaları silindi $1.",
        "hours": "{{PLURAL:$1|$1 saat|$1 saat}}",
        "days": "{{PLURAL:$1|$1 gün|$1 gün}}",
        "ago": "$1 əvvəl",
+       "monday-at": "Bazar ertəsi $1",
        "bad_image_list": "Format bu şəkildə olmalıdır:\n\nYalnız siyahı bəndləri (* işarəsi ilə başlayan sətirlər) nəzərə alınır.\nSətirdəki ilk keçid, əlavə olunması qadağan olunmuş şəkilə keçid olmalıdır.\nHəmin sətirdəki növbəti keçidlər istisna hesab olunur. Məsələn, fayl məqalədə sətrin içində görünə bilər.",
        "variantname-zh-hans": "hans",
        "variantname-zh-hant": "hant",
        "confirm-purge-top": "Bu səhifə keşdən (cache) silinsin?",
        "confirm-watch-button": "OK",
        "confirm-unwatch-button": "OK",
+       "confirm-rollback-button": "Oldu",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← əvvəlki səhifə",
        "imgmultipagenext": "sonrakı səhifə →",
        "imgmultigo": "Seç!",
        "imgmultigoto": "$1 səhifəyə get",
+       "img-lang-go": "Get",
        "ascending_abbrev": "artma sırasına görə",
        "descending_abbrev": "azalma sırasına görə",
        "table_pager_next": "Sonrakı səhifə",
        "watchlistedit-raw-done": "İzləmə səhifələriniz qeyd olundu.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 title was|$1 başlıq}} əlavə edildi:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 title was|$1 başlıq}} çıxarıldı:",
+       "watchlistedit-clear-titles": "Başlıqlar:",
        "watchlisttools-clear": "İzləmə siyahısını təmizlə",
        "watchlisttools-view": "Siyahıdakı səhifələrdə edilən dəyişikliklər",
        "watchlisttools-edit": "İzlədiyim səhifələri göstər və redaktə et",
        "watchlisttools-raw": "Adi mətn kimi redaktə et",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|müzakirə]])",
+       "timezone-local": "Lokal",
        "duplicate-defaultsort": "<strong>Diqqət:</strong> Susmaya görə \"$2\" çeşidləmə açarı susmaya görə əvvəlki \"$1\" çeşidləmə açarını inkar edir.",
        "version": "Versiya",
        "version-extensions": "NIzamlanmış genişlənmələr",
        "version-specialpages": "Xüsusi səhifələr",
        "version-parserhooks": "Parser hooks",
        "version-variables": "Dəyişkənlər",
+       "version-editors": "Redaktorlar",
        "version-antispam": "Spam önləmə",
        "version-other": "Digər",
        "version-hooks": "Çəngəllər",
        "version-hook-name": "Çəngəlin adı",
        "version-hook-subscribedby": "Abunə olan",
        "version-version": "($1)",
+       "version-no-ext-name": "[adsız]",
        "version-license": "MediaViki lisenziyası",
        "version-ext-license": "Lisenziya",
        "version-ext-colheader-version": "Versiya",
        "version-software-version": "Versiya",
        "version-entrypoints-header-url": "URL",
        "version-libraries-library": "Kitabxana",
+       "version-libraries-version": "Versiya",
+       "version-libraries-license": "Lisenziya",
        "version-libraries-authors": "Müəlliflər",
        "redirect-submit": "Keç",
        "redirect-lookup": "Bax",
        "htmlform-no": "Xeyr",
        "htmlform-yes": "Bəli",
        "htmlform-cloner-create": "Əlavə et",
+       "htmlform-date-placeholder": "İL-AY-GÜN",
        "logentry-delete-delete": "$1 $3 səhifəsini {{GENDER:$2|sildi}}",
        "logentry-suppress-delete": "$1 $3 səhifəsini {{GENDER:$2|gizlətdi}}",
        "revdelete-content-hid": "gizli mətn",
        "logentry-newusers-autocreate": "$1 istifadəçi hesabı avtomatik yaradıldı",
        "logentry-upload-upload": "$1 $3 faylını {{GENDER:$2|yüklədi}}.",
        "rightsnone": "(yoxdur)",
+       "feedback-back": "Əvvəlki",
        "feedback-bugnew": "Mən yoxladım. Yeni xəta barədə xəbər ver",
        "feedback-cancel": "İmtina",
        "feedback-close": "Oldu",
        "feedback-error2": "Xəta: Redaktə qeydə alınmadı",
        "feedback-message": "Mesaj:",
        "feedback-subject": "Mövzu:",
+       "feedback-submit": "Təsdiq et",
        "feedback-thanks-title": "Təşəkkür!",
        "searchsuggest-search": "{{grammar:prepositional|{{SITENAME}}}} axtar",
        "api-error-unknown-warning": "Naməlum xəbərdarlıq: \"$1\".",
        "limitreport-postexpandincludesize-value": "$1/$2 bayt",
        "expand_templates_output": "Nəticə",
        "expand_templates_ok": "OK",
+       "expand_templates_preview": "Sınaq görüntüsü",
        "pagelang-name": "Səhifə",
        "pagelang-language": "Dil",
+       "pagelang-select-lang": "Dili seçin",
+       "pagelang-reason": "Səbəb",
+       "pagelang-submit": "Təsdiq et",
+       "mediastatistics": "Media statistikası",
        "mediastatistics-nbytes": "$1 bayt ($2; $3%)",
+       "mediastatistics-table-count": "Faylların sayı",
        "mediastatistics-header-unknown": "Naməlum",
        "mediastatistics-header-audio": "Audio",
        "mediastatistics-header-video": "Videolar",
        "mediastatistics-header-office": "Ofis",
        "mediastatistics-header-text": "Mətn",
+       "mediastatistics-header-total": "Bütün fayllar",
        "special-characters-group-latin": "Latın",
        "special-characters-group-latinextended": "Latın genişləndirilmiş",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-khmer": "Khmer",
        "mw-widgets-dateinput-no-date": "Tarix seçilməyib",
        "mw-widgets-usersmultiselect-placeholder": "Əlavə et...",
+       "mw-widgets-titlesmultiselect-placeholder": "Əlavə et...",
        "date-range-from": "Tarixindən:",
-       "date-range-to": "Tarixədək:"
+       "date-range-to": "Tarixədək:",
+       "log-action-filter-all": "Hamısı",
+       "log-action-filter-block-block": "Bloklama",
+       "log-action-filter-upload-upload": "Yeni yükləmə"
 }
index 4653868..5e9f93e 100644 (file)
        "grant-group-high-volume": "Юғары әүҙемлекле алым эшләргә",
        "grant-group-customization": "Көйләүҙәр һәм өҫтөнлөк биргән көйләүҙәр",
        "grant-group-administration": "Административ алымдар ҡулланыу",
-       "grant-group-private-information": "Доступ к конфиденциальным данным о вас\nҺеҙҙең туралағы йәшерелгән белешмәләргә инеү",
+       "grant-group-private-information": "Һеҙҙең туралағы йәшерелгән белешмәләргә инеү",
        "grant-group-other": "Әүҙемлек төрлө",
        "grant-blockusers": "Иҫәп яҙмаларын блоклау һәм блоклауҙы асыу",
        "grant-createaccount": "Иҫәп яҙмаһын булдырырға",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|фекер алышыу]]) уҙгәртеүҙәре [[User:$1|$1]] өлгөһөнә ҡайтарылды",
        "revertpage-nouser": "(Ҡатнашыусының исеме йәшерелгән) үҙгәртеүҙәре {{GENDER:$1|[[User:$1|$1]]}}өлгөһөнә ҡайтарылды",
        "rollback-success": "{{GENDER:$3|$1}} үҙгәртеүҙәре кире алынды; {{GENDER:$4|$2}} версияһына ҡайтарылды.",
-       "rollback-success-notify": "Төҙәтеүҙәр кире тейәлгән $1; һуңғы $2 версияға кире ҡайтыу. [$3 Үҙгәрештәрҙе күрһәтеү]",
        "sessionfailure-title": "Сеанс хатаһы",
        "sessionfailure": "Хәҙерге сеанста хаталар килеп сыҡҡан, булырға тейеш;\n\"сеансты баҫып алыу\"ға юл ҡуймау өсөн был ғәмәл үтәлмәне.\nАлдағы биткә кире  ҡайтығыҙ, битте яңыртығыҙ һәм яңынан ҡабатлап ҡарағыҙ.",
        "changecontentmodel": "Биттең контент моделен мөхәррирләү",
        "log-action-filter-upload-upload": "Яңы күсереү",
        "log-action-filter-upload-overwrite": "Ҡабаттан тейәү",
        "authmanager-create-disabled": "Иҫәп яҙмаһын булдырыу бикләнгән.",
-       "authmanager-authplugin-setpass-failed-title": "Серһүҙҙе үҙгәртеү хатаһы",
        "authmanager-userdoesnotexist": "\"$1\" иҫәп яҙмаһы теркәлмәгән.",
        "authmanager-domain-help": "Тышҡы аутентификация домены (өҫтәмә).",
        "authmanager-email-label": "Электрон почта адресы",
index f5aedb0..00e65d3 100644 (file)
@@ -14,7 +14,8 @@
                        "Mjbmr",
                        "Macofe",
                        "Matěj Suchánek",
-                       "Rachitrali"
+                       "Rachitrali",
+                       "Sultanselim baloch"
                ]
        },
        "tog-underline": ":لینکانآ خط کش",
        "special-characters-group-devanagari": "دیواناگرى",
        "special-characters-group-thai": "تایلندی",
        "special-characters-group-lao": "لائو",
-       "special-characters-group-khmer": "خمر"
+       "special-characters-group-khmer": "خمر",
+       "log-action-filter-upload-revert": "Cahr Dayag"
 }
index f0ad576..33ff020 100644 (file)
@@ -65,6 +65,7 @@
        "tog-norollbackdiff": "Не паказваць зьмены пасьля выкананьня адкату",
        "tog-useeditwarning": "Папярэджваць мяне, калі я буду пакідаць старонку рэдагаваньня зь незахаванымі зьменамі",
        "tog-prefershttps": "Заўсёды карыстацца бясьпечным злучэньнем па ўваходзе ў сыстэму",
+       "tog-showrollbackconfirmation": "Паказваць акно пацьвярджэньня пры націсканьні спасылкі адкату",
        "underline-always": "Заўсёды",
        "underline-never": "Ніколі",
        "underline-default": "Паводле браўзэра або афармленьня",
        "badretype": "Уведзеныя Вамі паролі не супадаюць.",
        "usernameinprogress": "Стварэньне рахунку з гэтым імем удзельніка ўжо ідзе. Калі ласка, пачакайце.",
        "userexists": "Уведзенае Вамі імя ўдзельніка ўжо выкарыстоўваецца кімсьці іншым. \nКалі ласка, выберыце іншае імя.",
+       "createacct-normalization": "Вашае імя карыстальніка будзе скарэктаванае на «$2» праз тэхнічныя абмежаваньні.",
        "loginerror": "Памылка ўваходу",
        "createacct-error": "Памылка стварэньня рахунку",
        "createaccounterror": "Немагчыма стварыць рахунак: $1",
        "last": "папярэдняя",
        "page_first": "першая",
        "page_last": "апошняя",
-       "histlegend": "Ð\9fаÑ\80аÑ\9eнанÑ\8cне: Ð¿Ð°Ð·Ð½Ð°Ñ\87Ñ\86е ÐºÑ\80опкамі дзьве вэрсіі для параўнаньня і націсьніце «ўвод» альбо кнопку ўнізе.<br />\nТлумачэньне: <strong>({{int:cur}})</strong> = адрозьненьні ад цяперашняй вэрсіі, <strong>({{int:last}})</strong> = адрозьненьні ад папярэдняй вэрсіі, <strong>{{int:minoreditletter}}</strong> = дробная праўка.",
-       "history-fieldset-title": "Ð\9fоÑ\88Ñ\83к вэрсіяў",
+       "histlegend": "Ð\9fаÑ\80аÑ\9eнанÑ\8cне: Ð°Ð´Ð·Ð½Ð°Ñ\87Ñ\86е Ð¿Ñ\83нкÑ\82амі дзьве вэрсіі для параўнаньня і націсьніце «ўвод» альбо кнопку ўнізе.<br />\nТлумачэньне: <strong>({{int:cur}})</strong> = адрозьненьні ад цяперашняй вэрсіі, <strong>({{int:last}})</strong> = адрозьненьні ад папярэдняй вэрсіі, <strong>{{int:minoreditletter}}</strong> = дробная праўка.",
+       "history-fieldset-title": "ФÑ\96лÑ\8cÑ\82аÑ\80 вэрсіяў",
        "history-show-deleted": "Толькі выдаленыя",
        "histfirst": "найстарэйшыя",
        "histlast": "найноўшыя",
        "historysize": "($1 {{PLURAL:$1|байт|байты|байтаў}})",
-       "historyempty": "(пуста)",
+       "historyempty": "пуста",
        "history-feed-title": "Гісторыя зьменаў",
        "history-feed-description": "Гісторыя зьменаў гэтай старонкі ў вікі",
        "history-feed-item-nocomment": "$1 у $2",
        "right-reupload-own": "Перазапіс уласных існых файлаў",
        "right-reupload-shared": "Перазапіс файлаў з агульнага сховішча лякальнымі",
        "right-upload_by_url": "Загрузка файлаў з URL-адрасу",
-       "right-purge": "аÑ\87Ñ\8bÑ\81Ñ\82ка ÐºÑ\8dÑ\88Ñ\83 Ñ\81Ñ\82аÑ\80онак Ð±Ñ\8fз Ð·Ð°Ð¿Ñ\8bÑ\82Ñ\83 Ð¿Ð°Ñ\86Ñ\8cвеÑ\80джанÑ\8cнÑ\8f",
+       "right-purge": "Ð\90Ñ\87Ñ\8bÑ\81Ñ\82ка ÐºÑ\8dÑ\88Ñ\83 Ñ\81айÑ\82Ñ\83 Ð´Ð»Ñ\8f Ñ\81Ñ\82аÑ\80онкÑ\96",
        "right-autoconfirmed": "Ня дзейнічаюць абмежаваньні хуткасьці па IP",
        "right-bot": "Лічыцца аўтаматычным працэсам",
        "right-nominornewtalk": "Не паведамляць удзельнікам пра новыя паведамленьні на іх старонках гутарак, калі зробленыя там праўкі былі дробнымі",
        "pager-newer-n": "$1 {{PLURAL:$1|навейшая|навейшыя|навейшых}}",
        "pager-older-n": "$1 {{PLURAL:$1|старэйшая|старэйшыя|старэйшых}}",
        "suppress": "Падавіць вэрсію",
-       "querypage-disabled": "Гэта спэцыяльная старонка адключаная для падвышэньня прадукцыйнасьці",
+       "querypage-disabled": "Гэтая спэцыяльная старонка адключаная для падвышэньня прадукцыйнасьці.",
        "apihelp": "Даведка API",
        "apihelp-no-such-module": "Модуль «$1» ня знойдзены.",
        "apisandbox": "Пясочніца API",
        "apisandbox-jsonly": "Для выкарыстаньня API-пясочніцы патрэбны JavaScript.",
-       "apisandbox-api-disabled": "API Ð·Ð°Ð±Ð°Ñ\80онены на гэтым сайце.",
+       "apisandbox-api-disabled": "API Ð°Ð´ÐºÐ»Ñ\8eÑ\87аны на гэтым сайце.",
        "apisandbox-intro": "Выкарыстоўвайце гэтую старонку для экспэрымэнтаў з <strong>API вэб-сэрвісу MediaWiki</strong>.\nЗьвяртайцеся да [[mw:API:Main page|дакумэнтацыі API]] для дадатковай інфармацыі па выкарыстаньні API. Напрыклад, [https://www.mediawiki.org/wiki/API#A_simple_example як атрымаць зьмест галоўнай старонкі]. Абярыце дзеяньне, каб пабачыць болей узораў.\n\nЗьвярніце ўвагу, што нягледзячы на тое, што гэта пясочніца, вашыя дзеяньні могуць унесьці зьмены ў вікі.",
        "apisandbox-submit": "Зрабіць запыт",
        "apisandbox-reset": "Ачысьціць",
        "booksources-search-legend": "Пошук кніг",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Шукаць",
-       "booksources-text": "Ð\9dÑ\96жÑ\8dй Ð·Ð½Ð°Ñ\85одзÑ\96Ñ\86Ñ\86а Ñ\81Ñ\8cпÑ\96Ñ\81 Ñ\81паÑ\81Ñ\8bлак Ð½Ð° Ñ\96нÑ\88Ñ\8bÑ\8f Ñ\81айÑ\82Ñ\8b, Ñ\8fкÑ\96Ñ\8f Ð¿Ñ\80адаÑ\8eÑ\86Ñ\8c Ð½Ð¾Ð²Ñ\8bÑ\8f Ñ\96 Ð¿Ð°Ñ\82Ñ\80Ñ\8bманÑ\8bÑ\8f ÐºÐ½Ñ\96гÑ\96, Ñ\96 Ð¼Ð¾Ð³Ñ\83Ñ\86Ñ\8c Ñ\82акÑ\81ама Ð¼ÐµÑ\86Ñ\8c Ñ\96нÑ\84аÑ\80маÑ\86Ñ\8bÑ\8e Ð¿Ñ\80а ÐºÐ½Ñ\96гÑ\96, Ñ\8fкÑ\96Ñ\8f Ð\92ы шукаеце:",
+       "booksources-text": "Ð\9dÑ\96жÑ\8dй Ð·Ð½Ð°Ñ\85одзÑ\96Ñ\86Ñ\86а Ñ\81Ñ\8cпÑ\96Ñ\81 Ñ\81паÑ\81Ñ\8bлак Ð½Ð° Ñ\96нÑ\88Ñ\8bÑ\8f Ñ\81айÑ\82Ñ\8b, Ñ\8fкÑ\96Ñ\8f Ð¿Ñ\80адаÑ\8eÑ\86Ñ\8c Ð½Ð¾Ð²Ñ\8bÑ\8f Ñ\96 Ð¿Ð°Ñ\82Ñ\80Ñ\8bманÑ\8bÑ\8f ÐºÐ½Ñ\96гÑ\96, Ñ\96 Ð¼Ð¾Ð³Ñ\83Ñ\86Ñ\8c Ñ\82акÑ\81ама Ð¼ÐµÑ\86Ñ\8c Ñ\96нÑ\84аÑ\80маÑ\86Ñ\8bÑ\8e Ð¿Ñ\80а ÐºÐ½Ñ\96гÑ\96, Ñ\8fкÑ\96Ñ\8f Ð²ы шукаеце:",
        "booksources-invalid-isbn": "Пададзены няслушны ISBN; праверце, магчыма ўзьніклі памылкі пры пераносе нумару з арыгінальнай крыніцы.",
        "magiclink-tracking-rfc": "Старонкі, на якіх ужытыя магічныя спасылкі RFC",
        "magiclink-tracking-rfc-desc": "На гэтай старонцы ўжываюцца магічныя спасылкі RFC. Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] пра тое, як зладзіць міграцыю.",
        "alllogstext": "Сумесны паказ усіх журналаў падзеяў {{GRAMMAR:родны|{{SITENAME}}}}.\nВы можаце адфільтраваць вынікі па тыпе журналу, удзельніку (улічваецца рэгістар) ці старонцы (таксама ўлічваецца рэгістар).",
        "logempty": "Падобных запісаў у журнале няма.",
        "log-title-wildcard": "Шукаць назвы, якія пачынаюцца з гэтага тэксту",
-       "showhideselectedlogentries": "Ð\9fаказаÑ\86Ñ\8c\81Ñ\85аваÑ\86Ñ\8c Ð²Ñ\8bбÑ\80анÑ\8bÑ\8f Ð·Ð°Ð¿Ñ\96Ñ\81Ñ\8b Ñ\9e журнале",
+       "showhideselectedlogentries": "Ð\97Ñ\8cмÑ\8fнÑ\96Ñ\86Ñ\8c Ð±Ð°Ñ\87наÑ\81Ñ\8cÑ\86Ñ\8c Ð°Ð±Ñ\80анÑ\8bÑ\85 Ð·Ð°Ð¿Ñ\96Ñ\81аÑ\9e Ñ\83 журнале",
        "log-edit-tags": "Рэдагаваць меткі да абраных запісаў у журнале падзеяў",
        "checkbox-select": "Выбраць: $1",
        "checkbox-all": "усе",
        "allpages": "Усе старонкі",
        "nextpage": "Наступная старонка ($1)",
        "prevpage": "Папярэдняя старонка ($1)",
-       "allpagesfrom": "Паказаць старонкі, пачынаючы з:",
+       "allpagesfrom": "Паказаць старонкі ад:",
        "allpagesto": "Паказаць старонкі да:",
        "allarticles": "Усе старонкі",
        "allinnamespace": "Усе старонкі (прастора назваў: $1)",
        "delete-confirm": "Выдаліць «$1»",
        "delete-legend": "Выдаліць",
        "historywarning": "<strong>Папярэджаньне</strong>: старонка, якую Вы зьбіраецеся выдаліць, мае гісторыю з $1 {{PLURAL:$1|вэрсіі|вэрсіяў|вэрсіяў}}:",
-       "historyaction-submit": "Паказаць",
+       "historyaction-submit": "Паказаць вэрсіі",
        "confirmdeletetext": "Зараз Вы выдаліце старонку разам з усёй гісторыяй зьменаў.\nКалі ласка, пацьвердзіце, што Вы зьбіраецеся гэта зрабіць і што Вы разумееце ўсе наступствы, а таксама робіце гэта ў адпаведнасьці з [[{{MediaWiki:Policy-url}}|правіламі]].",
        "actioncomplete": "Дзеяньне выкананае",
        "actionfailed": "Дзеяньне ня выкананае",
        "deleting-backlinks-warning": "<strong>Увага:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|іншыя старонкі]] ўключаюць або спасылаюцца на старонку, якую вы зьбіраецеся выдаліць.",
        "deleting-subpages-warning": "<strong>Папярэджаньне:</strong> старонка, якую вы зьбіраецеся выдаліць, мае [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1 падстаронку|$1 падстаронкі|$1 падстаронак|51=болей за 50 падстаронак}}]].",
        "rollback": "Адкаціць рэдагаваньні",
+       "rollback-confirmation-confirm": "Калі ласка, пацьвердзіце:",
+       "rollback-confirmation-yes": "Адкаціць",
+       "rollback-confirmation-no": "Адмяніць",
        "rollbacklink": "адкат",
        "rollbacklinkcount": "адкаціць $1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}}",
        "rollbacklinkcount-morethan": "адкаціць больш за $1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}}",
        "revertpage": "Рэдагаваньні [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]]) скасаваныя да папярэдняй вэрсіі [[User:$1|$1]]",
        "revertpage-nouser": "Рэдагаваньні схаванага ўдзельніка скасаваныя да папярэдняй вэрсіі {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Адмененыя рэдагаваньні {{GENDER:$3|$1}};\nвернутая папярэдняя вэрсія {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Адмененыя праўкі $1;\nвернутая папярэдняя вэрсія $2. [$3 Паказаць зьмены]",
        "sessionfailure-title": "Памылка сэсіі",
        "sessionfailure": "Магчыма ўзьніклі праблемы ў вашым цяперашнім сэансе працы;\nгэтае дзеяньне было скасаванае для прадухіленьня перахопу сэансу.\nКалі ласка, падайце форму яшчэ раз.",
        "changecontentmodel": "Зьмена мадэлі зьместу старонкі",
        "mycontris": "Унёсак",
        "anoncontribs": "Унёсак",
        "contribsub2": "Для {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Для {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Рахунак удзельніка «$1» не зарэгістраваны.",
        "negative-namespace-not-supported": "Прасторы назваў з адмоўнымі значэньнямі не падтрымліваюцца.",
        "nocontribs": "Ня знойдзена зьменаў, якія адпавядаюць гэтым крытэрыям.",
        "ipb-confirm": "Пацьвердзіць блякаваньне",
        "ipb-sitewide": "На ўсім сайце",
        "ipb-partial": "Частковая",
+       "ipb-sitewide-help": "Кожная старонка ў гэтай вікі і ўсе іншыя дзеяньні.",
+       "ipb-partial-help": "Вызначаныя старонкі ці прасторы назваў.",
        "ipb-pages-label": "Старонкі",
        "ipb-namespaces-label": "Прасторы назваў",
        "badipaddress": "Некарэктны IP-адрас",
        "confirm-unwatch-top": "Выдаліць гэтую старонку з Вашага сьпісу назіраньня?",
        "confirm-rollback-button": "Так",
        "confirm-rollback-top": "Адкаціць праўкі на гэтай старонцы?",
+       "confirm-rollback-bottom": "Гэтае дзеяньне імгненна адкоціць абраныя зьмены гэтай старонкі.",
        "confirm-mcrrestore-title": "Аднавіць вэрсію",
        "confirm-mcrundo-title": "Адмяніць зьмену",
        "mcrundofailed": "Адмена не атрымалася",
        "logentry-rights-autopromote": "$1 {{GENDER:$1|быў аўтаматычна пераведзены|была аўтаматычна пераведзеная}} з групы $4 ў $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|загрузіў|загрузіла}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|загрузіў|загрузіла}} новую вэрсію $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|загÑ\80Ñ\83зÑ\96Ñ\9e|загÑ\80Ñ\83зÑ\96ла}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|вÑ\8fÑ\80нÑ\83Ñ\9e|вÑ\8fÑ\80нÑ\83ла}} $3 Ð´Ð° Ñ\81Ñ\82аÑ\80ой Ð²Ñ\8dÑ\80Ñ\81Ñ\96Ñ\96",
        "log-name-managetags": "Журнал кіраваньня меткамі",
        "log-description-managetags": "На гэтай старонцы пералічаныя спасылкі, зьвязаныя зь [[Special:Tags|меткамі]]. Журнал зьмяшчае толькі падзеі, выкананыя адміністратарам уручную; меткі могуць быць створаныя або выдаленыя праграмным забесьпячэньнем вікі бяз запісу пра падзею ў журнал.",
        "logentry-managetags-create": "$1 {{GENDER:$2|стварыў|стварыла}} метку «$4»",
        "log-action-filter-suppress-reblock": "Утойваньне ўдзельніка праз паўторнае блякаваньне",
        "log-action-filter-upload-upload": "Новая загрузка",
        "log-action-filter-upload-overwrite": "Паўторная загрузка",
+       "log-action-filter-upload-revert": "Адкат",
        "authmanager-authn-not-in-progress": "Аўтэнтыфікацыя не выконваецца або страчаныя зьвесткі пра сэсію. Калі ласка, пачніце зноў з самага пачатку.",
        "authmanager-authn-no-primary": "Пададзеныя ўліковыя зьвесткі ня могуць быць правераныя на сапраўднасьць.",
        "authmanager-authn-no-local-user": "Пададзеныя ўліковыя зьвесткі не зьвязаныя зь ніводным удзельнікам гэтай вікі.",
        "authmanager-create-no-primary": "Пададзеныя ўліковыя зьвесткі ня могуць быць выкарыстаныя для стварэньня рахунку.",
        "authmanager-link-no-primary": "Пададзеныя ўліковыя зьвесткі ня могуць быць выкарыстаныя для злучэньня рахункаў.",
        "authmanager-link-not-in-progress": "Злучэньне рахункаў не выконваецца або страчаныя зьвесткі сэсіі. Калі ласка, пачніце ізноў спачатку.",
-       "authmanager-authplugin-setpass-failed-title": "Памылка зьмены паролю",
-       "authmanager-authplugin-setpass-failed-message": "Дадатак аўтэнтыфікацыі адмовіў зьмену паролю.",
-       "authmanager-authplugin-create-fail": "Дадатак аўтэнтыфікацыі адмовіў у стварэньні рахунку.",
-       "authmanager-authplugin-setpass-denied": "Дадатак аўтэнтыфікацыі не дазваляе зьмяняць паролі.",
-       "authmanager-authplugin-setpass-bad-domain": "Няслушны дамэн.",
        "authmanager-autocreate-noperm": "Аўтаматычнае стварэньне рахункаў не дазволенае.",
        "authmanager-autocreate-exception": "Аўтаматычнае стварэньне рахункаў часова адключанае праз папярэднія памылкі.",
        "authmanager-userdoesnotexist": "Рахунак «$1» не зарэгістраваны.",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль мусіць быць даўжынёй менш за $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Пароль ня можа {{PLURAL:$1|супадаць з самым папулярным паролем|быць зь сьпісу $1 папулярных пароляў}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль ня можа быць зь сьпісу 100 000 найчасьцей ужываных пароляў.",
+       "passwordpolicies-policyflag-forcechange": "мусіць быць зьменены па ўваходзе",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "прапаноўваць зьмену па ўваходзе",
        "easydeflate-invaliddeflate": "Пададзены зьмест ня сьціснуты адпаведным чынам",
        "unprotected-js": "З прычынаў бясьпекі JavaScript ня можа быць загружаны зь неабароненых сайтаў. Калі ласка, стварайце javascript выключна ў прасторы назваў MediaWiki: ці як падстаронку ўдзельніка"
 }
index be1b221..7d6e3f0 100644 (file)
@@ -81,6 +81,7 @@
        "tog-norollbackdiff": "Не паказваць розніцу ў выніку адкату",
        "tog-useeditwarning": "Папярэдзіць мяне, калі я пакідаю старонку з незахаванымі праўкамі",
        "tog-prefershttps": "Заўсёды выкарыстоўваць бяспечнае злучэнне па ўваходзе ў сістэму",
+       "tog-showrollbackconfirmation": "Паказваць акно пацвярджэння пры націску спасылкі адкату",
        "underline-always": "Заўсёды",
        "underline-never": "Ніколі",
        "underline-default": "Як у браўзеры",
        "returnto": "Вярнуцца да $1.",
        "tagline": "З пляцоўкі {{SITENAME}}",
        "help": "Даведка",
+       "help-mediawiki": "Дапамога пра MediaWiki",
        "search": "Знайсці",
        "search-ignored-headings": " #<!-- не змяняйце гэты радок --> <pre>\n# Загалоўкі, якія будзе ігнараваць рухавік пошуку.\n# Змены набудуць моц па наступным індэксаванні старонкі.\n# Вы можаце змусіць пераіндэксаванне старонкі, зрабіўшы пустое рэдагаванне.\n# Сінтаксіс наступны:\n#   * Усё ад сімвала \"#\" да канца радка - каментарый.\n#   * Кожны непусты радок - дакладны загаловак, які трэба ігнараваць, з рэгістрам і інш.\nКрыніцы\nСпасылкі\nГл. таксама\n #</pre> <!-- не змяняйце гэты радок -->",
        "searchbutton": "Знайсці",
        "ns-specialprotected": "Не дазволена правіць старонкі ў прасторы назваў {{ns:special}}.",
        "titleprotected": "Назва засцерагаецца ад стварэння; ахова пастаўлена ўдзельнікам: [[User:$1|$1]].\nТлумачэнне пастаноўкі пад ахову: <em>$2</em>.",
        "filereadonlyerror": "Немагчыма змяніць файл \"$1\", таму што файлавае сховішча \"$2\" зараз у рэжыме \"толькі для чытання\".\n\nСістэмны адміністратар, які абмежаваў доступ, патлумачыў гэта так: \"$3\".",
+       "invalidtitle": "Няслушная назва",
        "invalidtitle-knownnamespace": "Недапушчальны загаловак з прасторай імёнаў \"$2\" і тэкстам \"$3\"",
        "invalidtitle-unknownnamespace": "Недапушчальны загаловак з невядомым лікам прасторы імён $1 і тэкстам \"$2\"",
        "exception-nologin": "Вы не ўвайшлі ў сістэму",
        "resetpass-temp-password": "Тымчасовы пароль:",
        "resetpass-abort-generic": "Змяненне пароля было спынена прыстаўкаю.",
        "resetpass-expired": "Ваш пароль пратэрмінаваны. Калі ласка, устанавіце новы пароль для ўваходу ў сістэму.",
-       "resetpass-expired-soft": "Ваш пароль пратэрмінаваны, яго трэба замяніць. Калі ласка, выберыце новы пароль зараз, ці націсніце \"{{int:authprovider-resetpass-skip-label}}\", каб змяніць яго пазней.",
+       "resetpass-expired-soft": "Ваш пароль пратэрмінаваны і яго трэба замяніць. Калі ласка, выберыце новы пароль зараз, ці націсніце \"{{int:authprovider-resetpass-skip-label}}\", каб змяніць яго пазней.",
+       "resetpass-validity": "Ваш пароль няверны: $1 \n\nКалі ласка, устанавіце новы пароль для ўваходу ў сістэму.",
        "resetpass-validity-soft": "Ваш пароль недапушчальны: $1\n\nКалі ласка, выберыце новы пароль зараз, або націсніце \"{{int:authprovider-resetpass-skip-label}}\", каб скінуць яго пазней.",
        "passwordreset": "Выслаць мне новы пароль",
        "passwordreset-text-one": "Запоўніце гэту форму, каб атрымаць часовы пароль па эл.пошце.",
        "histfirst": "найстарэйшыя",
        "histlast": "найноўшыя",
        "historysize": "({{PLURAL:$1|1 байт|$1 байты|$1 байтаў}})",
-       "historyempty": "(пуста)",
+       "historyempty": "пуста",
        "history-feed-title": "Гісторыя версій",
        "history-feed-description": "Гісторыя версій гэтай старонкі",
        "history-feed-item-nocomment": "$1 на $2",
        "difference-missing-revision": "{{PLURAL:$2|$2 версія|$2 версіі|$2 версій}} гэтай розніцы ($1) {{PLURAL:$2|не знойдзена|не знойдзены}}.\n\nЗвычайна такое здараецца з-за пераходу па састарэлай спасылцы на розніцу ў старонцы, якая была выдалена.\nПадрабязнасці могуць быць у [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленняў].",
        "searchresults": "Вынікі пошуку",
        "search-filter-title-prefix": "Шукаць толькі на старонках, назва якіх пачынаецца з «$1»",
+       "search-filter-title-prefix-reset": "Шукаць усе старонкі",
        "searchresults-title": "Вынікі пошуку «$1»",
        "titlematches": "Знойдзена ў назвах",
        "textmatches": "Знойдзена ў тэкстах",
        "saveusergroups": "Захаваць групы {{GENDER:$1|ўдзельнікаў|ўдзельніц}}",
        "userrights-groupsmember": "У групе:",
        "userrights-groupsmember-auto": "Няяўны член:",
-       "userrights-groups-help": "Тут можна мяняць групы, да якіх належыць гэты ўдзельнік.\n* Адзначанае поле выбару азначае ўваходжанне ўдзельніка ў пэўную групу.\n* Чыстае поле выбару азначае неўваходжанне.\n* Знак * азначае, што нельга выняць удзельніка з групы, калі ён ужо там, або наадварот.адкласці час \n* Знак # азначае, што Вы можаце толькі адкласці час выдалення з групы; Вы не можаце перанесці яго на больш ранні тэрмін.",
+       "userrights-groups-help": "Тут можна мяняць групы, да якіх належыць гэты ўдзельнік.\n* Адзначанае поле выбару азначае ўваходжанне ўдзельніка ў пэўную групу.\n* Чыстае поле выбару азначае неўваходжанне.\n* Знак * азначае, што нельга выняць удзельніка з групы, калі ён ужо там, або наадварот.\n* Знак # азначае, што Вы можаце толькі адкласці час выдалення з групы; Вы не можаце перанесці яго на больш ранні тэрмін.",
        "userrights-reason": "Прычына:",
        "userrights-no-interwiki": "Вам не дазволена мяняць дазволаў карыстальнікам на іншых Вікі-ах.",
        "userrights-nodatabase": "Не знойдзена тут, або не існуе база даных $1.",
        "group-autoconfirmed-member": "{{GENDER:$1|аўта-пацверджаны ўдзельнік|аўта-пацверджаная ўдзельніца}}",
        "group-bot-member": "{{GENDER:$1|бот}}",
        "group-sysop-member": "{{GENDER:$1|адміністратар}}",
+       "group-interface-admin-member": "{{GENDER:$1|адміністратар інтэрфейсу}}",
        "group-bureaucrat-member": "{{GENDER:$1|бюракрат}}",
        "group-suppress-member": "{{GENDER:$1|схоўваючы|схоўваючая}}",
        "grouppage-user": "{{ns:project}}:Удзельнікі",
        "grouppage-autoconfirmed": "{{ns:project}}:Аўтапацверджаныя ўдзельнікі",
        "grouppage-bot": "{{ns:project}}:Робаты",
        "grouppage-sysop": "{{ns:project}}:Адміністратары",
+       "grouppage-interface-admin": "{{ns:project}}:Адміністратары інтэрфейсу",
        "grouppage-bureaucrat": "{{ns:project}}:Бюракраты",
        "grouppage-suppress": "{{ns:project}}:Схоўваючыя",
        "right-read": "Чытаць старонкі",
        "right-reupload-own": "Запісваць паўзверх існуючага файла, які ўкладвалі самі",
        "right-reupload-shared": "Перамагаць файлы з агульнага сховішча тутэйшымі файламі",
        "right-upload_by_url": "Укладваць файлы з сеціўнага адраса (URL)",
-       "right-purge": "ЧÑ\8bÑ\81Ñ\86Ñ\96Ñ\86Ñ\8c ÐºÑ\8dÑ\88 Ð¿Ð»Ñ\8fÑ\86оÑ\9eкÑ\96 Ð´Ð»Ñ\8f Ñ\81Ñ\82аÑ\80онкÑ\96 Ð±ÐµÐ· Ð¿Ð°Ñ\86веÑ\80джаннÑ\8f",
+       "right-purge": "Ð\90Ñ\87Ñ\8bÑ\81Ñ\82ка ÐºÑ\8dÑ\88Ñ\83 Ð¿Ð»Ñ\8fÑ\86оÑ\9eкÑ\96 Ð´Ð»Ñ\8f Ñ\81Ñ\82аÑ\80онкÑ\96",
        "right-autoconfirmed": "Не падпарадкоўвацца абмежаванням хуткасці, накладзеным на IP",
        "right-bot": "Лічыцца аўтаматычным працэсам",
        "right-nominornewtalk": "Не паведамляць пра новыя паведамленні ў адказ на дробныя праўкі размоўных старонак",
        "grant-createaccount": "Ствараць уліковыя запісы",
        "grant-createeditmovepage": "Ствараць, правіць і пераносіць старонкі",
        "grant-delete": "Выдаляць старонкі, версіі і запісы ў журналах",
-       "grant-editinterface": "Правіць прасторы назваў MediaWiki і CSS/JSON/JavaScript удзельніка",
+       "grant-editinterface": "Правіць прасторы назваў MediaWiki і JSON сайту/удзельніка",
        "grant-editmycssjs": "Правіць Ваш карыстальніцкі CSS/JSON/JavaScript",
        "grant-editmyoptions": "Змяняць вашы настройкі",
        "grant-editmywatchlist": "Правіць ваш спіс назірання",
        "rcfilters-activefilters-hide": "Схаваць",
        "rcfilters-activefilters-show": "Паказаць",
        "rcfilters-activefilters-hide-tooltip": "Схаваць вобласць актыўных фільтраў",
+       "rcfilters-activefilters-show-tooltip": "Паказаць вобласць актыўных фільтраў",
        "rcfilters-advancedfilters": "Пашыраныя фільтры",
        "rcfilters-limit-title": "Вынікі для паказу",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|змена|змены|змен}}, $2",
        "rcfilters-watchlist-markseen-button": "Пазначыць усе змены як прагледжаныя",
        "rcfilters-watchlist-edit-watchlist-button": "Рэдагаваць Ваш спіс назіраных старонак",
        "rcfilters-watchlist-showupdated": "Змены старонак, якія Вы не наведвалі з таго часу, як яны адбыліся, выдзелены <strong>тлустым</strong> і пазначаны маркерам.",
-       "rcfilters-preference-label": "СÑ\85аваÑ\86Ñ\8c Ð¿Ð°Ð»ÐµÐ¿Ñ\88анÑ\83Ñ\8e Ð²ÐµÑ\80Ñ\81Ñ\96Ñ\8e Â«Ð\90поÑ\88нÑ\96Ñ\85 Ð·Ð¼ÐµÐ½Â»",
+       "rcfilters-preference-label": "Ð\92Ñ\8bкаÑ\80Ñ\8bÑ\81Ñ\82оÑ\9eваÑ\86Ñ\8c Ñ\96нÑ\82Ñ\8dÑ\80Ñ\84ейÑ\81 Ð±ÐµÐ· JavaScript",
        "rcfilters-preference-help": "Адкатвае рэдызайн інтэрфейсу 2017 года і ўсе інструменты, дададзеныя з тых часоў.",
-       "rcfilters-watchlist-preference-label": "СÑ\85аваÑ\86Ñ\8c Ð¿Ð°Ð»ÐµÐ¿Ñ\88анÑ\83Ñ\8e Ð²ÐµÑ\80Ñ\81Ñ\96Ñ\8e Ñ\81пÑ\96Ñ\81а Ð½Ð°Ð·Ñ\96Ñ\80аннÑ\8f",
+       "rcfilters-watchlist-preference-label": "Ð\92Ñ\8bкаÑ\80Ñ\8bÑ\81Ñ\82оÑ\9eваÑ\86Ñ\8c Ñ\96нÑ\82Ñ\8dÑ\80Ñ\84ейÑ\81 Ð±ÐµÐ· JavaScript",
        "rcfilters-watchlist-preference-help": "Адкатвае рэдызайн інтэрфейсу 2017 года і ўсе інструменты, дададзеныя з тых часоў.",
        "rcnotefrom": "Ніжэй {{PLURAL:$5|паказана змяненне|паказаны змены}} з <strong>$3, $4</strong> (не больш за <strong>$1</strong>).",
        "rclistfrom": "Паказаць змены з $3 $2",
        "recentchangeslinked-feed": "Звязаныя праўкі",
        "recentchangeslinked-toolbox": "Звязаныя праўкі",
        "recentchangeslinked-title": "Змяненні, якія датычаць \"$1\"",
-       "recentchangeslinked-summary": "Увядзіце імя старонкі, каб убачыць змяненні на старонках, якія спасылаюцца на дадзеную старонку ці на якія яна спасылаецца. (Каб убачыць складнікі катэгорыі, увядзіце Катэгорыя:Назва катэгорыі). Старонкі, якія ўваходзяць у [[Special:Watchlist|Ваш спіс назірання]], выдзелены <strong>тлустым шрыфтам</strong>.",
+       "recentchangeslinked-summary": "Увядзіце імя старонкі, каб убачыць змяненні на старонках, на якія яна спасылаецца або якія спасылаюцца на яе (каб убачыць складнікі катэгорыі, увядзіце {{ns:category}}:Назва катэгорыі). Змены старонак з [[Special:Watchlist|Вашага спісу назірання]] выдзелены <strong>тлустым шрыфтам</strong>.",
        "recentchangeslinked-page": "Назва старонкі:",
        "recentchangeslinked-to": "Паказваць, замест гэтага, змяненні на старонках, што спасылаюцца сюды",
        "recentchanges-page-added-to-category": "[[:$1]] дададзена ў катэгорыю",
        "uploadstash-thumbnail": "паказаць мініяцюру",
        "uploadstash-file-not-found-no-local-path": "Не знойдзена лакальнага шляху да отмасштабированному файлу.",
        "uploadstash-file-not-found-no-object": "Не атрымалася стварыць аб’ект лакальнага файла для мініяцюры.",
-       "uploadstash-file-not-found-missing-content-type": "Ð\9eÑ\82Ñ\81Ñ\83Ñ\82Ñ\81Ñ\82вÑ\83еÑ\82 загаловак content-type.",
+       "uploadstash-file-not-found-missing-content-type": "Ð\90дÑ\81Ñ\83Ñ\82нÑ\96Ñ\87ае загаловак content-type.",
        "uploadstash-file-not-found-not-exists": "Шлях не знойдзены, альбо файл незразумелы.",
        "uploadstash-no-extension": "Пустое расшырэнне.",
        "invalid-chunk-offset": "Недапушчальнае зрушэнне фрагмента",
        "listfiles_size": "Памер у байтах",
        "listfiles_description": "Апісанне",
        "listfiles_count": "Версіі",
-       "listfiles-show-all": "Уключыць старыя версіі відарысаў",
+       "listfiles-show-all": "Уключыць старыя версіі файлаў",
        "listfiles-latestversion": "Актуальная версія",
        "listfiles-latestversion-yes": "Так",
        "listfiles-latestversion-no": "Не",
        "filehist-filesize": "Аб'ём файла",
        "filehist-comment": "Тлумачэнне",
        "imagelinks": "Выкарыстанне файла",
-       "linkstoimage": "Наступн{{PLURAL:$1|ая старонка спасылаецца|ыя $1 старонкі спасылаюцца}} на гэты файл:",
+       "linkstoimage": "{{PLURAL:$1|Наступная $1 старонка выкарыстоўвае|Наступныя $1 старонкі выкарыстоўваюць|Наступныя $1 старонак выкарыстоўваюць}} гэты файл:",
        "linkstoimage-more": "На гэты файл існуюць спасылкі з больш як $1 {{PLURAL:$1|старонкі|старонак}}.\nНаступны пералік паказвае толькі {{PLURAL:$1|першую спасылку|першыя $1 з іх}}.\nТаксама ёсць [[Special:WhatLinksHere/$2|поўны пералік]].",
        "nolinkstoimage": "Няма старонак, якія б спасылаліся на файл.",
        "morelinkstoimage": "Паказаць [[Special:WhatLinksHere/$1|больш спасылак]] на гэты файл.",
        "statistics-files": "Укладзеныя файлы",
        "statistics-edits": "Праўкі старонак ад часу інсталяцыі {{SITENAME}}",
        "statistics-edits-average": "Колькасць правак на 1 старонку",
-       "statistics-users": "Registered [[Special:ListUsers|users]]",
+       "statistics-users": "Зарэгістраваныя ўдзельнікі",
        "statistics-users-active": "Актыўныя ўдзельнікі",
        "statistics-users-active-desc": "Удзельнікі, якія хоць нешта зрабілі за апошн{{PLURAL:$1|і дзень|ія $1 дзён}}",
        "pageswithprop": "Старонкі з уласцівасцю старонкі",
        "pageswithprop-legend": "Старонкі з пэўнай уласцівасцю",
        "pageswithprop-text": "На гэтай старонцы пералічаны старонкі, якія выкарыстоўваюць пэўную уласцівасць.",
        "pageswithprop-prop": "Назва ўласцівасці:",
+       "pageswithprop-reverse": "Сартаваць у зваротным парадку",
+       "pageswithprop-sortbyvalue": "Сартаваць па значэнню ўласцівасці",
        "pageswithprop-submit": "Перайсці",
        "pageswithprop-prophidden-long": "доўгае тэкставае значэнне ўласцівасці схавана ($1)",
        "pageswithprop-prophidden-binary": "двайковае значэнне ўласцівасці схавана ($1)",
        "doubleredirects": "Падвойныя перасылкі",
        "doubleredirectstext": "Тут пералічаныя старонкі-перасылкі, якія паказваюць на іншыя перасылкі.\nКожны радок утрымлівае спасылкі на першую і другую перасылкі, а таксама мэту другой перасылкі, якая звычайна і ёсць \"сапраўдная\" мэтавая старонка, на якую павінна была паказваць першая перасылка.\n<del>Закрэсленыя складнікі</del> ўжо былі папраўленыя.",
        "double-redirect-fixed-move": "Назва [[$1]] была перанесена.\nПасля аўтаматычнага абнаўлення зараз яна перасылае да [[$2]]",
-       "double-redirect-fixed-maintenance": "Аўтаматычнае выпраўленне падвойнай перасылкі з [[$1]] на [[$2]] цягам тэхнічнага абслугоўвання.",
+       "double-redirect-fixed-maintenance": "Аўтаматычнае выпраўленне падвойнай перасылкі з [[$1]] на [[$2]] цягам тэхнічнага абслугоўвання",
        "double-redirect-fixer": "Выпраўляльнік перасылак",
        "brokenredirects": "Паламаныя перасылкі",
        "brokenredirectstext": "Гэтыя перасылкі паказваюць на старонкі, якіх няма:",
        "prefixindex": "Старонкі з назвамі на ўзор",
        "prefixindex-namespace": "Усе старонкі з прэфіксам (прастора назваў «{{ns:$1}}»)",
        "prefixindex-submit": "Паказаць",
-       "prefixindex-strip": "Ð\9fÑ\80Ñ\8bбÑ\80аÑ\86Ñ\8c Ð¿Ñ\80Ñ\8dÑ\84Ñ\96кÑ\81 Ñ\83 Ð¿ÐµÑ\80алÑ\96кÑ\83",
+       "prefixindex-strip": "Ð\9fÑ\80Ñ\8bбÑ\80аÑ\86Ñ\8c Ð¿Ñ\80Ñ\8dÑ\84Ñ\96кÑ\81 Ñ\83 Ð²Ñ\8bнÑ\96каÑ\85",
        "shortpages": "Старонкі малога аб'ёму",
        "longpages": "Старонкі вялікага аб'ёму",
        "deadendpages": "Старонкі без спасылак",
        "protectedtitles-submit": "Паказаць назвы",
        "listusers": "Усе ўдзельнікі",
        "listusers-editsonly": "Толькі ўдзельнікі, якія маюць праўкі",
+       "listusers-temporarygroupsonly": "Паказваць толькі ўдзельнікаў у тымчасовых групах удзельнікаў",
        "listusers-creationsort": "У парадку датаў стварэння",
        "listusers-desc": "Парадкаваць да памяншэння",
        "usereditcount": "$1 {{PLURAL:$1|праўка|праўкі|правак}}",
        "deleting-backlinks-warning": "<strong>Увага:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Іншыя старонкі]] спасылаюцца на ці ўключаюць старонку, якую вы збіраецеся выдаліць.",
        "deleting-subpages-warning": "<strong>Увага:</strong> Старонка, якую Вы хочаце выдаліць, мае [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1 падстаронка|$1 падстаронкі|$1 падстаронак|51=болей за 50 падстаронак}}]].",
        "rollback": "Адкаціць праўкі",
+       "rollback-confirmation-confirm": "Калі ласка, пацвердзіце:",
+       "rollback-confirmation-yes": "Адкат",
+       "rollback-confirmation-no": "Адмяніць",
        "rollbacklink": "адкат",
        "rollbacklinkcount": "адкаціць $1 {{PLURAL:$1|праўку|праўкі|правак}}",
        "rollbacklinkcount-morethan": "адкаціць больш за $1 {{PLURAL:$1|праўку|праўкі|правак}}",
        "revertpage": "Праўкі аўтарства [[Special:Contributions/$2|$2]] ([[User talk:$2|размова]]) адкочаныя; вернута апошняя версія аўтарства [[User:$1|$1]]",
        "revertpage-nouser": "Праўкі (імя ўдзельніка схавана) адкочаны да версіі {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Адкочаны праўкі {{GENDER:$3|$1}}; вернута апошняя версія {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Адкочаны праўкі $1;\nвернута апошняя версія $2. [$3 Паказаць змены]",
        "sessionfailure-title": "Памылка сеансу",
        "sessionfailure": "Магчыма, ёсць праблемы з вашым сеансам працы ў сістэме. Таму вам было адмоўлена ў выкананні дзеяння, каб засцерагчыся ад захопу сеанса.\n\nВярніцеся на папярэднюю старонку, перазагрузіце яе і тады паспрабуйце зноў.",
        "changecontentmodel": "Змяніць мадэль змесціва старонкі",
        "authmanager-create-no-primary": "Прадастаўленыя ўліковыя дадзеныя не могуць быць выкарыстаны для стварэння ўліковага запісу.",
        "authmanager-link-no-primary": "Прадастаўленыя ўліковыя дадзеныя не могуць быць выкарыстаны для прывязкі рахунку.",
        "authmanager-link-not-in-progress": "Звязванне ўліковага запісу не выконваецца або сесія перадачы дадзеных была страчана. Калі ласка, пачніце зноў з самага пачатку.",
-       "authmanager-authplugin-setpass-failed-title": "Памылка змены пароля",
-       "authmanager-authplugin-setpass-failed-message": "Убудова аўтэнтыфікацыі адмоўлена па змене пароля.",
-       "authmanager-authplugin-create-fail": "Убудова аўтэнтыфікацыі адмоўлена ў рэгістрацыі.",
-       "authmanager-authplugin-setpass-denied": "Убудова праверкі сапраўднасці не дазваляе змяняць паролі.",
-       "authmanager-authplugin-setpass-bad-domain": "Недапушчальны дамен.",
        "authmanager-autocreate-noperm": "Аўтаматычнае стварэнне уліковых запісаў не дапускаецца.",
        "authmanager-autocreate-exception": "Аўтаматычнае стварэнне уліковых запісаў часова адключана з-за памылак папярэдніх.",
        "authmanager-userdoesnotexist": "Уліковы запіс удзельніка \"$1\" не зарэгістраваны.",
index a005d21..5df588d 100644 (file)
                        "Kareyac",
                        "ShockD",
                        "Fitoschido",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "Ted Masters"
                ]
        },
        "tog-underline": "Подчертаване на препратките:",
        "tog-hideminor": "Скриване на малки редакции в последните промени",
        "tog-hidepatrolled": "Скриване на патрулираните редакции от списъка с последните промени",
        "tog-newpageshidepatrolled": "Скриване на патрулираните редакции от списъка на новите страници",
-       "tog-hidecategorization": "Скриване на категоризацията на статии",
+       "tog-hidecategorization": "Скриване на категоризацията на страниците",
        "tog-extendwatchlist": "Разширяване на списъка за наблюдение, така че да показва всички промени, не само последните",
        "tog-usenewrc": "Групиране по страници на промените на Последни промени и в списъка за наблюдение",
        "tog-numberheadings": "Автоматично номериране на заглавията",
        "pool-timeout": "Изтичане на времето за заключване на страницата",
        "pool-queuefull": "Опашката за заявки е пълна",
        "pool-errorunknown": "Непозната грешка",
-       "poolcounter-usage-error": "Ð\93Ñ\80еÑ\88ка Ð¿Ñ\80и Ñ\83поÑ\82Ñ\80еба: $1",
+       "poolcounter-usage-error": "Ð\93Ñ\80еÑ\88ка Ð² Ñ\83поÑ\82Ñ\80ебаÑ\82а: $1",
        "aboutsite": "За {{SITENAME}}",
        "aboutpage": "Project:За {{SITENAME}}",
        "copyright": "Освен ако не е посочено друго, съдържанието е достъпно при условията на $1.",
        "missingarticle-rev": "(версия#: $1)",
        "missingarticle-diff": "(Разлика: $1, $2)",
        "readonly_lag": "Базата от данни беше автоматично заключена, докато подчинените сървъри успеят да се синхронизират с основния сървър.",
+       "nonwrite-api-promise-error": "HTTP-заглавката „Promise-Non-Write-API-Action“ е изпратена, но заявката е направена към модул за запис на API.",
        "internalerror": "Вътрешна грешка",
        "internalerror_info": "Вътрешна грешка: $1",
        "internalerror-fatal-exception": "Фатална грешка от тип „$1“",
        "badarticleerror": "Действието не може да бъде изпълнено на тази страница.",
        "cannotdelete": "Указаната страница или файл „$1“ не можа да бъде изтрит(а). Възможно е вече да е бил(а) изтрит(а) от някой друг.",
        "cannotdelete-title": "Страницата „$1“ не може да бъде изтрита",
+       "delete-scheduled": "Страница „$1“ е предвидена за изтриване.\nМоля, бъдете търпеливи.",
        "delete-hook-aborted": "Изтриването беше прекъснато от софтуерно прехващане.\nНе беше посочена причина за това.",
        "no-null-revision": "Не може да бъде създадена празна версия на страницата „$1“",
        "badtitle": "Невалидно заглавие",
        "customcssprotected": "Нямате права за редактиране на тази CSS страница, защото тя съдържа чужди потребителски настройки.",
        "customjsonprotected": "Нямате права за редактиране на тази JSON страница, защото тя съдържа чужди потребителски настройки.",
        "customjsprotected": "Нямате права за редактиране на тази JavaScript страница, тъй като съдържа чужди потребителски настройки.",
+       "sitecssprotected": "Нямате права за редактиране на тази CSS страница, защото може да засегне всички посетители.",
+       "sitejsonprotected": "Нямате права за редактиране на тази JSON страница, защото може да засегне всички посетители.",
+       "sitejsprotected": "Нямате права за редактиране на тази JavaScript страница, защото може да засегне всички посетители.",
        "mycustomcssprotected": "Нямате права за редактиране на тази CSS страница.",
        "mycustomjsonprotected": "Нямате права за редактиране на тази JSON страница.",
        "mycustomjsprotected": "Нямате права за редактиране на тази JavaScript страница.",
        "createacct-emailoptional": "Адрес за електронна поща (незадължително)",
        "createacct-email-ph": "Въведете Вашия адрес за електронна поща",
        "createacct-another-email-ph": "Въведете електронна поща",
-       "createaccountmail": "Ð\98зползване Ð½Ð° Ñ\81лÑ\83Ñ\87айна Ð²Ñ\80еменна Ð¿Ð°Ñ\80ола, ÐºÐ¾Ñ\8fÑ\82о Ñ\81е Ð¸Ð·Ð¿Ñ\80аÑ\89а Ð½Ð° ÐµÐ»ÐµÐºÑ\82Ñ\80оннаÑ\82а Ð¿Ð¾Ñ\89а, Ð¿Ð¾Ñ\81оÑ\87ена Ð¿Ð¾-долÑ\83",
+       "createaccountmail": "Ð\98зползване Ð½Ð° Ñ\81лÑ\83Ñ\87айна Ð²Ñ\80еменна Ð¿Ð°Ñ\80ола, ÐºÐ¾Ñ\8fÑ\82о Ñ\81е Ð¸Ð·Ð¿Ñ\80аÑ\89а Ð½Ð° Ð¿Ð¾Ñ\81оÑ\87енаÑ\82а ÐµÐ»ÐµÐºÑ\82Ñ\80оннаÑ\82а Ð¿Ð¾Ñ\89а",
        "createacct-realname": "Истинско име (незадължително)",
        "createacct-reason": "Причина",
        "createacct-reason-ph": "Защо създавате друга сметка",
+       "createacct-reason-help": "Съобщение, показвано в дневника на създадени сметки",
        "createacct-submit": "Създаване на сметката",
        "createacct-another-submit": "Създаване на сметка",
        "createacct-continue-submit": "Продължаване създаването на сметка",
        "createacct-benefit-body2": "{{PLURAL:$1|страница|страници}}",
        "createacct-benefit-body3": "{{PLURAL:$1|скорошен сътрудник|скорошни сътрудници}}",
        "badretype": "Въведените пароли не съвпадат.",
+       "usernameinprogress": "Създаването на сметката за този потребител се извършва в момента.\nМоля, изчакайте.",
        "userexists": "Въведеното потребителско име вече се използва.\nИзберете друго име.",
        "loginerror": "Грешка при влизане",
-       "createacct-error": "Грешка при създаване на сметка",
+       "createacct-error": "Грешка при създаването на сметка",
        "createaccounterror": "Не може да бъде създадена сметка: $1",
        "nocookiesnew": "Потребителската сметка беше създадена, но все още не сте влезли.\n{{SITENAME}} използва бисквитки при влизането на потребителите.\nРазрешете бисквитките в браузъра си, тъй като те са забранени, а след това влезте с потребителското си име и парола.",
        "nocookieslogin": "{{SITENAME}} използва бисквитки (cookies) за запис на влизанията.\nРазрешете бисквитките в браузъра си, тъй като те са забранени, и опитайте отново.",
        "noname": "Не указахте валидно потребителско име.",
        "loginsuccesstitle": "Успешно влизане",
        "loginsuccess": "<strong>Влязохте в {{SITENAME}} като „$1“.</strong>",
-       "nosuchuser": "Не съществува потребител с име „$1“.\nПотребителските имена са чувствителни към регистъра на буквите.\nПроверете изписването или [[Special:CreateAccount|създайте нова сметка]].",
+       "nosuchuser": "Няма потребител с име „$1“.\nПотребителските имена са чувствителни към регистъра на буквите.\nПроверете изписването или [[Special:CreateAccount|създайте нова сметка]].",
        "nosuchusershort": "Не съществува потребител с името „$1“.\nПроверете изписването.",
        "nouserspecified": "Необходимо е да се посочи потребителско име.",
        "login-userblocked": "Този потребител е блокиран. Влизането в системата не е позволено.",
        "passwordtooshort": "Необходимо е паролата да съдържа поне {{PLURAL:$1|1 знак|$1 знака}}.",
        "passwordtoolong": "Паролата не може да бъде по-дългa от {{PLURAL:$1|1 знак|$1 знака}}.",
        "passwordtoopopular": "Често използвани пароли не могат да бъдат ползвани. Моля, изберете парола, която е по-трудна за познаване.",
+       "passwordinlargeblacklist": "Въведената парола е между най-често ползваните. Моля, изберете по-различна парола.",
        "password-name-match": "Паролата Ви трябва да се различава от потребителското Ви име.",
        "password-login-forbidden": "Използването на това потребителско име и парола е забранено.",
        "mailmypassword": "Възстановяване на парола",
        "changepassword-success": "Паролата беше променена успешно!",
        "changepassword-throttled": "Направили сте твърде много опити да въведете паролата за тази сметка.\nНеобходимо е да изчакате $1 преди да опитате отново.",
        "botpasswords": "Пароли за ботове",
+       "botpasswords-summary": "<em>Паролите за ботове</em> дават достъп до потребителска сметка през API, без да се използват идентификационните данни в основната сметка. Потребителските права могат да бъдат ограничени при влизане по този начин.\n\nАко не знаете за какво би ви послужило това, по-добре не го правете. Никой никога не трябва да ви моли да създавате такава парола, за да му я дадете.",
        "botpasswords-disabled": "Паролите за ботове са изключени.",
        "botpasswords-no-central-id": "За да използвате пароли за ботове, трябва да сте влезли в централна сметка.",
        "botpasswords-existing": "Съществуващи пароли за ботове",
        "botpasswords-createnew": "Създаване на нова парола за бота",
-       "botpasswords-editexisting": "РедакÑ\82иÑ\80ане на съществуваща парола на бот",
+       "botpasswords-editexisting": "Ð\9fÑ\80омÑ\8fна на съществуваща парола на бот",
        "botpasswords-label-needsreset": "(нужна е нова парола)",
        "botpasswords-label-appid": "Име на бота:",
        "botpasswords-label-create": "Създаване",
        "botpasswords-label-delete": "Изтриване",
        "botpasswords-label-resetpassword": "Възстановяване на парола",
        "botpasswords-label-grants": "Приложими разрешения:",
+       "botpasswords-help-grants": "Разрешенията ви дават достъп до права, които вече имате. Като включите разрешение тук, няма да получавате никакви права, които вече няма сметката. Повече информация ще намерите на [[Special:ListGrants|таблицата на разрешения]].",
        "botpasswords-label-grants-column": "Дадено",
        "botpasswords-bad-appid": "Името на бота „$1“ не е валидно.",
        "botpasswords-insert-failed": "Неуспешно добавяне на име на бота „$1“. Дали не е добавяно вече?",
        "botpasswords-updated-body": "Паролата на бот „$1“ на потребител {{GENDER:$2|„$2“}} е обновена.",
        "botpasswords-deleted-title": "Паролата на бота е изтрита",
        "botpasswords-deleted-body": "Паролата на бот „$1“ на {{GENDER:$2|потребител}} „$2“ е премахната.",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider не е наличен.",
+       "botpasswords-needs-reset": "Паролата на бота с име „$2“ на {{GENDER:$2|потребител}} „$1“ трябва да бъде подновена.",
        "resetpass_forbidden": "Не е разрешена промяна на паролата",
        "resetpass_forbidden-reason": "Паролите не могат да се променят: $1",
        "resetpass-no-info": "За да имате директен достъп до тази страница е необходимо да влезете в системата.",
        "resetpass-abort-generic": "Промяната на паролата беше прекъсната от използвано разширение.",
        "resetpass-expired": "Срокът на валидност на паролата е изтекъл. Изберете нова парола за влизане.",
        "resetpass-expired-soft": "Вашата парола е изтекла и трябва да бъде променена. Моля, въведете нова парола сега или натиснете бутона \"{{int:authprovider-resetpass-skip-label}}\" за да я промените по-късно.",
-       "resetpass-validity": "Ð\9fаÑ\80олаÑ\82а Ð²Ð¸ Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð°: $1\n\nÐ\97адайте нова парола за влизане.",
+       "resetpass-validity": "Ð\9fаÑ\80олаÑ\82а Ð²Ð¸ Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð°: $1\n\nУÑ\81Ñ\82ановете нова парола за влизане.",
        "resetpass-validity-soft": "Вашата парола е невалидна: $1\n\nМоля, въведете нова парола или натиснете бутона „{{int:authprovider-resetpass-skip-label}}“ за да я промените по-късно.",
        "passwordreset": "Възстановяване на парола",
        "passwordreset-text-one": "Попълването на формуляра ще доведе до възстановяване на паролата.",
        "passwordreset-emailelement": "Потребителско име: \n$1\n\nВременна парола: \n$2",
        "passwordreset-emailsentemail": "Ако електронната Ви поща е свързана със сметката Ви, на нея е изпратено писмо за възстановяване на паролата.",
        "passwordreset-emailsentusername": "Ако това потребителско име е свързано с електронна поща, е изпратено писмо за възстановяване на паролата.",
+       "passwordreset-nocaller": "Трябва да е посочен източник на извикването",
        "passwordreset-nosuchcaller": "Източникът на извикването не съществува: $1",
+       "passwordreset-ignored": "Промяната на паролата беше неуспешна. Може би не е настроен доставчик?",
        "passwordreset-invalidemail": "Неправилен email адрес",
        "passwordreset-nodata": "Не сте указали нито потребителско име, нито адрес на ел. поща",
        "changeemail": "Промяна или премахване на адреса за е-поща",
        "subject-preview": "Предварителен преглед на заглавието:",
        "previewerrortext": "Възникна грешка при опита за преглед на промените.",
        "blockedtitle": "Потребителят е блокиран",
+       "blocked-email-user": "<strong>Вашето потребителско име е блокирано от изпращане на електронна поща. Все още можете да редактирате други страници в това уики.</strong> Всички подробности за забраната ще намерите в [[Special:MyContributions|приносите на сметката]].\n\nБлокирането е извършено от $1.\n\nПосочената причина е <em>$2</em>.\n\n* Начало на блокирането: $8\n* Край на блокирането: $6\n* Блокирането се отнася за: $7\n* Идентификатор на блокирането #$5",
        "blockedtext-partial": "<strong>Вашето потребителско име или IP-адрес е забранено да правите промени на тази страница. Все още можете да редактирате други страници в това уики. </strong> Всички подробности за забраната ще намерите в [[Special:MyContributions|приносите за сметката]].\n\nЗабраната даде $1.\n\nПосочената причина е <em>$2</em>.\n\n* Начало на забраната: $8\n* Край на забраната: $6\n* Забраната се отнася за: $7\n* Идентификатор на забраната #$5",
        "blockedtext": "'''Вашето потребителско име (или IP-адрес) беше блокирано.'''\n\nБлокирането е извършено от $1. Посочената причина е: ''$2''\n\n*Начало на блокирането: $8\n*Край на блокирането: $6\n*Блокирането се отнася за: $7\n\nМожете да се свържете с $1 или с някой от останалите [[{{MediaWiki:Grouppage-sysop}}|администратори]], за да обсъдите блокирането.\n\nМожете да използвате услугата „{{int:emailuser}}“ само ако не ви е забранена употребата ѝ и ако сте посочили валидна електронна поща в [[Special:Preferences|настройките]] си.\n\nВашият IP адрес е $3, а номерът на блокирането е $5. Включвайте едно от двете или и двете във всяко запитване, което правите.",
        "autoblockedtext": "IP-адресът ви беше блокиран автоматично, защото е бил използван от друг потребител, който е бил блокиран от $1.\nПосочената причина е:\n\n:<em>$2</em>\n\n* Начало на блокирането: $8\n* Край на блокирането: $6\n* Блокирането се отнася за: $7\n\nМожете да се свържете с $1 или с някой от останалите [[{{MediaWiki:Grouppage-sysop}}|администратори]], за да обсъдите блокирането.\n\nМожете да използвате услугата „{{int:emailuser}}“ само ако не ви е забранена употребата ѝ и ако сте посочили валидна електронна поща в [[Special:Preferences|настройките]] си.\n\nТекущият Ви IP-адрес е $3, а номерът на блокирането ви е $5.\nВключвайте ги във всяка заявка, която правите.",
        "userjsonyoucanpreview": "<strong>Съвет:</strong> Използвайте бутона „{{int:showpreview}}“, за да изпробвате новия код на JSON преди съхранението.",
        "userjsyoucanpreview": "<strong>Съвет:</strong> Използвайте бутона „{{int:showpreview}}“, за да изпробвате новия код на Джаваскрипт преди съхранението.",
        "usercsspreview": "<strong>Не забравяйте, че това е само предварителен преглед на кода на CSS.\nСтраницата все още не е съхранена!</strong>",
-       "userjsonpreview": "<strong>Ð\9dе Ð·Ð°Ð±Ñ\80авÑ\8fйÑ\82е, Ñ\87е Ñ\82ова Ðµ Ñ\81амо Ð¸Ð·Ð¿Ñ\80обване/пÑ\80едваÑ\80иÑ\82елен Ð¿Ñ\80еглед Ð½Ð° Ð¿Ð¾Ñ\81Ñ\82авеноÑ\81Ñ\82Ñ\82а Ð½Ð° Ð²Ð°Ñ\88иÑ\8f JSON.\nСтраницата все още не е съхранена!</strong>",
+       "userjsonpreview": "<strong>Ð\9dе Ð·Ð°Ð±Ñ\80авÑ\8fйÑ\82е, Ñ\87е Ñ\82ова Ðµ Ñ\81амо Ð¸Ð·Ð¿Ñ\80обване/пÑ\80едваÑ\80иÑ\82елен Ð¿Ñ\80еглед Ð½Ð° Ð²Ð°Ñ\88аÑ\82а Ð¿Ð¾Ñ\82Ñ\80ебиÑ\82елÑ\81ка JSON-конÑ\84игÑ\83Ñ\80аÑ\86иÑ\8f.\nСтраницата все още не е съхранена!</strong>",
        "userjspreview": "<strong>Не забравяйте, че това е само изпробване/предварителен преглед на кода на JavaScript.\nСтраницата все още не е съхранена!</strong>",
        "sitecsspreview": "<strong>Не забравяйте, че това е само предварителен преглед на този CSS.\nТой все още не е съхранен!</strong>",
-       "sitejsonpreview": "<strong>Не забравяйте, че това е само предварителен преглед на тази поставеност на JSON. Той все още не е съхранен!</strong>",
+       "sitejsonpreview": "<strong>Не забравяйте, че това е само предварителен преглед на тази JSON-конфигурация.\nТой все още не е съхранен!</strong>",
        "sitejspreview": "<strong>Не забравяйте, че това е само предварителен преглед на този JavaScript код.\nТой все още не е съхранен!</strong>",
        "userinvalidconfigtitle": "<strong>Внимание:</strong> Не съществува облик „$1“.\nИмената на потребителски .css, .json и .js страници трябва да използват малки букви, например: {{ns:user}}:Иван/vector.css (а не {{ns:user}}:Иван/Vector.css).",
        "updated": "(обновена)",
        "yourdiff": "Разлики",
        "copyrightwarning": "Обърнете внимание, че всички приноси към {{SITENAME}} се публикуват при условията на $2 (за подробности вижте $1).\nАко не сте съгласни вашата писмена работа да бъде променяна и разпространявана без ограничения, не я публикувайте.<br />\nСъщо потвърждавате, че вие сте написали материала или сте използвали свободни ресурси — <em>обществено достояние</em> или друг свободен източник.\nАко сте ползвали чужди материали, за които имате разрешение, непременно посочете източника.\n<strong>Не публикувайте произведения с авторски права без разрешение!</strong>",
        "copyrightwarning2": "Обърнете внимание, че всички приноси към {{SITENAME}} могат да бъдат редактирани, променяни или премахвани от останалите сътрудници.\nАко не сте съгласни вашата писмена работа да бъде променяна без ограничения, не я публикувайте.<br />\nСъщо потвърждавате, че вие сте написали материала или сте използвали свободни ресурси — обществено достояние< или друг свободен източник (за подробности вижте $1).\nАко сте ползвали чужди материали, за които имате разрешение, непременно посочете източника.\n<strong>Не публикувайте произведения с авторски права без разрешение!</strong>",
+       "editpage-cannot-use-custom-model": "Моделът на съдържанието на страницата не може да бъде променен.",
        "longpageerror": "<strong>Грешка: Изпратеният текст е с големина {{PLURAL:$1|един килобайт|$1 килобайта}}, което надвишава позволения максимум от {{PLURAL:$2|един килобайт|$2 килобайта}}.</strong>\nПоради тази причина той не може да бъде съхранен.",
        "readonlywarning": "<strong>Внимание: Базата данни беше затворена за поддръжка, затова в момента промените няма да могат да бъдат съхранени.</strong>\nАко желаете, можете да съхраните страницата като текстов файл и да се опитате да я публикувате по-късно.\n\nСистемният администратор, който е затворил базата данни, е посочил следната причина: $1",
        "protectedpagewarning": "<strong>Внимание: Страницата е защитена и само потребители със статут на администратори могат да я редактират.</strong>\nЗа справка по-долу е показан последният запис от дневниците.",
        "permissionserrorstext-withaction": "Нямате разрешение за $2 поради {{PLURAL:$1|следната причина|следните причини}}:",
        "recreate-moveddeleted-warn": "<strong>Внимание: Създавате страница, която по-рано вече е била изтрита.</strong>\n\nОбмислете добре дали е уместно повторното създаване на страницата.\nЗа ваша информация по-долу е посочена причината за предишното изтриване на страницата:",
        "moveddeleted-notice": "Тази страница е изтрита.\nДневниците на изтриванията, защитите и преместванията е показан по-долу.",
+       "moveddeleted-notice-recent": "За съжаление, страницата наскоро е била изтрита (в последните 24 часа).\nПо-долу можете да видите дневник на изтриванията, защитите и преместванията.",
        "log-fulllog": "Преглеждане на пълния дневник",
        "edit-hook-aborted": "Редакцията беше прекъсната от кука.\nНе беше посочена причина за това.",
        "edit-gone-missing": "Страницата не можа да се обнови.\nВероятно междувременно е била изтрита.",
        "edit-conflict": "Конфликт при редактирането.",
        "edit-no-change": "Редакцията Ви беше пренебрегната, защото не съдържа промени по текста.",
+       "edit-slots-cannot-add": "{{PLURAL:$1|Следното място не се поддържа|Следните места не се поддържат}} тук: $2",
+       "edit-slots-cannot-remove": "{{PLURAL:$1|Следното място е задължително и не може да бъде премахнато|Следните места са задължителни и не могат да бъде премахнати}}: $2.",
        "postedit-confirmation-created": "Страницата е създадена.",
        "postedit-confirmation-restored": "Страницата е възстановена.",
        "postedit-confirmation-saved": "Редакцията Ви беше съхранена.",
        "defaultmessagetext": "Текст на съобщението по подразбиране",
        "content-failed-to-parse": "Неуспех при анализиране на съдържанието от тип $2 за модела $1: $3",
        "invalid-content-data": "Невалидни данни за съдържание",
-       "content-not-allowed-here": "На страницата [[:$2]] не е позволено използването на $1",
+       "content-not-allowed-here": "На страницата [[:$2]] не е позволено използването на „$1“ на позиция „$3“",
        "editwarning-warning": "Ако излезете от тази страница, може да загубите всички несъхранени промени, които сте направили.\nАко сте влезли в системата, можете да изключите това предупреждение чрез менюто „{{int:prefs-editing}}“ в личните ви настройки.",
        "editpage-invalidcontentmodel-title": "Форматът на съдържанието не се поддържа",
        "editpage-invalidcontentmodel-text": "Модел на съдържание „$1“ не се поддържа.",
        "editpage-notsupportedcontentformat-title": "Форматът на съдържанието не се поддържа",
+       "editpage-notsupportedcontentformat-text": "Форматът $1 не се поддържа от модела на съдържание $2.",
        "slot-name-main": "Основно",
        "content-model-wikitext": "уикитекст",
        "content-model-text": "обикновен текст",
        "content-json-empty-object": "Празен обект",
        "content-json-empty-array": "Празен масив",
        "deprecated-self-close-category": "Страници, използващи невалидни самозатварящи се HTML тагове",
+       "deprecated-self-close-category-desc": "Страницата съдържа невалидни самозатварящи се HTML тагове, като <code>&lt;b/></code> или <code>&lt;span/></code>. Поведението им скоро ще се промени, за да съответства на изискванията на HTML5, а употреба им в уикитекста е непрепоръчителна.",
        "duplicate-args-category": "Страници, които използват повтарящи се аргументи в извикванията на шаблона",
        "duplicate-args-category-desc": "Страницата съдържа шаблонни извиквания, които използват повтарящи се аргументи, като например <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> или <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "<strong>Внимание:</strong> Тази страница прави твърде много ресурсоемки извиквания на анализиращи функции.\n\nВ момента има {{PLURAL:$1|$1 обръщение|$1 обръщения}} към такива функции, а трябва да {{PLURAL:$1|е|са}} по-малко от $2.",
        "expansion-depth-exceeded-warning": "Страницата е превишила разрешената дълбочина на разгръщане",
        "parser-unstrip-loop-warning": "Открито е ''unstrip'' зацикляне",
        "unstrip-depth-warning": "Превишено ограничение на дълбочина ($1)",
+       "unstrip-size-warning": "Превишено ограничение на размера на unstrip ($1)",
        "undo-success": "Редакцията може да бъде върната.\nПрегледайте долното сравнение и се уверете, че наистина искате да го направите. След това съхранете страницата, за да извършите връщането.",
        "undo-failure": "Редакцията не може да бъде върната поради конфликтни междинни редакции.",
+       "undo-main-slot-only": "Редакцията не може да бъде върната, защото е свързана със съдържание извън главния слот.",
        "undo-norev": "Редакцията не може да бъде върната, тъй като не съществува или е била изтрита.",
        "undo-nochange": "Тази редакция изглежда вече е отменена.",
        "undo-summary": "Премахната редакция $1 на [[Special:Contributions/$2|$2]] ([[User talk:$2|беседа]])",
        "powersearch-togglelabel": "Избор:",
        "powersearch-toggleall": "Всички",
        "powersearch-togglenone": "Никои",
-       "powersearch-remember": "Ð\97апомнÑ\8fне Ð² Ð±Ñ\8aдеÑ\89е",
+       "powersearch-remember": "Ð\97апомнÑ\8fне Ð½Ð° Ð¸Ð·Ð±Ð¾Ñ\80а Ð·Ð° Ð±Ñ\8aдеÑ\89и Ñ\82Ñ\8aÑ\80Ñ\81ениÑ\8f",
        "search-external": "Външно търсене",
        "searchdisabled": "Търсенето в {{SITENAME}} е временно изключено.\nМеждувременно можете да търсите чрез Google.\nОбърнете внимание, че съхранените при тях страници най-вероятно са остарели.",
-       "search-error": "Възникна грешка при търсене: $1",
+       "search-error": "Възникна грешка при търсенето: $1",
        "search-warning": "По време на търсенето беше генерирано предупреждение: $1",
        "preferences": "Настройки",
        "mypreferences": "Настройки",
        "prefs-watchlist-days": "Брой дни, които да се показват в списъка за наблюдение:",
        "prefs-watchlist-days-max": "Най-много $1 {{PLURAL:$1|ден|дни}}",
        "prefs-watchlist-edits": "Максимален брой редакции в списъка за наблюдение:",
-       "prefs-watchlist-edits-max": "Ð\9cакÑ\81имален Ð±Ñ\80ой: 1000",
+       "prefs-watchlist-edits-max": "Ð\9cакÑ\81имална Ñ\81Ñ\82ойноÑ\81Ñ\82: 1000",
        "prefs-watchlist-token": "Уникален идентификатор на списъка за наблюдение:",
        "prefs-watchlist-managetokens": "Управление на маркерите",
        "prefs-misc": "Други",
        "recentchangesdays": "Брой дни в последни промени:",
        "recentchangesdays-max": "(най-много $1 {{PLURAL:$1|ден|дни}})",
        "recentchangescount": "Брой показвани редакции в последните промени, историята на страници и логове по подразбиране:",
-       "prefs-help-recentchangescount": "Ð\9cакÑ\81имален Ð±Ñ\80ой: 1000",
+       "prefs-help-recentchangescount": "Ð\9cакÑ\81имална Ñ\81Ñ\82ойноÑ\81Ñ\82: 1000",
        "prefs-help-watchlist-token2": "Това е секретният ключ към уеб хранилката на вашия списък за наблюдение.\nВсеки, който го знае, би могъл да прегледа списъка ви за наблюдение, така че не го споделяйте.\nПри нужда можете да го [[Special:ResetTokens|изчистите]].",
        "prefs-help-tokenmanagement": "Можете да видите и нулирате тайния ключ за Вашата сметка, който може да има достъп до уеб хранилката на Вашия списък за наблюдение. Всеки, който знае ключа, ще може да види Вашия списък за наблюдение, така че не го споделяйте.",
        "savedprefs": "Настройките ви бяха съхранени.",
        "yourrealname": "Истинско име:",
        "yourlanguage": "Език:",
        "yourvariant": "Езиков вариант на съдържанието:",
+       "prefs-help-variant": "Вашият предпочитан вариант или правопис за показване на страници със съдържание в това уики.",
        "yournick": "Подпис:",
        "prefs-help-signature": "Коментарите в дискусионните страници трябва да се подписват с поредица от четири тилди \"<nowiki>~~~~</nowiki>\", която при съхранение на редакцията сървърът превръща в подпис с потребителско име, дата и час.",
        "badsig": "Избраният подпис не е валиден. Проверете HTML-етикетите!",
        "gender-unknown": "Когато Ви споменава, софтуерът ще използва неутрални думи за пол, когато е възможно",
        "gender-male": "Той редактира уики страниците",
        "gender-female": "Тя редактира уики страниците",
-       "prefs-help-gender": "УÑ\81Ñ\82ановÑ\8fванеÑ\82о Ð½Ð° Ñ\82ази Ð½Ð°Ñ\81Ñ\82Ñ\80ойка Ð½Ðµ Ðµ Ð·Ð°Ð´Ñ\8aлжиÑ\82елно.\nСоÑ\84Ñ\82Ñ\83еÑ\80Ñ\8aÑ\82 Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° Ð¿Ð¾Ñ\81оÑ\87ениÑ\8f Ñ\80од, Ð·Ð° Ð´Ð° Ñ\81е Ð¾Ð±Ñ\8aÑ\80не ÐºÑ\8aм Ð²Ð°Ñ\81 Ñ\81Ñ\8aобÑ\80азно Ð¿Ð¾Ð»Ð° Ð\92и.\nÐ\98нÑ\84оÑ\80маÑ\86иÑ\8fÑ\82а Ñ\89е Ð±Ñ\8aде Ð¿Ñ\83блиÑ\87но Ð´Ð¾Ñ\81Ñ\82Ñ\8aпна.",
+       "prefs-help-gender": "УÑ\81Ñ\82ановÑ\8fванеÑ\82о Ð½Ð° Ñ\82ази Ð½Ð°Ñ\81Ñ\82Ñ\80ойка Ð½Ðµ Ðµ Ð·Ð°Ð´Ñ\8aлжиÑ\82елно.\nСоÑ\84Ñ\82Ñ\83еÑ\80Ñ\8aÑ\82 Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° Ð¿Ð¾Ñ\81оÑ\87ениÑ\8f Ñ\80од, Ð·Ð° Ð´Ð° Ñ\81е Ð¾Ð±Ñ\8aÑ\80не ÐºÑ\8aм Ð\92аÑ\81 Ñ\81Ñ\8aобÑ\80азно Ð¿Ð¾Ð»Ð° Ð\92и.\nÐ\98нÑ\84оÑ\80маÑ\86иÑ\8fÑ\82а Ñ\89е Ð±Ñ\8aде Ð´Ð¾Ñ\81Ñ\82Ñ\8aпна Ð¿Ñ\83блиÑ\87но.",
        "email": "Е-поща",
        "prefs-help-realname": "Истинското име не е задължително.\nАко го посочите, вашите приноси ще бъдат приписани на него.",
        "prefs-help-email": "Електронната поща е незадължителна, но позволява възстановяване на забравена или загубена парола.",
        "userrights-expiry-current": "Изтича на $1",
        "userrights-expiry-none": "Не изтича",
        "userrights-expiry": "Изтича на:",
-       "userrights-expiry-existing": "Ð\9eÑ\81Ñ\82аваÑ\89о Ð²Ñ\80еме: $2, $3",
+       "userrights-expiry-existing": "ТекÑ\83Ñ\89оÑ\82о Ð²Ñ\80еме Ð½Ð° Ð¸Ð·Ñ\82иÑ\87ане: $3, $2",
        "userrights-expiry-othertime": "Друго време:",
        "userrights-expiry-options": "1 ден:1 day,1 седмица:1 week,1 месец:1 month,3 месеца:3 months,6 месеца:6 months,1 година:1 year",
+       "userrights-invalid-expiry": "Срокът на изтичане за групата „$1“ е невалиден.",
+       "userrights-expiry-in-past": "Срокът на изтичане на група „$1“ е в миналото.",
        "group": "Потребителска група:",
        "group-user": "Потребители",
        "group-autoconfirmed": "Автоматично одобрени потребители",
        "right-applychangetags": "Задаване на [[Special:Tags|етикети]] заедно с направените промени",
        "right-changetags": "Добавяне и премахване на произволни [[Special:Tags|етикети]] на индивидуални редакции и записи в дневници",
        "right-deletechangetags": "Изтриване на [[Special:Tags|етикети]] от базата от данни",
+       "grant-generic": "Пакет от права „$1“",
        "grant-group-page-interaction": "Взаимодействие със страници",
        "grant-group-file-interaction": "Взаимодействие с медийни файлове",
        "grant-group-watchlist-interaction": "Взаимодействие с вашия списък за наблюдение",
        "grant-createaccount": "Създаване на сметки",
        "grant-createeditmovepage": "Създаване, редактиране и преместване на страници",
        "grant-delete": "Изтриване на страници, редакции и записи в дневника",
-       "grant-editinterface": "РедакÑ\82иÑ\80ане Ð½Ð° Ð¿Ñ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82воÑ\82о „МедияУики“ и глобалния/потребителския JSON",
+       "grant-editinterface": "РедакÑ\82иÑ\80ане Ð½Ð° Ð¸Ð¼ÐµÐ½Ð½Ð¾Ñ\82о Ð¿Ñ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82Ð²о „МедияУики“ и глобалния/потребителския JSON",
        "grant-editmycssjs": "Редактиране на собствения CSS/JSON/JavaScript",
-       "grant-editmyoptions": "РедакÑ\82иÑ\80ане Ð½Ð° Ð²Ð°Ñ\88иÑ\82е Ð¿Ð¾Ñ\82Ñ\80ебиÑ\82елÑ\81ки Ð½Ð°Ñ\81Ñ\82Ñ\80ойки Ð¸ Ð¿Ð¾Ñ\81Ñ\82авеноÑ\81Ñ\82Ñ\82а Ð½Ð° JSON",
+       "grant-editmyoptions": "РедакÑ\82иÑ\80ане Ð½Ð° Ð²Ð°Ñ\88иÑ\82е Ð¿Ð¾Ñ\82Ñ\80ебиÑ\82елÑ\81ки Ð¿Ñ\80едпоÑ\87иÑ\82аниÑ\8f Ð¸ JSON-конÑ\84игÑ\83Ñ\80аÑ\86иÑ\8fÑ\82а",
        "grant-editmywatchlist": "Редактиране на списъка ви за наблюдение",
        "grant-editsiteconfig": "Редактиране на глобалните и потребителските CSS/JS",
        "grant-editpage": "Редактиране на съществуващи страници",
        "rcfilters-filter-watchlistactivity-seen-description": "Промени по страници, които сте посетили откакто са настъпили промените.",
        "rcfilters-filtergroup-changetype": "Вид на промяната",
        "rcfilters-filter-pageedits-label": "Редакции на страници",
-       "rcfilters-filter-pageedits-description": "Редакции на съдържанието, беседи, описания на категории...",
+       "rcfilters-filter-pageedits-description": "Редакции на съдържанието, беседите, описанията на категориите…",
        "rcfilters-filter-newpages-label": "Създавания на страници",
        "rcfilters-filter-newpages-description": "Редакции, чрез които се създават нови страници.",
        "rcfilters-filter-categorization-label": "Промяна на категории",
        "rcfilters-watchlist-edit-watchlist-button": "Редактиране на списъка за наблюдение",
        "rcfilters-watchlist-showupdated": "Промени по страници, които не сте посетили откакто са внесени промените, са в <strong>получер</strong>, с удебелени маркери.",
        "rcfilters-preference-label": "Използване на интерфейс без JavaScript",
-       "rcfilters-preference-help": "Ð\9eÑ\82менÑ\8f Ð¿Ñ\80еÑ\80абоÑ\82каÑ\82а Ð½Ð° Ð¸Ð½Ñ\82еÑ\80Ñ\84ейÑ\81а Ð½Ð°Ð¿Ñ\80авена Ð¿Ñ\80ез 2017 Ð³Ð¾Ð´Ð¸Ð½Ð°, ÐºÐ°ÐºÑ\82о Ð¸ Ð²Ñ\81иÑ\87ки Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82и Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð¸ Ð¾Ñ\82 Ñ\82огава Ð´Ð¾ Ñ\81ега.",
+       "rcfilters-preference-help": "Ð\97аÑ\80ежда Ð¿Ð¾Ñ\81ледниÑ\82е Ð¿Ñ\80омени Ð±ÐµÐ· Ñ\84илÑ\82Ñ\80и Ð·Ð° Ñ\82Ñ\8aÑ\80Ñ\81ене Ð¸ Ñ\84Ñ\83нкÑ\86ионалноÑ\81Ñ\82 Ð·Ð° Ð¾Ñ\86веÑ\82Ñ\8fване.",
        "rcfilters-watchlist-preference-label": "Използване на интерфейс без JavaScript",
-       "rcfilters-watchlist-preference-help": "Ð\9eÑ\82менÑ\8f Ð¿Ñ\80еÑ\80абоÑ\82каÑ\82а Ð½Ð° Ð¸Ð½Ñ\82еÑ\80Ñ\84ейÑ\81а Ð½Ð°Ð¿Ñ\80авена Ð¿Ñ\80ез 2017 Ð³Ð¾Ð´Ð¸Ð½Ð°, ÐºÐ°ÐºÑ\82о Ð¸ Ð²Ñ\81иÑ\87ки Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82и Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð¸ Ð¾Ñ\82 Ñ\82огава Ð´Ð¾ Ñ\81ега.",
+       "rcfilters-watchlist-preference-help": "Ð\97аÑ\80ежда Ñ\81пиÑ\81Ñ\8aка Ð·Ð° Ð½Ð°Ð±Ð»Ñ\8eдение Ð±ÐµÐ· Ñ\84илÑ\82Ñ\80и Ð·Ð° Ñ\82Ñ\8aÑ\80Ñ\81ене Ð¸ Ñ\84Ñ\83нкÑ\86ионалноÑ\81Ñ\82 Ð·Ð° Ð¾Ñ\86веÑ\82Ñ\8fване.",
        "rcfilters-filter-showlinkedfrom-label": "Показване на промени на страници, към които има връзка от",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Страници, към които има връзка от</strong> избраната страница",
        "rcfilters-filter-showlinkedto-label": "Показване на промени на страници, сочещи към",
        "uploadbtn": "Качване на файл",
        "reuploaddesc": "Връщане към формуляра за качване",
        "upload-tryagain": "Съхраняване на промененото описание на файла",
+       "upload-tryagain-nostash": "Изпращане на повторно качения файл и промененото описание",
        "uploadnologin": "Не сте влезли",
        "uploadnologintext": "За да могат да бъдат качвани файлове е необходимо $1 в системата.",
        "upload_directory_missing": "Директорията за качване ($1) липсва и не може да бъде създадена на сървъра.",
        "file-deleted-duplicate": "Идентичен с този файл ([[:$1]]) вече е бил изтриван.\nИсторията на изтриването на файла следва да се провери, преди да се пристъпи към повторното му качване.",
        "uploadwarning": "Предупреждение при качване",
        "uploadwarning-text": "Необходимо е да промените описанието на файла по-долу и да опитате отново.",
+       "uploadwarning-text-nostash": "Необходимо е да качите повторно файла, да промените описанието по-долу и да опитате отново.",
        "savefile": "Съхраняване на файл",
        "uploaddisabled": "Качванията са забранени.",
        "copyuploaddisabled": "Спряно е качването на файлове чрез URL.",
        "uploadstash-refresh": "Обновяване на списъка с файлове",
        "uploadstash-thumbnail": "преглед на миниатюра",
        "uploadstash-bad-path-unknown-type": "Неизвестен тип „$1“.",
+       "uploadstash-wrong-owner": "Файлът ($1) не принадлежи на текущия потребител.",
+       "uploadstash-no-such-key": "Няма такъв ключ ($1), не може да бъде премахнат.",
+       "uploadstash-no-extension": "Разширението е нулево.",
+       "uploadstash-zero-length": "Файлът е с нулева дължина.",
        "img-auth-accessdenied": "Достъпът е отказан",
        "img-auth-nopathinfo": "Липсва информация за пътя.\nВашият сървър трябва да бъде настроен да предава променливите REQUEST_URI и PATH_INFO .\nАко това е така, опитайте да активирате $wgUsePathInfo.\n\nВижте https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Търсеният път не е в настроената директория за качвания.",
        "http-timed-out": "Пресрочено време за HTTP заявка.",
        "http-curl-error": "Грешка при извличането на URL: $1",
        "http-bad-status": "Настъпи проблем по време на HTTP заявката: $1 $2",
+       "http-internal-error": "Вътрешна грешка в HTTP.",
        "upload-curl-error6": "Не е възможно достигането на указания URL адрес",
        "upload-curl-error6-text": "Търсеният адрес не може да бъде достигнат.\nПроверете дали е написан вярно и дали сайтът не е паднал.",
        "upload-curl-error28": "Времето за качване изтече",
        "filerevert-submit": "Връщане",
        "filerevert-success": "Файлът <strong>[[Media:$1|$1]]</strong> беше възвърнат към [$4 версия от $3, $2].",
        "filerevert-badversion": "Не съществува предишна локална версия на файла със зададения времеви отпечатък.",
+       "filerevert-identical": "Текущата версия на файла е идентична с избраната.",
        "filedelete": "Изтриване на $1",
        "filedelete-legend": "Изтриване на файл",
        "filedelete-intro": "На път сте да изтриете файла <strong>[[Media:$1|$1]]</strong> заедно с цялата му редакционна история.",
        "unwatchedpages": "Ненаблюдавани страници",
        "listredirects": "Списък на пренасочванията",
        "listduplicatedfiles": "Списък на повтарящи се файлове",
-       "listduplicatedfiles-summary": "Това Ðµ Ñ\81пиÑ\81Ñ\8aк Ð½Ð° Ñ\84айловеÑ\82е, Ð·Ð° ÐºÐ¾Ð¸Ñ\82о Ð¿Ð¾Ñ\81леднаÑ\82а Ð²ÐµÑ\80Ñ\81иÑ\8f Ðµ Ð´Ñ\83бликаÑ\82 Ñ\81 Ð¿Ð¾Ñ\81леднаÑ\82а Ð²ÐµÑ\80Ñ\81иÑ\8f Ð½Ð° Ð´Ñ\80Ñ\83г Ñ\84айл. Ð\9fоказани Ñ\81а Ñ\81амо Ð¼ÐµÑ\81Ñ\82ните файлове.",
+       "listduplicatedfiles-summary": "Това Ðµ Ñ\81пиÑ\81Ñ\8aк Ð½Ð° Ñ\84айловеÑ\82е, Ð·Ð° ÐºÐ¾Ð¸Ñ\82о Ð¿Ð¾Ñ\81леднаÑ\82а Ð²ÐµÑ\80Ñ\81иÑ\8f Ðµ Ð´Ñ\83бликаÑ\82 Ñ\81 Ð¿Ð¾Ñ\81леднаÑ\82а Ð²ÐµÑ\80Ñ\81иÑ\8f Ð½Ð° Ð´Ñ\80Ñ\83г Ñ\84айл. Ð\9fоказани Ñ\81а Ñ\81амо Ð»Ð¾ÐºÐ°Ð»ните файлове.",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] има [[$3|{{PLURAL:$2|дубликат|$2 дубликата}}]].",
        "unusedtemplates": "Неизползвани шаблони",
        "unusedtemplatestext": "Тази страница съдържа списък на страниците в именно пространство {{ns:template}}, които не са включени в друга страница. Проверявайте за препратки към отделните шаблони преди да ги изтриете или предложите за изтриване.",
        "statistics": "Статистика",
        "statistics-header-pages": "Статистики за страницата",
        "statistics-header-edits": "Статистики за редакциите",
-       "statistics-header-users": "Потребители",
+       "statistics-header-users": "Потребителски статистики",
        "statistics-header-hooks": "Други статистики",
        "statistics-articles": "Съдържателни страници",
        "statistics-pages": "Страници",
        "wantedpages-badtitle": "Невалидно заглавие в резултатното множество: $1",
        "wantedfiles": "Желани файлове",
        "wantedfiletext-cat": "Следните файлове се използват, но не съществуват. Файлове от външни хранилища могат да бъдат показани. Всички подобни неверни положителни резултати ще бъдат <del>зачеркнати</del>. Също така, страниците, които включват файлове, които не съществуват са включени в [[:$1]].",
+       "wantedfiletext-cat-noforeign": "Следните файлове се използват, но не съществуват. Страниците с несъществуващи файлове са изброени в [[:$1]].",
        "wantedfiletext-nocat": "Следните файлове се използват, но не съществуват. Възможно е да са включени файлове от външни хранилища, въпреки че съществуват. Всички такива случаи на възможна фалшива тревога ще бъдат показвани <del>зачеркнати</del>.",
+       "wantedfiletext-nocat-noforeign": "Следните файлове се използват, но не съществуват.",
        "wantedtemplates": "Желани шаблони",
        "mostlinked": "Най-препращани страници",
        "mostlinkedcategories": "Най-препращани категории",
        "pager-older-n": "{{PLURAL:$1|по-стара 1|по-стари $1}}",
        "suppress": "Подтискане",
        "querypage-disabled": "Тази специална страница е изключена, защото затруднява производителността на уикито.",
-       "apihelp": "Помощ за приложението",
+       "apihelp": "Помощ за API-то",
        "apihelp-no-such-module": "Модул „$1“ не беше намерен.",
        "apisandbox": "Пясъчник за API",
+       "apisandbox-jsonly": "Необходим е JavaScript, за да използвате API пясъчника.",
+       "apisandbox-api-disabled": "API е изключен за този сайт.",
        "apisandbox-submit": "Направи запитване",
        "apisandbox-reset": "Изчистване",
        "apisandbox-retry": "Повторен опит",
        "apisandbox-dynamic-parameters-add-label": "Добавяне на параметър:",
        "apisandbox-dynamic-parameters-add-placeholder": "Име на параметъра",
        "apisandbox-dynamic-error-exists": "Параметър с име „$1“ вече съществува.",
-       "apisandbox-deprecated-parameters": "Ð\9eÑ\81Ñ\82аÑ\80ели параметри",
+       "apisandbox-deprecated-parameters": "Ð\9dепÑ\80епоÑ\80Ñ\8aÑ\87иÑ\82елни параметри",
        "apisandbox-fetch-token": "Автоматично попълване на маркера",
        "apisandbox-add-multi": "Добавяне",
        "apisandbox-submit-invalid-fields-title": "Някои полета са невалидни",
        "apisandbox-results": "Резултати",
        "apisandbox-sending-request": "Изпращане на API заявка...",
        "apisandbox-loading-results": "Получаване на API резултати...",
+       "apisandbox-request-selectformat-label": "Показване на заявката с данни като:",
+       "apisandbox-request-format-url-label": "URL-низ на заявката",
        "apisandbox-request-url-label": "URL-адрес на заявката:",
        "apisandbox-request-format-json-label": "JSON",
        "apisandbox-request-json-label": "JSON заявка:",
        "apisandbox-alert-field": "Стойността на това поле не е валидна.",
        "apisandbox-continue": "Продължаване",
        "apisandbox-continue-clear": "Изчистване",
-       "apisandbox-param-limit": "Ð\92Ñ\8aведеÑ\82е <kbd>max</kbd> Ð·Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° ÐºÑ\80айниÑ\8f Ð¿Ñ\80едел.",
+       "apisandbox-param-limit": "Ð\92Ñ\8aведеÑ\82е <kbd>max</kbd> Ð·Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ð¼Ð°ÐºÑ\81ималнаÑ\82а Ñ\81Ñ\82ойноÑ\81Ñ\82.",
        "apisandbox-multivalue-all-namespaces": "$1 (Всички именни пространства)",
        "apisandbox-multivalue-all-values": "$1 (Всички стойности)",
        "booksources": "Източници на книги",
        "booksources-text": "По-долу е списъкът от връзки към други сайтове, продаващи нови и използвани книги или имащи повече информация за книгите, които търсите:",
        "booksources-invalid-isbn": "Предоставеният ISBN изглежда е невалиден; проверете за грешки и копирайте от оригиналния източник.",
        "magiclink-tracking-rfc": "Страници, използващи вълшебни препратки RFC",
+       "magiclink-tracking-rfc-desc": "Тази страница използва вълшебни препратки RFC. Вижте [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] как да ги пренесете.",
        "magiclink-tracking-pmid": "Страници, използващи вълшебни препратки PMID",
        "magiclink-tracking-pmid-desc": "Тази страница използва вълшебни препратки PMID. Вижте [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] как да ги пренесете.",
        "magiclink-tracking-isbn": "Страници, използващи вълшебни препратки ISBN",
        "trackingcategories-name": "Име на съобщението",
        "trackingcategories-desc": "Критерий за включване на категория",
        "restricted-displaytitle-ignored": "Страници с игнорирани заглавия за показване",
+       "restricted-displaytitle-ignored-desc": "Страницата съдържа игнориран <code><nowiki>{{DISPLAYTITLE}}</nowiki></code>, защото той не съвпада с действителното заглавие на страницата.",
+       "noindex-category-desc": "Страницата не се индексира от роботи, защото съдържа вълшебната думичка <code><nowiki>__NOINDEX__</nowiki></code> и е от именно пространство, в което такова отбелязване е позволено.",
+       "index-category-desc": "Страницата съдържа <code><nowiki>__INDEX__</nowiki></code> (и е от именно пространство, в което такова отбелязване е позволено), поради което се индексира от роботи, където обикновено не би била индексирана.",
+       "post-expand-template-inclusion-category-desc": "Страницата е по-голяма от <code>$wgMaxArticleSize</code> след разгръщането на всички шаблони, поради което някои шаблони не са разгърнати.",
+       "post-expand-template-argument-category-desc": "Страницата е по-голяма от <code>$wgMaxArticleSize</code> след разгръщането на аргументите на шаблона (нещо в тройни фигурни скоби, например <code>{{{Foo}}}</code>).",
+       "expensive-parserfunction-category-desc": "Страницата използва твърде много ресурсоемки анализиращи функции (като <code>#ifexist</code>). Вижте [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
+       "broken-file-category-desc": "Страницата съдържа повредена препратка към файл (препратка за поставяне на файл, когато такъв не съществува).",
+       "hidden-category-category-desc": "Категорията съдържа <code><nowiki>__HIDDENCAT__</nowiki></code>, което предотвратява показването ѝ в страниците по подразбиране.",
        "trackingcategories-nodesc": "Няма налично описание.",
        "trackingcategories-disabled": "Категорията е деактивирана",
        "mailnologin": "Няма електронна поща",
        "rollbacklinkcount": "отмяна на $1 {{PLURAL:$1|редакция|редакции}}",
        "rollbacklinkcount-morethan": "отмяна на повече от $1 {{PLURAL:$1|редакция|редакции}}",
        "rollbackfailed": "Отмяната не сполучи",
+       "rollback-missingparam": "Липсващи задължителни параметри на заявката.",
        "rollback-missingrevision": "Данните за версията не могат да бъдат заредени.",
        "cantrollback": "Не може да се извърши отмяна на редакциите. Последният редактор е и единствен автор на страницата.",
        "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}}]]).",
        "namespace": "Именно пространство:",
        "invert": "Обръщане на избора",
        "tooltip-invert": "Поставянето на отметка ще скрие всички промени в страниците от избраното именно пространство (и свързаните именни пространства)",
+       "tooltip-whatlinkshere-invert": "Отбележете полето, за да скриете препратки от страници от избраното именно пространство.",
        "namespace_association": "Свързани именни пространства",
        "tooltip-namespace_association": "Поставянето на отметка ще включи и беседите и именните пространства, свързани с избраното именно пространство.",
        "blanknamespace": "(Основно)",
        "anoncontribs": "Приноси",
        "contribsub2": "За {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Няма регистрирана потребителска сметка за „$1“.",
+       "negative-namespace-not-supported": "Именни пространства с негативни стойности не се поддържат.",
        "nocontribs": "Не са намерени промени, отговарящи на критерия.",
        "uctop": "текуща",
        "month": "От месец (и по-рано):",
        "ipb-disableusertalk": "Редактиране на собствената дискусионна страница",
        "ipb-change-block": "Повторно блокиране на потребителя с тези настройки",
        "ipb-confirm": "Потвърждаване на блокирането",
+       "ipb-sitewide": "За всички уикита",
+       "ipb-partial": "Частично",
+       "ipb-partial-help": "Конкретни страници или именни пространства.",
+       "ipb-pages-label": "Страници",
        "ipb-namespaces-label": "Именни пространства",
        "badipaddress": "Невалиден IP-адрес",
        "blockipsuccesssub": "Блокирането беше успешно",
        "ipb-blocklist-contribs": "Приноси на {{GENDER:$1|$1}}",
        "ipb-blocklist-duration-left": "{{PLURAL:$1|остава още $1|остават още $1}}",
        "block-actions": "Действия за блокиране:",
-       "block-expiry": "Срок:",
-       "block-options": "Ð\94опÑ\8aлниÑ\82елни Ð²Ñ\8aзможноÑ\81Ñ\82и:",
+       "block-expiry": "Срок на изтичане:",
+       "block-options": "Ð\94опÑ\8aлниÑ\82елни Ð½Ð°Ñ\81Ñ\82Ñ\80ойки:",
        "block-prevent-edit": "Редактиране",
        "block-reason": "Причина:",
        "block-target": "Потребителско име или IP-адрес:",
        "createaccountblock": "създаването на сметки е блокирано",
        "emailblock": "е-пощенската услуга е блокирана",
        "blocklist-nousertalk": "забрана за редактиране на личната беседа",
+       "blocklist-editing": "редактиране",
+       "blocklist-editing-sitewide": "редактиране (за всички уикита)",
        "blocklist-editing-page": "страници",
        "blocklist-editing-ns": "именни пространства",
        "ipblocklist-empty": "Списъкът на блокиранията е празен.",
        "ipb_expiry_old": "Срокът на изтичане е минал.",
        "ipb_expiry_temp": "Скритите потребителски имена трябва да се блокират безсрочно.",
        "ipb_hide_invalid": "Тази потребителска сметка не може да бъде прикрита; с нея са направени повече от {{PLURAL:$1|една редакция|$1 редакции}}.",
-       "ipb_hide_partial": "СкÑ\80иÑ\82иÑ\82е Ð·Ð°Ð±Ñ\80ани Ð·а потребителски имена трябва да се прилагат за цяло уики.",
+       "ipb_hide_partial": "СкÑ\80иÑ\82иÑ\82е Ð±Ð»Ð¾ÐºÐ¸Ñ\80аниÑ\8f Ð½а потребителски имена трябва да се прилагат за цяло уики.",
        "ipb_already_blocked": "„$1“ е вече блокиран.",
        "ipb-needreblock": "$1 е вече блокиран. Желаете ли да промените настройките?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Друго блокиране|Други блокирания}}",
        "ip_range_invalid": "Невалиден диапазон на IP-адреси.",
        "ip_range_toolarge": "Забранено е блокиране на диапазони от IP адреси по-големи от /$1.",
        "ip_range_exceeded": "IP диапазонът превишава максималния диапазон. Позволен диапазон: /$1.",
+       "ip_range_toolow": "IP-диапазоните не са позволени.",
        "proxyblocker": "Блокировач на проксита",
        "proxyblockreason": "IP-адресът Ви беше блокиран, тъй като представлява анонимно достъпен междинен сървър.\nСвържете се с доставчика си на Интернет и го информирайте за този сериозен проблем в сигурността.",
        "sorbs": "DNSBL",
        "move-watch": "Наблюдаване на изходната и целевата страници",
        "movepagebtn": "Преместване",
        "pagemovedsub": "Преместването беше успешно",
+       "cannotmove": "Страницата не може да бъде преместена, поради {{PLURAL:следната причина|следните $1 причини}}:",
        "movepage-moved": "<strong>Страницата „$1“ беше преместена под името „$2“</strong>",
        "movepage-moved-redirect": "Беше създадено пренасочване.",
        "movepage-moved-noredirect": "Създаването на пренасочване беше спряно.",
        "djvu_no_xml": "Не е възможно вземането на XML за DjVu-файла",
        "thumbnail-temp-create": "Временния файл с миникартинка не може да бъде създаден.",
        "thumbnail_invalid_params": "Параметрите за миникартинка са невалидни",
+       "thumbnail_toobigimagearea": "Файл с размери по-големи от $1",
        "thumbnail_dest_directory": "Целевата директория не може да бъде създадена",
        "thumbnail_image-type": "Типът картинка не се поддържа",
        "thumbnail_gd-library": "Непълна конфугурация на библиотеката GD: липсва функцията $1",
        "import-interwiki-history": "Копиране на всички версии на страницата",
        "import-interwiki-templates": "Включване на всички шаблони",
        "import-interwiki-submit": "Внасяне",
+       "import-mapping-default": "Внасяне в стандартни местоположения",
        "import-mapping-namespace": "Импортиране в именно пространство:",
        "import-mapping-subpage": "Импортиране като подстраници на следната страница:",
        "import-upload-filename": "Име на файл:",
+       "import-upload-username-prefix": "Междууики представка:",
        "import-comment": "Коментар:",
        "importtext": "Изнесете файла от изходното уики чрез „[[Special:Export|инструмента за изнасяне]]“. Съхранете го на твърдия диск на компютъра си и го качете тук.",
        "importstart": "Внасяне на страници…",
        "imported-log-entries": "{{PLURAL:$1|Внесен е $1 запис|Внесени са $1 записа}} в дневника.",
        "importfailed": "Внасянето беше неуспешно: nowiki>$1</nowiki>",
        "importunknownsource": "Непознат тип файл",
+       "importnoprefix": "Не е указана междууики представка",
        "importcantopen": "Не е възможно да се отвори файла за внасяне",
        "importbadinterwiki": "Невалидна уики препратка",
        "importsuccess": "Внасянето беше успешно!",
        "tooltip-n-help": "Място, където може да се информирате",
        "tooltip-t-whatlinkshere": "Списък на всички страници, сочещи насам",
        "tooltip-t-recentchangeslinked": "Последните промени на страници, сочени от тази страница",
-       "tooltip-feed-rss": "RSS feed за страницата",
+       "tooltip-feed-rss": "RSS-хранилка за страницата",
        "tooltip-feed-atom": "Atom feed за страницата",
        "tooltip-t-contributions": "Списък на приносите на {{GENDER:$1|потребителя}}",
        "tooltip-t-emailuser": "Изпращане на писмо до {{GENDER:$1|потребителя}}",
        "tooltip-watchlistedit-normal-submit": "Премахване на заглавия",
        "tooltip-watchlistedit-raw-submit": "Обновяване на списъка за наблюдение",
        "tooltip-recreate": "Възстановяване на страницата независимо, че е била изтрита",
-       "tooltip-upload": "Ð\97апоÑ\87ване на качването",
+       "tooltip-upload": "Ð\9dаÑ\87ало на качването",
        "tooltip-rollback": "Чрез „отмяна“ ще премахнете наведнъж всички промени, нанесени от последния редактор",
        "tooltip-undo": "Препратката „връщане“ премахва тази редакция и отваря страницата за редактиране в режим на предварителен преглед.\nВ полето за резюме може да се впише причина за връщането.",
        "tooltip-preferences-save": "Съхраняване на предпочитанията",
        "pageinfo-file-hash": "Хеш-стойност",
        "pageinfo-view-protect-log": "Преглед на дневника на защитата за тази страница.",
        "markaspatrolleddiff": "Отбелязване на редакцията като патрулирана",
-       "markaspatrolledtext": "Отбелязване на редакцията като проверена",
-       "markaspatrolledtext-file": "Отбелязване на версията на файла като проверена",
-       "markedaspatrolled": "Проверена редакция",
+       "markaspatrolledtext": "Отбелязване на редакцията като патрулирана",
+       "markaspatrolledtext-file": "Отбелязване на версията на файла като патрулирана",
+       "markedaspatrolled": "Патрулирана редакция",
        "markedaspatrolledtext": "Избраната редакция на [[:$1]] беше отбелязана като патрулирана.",
        "rcpatroldisabled": "Патрулът е деактивиран",
        "rcpatroldisabledtext": "Патрулирането на последните промени е деактивирано.",
-       "markedaspatrollederror": "Не е възможно да се отбележи като проверена",
-       "markedaspatrollederrortext": "Необходимо е да се посочи редакция, която да бъде отбелязана като проверена.",
+       "markedaspatrollederror": "Не е възможно да се отбележи като патрулирана",
+       "markedaspatrollederrortext": "Необходимо е да се посочи редакция, която да бъде отбелязана като патрулирана.",
        "markedaspatrollederror-noautopatrol": "Не е разрешено да маркирате своите редакции като патрулирани.",
        "markedaspatrollednotify": "Редакцията на $1 беше отбелязана като патрулирана.",
        "markedaspatrollederrornotify": "Неуспешно отбелязване на редакция като патрулирана.",
        "newimages-user": "IP-адрес или потребителско име",
        "newimages-newbies": "Показване на приносите само на нови потребители",
        "newimages-showbots": "Показване на качвания от ботове",
-       "newimages-hidepatrolled": "Скриване на проверените качвания",
+       "newimages-hidepatrolled": "Скриване на патрулираните качвания",
        "newimages-mediatype": "Файлов тип:",
        "noimages": "Няма нищо.",
        "gallery-slideshow-toggle": "Превключване на миниатюрите",
        "confirmemail_body_set": "Някой, вероятно Вие, от IP адрес $1,\nе посочил този адрес за електронната поща, свързан с потребителска сметка „$2“ в {{SITENAME}}.\n\nЗа потвърждаване, че тази потребителска сметка наистина Ви принадлежи и за да активирате отново функциите, свързани с електронна поща в {{SITENAME}}, необходимо е да отворите във вашия браузър следната препратка:\n\n$3\n\nАко потребителската сметка *не* Ви принадлежи, можете да откажете потвърждението, като последвате следната препратка:\n\n$5\n\nВалидността на този код за потвърждение изтича на $4.",
        "confirmemail_invalidated": "Отменено потвърждение за електронна поща",
        "invalidateemail": "Отмяна на потвърждението за електронна поща",
+       "notificationemail_body_changed": "Някой, вероятно вие, от IP-адрес $1,\nе сменил електронната поща на сметката „$2“ на „$3“ в {{SITENAME}}.\n\nАко не сте вие, веднага се свържете с администратор.",
        "scarytranscludedisabled": "[Включването между уикита е деактивирано]",
        "scarytranscludefailed": "[Зареждането на шаблона за $1 не сполучи]",
        "scarytranscludetoolong": "[Адресът е твърде дълъг]",
        "confirm-unwatch-top": "Премахване на страницата от списъка Ви за наблюдение?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Отменяне на редакции по тази страница?",
+       "confirm-mcrrestore-title": "Възстановяване на версия",
+       "confirm-mcrundo-title": "Връщане на промяна",
+       "mcrundofailed": "Неуспех при връщане",
+       "mcrundo-missingparam": "Липсващи задължителни параметри на заявката.",
        "semicolon-separator": ";&#32;",
        "comma-separator": ",&#32;",
        "colon-separator": ":&#32;",
        "autosumm-changed-redirect-target": "Промяна на целта на пренасочване от [[$1]] на [[$2]]",
        "autosumm-new": "Нова страница: „$1“",
        "autosumm-newblank": "Създаване на празна страница",
-       "lag-warn-normal": "Промените от {{PLURAL:$1|последната $1 секунда|последните $1 секунди}} вероятно не са показани в списъка.",
-       "lag-warn-high": "Поради голямото изоставане в сървърната синхронизация, промените от {{PLURAL:$1|последната $1 секунда|последните $1 секунди}} вероятно не са показани в списъка.",
+       "lag-warn-normal": "Промените от {{PLURAL:$1|последната секунда|последните $1 секунди}} вероятно не са показани в списъка.",
+       "lag-warn-high": "Поради голямото изоставане в сървърната синхронизация, промените от {{PLURAL:$1|последната секунда|последните $1 секунди}} вероятно не са показани в списъка.",
        "watchlistedit-normal-title": "Редактиране на списъка за наблюдение",
        "watchlistedit-normal-legend": "Премахване на записи от списъка за наблюдение",
        "watchlistedit-normal-explain": "По-долу са показани заглавията на страниците от списъка ви за наблюдение.\nЗа да премахнете страница, отбележете полето пред нея и щракнете на бутона „{{int:Watchlistedit-normal-submit}}“.\nМожете също да редактирате [[Special:EditWatchlist/raw|необработения списък за наблюдение]].",
        "tags-edit": "редактиране",
        "tags-delete": "изтриване",
        "tags-activate": "активиране",
-       "tags-deactivate": "спиране",
+       "tags-deactivate": "деактивиране",
        "tags-hitcount": "$1 {{PLURAL:$1|промяна|промени}}",
        "tags-manage-no-permission": "Нямате права за управление на етикети за промени.",
        "tags-manage-blocked": "Не може да управлявате етикети за промени, докато сте {{GENDER:$1|блокирани}}.",
        "logentry-rights-autopromote": "$1 е автоматично {{GENDER:$2|повишен|повишена}} от $4 до $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|качи}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|качи}} нова версия на $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|каÑ\87и}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|вÑ\8aÑ\80на}} $3 ÐºÑ\8aм Ð¿Ð¾-Ñ\81Ñ\82аÑ\80а Ð²ÐµÑ\80Ñ\81иÑ\8f",
        "log-name-managetags": "Дневник на управлението на етикети",
        "log-description-managetags": "На тази страница са изброени задачи, свързани с управлението на [[Special:Tags|етикети]]. Дневникът съдържа само действия, извършвани ръчно от администратор. Етикети могат да бъдат създавани или изтривани от уики софтуера без това да бъде отразено в този дневник.",
        "logentry-managetags-create": "$1 {{GENDER:$2|създаде}} етикета „$4“",
        "expand_templates_input": "Входящ уикитекст:",
        "expand_templates_output": "Резултат",
        "expand_templates_xml_output": "Изход на XML",
+       "expand_templates_html_output": "Суров HTML изход",
        "expand_templates_ok": "ОК",
        "expand_templates_remove_comments": "Премахване на коментари",
        "expand_templates_remove_nowiki": "Потискане на елементите <nowiki> в резултата",
        "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": "Дневник на езиковите промени",
        "mediastatistics-header-multimedia": "Мултимедия",
        "mediastatistics-header-office": "Офис",
        "mediastatistics-header-total": "Всички файлове",
+       "json-error-state-mismatch": "Невалиден или грешно структуриран JSON",
+       "json-error-ctrl-char": "Грешка в контролния знак. Вероятно е неправилно кодиран",
        "json-error-syntax": "Синтактична грешка",
        "headline-anchor-title": "Препратка към този раздел",
        "special-characters-group-latin": "Латиница",
        "special-characters-title-endash": "средно тире",
        "special-characters-title-emdash": "дълго тире",
        "special-characters-title-minus": "знак минус",
-       "mw-widgets-abandonedit": "Сигурни ли сте, че искате да напуснете режима за редактиране без да запишете статията преди това?",
+       "mw-widgets-abandonedit": "Сигурни ли сте, че искате да напуснете режима за редактиране без да съхраните промените?",
        "mw-widgets-abandonedit-discard": "Отказване на редакциите",
        "mw-widgets-abandonedit-keep": "Продължаване на редактирането",
        "mw-widgets-abandonedit-title": "Сигурни ли сте?",
        "mw-widgets-titleinput-description-redirect": "пренасочване към $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Добавяне на категория...",
        "mw-widgets-usersmultiselect-placeholder": "Добавяне на още...",
+       "mw-widgets-titlesmultiselect-placeholder": "Добавяне на още...",
        "date-range-from": "От дата:",
        "date-range-to": "До дата:",
        "sessionprovider-generic": "$1 сесии",
        "log-action-filter-protect-move_prot": "Преместване на защитата",
        "log-action-filter-rights-rights": "Ръчна промяна",
        "log-action-filter-rights-autopromote": "Автоматична промяна",
+       "log-action-filter-suppress-event": "Потискане на дневника",
+       "log-action-filter-suppress-revision": "Потискане на версията",
+       "log-action-filter-suppress-delete": "Потискане на страницата",
+       "log-action-filter-suppress-block": "Потискане на потребителя чрез блокиране",
+       "log-action-filter-suppress-reblock": "Потискане на потребителя чрез повторно блокиране",
        "log-action-filter-upload-upload": "Ново качване",
        "log-action-filter-upload-overwrite": "Повторно качване",
+       "log-action-filter-upload-revert": "Връщане",
        "authmanager-create-disabled": "Създаването на сметки е изключено.",
        "authmanager-create-from-login": "За да създадете сметка, моля попълнете полетата.",
-       "authmanager-authplugin-setpass-failed-title": "Промяната на паролата е неуспешна",
-       "authmanager-authplugin-setpass-bad-domain": "Невалиден домейн.",
        "authmanager-userdoesnotexist": "Няма регистрирана потребителска сметка за „$1“.",
        "authmanager-retype-help": "Парола (повторно) за потвърждение.",
        "authmanager-email-label": "Е-поща",
        "authmanager-email-help": "Електронна поща",
        "authmanager-realname-label": "Истинско име",
        "authmanager-realname-help": "Истинско име на потребителя",
-       "authmanager-provider-password": "Ð\90вÑ\82енÑ\82икаÑ\86иÑ\8f с парола",
+       "authmanager-provider-password": "УдоÑ\81Ñ\82овеÑ\80Ñ\8fване с парола",
        "authmanager-provider-temporarypassword": "Временна парола",
        "authprovider-confirmlink-option": "$1 ($2)",
        "authprovider-confirmlink-failed-line": "$1: $2",
        "specialpage-securitylevel-not-allowed-title": "Не е позволено",
        "cannotauth-not-allowed-title": "Достъпът е отказан",
        "cannotauth-not-allowed": "Не ви е позволено да използвате тази страница",
-       "changecredentials": "Ð\9fÑ\80омÑ\8fна Ð½Ð° Ð¿Ð¾Ñ\82Ñ\80ебиÑ\82елÑ\81ките данни",
-       "changecredentials-submit": "Ð\9fÑ\80омÑ\8fна Ð½Ð° Ð¿Ð°Ñ\80ола",
-       "removecredentials": "Ð\9fÑ\80емаÑ\85ване Ð½Ð° Ð¿Ð¾Ñ\82Ñ\80ебиÑ\82елÑ\81ките данни",
-       "removecredentials-submit": "Ð\9fÑ\80емаÑ\85ване Ð½Ð° Ð¿Ð¾Ñ\82Ñ\80ебиÑ\82елÑ\81ките данни",
-       "credentialsform-provider": "Тип Ð½Ð° Ð°Ð²Ñ\82енÑ\82икаÑ\86иÑ\8fÑ\82а:",
+       "changecredentials": "Ð\9fÑ\80омÑ\8fна Ð½Ð° Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\86ионните данни",
+       "changecredentials-submit": "Ð\9fÑ\80омÑ\8fна Ð½Ð° Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\86ионниÑ\82е Ð´Ð°Ð½Ð½Ð¸",
+       "removecredentials": "Ð\9fÑ\80емаÑ\85ване Ð½Ð° Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\86ионните данни",
+       "removecredentials-submit": "Ð\9fÑ\80емаÑ\85ване Ð½Ð° Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\86ионните данни",
+       "credentialsform-provider": "Тип Ð½Ð° Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\86ионниÑ\82е Ð´Ð°Ð½Ð½Ð¸:",
        "credentialsform-account": "Име на сметка:",
        "linkaccounts": "Свързване на сметки",
        "linkaccounts-success-text": "Сметката беше свързана.",
        "gotointerwiki-invalid": "Указаното заглавие е невалидно.",
        "pagedata-title": "Данни за страницата",
        "pagedata-bad-title": "Невалидно заглавие: $1.",
+       "unregistered-user-config": "От съображения за сигурност, потребителските подстраници с JavaScript, CSS и JSON не се зареждат за нерегистрирани потребители.",
        "passwordpolicies": "Правила за паролите",
        "passwordpolicies-summary": "Това е списъкът на действащите правила за паролите на потребителските групи дефинирани в това уики.",
        "passwordpolicies-group": "Група",
        "passwordpolicies-policy-passwordcannotmatchusername": "Паролата не може да бъде същата като потребителското име",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Паролата не може да съвпада с пароли от черния списък",
        "passwordpolicies-policy-maximalpasswordlength": "Паролата трябва да бъде по-малко от $1 {{PLURAL:$1|знак|знака}}",
-       "passwordpolicies-policy-passwordcannotbepopular": "Паролата не може да бъде {{PLURAL:$1|най-популярната такава|от списъка на най-популярните $1 пароли}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "Паролата не може да бъде {{PLURAL:$1|най-популярната такава|от списъка на най-популярните $1 пароли}}",
+       "passwordpolicies-policyflag-forcechange": "трябва да бъде променена при влизане"
 }
index 4c5b57b..3fccc3c 100644 (file)
@@ -39,7 +39,8 @@
                        "Shahadat1971",
                        "Rasal Lia",
                        "আফতাবুজ্জামান",
-                       "Tahmid02016"
+                       "Tahmid02016",
+                       "Ifsad"
                ]
        },
        "tog-underline": "সংযোগের নিচে দাগ দেখানো হোক:",
@@ -85,6 +86,7 @@
        "tog-norollbackdiff": "রোলব্যাকের পরে সংস্করণগুলির পার্থক্য না দেখানো হোক",
        "tog-useeditwarning": "কোনো সম্পাদনা পাতা ত্যাগের সময় পরিবর্তনগুলি সংরক্ষিত না হয়ে থাকলে আমাকে সাবধান করা হোক",
        "tog-prefershttps": "অ্যাকাউন্টে প্রবেশ করার সময় সবসময় নিরাপদ সংযোগ ব্যবহার করুন",
+       "tog-showrollbackconfirmation": "একটি রোলব্যাক লিঙ্ক ক্লিক করার সময় একটি নিশ্চিতকরণ বার্তা দেখান",
        "underline-always": "সব সময়",
        "underline-never": "কখনো নয়",
        "underline-default": "আবরণ বা ব্রাউজারে যেমনভাবে নির্দিষ্ট করা আছে",
        "delete-scheduled": "\"$1\" পাতাটি মুছে ফেলার জন্য তালিকাভুক্ত হয়েছে।\nদয়া করে ধৈর্য ধরুন।",
        "delete-hook-aborted": "হুকের কারণে পাতা মোছার কাজটি পরিত্যক্ত হয়েছে।\nকোন ব্যাখ্যা দেয়া হয়নি।",
        "no-null-revision": "\"$1\" পাতার জন্য ফাঁকা সংস্করণ তৈরী করা যায়নি",
-       "badtitle": "ভà§\81ল শিরোনাম",
-       "badtitletext": "অনুরোধকৃত পাতার শিরোনামটি অবৈধ, খালি কিংবা কোন ভুল আন্তঃভাষা বা আন্তঃউইকি শিরোনাম সংযোগ ছিল। এটিতে সম্ভবত এমন এক (একাধিক) ক্যারেক্টার আছে, যা (যেগুলি) শিরোনামে ব্যবহারযোগ্য নয়।",
+       "badtitle": "à¦\96ারাপ শিরোনাম",
+       "badtitletext": "অনুরোধকৃত পাতার শিরোনামটি অবৈধ, খালি কিংবা কোন ভুল আন্তঃভাষা বা আন্তঃউইকি শিরোনামে সংযুক্ত ছিল। এটিতে সম্ভবত এক বা একাধিক অক্ষর আছে, যা শিরোনাম হিসেবে ব্যবহার করা যাবে না।",
        "title-invalid-empty": "অনুরোধকৃত পাতার শিরোনামটি খালি বা শুধুমাত্র একটি নামস্থানের নাম ধারণ করে।",
        "title-invalid-utf8": "অনুরোধকৃত পাতার শিরোনামটিতে একটি অবৈধ ইউটিএফ-৮ অনুক্রম রয়েছে।",
        "title-invalid-interwiki": "অনুরোধকৃত পাতার শিরোনামে একটি আন্তঃউইকি সংযোগ উপস্থিত রয়েছে যা শিরোনামে ব্যবহার করা যাবে না।",
        "querypage-no-updates": "এই পাতার জন্য হালনাগাদ নিষ্ক্রিয় করা হয়েছে। এখানে রাখা উপাত্তগুলি এ মুহূর্তে হালনাগাদ করা হবে না।",
        "viewsource": "উৎস দেখুন",
        "viewsource-title": "$1-এর উৎস দেখুন",
-       "actionthrottled": "à¦\95াà¦\9cà§\87র à¦\97তি à¦§à§\80রà¦\95রণ",
+       "actionthrottled": "à¦\95রà§\8dম à¦§à§\80রà¦\95রা",
        "actionthrottledtext": "অপব্যবহার প্রতিরোধক সমাধান হিসেবে এই কাজটি খুব কম সময়ে অনেক বেশিবার সম্পাদন করার উপর সীমা বেঁধে দেওয়া হয়েছে, এবং আপনি সেই সীমা অতিক্রম করেছেন।\nঅনুগ্রহ করে কয়েক মিনিট পরে আবার চেষ্টা করুন।",
        "protectedpagetext": "সম্পাদনা অথবা অন্যান্য কাজে বাধা দিতে এই পাতাটিকে সুরক্ষিত করা হয়েছে।",
        "viewsourcetext": "আপনি এই পাতাটি দেখতে এবং উৎসের প্রতিলিপি করতে পারবেন।",
        "ns-specialprotected": "বিশেষ পাতাসমূহ সম্পাদনা করা যাবে না।",
        "titleprotected": "[[User:$1|$1]] কর্তৃক এই শিরোনামটি সৃষ্টি করা থেকে সুরক্ষিত করা হয়েছে। কারণ: <em>$2</em>।",
        "filereadonlyerror": "\"$1\" ফাইলটিকে পরিবর্তন করা সম্ভব হচ্ছে না কারণ \"$2\" ফাইল সংগ্রহশালাটি শুধুমাত্র-পঠন মোডে আছে।\n\nসিস্টেম প্রশাসক যিনি ফাইলটি অবরুদ্ধ করেছেন তিনি এই ব্যাখ্যা দিয়েছেন: \"$3\"।",
-       "invalidtitle": "ভà§\81ল শিরোনাম",
+       "invalidtitle": "à¦\85বà§\88ধ শিরোনাম",
        "invalidtitle-knownnamespace": "অবৈধ শিরোনাম, যেখানে নামস্থান \"$2\" এবং লেখা হয়েছে \"$3\"",
        "invalidtitle-unknownnamespace": "অবৈধ শিরোনাম, যেখানে ব্যবহৃত হয়েছে অপরিচিত নামস্থান সংখ্যা $1 এবং লেখা হয়েছে \"$2\"",
        "exception-nologin": "প্রবেশ করেন নি",
        "badretype": "আপনার প্রবেশ করানো পাসওয়ার্ডটি মিলছে না।",
        "usernameinprogress": "এই ব্যবহারকারী নামের জন্য একটি অ্যাকাউন্ট তৈরি আগে থেকেই চলছে। দয়া করে অপেক্ষা করুন।",
        "userexists": "এই ব্যবহারকারী নামটি ইতমধ্যে ব্যবহার করা হয়েছে।\nঅনুগ্রহ করে অন্য নাম বেছে নিন।",
+       "createacct-normalization": "কারিগরি সীমাবদ্ধতার কারণে আপনার ব্যবহারকারীর নাম সামঞ্জস্য করে \"$2\" করা হবে।",
        "loginerror": "প্রবেশ করতে সমস্যা হয়েছে",
        "createacct-error": "অ্যাকাউন্ট তৈরিতে ত্রুটি",
        "createaccounterror": "অ্যাকাউন্ট তৈরি হয়নি: $1",
        "accmailtitle": "পাসওয়ার্ড পাঠানো হয়েছে",
        "accmailtext": "[[User talk:$1|$1]] এর জন্য দৈব ভাবে উৎপন্ন শব্দ চাবি $2 এ পাঠানো হয়েছে।\nলগ-ইন করার পর ''[[Special:ChangePassword|পাসওয়ার্ড পরিবর্তন]]'' পাতা থেকে এটি পরিবর্তন করা যাব।",
        "newarticle": "(নতুন)",
-       "newarticletext": "à¦\86পনি à¦\8fমন à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾à¦° à¦¸à¦\82যà§\8bà¦\97 à¦\85নà§\81সরণ à¦\95রà¦\9bà§\87ন, à¦¯à¦¾à¦° à¦\85সà§\8dতিসà§\8dত নেই।\nপাতাটি তৈরি করতে, নিচের বাক্সে তা টাইপ করা শুরু করুন (আরও তথ্য জানতে [$1 সহায়িকা পাতা] দেখুন)।\nআপনি যদি ভুল করে এখানে এসে থাকেন, তাহলে আপনার ব্রাউজারের <strong>পিছন</strong> বোতামে ক্লিক করুন।",
+       "newarticletext": "à¦\86পনি à¦\8fমন à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾à¦° à¦¸à¦\82যà§\8bà¦\97 à¦\85নà§\81সরণ à¦\95রà¦\9bà§\87ন, à¦¯à¦¾à¦° à¦\85সà§\8dতিতà§\8dব নেই।\nপাতাটি তৈরি করতে, নিচের বাক্সে তা টাইপ করা শুরু করুন (আরও তথ্য জানতে [$1 সহায়িকা পাতা] দেখুন)।\nআপনি যদি ভুল করে এখানে এসে থাকেন, তাহলে আপনার ব্রাউজারের <strong>পিছন</strong> বোতামে ক্লিক করুন।",
        "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>, কিন্তু আপনার এই পাতাটি তৈরী করার অনুমতি নেই।",
        "histfirst": "সবচেয়ে পুরনো",
        "histlast": "সবচেয়ে নতুন",
        "historysize": "({{PLURAL:$1|১ বাইট|$1 বাইট}})",
-       "historyempty": "(খালি)",
+       "historyempty": "খালি",
        "history-feed-title": "সংশোধনের ইতিহাস",
        "history-feed-description": "এই উইকিতে এই পাতার সংশোধনের ইতিহাস",
        "history-feed-item-nocomment": "$2-এ $1",
        "right-reupload-own": "নিজের দ্বারা আপলোডকৃত ফাইল যা ইতিমধ্যেই বিদ্যমান, সেটি মুছে পুনরায় নতুন করে আপলোড করা",
        "right-reupload-shared": "স্থানীয়ভাবে শেয়ার্ড মিডিয়া রিপোজিটরীর ফাইল ওভাররাইড",
        "right-upload_by_url": "URL থেকে ফাইল আপলোড",
-       "right-purge": "নিশà§\8dà¦\9aিতà¦\95রণ à¦\9bাড়াà¦\87 সাইটের ক্যাশ শোধন করা",
+       "right-purge": "à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾à¦° à¦\9cনà§\8dয সাইটের ক্যাশ শোধন করা",
        "right-autoconfirmed": "অর্ধ-সুরক্ষিত পাতা সম্পাদনা",
        "right-bot": "সয়ংক্রিয় পদ্ধতি হিসাবে চিহ্নিত করণ",
        "right-nominornewtalk": "বার্তা লেখার মত আলাপ পাতায় কোনো অনুল্লেখ্য সম্পাদনা নেই",
        "deleting-backlinks-warning": "<strong>সতর্কীকরণ:</strong> আপনি যেটি মুছে ফেলতে যাচ্ছেন তা [[Special:WhatLinksHere/{{FULLPAGENAME}}|অন্যান্য পাতাসমূহে]] সংযুক্ত অথবা অন্তর্ভুক্ত রয়েছে।",
        "deleting-subpages-warning": "<strong>সতর্কীকরণ:</strong> আপনি যে পাতাটি মুছে ফেলতে যাচ্ছেন তাঁর [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|একটি উপপাতা|$1টি উপপাতা|51=৫০টির বেশী}}]] রয়েছে।",
        "rollback": "সম্পাদনা ফিরিয়ে নিন",
+       "rollback-confirmation-confirm": "দয়া করে নিশ্চিত করুন:",
+       "rollback-confirmation-yes": "পুনর্বহাল করুন",
+       "rollback-confirmation-no": "বাতিল করুন",
        "rollbacklink": "পুনর্বহাল",
        "rollbacklinkcount": "$1টি {{PLURAL:$1|সম্পাদনা}} রোলব্যাক করুন",
        "rollbacklinkcount-morethan": "$1টির বেশি {{PLURAL:$1|সম্পাদনা}} রোলব্যাক করুন",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলাপ]])-এর সম্পাদিত সংস্করণ হতে [[User:$1|$1]]-এর সম্পাদিত সর্বশেষ সংস্করণে ফেরত যাওয়া হয়েছে",
        "revertpage-nouser": "একজন গোপন ব্যবহারকারী কর্তৃক সম্পাদিত সম্পাদনাটি বাতিলপূর্বক {{GENDER:$1|[[User:$1|$1]]}}-এর সর্বশেষ সম্পাদনায় ফেরত যাওয়া হয়েছে",
        "rollback-success": "{{GENDER:$3|$1}}-এর সম্পাদনাগুলি পূর্বাবস্থায় ফিরিয়ে নেওয়া হয়েছে; {{GENDER:$4|$2}}-এর করা শেষ সংস্করণে পাতাটি ফেরত নেওয়া হয়েছে।",
-       "rollback-success-notify": "$1-এর সম্পাদনাগুলি বাতিল করা হয়েছে; \n$2-এর করা শেষ সংস্করণে ফেরত নেওয়া হয়েছে। [$3 পরিবর্তন দেখুন]",
        "sessionfailure-title": "সেশন পরিত্যক্ত",
        "sessionfailure": "আপনার প্রবেশ সেশনে একটি সমস্যা হয়েছে বলে মনে হচ্ছে;\nসেশন হাইজ্যাক প্রতিরোধের উপায় হিসেবে এই কাজটি বাতিল করা হয়েছে।\nদয়া করে ফরমটি পুনরায় জমা দিন।",
        "changecontentmodel": "একটি পাতার বিষয়বস্তুর রূপ পরিবর্তন",
        "mycontris": "অবদান",
        "anoncontribs": "অবদান",
        "contribsub2": "{{GENDER:$3|$1}} ($2)-এর জন্য",
+       "contributions-subtitle": "{{GENDER:$3|$1}}-এর জন্য",
        "contributions-userdoesnotexist": "ব্যবহারকারী অ্যাকাউন্ট \"$1\" অনিবন্ধিত।",
        "nocontribs": "এই শর্তগুলির সাথে মিলে যায়, এমন কোন পরিবর্তন খুঁজে পাওয়া যায়নি।",
        "uctop": "বর্তমান",
        "movepagetext": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\nযেসমস্ত পুনর্নির্দেশনা পুরনো শিরোনামটির দিকে নির্দেশ করছিল, সেগুলি স্বয়ংক্রিয়ভাবে হালনাগাদ করতে পারবেন।\nযদি তা না চান, তবে [[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে <strong>না</strong>, যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে।\nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n<strong>টীকা:</strong>\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে; অগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
        "movepagetext-noredirectfixer": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\n[[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে <strong>না</strong>, যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে। \nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n<strong>টীকা:</strong>\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে;\nঅগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
        "movepagetalktext": "আপনি যদি এই বাক্সে টিক দেন, তাহলে পাতাটির সাথে সংশ্লিষ্ট আলোচনা পাতাটিও স্বয়ংক্রিয়ভাবে নতুন শিরোনামে সরানো হবে যদি না নতুন শিরোনামটির অধীনে ইতিমধ্যেই একটি বিদ্যমান থাকে।\n\nএসব ক্ষেত্রে আপনি চাইলে নিজের হাতে পাতাটিকে সরাতে বা একত্রীকরণ করতে পারেন।",
-       "moveuserpage-warning": "'''সতর্কতা:''' আপনি একটি ব্যবহারকারী পাতা স্থানান্তর করছেন। অনুগ্রহ করে লক্ষ্য করুন যে এর মাধ্যমে কেবলমাত্র পাতাটি স্থানান্তর হবে, কিন্তু পাতার নাম পরিবর্তন হবে ''না''।",
+       "moveuserpage-warning": "<strong>সতর্কতা:</strong> আপনি একটি ব্যবহারকারী পাতা স্থানান্তর করছেন। অনুগ্রহ করে লক্ষ্য করুন যে এর মাধ্যমে কেবলমাত্র পাতাটি স্থানান্তর হবে, কিন্তু ব্যবহারকারীর নাম পরিবর্তন হবে <em>না</em>।",
        "movecategorypage-warning": "<strong>সতর্কীকরণ:</strong> আপনি একটি বিষয়শ্রেণীর পাতা স্থানান্তর করতে চলেছেন। দয়া করে মনে রাখবেন যে এতে শুধুমাত্র পাতাটি স্থানান্তরিত হবে এবং পুরাতন বিষয়শ্রেণীতে থাকা কোন পাতা নতুনটিতে পুনঃশ্রেণীকরণ করা হবে <em>না</em>।",
        "movenologintext": "কোন পাতা সরিয়ে ফেলতে চাইলে আপনাকে অবশ্যই একজন নিবন্ধিত ব্যবহারকারী হতে হবে ও অ্যাকাউন্টে [[Special:UserLogin|প্রবেশ]] করতে হবে।",
        "movenotallowed": "আপনার {{SITENAME}}-তে পাতা স্থানান্তরের অনুমতি নেই।",
        "specialpages-group-developer": "ডেভলপারের সরঞ্জাম",
        "blankpage": "খালি পাতা",
        "intentionallyblankpage": "এই পাতাটি ইচ্ছা করে খালি রাখা হয়েছে",
+       "disabledspecialpage-disabled": "এই পৃষ্ঠাটি একজন সিস্টেম প্রশাসক দ্বারা নিষ্ক্রিয় করা হয়েছে।",
        "external_image_whitelist": "  #এই লাইন ঠিক যেমন আছে<প্রাক> তেমন রাখুন<pre>\n #রেগুলার এক্সপ্রেশনের টুকরা নীচে (শুধুমাত্র অংশ / / মধ্যে যে যায়) বসান\n#এইগুলি এক্সটার্নাল (hotlinked) ইমেজের URL-এর সাথে মেলানো হবে\n#যেগুলি মিলবে, সেগুলি চিত্র হিসাবে প্রদর্শিত হবে, অন্যথায় শুধুমাত্র ইমেজ লিঙ্ক প্রদর্শিত হবে\n#যে লাইনের প্রারম্ভে # আছে সেই লাইনগুলি মন্তব্যসমূহ হিসাবে ব্যবহার করা হয়\n#এটি কেস-অসংবেদী\n\n#এই রেখার উপরের regex টুকরা বসান. এই লাইন ঠিক যেমন আছে তেমন রাখুন</pre>",
        "tags": "বৈধ পরিবর্তন ট্যাগ",
        "tag-filter": "[[Special:Tags|ট্যাগ]] ছাঁকনি:",
        "logentry-rights-autopromote": "$1 স্বয়ংক্রিয়ভাবে $4 থেকে $5-এ {{GENDER:$2|উন্নীত}} হয়েছেন",
        "logentry-upload-upload": "$1 $3 {{GENDER:$2|আপলোড করেছেন}}",
        "logentry-upload-overwrite": "$1 $3-এর একটি নতুন সংস্করণ {{GENDER:$2|আপলোড করেছেন}}",
-       "logentry-upload-revert": "$1 $3 {{GENDER:$2|আপলোড করেছেন}}",
+       "logentry-upload-revert": "$1 $3 কে একটি পুরাতন সংস্করণে {{GENDER:$2|প্রত্যাবর্তন করেছেন}}",
        "log-name-managetags": "ট্যাগ ব্যবস্থাপনা লগ",
        "log-description-managetags": "এই পাতাতে [[Special:Tags|ট্যাগ]] ব্যবস্থাপনা কার্যাবলির একটি তালিকা আছে। এই লগে কেবলমাত্র সেইসব কর্মের তালিকা আছে, যেগুলি একজন প্রশাসক নিজ হাতে সম্পাদন করেছেন; উইকি সফটওয়্যার দিয়ে ট্যাগ সৃষ্টি বা অপসারণ করা সম্ভব, যার কোন ভুক্তি এই লগে সংরক্ষিত হবে না।",
        "logentry-managetags-create": "$1 \"$4\" ট্যাগটি {{GENDER:$2|তৈরি করেছেন}}",
        "log-action-filter-suppress-reblock": "পুনরায় বাধাদানের মাধ্যমে ব্যবহারকারী দমন",
        "log-action-filter-upload-upload": "নতুন আপলোড",
        "log-action-filter-upload-overwrite": "পুনঃআপলোড",
+       "log-action-filter-upload-revert": "প্রত্যাবর্তন",
        "authmanager-authn-not-in-progress": "শনাক্তকরণ প্রক্রিয়াটি আর অগ্রসর হচ্ছে না কিংবা সেশনের উপাত্ত হারিয়ে গেছে। অনুগ্রহ করে আবার শুরু থেকে শুরু করুন।",
        "authmanager-authn-no-primary": "সরবরাহকৃত পরিচয়পত্রের অনুমোদন যাচাই করা যায়নি।",
        "authmanager-authn-no-local-user": "সরবরাহকৃত পরিচয়জ্ঞাপক তথ্যগুলি এই উইকির কোনও ব্যবহারকারীর সাথে সংশ্লিষ্ট নয়।",
        "authmanager-create-no-primary": "সরবরাহকৃত পরিচয়জ্ঞাপক উপাত্তগুলি অ্যাকাউন্ট সৃষ্টির জন্য ব্যবহার করা সম্ভব হ‍য়নি।",
        "authmanager-link-no-primary": "সরবরাহকৃত পরিচয়জ্ঞাপক উপাত্তগুলি অ্যাকাউন্ট সংযুক্তকরণের জন্য ব্যবহার করা সম্ভব হয়নি।",
        "authmanager-link-not-in-progress": "অ্যাকাউন্ট সংযুক্তকরণ প্রক্রিয়াটি আর অগ্রসর হচ্ছে না কিংবা সেশনের উপাত্ত হারিয়ে গেছে। অনুগ্রহ আবার শুরু থেকে শুরু করুন।",
-       "authmanager-authplugin-setpass-failed-title": "পাসওয়ার্ড পরিবর্তন ব্যর্থ হয়েছে",
-       "authmanager-authplugin-setpass-failed-message": "প্রমাণীকরণ প্লাগইন পাসওয়ার্ড পরিবর্তন করতে অস্বীকৃতি জানিয়েছে।",
-       "authmanager-authplugin-create-fail": "প্রমাণীকরণ প্লাগইন অ্যাকাউন্ট তৈরি করতে অস্বীকৃতি জানিয়েছে।",
-       "authmanager-authplugin-setpass-denied": "প্রমাণীকরণ প্লাগইন পাসওয়ার্ড পরিবর্তন করার অনুমতি দেয় না।",
-       "authmanager-authplugin-setpass-bad-domain": "অবৈধ ডোমেইন।",
        "authmanager-autocreate-noperm": "স্বয়ংক্রিয় অ্যাকাউন্ট সৃষ্টি মঞ্জুরিপ্রাপ্ত নয়।",
        "authmanager-autocreate-exception": "স্বয়ংক্রিয় অ্যাকাউন্ট সৃষ্টিকরণ পূর্ববর্তী ত্রুটির কারণে সাময়িকভাবে অক্ষম করা হয়েছে।",
        "authmanager-userdoesnotexist": "ব্যবহারকারী অ্যাকাউন্ট \"$1\" অনিবন্ধিত।",
index 4b3790d..a031eef 100644 (file)
@@ -95,7 +95,7 @@
        "march-gen": "مارس",
        "april-gen": "آڤریل",
        "may-gen": "مئی",
-       "june-gen": "جۊٱن",
+       "june-gen": "جۊئٱن",
        "july-gen": "جۊئیٱ",
        "august-gen": "آگوست",
        "september-gen": "سپتامبر",
        "category_header": "بٱلگاْیٱل میٛن دٱسداْ \"$1\"",
        "subcategories": "زیر دٱسداْیٱل",
        "category-media-header": "ڤارسگر میٛن دٱسداْ \"$1\"",
-       "category-empty": "<em> ای دٱسدٱ هیژ بٱلگاْ یا ڤارسگٱری مئن خوس ناراْ.</em>",
+       "category-empty": "<em> ای دٱسدٱ هیژ بٱلگاْ یا ڤارسگٱری میٛن خوس ناراْ.</em>",
        "hidden-categories": "{{PLURAL:$1|دٱسداْ قام ڤابیڌٱ|دٱسداْیٱل قام ڤابیڌٱ}}",
        "hidden-category-category": "دٱسداْیٱل قام ڤابیڌٱ",
        "category-subcat-count": "{{PLURAL:$2|ای دٱسداْ فٱقٱت ز ڤٱرگرهڌاْ زیردٱسداْیٱل نیاییاْ.|ای دٱسداْ ز ڤٱرگرهڌاْ {{PLURAL:$1|زیردٱسداْ|$1 زیردٱسداْیٱل}}, بیشتر ز کول $2 .}}",
        "faq": "اْف اٛی کیۊ",
        "actions": "کونشتکارۊن",
        "namespaces": "نوم ڤارگٱیٱل",
-       "variants": "Ø¢Ù\84شدگٱرÛ\8aÙ\86",
+       "variants": "Ø¢Ù\84شدکارٱÙ\84",
        "navigation-heading": "نوم جاگٱ ناڤگٱردی",
        "errorpagetitle": "خٱتا",
        "returnto": "ڤورگٱشدن ب $1.",
        "tagline": "ز {{SITENAME}}",
-       "help": "رٱنمۊنی",
+       "help": "رٱنمونی",
        "help-mediawiki": "هومیاری سی مدیاڤیکی",
        "search": "پاٛی جۊری",
        "search-ignored-headings": "#<!-- ای بٱلٛگاْ ناْ هٱمی بٱرتی کاْ هؽڌا رها کونین --> <pre>\n# سٱرتال ٱلؽ  که ڤا موڌی نیڌاْ اْڤۊهن\n# تٱسیر آلشڌ راتؽ ایاهاْ ڤارۊ کاْ بٱلٛگاْ هاڤی او سٱرتال، نماواْ ڤۊهاْ.\n# اؽسا تٱرین ڤا ٱنجوم یٱ آلشڌکاری پیک بٱلٛگاْ ناْ بؽرٱ ڤاْ دو کرات نماواْ ڤیڌن کونین\n# رڤشڌس چونوݩ هؽڌآ:\n#  *هٱر چاْ زاْ یٱ هؽلنیڌاْ «#» تا تٱهاْ هؽل ڤاهین، یٱ اشکافنیڌن هؽڌا.\n#  *هٱر هؽل بؽ تلاهاْ، دٱیخٱن اوڌڤانی  هؽڌا کاْ نیڌاْ گریڌاْ اْڤۊهاْ (ڤا رعایٱت گاپی ۉ ساوائی هٱرفٱل).\nکونڳگٱیٱل(مٱنابع)\nمؽنڌاری ڤا دٱر\nهٱم چونوݩ ڤنٱرین\n#</pre> <!-- leave this line exactly as it is -->",
        "history_short": "ڤیرگار",
        "history_small": "ڤیرگار",
        "updatedmarker": "ڤانها(ڤ رۊز)آڤیڌاْ زاْ ٱخیرین کرٱتی کاْ سٱرؤر داماْ",
-       "printableversion": "نوسقاْ پاْلا ڤابیڌنی",
+       "printableversion": "نوسقاْ پیٛلا ڤابیڌنی",
        "permalink": "هومپاٛیڤٱند دایومی",
        "print": "چاپ گرهڌن",
        "view": "ديڌن",
        "view-foreign": "میٛن $1 ناْ باْنیٱر",
-       "edit": "آلشدکاری",
+       "edit": "آلشدکاری کردن",
        "edit-local": "آلشڌکاری اشکافنیڌیٱل بۊمی",
        "create": "راس كردن",
        "create-local": "یٱ تۉزی ڤولات نشینی اْزاف کونین",
        "otherlanguages": "میٛن زڤونا دیٱ",
        "redirectedfrom": "(ڤاگٱردۊنی سی $1)",
        "redirectpagesub": "بٱلگاْ ڤاگٱردۊنی",
-       "redirectto": "ڤاگٱردۊنی سی:",
-       "lastmodifiedat": "ای بٱلگٱ تازاٛییا ماٛن $1 و میٛن $2 آلشدکاری ڤابیڌاْ.",
+       "redirectto": "ڤاگٱردونی سی:",
+       "lastmodifiedat": "ای بٱلگاْ تازاٛییا میٛن $1 و میٛن $2 آلشدکاری ڤابیڌاْ.",
        "viewcount": "ای بٱلگاْ میٛن دٱسرساْ {{PLURAL:$1|یٱ کاْرٱت|$1 چٱن کاْرٱت}}.",
        "protectedpage": "بٱلگاْ پٱر و پیم ڤابیڌاْ",
        "jumpto": "پراٛستن سی:",
        "viewsourceold": "دیڌن سرچشمٱ",
        "editlink": "آلشدکاری کردن",
        "viewsourcelink": "ساٛیل سرچشماْ کونین",
-       "editsectionhint": "آلشدکاری بٱرجا: $1",
+       "editsectionhint": "Ø¢Ù\84شدکارÛ\8c Ø¨Ù±Ø¦Ø±Ø¬Ø§: $1",
        "toc": "مینۊناْیٱل",
        "showtoc": "دیاری کردن",
        "hidetoc": "قام کردن",
        "nstab-project": "بٱلگاْ پوروجاْ",
        "nstab-image": "جانیا",
        "nstab-mediawiki": "پیغوم",
-       "nstab-template": "چۊاْ",
+       "nstab-template": "Ú\86Û\8aئاÙ\92",
        "nstab-help": "بٱلگاْ هومیاری",
        "nstab-category": "دٱسدٱ",
        "mainpage-nstab": "سرتال",
        "delete-hook-aborted": "پژار ڤا قولاڤ لٱق آڤیڌ\nاشکافنیڌنی سی هؽ داڌ نڤیڌ",
        "no-null-revision": "سی بٱلگاْ $1 ڤانیٱری خومسا ناْ راس کونین",
        "badtitle": "داسوݩ گٱن",
-       "badtitletext": "داسوݩ خاسدنی نادیار، هالی، یا داسۊنی کاْ میٛنجقا زڤونی یا میٛنجقا ڤیکی ڤا هومپاٛیڤٱند دوروسد ناراْ و یا گاشا چٱنتا کاراکتر داراْ کاْ ڤا میٛن داسۊن نۉ باْیوفتاْ ڤا کار.",
+       "badtitletext": "داسوݩ خاسدنی نادیار، هالی، یا داسۊنی کاْ میٛنجقا زڤونی یا میٛنجقا ڤیکی ڤا هومپاٛیڤٱند دوروسد ناراْ و یا گاشا چٱنتا کاراکتر داراْ کاْ ڤا میٛن داسوݩ نۉ باْیوفتاْ ڤا کار.",
        "title-invalid-empty": "اوڌڤان بٱلٛگاْ دٱرخاس آڤیڌاْ پٱتی هؽڌآ یا تاٛنا اوڌڤان مؽن نوم گوڌ آڤیڌاْ هؽڌآ",
        "title-invalid-utf8": "اوڌڤان بٱلٛگاْ دٱرخاس آڤیڌاْ هؽل ڤیڌاْ نادوروس یونیکوڌ هؽڌآ",
        "title-invalid-interwiki": "بٱلٛگاْ دٱرخاس آڤیڌاْ دارای پاٛڤٱن مؽن ڤیکی هؽڌآ کاْ نؽڤۊهاْ مؽن اوڌڤانٱل نهاڌاْ ڤۊهاْ",
        "actionthrottled": "نها کار اؽسا گریداٛ آڤیڌ",
        "actionthrottledtext": "ڤ سی نهاگری زاْ ؤولٱ ڤیڌن چۊلکاری،اْجازاٛ نارین کاْ چونوݩ کارؽ ناْ ڤؽشڌر زاْ چٱن کرٱت ڤ یٱ رات کول ٱنجوم ڤڌین\nلوتفٱن دیناتٱر زاْ چٱن دٱیخاْ سٱرزنۊ پلرڌ کونین",
        "protectedpagetext": "ای بٱلٛگاْ سی نهاگری راْ آلشڌکاری یا جومجیل دهرؽ پلڌاری آڤیڌاْ",
-       "viewsourcetext": "ایسا تاْرین سرچشماْ ای بلگاْ ناْ هٱم بنیٱرین و هم ڤوردارینس:",
+       "viewsourcetext": "ایسا تیٛرین سرچشماْ ای بلگاْ ناْ هٱم بنیٱرین و هم ڤوردارینس:",
        "viewyourtext": "ایسا تاْرین یٱ کوپی ز سرچشمٱ<strong>آلشدکاریٱل خوتوݩ</strong> ڤوردارین سی ای بٱلگاْ",
        "protectedinterface": "ای بٱلگاْ سی نٱرم ٱفزاری کاْ سی ڤیکی نڤیسی هڌ آماڌاْ ڤابیڌاْ،و ز موزاهمٱت کاری پٱر و پیم ڤابیڌاْ سی اْزاف کردن یا آلشدکاری کردن میٛن هٱماْ ڤیکیٱل لوتف کونین [https://translatewiki.net/ translatewiki.net] ناْ ڤٱنین ڤا کار، پوروجاْ ڤولات نشین سازی ڤیکیمدیا.",
        "editinginterface": "<strong>هوشڌار:</strong> بٱلٛگاْ کاْآلشڌکاری اْکونین مٱتنؽ ڌاراْ کاْ مؽن ڤاست  مؽنتور ای نٱرمٱفزار ڤ کار رٱئڌاْ\nآلشڌ ای بٱلٛگاْ ڤانی آلشڌ بارت ڤاست مؽنتور ای نٱرم‌ٱفزار سی مؽنتورٱل داٛری اْڤۊهاْ",
        "mycustomcssprotected": "ایسا ساْلا آلشدکاری css ای بٱلگاْ ناْ نارین",
        "mycustomjsonprotected": "ایسا ساْلا آلشدکاری JSON ای بٱلگاْ ناْ نارین",
        "mycustomjsprotected": "ایسا ساْلا آلشدکاری JavaScript ای بٱلگاْ ناْ نارین",
-       "myprivateinfoprotected": "ایسا سلا آلشدکاری دۊنسمٱندیٱل خوسۊسی خوتۊناْ نارین.",
+       "myprivateinfoprotected": "ایسا سلا آلشدکاری دۊنسمٱندیٱل خوسۊسی خوتوناْ نارین.",
        "mypreferencesprotected": "ایسا سلا آلشدکاری چیا دیٱر خوتۊناْ نارین.",
        "ns-specialprotected": "نیبۊ بٱلگاْیٱل ڤیجاْ ناْ آلشد کرد",
        "titleprotected": "ای داسۊن ڤا دٱسدا کاریار [[User:$1|$1]] نیاگری ڤابیڌاْ.\nدلیلس یوناْ <em>$2</em>.",
        "welcomecreation-msg": "هساوتوݩ راسد ڤابی.\nب ڤیرتوݩ بۊ کاْ {{نوم دیارگٱ}} [[Special:Preferences|preferences]]  خوتوناْ آلشد کونین.",
        "yourname": "نوم کاریاری:",
        "userlogin-yourname": "نوم کاریاری",
-       "userlogin-yourname-ph": "نوم کاریاریتۊناْ بزنین",
-       "createacct-another-username-ph": "نوم کاریاریتۊناْ بزنین",
+       "userlogin-yourname-ph": "نوم کاریاریتوناْ بزنین",
+       "createacct-another-username-ph": "نوم کاریاریتوناْ بزنین",
        "yourpassword": "رازیناْ گوڌٱشتن",
        "userlogin-yourpassword": "رازیناْ گوڌٱشتن",
        "userlogin-yourpassword-ph": "رازیناْ گوڌاْشتن ناْ بزٱ",
        "yourpasswordagain": "رازیناْ گوڌٱشدن خوتۊناْ ز نۉ بزنین:",
        "createacct-yourpasswordagain": "پوشت راسدکاری رازینٱ گوڌاْشتن",
        "createacct-yourpasswordagain-ph": "ز نۉ رازیناْ گوڌاْشتن نٱ بزٱ",
-       "userlogin-remembermypassword": "مۊناْ میٛن سامۊناْ ڤاڌار",
+       "userlogin-remembermypassword": "موناْ میٛن ساموناْ ڤاڌار",
        "userlogin-signwithsecure": "ز رٱڤشت ٱمن ڤٱسل ڤابۊین",
        "cannotlogin-title": "نٱترین بیایین ڤامیٛن",
        "cannotlogin-text": "نٱترین بیائین ڤامیٛن",
        "cannotcreateaccount-title": "نٱترین هساو کاریاری راسد کونین",
        "cannotcreateaccount-text": "ایسا نٱترین موستٱقیم میٛن ای ڤیکی هساو کاریاری راسد کونین.",
        "yourdomainname": "پۊشگر ايسا:",
-       "password-change-forbidden": "ایسا نٱترین رازیناْ گوڌٱشتن خوتۊناْ میٛن ای ڤیکی آلشد کونین.",
+       "password-change-forbidden": "ایسا نٱترین رازیناْ گوڌٱشتن خوتوناْ میٛن ای ڤیکی آلشد کونین.",
        "externaldberror": "اٛشتڤایی میٛن پاٛیڤٱند ڤا رسیناْگا اْتفاق ڤٱستاْ یا ایسا ساْلا یوناْ کاْ یٱ هساو کاریاری خارجی ز خوتۊناْ ب هاْنگوم سازی کونین نارین.",
        "login": "ڤامیٛن ٱڤوڌن",
        "login-security": "نشوݩ دیارکون خوتۊناْ آلشد کونین",
        "nav-login-createaccount": "ٱڤوڌن ڤامیٛن/راس کردن هساو کاریاری",
-       "logout": "ز سامۊناْ درٱڤوڌن",
-       "userlogout": "ز سامۊناْ درٱڤوڌن",
+       "logout": "ز ساموناْ درٱڤوڌن",
+       "userlogout": "ز ساموناْ درٱڤوڌن",
        "notloggedin": "هٱنی نٱڤۊڌیناْ ڤامیٛن",
        "userlogin-noaccount": "یٱ هساو کاریاری دارین؟",
        "userlogin-joinproject": "ٱندوم دیارگٱ {{SITENAME}} ڤابۊین",
        "createaccount": "راسد کردن هساو کاریاری",
-       "userlogin-resetpassword-link": "رازیناْ گوڤٱرتنتۊ ز ڤیرتۊن رٱهڌاْ؟",
+       "userlogin-resetpassword-link": "رازیناْ گوڤٱرتنتۊ ز ڤیرتوݩ رٱهڌاْ؟",
        "userlogin-helplink2": "هومیاری کردن سی ڤامیٛن ٱڤوڌن",
        "userlogin-loggedin": "ایسا ایساْ چی {{GENDER:$1|$1}} ٱڤۊڌین ڤامیٛن. فورم داْڤۊنی ناْ ڤٱنین ڤا کار و چی یٱ کاریار دیٱ بیائین ڤا میٛن",
        "userlogin-reauth": "ایسا ڤا ز نۉ بیائین ڤامیٛن سی یو کاْ دیار ڤابۊ ایسا {{GENDER:$1|$1}} هڌین.",
        "userlogin-createanother": "یٱ هساو کاریاری دیٱ راسد کونین",
        "createacct-emailrequired": "تیرنشوݩ ٱنجومانامٱ",
        "createacct-emailoptional": "تیرنشوݩ ٱنجومانامٱ",
-       "createacct-email-ph": "تیرنشوݩ ٱنجوماناماْ تۊناْ بزنین.",
+       "createacct-email-ph": "تیرنشوݩ ٱنجوماناماْ توناْ بزنین.",
        "createacct-another-email-ph": "تیرنشوݩ ٱنجوماناماْ تۊناْ بزنین.",
        "createaccountmail": "یٱ رازیناْ گوڌٱشتن موڤٱقٱتی ناْ ڤاْنین ڤا کار و سی یٱ تیرنشوݩ ٱنجوماناماْ تیار ڤابیڌاْ باْسیس کونین.",
        "createaccountmail-help": "ایسا ترین یٱ هساو کاریاری سی یکی دیٱ راسد کونین بی یو کاْ رازیناْ گوڌٱشتنساْ ڤٱنین ڤا ڤیر.",
        "loginlanguagelabel": "زڤون:$1",
        "suspicious-userlogout": "خاستتوݩ سی رٱهڌن ب دٱر ز ساموناْ رٱڌ ڤابی چونو کاْ دیاراْ چونو خاستی ڤا یٱ یا یٱ پوروکسی میٛنجقاگر بیٛسی ڤابیڌاْ بۊ",
        "createacct-another-realname-tip": "نو راستٱکی دل ب خائیاْ.\nٱر بزنینس گات ڤورگٱشتن ب آریٛنگٱلتوݩ و ڤورگٱشت هونو ب ایسا نوم راستٱکی توݩ ناْ ڤٱناْ ڤا کار.",
-       "pt-login": "ڤامین ٱڤوڌن",
+       "pt-login": "ڤاÙ\85Û\8cÙ\9bÙ\86 Ù±Ú¤Ù\88Ú\8cÙ\86",
        "pt-login-button": "ڤامیٛن ٱڤوڌن",
        "pt-login-continue-button": "پوشت سریٱک بیائین ڤامیٛن",
        "pt-createaccount": "راسد کردن هساو کاریاری",
        "publishchanges-start": "تیژنیڌن آلشڌکاریٱل",
        "preview": "پيش ساٛیل",
        "showpreview": "نشوݩ دائن پیش ساٛیل",
-       "showdiff": "نشوݩ دائن آلشدا",
+       "showdiff": "نشوݩ دائن آلشدکاریٱل",
        "anoneditwarning": "<strong>ب ڤیرتوݩ بۊ:</strong> ایسا هاْنی نٱڤۊڌین ڤامین. تیرنشوݩ آی پی ایسا سی هر گاتی کاْ آلشدکاری کونین سی کول خٱلک دیاراْ. ٱر <strong>[$1 رۉین ڤامین]</strong> یا <strong>[$2 یٱ هساو کاریاری راسد کونین]</strong>، آلشدکاریٱل ایسا ڤا نوم کاریاری خوتوݩ دیاری اْبۊ و یو سی ایسا بیتراْ.",
        "missingcommenttext": "لوتفٱن یٱ کامنت بیٛنین.",
        "missingcommentheader": "<strong>ب ڤیر ڤٱن:</strong> ایسا هیٛنی یٱ داسوݩ سی ای کامنت کۊ نکردیناْ.\nٱر ایسا یٱ کرٱت دٱ ری \"$1\" بپۊرنین، ڤیرایشت کاریوݩ هالی کۊ اْبۊ.",
        "loginreqpagetext": "$1 لوتف کونین بٱلگاْیٱل دیٱر ناْ ساٛیل کونین.",
        "accmailtitle": "رازیناْ گوڌٱشتن باْسی ڤابیڌاْ",
        "newarticle": "(تازاْ)",
-       "newarticletext": "ایسا ز دین یٱ هومپاٛیڤٱندی هڌین کاْ نیڌس. سی رٱڤٱندیاری بٱلگاْ شورۊ کونین میٛن ای جٱڤاْ داٛڤۊنی بنڤیسین(سی دۊنسدن بیشدر سئیل [$1]کونین).\nیر ایسا سی اْشتڤاکارش ايچونین، دوگماْ رٱهڌن ڤاپوشد نٱ بپۊرنین.",
+       "newarticletext": "ایسا ز دین یٱ هومپاٛیڤٱندی هڌین کاْ نیڌس. سی رٱڤٱندیاری بٱلگاْ شورۊ کونین میٛن ای جٱڤاْ دیٛڤونی بنڤیسین(سی دۊنسدن بیشدر ساٛیل [$1]کونین).\nیر ایسا سی اْشتڤاکارش ايچونین، دوگماْ رٱهڌن ڤاپوشد نٱ بپۊرنین.",
        "noarticletext": " ایساْ ای بٱلگاْ نڤشداْیی ناراْ، ایسا تاْرین [[Special:Search/{{PAGENAME}}داسۊن ای بٱلگاْ نٱ میٛن بٱلگاْیٱل دیٱری پاٛی جۊری کونین]] یا [{{fullurl:{{FULLPAGENAME}}|action=edit}} ای بٱلگاْ نٱ آلشدکاری کونين].",
        "noarticletext-nopermission": " ایساْ ای بٱلگاْ نڤشداْیی ناراْ، ایسا تاْرین [[Special:Search/{{PAGENAME}}داسۊن ای بٱلگاْ نٱ میٛن بٱلگاْیٱل دیٱری پاٛی جۊری کونین]] یا [{{fullurl:{{FULLPAGENAME}}|action=edit}} ای بٱلگاْ نٱ آلشد کونين].",
        "userpage-userdoesnotexist-view": "هساو کاریاری \"$1\" سٱبت نٱڤابیڌاْ.",
        "copyrightwarning2": "ب ڤیرتوݩ بۊ کاْ تٱموم هومیاریٱل ایسا {{SITENAME}} زیرناْخیز «$2» دٱرتیچ اْبوݩ).\n\n(سی دیڌن  جوزئیات بیشتر ز $1 رۉین\n\nٱر نیخاین نڤشداْیٱلوݩ گٱن آلشدکاری نٱڤبۊن و دل ب خایی باْسی ڤابۊن، ایچو باْسی سوݩ نٱکونین.<br />\nهٱنی ٱم ایسا دارین بیما قۉل اْڌین کاْ خوتوݩ یوناْ نڤشدیناْ یا هوناْ ز یٱ سرچشماْ آزاڌ ڤا مالکیت خٱلکمٱند یا چی هو ڤورداشتین ساْ. '''چیا ناْ بی موجٱڤز و بی سلا کوپی رایت باْسی نٱکونین!''''",
        "templatesused": "{{PLURAL:$1|چۊاْ|چۊاْیٱل}} ڤا کار ڤٱسداْ میٛن ای بٱلگاْ:",
        "templatesusedpreview": "قالڤٱل یا اولگۊیٱل ڤاْ کار رٱئڌاْ مؽن ای نهانماو",
+       "templatesusedsection": "{{PLURAL:$1|چۊاْ|چۊاْیٱل}} ڤا کار ڤٱسداْ میٛن ای بٱئرجا:",
        "template-protected": "(پٱر و پیم ڤابیڌٱ)",
        "template-semiprotected": "(نسم نیماْ پٱر و پیم ڤابیڌاْ)",
        "hiddencategories": "ای بٱلگاْ یکی ز ٱندوما {{PLURAL:$1|1 hidden category|$1 hidden categories}} اْ:",
        "nocreatetext": "{{SITENAME}}قابلیت درست کردن صفحات تازه را محدود کرده‌. ترین برگردین و صفحه‌ موجود را اصلاح کنین یا اینکه  [[Special:UserLogin|به سیستم داخل بوین یا حساب کاربری درست کنین]].",
+       "nocreate-loggedin": "ایسا سیٛلا راسد کرد ای بٱلگاْیٱل ناْ نارین",
        "sectioneditnotsupported-title": "ایسا سیٛلا آلشدکاری بٱئرجا ناْ نارین.",
+       "sectioneditnotsupported-text": "ایسا نٱترین آلشدکاری بٱئرجایی میٛن ای بٱلگاْ ٱنجوم بڌین",
        "permissionserrors": "پٱلاْ:اْجازاْ ڤگرا",
        "permissionserrorstext-withaction": "ایسا سی نیاگری $2 ساٛلا\nنارین {{PLURAL:$1|دلیل|دلیلٱل}}:",
        "recreate-moveddeleted-warn": "'''هوشڌار: ایسا هنؽ سٱرزاْنۊ بٱلٛگی ناْ ؤرکل اْکونین کاْ نهاتٱرپاکسا آڤیڌاْ '''مؽن فرگ داشڌ ڤۊهین کاْ آلشڌ ای بٱلٛگاْ کارؽ دوروساْ هؽڌا آ نٱ. نمایاٛ پاکسا  مؽنڌار ڤا ای بٱلٛگاْ سی راهٱتی کار ڤا دینا آؤوڌاْ",
        "history-edit-tags": "آلشدکاری سردیسٱل ڤانیاریٱل گولاْڤورچین ڤابیڌاْ.",
        "rev-deleted-comment": "(خولاساْ آلشدکاری پاکسا ڤابی)",
        "rev-deleted-user": "(نوم کاریاری پاکسا ڤابیڌاْ)",
+       "rev-deleted-event": "(جوزئیات پهرستنوماْ پاکسا ڤابیڌاْ)",
+       "rev-deleted-user-contribs": "[نوم کاریاری یا تیرنشوݩ آی پی پاکسا ڤابیڌاْ - چیا قام ڤابیڌاْ ز ڤٱر هومیارٱل ناْ آلشدکار کونین]",
        "rev-delundel": "آلشد هال و بال ديڌن",
        "rev-showdeleted": "دیاری کردن",
        "revisiondelete": "پاکسا کردن/زنداْ کردن ڤانیٱریٱل",
        "revdelete-nooldid-title": "ڤانیٱری نادیار",
        "revdelete-no-file": "جانیا تیار ڤابیڌاْ ڤوجۊڌ ناراْ.",
        "revdelete-show-file-submit": "هٱراْ",
+       "revdelete-selected-text": "{{PLURAL:$1|ڤانیٱری گولاْڤورچین ڤابیڌاْ|ڤانیٱریٱل گولاْڤورچین ڤابیڌاْ}} ڤا [[:$2]]:",
+       "revdelete-selected-file": "{{PLURAL:$1| نوسقاْ جانیا گولاْڤورچین ڤابیڌاْ|نوسقاْ جانیایٱل گولاْڤورچین ڤابیڌاْ}} ڤا [[:$2]]:",
        "revdelete-hide-text": "متن ڤانیٱری",
        "revdelete-hide-image": "میٛنۊناْیٱل جانیا ناْ قام کو",
        "revdelete-hide-comment": "خولاساْ آلشدکاری",
        "revdel-restore": "آلشد هال و بال ديڌن",
        "pagehist": "ڤیرگار بٱلگاْ",
        "deletedhist": "ڤیرگار پاکسا ڤابیڌاْ",
+       "revdelete-otherreason": "دیٱری/دلیل اْزافی:",
        "revdelete-reasonotherlist": "دلیل هاْنی",
        "revdelete-edit-reasonlist": "دلیل پاکسا کردن آلشدکاریٱل",
+       "suppressionlog": "پهرستنوماْ پاکساکاری",
+       "mergehistory": "یکی کردن ڤیرگار بٱگاْ",
+       "mergehistory-box": "یکی کردن ڤانیٱریٱل دوتا بٱلگاْ:",
        "mergehistory-from": "بٱلگاْ سرچشماْ:",
        "mergehistory-into": "بٱگاْ مٱقسٱڌ:",
        "mergehistory-list": "ڤیرگار آلشدکاریٱل سٱریٱک بیڌنی",
        "mergehistory-submit": "سر یٱک کردن ڤانیاریٱل",
        "mergehistory-fail-invalid-source": "سرچشمٱ بٱلگاْ نادیاراْ.",
        "mergehistory-fail-invalid-dest": "بٱلگاْ مٱقسٱڌ نادیاراْ.",
+       "mergehistory-no-source": "سرچشماْ بٱلگاْ $1 ڤوجۊڌ ناراْ.",
+       "mergehistory-no-destination": "بٱلگاْ $1 ڤوجۊڌ ناراْ.",
+       "mergehistory-invalid-source": "سرچشماْ بٱلگاْ ڤا یٱ داسوݩ خۊ داشداْ بۊ.",
+       "mergehistory-autocomment": "یکی بیڌاْ [[:$1]] ڤا [[:$2]]",
+       "mergehistory-comment": "یکی بیڌاْ [[:$1]] ڤا [[:$2]]: $3",
        "mergehistory-reason": "دلیل:",
        "mergelog": "سیائاْ ؤریٱک",
        "revertmerge": "سٱڤا کردن",
        "editundo": "ٱنجومشیڤ کردن",
        "diff-empty": "(یٱ جۊر)",
        "diff-multi-sameuser": "({{PLURAL:$1|یٱ دۊناٛ نوسقاٛ مؽنجخایی|$1 نوسقاٛیٱل مؽنجخایی}} ب دٱسد{{PLURAL:$2|کاریاری ديٱ|$2 کاريارا}} نشۊن دیاری نٱکرداْ)",
-       "diff-multi-otherusers": "({{PLURAL:$1|یٱ نوسقاْ میٛنجقایی|$1 نوسقاْیٱل میٛنجایی}} ڤا دٱسد {{PLURAL:$2|کاریاری دیٱ|$2 کاریارٱل}} نشۊن داڌاْ نٱڤابیڌاْ)",
+       "diff-multi-otherusers": "({{PLURAL:$1|یٱ نوسقاْ میٛنجقایی|$1 نوسقاْیٱل میٛنجایی}} ڤا دٱسد {{PLURAL:$2|کاریاری دیٱ|$2 کاریارٱل}} نشوݩ داڌاْ نٱڤابیڌاْ)",
        "diff-paragraph-moved-tonew": "پاراگراف جا ب جا ڤابی، یٱ کاْرٱت بپۊرنین تا رۉین یٱ جا دیٱر.",
        "diff-paragraph-moved-toold": "پاراگراف جا ب جا ڤابی، یٱ کاْرٱت بپۊرنین تا رۉین ب جا نیایی.",
        "searchresults": "نتيجاْیٱل پاٛی جۊری",
        "nextn-title": "نیایی $1 {{PLURAL:$1|نتيجٱ|نتیجاْیٱل}}",
        "shown-title": "نشوݩ دائن $1 {{PLURAL:$1|نتیجاْ|نتیجاْیٱل}} سی هر بٱلگاْ",
        "viewprevnext": "دیڌن ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-exists": "<strong>ایچو میٛن ای ڤیکی یٱ بٱلگاْ هڌ کاْاْسمس \"[[:$1]]\" اْ </strong> {{PLURAL:$2|0=|هٱمچونو ساٛیل نتیجاْیٱلی کاْ دیار کرداْ ناْ کونین.}}",
+       "searchmenu-exists": "<strong>ایچو میٛن ای ڤیکی یٱ بٱلگاْ هڌ کاْ اْسمس \"[[:$1]]\" اْ </strong> {{PLURAL:$2|0=|هٱمچونو ساٛیل نتیجاْیٱلی کاْ دیار کرداْ ناْ کونین.}}",
        "searchmenu-new": "<strong>اي بٱلگاْ نٱ میٛن \"[[:$1]]\" ای ڤیکی راسد کو!</strong> {{PLURAL:$2|0=|See also the page found with your search.|See also the search results found.}}",
        "searchprofile-articles": "بٱلگاْیٱل مینۊناْ دار",
        "searchprofile-images": "مۊلتی مدیا",
        "search-showingresults": "{{PLURAL:$4|نتیجاْیٱل<strong>$1</strong> ز <strong>$3</strong>|نتیجاْ یٱل<strong>$1 - $2</strong ز <strong>$3</strong>}}",
        "search-nonefound": "هیژ نتیجاْیی ڤا پاٛی جوست توݩ یکی نیڌ.",
        "powersearch-legend": "پاٛی جۊری پیشکرداْ",
+       "powersearch-ns": "پاٛی جۊری میٛن نومجایٱل:",
        "powersearch-togglelabel": "ڤارسی کردن:",
        "powersearch-toggleall": "هٱماْ",
        "powersearch-togglenone": "هيش کوم",
        "prefs-rc": "آلشدکاریٱل ایسنی",
        "prefs-watchlist": "ساٛیل بٱرگ",
        "prefs-editwatchlist": "آلشدکاری ساٛیل بٱرگ",
+       "prefs-editwatchlist-label": "چیا خوتوناْ میٛن ساٛیل بٱگرتوݩ آلشدکاری کونین:",
        "prefs-editwatchlist-clear": "ساٛیل بٱرگ خوتوناْ پاکسا کونین",
        "prefs-watchlist-edits-max": "شوماراْ بیشتروناْ:1000",
        "prefs-watchlist-token": "نشوناْ ساٛیل بٱرگ:",
        "group-user": "کاریارٱل",
        "group-autoconfirmed": "کاریارٱل خودپوشت راسد ڤابیڌاْ.",
        "group-bot": "روڤاتٱل",
-       "group-sysop": "سٱردیڤۊنکارۊن",
+       "group-sysop": "سٱردیڤۊنکاروݩ",
        "group-bureaucrat": "بوروکراتٱل",
        "group-all": "(هٱماْ)",
        "group-user-member": "{{GENDER:$1|کاریار}}",
        "nchanges": "$1 {{PLURAL:$1|آلشدکاری|آلشدکاریٱل}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ز آخری دیڌن}}",
        "enhancedrc-history": "ڤیرگار",
-       "recentchanges": "آلشدکاریا ایسنی",
+       "recentchanges": "آلشدکاریٱل ایسنی",
        "recentchanges-legend": "گوزیناْیٱل آلشدکاریٱل ایسنی",
        "recentchanges-summary": "دو بیشتر آلشدٱل تازاْ باڤ ڤیکی ناْ ز ای بٱلگاْ پاٛیگری کو.",
        "recentchanges-noresult": "هیژ آلشدکاری میٛن گات ای چیا اْتفاق نٱڤٱسداْ",
        "rc-enhanced-hide": "قام کردن جوزئیات",
        "rc-old-title": "زاتٱ چی \"$1\" راس ڤابیڌاْ",
        "recentchangeslinked": "آلشدکاریٱل تاْ یٱک",
-       "recentchangeslinked-feed": "تغÛ\8cÛ\8cرات Ù\85رتبط",
-       "recentchangeslinked-toolbox": "آلشدکاریٱل تاْ یٱک",
-       "recentchangeslinked-title": "آلشدکاریٱل تاٛ یکی سی $1",
+       "recentchangeslinked-feed": "Ø¢Ù\84شدکارÛ\8cÙ±Ù\84 ØªÛ\8cÙ\9b Û\8cÙ±Ú©",
+       "recentchangeslinked-toolbox": "آلشدکاریٱل تیٛ یٱک",
+       "recentchangeslinked-title": "آلشدکاریٱل تیٛ یکی سی $1",
        "recentchangeslinked-summary": "نوم یٱ بٱلٛگاْ ناْ ڤامؽ کونین تا آلشڌکاری بٱلٛگیٱل کاْ ڤاْ هومؽنڌارکرڌیناْ یا زاْ هو مؽنڌاری گریڌین ناْ ڤڤینین(سی نیٱشڌن هوم ڤٱنوناْ یٱ بنکۊ چونوݩ چی ائی ناْ ڤزٱنین:نوم بونکۊ). \nآلشڌکاریٱل بلٛگیٱلؽ کاْ مؽن[[Special:Watchlist|نومگٱ دیناگریٱل اؽسا]] هؽڌن <strong>ؤٱرڌار</strong> نمای اْڤۊهاْ",
        "recentchangeslinked-page": "نوم بٱلگاْ:",
-       "recentchangeslinked-to": "آلشدکاریٱلی کاْ میٛن بٱلگاْیٱل هومپاٛیڤٱند بیناْ ب جا بٱلگاْ داڌاْ ڤابیڌاْ دیاریسۊن کو",
+       "recentchangeslinked-to": "آلشدکاریٱلی کاْ میٛن بٱلگاْیٱل هومپاٛیڤٱند بیناْ ب جا بٱلگاْ داڌاْ ڤابیڌاْ دیاریسوݩ کو",
        "recentchanges-page-added-to-category": "[[:$1]] اْزاف ڤابی ب دٱسداْ",
        "recentchanges-page-removed-from-category": "[[:$1]] ز دٱسداْ جوڌا ڤابی",
        "upload": "سوڤار کردن جانیا",
        "linkstoimage-redirect": "$1 (ڤاگٱردۊنی جانیا) $2",
        "sharedupload": "ای جانیا کاْ ز  $1 گاشا میٛن پوروجاْیٱل دیٱ ڤٱسداْ بۊ ڤاکار",
        "sharedupload-desc-here": "جانیایی کاْ میٛن $1 گاشا میٛن پوروجٱیٱل هٱنی ٱم ب کار گرهڌاْ ڤابیڌاْ بۊ.\nتۉزی سی [$2 file description page] میٛن دڤۊن دیاراْ",
-       "filepage-nofile": "چونو جانیایی ڤا چونڤ اْسمی نیڌس.",
+       "filepage-nofile": "چونو جانیایی ڤا چونو اْسمی نیڌس.",
        "uploadnewversion-linktext": "یٱ نوسقاْ تازاْ زی جانیا سوڤار کونین",
        "shared-repo-from": "ز $1",
-       "upload-disallowed-here": "ايسا ناْترین ای جانیا نٱ ز نۉ سوڤار کونین",
+       "upload-disallowed-here": "ايسا نیٛترین ای جانیا نٱ ز نۉ سوڤار کونین",
        "filerevert": "ز سرگرهڌن سی $1",
        "filerevert-legend": "ز سرگرهڌن جانیا",
        "filerevert-comment": "دلیل:",
        "sp-contributions-logs": "پاْرستنۊماْیٱل",
        "sp-contributions-talk": "چٱک چناْ",
        "sp-contributions-search": "سی هومیاریٱل پاٛی جۊری ڤابۊ",
-       "sp-contributions-username": "Ù\86Ù\88Ù\85 Ù\86اÙ\9bØ´Û\8aÙ\86 آی پی یا نوم کاریاری",
+       "sp-contributions-username": "Ù\86Ù\88Ù\85 Ù\86Ø´Ù\88Ý© آی پی یا نوم کاریاری",
        "sp-contributions-toponly": "فقٱت آلشدکاریٱلی کاْ جۏزڤاْ آخریݩ دۉران دیاری کو",
        "sp-contributions-newonly": "فٱقٱت آلشدکاریٱلی نٱ کاْ میٛن گات راست کردن بٱلگاْ بیڌناْ دیاری کو.",
        "sp-contributions-submit": "پاٛی جۊری",
        "whatlinkshere-page": "بٱلگاْ",
        "linkshere": "چونو بٱلگاْیٱلی هومپاٛیڤٱند ڤابیناْ ب '''$2''':",
        "nolinkshere": "هیژ بٱلگاْ ب '''$2''' هوم پاٛیڤٱند ناراْ.",
-       "isredirect": "بٱلگاْ ڤاگٱردۊنی",
+       "isredirect": "بٱلگاْ ڤاگٱردونی",
        "istemplate": "ڤارو گونجایشدٱل",
        "isimage": "جانیا هومپاٛیڤٱند",
        "whatlinkshere-prev": "{{PLURAL:$1|دیندایی|دیندایی$1}}",
        "import-upload-filename": "نوم جانیا:",
        "import-comment": "ڤير و باڤٱر",
        "importlogpage": "پهرستنوماْ داڌن",
-       "tooltip-pt-userpage": "{{GENDER:|بٱلگاْ کاریاریتۊن}} بٱلگاْ",
+       "tooltip-pt-userpage": "{{GENDER:|بٱلگاْ کاریاریتوݩ}} بٱلگاْ",
        "tooltip-pt-mytalk": "{{GENDER:|بٱلگاْ چٱک چناْ کاریاریام}}",
        "tooltip-pt-preferences": "{{GENDER:|ایسا}} ٱسل کاریٱل",
        "tooltip-pt-watchlist": "نومگٱ بٱلگاْیٱلی کاْ ایسا آلشدکاریا خوتۊناْ دینداگٱردی اْکونین",
        "tooltip-pt-mycontris": "یٱ نومگٱ ز هومیاریٱل {{GENDER:|ایسا}}",
-       "tooltip-pt-login": "اÛ\8cÙ\85ا Ø§Ù\9bÚ¯Û\8aÛ\8cÙ\85 Ú©Ø§Ù\92 Ø±Û\89Û\8cÙ\86 Ú¤Ø§Ù\85Û\8cÙ\86 Ø³Ø§Ù\85Û\8aÙ\86Ú¯Ù±: Ú¤Ø§Ù\92Ù\84Û\8c Ú\86Ù\88Ù\86Ù\88 Ú©Ø§Ø±Û\8c Ø§Ù\9bژباری نی",
-       "tooltip-pt-logout": "ز سامۊناْ درٱڤوڌن",
-       "tooltip-pt-createaccount": "اÙ\8aسا Ù¾Ù\88شت Ú¯Ù±Ø±Ù\85 Ú¤Ø§Ø¨Û\8cÚ\8cÛ\8cÙ\86اÙ\92 Ú©Ø§Ù\92 Û\8cÙ± Ù\87ساÙ\88 Ø±Ø§Ø³Ø¯ Ú©Ù\88Ù\86Û\8cÙ\86 Ù\88 Ø¨Û\8cائÛ\8cÙ\86 Ú¤Ø§Ù\85Û\8cÙ\86. Ú¤Ø§Ù\92Ù\84Û\8c Ú\86Ù\88Ù\86Ù\88 Ú©Ø§Ø±Û\8c Ø§Ù\9bژباری نی.",
-       "tooltip-ca-talk": "Ú\86Ù±Ú© Ú\86Ù\86اÙ\92 Ø³Û\8c Ù\85Û\8cÙ\86Û\8aÙ\86اÙ\92 Ø¨Ù±Ù\84Ú¯Ù±",
+       "tooltip-pt-login": "اÛ\8cÙ\85ا Ø§Ù\92Ú¯Û\8aÛ\8cÙ\85 Ú©Ø§Ù\92 Ø±Û\89Û\8cÙ\86 Ú¤Ø§Ù\85Û\8cÙ\9bÙ\86 Ø³Ø§Ù\85Ù\88Ù\86Ú¯Ù±: Ú¤Ø§Ù\92Ù\84Û\8c Ú\86Ù\88Ù\86Ù\88 Ú©Ø§Ø±Û\8c Ø§Ù\92ژباری نی",
+       "tooltip-pt-logout": "ز ساموناْ درٱڤوڌن",
+       "tooltip-pt-createaccount": "اÙ\8aسا Ù¾Ù\88شت Ú¯Ù±Ø±Ù\85 Ú¤Ø§Ø¨Û\8cÚ\8cÛ\8cÙ\86اÙ\92 Ú©Ø§Ù\92 Û\8cÙ± Ù\87ساÙ\88 Ø±Ø§Ø³Ø¯ Ú©Ù\88Ù\86Û\8cÙ\86 Ù\88 Ø¨Û\8cائÛ\8cÙ\86 Ú¤Ø§Ù\85Û\8cÙ\9bÙ\86. Ú¤Ø§Ù\92Ù\84Û\8c Ú\86Ù\88Ù\86Ù\88 Ú©Ø§Ø±Û\8c Ø§Ù\92ژباری نی.",
+       "tooltip-ca-talk": "Ú\86Ù±Ú© Ú\86Ù\86اÙ\92 Ø³Û\8c Ù\85Û\8cÙ\9bÙ\86Ù\88Ù\86اÙ\92 Ø¨Ù±Ù\84گاÙ\92",
        "tooltip-ca-edit": "ای بٱلگاْ نٱ آلشدکاری کو",
        "tooltip-ca-addsection": "شورۊ کردن یٱ بٱرجا دیٱ",
        "tooltip-ca-viewsource": "ای بٱلگاْ پٱر و پیم ڤابیڌاْ.\nایسا تاْرین سرچشماْساْ بڤنین",
        "tooltip-ca-protect": "ای بٱلگاْ ناْ پٱر و پیم کو",
        "tooltip-ca-delete": "ای بٱلگاْ ناْ پاکسا کو",
        "tooltip-ca-move": "جابجا کردن ای بٱلگاْ",
-       "tooltip-ca-watch": "اْزاف کردن ای بٱلگٱ ب سئیل بٱرگ خوتۊن",
+       "tooltip-ca-watch": "اْزاف کردن ای بٱلگاْ ب ساٛیل بٱرگ خوتوݩ",
        "tooltip-ca-unwatch": "ڤورداشتن بٱلگاْ ز ساٛیل بٱرگتۊن",
        "tooltip-search": "جوستن {{SITENAME}}",
-       "tooltip-search-go": "رۉ میٛن بٱلگاْیٱلی کاْ نوم راستٱکی داشتاْ بۊن",
-       "tooltip-search-fulltext": "بٱلگاْیٱل نٱ سی چونو نڤشداْیٱلی پاٛی جۊری کو",
+       "tooltip-search-go": "رۉ میٛن بٱلگاْیٱلی کاْ نوم راستٱکی داشتاْ بوݩ",
+       "tooltip-search-fulltext": "بٱلگاْیٱل ناْ سی چونو نڤشداْیٱلی پاٛی جۊری کو",
        "tooltip-p-logo": "بنیٱرین ب سرآسوناْ",
        "tooltip-n-mainpage": "بنیٱرین ب سرآسوناْ",
        "tooltip-n-mainpage-description": "بنیٱرین ب سرآسوناْ",
        "tooltip-t-emailuser": "فرشناڌن ب ٱنجوماناماْ {{GENDER:$1|ای کاریار}}",
        "tooltip-t-upload": "سوڤار کردن جانیایٱل",
        "tooltip-t-specialpages": "یٱ نومگٱ ز بٱلگاْیٱل ڤیجٱ",
-       "tooltip-t-print": "نوسقاْ پرینت گرهڌنی سی ای بٱلگٱ",
-       "tooltip-t-permalink": "هومپاٛیڤٱند دایومی سی ڤانیٱری بٱلگٱ",
-       "tooltip-ca-nstab-main": "دÛ\8cÚ\8cÙ\86 Ù\85Û\8cÙ\86Û\8aÙ\86Ù± Ø¨Ù±Ù\84Ú¯Ù±",
+       "tooltip-t-print": "نوسقاْ پرینت گرهڌنی سی ای بٱلگاْ",
+       "tooltip-t-permalink": "هومپاٛیڤٱند دایومی سی ڤانیٱری بٱلگاْ",
+       "tooltip-ca-nstab-main": "دÛ\8cÚ\8cÙ\86 Ù\85Û\8cÙ\9bÙ\86Ù\88Ù\86اÙ\92 Ø¨Ù±Ù\84گاÙ\92",
        "tooltip-ca-nstab-user": "دیڌن بٱلگاْ کاریار",
        "tooltip-ca-nstab-media": "دیدن صفحه مدیا",
        "tooltip-ca-nstab-special": "ای بٱلگاْ یٱ بٱلگاْ ڤیجاْ، و نیبۊ آلشدکاریس کونین",
        "tooltip-recreate": "ز نۉ راسد کردن بٱلگاْیی کاْ دینداتر پاکسا ڤابیڌاْ.",
        "tooltip-upload": "شورۊ سوڤار کرد",
        "tooltip-rollback": "\"ڤورگٱنیئن\" لرنیڌن سی هال و بال ٱڤٱل ای بٱلگٱ سی یو کاْ هومیاری نیایی سی بیتٱر کردن بۊ ٱلڤٱت ڤا یٱ کرٱت پۊرنیڌن.",
-       "tooltip-undo": "Ù±Ù\86جÙ\88Ù\85 Ù\86ٱگرÙ\87Ú\8cÙ\86 Ø§Û\8c Ø¢Ù\84شدکارÛ\8c Ù\86اÙ\92 Ú¤Ù\88رگٱÙ\86 Ù\88 Ù\87Ù±Ù\85اÙ\92 Ù\81Ù\88رÙ\85Ù±Ù\84 Ú¤Û\8cراÛ\8cشت Ú©Ø§Ø±Û\8cا Ù\86Ù± Ø¬Û\8aر Ù\87اÙ\84 Ù\88 Ø¨Ø§Ù\84 Ù¾Û\8cØ´ Ø³Ø¦یل کو. چونو کاری بتون سلا اْڌاْ کاْ ب چٱکستاْ خوتۊن یٱ دلیل اْزاف کونین.",
+       "tooltip-undo": "Ù±Ù\86جÙ\88Ù\85 Ù\86ٱگرÙ\87Ú\8cÙ\86 Ø§Û\8c Ø¢Ù\84شدکارÛ\8c Ù\86اÙ\92 Ú¤Ù\88رگٱÙ\86 Ù\88 Ù\87Ù±Ù\85اÙ\92 Ù\81Ù\88رÙ\85Ù±Ù\84 Ú¤Û\8cراÛ\8cشت Ú©Ø§Ø±Û\8cا Ù\86Ù± Ø¬Û\8aر Ù\87اÙ\84 Ù\88 Ø¨Ø§Ù\84 Ù¾Û\8cØ´ Ø³Ø§Ù\9bیل کو. چونو کاری بتون سلا اْڌاْ کاْ ب چٱکستاْ خوتۊن یٱ دلیل اْزاف کونین.",
        "tooltip-summary": "یٱ چکستاْ کۊچیر ناْ بیارین ڤامیٛن",
        "others": "دیٱروݩ",
        "simpleantispam-label": "Anti-spam check.\nپور<strong>نکنين</strong> ایچو ناْ!",
        "pageinfo-title": "ڌونائی زاْ «$1»",
        "pageinfo-header-basic": "ڌونائیٱل بٱلٛگاْ",
-       "pageinfo-header-edits": "ڤیرایشت ڤیرگار",
+       "pageinfo-header-edits": "آلدشکاری کردن ڤیرگار",
        "pageinfo-header-restrictions": "هناڌاری زاْ بٱلٛگاْ",
        "pageinfo-header-properties": "ؤیژگیٱل بٱلٛگاْ",
        "pageinfo-display-title": "نماونیڌن داسوݩ",
        "pageinfo-subpages-value": "1 ($2 {{PLURAL:$2|آلشڌتور|آلشڌ تور}}; $3 {{PLURAL:$3|خاٛراز آلشڌ تور|خاٛراز آلشڌ تور}})",
        "pageinfo-firstuser": "بٱلگاْ راس کون",
        "pageinfo-firsttime": "گات دروس ڤابیڌن بٱلگاْ",
-       "pageinfo-lastuser": "آخری ڤیرایشتکار",
-       "pageinfo-lasttime": "گات آخری ڤیرایشت",
+       "pageinfo-lastuser": "آخری آلشدکار",
+       "pageinfo-lasttime": "گات آخری آلشدکاری کردن",
        "pageinfo-edits": "کول آلشدکاریٱل",
        "pageinfo-authors": "شوماراْ کولی نڤیسیارٱل یٱکۊنٱ",
        "pageinfo-recent-edits": "شوماراْ آلشدکاریٱل ایسنی (د $1 دینداتر)",
        "metadata-help": "ای جانیا ز ڤٱرگرهڌاْ دۊنسمٱندیٱل اْزافیاْ کاْ هونو گاشا(شایڌ) ڤا دیربین دیجیتالی یا اْسکٱنر سی ڤا کار ڤٱندن یا راست کردنسۊن یا دیجیتالی کردنسۊن اْزاف ڤابیناْ. ٱر جانیا ز هال و بال ٱڤلی خو آلشد ڤابیڌاْ بۊ شایڌ تٱموم تۉزیات دۊنسمٱندیٱل ٱسگ نٱ دیاری نٱکوناْ.",
        "metadata-expand": "نشودادن جزئیات تفصیلی",
        "metadata-collapse": "قایم کردن جزئیات تفصیلی",
-       "metadata-fields": "رشناْیٱل گٱپ دۊنسمٱندیٱلی کاْ میٛن ای پاٛیغوم نومگٱ کاری ڤابیڌاْ ناْ ز ڤٱر گرهڌاْ بٱلگاْ ٱسگی کاْ گات ڤٱختی کاْ جٱدڤٱل گٱپ دۊنسمٱندیٱل ڤا اْبۊن دیاری کونن.\n*راست کو\n*مودل\n*مجال گات ٱسل\n*گات آشگار\n*اْف اْن شومارٱ\n*ایزو نرخ میٛن سورٱت\n*فوکالنس\n*هونٱرمٱند\n*کوپی رایت\n*هال و بال جی پی اْس \n*جی پی اْس گٱپ\n*جی پی اْس هٱماْ جۊرٱ",
+       "metadata-fields": "رشناْیٱل گٱپ دۊنسمٱندیٱلی کاْ میٛن ای پاٛیغوم نومگٱ کاری ڤابیڌاْ ناْ ز ڤٱر گرهڌاْ بٱلگاْ ٱسگی کاْ گات ڤٱختی کاْ جٱدڤٱل گٱپ دۊنسمٱندیٱل ڤا اْبۊن دیاری کونن.\n*راست کو\n*مودل\n*مجال گات ٱسل\n*گات آشگار\n*اْف اْن شوماراْ\n*ایزو نرخ میٛن سورٱت\n*فوکالنس\n*هونٱرمٱند\n*کوپی رایت\n*هال و بال جی پی اْس \n*جی پی اْس گٱپ\n*جی پی اْس هٱماْ جۊرٱ",
        "namespacesall": "هٱمٱ",
        "monthsall": "هٱمٱ",
        "confirm_purge_button": "خۊڤاْ",
        "logentry-delete-revision": "$1 دیاری {{PLURAL:$5|یٱ نوسخاْ|$5 نوسخاْ}} بٱلٛگاْ $3 ناْ{{GENDER:$2|آلشڌکرڌ}}: $4",
        "revdelete-content-hid": "هؽلنیڌناْ بؽڌیارکرڌ",
        "logentry-move-move": "$1 {{GENDER:$2|جا ب جا کرداْ}} بٱلگاْ $3 نٱ سی $4",
-       "logentry-move-move-noredirect": "$1 {{GENDER:$2|جا ب جا کرد}} بٱلگاْ $3 نٱ سی $4 بی یو یٱ ڤاگٱردۊنی داشداْ بۊ",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|جا ب جا کرد}} بٱلگاْ $3 نٱ سی $4 بی یو یٱ ڤاگٱردونی داشداْ بۊ",
        "logentry-move-move_redir": "$1 بٱلٛگاْ $3 ناْ ڤاْ $4 کاْ آلشڌ تور ڤیڌاْ {{GENDER:$2|کل کرڌ}}",
        "logentry-patrol-patrol-auto": "$1 نوسخهٔ $4 بٱلٛگاْ $3 ناْ خودکار ڤاْ عنڤان لرخوؤٱرداٛ {{GENDER:$2|دزاْ کونین}}",
        "logentry-newusers-create": "هساڤ کاریاری $1 {{GENDER:$2|راسد ڤابی}}",
        "log-action-filter-block-block": "نیاگری ڤابۊ",
        "log-action-filter-block-unblock": "نیاگری نٱڤابۊ",
        "log-action-filter-delete-delete": "پاکسا کردن بٱلگاْ",
-       "authmanager-authplugin-setpass-bad-domain": "پۊشگر نادیار.",
        "authmanager-retype-help": "سی پوشت راسدکاری ز نۉ رازیناْ گوڌٱشتن ناْ بزنین",
        "authmanager-email-label": "ٱنجوماناماْ",
        "authmanager-email-help": "تیرنشۊن ٱنجوماناماْ",
index eb808fd..5aaea0d 100644 (file)
        "revertpage": "Kemmoù distaolet gant [[Special:Contributions/$2|$2]] ([[User talk:$2|Kaozeal]]); adlakaet d'ar stumm diwezhañ a-gent gant [[User:$1|$1]]",
        "revertpage-nouser": "Disteuler kemmoù un implijer kuzhet ha distreiñ d'ar stumm diwezhañ gant an {{GENDER:$1|[[implijer :$1|$1]]}}",
        "rollback-success": "Nullet ar c'hemmoù gant {{GENDER:$3|$1}};\nadlakaet diouzh ar stumm diwezhañ gant {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Nullet ar c'hemmoù gant $1;\nadlakaet diouzh ar stumm diwezhañ gant $2. [$3 Diskouez ar c'hemmoù]",
        "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",
        "authmanager-create-no-primary": "N'eus ket bet gallet implijout an titouroù kred lakaet evit krouiñ ur gont.",
        "authmanager-link-no-primary": "Ne c'hallomp ket liammañ ur gont gant an titouroù anaout pourchaset.",
        "authmanager-link-not-in-progress": "Ne'z a ket war-raok al liammañ kontoù pe kollet ez eus bet roadennoù dalc'h marteze. Adkrogit adalek ar penn-kentañ.",
-       "authmanager-authplugin-setpass-failed-title": "C'hwitet eo bet ar cheñchamant ger-tremen",
-       "authmanager-authplugin-setpass-failed-message": "Nac'het eo bet cheñch ar ger-tremen gant an adveziant dilesa.",
-       "authmanager-authplugin-create-fail": "Nac'het eo bet krouiñ ar gont gant an adveziant dilesa.",
-       "authmanager-authplugin-setpass-denied": "N'eo ket aotreet cheñch gerioù-tremen gant an adveziant dilesa.",
-       "authmanager-authplugin-setpass-bad-domain": "Domani direizh.",
        "authmanager-autocreate-noperm": "N'haller ket krouiñ kontoù ent emgefre.",
        "authmanager-autocreate-exception": "Diweredekaet eo bet ar c'hrouiñ kontoù evit ar mare abalamour da fazioù kent.",
        "authmanager-userdoesnotexist": "N'eo ket enrollet ar gont implijer \"$1\".",
index 2120a41..28e3a77 100644 (file)
        "revertpage": "Vraćene izmjene {{GENDER:$2|korisnika|korisnice}} [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]]) na posljednju izmjenu {{GENDER:$1|korisnika|korisnice}} [[User:$1|$1]]",
        "revertpage-nouser": "Vraćene izmjene skrivenog korisnika na posljednju reviziju, koju je {{GENDER:$1|napravio|napravila}} [[User:$1|$1]]",
        "rollback-success": "Vraćene izmjene {{GENDER:$3|korisnika|korisnice}} $1 na posljednju verziju {{GENDER:$4|korisnika|korisnice}} $2.",
-       "rollback-success-notify": "Vraćenje izmjene korisnika $1;\nvraćeno na posljednju izmjenu korisnika $2. [$3 Prikaži izmjene]",
        "sessionfailure-title": "Greška u sesiji",
        "sessionfailure": "Izgleda da postoji problem sa vašom sesijom; ova akcija je otkazana kao prevencija protiv napadanja sesija. Kliknite \"back\" (''nazad'') i osvježite stranicu sa koje ste došli, i opet pokušajte.",
        "changecontentmodel": "Promijeni model sadržaja stranice",
        "databaselocked": "Baza podataka već je zaključana.",
        "databasenotlocked": "Baza podataka nije zaključana.",
        "lockedbyandtime": "(od $1 dana $2 u $3)",
-       "move-page": "Premeštanje $1",
+       "move-page": "Premještanje $1",
        "move-page-legend": "Premjesti stranicu",
        "movepagetext": "Korištenjem ovog formulara možete preimenovati stranicu, premještajući cijelu historiju na novo ime.\nČlanak pod starim imenom postat će stranica koja preusmjerava na članak pod novim imenom. \nMožete automatski izmijeniti preusmjerenje do izvornog naslova.\nAko se ne odlučite na to, provjerite [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|neispravna preusmjeravanja]].\nDužni ste provjeriti da svi linkovi i dalje nastave voditi na prave stranice.\n\nImajte na umu da članak <strong>neće</strong> biti premješten ako već postoji članak pod imenom na koje ga namjeravate preusmjeriti osim u slučaju stranice za preusmjeravanje koja nema nikakvih starih izmjena.\nTo znači da možete vratiti stranicu na prethodno mjesto ako pogriješite, ali ne možete zamijeniti postojeću stranicu.\n\n<strong>Napomena:</strong>\nOvo može biti drastična i neočekivana promjena kad su u pitanju popularne stranice.\nMolimo da dobro razmislite prije no što premjestite stranicu.",
        "movepagetext-noredirectfixer": "Koristeći donji obrazac, preimenovat ćete stranicu i premjestiti cijelu njenu historiju na novi naziv.\nStari naziv postat će preusmjerenje na novi naziv.\nMolimo da provjerite postoje li [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|nedovršena preusmjerenja]].\nVi ste za to odgovorni te morate provjeriti jesu li linkovi ispravni i vode li tamo kamo bi trebali voditi.\n\nImajte na umu da stranica '''neće''' biti premještena ako već postoji stranica s tim imenom, osim ako je prazna ili je preusmjerenje ili nema ranije historije.\nOvo znači da možete preimenovati stranicu nazad gdje je ranije bila preimenovana ako ste pogriješili, ali ne možete ponovo preimenovati postojeću stranicu.\n\n<strong>Napomena:</strong>\nOvo može biti drastična i neočekivana promjena za popularnu stranicu;\ndobro razmislite o posljedicama prije nego što nastavite.",
        "authmanager-create-disabled": "Onemogućeno pravljenje računa.",
        "authmanager-create-from-login": "Popunite polja da biste napravili račun.",
        "authmanager-create-not-in-progress": "Pravljenje računa nije u toku ili su podaci o sesiji izgubljeni. Počnite ispočetka.",
-       "authmanager-authplugin-setpass-failed-title": "Promjena lozinke nije uspjela",
-       "authmanager-authplugin-setpass-failed-message": "Dodatak za autentifikaciju odbio je promjenu lozinke.",
-       "authmanager-authplugin-create-fail": "Dodatak za autentifikaciju odbio je pravljenje računa.",
-       "authmanager-authplugin-setpass-denied": "Dodatak za autentifikaciju ne dozvoljava mijenjanje lozinki.",
-       "authmanager-authplugin-setpass-bad-domain": "Neispravna domena.",
        "authmanager-autocreate-noperm": "Automatsko pravljenje računa nije dozvoljeno.",
        "authmanager-autocreate-exception": "Automatsko pravljenje računa privremeno je onemogućeno zbog prijašnjih greški.",
        "authmanager-userdoesnotexist": "Korisnički račun \"$1\" nije registriran.",
index dde20d9..99ee8dc 100644 (file)
        "tog-norollbackdiff": "No mostris les diferències després de realitzar una reversió",
        "tog-useeditwarning": "Avisa'm quan surti d'una pàgina d'edició amb canvis sense desar",
        "tog-prefershttps": "Utilitza sempre una connexió segura en iniciar una sessió",
+       "tog-showrollbackconfirmation": "Mostra una petició de confirmació en clicar un enllaç de reversió",
        "underline-always": "Sempre",
        "underline-never": "Mai",
        "underline-default": "Per defecte del navegador",
        "confirmable-no": "No",
        "thisisdeleted": "Voleu mostrar o restaurar $1?",
        "viewdeleted": "Voleu mostrar $1?",
-       "restorelink": "{{PLURAL:$1|una versió esborrada|$1 versions esborrades}}",
+       "restorelink": "{{PLURAL:$1|una versió suprimida|$1 versions suprimides}}",
        "feedlinks": "Sindicació:",
        "feed-invalid": "La subscripció no és vàlida pel tipus de sindicament.",
        "feed-unavailable": "Els canals de sindicació no estan disponibles",
        "formerror": "Error: No s'han pogut enviar les dades del formulari.",
        "badarticleerror": "Aquesta operació no es pot dur a terme en aquesta pàgina.",
        "cannotdelete": "No s'ha pogut suprimir la pàgina o fitxer «$1».\nPotser ja l'ha suprimit algú altre.",
-       "cannotdelete-title": "No es pot suprimir la pàgina \" $1 \"",
+       "cannotdelete-title": "No es pot suprimir la pàgina «$1»",
        "delete-scheduled": "S'ha programat la pàgina «$1» per ser eliminada.\nTingueu paciència.",
        "delete-hook-aborted": "Un «hook» ha interromput la supressió.\nNo ha donat cap explicació.",
        "no-null-revision": "No s'ha pogut crear una nova revisió nul·la de la pàgina «$1»",
        "badretype": "Les contrasenyes que heu introduït no coincideixen.",
        "usernameinprogress": "La creació d'un compte per a aquest usuari ja està en curs. Espereu.",
        "userexists": "El nom que heu entrat ja és en ús.\nEscolliu-ne un de diferent.",
+       "createacct-normalization": "El vostre nom d'usuari s'ajustarà a «$2» per restriccions tècniques.",
        "loginerror": "Error d'inici de sessió",
        "createacct-error": "Error de creació de compte",
        "createaccounterror": "No s'ha pogut crear el compte: $1",
        "page_last": "última",
        "histlegend": "Simbologia: (act) = diferència amb la versió actual,\n(prev) = diferència amb la versió anterior, m = modificació menor",
        "history-fieldset-title": "Cerca revisions",
-       "history-show-deleted": "Només revisions esborrades",
+       "history-show-deleted": "Només revisions suprimides",
        "histfirst": "les més antigues",
        "histlast": "les més noves",
        "historysize": "({{PLURAL:$1|1 octet|$1 octets}})",
        "right-deleterevision": "Esborrar i restaurar versions específiques de pàgines",
        "right-deletedhistory": "Veure els historials esborrats sense consultar-ne el text",
        "right-deletedtext": "Veure el text esborrat i els canvis entre revisions esborrades",
-       "right-browsearchive": "Cercar pàgines esborrades",
-       "right-undelete": "Restaurar pàgines esborrades",
+       "right-browsearchive": "Cercar pàgines suprimides",
+       "right-undelete": "Restaurar pàgines suprimides",
        "right-suppressrevision": "Mostra, amaga i revela revisions específiques de pàgines d'un usuari",
        "right-viewsuppressed": "Mostra les revisions amagades de qualsevol usuari",
        "right-suppressionlog": "Veure registres privats",
        "action-deletelogentry": "suprimeix les entrades de registre",
        "action-deletedhistory": "mostra l'historial esborrat d'una pàgina",
        "action-deletedtext": "mostra el text de la revisió eliminada",
-       "action-browsearchive": "cercar pàgines esborrades",
+       "action-browsearchive": "cercar pàgines suprimides",
        "action-undelete": "restaura les pàgines",
        "action-suppressrevision": "revisa i restaura les revisions ocultes",
        "action-suppressionlog": "visualitzar aquest registre privat",
        "categories-submit": "Mostra",
        "categoriespagetext": "{{PLURAL:$1|La següent categoria conté|Les següents categories contenen}} pàgines, o fitxers multimèdia.\n[[Special:UnusedCategories|Les categories no usades]] no s'hi mostren.\nVegeu també [[Special:WantedCategories|les categories sol·licitades]].",
        "categoriesfrom": "Mostra les categories que comencen a:",
-       "deletedcontributions": "Contribucions esborrades",
-       "deletedcontributions-title": "Contribucions esborrades",
+       "deletedcontributions": "Contribucions suprimides",
+       "deletedcontributions-title": "Contribucions suprimides",
        "sp-deletedcontributions-contribs": "contribucions",
        "linksearch": "Cerca d'enllaços externs",
        "linksearch-pat": "Patró de cerca:",
        "delete-confirm": "Supressió de la pàgina «$1»",
        "delete-legend": "Suprimeix",
        "historywarning": "<strong>Avís:</strong> la pàgina que esteu a punt d'eliminar té un historial amb $1 {{PLURAL:$1|revisió|revisions}}:",
-       "historyaction-submit": "Mostra",
+       "historyaction-submit": "Mostra les revisions",
        "confirmdeletetext": "Esteu a punt d'esborrar de forma permanent una pàgina o imatge i tot el seu historial de la base de dades.\nConfirmeu que realment ho voleu fer, que enteneu les\nconseqüències, i que el que esteu fent està d'acord amb la [[{{MediaWiki:Policy-url}}|política]] del projecte.",
        "actioncomplete": "Acció realitzada",
        "actionfailed": "L'acció ha fallat",
        "deleteprotected": "No podeu eliminar la pàgina perquè ha estat protegida.",
        "deleting-backlinks-warning": "<strong>Atenció:</strong>\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|Altres pàgines]] enllacen aquí o inclouen la pàgina que esteu a punt de suprimir.",
        "rollback": "Reverteix edicions",
+       "rollback-confirmation-no": "Cancel·la",
        "rollbacklink": "Reverteix",
        "rollbacklinkcount": "reverteix $1 {{PLURAL:$1|edició|edicions}}",
        "rollbacklinkcount-morethan": "reverteix més de $1 {{PLURAL:$1|edició|edicions}}",
        "revertpage": "Revertides les edicions de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussió]]) a l'última versió de [[User:$1|$1]]",
        "revertpage-nouser": "Edicions revertides per un usuari ocult a l'última revisió de {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Revertides les edicions de {{GENDER:$3|$1}}; recuperant la darrera versió de {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Modificacions revertides per $1;\ns'ha revertit a la darrera versió de $2. [$3 Mostra els canvis]",
        "sessionfailure-title": "Error de sessió",
        "sessionfailure": "S'ha produït un error amb la vostra sessió. S'ha anul·lat aquesta acció en prevenció de pirateig de sessió. Premeu «Torna», recarregueu la pàgina des d'on veniu i torneu-ho a intentar.",
        "changecontentmodel": "Canvia el model de contingut d'una pàgina",
        "restriction-level-autoconfirmed": "semiprotegida",
        "restriction-level-all": "qualsevol nivell",
        "undelete": "Restaura una pàgina esborrada",
-       "undeletepage": "Mostra i restaura pàgines esborrades",
+       "undeletepage": "Mostra i restaura pàgines suprimides",
        "undeletepagetitle": "'''A continuació teniu revisions eliminades de [[:$1]]'''.",
        "viewdeletedpage": "Visualitza les pàgines eliminades",
        "undeletepagetext": "{{PLURAL:$1|S'ha eliminat la pàgina següent, però encara és a l'arxiu i pot ser restaurada|S'han eliminat les $1 pàgines següents, però encara són a l'arxiu i poden ser restaurades}}.\nL'arxiu pot ser netejat periòdicament.",
        "cannotundelete": "Hi ha hagut un error en algunes o totes les restauracions:\n$1",
        "undeletedpage": "'''S'ha restaurat «$1»'''\n\nConsulteu el [[Special:Log/delete|registre d'esborraments]] per a veure els esborraments i els restauraments més recents.",
        "undelete-header": "Vegeu [[Special:Log/delete|el registre d'eliminació]] per a veure les pàgines eliminades recentment.",
-       "undelete-search-title": "Cerca de pàgines esborrades",
-       "undelete-search-box": "Cerca pàgines esborrades",
+       "undelete-search-title": "Cerca de pàgines suprimides",
+       "undelete-search-box": "Cerca pàgines suprimides",
        "undelete-search-prefix": "Mostra pàgines que comencin:",
        "undelete-search-full": "Mostra títols de pàgines que continguin:",
        "undelete-search-submit": "Cerca",
        "sp-contributions-newbies-title": "Contribucions dels comptes d'usuari més nous",
        "sp-contributions-blocklog": "Registre de blocatges",
        "sp-contributions-suppresslog": "contribucions suprimides de {{GENDER:$1|l'usuari|la usuària}}",
-       "sp-contributions-deleted": "Contribucions de {{GENDER:$1|l'usuari|la usuària}} esborrades",
+       "sp-contributions-deleted": "contribucions de {{GENDER:$1|l’usuari|la usuària}} suprimides",
        "sp-contributions-uploads": "càrregues",
        "sp-contributions-logs": "registres",
        "sp-contributions-talk": "discussió",
        "ipbreason": "Motiu:",
        "ipbreason-dropdown": "*Motius de blocatge més freqüents\n** Inserció d'informació falsa\n** Supressió de contingut sense justificació\n** Inserció d'enllaços promocionals (spam)\n** Inserció de contingut sense cap sentit\n** Conducta intimidatòria o hostil\n** Abús de comptes d'usuari múltiples\n** Nom d'usuari no acceptable",
        "ipb-hardblock": "Impedeix que els usuaris registrats puguin editar des d'aquesta adreça IP",
-       "ipbcreateaccount": "Impedeix la creació de comptes",
-       "ipbemailban": "Impedeix que l'usuari enviï correus electrònics",
+       "ipbcreateaccount": "Creació de comptes",
+       "ipbemailban": "Enviament de correus electrònics",
        "ipbenableautoblock": "Bloca l'adreça IP d'aquest usuari, i totes les subseqüents adreces des de les quals intenti registrar-se",
        "ipbsubmit": "Bloca aquest usuari",
        "ipbother": "Un altre termini",
        "ipboptions": "2 hores:2 hours,1 dia:1 day,3 dies:3 days,1 setmana:1 week,2 setmanes:2 weeks,1 mes:1 month,3 mesos:3 months,6 mesos:6 months,1 any:1 year,infinit:infinite",
        "ipbhidename": "Amaga el nom d'usuari de les edicions i llistes",
        "ipbwatchuser": "Vigila les pàgines d'usuari i de discussió de l'usuari",
-       "ipb-disableusertalk": "Impedeix que aquest usuari pugui modificar la seva pàgina de discussió mentre dura el blocatge",
+       "ipb-disableusertalk": "Modificació de la pròpia pàgina de discussió",
        "ipb-change-block": "Torna a blocar l'usuari amb aquests paràmetres",
        "ipb-confirm": "Confirma el blocatge",
        "ipb-sitewide": "A tot el lloc web",
        "logentry-block-block": "$1 {{GENDER:$2|ha blocat}} {{GENDER:$4|$3}} per un temps de $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|va desblocar}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|ha canviat}} la configuració del blocatge de {{GENDER:$4|$3}} per un temps de $5 $6",
+       "logentry-partialblock-block-page": "{{PLURAL:$1|la pàgina|les pàgines}} $2",
+       "logentry-partialblock-block-ns": "{{PLURAL:$1|l’espai de noms|els espais de noms}} $2",
        "logentry-suppress-block": "$1 {{GENDER:$2|ha blocat}} {{GENDER:$4|$3}} per un temps de $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|ha canviat}} la configuració de blocatge de {{GENDER:$4|$3}} per un temps de $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|va importar}} $3 a través de càrrega de fitxer",
        "log-action-filter-suppress-delete": "Supressió de pàgines",
        "log-action-filter-upload-upload": "Càrrega nova",
        "log-action-filter-upload-overwrite": "Torna a carregar",
+       "log-action-filter-upload-revert": "Reverteix",
        "authmanager-authn-not-in-progress": "L'autenticació no està en curs o les dades de sessió s'han perdut. Comenceu de nou des del principi.",
        "authmanager-authn-no-primary": "Les dades credencials no s'han pogut autenticar.",
        "authmanager-authn-autocreate-failed": "Ha fallat la creació automàtica d'un compte local: $1",
        "authmanager-create-disabled": "S'ha inhabilitat la creació de comptes.",
        "authmanager-create-from-login": "Per crear un compte, ompliu els camps.",
-       "authmanager-authplugin-setpass-failed-title": "El canvi de contrasenya ha fallat",
-       "authmanager-authplugin-setpass-bad-domain": "Domini invàlid.",
        "authmanager-autocreate-noperm": "No es permet la creació automàtica de comptes.",
        "authmanager-userdoesnotexist": "El compte d'usuari «$1» no està registrat.",
        "authmanager-username-help": "Nom d'usuari per a l'autenticació.",
index 36b7f36..d648d23 100644 (file)
        "content-failed-to-parse": "Чулацам $2 богӀуш бац $1: $3.",
        "invalid-content-data": "Хилийта йиш йоцу хаамаш",
        "content-not-allowed-here": "Чулацам \"$1\" [[:$2]] агӀонгахь хилийта йиш яц",
+       "editwarning-warning": "Кхий агӀо схьаелича ахьа бина хийцамаш дӀабала мега.\nАхьа системехь регистраци йина елахь, хьа йиш ю «{{int:prefs-editing}}» декъехь хӀара дӀахьедар дӀадайа хьайн нисдаран гӀирс чохь.",
        "editpage-notsupportedcontentformat-title": "Чулацаман тайпа ловш яц",
        "content-model-wikitext": "вики-йоза",
        "content-model-text": "цхьалхе йоза",
index 62b5980..7050e30 100644 (file)
        "logentry-suppress-block": "$1 $3ی بۆ ماوەی $5 $6 بەربەست کرد",
        "logentry-suppress-reblock": "$1 ھەڵبژاردەکانی بەربەستنی $3ی گۆڕی بە ماوەی بەسەرچوونی $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|بارکرد}} $3 بە بەکارھێنانی [[special:Import|بارکەر]]",
+       "logentry-import-interwiki": "$1 $3ی لە ویکییەکی ترەوە ھاوردەکرد",
+       "logentry-import-interwiki-details": "$1 $3ی لە $5ەوە ھەناردە کرد ($4 بەسەرداچوونەوە)",
+       "logentry-merge-merge": "$1 $3ی لەگەڵ $4 تێکەڵکرد (بەسەرداچوونەکان لە $5 زیاترن)",
        "logentry-move-move": "$1 پەڕەی $3ی {{GENDER:$2|گواستەوە}} بۆ $4",
        "logentry-move-move-noredirect": "$1 پەڕەی $3ی بە بێ بەجێھشتنی ڕەوانەکەرێک {{GENDER:$2|گواستەوە}} بۆ $4",
        "logentry-move-move_redir": "$1 پەڕەی $3 {{GENDER:$2|گواستەوە}} بۆ $4 کە پێشتر ڕەوانەکەر بوو",
        "log-action-filter-block": "جۆری بلۆک:",
        "log-action-filter-contentmodel": "جۆری گۆڕینی مۆدێلی ناوەڕۆک:",
        "log-action-filter-delete": "جۆری سڕینەوە:",
+       "log-action-filter-import": "جۆری ھاوردن:",
        "log-action-filter-all": "ھەموو",
        "log-action-filter-block-block": "بەربەستن",
        "log-action-filter-block-unblock": "ھەڵگرتنی بەربەستن",
index 157e9d5..83ff3be 100644 (file)
        "contributions-title": "Cuntribuzione di $1",
        "mycontris": "Cuntribuzioni",
        "contribsub2": "Per {{GENDER:$3|$1}} ($2)",
-       "uctop": "currente",
+       "uctop": "attuale",
        "month": "Da u mese (è nanzu):",
        "year": "Da l'annu (è nanzu):",
        "sp-contributions-newbies": "Mustrà solu e mudifiche di i novi cuntributori",
index 2855d3b..fa11cb5 100644 (file)
@@ -41,7 +41,8 @@
                        "Patriccck",
                        "Ed g2s",
                        "Radana",
-                       "Jan Růžička"
+                       "Jan Růžička",
+                       "Jaroslav Cerny"
                ]
        },
        "tog-underline": "Podtrhávat odkazy:",
@@ -87,6 +88,7 @@
        "tog-norollbackdiff": "Po vrácení změny nezobrazovat porovnání rozdílů",
        "tog-useeditwarning": "Upozornit, když budu opouštět editaci bez uložení změn",
        "tog-prefershttps": "Po přihlášení vždy používat zabezpečené připojení",
+       "tog-showrollbackconfirmation": "Při kliknutí na odkaz pro vrácení editace zobrazit žádost o potvrzení",
        "underline-always": "Vždy",
        "underline-never": "Nikdy",
        "underline-default": "Podle nastavení prohlížeče nebo vzhledu",
        "badaccess-group0": "Nemáte oprávnění k provedení požadované činnosti.",
        "badaccess-groups": "Požadovanou činnost smějí provádět jen uživatelé ve {{PLURAL:$2|skupině|skupinách}} $1.",
        "versionrequired": "Vyžadována MediaWiki verze $1",
-       "versionrequiredtext": "Pro použití této stránky je vyžadováno MediaWiki verze $1. Vizte [[Special:Version|stránku verze]].",
+       "versionrequiredtext": "Pro použití této stránky je vyžadováno MediaWiki verze $1. Viz [[Special:Version|stránku verze]].",
        "ok": "OK",
        "pagetitle": "$1 – {{SITENAME}}",
        "retrievedfrom": "Citováno z „$1“",
        "badretype": "Vámi napsaná hesla nesouhlasí.",
        "usernameinprogress": "Vytváření účtu tohoto uživatele již probíhá. Čekejte prosím.",
        "userexists": "Zadané uživatelské jméno se již používá.\nZvolte si prosím jiné jméno.",
+       "createacct-normalization": "Vaše uživatelské jméno bude z technických důvodů upraveno na „$2“.",
        "loginerror": "Chyba při přihlašování",
        "createacct-error": "Chyba při zakládání účtu",
        "createaccounterror": "Nepodařilo se vytvořit uživatelský účet: $1",
        "page_first": "první",
        "page_last": "poslední",
        "histlegend": "(teď) = rozdíly oproti nynější verzi, (předchozí) = rozdíly oproti předchozí verzi, <b>m</b> = malá editace",
-       "history-fieldset-title": "Hledat revize",
+       "history-fieldset-title": "Filtrovat revize",
        "history-show-deleted": "Pouze smazané",
        "histfirst": "nejstarší",
        "histlast": "nejnovější",
        "historysize": "({{PLURAL:$1|1 bajt|$1 bajty|$1 bajtů}})",
-       "historyempty": "(prázdné)",
+       "historyempty": "prázdné",
        "history-feed-title": "Historie editací",
        "history-feed-description": "Historie editací této stránky",
        "history-feed-item-nocomment": "$1 v $2",
        "revdelete-edit-reasonlist": "Editovat důvody smazání",
        "revdelete-offender": "Autor revize:",
        "suppressionlog": "Kniha utajení",
-       "suppressionlogtext": "Toto je seznam mazání a blokování zahrnující skrytí obsahu i před správci.\nVizte též [[Special:BlockList|seznam všech probíhajících bloků]].",
+       "suppressionlogtext": "Toto je seznam mazání a blokování zahrnující skrytí obsahu i před správci.\nViz též [[Special:BlockList|seznam všech probíhajících bloků]].",
        "mergehistory": "Slučování historií stránek",
        "mergehistory-header": "Tato stránka Vám umožní sloučit historii verzí jedné zdrojové stránky s novější stránkou.\nUjistěte se, že tato změna udrží souvislost a posloupnost verzí v historii.",
        "mergehistory-box": "Sloučení verzí dvou stránek:",
        "right-reupload-own": "Přepisování souborů nahraných sebou samotným",
        "right-reupload-shared": "Nahrávání lokálních souborů k potlačení těch ve sdíleném úložišti",
        "right-upload_by_url": "Nahrávání souborů z URL adres",
-       "right-purge": "Vyčištění vyrovnávací paměti stránky bez potvrzovacího dialogu",
+       "right-purge": "Vyčištění vyrovnávací paměti stránky",
        "right-autoconfirmed": "Imunita vůči rychlostním limitům založeným na IP adrese",
        "right-bot": "Být považován za automatický proces",
        "right-nominornewtalk": "Nevypisování oznámení o nové zprávě po malých úpravách diskusní stránky",
        "right-viewmyprivateinfo": "Prohlížení vlastních soukromých údajů (např. e-mailová adresa, skutečné jméno)",
        "right-editmyprivateinfo": "Změna vašich soukromých údajů (např. e-mailová adresa, skutečné jméno)",
        "right-editmyoptions": "Změna vašich uživatelských nastavení",
-       "right-rollback": "Rychlý revert Ãºprav posledního uživatele editujícího danou stránku",
+       "right-rollback": "Rychlé vracení zpÄ\9bt editací posledního uživatele editujícího danou stránku",
        "right-markbotedits": "Označování revertů jako editace bota",
        "right-noratelimit": "Imunita vůči rychlostním limitům",
        "right-import": "Import stránek z jiných wiki",
        "recentchanges-label-unpatrolled": "Tato změna dosud nebyla prověřena",
        "recentchanges-label-plusminus": "Velikost stránky se změnila o tolik bajtů",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vizte též [[Special:NewPages|seznam nových stránek]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (viz též [[Special:NewPages|seznam nových stránek]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Zobrazit",
        "rcfilters-tag-remove": "Odebrat '$1'",
        "lockmanager-fail-closelock": "Soubor se zámkem pro „$1“ nelze zavřít.",
        "lockmanager-fail-deletelock": "Soubor se zámkem pro „$1“ nelze smazat.",
        "lockmanager-fail-acquirelock": "Zámek pro „$1“ nelze získat.",
-       "lockmanager-fail-openlock": "Soubor zámku „$1“ nelze otevřít. Ujistěte se, že váš adresář nahraných souborů je správně nakonfigurován a že váš webový server má povolení k zápisu do tohoto adresáře. Pro další informace vizte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
+       "lockmanager-fail-openlock": "Soubor zámku „$1“ nelze otevřít. Ujistěte se, že váš adresář nahraných souborů je správně nakonfigurován a že váš webový server má povolení k zápisu do tohoto adresáře. Pro další informace viz https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
        "lockmanager-fail-releaselock": "Zámek pro „$1“ nelze uvolnit.",
        "lockmanager-fail-db-bucket": "Nelze navázat spojení s dostatečným počtem databází zámků v bloku $1.",
        "lockmanager-fail-db-release": "Uzamčení databáze $1 nelze uvolnit.",
        "uploadstash-zero-length": "Soubor má nulovou délku.",
        "invalid-chunk-offset": "Neplatný posun bloku",
        "img-auth-accessdenied": "Přístup odepřen",
-       "img-auth-nopathinfo": "Chybí informace o cestě.\nVáš server musí být nastaven tak, aby předával proměnné REQUEST_URI nebo PATH_INFO.\nPokud je, zkuste zapnout $wgUsePathInfo.\nVizte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Chybí informace o cestě.\nVáš server musí být nastaven tak, aby předával proměnné REQUEST_URI nebo PATH_INFO.\nPokud je, zkuste zapnout $wgUsePathInfo.\nViz https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Požadovaná cesta nespadá pod nakonfigurovaný adresář s načtenými soubory.",
        "img-auth-badtitle": "Z „$1“ nelze vytvořit platný název stránky.",
        "img-auth-nologinnWL": "Nejste přihlášen(a) a „$1“ není na bílé listině.",
        "brokenredirectstext": "Tato přesměrování vedou na neexistující stránky:",
        "brokenredirects-edit": "editovat",
        "brokenredirects-delete": "smazat",
-       "withoutinterwiki": "Stránky bez mezijazykových odkazů (interwiki)",
+       "withoutinterwiki": "Stránky bez mezijazykových odkazů",
        "withoutinterwiki-summary": "Tyto stránky neobsahují žádný mezijazykový odkaz:",
        "withoutinterwiki-legend": "Prefix",
        "withoutinterwiki-submit": "Zobrazit",
        "unusedimages": "Nepoužívané soubory",
        "wantedcategories": "Chybějící kategorie",
        "wantedpages": "Chybějící stránky",
-       "wantedpages-summary": "Seznam neexistujících stránek, na které vede nejvíce odkazů, kromě stránek, na které odkazují jen přesměrování. Pro seznam neexistujících stránek, na které odkazují přesměrování, vizte [[{{#special:BrokenRedirects}}|seznam přerušených přesměrování]].",
+       "wantedpages-summary": "Seznam neexistujících stránek, na které vede nejvíce odkazů, kromě stránek, na které odkazují jen přesměrování. Pro seznam neexistujících stránek, na které odkazují přesměrování, viz [[{{#special:BrokenRedirects}}|seznam přerušených přesměrování]].",
        "wantedpages-badtitle": "Výsledky obsahují neplatný název: $1",
        "wantedfiles": "Chybějící soubory",
        "wantedfiletext-cat": "Následující soubory se používají, ale neexistují. Soubory ze vzdálených úložišť zde mohou být uvedeny, přestože existují. Taková falešná pozitiva budou zobrazena <del>přeškrtnutě</del>. Stránky, které vkládají neexistující soubory, jsou navíc uvedeny v [[:$1]].",
        "index-category-desc": "Stránka obsahuje kouzelné slovo <code><nowiki>__INDEX__</nowiki></code> (a je ve jmenném prostoru, ve kterém je tento příznak dovolen), takže je indexována roboty, přestože by normálně nebyla.",
        "post-expand-template-inclusion-category-desc": "Stránka je po rozbalení všech šablon větší než <code>$wgMaxArticleSize</code>, takže některé šablony rozbaleny nebyly.",
        "post-expand-template-argument-category-desc": "Stránka je po rozbalení argumentu šablony (něco v trojitých závorkách, např. <code>{{{Foo}}}</code>) větší než <code>$wgMaxArticleSize</code>.",
-       "expensive-parserfunction-category-desc": "Stránka používá příliš mnoho náročných funkcí syntaktického analyzátoru (jako <code>#ifexist</code>). Vizte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
+       "expensive-parserfunction-category-desc": "Stránka používá příliš mnoho náročných funkcí syntaktického analyzátoru (jako <code>#ifexist</code>). Viz [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
        "broken-file-category-desc": "Stránka obsahuje nefunkční odkaz na soubor (odkaz pro vložení souboru, který neexistuje).",
        "hidden-category-category-desc": "Kategorie ve svém textu obsahuje <code><nowiki>__HIDDENCAT__</nowiki></code>, což způsobuje, že se na stránkách implicitně nezobrazuje v rámečku odkazů na kategorie.",
        "trackingcategories-nodesc": "Popis není k dispozici.",
        "enotif_subject_moved": "$2 {{gender:$2|přesunul|přesunula}} stránku $1 na {{grammar:6sg|{{SITENAME}}}}",
        "enotif_subject_restored": "$2 {{gender:$2|obnovil|obnovila}} stránku $1 na {{grammar:6sg|{{SITENAME}}}}",
        "enotif_subject_changed": "$2 {{gender:$2|změnil|změnila}} stránku $1 na {{grammar:6sg|{{SITENAME}}}}",
-       "enotif_body_intro_deleted": "$2 {{gender:$2|smazal|smazala}} $PAGEEDITDATE na {{grammar:6sg|{{SITENAME}}}} stránku $1, vizte $3.",
-       "enotif_body_intro_created": "V $PAGEEDITDATE {{gender:$2|založil|založila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, vizte aktuální verzi na $3 .",
-       "enotif_body_intro_moved": "V $PAGEEDITDATE {{gender:$2|přesunul|přesunula}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, vizte aktuální verzi na $3 .",
-       "enotif_body_intro_restored": "V $PAGEEDITDATE {{gender:$2|obnovil|obnovila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, vizte aktuální verzi na $3 .",
-       "enotif_body_intro_changed": "V $PAGEEDITDATE {{gender:$2|změnil|změnila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, vizte aktuální verzi na $3 .",
-       "enotif_lastvisited": "Pro všechny změny od vaší minulé návštěvy vizte $1",
+       "enotif_body_intro_deleted": "$2 {{gender:$2|smazal|smazala}} $PAGEEDITDATE na {{grammar:6sg|{{SITENAME}}}} stránku $1, viz $3.",
+       "enotif_body_intro_created": "V $PAGEEDITDATE {{gender:$2|založil|založila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, viz aktuální verzi na $3 .",
+       "enotif_body_intro_moved": "V $PAGEEDITDATE {{gender:$2|přesunul|přesunula}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, viz aktuální verzi na $3 .",
+       "enotif_body_intro_restored": "V $PAGEEDITDATE {{gender:$2|obnovil|obnovila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, viz aktuální verzi na $3.",
+       "enotif_body_intro_changed": "V $PAGEEDITDATE {{gender:$2|změnil|změnila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, viz aktuální verzi na $3 .",
+       "enotif_lastvisited": "Pro všechny změny od vaší minulé návštěvy viz $1",
        "enotif_lastdiff": "Tuto změnu si můžete prohlédnout na $1",
        "enotif_anon_editor": "anonymní uživatel $1",
        "enotif_body": "Vážený uživateli $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nShrnutí editace: $PAGESUMMARY $PAGEMINOREDIT\n\nUživatele, který změnu provedl, můžete kontaktovat:\ne-mailem: $PAGEEDITOR_EMAIL\nna wiki: $PAGEEDITOR_WIKI\n\nDo doby, než stránku navštívíte jako přihlášený uživatel, vám další oznámení k této stránce nebudou zasílána. Případně si můžete vynulovat příznaky ve svém seznamu sledovaných stránek.\n\nS pozdravem váš zasílač hlášení {{grammar:2sg|{{SITENAME}}}}\n\n--\nZměnit nastavení e-mailových oznámení můžete na\n{{canonicalurl:{{#special:Preferences}}}}\n\nNastavení sledovaných stránek může změnit na\n{{canonicalurl:Special:Watchlist/edit}}\n\nStránku můžete ze svých sledovaných vyřadit na\n$UNWATCHURL\n\nRady a kontakt:\n$HELPPAGE",
        "delete-confirm": "Smazání stránky „$1“",
        "delete-legend": "Smazat",
        "historywarning": "<strong>Varování:</strong> Stránka, kterou se chystáte smazat, má historii s $1 {{PLURAL:$1|revizí|revizemi}}:",
-       "historyaction-submit": "Zobrazit",
+       "historyaction-submit": "Zobrazit revize",
        "confirmdeletetext": "Chystáte se smazat stránku s celou její historií. Prosím potvrďte, že to opravdu chcete učinit, že si uvědomujete důsledky a že je to v souladu s [[{{MediaWiki:Policy-url}}|pravidly]].",
        "actioncomplete": "Provedeno",
        "actionfailed": "Operace se nezdařila",
-       "deletedtext": "„$1“ bylo smazáno.\n$2 zaznamenává poslední smazání.",
+       "deletedtext": "Stránka „$1“ byla smazána.\n$2 zaznamenává poslední smazání.",
        "dellogpage": "Kniha smazaných stránek",
        "dellogpagetext": "Zde je seznam posledních smazaných stránek.",
        "deletionlog": "Kniha smazaných stránek",
        "deleting-backlinks-warning": "<strong>Upozornění:</strong> Stránka, kterou se chystáte smazat, je [[Special:WhatLinksHere/{{FULLPAGENAME}}|na jiných stránkách]] odkazována nebo je do nich vložena.",
        "deleting-subpages-warning": "<strong>Upozornění:</strong> Stránka, kterou se chystáte smazat, má [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|podstránku|$1 podstránky|$1 podstránek|51=více než 50 podstránek}}]].",
        "rollback": "Vrátit zpět editace",
+       "rollback-confirmation-confirm": "Potvrďte prosím:",
+       "rollback-confirmation-yes": "Vrátit zpět",
+       "rollback-confirmation-no": "Storno",
        "rollbacklink": "vrácení zpět",
        "rollbacklinkcount": "vrácení $1 {{PLURAL:$1|editace|editací}} zpět",
        "rollbacklinkcount-morethan": "vrácení více než $1 {{PLURAL:$1|editace|editací}} zpět",
        "revertpage": "Editace uživatele „[[Special:Contributions/$2|$2]]“ ([[User talk:$2|diskuse]]) vráceny do předchozího stavu, jehož autorem je „[[User:$1|$1]]“",
        "revertpage-nouser": "Editace skrytého uživatele vráceny do předchozího stavu, jehož {{GENDER:$1|autorem|autorkou}} je „[[User:$1|$1]]“",
        "rollback-success": "Editace {{GENDER:$3|uživatele|uživatelky}} $1 byly vráceny na poslední verzi od {{GENDER:$4|uživatele|uživatelky}} $2.",
-       "rollback-success-notify": "Editace uživatele $1 byly vráceny;\nobnovena poslední verze od uživatele $2. [$3 Zobrazit změny]",
        "sessionfailure-title": "Chyba relace",
        "sessionfailure": "Nastal problém s vaším přihlášením;\nvámi požadovaná činnost byla zrušena jako prevence před neoprávněným přístupem.\nStiskněte tlačítko „zpět“, obnovte stránku, ze které jste přišli, a zkuste činnost znovu.",
        "changecontentmodel": "Změnit model obsahu stránky",
        "undeletecomment": "Důvod:",
        "cannotundelete": "Některá nebo všechna obnovení se nezdařila:\n$1",
        "undeletedpage": "<strong>Stránka „$1“ byla obnovena</strong>\n\nZáznam o posledních mazáních a obnoveních najdete v [[Special:Log/delete|knize smazaných stránek]].",
-       "undelete-header": "Vizte nedávno smazané stránky v [[Special:Log/delete|knize smazaných stránek]].",
+       "undelete-header": "Viz nedávno smazané stránky v [[Special:Log/delete|knize smazaných stránek]].",
        "undelete-search-title": "Hledání smazaných stránek",
        "undelete-search-box": "Hledání smazaných stránek",
        "undelete-search-prefix": "Zobrazit stránky začínající na:",
        "tooltip-namespace_association": "Zaškrtnutím tohoto políčka zahrnete i diskusní či obsahový jmenný prostor příslušný k vybranému jmennému prostoru",
        "blanknamespace": "(Hlavní)",
        "contributions": "Příspěvky {{GENDER:$1|uživatele|uživatelky}}",
-       "contributions-title": "Příspěvky {{GENDER:$1|uživatele|uživatelky|uživatele/uživatelky}} $1",
+       "contributions-title": "Příspěvky {{GENDER:$1|uživatele|uživatelky|uživatele}} $1",
        "mycontris": "Příspěvky",
        "anoncontribs": "Příspěvky",
        "contribsub2": "{{GENDER:$3|uživatele|uživatelky}} $1 ($2)",
+       "contributions-subtitle": "{{GENDER:$3|uživatele|uživatelky}} $1",
        "contributions-userdoesnotexist": "Uživatelský účet „$1“ není zaregistrován.",
        "negative-namespace-not-supported": "Jmenné prostory se zápornými hodnotami nejsou podporovány.",
        "nocontribs": "Nenalezeny žádné změny vyhovující kritériím.",
        "ipb-confirm": "Potvrdit zablokování",
        "ipb-sitewide": "Na celém projektu",
        "ipb-partial": "Částečný",
+       "ipb-sitewide-help": "Všechny stránky na wiki a všechny ostatní způsoby přispívání.",
+       "ipb-partial-help": "Konkrétní stránky nebo jmenné prostory.",
        "ipb-pages-label": "Stránky",
        "ipb-namespaces-label": "Jmenné prostory",
        "badipaddress": "Neplatná IP adresa",
        "blocklog-showsuppresslog": "{{GENDER:$1|Tento uživatel byl zablokován a skryt|Tato uživatelka byla zablokována a skryta}}. Zde je pro přehled zobrazen výpis záznamu utajení:",
        "blocklogentry": "blokuje „[[$1]]“ s časem vypršení $2 $3",
        "reblock-logentry": "mění nastavení bloku „[[$1]]“ s časem vypršení $2 $3",
-       "blocklogtext": "Toto je kniha úkonů blokování a odblokování uživatelů.\nAutomaticky blokované IP adresy nejsou vypsány.\nVizte též [[Special:BlockList|seznam všech probíhajících bloků]].",
+       "blocklogtext": "Toto je kniha úkonů blokování a odblokování uživatelů.\nAutomaticky blokované IP adresy nejsou vypsány.\nViz též [[Special:BlockList|seznam všech probíhajících bloků]].",
        "unblocklogentry": "odblokovává „$1“",
        "block-log-flags-anononly": "pouze anonymní uživatelé",
        "block-log-flags-nocreate": "vytváření účtů zablokováno",
        "ipb_expiry_old": "Čas vypršení je v minulosti.",
        "ipb_expiry_temp": "Blokování skrytých uživatelských jmen by měla být trvalá.",
        "ipb_hide_invalid": "Tento účet nelze utajit; má více než $1 {{PLURAL:$1|editaci|editace|editací}}.",
+       "ipb_hide_partial": "Zablokování se skrytím uživatelského jména musí platit na celém projektu.",
        "ipb_already_blocked": "„$1“ již je zablokován.",
        "ipb-needreblock": "$1 je již {{GENDER:$1|zablokován|zablokována|zablokován(a)}}. Chcete změnit nastavení bloku?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Jiné zablokování|Jiná zablokování}}",
        "import-logentry-interwiki-detail": "{{PLURAL:$1|naimportována $1 revize|naimportovány $1 revize|naimportováno $1 revizí}} z $2",
        "javascripttest": "Testování JavaScriptu",
        "javascripttest-pagetext-unknownaction": "Neznámá akce „$1“.",
-       "javascripttest-qunit-intro": "Vizte [$1 dokumentaci testování] na mediawiki.org",
+       "javascripttest-qunit-intro": "Viz [$1 dokumentaci testování] na mediawiki.org",
        "tooltip-pt-userpage": "{{GENDER:|Vaše uživatelská}} stránka",
        "tooltip-pt-anonuserpage": "Uživatelská stránka pro IP adresu, ze které editujete",
        "tooltip-pt-mytalk": "{{GENDER:|Vaše}} diskusní stránka",
        "spamprotectiontext": "Stránka, kterou jste se {{GENDER:|pokusil|pokusila|pokusil(a)}} uložit, byla zablokována protispamovým filtrem. Pravděpodobnou příčinou je odkaz na externí stránku, která je na černé listině.",
        "spamprotectionmatch": "Následující text spustil náš filtr proti spamu: $1",
        "spambot_username": "Systémový čistič spamu",
-       "spam_reverting": "Revert na poslední verzi neobsahující odkazy na $1",
+       "spam_reverting": "Vrácení zpět na poslední verzi neobsahující odkazy na $1",
        "spam_blanking": "Všechny verze obsahovaly odkazy na $1, vyprázdněno",
        "spam_deleting": "Všechny verze obsahovaly odkazy na $1, smazáno",
        "simpleantispam-label": "Antispamová kontrola.\n<strong>NEVYPLŇUJTE</strong> následující!",
        "confirm-unwatch-top": "Vyjmout tuto stránku ze sledovaných?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Vrátit editace této stránky?",
+       "confirm-rollback-bottom": "Tato akce okamžitě zruší vybrané změny této stránky.",
        "confirm-mcrrestore-title": "Obnovit revizi",
        "confirm-mcrundo-title": "Vrátit zpět změnu",
        "mcrundofailed": "Vrácení editace zpět se nezdařilo",
        "tag-mw-blank-description": "Editace, které vyprázdní stránku",
        "tag-mw-replace": "Nahrazeno",
        "tag-mw-replace-description": "Editace, které odstraňují více než 90 % obsahu stránky",
-       "tag-mw-rollback": "Rychlý revert",
+       "tag-mw-rollback": "Rychlé vrácení zpÄ\9bt",
        "tag-mw-rollback-description": "Editace, jimiž byly předchozí editace vráceny zpět pomocí rychlého revertu",
        "tag-mw-undo": "Vrácení zpět",
        "tag-mw-undo-description": "Editace, jimiž se ruší předchozí editace pomocí odkazu „zrušit editaci“",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|byl automaticky povýšen|byla automaticky povýšena}} z $4 na $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|načetl|načetla}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|načetl|načetla}} novou verzi $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|načetl|načetla}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|vrátil|vrátila}} $3 na starou verzi",
        "log-name-managetags": "Kniha správy značek",
        "log-description-managetags": "Tato stránka obsahuje seznam správcovských úkonů týkajících se [[Special:Tags|značek]]. Protokol obsahuje pouze akce, které provedl ručně správce; značky může vytvářet či mazat přímo software wiki, aniž by v tomto protokolu vznikl záznam.",
        "logentry-managetags-create": "$1 {{GENDER:$2|vytvořil|vytvořila}} značku „$4“",
        "log-action-filter-suppress-reblock": "Utajení uživatele novým zablokováním",
        "log-action-filter-upload-upload": "Nové načtení",
        "log-action-filter-upload-overwrite": "Znovunačtení",
+       "log-action-filter-upload-revert": "Vrácení zpět",
        "authmanager-authn-not-in-progress": "Autentizace neprobíhá nebo se ztratila data relace. Začněte, prosíme, znovu od začátku.",
        "authmanager-authn-no-primary": "Uvedené přihlašovací údaje se nepodařilo autentizovat.",
        "authmanager-authn-no-local-user": "Uvedené přihlašovací údaje neodpovídají žádnému uživateli této wiki.",
        "authmanager-create-no-primary": "Uvedené přihlašovací údaje nelze použít pro založení účtu.",
        "authmanager-link-no-primary": "Uvedené přihlašovací údaje nelze použít pro propojení účtů.",
        "authmanager-link-not-in-progress": "Propojování účtů neprobíhá nebo se ztratila data relace. Začněte, prosíme, znovu od začátku.",
-       "authmanager-authplugin-setpass-failed-title": "Změna hesla se nezdařila",
-       "authmanager-authplugin-setpass-failed-message": "Autentizační modul změnu hesla zamítl.",
-       "authmanager-authplugin-create-fail": "Autentizační modul založení účtu zamítl.",
-       "authmanager-authplugin-setpass-denied": "Autentizační modul neumožňuje měnit hesla.",
-       "authmanager-authplugin-setpass-bad-domain": "Neplatná doména.",
        "authmanager-autocreate-noperm": "Automatické zakládání účtů není povoleno.",
        "authmanager-autocreate-exception": "Automatické založení účtu je dočasně zakázáno kvůli předchozím chybám.",
        "authmanager-userdoesnotexist": "Uživatelský účet „$1“ není zaregistrován.",
        "edit-error-long": "Chyby:\n\n$1",
        "revid": "revize $1",
        "pageid": "Stránka s ID $1",
-       "interfaceadmin-info": "$1\n\nOprávnění editovat celoprojektové soubory s CSS/JS/JSON bylo nedávno odděleno z oprávnění <code>editinterface</code>. Pokud nerozumíte, proč se vám zobrazuje tato chyba, vizte [[mw:MediaWiki_1.32/interface-admin]].",
+       "interfaceadmin-info": "$1\n\nOprávnění editovat celoprojektové soubory s CSS/JS/JSON bylo nedávno odděleno z oprávnění <code>editinterface</code>. Pokud nerozumíte, proč se vám zobrazuje tato chyba, viz [[mw:MediaWiki_1.32/interface-admin]].",
        "rawhtml-notallowed": "Značky &lt;html&gt; nelze používat mimo běžné stránky.",
        "gotointerwiki": "Opustit {{GRAMMAR:4sg|{{SITENAME}}}}",
        "gotointerwiki-invalid": "Zadaný název je neplatný.",
        "passwordpolicies-policy-maximalpasswordlength": "Heslo musí být kratší než {{PLURAL:$1|$1 znak|$1 znaky|$1 znaků}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Heslo nesmí být {{PLURAL:$1|dané oblíbené heslo|v seznamu $1 oblíbených hesel}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Heslo nesmí být v seznamu 100 000 nejčastěji používaných hesel.",
+       "passwordpolicies-policyflag-forcechange": "nutné změnit při přihlášení",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "navrhnout změnu při přihlášení",
        "easydeflate-invaliddeflate": "Poskytnutý obsah nebyl správně zkomprimován",
        "unprotected-js": "Z bezpečnostních důvodů nelze načítat JavaScript z nechráněných stran. Vyrábějte prosím JavaScriptové skripty jen ve jmenném prostoru MediaWiki: nebo jako uživatelskou podstránku"
 }
index f4a37ae..d8b61ac 100644 (file)
        "alreadyrolled": "Ni mòże copnąc slédny edicëji starnë [[:$1]], chtërny ùsôdzcą je [[User:$2|$2]] ([[User talk:$2|Diskùsëjô]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nchtos jiny ju zeditowôł starnã abò copnął zmianë.\n\nSlédnym ùsódzcą starnë bëł [[User:$3|$3]] ([[User talk:$3|Diskùsëjô]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "revertpage": "Edicje brëkòwnika [[Special:Contributions/$2|$2]] ([[User talk:$2|diskùsjô]]) òstałë òdrzucóné. Aùtorã przëwrócóny wersji je [[User:$1|$1]].",
        "rollback-success": "Copniãto edicje {{GENDER:$3|brëkòwnika|brëkòwniczczi}} $1;\ndoprowadzóno nazôd slédną wersëjã ùsôdzcë {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Edicje brëkòwnika $1 òstałë òdrzucóné; \nòsta przëwrócónô òstatnô wersjô, aùtorã chtërny je $2. [$3 Pòkażë zjinaczi]",
        "protectlogpage": "Zazychrowóné",
        "protectedarticle": "zazychrowónô [[$1]]",
        "modifiedarticleprotection": "zmienionô léga zazychrowaniô [[$1]]",
index 0aac350..316b093 100644 (file)
        "accmailtext": "Anfonwyd cyfrinair a grewyd ar hap ar gyfer [[User talk:$1|$1]] at $2. Gellir newid y cyfrinair hwn ar y dudalen ''[[Special:ChangePassword|newid cyfrinair]]'', wrth fewngofnodi.",
        "newarticle": "(Newydd)",
        "newarticletext": "Rydych chi wedi dilyn cysylltiad i dudalen sydd heb gael ei chreu eto.\nI greu'r dudalen, dechreuwch deipio yn y blwch isod (gweler y [$1 dudalen gymorth] am fwy o wybodaeth).\nOs daethoch yma ar ddamwain, cliciwch botwm '''n&ocirc;l''' y porwr.",
-       "anontalkpagetext": "----''Dyma dudalen sgwrs ar gyfer defnyddiwr anhysbys sydd heb greu cyfrif eto, neu nad yw'n ei ddefnyddio. Felly mae'n rhaid inni ddefnyddio'r cyfeiriad IP i'w (h)adnabod. Mae cyfeiriadau IP yn gallu cael eu rhannu rhwng nifer o ddefnyddwyr. Os ydych chi'n ddefnyddiwr anhysbys ac yn teimlo'ch bod wedi derbyn sylwadau amherthnasol, [[Special:CreateAccount|crëwch gyfrif]] neu [[Special:UserLogin|mewngofnodwch]] i osgoi cael eich drysu gyda defnyddwyr anhysbys eraill o hyn ymlaen.''",
+       "anontalkpagetext": "<em>Dyma dudalen sgwrs ar gyfer defnyddiwr anhysbys sydd heb greu cyfrif eto, neu nad yw'n ei ddefnyddio.</em>\nFelly mae'n rhaid inni ddefnyddio'r cyfeiriad IP i'w adnabod.\nMae cyfeiriadau IP yn gallu cael eu rhannu rhwng nifer o ddefnyddwyr.\nOs ydych chi'n ddefnyddiwr anhysbys ac yn teimlo'ch bod wedi derbyn sylwadau amherthnasol, [[Special:CreateAccount|crëwch gyfrif]] neu [[Special:UserLogin|mewngofnodwch]] i osgoi cael eich drysu gyda defnyddwyr anhysbys eraill o hyn ymlaen.",
        "noarticletext": "Mae'r dudalen hon yn wag ar hyn o bryd.\nGallwch [[Special:Search/{{PAGENAME}}|chwilio am y teitl hwn]] ar ddalennau eraill, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} chwilio drwy'r logiau perthnasol], neu [{{fullurl:{{FULLPAGENAME}}|action=edit}} fe allwch greu'r ddalen hon]</span>.",
        "noarticletext-nopermission": "Mae'r dudalen hon yn wag ar hyn o bryd.\nGallwch [[Special:Search/{{PAGENAME}}|chwilio am y teitl hwn]] ar dudalennau eraill, neu gallwch <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} chwilio drwy'r logiau perthnasol]</span>, ond nid yw'r gallu gennych i ddechrau'r dudalen o'r dechrau cyntaf.",
        "missing-revision": "Nid yw'r diwygiad #$1 o'r dudalen \"{{FULLPAGENAME}}\" ar gael.\n\nFel arfer, fe ddigwydd hyn wrth ddilyn hen gyswllt i dudalen sydd wedi ei dileu.\nGallwch weld y manylion yn y [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} lòg dileu].",
        "histfirst": "cynharaf",
        "histlast": "diweddaraf",
        "historysize": "({{PLURAL:$1|$1 beit|$1 beit|$1 feit|$1 beit|$1 beit|$1 beit}})",
-       "historyempty": "(gwag)",
+       "historyempty": "gwag",
        "history-feed-title": "Hanes diwygio",
        "history-feed-description": "Hanes diwygio'r dudalen hon ar y wici",
        "history-feed-item-nocomment": "$1 am $2",
        "rcfilters-other-review-tools": "Teclynau adolygu eraill",
        "rcfilters-group-results-by-page": "Canlyniadau'r grwp bob yn ddalen",
        "rcfilters-activefilters": "Hidlau sydd ar waith",
+       "rcfilters-activefilters-hide": "Cuddio",
        "rcfilters-advancedfilters": "Ffiltrau ychwanegol",
        "rcfilters-limit-title": "Canlyniadau a ddangosir",
        "rcfilters-date-popup-title": "Cyfnod (i'w chwilio)",
        "rcfilters-filter-watchlist-watchednew-label": "Newidiadau newydd i'ch Rhestr Wylio",
        "rcfilters-filter-watchlist-notwatched-label": "Heb fod yn eich Rhestr Wylio",
        "rcfilters-filter-watchlist-notwatched-description": "Popeth ar wahan i'r newidiadau i'ch Rhestr Wylio.",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Newidiadau heb eu gweld gennych",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Newidiadau i'r tudalennau nad ydych wedi ymweld â nhw.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Newidiadau wedi eu gweld gennych",
+       "rcfilters-filter-watchlistactivity-seen-description": "Newidiadau i dudalennau rydych wedi ymweld â nhw ers iddynt gael eu newid.",
        "rcfilters-filtergroup-changetype": "Math o newid",
        "rcfilters-filter-pageedits-label": "Golygiadau i'r ddalen",
        "rcfilters-filter-pageedits-description": "Golygiadau i gynnwys wici, y sgyrsiau, categoriau...",
        "rcfilters-liveupdates-button": "Diweddariadau, byw (''Live updates'')",
        "rcfilters-liveupdates-button-title-on": "Diffod y 'Diweddariadau, byw'",
        "rcfilters-liveupdates-button-title-off": "Arddangos newidiadau wrth iddynt ddigwydd",
+       "rcfilters-watchlist-markseen-button": "Marcio'r newidiadau fel rhai a welwyd",
        "rcfilters-watchlist-edit-watchlist-button": "Golygwch eich Rhestr Wylio",
+       "rcfilters-watchlist-showupdated": "Mae tudalennau sydd wedi eu newid ers i chi ymweld â nhw ddiwethaf wedi'u <strong>hamlygu</strong>.",
        "rcfilters-preference-label": "Cuddio'r fersiwn ddiweddaraf o Newidiadau Diweddaraf",
        "rcnotefrom": "Isod rhestrir pob newid er <strong>$3, $4</strong> (ymddengys <strong>$1</strong> ohonynt).",
        "rclistfromreset": "Ailosod dyddiad yr hyn rydych wedi'i ddewis",
        "rclistfrom": "Dangos newidiadau newydd, gan ddechrau ers $3 $2",
        "rcshowhideminor": "$1 golygiadau bychain",
        "rcshowhideminor-show": "Dangoser",
-       "rcshowhideminor-hide": "Cuddier",
+       "rcshowhideminor-hide": "Cuddio",
        "rcshowhidebots": "$1 botiau",
        "rcshowhidebots-show": "Dangoser",
-       "rcshowhidebots-hide": "Cuddier",
+       "rcshowhidebots-hide": "Cuddio",
        "rcshowhideliu": "$1 o ddefnyddwyr cofrestredig",
        "rcshowhideliu-show": "Dangoser",
-       "rcshowhideliu-hide": "Cuddier",
+       "rcshowhideliu-hide": "Cuddio",
        "rcshowhideanons": "$1 defnyddwyr anhysbys",
        "rcshowhideanons-show": "Dangoser",
-       "rcshowhideanons-hide": "Cuddier",
+       "rcshowhideanons-hide": "Cuddio",
        "rcshowhidepatr": "$1 golygiadau wedi derbyn ymweliad patrôl",
        "rcshowhidepatr-show": "Dangoser",
-       "rcshowhidepatr-hide": "Cuddier",
+       "rcshowhidepatr-hide": "Cuddio",
        "rcshowhidemine": "$1 fy ngolygiadau",
        "rcshowhidemine-show": "Dangoser",
-       "rcshowhidemine-hide": "Cuddier",
+       "rcshowhidemine-hide": "Cuddio",
        "rcshowhidecategorization": "Categoreiddio tudalen $1",
        "rcshowhidecategorization-show": "Dangos",
        "rcshowhidecategorization-hide": "Cuddio",
        "rclinks": "Dangos y $1 newid diweddaraf yn y $2 diwrnod diwethaf",
        "diff": "gwahan",
        "hist": "hanes",
-       "hide": "Cuddier",
+       "hide": "Cuddio",
        "show": "Dangoser",
        "minoreditletter": "B",
        "newpageletter": "N",
        "recentchangeslinked-feed": "Newidiadau perthnasol",
        "recentchangeslinked-toolbox": "Newidiadau perthnasol",
        "recentchangeslinked-title": "Newidiadau cysylltiedig â \"$1\"",
-       "recentchangeslinked-summary": "Rhowch enw dalen i weld newidiadau ar ddalenau sy'n cyfeirio neu'n dolennu iddi. I weld aelodau o gategori, nodwch Categori:Enw'r categori. Bydd newidiadau i unrhyw ddalen sydd o fewn eich [[Special:Watchlist|Rhestr Wylio]] mewn ffont <strong>trwm</strong>.",
+       "recentchangeslinked-summary": "Rhowch enw dalen i weld newidiadau ar dudalennau sy'n cyfeirio neu'n dolennu iddi. I weld aelodau o gategori, nodwch {{ns:category}}:Enw'r categori. Bydd newidiadau i unrhyw dudalen sydd o fewn eich [[Special:Watchlist|Rhestr Wylio]] mewn ffont <strong>trwm</strong>.",
        "recentchangeslinked-page": "Tudalen:",
        "recentchangeslinked-to": "Dangos newidiadau i'r tudalennau â chyswllt arnynt sy'n arwain at y dudalen a enwir",
        "recentchanges-page-added-to-category": "Ychwanegwyd [[:$1]] at y categori",
        "filehist-filesize": "Maint y ffeil",
        "filehist-comment": "Sylw",
        "imagelinks": "Defnydd y ffeil",
-       "linkstoimage": "Mae'r {{PLURAL:$1|tudalen|dudalen|tudalennau|tudalennau|tudalennau|tudalennau}} isod yn cysylltu i'r ddelwedd hon:",
-       "linkstoimage-more": "Mae mwy na $1 {{PLURAL:$1|tudalen yn|dudalen yn|dudalen yn|o dudalennau'n|o dudalennau'n|o dudalennau'n}} cysylltu at y ffeil hon.\nMae'r rhestr ganlynol yn dangos y {{PLURAL:$1|$1 cysylltiad cyntaf}} at y ffeil hon yn unig. Mae [[Special:WhatLinksHere/$2|rhestr lawn]] ar gael.",
-       "nolinkstoimage": "Nid oes cyswllt ar unrhyw dudalen yn arwain at y ffeil hon.",
+       "linkstoimage": "Mae'r {{PLURAL:$1|tudalennau a ddefnyddir|$1 tudalennau a ddefnyddir}} isod yn cysylltu i'r ddelwedd hon:",
+       "linkstoimage-more": "Mae mwy na $1 {{PLURAL:$1|un tudalen yn|o dudalennau'n}} yn defnyddio'r ffeil hon.\nMae'r rhestr ganlynol yn dangos y {{PLURAL:$1|$1 tudalen cyntaf}} sy'n defnyddio'r ffeil hon yn unig.\nMae [[Special:WhatLinksHere/$2|rhestr lawn]] ar gael.",
+       "nolinkstoimage": "Nid oes tudalennau'n defnyddio'r ffeil hon.",
        "morelinkstoimage": "Gweld [[Special:WhatLinksHere/$1|rhagor o gysylltiadau]] at y ffeil hon.",
        "linkstoimage-redirect": "$1 (tudalen ffeil sy'n ailgyfeirio) $2",
        "duplicatesoffile": "Mae'r {{PLURAL:$1||ffeil|$1 ffeil|$1 ffeil|$1 ffeil|$1 ffeil}} canlynol yn union debyg i'r ffeil hon ([[Special:FileDuplicateSearch/$2|rhagor o fanylion]]):",
        "showhideselectedlogentries": "Dewis dangos neu guddio cofnodion lòg",
        "checkbox-all": "Y cyfan",
        "checkbox-none": "Dim",
+       "checkbox-invert": "Gwrthdroi",
        "allpages": "Pob tudalen",
        "nextpage": "Y bloc nesaf gan ddechrau gyda ($1)",
        "prevpage": "Y bloc cynt gan ddechrau gyda ($1)",
        "revertpage": "Wedi gwrthdroi golygiadau gan [[Special:Contributions/$2|$2]] ([[User talk:$2|Sgwrs]]); wedi adfer y golygiad diweddaraf gan [[User:$1|$1]]",
        "revertpage-nouser": "Wedi gwrthdroi golygiadau gan ddefnyddiwr cudd; wedi adfer y golygiad diweddaraf gan {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Gwrthdrowyd y golygiadau gan {{GENDER:$3|$1}};\nailosodwyd y golygiad olaf gan {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Gwrthdrowyd y golygiadau gan $1;\nailosodwyd y golygiad olaf gan $2. [$3 Dangoser y gwahaniaeth]",
        "sessionfailure-title": "Sesiwn wedi methu",
        "sessionfailure": "Mae'n debyg fod yna broblem gyda'ch sesiwn mewngofnodi; diddymwyd y weithred er mwyn diogelu'r sustem rhag ddefnyddwyr maleisus. Gwasgwch botwm 'nôl' eich porwr ac ail-lwythwch y dudalen honno, yna ceisiwch eto.",
        "changecontentmodel-title-label": "Teitl y ddalen",
index 2660f72..5a1c423 100644 (file)
@@ -72,7 +72,8 @@
                        "Jorn Ari",
                        "Fnielsen",
                        "Weblars",
-                       "Kranix"
+                       "Kranix",
+                       "Psl85"
                ]
        },
        "tog-underline": "Understreg link:",
        "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 jeg er logget ind",
+       "tog-showrollbackconfirmation": "Bed om bekræftelse når der bliver klikket på et tilbagerulningslink",
        "underline-always": "Altid",
        "underline-never": "Aldrig",
        "underline-default": "Standard for browseren eller udseendet",
        "edithelp": "Hjælp til redigering",
        "helppage-top-gethelp": "Hjælp",
        "mainpage": "Forside",
-       "mainpage-description": "Hovedside",
+       "mainpage-description": "Forside",
        "policy-url": "Project:Politik",
        "portal": "Fællesskabs portal",
        "portal-url": "Project:Fællesskabs portal",
        "nstab-template": "Skabelon",
        "nstab-help": "Hjælpeside",
        "nstab-category": "Kategori",
-       "mainpage-nstab": "Fovedside",
+       "mainpage-nstab": "Forside",
        "nosuchaction": "Funktionen findes ikke",
        "nosuchactiontext": "Handlingen som er angivet i URL'en er ugyldig.\nDu har måske skrevet URL'en forkert eller fulgt et ukorrekt link.\nDet kan også skyldes en fejl i softwaren, som bruges af {{SITENAME}}.",
        "nosuchspecialpage": "En sådan specialside findes ikke",
        "cannotlogoutnow-title": "Kan ikke logge af på nuværende tidspunkt",
        "cannotlogoutnow-text": "Det er ikke muligt at logge af når du bruger $1.",
        "welcomeuser": "Velkommen, $1!",
-       "welcomecreation-msg": "Din konto er blevet oprettet.\nDu kan ændre dine {{SITENAME}} [[Special:Indstilling|indstillinger]] hvis du ønsker.",
+       "welcomecreation-msg": "Din konto er blevet oprettet.\nDu kan ændre dine {{SITENAME}} [[Special:Preferences|indstillinger]] hvis du ønsker.",
        "yourname": "Brugernavn:",
        "userlogin-yourname": "Brugernavn",
        "userlogin-yourname-ph": "Indtast dit brugernavn",
        "badretype": "De indtastede adgangskoder er ikke ens.",
        "usernameinprogress": "En oprettelse af konto for dette brugernavn er allerede i gang.\nVent venligst.",
        "userexists": "Det brugernavn, du har valgt, er allerede i brug.\nVælg venligst et andet brugernavn.",
+       "createacct-normalization": "Dit brugernavn vil blive ændret til «$2» på grund af tekniske begrænsninger.",
        "loginerror": "Logon mislykket",
        "createacct-error": "Fejl ved kontooprettelse",
        "createaccounterror": "Kunne ikke oprette brugerkonto: $1",
        "content-json-empty-array": "Tomt matrix",
        "deprecated-self-close-category": "Sider, der bruger ugyldige, selvlukkende HTML-tags",
        "deprecated-self-close-category-desc": "Siden bruger ugyldige selvlukkende HTML tags, som <code>&lt;b/></code> eller <code>&lt;span/></code>. De vil snart blive ændret i overensstemmelse med HTML5-specifikationen, så de ikke kan bruges i wikitext.",
+       "duplicate-args-warning": "<strong>Advarsel</strong>: [[:$1]] kaldes [[:$2]] med flere end en værdi for \"$3\"-parameteren. Bare den sidst angitte værdien vil bruges.",
        "duplicate-args-category": "Sider der bruger samme argument mere end en gang i en skabelon",
        "duplicate-args-category-desc": "Siden indeholder en skabelon hvor et argument er brugt mere end en gang, som <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> eller <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "Advarsel: Der er for mange beregningstunge oversætter-funktionskald på denne side.\n\nDer bør være færre end {{PLURAL:$2|$2 kald}}, lige nu er der {{PLURAL:$1|$1 kald}}.",
        "post-expand-template-argument-category": "Sider med udeladte skabelonparametre",
        "parser-template-loop-warning": "Skabelonløkke fundet: [[$1]]",
        "template-loop-category": "Sider med skabelonløkker",
+       "template-loop-category-desc": "Siden indeholder en malløkke, altså en skabelon som kalder sig selv rekursivt.",
        "parser-template-recursion-depth-warning": "En skabelon er rekursivt inkluderet for mange gange ($1)",
        "language-converter-depth-warning": "Dybdegrænse for sprogkonvertering overskredet ($1)",
        "node-count-exceeded-category": "Sider hvor antal noder er overskredet",
        "histfirst": "ældste",
        "histlast": "nyeste",
        "historysize": "($1 {{PLURAL:$1|Byte|Bytes}})",
-       "historyempty": "(tom)",
+       "historyempty": "tom",
        "history-feed-title": "Versionshistorie",
        "history-feed-description": "Versionshistorie for denne side i {{SITENAME}}",
        "history-feed-item-nocomment": "$1 med $2",
        "right-reupload-own": "Overskrive en eksisterende fil, som er lagt op af brugeren selv",
        "right-reupload-shared": "Lægge en lokal fil op, selvom den allerede findes centralt",
        "right-upload_by_url": "Lægge en fil op fra en URL",
-       "right-purge": "Nulstille sidens cache uden bekræftelse",
+       "right-purge": "Nulstil sidens cache for en side",
        "right-autoconfirmed": "Påvirkes ikke af IP-baserede hastighedsgrænser",
        "right-bot": "Redigeringer markeres som robot",
        "right-nominornewtalk": "Mindre ændringer på diskussionssider markerer ikke disse med nyt indhold",
        "rcfilters-liveupdates-button-title-off": "Vis nye ændringer når de sker",
        "rcfilters-watchlist-markseen-button": "Marker alle ændringer som set",
        "rcfilters-watchlist-edit-watchlist-button": "Rediger din liste med overvågede sider",
-       "rcfilters-watchlist-showupdated": "Ændringer til sider du ikke har besøgt siden ændringerne blev gjort vises med <strong>fed</strong>.",
+       "rcfilters-watchlist-showupdated": "Ændringer til sider du ikke har besøgt siden ændringerne blev gjort vises med <strong>fed</strong> skrift.",
        "rcfilters-preference-label": "Brug grænsefladesnittet uden JavaScript",
+       "rcfilters-preference-help": "Indlæser Seneste ændringer uden mulighed for søgning med filter eller for fremhævelse.",
        "rcfilters-watchlist-preference-label": "Brug grænsefladesnittet uden JavaScript",
        "rcfilters-watchlist-preference-help": "Indlæser overvågningslisten uden mulighed for søgning med filter eller fremhævelse.",
+       "rcfilters-filter-showlinkedfrom-label": "Vis ændringer på sider hvortil der linkes fra",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sider hvortil der linkes fra</strong> den valgte side",
        "rcfilters-filter-showlinkedto-label": "Vis ændringer på sider der linker til",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Sider som linker til</strong> den valgte side",
        "rcfilters-target-page-placeholder": "Indtast et sidenavn (eller en kategori)",
        "rcnotefrom": "Nedenfor er op til '''$1''' {{PLURAL:$5|ændring|ændringer}} siden '''$2''' vist.",
        "rclistfromreset": "Nulstil datovalg",
        "deleteprotected": "Du kan ikke slette denne side, fordi den er beskyttet.",
        "deleting-backlinks-warning": "<strong>Advarsel:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Andre sider]] henviser til eller inkluderer den side, du er ved at slette.",
        "rollback": "Fjern redigeringer",
+       "rollback-confirmation-confirm": "Bekræft venligst:",
+       "rollback-confirmation-yes": "Tilbagerul",
+       "rollback-confirmation-no": "Fortryd",
        "rollbacklink": "rul tilbage",
        "rollbacklinkcount": "rul {{PLURAL:$1|en redigering|$1 redigeringer}} tilbage",
        "rollbacklinkcount-morethan": "rul mere end {{PLURAL:$1|en redigering|$1 redigeringer}} tilbage",
        "ipb-change-block": "Forny brugerens blokering med disse indstillinger",
        "ipb-confirm": "Bekræft blokering",
        "ipb-partial": "Delvist",
+       "ipb-partial-help": "Specifikke sider eller navnerum.",
        "ipb-pages-label": "Sider",
        "ipb-namespaces-label": "Navnerum",
        "badipaddress": "IP-adressen/brugernavnet er udformet forkert eller eksistere ikke.",
        "confirmrecreate-noreason": "[[User:$1|$1]] ([[User talk:$1|diskussion]]) har {{GENDER:$1|slettet}} denne side, efter du begyndte at redigere. Bekræft venligst, at du gerne vil genoprette siden.",
        "recreate": "Genopret",
        "confirm-purge-title": "Fjern denne side",
-       "confirm_purge_button": "O.k.",
+       "confirm_purge_button": "OK",
        "confirm-purge-top": "Slet denne side fra serverens mellemlager (''cache'')?",
        "confirm-purge-bottom": "Rensning af en side sletter mellemlageret og fremtvinger den nyeste version.",
        "confirm-watch-button": "OK",
        "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2",
        "tag-mw-new-redirect": "Ny omdirigering",
        "tag-mw-removed-redirect": "Fjernede omdirigering",
-       "tag-mw-changed-redirect-target": "Omdigeringsmål ændret",
+       "tag-mw-changed-redirect-target": "Omdirigeringsmål ændret",
        "tag-mw-blank": "Sidetømning",
        "tag-mw-blank-description": "Redigeringer som tømmer en side",
        "tag-mw-replace": "Erstattet",
        "logentry-rights-autopromote": "$1 blev automatisk {{GENDER:$2|forfremmet}} fra $4 til $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|lagde}} $3 op",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|lagde}} en ny udgave af $3 op",
-       "logentry-upload-revert": "$1 {{GENDER:$2|lagde}} $3 op",
+       "logentry-upload-revert": "$1 {{GENDER:$2|gendannede}} $3 til en gammel version",
        "logentry-managetags-create": "$1 {{GENDER:$2|oprettede}} tagget \"$4\"",
        "rightsnone": "(-)",
        "rightslogentry-temporary-group": "$1 (midlertidig, indtil $2)",
        "log-action-filter-rights-rights": "Manuel ændring",
        "log-action-filter-rights-autopromote": "Automatisk ændring",
        "log-action-filter-upload-upload": "Ny overførsel",
+       "log-action-filter-upload-revert": "Gendan",
        "authmanager-create-disabled": "Kontooprettelse deaktiveret",
        "authmanager-create-from-login": "For at oprette din konto, så udfyld venligst felterne.",
-       "authmanager-authplugin-setpass-failed-title": "Ændring af adgangskode mislykkedes",
-       "authmanager-authplugin-setpass-bad-domain": "Ugyldig domæne.",
        "authmanager-autocreate-noperm": "Automatisk kontooprettelse er ikke tilladt.",
        "authmanager-userdoesnotexist": "Brugerkontoen \"$1\" er ikke registreret.",
        "authmanager-email-label": "E-post",
        "authpage-cannot-login": "Kunne ikke starte login.",
        "cannotauth-not-allowed-title": "Adgang nægtet",
        "cannotauth-not-allowed": "Du har ikke tilladelse til at bruge denne side",
+       "changecredentials": "Skift adgangskode",
+       "changecredentials-submit": "Skift adgangskode",
        "removecredentials": "Fjern akkreditiver",
        "removecredentials-submit": "Fjern akkreditiver",
        "removecredentials-invalidsubpage": "$1 er ikke en gyldig type for akkreditiver.",
index cdfe035..13c20ea 100644 (file)
@@ -95,7 +95,8 @@
                        "ToBeFree",
                        "PerfektesChaos",
                        "Kurt Jansson",
-                       "McDutchie"
+                       "McDutchie",
+                       "Johanna Strodt (WMDE)"
                ]
        },
        "tog-underline": "Links unterstreichen:",
        "tog-enotifminoredits": "Auch bei kleinen Änderungen an Seiten und Dateien E-Mails senden",
        "tog-enotifrevealaddr": "Meine E-Mail-Adresse in Benachrichtigungs-E-Mails anzeigen",
        "tog-shownumberswatching": "Anzahl der beobachtenden Benutzer anzeigen",
-       "tog-oldsig": "Die vorhandene Signatur:",
+       "tog-oldsig": "Die genutzte Signatur:",
        "tog-fancysig": "Signatur als Wikitext behandeln (ohne automatische Verlinkung)",
        "tog-uselivepreview": "Vorschau ohne Neuladen der Seite anzeigen",
        "tog-forceeditsummary": "Warnen, sofern beim Speichern die Zusammenfassung fehlt",
        "tog-norollbackdiff": "Unterschiede nach dem Zurücksetzen nicht anzeigen",
        "tog-useeditwarning": "Warnen, sofern eine zur Bearbeitung geöffnete Seite verlassen wird, die nicht gespeicherte Änderungen enthält",
        "tog-prefershttps": "Immer eine sichere Verbindung benutzen, solange ich angemeldet bin",
+       "tog-showrollbackconfirmation": "Bei Klick auf „kommentarlos zurücksetzen“ eine Sicherheitsabfrage anzeigen",
        "underline-always": "immer",
        "underline-never": "nie",
        "underline-default": "abhängig von der Benutzeroberfläche oder Browsereinstellung",
        "virus-badscanner": "Fehlerhafte Konfiguration: unbekannter Virenscanner: <em>$1</em>",
        "virus-scanfailed": "Scan fehlgeschlagen (Code $1)",
        "virus-unknownscanner": "Unbekannter Virenscanner:",
-       "logouttext": "<strong>Du bist nun abgemeldet.</strong>\n\nBeachte, dass einige Seiten noch anzeigen können, dass du angemeldet bist, solange du nicht deinen Browsercache geleert hast.",
+       "logouttext": "<strong>Du bist nun abgemeldet.</strong>\n\nBeachte, dass einige Seiten noch anzeigen können, dass du angemeldet wärst, solange du nicht deinen Browsercache leerst.",
        "cannotlogoutnow-title": "Abmeldung nicht erfolgreich",
        "cannotlogoutnow-text": "Eine Abmeldung ist mit Verwendung von $1 nicht möglich.",
        "welcomeuser": "Willkommen, $1!",
        "badretype": "Die beiden Passwörter stimmen nicht überein.",
        "usernameinprogress": "Eine Benutzerkontenerstellung für diesen Benutzernamen ist bereits in Bearbeitung.\nBitte warten.",
        "userexists": "Dieser Benutzername ist schon vergeben.\nBitte wähle einen anderen.",
+       "createacct-normalization": "Dein Benutzername wird aufgrund technischer Beschränkungen zu „$2“ geändert.",
        "loginerror": "Fehler bei der Anmeldung",
        "createacct-error": "Fehler beim Erstellen des Benutzerkontos",
        "createaccounterror": "Benutzerkonto konnte nicht erstellt werden: $1",
        "page_first": "Anfang",
        "page_last": "Ende",
        "histlegend": "Zur Anzeige der Änderungen einfach die zu vergleichenden Versionen auswählen und die Schaltfläche „{{int:compareselectedversions}}“ klicken.<br />\n* ({{int:cur}}) = Unterschied zur aktuellen Version, ({{int:last}}) = Unterschied zur vorherigen Version\n* Uhrzeit/Datum = Version zu dieser Zeit, Benutzername/IP-Adresse des Bearbeiters, {{int:minoreditletter}} = Kleine Änderung",
-       "history-fieldset-title": "Nach Versionen suchen",
+       "history-fieldset-title": "Versionen filtern",
        "history-show-deleted": "Nur gelöschte Versionen zeigen",
        "histfirst": "älteste",
        "histlast": "neueste",
        "historysize": "({{PLURAL:$1|1 Byte|$1 Bytes}})",
-       "historyempty": "(leer)",
+       "historyempty": "leer",
        "history-feed-title": "Versionsgeschichte",
        "history-feed-description": "Versionsgeschichte dieser Seite in {{SITENAME}}",
        "history-feed-item-nocomment": "$1 am $3 um $4 Uhr",
        "right-reupload-own": "Überschreiben einer zuvor selbst hochgeladenen Datei",
        "right-reupload-shared": "Lokales Überschreiben einer in einem gemeinsam genutzten Repositorium vorhandenen Datei",
        "right-upload_by_url": "Dateien von einer URL-Adresse hochladen",
-       "right-purge": "Seitencache leeren ohne Rückfrage",
+       "right-purge": "Seitencache leeren",
        "right-autoconfirmed": "Keine Beschränkung durch IP-basierte Limits",
        "right-bot": "Behandlung als automatischer Prozess",
        "right-nominornewtalk": "Kleine Bearbeitungen an Diskussionsseiten führen zu keiner „Neue Nachrichten“-Anzeige",
        "unusedimages": "Verwaiste Dateien",
        "wantedcategories": "Gewünschte Kategorien",
        "wantedpages": "Gewünschte Seiten",
-       "wantedpages-summary": "Liste nicht vorhandener Seiten mit den meisten Links auf diese Seiten, ausschließlich solche, die nur Weiterleitungen haben. Für eine Liste nicht vorhandener Seiten mit Weiterleitungen, siehe [[{{#special:BrokenRedirects}}|die Liste defekter Weiterleitungen]].",
+       "wantedpages-summary": "Liste der am häufigsten verlinkten, aber nicht vorhandenen Seiten. Hiervon ausgenommen sind Seiten, die ausschließlich als Ziele defekter Weiterleitungen dienen. Siehe dafür [[{{#special:BrokenRedirects}}|die Liste defekter Weiterleitungen]].",
        "wantedpages-badtitle": "Ungültiger Titel im Ergebnis: $1",
        "wantedfiles": "Gewünschte Dateien",
        "wantedfiletext-cat": "Die folgenden Dateien werden verwendet, sind jedoch nicht vorhanden. Vorhandene Dateien aus fremden Repositorien können dennoch hier aufgelistet sein und werden <del>durchgestrichen</del> dargestellt. Zusätzlich werden Seiten, die nicht vorhandene Dateien enthalten, in die [[:$1]] eingeordnet.",
        "delete-confirm": "Löschen von „$1“",
        "delete-legend": "Löschen",
        "historywarning": "<strong>Achtung:</strong> Die Seite, die du löschen möchtest, hat eine Versionsgeschichte mit {{PLURAL:$1|einer Version|$1 Versionen}}:",
-       "historyaction-submit": "Anzeigen",
+       "historyaction-submit": "Versionen anzeigen",
        "confirmdeletetext": "Du bist dabei, eine Seite mit allen zugehörigen älteren Versionen zu löschen. Bitte bestätige dazu, dass du dir der Konsequenzen bewusst bist, und dass du in Übereinstimmung mit den [[{{MediaWiki:Policy-url}}|Richtlinien]] handelst.",
        "actioncomplete": "Aktion beendet",
        "actionfailed": "Aktion fehlgeschlagen",
        "deleting-backlinks-warning": "<strong>Warnung:</strong> Es verweisen noch [[Special:WhatLinksHere/{{FULLPAGENAME}}|andere Seiten]] auf diese zu löschende Seite oder sie ist noch an anderer Stelle eingebunden.",
        "deleting-subpages-warning": "<strong>Warnung:</strong> Die Seite, die du löschen möchtest, hat [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|eine Unterseite|$1 Unterseiten|51=über 50 Unterseiten}}]].",
        "rollback": "Zurücksetzen der Änderungen",
+       "rollback-confirmation-confirm": "Bitte bestätigen:",
+       "rollback-confirmation-yes": "Zurücksetzen",
+       "rollback-confirmation-no": "Abbrechen",
        "rollbacklink": "Zurücksetzen",
        "rollbacklinkcount": "{{PLURAL:$1|Eine Version|$1 Versionen}} zurücksetzen",
        "rollbacklinkcount-morethan": "Mehr als {{PLURAL:$1|eine Version|$1 Versionen}} zurücksetzen",
        "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",
        "rollback-success": "Die Änderungen von {{GENDER:$3|$1}} wurden rückgängig gemacht und die letzte Version von {{GENDER:$4|$2}} wurde wiederhergestellt.",
-       "rollback-success-notify": "Bearbeitungen von $1 rückgängig gemacht;\nzurückgeändert auf die letzte Version von $2. [$3 Änderungen zeigen]",
        "sessionfailure-title": "Sitzungsfehler",
        "sessionfailure": "Es gab ein Problem bei der Übertragung deiner Benutzerdaten.\nDiese Aktion wurde daher sicherheitshalber abgebrochen, um eine falsche Zuordnung deiner Änderungen zu einem anderen Benutzer zu verhindern.\nBitte sende das Formular erneut ab.",
        "changecontentmodel": "Inhaltsmodell einer Seite ändern",
        "mycontris": "Beiträge",
        "anoncontribs": "Beiträge",
        "contribsub2": "Von {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Für {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Das Benutzerkonto „$1“ ist nicht vorhanden.",
        "negative-namespace-not-supported": "Namensräume mit negativen Werten werden nicht unterstützt.",
        "nocontribs": "Es wurden keine Benutzerbeiträge mit diesen Kriterien gefunden.",
        "ipb-confirm": "Sperrung bestätigen",
        "ipb-sitewide": "Auf der gesamten Website",
        "ipb-partial": "Teilweise",
+       "ipb-sitewide-help": "Jede Seite auf dem Wiki und alle anderen Beitragsaktionen.",
+       "ipb-partial-help": "Spezielle Seiten oder Namensräume.",
        "ipb-pages-label": "Seiten",
        "ipb-namespaces-label": "Namensräume",
        "badipaddress": "Die IP-Adresse hat ein falsches Format.",
        "pageinfo-robot-index": "Erlaubt",
        "pageinfo-robot-noindex": "Nicht erlaubt",
        "pageinfo-watchers": "Anzahl der Beobachter dieser Seite",
-       "pageinfo-visiting-watchers": "Anzahl der Beobachter dieser Seite, die die letzten Bearbeitungen besucht haben",
+       "pageinfo-visiting-watchers": "Anzahl der Beobachter dieser Seite, welche die letzten Bearbeitungen besucht haben",
        "pageinfo-few-watchers": "Weniger als {{PLURAL:$1|ein|$1}} Beobachter",
        "pageinfo-few-visiting-watchers": "Es könnte einen beobachtenden Benutzer geben oder nicht, der die letzten Bearbeitungen besucht hat",
        "pageinfo-redirects-name": "Anzahl der Weiterleitungen zu dieser Seite",
        "confirm-unwatch-top": "Diese Seite von der persönlichen Beobachtungsliste entfernen?",
        "confirm-rollback-button": "Okay",
        "confirm-rollback-top": "Bearbeitungen an dieser Seite zurücksetzen?",
+       "confirm-rollback-bottom": "Diese Aktion wird sofort die ausgewählten Änderungen an dieser Seite zurücksetzen.",
        "confirm-mcrrestore-title": "Eine Version wiederherstellen",
        "confirm-mcrundo-title": "Eine Änderung rückgängig machen",
        "mcrundofailed": "Rückgängigmachung fehlgeschlagen",
        "logentry-rights-autopromote": "$1 wurde automatisch von $4 zu $5 {{GENDER:$2|zugeordnet}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|lud}} $3 hoch",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|lud}} eine neue Version von $3 hoch",
-       "logentry-upload-revert": "$1 {{GENDER:$2|lud}} $3 hoch",
+       "logentry-upload-revert": "$1 {{GENDER:$2|setzte}} $3 auf eine alte Version zurück",
        "log-name-managetags": "Markierungsverwaltungs-Logbuch",
        "log-description-managetags": "Diese Seite listet Verwaltungsaufgaben bezüglich der [[Special:Tags|Markierungen]] auf. Das Logbuch enthält nur Aktionen, die manuell von einem Administrator ausgeführt wurden; Markierungen können auch von der Wikisoftware erstellt oder gelöscht werden, ohne dass ein aufgezeichneter Eintrag in diesem Logbuch vorliegt.",
        "logentry-managetags-create": "$1 {{GENDER:$2|erstellte}} die Markierung „$4“",
        "log-action-filter-suppress-reblock": "Benutzerunterdrückung durch Neusperre",
        "log-action-filter-upload-upload": "Neue Hochladung",
        "log-action-filter-upload-overwrite": "Wiederhochladung",
+       "log-action-filter-upload-revert": "Zurücksetzung",
        "authmanager-authn-not-in-progress": "Die Authentifizierung ist nicht im Gang oder es sind Sitzungsdaten verloren gegangen. Bitte beginne von vorn.",
        "authmanager-authn-no-primary": "Die angegebenen Anmeldeinformationen konnten nicht überprüft werden.",
        "authmanager-authn-no-local-user": "Die angegebenen Anmeldeinformationen sind mit keinem Benutzer auf diesem Wiki verknüpft.",
        "authmanager-create-no-primary": "Die angegebenen Anmeldeinformationen konnten nicht für die Benutzerkontenerstellung verwendet werden.",
        "authmanager-link-no-primary": "Die angegebenen Anmeldeinformationen konnten nicht für die Benutzerkontenverknüpfung verwendet werden.",
        "authmanager-link-not-in-progress": "Die Benutzerkontenverknüpfung ist nicht im Gang oder es sind Sitzungsdaten verloren gegangen. Bitte beginne von vorn.",
-       "authmanager-authplugin-setpass-failed-title": "Passwortänderung fehlgeschlagen",
-       "authmanager-authplugin-setpass-failed-message": "Das Authentifizierungs-Plugin hat die Passwortänderung abgelehnt.",
-       "authmanager-authplugin-create-fail": "Das Authentifizierungs-Plugin hat die Benutzerkontenerstellung abgelehnt.",
-       "authmanager-authplugin-setpass-denied": "Das Authentifizierungs-Plugin erlaubt keine Passwortänderungen.",
-       "authmanager-authplugin-setpass-bad-domain": "Ungültige Domain.",
        "authmanager-autocreate-noperm": "Die automatische Benutzerkontenerstellung ist nicht erlaubt.",
        "authmanager-autocreate-exception": "Die automatische Benutzerkontenerstellung ist aufgrund früherer Fehler vorübergehend deaktiviert.",
        "authmanager-userdoesnotexist": "Das Benutzerkonto „$1“ ist nicht registriert.",
        "passwordpolicies-policy-maximalpasswordlength": "Ein Passwort muss weniger als {{PLURAL:$1|ein|$1}} Zeichen lang sein",
        "passwordpolicies-policy-passwordcannotbepopular": "Ein Passwort kann nicht {{PLURAL:$1|das beliebteste Passwort|in der Liste der $1 beliebtesten Passwörter}} sein",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Das Passwort kann nicht in der Liste der 100.000 am häufigsten verwendeten Passwörter sein.",
+       "passwordpolicies-policyflag-forcechange": "muss bei der Anmeldung geändert werden",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "Änderung bei der Anmeldung vorschlagen",
        "easydeflate-invaliddeflate": "Der angegebene Inhalt ist nicht ordnungsgemäß komprimiert",
        "unprotected-js": "Aus Sicherheitsgründen kann JavaScript-Code nicht mehr von ungeschützten Seiten geladen werden. Erstelle die JavaScript-Seite bitte ausschließlich im Namensraum „MediaWiki“ oder als Benutzerunterseite."
 }
index a6ac049..10f58a4 100644 (file)
        "category-file-count": "{{PLURAL:$2|Na kategori tenya dosya ya cêri muhtewa kena.|Na kategori de $2 ra pêro piya {{PLURAL:$1|1 dosya est a|$1 dosyey est ê}}.}}",
        "category-file-count-limited": "{{PLURAL:$1|Dosye|$1 Dosyey}} na kategori de yê.",
        "listingcontinuesabbrev": "dewam...",
-       "index-category": "Perrê rêzıni",
+       "index-category": "Pelê rêzıni",
        "noindex-category": "Perrê bêrêzıni",
        "broken-file-category": "Perri be linkanê dosya çewte",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "unprotect": "Starnayışi bıvurne",
        "newpage": "Perra newi",
        "talkpagelinktext": "werênayış",
-       "specialpage": "Perra xısusiye",
+       "specialpage": "Pela xısusiye",
        "personaltools": "Hacetê şexsiy",
        "talk": "Werênayış",
        "views": "Asayışi",
        "policy-url": "Project:Terzê hereketi",
        "portal": "Portalê cemati",
        "portal-url": "Project:Portalê cemati",
-       "privacy": "Politikay nımıtışi",
+       "privacy": "Politikaya dızdêni",
        "privacypage": "Project:Xısusiyetê nımıtışi",
        "badaccess": "Xeta mısadey",
        "badaccess-group0": "Heqa şıma çıniya, karo ke şıma waşt, bıkerê.",
        "nstab-main": "Pele",
        "nstab-user": "Pera karberi",
        "nstab-media": "Pela medya",
-       "nstab-special": "Perra xısusiye",
+       "nstab-special": "Pela xısusiye",
        "nstab-project": "Perra proji",
        "nstab-image": "Dosya",
        "nstab-mediawiki": "Mesac",
        "acct_creation_throttle_hit": "Yew ten IP adresê şıma xebıtnayo u kewto no wiki, $2roco peyin de {{PLURAL:$1|1 hesabi|$1 hesaban}} vıraşto.\nxulasa ney kesê ke IP adresê şıma xebıtneni hini nêeşkeni ney ra zêdêr hesab akeri.",
        "emailauthenticated": "E-postay şıma $2 sehat $3 dı biya araşt",
        "emailnotauthenticated": "Adresa e-pota da şıma qebul nébiya.\nQandé céréna şımaré teba do nérışiyo.",
-       "noemailprefs": "Hesab biyo a.",
+       "noemailprefs": "Seba gurenayışê nê xısusiyetayew adresê e-posta cı kerê .",
        "emailconfirmlink": "E-postayê xo araşt kerê",
        "invalidemailaddress": "No format de nuştışê e-postayi qebul nêbeno. Yew formato meqbul de adresê e-posta bınuse ya zi veng bıverde.",
        "cannotchangeemail": "E-postay hesabi ena wiki sera nêvurneyêno.",
        "watchthis": "Na pele de seyr ke",
        "savearticle": "Pele qeyd ke",
        "savechanges": "Vurnayışan qeyd ke",
-       "publishpage": "Riperri bare ke",
-       "publishchanges": "Vırnayışan qeyd ke",
+       "publishpage": "Pele qeyd ke",
+       "publishchanges": "Vurnayışan qeyd ke",
        "savearticle-start": "Pele qeyd ke...",
        "savechanges-start": "Vurnayışan qeyd ke...",
        "publishpage-start": "Pele weşane...",
        "template-protected": "(şeveknaye)",
        "template-semiprotected": "(nime staryayış)",
        "hiddencategories": "Ena per de {{PLURAL:$1|1 kategoriyo nımıte|$1 kategoriyê nımıtey}} muhtewa benê:",
-       "edittools": "<div id=\"specialcharss\" class=\"toccolours specialchars\" style=\"margin-top:.5em; padding: .3em .5em; font-size: 100%; color:#aaa; text-align:left;\" title=\"{{int:bw-edittools-tooltip}}\">\n<p class=\"specialbasic\" id=\"Standard\">\n'''{{int:bw-edittools-lead-in}}''' \n<charinsert>Á á É é Í í Ó ó Ú ú Ý ý</charinsert> –\n<charinsert>À à È è Ì ì Ò ò Ù ù </charinsert> –\n<charinsert> â Ê ê Î î Ô ô Û û </charinsert> –\n<charinsert>Ä ä Ë ë Ï ï Ö ö Ü ü Ÿ ÿ</charinsert> –\n<charinsert>Æ æ Ø ø Œ œ ẞ ß </charinsert> –\n<charinsert>Å å Ů ů </charinsert> –\n<charinsert>àã Ẽ ẽ ɛ̃ Ĩ ĩ Ñ ñ Õ õ ɔ̃ Ũ ũ </charinsert> –\n<charinsert>Рð Þ þ </charinsert> –\n<charinsert>Ç ç Ģ ģ Ķ ķ Ļ ļ Ņ ņ Ŗ ŗ Ş ş Ţ ţ </charinsert> –\n<charinsert>Ć ć Ĺ ĺ Ń ń Ŕ ŕ Ś ś Ý ý Ź ź </charinsert> –\n<charinsert>Č č Ď ď Ľ ľ Ň ň Ř ř Š š Ť ť Ž ž </charinsert> –\n<charinsert>Ǎ ǎ Ě ě Ǐ ǐ Ǒ ǒ Ǔ ǔ </charinsert> –\n<charinsert>Ā ā Ē ē Ī ī Ō ō Ū ū </charinsert> –\n<charinsert>ǖ ǘ ǚ ǜ </charinsert> –\n<charinsert>Ĉ ĉ Ĝ ĝ Ĥ ĥ Ĵ ĵ Ŝ ŝ Ŵ ŵ Ŷ ŷ </charinsert> –\n<charinsert>Ă ă Ğ ğ Ŭ ŭ </charinsert> –\n<charinsert>Ċ ċ Ė ė Ġ ġ Għ għ İ ı Ż ż </charinsert> –\n<charinsert>Ą ą Ę ę Į į Ų ų </charinsert> –\n<charinsert>Ő ő Ű ű </charinsert> –\n<charinsert>Đ đ Ħ ħ Ł ł Ŀ ŀ </charinsert> –\n<charinsert>Ɖ ɖ Ɛ ɛ Ƒ ƒ Ɣ ɣ Ŋ ŋ Ɔ ɔ Ʋ ʋ </charinsert> -\n<charinsert>Ə ə </charinsert> –\n<charinsert>– — ’</charinsert> –\n<charinsert>~ | ° ¹ ² ³ ⅛ ¼ ⅓ ⅜ ½ ⅝ ¾ ⅔ ⅞ € $ ¥ £ † × ← → ↔ ↑ ± ≠ © ® ™ ‰ «+» ‹+› „+“ „+” ‚+‘ ¡ ¿ …</charinsert> –\n<charinsert>&amp;nbsp; &nbsp; [[Category:+]] #REDIRECT[[+]] {{msg-mw|+|notext=1}} &#33;!FUZZY!! ~~~~  &lt;nowiki>+</nowiki></charinsert>\n<charinsert>ڈ ڑ ٹ </charinsert>\n<charinsert>ټ څ ځ ډ ړ ږ ښ ڼ ؤ ي ې ۍ ئ </charinsert>\n<charinsert>{{{+}}} {{+}} {{subst:+}} <noinclude>+</noinclude></charinsert>\n<charinsert>&lt;!--&nbsp;+&nbsp;--> &lt;br&nbsp;/></charinsert>\n</p></div>",
+       "edittools": "<!-- Beno ke no metın bınê formanê vurnayışi û barkerdışi de bımocniyo. -->",
        "edittools-upload": "-",
        "nocreatetext": "{{SITENAME}}, Perrê newey vıraştış rê destur çıniyo.\nŞıma şenê tepeya şorê u eke şıma qeydbiyayey [[Special:UserLogin|şıma şenê yew hesab akerê]], eke şıma niyê [[Special:UserLogin|şıma şenê qeyd bıbê]].",
        "nocreate-loggedin": "Desturê şıma çıniyo ke pelanê neweyan vırazê.",
        "unstrip-depth-warning": "Sinorê newekerdışê ($1) viyarna ra",
        "unstrip-size-warning": "Sinorê newekerdışê ($1) viyarna ra",
        "converter-manual-rule-error": "Rehberê zıwan açarnayışi dı xırabin tesbit biya",
-       "undo-success": "No vurnayiş tepeye geryeno. pêverronayişêyê cêrıni kontrol bıkeri.",
-       "undo-failure": "Poxta pëverameyişa vurnayişan ra  peyd grotışë kari në bı",
-       "undo-norev": "Vurnayiş tepêya nêgeryeno çunke ya vere cû hewna biyo ya zi ca ra çino.",
-       "undo-summary": "Vırnayışê $1'i [[Special:Contributions/$2|$2i]] ([[User talk:$2|Werênayış]]) peyser gırewt",
+       "undo-success": "Eno vurnayış şeno peyser bıgêriyo. Kerem ke, têvereştışê cêrêni kontrol ke, waştena nê vurnayışi kerdene rê bawer be û be qeydkerdışê pele ra vurnayışê vêrêni peyser bıgê.",
+       "undo-failure": "Seba vurnayışanê yewbininêgırewteyan ra vurnayış peyser nêgêriya.",
+       "undo-norev": "Vurnayış peyser nêgêriyeno, çıke çıniyo ya zi esteriyayo.",
+       "undo-nochange": "Vurnayış xora zey peysergırewte aseno.",
+       "undo-summary": "[[Special:Contributions/$2|$2]]i ([[User talk:$2|werênayış]]) vurnayışê $1i peyser gırewt",
        "undo-summary-username-hidden": "Rewizyona veri $1'i hewada",
        "cantcreateaccount-text": "Hesabvıraştışê na IP adrese ('''$1''') terefê [[User:$3|$3]] kılit biyo.\n\nSebebo ke terefê $3 ra diyao ''$2''",
        "viewpagelogs": "Qeydanê na pele bımocne",
        "currentrevisionlink": "Tewr halê peyn",
        "cur": "ferq",
        "next": "bahdoyên",
-       "last": "peyên",
+       "last": "verên",
        "page_first": "verên",
        "page_last": "peyên",
        "histlegend": "Ferqê weçinayışi: Qutiya versiyonan qandé  têversanayış işaret ke u dest be ''enter''i ya zi gocega cêrêne rone.<br />\nCetwel: <strong>({{int:ferq}})</strong> = ferqê versiyonê peyêni, <strong>({{int:peyên}})</strong> = ferqê versiyonê verêni, <strong>{{int:q}}</strong> = vırnayışo werdiyo.",
-       "history-fieldset-title": "Çım ra viyarnayışan cı geyre",
+       "history-fieldset-title": "Çımraviyarnayışan cı geyre",
        "history-show-deleted": "Tenya çımraviyarnayışanê esterıteyan bımocne",
        "histfirst": "Verênêr",
        "histlast": "Peyênêr",
        "historysize": "({{PLURAL:$1|1 bayt|$1 bayti}})",
-       "historyempty": "(veng)",
+       "historyempty": "veng",
        "history-feed-title": "Tarixê çımraviyarnayışi",
        "history-feed-description": "Wiki de tarixê çım ra viyarnayışë na perer",
        "history-feed-item-nocomment": "$1 miyanê $2i de",
        "lineno": "Xeta $1:",
        "compareselectedversions": "Rewizyonanê weçineyan pêver ke",
        "showhideselectedversions": "weçinaye revizyona bımotne/bınımne",
-       "editundo": "Peyser bıgêre",
+       "editundo": "peyser bıgê",
        "diff-empty": "(Babetna niyo)",
        "diff-multi-sameuser": "(Terefê eyni karberi ra {{PLURAL:$1|yew revizyono miyanên nêmocno|$1 revizyonê miyanêni nêmocnê}})",
        "diff-multi-otherusers": "(Terefê {{PLURAL:$2|yew karberi|$2 karberan}} ra {{PLURAL:$1|yew revizyono miyanên nêmocno|$1 revizyonê miyanêni nêmocnê}})",
        "prevn": "{{PLURAL:$1|$1}} verên",
        "nextn": "{{PLURAL:$1|$1}} peyên",
        "prev-page": "Perra verêne",
-       "next-page": "pela peyco",
+       "next-page": "pela bahdoyêne",
        "prevn-title": "$1o verên  {{PLURAL:$1|netice|neticeyan}}",
        "nextn-title": "$1o ke yeno {{PLURAL:$1|netice|neticey}}",
        "shown-title": "Her pele sero $1 {{PLURAL:$1|netici|netica}} bımocne",
        "searchmenu-new": "<strong>Ena wiki de perra \"[[:$1]]\" vıraze!</strong> {{PLURAL:$2|0=|Sewbina pela ke şıma geyrayê cı aye bıvênê.|Yew zi peyniyanê cıgeyrayışê xo bıvênê.}}",
        "searchprofile-articles": "Pelê zerreki",
        "searchprofile-images": "Multimedya",
-       "searchprofile-everything": "Pêro çi",
-       "searchprofile-advanced": "Herayen",
+       "searchprofile-everything": "Her çi",
+       "searchprofile-advanced": "Herayên",
        "searchprofile-articles-tooltip": "$1 de cı geyre",
        "searchprofile-images-tooltip": "Dosya cı geyre",
        "searchprofile-everything-tooltip": "Tedeesteyan hemine cı geyre (pelanê werênayışi zi tey)",
-       "searchprofile-advanced-tooltip": "Cayê namanê xısusiyan de cı geyre",
+       "searchprofile-advanced-tooltip": "Cayê nameyanê xısusiyan de cı geyre",
        "search-result-size": "$1 ({{PLURAL:$2|1 çeku|$2 çekuy}})",
        "search-result-category-size": "{{PLURAL:$1|1 eza|$1 ezayi}} ({{PLURAL:$2|1 kategoriya bınêne|$2 kategoriyê bınêni}}, {{PLURAL:$3|1 dosya|$3 dosyeyi}})",
        "search-redirect": "($1 ra kırışiyaya)",
        "prefs-labs": "Xacetê labs",
        "prefs-user-pages": "Pelê karberi",
        "prefs-personal": "Profilê karberi",
-       "prefs-rc": "Vırnayışê peyêni",
+       "prefs-rc": "Vurnayışê peyêni",
        "prefs-watchlist": "Lista seyrkerdışi",
        "prefs-editwatchlist": "Lista seyrkerdışi bıvurne",
        "prefs-editwatchlist-label": "Listey serkerdışanê cıkewtışi timar kerê",
        "prefs-misc": "ê bini",
        "prefs-resetpass": "Parola bıvurne",
        "prefs-changeemail": "E-postay bıvurne ya zi wedarne",
-       "prefs-setemail": "E-posta adresiyê xo saz kerê",
+       "prefs-setemail": "Adresê eposta cı kerê",
        "prefs-email": "Tercihê e-maili",
        "prefs-rendering": "Asayış",
        "saveprefs": "Qeyd ke",
        "email-blacklist-label": "Wa nê karberi mı rê mesac nêrışê:",
        "prefs-searchoptions": "Cı geyre",
        "prefs-namespaces": "Heruna nameyan",
-       "default": "qısur",
+       "default": "Keyfi",
        "prefs-files": "Dosyeyi",
        "prefs-custom-css": "CSSê xasi",
        "prefs-custom-json": "JSONo xısusi",
        "prefs-help-signature": "Mışewreyê ke pelanê werênayışi derê, gani be \"<nowiki>~~~~</nowiki>\" ra imza bıbê, no bahdo beno çerxê imza û wadeyê zemani.",
        "badsig": "Îmzayê tu raşt niyo.\nEtiketê HTMLî kontrol bike.",
        "badsiglength": "İmzaya şıma zaf derga.\nA gani be $1 {{PLURAL:$1|karakter|karakteran}} ra zêde mebo.",
-       "yourgender": "Şeklê xitabi?",
-       "gender-unknown": "Çımhal tı kerdê etiket, Nusner do çekuya Nerimaki cinsiyeti de şeno bıkar no",
-       "gender-male": "Perané wiki camérd deyne ezo vırnena",
-       "gender-female": "Perané wiki cıni deyne eza vırnena",
-       "prefs-help-gender": "Na tercih keyfiya.\nNa nustenek ercana qısan de qandé grameri karneyéna, na malumater herkes şeno bıvino .",
+       "yourgender": "Şıma yê xo seni tarif kenê?",
+       "gender-unknown": "Software şıma ra bahs kerdış dê, hendık cı dest ra biro cınsiyeti ya aleqeyın çekuy nêvaco.",
+       "gender-male": "Oyo pelanê wiki vurneno",
+       "gender-female": "Aya pelanê wiki vırnena.",
+       "prefs-help-gender": "Na eyara tercihi keyfiya.\nNa software seraniya ercê çekuyan de gorey cınsiyeta hol Gramer kar nêna. \nNê melumati herkesi rê asenê.",
        "email": "E-posta",
        "prefs-help-realname": "Nameyo raşt waştena şıma rê mendo.\nEka tu wazene ke nameyo raşt xo bide, ma nameyo raşt ti iştirakanê ti de mocnenê.",
        "prefs-help-email": "Dayışê adresa e-postey keyfiyo, labelê seba eyarê parola lazıma, wexto ke şıma naye xo vira kerê.",
        "userrights-conflict": "Heqan de karberi de dıbare vıcyayo! Kerem ke vurnayışane xo çımser ra ravyarne  u tesdiq keri.",
        "group": "Grube:",
        "group-user": "Karberi",
-       "group-autoconfirmed": "Karberê ke otomatikmen biyê araşt",
+       "group-autoconfirmed": "Otomatik raşt bıyaye karberi",
        "group-bot": "Boti",
        "group-sysop": "İdarekari",
        "group-interface-admin": "İdarekarê namnişani",
        "group-suppress": "Pawıteri",
        "group-all": "(pêro)",
        "group-user-member": "{{GENDER:$1|karber}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|Karberê ke otomatikmen biyê araşt}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|Otomatik raşt bıyaye karberi}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|İdarekar}}",
        "group-interface-admin-member": "{{GENDER:$1|idarekarê namnişani}}",
        "group-bureaucrat-member": "{{GENDER:$1|buroqrat}}",
        "group-suppress-member": "{{GENDER:$1|Temaşekar}}",
        "grouppage-user": "{{ns:project}}:Karberi",
-       "grouppage-autoconfirmed": "{{ns:project}}:Karberê ke otomatikmen biyê araşt",
+       "grouppage-autoconfirmed": "{{ns:project}}:Otomatik raşt bıyaye karberi",
        "grouppage-bot": "{{ns:project}}:Boti",
        "grouppage-sysop": "{{ns:project}}:İdarekeri",
        "grouppage-interface-admin": "{{ns:project}}:İdarekarê namnişani",
        "grant-group-watchlist-interaction": "Lista da xoya tesir",
        "grant-group-email": "e-poste bırışe",
        "grant-group-high-volume": "Performansa aktiviteya vengê berzi",
-       "grant-group-customization": "Şexsi kerdış u tercihi",
+       "grant-group-customization": "Xısusikerdış û tercihi",
        "grant-group-administration": "Performans hereketa idarey",
        "grant-group-private-information": "Melumatê xısusiyê ke heqa şıma derê, bıresê inan",
        "grant-group-other": "Enwayi babet aktivitey",
        "grant-basic": "Heqê basiti",
        "grant-viewdeleted": "Besteryaya peran u dosyaya bıasne",
        "grant-viewmywatchlist": "Lista serykerdışê xo bıvêne",
-       "newuserlogpage": "Roceka karberanê newa",
+       "newuserlogpage": "Qeydê karberanê neweyan",
        "newuserlogpagetext": "No yew qeydê afernayışanê karberio.",
        "rightslog": "Qeydê heqanê karberi",
        "rightslogtext": "Ena listeyê loganê ke heqqa karbaranî mucneno.",
        "nchanges": "$1 {{PLURAL:$1|vurnayış|vurnayışi}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ziyaretê peyêni ra nata}}",
        "enhancedrc-history": "tarix",
-       "recentchanges": "Vırnayışê peyêni",
+       "recentchanges": "Vurnayışê peyêni",
        "recentchanges-legend": "Tercihê vırnayışanê peyênan",
-       "recentchanges-summary": "Wiki sero vırnayışê peyêni asenê.",
+       "recentchanges-summary": "Ena pele de Wiki sero vurnayışê peyêni asenê.",
        "recentchanges-noresult": "Demê periyodi de vırnayış be enê kriteran çıniyo.",
        "recentchanges-feed-description": "Ena feed dı vurnayişanê tewr peniyan teqip bık.",
        "recentchanges-label-newpage": "Enê vırnayışi yew perra newiye vıraşta.",
        "recentchanges-label-bot": "Eno vırnayış terefê yew boti ra vıraziyo",
        "recentchanges-label-unpatrolled": "Eno vurnayış hewna dewriya nêbiyo",
        "recentchanges-label-plusminus": "Ebadê perre de bazê bayti de vayey cı",
-       "recentchanges-legend-heading": "<strong>Kıtabekê vırnayışê peyêni:</strong>",
+       "recentchanges-legend-heading": "<strong>Kıtabekê vurnayışê peyêni:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} Şıma şenê ([[Special:NewPages|Lista peranê  newan]] zi bıvênê)",
        "recentchanges-legend-plusminus": "''(±123)''",
        "recentchanges-submit": "Bımocne",
        "unusedtemplates": "Şablonê ke nêguriyenê",
        "unusedtemplatestext": "no pel, {{ns:template}} pelê ke pelê binan de nêaseni, ninan keno.",
        "unusedtemplateswlh": "linkanê binî",
-       "randompage": "Perra raştameyiye",
+       "randompage": "Pela raştameyiye",
        "randompage-nopages": "Na {{PLURAL:$2|heruna namey|heruna nameyan}} de nê peli çıniyê: $1.",
        "randomincategory": "Ena kategoriye dı pela raştameye",
        "randomincategory-invalidcategory": "\"$1\" yew nameyê kategoriya vêrdiye niyo.",
        "checkbox-none": "Çıniyo",
        "checkbox-invert": "Dimlaşt ke",
        "allpages": "Pêro peli",
-       "nextpage": "Pela peyco ($1)",
+       "nextpage": "Pela bahdoyêne ($1)",
        "prevpage": "Pela veri ($1)",
        "allpagesfrom": "Herfa kı pa liste bo:",
        "allpagesto": "Perranê ke ena herfe qediyenê bımotne:",
        "delete-confirm": "\"$1\" bestere",
        "delete-legend": "Bestere",
        "historywarning": "'''Teme:''' Pela ke şıma esterenê tede yew viyarte be teqriben $1 {{PLURAL:$1|versiyon esto|versiyoni estê}}:",
-       "historyaction-submit": "Bımocne",
+       "historyaction-submit": "Versiyonan bımocne",
        "confirmdeletetext": "Tı ho yew pele u tarixê pele wederneno.\nTı ra rica keno, tı zani tı ho sekeno, tı zani neticeyanê eno wedarnayışi u tı zani tı ser [[{{MediaWiki:Policy-url}}|poliçe]] kar keno.",
        "actioncomplete": "Kar bi temam",
        "actionfailed": "kar nêbı",
        "delete-warning-toobig": "no pel wayirê tarixê vurnayiş ê derg o, $1 {{PLURAL:$1|revizyonê|revizyonê}} seri de.\nhewn a kerdışê ıney {{SITENAME}} şuxul bıne gırano;\nbı diqqet dewam kerê.",
        "deleteprotected": "Şıma nêşenê ena perer esternê,  çıkı per starya ya.",
        "rollback": "vurnayişan tepiya bıger",
+       "rollback-confirmation-yes": "Peyser biya",
+       "rollback-confirmation-no": "Bıtexelne",
        "rollbacklink": "ageyrayış",
        "rollbacklinkcount": "$1 {{PLURAL:$1|vurnayış|vurnayışi}} peyd gıroti",
        "rollbacklinkcount-morethan": "$1 {{PLURAL:$1|vurnayış|vuranyışi}} tewr peyd gırot",
        "isredirect": "pera hetenayışi",
        "istemplate": "Açarnayene",
        "isimage": "gırey dosye",
-       "whatlinkshere-prev": "{{PLURAL:$1|veror|veror $1}}",
+       "whatlinkshere-prev": "{{PLURAL:$1|verên|verên $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|verni|verni $1}}",
        "whatlinkshere-links": "← gırey",
        "whatlinkshere-hideredirs": "Hetenayışê $1",
        "djvu_no_xml": "Qe DjVu nieşkenî XML fetch bikî",
        "thumbnail-temp-create": "İdare dosyay resimiya nêvırazêna",
        "thumbnail-dest-create": "Resimo werdiyo keyd nêbeno",
-       "thumbnail_invalid_params": "Parametreya thumbnailî raşt niyşê",
+       "thumbnail_invalid_params": "Parametreya xıraba resimanê werdiyan",
        "thumbnail_toobigimagearea": "Ebadê $1 ra gırd dosyeyi",
        "thumbnail_dest_directory": "Nieşkenî direktorê destinasyonî virazî",
        "thumbnail_image-type": "Tipê resimî kebul nibeno",
        "tooltip-search-go": "Ebe nê namey tami şo yew pela ke esta",
        "tooltip-search-fulltext": "Pelan miyan de nê metıni cı geyre",
        "tooltip-p-logo": "Şo perra seri",
-       "tooltip-n-mainpage": "Şo perra seri",
+       "tooltip-n-mainpage": "Şo pela seri",
        "tooltip-n-mainpage-description": "Şo perra seri",
        "tooltip-n-portal": "Heqa procey de, kes çı şeno bıkero, çı kamca vêniyeno",
        "tooltip-n-currentevents": "Vurnayışanê peyênan de melumatê pey bıvêne",
-       "tooltip-n-recentchanges": "Wiki dı yew lista vurnayışanê peyênan",
+       "tooltip-n-recentchanges": "Wiki de yew lista vurnayışanê peyênan",
        "tooltip-n-randompage": "Pelê da raştameyiye bar ke",
        "tooltip-n-help": "Cayê peştigırewtışi",
        "tooltip-t-whatlinkshere": "Lista pelanê wikiya pêroina ke tiya gırê bena",
        "tooltip-t-emailuser": "{{GENDER:$1|Enê karberi}} rê yew e-poste bırışe",
        "tooltip-t-info": "Derheqê ena pele de zêdêr melumat",
        "tooltip-t-upload": "Dosyeyan bar ke",
-       "tooltip-t-specialpages": "Listeya peranê hısusiyan hemın",
+       "tooltip-t-specialpages": "Yew lista pelanê xısusiyanê pêroyinan",
        "tooltip-t-print": "Versiyono perre ro ke nuşterniyaye.",
        "tooltip-t-permalink": "Gırêyo daimi be ena versiyonê pele",
        "tooltip-ca-nstab-main": "Pela zerreki bıvêne",
        "tooltip-ca-nstab-category": "Pela kategoriye bıvêne",
        "tooltip-minoredit": "Ney vırnayışo werdi nışan bıkerê",
        "tooltip-save": "Vurnayışanê xo qeyd ke",
-       "tooltip-publish": "Vırnayışê xo aşkera ke",
+       "tooltip-publish": "Vurnayışê xo qeyd ke",
        "tooltip-preview": "Vurnayışanê xo çım ra bıviyarnê. Qeydkerdış ra ver bıgurê cı!",
        "tooltip-diff": "Kamci vırnayışê ke şıma nuştey sero kerdê, inan bıvênê.",
        "tooltip-compareselectedversions": "Ena per de ferqê rewziyonan de dı weçinaya bıvinê",
        "tooltip-recreate": "pel hewn a bışiyo zi tepiya biya",
        "tooltip-upload": "Sergen de bari be",
        "tooltip-rollback": "\"Peyser biya\" be yew tık pela iştıraqanê peyênan peyser ano",
-       "tooltip-undo": "\"Undo\" ena vurnayışê newi iptal kena u vurnayışê verni a kena.\nTı eşkeno yew sebeb bınus.",
+       "tooltip-undo": "\"Peyser\" nê vurnayışi peyser ano û modusê verqayti de vurnayışê formi keno a. Têserkerdışê yew sebebi rê xulasa de imkan dano cı.",
        "tooltip-preferences-save": "Terciha qeyd ke",
        "tooltip-summary": "Xulasa kılmek bınuse",
        "interlanguage-link-title": "$1 - $2",
+       "group-autoconfirmed.css": "/* Ronışyaye  CSS seba otomatik raşt bıyaye karberan rê tesir keno */",
+       "group-autoconfirmed.js": "/* No JavaScript teyna seba otomatik raşt bıyaye karberan rê do bar bo */",
        "anonymous": "{{PLURAL:$1|karberê|karberê}} anonimi yê keyepelê {{SITENAME}}i",
        "siteuser": "karberê {{SITENAME}}i $1",
        "anonuser": "karberê anonim o {{SITENAME}}i $1",
        "markaspatrolledtext": "Ena pele kontrol biyayi nışan ke",
        "markedaspatrolled": "Nişan biyo ke verni de devriye biyo",
        "markedaspatrolledtext": "Versiyone weçinaye [[:$1]] nişan biyo ke devriye biyo",
-       "rcpatroldisabled": "Dewriyay vırnayışê peyêni nêxebetiyena",
+       "rcpatroldisabled": "Dewriyaya vurnayışanê peyênan nêxebetiyena",
        "rcpatroldisabledtext": "Dewriya vırnayışanê peyênan nêgırweniyena.",
        "markedaspatrollederror": "Nişan nibeno ke devriye biyo",
        "markedaspatrollederrortext": "Ti gani revizyon işaret bike ke Nişanê devriye biyo",
        "nextdiff": "Vurnayışo peyên →",
        "mediawarning": "'''Teme''': Na dosya de belkia kodê xırabıni estê.\nGurênayışê nae de, beno ke sistemê şıma zerar bıvêno.",
        "imagemaxsize": "Sinorê ebadê resımiyo ke pelanê şınasnayışê dosyeyan dero:",
-       "thumbsize": "Ebadê Thumbnaili",
+       "thumbsize": "Ebado werdı",
        "widthheight": "$1 - $2",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|pele|peli}}",
        "file-info": "ebatê dosyayi: $1, MIME tip: $2",
        "brackets": "[$1]",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← pela veri",
-       "imgmultipagenext": "pela peyco →",
+       "imgmultipagenext": "pela bahdoyêne →",
        "imgmultigo": "Şo!",
        "imgmultigoto": "Şo pela da $1",
        "img-lang-default": "(zıwano hesabiyaye)",
        "img-lang-go": "Şo",
        "ascending_abbrev": "berz",
        "descending_abbrev": "nızm",
-       "table_pager_next": "Pela peyco",
+       "table_pager_next": "Pela bahdoyêne",
        "table_pager_prev": "Pela veri",
        "table_pager_first": "Pela sıfteyêne",
        "table_pager_last": "Pela peyêne",
        "version": "Versiyon",
        "version-extensions": "Ekstensiyonî ke ronaye",
        "version-skins": "Bar kerde bejni",
-       "version-specialpages": "Perê hısusiy",
+       "version-specialpages": "Pelê xısusiyi",
        "version-parserhooks": "Çengelê Parserî",
        "version-variables": "Vurnayeyî",
        "version-editors": "Vurnayoği",
        "specialpages-group-maintenance": "Rapora pawıtışi",
        "specialpages-group-other": "Pelê xısusiyê bini",
        "specialpages-group-login": "Cı kewe / hesab vıraze",
-       "specialpages-group-changes": "Vırnayışê peyêni u qeydi",
+       "specialpages-group-changes": "Vurnayışê peyêni û qeydi",
        "specialpages-group-media": "Raporê medya û barkerdışi",
        "specialpages-group-users": "Karberi u heqê inan",
        "specialpages-group-highuse": "Pelê ke zêdêr gureniyenê",
        "tag-mw-blank-description": "Vengiya na pele bıvurne",
        "tag-mw-replace": "Zerrek vurriya",
        "tag-mw-rollback": "Peyserardış",
-       "tag-mw-undo": "Peyser bıgê",
+       "tag-mw-undo": "Peyser bıgê",
        "tags-title": "Etiketi",
        "tags-intro": "Ena pele etiketê ke be vurnayışê nuşiyayışi ra nişan biyê û maneyê inan lista kena.",
        "tags-tag": "Nameyê etiketi",
        "htmlform-int-toohigh": "Ena değer ke ti spesife kerd maxsimumê $1î ra zafyer o.",
        "htmlform-required": "Ena deger lazim o",
        "htmlform-submit": "Bişirav",
-       "htmlform-reset": "Vurnayişî reyna biyar",
+       "htmlform-reset": "Vurnayışan peyser bıgê",
        "htmlform-selectorother-other": "Sewbi",
        "htmlform-no": "Nê",
        "htmlform-yes": "Eya",
        "logentry-rights-autopromote": "$1 otomatikmen $4 ra $5 {{GENDER:$2|terfi bi}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|bar kerd}} $3",
        "logentry-upload-overwrite": "$1 versiyonê $3 {{GENDER:$2|bar kerd}}",
-       "logentry-upload-revert": "$1, {{GENDER:$2|bar kerd}} $3",
+       "logentry-upload-revert": "$1, {{GENDER:$2|bar kerd}} $3\n\n$1 peyser {{GENDER:$2|na}} be yew versiyonê keheni $3 ra",
        "log-name-managetags": "Qeydê idareyê etiketi",
        "log-name-tag": "Qeydê etiketi",
        "rightsnone": "(çıniyo)",
        "date-range-from": "Nê tarixi ra:",
        "date-range-to": "Heta nê tarixi:",
        "randomrootpage": "Pela raştameya rıçıkıne",
-       "log-action-filter-block": "Tipê kılitkerdışi:",
+       "log-action-filter-block": "Tewrê kılitkerdışi:",
+       "log-action-filter-contentmodel": "Tewrê vurnayışê modelê zerreki:",
        "log-action-filter-delete": "Tewrê esterıtışi:",
        "log-action-filter-import": "Tewrê zerrenayışi:",
        "log-action-filter-move": "Tewrê berdışi:",
        "log-action-filter-block-reblock": "Vurniyayışê kılitkerdışi",
        "log-action-filter-block-unblock": "Ake",
        "log-action-filter-contentmodel-change": "Modelê zerreki bıvurne",
+       "log-action-filter-contentmodel-new": "Ebe modelê zerrekiyê nêhesabiyayeyi ra vıraştışê pele",
        "log-action-filter-delete-delete": "Esterıtışê pele",
+       "log-action-filter-delete-delete_redir": "Serşıkıtışi sero bınusne",
        "log-action-filter-delete-restore": "Esterıtışê pele peyser bıgê",
-       "log-action-filter-delete-event": "Rocek esterıtış",
+       "log-action-filter-delete-event": "Esterıtışê roceki",
+       "log-action-filter-delete-revision": "Esterıtışê çımraviyarnayışi",
+       "log-action-filter-import-interwiki": "Zerrenayışê Transwikiyi",
+       "log-action-filter-import-upload": "Ebe barkerdışê XMLi ra zerre ke",
+       "log-action-filter-upload-revert": "Wegeyrayış",
        "authprovider-resetpass-skip-label": "Ravêre",
        "authprovider-resetpass-skip-help": "Peysereştışê parola ra bıvêre.",
        "authform-notoken": "Tokeno kemi",
index 091c69f..70bf7e3 100644 (file)
        "undo-failure": "Η επεξεργασία δεν μπορούσε να αναστραφεί λόγω αντικρουόμενων ενδιάμεσων επεξεργασιών.",
        "undo-norev": "Η ανάκληση αυτής της επεξεργασίας δεν ηταν δυνατό να πραγματοποιηθεί επειδή δεν υπάρχει ή επειδή έχει διαγραφεί.",
        "undo-nochange": "Η επεξεργασία φαίνεται να έχει ήδη αναιρεθεί.",
-       "undo-summary": "Αναίρεση αναθεώρησης $1 υπό τον/την [[Special:Contribs/$2|$2]] ([[User talk:$2|Συζήτηση]])",
+       "undo-summary": "Αναίρεση αναθεώρησης $1 από {{GENDER:$2|τον|την}} [[Special:Contribs/$2|$2]] ([[User talk:$2|Συζήτηση]])",
        "undo-summary-username-hidden": "Αναίρεση αναθεώρησης $1 από ένα κρυμμένο χρήστη",
        "cantcreateaccount-text": "Η δημιουργία λογαριασμού από αυτή τη διεύθυνση IP ('''$1''') έχει αποτραπεί από τον [[User:$3|$3]].\n\nΟ λόγος που δόθηκε από τον $3 είναι ''$2''",
        "cantcreateaccount-range-text": "Η δημιουργία λογαριασμού από διευθύνσεις IP στην περιοχή  <strong>$1</strong>, που περιλαμβάνει τη δική σας διεύθυνση IP (<strong>$4</strong>), έχει αποκλειστεί από τον [[User:$3|$3]].\n\nΗ αιτιολογία που δόθηκε από τον $3 είναι \"$2\"",
        "revertpage": "Ανάκληση των αλλαγών [[Special:Contributions/$2|$2]] ([[User talk:$2|συζήτηση]]) επιστροφή στην προηγούμενη αναθεώρηση [[User:$1|$1]]",
        "revertpage-nouser": "Αναστράφηκαν οι επεξεργασίες από τον (όνομα χρήστη αφαιρέθηκε) στη τελευταία έκδοση από τον/την {{GENDER:$1|[[User:$1|$1]]}}φ",
        "rollback-success": "Αναστροφή επεξεργασιών από {{GENDER:$3|τον|την}} $1, επιστροφή στην προηγούμενη έκδοση από {{GENDER:$4|τον|την}} $2.",
-       "rollback-success-notify": "Αναίρεση επεξεργασιών από $1; επιστροφή στην τελευταία αναθεώρηση από $2.[$3 Εμφάνιση αλλαγών]",
        "sessionfailure-title": "Η συνεδρία απέτυχε",
        "sessionfailure": "Υπάρχει πρόβλημα με τη σύνδεσή σας -η ενέργεια αυτή ακυρώθηκε προληπτικά για την αντιμετώπιση τυχόν πειρατείας συνόδου (session hijacking). Παρακαλoύμε πατήστε \"Επιστροφή\", ξαναφορτώστε τη σελίδα από την οποία φθάσατε εδώ και προσπαθήστε ξανά.",
        "changecontentmodel": "Αλλαγή μοντέλου περιεχομένου της σελίδας",
        "pageinfo-category-subcats": "Αριθμός υποκατηγοριών",
        "pageinfo-category-files": "Αριθμός αρχείων",
        "pageinfo-user-id": "Αναγνωριστικό χρήση",
+       "pageinfo-view-protect-log": "Δείτε το αρχείο καταγραφών προστασίας για αυτή τη σελίδα.",
        "markaspatrolleddiff": "Σήμανση ως ελεγμένο",
        "markaspatrolledtext": "Σήμανση αυτής της σελίδας ως ελεγμένης",
        "markaspatrolledtext-file": "Επισημάνετε αυτή τη έκδοση του αρχείου ως ελεγμένη",
        "log-action-filter-upload-upload": "Νέα μεταφόρτωση",
        "log-action-filter-upload-overwrite": "Επαναμεταφόρτωση",
        "authmanager-create-disabled": "Η δημιουργία λογαριασμού έχει απενεργοποιηθεί.",
-       "authmanager-authplugin-setpass-failed-title": "Η αλλαγή κωδικού πρόσβασης απέτυχε",
        "authmanager-email-label": "Διεύθυνση ηλ. ταχυδρομείου",
        "authmanager-email-help": "Διεύθυνση ηλεκτρονικού ταχυδρομείου:",
        "authmanager-realname-label": "Πραγματικό όνομα",
index 34c4c97..6f81c4b 100644 (file)
        "edit": "Edit",
        "edit-local": "Edit local description",
        "create": "Create",
-       "create-local": "Add local description",
        "delete": "Delete",
        "undelete_short": "Undelete {{PLURAL:$1|one edit|$1 edits}}",
        "viewdeleted_short": "View {{PLURAL:$1|one deleted edit|$1 deleted edits}}",
index c371cc2..56ff467 100644 (file)
@@ -46,6 +46,7 @@
        "tog-norollbackdiff": "Don't show diff after performing a rollback",
        "tog-useeditwarning": "Warn me when I leave an edit page with unsaved changes",
        "tog-prefershttps": "Always use a secure connection while logged in",
+       "tog-showrollbackconfirmation": "Show a confirmation prompt when clicking on a rollback link",
        "underline-always": "Always",
        "underline-never": "Never",
        "underline-default": "Skin or browser default",
        "badretype": "The passwords you entered do not match.",
        "usernameinprogress": "An account creation for this user name is already in progress.\nPlease wait.",
        "userexists": "Username entered already in use.\nPlease choose a different name.",
+       "createacct-normalization": "Your username will be adjusted to \"$2\" due to technical restrictions.",
        "loginerror": "Login error",
        "createacct-error": "Account creation error",
        "createaccounterror": "Could not create account: $1",
        "page_first": "first",
        "page_last": "last",
        "histlegend": "Diff selection: Mark the radio boxes of the revisions to compare and hit enter or the button at the bottom.<br />\nLegend: <strong>({{int:cur}})</strong> = difference with latest revision, <strong>({{int:last}})</strong> = difference with preceding revision, <strong>{{int:minoreditletter}}</strong> = minor edit.",
-       "history-fieldset-title": "Search for revisions",
+       "history-fieldset-title": "Filter revisions",
        "history-show-deleted": "Revision deleted only",
        "history_copyright": "-",
        "histfirst": "oldest",
        "histlast": "newest",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
-       "historyempty": "(empty)",
+       "historyempty": "empty",
        "history-feed-title": "Revision history",
        "history-feed-description": "Revision history for this page on the wiki",
        "history-feed-item-nocomment": "$1 at $2",
        "right-reupload-own": "Overwrite existing files uploaded by oneself",
        "right-reupload-shared": "Override files on the shared media repository locally",
        "right-upload_by_url": "Upload files from a URL",
-       "right-purge": "Purge the site cache for a page without confirmation",
+       "right-purge": "Purge the site cache for a page",
        "right-autoconfirmed": "Not be affected by IP-based rate limits",
        "right-bot": "Be treated as an automated process",
        "right-nominornewtalk": "Not have minor edits to discussion pages trigger the new messages prompt",
        "action-changetags": "add and remove arbitrary tags on individual revisions and log entries",
        "action-deletechangetags": "delete tags from the database",
        "action-purge": "purge this page",
+       "action-apihighlimits": "use higher limits in API queries",
+       "action-autoconfirmed": "not be affected by IP-based rate limits",
+       "action-bigdelete": "delete pages with large histories",
+       "action-blockemail": "block a user from sending email",
+       "action-bot": "be treated as an automated process",
+       "action-editprotected": "edit pages protected as \"{{int:protect-level-sysop}}\"",
+       "action-editsemiprotected": "edit pages protected as \"{{int:protect-level-autoconfirmed}}\"",
+       "action-editinterface": "edit the user interface",
+       "action-editusercss": "edit other users' CSS files",
+       "action-edituserjson": "edit other users' JSON files",
+       "action-edituserjs": "edit other users' JavaScript files",
+       "action-editsitecss": "edit sitewide CSS",
+       "action-editsitejson": "edit sitewide JSON",
+       "action-editsitejs": "edit sitewide JavaScript",
+       "action-editmyusercss": "edit your own user CSS files",
+       "action-editmyuserjson": "edit your own user JSON files",
+       "action-editmyuserjs": "edit your own user JavaScript files",
+       "action-viewsuppressed": "view revisions hidden from any user",
+       "action-hideuser": "block a username, hiding it from the public",
+       "action-ipblock-exempt": "bypass IP blocks, auto-blocks and range blocks",
+       "action-unblockself": "unblock oneself",
+       "action-noratelimit": "not be affected by rate limits",
+       "action-reupload-own": "overwrite existing files uploaded by oneself",
+       "action-nominornewtalk": "not have minor edits to discussion pages trigger the new messages prompt",
+       "action-markbotedits": "mark rolled-back edits as bot edits",
+       "action-patrolmarks": "view recent changes patrol marks",
+       "action-override-export-depth": "export pages including linked pages up to a depth of 5",
+       "action-suppressredirect": "not create redirects from source pages when moving pages",
        "nchanges": "$1 {{PLURAL:$1|change|changes}}",
        "ntimes": "$1×",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|since last visit}}",
        "delete-confirm": "Delete \"$1\"",
        "delete-legend": "Delete",
        "historywarning": "<strong>Warning:</strong> The page you are about to delete has a history with $1 {{PLURAL:$1|revision|revisions}}:",
-       "historyaction-submit": "Show",
+       "historyaction-submit": "Show revisions",
        "confirmdeletetext": "You are about to delete a page along with all of its history.\nPlease confirm that you intend to do this, that you understand the consequences, and that you are doing this in accordance with [[{{MediaWiki:Policy-url}}|the policy]].",
        "actioncomplete": "Action complete",
        "actionfailed": "Action failed",
        "deleting-backlinks-warning": "<strong>Warning:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Other pages]] link to or transclude the page you are about to delete.",
        "deleting-subpages-warning": "<strong>Warning:</strong> The page you are about to delete has [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|a subpage|$1 subpages|51=over 50 subpages}}]].",
        "rollback": "Roll back edits",
+       "rollback-confirmation-confirm": "Please confirm:",
+       "rollback-confirmation-yes": "Rollback",
+       "rollback-confirmation-no": "Cancel",
        "rollbacklink": "rollback",
        "rollbacklinkcount": "rollback $1 {{PLURAL:$1|edit|edits}}",
        "rollbacklinkcount-morethan": "rollback more than $1 {{PLURAL:$1|edit|edits}}",
        "revertpage": "Reverted edits by [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]]) to last revision by [[User:$1|$1]]",
        "revertpage-nouser": "Reverted edits by a hidden user to last revision by {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Reverted edits by {{GENDER:$3|$1}};\nchanged back to last revision by {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Reverted edits by $1;\nchanged back to last revision by $2. [$3 Show changes]",
        "sessionfailure-title": "Session failure",
        "sessionfailure": "There seems to be a problem with your login session;\nthis action has been canceled as a precaution against session hijacking.\nPlease resubmit the form.",
        "changecontentmodel" : "Change content model of a page",
        "mycontris": "Contributions",
        "anoncontribs": "Contributions",
        "contribsub2": "For {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "For {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "User account \"$1\" is not registered.",
        "negative-namespace-not-supported": "Namespaces with negative values are not supported.",
        "nocontribs": "No changes were found matching these criteria.",
        "ipb-confirm": "Confirm block",
        "ipb-sitewide": "Sitewide",
        "ipb-partial": "Partial",
+       "ipb-sitewide-help": "Every page on the wiki and all other contribution actions.",
+       "ipb-partial-help": "Specific pages or namespaces.",
        "ipb-pages-label": "Pages",
        "ipb-namespaces-label": "Namespaces",
        "badipaddress": "Invalid IP address",
        "confirm-unwatch-top": "Remove this page from your watchlist?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Revert edits to this page?",
+       "confirm-rollback-bottom": "This action will instantly rollback the selected changes to this page.",
        "confirm-mcrrestore-title": "Restore a revision",
        "confirm-mcrundo-title": "Undo a change",
        "mcrundofailed": "Undo failed",
        "logentry-rights-autopromote": "$1 was automatically {{GENDER:$2|promoted}} from $4 to $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|uploaded}} a new version of $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|uploaded}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|reverted}} $3 to an old version",
        "log-name-managetags": "Tag management log",
        "log-description-managetags": "This page lists management tasks related to [[Special:Tags|tags]]. The log contains only actions carried out manually by an administrator; tags may be created or deleted by the wiki software without an entry being recorded in this log.",
        "logentry-managetags-create": "$1 {{GENDER:$2|created}} the tag \"$4\"",
        "log-action-filter-suppress-reblock": "User suppression by reblock",
        "log-action-filter-upload-upload": "New upload",
        "log-action-filter-upload-overwrite": "Reupload",
+       "log-action-filter-upload-revert": "Revert",
        "authmanager-authn-not-in-progress": "Authentication is not in progress or session data has been lost. Please start again from the beginning.",
        "authmanager-authn-no-primary": "The supplied credentials could not be authenticated.",
        "authmanager-authn-no-local-user": "The supplied credentials are not associated with any user on this wiki.",
        "authmanager-create-no-primary": "The supplied credentials could not be used for account creation.",
        "authmanager-link-no-primary": "The supplied credentials could not be used for account linking.",
        "authmanager-link-not-in-progress": "Account linking is not in progress or session data has been lost. Please start again from the beginning.",
-       "authmanager-authplugin-setpass-failed-title": "Password change failed",
-       "authmanager-authplugin-setpass-failed-message": "The authentication plugin denied the password change.",
-       "authmanager-authplugin-create-fail": "The authentication plugin denied the account creation.",
-       "authmanager-authplugin-setpass-denied": "The authentication plugin does not allow changing passwords.",
-       "authmanager-authplugin-setpass-bad-domain": "Invalid domain.",
        "authmanager-autocreate-noperm": "Automatic account creation is not allowed.",
        "authmanager-autocreate-exception": "Automatic account creation temporarily disabled due to prior errors.",
        "authmanager-userdoesnotexist": "User account \"$1\" is not registered.",
        "passwordpolicies-group": "Group",
        "passwordpolicies-policies": "Policies",
        "passwordpolicies-policy-display": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span>",
+       "passwordpolicies-policy-displaywithflags": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span> <span class=\"passwordpolicies-policy-flags\">($3)</span>",
        "passwordpolicies-policy-minimalpasswordlength": "Password must be at least $1 {{PLURAL:$1|character|characters}} long",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "Password must be at least $1 {{PLURAL:$1|character|characters}} long to be able to login",
        "passwordpolicies-policy-passwordcannotmatchusername": "Password cannot be the same as username",
        "passwordpolicies-policy-maximalpasswordlength": "Password must be less than $1 {{PLURAL:$1|character|characters}} long",
        "passwordpolicies-policy-passwordcannotbepopular": "Password cannot be {{PLURAL:$1|the popular password|in the list of $1 popular passwords}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Password cannot be in the list of 100,000 most commonly used passwords.",
+       "passwordpolicies-policyflag-forcechange": "must change on login",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "suggest change on login",
        "easydeflate-invaliddeflate": "Content provided is not properly deflated",
        "unprotected-js": "For security reasons JavaScript cannot be loaded from unprotected pages. Please only create javascript in the MediaWiki: namespace or as a User subpage"
 }
index f8507b8..21a3ef0 100644 (file)
        "accmailtext": "Hazarde generita pasvorto por [[User talk:$1|$1]] estas sendita al $2.\n\nLa pasvorto por ĉi tiu nova konto povas esti ŝanĝita en la paĝo ''[[Special:ChangePassword|ŝanĝi pasvorton]]'' dum ensalutado.",
        "newarticle": "(Nova)",
        "newarticletext": "Vi sekvis ligilon al paĝo ankoraŭ ne ekzistanta. Se vi volas krei ĝin, ektajpu malsupre (vidu la [$1 helpopaĝon] por klarigoj.) Se vi malintence alvenis ĉi tien, simple alklaku <strong>Reen</strong>-butonon de via retumilo.",
-       "anontalkpagetext": "<em>Jen diskutopaĝo por anonima kontribuanto kiu ankoraŭ ne kreis konton aŭ ne uzas ĝin.</em>\nNi tial devas uzi la cifran IP-adreson por identigi tiun kontribuanton.\nĈi tia IP-adreso povas esti uzata de pluraj uzantoj.\nSe vi estas anonimulo kaj preferus eviti tiajn mistrafajn komentojn al vi, bonvolu [[Special:CreateAccount|krei konton]] aŭ [[Special:UserLogin|ensaluti]] por eviti estontan konfuzon pro aliaj anonimaj uzantoj.''",
+       "anontalkpagetext": "----\n<em>Jen diskutopaĝo por anonima kontribuanto kiu ankoraŭ ne kreis konton aŭ ne uzas ĝin.</em>\nNi tial devas uzi nombran IP-adreson por identigi tiun kontribuanton.\nĈi tia IP-adreso povas esti uzata de pluraj uzantoj.\nSe vi estas anonimulo kaj preferus eviti tiajn mistrafajn komentojn al vi, bonvolu [[Special:CreateAccount|krei konton]] aŭ [[Special:UserLogin|ensaluti]] por eviti estontan konfuzon pro aliaj anonimaj uzantoj.",
        "noarticletext": "Mankas teksto en ĉi tiu paĝo.\nVi povas [[Special:Search/{{PAGENAME}}|serĉi ĉi tiun paĝtitolon]] en aliaj paĝoj,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serĉi la rilatajn protokolojn],\naŭ [{{fullurl:{{FULLPAGENAME}}|action=edit}} krei ĉi tiun paĝon]</span>.",
        "noarticletext-nopermission": "Estas neniom da teksto en ĉi tiu paĝo.\nVi povas [[Special:Search/{{PAGENAME}}|serĉi ĉi tiun paĝan titolon]] en aliaj paĝoj,\naŭ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serĉi la rilatajn protokolojn]</span>, sed vi ne rajtas krei ĉi tiun paĝon.",
        "missing-revision": "La revizio n-ro $1 de la paĝo nomata \"{{FULLPAGENAME}}\" ne ekzistas.\n\nTio kutime estas kaŭzata per sekvado de malaktuala historio-ligilo al paĝo forigita.\nDetaloj troveblos en la [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de forigoj].",
        "revertpage": "Malfaris redaktojn de [[Special:Contributions/$2|$2]] ([[User talk:$2|diskuto]]) al la lasta versio de [[User:$1|$1]]",
        "revertpage-nouser": "Restarigis redaktojn de (salutnomo forigita) al lasta revizio de {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Restaris redaktojn de {{GENDER:$3|$1}}; ŝanĝis al lasta versio de {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Malfaritis redaktojn far $1;\nŝanĝis al la lasta reviziaĵo far $2. [$3 Prezenti ŝanĝojn]",
        "sessionfailure-title": "Seanco malsukcesis",
        "sessionfailure": "Ŝajnas, ke estas problemo kun via ensalutado;\nĈi ago estis nuligita por malhelpi fiensalutadon.\nBonvolu resendi la formularoj",
        "changecontentmodel": "Ŝanĝi la enhavomodelon de paĝo",
        "authmanager-create-no-primary": "La provizitaj legitimaĵoj ne povus esti uzita por konta kreo.",
        "authmanager-link-no-primary": "La provizitaj legitimaĵoj ne povus esti uzita por konta ligado.",
        "authmanager-link-not-in-progress": "La kontokreado ne estas progresanta aŭ la sencaj datumoj perdiĝis. Bonvolu provi denove ekde la komenco.",
-       "authmanager-authplugin-setpass-failed-title": "Pasvorta ŝanĝo malsukcesis",
-       "authmanager-authplugin-setpass-failed-message": "La aŭtentikigado kromprogramo neis la pasvortan ŝanĝon.",
-       "authmanager-authplugin-create-fail": "La kromprogramo de aŭtentikigado neis la keon de konto.",
-       "authmanager-authplugin-setpass-denied": "La kromprogramaro de aŭtentikigado ne permisas ŝanĝadon de pasvorto.",
-       "authmanager-authplugin-setpass-bad-domain": "Malvalida domajno.",
        "authmanager-autocreate-noperm": "Aŭtomata kreo de konto ne estas permesita.",
        "authmanager-autocreate-exception": "Aŭtomata kreo de konto estas provizore malfunkciigita pro antaŭaj eraroj.",
        "authmanager-userdoesnotexist": "Uzanto-konto \"$1\" ne estas registrita.",
index 0a036b3..5078817 100644 (file)
                        "Laura Ospina",
                        "Pipino-pumuki",
                        "Carlosmg.dg",
-                       "Mynor Archila"
+                       "Mynor Archila",
+                       "Jorge Ubilla",
+                       "Marcelo9987"
                ]
        },
        "tog-underline": "Enlaces a subrayar:",
        "tog-norollbackdiff": "No mostrar la lista de diferencias después de revertir",
        "tog-useeditwarning": "Avisarme cuando abandone una página en edición con cambios sin guardar",
        "tog-prefershttps": "Utilizar siempre conexiones seguras en mis sesiones",
+       "tog-showrollbackconfirmation": "Mostrar una pantalla de confirmación al hacer clic en un enlace de reversión",
        "underline-always": "Siempre",
        "underline-never": "Nunca",
        "underline-default": "Configuración predeterminada de la apariencia o el navegador",
        "badretype": "Las contraseñas no coinciden.",
        "usernameinprogress": "Ya está en marcha la creación de una cuenta para este nombre de usuario.\nEspera.",
        "userexists": "El nombre de usuario indicado ya está en uso.\nElige un nombre diferente.",
+       "createacct-normalization": "Tu nombre de usuario será \"$2\" debido a restricciones técnicas.",
        "loginerror": "Error de inicio de sesión",
        "createacct-error": "Error al crear la cuenta",
        "createaccounterror": "No se pudo crear la cuenta: $1",
        "edit-gone-missing": "No se ha podido actualizar la página.\nParece haber sido borrada.",
        "edit-conflict": "Conflicto de edición.",
        "edit-no-change": "Se ignoró tu edición porque no se hizo ningún cambio en el texto.",
-       "edit-slots-cannot-add": "{{PLURAL:$1|La siguiente ranura no es soportada|Las siguientes ranuras no son soportadas}} aquí:",
+       "edit-slots-cannot-add": "{{PLURAL:$1|La siguiente ranura no es soportada|Las siguientes ranuras no son soportadas}} aquí: $2.",
+       "edit-slots-cannot-remove": "Se {{PLURAL:$1|requiere el siguiente espacio y no puede ser eliminado|requieren los siguientes espacios y no pueden ser eliminados}}: $2.",
        "edit-slots-missing": "{{PLURAL:$1|Falta el siguiente espacio|Faltan los siguientes espacios}}: $2",
        "postedit-confirmation-created": "Se ha creado la página.",
        "postedit-confirmation-restored": "Se ha restaurado la página.",
        "right-reupload-own": "Subir una nueva versión de un archivo propio",
        "right-reupload-shared": "Sobrescribir localmente archivos presentes en el repositorio multimedia compartido",
        "right-upload_by_url": "Subir un archivo a traves de un URL",
-       "right-purge": "Purgar la antememoria de una página sin confirmación",
+       "right-purge": "Purgar la caché de una página en el servidor",
        "right-autoconfirmed": "No resultar afectado por los límites de frecuencia de edición para las IP",
        "right-bot": "Ser tratado como un proceso automático",
        "right-nominornewtalk": "No accionar el aviso de mensajes nuevos al realizar ediciones menores en páginas de discusión",
        "removedwatchtext-short": "La página \"$1\" ha sido eliminada de tu lista de seguimiento.",
        "watch": "Vigilar",
        "watchthispage": "Vigilar esta página",
-       "unwatch": "Desmarcar",
+       "unwatch": "Dejar de vigilar",
        "unwatchthispage": "Dejar de vigilar",
        "notanarticle": "No es una página de contenido",
        "notvisiblerev": "La última revisión de un usuario diferente ha sido borrada",
        "revertpage": "Revertidos los cambios de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc.]]) a la última edición de [[User:$1|$1]]",
        "revertpage-nouser": "Revertidas las ediciones hechas por un usuario oculto a la última revisión hecha por {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Revertidas las ediciones de {{GENDER:$3|$1}};\nrecuperada la última versión de {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Revertidas las ediciones de $1 hasta la última revisión de $2. [$3 Ver cambios]",
        "sessionfailure-title": "Error de sesión",
        "sessionfailure": "Parece que hay un problema con tu sesión;\nse ha cancelado esta acción como medida de precaución contra el robo de sesiones.\nEnvía el formulario otra vez.",
        "changecontentmodel": "Cambiar el modelo de contenido de una página",
        "mycontris": "Contribuciones",
        "anoncontribs": "Contribuciones",
        "contribsub2": "Para {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Para {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "La cuenta de usuario «$1» no está registrada.",
+       "negative-namespace-not-supported": "Los espacios de nombres con valores negativos no están permitidos",
        "nocontribs": "No se encontraron cambios que cumplieran estos criterios.",
        "uctop": "última",
        "month": "Desde el mes (y anteriores):",
        "ipb-confirm": "Confirmar bloqueo",
        "ipb-sitewide": "En todo el sitio",
        "ipb-partial": "Parcial",
+       "ipb-sitewide-help": "Todas las páginas del wiki y el resto de las acciones de contribución.",
+       "ipb-partial-help": "Páginas concretas o espacios de nombres.",
        "ipb-pages-label": "Páginas",
        "ipb-namespaces-label": "Espacios de nombres",
        "badipaddress": "La dirección IP no tiene el formato correcto.",
        "recreate": "Recrear",
        "confirm-purge-title": "Purgar esta página",
        "confirm_purge_button": "Aceptar",
-       "confirm-purge-top": "¿Quieres vaciar la antememoria de esta página?",
-       "confirm-purge-bottom": "Purgar una página limpia la antememoria y fuerza a que aparezca la versión más actual.",
+       "confirm-purge-top": "¿Quieres vaciar la caché de esta página?",
+       "confirm-purge-bottom": "Purgar una página limpia la caché y fuerza a que aparezca la versión más actual.",
        "confirm-watch-button": "Aceptar",
        "confirm-watch-top": "¿Añadir esta página a tu lista de seguimiento?",
        "confirm-unwatch-button": "Aceptar",
        "logentry-rights-autopromote": "$1 ha sido {{GENDER:$2|promocionado|promocionada}} automáticamente de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|subió}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|subió}} una nueva versión de $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|subió}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|revirtió}} $3 a una versión anterior",
        "log-name-managetags": "Registro de gestión de etiquetas",
        "log-description-managetags": "Esta página muestra las acciones realizadas sobre las [[Special:Tags|etiquetas]]. El registro solo contiene acciones llevadas a cabo por un administrador de forma manual; el software del wiki podría crear o eliminar etiquetas sin que se registre aquí.",
        "logentry-managetags-create": "$1 {{GENDER:$2|creó}} la etiqueta «$4»",
        "log-action-filter-suppress-reblock": "Usuario supresión de rebloqueo",
        "log-action-filter-upload-upload": "Subida nueva",
        "log-action-filter-upload-overwrite": "Volver a subir",
+       "log-action-filter-upload-revert": "Revertir",
        "authmanager-authn-not-in-progress": "La autenticación no está en curso o los datos de sesión se han perdido. Por favor, vuelve a empezar desde el principio.",
        "authmanager-authn-no-primary": "Las credenciales proporcionadas no se han podido autentificar.",
        "authmanager-authn-no-local-user": "Las credenciales suministradas no están asociadas con ningún usuario en este wiki.",
        "authmanager-create-no-primary": "Las credenciales suministradas no pueden usarse para la creación de la cuenta.",
        "authmanager-link-no-primary": "Las credenciales proporcionadas no se han podido utilizar para enlazar cuentas.",
        "authmanager-link-not-in-progress": "La vinculación de cuentas no está en curso o los datos de la sesión se han perdido. Por favor, vuelve a empezar desde el principio.",
-       "authmanager-authplugin-setpass-failed-title": "Error de cambio de contraseña",
-       "authmanager-authplugin-setpass-failed-message": "El complemento de autenticación denegó el cambio de contraseña.",
-       "authmanager-authplugin-create-fail": "El complemento de autenticación denegó la creación de la cuenta.",
-       "authmanager-authplugin-setpass-denied": "El complemento de autenticación no permite el cambio de contraseñas.",
-       "authmanager-authplugin-setpass-bad-domain": "El dominio no es válido.",
        "authmanager-autocreate-noperm": "La creación automática de cuentas no está permitida.",
        "authmanager-autocreate-exception": "La creación automática de cuentas ha sido temporalmente desactivada debido a errores previos.",
        "authmanager-userdoesnotexist": "El usuario «$1» no está registrado.",
        "passwordpolicies-policy-maximalpasswordlength": "La contraseña no puede tener más de $1 {{PLURAL:$1|caracter|caracteres}}",
        "passwordpolicies-policy-passwordcannotbepopular": "La contraseña no puede {{PLURAL:$1|ser la contraseña más popular|encontrarse en la lista de $1 contraseñas populares}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "La contraseña no puede estar en la lista de las 100.000 contraseñas más usadas.",
+       "passwordpolicies-policyflag-forcechange": "debe cambiar al acceder a la cuenta",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "sugerir cambio al acceder a la cuenta",
        "easydeflate-invaliddeflate": "El contenido proporcionado no esta comprimido correctamente",
        "unprotected-js": "Por razones de seguridad, JavaScript no se puede cargar desde páginas desprotegidas. Crea javascript solo en MediaWiki: espacio de nombres o como subpágina de usuario"
 }
index 25db9dd..a8515a9 100644 (file)
@@ -78,6 +78,7 @@
        "tog-norollbackdiff": "Ära näita erinevusi pärast tühistamist",
        "tog-useeditwarning": "Hoiata mind, kui lahkun redigeerimisleheküljelt muudatusi salvestamata",
        "tog-prefershttps": "Kasuta sisselogimisel alati turvalist ühendust",
+       "tog-showrollbackconfirmation": "Küsi tühistamislingile klõpsamise järel kinnitust",
        "underline-always": "Alati",
        "underline-never": "Mitte kunagi",
        "underline-default": "Kujunduse või brauseri vaikeväärtus",
        "badretype": "Sisestatud paroolid ei lange kokku.",
        "usernameinprogress": "Selle kasutajanimega konto loomine on juba pooleli.\nPalun oota.",
        "userexists": "Sisestatud kasutajanimi on juba kasutusel.\nPalun valige uus nimi.",
+       "createacct-normalization": "Tehniliste piirangute tõttu kohandatakse sinu kasutajanimi kujule \"$2\".",
        "loginerror": "Viga sisselogimisel",
        "createacct-error": "Tõrge konto loomisel",
        "createaccounterror": "Kasutajakonto loomine ebaõnnestus: $1",
        "deleting-backlinks-warning": "<strong>Hoiatus:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Teised leheküljed]] viitavad leheküljele, mida oled kustutamas, või see lehekülg on kasutuses mallina.",
        "deleting-subpages-warning": "<strong>Hoiatus:</strong> Oled kustutamas lehekülge, millel on [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|alamlehekülg|$1 alamlehekülge|51=üle 50 alamlehekülje}}]].",
        "rollback": "Tühista muudatused",
+       "rollback-confirmation-confirm": "Palun kinnita:",
+       "rollback-confirmation-yes": "Tühista",
+       "rollback-confirmation-no": "Loobu",
        "rollbacklink": "tühista",
        "rollbacklinkcount": "tühista {{PLURAL:$1|üks muudatus|$1 muudatust}}",
        "rollbacklinkcount-morethan": "tühista üle {{PLURAL:$1|ühe muudatuse|10 muudatuse}}",
        "revertpage": "Tühistati kasutaja [[Special:Contributions/$2|$2]] ([[User talk:$2|arutelu]]) tehtud muudatused ja pöörduti tagasi viimasele muudatusele, mille tegi [[User:$1|$1]].",
        "revertpage-nouser": "Tühistati peidetud kasutaja muudatused ja pöörduti tagasi viimasele muudatusele, mille tegi [[User:$1|$1]].",
        "rollback-success": "Tühistati muudatused, mille tegi {{GENDER:$3|$1}};\npöörduti tagasi viimasele muudatusele, mille tegi {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Tühistatud kasutaja $1 tehtud muudatused;\npöördutud tagasi kasutaja $2 viimase redaktsiooni juurde. [$3 Näita muudatusi]",
        "sessionfailure-title": "Seansiviga",
        "sessionfailure": "Näib, et sinu sisselogimisseanss on probleemne.\nSeansiärandamise vastase ettevaatusabinõuna on see toiming tühistatud.\nPalun saada vorm uuesti.",
        "changecontentmodel": "Lehekülje sisumudeli muutmine",
        "ipb-confirm": "Kinnita blokeering",
        "ipb-sitewide": "Saidiülene",
        "ipb-partial": "Osaline",
+       "ipb-sitewide-help": "Viki kõigi lehekülgede muutmine ja kogu ülejäänud kaastöö.",
+       "ipb-partial-help": "Teatud lehekülgede või nimeruumide muutmine.",
        "ipb-pages-label": "Leheküljed",
        "ipb-namespaces-label": "Nimeruumid",
        "badipaddress": "Vigane IP-aadress",
        "confirm-unwatch-top": "Kas eemaldad selle lehekülje oma jälgimisloendist?",
        "confirm-rollback-button": "Sobib",
        "confirm-rollback-top": "Kas tühistad sellel leheküljel tehtud muudatused?",
+       "confirm-rollback-bottom": "See toiming tühistab koheselt valitud muudatused sellel leheküljel.",
        "confirm-mcrrestore-title": "Redaktsiooni taastamine",
        "confirm-mcrundo-title": "Muudatuse eemaldamine",
        "mcrundofailed": "Eemaldamine ebaõnnestus",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|viidi}} automaatselt üle teise rühma; enne oli $4, nüüd on $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|laadis üles}} faili $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|laadis üles}} uue versiooni failist $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|laadis üles}} faili $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|taastas}} faili $3 vanema versiooni",
        "log-name-managetags": "Märgiste haldamise logi",
        "log-description-managetags": "Sellel leheküljel on toodud [[Special:Tags|märgiste]] haldamisega seotud tegevused. Logis on ainult toimingud, mida administraatorid on teinud käsitsi. Siin puuduvad logisissekanded viki tarkvaras koostatud või sealt kustutatud märgiste kohta.",
        "logentry-managetags-create": "$1 {{GENDER:$2|koostas}} märgise \"$4\"",
        "log-action-filter-suppress-reblock": "Kasutaja varjamine taasblokeerimise teel",
        "log-action-filter-upload-upload": "Uus üleslaadimine",
        "log-action-filter-upload-overwrite": "Uuesti üleslaadimine",
+       "log-action-filter-upload-revert": "Taastamine",
        "authmanager-authn-not-in-progress": "Autentimine pole teoksil või seansiandmed läksid kaduma. Palun alusta uuesti.",
        "authmanager-authn-no-primary": "Ette antud autentimisandmeid ei õnnestunud autentida.",
        "authmanager-authn-no-local-user": "Ette antud autentimisandmed pole selles vikis seotud ühegi kasutajaga.",
        "authmanager-create-no-primary": "Ette antud autentimisandmetega ei õnnestunud kontot luua.",
        "authmanager-link-no-primary": "Ette antud autentimisandmetega ei õnnestunud kontot linkida.",
        "authmanager-link-not-in-progress": "Konto linkimine pole teoksil või läksid seansiandmed kaduma. Palun alusta uuesti.",
-       "authmanager-authplugin-setpass-failed-title": "Parooli muutmine ebaõnnestus",
-       "authmanager-authplugin-setpass-failed-message": "Autentimise tarkvaralisa keeldus parooli muutmast.",
-       "authmanager-authplugin-create-fail": "Autentimise tarkvaralisa keeldus kontot loomast.",
-       "authmanager-authplugin-setpass-denied": "Autentimise tarkvaralisa ei luba paroole muuta.",
-       "authmanager-authplugin-setpass-bad-domain": "Vigane domeen.",
        "authmanager-autocreate-noperm": "Kontode automaatne loomine pole lubatud.",
        "authmanager-autocreate-exception": "Kontode automaatne loomine on varasemate tõrgete tõttu ajutiselt keelatud.",
        "authmanager-userdoesnotexist": "Kasutajakonto \"$1\" pole registreeritud.",
        "passwordpolicies-policy-maximalpasswordlength": "Parool peab olema $1 {{PLURAL:$1|märgist}} lühem.",
        "passwordpolicies-policy-passwordcannotbepopular": "Parool ei tohi olla {{PLURAL:$1|populaarne parool|$1 populaarse parooli loendis}}.",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Parool ei saa olla 100&nbsp;000 kõige levinuma parooli loendis.",
+       "passwordpolicies-policyflag-forcechange": "peab muutma sisselogimisel",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "soovita muutmist sisselogimisel",
        "easydeflate-invaliddeflate": "Ette antud sisu ei ole õigesti vähendatud",
        "unprotected-js": "Turvalisuse huvides ei saa JavaScripti laadida kaitsmata lehekülgedelt. Palun koosta JavaScripti ainult nimeruumis MediaWiki või kasutajate nimeruumi alamleheküljel."
 }
index 69fba10..6ae07b3 100644 (file)
@@ -34,7 +34,9 @@
                        "Iñaki LL",
                        "Amaia",
                        "Matěj Suchánek",
-                       "CiaPan"
+                       "CiaPan",
+                       "Egonichan",
+                       "Isabel.losaneko"
                ]
        },
        "tog-underline": "Azpimarratu loturak:",
@@ -80,6 +82,7 @@
        "tog-norollbackdiff": "Lehengoratze bat egin ondoren ezberdintasunak ez erakutsi",
        "tog-useeditwarning": "Abisa nazazu gorde gabeko aldaketak eginez edizio orrialde bat uzten dudanean",
        "tog-prefershttps": "Erabili beti konexio seguru bat sartzerakoan",
+       "tog-showrollbackconfirmation": "Zabaldu baieztapen-leiho bat atzera-jotze esteka batean klik egiterakoan",
        "underline-always": "Beti",
        "underline-never": "Inoiz ez",
        "underline-default": "Lehenetsitako nabigatzailea",
        "editfont-monospace": "Monospace iturria",
        "editfont-sansserif": "Sans-serif iturria",
        "editfont-serif": "Serif iturria",
-       "sunday": "Igandea",
-       "monday": "Astelehena",
-       "tuesday": "Asteartea",
-       "wednesday": "Asteazkena",
-       "thursday": "Osteguna",
-       "friday": "Ostirala",
-       "saturday": "Larunbata",
+       "sunday": "igandea",
+       "monday": "astelehena",
+       "tuesday": "asteartea",
+       "wednesday": "asteazkena",
+       "thursday": "osteguna",
+       "friday": "ostirala",
+       "saturday": "larunbata",
        "sun": "Iga",
        "mon": "Asl",
        "tue": "Asr",
        "returnto": "$1(e)ra itzuli.",
        "tagline": "{{SITENAME}}tik",
        "help": "Laguntza",
+       "help-mediawiki": "MediaWikiri buruzko laguntza",
        "search": "Bilatu",
        "search-ignored-headings": " #<!-- utzi marra hau den bezala --> <pre>\n# Bilaketan ez ikusi egingo diren izenburuak.\n# Honetarako aldaketek eragina izango dute goiburua indexatuta dagoen orrialdean.\n# Orriaren birdefinizioa behartu dezakezu edizio nulua egiteaz.\n# Sintaxia horrela da:\n#   * \"#\" karakteretik marraren bukaerararte dagoen guztia iruzkina da.\n#   * Hutsunezko lerroa ez den bakoitza kontuan ez hartzeko izenburu zehatza da, kasu eta guzti.\nErreferentziak\nKanpoko linkak\nIkusi ere\n #</pre> <!-- utzi marra hau den bezala -->",
        "searchbutton": "Bilatu",
        "badretype": "Idatzitako pasahitzak ez dira berdinak.",
        "usernameinprogress": "Erabiltzaile honetarako kontu eraketa martxan dago jadanik. Mesedez, itxaron.",
        "userexists": "Aukeratutako erabiltzaile izena hartuta dago.\nMesedez beste bat aukeratu.",
+       "createacct-normalization": "Zure erabiltzaile-izena \"$2\" izango da murriztapen teknikoen ondorioz.",
        "loginerror": "Errorea saioa hastean",
        "createacct-error": "Kontua sortzerakoan arazoa",
        "createaccounterror": "Ezin izan da kontua sortu: $1",
        "passwordtooshort": "Pasahitzek {{PLURAL:$1|karaktere 1|$1 karaktere}} gutxienez eduki behar dituzte.",
        "passwordtoolong": "Pasahitzak ezin dira {{PLURAL:$1|karaktere bat|$1 karaktere}} baino luzeagoak izan.",
        "passwordtoopopular": "Ezin dira pasahitz ohikoenak erabili. Aukera ezazu asmatzeko zailagoa den pasahitz bat.",
+       "passwordinlargeblacklist": "Sartu duzun pasahitza pasahitza oso erabilien zerrenda batean dago. Mesedez, erabili ezazu hain ohikoa ez den bat.",
        "password-name-match": "Zure pasahitza ezin da zure erabiltzaile-izen bera izan.",
        "password-login-forbidden": "Erabiltzaile izen eta pasahitz hau erabiltzea debekaturik dago.",
        "mailmypassword": "Pasahitza berrezarri",
        "botpasswords-invalid-name": "Zehaztutako erabiltzaileak ez du bot pasahitzaren ($1) bereizlea.",
        "botpasswords-not-exist": "$1 erabiltzaileak ez du $2 izeneko pasahitza.",
        "botpasswords-needs-reset": "\"$1\"{{GENDER:$1|erabiltzailearen}} \"$2\" robotaren pasahitza berrezarri behar da.",
+       "botpasswords-locked": "Ezin zara sartu bot pasahitz batekin zure kontua blokeatua dagoelako.",
        "resetpass_forbidden": "Ezin dira pasahitzak aldatu",
        "resetpass_forbidden-reason": "Ezin dira pasahitzak aldatu: $1",
        "resetpass-no-info": "Orrialde honetara zuzenean sartzeko izena eman behar duzu.",
        "resetpass-abort-generic": "Estentsio batek pasahitza aldatzea ekidin du.",
        "resetpass-expired": "Zure pasahitza iraungitu da. Sartzeko, pasahitz berria ezarri, mesedez.",
        "resetpass-expired-soft": "Zure pasahitza iraungi egin da eta aldatu beharra dago. Mesedez, aukeratu orain pasahitz berria edo egin klik \"{{int:authprovider-resetpass-skip-label}}\"-n geroago aldatzeko.",
+       "resetpass-validity": "Zure pasahitza ez da baliagarria: $1\n\nMesedez, aukera ezazu beste pasahitz bat sartzeko.",
        "resetpass-validity-soft": "Zure pasahitzak ez du balio: $1\n\nMesedez, aukeratu orain pasahitz berri bat, edo \"{{int:authprovider-resetpass-skip-label}}\" klikatu geroago berrezartzeko.",
        "passwordreset": "Pasahitzaren berrezarpena",
        "passwordreset-text-one": "Bete formulario hau zure pasahitza berrezartzeko.",
        "subject-preview": "Gaiaren aurrebista:",
        "previewerrortext": "Errore bat gertatu da aldaketak aurrezten saiatzean.",
        "blockedtitle": "Erabiltzailea blokeatuta dago",
+       "blocked-email-user": "<strong> Zure erabiltzailea blokeatua izan da eta ezin duzu mezurik bidali. Oraindik wiki honetako beste orri batzuk editatu ditzakezu.</strong> Blokeoaren detaile guztiak hemen ikus ditzakezu [[Special:MyContributions|account contributions]].\n\nBlokeoa $1-(e)k egin zuen.\n\nBlokeoaren arrazoiak hauek dira <em>$2</em>.\n\n*Blokeoa hemen hasten da: $8\n*Blokeoa amaitzen da: $6\n*Berariazko blokeoa: $7\n*Blokeoaren ID #$5",
+       "blockedtext-partial": "<strong>Zure erabiltzailea edo IP helbidea blokeatua izan da eta ezin du aldaketarik egin orrialde honetan. Wiki honetako beste orrialdeak oraindik editatu ditzakezu.</strong> Blokeoaren xehetasun guztiak hemen ikus ditzakezu: [[Special:MyContributions|account contributions]].\n\nBlokeoa $1-(e)k egin du.\n\nBlokeoaren arrazoia <em>$2</em> da.\n\n* Blokeoaren hasiera: $8\n* Blokeoaren amaiera: $6\n* Berariazko blokeoa: $7\n* Blokeoaren IDa #$5 da.",
        "blockedtext": "<strong> Zure erabiltzaile izena edo IP helbidea blokeatuta dago. </strong>\n\nBlokeoa $1-ek ezarri du.\nEmandako arrazoia hau da: ''$2''.\n\n* Blokeoaren hasiera: $8\n* Blokeoaren bukaera: $6\n* Blokeatua: $7\n\nBlokeoari buruz eztabaidatzeko, jo ezazu $1 edo beste [[{{MediaWiki:Grouppage-sysop}}|administratzaile]] batengana.\n\"{{int:emailuser}}\" tresna erabili ahal izateko, ezinbestekoa da zure [[Special:Preferences|hobespenetan]] baliozkoa den helbide elektroniko bat emanda izatea, eta tresna hori erabiltzeko aukera blokeatu ez izana.\nOrain duzun IP helbidea $3 da, eta blokeoaren zenbakia #$5.\nMesedez, eman aipatutako datu hauek guztiak, blokeoari buruzko edozein eskaera egitean.",
        "autoblockedtext": "Zure IP helbidea automatikoki blokeaturik dago, $1-ek blokeatutako beste erabiltzaile batek erabili zuelako. Emandako arrazoia hau da:\n\n:<em>$2</em>\n\n* Blokeoaren hasiera: $8\n* Blokeoaren bukaera: $6\n* Blokeatua: $7\n\nBlokeoari buruz eztabaidatzeko, jo ezazu $1 edo beste [[{{MediaWiki:Grouppage-sysop}}|administratzaile]] batengana.\n\n\"{{int:emailuser}}\" tresna erabili ahal izateko, ezinbestekoa da zure [[Special:Preferences|hobespenetan]] baliozkoa den helbide elektroniko bat emanda izatea, eta tresna hori erabiltzeko aukera blokeatu ez izana.\n\nOrain duzun IP helbidea $3 da, eta blokeoaren zenbakia #$5.\n\nMesedez, eman itzazu aipatutako datu guztiak, blokeoari buruzko edozein eskaera egitean.",
        "systemblockedtext": "Zure erabiltzaile izena edo IP helbidea MediaWiki-k automatikoki blokeatu du.\nHau da emandako arrazoia:\n\n:<em>$2</em>\n\n*Bloke sarrera: $8\n*Blokearen iraungintzea: $6\n*Blokeo helburua: $7\n\nZure uneko IP helbidea: $3.\nSartu goiko xehetasun guztiak egiten dituzun kontsulta guztietan mesedez.",
        "edit-gone-missing": "Ezin da orria eguneratu. Ezabatu omen dute.",
        "edit-conflict": "Aldaketa gatazka.",
        "edit-no-change": "Zure edizioa baztertu da testua aldatu ez duzulako.",
+       "edit-slots-cannot-add": "Hurrengo {{PLURAL:$1|eremua|eremuak}} ez {{PLURAL:$1|dago|daude}} $2-n sostengatuta.",
+       "edit-slots-cannot-remove": "{{PLURAL:$1|slot is|slots are}} behar da eta $2 ezin da ezabatu",
+       "edit-slots-missing": "Hurrengo {{PLURAL:$1|eremua|eremuak}} falta {{PLURAL:$1|da|dira}}: $2",
        "postedit-confirmation-created": "Orrialdea sortu da.",
        "postedit-confirmation-restored": "Orrialdea leheneratua izan da.",
        "postedit-confirmation-saved": "Zure aldaketa gorde da.",
        "defaultmessagetext": "Testu lehenetsia",
        "content-failed-to-parse": "Ezin izan da $2(r)en edukia parseatu $1 modeloarentzat: $3",
        "invalid-content-data": "Eduki datu baliogabea",
-       "content-not-allowed-here": "\"$1\" edukia ez dago baimendua [[:$2]] orrialdean",
+       "content-not-allowed-here": "\"$1\"-(e)n edukia ez dago baimenduta [[:$2]] orrialdeko \"$3\" posizioan",
        "editwarning-warning": "Orri honetatik irteten bazara, egindako aldaketak galdu egingo dira, beharbada.\nSaioa hasi baduzu, mezu hau kendu dezakezu zure hobespenen orriko «{{int:prefs-editing}}» atalean.",
        "editpage-invalidcontentmodel-title": "Eduki eredua ez da onartzen.",
        "editpage-invalidcontentmodel-text": "$1 eduki eredua ezin da erabili.",
        "editpage-notsupportedcontentformat-title": "Eduki formatu hori ez da onartzen",
        "editpage-notsupportedcontentformat-text": "$2 eduki ereduak ezin da erabili $1 eduki formatuarekin.",
+       "slot-name-main": "Nagusia",
        "content-model-wikitext": "wikitestua",
        "content-model-text": "testu laua",
        "content-model-javascript": "JavaScript",
        "histfirst": "zaharrena",
        "histlast": "berriena",
        "historysize": "({{PLURAL:$1|byte 1|$1 byte}})",
-       "historyempty": "(hutsik)",
+       "historyempty": "hutsik",
        "history-feed-title": "Berrikuspenen historia",
        "history-feed-description": "Wikiko orrialde honen berrikuspenen historia",
        "history-feed-item-nocomment": "nork: $1 noiz: $2",
        "localtime": "Ordu lokala:",
        "timezoneuseserverdefault": "Erabili lehenetsitako wikia ($1)",
        "timezoneuseoffset": "Beste bat (diferentzia ezarri)",
+       "timezone-useoffset-placeholder": "Adibideak: \"-07:00\" edo \"01:00\"",
        "servertime": "Zerbitzariko ordua:",
        "guesstimezone": "Nabigatzailetik jaso",
        "timezoneregion-africa": "Afrika",
        "prefs-advancedwatchlist": "Aukera aurreratuak",
        "prefs-displayrc": "Aukerak erakutsi",
        "prefs-displaywatchlist": "Aukerak erakutsi",
+       "prefs-changesrc": "Erakusten diren aldaketak",
+       "prefs-changeswatchlist": "Erakusten diren aldaketak",
+       "prefs-pageswatchlist": "Jarraitutako orrialdeak",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Ezberdintasunak",
        "prefs-help-prefershttps": "Hobespen hauek eragina izango dute sartzen zaren hurrengoan.",
        "right-reupload-own": "Norberak igotako fitxategi baten gainean idatzi",
        "right-reupload-shared": "Media biltegi komun batean dauden fitxategiak lokalki gainpasa",
        "right-upload_by_url": "URL helbide batetik fitxategi bat igo",
-       "right-purge": "Leku honen katxea garbitu konfirmaziorik gabeko orrialde batentzat",
+       "right-purge": "Web-orrialdearen cachea garbitu",
        "right-autoconfirmed": "Erdi-babestuak dauden orriak aldatu",
        "right-bot": "Prozesu automatikoki gisa jokatu",
        "right-nominornewtalk": "Estabaida orrietan aldaketa txikirik ez edukitzea mezu berrietan",
        "grant-createaccount": "Kontuak sortu",
        "grant-createeditmovepage": "Orrialdeak sortu, aldatu eta mugitu",
        "grant-delete": "Ezabatu orriak, berrikuspenak eta sarrerak",
-       "grant-editinterface": "MediaWiki izen eremua eta CSS/JSON/JavaScript erabiltzailea aldatu",
+       "grant-editinterface": "MediaWiki izen eremua eta web-orri zabalera/erabiltzailea JSON editatu",
        "grant-editmycssjs": "Zure CSS/JSON/JavaScript erabiltzailea aldatu",
-       "grant-editmyoptions": "Aldatu zure hobespenak",
+       "grant-editmyoptions": "Zure erabiltzaile hobespenak eta JSON konfigurazioa aldatu",
        "grant-editmywatchlist": "Zure jarraipen zerrenda aldatu",
        "grant-editsiteconfig": "Gune osoaren eta erabiltzaileen CSS/JS aldatu",
        "grant-editpage": "Aldatu dauden orrialdeak",
        "rcfilters-watchlist-markseen-button": "Aldaketa guztiak ikusitakoak bezala markatu",
        "rcfilters-watchlist-edit-watchlist-button": "Zure ikusitako orrien zerrenda aldatu",
        "rcfilters-watchlist-showupdated": "Azkenengo aldaketak egin zirenetik bisitatu ez dituzun orrietan eman diren aldaketak <strong>lodi estiloan</strong> daude, markatzaile sendoekin.",
-       "rcfilters-preference-label": "Azkenengo Aldaketen hobetutako bertsioa ezkutatu",
-       "rcfilters-preference-help": "2017 interfazearen birmoldaketa eta geroztik gehitu diren tresna guztietara bueltatzen da.",
-       "rcfilters-watchlist-preference-label": "Ezkutatu jarraipen zerrendaren bertsio hobetua",
-       "rcfilters-watchlist-preference-help": "Alderantzikatu 2017ko interfaze diseinu berria eta ordutik eta ordura arte gehitutako tresnak.",
+       "rcfilters-preference-label": "non-JavaScript interfazea erabili",
+       "rcfilters-preference-help": "Azken aldaketak kargatu bilaketa iragazkiak edo funtzio nabarmenduak erabili gabe",
+       "rcfilters-watchlist-preference-label": "non-JavaScript interfazea erabili",
+       "rcfilters-watchlist-preference-help": "Jarraipen lista kargatu bilaketa iragazkiak edo funtzio nabarmenduak erabili gabe",
        "rcfilters-filter-showlinkedfrom-label": "-tik linkatutako orrietako aldaketak erakutsi",
        "rcfilters-filter-showlinkedfrom-option-label": "hautatutako orritik <strong>linkatutako orriak</strong>",
        "rcfilters-filter-showlinkedto-label": "-ra linkatutako orrietako aldaketak erakutsi",
        "uploadstash-zero-length": "Fitxategiaren luzeera zero da.",
        "invalid-chunk-offset": "Desplazamendu zati baliogabea",
        "img-auth-accessdenied": "Sarbide ukatua",
-       "img-auth-nopathinfo": "PATH_INFO falta da.\nZure zerbitzaria ez dago informazio hau pasatzeko konfiguratuta.\nCGI-oinarriduna izan daiteke, img_auth onartzen ez duena.\nIkusi https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Bideratze informazioa falta da.\nZure zerbitzaria konfiguratua egon behar du REQUEST_URI eta/edo PATH_INFO aldagaiak gainditzeko.\nBaldin badago, saiatu $wgUsePathInfo gaitzen.\nIkusi https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Eskatutako bidea ez dago kofiguratutako igoera-direktorioan.",
        "img-auth-badtitle": "Ezin izan da baleko izenbururik eraiki \"$1\" izenetik abiatuta",
        "img-auth-nologinnWL": "Ez duzu saioa hasi eta \"$1\" ez dago zerrenda zurian.",
        "prefixindex": "Orri guztiak aurrizkiekin",
        "prefixindex-namespace": "$1 izentartean honako aurrizkia duten orrialde guztiak:",
        "prefixindex-submit": "Erakutsi",
-       "prefixindex-strip": "Zerrendako aurrizkia kendu",
+       "prefixindex-strip": "Emaitzetan aurrizkiak ezkutatu",
        "shortpages": "Orrialde laburrak",
        "longpages": "Orrialde luzeak",
        "deadendpages": "Orrialde itsuak",
        "cachedspecial-refresh-now": "Azkena ikusi.",
        "categories": "Kategoriak",
        "categories-submit": "Erakutsi",
-       "categoriespagetext": "Ondorengo {{PLURAL:$1|kategoria honek|kategoria hauek}} orriak edo fitxategiak {{PLURAL:$1|dauzka|dauzkate}}.\n[[Special:UnusedCategories|Erabili gabeko kategoriak]] ez dira hemen erakusten.\nIkus, gainera, [[Special:WantedCategories|kategoriarik eskatuenak]].",
+       "categoriespagetext": "Ondorengo {{PLURAL:$1|kategoria existitu|kategoriak existitu}} wikian, eta erabilita edo erabili gabe egon daitezke.\nIkus, gainera, [[Special:WantedCategories|kategoriarik eskatuenak]].",
        "categoriesfrom": "Honela hasten diren kategoriak erakutsi:",
        "deletedcontributions": "Ezabatutako ekarpenak",
        "deletedcontributions-title": "Ezabatutako ekarpenak",
        "deleting-backlinks-warning": "<strong>Abisua:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Beste orriek]] ezabatzear zauden orrira linkatu edo doaz.",
        "deleting-subpages-warning": "<strong>Oharra:</strong> Ezabatuko duzun orrialdeak [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|a subpage|$1 subpages|51=over 50 subpages}}]] dauka.",
        "rollback": "Desegin aldaketak",
+       "rollback-confirmation-confirm": "Mesedez baieztatu:",
+       "rollback-confirmation-yes": "Desegin",
+       "rollback-confirmation-no": "Utzi",
        "rollbacklink": "desegin",
        "rollbacklinkcount": "desegin {{PLURAL:$1|edizio bat|$1 edizio}}",
        "rollbacklinkcount-morethan": "desegin {{PLURAL:$1|edizio bat|$1 edizio}} baino gehiago",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|talk]]) wikilariaren aldaketak deseginda, edukia [[User:$1|$1]] wikilariaren azken bertsiora itzuli da.",
        "revertpage-nouser": "{{GENDER:$1|[[User:$1|$1]]}}-n azken berrikuspena ezkutatutako erabiltzaile batek egindako leheneraketa aldaketak.",
        "rollback-success": "{{GENDER:$3|$1}}; wikilariaren aldaketak deseginda,\nedukia {{GENDER:$4|$2}} wikilariaren azken bertsiora itzuli da.",
-       "rollback-success-notify": "$1k leheneratutako aldaketal;\nazkenengo berrikusketara aldatu da berriz $2ren eskutik. [$3 Erakutsi aldaketak]",
        "sessionfailure-title": "Saio-akatsa",
        "sessionfailure": "Badirudi saioarekin arazoren bat dagoela; ekintza hau ezeztatua izan da, saio bahiketa saihesteko neurri bezala. Mesedez, nabigatzaileko \"atzera\" botoian klik egin, hona ekarri zaituen orrialde hori berriz kargatu, eta saiatu berriz.",
        "changecontentmodel": "Aldatu orri bateko eduki eredua",
        "mycontris": "Ekarpenak",
        "anoncontribs": "Ekarpenak",
        "contribsub2": "{{GENDER:$3|$1(r)entzat}} ($2)",
+       "contributions-subtitle": "{{GENDER:$3|$1(r)entzat}}",
        "contributions-userdoesnotexist": "\"$1\" erabiltzaile-kontua ez dago erregistraturik.",
+       "negative-namespace-not-supported": "Balio negatiboko izen eremuak ez daude babestuak.",
        "nocontribs": "Ez da ezaugarri horiekin bat datorren aldaketarik aurkitu.",
        "uctop": "azken aldaketa",
        "month": "Hilabetea (eta lehenagokoak):",
        "ipbreason": "Arrazoia:",
        "ipbreason-dropdown": "*Blokeaketa arrazoi arruntak\n** Benetakoa ez den informazioa ezartzea\n** Orrialdetatik edukia ezabatzea\n** Spam-a edota kanpoko loturak ezarri\n** Bandalismoa egitea\n** Beste erabiltzaileei mehatxatzea\n** Kontu ugari erabiltzea\n** Erabiltzaile izen desegokia",
        "ipb-hardblock": "Galarazi izena emandako erabiltzaileek IP helbide honetatik editatzea",
-       "ipbcreateaccount": "Debekatu konturik sortzea",
-       "ipbemailban": "Galarazi erabiltzaile honi mezu elektronikoak bidal ditzan",
+       "ipbcreateaccount": "Sortu erabiltzailea",
+       "ipbemailban": "Mezu bat bidali",
        "ipbenableautoblock": "Erabiltzaile honek erabilitako azken IP helbidea automatikoki blokeatu, eta baita erabili dezakeen beste edozein IP ere",
        "ipbsubmit": "Blokeatu erabiltzaile hau",
        "ipbother": "Beste denbora-tarte bat",
        "ipboptions": "2 ordu:2 hours,1 egun:1 day,3 egun:3 days,astebete:1 week,2 aste:2 weeks,hilabete:1 month,3 hilabete:3 months,6 hilabete:6 months,urtebete:1 year,betiko:infinite",
        "ipbhidename": "Lankide izena aldaketa eta zerrendetatik ezkutatu",
        "ipbwatchuser": "Egin jarraipena erabiltzaile honen erabiltzaile eta eztabaida orriei",
-       "ipb-disableusertalk": "Galarazi erabiltzaile honi bere eztabaida orria editatzea, blokeatuta dagoen aldian",
+       "ipb-disableusertalk": "Haien hitz-egiteko orrialde propioa editatu",
        "ipb-change-block": "Berriz blokeatu erabiltzailea, parametro hauekin",
        "ipb-confirm": "Blokeoa baieztatu",
+       "ipb-sitewide": "web-orrialdea",
+       "ipb-partial": "Partzial",
+       "ipb-sitewide-help": "Wikiko edozein orrialde eta beste ekarpen ekintza guztiak",
+       "ipb-partial-help": "Orrialde edo izen-eremu zehatzak",
+       "ipb-pages-label": "Orrialdeak",
+       "ipb-namespaces-label": "Izen-tarteak",
        "badipaddress": "Baliogabeko IP helbidea",
        "blockipsuccesssub": "Blokeoa burutu da",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] blokeatua izan da.<br />\nIkus [[Special:BlockList|blokeoen zerrenda]] blokeoak aztertzeko.",
        "ipb-blocklist-duration-left": "gainerako $1",
        "block-actions": "Blokeatuko diren ekintzak:",
        "block-expiry": "Iraungipena",
+       "block-options": "Aukera gehigarriak:",
+       "block-prevent-edit": "Aldatzen",
+       "block-reason": "Arrazoia:",
+       "block-target": "Erabiltzaile izena edo IP helbidea:",
        "unblockip": "Erabiltzailea desblokeatu",
        "unblockiptext": "Erabili beheko formularioa lehenago blokeatutako IP helbide edo erabiltzaile baten idazketa baimenak leheneratzeko.",
        "ipusubmit": "Blokeoa ezabatu",
        "blocklist-nousertalk": "zure buruaren eztabaida orrialdea ezin duzu aldatu",
        "blocklist-editing": "aldatzen",
        "blocklist-editing-sitewide": "editatzea (gune osoan)",
+       "blocklist-editing-page": "orrialdeak",
+       "blocklist-editing-ns": "izen-tarteak",
        "ipblocklist-empty": "Blokeaketa zerrenda hutsik dago.",
        "ipblocklist-no-results": "Zehaztutako IP helbide edo erabiltzaile izena ez dago blokeatuta.",
        "blocklink": "blokeatu",
        "ipb_expiry_old": "Epemuga iraganean dago.",
        "ipb_expiry_temp": "Izkutuan dauden lankide izenen blokeoa betierekikoa izan behar du.",
        "ipb_hide_invalid": "Ezin izan da kontu hau ezabatu; {{PLURAL:$1|one edit|$1 edits}} baino gehiago baiditu.",
+       "ipb_hide_partial": "Izkutuan dauden erabiltzaile blokeatuak orrialde osorako blokeatuak egon behar dute.",
        "ipb_already_blocked": "\"$1\" badago blokeatuta",
        "ipb-needreblock": "$1 dagoeneko blokeaturik dago. Ezarpenak aldatu nahi al dituzu?",
        "ipb-otherblocks-header": "Bestelako {{PLURAL:$1|blokeoa|blokeoak}}",
        "move-watch": "Orrialde hau jarraitu",
        "movepagebtn": "Mugitu orria",
        "pagemovedsub": "Mugimendua eginda",
+       "cannotmove": "Orrialdea ezin da mugitua izan hurrengo ekintzarako: {{PLURAL:$1|reason|reasons}}:",
        "movepage-moved": "'''\"$1\" \"$2\"(e)ra mugitu da'''",
        "movepage-moved-redirect": "Birbideratze orri bat sortu da.",
        "movepage-moved-noredirect": "Birbideratzea sortzeko aukera kendu da.",
        "pageinfo-display-title": "Ageri den izenburua",
        "pageinfo-default-sort": "Ordenatze irizpide lehenetsia",
        "pageinfo-length": "Orriaren neurria (byteak)",
+       "pageinfo-namespace": "Izen-tartea",
        "pageinfo-article-id": "Orriaren identifikazio zenbakia",
        "pageinfo-language": "Orriaren edukiaren hizkuntza",
        "pageinfo-language-change": "aldatu",
        "pageinfo-category-files": "Fitxategi kopurua",
        "pageinfo-user-id": "Erabiltzaile IDa",
        "pageinfo-file-hash": "Hash balioa",
+       "pageinfo-view-protect-log": "Erregistro babesak ikusi orrialde honetarako",
        "markaspatrolleddiff": "Patruilatutzat markatu",
        "markaspatrolledtext": "Artikulu hau patruilatutzat markatu",
        "markaspatrolledtext-file": "Fitxategi honen bertsioa patruilatutzat markatu",
        "previousdiff": "← Aldaketa zaharragoa",
        "nextdiff": "Aldaketa berriagoa →",
        "mediawarning": "'''Oharra''': Fitxategi honek kode mingarria izan lezake.\nZure sisteman exekutatzea arriskutsua izan liteke.",
-       "imagemaxsize": "Irudiaren tamainaren muga:<br />''(fitxategia deskribatzen duten orrietarako)''",
+       "imagemaxsize": "Irudiaren tamainaren muga fitxategia deskribatzen duten orrietarako:",
        "thumbsize": "Irudi txikiaren tamaina:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|orri|orri}}",
        "file-info": "fitxategiaren tamaina: $1, MIME mota: $2",
        "seconds-ago": "Orain dela {{PLURAL:$1|segundu bat|$1 segundu}}",
        "monday-at": "Astelehena $1(e)tan",
        "tuesday-at": "Asteartea $1(e)tan",
-       "wednesday-at": "Asteazkena $1(e)tan",
+       "wednesday-at": "asteazkenean (ordua: $1)",
        "thursday-at": "Osteguna $1(e)tan",
        "friday-at": "Ostirala $1(e)tan",
        "saturday-at": "Larunbata $1(e)tan",
        "confirm-unwatch-top": "Orrialde hau zure jarraipen-zerrendatik kendu?",
        "confirm-rollback-button": "Ados",
        "confirm-rollback-top": "Orrialde honen edizioak leheneratu?",
+       "confirm-rollback-bottom": "Ekintza honek orrialde honetan hautatutako aldaketak zuzenean desegingo ditu.",
+       "confirm-mcrrestore-title": "Errebisio bat berritu",
        "confirm-mcrundo-title": "Aldaketa bat desegin",
        "mcrundofailed": "Desegiteak akatsa",
        "mcrundo-missingparam": "Beharrezko eskaera parametroak falta dira.",
+       "mcrundo-changed": "Diff-a ikusi zenuen azken alditik orrialdea aldatu egin da. Mesedez, aldaketak errebisatu.",
+       "mcrundo-parse-failed": "Errebisio berriaren analisia huts egin du: $1",
        "word-separator": "&#32;",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← aurreko orrialdea",
        "redirect-file": "Fitxategiaren izena",
        "redirect-logid": "Log IDa",
        "redirect-not-exists": "Ez da baliorik aurkitu",
+       "redirect-not-numeric": "Balio ez-zenbakizkoa",
        "fileduplicatesearch": "Artxibo bikoiztuen bilaketa",
        "fileduplicatesearch-summary": "Bikoiztutako fitxategiak bilatu bere hash balioaren arabera.",
        "fileduplicatesearch-filename": "Fitxategi izena:",
        "specialpages-group-developer": "Garatzaileen tresnak",
        "blankpage": "Orrialde txuria",
        "intentionallyblankpage": "Orri hau nahita utzi da hutsik",
+       "disabledspecialpage-disabled": "Orrialde hau sistemako administratzaile batek desgaitu du.",
        "external_image_whitelist": " #Lerro hau utzi dagoen bezala<pre>\n#Jarri espresio zati erregularrak (bakarrik // artean doan zatia) azpian\n#Hauek kanpo irudien URLekin lotuko dira\n#Lotutako horiek irudi bezala agertuko dira, bestela lotura besterik ez da agertuko\n# #-arekin hasten diren lerroak iruzkin bezala hartuko dira\n# Hau case-insensitive da\n\n#Jarri regex zatiak lerro honen gainetik. Lerro hau utzi dagoen bezala</pre>",
        "tags": "Etiketa aldaketa zuzena",
        "tag-filter": "[[Special:Tags|Etiketa]] iragazkia:",
        "logentry-block-block": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} blokeatu du. Iraupena: $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} wikilaria desblokeatu du",
        "logentry-block-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
+       "logentry-partialblock-block-page": "$2 {{PLURAL:$1|orrialdea|orrialdeak}}",
+       "logentry-partialblock-block-ns": "$2 {{PLURAL:$1|izen-eremua|izen-eremuak}}",
+       "logentry-partialblock-block": "$1 {{GENDER:$2|blokeatuta}} {{GENDER:$4|$3}} $7 ediziotik  bukaerako denbora honekin $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} blokeatu du. Iraupena: $5 $6",
        "logentry-suppress-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
        "logentry-import-upload": "$1(e)k $3 {{GENDER:$2|inportatu du}} fitxategi-igoera bidez",
        "logentry-rights-autopromote": "$1 automatikoki $4tik $5ra  {{GENDER:$2|igo}} egin zaio",
        "logentry-upload-upload": "$1(e)k $3 {{GENDER:$2|igo du}}",
        "logentry-upload-overwrite": "$1(e)k $3(r)en bertsio berria {{GENDER:$2|igo du}}",
-       "logentry-upload-revert": "$1(e)k $3 {{GENDER:$2|igo du}}",
+       "logentry-upload-revert": "$1(e)k $3 bertsio zahar batera {{GENDER:$2|itzuli du}}",
        "log-name-managetags": "Etiketa kudeatze erregistroa",
        "log-description-managetags": "Orrialde honetan [[Special:Tags|etiketekin]] lotutako kudeaketa-zereginak zerrendatzen dira. Saioak administratzaileak eskuz egiten dituen ekintzak soilik ditu; Wiki softwarerrarekin etiketak sortu edo ezabatzeko ahalmenarekin erregistro honetan erregistratutako sarrerarik gabe.",
        "logentry-managetags-create": "$1 lankideak \"$4\" etiketa {{GENDER:$2|sortu du}}",
        "log-action-filter-suppress-reblock": "Birblokoz kendutako erabiltzailea",
        "log-action-filter-upload-upload": "Igoera berria",
        "log-action-filter-upload-overwrite": "Birkargatu",
+       "log-action-filter-upload-revert": "Leheneratu",
        "authmanager-authn-not-in-progress": "Egiaztatzea ez dago prozesuan edo saioaren datuak galdu egin dira. Hasi berriro hasieratik mesedez.",
        "authmanager-authn-no-primary": "Emandako kredentzialak ezin izan dira egiaztatu.",
        "authmanager-authn-no-local-user": "Emandako kredentzialak ez dute lotura wiki honetako erabiltzaileekin.",
        "authmanager-create-no-primary": "Ezin izan dira hornitutako kredentzialak kontu-sortzerakoan erabili.",
        "authmanager-link-no-primary": "Ezin izan dira hornitutako kredentzialak kontuari lotzeko erabili.",
        "authmanager-link-not-in-progress": "Kontua sortzea ez doa aurrera edo saioaren datuak galdu egin dira. Hasi berriro hasieratik mesedez.",
-       "authmanager-authplugin-setpass-failed-title": "Ezin izan da pasahitza aldatu",
-       "authmanager-authplugin-setpass-failed-message": "Autentifikazio pluginak pasahitza aldatzea ukatu du.",
-       "authmanager-authplugin-create-fail": "Autentifikazio pluginak kontua sortzea ukatu du.",
-       "authmanager-authplugin-setpass-denied": "Autentifikazio pluginak pasahitza aldatzerik ez du ahalbidetzen.",
-       "authmanager-authplugin-setpass-bad-domain": "Balio ez duen domeinua.",
        "authmanager-autocreate-noperm": "Ezin da automatikoki erabiltzaile bat sortu.",
        "authmanager-autocreate-exception": "Kontua automatikoki sortzea aldi baterako desgaituta aurreko erroreak direla eta.",
        "authmanager-userdoesnotexist": "\"$1\" erabiltzaile kontua ez dago erregistratua.",
        "passwordpolicies-policy-passwordcannotmatchusername": "Pasahitza ezin da erabiltzaile izenaren berdina izan",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Pasahitza ezin da zerrenda beltzean zehaztutakoren bat izan",
        "passwordpolicies-policy-maximalpasswordlength": "Pasahitza ezin da {{PLURAL:$1|karaktere $1|$1 karaktere}} baino luzeagoa izan",
-       "passwordpolicies-policy-passwordcannotbepopular": "Pasahitza ezin da {{PLURAL:$1|pasahitz erabiliena izan|$1 pasahitz erabilienen zerrendan egon}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "Pasahitza ezin da {{PLURAL:$1|pasahitz erabiliena izan|$1 pasahitz erabilienen zerrendan egon}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Pasahitza ezin da egon\"100.000 pasahitz erabilien\" listan.",
+       "passwordpolicies-policyflag-forcechange": "Saioa hastean aldatzea derrigorrezkoa",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "Aholkuak saioa hastean aldatu",
+       "unprotected-js": "Segurtasun arrazoiengatik JavaScript ezin da babesik gabeko orrialdetan kargatu. Soilik MediaWiki atal hauetan erabili JavaScript: Izen-eremuak edo erabiltzaile orrialdetan"
 }
index ae49993..d53895f 100644 (file)
@@ -2,7 +2,8 @@
        "@metadata": {
                "authors": [
                        "Esbardu",
-                       "Xuacu"
+                       "Xuacu",
+                       "Enolp"
                ]
        },
        "exif-imagewidth": "Anchor",
@@ -29,7 +30,7 @@
        "exif-datetime": "Data y hora de cambiu del ficheru",
        "exif-imagedescription": "Títulu de la imaxe",
        "exif-make": "Fabricante de la cámara",
-       "exif-model": "Modelu de cámara",
+       "exif-model": "Modelu de la cámara",
        "exif-software": "Software usáu",
        "exif-artist": "Autor",
        "exif-copyright": "Titular del Copyright",
@@ -63,6 +64,7 @@
        "exif-lightsource": "Fonte de la lluz",
        "exif-flash": "Flax",
        "exif-focallength": "Llonxitú focal de la lente",
+       "exif-focallength-format": "$1 mm",
        "exif-subjectarea": "Área del suxetu",
        "exif-flashenergy": "Enerxía del flax",
        "exif-focalplanexresolution": "Resolución X del planu focal",
@@ -89,7 +91,7 @@
        "exif-gpsversionid": "Versión de la etiqueta GPS",
        "exif-gpslatituderef": "Llatitú Norte o Sur",
        "exif-gpslatitude": "Llatitú",
-       "exif-gpslongituderef": "Llonxitú Este o Oeste",
+       "exif-gpslongituderef": "Llonxitú este u oeste",
        "exif-gpslongitude": "Llonxitú",
        "exif-gpsaltituderef": "Referencia d'altitú",
        "exif-gpsaltitude": "Altitú",
index 5372a88..92c83d9 100644 (file)
        "exif-countrycodecreated": "Код на държавата, в която е направена снимката",
        "exif-provinceorstatecreated": "Област или щат, в който е направена снимката",
        "exif-citycreated": "Град, в който е направена снимката",
+       "exif-sublocationcreated": "Район на града в който е направена снимката",
        "exif-worldregiondest": "Показан регион на света",
        "exif-countrydest": "Показана държава",
        "exif-countrycodedest": "Код на показаната държава",
        "exif-objectname": "Кратко заглавие",
        "exif-specialinstructions": "Специални инструкции",
        "exif-headline": "Заглавие",
+       "exif-credit": "Субект, предоставил изображението",
        "exif-source": "Източник",
+       "exif-editstatus": "Редакционен статус на изображението",
        "exif-urgency": "Спешност",
+       "exif-locationdest": "Показано място",
+       "exif-locationdestcode": "Код на показаното място",
+       "exif-objectcycle": "Време от деня за което е предназначена снимката",
        "exif-contact": "Информация за контакти",
        "exif-writer": "Автор на текста",
        "exif-languagecode": "Език",
        "exif-iimcategory": "Категория",
        "exif-iimsupplementalcategory": "Допълнителни категории",
        "exif-datetimeexpires": "Да не се използва след",
+       "exif-datetimereleased": "Издадена на",
+       "exif-originaltransmissionref": "Код на мястото от което е изпратена снимката",
        "exif-identifier": "Идентификатор",
        "exif-lens": "Използвана оптична леща",
        "exif-serialnumber": "Сериен номер на фотоапарата",
        "exif-originaldocumentid": "Уникален номер на оригиналния документ",
        "exif-licenseurl": "Адрес с информация за авторски права",
        "exif-morepermissionsurl": "Алтернативна информация за лиценза",
+       "exif-attributionurl": "При използване на творбата, моля поставете връзка до",
+       "exif-preferredattributionname": "При използване на творбата, моля укажете автора",
        "exif-pngfilecomment": "Kоментар на PNG файл",
        "exif-disclaimer": "Уточнение",
        "exif-contentwarning": "Предупреждение за съдържанието",
        "exif-giffilecomment": "Kоментар на GIF файл",
        "exif-intellectualgenre": "Тип елемент",
+       "exif-subjectnewscode": "Код на темата",
        "exif-event": "Изобразено събитие",
        "exif-organisationinimage": "Изобразена организация",
        "exif-personinimage": "Изобразена личност",
        "exif-compression-7": "JPEG",
        "exif-copyrighted-true": "Заштитено с авторски права",
        "exif-copyrighted-false": "Статутът на авторските права не е указан",
+       "exif-photometricinterpretation-0": "Чернобяло (Бялото е 0)",
+       "exif-photometricinterpretation-1": "Чернобяло (Черното е 0)",
        "exif-photometricinterpretation-2": "RGB",
+       "exif-photometricinterpretation-3": "Цветова палитра",
+       "exif-photometricinterpretation-4": "Маска на прозрачност",
+       "exif-photometricinterpretation-5": "Разделено (Вероятно CMYK)",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (ICC-кодиране)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (ITU-кодиране)",
        "exif-unknowndate": "Неизвестна дата",
        "exif-orientation-1": "Нормално",
        "exif-orientation-2": "Отражение по хоризонталата",
        "exif-gpsdop-poor": "Лошо ($1)",
        "exif-objectcycle-a": "Само сутрин",
        "exif-objectcycle-p": "Само вечер",
+       "exif-objectcycle-b": "Сутрин и вечер",
        "exif-gpsdirection-t": "Истинска",
        "exif-gpsdirection-m": "Магнитна",
        "exif-ycbcrpositioning-1": "Центрирани",
index c6c1906..53e0389 100644 (file)
        "exif-gpsdifferential": "GPS differential correction",
        "exif-coordinate-format": "$1° $2′ $3″ $4",
        "exif-jpegfilecomment": "Vatışê dosyada JPEG'i",
-       "exif-keywords": "Qesa kelimey",
+       "exif-keywords": "Çekuyên kıliti",
        "exif-worldregioncreated": "Mıntıqaya dınyaya ke tede resım gêriyayayo",
        "exif-countrycreated": "Dewleta ke tede resım gêriyayayo",
        "exif-countrycodecreated": "Kodê dewleta ke tede resım anciyayo",
        "exif-iimcategory-hth": "Weşeyey",
        "exif-iimcategory-hum": "Elekey merduman",
        "exif-iimcategory-lab": "Gurweyayin",
-       "exif-iimcategory-lif": "Cıwiyayış u keyf kerdış",
+       "exif-iimcategory-lif": "Cıwiyayış û keyfkerdış",
        "exif-iimcategory-pol": "Siyaset",
-       "exif-iimcategory-rel": "Din u iman kerdış",
+       "exif-iimcategory-rel": "Din û baweriye",
        "exif-iimcategory-sci": "Zanış u teknoloci",
        "exif-iimcategory-soi": "Sosyal meseley",
        "exif-iimcategory-spo": "Spor",
index 5831e69..d266bea 100644 (file)
        "exif-compression-6": "JPEG",
        "exif-copyrighted-true": "Copyrightduna",
        "exif-copyrighted-false": "Copyright egoera ez da ezarri",
+       "exif-photometricinterpretation-0": "Zuri-beltza (beltza 0 da)",
        "exif-photometricinterpretation-1": "Zuri-beltza (beltza 0 da)",
        "exif-photometricinterpretation-2": "GBU (RGB)",
+       "exif-photometricinterpretation-3": "Kolore-paleta",
+       "exif-photometricinterpretation-4": "Gardentasun maskara",
+       "exif-photometricinterpretation-5": "Bereiztuak (ziurrenik CMYK)",
        "exif-photometricinterpretation-6": "YCbCr",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (ICC kodeketa)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (ITU kodeketa)",
        "exif-unknowndate": "Data ezezaguna",
        "exif-orientation-1": "Arrunta",
        "exif-orientation-2": "Horizontalki buelta emana",
index 13454d1..9c4c047 100644 (file)
@@ -4,7 +4,8 @@
                        "Ebraminio",
                        "Huji",
                        "Meisam",
-                       "ZxxZxxZ"
+                       "ZxxZxxZ",
+                       "Reza1615"
                ]
        },
        "exif-imagewidth": "عرض",
@@ -52,6 +53,7 @@
        "exif-exposuretime": "زمان نوردهی",
        "exif-exposuretime-format": "$1 ثانیه ($2)",
        "exif-fnumber": "ضریب اف",
+       "exif-fnumber-format": "f/$1",
        "exif-exposureprogram": "برنامهٔ نوردهی",
        "exif-spectralsensitivity": "حساسیت طیفی",
        "exif-isospeedratings": "درجه‌بندی سرعت ایزو",
        "exif-compression-4": "رمزگذاری نمابر سی‌سی‌آی‌تی‌تی گروه ۴",
        "exif-copyrighted-true": "دارای حق تکثیر",
        "exif-copyrighted-false": "وضعیت حق‌تکثیر تعیین نشده است",
+       "exif-photometricinterpretation-0": "سیاه و سفید (سفید ۰ است)",
        "exif-photometricinterpretation-1": "سیاه و سفید (سیاه ۰ است)",
+       "exif-photometricinterpretation-3": "پالت",
+       "exif-photometricinterpretation-4": "شفافیت پوشش",
+       "exif-photometricinterpretation-5": "جداشده (احتمالاُ CMYK)",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (رمزنگاری ICC)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (رمزنگاری ITU)",
        "exif-unknowndate": "تاریخ نامعلوم",
        "exif-orientation-1": "عادی",
        "exif-orientation-2": "افقی پشت و روشده",
index a3ce398..40f962a 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Kening Aldgilles",
                        "Robin van der Vliet",
-                       "Snakesteuben"
+                       "Snakesteuben",
+                       "PiefPafPier"
                ]
        },
        "exif-imagewidth": "Breedte",
@@ -24,7 +25,7 @@
        "exif-pixelxdimension": "Ofbyldingsbreedte",
        "exif-pixelydimension": "Ofbyldingshichte",
        "exif-usercomment": "Opmerkings",
-       "exif-relatedsoundfile": "Besibbe audiotriem",
+       "exif-relatedsoundfile": "Besibbe audiobestân",
        "exif-datetimeoriginal": "Tiidstip gegevensoanmaak",
        "exif-datetimedigitized": "Tiidstip digitalisearring",
        "exif-subsectime": "Datum tijd subsekonden",
@@ -37,7 +38,7 @@
        "exif-lightsource": "Ljochtboarne",
        "exif-flash": "Flits",
        "exif-focallength-format": "$1 mm",
-       "exif-filesource": "Triemboarne",
+       "exif-filesource": "Bestânsboarne",
        "exif-whitebalance": "Wytbalâns",
        "exif-contrast": "Kontrast",
        "exif-saturation": "Sêding",
index 9ba8e44..a323e26 100644 (file)
        "exif-compression-6": "JPEG (vecchio)",
        "exif-copyrighted-true": "Protetto da copyright",
        "exif-copyrighted-false": "Status del copyright non impostato",
+       "exif-photometricinterpretation-0": "Bianco e nero (bianco è 0)",
        "exif-photometricinterpretation-1": "Bianco e nero (nero è 0)",
+       "exif-photometricinterpretation-3": "Tavolozza",
+       "exif-photometricinterpretation-4": "Maschera di trasparenza",
+       "exif-photometricinterpretation-5": "Separato (probabilmente CMYK)",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (codifica ICC)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (codifica ITU)",
        "exif-unknowndate": "Data sconosciuta",
        "exif-orientation-1": "Normale",
        "exif-orientation-2": "Capovolto orizzontalmente",
index 0c5ed54..353ad9c 100644 (file)
        "exif-compression-34712": "JPEG2000",
        "exif-copyrighted-true": "著作権あり",
        "exif-copyrighted-false": "著作権情報未設定",
-       "exif-photometricinterpretation-0": "黒と白(白が0です)",
+       "exif-photometricinterpretation-0": "黒と白(白が0)",
        "exif-photometricinterpretation-1": "黒と白(黒が0)",
        "exif-photometricinterpretation-2": "RGB",
-       "exif-photometricinterpretation-3": "Palette",
-       "exif-photometricinterpretation-5": "Separated (Probably CMYK)",
+       "exif-photometricinterpretation-3": "パレット",
+       "exif-photometricinterpretation-4": "透明マスク",
+       "exif-photometricinterpretation-5": "分版 (おそらく CMYK)",
        "exif-photometricinterpretation-6": "YCbCr",
        "exif-photometricinterpretation-8": "CIE L*a*b*",
        "exif-photometricinterpretation-9": "CIE L*a*b* (ICC エンコード)",
index 8ddd137..bcd7ca4 100644 (file)
@@ -2,7 +2,8 @@
        "@metadata": {
                "authors": [
                        "Robby",
-                       "Soued031"
+                       "Soued031",
+                       "Les Meloures"
                ]
        },
        "exif-imagewidth": "Breet",
        "exif-sensingmethod-7": "Dräilineare Sensor",
        "exif-sensingmethod-8": "Sequentielle lineare Farwsensor",
        "exif-filesource-3": "Digital Kamera",
-       "exif-scenetype-1": "D'Bild gouf photograféiert",
+       "exif-scenetype-1": "D'Bild gouf fotograféiert",
        "exif-customrendered-0": "Standard",
        "exif-customrendered-1": "Benotzerdefinéiert",
        "exif-exposuremode-0": "Automatesch Beliichtung",
index 4c19e31..43c77e8 100644 (file)
        "exif-writer": "نیسنه",
        "exif-languagecode": "زون",
        "exif-iimversion": "نسقه آی آی ام",
-       "exif-iimcategory": "دسه",
+       "exif-iimcategory": "دٱسٱ",
        "exif-iimsupplementalcategory": "دسه یا اضافی",
        "exif-datetimeexpires": "وا نها دش استفاده نبوئه",
        "exif-datetimereleased": "ول بیه د",
index 5253e8d..89a5d4b 100644 (file)
        "exif-gpsspeed-n": "Јазли",
        "exif-gpsdestdistance-k": "Километри",
        "exif-gpsdestdistance-m": "Милји",
-       "exif-gpsdestdistance-n": "Ð\9dаÑ\83Ñ\82иÑ\87ки милји",
+       "exif-gpsdestdistance-n": "Ð\9cоÑ\80Ñ\81ки милји",
        "exif-gpsdop-excellent": "Одлична ($1)",
        "exif-gpsdop-good": "Добра ($1)",
        "exif-gpsdop-moderate": "Умерена ($1)",
index 405a3c1..f30c520 100644 (file)
@@ -39,7 +39,7 @@
        "exif-rowsperstrip": "Number of rows per strip",
        "exif-stripbytecounts": "Bytes per compressed strip",
        "exif-jpeginterchangeformat": "Offset to JPEG SOI",
-       "exif-jpeginterchangeformatlength": "Bytes of JPEG data",
+       "exif-jpeginterchangeformatlength": "JPEG verilerinin baytı",
        "exif-whitepoint": "Beyaz nokta kromatiği",
        "exif-primarychromaticities": "Chromaticities of primarities",
        "exif-ycbcrcoefficients": "Renk aralığı dönüştürme matris katsayısı",
index 55c73d0..915d9a0 100644 (file)
@@ -71,7 +71,9 @@
                        "Amirsara",
                        "Physicsch",
                        "Nbi",
-                       "Amjad Khan"
+                       "Amjad Khan",
+                       "Ahmad252",
+                       "FarsiNevis"
                ]
        },
        "tog-underline": "خط کشیدن زیر پیوندها:",
        "tog-norollbackdiff": "بعد از واگردانی، تفاوت نشان داده نشود",
        "tog-useeditwarning": "زمان خروج از صفحهٔ ویرایش در صورت داشتن ویرایش‌های‌ ذخیره‌نشده به من هشدار داده شود",
        "tog-prefershttps": "هنگامی که به سامانه وارد شده‌ام، همواره از اتصال امن استفاده شود",
+       "tog-showrollbackconfirmation": "نمایش یک هشدار در هنگام کلیک بر دکمه واگردانی",
        "underline-always": "همیشه",
        "underline-never": "هرگز",
        "underline-default": "پیش‌فرض پوسته یا مرورگر",
        "returnto": "بازگشت به $1.",
        "tagline": "از {{SITENAME}}",
        "help": "راهنما",
+       "help-mediawiki": "راهنما درباره مدیاویکی",
        "search": "جستجو",
        "search-ignored-headings": "#<!-- این صفحه را درست همانطور که هست رها کنید --> <pre>\n# سر‌فصل‌هایی که توسط جستجو نادیده گرفته خواهندشد.‌\n# تأثیر تغییرات زمانی رخ می‌دهد که صفحهٔ حاوی آن سرفصل، نمایه شود.\n# شما می‌توانید با انجام یک ویرایش پوچ صفحه را وادار به دوباره نمایه‌شدن کنید.\n# نحو به شرح زیر است:\n#  *هر چه از یک نویسهٔ «#» تا آخر خط بیاید، یک توضیح است.\n#  *هر خط بدون فاصله، دقیقاً عنوانی است که نادیده گرفته می‌شود (با رعایت بزرگی و کوچکی حروف).\nمنابع\nپیوند به بیرون\nهمچنین ببینید\n#</pre> <!-- leave this line exactly as it is -->",
        "searchbutton": "جستجو",
        "badretype": "گذرواژه‌هایی که وارد کرده‌اید یکسان نیستند.",
        "usernameinprogress": "ایجاد حساب برای این نام کاربر در جریان است. لطفا صبور باشید.",
        "userexists": "نام کاربری‌ای که وارد کردید قبلاً استفاده شده‌است.\nلطفاً یک نام دیگر انتخاب کنید.",
+       "createacct-normalization": "نام کاربری شما به دلایل فنی به «$2» تبدیل خواهد شد.",
        "loginerror": "خطا در ورود به سامانه",
        "createacct-error": "خطای ایجاد حساب کاربری",
        "createaccounterror": "امکان ساختن این حساب وجود ندارد: $1",
        "botpasswords-invalid-name": "نام کاربری مشخص شده دارای جداکنندهٔ گذرواژهٔ رباتی نیست («$1»).",
        "botpasswords-not-exist": "کاربر «$1» گذرواژهٔ رباتی نام‌دهی شدهٔ «$2» ندارد.",
        "botpasswords-needs-reset": "گذرواژهٔ رباتی برای ربات «$2» و {{GENDER:$1|کاربر}} «$1» باید از نو تنظیم شود.",
+       "botpasswords-locked": "حساب شما قفل شده است و با گذرواژه رباتی نمی‌توانید وارد شوید",
        "resetpass_forbidden": "نمی‌توان گذرواژه‌ها را تغییر داد",
        "resetpass_forbidden-reason": "نمی‌توانید گذرواژه‌ها را تغییر داد: $1",
        "resetpass-no-info": "برای دسترسی مستقیم به این صفحه شما باید به سامانه وارد شده باشید.",
        "resetpass-abort-generic": "تغییر گذرواژه به دست یکی از افزونه‌ها لغو شده است.",
        "resetpass-expired": "رمز عبور شما منقضی شده‌است. لطفاً برای ورود رمز عبور جدیدی را تنظیم کنید.",
        "resetpass-expired-soft": "رمز عبور شما منقضی شده‌است و نیاز به تغییر دارد. لطفاً اکنون رمز عبور جدیدی را انتخاب کنید، یا برای تغییر آن در آینده، دکمهٔ «{{int:authprovider-resetpass-skip-label}}» را کلیک کنید.",
+       "resetpass-validity": "گذرواژه شما معتبر نیست: $1\n\nلطفا برای ورود گذرواژه جدیدی را انتخاب کنید.",
        "resetpass-validity-soft": "گذرواهٔ شما صحیح نیست: $1\n\nلطفاً یک گذرواژهٔ تازه الآن انتخاب کنید یا بر «{{int:authprovider-resetpass-skip-label}}» کلیک کنید که دوباره آن را بعداً تغییر دهید.",
        "passwordreset": "بازنشانی گذرواژه",
        "passwordreset-text-one": "برای بازنشانی گذرواژه‌تان این فرم را کامل کنید.",
        "subject-preview": "پیش‌نمایش موضوع:",
        "previewerrortext": "در زمان تلاش برای نمایش دادن تغییرات شما، خطایی رخ داد.",
        "blockedtitle": "کاربر بسته شده‌است",
+       "blocked-email-user": "<strong>دسترسی حساب کاربری شما از ارسال ایمیل قطع شده است. شما همچنان می‌توانید سایر صفحات این ویکی را ویرایش کنید.</strong>می‌توانید جزئیات کامل قطع دسترسی را در [[Special:MyContributions|مشارکت‌های حساب]] ببینید.\n\nقطع دسترسی توسط $1 انجام شده است.\n\nدلیل داده‌شده <em>$2</em> بوده است.\n\n* شروع قطع دسترسی: $8\n* اتمام قطع دسترسی: $6\n* هدف قطع دسترسی: $7\n* شناسه قطع دسترسی #$5",
+       "blockedtext-partial": "<strong>حساب کاربری یا آدرس آی‌پی شما از انجام تغییرات در این صفحه منع شده‌است. شما همچنان می‌توانید در دیگر صفحه‌های این ویکی ویرایش کنید.</strong> برای مشاهده جزئیات کامل قطع دسترسی به [[Special:MyContributions|مشارکت‌های حساب]] مراجعه کنید.\n\nاین قطع دسترسی توسط $1 انجام گرفته‌است.\n\nدلیل قطع دسترسی <em>$2</em> است.\n\n* زمان آغاز قطع دسترسی: $8\n* زمان پایان قطع دسترسی: $6\n* موارد مورد نظر: $7\n* شناسه قطع دسترسی: #$5",
        "blockedtext": "<strong>دسترسی حساب کاربری یا نشانی آی‌پی شما بسته شده‌است.</strong>\n\nاین قطع دسترسی توسط $1 انجام شده است.\nدلیل ارائه‌شده چنین است: <em>$2</em>\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «{{int:emailuser}}» استفاده کنید مگر آنکه آدرس ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
        "autoblockedtext": "دسترسی نشانی آی‌پی شما قطع شده‌است، زیرا این نشانی آی‌پی توسط کاربر دیگری استفاده شده که دسترسی او توسط $1 قطع شده‌است.\nدلیل ارائه‌شده چنین است:\n\n:''$2''\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «{{int:emailuser}}» استفاده کنید مگر آنکه نشانی ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
        "systemblockedtext": "نام کاربری یا نشانی آی‌پی شما خودکار توسط مدیاویکی مسدود شده‌است.\nدلیل ارائه‌شده:\n\n:<em>$2</em>\n\n* آغاز بلاک: $8\n* پایان بلاک: $6\n* قطع دسترسی‌شده مورد نظر: $7\n\nنشانی آی‌پی کنونی شما $3 است.\nخواهشمند است تمام جزئیات بالا را در هر پرس‌وجویی که انجام می‌دهید قرار دهید.",
        "accmailtext": "یک گذرواژهٔ تصادفی برای [[User talk:$1|$1]] به $2 فرستاده شد. می‌توان آن را از صفحهٔ ''[[Special:ChangePassword|تغییر گذرواژه]]'' که هنگام ثبت ورود نمایش می‌یابد تغییر داد.",
        "newarticle": "(تازه)",
        "newarticletext": "شما پیوندی را دنبال کرده‌اید و به صفحه‌ای رسیده‌اید که هنوز وجود ندارد.\nبرای ایجاد صفحه، در مستطیل زیر شروع به نوشتن کنید (برای اطلاعات بیشتر به [$1 صفحهٔ راهنما] مراجعه کنید).\nاگر به اشتباه اینجا آمده‌اید، دکمهٔ «بازگشت» مرورگرتان را بزنید.",
-       "anontalkpagetext": "----<em>این صفحهٔ بحث برای کاربر گمنامی است که هنوز حسابی درست نکرده است یا از آن استفاده نمی‌کند.\nبنا بر این برای شناسایی‌اش مجبوریم از نشانی آی‌پی عددی استفاده کنیم.</em>\nچنین نشانی‌های آی‌پی ممکن است توسط چندین کاربر به شکل مشترک استفاده شود.\nاگر شما کاربر گمنامی هستید و تصور می‌کنید اظهار نظرات نامربوط به شما صورت گرفته است، لطفاً برای پیشگیری از اشتباه گرفته شدن با کاربران گمنام دیگر در آینده [[Special:CreateAccount|حسابی ایجاد کنید]] یا [[Special:UserLogin|به سامانه وارد شوید]].",
+       "anontalkpagetext": "----<em>این صفحهٔ بحث برای کاربر گمنامی است که هنوز حسابی درست نکرده است یا از آن استفاده نمی‌کند.\nبنا بر این برای شناسایی‌اش مجبوریم از نشانی آی‌پی عددی استفاده کنیم.</em> \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}}|این عنوان را جستجو کنید]]،\nیا <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} سیاهه‌های مرتبط را بگردید]</span> ولی شما اجازه ایجاد این صفحه را ندارید.",
        "missing-revision": "ویرایش #$1 از صفحهٔ «{{FULLPAGENAME}}» موجود نیست.\n\nاین اتفاق معمولاً در اثر دنبال کردن پیوندی به تاریخچهٔ یک صفحهٔ حذف‌شده پیش می‌آید.\nمی‌توانید جزئیات بیشتر را در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] بیابید.",
        "edit-gone-missing": "امکان به‌روز کردن صفحه وجود ندارد.\nبه نظرمی‌رسد که صفحه حذف شده باشد.",
        "edit-conflict": "تعارض ویرایشی.",
        "edit-no-change": "ویرایش شما نادیده گرفته شد، زیرا تغییری در متن داده نشده بود.",
+       "edit-slots-cannot-add": "این {{PLURAL:$1|اسلات|اسلات‌ها}} پشتیبانی نمی‌شود: $2.",
+       "edit-slots-cannot-remove": "امکان حذف این {{PLURAL:$1|اسلات|اسلات‌ها}} وجود ندارد: $2.",
+       "edit-slots-missing": "این {{PLURAL:$1|اسلات|اسلات‌ها}} ناموجود است: $2.",
        "postedit-confirmation-created": "صفحه ایجاد شده است.",
        "postedit-confirmation-restored": "صفحه بازیابی شده است.",
        "postedit-confirmation-saved": "ویرایش شما ذخیره شد.",
        "defaultmessagetext": "متن پیش‌فرض پیغام",
        "content-failed-to-parse": "عدم موفقیت در تجزیه محتوای $2 برای مدل $1: $3",
        "invalid-content-data": "داده محتوای نامعتبر",
-       "content-not-allowed-here": "محتوای «$1» در صفحهٔ [[:$2]] مجاز نیست",
+       "content-not-allowed-here": "محتوای «$1» در صفحهٔ [[:$2]] بخش «$3» مجاز نیست",
        "editwarning-warning": "خروج از این صفحه ممکن است باعث شود که شما هر شانسی که به وجود آورده‌اید را از دست بدهید.\nاگر شما وارد سامانه شده‌اید، می‌توانید این هشدار را در بخش «{{int:prefs-editing}}» ترجیحاتتان غیرفعال کنید.",
        "editpage-invalidcontentmodel-title": "مدل محتوای پشتیبانی نشده",
        "editpage-invalidcontentmodel-text": "مدل محتوای «$1» پشتیبای نمی‌شود.",
        "histfirst": "قدیمی‌ترین",
        "histlast": "جدیدترین",
        "historysize": "({{PLURAL:$1|۱ بایت|$1 بایت}})",
-       "historyempty": "(خالی)",
+       "historyempty": "خالی",
        "history-feed-title": "تاریخچهٔ ویرایش‌ها",
        "history-feed-description": "تاریخچهٔ ویرایش‌های این صفحه در ویکی",
        "history-feed-item-nocomment": "$1 در $2",
        "prefs-displayrc": "گزینه‌های نمایش",
        "prefs-displaywatchlist": "گزینه‌های نمایش",
        "prefs-changesrc": "نمایش تغییرات",
+       "prefs-changeswatchlist": "نمایش تغییرات",
        "prefs-pageswatchlist": "صفحه‌های پی‌گیری‌شده",
        "prefs-tokenwatchlist": "بلیط",
        "prefs-diffs": "تفاوت‌ها",
        "right-reupload-own": "بارگذاری دوبارهٔ پرونده‌ای که پیش از این توسط همان کاربر بارگذاری شده‌است",
        "right-reupload-shared": "باطل‌کردن محلی پرونده‌های مشترک",
        "right-upload_by_url": "بارگذاری پرونده از یک نشانی اینترنتی",
-       "right-purge": "پاک‌کردن میانگیر صفحه بدون مشاهدهٔ صفحهٔ تأیید",
+       "right-purge": "پاک‌کردن میانگیر صفحه",
        "right-autoconfirmed": "از محدودیت‌های سرعت آی‌پی‌-محور تاثیر نمی‌گیرد",
        "right-bot": "تلقی‌شده به عنوان یک فرآیند خودکار",
        "right-nominornewtalk": "ویرایش جزئی صفحه‌های بحث به شکلی که باعث اعلان پیغام تازه نشود",
        "grant-delete": "حذف صفحات، نسخه‌های ویرایش و سیاهه ورودی",
        "grant-editinterface": "ویرایش صفحه‌های جی‌سان کاربری یا سراسری و فضای نام مدیاویکی",
        "grant-editmycssjs": "ویرایش  CSS /جاوااسکریپت/JSON  کاربری",
-       "grant-editmyoptions": "اولویت‌های کاربری را ویرایش کنید",
+       "grant-editmyoptions": "اولویت‌های کاربری و پیکربندی JSON را ویرایش کنید",
        "grant-editmywatchlist": "ویرایش فهرست پی‌گیری‌هایتان",
        "grant-editsiteconfig": "ویرایش گسترده CSS/JS کاربر",
        "grant-editpage": "ویرایش صفحات موجود",
        "rcfilters-watchlist-markseen-button": "نشانه‌گذاری تمام تغییرات به‌عنوان خوانده‌شده",
        "rcfilters-watchlist-edit-watchlist-button": "ویرایش فهرست صفحه‌های پی‌گیری‌هایتان",
        "rcfilters-watchlist-showupdated": "تغییرات صفحاتی که شما از زمانی که تغییر بازدیدشان نکرده‌اید به صورت <strong>پررنگ</strong> و با نشانگر توپر نمایش می‌یابد.",
-       "rcfilters-preference-label": "مخفی کردن نسخه بهبود یافته تغییرات اخیر",
-       "rcfilters-preference-help": "تغییرات رابط کاربری که در سال ۲۰۱۷ اضافه شده است را بر می‌گرداند.",
+       "rcfilters-preference-label": "استفاده واسط بدون جاوااسکریپت",
+       "rcfilters-preference-help": "نمایش تغییرات اخیر بدون پالایه‌های جستجو یا قابلیت پررنگ کردن.",
        "rcfilters-watchlist-preference-label": "استفاده واسط بدون جاوااسکریپت",
-       "rcfilters-watchlist-preference-help": "Ù\88اگرداÙ\86 Ø¯Ø± Ø³Ø§Ù\84 Û²Û°Û±Û· Ø¯Ù\88بارÙ\87 Ø·Ø±Ø§Ø­Û\8c Ø´Ø¯ Ù\88 ØªÙ\85اÙ\85 Ø§Ø¨Ø²Ø§Ø±Ù\87ا Ø§Ø¶Ø§Ù\81Ù\87 Ù\88 Ø§Ø² Ø¢Ù\86 Ø²Ù\85اÙ\86 Ø¨Ù\87 Ø¨Ø¹Ø¯ Ø§Ø¶Ø§Ù\81Ù\87 Ø´Ø¯Ù\86د.",
+       "rcfilters-watchlist-preference-help": "Ù\86Ù\85اÛ\8cØ´ Ù\81Ù\87رست Ù¾Û\8câ\80\8cÚ¯Û\8cرÛ\8c Ø¨Ø¯Ù\88Ù\86 Ù¾Ø§Ù\84اÛ\8cÙ\87â\80\8cÙ\87اÛ\8c Ø¬Ø³ØªØ¬Ù\88 Û\8cا Ù\82ابÙ\84Û\8cت Ù¾Ø±Ø±Ù\86Ú¯ Ú©Ø±Ø¯Ù\86.",
        "rcfilters-filter-showlinkedfrom-label": "نمایش تغییرات صفحاتی که پیوند شده‌اند",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>صفحات پیوند به</strong> صفحهٔ انتخاب شده",
        "rcfilters-filter-showlinkedto-label": "نمایش تغییرات در صفحاتی که در ون این صفحه پیوند شده‌اند",
        "move": "انتقال",
        "movethispage": "انتقال این صفحه",
        "unusedimagestext": "پرونده‌های زیر موجودند اما در هیچ صفحه‌ای به کار نرفته‌اند.\nلطفاً توجه داشته باشید که دیگر وبگاه‌ها ممکن است با یک نشانی اینترنتی مستقیم به یک پرونده پیوند دهند، و با وجود این که در استفادهٔ فعال هستند در این جا فهرست شوند.",
+       "unusedimagestext-categorizedimgisused": "فایل موردنظر موجود است اما در هیچ صفحه‌ای استفاده نشده است. تصاویر رده‌بندی‌شده حتی اگر در هیچ صفحه‌ای درج نشده باشند، به عنوان تصاویر مورداستفاده محسوب می‌شوند.\nلطفا توجه داشته باشید که دیگر وب‌سایت‌ها ممکن است به صورت مستقیم به یک فایل پیوند داده باشند و با وجود اینکه آن فایل فعال محسوب می‌شود در اینجا لیست شده باشد.",
        "unusedcategoriestext": "این رده‌ها وجود دارند ولی هیچ مقاله یا ردهٔ دیگری از آنها استفاده نمی‌کند.",
        "notargettitle": "مقصدی نیست",
        "notargettext": "شما صفحهٔ یا کاربر مقصدی برای انجام این عمل روی آن مشخص نکرده‌اید.",
        "deleting-backlinks-warning": "<strong>هشدار:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|صفحه‌های دیگری]] هستند که به صفحه‌ای که شما در حال حذف آن هستید پیوند دارند یا آن را تراگنجانیده‌اند.",
        "deleting-subpages-warning": "<strong>هشدار:</strong> صفحه‌ای که شما می‌خواهید حذف کنید [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|یک زیرصفحه|$1 زیرصفحه|51=بیش از پنجاه زیرصفحه}}]] دارد.",
        "rollback": "واگردانی ویرایش‌ها",
+       "rollback-confirmation-confirm": "لطفاً تأیید کنید:",
+       "rollback-confirmation-yes": "واگردانی",
+       "rollback-confirmation-no": "انصراف",
        "rollbacklink": "واگردانی",
        "rollbacklinkcount": "واگردانی $1 ویرایش",
        "rollbacklinkcount-morethan": "واگردانی بیش از $1 ویرایش",
        "revertpage": "ویرایش [[Special:Contributions/$2|$2]] ([[User talk:$2|بحث]]) به آخرین تغییری که [[User:$1|$1]] انجام داده بود واگردانده شد",
        "revertpage-nouser": "ویرایش‌های انجام‌شده توسط (نام کاربری حذف شده) به آخرین ویرایش [[User:$1|$1]] واگردانی شد.",
        "rollback-success": "ویرایش‌های {{GENDER:$3|$1}} واگردانی شد؛\nصفحه به آخرین ویرایش {{GENDER:$4|$2}} برگردانده شد.",
-       "rollback-success-notify": "ویرایش‌های توسط $1 واگردانی شد؛\nبه آخرین نسخه توسط $2 بازگردانی شد. [$3 نمایش تغییرات]",
        "sessionfailure-title": "خطای نشست کاربری",
        "sessionfailure": "به نظر می‌رسد مشکلی در مورد نشست کاربری شما وجود دارد؛\nعمل درخواست شده در اقدامی پیشگیرانه در برابر ربوده‌شدن اطلاعات نشست کاربری، لغو شد.\nلطفاً فرم را از نو بارگذاری کنید.",
        "changecontentmodel": "ویرایش نمونه محتوای یک صفحه",
        "mycontris": "مشارکت‌ها",
        "anoncontribs": "مشارکت‌ها",
        "contribsub2": "برای {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "برای {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "حساب کاربری «$1» ثبت نشده‌است.",
+       "negative-namespace-not-supported": "فضاهای نام با مقدار منفی پشتیبانی نمی‌شوند.",
        "nocontribs": "هیچ تغییری با این مشخصات یافت نشد.",
        "uctop": "نسخهٔ کنونی",
        "month": "در این ماه (و پیش از آن):",
        "ipb-disableusertalk": "ویرایش صفحهً بحث توسط خود کاربر",
        "ipb-change-block": "بستن دوبارهٔ کاربر با این تنظیم‌ها",
        "ipb-confirm": "تأیید بستن",
-       "ipb-partial": "جزئی",
+       "ipb-sitewide": "کلی",
+       "ipb-partial": "موردی",
+       "ipb-sitewide-help": "هر صفحه‌ای در ویکی و تمام فعالیت‌های مشارکتی دیگر",
+       "ipb-partial-help": "صفحات خاص یا فضاهای نامی",
        "ipb-pages-label": "صفحات",
        "ipb-namespaces-label": "فضاهای نام",
        "badipaddress": "نشانی آی‌پی نامعتبر",
        "ipb-blocklist": "دیدن قطع دسترسی‌های موجود",
        "ipb-blocklist-contribs": "مشارکت‌های $1",
        "ipb-blocklist-duration-left": "$1 باقی مانده",
+       "block-actions": "اقدامات قطع دسترسی شده:",
        "block-expiry": "زمان سرآمدن:",
+       "block-options": "گزینه‌های بیشتر:",
        "block-prevent-edit": "در حال ویرایش",
        "block-reason": "دلیل:",
        "block-target": "نام کاربری یا آدرس آی‌پی:",
        "emailblock": "ایمیل بسته‌شده",
        "blocklist-nousertalk": "نمی‌تواند صفحهٔ بحث خود را ویرایش کند",
        "blocklist-editing": "در حال ویرایش",
+       "blocklist-editing-sitewide": "ویرایش (کل ویکی)",
        "blocklist-editing-page": "صفحات",
        "blocklist-editing-ns": "فضاهای نام",
        "ipblocklist-empty": "فهرست بسته‌شدن‌ها خالی‌است.",
        "ipb_expiry_old": "زمان سرآمدن در گذشته‌است.",
        "ipb_expiry_temp": "قطع دسترسی کاربرهای پهنان باید همیشگی باشد.",
        "ipb_hide_invalid": "قادر به سرکوب این حساب نیست; این بیشتر از {{PLURAL:$1|یک ویرایش|$1 ویرایش‌ها}} دارد.",
+       "ipb_hide_partial": "قطع دسترسی با پنهان کردن نام کاربری حتما باید یک قطع دسترسی سراسری باشد",
        "ipb_already_blocked": "«$1» همین الان هم بسته‌است",
        "ipb-needreblock": "دسترسی $1 از قبل بسته است. آیا می‌خواهید تنظیمات آن را تغییر دهید؟",
        "ipb-otherblocks-header": "سایر {{PLURAL:$1|قطع دسترسی‌ها|قطع دسترسی‌ها}}",
        "move-watch": "پی‌گیری صفحه‌های مبدأ و مقصد",
        "movepagebtn": "صفحه منتقل شود",
        "pagemovedsub": "انتقال با موفقیت انجام شد",
+       "cannotmove": "این صفحه قابل انتقال نیست به {{PLURAL:$1|دلیل|دلایل}}:",
        "movepage-moved": "'''«$1» به «$2» منتقل شد'''",
        "movepage-moved-redirect": "یک تغییرمسیر ایجاد شد.",
        "movepage-moved-noredirect": "از ایجاد تغییرمسیر ممانعت شد.",
+       "movepage-delete-first": "صفحه مقصد تعداد زیادی نسخه برای حذف دارد. لطفا ابتدا صفحه را دستی حذف کنید و سپس دوباره سعی کنید.",
        "articleexists": "صفحه‌ای با این نام از قبل وجود دارد، یا نامی که انتخاب کرده‌اید معتبر نیست.\nلطفاً نام دیگری انتخاب کنید.",
        "cantmove-titleprotected": "شما نمی‌توانید صفحه را به این نشانی انتقال دهید، چرا که عنوان جدید در برابر ایجاد محافظت شده‌است",
        "movetalk": "صفحهٔ بحث هم منتقل شود",
        "pageinfo-category-files": "تعداد پرونده‌ها",
        "pageinfo-user-id": "شناسه کاربر",
        "pageinfo-file-hash": "مقدار هش",
+       "pageinfo-view-protect-log": "نمایش سیاهه محفاظت برای این صفحه.",
        "markaspatrolleddiff": "برچسب گشت بزن",
        "markaspatrolledtext": "به این صفحه برچسب گشت بزن",
        "markaspatrolledtext-file": "انتخاب این نسخهٔ پرونده به عنوان گشت خورده",
        "confirm-unwatch-top": "این صفحه از فهرست پی‌گیری‌های شما حذف شود؟",
        "confirm-rollback-button": "باشد",
        "confirm-rollback-top": "خنثی‌سازی ویرایش‌های این صفحه؟",
+       "confirm-rollback-bottom": "این عمل به سرعت تغییرات انتخاب‌شده در صفحه را واگردانی خواهد کرد.",
        "confirm-mcrrestore-title": "بازیابی نسخه",
        "confirm-mcrundo-title": "خنثی کردن تغییرات",
        "mcrundofailed": "واگردانی ناموفق بود",
+       "mcrundo-missingparam": "فقدان پارامترهای ضروری در درخواست",
+       "mcrundo-changed": "این صفحه از زمانی که شما تفاوت را دیده‌اید تغییر کرده است. تغییر جدید را مشاهده کنید.",
+       "mcrundo-parse-failed": "قادر به تجزیه نسخه جدید نیست: $1",
        "semicolon-separator": "؛&#32;",
        "comma-separator": "،&#32;",
        "percent": "$1٪",
        "specialpages-group-developer": "ابزارهای توسعه‌دهندگان",
        "blankpage": "صفحهٔ خالی",
        "intentionallyblankpage": "این صفحه به طور عمدی خالی گذاشته شده است.",
+       "disabledspecialpage-disabled": "این صفحه توسط یک مدیر غیرفعال شده‌است.",
        "external_image_whitelist": " #این سطر را همان‌گونه که هست رها کنید<pre>\n#عبارت‌های باقاعده (regex) را در زیر قرار دهید (فقط بخشی که بین // قرار می‌گیرد)\n#آن‌ها با نشانی اینترنتی تصاویر خارجی پیوند داده شده تطبیق داده می‌شوند\n#مواردی که مطابق باشند به صورت تصویر نمایش می‌یابند، و در غیر این صورت تنها یک پیوند به تصویر نمایش می‌یابد\n#سطرهایی که با # آغاز شوند به عنوان توضیحات در نظر گرفته می‌شوند\n#این سطرها به کوچکی و بزرگی حروف حساس هستند\n\n#عبارت‌های باقاعده (regex)  را زیر این سطر قرار دهید. این سطر را همان‌گونه که هست رها کنید</pre>",
        "tags": "برچسب‌های تغییر مجاز",
        "tag-filter": "پالایش [[Special:Tags|برچسب‌ها]]:",
        "logentry-block-block": "$1 {{GENDER:$4|$3}} را $5 {{GENDER:$2|بست}} $6",
        "logentry-block-unblock": "$1 {{GENDER:$4|$3}} را {{GENDER:$2|بازکرد}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|تنظیمات}} بستن {{GENDER:$4|$3}} را به پایان قطع دسترسی $5 $6 تغییر داد.",
+       "logentry-partialblock-block-page": "{{PLURAL:$1|صفحه|صفحات}} $2",
+       "logentry-partialblock-block-ns": "{{PLURAL:$1|فضای نام|فضاهای نام}} $2",
+       "logentry-partialblock-block": "$1 {{GENDER:$4|$3}} را از ویرایش $7 با انقضای $5 $6 {{GENDER:$2|قطع دسترسی کرد}}",
+       "logentry-partialblock-reblock": "$1 {{GENDER:$2|تنظیمات}} بستن {{GENDER:$4|$3}} را به جلوگیری از ویرایش $7 و پایان قطع دسترسی $5 $6 تغییر داد",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$4|$3}} را از اعمال مشخص‌شده غیرویرایشی با انقضای $5 $6 {{GENDER:$2|قطع دسترسی کرد}}",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|تنظیمات}} بستن {{GENDER:$4|$3}} را به جلوگیری از اعمال مشخص‌شده غیرویرایشی و پایان قطع دسترسی $5 $6 تغییر داد.",
        "logentry-suppress-block": "$1 {{GENDER:$2|بسته شد}} {{GENDER:$4|$3}} با پایان قطع دسترسی در زمان $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|تنظیمات}} بستن برای  {{GENDER:$4|$3}} به پایان قطع دسترسی  $5 $6 تغییر یافت",
        "logentry-import-upload": "$1 $3 را توسط بارگذار پرونده {{GENDER:$2|درون‌ریزی کرد}}",
        "logentry-rights-autopromote": "$1 به طور خودکار از $4 به $5 {{GENDER:$2|ارتقاء یافت}}",
        "logentry-upload-upload": "$1 $3 را {{GENDER:$2|بارگذاری کرد}}",
        "logentry-upload-overwrite": "$1 نسخهٔ تازه‌ای از $3 را {{GENDER:$2|بارگذاری کرد}}",
-       "logentry-upload-revert": "$1 {{GENDER:$2|بارگذاری کرد}} $3",
+       "logentry-upload-revert": "$1 $3 را به نسخه قدیمی {{GENDER:$2|واگردانی کرد}}",
        "log-name-managetags": "تاریخچه مدیریت برچسب",
        "log-description-managetags": "این صفحه امور مدیریتی مربوط به [[Special:Tags|برچسب‌ها]] را فهرست می‌کند. سیاهه فقط حاوی فعالیت‌هایی است که توسط یک مدیر به صورت دستی انجام شده‌اند؛ برچسب‌ها ممکن است توسط نرم‌افزار ویکی ساخته یا حذف بشوند بدون اینکه هیچ ورودی در این سیاهه ثبت گردد.",
        "logentry-managetags-create": "$1 برچسب «$4» را {{GENDER:$2|ایجاد کرد}}",
        "log-action-filter-suppress-reblock": "مخفی‌سازی کاربر با بستن مجدد",
        "log-action-filter-upload-upload": "بارگذاری جدید",
        "log-action-filter-upload-overwrite": "بارگذاری دوباره",
+       "log-action-filter-upload-revert": "واگردانی",
        "authmanager-authn-not-in-progress": "ارزیابی ورود در جريان نيست یا اطلاعات جلسه کاری از بين رفته است. لطفاً دوباره از ابتدا شروع کنيد.",
        "authmanager-authn-no-primary": "اعتبارسنجی اطلاعات ارائه شده جهت ورود ميسر نيست",
        "authmanager-authn-no-local-user": "اطلاعات ورود ارائه شده با هيچ کاربری در اين ويکی مرتبط نيست",
        "authmanager-create-no-primary": "اطلاعات اعتبارسنجی ارائه شده نمی‌تواند جهت ايجاد حساب بکار رود.",
        "authmanager-link-no-primary": "اطلاعات اعتبارسنجی ارائه شده نمی‌تواند جهت مرتبط کردن حساب بکار رود.",
        "authmanager-link-not-in-progress": "مرتبط کردن حساب در جريان نيست یا اطلاعات جلسه کاری از بين رفته است. لطفاً دوباره از ابتدا شروع کنيد.",
-       "authmanager-authplugin-setpass-failed-title": "تغییر گذرواژه ناموفق بود",
-       "authmanager-authplugin-setpass-failed-message": "افزونهٔ اعتبارسنجی، تغيير گذزواژه را مردود دانست",
-       "authmanager-authplugin-create-fail": "افزونهٔ اعتبارسنجی، ايجاد حساب را مردود دانست",
-       "authmanager-authplugin-setpass-denied": "افزونهٔ اعتبارسنجی اجازهٔ تغيير گذرواژه را نمی‌دهد",
-       "authmanager-authplugin-setpass-bad-domain": "دامنه نامعتبر است.",
        "authmanager-autocreate-noperm": "ایجاد حساب خودکار مجاز نیست.",
        "authmanager-autocreate-exception": "ایجاد حساب کاربری به خاطر خطاهای قبلی به طور موقت غیرفعال است.",
        "authmanager-userdoesnotexist": "حساب کاربری «$1» ثبت نشده‌است.",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "گذرواژه نمی‌تواند مشابه گذرواژه‌های فهرست شده در فهرست سیاه باشد",
        "passwordpolicies-policy-maximalpasswordlength": "گذرواژه باید کمتر از $1 {{PLURAL:$1|نویسه|نویسه}} طول داشته باشد",
        "passwordpolicies-policy-passwordcannotbepopular": "گذرواژه نمی‌تواند {{PLURAL:$1|گذرواژه پراستفاده باشد|در فهرست $1 گذرواژه‌های پراستفاده باشد}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "گذرواژه نمی‌تواند یکی از ۱۰۰٬۰۰۰ گذرواژه پراستفاده باشد.",
+       "passwordpolicies-policyflag-forcechange": "در هنگام ورود باید تغییر دهید",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "در هنگام ورود، پیشنهاد تغییر بده",
        "easydeflate-invaliddeflate": "محتوی تهیه‌شده به صورت درست خالی نشده‌است",
        "unprotected-js": "به دلایل امنیتی، جاوااسکریپت نمی‌تواند از صفحات محافظت‌نشده بارگیری شود. لطفا جاوااسکریپت را تنها در فضای نام مدیاویکی: و یا در زیرصفحهٔ کاربری خودتان ایجاد کنید."
 }
index cefb492..8f96bd3 100644 (file)
        "nstab-category": "Luokka",
        "mainpage-nstab": "Etusivu",
        "nosuchaction": "Toimintoa ei ole olemassa",
-       "nosuchactiontext": "URL:ssä määritelty toiminto ei ole kelvollinen.\nOlet saattanut kirjoittaa URL:in väärin tai olet seurannut virheellistä linkkiä.\nKyseessä voi myös mahdollisesti olla virhe sivuston {{SITENAME}} käyttämässä ohjelmistossa.",
+       "nosuchactiontext": "URL:ssä määritelty toiminto ei ole kelvollinen.\nOlet saattanut kirjoittaa URL:in väärin tai olet seurannut virheellistä linkkiä.\nKyseessä voi myös mahdollisesti olla virhe {{GRAMMAR:genitive|{{SITENAME}}}} käyttämässä ohjelmistossa.",
        "nosuchspecialpage": "Kyseistä toimintosivua ei ole",
        "nospecialpagetext": "<strong>Ohjelmisto ei tunnista pyytämääsi toimintosivua.</strong>\n\nLuettelo toimintosivuista löytyy sivulta [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Virhe",
        "welcomecreation-msg": "Käyttäjätunnuksesi on luotu.\nVoit nyt muuttaa {{GRAMMAR:genitive|{{SITENAME}}}} [[Special:Preferences|asetuksia]] itsellesi.",
        "yourname": "Käyttäjänimi:",
        "userlogin-yourname": "Käyttäjänimi",
-       "userlogin-yourname-ph": "Kirjoita käyttäjätunnus",
+       "userlogin-yourname-ph": "Kirjoita käyttäjänimi",
        "createacct-another-username-ph": "Lisää käyttäjätunnus",
        "yourpassword": "Salasana:",
        "userlogin-yourpassword": "Salasana",
        "badretype": "Syöttämäsi salasanat ovat keskenään erilaiset.",
        "usernameinprogress": "Tunnuksen luominen tälle käyttäjänimelle on parhaillaan käynnissä.\nOle hyvä ja odota.",
        "userexists": "Pyytämäsi käyttäjänimi on jo käytössä. Valitse toinen käyttäjänimi.",
+       "createacct-normalization": "Käyttäjätunnuksesi muutetaan muotoon \"$2\" teknisten rajoitusten vuoksi.",
        "loginerror": "Sisäänkirjautumisvirhe",
        "createacct-error": "Virhe tunnuksen luomisessa",
        "createaccounterror": "Tunnuksen luonti ei onnistunut: $1",
        "createacct-loginerror": "Tunnus luotiin onnistuneesti, mutta automaattista sisäänkirjautumista ei voitu tehdä. Siirry [[Special:UserLogin|manuaaliseen kirjautumiseen]].",
        "noname": "Et ole määritellyt kelvollista käyttäjänimeä.",
        "loginsuccesstitle": "Olet kirjautunut sisään",
-       "loginsuccess": "'''Olet kirjautunut sivustolle {{SITENAME}} käyttäjänä $1.'''",
+       "loginsuccess": "<strong>Olet kirjautunut {{GRAMMAR:illative|{{SITENAME}}}} käyttäjänä \"$1\".</strong>",
        "nosuchuser": "Käyttäjää ”$1” ei ole olemassa.\nNimet ovat kirjainkoosta riippuvaisia. \nTarkista, kirjoititko nimen oikein, tai [[Special:CreateAccount|luo uusi käyttäjätunnus]].",
        "nosuchusershort": "Käyttäjää nimeltä ”$1” ei ole. Kirjoititko nimen oikein?",
        "nouserspecified": "Käyttäjätunnusta ei ole määritelty.",
        "passwordreset-email": "Sähköpostiosoite:",
        "passwordreset-emailtitle": "Tunnuksen tiedot {{GRAMMAR:inessive|{{SITENAME}}}}",
        "passwordreset-emailtext-ip": "Joku (todennäköisesti sinä, IP-osoitteesta $1) pyysi salasanasi\nvaihtamista sivustolla {{SITENAME}} ($4). {{PLURAL:$3|Seuraava käyttäjätunnus on|Seuraavat käyttäjätunnukset ovat}}\nyhdistettynä tähän sähköpostiosoitteeseen:\n\n$2\n\n{{PLURAL:$3|Tämä väliaikainen salasana vanhentuu|Nämä väliaikaiset salasanat vanhentuvat}} {{PLURAL:$5|yhden päivän|$5 päivän}} kuluttua.\nKirjaudu sisään nyt ja valitse uusi salasana heti. Jos joku toinen teki tämän pyynnön \ntai jos muistitkin vanhan salasanasi etkä halua enää muuttaa sitä,\nvoit jättää tämän viestin huomiotta ja jatkaa vanhan salasanasi käyttämistä.",
-       "passwordreset-emailtext-user": "Käyttäjä $1 pyysi muistutusta tunnuksesi tiedoista sivustolla {{SITENAME}} ($4).\n{{PLURAL:$3|Seuraava käyttäjätunnus on|Seuraavat käyttäjätunnukset ovat}} liitetty tähän sähköpostiosoitteeseen:\n\n$2\n\n{{PLURAL:$3|Tämä väliaikainen salasana vanhentuu|Nämä väliaikaiset salasanat vanhentuvat}} {{PLURAL:$5|yhden päivän|$5 päivän}} kuluttua.\nSinun kannattaa kirjautua sisään ja valita uusi salasana. Jos joku toinen teki tämän\npyynnön, tai muistat sittenkin vanhan salasanasi, etkä halua muuttaa sitä,\nvoit jättää tämän viestin huomiotta ja jatkaa vanhan salasanan käyttöä.",
+       "passwordreset-emailtext-user": "Käyttäjä $1 pyysi muistutusta tunnuksesi tiedoista {{GRAMMAR:inessive|{{SITENAME}}}} ($4).\n{{PLURAL:$3|Seuraava käyttäjätunnus on|Seuraavat käyttäjätunnukset ovat}} liitetty tähän sähköpostiosoitteeseen:\n\n$2\n\n{{PLURAL:$3|Tämä väliaikainen salasana vanhentuu|Nämä väliaikaiset salasanat vanhentuvat}} {{PLURAL:$5|yhden päivän|$5 päivän}} kuluttua.\nSinun kannattaa kirjautua sisään ja valita uusi salasana. Jos joku toinen teki tämän\npyynnön, tai muistat sittenkin vanhan salasanasi, etkä halua muuttaa sitä,\nvoit jättää tämän viestin huomiotta ja jatkaa vanhan salasanan käyttöä.",
        "passwordreset-emailelement": "Käyttäjätunnus: \n$1\n\nVäliaikainen salasana: \n$2",
        "passwordreset-emailsentemail": "Jos tämä on sinun tunnuksellesi rekisteröity sähköpostiosoite, salasanan uudistamisesta kertova viesti lähetetään.",
        "passwordreset-emailsentusername": "Jos on olemassa vastaava rekisteröity sähköpostiosoite, salasanan uudistamisesta kertova viesti lähetetään.",
        "continue-editing": "Siirry muokkauskenttään",
        "previewconflict": "Tämä esikatselu näyttää miltä muokkausalueella oleva teksti näyttää tallennettuna.",
        "session_fail_preview": "Muokkaustasi ei voitu tallentaa, koska istuntosi tiedot ovat kadonneet.\n\nSaatat olla kirjautunut ulos. '''Varmista, että olet edelleen kirjautunut sisään ja yritä uudelleen'''. Jos ongelma ei katoa, yritä [[Special:UserLogout|kirjautua ulos]] ja takaisin sisään, ja varmista, että selaimesi sallii evästeet tältä sivustolta.",
-       "session_fail_preview_html": "Valitettavasti muokkaustasi ei voitu käsitellä istunnon tietojen katoamisen vuoksi.\n\n<em>Koska sivustolla {{SITENAME}} on käytössä suodattamaton HTML-koodi, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi</em>\n\n<strong>Jos tämä on oikea muokkausyritys, yritä uudelleen.</strong> Jos ongelma ei katoa, yritä [[Special:UserLogout|kirjautua ulos]] ja takaisin sisään. Tarkista myös, että selaimesi sallii evästeet tältä sivustolta.",
+       "session_fail_preview_html": "Valitettavasti muokkaustasi ei voitu käsitellä istunnon tietojen katoamisen vuoksi.\n\n<em>Koska {{GRAMMAR:inessive|{{SITENAME}}}} on käytössä suodattamaton HTML-koodi, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi</em>\n\n<strong>Jos tämä on oikea muokkausyritys, yritä uudelleen.</strong> Jos ongelma ei katoa, yritä [[Special:UserLogout|kirjautua ulos]] ja takaisin sisään. Tarkista myös, että selaimesi sallii evästeet tältä sivustolta.",
        "token_suffix_mismatch": "'''Muokkauksesi on hylätty, koska asiakasohjelmasi ei osaa käsitellä välimerkkejä muokkaustarkisteessa. Syynä voi olla viallinen välityspalvelin.'''",
        "edit_form_incomplete": "'''Osa muokkauslomakkeesta ei saavuttanut palvelinta. Tarkista, että muokkauksesi ovat vahingoittumattomia ja yritä uudelleen.'''",
        "editing": "Muokataan sivua $1",
        "edit-gone-missing": "Sivun päivitys ei onnistunut.\nSe on ilmeisesti poistettu.",
        "edit-conflict": "Päällekkäinen muokkaus.",
        "edit-no-change": "Muokkauksesi sivuutettiin, koska tekstiin ei tehty mitään muutoksia.",
+       "edit-slots-cannot-add": "{{PLURAL:$1|Seuraava slotti ei ole tuettu|Seuraavat slotit eivät ole tuettuja}} täällä: $2.",
+       "edit-slots-cannot-remove": "{{PLURAL:$1|Seuraava slotti vaaditaan eikä sitä voi poistaa|Seuraavat alueet vaaditaan eikä niitä voida poistaa}}: $2.",
+       "edit-slots-missing": "{{PLURAL:$1|Seuraava slotti puuttuu|Seuraavat slotit puuttuvat}}: $2.",
        "postedit-confirmation-created": "Sivu on nyt luotu.",
        "postedit-confirmation-restored": "Sivu on nyt palautettu (aiempaan versioonsa).",
        "postedit-confirmation-saved": "Muokkauksesi on tallennettu.",
        "defaultmessagetext": "Viestin oletusteksti",
        "content-failed-to-parse": "Sisältö tyypiltään $2 ei jäsenny tyypiksi $1: $3",
        "invalid-content-data": "Virheellinen sisältö",
-       "content-not-allowed-here": "Sivun [[:$2]] sisältö ei voi olla tyyppiä $1.",
+       "content-not-allowed-here": "Sivun [[:$2]] sisältö ei voi olla tyyppiä \"$1\" slotissa \"$3\"",
        "editwarning-warning": "Tältä sivulta poistuminen saattaa aiheuttaa kaikkien tekemiesi muutosten katoamisen.\nJos olet kirjautunut sisään, voit poistaa tämän varoituksen käytöstä omien asetuksien osiossa ”{{int:prefs-editing}}”.",
        "editpage-invalidcontentmodel-title": "Sisältömalli ei ole tuettu",
        "editpage-invalidcontentmodel-text": "Sisältömalli ”$1” ei ole tuettu.",
        "histfirst": "vanhimmat",
        "histlast": "uusimmat",
        "historysize": "({{PLURAL:$1|1 tavu|$1 tavua}})",
-       "historyempty": "(tyhjä)",
+       "historyempty": "tyhjä",
        "history-feed-title": "Muutoshistoria",
        "history-feed-description": "Tämän sivun muutoshistoria",
        "history-feed-item-nocomment": "$1 ($2)",
        "right-reupload-own": "Korvata itsetallennettu tiedosto uudella tiedostolla",
        "right-reupload-shared": "Korvata yhteiseen mediavarastoon tallennettuja tiedostoja paikallisesti",
        "right-upload_by_url": "Tallentaa tiedostoja verkko-osoitteella",
-       "right-purge": "Tyhjentää sivuston välimuisti ilman varmennussivua",
+       "right-purge": "Tyhjentää sivuston välimuisti",
        "right-autoconfirmed": "IP-pohjaiset nopeusrajoitukset eivät ole voimassa",
        "right-bot": "Kohdellaan automaattisena prosessina",
        "right-nominornewtalk": "Tehdä pieniä muokkauksia käyttäjien keskustelusivuille siten, että käyttäjälle ei ilmoiteta siitä uutena viestinä",
        "upload-form-label-own-work": "Tämä on oma työni",
        "upload-form-label-infoform-categories": "Luokat",
        "upload-form-label-infoform-date": "Päivämäärä",
-       "upload-form-label-own-work-message-generic-local": "Vakuutan, että tallennan tämän tiedoston noudattaen sivustolla {{SITENAME}} voimassa olevia käyttöehtoja sekä lisenssejä koskevia käytäntöjä.",
-       "upload-form-label-not-own-work-message-generic-local": "Jos et kykene tallentamaan tätä tiedostoa noudattaen niitä käytäntöjä, jotka ovat voimassa sivustolla {{SITENAME}}, sulje tämä dialogi ja kokeile jotain toista menetelmää.",
+       "upload-form-label-own-work-message-generic-local": "Vakuutan, että tallennan tämän tiedoston noudattaen {{GRAMMAR:inessive|{{SITENAME}}}} voimassa olevia käyttöehtoja sekä lisenssejä koskevia käytäntöjä.",
+       "upload-form-label-not-own-work-message-generic-local": "Jos et kykene tallentamaan tätä tiedostoa noudattaen niitä käytäntöjä, jotka ovat voimassa {{GRAMMAR:inessive|{{SITENAME}}}}, sulje tämä dialogi ja kokeile jotain toista menetelmää.",
        "upload-form-label-not-own-work-local-generic-local": "Voit myös kokeilla [[Special:Upload|yleistä tallentamista]].",
        "upload-form-label-own-work-message-generic-foreign": "Ymmärrän, että olen tallentamassa tätä tiedostoa yhteiseen mediasäilöön. Vakuutan, että teen tämän noudattaen asiaankuuluvia käyttöehtoja ja lisenssejä koskevia käytäntöjä.",
        "upload-form-label-not-own-work-message-generic-foreign": "Jos et kykene tallentamaan tätä tiedostoa noudattaen niitä käytäntöjä, jotka ovat voimassa yhteisessä mediasäilössä, sulje tämä dialogi ja kokeile jotain toista menetelmää.",
-       "upload-form-label-not-own-work-local-generic-foreign": "Voit myös kokeilla [[Special:Upload|tallennussivua sivustolla {{SITENAME}}]]. Saattaa olla, että tämän tiedoston tallentaminen sinne on mahdollista siellä voimassa olevien käytäntöjen mukaisesti.",
+       "upload-form-label-not-own-work-local-generic-foreign": "Voit myös kokeilla [[Special:Upload|tallennussivua {{GRAMMAR:inessive|{{SITENAME}}}}]]. Saattaa olla, että tämän tiedoston tallentaminen sinne on mahdollista siellä voimassa olevien käytäntöjen mukaisesti.",
        "backend-fail-stream": "Tiedoston $1 virtauttaminen epäonnistui.",
        "backend-fail-backup": "Tiedostoa $1 ei voitu varmuuskopioida.",
        "backend-fail-notexists": "Tiedostoa $1 ei ole olemassa.",
        "emailuser-title-target": "Lähetä sähköpostia tälle {{GENDER:$1|käyttäjälle}}",
        "emailuser-title-notarget": "Lähetä sähköpostia käyttäjälle",
        "emailpagetext": "Jos tämä {{GENDER:$1|käyttäjä}} on antanut asetuksissaan kelvollisen sähköpostiosoitteen, alla olevalla lomakkeella voit lähettää hänelle viestin. [[Special:Preferences|Omissa asetuksissasi]] annettu sähköpostiosoite näkyy sähköpostin lähettäjän osoitteena, jotta vastaanottaja voi suoraan vastata viestiin.",
-       "defemailsubject": "Sähköpostia käyttäjältä $1 sivustolta {{SITENAME}}",
+       "defemailsubject": "Sähköpostia käyttäjältä $1 {{GRAMMAR:elative|{{SITENAME}}}}",
        "usermaildisabled": "Käyttäjien sähköposti poistettu käytöstä",
        "usermaildisabledtext": "Et voi lähettää sähköpostia muille käyttäjille tässä wikissä",
        "noemailtitle": "Ei sähköpostiosoitetta",
        "emailccsubject": "Kopio lähettämästäsi viestistä osoitteeseen $1: $2",
        "emailsent": "Sähköposti lähetetty",
        "emailsenttext": "Sähköpostiviestisi on lähetetty.",
-       "emailuserfooter": "Tämän sähköpostin {{GENDER:$1|lähetti}} $1 vastaanottajalle {{GENDER:$2|$2}} käyttämällä ”{{int:emailuser}}” -toimintoa {{GRAMMAR:inessive|{{SITENAME}}}}. Jos vastaat tähän sähköpostiin, sinun sähköpostiviestisi lähetetään suoraan {{GENDER:$1|alkuperäiselle lähettäjälle}} ja samalla paljastetaan {{GENDER:$2|sinun}} sähköpostiosoitteesi {{GENDER:$1|hänelle}}.",
+       "emailuserfooter": "Tämän sähköpostin {{GENDER:$1|lähetti}} $1 vastaanottajalle {{GENDER:$2|$2}} käyttämällä ”{{int:emailuser}}” -toimintoa {{GRAMMAR:inessive|{{SITENAME}}}}. Jos vastaat tähän sähköpostiin, sähköpostiviestisi lähetetään suoraan {{GENDER:$1|alkuperäiselle lähettäjälle}} ja samalla paljastetaan {{GENDER:$2|sinun}} sähköpostiosoitteesi {{GENDER:$1|hänelle}}.",
        "usermessage-summary": "Jätetään järjestelmäviesti.",
        "usermessage-editor": "Järjestelmäviestittäjä",
        "watchlist": "Tarkkailulista",
        "watcherrortext": "Sivun ”$1” tarkkailulista-asetusten muutoksissa tapahtui virhe.",
        "enotif_reset": "Merkitse kaikki sivut nähdyiksi",
        "enotif_impersonal_salutation": "{{GRAMMAR:genitive|{{SITENAME}}}} käyttäjä",
-       "enotif_subject_deleted": "{{GENDER:$2|$2}} poisti {{GRAMMAR:elative|{{SITENAME}}}} sivun $1",
-       "enotif_subject_created": "{{GENDER:$2|$2}} loi {{GRAMMAR:illative|{{SITENAME}}}} sivun $1",
-       "enotif_subject_moved": "{{GENDER:$2|$2}} siirsi {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1",
-       "enotif_subject_restored": "{{GENDER:$2|$2}} palautti {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1",
-       "enotif_subject_changed": "{{GENDER:$2|$2}} muutti {{GRAMMAR:inessive|{{SITENAME}}}} sivua $1",
-       "enotif_body_intro_deleted": "{{GENDER:$2|$2}} poisti {{GRAMMAR:elative|{{SITENAME}}}} sivun $1 $PAGEEDITDATE ($3).",
+       "enotif_subject_deleted": "$2 {{GENDER:$2|poisti}} {{GRAMMAR:elative|{{SITENAME}}}} sivun $1",
+       "enotif_subject_created": "$2 {{GENDER:$2|loi}} {{GRAMMAR:illative|{{SITENAME}}}} sivun $1",
+       "enotif_subject_moved": "$2 {{GENDER:$2|siirsi}} {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1",
+       "enotif_subject_restored": "$2 {{GENDER:$2|palautti}} {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1",
+       "enotif_subject_changed": "$2 {{GENDER:$2|muutti}} {{GRAMMAR:inessive|{{SITENAME}}}} sivua $1",
+       "enotif_body_intro_deleted": "$2 {{GENDER:$2|poisti}} {{GRAMMAR:elative|{{SITENAME}}}} sivun $1 $PAGEEDITDATE ($3).",
        "enotif_body_intro_created": "{{GENDER:$2|$2}} loi {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1 $PAGEEDITDATE. Sivun nykyinen versio on osoitteessa $3.",
        "enotif_body_intro_moved": "{{GENDER:$2|$2}} siirsi {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1 $PAGEEDITDATE. Sivun nykyinen versio on osoitteessa $3.",
        "enotif_body_intro_restored": "{{GENDER:$2|$2}} palautti {{GRAMMAR:inessive|{{SITENAME}}}} sivun $1 $PAGEEDITDATE. Sivun nykyinen versio on osoitteessa $3.",
        "delete-confirm": "Poista ”$1”",
        "delete-legend": "Sivun poisto",
        "historywarning": "<strong>Varoitus:</strong> Sivulla, jota olet poistamassa, on muokkaushistoriaa ja sitä on muokattu $1 {{PLURAL:$1|kerran|kertaa}}:",
-       "historyaction-submit": "Näytä",
+       "historyaction-submit": "Näytä muokkaushistoria",
        "confirmdeletetext": "Olet poistamassa sivun ja kaiken sen historian.\nVahvista, että olet aikeissa tehdä tämän ja että ymmärrät teon seuraukset ja teet poiston [[{{MediaWiki:Policy-url}}|käytäntöjen]] mukaisesti.",
        "actioncomplete": "Toiminto suoritettu",
        "actionfailed": "Toiminto epäonnistui",
        "deletereasonotherlist": "Muu syy",
        "deletereason-dropdown": "* Yleiset poistosyyt\n** Spam tai mainossivu\n** Vandalismi\n** Tekijänoikeusrikkomus\n** Sivun tekijän pyyntö\n** Virheellinen ohjaus",
        "delete-edit-reasonlist": "Muokkaa poistosyitä",
-       "delete-toobig": "Tällä sivulla on pitkä muokkaushistoria, yli $1 {{PLURAL:$1|versio|versiota}}. \nTämänkaltaisten sivujen poistamista on rajoitettu. Tällä ehkäistään sivuston {{SITENAME}} vaurioitumista tahattomasti.",
-       "delete-warning-toobig": "Tällä sivulla on pitkä muutoshistoria – yli $1 {{PLURAL:$1|versio|versiota}}. Näin suurien muutoshistorioiden poistaminen voi haitata sivuston suorituskykyä.",
+       "delete-toobig": "Tällä sivulla on pitkä muokkaushistoria, yli $1 {{PLURAL:$1|versio|versiota}}. \nTämänkaltaisten sivujen poistamista on rajoitettu. Tällä ehkäistään {{GRAMMAR:genitive|{{SITENAME}}}} vaurioitumista tahattomasti.",
+       "delete-warning-toobig": "Tällä sivulla on pitkä muutoshistoria – yli $1 {{PLURAL:$1|versio|versiota}}. Näin suurien muutoshistorioiden poistaminen voi haitata {{GRAMMAR:genitive|{{SITENAME}}}} suorituskykyä.",
        "deleteprotected": "Et voi poistaa tätä sivua, koska se on suojattu.",
        "deleting-backlinks-warning": "<strong>Varoitus:</strong> Sivulle, jota olet poistamassa, johtaa [[Special:WhatLinksHere/{{FULLPAGENAME}}|linkkejä muilta sivuilta]], taikka sivu on sisällytetty muuhun sivuun.",
        "deleting-subpages-warning": "<strong>Varoitus:</strong> Sivu jota olet poistamassa on [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|alasivu|$1 alasivua|51=yli 50 alasivua}}]].",
        "rollback": "palauta aiempaan versioon",
+       "rollback-confirmation-confirm": "Vahvista:",
+       "rollback-confirmation-yes": "Palauta",
+       "rollback-confirmation-no": "Peruuta",
        "rollbacklink": "palauta",
        "rollbacklinkcount": "palauta $1 {{PLURAL:$1|muutos|muutosta}}",
        "rollbacklinkcount-morethan": "palauta yli $1 {{PLURAL:$1|muutos|muutosta}}",
        "revertpage": "Käyttäjän [[Special:Contributions/$2|$2]] ([[User talk:$2|keskustelu]]) muokkaukset kumottiin ja sivu palautettiin viimeisimpään käyttäjän [[User:$1|$1]] tekemään versioon.",
        "revertpage-nouser": "Käyttäjän (käyttäjänimi poistettu) muokkaukset kumottiin ja sivu palautettiin viimeisimpään käyttäjän {{GENDER:$1|[[User:$1|$1]]}} tekemään versioon",
        "rollback-success": "Käyttäjän {{GENDER:$3|$1}} tekemät muokkaukset kumottiin ja sivu palautettiin käyttäjän {{GENDER:$4|$2}} versioon.",
-       "rollback-success-notify": "Kumottiin käyttäjän $1 muokkaukset; palautettiin viimeiseen käyttäjän $2 versioon. [$3 Näytä muutokset]",
        "sessionfailure-title": "Istuntovirhe",
        "sessionfailure": "Näyttää siltä, että tämänhetkisessä istunnossasi on jokin ongelma; \ntämä toiminto on peruutettu varotoimena istunnon kaappaamisen estämiseksi.\nLähetä lomake uudelleen.",
        "changecontentmodel": "Muuta sivun sisältömallia",
        "mycontris": "Muokkaukset",
        "anoncontribs": "Muokkaukset",
        "contribsub2": "Käyttäjän {{GENDER:$3|$1}} ($2) muokkaukset",
+       "contributions-subtitle": "Käyttäjän {{GENDER:$3|$1}} muokkaukset",
        "contributions-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
+       "negative-namespace-not-supported": "Negatiivisia arvoja sisältäviä nimiavaruuksia ei tueta.",
        "nocontribs": "Näihin ehtoihin sopivia muokkauksia ei löytynyt.",
        "uctop": "uusin",
        "month": "Alkaen kuukaudesta (ja aiemmin):",
        "ipbreason-dropdown": "*Yleiset estosyyt\n** Väärän tiedon lisääminen\n** Sisällön poistaminen\n** Mainoslinkkien lisääminen\n** Sotkeminen tai roskan lisääminen\n** Häiriköinti\n** Useamman käyttäjätunnuksen väärinkäyttö\n** Sopimaton käyttäjätunnus",
        "ipb-hardblock": "Estä sisäänkirjautuneita käyttäjiä muokkaamasta tästä IP-osoitteesta",
        "ipbcreateaccount": "Tunnusten luominen",
-       "ipbemailban": "(Estä) sähköpostin lähettäminen",
+       "ipbemailban": "Sähköpostin lähettäminen",
        "ipbenableautoblock": "Estä automaattisesti viimeisin IP-osoite, josta käyttäjä on muokannut, sekä ne osoitteet, joista hän jatkossa yrittää muokata.",
        "ipbsubmit": "Estä tämä käyttäjä",
        "ipbother": "Muu aikamääre:",
        "ipboptions": "2 tuntia:2 hours,1 päivä:1 day,3 päivää:3 days,1 viikko:1 week,2 viikkoa:2 weeks,1 kuukausi:1 month,3 kuukautta:3 months,6 kuukautta:6 months,1 vuosi:1 year,ikuinen:infinite",
        "ipbhidename": "Piilota tunnus muokkauksista ja listauksista",
        "ipbwatchuser": "Tarkkaile tämän käyttäjän käyttäjä- ja keskustelusivua",
-       "ipb-disableusertalk": "(Estä) oman keskustelusivun muokkaaminen",
+       "ipb-disableusertalk": "Oman keskustelusivun muokkaaminen",
        "ipb-change-block": "Estä uudelleen näillä asetuksilla",
        "ipb-confirm": "Vahvista esto",
        "ipb-sitewide": "Sivuston laajuinen",
        "ip_range_toolow": "IP-alueet eivät käytännöllisesti katsoen ole sallittuja.",
        "proxyblocker": "Välityspalvelinesto",
        "proxyblockreason": "IP-osoitteestasi on estetty muokkaukset, koska se on avoin välityspalvelin. Ota yhteyttä Internet-palveluntarjoajaasi tai tekniseen tukeen ja kerro heille tästä tietoturvaongelmasta.",
-       "sorbsreason": "IP-osoitteesi on listattu avoimena välityspalvelimena DNSBL:n mustalla listalla sivustolla {{SITENAME}}.",
-       "sorbs_create_account_reason": "IP-osoitteesi on listattu avoimena välityspalvelimena DNSBL:n mustalla listalla sivustolla {{SITENAME}}. \nEt voi luoda käyttäjätunnusta.",
+       "sorbsreason": "IP-osoitteesi on listattu avoimena välityspalvelimena DNSBL:n mustalla listalla {{GRAMMAR:inessive|{{SITENAME}}}}.",
+       "sorbs_create_account_reason": "IP-osoitteesi on listattu avoimena välityspalvelimena DNSBL:n mustalla listalla {{GRAMMAR:inessive|{{SITENAME}}}}.\nEt voi luoda käyttäjätunnusta.",
        "softblockrangesreason": "Anonyymit muokkaukset eivät ole sallittuja IP-osoitteestasi ($1). Ole hyvä ja kirjaudu.",
        "xffblockreason": "Yhteydet IP-osoitteesta, joka löytyy sinun tai käyttämäsi välipalvelimen X-Forwarded-For-otsakkeesta, on estetty. Alkuperäinen estämisen syy oli: $1",
        "cant-see-hidden-user": "Käyttäjä, jota yrität estää, on jo estetty ja käyttäjänimi on piilotettu. \nKoska sinulla ei ole hideuser-oikeutta, et voi nähdä tai muuttaa käyttäjän estoasetuksia.",
        "confirmemail_body_set": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on vaihtanut {{GRAMMAR:inessive|{{SITENAME}}}} tunnuksen $2 sähköpostiosoitteeksi tämän osoitteen.\n\nVarmenna, että tämä tunnus kuuluu sinulle ja aktivoi sähköpostitoiminnot uudelleen avaamalla seuraava linkki selaimellasi:\n\n$3\n\nJos tunnus ei kuulu sinulle, peruuta sähköpostiosoitteen varmennus avaamalla seuraava linkki:\n\n$5\n\nVarmennuskoodi vanhenee $4.",
        "confirmemail_invalidated": "Sähköpostiosoitteen varmennus peruutettiin",
        "invalidateemail": "Sähköpostiosoitteen varmennuksen peruuttaminen",
-       "notificationemail_subject_changed": "Sivuston {{SITENAME}} rekisteröity sähköpostiosoite on vaihdettu",
-       "notificationemail_subject_removed": "Sivuston {{SITENAME}} rekisteröity sähköpostiosoite on poistettu",
-       "notificationemail_body_changed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on vaihtanut tunnuksen ”$2” sähköpostiosoitteeksi ”$3” sivustolla {{SITENAME}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
-       "notificationemail_body_removed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on poistanut tunnuksen ”$2” sähköpostiosoitteen sivustolla {{SITENAME}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
+       "notificationemail_subject_changed": "{{GRAMMAR:genitive|{{SITENAME}}}} rekisteröity sähköpostiosoite on vaihdettu",
+       "notificationemail_subject_removed": "{{GRAMMAR:genitive|{{SITENAME}}}} rekisteröity sähköpostiosoite on poistettu",
+       "notificationemail_body_changed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on vaihtanut tunnuksen ”$2” sähköpostiosoitteeksi ”$3” {{GRAMMAR:inessive|{{SITENAME}}}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
+       "notificationemail_body_removed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on poistanut tunnuksen ”$2” sähköpostiosoitteen {{GRAMMAR:inessive|{{SITENAME}}}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
        "scarytranscludedisabled": "[Wikienvälinen sisällytys ei ole käytössä]",
        "scarytranscludefailed": "[Mallineen hakeminen epäonnistui: $1]",
        "scarytranscludefailed-httpstatus": "[Mallineen hakeminen epäonnistui: $1 HTTP $2]",
        "logentry-partialblock-block-page": "the {{PLURAL:$1|page|pages}} $2",
        "logentry-partialblock-block-ns": "the {{PLURAL:$1|namespace|namespaces}} $2",
        "logentry-partialblock-block": "$1 {{GENDER:$2|blocked}} {{GENDER:$4|$3}} from editing $7 with an expiration time of $5 $6",
-       "logentry-partialblock-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} muokkauseston asetuksia estäen muokkausten tekemisen {{PLURAL:$8||sivuihin}} $7. Eston kesto on $5 $6",
+       "logentry-partialblock-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} muokkauseston asetuksia estäen muokkausten tekemisen $7. Eston kesto on $5 $6",
        "logentry-non-editing-block-block": "$1 {{GENDER:$2|esti}} käyttäjää {{GENDER:$4|$3}} suorittamasta määrättyjä toimenpiteitä (lukuun ottamatta muokkaamista). Eston kesto on $5 $6",
        "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} toimintaeston asetuksia, jotka koskevat määrättyjä toimenpiteitä. Eston kesto on $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|esti}} käyttäjän {{GENDER:$4|$3}}. Eston kesto on $5 $6",
        "logentry-rights-autopromote": "Käyttäjän $1 oikeudet {{GENDER:$2|muuttuivat}} automaattisesti ryhmistä $4 ryhmiin $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|tallensi}} tiedoston $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|tallensi}} uuden version tiedostosta $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|tallensi}} tiedoston $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|palautti}} tiedoston $3 vanhaan versioon",
        "log-name-managetags": "Merkkausten hallinnan loki",
        "log-description-managetags": "Tällä sivulla on luettelo tehtävistä, jotka koskevat [[Special:Tags|merkkauksia]]. Lokissa ovat vain ne toimenpiteet, jotka ylläpitäjä on suorittanut käsin. Merkkauksia voi syntyä ja poistua myös wikin ohjelmiston kautta eivätkä ne näy tässä lokissa.",
        "logentry-managetags-create": "$1 {{GENDER:$2|on luonut}} merkkauksen ”$4”",
        "expand_templates_generate_xml": "Näytä XML-jäsennyspuu",
        "expand_templates_generate_rawhtml": "Näytä raaka HTML",
        "expand_templates_preview": "Esikatselu",
-       "expand_templates_preview_fail_html": "<em>Koska sivustolla {{SITENAME}} on käytössä suodattamaton HTML-koodi ja koska istunnon tiedot ovat kadonneet, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi.</em>\n\n<strong>Jos yritit esikatsella sivua, yritä uudestaan.</strong>\nJos esikatselu ei vieläkään toimi, yritä [[Special:UserLogout|kirjautua ulos]] ja sitten kirjautua uudestaan sisään. Tarkista myös, että selaimesi sallii evästeet tältä sivustolta.",
-       "expand_templates_preview_fail_html_anon": "<em>Koska sivustolla {{SITENAME}} on käytössä puhdas HTML-koodi ja koska et ole kirjautunut sisään, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi.</em>\n\n<strong>Jos olet oikealla asialla, [[Special:UserLogin|kirjaudu sisään]] ja yritä uudestaan.</strong>",
+       "expand_templates_preview_fail_html": "<em>Koska {{GRAMMAR:inessive|{{SITENAME}}}} on käytössä suodattamaton HTML-koodi ja koska istunnon tiedot ovat kadonneet, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi.</em>\n\n<strong>Jos yritit esikatsella sivua, yritä uudestaan.</strong>\nJos esikatselu ei vieläkään toimi, yritä [[Special:UserLogout|kirjautua ulos]] ja sitten kirjautua uudestaan sisään. Tarkista myös, että selaimesi sallii evästeet tältä sivustolta.",
+       "expand_templates_preview_fail_html_anon": "<em>Koska {{GRAMMAR:inessive|{{SITENAME}}}} on käytössä puhdas HTML-koodi ja et ole kirjautunut sisään, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi.</em>\n\n<strong>Jos olet oikealla asialla, [[Special:UserLogin|kirjaudu sisään]] ja yritä uudestaan.</strong>",
        "expand_templates_input_missing": "Sinun on annettava ainakin jotakin wikitekstiä syötteeksi.",
        "pagelanguage": "Sivun kielen vaihto",
        "pagelang-name": "Sivu",
        "log-action-filter-suppress-reblock": "Käyttäjätunnuksen häivyttäminen uudella estolla",
        "log-action-filter-upload-upload": "Uusi tallennus",
        "log-action-filter-upload-overwrite": "Päälletallennus",
+       "log-action-filter-upload-revert": "Palauta",
        "authmanager-authn-not-in-progress": "Varmennus ei ole käynnissä tai istunnon tiedot ovat hävinneet. Ole hyvä ja aloita uudelleen alusta.",
        "authmanager-authn-no-primary": "Annettua kirjautumistietoja ei pystytty varmentamaan.",
        "authmanager-authn-no-local-user": "Annetut kirjautumistiedot eivät kuulu millekään tämän wikin käyttäjistä.",
        "authmanager-create-no-primary": "Annettuja kirjautumistietoja ei voitu käyttää tunnuksen luontiin.",
        "authmanager-link-no-primary": "Annettuja kirjautumistietoja ei voitu käyttää tunnuksen linkittämiseen.",
        "authmanager-link-not-in-progress": "Tunnuksen linkitys ei ole käynnissä tai istunnon tiedot ovat hävinneet. Ole hyvä ja aloita uudelleen alusta.",
-       "authmanager-authplugin-setpass-failed-title": "Salasanan muuttaminen epäonnistui",
-       "authmanager-authplugin-setpass-failed-message": "Varmennuslisäosa esti salasanan muuttamisen.",
-       "authmanager-authplugin-create-fail": "Varmennuslisäosa esti tunnuksen luonnin.",
-       "authmanager-authplugin-setpass-denied": "Varmennuslisäosa ei salli salasanojen muuttamista.",
-       "authmanager-authplugin-setpass-bad-domain": "Virheellinen domain.",
        "authmanager-autocreate-noperm": "Automaattinen tunnustenluonti ei ole sallittu.",
        "authmanager-autocreate-exception": "Automaattinen tunnuksenluonti on tilapäisesti poistettu käytöstä aikaisempien virheiden vuoksi.",
        "authmanager-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
index d71b325..e0d6022 100644 (file)
        "tog-watchlisthideminor": "Masquer les modifications mineures dans la liste de suivi",
        "tog-watchlisthideliu": "Masquer les modifications faites par des utilisateurs inscrits dans la liste de suivi",
        "tog-watchlistreloadautomatically": "Recharger automatiquement la liste de suivi lorsque les options de filtrage sont modifiées (JavaScript requis)",
-       "tog-watchlistunwatchlinks": "Ajouter des marqueurs directs ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) pour les pages suivies avec des changements (JavaScript est nécessaire pour utiliser la fonctionnalité)",
+       "tog-watchlistunwatchlinks": "Ajouter des liens pour directement suivre ou arrêter de suivre ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) les entrées de la liste de suivi (JavaScript est nécessaire pour utiliser la fonctionnalité)",
        "tog-watchlisthideanons": "Masquer les modifications d’utilisateurs anonymes dans la liste de suivi",
        "tog-watchlisthidepatrolled": "Masquer les modifications relues dans la liste de suivi",
        "tog-watchlisthidecategorization": "Masquer la catégorisation des pages",
        "tog-norollbackdiff": "Ne pas afficher le diff après avoir révoqué",
        "tog-useeditwarning": "M’avertir quand je quitte une page en cours de modification sans avoir sauvegardé",
        "tog-prefershttps": "Toujours utiliser une connexion sécurisée lorsque je suis connecté",
+       "tog-showrollbackconfirmation": "Afficher une demande de confirmation en cliquant sur un lien d’annulation",
        "underline-always": "Toujours",
        "underline-never": "Jamais",
        "underline-default": "Valeur par défaut du thème ou du navigateur",
        "badretype": "Les mots de passe que vous avez saisis ne correspondent pas.",
        "usernameinprogress": "Une création de compte pour ce nom d’utilisateur est déjà en cours.\nVeuillez patienter.",
        "userexists": "Le nom d’utilisateur saisi est déjà utilisé.\nVeuillez choisir un nom différent.",
+       "createacct-normalization": "Votre nom d’utilisateur sera modifié en « $2 » à cause de restrictions techniques.",
        "loginerror": "Erreur de connexion",
        "createacct-error": "Erreur lors de la création du compte",
        "createaccounterror": "Impossible de créer le compte : $1",
        "botpasswords-label-delete": "Supprimer",
        "botpasswords-label-resetpassword": "Réinitialiser le mot de passe",
        "botpasswords-label-grants": "Droits applicables :",
-       "botpasswords-help-grants": "Les autorisations permettent d’accéder aux droits déjà accordés à votre compte utilisateur. Activer une autorisation ici ne fournit l’accès à aucun droit que votre compte utilisateur n’aurait pas par ailleurs. Voyez le [[Special:ListGrants|tableau des autorisations]] pour plus d’information.",
+       "botpasswords-help-grants": "Les autorisations permettent d’accéder aux droits déjà accordés à votre compte utilisateur. Activer une autorisation ici ne fournit l’accès à aucun droit que votre compte utilisateur n’aurait pas par ailleurs. Voyez le [[Special:ListGrants|tableau des autorisations]] pour plus d’informations.",
        "botpasswords-label-grants-column": "Accordé",
        "botpasswords-bad-appid": "Le nom de robot « $1 » n’est pas valide.",
        "botpasswords-insert-failed": "Échec de l’ajout du nom de robot « $1 ». A-t-il déjà été ajouté ?",
        "page_first": "première",
        "page_last": "dernière",
        "histlegend": "Sélection du diff : cochez les boutons radio des versions à comparer et appuyez sur entrée ou sur le bouton en bas.<br />\nLégende : <strong>({{int:cur}})</strong> = différence avec la dernière version, <strong>({{int:last}})</strong> = différence avec la version précédente, <strong>{{int:minoreditletter}}</strong> = modification mineure.",
-       "history-fieldset-title": "Rechercher des révisions",
+       "history-fieldset-title": "Filtrer les révisions",
        "history-show-deleted": "Révision supprimée uniquement",
        "histfirst": "les plus anciennes",
        "histlast": "les plus récentes",
        "historysize": "($1 octet{{PLURAL:$1||s}})",
-       "historyempty": "(vide)",
+       "historyempty": "vide",
        "history-feed-title": "Historique des versions",
        "history-feed-description": "Historique des versions pour cette page sur le wiki",
        "history-feed-item-nocomment": "$1 le $2",
        "right-reupload-own": "Écraser un fichier que l'on a soi-même importé",
        "right-reupload-shared": "Écraser localement des fichiers présents sur un dépôt partagé",
        "right-upload_by_url": "Importer un fichier depuis une adresse URL",
-       "right-purge": "Effacer une page du cache local sans demander de confirmation",
+       "right-purge": "Vider le cache du site pour une page",
        "right-autoconfirmed": "Ne pas être affecté par les limitations de débit liées aux adresses IP",
        "right-bot": "Être traité comme un processus automatisé",
        "right-nominornewtalk": "Ne pas déclencher la notification de nouveau message lorsqu'on effectue une modification mineure sur la page de discussion d'un utilisateur",
        "delete-confirm": "Supprimer « $1 »",
        "delete-legend": "Supprimer",
        "historywarning": "<strong>Attention :</strong> la page que vous êtes sur le point de supprimer a un historique avec $1 {{PLURAL:$1|version|versions}} :",
-       "historyaction-submit": "Lister",
+       "historyaction-submit": "Afficher les révisions",
        "confirmdeletetext": "Vous êtes sur le point de supprimer une page ou un fichier, ainsi que toutes ses versions antérieures historisées. Veuillez confirmer que c’est bien là ce que vous voulez faire, que vous en comprenez les conséquences et que vous faites ceci en accord avec les [[{{MediaWiki:Policy-url}}|règles internes]].",
        "actioncomplete": "Action effectuée",
        "actionfailed": "L'action a échoué",
        "deleting-backlinks-warning": "<strong>Attention :</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|D’autres pages]] lient vers ou incluent la page que vous allez supprimer.",
        "deleting-subpages-warning": "<strong>Attention :</strong> la page que vous essayez de supprimer possède  [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|une sous-page|$1 sous-pages|51=plus de 50 sous-pages}}]].",
        "rollback": "Révoquer les modifications",
+       "rollback-confirmation-confirm": "Veuillez confirmer :",
+       "rollback-confirmation-yes": "Révoquer",
+       "rollback-confirmation-no": "Annuler",
        "rollbacklink": "révoquer",
        "rollbacklinkcount": "révoquer $1 {{PLURAL:$1|modification|modifications}}",
        "rollbacklinkcount-morethan": "révoquer plus de $1 {{PLURAL:$1|modification|modifications}}",
        "revertpage": "Révocation des modifications de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]]) vers la dernière version de [[User:$1|$1]]",
        "revertpage-nouser": "Révocation des modifications par un utilisateur masqué à la dernière version par {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Révocation des modifications effectuées par {{GENDER:$3|$1}} ;\nrétablissement de la dernière version par {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Modifications annulées par $1 ;\nretour à la dernière révision par $2. [$3 Voir les changements]",
        "sessionfailure-title": "Erreur de session",
        "sessionfailure": "Votre session de connexion semble avoir des problèmes ;\ncette action a été annulée en prévention d'un piratage de session.\nVeuillez soumettre le formulaire de nouveau.",
        "changecontentmodel": "Modifier le modèle de contenu d’une page",
        "mycontris": "Contributions",
        "anoncontribs": "Contributions",
        "contribsub2": "Pour {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Pour {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Le compte d’utilisateur « $1 » n’est pas enregistré.",
        "negative-namespace-not-supported": "Les espaces de noms avec des valeurs négatives ne sont pas supportés.",
        "nocontribs": "Aucune modification correspondant à ces critères n'a été trouvée.",
        "ipb-confirm": "Confirmer le blocage",
        "ipb-sitewide": "À tout le site",
        "ipb-partial": "Partiel",
+       "ipb-sitewide-help": "Chaque page du wiki et toutes les autres actions de contribution.",
+       "ipb-partial-help": "Pages ou espaces de noms spécifiques.",
        "ipb-pages-label": "Pages",
        "ipb-namespaces-label": "Espaces de noms",
        "badipaddress": "Adresse IP incorrecte",
        "ip_range_exceeded": "L'intervalle des adresses IP est plus grand l'intervalle maximum. Intervalle autorisé : /$1 .",
        "ip_range_toolow": "Les intervalles d'adresses IP ne sont effectivement pas autorisés.",
        "proxyblocker": "Bloqueur de mandataires",
-       "proxyblockreason": "Votre adresse IP a été bloquée car il s’agit d’un mandataire ouvert.\nVeuillez contacter votre fournisseur d’accès Internet ou votre soutien technique et l’informer de ce sérieux problème de sécurité.",
+       "proxyblockreason": "Votre adresse IP a été bloquée car il s’agit d’un mandataire ouvert.\nVeuillez contacter votre fournisseur d’accès à Internet ou votre service d’assistance technique et l’informer de ce sérieux problème de sécurité.",
        "sorbsreason": "Votre adresse IP est listée comme mandataire ouvert dans le DNSBL utilisé par {{SITENAME}}.",
        "sorbs_create_account_reason": "Votre adresse IP est listée comme mandataire ouvert dans le DNSBL utilisé par {{SITENAME}}.\nVous ne pouvez pas créer un compte.",
        "softblockrangesreason": "Les contributions anonymes ne sont pas autorisées à partir de votre adresse IP ($1). Veuillez vous connecter.",
        "confirm-unwatch-top": "Supprimer cette page de votre liste de suivi ?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Révoquer les modifications de cette page ?",
+       "confirm-rollback-bottom": "Cette action annulera immédiatement les modifications sélectionnées sur cette page.",
        "confirm-mcrrestore-title": "Restaurer une version",
        "confirm-mcrundo-title": "Annuler une modification",
        "mcrundofailed": "L’annulation a échoué",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|a été promu}} automatiquement de $4 à $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|a téléversé}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|a téléversé}} une nouvelle version de $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|a téléversé}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|a annulé}} $3 vers une ancienne version",
        "log-name-managetags": "Journal des modifications de balises",
        "log-description-managetags": "Cette page recense les tâches de maintenance liées aux [[Special:Tags|balises]]. Le journal contient uniquement les actions faites manuellement par un administrateur ; les balises peuvent être créées ou supprimées par le logiciel wiki sans que cette action ne soit inscrite dans ce journal.",
        "logentry-managetags-create": "$1 {{GENDER:$2|a créé}} la balise « $4 ».",
        "log-action-filter-suppress-reblock": "Suppression d’utilisateur par blocage réitéré",
        "log-action-filter-upload-upload": "Nouveau téléversement",
        "log-action-filter-upload-overwrite": "Réitérer le téléversement",
+       "log-action-filter-upload-revert": "Révoquer",
        "authmanager-authn-not-in-progress": "L’authentification n’est pas en cours ou les données de session ont été perdues. Veuillez recommencer depuis le début.",
        "authmanager-authn-no-primary": "Les informations d’identification fournies n’ont pas pu être authentifiées.",
        "authmanager-authn-no-local-user": "Les informations d’identification fournies ne sont associées à aucun utilisateur sur ce wiki.",
        "authmanager-create-no-primary": "Les informations d’identification fournies n’ont pas pu être utilisées pour la création de compte.",
        "authmanager-link-no-primary": "Les informations d’identification fournies n’ont pas pu être utilisées pour lier un compte.",
        "authmanager-link-not-in-progress": "La liaison de compte n’est pas en cours ou les données de session ont été perdues. Veuillez recommencer depuis le début.",
-       "authmanager-authplugin-setpass-failed-title": "Échec du changement de mot de passe",
-       "authmanager-authplugin-setpass-failed-message": "Le module d’authentification a refusé le changement de mot de passe.",
-       "authmanager-authplugin-create-fail": "Le module d’authentification a refusé la création de compte.",
-       "authmanager-authplugin-setpass-denied": "Le module d’authentification ne permet pas la modification des mots de passe.",
-       "authmanager-authplugin-setpass-bad-domain": "Domaine non valide.",
        "authmanager-autocreate-noperm": "La création automatique de compte n’est pas autorisée.",
        "authmanager-autocreate-exception": "La création automatique de compte est désactivée temporairement, du fait d’erreurs antérieures.",
        "authmanager-userdoesnotexist": "Le compte utilisateur « $1 » n’est pas inscrit.",
        "usercssispublic": "Veuillez noter : les sous-pages CSS ne doivent pas contenir de données confidentielles parce qu’elles sont visibles des autres utilisateurs.",
        "restrictionsfield-badip": "Adresse IP ou plage non valide : $1",
        "restrictionsfield-label": "Plages IP autorisées :",
-       "restrictionsfield-help": "Une adresse IP ou une plage CIDR par ligne. Pour tout activer, utiliser <pre>0.0.0.0/0\n::/0</pre>",
+       "restrictionsfield-help": "Une adresse IP ou une plage CIDR par ligne. Pour tout activer, utiliser :<pre>0.0.0.0/0\n::/0</pre>",
        "edit-error-short": "Erreur : $1",
        "edit-error-long": "Erreurs :\n\n$1",
        "revid": "version $1",
        "passwordpolicies-policy-maximalpasswordlength": "Les mots de passe doivent avoir moins de $1 caractère{{PLURAL:$1||s}} de long",
        "passwordpolicies-policy-passwordcannotbepopular": "Le mot de passe ne peut pas être {{PLURAL:$1|le mot de passe populaire|dans la liste des $1 mots de passe populaires}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Le mot de passe ne peut pas faire partie de la liste des 100 000 mots de passe les plus communément utilisés.",
+       "passwordpolicies-policyflag-forcechange": "doit changer à la reconnexion",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "suggérer une modification à la connexion",
        "easydeflate-invaliddeflate": "Le contenu fourni n'est pas correctement développé",
        "unprotected-js": "Pour des raisons de sécurité, JavaScript ne peut pas être chargé depuis des pages non protégées. Veuillez ne créer du javascript que dans l’espace de noms MediaWiki: ou comme sous-page utilisateur"
 }
index e14a014..91a617f 100644 (file)
@@ -25,7 +25,7 @@
                ]
        },
        "tog-underline": "Keppelings ûnderstreekje:",
-       "tog-hideminor": "Tekstwizigings wei litte út 'Koartlyn feroare'",
+       "tog-hideminor": "Feroarings fan lytse betsjutting ferbergje yn Koartlyn feroare",
        "tog-hidepatrolled": "Markearre feroarings ferskûlje yn resinte feroarings",
        "tog-newpageshidepatrolled": "Markearre siden ferskûlje yn 'e list mei nije siden",
        "tog-extendwatchlist": "Wreidzje folchlist út om alle wizigings sjen te litten, net allinnich de lêste wizigings",
        "tog-watchdefault": "Sides dy't jo feroare hawwe folgje",
        "tog-watchmoves": "Siden dy't jo werneamd hawwe folgje",
        "tog-watchdeletion": "Siden dy't jo wiske hawwe folgje",
-       "tog-minordefault": "Feroarings yn it earst oanjaan as tekstwizigings.",
+       "tog-watchrollback": "Siden dêr't ik wizigings weromdraaid haw oan myn folchlist taheakje",
+       "tog-minordefault": "Markearje alle feroarings standert as fan lytse betsjutting",
        "tog-previewontop": "By it neisjen, bewurkingsfjild ûnderoan sette",
        "tog-previewonfirst": "Lit foarbyld sjen by earste wiziging",
        "tog-enotifwatchlistpages": "E-mail my as in side op myn folchlist feroare is.",
        "tog-enotifusertalkpages": "E-mail my as myn oerlisside feroare wurdt",
-       "tog-enotifminoredits": "E-mail my ek by lytse feroarings fan siden op myn folchlist",
+       "tog-enotifminoredits": "E-mail my ek by feroarings fan lytse betsjutting oan siden en bestannen",
        "tog-enotifrevealaddr": "Myn e-mailadres sjen litte yn e-mailberjochten",
-       "tog-shownumberswatching": "It tal brûkers sjen litte dat dizze side folget",
-       "tog-oldsig": "Aktuele sinjatuerprintallyk:",
-       "tog-fancysig": "Sinjatuer as wikitekst behannelje (sûnder automatyske keppeling)",
+       "tog-shownumberswatching": "It tal meidoggers sjen litte dat dizze side folget",
+       "tog-oldsig": "Jo besteande sinjatuer:",
+       "tog-fancysig": "Sinjatuer as wikitekst behannelje (sûnder in automatyske keppeling)",
        "tog-uselivepreview": "\"Live proefbyld\" brûke",
        "tog-forceeditsummary": "Warskôgje at ik de gearfetting leech lit.",
        "tog-watchlisthideown": "Eigen bewurkings op myn folchlist ferbergje",
        "tog-watchlisthidebots": "Lit gjin bot wizigings sjen yn de folchlist",
-       "tog-watchlisthideminor": "Lit gjin tekstwizigings sjen yn de folchlist",
-       "tog-watchlisthideliu": "Bewurkings fan oanmelde brûkers op myn folchlist ferbergje",
-       "tog-watchlisthideanons": "Bewurkings fa anonyme brûkers op myn folchlist ferbergje",
+       "tog-watchlisthideminor": "Feroarings fan lytse betsjutting ferbergje yn de folchlist",
+       "tog-watchlisthideliu": "Bewurkings fan oanmelde meidoggers op myn folchlist ferbergje",
+       "tog-watchlisthideanons": "Bewurkings fa anonyme meidoggers op myn folchlist ferbergje",
        "tog-watchlisthidepatrolled": "Markearre feroarings op myn folchlist ferskûlje",
-       "tog-ccmeonemails": "Stjoer my in kopy fan e-mails dy't ik nei oare brûkers stjoer",
+       "tog-ccmeonemails": "Stjoer my in kopy fan e-mails dy't ik nei oare meidoggers stjoer",
        "tog-diffonly": "Side-ynhâld dy't feroare wurdt net sjen litte",
        "tog-showhiddencats": "Ferburgen kategoryen werjaan",
-       "tog-norollbackdiff": "Feroarings weilitte nei tebekdraaien",
+       "tog-norollbackdiff": "Gjin ferskillen sjen litte nei it útfieren fan weromdraaien",
+       "tog-showrollbackconfirmation": "Befêstigingsdialooch sjen litte by it klikken op 'weromdraaie'",
        "underline-always": "Altyd",
        "underline-never": "Nea",
        "underline-default": "Webblêder-standert",
        "category_header": "Siden yn de kategory \"$1\"",
        "subcategories": "Subkategoryen",
        "category-media-header": "Media yn de kategory \"$1\"",
-       "category-empty": "<em>Yn dizze kategory binne gjin siden of triemmen opnaam.</em>",
+       "category-empty": "<em>Dizze kategory befettet op it stuit gjin siden of media.</em>",
        "hidden-categories": "Ferburgen {{PLURAL:$1|kategory|kategoryen}}",
        "hidden-category-category": "Ferburgen kategoryen",
        "category-subcat-count": "{{PLURAL:$2|Dizze kategory hat allinne de folgjende ûnderkategory.|Dizze kategory hat de folgjende {{PLURAL:$1|ûnderkategory|$1 ûnderkategoryen}}, fan yn totaal $2.}}",
        "category-subcat-count-limited": "Dizze kategory hat de folgjende {{PLURAL:$1|ûnderkategory|$1 ûnderkategoryen}}.",
        "category-article-count": "{{PLURAL:$2|Dizze kategory befettet allinne de folgjende side.|De folgjende {{PLURAL:$1|side is|$1 siden binne}} yn dizze kategory, fan yn totaal $2.}}",
        "category-article-count-limited": "De folgjende {{PLURAL:$1|side is|$1 siden binne}} yn dizze kategory.",
-       "category-file-count": "{{PLURAL:$2|Dizze kategory befettet de folgjende triem.|Dizze kategory befettet {{PLURAL:$1|de folgjende triem|$1 de folgjende triemmen}}, fan yn totaal $2.}}",
-       "category-file-count-limited": "Dizze kategory befettet {{PLURAL:$1|de folgjende triem|de folgjende $1 triemmen}}.",
+       "category-file-count": "{{PLURAL:$2|Dizze kategory befettet it folgjende bestân.|Dizze kategory befettet {{PLURAL:$1|it folgjende bestân|$1 de folgjende bestannen}}, fan yn totaal $2.}}",
+       "category-file-count-limited": "Dizze kategory befettet {{PLURAL:$1|it folgjende bestân|de folgjende $1 bestannen}}.",
        "listingcontinuesabbrev": "(ferfolch)",
        "index-category": "Yndeksearre siden",
        "noindex-category": "Net-yndeksearre siden",
        "cancel": "Annulearje",
        "moredotdotdot": "Mear...",
        "mypage": "Myn side",
-       "mytalk": "Myn oerlis",
+       "mytalk": "Oerlis",
        "anontalk": "Oerlisside foar dit IP-adres",
        "navigation": "Navigaasje",
        "and": "&#32;en",
        "history": "Sideskiednis",
        "history_short": "Skiednis",
        "updatedmarker": "bewurke sûnt myn lêste besite",
-       "printableversion": "Ofdruk-ferzje",
+       "printableversion": "Ofdrukferzje",
        "permalink": "Fêste keppeling",
        "print": "Ofdrukke",
        "view": "Lêze",
        "create-local": "Lokale beskriuwing tafoegje",
        "delete": "Fuortsmite",
        "undelete_short": "$1 {{PLURAL:$1|ferzje|ferzjes}} weromsette",
-       "protect": "Skoattel",
+       "protect": "Skoattelje",
        "protect_change": "feroarje nivo fan skoatteljen",
        "unprotect": "Jou frij",
        "newpage": "Nije side",
-       "talkpagelinktext": "Oerlis",
+       "talkpagelinktext": "oerlis",
        "specialpage": "Bysûndere side",
        "personaltools": "Persoanlike ynstellingen",
        "talk": "Oerlis",
-       "views": "Aspekten/aksjes",
-       "toolbox": "Arkkiste",
-       "imagepage": "Besjoch triemside",
+       "views": "Werjeften",
+       "toolbox": "Ark",
+       "imagepage": "Besjoch bestânsside",
        "mediawikipage": "Berjochtside sjen litte",
        "templatepage": "Berjochtside lêze",
        "viewhelppage": "Helpside sjen litte",
        "categorypage": "Besjoch kategoryside",
        "viewtalkpage": "Oerlisside",
-       "otherlanguages": "In oare talen",
-       "redirectedfrom": "(Trochwiisd fan \"$1\")",
+       "otherlanguages": "Yn oare talen",
+       "redirectedfrom": "(Trochwiisd fan $1)",
        "redirectpagesub": "Trochferwiis-side",
        "lastmodifiedat": "Dizze side is it lêst bewurke op $1 om $2.",
-       "viewcount": "Disse side is {{PLURAL:$1|ienris|$1 kear}} iepenslein.",
+       "viewcount": "Dizze side is {{PLURAL:$1|ienris|$1 kear}} iepenslein.",
        "protectedpage": "Skoattele side",
-       "jumpto": "Gean nei:",
+       "jumpto": "Spring nei:",
        "jumptonavigation": "navigaasje",
        "jumptosearch": "sykje",
        "view-pool-error": "Ekskuseare, de tsjinners hawwe it op it stuit te drok.\nTefolle meidoggers probearje dizze side te besjen.\nWachtsje efkes foardatsto op 'e nij tagong ta dizze side probearrest te krijen.\n\n$1",
        "aboutpage": "Project:Ynfo",
        "copyright": "Ynhâld is beskikber ûnder de $1.",
        "copyrightpage": "{{ns:project}}:Auteursrjocht",
-       "currentevents": "Hjoeddeis",
+       "currentevents": "Rinnende saken",
        "currentevents-url": "Project:Rinnende saken",
        "disclaimers": "Foarbehâld",
        "disclaimerpage": "Project:Algemien foarbehâld",
        "mainpage": "Haadside",
        "mainpage-description": "Haadside",
        "policy-url": "Project:Belied",
-       "portal": "Brûkersportaal",
-       "portal-url": "Project:Brûkersportaal",
+       "portal": "Mienskipsportaal",
+       "portal-url": "Project:Mienskipsportaal",
        "privacy": "Privacybelied",
        "privacypage": "Project:Privacybelied",
        "badaccess": "Gjin tastimming",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "Untfongen fan \"$1\"",
-       "youhavenewmessages": "Jo hawwe $1 ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Jo hawwe}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Jo hawwe}} $1 fan {{PLURAL:$3|in oare meidogger|$3 meidoggers}} ($2).",
+       "youhavenewmessagesmanyusers": "Jo hawwe $1 fan in protte meidoggers ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|in nij berjocht|999=nije berjochten}}",
        "newmessagesdifflinkplural": "lêste {{PLURAL:$1|feroaring|999=feroarings}}",
        "youhavenewmessagesmulti": "Jo hawwe nije berjochten op $1",
        "editold": "bewurkje",
        "viewsourceold": "boarnetekst besjen",
        "editlink": "bewurkje",
-       "viewsourcelink": "boarnetekst besjen",
+       "viewsourcelink": "besjoch de boarne",
        "editsectionhint": "Dielside bewurkje: $1",
        "toc": "Ynhâld",
        "showtoc": "sjen litte",
        "feed-rss": "RSS",
        "red-link-title": "$1 (de side bestiet net)",
        "nstab-main": "Side",
-       "nstab-user": "Meidogger",
+       "nstab-user": "Meidoggerside",
        "nstab-media": "Mediaside",
        "nstab-special": "Bysûndere side",
        "nstab-project": "Projektside",
-       "nstab-image": "Triem",
-       "nstab-mediawiki": "Berjocht",
+       "nstab-image": "Bestân",
+       "nstab-mediawiki": "Systeemberjocht",
        "nstab-template": "Berjocht",
        "nstab-help": "Helpside",
        "nstab-category": "Kategory",
        "mainpage-nstab": "Haadside",
        "nosuchaction": "Unbekende aksje.",
-       "nosuchactiontext": "De opdracht yn de URL is ûnjildich.\nMooglik hasto in typefout makke yn de URL of in ferkearde keppeling folge.\nIt soe likegoed in programmatuerflater fan {{SITENAME}} wêze kinne.",
-       "nosuchspecialpage": "Unbekende side",
-       "nospecialpagetext": "<strong>Jo hawwe in Wiki-side opfrege dy't net bekend is by it Wiki-programma.</strong>",
+       "nosuchactiontext": "De opdracht yn de URL is ûnjildich.\nMooglik hawwe jo in typflater yn 'e URL makke of in ferkearde keppeling folge.\nIt soe likegoed in programmatuerflater fan {{SITENAME}} wêze kinne.",
+       "nosuchspecialpage": "Gjin soksoarte bysûndere side",
+       "nospecialpagetext": "<strong>Jo hawwe in ûnjildige bysûndere side opfrege.</strong>\n\nIn list fan jildige bysûndere siden stiet op [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Flater",
        "databaseerror": "Databankfout",
        "databaseerror-query": "Sykopdracht: $1",
        "readonly_lag": "De database is automatysk beskoattele wylst de ûndergeskikte databaseservers syngronisearje mei de haadserver.",
        "internalerror": "Ynterne fout",
        "internalerror_info": "Ynterne fout: $1",
-       "filecopyerror": "Koe triem \"$1\" net kopiearje as \"$2\".",
-       "filerenameerror": "Koe triem \"$1\" net omneame as \"$2\".",
-       "filedeleteerror": "Koe triem \"$1\" net wiskje.",
+       "filecopyerror": "Koe bestân \"$1\" net kopiearje as \"$2\".",
+       "filerenameerror": "Koe bestân \"$1\" net omneame as \"$2\".",
+       "filedeleteerror": "Koe bestân \"$1\" net wiskje.",
        "directorycreateerror": "Map \"$1\" koe net oanmakke wurde.",
-       "filenotfound": "Koe triem \"$1\" net fine.",
+       "filenotfound": "Koe bestân \"$1\" net fine.",
        "unexpected": "Hommelse wearde: \"$1\"=\"$2\".",
        "formerror": "Flater: Koe formulier net oerlizze",
        "badarticleerror": "Dat kin op dizze side net dien wurden.",
        "perfcachedts": "De neikommende gegevens komme út de bewarre ynformaasje, dizze is it lêst fernijd op $1. In maksimum fan {{PLURAL:$4|ien resultaat is|$4 resultaten binne}} beskikber yn de cache.",
        "querypage-no-updates": "Dizze side kin net bywurke wurde. Dizze gegevens wurde net ferfarske.",
        "viewsource": "Besjoch de boarne",
+       "viewsource-title": "Besjoch de boarne foar $1",
        "actionthrottled": "Hanneling opkeard",
        "actionthrottledtext": "As maatregel tsjin spam is it tal kearen per tiidsienheid beheind dat jo dizze hanneling ferrjochtsje kinne. Jo binne oer de limyt. Besykje it in tal minuten letter wer.",
        "protectedpagetext": "Dizze side is befeilige. Bewurkjen is net mooglik.",
        "viewsourcetext": "Jo kinne de boarnetekst fan dizze side besjen en kopiearje:",
        "protectedinterface": "Dizze side jout systeemteksten fan 'e software en is befeilige tsjin misbrûk. Asto oersettingen foar alle wiki's tafoegje of bewurkje wolst, kinsto [https://translatewiki.net/ translatewiki.net] brûke.",
-       "editinginterface": "<strong>Warskôging:</strong> Jo bewurkje in side dy't brûkt wurdt foar systeemteksten foar de software.\nBewurkings op dizze side beynfloedzje de brûkersynterface fan elkenien.",
+       "editinginterface": "<strong>Warskôging:</strong> Jo bewurkje in side dy't brûkt wurdt foar systeemteksten foar de software.\nBewurkings op dizze side beynfloedzje de meidoggersynterface fan elkenien.",
        "cascadeprotected": "Dizze side is skoattele tsjin wizigjen, om't der in ûnderdiel útmakket fan de neikommende {{PLURAL:$1|side|siden}}, dy't skoattele {{PLURAL:$1|is|binne}} mei de \"ûnderlizzende siden\" opsje ynskeakele: $2",
-       "namespaceprotected": "Jo hawwe gjin rjochten om siden yn'e nammerûmte '''$1''' te bewurkjen.",
+       "namespaceprotected": "Jo hawwe gjin rjochten om siden yn'e nammeromte '''$1''' te bewurkjen.",
        "ns-specialprotected": "Siden yn'e nammerûmte {{ns:special}} kinne net bewurke wurde.",
        "titleprotected": "It oanmeitsjen fan dizze side is befeilige troch [[User:$1|$1]].\nDe oanfierde reden is <em>$2</em>.",
        "exception-nologin": "Net oanmeld",
+       "exception-nologin-text-manual": "Jo moatte $1 om tagong ta dizze side of hanneling krije te kinnen.",
        "virus-badscanner": "Minne konfiguraasje: ûnbekende virusscanner: ''$1''",
-       "virus-scanfailed": "scannen is mislearre (koade $1)",
+       "virus-scanfailed": "scan is mislearre (koade $1)",
        "virus-unknownscanner": "ûnbekend antivirus:",
-       "logouttext": "<strong>Jo binne no ôfmeld.</strong>\n\nGuon siden kinne noch foar it ljocht komme, krekt as wiesto noch oanmeld. Asto de cache fan dyn webblêder leechhellest feroaret dat wer.",
+       "logouttext": "<strong>Jo binne no ôfmeld.</strong>\n\nTink derom dat guon siden trochgeand werjûn wurde kinne krekt as wiene jo noch oanmeld, oant jo de oerslach fan jo webblêder leegje.",
        "welcomeuser": "Wolkom, $1!",
-       "yourname": "Brûkersnamme:",
-       "userlogin-yourname": "Brûkersnamme",
-       "userlogin-yourname-ph": "Jou jo brûkersnamme",
-       "createacct-another-username-ph": "Jou jo brûkersnamme",
+       "yourname": "Meidochnamme:",
+       "userlogin-yourname": "Meidochnamme",
+       "userlogin-yourname-ph": "Jou jo meidochnamme",
+       "createacct-another-username-ph": "Jou jo meidochnamme",
        "yourpassword": "Wachtwurd:",
        "userlogin-yourpassword": "Wachtwurd",
        "userlogin-yourpassword-ph": "Jou jo wachtwurd",
        "logout": "Ofmelde",
        "userlogout": "Ofmelde",
        "notloggedin": "Net oanmeld",
-       "userlogin-noaccount": "Hasto gjin akkount?",
-       "userlogin-joinproject": "Meidwaan {{SITENAME}}",
+       "userlogin-noaccount": "Hawwe jo gjin akkount?",
+       "userlogin-joinproject": "Doch mei op {{SITENAME}}",
        "createaccount": "Registrearje",
        "userlogin-resetpassword-link": "Wachtwurd fergetten?",
+       "userlogin-helplink2": "Help by it oanmelden",
        "createacct-emailrequired": "E-mailadres",
        "createacct-emailoptional": "E-mailadres (net ferplichte)",
        "createacct-email-ph": "E-mailadres ynfiere",
        "createacct-reason-ph": "Wêrom makkesto in oare akkount?",
        "createacct-submit": "Meitsje in akkount",
        "createacct-another-submit": "Meitsje in oare akkount",
-       "createacct-benefit-heading": "{{SITENAME}} is makke troch minsken krekt as dy.",
+       "createacct-benefit-heading": "{{SITENAME}} is makke troch minsken krekt as jo.",
        "createacct-benefit-body1": "{{PLURAL:$1|bewurking|bewurkings}}",
        "createacct-benefit-body2": "{{PLURAL:$1|side|siden}}",
        "createacct-benefit-body3": "aktive {{PLURAL:$1|skriuwer|skriuwers}}",
        "badretype": "De ynfierde wachtwurden binne net lyk.",
-       "userexists": "Dy meidoggersnamme wurdt al brûkt. \nBesykje in oarenien.",
+       "userexists": "De opjûne meidochnamme wurdt al brûkt.\nKies a.j.w. in oare namme.",
        "loginerror": "Oanmeldflater",
        "createacct-error": "Flater slein by meitsjen fan akkount",
        "createaccounterror": "Koe akkount net meitsje: $1",
-       "nocookiesnew": "De brûker is oanmakke mar net oanmeld. {{SITENAME}} brûkt cookies foar it oanmelden fan brûkers. Skeakelje dy yn en meld jo dan oan mei jo nije brûkersnamme en wachtwurd.",
-       "nocookieslogin": "{{SITENAME}} brûkt cookies foar it oanmelden fan brûkers. Jo hawwe cookies útskeakele. Skeakelje dy opsje oan en besykje it nochris.",
+       "nocookiesnew": "De meidogger is oanmakke mar net oanmeld. {{SITENAME}} brûkt cookies foar it oanmelden fan meidoggers. Skeakelje dy yn en meld jo dan oan mei jo nije meidochnamme en wachtwurd.",
+       "nocookieslogin": "{{SITENAME}} brûkt cookies foar it oanmelden fan meidoggers. Jo hawwe cookies útskeakele. Skeakelje dy opsje oan en besykje it nochris.",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
-       "noname": "Jo moatte in meidognamme opjaan.",
+       "noname": "Jo hawwe gjin jildige meidochnamme opjûn.",
        "loginsuccesstitle": "Oanmelden slagge.",
        "loginsuccess": "<strong>Jo binne no oanmeld op {{SITENAME}} as \"$1\".</strong>",
-       "nosuchuser": "Der is gjin meidogger \"$1\".\nKontrolearje de stavering, of [[Special:CreateAccount|meitsje in nije meidogger oan]].",
+       "nosuchuser": "Der is gjin meidogger mei de namme \"$1\".\nMeidochnammen binne haadlettergefoelich.\nSjoch de stavering nei, of [[Special:CreateAccount|meitsje in nij akkount oan]].",
        "nosuchusershort": "Der is gjin meidogger mei de namme \"$1\". It is goed skreaun?",
-       "nouserspecified": "Jo moatte in brûkersnamme opjaan.",
-       "wrongpassword": "Meidochnamme en wachtwurd hearre net by elkoar. Besykje op 'e nij, of fier it wachtwurd twa kear yn en meitsje nije meidoggersynstellings.",
+       "nouserspecified": "Jo moatte in meidochnamme opjaan.",
+       "wrongpassword": "Ferkearde meidochnamme of wachtwurd ynfolle.\nBesykje it nochris.",
        "wrongpasswordempty": "It opjûne wachtwurd wie leech. Besykje it nochris.",
        "passwordtooshort": "Wachtwurden moatte op syn minst {{PLURAL:$1|1 teken|$1 tekens}} lang wêze.",
-       "password-name-match": "Jo wachtwurd mei net itselde wêze as jo meidoggersnamme.",
-       "mailmypassword": "E-mail my in nij wachtwurd.",
+       "password-name-match": "Jo wachtwurd moat oars wêze as jo meidochnamme.",
+       "mailmypassword": "Nij wachtwurd",
        "passwordremindertitle": "Nij tydlik wachtwurd foar {{SITENAME}}",
-       "passwordremindertext": "Immen (nei alle gedachten jo, fan ynternetadres $1) had in nij wachtwurd\nfoar {{SITENAME}} ($4) oanfrege. Der is in tydlik wachtwurd foar meidogger\n\"$2\"  makke en ynstelt as \"$3\". As dat jo bedoeling wie, melde jo jo dan\nno oan en kies in nij wachtwurd. Dyn tydlik wachtwurd komt yn {{PLURAL:$5|ien dei|$5 dagen}} te ferfallen.\nDer is in tydlik wachtwurd oanmakke foar brûker \"$2\": \"$3\".\n\nAs immen oars as jo dit fersyk dien hat of at it wachtwurd jo tuskentiidsk wer yn 't sin kommen is en\njo it net langer feroarje wolle, dan kinne jo dit berjocht ferjitte en\nfierdergean mei it brûken fan jo âlde wachtwurd.",
+       "passwordremindertext": "Immen (mei it IP-adres $1) hat in nij\nwachtwurd  oanfrege foar {{SITENAME}} ($4). Der is in tydlik wachtwurd foar\nmeidogger \"$2\" oanmakke, en dat is \"$3\". At dat jo\ndoel wie, meld jo dan no oan en kies in nij wachtwurd.\nJo tydlik wachtwurd ferrint nei {{PLURAL:$5|ien dei|$5 dagen}}.\n\nAt immen oars dy oanfraach dien hat, of at jo jo wachtwurd wer witte\nen it net mear feroarje wolle, dan kinne jo dit berjocht negearje en\njo âlde wachtwurd brûken bliuwe.",
        "noemail": "Der is gjin e-postadres foar meidogger \"$1\".",
-       "passwordsent": "In nij wachtwurd is tastjoerd oan it e-postadres foar \"$1\". Jo kinne jo wer oanmelde as jo it wachtwurd ûntfongen hawwe.",
+       "passwordsent": "Der is in nij wachtwurd ferstjoerd nei it opjûne e-mailadres fan \"$1\".\nMeld jo nei ûntfangst op 'e nij oan.",
        "blocked-mailpassword": "Jo IP-adres is blokkearre foar it meitsjen fan feroarings. Om misbrûk tefoaren te kommen is it net mûglik in oar wachtwurd oan te freegjen.",
        "eauthentsent": "Foar befêstiging is jo in netpostberjocht tastjoerd op it adres dat jo ynsteld hawwe. Der wurdt gjin oare netpost stjoerd, oant jo it adres befêstigje sa't it yn it netpostberjocht stiet.",
        "throttled-mailpassword": "Yn {{PLURAL:$1|de lêste oere|de lêste $1 oeren}} is der al in wachtwurdwink ferstjoerd.\nOm misbrûk tefoaren te kommen wurdt der mar ien wachtwurdwink yn 'e {{PLURAL:$1|oere|$1 oeren}} ferstjoerd.",
        "mailerror": "Flater by it ferstjoeren fan e-mail: $1",
        "acct_creation_throttle_hit": "Besikers fan dizze wiky mei itselde ynternet-adres as jo hawwe de ôfrûne $2 al {{PLURAL:$1|1 meidochnamme|$1 meidochnammen}} oanmakke, wat it maksimaal tasteane oantal is foar dizze perioade.\nDêrom kinne jo fan jo ynternet-adres ôf op dit stuit gjin nije meidochnammen oanmeitsje.",
        "emailauthenticated": "Jo netpostadres waard befêstige op $2 om $3.",
-       "emailnotauthenticated": "Jo netpostadres is <strong>noch net befêstige</strong>. Jo kinne oare brûkers gjin post stjoere, en foar de neikommende opsjes wurdt jo gjin post stjoerd.",
+       "emailnotauthenticated": "Jo e-mailadres is noch net befêstige.\nDer sil gjin e-mail stjoerd wurde foar alle neikommende funksjes.",
        "noemailprefs": "Jou in e-mailadres op om dizze funksjes te brûken.",
        "emailconfirmlink": "Befêstigje jo netpostadres.",
        "invalidemailaddress": "It e-mailadres is net akseptearre om't it in ûnjildige opmaak hat.\nJou beleaven in jildich e-mailadres op of lit it fjild leech.",
        "accountcreated": "Meidogger oanmakke",
        "accountcreatedtext": "It meidoggersakkount [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|oerlis]]) is oanmakke.",
-       "createaccount-title": "Brûkers registrearje foar {{SITENAME}}",
-       "createaccount-text": "Immen hat in brûker op {{SITENAME}} ($4) oanmakke mei de namme \"$2\" en jo e-mailadres. It wachtwurd foar \"$2\" is \"$3\". Meld jo oan en feroarje jo wachtwurd.\n\nNegearje it berjocht as dizze brûker sûnder jo meiwitten oanmakke is.",
+       "createaccount-title": "Meidoggers registrearje foar {{SITENAME}}",
+       "createaccount-text": "Immen hat in meidogger op {{SITENAME}} ($4) oanmakke mei de namme \"$2\" en jo e-mailadres. It wachtwurd foar \"$2\" is \"$3\". Meld jo oan en feroarje jo wachtwurd.\n\nNegearje it berjocht as dizze meidogger sûnder jo meiwitten oanmakke is.",
        "login-throttled": "Jo hawwe koartlyn te faak besocht oan te melden mei in ûnkrekt wachtwurd.\nJo moatte efkes wachtsje foar't jo it op'e nij besykje kinne.",
        "loginlanguagelabel": "Taal: $1",
        "pt-login": "Oanmelde",
        "resetpass_submit": "Wachtwurd ynstelle en oanmelde",
        "changepassword-success": "Jo wachtwurd is feroare.",
        "resetpass_forbidden": "Wachtwurden kinne net feroare wurde",
-       "resetpass-no-info": "Jo moatte oanmeld wêze foar't Jo dizze side brûke kinne.",
+       "resetpass-no-info": "Jo moatte oanmeld wêze om streekrjocht tagong ta dizze side te hawwen.",
        "resetpass-submit-loggedin": "Wachtwurd feroarje",
        "resetpass-submit-cancel": "Annulearje",
        "resetpass-wrong-oldpass": "It momintele of tydlike wachtwurd is ûnjildich.\nMûglik hawwe Jo Jo wachtwurd al feroare of in nij tydlik wachtwurd oanfrege.",
        "resetpass-temp-password": "Tydlik wachtwurd:",
-       "passwordreset": "Wachtwurd ferfarskje",
-       "passwordreset-username": "Brûkersnamme:",
+       "passwordreset": "Wachtwurd op 'e nij oanmeitsje",
+       "passwordreset-text-many": "{{PLURAL:$1|Folje ien fan 'e fjilden yn, en ûntfang in tydlik wachtwurd mei de e-mail.}}",
+       "passwordreset-username": "Meidochnamme:",
        "passwordreset-domain": "Domein:",
        "passwordreset-email": "E-mailadres:",
        "passwordreset-emailtitle": "Akkountdetails op {{SITENAME}}",
-       "passwordreset-emailelement": "Brûkersnamme: \n$1\n\nTydlik wachtwurd: \n$2",
+       "passwordreset-emailelement": "Meidochnamme: \n$1\n\nTydlik wachtwurd: \n$2",
        "changeemail": "Feroarje e-mailadres",
        "changeemail-header": "Feroarje akkount e-mailadres",
+       "changeemail-no-info": "Jo moatte oanmeld wêze om streekrjocht tagong ta dizze side te hawwen.",
        "changeemail-newemail": "Nij e-mailadres:",
        "changeemail-none": "(gjin)",
        "changeemail-password": "Jo wachtwurd foar {{SITENAME}}:",
        "headline_sample": "Koptekst",
        "headline_tip": "Underkopke",
        "nowiki_sample": "Foechje hjir platte tekst yn",
-       "nowiki_tip": "Negearje it wiki formaat",
+       "nowiki_tip": "Wiki-opmaak negearje",
        "image_sample": "Foarbyld.jpg",
-       "image_tip": "Mediatriem",
-       "media_tip": "Link nei triem",
-       "sig_tip": "Jo hântekening mei dei en oere",
+       "image_tip": "Mediabestân",
+       "media_tip": "Link nei bestân",
+       "sig_tip": "Jo sinjatuer mei dei en oere",
        "hr_tip": "Horizontale line (mei ferdrach brûke)",
        "summary": "Gearfetting:",
        "subject": "Underwerp:",
-       "minoredit": "Dit is in tekstwiziging",
+       "minoredit": "Dit is fan lytse betsjutting",
        "watchthis": "Folgje dizze side",
        "savearticle": "Side bewarje",
        "publishpage": "Side fêstlizze",
        "autoblockedtext": "Jo ynternet-adres is automatysk útsletten, om't it brûkt is troch in oare meidogger dy't útsletten is troch $1.\nAs reden is opjûn:\n\n:<em>$2</em>\n\n* Begjin útsluting: $8\n* Ein útsluting: $6\n* Bedoeld út te sluten: $7\n\nAs jo wolle, meie jo kontakt opnimme mei $1 of ien fan 'e oare [[{{MediaWiki:Grouppage-sysop}}|behearders]] en besprekke de útsluting.\n\nTink derom dat jo de funksje \"{{int:emailuser}}\" net brûke kinne, of it moast wêze dat jo in jildich e-mailadres fêstlein hawwe yn jo [[Special:Preferences|ynstellings]] en net útsletten binne dat te brûken.\n\nJo hjoeddeisk ynternet-adres is $3, en it útslútnûmer is #$5.\nNim alle boppesteande gegevens op yn jo reäksjes.",
        "systemblockedtext": "Jo meidochnamme of ynternet-adres is automatysk útsletten troch MediaWiki.\nAs reden is opjûn:\n\n:<em>$2</em>\n\n* Begjin útsluting: $8\n* Ein útsluting: $6\n* Bedoeld út te sluten: $7\n\nJo hjoeddeisk ynternet-adres is $3.\nNim alle boppesteande gegevens op yn jo reäksjes.",
        "blockednoreason": "gjin reden opjûn",
-       "whitelistedittext": "Jo moatte $1 om siden te bewurkjen.",
-       "confirmedittext": "Jo moatte jo e-mailadres befêstichje foar't jo siden feroarje kinne.\nFier in e-mailadres yn by jo [[Special:Preferences|foarkarren]] en befêstichje it.",
+       "whitelistedittext": "Jo moatte $1 om siden bewurkje te kinnen.",
+       "confirmedittext": "Jo moatte jo e-mailadres befêstigje foar't jo siden bewurkje kinne.\nStel by jo [[Special:Preferences|foarkarren]] in e-mailadres yn en befêstigje it.",
        "nosuchsectiontitle": "Dizze subkop bestiet net",
        "nosuchsectiontext": "Jo besochten in subkop te bewurkjen dy't net bestiet.",
        "loginreqtitle": "Oanmelding frege",
-       "loginreqlink": "Oanmelde",
-       "loginreqpagetext": "Jo moatte jo $1 om oare siden besjen te kinnen.",
+       "loginreqlink": "jo oanmelde",
+       "loginreqpagetext": "Jo moatte $1 om oare siden besjen te kinnen.",
        "accmailtitle": "Wachtwurd ferstjoerd.",
        "accmailtext": "Samar in wachtwurd foar [[User talk:$1|$1]] is ferstjoerd nei $2. It kin wizige wurde op 'e side \n<em>[[Special:ChangePassword|Wachtwurd feroarje]]</em> nei oanmelden.",
        "newarticle": "(Nij)",
-       "newarticletext": "Jo hawwe in keppeling folge nei in side dêr't noch gjin tekst op stiet.\nOm sels tekst te meistjsen kinne jo dy gewoan yntype in dit bewurkingsfjild\n([$1 Mear ynformaasje oer bewurkjen].)\nOars kinne jo tebek mei de tebek-knop fan jo blêder.",
+       "newarticletext": "Jo hawwe in keppeling folge nei in side dêr't noch gjin tekst op stiet.\nBegjin mei skriuwen yn it fjild hjirûnder om de side oan te meitsjen (sjoch de [$1 helpside] foar mear ynformaasje).\nKlik op de <strong>tebek</strong>-knop fan jo webblêder at jo hjir by ûngelok telâne kommen binne.",
        "anontalkpagetext": "----\n<em>Dit is de oerlisside fan in ûnbekende meidogger; in meidogger dy't him/har net oanmeld hat.</em>\nOm't der gjin namme bekend is, wurdt it ynternet-adres brûkt om oan te jaan om wa't it giet.\nMar faak is it sa dat sa'n adres net altyd troch deselde persoan brûkt wurdt.\nAs jo it idee hawwe dat jo as ûnbekende meidogger opmerkings foar in oar krije, dan kinne jo jo [[Special:CreateAccount|registrearje]], of jo [[Special:UserLogin|oanmelde]]. Fan in oanmelde meidogger is it ynternet-adres net sichtber, en as oanmelde meidogger krije jo allinnich opmerkings dy't foar josels bedoeld binne.",
-       "noarticletext": "Der stjit noch gjin tekst op dizze side. Jo kinne\n[[Special:Search/{{PAGENAME}}|hjirboppe nei dy tekst sykje]], of [{{fullurl:{{FULLPAGENAME}}|action=edit}} de side skriuwe].",
-       "userpage-userdoesnotexist": "Jo bewurkje in brûkersside fan in brûker dy't net bestiet (brûker \"<nowiki>$1</nowiki>\").\nKontrolearje oft jo dizze side wol oanmeitsje/bewurkje wolle.",
+       "noarticletext": "Der stiet noch gjin tekst op dizze side.\nJo kinne [[Special:Search/{{PAGENAME}}|nei dizze sidenamme sykje]] yn oare siden,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} de besibbe lochs trochsykje]\nof [{{fullurl:{{FULLPAGENAME}}|action=edit}} dizze side oanmeitsje]</span>.",
+       "userpage-userdoesnotexist": "Jo bewurkje in meidoggerside fan in meidogger dy't net bestiet (meidogger \"<nowiki>$1</nowiki>\").\nKontrolearje oft jo dizze side wol oanmeitsje/bewurkje wolle.",
+       "userpage-userdoesnotexist-view": "It meidochakkount \"$1\" bestiet net.",
        "clearyourcache": "<strong>Opmerking:</strong> Nei it fêstlizzen kin it nedich wêze de oerslach fan dyn blêder te leegjen foardat de wizigings te sjen binne.\n* <strong>Firefox / Safari:</strong> Hâld <em>Shift</em> yntreaun wylst jo op <em>Dizze side fernije</em> klikke, of typ <em>Ctrl-F5</em> of <em>Ctrl-R</em> (<em>⌘-R</em> op in Mac)\n* <strong>Google Chrome:</strong> Typ <em>CTRL-Shift-R</em> (<em>⌘-Shift-R</em> op in Mac)\n* <strong>Internet Explorer:</strong> Hâld <em>Ctrl</em> yntreaun wylst jo <em>Vernieuwen'' klikke of typ <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Leegje jo cache yn <em>Extra → Voorkeuren</em>",
        "usercssyoucanpreview": "<strong>Tip:</strong> Brûk de knop \"{{int:showpreview}}\" om jo nije CSS te testen foar it fêstlizzen.",
        "userjsyoucanpreview": "<strong>Tip:</strong> Brûk de knop \"{{int:showpreview}}\" om jo nije JS te testen foar it fêstlizzen.",
        "userinvalidconfigtitle": "<strong>Warskôging:</strong> der is gjin skin \"$1\".\nTink derom: jo eigen .css- en .js-siden begjinne mei in lytse letter, bygelyks {{ns:user}}:Namme/vector.css ynsté fan {{ns:user}}:Namme/Vector.css.",
        "updated": "(Bewurke)",
        "note": "<strong>Opmerking:</strong>",
-       "previewnote": "<strong>Tink der om dat dizze side noch net fêstlein is!</strong>",
+       "previewnote": "<strong>Tink derom dat dit allinnich in foarfertoaning is!</strong>\nJo feroarings binne noch net fêstlein!",
+       "continue-editing": "Gean nei it bewurkingsfjild",
        "previewconflict": "Dizze side belanget allinich it earste bewurkingsfjild oan.",
        "session_fail_preview": "<strong>Jo bewurking is net ferwurke, om't de sessygegevens ferlern gien binne.</strong>\nBesykje it nochris. As it dan noch net slagget, [[Special:UserLogout|meld jo dan ôf]] en wer oan.",
        "session_fail_preview_html": "<strong>Jo bewurking is net ferwurke, om't sesjegegevens ferlern gien binne.</strong>\n\n<em>Om't yn {{SITENAME}} rûge HTML ynskeakele is, is in foarfertoaning net mûglik as beskerming tsjin oanfallen mei JavaScript.</em>\n\n<strong>As dit in legitime bewurking is, besykje it dan fannijs.</strong>\nAs it dan  noch net slagget, [[Special:UserLogout|meld jo dan ôf]] en wer oan.",
        "editing": "Bewurkje \"$1\"",
        "creating": "$1 oanmeitsje",
        "editingsection": "Bewurkje $1 (seksje)",
-       "editingcomment": "Dwaande mei bewurkjen fan $1 (opmerking)",
+       "editingcomment": "Bewurkjen fan $1 (nij mêd)",
        "editconflict": "Tagelyk bewurke: \"$1\"",
        "explainconflict": "In oar hat de side feroare sûnt jo begûn binne mei it bewurkjen.\nIt earste bewurkingsfjild is hoe't de tekst wilens wurden is.\nJo feroarings stean yn it twadde fjild.\nDy wurde allinnich tapast safier as jo se yn it earste fjild ynpasse.\n'''Allinnich''' de tekst út it earste fjild kin fêstlein wurde.",
        "yourtext": "Jo tekst",
        "editingold": "<strong>Warskôging: Jo binne dwaande mei in âldere ferzje fan dizze side.</strong>\nSoene jo dy fêstlizze, dan is alles wei wat sûnt dy tiid feroare is.",
        "yourdiff": "Feroarings",
        "copyrightwarning": "Tink derom dat alle bydragen oan {{SITENAME}} beskôge wurde frijjûn te wêzen ûnder de $2 (sjoch $1 foar bysûnderheden). As jo net wolle dat jo tekst troch oaren neffens eigen goedfinen bewurke en ferspraat wurde kin, kies dan net foar 'Side Bewarje'.</br>\nHjirby sizze jo tagelyk ta, dat jo dizze tekst sels skreaun hawwe, of oernommen hawwe út in frije, iepenbiere boarne.</br/>\n'''BRûK GJIN MATERIAAL DAT BESKERME WURDT TROCH AUTERURSRJOCHT, OF JO MOATTE DêR TASTIMMING TA HAWWE!</STRONG>",
-       "copyrightwarning2": "Al jo bydragen oan {{SITENAME}} kinne bewurke, feroare of fuorthelle wurde troch oare brûkers.\nAs jo net wolle dat jo teksten yngeand oanpast wurde troch oaren, set se hjir dan net.<br />\nJo sizze ek ta dat jo de oarspronklike auteur binne fan dit materiaal, of dat jo it kopiearre hawwe út in boarne yn it publike domein, of in soartgelikense frije boarne (sjuch $1 foar details).\n'''BRUK GJIN MATERIAAL DAT BESKERME WURDT TROCH AUTEURSRJOCHT, OF JO MOATTE DER TASTIMMING FOAR HAWWE!'''",
+       "copyrightwarning2": "Al jo bydragen oan {{SITENAME}} kinne bewurke, feroare of fuorthelle wurde troch oare meidoggers.\nAs jo net wolle dat jo teksten yngeand oanpast wurde troch oaren, set se hjir dan net.<br />\nJo sizze ek ta dat jo de oarspronklike auteur binne fan dit materiaal, of dat jo it kopiearre hawwe út in boarne yn it publike domein, of in soartgelikense frije boarne (sjuch $1 foar details).\n'''BRUK GJIN MATERIAAL DAT BESKERME WURDT TROCH AUTEURSRJOCHT, OF JO MOATTE DER TASTIMMING FOAR HAWWE!'''",
        "longpageerror": "<strong>Flater: de tekst dy't jo tafoege hawwe is {{PLURAL:$1|ien kilobyte|$1 kilobytes}} grut, wat grutter is as it maksimum fan {{PLURAL:$2|ien kilobyte|$2 kilobytes}}.</strong>\nBewarjen is net mûglik.'''",
-       "readonlywarning": "<strong>Warskôging: De databank is ôfsletten foar ûnderhâld, dus jo kinne jo bewurkings no net fêstlizze. Bewarje de tekst foar lettere pleatsing yn in teksttriem.</strong>\n\nIn  behearder hat de database blokkearre om de folgjende reden: $1",
-       "protectedpagewarning": "<strong>Warskôging: Dizze side is beskerme, dat gewoane brûkers dy net bewurkje kinne.</strong>",
-       "semiprotectedpagewarning": "<strong>Opmerking:</strong> Dizze side is befeilige en kin allinne troch registrearre brûkers bewurke wurde.",
+       "readonlywarning": "<strong>Warskôging: De databank is skoattele foar ûnderhâld, dat jo kinne jo bewurkings op dit stuit net fêstlizze.</strong>\nJo soene jo tekst knippe en plakke kinne nei in tekstbestân, en bewarje foar letter.\n\nDe systeembehearder dy't it skoattele hat joech dizze taljochting: $1",
+       "protectedpagewarning": "<strong>Warskôging: Dizze side is beskerme, dat allinne meidoggers mei beheardersrjochten it bewurkje kinne.</strong>\nDe lêste lochrigel is hjirûnder jûn as referinsje:",
+       "semiprotectedpagewarning": "<strong>Opmerking:</strong> Dizze side is befeilige en kin allinne troch registrearre meidoggers bewurke wurde.",
        "cascadeprotectedwarning": "<strong>Warskôging:</strong> Dizze side is skoattele sadat allinnich behearders de side wizigje kinne, om't der in ûnderdiel útmakket fan de neikommende {{PLURAL:$1|side|siden}}, dy't skoattele binne mei de \"ûnderlizzende siden\" opsje ynskeakele:",
        "titleprotectedwarning": "<strong>Warskôging: Dizze side is befeilige. Der binne [[Special:ListGroupRights|spesjale rjochten]] nedich om dizze side meitsje te kinnen.</strong>\nDe lêste lochrigel stiet hjirûnder:",
        "templatesused": "{{PLURAL:$1|Berjocht|Berjochten}} brûkt op dizze side:",
        "hiddencategories": "Dizze side falt yn de folgjende ferburgen\n{{PLURAL:$1|kategory|kategoryen}}:",
        "edittools": "<!-- Tekst hjir stiet ûnder bewurkingsfjilden en oanbringfjilden.  -->",
        "edittools-upload": "-",
-       "nocreatetext": "{{SITENAME}} hat de mûglikheid beheind om nije siden te meitsjen.\nJo kinne al besteande siden feroarje of jo kinne [[Special:UserLogin|jo oanmelde of in brûker oanmeitsje]].",
+       "nocreatetext": "{{SITENAME}} hat de mûglikheid beheind om nije siden oan te meitsjen.\nJo kinne al weromgean en besteande siden bewurkje, [[Special:UserLogin|jo oanmelde of in akkount oanmeitsje]].",
        "nocreate-loggedin": "Jo meie gjin nije siden meitsje",
        "permissionserrors": "Flaters yn rjochten",
        "permissionserrorstext": "Jo hawwe gjin rjochtem dit te dwaan om de folgjende {{PLURAL:$1|reden|redenen}}:",
        "undo-failure": "De feroarings kinne net werom set wurde troch in konflikt mei oare feroarings tuskentroch.",
        "undo-norev": "De feroaring kin werom set wurde, omdat it net bestiet of is wiske.",
        "undo-summary": "Werom sette fan ferzje $1 fan [[Special:Contributions/$2|$2]] ([[User talk:$2|Oerlis]])",
-       "cantcreateaccount-text": "Registraasje fan in brûker fia dit IP-adres ('''$1''') is blokkearre troch [[User:$3|$3]].\n\nDe fan $3 opjûne reden is ''$2''",
+       "cantcreateaccount-text": "Registraasje fan in meidogger fia dit IP-adres ('''$1''') is blokkearre troch [[User:$3|$3]].\n\nDe fan $3 opjûne reden is ''$2''",
        "viewpagelogs": "Lochboek foar dizze side sjen litte",
        "nohistory": "Dit is de earste ferzje fan de side.",
        "currentrev": "Aktuele ferzje",
        "last": "foarige",
        "page_first": "earste",
        "page_last": "lêste",
-       "histlegend": "Utlis: (no) = ferskil mei de side sa't dy no is,\n(doe) = ferskill mei de side sa't er doe wie, foar de feroaring, T = Tekstwiziging",
+       "histlegend": "Ferskil oanjaan: Markearje de rûntsjes fan 'e te ferlykjen ferzjes, en druk op Enter of de knop ûnderoan.<br />\nLeginda: <strong>({{int:cur}})</strong> = ferskil mei de lêste ferzje, <strong>({{int:last}})</strong> = ferskil mei de eardere ferzje, <strong>{{int:minoreditletter}}</strong> = lytse feroaring.",
        "history-fieldset-title": "Troch skiednis blêdzje",
        "histfirst": "âldste",
        "histlast": "nijste",
        "history-feed-item-nocomment": "$1 op $2",
        "history-feed-empty": "De frege side bestiet net.\nFaaks is dy fuorthelle of omneamd.\n[[Special:Search|Sykje de wiki troch]] foar relevante nije siden.",
        "rev-deleted-comment": "(opmerking wiske)",
-       "rev-deleted-user": "(meidoggernamme wiske)",
-       "rev-deleted-event": "(logboekrigel fuorthelle)",
+       "rev-deleted-user": "(meidochnamme fuorthelle)",
+       "rev-deleted-event": "(lochrigel fuorthelle)",
        "rev-deleted-text-permission": "Dy bewurking fan de side is fuorthelle út de publike argiven.\nDer kinne details oanwêzich wêze yn it [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} fuorthel-logboek].",
        "rev-deleted-text-view": "Dizze bewurking fan de side is fuorthelle út de publike argiven.\nAs behearder fan {{SITENAME}} kinne jo him besjen;\nder kinne details wêze yn it [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} fuorthel-logboek].",
        "rev-delundel": "sjen litte/ferbergje",
        "revisiondelete": "Wiskje/weromsette ferzjes",
        "revdelete-nooldid-title": "Gjin doelferzje",
        "revdelete-nooldid-text": "Jo hawwe gjin doelferzje(s) foar dizze hanneling opjûn, de oanjûne ferzje bestiet net, of jo besykje de lêste ferzje te ferskûljen.",
-       "revdelete-no-file": "De spesifisearre triem bestiet net.",
+       "revdelete-no-file": "It spesifisearre bestân bestiet net.",
        "revdelete-show-file-submit": "Ja",
        "logdelete-selected": "{{PLURAL:$1|keazen lochboekregel|keazen lochboekregels}}:",
        "revdelete-legend": "Sichtberensbeheinings ynstelle.",
        "revdelete-hide-text": "De bewurke tekst ferskûlje",
-       "revdelete-hide-image": "Triem ynhâld ferskûlje",
+       "revdelete-hide-image": "Bestânsynhâld ferskûlje",
        "revdelete-hide-name": "Aksje en doel ferskûlje",
        "revdelete-hide-comment": "Bewurkingsgearfetting",
-       "revdelete-hide-user": "Meidoggernamme/IP fan de meidogger ferskûlje",
+       "revdelete-hide-user": "Meidochnamme/IP-adres fan 'e bewurker",
        "revdelete-hide-restricted": "Dizze beheinings tapasse op behearders en dizze ynterface ôfslute",
        "revdelete-radio-set": "Ferburgen",
        "revdelete-radio-unset": "Sichtber",
        "mergehistory": "Skiednis fan kombinearjen",
        "mergehistory-header": "Troch dizze side kinne jo ferzjes fan 'e skiednis fan in boarneside nei in nijere side gearfoegje.\nSoargje dat jo mei dizze feroaring it skiednisferrin fan de side net oantaaste.",
        "mergehistory-box": "Ferzjes fan twa siden kombinearje:",
-       "mergehistory-from": "Triemnamme boarne:",
+       "mergehistory-from": "Bestânsnamme boarne:",
        "mergehistory-into": "Bestimmingside:",
        "mergehistory-list": "Gearfoegbere bewurkingsskiednis",
        "mergehistory-merge": "De folgjende ferzjes fan [[:$1]] kinne gearfoege wurde nei [[:$2]].\nBrûk de kolom mei de karrûntsjes om allinne de ferzjes makke op en foar de oanjûne tiid gear te foegjen.\nTink derom it brûken fan de navigaasjeferwizings dy kolom op'e nij ynstelt.",
-       "mergehistory-go": "Besjen bewurkings dy't kombinearre wurde kinne",
+       "mergehistory-go": "Gearfoegbere bewurkings besjen",
        "mergehistory-submit": "Kombinearje ferzjes",
        "mergehistory-empty": "Gjin ferzjes kinne kombinearren wurde.",
        "mergehistory-done": "Kombinearjen slagge fan $3 {{PLURAL:$3|ferzje|ferzjes}} fan $1 no [[:$2]].",
        "lineno": "Rigel $1:",
        "compareselectedversions": "Ferlykje selektearre ferzjes",
        "showhideselectedversions": "Oantikke ferzjes wol/net sjen litte",
-       "editundo": "werom sette",
+       "editundo": "weromsette",
        "diff-empty": "(Gjin ferskil)",
-       "searchresults": "Sykresultaat",
+       "diff-multi-sameuser": "({{PLURAL:$1|Ien tuskenferzje|$1 tuskenferzjes}} fan deselde meidogger net werjûn)",
+       "diff-multi-otherusers": "({{PLURAL:$1|Ien tuskenferzje|$1 tuskenferzjes}} fan {{PLURAL:$2|ien oare meidogger|$2 meidoggers}} net werjûn)",
+       "diff-multi-manyusers": "({{PLURAL:$1|Ien tuskenferzje|$1 tuskenferzjes}} fan mear as $2 {{PLURAL:$2|meidogger|meidoggers}} net werjûn)",
+       "searchresults": "Sykresultaten",
        "searchresults-title": "Sykresultaten foar \"$1\"",
        "titlematches": "Titels",
        "textmatches": "Siden",
        "notextmatches": "Gjin siden",
-       "prevn": "foarige {{PLURAL:$1|$1}}",
-       "nextn": "folgende {{PLURAL:$1|$1}}",
+       "prevn": "{{PLURAL:$1|$1}} foargeand",
+       "nextn": "{{PLURAL:$1|$1}} neikommend",
        "prev-page": "foarige side",
        "next-page": "folgjende side",
        "prevn-title": "{{PLURAL:$1|Foarich risseltaat|Foarige $1 risseltaten}}",
        "nextn-title": "{{PLURAL:$1|Folgjend risseltaat|Folgjende $1 risseltaat}}",
-       "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) besjen.",
-       "searchmenu-exists": "<strong>Der is in side mei namme \"[[:$1]]\" yn dizze wiki</strong>",
-       "searchmenu-new": "<strong>Meitsje de side \"[[:$1]]\" yn dizze wiki!</strong>",
+       "shown-title": "Lit $1 {{PLURAL:$1|resultaat|resultaten}} de side sjen",
+       "viewprevnext": "Besjoch ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>Der is in side mei de namme \"[[:$1]]\" op 'e wiki.</strong> {{PLURAL:$2|0=|Sjoch ek de oare sykresultaten.}}",
+       "searchmenu-new": "<strong>Meitsje de side \"[[:$1]]\" op dizze wiki!</strong> {{PLURAL:$2|0=|Sjoch ek de side fûn mei jo sykopdracht.|Sjoch ek de sykresultaten dy't fûn binne.}}",
        "searchprofile-articles": "Ynhâldlike siden",
        "searchprofile-images": "Multymedia",
        "searchprofile-everything": "Alles",
        "searchprofile-advanced": "Utwreide",
        "searchprofile-articles-tooltip": "Sykje yn $1",
-       "searchprofile-images-tooltip": "Sykje om triemmen",
+       "searchprofile-images-tooltip": "Sykje om bestannen",
        "searchprofile-everything-tooltip": "Alle ynhâld trochsykje (ynklusyf oerlissiden)",
-       "searchprofile-advanced-tooltip": "Sykje yn oanjûne nammerûmten",
+       "searchprofile-advanced-tooltip": "Sykje yn oanjûne nammeromten",
        "search-result-size": "$1 ({{PLURAL:$2|1 wurd|$2 wurden}})",
        "search-redirect": "(trochferwizing $1)",
        "search-section": "(seksje $1)",
        "search-relatedarticle": "Besibbe",
        "searchrelated": "besibbe",
        "searchall": "alle",
-       "showingresults": "{{PLURAL:$1|<strong>1</strong> resultaat|<strong>$1</strong> resultaten}} fan #<strong>$2</strong> ôf.",
+       "showingresults": "Totaal {{PLURAL:$1|<strong>1</strong> resultaat|<strong>$1</strong> resultaten}}, hjirûnder werjûn fan #<strong>$2</strong> ôf.",
        "search-showingresults": "{{PLURAL:$4|Resultaat <strong>$1</strong> fan <strong>$3</strong>|Resultaten <strong>$1 - $2</strong> fan <strong>$3</strong>}}",
        "search-nonefound": "Der binne gjin resultaten foar jo sykopdracht.",
-       "powersearch-legend": "Sykje",
+       "powersearch-legend": "Utwreidich sykje",
        "powersearch-ns": "Sykje yn nammeromten:",
        "powersearch-togglelabel": "Oantikje:",
        "powersearch-toggleall": "Alle",
        "powersearch-togglenone": "Gjin",
        "powersearch-remember": "Seleksje ûnthâlde foar sykopdrachten yn 'e takomst",
        "search-external": "Utwindich sykje",
-       "searchdisabled": "<p>Op it stuit stiet it trochsykjen fan tekst út omdat dizze funksje tefolle kompjûterkapasiteit ferget. As we nije apparatuer krije, en dy is ûnderweis, dan wurdt dizze funksje wer aktyf. Oant salang kinne jo sykje fia Google:</p>",
+       "searchdisabled": "Sykjen op {{SITENAME}} is útskeakele.\nJo kinne yn 'e tuskentiid mei Google sykje.\nTink derom dat harren yndeksearring fan 'e ynhâld op {{SITENAME}} ferâldere wêze kin.",
        "preferences": "Foarkarren",
        "mypreferences": "Foarkarren",
        "prefs-edits": "Tal bewurkings:",
+       "prefsnologintext2": "Jo moatte jo oanmelde om jo ynstellings wizigje te kinnen.",
        "prefs-skin": "Side-oansjen",
        "skin-preview": "Proefbyld",
        "datedefault": "Gjin foarkar",
        "prefs-user-pages": "Meidoggersiden",
-       "prefs-personal": "Persoanlike gegevens",
+       "prefs-personal": "Meidogger",
        "prefs-rc": "Koartlyn feroare",
        "prefs-watchlist": "Folchlist",
        "prefs-editwatchlist": "Folchlist bewurkje",
        "prefs-email": "E-mail",
        "prefs-rendering": "Uterlik",
        "saveprefs": "Bewarje",
-       "restoreprefs": "Tebek nei de standertynstellings",
+       "restoreprefs": "Alle standertynstellings weromsette (yn alle parten)",
        "prefs-editing": "Siden bewurkje",
        "searchresultshead": "Sykje",
        "stub-threshold": "Drompel foar markearring <a href=\"#\" class=\"stub\">stobbe</a> (bytes):",
        "prefs-searchoptions": "Sykje",
        "prefs-namespaces": "Nammeromten",
        "default": "standert",
-       "prefs-files": "Triemmen",
+       "prefs-files": "Bestannen",
        "prefs-custom-js": "Persoanlik JS",
+       "prefs-reset-intro": "Jo kinne dizze side brûke, en set jo ynstellings werom nei de websteestandert.\nDat kin net ûngedien makke wurde.",
        "prefs-emailconfirm-label": "E-mailbefêstiging:",
        "youremail": "E-mail:",
-       "username": "{{GENDER:$1|Brûkersnamme}}:",
+       "username": "{{GENDER:$1|Meidochnamme}}:",
        "prefs-memberingroups": "Lid fan {{PLURAL:$1|groep|groepen}}:",
        "prefs-memberingroups-type": "$1",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Jo wiere namme:",
        "yourlanguage": "Taal:",
-       "yournick": "Jo alias (foar sinjaturen)",
-       "badsig": "Unjildige ûndertekening; kontrolearje de HTML-tags.",
+       "yournick": "Nije sinjatuer:",
+       "badsig": "Unjildige sinjatuer yn koadefoarm.\nKontrolearje de HTML-tags.",
        "badsiglength": "Bynamme is te lang; dy moat koarter as $1 {{PLURAL:$1|teken|tekens}} wêze.",
        "yourgender": "Hoe wolsto beskreaun wurde?",
        "gender-unknown": "Ik wol dit net oanjûn",
        "prefs-help-gender": "Kar: dit wurdt troch de programmatuer brûkt om de goeie oansprekfoarm te kiezen.\nDizze ynformaasje is foar oare meidoggers te sjen.",
        "email": "E-mail",
        "prefs-help-realname": "Echte namme is net ferplicht; as jo dy opjouwe kin dy namme brûkt wurde om jo erkenning te jaan foar jo wurk.",
-       "prefs-help-email": "E-mail is opsjoneel, mar makket it mûglik jo wachtwurd te stjoeren as jo it fergetten hawwe.\nJo kinne ek oaren de mûglikheid jaan kontakt mei jo op te nimmen troch in ferwizing op jo brûkers- en oerlisside, sûnder dat jo jo identiteit oer hoege te jaan.",
+       "prefs-help-email": "In e-mailadres hoecht net, mar is al nedich foar it op 'e nij oanmeitsjen fan jo wachtwurd, at jo dat ferjitte.",
        "prefs-help-email-required": "Hjir is in e-mailadres foar nedich.",
        "prefs-info": "Basisynformaasje",
        "prefs-i18n": "Taalynstellingen",
        "prefs-dateformat": "Datumopmaak",
        "prefs-timeoffset": "Tiidsferskil",
        "prefs-advancedediting": "Algemiene opsjes",
-       "prefs-editor": "Tekstferwurker",
+       "prefs-editor": "Tekstbewurker",
        "prefs-preview": "Proefbyld",
        "prefs-advancedrc": "Avansearre opsjes",
        "prefs-advancedrendering": "Avansearre opsjes",
        "prefs-diffs": "Ferskillen",
        "userrights": "Behear fan meidoggerrjochten",
        "userrights-lookup-user": "Behear fan meidoggerrjochten",
-       "userrights-user-editname": "Meidoggernamme:",
+       "userrights-user-editname": "Jou in meidochnamme:",
        "editusergroup": "Wizigje meidoggerrjochten",
        "editinguser": "Bewurkje meidoggerrjochten fan <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Wizigje meidoggerrjochten",
        "saveusergroups": "Meidoggerrjochten bewarje",
        "userrights-groupsmember": "Sit yn group:",
        "userrights-groupsmember-type": "$1",
-       "userrights-groups-help": "Jo kinne de groepen feroarje dêr't dizze brûker lid fan is.\n* In oankrúst fekje betsjut dat de brûker lid is fan 'e groep.\n* In net oankrúst fekje betsjut dat de brûker gjin lid is fan 'e groep.\n* In \"*\" betsjut dat jo in brûker net út in groep weihelje kinne nei't jo dy tafoege hawwe, of oarsom.",
+       "userrights-groups-help": "Jo kinne de groepen feroarje dêr't dizze meidogger lid fan is.\n* In oankrúst fekje betsjut dat de meidogger lid is fan 'e groep.\n* In net oankrúst fekje betsjut dat de meidogger gjin lid is fan 'e groep.\n* In \"*\" betsjut dat jo in meidogger net út in groep weihelje kinne nei't jo dy tafoege hawwe, of oarsom.",
        "userrights-reason": "Reden:",
        "userrights-no-interwiki": "Jo hawwe gjin foech om rjochten fan meidoggers op oare wikis te wizigjen.",
        "userrights-nodatabase": "Databank $1 bestiet net of is net lokaal.",
        "userrights-irreversible-marker": "$1*",
        "group": "Groep:",
        "group-user": "Meidoggers",
-       "group-autoconfirmed": "befêstige brûkers",
+       "group-autoconfirmed": "befêstige meidoggers",
        "group-bot": "Bots",
        "group-sysop": "Behearders",
        "group-bureaucrat": "Rjochtenútfurders",
        "group-suppress": "tasichthâlders",
        "group-all": "(eltsenien)",
        "group-user-member": "{{GENDER:$1|meidogger}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|registrearre brûker}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|registrearre meidogger}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|behearder}}",
        "group-bureaucrat-member": "{{GENDER:$1|rjochtenútfurder}}",
        "group-suppress-member": "{{GENDER:$1|tasichthâlder}}",
        "grouppage-user": "{{ns:project}}:Meidoggers",
-       "grouppage-autoconfirmed": "{{ns:project}}:Registrearre brûkers",
+       "grouppage-autoconfirmed": "{{ns:project}}:Registrearre meidoggers",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Behearders",
        "grouppage-bureaucrat": "{{ns:project}}:Rjochtenútfurders",
        "right-edit": "Siden bewurkjen",
        "right-createpage": "Siden oanmeitsjen (net oerlissiden)",
        "right-createtalk": "Oerlissiden oanmeitsjen",
-       "right-createaccount": "Nije brûkers oanmeitsje",
-       "right-minoredit": "Bydragen markearje as tekstwiziging",
+       "right-createaccount": "Nije meidoggers oanmeitsje",
+       "right-minoredit": "Feroarings as fan lytse betsjutting markearje",
        "right-move": "Siden werneamen",
        "right-move-subpages": "Siden ynklusyf har subsiden ferpleatse.",
-       "right-move-rootuserpages": "Brûkerssiden fan it heechste nivo in oare namme jaan",
-       "right-movefile": "Triemmen in oare namme jaan",
+       "right-move-rootuserpages": "Meidoggersiden fan it heechste nivo in oare namme jaan",
+       "right-movefile": "Bestannen in oare namme jaan",
        "right-suppressredirect": "In trochferwizing op 'e doelside fuorthelje by werneamen fan in side",
-       "right-upload": "Triemmen oanbieden",
-       "right-reupload": "In besteande triem oerskriuwen",
-       "right-reupload-own": "Sels heechladene triemmen oerskriuwe",
+       "right-upload": "Bestannen oanbiede",
+       "right-reupload": "In besteand bestân oerskriuwen",
+       "right-reupload-own": "Sels heechladene bestannen oerskriuwe",
        "right-reupload-shared": "Media út 'e dielde mediadatabank lokaal oerskriuwe",
-       "right-upload_by_url": "Triemen oanbieden fia in URL",
+       "right-upload_by_url": "Bestannen oanbiede fia in URL",
        "right-purge": "De cache foar in side leegje sûnder befêstiging",
-       "right-autoconfirmed": "Behannele wurde as in registrearre brûker",
+       "right-autoconfirmed": "Hat gjin op IP-adres basearre tiidsôfhinklike beheinings",
        "right-bot": "Behannele wurde as in automatisearre proses",
-       "right-nominornewtalk": "Lytse bewurkings oan in oerlisside liede net ta in melding 'nije berjochten'",
+       "right-nominornewtalk": "Feroarings fan lytse betsjutting oan in oerlisside liede net ta in melding 'nije berjochten'",
        "right-apihighlimits": "Hegere limiten yn API-sykopdrachten brûke",
        "right-writeapi": "Bewurkje fia API",
        "right-delete": "Siden wiskje",
        "right-deletedhistory": "Wiske ferzjes besjen, sûnder sjen te kinnen wat wiske is.",
        "right-browsearchive": "Wiske siden besjen",
        "right-undelete": "Wiske siden tebeksette",
-       "right-suppressrevision": "Ferskûle ferzjes besjen en tebeksette",
+       "right-suppressrevision": "Beskate sideferzjes fan in meidogger besjen, ferbergje of net ferbergje",
        "right-suppressionlog": "Net-publike logboeken besjen",
-       "right-block": "Oare brûkers de mûglikheid ta bewurkjen ôfnimme",
-       "right-blockemail": "In brûker it rjocht ta it ferstjoeren fan e-mail ôfnimme",
-       "right-hideuser": "In brûkersnamme foar oare brûkers ferskûlje",
+       "right-block": "Oare meidoggers de mûglikheid ta bewurkjen ôfnimme",
+       "right-blockemail": "In meidogger it rjocht ta it ferstjoeren fan e-mail ôfnimme",
+       "right-hideuser": "In meidochnamme foar oare meidoggers ferskûlje",
        "right-ipblock-exempt": "IP-blokkades út 'e wei gean",
        "right-protect": "Befeiligingsnivo's feroarje en beskerme siden bewurkje",
        "right-editprotected": "Befeilige siden bewurkje (sûnder cascading-befeiliging)",
-       "right-editinterface": "Brûkersinterface bewurkje",
-       "right-editusercss": "De CSS-triemmen fan oare brûkers bewurkje",
-       "right-edituserjson": "De JSON-triemmen fan oare brûkers bewurkje",
-       "right-edituserjs": "De JS-triemmen fan oare brûkers bewurkje",
-       "right-rollback": "Gau de lêste bewurking(s) fan in brûker fan in side tebekdraaie",
-       "right-markbotedits": "Tebekdraaide bewurkings markearje as botbewurkings",
+       "right-editinterface": "Meidoggersinterface bewurkje",
+       "right-editusercss": "De CSS-bestannen fan oare meidoggers bewurkje",
+       "right-edituserjson": "De JSON-bestannen fan oare meidoggers bewurkje",
+       "right-edituserjs": "De JS-bestannen fan oare meidoggers bewurkje",
+       "right-rollback": "Gau de bewurkings weromdraaie fan 'e lêste meidogger dy't in beskate side bewurke",
+       "right-markbotedits": "Weromdraaide bewurkings markearje as botbewurkings",
        "right-noratelimit": "Hat gjin tiidsôfhinklike beheinings",
        "right-import": "Siden út oare wiki's ymportearje",
-       "right-importupload": "Ymportearjen siden fan in triemoanbied",
+       "right-importupload": "Siden ymportearje út in opladen bestân",
        "right-patrol": "Bewurkings as kontrolearre markearje",
        "right-autopatrol": "Bewurkings wurde automatysk as kontrolearre markearre",
        "right-patrolmarks": "Kontroletekens yn resinte feroarings besjen",
        "right-siteadmin": "De database blokkearje en wer frij jaan",
        "right-override-export-depth": "Alle siden oant en mei in keppelingsdjipte fan fiif fuortskriuwe",
        "grant-group-email": "E-mail stjoere",
+       "grant-rollback": "Wizigings oan siden weromdraaie",
        "newuserlogpage": "Ynskriuwingsloch",
        "newuserlogpagetext": "Dit is in loch fan meidoggers dy't de lêste tiid ynskreaun binne.",
-       "rightslog": "Rjochten-loch",
+       "rightslog": "Rjochtenloch",
        "rightslogtext": "Dit is in loch fan feroarings fan meidoggerrjochten.",
        "action-read": "dizze side besjen",
        "action-edit": "dizze side te bewurkjen",
        "action-createpage": "siden oan te meitsjen",
        "action-createtalk": "oerlissiden oan te meitsjen",
-       "action-createaccount": "dizze meidogger oan te meitsjen",
-       "action-minoredit": "dizze bewurking as lyts te markearjen",
+       "action-createaccount": "oanmeitsjen fan dit meidochakkount",
+       "action-minoredit": "dizze feroaring as fan lytse betsjutting te markearjen",
        "action-move": "dizze side in oare namme te jaan",
        "action-move-subpages": "dizze side en de derby hearrende subsiden in oare namme te jaan",
        "action-move-rootuserpages": "meidoggersiden fan it heechste nivo in oare namme te jaan",
        "action-move-categorypages": "categorysiden ferpleatse",
-       "action-movefile": "dizze triem in oare namme te jaan",
-       "action-upload": "dizze triem te opladen",
-       "action-reupload": "dizze besteande triem te oerskriuwen",
-       "action-reupload-shared": "dizze triem te opladen, wylst der al in triem mei deselde namme yn 'e dielde repository stiet",
-       "action-upload_by_url": "dizze triem fan in URL ôf op te laden",
+       "action-movefile": "dit bestân in oare namme jaan",
+       "action-upload": "dit bestân oplade",
+       "action-reupload": "dit besteande bestân te oerskriuwen",
+       "action-reupload-shared": "dit bestân oplade, wylst der al in bestân mei deselde namme yn 'e dielde repository stiet",
+       "action-upload_by_url": "dit bestân fan in URL ôf oplade",
        "action-writeapi": "fia de API te bewurkjen",
        "action-delete": "dizze side fuort te heljen",
        "action-deleterevision": "dizze ferzje fuort te heljen",
        "action-suppressionlog": "dit beskerme logboek besjen",
        "action-block": "dizze meidogger in bewurkingsblokkade oplizze",
        "action-protect": "it befeiligingsnivo fan dizze side oanpasse",
+       "action-rollback": "gau de bewurkings weromdraaien fan 'e lêste meidogger dy't in beskate side bewurke",
        "action-import": "dizze side fan in oare wiki ymportearje",
-       "action-importupload": "dizze side ymportearje fan in triem-oplading",
+       "action-importupload": "siden ymportearjen út in opladen bestân",
        "action-patrol": "bewurkings fan oaren as kontrolearre beskôgje",
        "action-autopatrol": "eigen bewurkings as kontrolearre markearje litte",
        "action-unwatchedpages": "de list mei siden dy't net op in folchlist steane besjen",
        "recentchanges-summary": "Folgje de lêste feroarings oan 'e wiki op dizze side.",
        "recentchanges-feed-description": "Mei dizze feed kinne jo de nijste feroarings yn dizze wiki besjen.",
        "recentchanges-label-newpage": "Mei dizze wiziging is in nije side makke",
-       "recentchanges-label-minor": "Dit is in tekstwiziging",
+       "recentchanges-label-minor": "Dizze feroaring is fan lytse betsjutting",
        "recentchanges-label-bot": "Dizze bewurking is troch in bot útfierd",
-       "recentchanges-label-unpatrolled": "Dizze wiziging is noch net neisjûn",
+       "recentchanges-label-unpatrolled": "Dizze wiziging is noch net neisjoen",
        "recentchanges-label-plusminus": "De sidegrutte is mei dit oantal bytes wizige",
        "recentchanges-legend-heading": "<strong>Leginda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}}<br />(sjoch ek de [[Special:NewPages|list mei nije siden]])",
        "rcfilters-legend-heading": "<strong>List fan ôfkoartings:</strong>",
-       "rcnotefrom": "Dit binne de feroarings sûnt <b>$2</b> (maksimaal <b>$1</b>).",
+       "rcfilters-search-placeholder": "Feroarings filterje (brûk it menu of sykje op filternamme)",
+       "rcfilters-filterlist-feedbacklink": "Lit ús hearre wat jo fan dit filterark fine",
+       "rcfilters-highlightbutton-title": "Resultaten aksintuearje",
+       "rcfilters-highlightmenu-title": "Kies in kleur",
+       "rcfilters-highlightmenu-help": "Kleur kieze foar it aksintuearjen fan dizze eigenskip",
+       "rcfilters-filter-excluded": "Utsein",
+       "rcfilters-exclude-button-off": "Seleksje omkeare",
+       "rcfilters-exclude-button-on": "Omkearde seleksje",
+       "rcfilters-view-tags": "Lebele bewurkings",
+       "rcfilters-view-namespaces-tooltip": "Resultaten op nammeromte filterje",
+       "rcfilters-view-tags-tooltip": "Resultaten mei bewurkingslebels filterje",
+       "rcfilters-view-return-to-default-tooltip": "Werom nei it filterhaadmenu",
+       "rcfilters-view-tags-help-icon-tooltip": "Kom mear oan 'e weet oer Lebele bewurkings",
+       "rcnotefrom": "Hjirûnder {{PLURAL:$5|stiet de feroaring|steane de feroarings}} sûnt <strong>$3, $4</strong> (maksimaal <strong>$1</strong> werjûn).",
        "rclistfrom": "Jou nije feroarings, begjinnende mei $3 $2",
-       "rcshowhideminor": "$1 tekstwizigings",
+       "rcshowhideminor": "Lytse feroarings $1",
        "rcshowhideminor-show": "werjaan",
        "rcshowhideminor-hide": "ferbergje",
-       "rcshowhidebots": "bots $1",
+       "rcshowhidebots": "Bots $1",
        "rcshowhidebots-show": "werjaan",
        "rcshowhidebots-hide": "ferbergje",
-       "rcshowhideliu": "registrearre brûkers $1",
+       "rcshowhideliu": "Registrearre meidoggers $1",
        "rcshowhideliu-show": "werjaan",
        "rcshowhideliu-hide": "ferbergje",
-       "rcshowhideanons": "$1 anonimen",
+       "rcshowhideanons": "Anonime meidoggers $1",
        "rcshowhideanons-show": "werjaan",
        "rcshowhideanons-hide": "ferbergje",
        "rcshowhidepatr": "kontrolearre bewurkings $1",
        "rcshowhidepatr-show": "werjaan",
        "rcshowhidepatr-hide": "ferbergje",
-       "rcshowhidemine": "$1 eigen bewurkings",
+       "rcshowhidemine": "Myn bewurkings $1",
        "rcshowhidemine-show": "werjaan",
        "rcshowhidemine-hide": "ferbergje",
-       "rclinks": "Jou $1 nije feroarings yn de lêste $2 dagen",
-       "diff": "ferskil",
-       "hist": "skiednis",
+       "rclinks": "Jou de lêste $1 feroarings fan 'e lêste $2 dagen",
+       "diff": "fersk.",
+       "hist": "skied.",
        "hide": "gjin",
        "show": "al",
-       "minoreditletter": "T",
+       "minoreditletter": "L",
        "newpageletter": "N",
        "boteditletter": "b",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 folgjende {{PLURAL:$1|meidogger|meidoggers}}]",
        "rc-change-size": "$1",
-       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} nei de wiziging",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} nei wiziging",
        "newsectionsummary": "/* $1 */ nije seksje",
        "rc-enhanced-expand": "Details werjaan",
        "rc-enhanced-hide": "Details ferskûlje",
        "recentchangeslinked-summary": "Dizze spesjale side lit de lêste bewurkings sjen op siden dy't keppele wurde fan in spesifisearre side ôf (of fan in spesifisearre Kategory ôf). Siden dy't op [[Special:Watchlist|jo folchlist]] steane, wurde '''tsjûk''' werjûn.",
        "recentchangeslinked-page": "Sidenamme:",
        "recentchangeslinked-to": "Feroarings oan siden mei ferwizings nei dizze side besjen",
-       "upload": "Bied triem oan",
-       "uploadbtn": "Bied triem oan",
-       "reuploaddesc": "Werom nei oanbied-side.",
+       "upload": "Bied bestân oan",
+       "uploadbtn": "Bied bestân oan",
+       "reuploaddesc": "Opladen annulearje en weromgean nei it oanbiedformulier",
        "uploadnologin": "Net oanmeld",
-       "uploadnologintext": "Jo moatte [[Special:UserLogin|oanmeld]] wêze om in triem oanbiede te kinnen.",
+       "uploadnologintext": "Jo moatte $1 om bestannen oplade te kinnen.",
        "upload_directory_missing": "De heechlaadmap ($1) is der net en koe net oanmakke wurde troch de webserver.",
        "upload_directory_read_only": "De webserver kin net skriuwe yn de oanbiedpad ($1).",
        "uploaderror": "Oanbiedfout",
-       "uploadtext": "Om in nije triemmen oan te bieden, brûke jo de ûndersteande formulier. Earder oanbeane triemmen, kinne jo fine op de [[Special:FileList|list fan oanbeane ôfbylden]].\nWat oanbean en wat wiske wurdt, wurdt delskreaun yn it [[Special:Log/upload|lochboek]].\n\nOm de triem yn in side op te nimmen, meitsje jo dêr sa'n keppeling:\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:jo_foto.jpg]]</nowiki></code>''', foar grutte ferzje,\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:jo_logo.png|omskriuwing]]</nowiki></code>''' foar 200 in piksel ferzje, mei 'alternative tekst' as beskriuwing, of\n*'''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:jo_lûd.ogg]]</nowiki></code>''', foar direkt keppeling nei de triem (sûnder byld).",
-       "upload-permitted": "Talitten triemtypen: $1.",
-       "upload-preferred": "Oanwiisde triemtypen: $1.",
-       "upload-prohibited": "Ferbeane triemtypen: $1.",
+       "uploadtext": "Brûk it formulier dat hjir folget om bestannen op te laden.\nGean nei de [[Special:FileList|bestânslist]], om earder opladen bestannen te besjen of op te sykjen. De (wer)opladen bestannen wurde ek opnommen yn it [[Special:Log/upload|oanbiedloch]], fuortsmiten bestannen yn it [[Special:Log/delete|wiskloch]].\n\nBrûk in keppeling yn ien fan 'e neikommende foarmen, en heakje in bestân oan in side ta:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Bestân.jpg]]</nowiki></code></strong> om de folsleine ferzje fan it bestân te brûken\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Bestân.png|200px|thumb|left|alt. tekst]]</nowiki></code></strong> om in ôfbylding fan 200 pixel breed te brûken, yn in ramt oan de lofter kant mei \"alt. tekst\" as beskriuwing\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Bestân.ogg]]</nowiki></code></strong> foar it sûnder werjefte, streekrjocht ferwizen nei it bestân",
+       "upload-permitted": "Talitten bestânstypen: $1.",
+       "upload-preferred": "Oanwiisde bestânstypen: $1.",
+       "upload-prohibited": "Ferbeane bestânstypen: $1.",
        "uploadlogpage": "Oanbiedloch",
-       "uploadlogpagetext": "List fan de lêst oanbeane triemmen. (Tiid oanjûn as UTC).",
-       "filename": "Triemnamme",
+       "uploadlogpagetext": "Hjirûnder stiet in list fan 'e meast resint opladen bestannen.\nSjoch de [[Special:NewFiles|galery mei nije bestannen]] foar in fisueler oersjoch.",
+       "filename": "Bestânsnamme",
        "filedesc": "Omskriuwing",
        "fileuploadsummary": "Gearfetting:",
-       "filereuploadsummary": "Triemferoarings:",
+       "filereuploadsummary": "Bestânsferoarings:",
        "filestatus": "Auteursrjochtensituaasje:",
        "filesource": "Boarne:",
-       "ignorewarning": "Negearje de warskôging en lis triem dochs fêst.",
+       "ignorewarning": "Negearje de warskôging en lis bestân dochs fêst.",
        "ignorewarnings": "Negearje warskôgings",
-       "minlength1": "Triemnammen moatte minstens út ien teken bestean.",
-       "illegalfilename": "De triemnamme \"$1\" befettet ûnjildige tekens.\nJou de triem in oare namme en besykje him dan op'e nij heech te laden.",
+       "minlength1": "Bestânsnammen moatte minstens út ien teken bestean.",
+       "illegalfilename": "De bestânsnamme \"$1\" befettet ûnjildige tekens.\nJou it bestân in oare namme en besykje him dan op 'e nij heech te laden.",
        "badfilename": "De ôfbyldnamme is feroare nei \"$1\".",
-       "filetype-badmime": "Triemmen fan it MIME type \"$1\" meie net heechladen wurde.",
-       "filetype-bad-ie-mime": "Dizze triem kin net tafoege wurde, om't Internet Explorer dy idintifisearje soe as \"$1\", in net talitten triemtype dat potinsjeel skealik is.",
-       "filetype-unwanted-type": "'''\".$1\"''' is in net winske triem-type.\n{{PLURAL:$3|Oanwiisd triem-type is|Oanwiisde triem-typen binne}} $2.",
-       "filetype-banned-type": "'''\".$1\"''' is gjin talitten triem-type.\n{{PLURAL:$3|Talitten triem-type is|Talittene triem-typen binne}} $2.",
-       "filetype-missing": "De triem hat gjin taheaksel (lykas \".jpg\").",
-       "large-file": "Oanbefelling: meitsje triemmen net grutter as $1; dizze triem is $2.",
-       "largefileserver": "De triem is grutter as dat de ynstelling fan de server talit.",
-       "emptyfile": "De triem dy jo heechladen hawwe liket leech te wêzen.\nDat soe komme kinne fan in typflater yn 'e triemnamme.\nGean nei oft jo dizze triem wier bedoelden heech te laden.",
-       "fileexists": "Der bestiet al in triem mei dizze namme.\nKontrolearje <strong>[[:$1]]</strong> as jo net wis binne oft jo de besteande triem oerskriuwe wolle.\n[[$1|thumb]]",
-       "filepageexists": "De beskriuwingsside foar dizze triem bestiet al op <strong>[[:$1]]</strong>, mar der bestiet gjin triem mei dizze namme.\nDe gearfetting dy't jo opjûn hawwe sil net op 'e beskriuwingsside ferskine.\nBewurkje de side mei de hân om de beskriuwing dêr wer te jaan.",
-       "fileexists-extension": "In triem mei deselde namme bestiet al: [[$2|thumb]]\n* Namme fan 'e heechladene triem: <strong>[[:$1]]</strong>\n* Namme fan 'e besteande triem: <strong>[[:$2]]</strong>\nKies in oare namme.",
-       "fileexists-thumbnail-yes": "De triem liket in ferlytse ferzje te wêzen ''(miniatuerôfbylding)''. [[$1|thumb]]\nKontrolearje de triem <strong>[[:$1]]</strong>.\nAs de kontrolearre triem deselde ôfbylding fan deselde grutte is, dan hoecht net in ekstra miniatuerôfbylding oanbean te wurden.",
-       "file-thumbnail-no": "De triemnamme begjint mei <strong>$1</strong>.\nIt liket in ferlytse ôfbylding te wêzen ''(miniatuerôfbylding)''.\nAs jo dy ôfbylding yn folsleine resolúsje hawwe, bied him dan oan.\nFeroarje oars de triemnamme.",
-       "fileexists-forbidden": "Der bestiet al in triem mei dizze namme.\nBied jo triem ûnder in oare namme oan.\n[[File:$1|thumb|center|$1]]",
-       "fileexists-shared-forbidden": "Der bestiet al in triem mei dizze namme by de dielde triemmen.\nAs jo de triem dochs noch oanbiede wolle, gean dan werom en kies in oare namme.\n[[File:$1|thumb|center|$1]]",
-       "file-exists-duplicate": "Dizze triem is idintyk oan {{PLURAL:$1|de folgjende triem|de folgjende triemmen}}:",
-       "file-deleted-duplicate": "In triem idintyk oan dizze triem ([[:$1]]) is foarhinne fuorthelle.\nRieplachtsje it fuorthel-logboek foar't jo fierder geane.",
+       "filetype-badmime": "Bestannen fan it MIME type \"$1\" meie net heechladen wurde.",
+       "filetype-bad-ie-mime": "Dit bestân kin net tafoege wurde, om't Internet Explorer dy idintifisearje soe as \"$1\", in net talitten bestânstype dat potinsjeel skealik is.",
+       "filetype-unwanted-type": "'''\".$1\"''' is in net winske bestânstype.\n{{PLURAL:$3|Oanwiisd bestânstype is|Oanwiisde bestânstypen binne}} $2.",
+       "filetype-banned-type": "<strong>\".$1\"</strong> {{PLURAL:$4|is gjin talitten bestânstype|binne gjin talitten bestânstypen}}.\nTalitten {{PLURAL:$3|bestânstype is|bestânstypen binne}} $2.",
+       "filetype-missing": "It bestân hat gjin taheaksel (lykas \".jpg\").",
+       "large-file": "Oanbefelling: meitsje bestannen net grutter as $1; dit bestân is $2.",
+       "largefileserver": "It bestân is grutter as dat de ynstelling fan de server talit.",
+       "emptyfile": "It bestân dat jo heechladen hawwe liket leech te wêzen.\nDat soe komme kinne fan in typflater yn 'e bestânsnamme.\nGean nei oft jo dit bestân wier bedoelden heech te laden.",
+       "fileexists": "In bestân mei dizze namme bestiet al; kontrolearje <strong>[[:$1]]</strong> at {{GENDER:|jo}} net wis binne oft jo it ferfange wolle.\n[[$1|thumb]]",
+       "filepageexists": "De beskriuwingsside foar dit bestân bestiet al op <strong>[[:$1]]</strong>, mar der bestiet gjin bestân mei dizze namme.\nDe gearfetting dy't jo opjûn hawwe sil net op 'e beskriuwingsside ferskine.\nBewurkje de side mei de hân om de beskriuwing dêr wer te jaan.",
+       "fileexists-extension": "In bestân mei in soartgelikense namme bestiet al: [[$2|thumb]]\n* Namme fan it opladen bestân: <strong>[[:$1]]</strong>\n* Namme fan it besteande bestân: <strong>[[:$2]]</strong>\nBrûk a.j.w. in wat oare namme.",
+       "fileexists-thumbnail-yes": "It bestân liket in ferlytse ferzje te wêzen ''(miniatuerôfbylding)''. [[$1|thumb]]\nKontrolearje it bestân <strong>[[:$1]]</strong>.\nAs it kontrolearre bestân deselde ôfbylding fan deselde grutte is, dan hoecht net in ekstra miniatuerôfbylding oanbean te wurden.",
+       "file-thumbnail-no": "De bestânsnamme begjint mei <strong>$1</strong>.\nIt liket in ferlytse ôfbylding te wêzen ''(miniatuerôfbylding)''.\nAs jo dy ôfbylding yn folsleine resolúsje hawwe, bied him dan oan.\nFeroarje oars de bestânsnamme.",
+       "fileexists-forbidden": "In bestân mei dizze namme bestiet al, en kin net oerskreaun wurde.\nAt jo jo bestân noch oplade wolle, gean dan werom en brûk in nije namme.\n[[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "Der bestiet al in bestân mei dizze namme by de dielde bestannen.\nAs jo it bestân dochs noch oanbiede wolle, gean dan werom en kies in oare namme.\n[[File:$1|thumb|center|$1]]",
+       "file-exists-duplicate": "Dit bestân is idintyk oan {{PLURAL:$1|it folgjende bestân|de folgjende bestannen}}:",
+       "file-deleted-duplicate": "In bestân idintyk oan dit bestân ([[:$1]]) is foarhinne fuorthelle.\nRieplachtsje it fuorthel-logboek foar't jo fierder geane.",
        "uploadwarning": "Oanbied-warskôging",
-       "savefile": "Lis triem fêst",
+       "savefile": "Lis bestân fêst",
        "uploaddisabled": "Sorry, op dizze tsjinner kin net oanbean wurde.",
-       "uploaddisabledtext": "It oanbieden fan triemmen is útskeakele.",
-       "php-uploaddisabledtext": "PHP-triemuploads binne útskeakele.\nKontrolearje de ynstelling \"file_uploads\".",
-       "uploadscripted": "Dizze triem befettet HTML- of scriptkoade dy't ferkeard troch jo browser werjûn wurde kin.",
-       "uploadvirus": "De triem befettet in firus! Details: $1",
-       "upload-source": "Boarnetriem",
-       "sourcefilename": "Triemnamme boarne:",
+       "uploaddisabledtext": "It oanbieden fan bestannen is útskeakele.",
+       "php-uploaddisabledtext": "PHP-bestânsuploads binne útskeakele.\nKontrolearje de ynstelling \"file_uploads\".",
+       "uploadscripted": "Dit bestân befettet HTML- of scriptkoade dy't ferkeard troch jo browser werjûn wurde kin.",
+       "uploadvirus": "It bestân befettet in firus! Details: $1",
+       "upload-source": "Boarnebestân",
+       "sourcefilename": "Bestânsnamme boarne:",
        "sourceurl": "Boarne-URL:",
-       "destfilename": "Triemnamme om op te slaan:",
-       "upload-maxfilesize": "Maksimale triemgrutte: $1",
-       "upload-description": "Triembeskriuwing",
-       "upload-options": "Uploadynstellingen",
-       "watchthisupload": "Folgje dizze triem",
-       "filewasdeleted": "Der is earder in triem mei dizze namme fuorthelle.\nRieplachtsje it $1 foar't jo him op'e nij tafoegje.",
-       "filename-bad-prefix": "De namme fan de triem dy't jo oanbiede begjint mei '''\"$1\"''', dit wiist op in namme dy't automatysk troch in digitale kamera oanmakke wurdt. Feroarje de namme as jo wolle yn ien dy't in omskriuwing jout fan de triem.",
-       "filename-prefix-blacklist": " #<!-- lit dizze line exakt sa't er is --> <pre>\n# Syntax is as folget:\n#   * Alles fan in \"#\"-teken oan't de ein fan de line is in kommintaar\n#   * Elke net blanke line is a foarheaksel foar triemnammen sa't dy automatysk jûn wurde troch digitale kamera's\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # guon mobile tillefoanen\nIMG # algemien\nJD # Jenoptik\nMGP # Pentax\nPICT # ferskaat\n #</pre> <!-- lit dizze line exakt sa't er is -->",
+       "destfilename": "Bestânsnamme om op te slaan:",
+       "upload-maxfilesize": "Maksimale bestânsgrutte: $1",
+       "upload-description": "Bestânsbeskriuwing",
+       "upload-options": "Oplaadynstellingen",
+       "watchthisupload": "Folgje dit bestân",
+       "filewasdeleted": "Der is earder in bestân mei dizze namme fuorthelle.\nRieplachtsje it $1 foar't jo him op'e nij tafoegje.",
+       "filename-bad-prefix": "De namme fan it bestân dat jo oanbiede begjint mei '''\"$1\"''', dit wiist op in namme dy't automatysk troch in digitale kamera oanmakke wurdt. Feroarje de namme as jo wolle yn ien dy't in omskriuwing jout fan it bestân.",
+       "filename-prefix-blacklist": " #<!-- lit dizze line exakt sa't er is --> <pre>\n# Syntax is as folget:\n#   * Alles fan in \"#\"-teken oan't de ein fan de line is in kommintaar\n#   * Elke net blanke line is a foarheaksel foar bestânsnammen sa't dy automatysk jûn wurde troch digitale kamera's\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # guon mobile tillefoanen\nIMG # algemien\nJD # Jenoptik\nMGP # Pentax\nPICT # ferskaat\n #</pre> <!-- lit dizze line exakt sa't er is -->",
        "upload-proto-error": "Ferkeard protokol",
        "upload-proto-error-text": "Oanbieden mei dizze metoade freget URL's dy't begjinne mei <code>http://</code> of <code>ftp://</code>.",
        "upload-file-error": "Ynterne fout",
-       "upload-file-error-text": "Der wie in ynterne fout doe't in tydlike triem op'e server oanmakke waard.\nNim kontakt op mei in [[Special:ListUsers/sysop|behearder]].",
+       "upload-file-error-text": "Der wie in ynterne fout doe't in tydlik bestân op 'e server oanmakke waard.\nNim kontakt op mei in [[Special:ListUsers/sysop|behearder]].",
        "upload-misc-error": "Unbekende oanbiedflater",
        "upload-misc-error-text": "Der is by it oanbieden in ûnbekende fout optreden.\nKontrolearje of de URL krekt en beskikber is en besykje it nochris.\nAs it probleem oanhâldt, nim dan kontakt op mei in\n[[Special:ListUsers/sysop|behearder]].",
        "upload-dialog-button-done": "Klear",
        "license": "Lisinsje:",
        "license-header": "Lisinsje",
        "nolicense": "Neat keazen",
+       "licenses-edit": "Lisinsje-opsjes bewurkje",
        "license-nopreview": "(Foarfertoaning net beskikber)",
-       "upload_source_url": " (in jildige, publyk tagonklike URL)",
-       "upload_source_file": " (in triem op jo kompjûter)",
+       "upload_source_url": "(it útkeazen bestân op in jildige, publyk tagonklike URL)",
+       "upload_source_file": "(it útkeazen bestân op jo kompjûter)",
        "listfiles-delete": "fuortsmite",
-       "listfiles-summary": "Op dizze spesjale side binne alle tafoege triemmen te besjen.\nStandert wurde de lêst tafoege triemmen boppe oan de list werjûn.\nKlikken op in kolomkop feroaret de sortearring.",
-       "listfiles_search_for": "Sykje nei triem:",
-       "imgfile": "triem",
-       "listfiles": "Triemlist",
+       "listfiles-summary": "Op dizze bysûndere side binne alle opladen bestannen te sjen.",
+       "listfiles_search_for": "Sykje nei bestân:",
+       "imgfile": "bestân",
+       "listfiles": "Bestânslist",
        "listfiles_thumb": "Miniatuerôfbylding",
        "listfiles_date": "Datum",
        "listfiles_name": "Namme",
        "listfiles_count": "Ferzjes",
        "listfiles-latestversion-yes": "Ja",
        "listfiles-latestversion-no": "Nee",
-       "file-anchor-link": "Triem",
-       "filehist": "Triem skiednis",
-       "filehist-help": "Klik op in tiid om de ferzje fan de triem op dat stuit te sjen.",
+       "file-anchor-link": "Bestân",
+       "filehist": "Bestânsskiednis",
+       "filehist-help": "Klik op in datum/tiid, en besjoch it bestân sa't it op dat stuit wie.",
        "filehist-deleteall": "wiskje alles",
        "filehist-deleteone": "fuortsmite",
        "filehist-revert": "werom sette",
        "filehist-current": "lêste",
-       "filehist-datetime": "Tiid",
-       "filehist-thumb": "Miniatuerôfbylding",
-       "filehist-thumbtext": "Miniatuerôfbylding foar ferzje fan $1 ôf",
+       "filehist-datetime": "Datum/tiid",
+       "filehist-thumb": "Miniatuer",
+       "filehist-thumbtext": "Miniatuer foar de ferzje sûnt $1",
        "filehist-nothumb": "Gjin miniatuerôfbylding",
        "filehist-user": "Meidogger",
        "filehist-dimensions": "Ofmjittings",
-       "filehist-filesize": "Triemgrutte",
+       "filehist-filesize": "Bestânsgrutte",
        "filehist-comment": "Opmerkings",
-       "imagelinks": "Ofbyldkeppelings",
+       "imagelinks": "Bestânsgebrûk",
        "linkstoimage": "Dizze {{PLURAL:$1|side is|$1 siden binne}} keppele oan it ôfbyld:",
-       "linkstoimage-more": "Der {{PLURAL:$2|is|binne}} mear as $1 {{PLURAL:$1|ferwizing|ferwizings}} nei dizze triem.\nDe folgjende list jout allinne de earste {{PLURAL:$1|ferwizing|$1 ferwizings}} nei dizze triem wer.\nDer is ek in [[Special:WhatLinksHere/$2|folsleine list]].",
+       "linkstoimage-more": "Der {{PLURAL:$2|is|binne}} mear as $1 {{PLURAL:$1|ferwizing|ferwizings}} nei dit bestân.\nDe folgjende list jout allinne de earste {{PLURAL:$1|ferwizing|$1 ferwizings}} nei dit bestân wer.\nDer is ek in [[Special:WhatLinksHere/$2|folsleine list]].",
        "nolinkstoimage": "Der binne gjin siden oan dit ôfbyld keppele.",
-       "morelinkstoimage": "[[Special:WhatLinksHere/$1|Mear ferwizings]] nei dizze triem besjen.",
-       "duplicatesoffile": "{{PLURAL:$1|De folgjende triem is|De folgjende $1 triemmen binne}} idintyk oan dizze triem:",
-       "sharedupload": "Dizze triem is in dielde oanbieding en kin ek troch oare projekten brûkt wurde.",
-       "filepage-nofile": "Der bestiet gjin triem mei sa'n namme.",
-       "filepage-nofile-link": "Der bestiet gjin triem mei sa'n namme [bied $1 oan].",
-       "uploadnewversion-linktext": "Bied in nije ferzje fan dizze triem oan",
+       "morelinkstoimage": "[[Special:WhatLinksHere/$1|Mear ferwizings]] nei dit bestân besjen.",
+       "duplicatesoffile": "{{PLURAL:$1|It|De}} neikommend{{PLURAL:$1|&#32;bestân is|e $1 bestannen binne}} identyk oan dit bestân ([[Special:FileDuplicateSearch/$2|mear bysûnderheden]]):",
+       "sharedupload": "Dit bestân komt fan $1, en kin ek troch oare projekten brûkt wurde.",
+       "sharedupload-desc-here": "Dit bestân komt fan $1, en kin ek troch oare projekten brûkt wurde.\nDe beskriuwing op syn [$2 bestânsside] dêre wurdt hjirûnder werjûn.",
+       "filepage-nofile": "Der bestiet gjin bestân mei sa'n namme.",
+       "filepage-nofile-link": "Der bestiet gjin bestân mei sa'n namme [bied $1 oan].",
+       "uploadnewversion-linktext": "Bied in nije ferzje fan dit bestân oan",
        "shared-repo-from": "fan $1",
        "filerevert": "$1 weromsette",
-       "filerevert-legend": "Triem weromsette",
+       "filerevert-legend": "Bestân weromsette",
        "filerevert-intro": "Jo binne '''[[Media:$1|$1]]''' oan it weromdraaien ta de [$4 ferzje op $2, $3].",
        "filerevert-comment": "Reden:",
        "filerevert-defaultcomment": "Weromdraaid ta de ferzje op $1, $2 ($3)",
        "filerevert-submit": "werom sette",
        "filerevert-success": "<strong>[[Media:$1|$1]]</strong> is weromdraaid ta de [$4 ferzje op $2, $3].",
-       "filerevert-badversion": "Der is gjin foarige lokale ferzje fan dizze triem fan 'e opjûne tiid.",
+       "filerevert-badversion": "Der is gjin foarige lokale ferzje fan dit bestân fan 'e opjûne tiid.",
        "filedelete": "Wiskje $1",
-       "filedelete-legend": "Wiskje triem",
+       "filedelete-legend": "Wiskje bestân",
        "filedelete-intro": "Jo wiskje '''[[Media:$1|$1]]'''.",
        "filedelete-intro-old": "Jo wiskje de ferzje fan '''[[Media:$1|$1]]''' fan [$4 $3, $2].",
        "filedelete-comment": "Reden:",
        "filedelete-nofile-old": "Der is gjin opsleine ferzje fan '''$1''' mei de oanjûne eigenskippen.",
        "filedelete-otherreason": "Oare/eventuele reden:",
        "filedelete-reason-otherlist": "Oare reden",
-       "filedelete-reason-dropdown": "*Faak foarkommende redenen foar fuortheljen\n** Skeinen fan auteursrjochten\n** Duplikaattriem",
+       "filedelete-reason-dropdown": "*Faak foarkommende redenen foar fuortheljen\n** Skeinen fan auteursrjochten\n** Duplikaatbestân",
        "filedelete-edit-reasonlist": "Redenen foar fuortheljen bewurkje",
        "mimesearch": "Sykje op MIME-type",
-       "mimesearch-summary": "Dizze side makket it filterjen mûglik fan triemmen foar it MIME-type.\nYnfier: contenttype/subtype, bygelyks <code>image/jpeg</code>.",
+       "mimesearch-summary": "Op dizze side kinne bestannen op har MIME-type filtere wurde.\nYnfier: ynhâldstype/subtype as ynhâldstype/*, bgl. <code>image/jpeg</code>.",
        "mimetype": "MIME-type:",
        "download": "oanbiede",
        "unwatchedpages": "Siden dy't net op in folchlist steane",
        "randompage-nopages": "Der binne gjin siden yn'e nammeromte \"$1\".",
        "randomincategory-category": "Kategory:",
        "randomredirect": "Samar in trochferwizing",
-       "randomredirect-nopages": "Der binne gjin trochferwizings yn'e nammerûmte \"$1\".",
+       "randomredirect-nopages": "Der binne gjin trochferwizings yn'e nammeromte \"$1\".",
        "statistics": "Statistyk",
        "statistics-header-pages": "Sidestatistiken",
        "statistics-header-edits": "Bewurkingsstatistiken",
        "statistics-articles": "Ynhâldlike siden",
        "statistics-pages": "Siden",
        "statistics-pages-desc": "Alle siden yn 'e wiki, ynbegrepen oerlissiden, trochferwizings ens.",
-       "statistics-files": "Triemmen",
+       "statistics-files": "Bestannen",
        "statistics-edits": "Sidebewurkings sûnt it begjin fan {{SITENAME}}",
        "statistics-edits-average": "Trochstrings tal bewurkings per side",
-       "statistics-users": "Registrearre brûkers",
-       "statistics-users-active": "Aktive brûkers",
-       "statistics-users-active-desc": "Brûkers dy't yn 'e ôfrûne {{PLURAL:$1|dei|$1 dagen}} in hanneling útfierd hawwe",
+       "statistics-users": "Registrearre meidoggers",
+       "statistics-users-active": "Aktive meidoggers",
+       "statistics-users-active-desc": "Meidoggers dy't yn 'e ôfrûne {{PLURAL:$1|dei|$1 dagen}} in hanneling útfierd hawwe",
        "pageswithprop-prop": "Eigenskipnamme:",
        "pageswithprop-submit": "OK",
        "doubleredirects": "Dûbelde synonimen",
        "unusedimages": "Lossteande ôfbylden",
        "wantedcategories": "Nedige kategoryen",
        "wantedpages": "Nedige siden",
-       "wantedfiles": "Net-besteande triemmen mei ferwizings",
+       "wantedfiles": "Net-besteande bestannen mei ferwizings",
        "wantedtemplates": "Net besteande sjabloanen mei ferwizings",
        "mostlinked": "Siden wêr it meast mei keppele is",
        "mostlinkedcategories": "Kategoryen dy't it meast brûkt wurde",
        "protectedpages-unknown-timestamp": "Unbekend",
        "protectedtitles": "Skoattele titels",
        "protectedtitlesempty": "Der binne op it stuit gjin sidenammen befeilige, dy't oan dizze betingsten foldogge.",
-       "listusers": "Meidoggerlist",
-       "listusers-editsonly": "Allinne brûkers mei bewurkings werjaan",
+       "listusers": "Meidoggerslist",
+       "listusers-editsonly": "Allinne meidoggers mei bewurkings werjaan",
        "listusers-creationsort": "Oarderje op dei fan oanmeitsjen",
        "usereditcount": "$1 {{PLURAL:$1|bewurking|bewurkings}}",
        "newpages": "Nije siden",
-       "newpages-username": "Brûkersnamme:",
+       "newpages-username": "Meidochnamme:",
        "ancientpages": "Aldste siden",
        "move": "Omneame",
        "movethispage": "Dizze side omneame",
        "notargettext": "Jo hawwe net sein oer hokfoar side jo dit witte wolle.",
        "nopagetitle": "Side bestiet net",
        "nopagetext": "De side dy't jo in oare namme jaan wolle bestiet net.",
-       "pager-newer-n": "{{PLURAL:$1|nijere 1|nijere $1}}",
+       "pager-newer-n": "{{PLURAL:$1|1 nijer|$1 nijer}}",
        "pager-older-n": "{{PLURAL:$1|1 âlder|$1 âlder}}",
        "suppress": "Tafersjoch",
        "apihelp": "API-help",
        "booksources-search": "Sykje",
        "booksources-text": "Hjirûnder is in list mei keppelings nei oare websites dy't nije of brûkte boeken ferkeapje en dy't faaks mear ynformaasje hawwe oer it boek dat jo sykje:",
        "booksources-invalid-isbn": "It ynjûne ISBN liket net jildich te wêzen.\nKontrolearje oft jo faaks in flater makke hawwe by de ynfier.",
-       "specialloguserlabel": "Útfierende meidogger:",
-       "speciallogtitlelabel": "Doel (titel of brûker):",
+       "specialloguserlabel": "Utfierder:",
+       "speciallogtitlelabel": "Doel (sidetitel of {{ns:user}}:meidochnamme foar meidogger):",
        "log": "Lochs",
        "all-logs-page": "Alle iepenbiere lochboeken",
-       "alllogstext": "Dit is it kombinearre logboek fan {{SITENAME}}.\nJo kinne ek kieze foar spesifike logboeken en filterje op brûker (haadstêfgefoelich) en sidenamme  (haadstêfgefoelich).",
+       "alllogstext": "Gearfoege werjefte fan alle beskikbere lochs op {{SITENAME}}.\nJo kinne it byld beheine troch it kiezen fan in lochtype, de meidochnamme (haadlettergefoelich) of de oanbelangjende side (ek haadlettergefoelich).",
        "logempty": "Gjin treffers yn it loch.",
        "log-title-wildcard": "Siden sykje dy't mei dizze namme begjinne",
        "allpages": "Alle siden",
        "allpagessubmit": "Los!",
        "allpagesprefix": "Siden sjen litte dy't begjinne mei:",
        "allpagesbadtitle": "De opjûne sidenamme is ûnjildich of hat in yntertaal- of ynterwikifoarheaksel.\nMûglik befettet de namme karakters dy't net brûkt wurde meie yn sidenammen.",
-       "allpages-bad-ns": "{{SITENAME}} hat gjin nammerûmte \"$1\".",
+       "allpages-bad-ns": "{{SITENAME}} hat gjin nammeromte \"$1\".",
        "categories": "Kategoryen",
-       "categoriespagetext": "De folgjende kategoriyen befetsje siden of mediatriemmen.\n[[Special:UnusedCategories|Net brûkte kategoryen]] wurde hjir net werjûn.\nSjuch ek [[Special:WantedCategories|net-besteande kategoryen mei ferwizings]].",
+       "categoriespagetext": "De folgjende {{PLURAL:$1|kategory bestiet|kategoryen bestean}} op 'e wiki, en {{PLURAL:$1|is|binne}} al of net brûkt.\nSjoch ek [[Special:WantedCategories|Net-besteande kategoryen mei ferwizings]].",
        "categoriesfrom": "Kategoryen werjaan fan .. ôf:",
        "deletedcontributions": "Wiske meidogger bydragen",
        "deletedcontributions-title": "Wiske meidogger bydragen",
        "linksearch-error": "Wildcards binne allinne tastien oan it begjin fan in hostnamme.",
        "listusersfrom": "Lit meidoggers sjen fanôf:",
        "listusers-submit": "Sjen litte",
-       "listusers-noresult": "Gjin brûker fûn.",
+       "listusers-noresult": "Gjin meidogger fûn.",
        "listusers-blocked": "(blokkearre)",
        "activeusers": "Aktive meidoggers",
        "activeusers-count": "$1 {{PLURAL:$1|aksje|aksjes}} yn de lêste {{PLURAL:$3|dei|$3 dagen}}",
        "activeusers-noresult": "Gjin meidoggers fûn.",
-       "listgrouprights": "Rjochten fan brûkersgroepen",
-       "listgrouprights-summary": "Op dizze side steane de brûkersgroepen yn dizze wiki beskreaun, mei har derby hearrende rjochten.\nDer kin [[{{MediaWiki:Listgrouprights-helppage}}|ekstra ynformaasje]] oer yndividuele rjochten oanwêzich wêze.",
+       "listgrouprights": "Rjochten fan meidoggersgroepen",
+       "listgrouprights-summary": "Op dizze side steane de meidoggersgroepen yn dizze wiki beskreaun, mei har derby hearrende rjochten.\nDer kin [[{{MediaWiki:Listgrouprights-helppage}}|ekstra ynformaasje]] oer yndividuele rjochten oanwêzich wêze.",
        "listgrouprights-group": "Groep",
        "listgrouprights-rights": "Rjochten",
-       "listgrouprights-helppage": "Help:Brûkersrjochten",
+       "listgrouprights-helppage": "Help:Meidoggersrjochten",
        "listgrouprights-members": "(ledelist)",
-       "listgrouprights-addgroup": "Kin brûkers oan dizze {{PLURAL:$2|groep|groepen}} tafoegje: $1",
-       "listgrouprights-removegroup": "Kin brûkers út dizze {{PLURAL:$2|groep|groepen}} fuorthelje: $1",
-       "listgrouprights-addgroup-all": "Kin brûkers oan alle groepen tafoegje",
-       "listgrouprights-removegroup-all": "Kin brûkers út alle groepen fuorthelje",
+       "listgrouprights-addgroup": "Kin meidoggers oan dizze {{PLURAL:$2|groep|groepen}} tafoegje: $1",
+       "listgrouprights-removegroup": "Kin meidoggers út dizze {{PLURAL:$2|groep|groepen}} fuorthelje: $1",
+       "listgrouprights-addgroup-all": "Kin meidoggers oan alle groepen tafoegje",
+       "listgrouprights-removegroup-all": "Kin meidoggers út alle groepen fuorthelje",
        "listgrouprights-namespaceprotection-namespace": "Nammeromte",
        "trackingcategories-name": "Berjochtnamme",
        "mailnologin": "Gjin adres beskikber",
        "mailnologintext": "Jo moatte [[Special:UserLogin|oanmelden]] wêze, en in jildich e-postadres [[Special:Preferences|ynsteld]] hawwe, om oan oare meidoggers e-post stjoere te kinnen.",
        "emailuser": "E-mail dizze meidogger",
        "emailuser-title-notarget": "E-mail nei meidogger",
-       "emailpagetext": "Fia dit berjocht kinne jo in e-mail oan dizze brûker ferstjoere.\nIt e-mailadres dat jo opjûn hawwe by [[Special:Preferences|jo foarkarren]] wurdt as ôfstjoerder  brûkt.\nDe ûntfanger kin dus daliks nei jo reagearje.",
-       "defemailsubject": "E-mail fan {{SITENAME}}-brûker \"$1\"",
+       "emailpagetext": "Jo kinne it formulier hjirûnder brûke om in e-mailberjocht nei dizze {{GENDER:$1|meidogger|meidochster}} te stjoeren.\nIt e-mailadres opjûn yn [[Special:Preferences|jo ynstellings]] wurdt sichtber as it 'Fan'-adres yn de e-mail, dat de ûntfanger jo streekrjocht antwurdzje kin.",
+       "defemailsubject": "E-mail fan {{SITENAME}}-meidogger \"$1\"",
        "noemailtitle": "Gjin e-postadres",
-       "noemailtext": "Dizze meidogger hat gjin jildich e-postadres ynsteld, of hat oanjûn gjin post fan oare meidoggers krije te wollen.",
-       "nowikiemailtext": "Dizze brûker wol gjin e-mail ûntfange fan oare brûkers.",
-       "emailusername": "Brûkersnamme:",
+       "noemailtext": "Dizze meidogger hat gjin jildich e-mailadres opjûn.",
+       "nowikiemailtext": "Dizze meidogger wol gjin e-mail ûntfange fan oare meidoggers.",
+       "emailusername": "Meidochnamme:",
        "emailusernamesubmit": "Ferstjoere",
-       "email-legend": "In e-mail ferstjoere nei in oare brûker fan {{SITENAME}}",
+       "email-legend": "In e-mail ferstjoere nei in oare meidogger fan {{SITENAME}}",
        "emailfrom": "Fan:",
        "emailto": "Oan:",
        "emailsubject": "Ûnderwerp:",
        "mywatchlist": "Folchlist",
        "watchlistfor2": "Foar $1 $2",
        "nowatchlist": "Jo hawwe gjin siden op jo folchlist.",
+       "watchlistanontext": "Jo moatte $1 om siden op jo folchlist besjen of bewurkje te kinnen.",
        "watchnologin": "Net oanmeld yn",
        "addwatch": "Oan folchlist tafoegje",
        "addedwatchtext": "\"[[:$1]]\" en de bybehearrende oerlisside binne tafoege oan jo [[Special:Watchlist|folchlist]].",
        "removedwatchtext": "De side \"[[:$1]]\" stiet net mear op jo folchlist.",
        "watch": "Folgje",
        "watchthispage": "Folgje dizze side",
-       "unwatch": "Ferjit",
+       "unwatch": "Net folgje",
        "unwatchthispage": "Ferjit dizze side",
        "notanarticle": "Dit kin net folge wurde.",
        "watchlist-details": "Jo folchlist hat {{PLURAL:$1|$1 side|$1 siden}}, oerlissiden net meiteld.",
        "deleteotherreason": "Oare/eventuele reden:",
        "deletereasonotherlist": "Oare reden",
        "deletereason-dropdown": "*Faak-brûkte redenen\n** Frege troch de skriuwer\n** Skeining fan auteursrjocht\n** Fandalisme",
-       "rollback": "Feroarings werom sette",
-       "rollbacklink": "feroaring werom sette",
-       "rollbackfailed": "Feroaring werom sette net slagge",
+       "rollback": "Wizigings weromdraaie",
+       "rollback-confirmation-yes": "Weromdraaie",
+       "rollbacklink": "weromdraaie",
+       "rollbacklinkcount": "$1 {{PLURAL:$1|bewurking|bewurkings}} weromdraaie",
+       "rollbacklinkcount-morethan": "mear as $1 {{PLURAL:$1|bewurking|bewurkings}} weromdraaie",
+       "rollbackfailed": "Weromdraaien fan wizigings net slagge.",
        "cantrollback": "Dizze feroaring kin net werom setten wurde, om't der mar ien skriuwer is.",
-       "alreadyrolled": "Kin de feroaring fan [[:$1]] troch [[User:$2|$2]] ([[User talk:$2|oerlis]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) net werom sette;\nin oar hat de feroaring werom set, of oars wat oan de side feroare.\n\nDe lêste feroaring wie fan [[User:$3|$3]] ([[User talk:$3|oerlis]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
+       "alreadyrolled": "Kin de wiziging fan [[:$1]] troch [[User:$2|$2]] ([[User talk:$2|oerlis]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) net weromdraaie;\nin oar hat de wiziging weromdraaid, of oars wat oan de side feroare.\n\nDe lêste wiziging wie fan [[User:$3|$3]] ([[User talk:$3|oerlis]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "De gearfetting wie: <em>$1</em>.",
-       "revertpage": "Bewurkings fan [[Special:Contributions/$2|$2]] ([[User talk:$2|Oerlis]]) werom set ta de ferzje fan [[User:$1|$1]]",
-       "rollback-success": "Feroarings werom set fan $1; werom set nei de lêste ferzje fan $2.",
+       "revertpage": "Bewurkings fan [[Special:Contributions/$2|$2]] ([[User talk:$2|oerlis]]) weromset ta de lêste ferzje fan [[User:$1|$1]]",
+       "rollback-success": "Wizigings fan {{GENDER:$3|$1}} weromdraaid;\nde lêste ferzje fan {{GENDER:$4|$2}} weromset.",
        "protectlogpage": "Skoattelloch",
        "protectlogtext": "Hjirûnder wurdt it skoateljen en frijjaan fan siden oanjûn.\nSjoch [[Special:ProtectedPages|Skoattele side]] foar mear ynformaasje.",
        "protectedarticle": "\"[[$1]]\" skoattele",
        "protect-text": "Hjir kin jo it nivo fan skoatteljen sjen en oanpasse foar de side '''$1'''.",
        "protect-locked-blocked": "Jo kinne it befeiligingsnivo net feroarje wylst jo blokkearre binne.\nHjir binne de hjoeddeiske ynstellingen foar de side '''$1''':",
        "protect-locked-dblock": "It befeiligingsnivo kin net feroare wurde om't de database sletten is.\nHjir binne de hjoeddeiske ynstellingen foar de side '''$1''':",
-       "protect-locked-access": "'''Jo brûker hat gjin rjochten om it befeiligingsnivo te feroarjen.'''\nDit binne de rinnende ynstellingen foar de side '''$1''':",
+       "protect-locked-access": "'''Jo akkount hat gjin rjochten om it befeiligingsnivo te feroarjen.'''\nDit binne de rinnende ynstellingen foar de side '''$1''':",
        "protect-cascadeon": "Dizze side is op 't stuit befeilige, om't er yn 'e folgjende {{PLURAL:$1|side|siden}} opnommen is, dy't befeilige {{PLURAL:$1|is|binne}} mei de kaskade-opsje. It befeiligingsnivo feroarje hat alhiel gjin effekt.",
-       "protect-default": "Tastean foar alle brûkers",
+       "protect-default": "Tastean foar alle meidoggers",
        "protect-fallback": "Hjir is it rjocht \"$1\" foar nedich",
        "protect-level-autoconfirmed": "Slút anonymen út",
        "protect-level-sysop": "Allinnich behearders",
        "namespace": "Nammeromte:",
        "invert": "Seleksje útsein",
        "blanknamespace": "(Haad)",
-       "contributions": "{{GENDER:$1|Meidogger}}-bydragen",
+       "contributions": "Bydragen fan 'e {{GENDER:$1|meidogger|meidochster}}",
        "contributions-title": "Bydragen fan $1",
        "mycontris": "Bydragen",
        "anoncontribs": "Bydragen",
        "uctop": "lêste feroaring",
        "month": "Fan moanne (en earder):",
        "year": "Fan jier (en earder):",
-       "sp-contributions-newbies": "Allinne bydragen fan nije brûkers besjen",
+       "sp-contributions-newbies": "Allinne bydragen fan nije akkounts besjen",
        "sp-contributions-newbies-sub": "Foar nijlingen",
        "sp-contributions-newbies-title": "Bydragen fan nije meidoggers",
-       "sp-contributions-blocklog": "Blokkearlochboek",
-       "sp-contributions-deleted": "Wiske meidogger bydragen",
+       "sp-contributions-blocklog": "útslútloch",
+       "sp-contributions-deleted": "wiske {{GENDER:$1|meidogger}}bydragen",
+       "sp-contributions-uploads": "opladen",
+       "sp-contributions-logs": "lochs",
        "sp-contributions-talk": "oerlis",
-       "sp-contributions-userrights": "behear fan meidoggerrjochten",
+       "sp-contributions-userrights": "behear fan {{GENDER:$1|meidogger}}rjochten",
        "sp-contributions-search": "Sykje nei bydragen",
-       "sp-contributions-username": "IP Adres of meidoggernamme:",
+       "sp-contributions-username": "IP-adres of meidochnamme:",
        "sp-contributions-submit": "Sykje",
        "whatlinkshere": "Wat is hjirmei keppele?",
        "whatlinkshere-title": "Siden dy't keppele binne mei \"$1\"",
        "whatlinkshere-page": "Side:",
-       "linkshere": "Dizze siden binne keppele oan '''$2''':",
+       "linkshere": "De neikommende siden ferwize nei <strong>$2</strong>:",
        "nolinkshere": "Der binne gjin siden oan '''$2''' keppele.",
        "nolinkshere-ns": "Gjin siden yn de keazen nammeromte keppelje nei '''$2'''.",
        "isredirect": "synonym",
        "istemplate": "opnaam",
-       "isimage": "triemkeppeling",
-       "whatlinkshere-prev": "{{PLURAL:$1|foarige|foarige $1}}",
-       "whatlinkshere-next": "{{PLURAL:$1|folgjende|folgjende $1}}",
+       "isimage": "bestânskeppeling",
+       "whatlinkshere-prev": "{{PLURAL:$1|foargeande|$1 foargeand}}",
+       "whatlinkshere-next": "{{PLURAL:$1|neikommende|$1 neikommend}}",
        "whatlinkshere-links": "← keppelings",
        "whatlinkshere-hideredirs": "$1 trochferwizings",
        "whatlinkshere-hidetrans": "$1 trânsklúzjes",
        "whatlinkshere-filters": "Filters",
        "blockip": "Slút {{GENDER:$1|meidogger}} út",
        "blockiptext": "Brûk dizze fjilden om in beskaat IP-adres of meidochnamme fan skriuwtagong út te sluten.\nDat soe allinnich dien wurde moatte fanwegen fandalisme of oar ûnakseptabel hâlden en dragen, sa't de\n[[{{MediaWiki:Policy-url}}|útslút-rie]] it oanjout.\nMeld de krekte reden! Neam bygelyks de siden dy't oantaaste waarden.\nJo kinne IP-adresrigen útslute mei de syntaksis fan [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; de grutst tastiene rige is /$1 foar IPv4 en /$2 foar IPv6.",
-       "ipaddressorusername": "IP Adres of meidoggernamme:",
+       "ipaddressorusername": "IP-adres of meidochnamme:",
        "ipbreason": "Reden:",
-       "ipbreason-dropdown": "*Faak foarkommende redenen foar blokkades\n** Ferkearde ynformaasje ynfiere\n** Fuortheljen fan ynformaasje út siden\n** Spamferwizing nei eksterne websites\n** Ynfoegjen fan ûnsin yn siden\n** Yntimidearjend gedrach\n** Misbrûk troch meardere brûkers\n** Unakseptabele brûkersnamme",
+       "ipbreason-dropdown": "*Faak foarkommende redenen foar blokkades\n** Ferkearde ynformaasje ynfiere\n** Fuortheljen fan ynformaasje út siden\n** Spamferwizing nei eksterne websites\n** Ynfoegjen fan ûnsin yn siden\n** Yntimidearjend gedrach\n** Misbrûk troch meardere meidoggers\n** Unakseptabele meidochnamme",
        "ipbcreateaccount": "Blokkearje it oanmeitsjen fan in nij profyl",
        "ipbenableautoblock": "Automatysk de lêste IP adressen útslute dy't troch dizze meidogger brûkt binne.",
        "ipbsubmit": "Slút dizze meidogger út",
        "blocklist-reason": "Reden",
        "ipblocklist-submit": "Sykje",
        "infiniteblock": "trochgeand",
-       "blocklink": "slút út",
-       "unblocklink": "lit yn",
-       "change-blocklink": "blokkade feroarje",
+       "blocklink": "útslute",
+       "unblocklink": "ynlitte",
+       "change-blocklink": "útsluting feroarje",
        "contribslink": "bydragen",
        "emaillink": "e-mail stjoere:",
        "autoblocker": "Automatysk útsletten om't jo ynternet-adres okkerdeis brûkt is troch \"[[User:$1|$1]]\".\nAs reden foar de útsluting fan $1 is opjûn \"$2\"",
        "movepagetext": "Dit werneamt in side, mei alle sideskiednis.\nDe âlde titel wurdt in trochferwizing nei de nije.\nKeppelings mei de âlde side wurde net feroare;\ngean sels nei of't der dûbele of misse ferwizings binne.\nIt hinget fan jo ôf of't de siden noch keppelen binne sa't it mient wie.\n\nDe side wurdt '''net''' werneamt as der al in side mei dy namme is, útsein as it in side\nsûnder skiednis is en de side leech is of in trochferwizing is. Sa kinne jo in side\ndaalks weromneame as jo in flater meitsje, mar jo kinne in oare side net oerskriuwe.",
        "movepagetalktext": "As der in oerlisside by heart, dan bliuwt dy oan de side keppele, '''útsein''':\n*De nije sidenamme yn in oare nammeromte is,\n*Der keppele oan de nije namme al in net-lege oerlisside is, of\n*Jo dêr net foar kieze.\n\nIn dizze gefallen is it oan jo hoe't jo de oerlisside omneame of ynfoegje wolle.",
        "movenologintext": "Jo moatte [[Special:UserLogin|oanmeld]] wêze om in side wer te neamen.",
-       "newtitle": "As nij titel",
+       "newtitle": "Nije titel:",
        "move-watch": "Folch dizze side",
        "movepagebtn": "Side omneame",
        "pagemovedsub": "Werneamen slagge",
        "movepage-moved": "<strong>\"$1\" hjit no \"$2\"</strong>",
+       "movepage-moved-redirect": "In trochferwizing is oanmakke.",
        "articleexists": "Der is al in side mei dy namme, of oars is de namme dy't jo oanjûn hawwe net tastien. Besykje it op 'e nij.",
        "movetalk": "Titel fan oerlisside ek feroarje, as dy der is.",
        "movepage-page-moved": "De side $1 is werneamd nei $2.",
-       "movelogpage": "Omneamloch",
+       "movelogpage": "Side-omneamloch",
        "movelogpagetext": "Dit is in list fan feroare titels.",
        "movereason": "Reden:",
        "revertmove": "werom sette",
        "delete_and_move_text": "== Wiskjen nedich ==\nDe doelside \"[[:$1]]\" is der al.\nMoat dy wiske wurde om plak te meitsjen foar it werneamen?",
        "delete_and_move_confirm": "Ja, wiskje de side",
-       "delete_and_move_reason": "Wiske om plak te meitsjen foar in werneamde side",
+       "delete_and_move_reason": "Wiske en meitsje plak foar it werneamen fan \"[[$1]]\"",
        "export": "Eksportearje",
        "exportall": "Alle siden eksportearje",
        "export-submit": "Eksportearje",
        "export-addcattext": "Siden tafoegje fan kategory:",
        "export-addcat": "Tafoegje",
        "export-addns": "Tafoegje",
-       "export-download": "Bewarje as triem",
+       "export-download": "Bewarje as bestân",
        "export-templates": "Tafoegje berjochten",
        "allmessages": "Alle wikiberjochten",
        "allmessagesname": "Namme",
        "allmessages-language": "Taal:",
        "allmessages-filter-translate": "Oersette",
        "thumbnail-more": "Fergrutsje",
-       "filemissing": "Triem net fûn",
+       "filemissing": "Bestân net fûn",
        "thumbnail_error": "Flater by it oanmeitsjen fan thumbnail: $1",
        "thumbnail_dest_directory": "Kin de doelmap net oanmeitsje",
        "import": "Importearje siden",
        "import-interwiki-sourcewiki": "Boarnewiki:",
        "import-interwiki-sourcepage": "Boarneside:",
        "import-interwiki-submit": "Ymportearje",
-       "import-upload-filename": "Triemnamme:",
+       "import-upload-filename": "Bestânsnamme:",
        "import-comment": "Oanmerking:",
        "importstart": "Siden oan it ymportearjen ...",
        "import-revision-count": "$1 {{PLURAL:$1|ferzje|ferzjes}}",
        "importnopages": "Gjin siden te ymportearjen.",
        "importfailed": "Ymport fout: <nowiki>$1</nowiki>",
        "importunknownsource": "Unbekende ymportboarnetype",
-       "importcantopen": "De ymporttriem koe net iepenen wurde.",
+       "importcantopen": "It ymportbestân koe net iepene wurde.",
        "importbadinterwiki": "Ferkearde ynterwikiferwizing",
        "importsuccess": "Ymport slagge!",
-       "importnofile": "Gjin ymporttriem is oanbeane.",
+       "importnofile": "Gjin ymportbestân is oanbean.",
        "import-noarticle": "Gjin side te ymportearjen!",
        "import-nonewrevisions": "Alle ferzjes wurde al ymportearre.",
        "xml-error-string": "$1 op regel $2, kolom $3 (byte $4): $5",
        "importlogpage": "Ymportlochboek",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|ferzje|ferzjes}}",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|ferzje|ferzjes}} fan $2",
-       "tooltip-pt-userpage": "Myn brûkersside",
-       "tooltip-pt-mytalk": "Jo oerlisside",
+       "tooltip-pt-userpage": "Jo {{GENDER:|meidogger}}side",
+       "tooltip-pt-mytalk": "{{GENDER:|Jo}} oerlisside",
        "tooltip-pt-preferences": "Myn foarkarynstellings",
        "tooltip-pt-watchlist": "List fan siden dy'sto besjochst op feroarings",
        "tooltip-pt-mycontris": "Oersjocht fan jo bydragen",
        "tooltip-pt-login": "Jo wurde fan herten útnûge jo oan te melden, mar it hoecht net.",
        "tooltip-pt-logout": "Ofmelde",
-       "tooltip-ca-talk": "Oerlis oer dizze side",
-       "tooltip-ca-edit": "Jo kinne dizze side bewurkje. Brûk a.j.w. de foarbyldwerjefteknop foar't Jo de boel bewarje.",
-       "tooltip-ca-addsection": "In opmerking tafoegje oan de oerlis-side.",
-       "tooltip-ca-viewsource": "Dizze side is befeilige, mar jo kinne de boarne wol besjen.",
-       "tooltip-ca-history": "Eardere ferzjes fan dizze side.",
+       "tooltip-pt-createaccount": "Jo wurde fan herten útnûge in akkount oan te meitsjen en jo oan te melden, mar it hoecht net.",
+       "tooltip-ca-talk": "Oerlis oer de ynhâldlike side",
+       "tooltip-ca-edit": "Dizze side bewurkje",
+       "tooltip-ca-addsection": "In nij mêd tafoegje",
+       "tooltip-ca-viewsource": "Dizze side is skoattele, mar jo kinne de boarne wol besjen.",
+       "tooltip-ca-history": "Eardere ferzjes fan dizze side",
        "tooltip-ca-protect": "Dizze side befeiligje",
        "tooltip-ca-delete": "Dizze side weidwaan",
        "tooltip-ca-undelete": "Fuorthelle bewurkings fan dizze side weromsette",
-       "tooltip-ca-move": "Dizze side ferskowe",
-       "tooltip-ca-watch": "Dizze side oan myn folchside tafoegje",
-       "tooltip-ca-unwatch": "Dizze side fan myn folchlist ôfhelje",
+       "tooltip-ca-move": "Dizze side omneame",
+       "tooltip-ca-watch": "Dizze side oan jo folchlist taheakje",
+       "tooltip-ca-unwatch": "Dizze side fan jo folchlist ôfhelje",
        "tooltip-search": "{{SITENAME}} trochsykje",
-       "tooltip-search-go": "Gean nei in side mei dizze namme as dy bestiet",
+       "tooltip-search-go": "Gean nei de side mei dizze namme at dy bestiet",
        "tooltip-search-fulltext": "De siden foar dizze tekst sykje",
        "tooltip-p-logo": "Haadside",
        "tooltip-n-mainpage": "Gean nei de haadside",
-       "tooltip-n-mainpage-description": "Nei de haadside gean",
-       "tooltip-n-portal": "Oer it projekt: wat'st dwaan kinst, wêr'st dingen fine kinst.",
-       "tooltip-n-currentevents": "Eftergrûnynformaasje oer rinnende saken.",
-       "tooltip-n-recentchanges": "De list fan koartlyn oanbrochte feroarings yn dizze wiki.",
-       "tooltip-n-randompage": "Samar in side sjen litte.",
-       "tooltip-n-help": "Helpynformaasje oer dizze wiki.",
+       "tooltip-n-mainpage-description": "Gean nei de haadside",
+       "tooltip-n-portal": "Oer it projekt: wat jo dwaan kinne, wêr jo dingen fine",
+       "tooltip-n-currentevents": "Eftergrûnynformaasje oer rinnende saken",
+       "tooltip-n-recentchanges": "List fan de lêste feroarings oan 'e wiki",
+       "tooltip-n-randompage": "Gean nei likefolle hokfoar side",
+       "tooltip-n-help": "It plak om eat út te fiskjen",
        "tooltip-t-whatlinkshere": "List fan alle siden dy't nei dizze side ferwize",
+       "tooltip-t-recentchangeslinked": "De lêste feroarings yn siden dêr't dizze side nei ferwiisd",
        "tooltip-feed-rss": "RSS-feed foar dizze side",
        "tooltip-feed-atom": "Atom-feed foar dizze side",
-       "tooltip-t-contributions": "Bydragen fan dizze brûker",
-       "tooltip-t-emailuser": "Stjoer in e-mail nei {{GENDER:$1|dizze meidogger}}",
-       "tooltip-t-upload": "Triemmen oplade",
-       "tooltip-t-specialpages": "List fan alle spesjale siden",
-       "tooltip-ca-nstab-user": "Brûkersside sjen litte",
-       "tooltip-ca-nstab-special": "Dit is in spesjale side; jo kinne de side sels net feroarje",
+       "tooltip-t-contributions": "List fan bydragen troch dizze {{GENDER:$1|meidogger|meidochster}}",
+       "tooltip-t-emailuser": "Stjoer in e-mail nei dizze {{GENDER:$1|meidogger|meidochster}}",
+       "tooltip-t-upload": "Bestannen oplade",
+       "tooltip-t-specialpages": "List fan alle bysûndere siden",
+       "tooltip-t-print": "Ofdrukferzje fan dizze side",
+       "tooltip-t-permalink": "Bliuwende keppeling nei dizze ferzje fan 'e side",
+       "tooltip-ca-nstab-main": "De ynhâldlike side sjen litte",
+       "tooltip-ca-nstab-user": "Besjoch de meidoggerside",
+       "tooltip-ca-nstab-special": "Dit is in bysûndere side, en kin net bewurke wurde",
        "tooltip-ca-nstab-project": "Projektside sjen litte",
-       "tooltip-ca-nstab-image": "De triemside sjen litte",
-       "tooltip-ca-nstab-mediawiki": "Systeemberjocht sjen litte",
-       "tooltip-ca-nstab-template": "Sjabloan sjen litte",
+       "tooltip-ca-nstab-image": "De bestânsside sjen litte",
+       "tooltip-ca-nstab-mediawiki": "It systeemberjocht sjen litte",
+       "tooltip-ca-nstab-template": "It berjocht sjen litte",
        "tooltip-ca-nstab-help": "Helpside sjen litte",
        "tooltip-ca-nstab-category": "Kategory-side sjen litte",
-       "tooltip-minoredit": "Markearje dit as in lytse feroaring",
+       "tooltip-minoredit": "Markearje dizze feroaring as fan lytse betsjutting",
        "tooltip-save": "Jo feroarings bewarje",
        "tooltip-preview": "Oerlêze foar't de side fêstlein is!",
        "tooltip-diff": "Sjen litte hokker feroarings jo yn'e tekst makke hawwe.",
        "tooltip-compareselectedversions": "Sjoch de ferskillen tusken de twa keazen ferzjes fan dizze side.",
        "tooltip-watch": "Foegje dizze side ta oan jo folchlist [alt-w]",
+       "tooltip-rollback": "\"Weromdraaie\" set dizze side yn ien klik werom nei hoe't er wie foar't de lêste bydrager syn bewurkings trochfierde",
        "interlanguage-link-title": "$1 – $2",
        "interlanguage-link-title-nonlang": "$1 – $2",
-       "common.js": "/* Alles wat hjir oan JavaScript delset wurdt, wurdt foar alle brûkers laden foar eltse side! */",
+       "common.js": "/* Alles wat hjir oan JavaScript delset wurdt, wurdt foar alle meidoggers laden foar eltse side! */",
        "anonymous": "Anonime {{PLURAL:$1|meidogger|meidoggers}} fan {{SITENAME}}",
        "siteuser": "{{SITENAME}} meidogger $1",
-       "anonuser": "{{SITENAME}} anonime brûker $1",
+       "anonuser": "{{SITENAME}} anonime meidogger $1",
        "othercontribs": "Basearre op wurk fan $1.",
        "others": "Oaren",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|meidogger|meidoggers}} $1",
-       "anonusers": "Anonime {{SITENAME}}-{{PLURAL:$2|brûker|brûkers}} $1",
+       "anonusers": "Anonime {{SITENAME}}-{{PLURAL:$2|meidogger|meidoggers}} $1",
        "creditspage": "Auteursside",
        "spamprotectiontext": "De side dy't jo fêstlizze woene is blokkearre troch in spam filter. Dit wurdt wierskynlik feroarsake troch in ferwizing nei in ekstern webstee.",
        "spamprotectionmatch": "De neikommende tekst hat it spam filter aktivearre: $1",
        "pageinfo-category-total": "Totaal oantal lidden",
        "pageinfo-category-pages": "Oantal siden",
        "pageinfo-category-subcats": "Oantal subkategoryen",
-       "pageinfo-category-files": "Oantal triemmen",
+       "pageinfo-category-files": "Oantal bestannen",
        "markaspatrolleddiff": "Markearje as kontroleare",
        "markaspatrolledtext": "Markearje dizze side as kontrolearre",
        "markedaspatrolled": "Markearre as kontrolearre",
        "markedaspatrollederror": "Kin net as kontrolearre markearre wurde",
        "markedaspatrollederrortext": "Jo moatte in ferzje oanjaan dy't jo as kontrolearre markearje.",
        "markedaspatrollederror-noautopatrol": "Jo meie jo eigen bewurkings net sels markearre.",
-       "previousdiff": "← Âldere feroaring",
+       "previousdiff": "← Eardere ferskillen",
        "nextdiff": "Neikommende ferskillen →",
-       "imagemaxsize": "Behein ôfmjittings fan ôfbyld op beskriuwingsside ta:",
-       "thumbsize": "Mjitte fan miniatueren:",
+       "imagemaxsize": "Beheining fan 'e ôfbyldingsgrutte op bestânsbeskriuwingssiden:",
+       "thumbsize": "Miniatuergrutte:",
        "widthheight": "$1 × $2",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|side|siden}}",
-       "file-info": "triemgrutte: $1, MIME-type: $2",
-       "file-info-size": "$1 × $2 pixels, triemgrutte: $3, MIME-type: $4",
-       "file-info-size-pages": "$1 × $2 pixels, triemgrutte: $3, MIME-type: $4, $5 {{PLURAL:$5|side|siden}}",
+       "file-info": "bestânsgrutte: $1, MIME-type: $2",
+       "file-info-size": "$1 × $2 pixels, bestânsgrutte: $3, MIME-type: $4",
+       "file-info-size-pages": "$1 × $2 pixels, bestânsgrutte: $3, MIME-type: $4, $5 {{PLURAL:$5|side|siden}}",
        "file-nohires": "Gjin hegere resolúsje beskikber.",
-       "svg-long-desc": "SVG-triem, nominaal $1 × $2 pixels, triemgrutte: $3",
-       "show-big-image": "Oarspronklike triem",
+       "svg-long-desc": "SVG-bestân, nominaal $1 × $2 pixels, bestânsgrutte: $3",
+       "show-big-image": "Oarspronklik bestân",
        "show-big-image-other": "Oare {{PLURAL:$2|resolúsje|resolúsjes}}: $1.",
        "show-big-image-size": "$1 × $2 pixels",
-       "newimages": "Nije ôfbylden",
-       "imagelisttext": "Dit is in list fan '''$1''' {{PLURAL:$1|triem|triemen}}, op $2.",
+       "newimages": "Galery mei nije ôfbylden",
+       "imagelisttext": "Dit is in list fan '''$1''' {{PLURAL:$1|bestân|bestannen}}, op $2.",
+       "newimages-summary": "Dizze bysûndere side lit de lêst opladen bestannen sjen.",
        "newimages-legend": "Filter",
        "noimages": "Neat te sjen.",
        "ilsubmit": "Sykje",
        "bydate": "datum",
+       "sp-newimages-showfrom": "Nije bestannen besjen fan $2, $1 ôf",
        "video-dims": "$1, $2 × $3",
        "seconds-abbrev": "$1 s",
        "minutes-abbrev": "$1 min",
        "days-abbrev": "$1 d",
        "seconds": "{{PLURAL:$1|$1 sekonde|$1 sekonden}}",
        "minutes": "{{PLURAL:$1|$1 minút|$1 minuten}}",
-       "hours": "{{PLURAL:$1|$1 oere|$1 oere}}",
+       "hours": "{{PLURAL:$1|$1 oere|$1 oeren}}",
        "days": "{{PLURAL:$1|$1 dei|$1 dagen}}",
        "weeks": "{{PLURAL:$1|$1 wike|$1 wiken}}",
        "months": "{{PLURAL:$1|$1 moanne|$1 moannen}}",
        "yesterday-at": "juster om $1",
        "bad_image_list": "De opmaak is as folget:\n\nAllinne rigels fan in list (rigels dy't begjinne mei *) wurde ferwurke. De earste link op in rigel moat in link wêze nei in net winske ôfbylding.\nAlle folgjende links dy't op deselde rigel steane, wurde behannele as útsûndering, lykas bygelyks siden dêr't de ôfbylding yn'e tekst opnommen is.",
        "metadata": "Metadata",
-       "metadata-help": "Dizze triem befettet oanfoljende ynformaasje, dy't troch in fotokamera, scanner of fotobewurkingsprogramma tafoege wêze kin. As de triem oanpast is, komme de details mûglik net folslein oerien mei de feroare ôfbylding.",
+       "metadata-help": "Dit bestân befettet oanfoljende ynformaasje, dy't troch in fotokamera, scanner of fotobewurkingsprogramma tafoege wêze kin. As it bestân oanpast is, komme de details mûglik net folslein oerien mei de feroare ôfbylding.",
        "metadata-expand": "Utwreide details sjen litte",
        "metadata-collapse": "Ferskûlje útwreide details",
-       "metadata-fields": "De ôfbyldingsmetadatafjilden yn dit berjocht steane op in ôfbyldingsside as de metadatatabel ynklapt is.\nOare fjilden wurde ferburgen.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "metadata-fields": "De oanjûne ôfbyldingsmetadatafjilden yn dit berjocht, sille op 'e ôfbyldingsside werjûn wurde, at de metadatatabel ynklapt is.\nOare sille standert ferburgen wurde.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "metadata-langitem-default": "$1",
        "namespacesall": "alle",
        "monthsall": "alle",
        "confirmemail_sent": "Befêstiginskoade tastjoerd.",
        "confirmemail_sendfailed": "De befêstigingskoade koe net stjoerd wurde. Faaks stean der ferkearde tekens yn it e-postadres.\n\nBerjocht: $1",
        "confirmemail_invalid": "Dizze befêstiginskoade jildt net (mear).\nFaaks is de koade ferrûn.",
+       "confirmemail_needlogin": "Jo moatte $1 om jo e-mailadres befêstigje te kinnen.",
        "confirmemail_success": "Jo netpostadres is befêstige. Jo kinne jo no oanmelde en de wiki brûke.",
        "confirmemail_loggedin": "Jo netpostadres is no befêstige.",
        "confirmemail_subject": "Netpost-befêstigingskoade foar {{SITENAME}}",
        "confirm-watch-button": "OK",
        "confirm-unwatch-button": "OK",
        "confirm-unwatch-top": "Dizze side fan myn folchlist ôfhelje",
+       "confirm-rollback-bottom": "Dizze hanneling sil de oanjûne sidewizigings fuortdaliks weromdraaie.",
        "semicolon-separator": ";&#32;",
        "comma-separator": ",&#32;",
        "colon-separator": ":&#32;",
        "autosumm-blank": "Alle ynhâld fan de side weismiten",
        "autosumm-replace": "Side ferfong mei '$1'",
        "autoredircomment": "Ferwiist troch nei [[$1]]",
-       "autosumm-new": "Nije Side: $1",
+       "autosumm-removed-redirect": "Trochferwizing nei [[$1]] wiske",
+       "autosumm-new": "Side makke mei \"$1\"",
        "size-bytes": "$1 B",
        "size-kilobytes": "$1 KB",
        "size-megabytes": "$1 MB",
        "redirect-user": "Meidogger-ID",
        "redirect-page": "Sidenûmer",
        "redirect-revision": "Sideferzje",
-       "redirect-file": "Triemnamme",
+       "redirect-file": "Bestânsnamme",
        "redirect-not-exists": "Wearde net fûn",
        "fileduplicatesearch": "Sykje op duplikaten",
-       "fileduplicatesearch-filename": "Triemnamme:",
+       "fileduplicatesearch-filename": "Bestânsnamme:",
        "fileduplicatesearch-submit": "Sykje",
-       "fileduplicatesearch-info": "$1 × $2 pixel<br />Triemgrutte: $3<br />MIME-type: $4",
-       "fileduplicatesearch-result-1": "De triem \"$1\" hat gjin duplikaten.",
-       "fileduplicatesearch-result-n": "De triem \"$1\" hat {{PLURAL:$2|1 duplikaat|$2 duplikaten}}.",
+       "fileduplicatesearch-info": "$1 × $2 pixel<br />Bestânsgrutte: $3<br />MIME-type: $4",
+       "fileduplicatesearch-result-1": "It bestân \"$1\" hat gjin duplikaten.",
+       "fileduplicatesearch-result-n": "It bestân \"$1\" hat {{PLURAL:$2|1 duplikaat|$2 duplikaten}}.",
        "specialpages": "Bysûndere siden",
        "specialpages-note-top": "Leginda",
        "specialpages-note-restricted": "* Normale bysûndere siden.\n* <strong class=\"mw-specialpagerestricted\">Beheinde bysûndere siden.</strong>",
        "specialpages-group-other": "Oare bysûndere siden",
        "specialpages-group-login": "Oanmelde / registrearje",
        "specialpages-group-changes": "Koartlyn feroare en lochs",
-       "specialpages-group-media": "Oanbieden en oare triemsiden",
+       "specialpages-group-media": "Oanbieden en oare bestânssiden",
        "specialpages-group-users": "Meidoggers en rjochten",
        "specialpages-group-highuse": "Siden dy't in protte brûkt wurde",
        "specialpages-group-pages": "Sidelisten",
        "specialpages-group-spam": "Spamhelpmiddels",
        "blankpage": "Side is leech",
        "intentionallyblankpage": "Dizze side is bewust leech lizzen en wurdt brûkt foar benchmarks, ensfh.",
-       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Label|Labels}}]]: $2",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Lebel|Lebels}}]]: $2",
+       "tag-mw-new-redirect": "Nije trochferwizing",
+       "tag-mw-removed-redirect": "Trochferwizing wiske",
+       "tag-mw-changed-redirect-target": "Trochferwizingsdoel feroare",
+       "tag-mw-changed-redirect-target-description": "Bewurkings dy't it einpunt fan in trochferwizing feroarje",
+       "tag-mw-blank": "Leech meitsjen",
+       "tag-mw-replace": "Ferfongen",
+       "tag-mw-rollback": "Weromdraaid",
+       "tag-mw-rollback-description": "Bewurkings mei de keppeling 'weromdraaie', dy't foargeande wizigings ûngedien makke hawwe",
+       "tag-mw-undo": "Ungedien meitsjen",
+       "tags-title": "Lebels",
+       "tags-intro": "Op dizze side steane de lebels en har betsjutting, wêrmei't de programmatuer bewurkings markearje kin.",
+       "tags-tag": "Lebelnamme",
+       "tags-display-header": "Werjefte yn feroaringslisten",
+       "tags-description-header": "Folsleine beskriuwing fan 'e betsjutting",
        "tags-source-header": "Boarne",
        "tags-active-header": "Aktyf?",
+       "tags-hitcount-header": "Lebele bewurkings",
        "tags-actions-header": "Aksjes",
        "tags-active-yes": "Ja",
        "tags-active-no": "Nee",
+       "tags-source-extension": "Definiearre yn de programmatuer",
+       "tags-source-manual": "Hânmjittich taheakke troch meidoggers en bots",
+       "tags-source-none": "Net mear yn gebrûk",
        "tags-edit": "bewurkje",
        "tags-delete": "fuortsmite",
        "tags-activate": "aktivearje",
        "tags-deactivate": "deaktivearje",
        "tags-hitcount": "$1 {{PLURAL:$1|bewurking|bewurkings}}",
+       "tags-create-tag-name": "Lebelnamme:",
        "tags-create-reason": "Reden:",
        "tags-delete-reason": "Reden:",
        "tags-activate-reason": "Reden:",
        "htmlform-yes": "Ja",
        "htmlform-cloner-create": "Mear tafoegje",
        "htmlform-cloner-delete": "Fuortsmite",
+       "logentry-delete-delete": "$1 {{GENDER:$2|hat}} de side $3 wiske",
+       "logentry-delete-delete_redir": "$1 {{GENDER:$2|hat}} de trochferwizing $3 by it oerskriuwen wiske",
        "revdelete-restricted": "hat beheinings oplein oan behearders",
        "revdelete-unrestricted": "hat beheinings foar behearders goedmakke",
+       "logentry-move-move": "$1 {{GENDER:$2|hat}} de side $3 omneamd ta $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|hat}} de side $3 omneamd ta $4 sûnder in trochferwizing efter te litten",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|hat}} de side $3 omneamd ta $4 fan de trochferwizing",
+       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|hat}} de side $3 omneamd ta $4 fan de trochferwizing, sûnder in trochferwizing efter te litten",
+       "logentry-newusers-create": "It meidochakkount $1 is {{GENDER:$2|oanmakke}}",
+       "logentry-newusers-autocreate": "It meidochakkount $1 is automatysk {{GENDER:$2|oanmakke}}",
+       "logentry-upload-upload": "$1 hat $3 {{GENDER:$2|opladen}}",
+       "logentry-upload-overwrite": "$1 hat in nije ferzje fan $3 {{GENDER:$2|opladen}}",
        "rightsnone": "(gjin)",
        "feedback-back": "Foarige",
        "feedback-cancel": "Annulearje",
        "mediastatistics-nfiles": "$1 ($2%)",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
        "mediastatistics-table-mimetype": "MIME-type",
-       "mediastatistics-table-count": "Oantal triemmen",
+       "mediastatistics-table-count": "Oantal bestannen",
        "mediastatistics-header-unknown": "Unbekend",
        "mediastatistics-header-bitmap": "Bitmapôfbyldings",
        "mediastatistics-header-drawing": "Tekeningen (fektorôfbyldings)",
        "mediastatistics-header-audio": "Audio",
        "mediastatistics-header-video": "Fideo's",
        "mediastatistics-header-multimedia": "Ynteraktive media",
-       "mediastatistics-header-office": "Kantoartriemmen",
-       "mediastatistics-header-text": "Tekstriemmen",
-       "mediastatistics-header-executable": "Utfierbere triemmen",
-       "mediastatistics-header-archive": "Komprimearre triemmen",
+       "mediastatistics-header-office": "Kantoarbestannen",
+       "mediastatistics-header-text": "Tekstbestannen",
+       "mediastatistics-header-executable": "Utfierbere bestannen",
+       "mediastatistics-header-archive": "Komprimearre bestannen",
        "json-error-syntax": "Syntaksisflater",
        "special-characters-group-latin": "Latyn",
        "special-characters-group-latinextended": "Latyn útwreide",
index c0c3832..fc566aa 100644 (file)
@@ -22,7 +22,8 @@
                        "Macofe",
                        "Tem",
                        "Nmacu",
-                       "ديفيد"
+                       "ديفيد",
+                       "Xqt"
                ]
        },
        "tog-underline": "Folínte faoi naisc:",
        "ilsubmit": "Cuardaigh",
        "bydate": "de réir dáta",
        "sp-newimages-showfrom": "Taispeáin íomhánna nua as $2, $1",
-       "days": "{{PLURAL:$1|$1 lá}}",
+       "days": "$1 lá",
        "bad_image_list": "Is é seo a leanas an formáid:\n\nNíl ach míreanna liosta amháin (línte ag tosú le *) san áireamh.\nIs riachtanach gur nasc do dhrochchomhad é an chéad nasc ar líne.\nIs eisceachtaí iad na naisc eile ar an líne céanna, .i. leathanaigh gur féidir an comhad a bheith orthu go hinlíne.",
        "metadata": "Meiteasonraí",
        "metadata-help": "Tá breis eolais sa comhad seo, curtha, is dócha, as ceamara digiteach ná scanóir a chruthaigh ná a digitigh é.\nMá tá an comhad mionathraithe as an bunleagan, b'fhéidir nach mbeidh ceann de na sonraí fágtha sa comhad atá athruithe.",
index 5bdfdab..6fd1e82 100644 (file)
        "view": "Lir",
        "view-foreign": "Wè asou $1",
        "edit": "Modifyé",
-       "edit-local": "Modifyé dèskripsyon lokal",
+       "edit-local": "Modifyé dèskripsyon lokal-a",
        "create": "Kréyé",
        "create-local": "Ajouté roun dèskripsyon lokal",
        "delete": "Siprimen",
        "newmessageslinkplural": "{{PLURAL:$1|oun nouvèl mésaj|dé nouvèl mésaj}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|dannyé modifikasyon}}",
        "youhavenewmessagesmulti": "Zòt gen dé nouvèl mésaj asou $1.",
-       "editsection": "Modifyé",
+       "editsection": "modifyé",
        "editold": "modifyé",
        "viewsourceold": "wè sours-a",
        "editlink": "modifyé",
        "yourpasswordagain": "Konfirmen modipas-a :",
        "createacct-yourpasswordagain": "Konfirmen modipas-a",
        "createacct-yourpasswordagain-ph": "Rantré òkò menm modipas-a",
-       "userlogin-remembermypassword": "Gardé mo sésyon aktiv",
+       "userlogin-remembermypassword": "Gadé mo sésyon agtiv",
        "userlogin-signwithsecure": "Itilizé roun konnègsyon sékirizé",
        "cannotlogin-title": "Enposib di konnègté so kò",
        "cannotlogin-text": "Konnègsyon-an pa posib",
        "cannotcreateaccount-title": "Kréyasyon di kont enposib",
        "cannotcreateaccount-text": "Kréyasyon-an dirèk di kont itilizatò pa fika agtivé asou sa wiki.",
        "yourdomainname": "Zòt domenn :",
-       "password-change-forbidden": "Zòt pa pouvé modifyé mo di pas asou sa wiki.",
+       "password-change-forbidden": "Zòt pa pouvé chanjé modipas-ya asou sa wiki.",
        "externaldberror": "Swé roun lérò prodjwi so kò asou baz-a di data d'otantifikasyon, swé zòt pa otorizé à mété à jou zòt kont ègstèrn.",
        "login": "Konnègsyon",
        "login-security": "Vérifyé zòt idantité",
        "userlogin-noaccount": "Zòt pa gen roun kont ?",
        "userlogin-joinproject": "Roujwenn {{SITENAME}}",
        "createaccount": "Kréyé roun kont",
-       "userlogin-resetpassword-link": "Zòt bliyé zòt mo di pas ?",
+       "userlogin-resetpassword-link": "Zòt bliyé zòt modipas ?",
        "userlogin-helplink2": "Lèd pou konnègté so kò",
        "userlogin-loggedin": "Zòt déja konnègté an tan ki $1.\nItilizé fòrmilèr-a ki anba pou konnègté zòt kò ké rounòt kont itilizatò.",
        "userlogin-reauth": "Zòt divèt roukonèkté zòt kò pou vérifyé ki zòt sa {{GENDER:$1|$1}}.",
        "createacct-benefit-body1": "modifikasyon{{PLURAL:$1|}}",
        "createacct-benefit-body2": "paj{{PLURAL:$1|}}",
        "createacct-benefit-body3": "{{PLURAL:$1|kontribitò résan}}",
-       "badretype": "Mo di pas ki zòt sézi pa ka korèsponn.",
+       "badretype": "Modipas-ya ki zòt sézi pa ka korèsponn.",
        "usernameinprogress": "Oun kréyasyon di kont pou sa non d'itilizatò ja an kour.\nSouplé, pasyanté.",
        "userexists": "Non d'itilizatò sézi ja itilizé.\nSouplé, chwézi roun non diféran.",
        "loginerror": "Lérò di konnègsyon",
        "nosuchusershort": "I pa gen kontribitò ké non-an « $1 ».\nSouplé, vérifyé lòrtograf.",
        "nouserspecified": "Zòt divèt sézi roun non d'itilizatò.",
        "login-userblocked": "{{GENDER:$1|Sa itilizatò}} bloké. Konnègsyon-an pa otorizé.",
-       "wrongpassword": "Non d'itilizatò oben mo di pas enkorèk.\nSouplé, éséyé òkò.",
+       "wrongpassword": "Non-an di itilizatò oben modipas enkorèk.\nSouplé, éséyé òkò.",
        "wrongpasswordempty": "Zòt pa rantré pyès modipas.\nSouplé, éséyé òkò.",
        "passwordtooshort": "Zòt mo di pas divèt kontni omwen $1 karaktèr{{PLURAL:$1|}}.",
-       "passwordtoolong": "Mo di pas pa pouvé dépasé $1 karaktèr{{PLURAL:$1|}}.",
-       "passwordtoopopular": "Mo di pas ki tròp kouran pa pouvé fika itilizé. Souplé, chwézi roun mo di pas pli difisil à douviné.",
+       "passwordtoolong": "Modipas-ya pa pouvé dépasé $1 karagtèr{{PLURAL:$1|}}.",
+       "passwordtoopopular": "Modipas ki tròp kouran pa pouvé fika itilizé. Souplé, chwézi roun modipas ki pi difisil pou sonjé.",
        "password-name-match": "Zòt mo di pas divèt fika diféran di zòt non d'itilizatò.",
        "password-login-forbidden": "Litilizasyon-an di sa non d'itilizatò oben di sa modipas sa entèrdi.",
        "mailmypassword": "Réynisyalizé modipas-a",
-       "passwordremindertitle": "Nouvèl mo di pas tanporèr pou {{SITENAME}}",
-       "passwordremindertext": "Tchèk moun (dipi adrès IP-a $1) doumandé roun modipas nòv pou {{SITENAME}} ($4). Oun modipas tanporèr pou itilizatò-a\n« $2 » té kréyé é sa « $3 ». Si sala té zòt entansyon,\nzòt divèt konnègté zòt kò é chwézi roun modipas nòv.\nZòt modipas tanporèr ké èspiré annan $5 jou{{PLURAL:}}.\n\nSi zòt pa lotò di sa doumann, oben si zòt ka souvni zòt kò atchwèlman di zòt modipas é zòt pli ka swété an chanjé, zòt pouvé ignoré sa mésaj é kontinwé di itilizé zòt ansyen modipas.",
+       "passwordremindertitle": "Nouvèl modipas tanporèr pou {{SITENAME}}",
+       "passwordremindertext": "Tchèk moun (dipi adrès IP-a $1) doumandé roun modipas nòv pou {{SITENAME}} ($4). Oun modipas tanporèr pou itilizatò-a\n« $2 » té kréyé é sa « $3 ». Si sa té zòt lentansyon,\nzòt divèt konnègté zòt kò é chwézi roun modipas nòv.\nZòt modipas tanporèr ké èspiré annan $5 jou{{PLURAL:}}.\n\nSi zòt pa lotò di sa doumann, oben si zòt routrouvé zòt modipas é zòt pli ka swété chanjé li, zòt pouvé ignoré sa mésaj é kontinwé di itilizé zòt ansyen modipas.",
        "noemail": "Pyès adrès di kourilèt fika anréjistré pou itilizatò-a « $1 ».",
        "noemailcreate": "Zòt divèt fourni roun adrès di kourilèt valid",
        "passwordsent": "Roun nouvèl modipas fika voyé bò'd adrès-a di kourilèt di itilizatò « $1 ».\nSouplé, roukonnègté zòt kò apré ki zòt rousouvri li.",
        "user-mail-no-addy": "Enposib di voyé roun kourilèt san adrès di kourilèt.",
        "user-mail-no-body": "Lésè di voyé di roun kourilèt ké roun kò vid oben anòrmalman kourt.",
        "changepassword": "Chanjé di modipas",
-       "resetpass_announce": "Pou tèrminé zòt enskripsyon, zòt divèt fourni roun mo di pas nòv.",
+       "resetpass_announce": "Pou tèrminen zòt lenskripsyon, zòt divèt fourni roun modipas nòv.",
        "resetpass_text": "<!-- Ajouté tègs-a isi -->",
-       "resetpass_header": "Chanjé mo di pas di kont",
+       "resetpass_header": "Chanjé modipas-a di kont",
        "oldpassword": "Ansyen modipas :",
        "newpassword": "Nouvèl modipas :",
        "retypenew": "Konfirmen modipas nòv-a :",
        "resetpass_submit": "Chanjé modipas-a é konnègté so kò.",
-       "changepassword-success": "Zòt modipas modifyé !",
+       "changepassword-success": "Zòt modipas chanjé !",
        "changepassword-throttled": "Zòt fè tròp di tantativ di konnègsyon résaman. \nSouplé, antann $1 anvan di réyéséyé.",
-       "botpasswords": "Mo di pas di robo",
+       "botpasswords": "Modipas di robo",
        "botpasswords-summary": "<em>Modipas-ya di robo</em> ka pèrmèt di agsédé à roun kont itilizatò vya API-a san itilizé idantifyan-yan di konnègsyon prensipal. Drwè itilizatò-ya ki disponnib lò to konnègté ké roun modipas robo pouvé fika rédjwi.\n\nSi zòt pa ka wè poukisa zòt ké lé fè sa, a ki zòt pa benzwen di fè sa. Pésonn divèt janmen doumandé zòt di an jénéré roun é di bay li.",
-       "botpasswords-disabled": "Mo di pas di robo sa dézaktivé.",
+       "botpasswords-disabled": "Modipas-ya di robo dézagtivé.",
        "botpasswords-no-central-id": "Pou itilizé modipas-ya di robo, zòt divèt fika konnègté à roun kont ki santralizé.",
-       "botpasswords-existing": "Mo di pas di robo ègzistan",
-       "botpasswords-createnew": "Kréyé roun mo di pas nòv di robo",
-       "botpasswords-editexisting": "Modifyé roun mo di pas di robo ègzistan",
+       "botpasswords-existing": "Modipas di robo ki ka ègzisté",
+       "botpasswords-createnew": "Kréyé roun nouvèl modipas di robo",
+       "botpasswords-editexisting": "Modifyé roun modipas di robo ki ka ègzisté",
        "botpasswords-label-needsreset": "(Modipas-a divèt fika réynisyalizé)",
        "botpasswords-label-appid": "Non di robo :",
        "botpasswords-label-create": "Kréyé",
        "botpasswords-bad-appid": "Non-an di robo « $1 » pa valid.",
        "botpasswords-insert-failed": "Échèk di ajou-a di non di robo « $1 ». Ès i té ja ajouté ?",
        "botpasswords-update-failed": "Léchèk di mizajou di non di robo « $1 ». Ès i té ja siprimen ?",
-       "botpasswords-created-title": "Mo di pas di robo kréyé",
+       "botpasswords-created-title": "Modipas di robo kréyé",
        "botpasswords-created-body": "Mo di pas pou robo-a « $1 » di {{GENDER:$2|itilizatò|itilizatris}}-a « $2 » té kréyé.",
-       "botpasswords-updated-title": "Mo di pas di robo mizajou",
+       "botpasswords-updated-title": "Modipas di robo mizajou",
        "botpasswords-updated-body": "Mo di pas pou robo-a « $1 » di {{GENDER:$2|itilizatò|itilizatris}}-a « $2 » té mizajou.",
        "botpasswords-deleted-title": "Modipas di robo siprimen",
        "botpasswords-deleted-body": "Modipas-a pou robo-a « $1 » di {{GENDER:$2|itilizatò|itilizatris}}-a « $2 » té siprimen.",
        "botpasswords-newpassword": "Nouvèl modipas-a pou konnègté so kò à<strong>$1</strong> sa <strong>$2</strong>. <em>Souplé, anréjistré li pou fè référans asou li iltèryòrman.</em><br> (Pou ansyen robo-ya ki ka nésésité ki non-an ki fourni pou konnègsyon-an ka fika menm-an ki non-an di itilizatò évantchwèl, zòt pouvé osi itilizé <strong>$3</strong> kou non di itilizatò é <strong>$4</strong> kou modipas).",
        "botpasswords-no-provider": "BotPasswordsSessionProvider pa disponnib.",
        "botpasswords-restriction-failed": "Rèstrigsyon-yan di modipas di robo ka anpéché sa konnègsyon.",
-       "botpasswords-invalid-name": "Non-an d'itilizatò spésifyé pa ka kontni di séparatò di mo di pas di robo (« $1 »).",
+       "botpasswords-invalid-name": "Non-an d'itilizatò ki èspésifyé pa ka kontni di séparatò di modipas di robo (« $1 »).",
        "botpasswords-not-exist": "{{GENDER:$1|Itilizatò|Itilizatris}}-a « $1 » pa gen di mo di pas di robo nonmen « $2 ».",
        "botpasswords-needs-reset": "Modipas-a di robo di non « $2 » di itilizatò-a « $1 » divèt fika réynisyalizé.",
-       "resetpass_forbidden": "Mo di pas pa pouvé fika chanjé.",
-       "resetpass_forbidden-reason": "Mo di pas pa pouvé fika modifyé : $1",
+       "resetpass_forbidden": "Modipas-ya pa pouvé fika chanjé.",
+       "resetpass_forbidden-reason": "Modipas-ya pa pouvé fika chanjé : $1",
        "resetpass-no-info": "Zòt divèt fika konnègté pou agsédé dirèkman à sa paj.",
        "resetpass-submit-loggedin": "Chanjé di modipas",
        "resetpass-submit-cancel": "Annilé",
-       "resetpass-wrong-oldpass": "Mo di pas atchwèl oben tanporèr envalid.\nZòt pitèt ja chanjé zòt mo di pas oben doumandé roun mo di pas nòv tanporèr.",
+       "resetpass-wrong-oldpass": "Modipas atchwèl oben tanporèr envalid.\nZòt pitèt déja chanjé zòt modipas oben doumandé roun modipas nòv tanporèr.",
        "resetpass-recycled": "Souplé, modifyé zòt modipas ké ròt kichoz ki atchwèl-a.",
        "resetpass-temp-emailed": "Zòt konnègté ké roun kod tanporèr ki fourni pa kourilèt.\nPou tèrminen konnègsyon-an, zòt divèt fourni roun nouvèl modipas isi :",
        "resetpass-temp-password": "Modipas tanporèr :",
        "resetpass-expired-soft": "Zòt modipas èspiré, é divèt fika modifyé. Souplé, chwézi roun nouvèl atchwèlman oben kliké asou « {{int:authprovider-resetpass-skip-label}} » pou fè li plita.",
        "resetpass-validity-soft": "Zòt modipas pa valid : $1\n\nSouplé, chwézi roun nouvèl modipas atchwèlman, oben kliké asou « {{int:authprovider-resetpass-skip-label}} » pou modifyé li plita.",
        "passwordreset": "Réynisyalizasyon di modipas",
-       "passwordreset-text-one": "Ranplisé sa fòrmilèr pou zòt mo di pas.",
+       "passwordreset-text-one": "Ranpli sa fòrmilèr pou réynisyalizé zòt modipas.",
        "passwordreset-emaildisabled": "Fongsyonnalité-ya di kourilèt fika dézagtivé asou sa wiki.",
        "passwordreset-username": "Non di itilizatò :",
        "passwordreset-domain": "Domenn :",
        "passwordreset-email": "Adrès di kourilèt :",
        "passwordreset-emailtitle": "Détay di kont asou {{SITENAME}}",
-       "passwordreset-emailelement": "Non di itilizatò : \n$1\n\nMo di pas tanporèr : \n$2",
+       "passwordreset-emailelement": "Non di itilizatò : \n$1\n\nModipas tanporèr : \n$2",
        "passwordreset-nocaller": "Oun apélan divèt fika fourni",
        "passwordreset-nosuchcaller": "Apélan-an pa ka ègzisté : $1",
        "passwordreset-invalidemail": "Adrès di mésajri envalid",
        "changeemail-oldemail": "Adrès di kourilèt atchwèl :",
        "changeemail-newemail": "Nouvèl adrès di kourilèt :",
        "changeemail-none": "(pyès)",
-       "changeemail-password": "Zòt mo di pas asou {{SITENAME}} :",
+       "changeemail-password": "Zòt modipas asou {{SITENAME}} :",
        "changeemail-submit": "Chanjé adrès-a di kourilèt",
        "changeemail-throttled": "Zòt fè tròp tantativ di konnègsyon. \nSouplé, antann $1 anvan di réyéséyé.",
        "changeemail-nochange": "Souplé, sézi roun nouvèl adrès di kourilèt ki diféran di présédant-a.",
        "showpreview": "Prévizwèlizé",
        "showdiff": "Wè modifikasyon-yan",
        "anoneditwarning": "<strong>Panga :</strong> zòt pa konnègté. Zòt adrès IP ké vizib pa tout moun si zòt ka fè dé modifikasyon. Si zòt <strong>[$1 ka konnègté zòt kò]</strong> oben <strong>[$2 kréyé roun kont]</strong>, zòt modifikasyon ké fika atribiyé à zòt pròp non di itilizatò é zòt ké gen ròt avantaj.",
+       "blockedtitle": "Itilizatò-a bloké.",
        "blockedtext": "<strong>Zòt kont itilizatò oben zòt adrès IP fika bloké.</strong>\n\nBlokaj té éfègtchwé pa $1.\nRézon-an ki évoké ka swiv : <em>$2</em>.\n\n* Koumansman di blokaj : $8\n* Lèspirasyon di blokaj : $6\n* Kont bloké : $7.\n\nZòt pouvé kontagté $1 oben rounòt [[{{MediaWiki:Grouppage-sysop}}|administratò]] pou diskité apropo di sa.\nZòt pouvé itilizé fongsyon-an « {{int:emailuser}} » rounso si roun adrès di kourilèt valid sa èspésifyé annan zòt [[Special:Preferences|préférans]] é rounso si sa fongsyonnalité pa fika bloké ba zòt.\nZòt adrès IP atchwèl sa $3 é zòt idantifyan di blokaj sa $5.\nSouplé, enkli tout détay-ya lasou'l annan chak rékèt ki zòt ké fè.",
+       "blockednoreason": "pyès rézon bay",
        "loginreqlink": "konnègté so kò",
+       "accmailtitle": "Modipas voyé.",
+       "newarticle": "(Nòv)",
        "newarticletext": "Zòt swiv roun lyannaj bò'd roun paj ki pa ka ègzisté òkò. \nAfen di kréyé sa paj, rantré zòt tègs annan bwèt-a ki apré (zòt pouvé konsilté [$1 paj di lèd-a] pou plis di lenfòrmasyon).\nSi zòt vini{{GENDER:|}} isi pa lérò, kliké asou bouton-an <strong>Viré</strong> di zòt navigatò.",
        "anontalkpagetext": "----\n<em>Zòt asou paj-q di diskisyon di roun itilizatò annonnim ki pa òkò kréyé di kont oben ki pa ka itilizé roun</em>.\nPou sa rézon, nou divèt itilizé so adrès IP pou idantifyé li.\nOun adrès konran IP pouvé fika patajé pa plizyò itilizatò.\nSi zòt sa roun itiliza{{GENDER:|ò}} annonnim é si zòt ka kontasté ki dé koumantèr ki pa ka konsèrnen zòt, fika adrésé ba zòt, zòt pouvé [[Special:CreateAccount|kréyé roun kont]] oben [[Special:UserLogin|konnègté zòt kò]] pou évité tout konfizyon fitir ké ròt kontribitò annonnim.",
        "noarticletext": "I pa gen atchwèlman pyès tègs asou sa paj.\nZòt pouvé [[Special:Search/{{PAGENAME}}|lansé oun sasé asou sa tit]] annan ròt paj-ya,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} sasé annan lopérasyon-yan ki lyannen]\noben [{{fullurl:{{FULLPAGENAME}}|action=edit}} kréyé sa paj]</span>.",
        "noarticletext-nopermission": "I pa gen atchwèlman pyès tègs asou sa paj.\nZòt pouvé [[Special:Search/{{PAGENAME}}|fè roun sasé asou sa tit]] annan ròt paj-ya,\noben <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|paj={{FULLPAGENAMEE}}}} sasé annan journal-ya ki asosyé]</span>, mé zòt pa gen pèrmisyon-an di kréyé sa paj.",
        "userpage-userdoesnotexist-view": "Kont itilizatò-a « $1 » pa anréjistré.",
        "clearyourcache": "<strong>Nòt :</strong> apré zòt anréjistré zòt modifikasyon, zòt divèt fòrsé roucharjman konplè di kach di zòt navigatò pou wè chanjman-yan.\n* <strong>Firefox / Safari :</strong> mentni touch-a <em>Maj</em> (<em>Shift</em>) an klikan asou bouton-an <em>Atchwalizé</em> oben présé <em>Ctrl-F5</em> oben <em>Ctrl-R</em> (<em>⌘-R</em> asou roun Mac) \n* <strong>Google Chrome :</strong> apiyé asou <em>Ctrl-Maj-R</em> (<em>⌘-Shift-R</em> asou roun Mac) \n* <strong>Internet Explorer :</strong> mentni touch-a <em>Ctrl</em> an klikan asou bouton-an <em>Atchwalizé</em> oben présé <em>Ctrl-F5</em> \n* <strong>Opera :</strong> alé annan <em>Menu → Settings</em> (<em>Opera → Préférences</em> asou roun Mac) é answit à <em>Konfidansyalité & sékrité → Éfasé data di lésplorasyon-yan → Zimaj ké fiché an kach</em>.",
+       "updated": "(Mizajou)",
+       "note": "<strong>Nòt :</strong>",
        "previewnote": "<strong>Pa bliyé ki a jis roun prévizwèlizasyon.</strong>\nZòt modifikasyon pa òkò fika anréjistré !",
        "continue-editing": "Alé kot zonn di modifikasyon",
        "editing": "Modifikasyon di $1",
        "enhancedrc-history": "listorik",
        "recentchanges": "Modifikasyon résan",
        "recentchanges-legend": "Lòpsyon dé modifikasyon résan",
-       "recentchanges-summary": "Swiv chanjman-yan pli résan wiki asou sa paj.",
+       "recentchanges-summary": "Swiv chanjman-yan ki pli résan di wiki asou sa paj.",
        "recentchanges-noresult": "Pyès modifikasyon ka korèsponn à sa kritèr asou péryòd endiké.",
        "recentchanges-feed-description": "Swiv dannyé modifikasyon-yan di wiki annan sa fligs.",
        "recentchanges-label-newpage": "Sa modifikasyon té kréyé roun nouvèl paj",
        "recentchanges-label-minor": "Sa modifikasyon sa minò.",
        "recentchanges-label-bot": "Sa modifikasyon té fika éfègtchwé pa roun robo.",
        "recentchanges-label-unpatrolled": "Sa modifikasyon pa té òkò réli.",
-       "recentchanges-label-plusminus": "Tay di paj-a chanjé di sa nonm d'oktè.",
+       "recentchanges-label-plusminus": "Tay-a di paj-a chanjé di sa nonm di ògtè.",
        "recentchanges-legend-heading": "<strong>Léjann :</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (wè osi [[Special:NewPages|lis dé nouvèl paj]]).",
        "rcnotefrom": "Anba {{PLURAL:$5|modifikasyon-an ki éfègtchwé|modifikasyon-yan ki éfègtchwé}} dipi <strong>$3, $4</strong> (afiché jouk <strong>$1</strong>).",
        "pageinfo-magic-words": "{{PLURAL:$1|Mo majik}} ($1)",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Katégori kaché|}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|Modèl enkli}} ($1)",
-       "pageinfo-toolboxlink": "Lenfòrmasyon asou paj-a",
+       "pageinfo-toolboxlink": "Lenfòrmasyon asou paj",
        "pageinfo-contentpage": "Konté kou paj di kontni",
        "pageinfo-contentpage-yes": "Enren",
        "patrol-log-page": "Journal dé roulèktir",
index 495fd47..24ffad3 100644 (file)
        "revertpage": "Deasachaidhean a chaidh a thilleadh leis [[Special:Contributions/$2|$2]] ([[User talk:$2|an deasbaireachd]]) dhan mhùthadh mu dheireadh le [[User:$1|$1]]",
        "revertpage-nouser": "Deasachaidhean a chaidh a thilleadh le cleachdaiche falaichte dhan mhùthadh mu dheireadh le [[User:$1|$1]]",
        "rollback-success": "Na deasachaidhean a chaidh a thilleadh le $1;\nchaidh an tilleadh gun mhùthadh mu dheireadh le $2.",
-       "rollback-success-notify": "Na deasachaidhean a chaidh a thilleadh le $1;\nchaidh an tilleadh gun mhùthadh mu dheireadh le $2. [$3 Seall na h-atharraichean]",
        "sessionfailure-title": "Trioblaid leis an t-seisean",
        "sessionfailure": "Tha duilgheadas ann leis an seisean logaidh a-steach agad a-rèir coltais;\nchaidh sgur dhen ghnìomh seo a chum dìon o session hijacking.\nTill dhan duilleag roimhpe, ath-luchdaich an duilleag ud 's feuch ris a-rithist an uairsin.",
        "logentry-contentmodel-change-revertlink": "till",
index c04a816..274047f 100644 (file)
@@ -74,6 +74,7 @@
        "tog-norollbackdiff": "Omitir as diferenzas despois de levar a cabo unha reversión de edicións",
        "tog-useeditwarning": "Avisar ao deixar unha páxina de edición cos cambios sen gardar",
        "tog-prefershttps": "Utilizar sempre unha conexión segura para acceder ao sistema",
+       "tog-showrollbackconfirmation": "Amosar unha mensaxe de confirmación ó facer clic nunha ligazón de reversión",
        "underline-always": "Sempre",
        "underline-never": "Nunca",
        "underline-default": "Opción predeterminada da aparencia ou do navegador",
        "badretype": "Os contrasinais que inseriu non coinciden.",
        "usernameinprogress": "Xa está en marcha a creación dunha conta para este nome de usuario.\nPor favor, agarde.",
        "userexists": "O nome de usuario que inseriu xa está en uso.\nEscolla un nome diferente.",
+       "createacct-normalization": "O seu nome de usuario quedará axustado a \"$2\" debido a restricións técnicas.",
        "loginerror": "Erro ao acceder ao sistema",
        "createacct-error": "Erro ao crear a conta",
        "createaccounterror": "Non se puido crear a conta: $1",
        "deleting-backlinks-warning": "<strong>Atención:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Outras páxinas]] conteñen unha ligazón ou unha transclusión da páxina que está a piques de borrar.",
        "deleting-subpages-warning": "<strong>Aviso:</strong> A páxina que quere eliminar ten [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|unha subpáxina|$1 subpáxinas|51=máis de 50 subpáxinas}}]].",
        "rollback": "Reverter as edicións",
+       "rollback-confirmation-confirm": "Por favor, confirme:",
+       "rollback-confirmation-yes": "Reverter",
+       "rollback-confirmation-no": "Cancelar",
        "rollbacklink": "reverter",
        "rollbacklinkcount": "reverter $1 {{PLURAL:$1|edición|edicións}}",
        "rollbacklinkcount-morethan": "reverter máis de $1 {{PLURAL:$1|edición|edicións}}",
        "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 {{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 Amosar 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.\nPor favor, volva enviar o formulario.",
        "changecontentmodel": "Cambiar o modelo de contido dunha páxina",
        "mycontris": "Contribucións",
        "anoncontribs": "Contribucións",
        "contribsub2": "De {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Para{{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "A conta de usuario \"$1\" non está rexistrada.",
+       "negative-namespace-not-supported": "Non están soportados os espazos de nomes con valore negativos.",
        "nocontribs": "Non se deron atopado cambios con eses criterios.",
        "uctop": "actual",
        "month": "Desde o mes de (e anteriores):",
        "ipb-confirm": "Confirmar o bloqueo",
        "ipb-sitewide": "En todo o sitio",
        "ipb-partial": "Parcial",
+       "ipb-sitewide-help": "Tódalas páxinas na wiki e tódalas outras contribucións.",
+       "ipb-partial-help": "Páxinas ou nomes de espazo específicos.",
        "ipb-pages-label": "Páxinas",
        "ipb-namespaces-label": "Espazos de nomes",
        "badipaddress": "O enderezo IP non é válido",
        "confirm-unwatch-top": "Quere eliminar esta páxina da lista de vixilancia?",
        "confirm-rollback-button": "Aceptar",
        "confirm-rollback-top": "Quere reverter as edicións desta páxina?",
+       "confirm-rollback-bottom": "Esta acción reverterá de forma instantánea os cambios seleccionados desta páxina.",
        "confirm-mcrrestore-title": "Restaurar unha revisión",
        "confirm-mcrundo-title": "Desfacer un cambio",
        "mcrundofailed": "Erro ao desfacer",
        "logentry-rights-autopromote": "$1 foi {{GENDER:$2|promovido|promovida}} automaticamente de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|cargou}} \"$3\"",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|cargou}} unha nova versión de \"$3\"",
-       "logentry-upload-revert": "$1 {{GENDER:$2|cargou}} \"$3\"",
+       "logentry-upload-revert": "$1 {{GENDER:$2|reverteu}} $3 a unha versión antiga",
        "log-name-managetags": "Rexistro de xestión de etiquetas",
        "log-description-managetags": "Esta páxina contén unha lista das tarefas de xestión relacionadas con [[Special:Tags|tags]]. No rexistro figuran só aquelas accións realizadas de forma manual por un administrador; pódense crear ou borrar etiquetas por medio do software wiki sen que se engada unha nova entrada ao rexistro.",
        "logentry-managetags-create": "$1 {{GENDER:$2|created}} a etiqueta \"$4\"",
        "expand_templates_generate_rawhtml": "Amosar o HTML en bruto",
        "expand_templates_preview": "Vista previa",
        "expand_templates_preview_fail_html": "<em>Dado que o código HTML puro está activado en {{SITENAME}} e se produciu unha perda dos datos da sesión, a vista previa está oculta como precaución contra ataques mediante código JavaScript.</em>\n\n<strong>Se este é un intento lexítimo de acceso á vista previa, probe de novo.</strong>\nEn caso de que siga sen funcionar, intente [[Special:UserLogout|saír]] e volver entrar na súa conta e verifique que o seu navegador permite o uso de cookies neste sitio.",
-       "expand_templates_preview_fail_html_anon": "<em>Dado que o código HTML puro está activado en {{SITENAME}} e produciuse unha perda dos datos da sesión, a vista previa está oculta como precaución contra ataques mediante código JavaScript.</em>\n\n<strong>Se este é un intento lexítimo de acceso á vista previa, probe a [[UserLogin|iniciar a sesión]] e volver a entrar coa súa conta.</strong>",
+       "expand_templates_preview_fail_html_anon": "<em>Dado que o código HTML puro está activado en {{SITENAME}} e non iniciou sesión, a vista previa está oculta como precaución contra ataques mediante código JavaScript.</em>\n\n<strong>Se este é un intento lexítimo de acceso á vista previa, probe a [[Special:UserLogin|iniciar a sesión]] e ténteo de novo.</strong>",
        "expand_templates_input_missing": "Necesita proporcionar polo menos algún texto wiki de entrada.",
        "pagelanguage": "Cambiar a lingua da páxina",
        "pagelang-name": "Páxina",
        "log-action-filter-suppress-reblock": "Supresión de usuario por bloqueo reiterado",
        "log-action-filter-upload-upload": "Nova subida",
        "log-action-filter-upload-overwrite": "Resubida",
+       "log-action-filter-upload-revert": "Reverter",
        "authmanager-authn-not-in-progress": "O proceso de autenticación non está en progreso ou perdéronse os datos da sesión. Empece de novo desde o principio.",
        "authmanager-authn-no-primary": "A información de identificación proporcionada non pode ser autenticada.",
        "authmanager-authn-no-local-user": "As credenciais proporcionadas non están asociadas con ningún usuario neste wiki.",
        "authmanager-create-no-primary": "As credenciais subministradas non poden usarse para a creación da conta.",
        "authmanager-link-no-primary": "As credenciais subministradas non poden usarse para a ligazón da conta.",
        "authmanager-link-not-in-progress": "A vinculación da conta non está en progreso ou perdéronse os datos da sesión. Empece de novo desde o principio.",
-       "authmanager-authplugin-setpass-failed-title": "Fallou o cambio do contrasinal",
-       "authmanager-authplugin-setpass-failed-message": "O complemento de autenticación denegou o cambio de contrasinal.",
-       "authmanager-authplugin-create-fail": "O complemento de autenticación denegou a creación da conta.",
-       "authmanager-authplugin-setpass-denied": "O complemento de autenticación non permite o cambio de contrasinais.",
-       "authmanager-authplugin-setpass-bad-domain": "Dominio non válido.",
        "authmanager-autocreate-noperm": "A creación automatica de contas non está permitida.",
        "authmanager-autocreate-exception": "A creación automatica de contas foi desactivada temporalmente debido a erros previos.",
        "authmanager-userdoesnotexist": "O usuario \"$1\" non está rexistrado.",
        "passwordpolicies-policy-maximalpasswordlength": "O contrasinal debe conter menos de $1 {{PLURAL:$1|carácter|caracteres}}",
        "passwordpolicies-policy-passwordcannotbepopular": "O contrasinal non pode {{PLURAL:$1|ser o contrasinal máis habitual|estar na lista dos $1 máis habituais}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "O contrasinal non pode estar na lista dos 100.000 contrasinais máis usados.",
+       "passwordpolicies-policyflag-forcechange": "debe modificarse ó iniciar sesión",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "suxerir cambio ó iniciar sesión",
        "easydeflate-invaliddeflate": "O contido fornecido non está debidamente comprimido",
        "unprotected-js": "Por motivos de seguridade non se pode cargar JavaScript desde páxinas non protexidas. Por favor, cree só JavaScript no espazo de nomes MediaWiki ou como subpáxina de usuario"
 }
index 8bddb37..ccbe44d 100644 (file)
        "group-all": "(soglle)",
        "grouppage-bot": "{{ns:project}}:Robotam",
        "grouppage-sysop": "{{ns:project}}:Karbhari",
+       "right-move": "Panam haloi",
        "right-writeapi": "Borovpeache API-cho upeog",
        "newuserlogpage": "Vapurpi rochnnechem sotr",
        "rightslog": "Vaporpeachea hokancho sotr",
        "recentchanges-label-plusminus": "Hea panacho akar itlea baitani bodol'lo",
        "recentchanges-legend-heading": "<strong>Kunji:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|nove pananchi suchi]]-ui polloi)",
+       "rcfilters-tag-remove": "'$1' kadd",
        "rcfilters-activefilters-hide": "Lipoi",
        "rcfilters-activefilters-show": "Dakhoi",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|bodol}}, $2",
+       "rcfilters-days-title": "Halinche dis",
+       "rcfilters-hours-title": "Halinche voram",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|dis}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|vor|voram}}",
+       "rcfilters-savedqueries-rename": "Nanv bodol",
+       "rcfilters-savedqueries-remove": "Kadun udoi",
+       "rcfilters-savedqueries-new-name-label": "Nanv",
+       "rcfilters-savedqueries-cancel-label": "Rod'd kor",
+       "rcfilters-show-new-changes": "Soglleavon noveo bodol polloi",
+       "rcfilters-filter-editsbyself-label": "Tuven kel'leo bodol",
+       "rcfilters-filter-editsbyself-description": "Tujeo svotacheo yogdanam.",
+       "rcfilters-filter-editsbyother-label": "Dusreanim kel'le bodol",
+       "rcfilters-filter-bots-label": "Robot",
+       "rcfilters-filter-minor-label": "Dhakte bodol",
+       "rcfilters-filter-pageedits-label": "Panacheo sompadonam",
+       "rcfilters-filter-categorization-label": "Vorgache bodol",
+       "rcfilters-filtergroup-lastRevision": "Akherchim uzollnnim",
+       "rcfilters-filter-lastrevision-label": "Sogleanvon novi uzollnni",
+       "rcfilters-tag-prefix-namespace-inverted": "$1 <strong>:nhoi</strong>",
        "rcnotefrom": "Sokoil <strong>$3, $4<strong> savn {{PLURAL:$5|zalelem bodol dilam|zalelem bodol dileant}} (<strong>$1<strong> meren {{PLURAL:$5|dakhoilam|dakhoileant}}).",
        "rclistfrom": "$3 $2 savn suru zatelim nove bodol dakhoi",
        "rcshowhideminor": "$1 dhakte bodol",
        "reblock-logentry": "addavpachem bosovp bodol’lam [[$1]] hache khatir sompacho vell dilam $2 $3‎",
        "block-log-flags-nocreate": "Khatem rochop opatr kelam",
        "proxyblocker": "Protinidhi-sirvidor addavpi‎",
+       "move-page": "$1 haloi",
+       "move-page-legend": "Pan haloi",
        "move-watch": "Hea panar dixtt dovor",
        "movepagebtn": "Pan haloi",
+       "movepage-moved": "<strong>\"$1\" haka \"$2\" hanga haloila</strong>",
+       "movepage-moved-redirect": "Punornirdexon rochun ailam.",
+       "movepage-moved-noredirect": "Punornirdexon rochop addaila.",
+       "movepage-page-moved": "$1 panak $2 hanga haloila.",
+       "movepage-page-unmoved": "$1 haka $2 hanga halounk zaunk na.",
        "movelogpage": "Pan halovneancho sotr",
        "movereason": "Karonn:",
        "revertmove": "porti",
index 75b4c20..9ca872d 100644 (file)
@@ -64,8 +64,8 @@
        "tog-uselivepreview": "પૃષ્ઠ ફરીથી લોડ કર્યા વગર પૂર્વાવલોકનો બતાવો",
        "tog-forceeditsummary": "કોરો 'ફેરફાર સારાંશ' ઉમેરતા પહેલા મને ચેતવો",
        "tog-watchlisthideown": "'મારી ધ્યાનસુચી'માં મે કરેલા ફેરફારો છુપાવો",
-       "tog-watchlisthidebots": "ધ્યાનસુચીમાં બોટ દ્વારા થયેલા ફેરફાર સંતાડો.",
-       "tog-watchlisthideminor": "'મારી ધ્યાનસુચી'માં નાનાં ફેરફારો છુપાવો",
+       "tog-watchlisthidebots": "ધ્યાનસુચીમાં બોટ દ્વારા થયેલા ફેરફાર સંતાડો",
+       "tog-watchlisthideminor": "ધ્યાનસુચીમાં નાનાં ફેરફારો છુપાવો",
        "tog-watchlisthideliu": "લોગ થયેલા સભ્ય દ્વારા કરવામાં આવેલ ફેરફાર ધ્યાનસુચીમાં છુપાવો.",
        "tog-watchlistreloadautomatically": "જ્યારેપણ ફિલ્ટર બદલાઈ જાય ત્યારે આપમેળે જોવાની સૂચિ ફરીથી લોડ કરો (JavaScript આવશ્યક છે)",
        "tog-watchlistunwatchlinks": "દૃશ્યયાદી પ્રવેશોમાં સીધી નિષ્ક્રિય/દૃશ્ય લિંક્સ ઉમેરો (ટૉગલ કાર્યક્ષમતા માટે આવશ્યક JavaScript)",
        "formerror": "ત્રુટિ: પત્રક રજૂ થયું નહીં",
        "badarticleerror": "આ ક્રિયા આ પાના ઉપર કરવી શક્ય નથી.",
        "cannotdelete": "ફાઇલ કે પાનું \"$1\" હટાવી શકાયું નથી.\nશક્ય છે કે અન્ય કોઈએ પહેલેથી હટાવી દીધું હોય.",
-       "cannotdelete-title": "\"$1\" àªªàª¾àª¨à«\81àª\82 àª\95ાઢà«\80 àª¶àª\95તા નથી",
+       "cannotdelete-title": "\"$1\" àªªàª¾àª¨à«\81àª\82 àª¦à«\82ર àª\95રà«\80 àª¶àª\95ાતà«\81àª\82 નથી",
        "delete-hook-aborted": "દૂર કરવાનું હૂક વડે રોકી રાખવામાં આવ્યું.\nતે કોઇ કારણ આપતું નથી.",
        "no-null-revision": "પૃષ્ઠ \"$1\" માટે નવો નલ પુનરાવર્તન બનાવી શક્યું નથી",
        "badtitle": "ખરાબ શિર્ષક",
        "createacct-benefit-body2": "{{PLURAL:$1|પાનું|પાનાં}}",
        "createacct-benefit-body3": "તાજેતરના {{PLURAL:$1|યોગદાનકર્તા|યોગદાનકર્તાઓ}}",
        "badretype": "તમે દાખલ કરેલ ગુપ્તસંજ્ઞા મળતી આવતી નથી.",
-       "userexists": "દાખલ કરેલું સભ્યનામ વપરાશમાં છે.</br>\nકૃપયા અન્ય નામ પસંદ કરો.",
+       "userexists": "દાખલ કરેલું સભ્યનામ વપરાશમાં છે.\nકૃપયા અન્ય નામ પસંદ કરો.",
        "loginerror": "પ્રવેશ ત્રુટિ",
        "createacct-error": "ખાતું બનાવવામાં ક્ષતિ આવી",
        "createaccounterror": "ખાતું ખોલી શકાયું નથી: $1",
        "nocookiesfornew": "સભ્ય ખાતાની પુષ્ટિ નથી થઇ, અમે તેના સ્ત્રોતની પુષ્ટિ ન કરી શક્યા.\nખાત્રી કરો કે તમે કુકીઝ સક્રીય કરી છે, અને પાનું ફરીથી ચડાવો",
        "noname": "તમે પ્રમાણભૂત સભ્યનામ જણાવેલ નથી.",
        "loginsuccesstitle": "પ્રવેશીત",
-       "loginsuccess": "'''તમે હવે {{SITENAME}}માં \"$1\" તરીકે પ્રવેશી ચુક્યા છો.'''",
+       "loginsuccess": "<strong>તમે હવે {{SITENAME}}માં \"$1\" તરીકે પ્રવેશી ચુક્યા છો.</strong>",
        "nosuchuser": "\"$1\" નામ ધરાવતો કોઇ સભ્ય અસ્તિત્વમાં નથી.\n\nસભ્યનામો અક્ષરસંવેદી (કેસ સેન્સિટીવ) હોય છે.\n\nકૃપા કરી સ્પેલીંગ/જોડણી ચકાસો અથવા [[Special:CreateAccount|નવું ખાતુ ખોલો]].",
-       "nosuchusershort": "\"$1\" નામનો કોઇ સભ્ય નથીતમારી જોડણી તપાસો.",
-       "nouserspecified": "તમારે સભ્ય નામ દર્શાવવાની જરૂર છે.",
-       "login-userblocked": "àª\86 àª¯à«\81àª\9dર àªªà«\8dરતિબàª\82ધિત àª\9bà«\87. àªªà«\8dરવà«\87શ àªµàª°à«\8dàª\9cà«\80ત.",
-       "wrongpassword": "ખોટું સભ્યનામ અથવા ગુપ્ત સંજ્ઞા (પાસવર્ડ‌) દાખલ કરે છે.\nફરીથી પ્રયત્ન કરો.",
+       "nosuchusershort": "\"$1\" નામનો કોઇ સભ્ય નથી.\nતમારી જોડણી તપાસો.",
+       "nouserspecified": "તમારે સભ્યનામ દર્શાવવાની જરૂર છે.",
+       "login-userblocked": "àª\86 àª¸àª­à«\8dય àªªà«\8dરતિબàª\82ધિત àª\9bà«\87. àªªà«\8dરવà«\87શ àªµàª°à«\8dàª\9cà«\80ત àª\9bà«\87.",
+       "wrongpassword": "ખોટું સભ્યનામ અથવા ગુપ્ત સંજ્ઞા (પાસવર્ડ‌) દાખલ કરે છે.\nફરીથી પ્રયત્ન કરો.",
        "wrongpasswordempty": "તમે ગુપ્ત સંજ્ઞા લખવાનું ભુલી ગયા લાગો છો.\nફરીથી પ્રયત્ન કરો.",
-       "passwordtooshort": "ગુપ્ત સંજ્ઞામાં ઓછામાં {{PLURAL:$1|ઓછો એક અક્ષર હોવો |ઓછા $1 અક્ષર હોવા}} જોઇએ.",
+       "passwordtooshort": "ગુપ્ત સંજ્ઞામાં ઓછામાં {{PLURAL:$1|ઓછો એક અક્ષર હોવો|ઓછા $1 અક્ષર હોવા}} જોઇએ.",
        "passwordtoolong": "ગુપ્ત સંજ્ઞા (પાસવર્ડ) {{PLURAL:$1|1 અક્ષર|$1 અક્ષરો}} કરતા લાંબો રાખી શકાતો નથી.",
        "password-name-match": "તમારી ગુપ્તસંજ્ઞા તમારા સભ્યનામ કરતાં અલગ જ હોવી જોઇએ.",
        "password-login-forbidden": "આ સભ્યનામ અને ગુપ્તસંજ્ઞા વાપરવા પર પ્રતિબંધ છે.",
        "passwordsent": "\"$1\" ની નવી ગુપ્તસંજ્ઞા (પાસવર્ડ) આપના ઇમેઇલ પર મોકલવામાં આવ્યો છે.\nકૃપા કરી તે મળ્યા બાદ ફરી લોગ ઇન કરો.",
        "blocked-mailpassword": "ફેરફાર કરવા માટે તમારું IP એડ્રેસ સ્થગિત કરી દેવાયું છે, તેથી દૂરુપયોગ ટાળવા માટે તમને આ IP એડ્રેસ પરથી ગુપ્તસંજ્ઞા ફરી મેળવવાની છૂટ નથી.",
        "eauthentsent": "પુષ્ટિ કરવા માટે નિશ્ચિત થયેલા સરનામાં પર ઇમેલ મોકલવામાં આવ્યો છે.\nએ જ સરનામે બીજો ઇમેલ થતાં પહેલાં તમારે ઇમેલમાં લખેલી સૂચનાઓ પ્રમાણે કરવું પડશે જેથી એ પુષ્ટિ થઇ શકે કે આપેલું સરનામું તમારું છે.",
-       "throttled-mailpassword": "ગુપ્ત સંજ્ઞા યાદ અપાવતી ઇમેઇલ છેલ્લા {{PLURAL:$1|કલાકમાં|$1 કલાકોમાં}} મોકલેલી છે.\nદૂરુપયોગ રોકવા માટે, {{PLURAL:$1|કલાકમાં|$1 કલાકોમાં}} ફક્ત એક જ આવી મેઇલ કરવામાં આવે છે.",
+       "throttled-mailpassword": "ગુપ્ત સંજ્ઞા યાદ અપાવતી ઇમેઇલ છેલ્લા {{PLURAL:$1|કલાક|$1 કલાકો}}માં મોકલેલી છે.\nદૂરુપયોગ રોકવા માટે, {{PLURAL:$1|કલાક|$1 કલાકો}}માં ફક્ત એક જ આવી મેઇલ કરવામાં આવે છે.",
        "mailerror": "મેઇલ મોકલવામાં ત્રુટિ: $1",
        "acct_creation_throttle_hit": "આ વિકિના મુલાકાતીઓએ તમારું IP વાપરીને પાછલા $2માં {{PLURAL:$1|1 ખાતું |$1 ખાતા}} ખોલ્યાં છે, જે પરવાનગીની મહત્તમ સંખ્યા છે. આને પરિણામે મુલાકાતી આ ક્ષણેવધુ ખાતા નહીં ખોલી શકે.",
        "emailauthenticated": "તમારૂં ઇ-મેઇલ સરનામું $2 ના $3 સમયે પ્રમાણિત કરેલું છે.",
        "accmailtext": "[[User talk:$1|$1]] માટે રચેલ ગુપ્તસંજ્ઞા $2 ને મોકલાવી દેવાઇ છે. આ નવા ખાતાનીગુપ્તસંજ્ઞા પ્રવેશ કર્યા બાદ ''[[Special:ChangePassword|ગુપ્તસંજ્ઞા બદલો]]'' વાપરીને બદલી શકાશે.",
        "newarticle": "(નવીન)",
        "newarticletext": "તમે અસ્તિત્વ ન ધરાવતા પાનાંની કડી ખોલી છે.\nપાનું બનાવવા માટે, નીચેની જગ્યામાં લખવાનું શરૂ કરો (વધુ માહિતી માટે જુઓ [$1 મદદ પાનું]).\nજો તમે ભૂલથી અહીં આવી ગયા હોવ તો, તમારા બ્રાઉઝરનું <strong>પાછાં જાવ</strong> બટન ક્લિક કરી પાછાં જાવ.",
-       "anontalkpagetext": "----\n<em>આ એક અજ્ઞાત સભ્યનું ચર્ચા પાનું છે જેમણે ક્યાં તો પોતાનું ખાતું ખોલ્યું નથી અથવા તો તેને વાપરતા નથી.</em>\nઆથી તેમને ઓળખવા માટે અમારે સાંખ્યિક IP સરનામાની મદદ લેવી પડી છે.\nઆવું IP સરનામું ઘણાં અન્ય સભ્યો પણ વાપરતા હોઇ શકે.\nજો તમે અજ્ઞાત સભ્ય હોવ અને માનતા હોવ કે અસંધિત ટિપ્પણીઓ તમારી તરફ વાળવામાં આવી છે, તો કૃપયા  [[Special:CreateAccount|create an account]] અથવા [[Special:UserLogin|log in]]નો ઉપયોગ કરશો જેથી તમને કોઈ અજ્ઞાત સભ્ય સમજવાની ભૂલ ભવિષ્યમાં ટાળી શકાય.",
+       "anontalkpagetext": "----\n<em>આ એક અજ્ઞાત સભ્યનું ચર્ચા પાનું છે, જેમણે ક્યાં તો પોતાનું ખાતું ખોલ્યું નથી અથવા તો તેને વાપરતા નથી.</em>\n\nઆથી તેમને ઓળખવા માટે અમારે સાંખ્યિક IP સરનામાની મદદ લેવી પડી છે.\n\nઆવું IP સરનામું ઘણાં અન્ય સભ્યો પણ વાપરતા હોઇ શકે છે.\n\nજો તમે અજ્ઞાત સભ્ય હોવ અને માનતા હોવ કે અસંધિત ટિપ્પણીઓ તમારી તરફ વાળવામાં આવી છે, તો કૃપયા [[Special:CreateAccount|ખાતું ખોલો]] અથવા [[Special:UserLogin|પ્રવેશ કરો]]નો ઉપયોગ કરશો જેથી તમને કોઈ અજ્ઞાત સભ્ય સમજવાની ભૂલ ભવિષ્યમાં ટાળી શકાય.",
        "noarticletext": "આ પાનામાં હાલમાં કોઇ લખાણ નથી.\nતમે બીજાં પાનાંમાં [[Special:Search/{{PAGENAME}}|આ પાનાંના શીર્ષક માટે શોધી શકો છો]], <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} સંલગ્ન માહિતિ પત્રકોમાં શોધી શકો છો],\nઅથવા [{{fullurl:{{FULLPAGENAME}}|action=edit}} આ પાનું બનાવી શકો છો]</span>.",
        "noarticletext-nopermission": "આ પાનામાં હાલમાં કોઇ માહિતિ નથી.\nતમે  [[Special:Search/{{PAGENAME}}|આ શબ્દ]] ધરાવતાં અન્ય લેખો શોધી શકો છો, અથવા <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} સંલગ્ન માહિતિ પત્રકોમાં શોધી શકો છો], પરંતુ તમને આ પાનું બનાવવાની મંજૂરી નથી.",
        "userpage-userdoesnotexist": "સભ્ય ખાતું \"<nowiki>$1</nowiki>\"ની નોંધણીનથી થઈ.\nશું તમે ખરેખર આ પાનાની રચના કે ફેરફાર કરવા માંગો છો",
        "ignorewarnings": "કોઇ પણ ચેતવણી અવગણો",
        "minlength1": "ફાઇલ નામની લંબાઇ કમ સે કમ એક અક્ષર જેટલી તો હોવી જ જોઇએ.",
        "illegalfilename": "ફાઇલનામ \"$1\" એવા ચિન્હો ધરાવે છે જેનો પ્રયોગ શીર્ષકોમાં વર્જિત  છે.\nકૃપયા ફાઇઅલ નું નામ બદલીને ફરી ચઢાવો.",
-       "filename-toolong": "ફાઈલ નામો 240 બાઇટ્સ કરતાં લાંબા હોઈ શકે નહિં.",
+       "filename-toolong": "ફાઈલનામો ૨૪૦ બાઇટ્સ કરતાં લાંબા હોઈ શકે નહીં.",
        "badfilename": "ફાઇલ નામ  \"$1\" નામે બદલાયું છે.",
        "filetype-mime-mismatch": "ફાઇલ પ્રકાર \".$1\"  શોધાયેલ MIME પ્રકારની ફાઇલ ($2) સાથે મેળ ખાતો નથી.",
        "filetype-badmime": "MIME પ્રકારની \"$1\"  ફાઇલ ચડાવવાની પરવાનગી નથી",
        "ipbreason-dropdown": "*સામાન્ય પ્રતિબંધ કારણો\n** ખોટી માહિતી ઉમેરાઈ  \n** પાનામાંથી માહિતી ભૂંસી નાંખી\n** અનાવશ્યક બાહ્ય કડીઓ ઉમેરી \n** પાનામાં મૂર્ખામીભરી/અર્થહીન માહિતી ઉમેરી\n** ત્રાસદાયક વર્તન \n** ઘણા ખાતાઓ અને દુરુપયોગ\n** અસ્વીકાર્ય સભ્ય નામ\n** આત્યંતિક ભાંગફોડ",
        "ipb-hardblock": "આ IP સરનામાં પરથી લોગ-ઈન થયેલા સભ્યોને ફેરફાર કરતા અટકાવો.",
        "ipbcreateaccount": "ખાતા ખોલવા પર પ્રતિબંધ",
-       "ipbemailban": "સભà«\8dયના àª\87-મà«\87લ àª®à«\8bàª\95લવા àªªàª° àªªà«\8dરતિબàª\82ધ àª®à«\82àª\95à«\8b",
+       "ipbemailban": "àª\87મà«\87લ àª®à«\8bàª\95લાàª\87 àª°àª¹à«\8dયà«\8b àª\9bà«\87",
        "ipbenableautoblock": "આ સભ્ય દ્વારા વપરાયેલ  IP સરનામા પર અને તત-પશ્ચ્યાત વપરાયેલ IP સરનામા ને સ્વયંચાલિત રીતે રોક લગાવો",
        "ipbsubmit": "આ સભ્ય પર પ્રતિબંધ મૂકો",
        "ipbother": "અન્ય સમય:",
        "anonymous": "{{SITENAME}} ના અ‍જ્ઞાત {{PLURAL:$1|સભ્ય|સભ્યો}}",
        "siteuser": "{{SITENAME}} સભ્ય $1",
        "anonuser": "{{SITENAME}} અજ્ઞાત સભ્ય  $1",
-       "lastmodifiedatby": "આ પાનામાં છેલ્લે  $3 દ્વારા $1 તારીખે $2 વાગ્યે ફેરફાર થયો",
+       "lastmodifiedatby": "આ પાનામાં છેલ્લે $3 દ્વારા $1 તારીખે $2 વાગે ફેરફાર થયો હતો.",
        "othercontribs": "$1 ના કાર્ય પર આધારિત",
        "others": "અન્યો",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|સભ્ય|સભ્યો}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|સભ્ય}}|સભ્યો}} $1",
        "anonusers": "{{SITENAME}} અજ્ઞાત {{PLURAL:$2|સભ્ય|સભ્યો}} $1",
        "creditspage": "પાનાના ઋણ સ્વીકાર",
        "nocredits": "આ પાના માટે કોઇ પણ ઋણસ્વીકાર મોજુદ નથી",
index 9362132..a9c4ba1 100644 (file)
        "viewprevnext": "Duba ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-new": "''Zaku iya ƙirƙirar shafin \"[[:$1]]\"''.",
        "searchprofile-everything": "Duk abin da",
+       "searchprofile-articles-tooltip": "Nemo a $1",
        "search-result-size": "$1 ({{PLURAL:$2|1 kalma|$2 kalmomi}})",
        "search-redirect": "(an turo daga $1)",
        "search-section": "(sashe $1)",
        "imagelinks": "Amfani da fayil",
        "linkstoimage": "{{PLURAL:$1|Wannan shafi yana|wanɗannan shafuna $1 suna}} amfani da wannan fayil:",
        "sharedupload": "Wannan fayil na da tushe daga $1 kuma wasu shire-shire suna iya amfani da shi.",
+       "sharedupload-desc-here": "Wannan hoto yazo daga $1 kuma za'a iya amfani dashi a wasu projects.\nAnan kasa an nuna [$2 asalin bayanin shi]",
        "uploadnewversion-linktext": "Ɗauki sabon zubi na wannan fayil",
        "upload-disallowed-here": "Ba zaku iya sabunta wannan hoto ba",
        "filerevert-comment": "Dalili:",
index 7baf17c..9772a3f 100644 (file)
@@ -85,6 +85,7 @@
        "tog-norollbackdiff": "לא להציג את ההבדלים בין הגרסאות לאחר ביצוע שחזור",
        "tog-useeditwarning": "הצגת אזהרה בעת עזיבת דף עריכה עם שינויים שטרם נשמרו",
        "tog-prefershttps": "תמיד להשתמש בתקשורת מאובטחת לאחר הכניסה לחשבון",
+       "tog-showrollbackconfirmation": "הצגת הודעת אישור לאחר לחיצה על קישור \"שחזור\"",
        "underline-always": "תמיד",
        "underline-never": "לעולם לא",
        "underline-default": "ברירת המחדל של העיצוב או של הדפדפן",
        "badretype": "הסיסמאות שהזנת אינן תואמות.",
        "usernameinprogress": "יצירת חשבון עבור שם המשתמש הזה כבר התחילה.\nנא להמתין.",
        "userexists": "שם המשתמש שבחרת כבר נמצא בשימוש.\nנא לבחור שם אחר.",
+       "createacct-normalization": "שם המשתמש שבחרת ישונה ל\"$2\" עקב הגבלות טכניות.",
        "loginerror": "שגיאה בכניסה לחשבון",
        "createacct-error": "שגיאה ביצירת חשבון",
        "createaccounterror": "לא ניתן היה ליצור את החשבון: $1",
        "page_first": "ראשון",
        "page_last": "אחרון",
        "histlegend": "בחירת גרסאות להשוואה: יש לבחור את הגרסאות שברצונך להשוות ולאחר מכן להקיש על Enter או ללחוץ על הכפתור שלמטה.<br />\nמקרא: <strong>({{int:cur}})</strong> = השוואה עם הגרסה הנוכחית, <strong>({{int:last}})</strong> = השוואה עם הגרסה הקודמת, <strong>{{int:minoreditletter}}</strong> = עריכה משנית.",
-       "history-fieldset-title": "×\97×\99פ×\95ש גרסאות",
+       "history-fieldset-title": "ס×\99× ×\95×\9f גרסאות",
        "history-show-deleted": "גרסאות מוסתרות בלבד",
        "histfirst": "הישנות ביותר",
        "histlast": "החדשות ביותר",
        "historysize": "({{PLURAL:$1|בית אחד|$1 בתים}})",
-       "historyempty": "(ריק)",
+       "historyempty": "ריק",
        "history-feed-title": "היסטוריית גרסאות",
        "history-feed-description": "היסטוריית הגרסאות של הדף הזה בוויקי",
        "history-feed-item-nocomment": "$1 ב־$2",
        "right-reupload-own": "העלאת גרסאות חדשות של קבצים קיימים שהועלו על־ידי המשתמש עצמו",
        "right-reupload-shared": "דריסה מקומית של קבצים מאתר קובצי המדיה המשותף",
        "right-upload_by_url": "העלאת קבצים מכתובת אינטרנט (URL)",
-       "right-purge": "ניקוי זיכרון המטמון של דף ללא מעבר בדף אישור",
+       "right-purge": "ניקוי זיכרון המטמון של דף",
        "right-autoconfirmed": "עקיפת ההגבלה על קצב הפעולות שניתן לבצע מכתובת IP מסוימת",
        "right-bot": "התייחסות לעריכות כאוטומטיות",
        "right-nominornewtalk": "ביטול שליחת התראה על הודעה חדשה למשתמש בעת עריכה משנית בדף השיחה שלו",
        "delete-confirm": "מחיקת הדף \"$1\"",
        "delete-legend": "מחיקה",
        "historywarning": "<strong>אזהרה:</strong> לדף שעומד להימחק יש היסטוריית שינויים של {{PLURAL:$1|גרסה אחת|$1 גרסאות}}:",
-       "historyaction-submit": "×\94צ×\92×\94",
+       "historyaction-submit": "×\94צ×\92ת ×\94×\92רס×\90×\95ת",
        "confirmdeletetext": "ניתן להשתמש בטופס שלהלן כדי למחוק דף יחד עם כל ההיסטוריה שלו.\nנא לאשר שזה אכן מה שהתכוונת לעשות, שהתוצאות של הפעולה הזו ידועות לך, ושהמעשה מבוצע בהתאם ל[[{{MediaWiki:Policy-url}}|נוהלי האתר]].",
        "actioncomplete": "הפעולה בוצעה",
        "actionfailed": "הפעולה נכשלה",
        "deleting-backlinks-warning": "<strong>אזהרה:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|דפים אחרים]] מקשרים לדף זה (שעומד להימחק) או מכלילים אותו.",
        "deleting-subpages-warning": "<strong>אזהרה:</strong> לדף שעומד להימחק יש [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|דף משנה|$1 דפי משנה|51=יותר מ־50 דפי משנה}}]].",
        "rollback": "שחזור עריכות",
+       "rollback-confirmation-confirm": "לאישורך:",
+       "rollback-confirmation-yes": "שחזור",
+       "rollback-confirmation-no": "ביטול",
        "rollbacklink": "שחזור",
        "rollbacklinkcount": "שחזור {{PLURAL:$1|עריכה אחת|$1 עריכות}}",
        "rollbacklinkcount-morethan": "שחזור יותר מ{{PLURAL:$1|עריכה אחת|־$1 עריכות}}",
        "revertpage": "שוחזר מעריכות של [[Special:Contributions/$2|$2]] ([[User talk:$2|שיחה]]) לעריכה האחרונה של [[User:$1|$1]]",
        "revertpage-nouser": "שוחזר מעריכות של משתמש מוסתר לעריכה האחרונה של {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "שוחזר מעריכות של {{GENDER:$3|$1}}\nלעריכה האחרונה של {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "שוחזר מעריכות של $1\nלעריכה האחרונה של $2. [$3 הצגת שינויים]",
        "sessionfailure-title": "בעיה בחיבור",
        "sessionfailure": "נראה שיש בעיה בחיבור שלך לאתר;\nפעולה זו בוטלה כאמצעי זהירות נגד התחזות לתקשורת ממחשבך.\nנא לשלוח מחדש את הטופס.",
        "changecontentmodel": "שינוי מודל התוכן של דף",
        "mycontris": "תרומות",
        "anoncontribs": "תרומות",
        "contribsub2": "עבור {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "עבור {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "חשבון המשתמש \"$1\" אינו רשום.",
        "negative-namespace-not-supported": "אין תמיכה במרחבי שם בעלי ערך שלילי.",
        "nocontribs": "לא נמצאו שינויים המתאימים לקריטריונים אלו.",
        "ipb-confirm": "אישור החסימה",
        "ipb-sitewide": "כל האתר",
        "ipb-partial": "חלקית",
+       "ipb-sitewide-help": "כל דף באתר הוויקי וכל שינוי אחר באתר.",
+       "ipb-partial-help": "דפים מסוימים או מרחבי שם מסוימים.",
        "ipb-pages-label": "דפים",
        "ipb-namespaces-label": "מרחבי שם",
        "badipaddress": "כתובת IP שגויה",
        "confirm-unwatch-top": "להסיר את הדף הזה מרשימת המעקב שלך?",
        "confirm-rollback-button": "אישור",
        "confirm-rollback-top": "לשחזר את העריכות בדף זה?",
+       "confirm-rollback-bottom": "פעולה זו תשחזר באופן מיידי את השינויים שבחרת בדף זה.",
        "confirm-mcrrestore-title": "שחזור גרסה",
        "confirm-mcrundo-title": "ביטול שינוי",
        "mcrundofailed": "הביטול נכשל",
        "logentry-rights-autopromote": "$1 קודם אוטומטית מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|העלה|העלתה}} גרסה חדשה של $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|×\94×¢×\9c×\94\94×¢×\9cת×\94}} ×\90ת $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|ש×\97×\96ר|ש×\97×\96ר×\94}} ×\90ת $3 ×\9c×\92רס×\94 ×\99שנ×\94",
        "log-name-managetags": "יומן ניהול תגיות",
        "log-description-managetags": "דף זה כולל רשימה של פעולות ניהול הקשורות ל[[Special:Tags|תגיות]]. היומן כולל רק פעולות שבוצעו ידנית על־ידי מפעיל מערכת; ייתכן שתגיות ייווצרו או יימחקו על־ידי תוכנת הוויקי ללא הוספת ערך ליומן זה.",
        "logentry-managetags-create": "$1 {{GENDER:$2|יצר|יצרה}} את התגית \"$4\"",
        "log-action-filter-suppress-reblock": "העלמות של משתמשים באמצעות חסימה מחדש",
        "log-action-filter-upload-upload": "העלאות של קבצים חדשים",
        "log-action-filter-upload-overwrite": "דריסות של קבצים קיימים",
+       "log-action-filter-upload-revert": "שחזורי קבצים לגרסה ישנה",
        "authmanager-authn-not-in-progress": "האימות נכשל או שנתוני הפעולה נאבדו. נא להתחיל את התהליך מחדש.",
        "authmanager-authn-no-primary": "לא ניתן היה לאמת את נתוני ההזדהות שסופקו.",
        "authmanager-authn-no-local-user": "נתוני ההזדהות שסופקו אינם שייכים לשום משתמש באתר זה.",
        "authmanager-create-no-primary": "נתוני ההזדהות שסופקו לא יכולים להיות בשימוש ביצירת חשבון.",
        "authmanager-link-no-primary": "נתוני ההזדהות שסופקו לא יכולים להיות בשימוש לשם קישור חשבונות.",
        "authmanager-link-not-in-progress": "קישור החשבונות נכשל או שנתוני הפעולה נאבדו. נא להתחיל את התהליך מחדש.",
-       "authmanager-authplugin-setpass-failed-title": "שינוי הסיסמה נכשל",
-       "authmanager-authplugin-setpass-failed-message": "תוסף האימות דחה את שינוי הסיסמה.",
-       "authmanager-authplugin-create-fail": "תוסף האימות דחה את יצירת החשבון.",
-       "authmanager-authplugin-setpass-denied": "תוסף האימות אינו מאפשר לשנות סיסמאות.",
-       "authmanager-authplugin-setpass-bad-domain": "דומיין לא תקין.",
        "authmanager-autocreate-noperm": "אין אפשרות ליצור חשבונות באופן אוטומטי.",
        "authmanager-autocreate-exception": "יצירת חשבונות אוטומטית מבוטלת באופן אוטומטי בשל שגיאות קודמות.",
        "authmanager-userdoesnotexist": "חשבון המשתמש \"$1\" אינו רשום.",
        "passwordpolicies-policy-maximalpasswordlength": "הסיסמה חייבת להיות קצרה יותר {{PLURAL:$1|מתו אחד|מ־$1 תווים}}",
        "passwordpolicies-policy-passwordcannotbepopular": "הסיסמה לא יכולה להיות זהה {{PLURAL:$1|לסיסמה נפוצה|לאחת הסיסמאות שנמצאות ברשימה של $1 הסיסמאות הנפוצות}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "הסיסמה לא יכולה להיות ברשימת 100,000 הסיסמאות הנפוצות ביותר.",
+       "passwordpolicies-policyflag-forcechange": "לדרוש שינוי בעת כניסה לחשבון",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "להציע שינוי בעת כניסה לחשבון",
        "easydeflate-invaliddeflate": "התוכן שהועבר אינו דחוס כנדרש",
        "unprotected-js": "מסיבות אבטחה, לא ניתן לטעון JavaScript מדפים שאינם מוגנים. ניתן ליצור סקריפטי JavaScript רק במרחב השם \"מדיה ויקי:\" או בדפי משנה של דף המשתמש."
 }
index 0a58ddf..17137af 100644 (file)
@@ -96,7 +96,8 @@
                        "Tavleen",
                        "Jayantanth",
                        "Gopalindians",
-                       "Prong$31"
+                       "Prong$31",
+                       "Eisheeta"
                ]
        },
        "tog-underline": "कड़ी रेखांकित:",
        "tog-norollbackdiff": "सम्पादन वापस लेने के बाद अन्तर न दिखायें",
        "tog-useeditwarning": "जब मैं किसी सम्पादन पृष्ठ को बिना बदलावों को बिना सहेजे छोड़ूँ तो मुझे सूचित करें।",
        "tog-prefershttps": "सत्र आरम्भ करते समय सदैव सुरक्षित कनेक्शन का प्रयोग करें",
+       "tog-showrollbackconfirmation": "रोलबैक लिंक पर क्लिक करते समय एक पुष्टिकरण संकेत दिखाएं",
        "underline-always": "सदैव",
        "underline-never": "कभी नहीं",
        "underline-default": "त्वचा या प्राथमिक ब्राउज़र",
        "badretype": "आपने जो कूटशब्द दिये हैं वे एक दूसरे से नहीं मिलते। फिर से लिखें।",
        "usernameinprogress": "इस प्रयोक्ता का खाता निर्माण अभी चालू है।\nकृपया प्रतीक्षा करें।",
        "userexists": "आपका दिया सदस्यनाम पहले से प्रयोग में है।\nकृपया कोई अन्य सदस्यनाम चुनें।",
+       "createacct-normalization": "आपका उपयोगकर्ता नाम तकनीकी प्रतिबंधों के कारण \"$2\" में समायोजित किया जाएगा।",
        "loginerror": "लॉग इन त्रुटि",
        "createacct-error": "खाता निर्माण त्रुटि",
        "createaccounterror": "खाता नहीं बन पाया: $1",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]) के संपादनों को हटाकर [[User:$1|$1]] के अन्तिम अवतरण को पूर्ववत किया",
        "revertpage-nouser": "(सदस्य नाम हटाया गया है) के संपादनों को हटाकर {{GENDER:$1|[[User:$1|$1]]}} के अन्तिम अवतरण को पूर्ववत किया।",
        "rollback-success": "{{GENDER:$3|$1}} के संपादन हटाए;\n{{GENDER:$4|$2}} द्वारा संपादित अन्तिम अवतरण को पुनर्स्थापित किया।",
-       "rollback-success-notify": "$1 के सम्पादन वापिस लौटाए;\n$2 द्वारा संपादित अंतिम संस्करण पुनर्स्थापित किया। [$3 बदलाव दिखाएँ]",
        "sessionfailure-title": "सत्र विफलता",
        "sessionfailure": "ऐसा प्रतीत होता है कि आपके लॉगिन सत्र के साथ कोई समस्या है।\nसत्र अपहरण से बचाने के लिए सावधानी के तौर पर आपका यह क्रियाकलाप रद्द कर दिया गया है।\nकृपया प्रपत्र दोबारा जमा करें।",
        "changecontentmodel": "पन्ने का सामग्री प्रारूप बदलें",
        "log-action-filter-suppress-reblock": "पुन: ब्लॉक द्वारा युजर अवरोध",
        "log-action-filter-upload-upload": "नया अपलोड",
        "log-action-filter-upload-overwrite": "फिर से अपलोड",
+       "log-action-filter-upload-revert": "पूर्ववत करें",
        "authmanager-authn-not-in-progress": "प्रमाणीकरण प्रगति में नहीं है या सत्र डेटा खो गया है। कृपया शुरुआत से फिर से शुरू करें",
        "authmanager-authn-no-primary": "आपूर्ति किए गए क्रेडेंशियल्स को प्रमाणित नहीं किया जा सका।",
        "authmanager-authn-no-local-user": "दिए गए क्रेडेंशियल इस विकी पर किसी भी उपयोगकर्ता से जुड़े नहीं हैं।",
        "authmanager-create-no-primary": "खाता निर्माण के लिए आपूर्ति की गई क्रेडेंशियल्स का उपयोग नहीं किया जा सका।",
        "authmanager-link-no-primary": "खाता लिंकिंग के लिए आपूर्ति की गई क्रेडेंशियल का उपयोग नहीं किया जा सका।",
        "authmanager-link-not-in-progress": "खाता लिंक प्रगति में नहीं है या सत्र डेटा खो गया है। कृपया शुरुआत से फिर से शुरू करें",
-       "authmanager-authplugin-setpass-failed-title": "पासवर्ड बदलाव विफल हुआ।",
-       "authmanager-authplugin-setpass-failed-message": "प्रमाणन प्लगइन ने पासवर्ड बदलाव से इनकार किया।",
-       "authmanager-authplugin-create-fail": "प्रमाणीकरण प्लग इन ने खाता निर्माण को अस्वीकार कर दिया।",
-       "authmanager-authplugin-setpass-denied": "प्रमाणन प्लगइन पासवर्ड बदलने की अनुमति नहीं देता है",
-       "authmanager-authplugin-setpass-bad-domain": "अमान्य जालस्थल।",
        "authmanager-autocreate-noperm": "स्वचालित खाता निर्माण की अनुमति नहीं है।",
        "authmanager-autocreate-exception": "स्वचालित खाता निर्माण को पहले के कुछ त्रुटियों के कारण कुछ समय के लिए निष्क्रिय किया गया है।",
        "authmanager-userdoesnotexist": "सदस्य खाता \"$1\" पंजीकृत नहीं है।",
index 8142367..6ccad2a 100644 (file)
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]]) ke badlao ke [[User:$1|$1]] ke aakhri badlao ke jaise kar dewa gais hai.",
        "revertpage-nouser": "Reverted edits by a hidden user to last revision by {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Reverted edits by {{GENDER:$3|$1}};\nchanged back to last revision by {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "$1 ke badlao ke pahile jaise kar dewa gais hai;\nbadlao ke $2 ke aakhri version kar dewa gais hai.[$3 Show changes]",
        "sessionfailure-title": "Session fail hoe gais hae",
        "sessionfailure": "Aap ke login session me kuch karrbarr hai.\niske cancel kar dewa gais hai jisse ki koi iisession ke hijack nai kar.\nMeharbani kar ke  \"back\" ke press kar ke jon pana se aap aae rahaa ke fir se load karo, tab fir kosis karo.",
        "changecontentmodel": "Panna ke content model ke badlo",
        "authmanager-create-no-primary": "Supplied credentials ke account banae me nai kaam me laae sakaa.",
        "authmanager-link-no-primary": "Supplied credentials ke account linking me nai kaam me laae sakaa.",
        "authmanager-link-not-in-progress": "Account linking progress me nai hai, nai to, session data has been lost. Meharbaani kar ke suruu se suruu karo.",
-       "authmanager-authplugin-setpass-failed-title": "Pasword ke nai badle sakaa",
-       "authmanager-authplugin-setpass-failed-message": "The authentication plugin denied the password change.",
-       "authmanager-authplugin-create-fail": "The authentication plugin denied the account creation.",
-       "authmanager-authplugin-setpass-denied": "The authentication plugin does not allow changing passwords.",
-       "authmanager-authplugin-setpass-bad-domain": "Domain invalid hai.",
        "authmanager-autocreate-noperm": "Automatic account creation, allowed nai hai.",
        "authmanager-autocreate-exception": "Automatic account creation ke temporarily disable kar dewa gais hai, due to prior errors.",
        "authmanager-userdoesnotexist": "User account \"$1\" abhi registered nai hai",
index 55e4f5d..2383108 100644 (file)
        "history": "Povijest stranice",
        "history_short": "Stare izmjene",
        "history_small": "povijest",
-       "updatedmarker": "obnovljeno od posljednjeg posjeta",
+       "updatedmarker": "Obnovljeno od posljednjeg posjeta",
        "printableversion": "Inačica za ispis",
        "permalink": "Trajna poveznica",
        "print": "Ispiši",
        "delete-warning-toobig": "Ova stranica ima veliku povijest uređivanja, preko $1 {{PLURAL:$1|promjene|promjena}}. Brisanje može poremetiti bazu podataka {{SITENAME}}; postupajte s oprezom.",
        "deleteprotected": "Ne možete obrisati ovu stranicu jer je zaštićena.",
        "deleting-backlinks-warning": "<strong>Upozorenje:</strong> \nbrišete stranicu koja je uključena u [[Special:WhatLinksHere/{{FULLPAGENAME}}|druge]] ili druge stranice povezuju na nju.",
+       "deleting-subpages-warning": "<strong>Upozorenje:</strong> Stranica koju ste nakanili izbrisati ima [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1 podstranicu|$1 podstranice|$1 podstranica|51=preko 50 podstranica}}]].",
        "rollback": "Ukloni posljednju promjenu",
        "rollbacklink": "ukloni",
        "rollbacklinkcount": "ukloni $1 {{PLURAL:$1|uređivanje|uređivanja}}",
        "revertpage": "uklonjena promjena {{GENDER:$2|suradnika|suradnice}} [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]]), vraćeno na posljednju inačicu {{GENDER:$1|suradnika|suradnice}} [[User:$1|$1]]",
        "revertpage-nouser": "Vraćene izmjene suradnika (suradničko ime uklonjeno) na posljednju inačicu suradnika [[User:$1|$1]]",
        "rollback-success": "Uklonjeno uređivanje {{GENDER:$3|suradnika|suradnice}} $1; vraćeno na posljednju inačicu {{GENDER:$4|suradnika|suradnice}} $2.",
-       "rollback-success-notify": "Uklonili ste izmjene suradnika $1;\nvraćeno na posljednju izmjenu suradnika $2. [$3 Prikaži izmjene]",
        "sessionfailure-title": "Prekid sesije",
        "sessionfailure": "Izgleda da postoji problem s Vašom prijavom; ta radnja otkazana je kao način sprječavanja zlouporabe. Molimo ponovno pošaljite obrazac.",
        "changecontentmodel": "Promjena modela sadržaja stranice",
        "logentry-rights-autopromote": "Suradničkom računu $1 {{GENDER:$2|automatski je promijenjeno članstvo|automatski su promijenjena članstva}} iz $4 u $5",
        "logentry-upload-upload": "$1 је {{GENDER:$2|postavio|postavila}} $3",
        "logentry-upload-overwrite": "$1 је {{GENDER:$2|postavio|postavila}} novu inačicu $3",
-       "logentry-upload-revert": "$1 је {{GENDER:$2|postavio|postavila}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|postavio|postavila}} je $3 na stariju inačicu",
        "log-name-managetags": "Evidencija upravljanja oznakama",
        "log-name-tag": "Evidencija oznaka",
        "rightsnone": "(osnovno)",
index 0ebfb58..d7f91b9 100644 (file)
@@ -98,6 +98,7 @@
        "tog-norollbackdiff": "Ne jelenjenek meg az eltérések visszaállítás után",
        "tog-useeditwarning": "Figyelmeztessen, ha szerkesztéskor a módosítások mentése nélkül akarom elhagyni a lapot",
        "tog-prefershttps": "Mindig biztonságos kapcsolatot használjon, amikor be vagyok jelentkezve",
+       "tog-showrollbackconfirmation": "Megerősítés kérése, amikor a visszaállítás linkre kattintasz",
        "underline-always": "mindig",
        "underline-never": "soha",
        "underline-default": "Felület és böngésző alapértelmezése szerint",
        "badretype": "A megadott jelszavak nem egyeznek.",
        "usernameinprogress": "Egy fiók létrehozása ezzel a névvel már folyamatban van.\nKérlek, várj.",
        "userexists": "A megadott felhasználónév már foglalt.\nKérlek, válassz másikat!",
+       "createacct-normalization": "A felhasználóneved a következőre fog változni technikai korlátozások miatt: „$2”.",
        "loginerror": "Hiba történt a bejelentkezés során",
        "createacct-error": "Fióklétrehozási hiba",
        "createaccounterror": "Nem sikerült létrehozni a felhasználói fiókot: $1",
        "histfirst": "legelső",
        "histlast": "legutolsó",
        "historysize": "({{PLURAL:$1|egy|$1}} bájt)",
-       "historyempty": "(üres)",
+       "historyempty": "üres",
        "history-feed-title": "Laptörténet",
        "history-feed-description": "Az oldal laptörténete a wikiben",
        "history-feed-item-nocomment": "$1, $2-n",
        "right-reupload-own": "a saját maga által feltöltött fájlok felülírása",
        "right-reupload-shared": "felülírhatja a közös megosztóhelyen lévő fájlokat helyben",
        "right-upload_by_url": "fájl feltöltése URL-cím alapján",
-       "right-purge": "oldal gyorsítótárának ürítése megerősítés nélkül",
+       "right-purge": "oldal gyorsítótárának ürítése",
        "right-autoconfirmed": "Nem érinti az IP-alapú szerkesztéskorlátozás",
        "right-bot": "automatikus folyamatként való kezelés",
        "right-nominornewtalk": "felhasználói lapok apró szerkesztésével nem jelenik meg az új üzenet értesítés",
        "recentchangeslinked-feed": "Kapcsolódó változtatások",
        "recentchangeslinked-toolbox": "Kapcsolódó változtatások",
        "recentchangeslinked-title": "A(z) $1 laphoz kapcsolódó változtatások",
-       "recentchangeslinked-summary": "Alább azon lapoknak a legutóbbi változtatásai láthatóak, amelyekre hivatkozik egy megadott lap. (Ha egy kategória tagjaira vagy kíváncsi, írd be, hogy {{ns:category}}:katerógianév.)\nA [[Special:Watchlist|figyelőlistádon]] szereplő lapok <strong>félkövérrel</strong> vannak jelölve.",
+       "recentchangeslinked-summary": "Alább azon lapoknak a legutóbbi változtatásai láthatóak, amelyekre hivatkozik egy megadott lap. (Ha egy kategória tagjaira vagy kíváncsi, írd be, hogy {{ns:category}}:kategórianév.)\nA [[Special:Watchlist|figyelőlistádon]] szereplő lapok <strong>félkövérrel</strong> vannak jelölve.",
        "recentchangeslinked-page": "Lap neve:",
        "recentchangeslinked-to": "Inkább az erre linkelő lapok változtatásait mutasd",
        "recentchanges-page-added-to-category": "[[:$1]] hozzáadva a kategóriához",
        "deleting-backlinks-warning": "<strong>Figyelem:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Más lapok]] hivatkoznak a törlendő oldalra (vagy beillesztik azt).",
        "deleting-subpages-warning": "<strong>Figyelem:</strong> A törlésre jelölt lapnak [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|van egy allapja|$1 allapja van|51=több mint 50 allapja van}}]].",
        "rollback": "Szerkesztések visszaállítása",
+       "rollback-confirmation-confirm": "Kérlek erősítsd meg:",
+       "rollback-confirmation-yes": "Visszaállítás",
+       "rollback-confirmation-no": "Mégse",
        "rollbacklink": "visszaállítás",
        "rollbacklinkcount": "$1 szerkesztés visszaállítása",
        "rollbacklinkcount-morethan": "több mint $1 szerkesztés visszaállítása",
        "revertpage": "Visszaállítottam a lap korábbi változatát [[Special:Contributions/$2|$2]] ([[User talk:$2|vita]]) szerkesztéséről [[User:$1|$1]] szerkesztésére",
        "revertpage-nouser": "Visszaállítottam a lap korábbi változatát (szerkesztőnév eltávolítva) szerkesztéséről [[User:$1|$1]] szerkesztésére",
        "rollback-success": "{{GENDER:$3|$1}} szerkesztéseit visszaállítottam {{GENDER:$4|$2}} utolsó változatára.",
-       "rollback-success-notify": "$1 szerkesztései visszaállítva;\nhelyreállítva $2 utolsó változata. [$3 Változtatások megtekintése]",
        "sessionfailure-title": "Munkamenethiba",
        "sessionfailure": "Úgy látszik, hogy probléma van a bejelentkezési munkameneteddel;\nez a művelet a munkamenet eltérítése miatti óvatosságból megszakadt.\nKérjük, küldd el újra az űrlapot.",
        "changecontentmodel": "A lap tartalommodelljének megváltoztatása",
        "anoncontribs": "Közreműködések",
        "contribsub2": "$1 ($2)",
        "contributions-userdoesnotexist": "Nincs regisztrálva „$1” szerkesztői azonosító.",
+       "negative-namespace-not-supported": "Negatív értékű névterek nem támogatottak.",
        "nocontribs": "Nem található a feltételeknek megfelelő változtatás.",
        "uctop": "aktuális",
        "month": "E hónap végéig:",
        "ipb-confirm": "Blokk megerősítése",
        "ipb-sitewide": "Teljes körű",
        "ipb-partial": "Részleges",
+       "ipb-sitewide-help": "A wiki összes lapja és minden egyéb közreműködési művelet.",
+       "ipb-partial-help": "Meghatározott lapok vagy névterek.",
        "ipb-pages-label": "Lapok",
        "ipb-namespaces-label": "Névterek",
        "badipaddress": "Érvénytelen IP-cím",
        "ipb_expiry_old": "A lejárati idő a múltban van.",
        "ipb_expiry_temp": "A láthatatlan felhasználóinév-blokkok lehetnek állandóak.",
        "ipb_hide_invalid": "A felhasználói fiókot nem lehet elrejteni; több mint $1 szerkesztése van.",
+       "ipb_hide_partial": "Felhasználói nevek elrejtésekor és blokkolásakor a blokknak az egész wikire ki kell terjednie.",
        "ipb_already_blocked": "\"$1\" már blokkolva",
        "ipb-needreblock": "$1 már blokkolva van. Meg szeretnéd változtatni a beállításokat?",
        "ipb-otherblocks-header": "További {{PLURAL:$1|blokk|blokkok}}",
        "confirm-unwatch-top": "El szeretnéd távolítani a lapot a figyelőlistádról?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Visszavonod a változtatásokat?",
+       "confirm-rollback-bottom": "Ez a művelet azonnal visszaállítja a lap kiválasztott változtatásait.",
        "confirm-mcrrestore-title": "Egy változat visszaállítása",
        "confirm-mcrundo-title": "Egy változtatás visszavonva",
        "mcrundofailed": "A visszavonás nem sikerült",
        "mcrundo-missingparam": "Kötelező paraméterek hiányoznak a kérésből.",
        "mcrundo-changed": "A változtatások megtekintése óta az oldal megváltozott. Kérlek, tekintsd meg az új változtatásokat.",
+       "mcrundo-parse-failed": "Az új változat feldolgozása sikertelen: $1",
        "ellipsis": "…",
        "quotation-marks": "„$1”",
        "imgmultipageprev": "← előző oldal",
        "logentry-rights-autopromote": "$1 automatikusan előléptetve erről: $4 erre: $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|feltöltötte}} ezt: $3",
        "logentry-upload-overwrite": "$1 $3 új verzióját {{GENDER:$2|töltötte}} fel",
-       "logentry-upload-revert": "$1 {{GENDER:$2|feltöltötte}} $3-t",
+       "logentry-upload-revert": "$1 {{GENDER:$2|visszaállította}} „$3”-t egy régebbi változatra",
        "log-name-managetags": "Címkekezelési napló",
        "log-description-managetags": "Ez a lap a [[Special:Tags|címkék]] kezelésével kapcsolatos tevékenységeket listázza. A napló csak azokat a műveleteket tartalmazza, amelyet az adminisztrátorok kézzel hajtottak végre; a wikiszoftver képes naplóbejegyzés nélkül is létrehozni és törölni címkéket.",
        "logentry-managetags-create": "$1 {{GENDER:$2|létrehozta}} a(z) „$4” címkét",
        "log-action-filter-suppress-reblock": "Felhasználó elrejtést újra blokkolással",
        "log-action-filter-upload-upload": "Új feltöltés",
        "log-action-filter-upload-overwrite": "Újrafeltöltés",
+       "log-action-filter-upload-revert": "Visszaállítás",
        "authmanager-authn-not-in-progress": "Hitelesítés nincs folyamatban, vagy a folyamat adatai elvesztek. Kérjük, indítsd újra az elejétől.",
        "authmanager-authn-no-primary": "A megadott hitelesítő adatokkal nem lehet hitelesíteni.",
        "authmanager-authn-no-local-user": "A megadott hitelesítő adatok nincsenek társítva egyetlen felhasználóval sem ezen a wikin.",
        "authmanager-create-no-primary": "A megadott hitelesítő adatok nem használhatók fióklétrehozásra.",
        "authmanager-link-no-primary": "A megadott hitelesítő adatok nem használhatók fiókok összekapcsolására.",
        "authmanager-link-not-in-progress": "Fiókok összekapcsolása nincs folyamatban, vagy a folyamat adatai elvesztek. Kérjük, indítsd újra az elejétől.",
-       "authmanager-authplugin-setpass-failed-title": "Jelszó megváltoztatása nem sikerült",
-       "authmanager-authplugin-setpass-failed-message": "A hitelesítés beépülője megtagadta a jelszó módosítását.",
-       "authmanager-authplugin-create-fail": "A hitelesítés beépülője megtagadta a fiók létrehozását.",
-       "authmanager-authplugin-setpass-denied": "A hitelesítés beépülője nem teszi lehetővé a jelszó megváltoztatását.",
-       "authmanager-authplugin-setpass-bad-domain": "Érvénytelen domain.",
        "authmanager-autocreate-noperm": "Az automatikus fióklétrehozás nem engedélyezett.",
        "authmanager-autocreate-exception": "A fiókok automatikus létrehozását átmenetileg letiltottuk a korábbi hibák miatt.",
        "authmanager-userdoesnotexist": "A(z) „$1” felhasználó nincs regisztrálva.",
        "passwordpolicies-policy-maximalpasswordlength": "A jelszó legfeljebb $1 karakter hosszú lehet",
        "passwordpolicies-policy-passwordcannotbepopular": "A jelszó nem {{PLURAL:$1|lehet a gyakran használt jelszó|szerepelhet a(z) $1 leggyakrabban használt jelszó listáján}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "A jelszó nem szerepelhet a 100 000 leggyakrabban használt jelszó listáján .",
+       "passwordpolicies-policyflag-forcechange": "lecserélés követelése bejelentkezéskor",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "lecserélés ajánlása bejelentkezéskor",
        "unprotected-js": "Biztonsági okokból JavaScript nem tölthető be védtelen lapokról. Kérlek egyedül a MediaWiki névtérben készíts JavaScriptet, vagy szerkesztői allapként."
 }
index 0f072ab..8c191d9 100644 (file)
@@ -33,7 +33,8 @@
                        "23artashes",
                        "Fitoschido",
                        "Սահակ",
-                       "ديفيد"
+                       "ديفيد",
+                       "Azniv Stepanian"
                ]
        },
        "tog-underline": "ընդգծել հղումները՝",
        "mainpage": "Գլխավոր էջ",
        "mainpage-description": "Գլխավոր էջ",
        "policy-url": "Project:Կանոնակարգ",
-       "portal": "Խորհրդարան",
+       "portal": "Համայնքային պորտալ",
        "portal-url": "Project:Համայնքային պորտալ",
        "privacy": "Գաղտնիության քաղաքականություն",
        "privacypage": "Project:Գաղտնիության քաղաքականություն",
        "mypreferencesprotected": "Դուք բավարար իրավունքներ չունեք Ձեր նախընտրությունները խմբագրելու համար։",
        "ns-specialprotected": "«{{ns:special}}» անվանատարածքի էջերը չեն կարող խմբագրվել։",
        "titleprotected": "Այս անվանմամբ էջի ստեղծումը արգելվել է [[User:$1|$1]] մասնակցի կողմից։\nՏրված պատճառն է՝ <em>$2</em>։",
+       "invalidtitle": "Սխալ վերնագիր",
        "exception-nologin": "Չեք մտել համակարգ",
        "exception-nologin-text": "Խնդրում ենք, մուտք գործեք՝ այս էջը դիտելու կամ գործողությունը կատարելու համար։",
        "virus-badscanner": "Սխալ կարգավորւմ։ Անծանոթ վիրուսների զննիչ. ''$1''",
        "savechanges": "Պահպանել փոփոխությունները",
        "publishpage": "Ստեղծել էջը",
        "publishchanges": "Պահպանել",
+       "savearticle-start": "Հիշել էջը...",
+       "savechanges-start": "Հիշել փոփոխությունները...",
+       "publishpage-start": "Հրատարակել էջը...",
        "publishchanges-start": "Պահպանել…",
        "preview": "Նախադիտում",
        "showpreview": "Նախադիտել",
        "edit-already-exists": "Հրարավոր չէ նոր էջ ստեղծել․ այն արդեն գոյություն ունի։",
        "defaultmessagetext": "Լռելյան տեքստը",
        "editwarning-warning": "Այս էջը լքելով դուք կարող եք կորցնել ձեր կատարած փոփոխությունները։\nԵթե դուք գրանցված եք համակարգում, կարող եք անջատել այս նախազգուշացումը ձեր նախընրությունների «{{int:prefs-editing}}» բաժնում։",
+       "slot-name-main": "Հիմնական",
        "content-model-wikitext": "վիքիտեքստ",
        "content-model-text": "պարզ տեքստ",
        "content-model-javascript": "ՋավաՍկրիպտ",
        "diff-empty": "(Տարբերություն չկա)",
        "diff-multi-sameuser": "(Միևնույն մասնակցի {{PLURAL:$1|մեկ միջանկյալ տարբերակ|$1 միջանկյալ տարբերակներ}} թաքցված է)",
        "searchresults": "Որոնման արդյունքներ",
+       "search-filter-title-prefix-reset": "Որոնել բոլոր էջեր",
        "searchresults-title": "«$1»-ի որոնման արդյունքներ",
        "titlematches": "Համընկած հոդվածների անվանումներ",
        "textmatches": "Համընկած տեքստերով էջեր",
        "prefs-rc": "Վերջին փոփոխություններ",
        "prefs-watchlist": "Հսկացանկ",
        "prefs-editwatchlist": "Խմբագրել հսկացանկը",
+       "prefs-editwatchlist-clear": "Մաքրել հսկացանկը",
        "prefs-watchlist-days": "Հսկացանկում ցուցադրվող օրերի թիվը՝",
        "prefs-watchlist-days-max": "Առավելագույնը $1 {{PLURAL:$1|օր}}",
        "prefs-watchlist-edits": "Ընդարձակված հսկացանկում ցուցադրվող օրերի թիվը՝",
        "prefs-email": "Էլ-հասցեի ընտրանքներ",
        "prefs-rendering": "Արտաքին տեսք",
        "saveprefs": "Հիշել",
-       "restoreprefs": "Զրոյացնել, բերելով իլռելայն նախընտրանքներին (բոլոր բաժիններում)",
+       "restoreprefs": "Վերականգնել սկզբնական կարգավորումները (բոլոր ներդիրներում)",
        "prefs-editing": "Խմբագրում",
        "searchresultshead": "Որոնում",
        "stub-threshold": "<a href=\"#\" class=\"stub\">Պատառ հոդվածների հղումների</a> ձևավորման որոշման սահմանը.",
        "grant-group-email": "Ուղարկել էլ. նամակ",
        "grant-createaccount": "Ստեղծել հաշիվներ",
        "grant-createeditmovepage": "Ստեղծել․ խմբագրել և տեղափոխել էջեր",
+       "grant-uploadfile": "Բեռնել նոր նիշքեր",
        "grant-basic": "Հիմնական իրավունքներ",
+       "grant-viewmywatchlist": "Դիտել ձեր հսկացանկը",
        "newuserlogpage": "Մասնակիցների գրանցման տեղեկամատյան",
        "newuserlogpagetext": "Սա նոր մասնակիցների գրանցման տեղեկամատյանն է.",
        "rightslog": "Մասնակցի իրավունքների տեղեկամատյան",
        "action-read": "կարդալ այս էջը",
        "action-edit": "խմբագրել այս էջը",
        "action-createpage": "Ստեղծել էջ",
+       "action-createtalk": "Ստեղծել քննարկման էջ",
        "action-createaccount": "ստեղծել այս մասնակցային հաշիվը",
        "action-move": "տեղափոխել այս էջը",
        "action-move-rootuserpages": "տեղափոխել մասնակցի էջի արմատը",
        "rcfilters-other-review-tools": "Վերանայման այլ գործիքներ",
        "rcfilters-group-results-by-page": "Արդյունքները խմբավորել էջերով",
        "rcfilters-activefilters": "Ակտիվ զտիչներ",
+       "rcfilters-activefilters-hide": "Թաքցնել",
+       "rcfilters-activefilters-show": "Ցուցադրել",
        "rcfilters-advancedfilters": "Ընդլայնված ֆիլտրեր",
        "rcfilters-limit-title": "Ցուցադրվող արդյունքներ",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|փոփոխություն|փոփոխություններ}}, $2",
        "upload-misc-error-text": "Տեղի ունեցավ անհայտ սխալ բեռնման ընթացքում։ Խնդրում ենք ստուգել URL-հասցեի ճշտությունն ու հասանելիությունը և փորձել կրկին։ Սխալի կրկնման դեպքում կապնվեք համակարգային ադմինիստրատորի հետ։",
        "upload-dialog-title": "Բեռնել նիշք",
        "upload-dialog-button-cancel": "Չեղարկել",
+       "upload-dialog-button-back": "Հետ",
        "upload-dialog-button-done": "Արված է",
        "upload-dialog-button-save": "Հիշել",
        "upload-dialog-button-upload": "Բեռնել",
        "license-nopreview": "(Նախադիտումը մատչելի չէ)",
        "upload_source_url": " (գործուն, հանրամատչելի URL-հասցե)",
        "upload_source_file": " (նիշք ձեր համակարգչի վրա)",
+       "listfiles-delete": "ջնջել",
        "listfiles_search_for": "Որոնել պատկերի անվամբ.",
        "imgfile": "նիշք",
        "listfiles": "Նիշքերի ցանկ",
        "listfiles_size": "Չափ",
        "listfiles_description": "Նկարագրություն",
        "listfiles_count": "Տարբերակ",
+       "listfiles-latestversion": "Ընթացիկ տարբերակ",
        "listfiles-latestversion-yes": "Այո",
        "listfiles-latestversion-no": "Ոչ",
        "file-anchor-link": "Նիշք",
        "unusedtemplateswlh": "այլ հղումներ",
        "randompage": "Պատահական էջ",
        "randompage-nopages": "Այս անվանատարածքում էջեր չկան։",
+       "randomincategory-category": "Կատեգորիա:",
+       "randomincategory-legend": "Կատեգորիայի պատահական էջ",
        "randomincategory-submit": "Անցնել",
        "randomredirect": "Պատահական վերահղում",
        "randomredirect-nopages": "Այս անվանատարածքում վերահղումներ չկան։",
        "protectedpages": "Պաշտպանված էջեր",
        "protectedpages-noredirect": "Թաքցնել վերահղումները",
        "protectedpagesempty": "Ներկայումս չկան պաշտպանված էջեր նշված պարամետրերով։",
+       "protectedpages-page": "Էջ",
+       "protectedpages-expiry": "Լրանում է",
        "protectedpages-submit": "Ցույց տալ էջերը",
+       "protectedpages-unknown-timestamp": "Անհայտ",
        "protectedtitles": "Պաշտպանված անվանումներ",
        "protectedtitles-submit": "Ցույց տալ վերնագրերը",
        "listusers": "Մասնակիցների ցանկ",
        "notargettext": "Դուք չեք նշել նպատակային էջ կամ մասնակից այս ֆունկցիայի գործածման համար։",
        "pager-newer-n": "{{PLURAL:$1|ավելի թարմ 1|ավելի թարմ $1}}",
        "pager-older-n": "{{PLURAL:$1|ավելի հին 1|ավելի հին $1}}",
+       "apisandbox-reset": "Մաքրել",
+       "apisandbox-retry": "Կրկնել",
+       "apisandbox-examples": "Օրինակներ",
+       "apisandbox-add-multi": "Ավելացնել",
+       "apisandbox-results": "Արդյունք",
+       "apisandbox-continue": "Շարունակել",
+       "apisandbox-continue-clear": "Մաքրել",
        "booksources": "Գրքային աղբյուրներ",
        "booksources-search-legend": "Գրքի մասին տեղեկությունների որոնում",
        "booksources-search": "Որոնել",
        "alllogstext": "{{SITENAME}} կայքի տեղեկամատյանների համընդհանուր ցանկ։\nԴուք կարող եք սահմանափակել արդյունքները ըստ տեղեկամատյանի տեսակի, մասնակցի անունի կամ համապատասխան էջի։",
        "logempty": "Տեղեկամատյանում չկան համընկնող տարրեր։",
        "log-title-wildcard": "Որոնել այս տեքստով սկսվող անվանումներ",
+       "checkbox-all": "Բոլորը",
+       "checkbox-none": "Ոչ մեկը",
        "allpages": "Բոլոր էջերը",
        "nextpage": "Հաջորդ էջը ($1)",
        "prevpage": "Նախորդ էջը ($1)",
        "deletedcontributions-title": "Մասնակցի ջնջված ներդրում",
        "sp-deletedcontributions-contribs": "ներդրում",
        "linksearch": "Արտաքին հղումներ",
+       "linksearch-ns": "Անվանատարածք.",
        "linksearch-ok": "Որոնել",
        "linksearch-line": " \n$1-ը հղվել է $2 ից",
        "listusersfrom": "Ցուցադրել մասնակիցներին՝ սկսած.",
        "activeusers": "Ակտիվ մասնակիցների ցանկ",
        "activeusers-noresult": "Այդպիսի մասնակիցներ չեն գտնվել։",
        "activeusers-submit": "Ցույց տալ ակտիվ մասնակիցներին",
+       "listgrouprights-group": "Խումբ",
+       "listgrouprights-rights": "Իրավունքներ",
        "listgrouprights-members": "(անդամների ցանկ)",
        "listgrouprights-addgroup": "Ավելացնեել {{PLURAL:$2|խումբ|խմբեր}}՝  $1",
+       "listgrants-rights": "Իրավունքներ",
        "mailnologin": "Ուղարկման հասցե չկա",
        "mailnologintext": "Անհրաժեշտ է [[Special:UserLogin|մտնել համակարգ]] և ունենալ գործող էլ-փոստի հասցե ձեր [[Special:Preferences|նախընտրություններում]]՝ ուրիշ մասնակիցներին էլեկտրոնային նամակներ ուղարկելու համար։",
        "emailuser": "էլ-նամակ ուղարկել այս մասնակցին",
        "delete-edit-reasonlist": "Խմբագրել ջնջման պատճառները",
        "deleting-backlinks-warning": "'''Զգուշացում''', ձեր կողմից ջնջվող էջին հղվում են [[Special:WhatLinksHere/{{FULLPAGENAME}}|այլ հոդվածներ]]:",
        "rollback": "Հետ գլորել խմբագրումները",
+       "rollback-confirmation-confirm": "Խնդրում ենք հաստատել.",
+       "rollback-confirmation-no": "Չեղարկել",
        "rollbacklink": "հետ գլորել",
        "rollbacklinkcount": "հետ գլորել $1 {{PLURAL:$1|խմբագրում}}",
        "rollbacklinkcount-morethan": "հետ գլորել ավելի քան $1 {{PLURAL:$1|խմբագրում|խմբագրում}}",
        "rollback-success": "Հետ են շրջվել $1 մասնակցի խմբագրումները. վերադարձվել է $2 մասնակցի վերջին տարբերակին։",
        "sessionfailure-title": "Սեսիայի խափանում",
        "sessionfailure": "Կարծես խնդիր է առաջացել կապված ձեր ընթացիկ աշխատանքային սեսիայի հետ.\nայս գործողությունը բեկանվել է սեսիայի հափշտակման կանխման նպատակով։\nԽնդրում ենք սեղմել «back» կոճակը և վերբեռնել այն էջը որտեղից եկել եք ու փորձել կրկին։",
+       "changecontentmodel-reason-label": "Պատճառ՝",
+       "changecontentmodel-submit": "Փոխել",
+       "logentry-contentmodel-change-revertlink": "հետ շրջել",
+       "logentry-contentmodel-change-revert": "հետ շրջել",
        "protectlogpage": "Պաշտպանման տեղեկամատյան",
        "protectlogtext": "Ստորև բերված է պաշտպանված և պաշտպանումից հանված էջերի ցանկը։ Տես նաև [[Special:ProtectedPages|ներկայումս պաշտպանված էջերի ցանկը]]։",
        "protectedarticle": "պաշտպանվեց «[[$1]]» էջը",
        "mycontris": "Ներդրում",
        "anoncontribs": "Ներդրումներ",
        "contribsub2": "{{GENDER:$3|$1}}-ի ներդրումները ($2)",
+       "contributions-subtitle": "{{GENDER:$3|$1}}-ի համար",
        "nocontribs": "Այս չափանիշներին համապատասխանող փոփոխություններ չեն գտնվել։",
        "uctop": " վերջինը",
        "month": "Սկսած ամսից (և վաղ)՝",
        "sp-contributions-username": "IP-հասցե կամ մասնակցի անուն.",
        "sp-contributions-toponly": "Ցույց տալ միայն այն խմբագրումները, որոնք վերջին փոփոխություն են",
        "sp-contributions-newonly": "Ցույց տալ միայն նոր էջերի խմբագրումները",
+       "sp-contributions-hideminor": "Թագցնել չնչին խմբագրումներ",
        "sp-contributions-submit": "Որոնել",
        "whatlinkshere": "Այստեղ հղվող էջերը",
        "whatlinkshere-title": "Էջեր, որոնք հղում են դեպի «$1»",
        "ipbwatchuser": "Հսկացանկում ավելացնել մասնակցի էջն ու քննարկման էջը",
        "ipb-disableusertalk": "Արգելել մասնակցին խմբագրել իր քննարկման էջն արգելափակման ընթացքում",
        "ipb-pages-label": "Էջեր",
+       "ipb-namespaces-label": "Անվանատարածքներ",
        "badipaddress": "Սխալ IP-հասցե",
        "blockipsuccesssub": "Արգելափակումը կատարված է",
        "blockipsuccesstext": "[[Special:Contributions/$1|«$1»]] արգելափակված է։\n<br />Տես [[Special:BlockList|արգելափակված IP-հասցեների ցանկը]]։",
        "ipb-blocklist": "Դիտել գործող արգելափակումները",
        "ipb-blocklist-contribs": "$1 մասնակցի ներդրումը",
        "block-expiry": "Մարման ժամկետ.",
+       "block-reason": "Պատճառ՝",
        "unblockip": "Արգելափակումից հանել մասնակցին",
        "unblockiptext": "Օգտագործեք ստորև ձևը՝ նախկինում արգելափակված IP-հասցեի կամ մասնակցի գրելու հնարավորությունը վերականգնելու համար։",
        "ipusubmit": "Հանել արգելափակումը",
        "unblocked": "[[User:$1|$1]] մասնակիցը անարգելված է։",
        "unblocked-id": "$1 արգելափակումը հանված է",
        "blocklist": "Արգելափակված մասնակիցներ։",
+       "autoblocklist-submit": "Որոնել",
        "ipblocklist": "Արգելափակված IP-հասցեները և մասնակիցները",
        "ipblocklist-legend": "Արգելափակված մասնակցի որոնում",
        "blocklist-expiry": "Լրանում է",
+       "blocklist-reason": "Պատճառ",
        "ipblocklist-submit": "Որոնել",
        "infiniteblock": "ընդմիշտ",
        "expiringblock": "կմարվի $1 $2",
        "createaccountblock": "մասնակցային հաշվի ստեղծումը արգելափակված է",
        "emailblock": "էլ-փոստը արգելափակված",
        "blocklist-nousertalk": "չի կարող խմբագրել իր քննարկման էջը",
+       "blocklist-editing-page": "էջեր",
+       "blocklist-editing-ns": "անվանատարածքներ",
        "ipblocklist-empty": "Արգելափակումների ցանկը դատարկ է։",
        "ipblocklist-no-results": "Նշված IP-հասցեն կամ մասնակցի անունը արգելափակված չէ։",
        "blocklink": "արգելափակել",
        "allmessages-filter-all": "Բոլորը",
        "allmessages-language": "Լեզու",
        "allmessages-filter-submit": "Անցնել",
+       "allmessages-filter-translate": "Թարգմանել",
        "thumbnail-more": "Ընդարձակել",
        "filemissing": "Նման նիշք չկա",
        "thumbnail_error": "Պատկերիկի ստեղծման սխալ. $1",
        "import": "Էջերի ներմուծում",
        "importinterwiki": "Միջվիքի ներմուծում",
        "import-interwiki-text": "Նշեք վիքի և ներմուծվող էջի անվանումը։\nՓոփոխումների ժամանակները և խմբագրողների անունները կպահպանվեն։\nԲոլոր միջվիքի ներմուծման գործողությունները գրանցվում են [[Special:Log/import|ներմուծման տեղեկամատյանում]]։",
+       "import-interwiki-sourcewiki": "Աղբյուր վիքի.",
+       "import-interwiki-sourcepage": "Աղբյուր էջ.",
        "import-interwiki-history": "Պատճենել այս էջի փոփոխումների լրիվ պատմությունը",
        "import-interwiki-submit": "Ներմուծել",
        "import-upload-filename": "Նիշքի անուն․",
        "pageinfo-display-title": "Վերնագիր",
        "pageinfo-default-sort": "Լռելյայն տեսակավորման բանալի",
        "pageinfo-length": "Ծավալ (բայթերով)",
+       "pageinfo-namespace": "Անվանատարածք",
        "pageinfo-article-id": "Էջի N",
        "pageinfo-language": "Բովանդակության լեզու",
        "pageinfo-language-change": "փոխել",
        "pageinfo-content-model": "Էջի բովանդակության մոդելը",
+       "pageinfo-content-model-change": "փոխել",
        "pageinfo-robot-policy": "Կարգավիճակը որոնողական համակարգերում",
        "pageinfo-robot-index": "ինդեքսավորվող",
        "pageinfo-robot-noindex": "ինդեքսավորվող չէ",
        "pageinfo-contentpage": "Հաշվառված որպես բովանդակային էջ",
        "pageinfo-contentpage-yes": "Այո",
        "pageinfo-protect-cascading-yes": "Այո",
+       "pageinfo-category-pages": "Էջերի քանակ",
+       "pageinfo-category-subcats": "Ենթակատեգորիաների քանակ",
+       "pageinfo-category-files": "Հոդվածների քանակ",
+       "pageinfo-user-id": "Մասնակցի ID-ն",
        "markaspatrolleddiff": "Նշել որպես ստուգված",
        "markaspatrolledtext": "Նշել այս էջը որպես ստուգված",
        "markedaspatrolled": "Նշված է որպես ստուգված",
        "confirm-watch-top": "Ավելացնե՞լ ձեր հսկացանկին",
        "confirm-unwatch-button": "Լավ",
        "confirm-unwatch-top": "Հեռացնե՞լ Ձեր հսկացանկից։",
+       "confirm-rollback-button": "Լավ",
        "imgmultipageprev": "← նախորդ էջ",
        "imgmultipagenext": "հաջորդ էջ →",
        "imgmultigo": "Անցնե՛լ",
        "imgmultigoto": "Անցնել $1 էջը",
+       "img-lang-go": "Անցնել",
        "ascending_abbrev": "աճմ. կարգ.",
        "descending_abbrev": "նվազ",
        "table_pager_next": "Հաջորդ էջ",
        "watchlistedit-raw-done": "Ձեր հսկացանկը թարմացված է։",
        "watchlistedit-raw-added": "Ավելացվեց {{PLURAL:$1|1 անվանում|$1 անվանում}}.",
        "watchlistedit-raw-removed": "Հեռացվեց {{PLURAL:$1|1 անվանում|$1 անվանում}}.",
+       "watchlistedit-clear-title": "Մաքրել հսկացանկը",
+       "watchlistedit-clear-legend": "Մաքրել հսկացանկը",
        "watchlisttools-clear": "Մաքրել հսկացանկը",
        "watchlisttools-view": "Փոփոխությունները հսկացանկում",
        "watchlisttools-edit": "Դիտել և խմբագրել հսկացանկը",
        "watchlisttools-raw": "Խմբագրել հում հսկացանկը",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|քննարկում]])",
        "version": "ՄեդիաՎիքի տարբերակը",
+       "version-editors": "Խմբագիրներ",
        "version-ext-license": "Արտոնագիր",
        "version-ext-colheader-name": "Ընդլայնում",
        "version-ext-colheader-version": "Տարբերակ",
        "version-ext-colheader-license": "Արտոնագիր",
+       "version-ext-colheader-description": "Նկարագրություն",
+       "version-ext-colheader-credits": "Հեղինակներ",
        "version-license-title": "Արտոնագիր $1-ի համար",
        "version-poweredby-credits": "Այս վիքին աշխատում է '''[https://www.mediawiki.org/ MediaWiki]'''֊ով, copyright © 2001-$1 $2։",
+       "version-poweredby-translators": "translatewiki.net թարգմանիչներ",
+       "version-software-version": "Տարբերակ",
+       "version-libraries-library": "Գրադարան",
+       "version-libraries-version": "Տարբերակ",
+       "version-libraries-license": "Արտոնագիր",
+       "version-libraries-description": "Նկարագրություն",
+       "version-libraries-authors": "Հեղինակներ",
        "redirect": "Վերահղում նիշքի, մասնակցի, էջի, տարբերակի կամ գրանցամատյանի նույնականացման համարից",
        "redirect-submit": "Անցնել",
        "redirect-lookup": "Որոնում՝",
        "tag-filter": "[[Special:Tags|Պիտակների]] զտիչ՝",
        "tag-filter-submit": "Ֆիլտրել",
        "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Պիտակ}}]]: $2",
+       "tag-mw-new-redirect": "Նոր վերահղում",
        "tags-title": "Պիտակներ",
        "tags-source-header": "Աղբյուր",
        "tags-actions-header": "Գործողություններ",
        "compare-invalid-title": "Ձեր նշած վերնագիրը անվավեր է։",
        "compare-title-not-exists": "Ձեր նշած վերնագիրը գոյություն չունի:",
        "compare-revision-not-exists": "Ձեր նշած փոփոխությունը գոյություն չունի։",
+       "diff-form": "Տարբերությունները",
+       "permanentlink": "Մշտական հղում",
        "dberr-problems": "Այս կայքում առաջացել են տեխնիկական խնդիրներ։ Հայցում ենք ձեր ներողությունը։",
        "dberr-again": "Փորձեք մի քանի րոպե սպասել և վերաբեռնել էջը։",
        "htmlform-submit": " \nՀաշվել",
+       "htmlform-selectorother-other": "Այլ",
+       "htmlform-no": "Ոչ",
+       "htmlform-yes": "Այո",
+       "htmlform-title-not-exists": "$1՝ գոյություն չունի",
        "logentry-delete-delete": "$1 {{GENDER:$2|ջնջեց}} $3 էջը",
        "logentry-delete-restore": "$1 վերականգնեց $3 ($4) էջը",
        "logentry-delete-event": "$1 փոխեց տեղեկամատյանի {{PLURAL:$5|1 գրանցման|$5 գրանցումների}} տեսանելությունը $3-ում. $4",
        "feedback-close": "Արված է",
        "feedback-message": "Հաղորդագրություն․",
        "feedback-subject": "Թեմա.",
+       "feedback-thanks-title": "Շնորհակալություն",
        "searchsuggest-search": "Որոնել {{SITENAME}} կայքում",
        "duration-seconds": "$1 {{PLURAL:$1|վայրկյան}}",
        "duration-minutes": "$1 {{PLURAL:$1|րոպե}}",
        "duration-centuries": "$1 {{PLURAL:$1|դար}}",
        "duration-millennia": "$1 {{PLURAL:$1|հազարամյակ}}",
        "expandtemplates": "Կաղապարների ընդարձակում",
+       "expand_templates_ok": "Լավ",
+       "pagelang-name": "Էջ",
+       "pagelang-select-lang": "Ընտրեք լեզուն",
+       "pagelang-reason": "Պատճառ",
+       "pagelang-submit": "Հաստատել",
        "pagelang-nonexistent-page": "$1 էջը գոյություն չունի",
+       "mediastatistics-header-total": "Բոլոր նիշքեր",
        "special-characters-group-latin": "Լատիներեն",
        "special-characters-group-latinextended": "Լատիներեն ընդլայնված",
        "special-characters-group-ipa": "ՄՀԱ (IPA)",
        "date-range-from": "Սկսած՝",
        "date-range-to": "Մինչև՝",
        "randomrootpage": "Պատահական կենտրոնական էջ",
-       "authmanager-create-from-login": "Հաշիվ ստեղծելու համար, խնդրում ենք լրացնել ստորև դաշտերը"
+       "authmanager-create-from-login": "Հաշիվ ստեղծելու համար, խնդրում ենք լրացնել ստորև դաշտերը",
+       "authprovider-resetpass-skip-label": "Բաց թողնել",
+       "passwordpolicies-group": "Խումբ"
 }
index a3d2128..9dfa8b3 100644 (file)
@@ -5,9 +5,18 @@
                        "Armeniki",
                        "Azniv Stepanian",
                        "Rajemian",
-                       "Դավիթ Սարոյան"
+                       "Դավիթ Սարոյան",
+                       "Kareyac"
                ]
        },
+       "tog-underline": "Ընդգծել յղումները․",
+       "tog-hideminor": "Թաքցնել չնչին խմբագրումները վերջին փոփոխութիւններու ցանկէն",
+       "tog-extendwatchlist": "Տարածել հսկացանկը՝ ցոյց տալով բոլոր փոփոխութիւնները, ոչ միայն վերջինները",
+       "tog-numberheadings": "Ինքնահամարակալել վերնագիրները",
+       "tog-editondblclick": "Խմբագրել էջերը կրկնակի սեղմամբ",
+       "tog-watchlisthideown": "Թաքցնել իմ խմբագրումները հսկացանկէն",
+       "tog-watchlisthidebots": "Թաքցնել իմ խմբագրումները հսկացանկէն",
+       "tog-watchlisthideminor": "Թաքցնել իմ խմբագրումները հսկացանկէն",
        "underline-always": "Միշտ",
        "underline-never": "Երբեք",
        "editfont-serif": "Սերիֆ տառատեսակ",
@@ -87,7 +96,7 @@
        "category-article-count": "{{PLURAL:$2|Այս ստորոգութիւնը կը պարունակէ միայն հետեւեալ էջը։|Ստորեւ այս ստորոգութեան ընդհանուր $2էն {{PLURAL:$1|էջը|$1 էջերը}}։}}",
        "category-article-count-limited": "Այս ստորոգութիւնի մէջ կը գտնուին հետեւեալ {{PLURAL:$1|էջը|$1 էջերը}}։",
        "category-file-count": "{{PLURAL:$2|Այս ստորոգութիւնը կը պարունակէ միայն հետեւեալ էջը։|Ստորեւ այս ստորոգութեան ընդհանուր $2-էն {{PLURAL:$1|էջը|$1 էջերը}}։}}",
-       "category-file-count-limited": "Ô±ÕµÕ½ Õ½Õ¿Õ¸Ö\80Õ¸Õ£Õ¸Ö\82Õ©Õ«Ö\82Õ¶Õ« մէջ կը գտնուին հետեւեալ  {{PLURAL:$1|նիշքը|$1 նիշքերը}}։",
+       "category-file-count-limited": "Ô±ÕµÕ½ Õ½Õ¿Õ¸Ö\80Õ¸Õ£Õ¸Ö\82Õ©Õ¥Õ¡Õ¶ մէջ կը գտնուին հետեւեալ  {{PLURAL:$1|նիշքը|$1 նիշքերը}}։",
        "listingcontinuesabbrev": "շար.",
        "index-category": "Չցուցակագրուած էջեր",
        "noindex-category": "Չցուցակագրուած էջեր",
        "disclaimerpage": "Project:Պատասխանատուութեան ընդհանուր բացասում",
        "edithelp": "Խմբագրութեան ուղեցոյց",
        "helppage-top-gethelp": "Օգնութիւն",
-       "mainpage": "Գլխաւոր էջ",
-       "mainpage-description": "Գլխաւոր էջ",
+       "mainpage": "Գլխաւոր Էջ",
+       "mainpage-description": "Գլխաւոր Էջ",
        "portal": "Համայնքային դարպաս",
        "portal-url": "Project:Համայնքային դարպաս",
        "privacy": "Սեփական տուեալներու պահպանման քաղաքականութիւն",
        "badaccess-group0": "Արտունութիւն չունիք այս գործողութիւնը կատարել:",
        "badaccess-groups": "Տուեալ գործողութիւնը միայն $1 {{PLURAL:$2|խումբի|խումբերի}} մասնակիցները կ՛րնան կատարել։",
        "ok": "Լաւ",
+       "pagetitle": "Միացէ՛ք {{SITENAME}} նախագիծին",
        "retrievedfrom": "Վերցուած է «$1» էջէն",
        "youhavenewmessages": "{{PLURAL:$3|Դուք ունիք}} $1 ($2)։",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Դուք ունիք}} $1 {{PLURAL:$3|այլ մասնակից|$3 մասնակիցէն}} ($2):",
        "nstab-template": "Կաղապար",
        "nstab-help": "Օգնութեան էջ",
        "nstab-category": "Ստորոգութիւն",
-       "mainpage-nstab": "Գլխաւոր էջ",
+       "mainpage-nstab": "Գլխաւոր Էջ",
        "nosuchaction": "Այս գործողութիւնը չկայ",
        "nosuchspecialpage": "Այդպիսի յատուկ էջ չկայ",
        "nospecialpagetext": "<strong> Ձեր խնդրած յատուկ էջը անվաւեր է։</strong>\n\nՎաւերական յատուկ էջերու ցանկը կը գտնէք այստեղ՝ [[Special:SpecialPages|{{int:յատուկէջեր}}]].",
+       "error": "Սխալ",
        "databaseerror-query": "Հարցակէտ. $1",
        "databaseerror-function": "Գործառնութիւն. $1",
        "databaseerror-error": "Սխալ. $1",
        "viewsource": "Տեսնել աղբիւրը",
        "viewsource-title": "Տեսնել $1 էջի աղբիւրը",
        "viewsourcetext": "Կրնաք այս էջին աղբիւրը տեսնել ու ընդօրինակել։",
-       "yourname": "Գործածողի անուն.",
-       "userlogin-yourname": "Մասնակցային անուն",
-       "userlogin-yourname-ph": "Մուտքագրեցէ'ք ձեր մասնակցային անունը",
-       "createacct-another-username-ph": "Մուտքագրէք գործածողի անունը",
-       "yourpassword": "Գաղտնաբառ.",
+       "invalidtitle": "Անվաւեր վերնագիր",
+       "exception-nologin": "Դուք մուտք չէք գործած համակարգ",
+       "welcomeuser": "Բարի գալո՜ւստ, $1",
+       "welcomecreation-msg": "Ձեր հաշիւը ստեղծուած է։\nՉմոռնաք փոփոխել ձեր [[Special:Preferences|նախընտրութիւնները]]։",
+       "yourname": "Մասնակիցի անուն",
+       "userlogin-yourname": "Մասնակիցի անուն",
+       "userlogin-yourname-ph": "Մուտքագրեցէ'ք ձեր մասնակիցի անունը",
+       "createacct-another-username-ph": "Մուտքագրեցէ՛ք ձեր մասնակիցի անունը",
+       "yourpassword": "Անցաբառ՝",
        "userlogin-yourpassword": "Անցաբառ",
        "userlogin-yourpassword-ph": "Մուտքագրեցէ'ք ձեր անցաբառը",
-       "createacct-yourpassword-ph": "Մուտքագրեցէ'ք անցաբառ մը",
-       "yourpasswordagain": "Նորէն մուտքագրէք գաղտնաբառը",
-       "createacct-yourpasswordagain": "Հաստատեցէ'ք անցաբառը",
-       "createacct-yourpasswordagain-ph": "Դարձեալ մուտքագրեցէ'ք անցաբառը",
+       "createacct-yourpassword-ph": "Մուտքագրեցէ՛ք անցաբառ մը",
+       "yourpasswordagain": "Դարձեալ մուտքագրեցէ՛ք անցաբառը",
+       "createacct-yourpasswordagain": "Հաստատեցէ՛ք անցաբառը",
+       "createacct-yourpasswordagain-ph": "Դարձեալ մուտքագրեցէ՛ք անցաբառը",
        "userlogin-remembermypassword": "Մնալ համակարգին մէջ",
+       "cannotloginnow-title": "Այժմ դուք չէք կրնար մուտք գործել",
+       "cannotcreateaccount-title": "Չէք կրնար հաշիւներ ստեղծել",
+       "password-change-forbidden": "Այս Ուիքիին մէջ դուք չէք կրնար անցաբառեր փոխել։",
        "login": "Մուտք գործել",
+       "login-security": "Հաստատեցէէ՛ք Ձեր ինքնութիւնը",
+       "nav-login-createaccount": "Մուտք գործել/Հաշիւ ստեղծել",
+       "logout": "Դուրս գալ",
+       "userlogout": "Դուրս գալ",
+       "notloggedin": "Դուք մուտք չէք գործած համակարգ",
        "userlogin-noaccount": "Հաշիւ չունի՞ք։",
        "userlogin-joinproject": "Միացէ՛ք {{SITENAME}} նախագիծին",
        "createaccount": "Հաշիւ ստեղծել",
        "userlogin-resetpassword-link": "Անցաբառը մոռցա՞ծ էք",
        "userlogin-helplink2": "Մուտք գործելու օգնութիւն",
-       "createacct-emailoptional": "Իմակահասցէ (ոչ պարտադիր)",
-       "createacct-email-ph": "Մուտքագրեցէ՛ք ձեր իմակահասցէն",
+       "userlogin-createanother": "Այլ հաշիւ ստեղծել",
+       "createacct-emailrequired": "Ելեկտրոնային հասցէ",
+       "createacct-emailoptional": "Ելեկտրոնային հասցէ (ոչ պարտադիր)",
+       "createacct-email-ph": "Մուտքագրեցէ՛ք ձեր ելեկտրոնային հասցէն",
+       "createacct-another-email-ph": "Մուտքագրեցէ՛ք ձեր ելեկտրոնային հասցէն",
+       "createacct-realname": "Իրական անուն (ոչ պարտադիր)",
        "createacct-reason": "Պատճառ",
        "createacct-submit": "Ստեղծել ձեր հաշիւը",
+       "createacct-another-submit": "Հաշիւ ստեղծել",
+       "createacct-continue-submit": "Շարունակեցէ՛ք հաշիւի ստեղծումը",
+       "createacct-another-continue-submit": "Շարունակեցէ՛ք հաշիւի ստեղծումը",
        "createacct-benefit-heading": "{{SITENAME}}՝ ստեղծուած է ձեզի պէս մարդոց կողմէ։",
        "createacct-benefit-body1": "{{PLURAL:$1|խմբագրում}}",
        "createacct-benefit-body2": "$1 {{PLURAL:$1|էջ}}",
        "createacct-benefit-body3": "վերջին {{PLURAL:$1|մասնակից}}",
+       "badretype": "Ձեր նշած անցաբառերը իրարու չեն համապատասխաներ։",
+       "loginerror": "Մուտքի սխալ",
+       "createacct-error": "Հաշուի ստեղծման սխալ",
        "loginsuccesstitle": "Բարեյաջող մուտք",
        "loginsuccess": "'''Դուք մուտք գործեցիք {{SITENAME}}, իբր \"$1\"։'''",
        "nouserspecified": "Հարկաւոր է նշել մասնակցին անունը։",
        "pt-userlogout": "Դուրս գալ",
        "php-mail-error-unknown": "Անյայտ սխալ PHP-ի mail() կախարկութեան մէջ:",
        "changepassword": "Գաղտնաբառը փոխել",
-       "newpassword": "Նոր գաղտնաբառը.",
+       "resetpass_header": "Փոխել հաշիւի անցաբառը",
+       "oldpassword": "Հին անցաբառը.",
+       "newpassword": "Նոր անցաբառը.",
        "retypenew": "Նորէն մուտքագրէք գաղտնաբառը",
-       "changepassword-success": "Ձեր գաղտնաբառը փոխուեցաւ։",
+       "resetpass_submit": "Հաստատեցէ՛ք անցաբառը եւ մուտք գործեցէ՛ք համակարգ",
+       "changepassword-success": "Ձեր անցաբառը փոխուեցաւ։",
+       "botpasswords-label-appid": "Մեքենայիկի անուն՝",
        "botpasswords-label-create": "Ստեղծել",
        "botpasswords-label-cancel": "Չեղարկել",
        "botpasswords-label-delete": "Ջնջել",
        "botpasswords-label-resetpassword": "Վերականգնել գաղտնաբառը",
+       "botpasswords-label-grants-column": "Արտօնութիւնը տրուած է",
+       "botpasswords-bad-appid": "\"$1\" մեքենայիկին անունը չէ վաւերացուած:",
+       "botpasswords-created-title": "Մեքենայիկին անցաբառը ստեղծուեցաւ",
+       "botpasswords-deleted-title": "Մեքենայիկին անցաբառը ջնջուեցաւ",
+       "resetpass_forbidden": "Անցաբառերը չեն կրնար փոխել",
+       "resetpass-submit-loggedin": "Անցաբառը փոխել",
        "resetpass-submit-cancel": "Չեղարկել",
        "resetpass-temp-password": "Ժամանակաւոր գաղտնաբառ.",
        "passwordreset": "Վերականգնել անցաբառը",
+       "passwordreset-username": "Մասնակիցի անուն՝",
        "passwordreset-domain": "Համակարգիչի պետութիւն.",
        "passwordreset-email": "Էլ-նամակաի հասցէն.",
        "passwordreset-emailtitle": "{{SITENAME}} հաշիւի մանրամասները",
+       "passwordreset-invalidemail": "Անվաւեր ելեկտրոնային հասցէ",
+       "changeemail": "Փոխել կամ հանել ելեկտրոնային հասցէն",
+       "changeemail-oldemail": "Այժմու ելեկտրոնային հասցէ․",
+       "changeemail-newemail": "Նոր ելեկտրոնային հասցէ․",
+       "changeemail-none": "(ոչ մէկ)",
+       "changeemail-password": "Ձեր {{SITENAME}} անցաբառը՝",
+       "changeemail-submit": "Փոխել ելեկտրոնային հասցէն",
        "bold_sample": "Շեշտուած տառերով գրութիւն",
        "bold_tip": "Շեշտուած տառերով գրութիւն",
        "italic_sample": "Շեղատառ գրութիւն",
        "headline_tip": "Երկրորդ մակարդակի վերնագիր",
        "nowiki_sample": "Մուտքագրեցէ՛ք չձեւաւորուած գրութիւնը այստեղ",
        "nowiki_tip": "Անտեսել ուիքի ձեւաւորումը",
+       "image_sample": "Օրինակ.jpg",
        "image_tip": "Ներփակ նիշք",
+       "media_sample": "Օրինակ.jpg",
        "media_tip": "Նիշքին յղումը",
        "sig_tip": "Ձեր ստորագրութիւնը ժամակնիքով",
        "hr_tip": "Հորիզոնական գիծ (գործածել խնայողաբար)",
        "preview": "Կանխաստուգել",
        "showpreview": "Կանխաստուգել",
        "showdiff": "Ցուցնել փոփոխութիւնները",
-       "anoneditwarning": "<strong>Զգուշացում։</strong> Մուտք գործած չէք համակարգ։ Որեւէ խմբագրումի պարագային ձեր IP հասցէն տեսանելի կը դառնայ բոլորին։ Եթե <strong>[$1 մուտք գործէք]</strong> կամ <strong>[$2 ստեղծէք մասնակցային հաշիւ]</strong>, ձեր կատարած խմբագրումները կը կապուին ձեր մասնակցային անունին հետ, ինչպէս նաեւ կ՚ունենաք այլ առաւելութիւններ։",
+       "anoneditwarning": "<strong>Զգուշացում։</strong> Մուտք գործած չէք համակարգ։ Որեւէ խմբագրումի պարագային ձեր IP հասցէն տեսանելի կը դառնայ բոլորին։ Եթէ <strong>[$1 մուտք գործէք]</strong> կամ <strong>[$2 ստեղծէք մասնակիցի հաշիւ]</strong>, ձեր կատարած խմբագրումները կը կապուին ձեր մասնակիցի անունին հետ, ինչպէս նաեւ կ՚ունենաք այլ առաւելութիւններ։",
+       "blockedtitle": "Մասնակիցը արգելափակուած է",
        "blockedtext": "<strong>Ձեր մասնակցային անոիւնը կամ IP հասցէն արգելակուած է։</strong>\n\nԱրգելակումը կատարուած է $1ի կողմէ.\nՊարտճառը՝ <em>$2</em>.\n\n* Արգելակման սկիբժ՝ $8\n* Արգելակման աւարտ՝ $6\n* արգելակուած առարկայ՝ $7\n\nԿրնաք կապուիլ $1ի կամ այլ անդատներու հետ [[{{MediaWiki:Grouppage-sysop}}|վարիչ]] արգելակման մասին զրուցելու համար.\nՉէք կրնար օգտագործել \"{{int:emailuser}}\" հնարաւորութիւնը բացի եթէ նշած էք իմակի վաւերական հասցէ մը ձեր [[Special:Preferences|account preferences]] եւ արգելակուած չէ վեր անոր օգտագործումը.\nՁեր ընթացիկ IP հասցէն է $3, եւ արգելակման ինքնութեան համարն է #$5.\nԿը շնդրենք որ այս մանրամասնութիւնները նշէք ձեր բոլոր թղթակցութիւններուն մէջ։",
-       "loginreqlink": "մուտք գործել",
+       "loginreqtitle": "Կը խնդրուի մուտք գործել համակարգ",
+       "loginreqlink": "Մուտք գործել",
+       "newarticle": "(Նոր)",
        "newarticletext": "Դուք յղուած էք տակաւին գոյութիւն չունեցող էջի մը։\nԷջը ստեղծելու համար, մեքենագրեցէք ներքեւի տուփիկին մէջ (յաւելեալ տեղեկութեանց համար տե՛ս [$1 օգնութեան ցուցմունքներու էջը])։\nԵթէ սխալմամբ հոս հասած էք, սեղմել դիտարկիչի <strong>ետ</strong> կոճակը։",
        "anontalkpagetext": "<em> Այս էջը առայժմ հաշիւ չստեղծած, կամ հաշիւ չօգտագործող, անանուն մասնակիցներու քննարկման էջն է։</em>\nՈւրեմն որպէս ինքնութիւն ստիպուած ենք օգտագործել անոնց IP հասցէն։\nԱյսպիսի IP հասցէ կրնան ունենալ մէկէ աւելի մասնակիցներ։\nԵթէ դուք անանուն մասնակից էք եւ կը խորհիք որ անկապ դիտողութիւններու թիրախ դարձած էք, կը խնդրուի [[Special:CreateAccount|Հաշիւ ստեղծել]] կամ [[Special:UserLogin|մուտք գործել]] խուսափելու համար ապագային այլ անդանուն մասնակիցներու հետ շփոթուելու հնարաւորութենէն։",
        "noarticletext": "Ներկայիս այս էջին վրայ որեւէ գրութիւն չկայ։\nԴուք կրնաք [[Special:Search/{{PAGENAME}}|որոնել այս անուանումը]] այլ էջերու մէջ, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} որոնել համապատասխան տեղեկամատեանները] կամ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ստեղծել նոր էջ այս անուանումով]</span>։",
        "editing": "Կը խմբագրուի՝ $1 էջը",
        "creating": "«$1» էջի ստեղծում",
        "editingsection": "$1 բաժինի խմբագրում",
+       "yourtext": "Ձեր գրութիւնը",
+       "storedversion": "Պահուած տարբերակ",
        "yourdiff": "Տարբերութիւններ",
        "templatesused": "Այս էջին մէջ օգտագործուած {{PLURAL:$1|կաղապարը|կաղապարները}}.",
        "templatesusedpreview": "{{PLURAL:$1|Կաղապար}} օգտագործուած այս կանխաստուգումին մէջ՝",
        "recreate-moveddeleted-warn": "<strong>Զգուշացում. Նախապէս ջնջուած էջ մը պիտի վերստեղծուի։<strong>\n\nԿը խնդրուի մտածել այս էջի խմբագրման նպատակայարմարութեան մասին։ \nՁեր դիւրութեան համար ներքեւ կը գտնէք այս էջի ջնջումին և տեղափոխումին տեղեկատետրերը։",
        "moveddeleted-notice": "Այս էջը ջնջուած է։\nԷջին ջնջումի, պահպանումի եւ փոխադրումի տեղեկատետրը տրամադրելի է ներքեւ որպէս տեղեկութիւն։",
        "edit-conflict": "Խմբագրման ընհարում։",
+       "postedit-confirmation-created": "Էջը ստեղծուած է։",
+       "postedit-confirmation-saved": "Ձեր խմբագրումը պահուած է:",
+       "postedit-confirmation-published": "Ձեր խմբագրումը հրատարակուած է:",
+       "slot-name-main": "Գլխաւոր",
        "content-model-wikitext": "ուիքիթէքսթ",
        "content-model-text": "պարզ բնաբան",
        "content-model-javascript": "ՃաւաՍքրիփթ",
        "history-fieldset-title": "Որոնել տարբերակներ",
        "histfirst": "հնագոյն",
        "histlast": "նորագոյն",
+       "historyempty": "պարապ",
        "history-feed-title": "Վերանայումներու ցուցակ",
        "history-feed-description": "Ուիքիի այս էջին վերանայումներու ցուցակը",
        "history-feed-item-nocomment": "$1՝ $2",
        "rev-delundel": "ցուցնել/թաքցնել",
        "rev-showdeleted": "Ցուցադրել",
        "revdelete-show-file-submit": "Այո",
+       "revdelete-hide-image": "Թաքցնել նիշքին բովանդակութիւնը",
+       "revdelete-radio-unset": "Տեսանելի",
        "revdelete-log": "Պատճառ.",
+       "pagehist": "Էջի պատմութիւն",
        "revdelete-reasonotherlist": "Ուրիշ պատճառ.",
+       "revdelete-edit-reasonlist": "Խմբագրել ջնջման պատճառները",
        "mergehistory-reason": "Պատճառ.",
        "mergelog": "Ձուլման տեղեկատետր",
        "history-title": "«$1»ի վերանայումներու ցուցակ",
        "diff-multi-otherusers": "(նոյն մասնակիցի ցոյց չտրուած {{PLURAL:$1|մէկ միջանկեալ վերանայում|$2 միջանկեալ վերանայումներ}})",
        "searchresults": "Որոնման արդիւնքներ",
        "searchresults-title": "«$1»-ի որոնման արդիւնքները",
+       "notextmatches": "Չկան համապատասխան գրութիւնով էջեր",
        "prevn": "նախորդ {{PLURAL:$1|$1}}",
        "nextn": "յաջորդ {{PLURAL:$1|$1}}",
        "prev-page": "նախորդ էջ",
        "searchall": "բոլոր",
        "search-showingresults": "{{PLURAL:$4|<strong>$1</strong> արդիւնք <strong>$3</strong>-էն|<strong>$1 - $2</strong> արդիւնքներ <strong>$3</strong>-էն}}",
        "search-nonefound": "Որոնումին համապատասխանող արդիւնքներ չգտնուեցան",
+       "powersearch-toggleall": "Բոլոր",
+       "powersearch-togglenone": "Ոչ մէկ",
+       "search-external": "Արտաքին որոնում",
+       "preferences": "Նախընտրութիւններ",
        "mypreferences": "Նախընտրութիւններ",
        "skin-preview": "Նախադիտել",
+       "prefs-watchlist": "Հսկողութեան ցանկ",
+       "prefs-editwatchlist-clear": "Մաքրել հսկողութեան ցանկը",
+       "saveprefs": "Յիշել",
+       "searchresultshead": "Որոնել",
        "stub-threshold-sample-link": "օրինակ",
        "timezoneregion-africa": "Ափրիկէ",
        "timezoneregion-america": "Ամերիկա",
        "timezoneregion-europe": "Եւրոպա",
        "timezoneregion-indian": "Հնդկական Ովկիանոս",
        "timezoneregion-pacific": "Խաղաղ Ովկիանոս",
+       "prefs-searchoptions": "Որոնել",
        "youremail": "Էլեկտրական Նամակ",
+       "yourlanguage": "Լեզու.",
        "email": "Էլեկտրական Նամակ",
+       "prefs-info": "Հիմնական տուեալներ",
+       "prefs-editor": "Խմբագրող",
+       "prefs-preview": "Նախադիտել",
        "group": "Խումբ.",
        "group-bot": "Մեքենայիկներ",
        "group-sysop": "Վարիչներ",
        "recentchanges-label-plusminus": "Էջին ծաւալը փոխուեցաւ այսքան պայթով",
        "recentchanges-legend-heading": "<strong>Ծանօթ.՝</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (տե՛ս նաեւ՝  [[Special:NewPages|նոր էջերու ցանկ]])",
+       "rcfilters-activefilters": "Աշխոյժ զտիչներ",
        "rcnotefrom": "Ներքեւ {{PLURAL:$5|փոփոխութիւնն է|փոփոխութիւններն են}} սկսեալ <strong>$3, $4</strong> (մինչեւ <strong>$1</strong> ցոյց տրուած).",
        "rclistfrom": "Ցոյց տալ նոր փոփոխութիւնները սկսած $3 $2",
        "rcshowhideminor": "$1 չնչին խմբագրումներ",
        "imgmultipagenext": "յաջորդ էջը →",
        "imgmultigo": "Անցնի՛լ",
        "imgmultigoto": "Անցնիլ $1 էջը",
+       "watchlistedit-clear-title": "Մաքրել հսկողութեան ցանկը",
+       "watchlistedit-clear-legend": "Մաքրել հսկողութեան ցանկը",
        "watchlisttools-clear": "Մաքրել հսկողութեան ցանկը",
        "watchlisttools-view": "Ցուցադրել փոփոխութիւնները",
        "watchlisttools-edit": "Տեսնել եւ խմբագրել հսկողութեան ցանկը",
        "logentry-newusers-autocreate": "$1 մասնակցային հաշիւը {{GENDER:$2|ստեղծուած է}} ինքնաբերաբար",
        "logentry-upload-upload": "$1 {{GENDER:$2|ներբեռնուած է}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|վերբեռնեց}} $3ի նոր տարբերակ",
+       "feedback-cancel": "Չեղարկել",
        "searchsuggest-search": "Որոնել {{SITENAME}} կայքին մէջ",
        "duration-days": "$1 {{PLURAL:$1|օր}}",
        "randomrootpage": "Պատահական արմատ էջ"
index 4ad1d0b..e748e28 100644 (file)
@@ -63,6 +63,7 @@
        "tog-norollbackdiff": "Non monstrar differentias post exequer un revocation",
        "tog-useeditwarning": "Advertir me quando io quita un pagina de modification sin publicar le cambiamentos",
        "tog-prefershttps": "Sempre usar un connexion secur durante session aperte",
+       "tog-showrollbackconfirmation": "Monstrar un demanda de confirmation al cliccar sur un ligamine de revocation",
        "underline-always": "Sempre",
        "underline-never": "Nunquam",
        "underline-default": "Como definite per tu navigator o apparentia",
        "badretype": "Le duo contrasignos que tu scribeva non es identic.",
        "usernameinprogress": "Le creation de un conto con iste nomine de usator es jam in curso.\nPer favor, attende.",
        "userexists": "Iste nomine de usator es jam in uso.\nSelige un altere nomine.",
+       "createacct-normalization": "Tu nomine de usator essera adjustate a \"$2\" a causa de restrictiones technic.",
        "loginerror": "Error in le apertura del session",
        "createacct-error": "Error de creation de conto",
        "createaccounterror": "Non poteva crear le conto: $1",
        "page_first": "prime",
        "page_last": "ultime",
        "histlegend": "Pro comparar duo versiones: marca lor circulos correspondente, e preme <code>Enter</code> o clicca le button in basso.<br />\nLegenda: '''({{int:cur}})''' = comparar con le version actual,\n'''({{int:last}})''' = comparar con le version precedente, '''{{int:minoreditletter}}''' = modification minor.",
-       "history-fieldset-title": "Cercar versiones",
+       "history-fieldset-title": "Filtrar versiones",
        "history-show-deleted": "Solmente versiones delite",
        "histfirst": "le plus ancian",
        "histlast": "le plus nove",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
-       "historyempty": "(vacue)",
+       "historyempty": "vacue",
        "history-feed-title": "Historia de versiones",
        "history-feed-description": "Historia del versiones de iste pagina in le wiki",
        "history-feed-item-nocomment": "$1 a $2",
        "right-reupload-own": "Superscriber un file anteriormente incargate per uno mesme",
        "right-reupload-shared": "Supplantar localmente le files del respositorio commun de media",
        "right-upload_by_url": "Incargar un file ab un adresse URL",
-       "right-purge": "Purgar le cache de un pagina in le sito sin confirmation",
+       "right-purge": "Purgar le cache de un pagina in le sito",
        "right-autoconfirmed": "Non esser subjecte al limites de frequentia a base de adresse IP",
        "right-bot": "Esser tractate como processo automatic",
        "right-nominornewtalk": "Non reciper notification de nove messages quando se face modificationes minor in le pagina de discussion",
        "delete-confirm": "Deler \"$1\"",
        "delete-legend": "Deler",
        "historywarning": "<strong>Attention:</strong> Le pagina que tu vole deler ha un historia de circa $1 {{PLURAL:$1|version|versiones}}:",
-       "historyaction-submit": "Monstrar",
+       "historyaction-submit": "Monstrar versiones",
        "confirmdeletetext": "Tu va deler un pagina con tote su historia.\nPer favor confirma que tu ha le intention de facer isto, que tu comprende le consequentias, e que tu face isto in accordo con [[{{MediaWiki:Policy-url}}|le politicas]].",
        "actioncomplete": "Action complete",
        "actionfailed": "Action fallite",
        "deleting-backlinks-warning": "<strong>Attention:</strong> Il ha [[Special:WhatLinksHere/{{FULLPAGENAME}}|altere paginas]] que liga a o transclude le pagina que tu es sur le puncto de deler.",
        "deleting-subpages-warning": "<strong>Attention:</strong> Le pagina que tu es sur le puncto de deler ha [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|un subpagina|$1 subpaginas|51=plus de 50 subpaginas}}]].",
        "rollback": "Revocar modificationes",
+       "rollback-confirmation-confirm": "Per favor confirma:",
+       "rollback-confirmation-yes": "Revocar",
+       "rollback-confirmation-no": "Cancellar",
        "rollbacklink": "revocar",
        "rollbacklinkcount": "revocar $1 {{PLURAL:$1|modification|modificationes}}",
        "rollbacklinkcount-morethan": "revocar plus de $1 {{PLURAL:$1|modification|modificationes}}",
        "revertpage": "Reverteva modificationes per [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussion]]) al ultime version per [[User:$1|$1]]",
        "revertpage-nouser": "Reverteva modificationes per un usator celate al ultime version per {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Revocava modificationes per {{GENDER:$3|$1}};\nretornava al version per {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Modificationes de $1 revertite;\nultime version de $2 restaurate. [$3 Monstrar cambiamentos]",
        "sessionfailure-title": "Error de session",
        "sessionfailure": "Il pare haber un problema con tu session;\niste action ha essite cancellate como precaution contra le robamento de sessiones.\nPer favor, resubmitte le formulario.",
        "changecontentmodel": "Cambiar le modello de contento de un pagina",
        "mycontris": "Contributiones",
        "anoncontribs": "Contributiones",
        "contribsub2": "Pro {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Pro {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Le conto de usator \"$1\" non es registrate.",
        "negative-namespace-not-supported": "Le spatios de nomines con valores negative non es supportate.",
        "nocontribs": "Nulle modification correspondente a iste criterios ha essite trovate.",
-       "uctop": "ultime",
+       "uctop": "actual",
        "month": "A partir del mense (e anterior):",
        "year": "A partir del anno (e anterior):",
        "date": "A partir del data (e anterior):",
        "ipb-confirm": "Confirmar blocada",
        "ipb-sitewide": "Sur tote le sito",
        "ipb-partial": "Partial",
+       "ipb-sitewide-help": "Cata pagina del wiki e tote le altere actiones de contribution.",
+       "ipb-partial-help": "Paginas o spatios de nomines specific.",
        "ipb-pages-label": "Paginas",
        "ipb-namespaces-label": "Spatios de nomines",
        "badipaddress": "Adresse IP mal formate.",
        "confirm-unwatch-top": "Remover iste pagina de tu observatorio?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Reverter le modificationes a iste pagina?",
+       "confirm-rollback-bottom": "Iste action revocara instantaneemente le modificationes seligite de iste pagina.",
        "confirm-mcrrestore-title": "Restaurar version",
        "confirm-mcrundo-title": "Disfacer un modification",
        "mcrundofailed": "Disfaction fallite",
        "logentry-rights-autopromote": "$1 ha essite automaticamente {{GENDER:$2|promovite}} de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|ha incargate}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha incargate}} un nove version de $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|ha incargate}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|ha revertite}} $3 a un version ancian",
        "log-name-managetags": "Registro de gestion de etiquettas",
        "log-description-managetags": "Iste pagina lista le cargas de gestion relative a [[Special:Tags|etiquettas]]. Le registro contine solmente le actiones exequite manualmente per un administrator; etiquettas pote esser create o delite per le software wiki sin insertion de un entrata in iste registro.",
        "logentry-managetags-create": "$1 {{GENDER:$2|creava}} le etiquetta \"$4\"",
        "log-action-filter-suppress-reblock": "Suppression de usator per re-blocada",
        "log-action-filter-upload-upload": "Nove file incargate",
        "log-action-filter-upload-overwrite": "File re-incargate",
+       "log-action-filter-upload-revert": "Reverter",
        "authmanager-authn-not-in-progress": "Le authentication non es in curso o le datos del session ha essite perdite. Per favor, recomencia ab initio.",
        "authmanager-authn-no-primary": "Le credentiales fornite non poteva esse authenticate.",
        "authmanager-authn-no-local-user": "Le credentiales fornite non es associate a alcun usator in iste wiki.",
        "authmanager-create-no-primary": "Le credentiales fornite non pote esser usate pro crear un conto.",
        "authmanager-link-no-primary": "Le credentiales fornite non pote esser usate pro ligar un conto.",
        "authmanager-link-not-in-progress": "Nulle ligation de conto es in curso, o le datos del session ha essite perdite. Per favor, recomencia ab initio.",
-       "authmanager-authplugin-setpass-failed-title": "Cambio de contrasigno fallite",
-       "authmanager-authplugin-setpass-failed-message": "Le modulo de authentication ha refusate le cambio de contrasigno.",
-       "authmanager-authplugin-create-fail": "Le modulo de authentication ha refusate le creation de conto.",
-       "authmanager-authplugin-setpass-denied": "Le modulo de authentication non permitte cambiar contrasignos.",
-       "authmanager-authplugin-setpass-bad-domain": "Dominio non valide.",
        "authmanager-autocreate-noperm": "Le creation automatic de contos non es permittite.",
        "authmanager-autocreate-exception": "Le creation automatic de contos ha essite temporarimente disactivate a causa de errores previe.",
        "authmanager-userdoesnotexist": "Le conto de usator \"$1\" non es registrate.",
        "passwordpolicies-policy-maximalpasswordlength": "Le contrasigno debe continer minus de $1 {{PLURAL:$1|character|characteres}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Le contrasigno non pote esser {{PLURAL:$1|le contrasigno le plus popular|in le lista de $1 contrasignos popular}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Le contrasigno non pote apparer in le lista del 100.000 contrasignos le plus commun.",
+       "passwordpolicies-policyflag-forcechange": "debe cambiar al apertura de session",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "suggerer cambio al apertura de session",
        "easydeflate-invaliddeflate": "Le contento fornite non es correctemente comprimite",
        "unprotected-js": "Pro motivos de securitate, non es possibile cargar codice JavaScript de paginas non protegite. Crea JavaScript solmente in le spatio de nomines \"MediaWiki:\" o como un subpagina de usator."
 }
index 6644302..95b8012 100644 (file)
@@ -61,7 +61,9 @@
                        "Dodolzk",
                        "Fitoschido",
                        "Palladin911",
-                       "Bagas Chrisara"
+                       "Bagas Chrisara",
+                       "Pebaryan",
+                       "Veracious"
                ]
        },
        "tog-underline": "Garis bawahi pranala:",
@@ -96,7 +98,7 @@
        "tog-watchlisthidebots": "Sembunyikan suntingan bot di daftar pantauan",
        "tog-watchlisthideminor": "Sembunyikan suntingan kecil di daftar pantauan",
        "tog-watchlisthideliu": "Sembunyikan suntingan pengguna masuk log di daftar pantauan",
-       "tog-watchlistreloadautomatically": "Muat ulang daftar pantauan secara otomatis ketika sebuah tapis berubah (JavaScript diperlukan)",
+       "tog-watchlistreloadautomatically": "Muat ulang daftar pantauan secara otomatis ketika sebuah filter berubah (JavaScript diperlukan)",
        "tog-watchlistunwatchlinks": "Tambahkan penanda pantau/hapus pantauan ke halaman yang dipantau yang berubah (JavaScript diperlukan untuk mengganti fungsi ini)",
        "tog-watchlisthideanons": "Sembunyikan suntingan pengguna anonim di daftar pantauan",
        "tog-watchlisthidepatrolled": "Sembunyikan suntingan terpatroli di daftar pantauan",
        "sitejspreview": "'''Ingatlah bahwa Anda hanya menampilkan pratayang dari kode JavaScript ini.'''\n'''Perubahan belum disimpan!'''",
        "userinvalidconfigtitle": "<strong>Peringatan:</strong> Kulit \"$1\" tidak ditemukan. Harap diingat bahwa halaman .css, .json, dan .js menggunakan huruf kecil, contoh {{ns:user}}:Foo/vector.css dan bukannya {{ns:user}}:Foo/Vector.css.",
        "updated": "(Diperbarui)",
-       "note": "'''Catatan:'''",
+       "note": "<strong>Catatan:</strong>",
        "previewnote": "'''Ingatlah bahwa ini hanya pratayang.'''\nPerubahan Anda belum disimpan!",
        "continue-editing": "Lanjutkan penyuntingan",
        "previewconflict": "Pratayang ini mencerminkan teks pada bagian atas kotak suntingan teks sebagaimana akan terlihat bila Anda menyimpannya.",
        "previousrevision": "← Revisi sebelumnya",
        "nextrevision": "Revisi selanjutnya →",
        "currentrevisionlink": "Revisi terkini",
-       "cur": "skr",
+       "cur": "skrg.",
        "next": "selanjutnya",
-       "last": "sebelum",
+       "last": "sblm.",
        "page_first": "pertama",
        "page_last": "terakhir",
        "histlegend": "Pilih dua tombol radio lalu tekan tombol ''bandingkan'' untuk membandingkan versi. Klik suatu tanggal untuk melihat versi halaman pada tanggal tersebut.<br />(skr) = perbedaan dengan versi sekarang, (akhir) = perbedaan dengan versi sebelumnya, '''k''' = suntingan kecil, '''b''' = suntingan bot, → = suntingan bagian, ← = ringkasan otomatis",
        "notextmatches": "Tidak ada teks halaman yang cocok",
        "prevn": "{{PLURAL:$1|$1}} sebelumnya",
        "nextn": "{{PLURAL:$1|$1}} selanjutnya",
-       "prev-page": "Halaman sebelumnya",
+       "prev-page": "halaman sebelumnya",
        "next-page": "Halaman selanjutnya",
        "prevn-title": "$1 {{PLURAL:$1|hasil|hasil}} sebelumnya",
        "nextn-title": "$1 {{PLURAL:$1|hasil|hasil}} selanjutnya",
        "rcfilters-noresults-conflict": "Hasil tidak ditemukan karena kriteria pencariannya bertentangan",
        "rcfilters-state-message-subset": "Filter ini tidak akan berpengaruh karena hasilnya disertakan oleh {{PLURAL:$2|filter}} berikut yang lebih luas (coba soroti untuk membedakannya): $1",
        "rcfilters-state-message-fullcoverage": "Memilih semua penyaringan dalam kelompok ini sama dengan tidak memilih apapun, sehingga penyaringan ini tidak memberikan hasil. Kelompok termasuk: $1",
-       "rcfilters-filtergroup-authorship": "Kontribusi pengarang",
+       "rcfilters-filtergroup-authorship": "Kontribusi penulis",
        "rcfilters-filter-editsbyself-label": "Suntingan Anda",
        "rcfilters-filter-editsbyself-description": "Kontribusi saya",
        "rcfilters-filter-editsbyother-label": "Suntingan orang lain",
        "rcfilters-liveupdates-button-title-off": "Tampilkan perubahan baru ketika perubahan tersebut terjadi",
        "rcfilters-watchlist-markseen-button": "Tandai semua perubahan sebagai terlihat",
        "rcfilters-watchlist-edit-watchlist-button": "Sunting daftar pantauan Anda",
-       "rcfilters-watchlist-showupdated": "Perubahan di halaman-halaman yang belum Anda kunjungi sejak perubahan terjadi ditampilkan dalam <strong>huruf terbal</strong>, dan tanda titik tebal di daftar.",
+       "rcfilters-watchlist-showupdated": "Perubahan di halaman-halaman yang belum Anda kunjungi sejak perubahan terjadi ditampilkan dalam <strong>huruf tebal</strong>, dan tanda titik tebal di daftar.",
        "rcfilters-preference-label": "Gunakan antarmuka non-Javascript",
        "rcfilters-preference-help": "Muat perubahan terbaru tanpa tapis pencarian atau fungsi penyorotan",
        "rcfilters-watchlist-preference-label": "Gunakan antarmuka non-Javascript",
        "uncategorizedcategories": "Kategori yang tak terkategori",
        "uncategorizedimages": "Berkas yang tak terkategori",
        "uncategorizedtemplates": "Templat yang tak terkategori",
+       "uncategorized-categories-exceptionlist": "# Terkandung daftar kategori, yang tidak boleh disebut di Special:UncategorizedCategories. Satu per baris, dimulai dengan \"*\". Baris-baris dimulai dengan karakter lain (termasuk baris putih) tidak dianggap. Gunakan \"#\" untuk memberikan komentar.",
        "unusedcategories": "Kategori yang tak terpakai (kosong)",
        "unusedimages": "Berkas yang tak terpakai",
        "wantedcategories": "Kategori yang diinginkan",
        "apisandbox-dynamic-parameters-add-label": "Tambah parameter:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nama parameter",
        "apisandbox-dynamic-error-exists": "Parameter bernama \"$1\" telah tersedia.",
+       "apisandbox-templated-parameter-reason": "Ini adalah [[Special:ApiHelp/main#main/templatedparams|parameter templat]] yang ditawarkan berdasarkan {{PLURAL:$1|value|values}} dari $2.",
        "apisandbox-deprecated-parameters": "Parameter usang",
        "apisandbox-fetch-token": "Isi token dengan otomatis",
        "apisandbox-add-multi": "Tambahkan",
        "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-results-login-suppressed": "Permintaan ini akan diproses sebagai pengguna log-out dan akan digunakan untuk memotong keamanan browser yang memiliki asal yang sama. Tolong diperhatikan pengurusan token bak pasir otomatis tidak bekerja dengan baik dengan permintaan tersebut, tolong isi secara manual.",
        "apisandbox-request-selectformat-label": "Tampilkan permintaan data sebagai:",
        "apisandbox-request-format-url-label": "String kueri URL",
        "apisandbox-request-url-label": "URL Permintaan:",
        "magiclink-tracking-isbn-desc": "Halaman ini menggunakan pranala magis ISBN. Lihat [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] bagaimana melakukan migrasi.",
        "specialloguserlabel": "Pengguna:",
        "speciallogtitlelabel": "Target (judul atau {{ns:user}}:nama pengguna untuk pengguna)",
-       "log": "Catatan (Log)",
+       "log": "Log",
        "logeventslist-submit": "Tampilkan",
        "logeventslist-more-filters": "Tampilkan log tambahan:",
        "logeventslist-patrol-log": "Log patroli",
        "deleting-backlinks-warning": "<strong>Peringatan:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Halaman lain]] mengarah atau memiliki transklusi ke halaman yang akan Anda hapus.",
        "deleting-subpages-warning": "<strong>Peringatan:</strong> Halaman yang akan Anda hapus memiliki [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|subhalaman|$1 subhalaman|51=lebih dari 50 subhalaman}}]].",
        "rollback": "Kembalikan suntingan",
+       "rollback-confirmation-confirm": "Silakan konfirmasi:",
+       "rollback-confirmation-yes": "Kembalikan",
+       "rollback-confirmation-no": "Batal",
        "rollbacklink": "kembalikan",
        "rollbacklinkcount": "kembalikan $1 {{PLURAL:$1|suntingan}}",
        "rollbacklinkcount-morethan": "kembalikan lebih dari $1 {{PLURAL:$1|suntingan|suntingan}}",
        "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 {{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 sebagai antisipasi untuk mencegah pembajakan. Silakan tekan tombol \"kembali\" dan muat kembali halaman sebelum Anda masuk, lalu coba lagi.",
        "changecontentmodel": "Ubah model isi sebuah halaman",
        "mycontris": "Kontribusi",
        "anoncontribs": "Kontribusi",
        "contribsub2": "Untuk {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Untuk {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Pengguna \"$1\" tidak terdaftar.",
+       "negative-namespace-not-supported": "Ruangnama dengan nilai negatif tidak didukung.",
        "nocontribs": "Tidak ada perubahan yang sesuai dengan kriteria tersebut.",
        "uctop": "saat ini",
        "month": "Sejak bulan (dan sebelumnya):",
        "ipb-confirm": "Konfirmasi blokir",
        "ipb-sitewide": "Keseluruhan situs",
        "ipb-partial": "Parsial",
+       "ipb-partial-help": "Halaman atau ruangnama khusus.",
        "ipb-pages-label": "Halaman",
+       "ipb-namespaces-label": "Ruang nama",
        "badipaddress": "Format alamat IP atau nama pengguna salah.",
        "blockipsuccesssub": "Pemblokiran sukses",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] telah diblokir.<br />\nLihat [[Special:BlockList|daftar pemblokiran]] untuk meninjau kembali pemblokiran.",
        "blocklist-nousertalk": "tidak dapat menyunting halaman pembicaraan sendiri",
        "blocklist-editing": "penyuntingan",
        "blocklist-editing-sitewide": "editing (keseluruhan situs)",
+       "blocklist-editing-page": "laman",
+       "blocklist-editing-ns": "Ruang nama",
        "ipblocklist-empty": "Daftar pemblokiran kosong.",
        "ipblocklist-no-results": "Alamat IP atau pengguna yang diminta tidak diblokir.",
        "blocklink": "blokir",
        "redirect-file": "Nama berkas",
        "redirect-logid": "ID log",
        "redirect-not-exists": "Nilai tidak ditemukan",
+       "redirect-not-numeric": "Nilai bukan numerik",
        "fileduplicatesearch": "Pencarian berkas duplikat",
        "fileduplicatesearch-summary": "Pencarian duplikat berkas berdasarkan nilai hash-nya.",
        "fileduplicatesearch-filename": "Nama berkas:",
        "logentry-block-block": "$1 {{GENDER:$2|memblokir}} {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
        "logentry-block-unblock": "$1 telah {{GENDER:$2|mencabut pemblokiran}} atas {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|mengubah}} pemblokiran {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
+       "logentry-partialblock-block-page": "{{PLURAL:$1|halaman|halaman}} $2",
+       "logentry-partialblock-block-ns": "{{PLURAL:$1|ruangnama|ruangnama}} $2",
        "logentry-partialblock-block": "$1 {{GENDER:$2|memblokir}} {{GENDER:$4|$3}} dari penyuntingan $7 dengan waktu kedaluwarsa $5 $6",
+       "logentry-partialblock-reblock": "$1 {{GENDER:$2|mengubah}} pengaturan blokir pada {{GENDER:$4|$3}} untuk mencegah penyuntingan pada $7 dengan masa pemblokiran $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|memblokir}} {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|mengubah}} pemblokiran {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|mengimpor}} $3 melalui pemuatan berkas",
        "logentry-rights-autopromote": "$1 secara otomatis {{GENDER:$2|dipromosikan}} dari $4 menjadi $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|mengunggah}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|mengunggah}} versi baru dari $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|mengunggah}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|mengembalikan}} $3 ke versi lama",
        "log-name-managetags": "Log pengelolaan tag",
        "log-description-managetags": "Daftar halaman ini mencantumkan tugas-tugas yang terkait dengan [[Special:Tags|tag]]. Lognya hanya mengandung tindakan-tindakan yang dijalankan secara manual oleh pengurus; tag-tag bisa dibuat atau dihapus oleh perangkat lunak wiki tanpa tercatat entrinya dalam log ini.",
        "logentry-managetags-create": "$1 {{GENDER:$2|membuat}} tag \"$4\"",
        "log-action-filter-suppress-reblock": "Penyembunyian oleh pengguna menurut pemblokiran",
        "log-action-filter-upload-upload": "Unggahan baru",
        "log-action-filter-upload-overwrite": "Unggah kembali",
+       "log-action-filter-upload-revert": "Batalkan",
        "authmanager-authn-not-in-progress": "Otentikasi tidak dilanjutkan atau data sesi telah hilang. Ulang kembali dari awal.",
        "authmanager-authn-no-primary": "Kredensial yang diberikan tidak dapat diotentikasi.",
        "authmanager-authn-no-local-user": "Kredensial yang diberikan tidak terkait dengan satu orang pun pengguna di wiki ini.",
        "authmanager-create-no-primary": "Kredensial yang diberikan tidak dapat digunakan untuk pembuatan akun.",
        "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.",
        "authmanager-userdoesnotexist": "Pengguna \"$1\" tidak terdaftar.",
        "passwordpolicies-policy-maximalpasswordlength": "Kata sandi tidak boleh kurang dari {{PLURAL:$1|karakter|karakter}}.",
        "passwordpolicies-policy-passwordcannotbepopular": "Kata sandi tidak boleh {{PLURAL:$1|kata sandi populer|dalam senarai $1 kata sandi populer}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Kata sandi tidak boleh termasuk dalam daftar 100.000 kata sandi yang paling umum digunakan.",
+       "passwordpolicies-policyflag-forcechange": "wajib diganti ketika masuk log",
        "unprotected-js": "Karena alasan keamanan Javascript tidak dapat dimuat dari halaman yang tidak dilindungi. Mohon hanya buat javascript di ruangnama MediaWiki: atau sebagai subhalaman  Pengguna"
 }
index ea128ce..b02198c 100644 (file)
        "help": "Inyeáká",
        "help-mediawiki": "Enyemaka gbasara MidiyaWiki",
        "search": "Tùwe",
+       "search-ignored-headings": "#</pre><!--hapụ akara a otu ọdi-->",
        "searchbutton": "Tùwe",
        "go": "Gá",
        "searcharticle": "Gá",
        "ok": "Ngwanu",
        "retrievedfrom": "Wefụtàrà ya shí ''$1''",
        "youhavenewmessages": "I nwèrè $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|I nwere}}$1 site na {{PLURAL:$3|Onye ọru ọzọ|$3 ndi ọru}} ($2).",
+       "youhavenewmessagesmanyusers": "I nwere $1 si na ọtụtụ ndi ọru ($2)",
+       "newmessageslinkplural": "{{PLURAL:$1|ozi ọhụrụ|999=ozi ọhuru}}",
+       "newmessagesdifflinkplural": "ikpeazu{{PLURAL:$1|mgbanwe|999=mgbanwe}}",
        "youhavenewmessagesmulti": "Inwere eziohu na $1",
        "editsection": "mèzi",
        "editold": "mèzi",
        "nospecialpagetext": "<strong>Í chọrọ ihü mkpà nke à díghị ézíbóté.</strong>\n\nNdetu màkà ihü mkpà nke à díghị ézíbóté nọ nà [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Nsogbú",
        "databaseerror": "Nsogbu nọr na njikota ómárí",
+       "databaseerror-query": "Ajụjụ:$1",
+       "databaseerror-function": "Ọrụ:$1",
+       "databaseerror-error": "Mmejọ:$1",
        "laggedslavemode": "'''Gé ntị:''' Ihüá nwèríkí bu na o nwéghị ihe gáránirú na ógè nso.",
        "readonly": "Njikota ómárí gbachịrị",
        "missing-article": "Njidé uche nsónùsòrò ènwéghịki tuó mkpụrụ edemede nke ihü nke áhù o kwèshírí hü, nke ha gùrù \"$1\" $2.\n\nIhe méré na mgbe ndiá bu ihe diff dáfùrù na ógè ndụ ya ma jikodo ákíkó mbu nke ótù ihü à gbákáshíálá.\n\nÓ bú nà ọ búghị ihe mèrè, ȯ nwèríkí bu Í gbákọtàrà àkà na áká nsónùsòrò.\nBiko chi ihe á na áká [[Special:ListUsers/sysop|onye íshí]], dètú URL.",
index 9f441c7..e506555 100644 (file)
        "revertpage": "Insubli ti panagurnos babaen ni [[Special:Contributions/$2|$2]] ([[User talk:$2|tungtungan]]), naisubli iti naudi a rebision babaen ni [[User:$1|$1]]",
        "revertpage-nouser": "Naisubli dagiti inurnos babaen ti nailemmeng nga agar-aramat iti kinaudi a rebision babaen ni {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Naibabawi dagiti panagurnos babaen ni {{GENDER:$3|$1}};\nnaisubli manen ti naudi a rebision babaen ni {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Naibabawi dagiti panagurnos babaen ni $1;\nisubli ti naudi a rebision babaen ni $2. [$3 Ipakita dagiti binaliwan]",
        "sessionfailure-title": "Napaay ti sesion",
        "sessionfailure": "Adda parikut ti sesion ti panagserrekmo;\ndaytoy nga aramid ket naibabawi a kas pagpawilan ti panaghijack ti sesion.\nPangngaasi nga ited manen ti porma.",
        "changecontentmodel": "Baliwan ti modelo ti linaon ti panid",
        "authmanager-create-no-primary": "Dagiti naited a kredensial ket saan a mabalin a mausar para iti panagpartuat ti pakabilangan.",
        "authmanager-link-no-primary": "Dagiti naited a kredensial ket saan a mabalin a mausar para iti panangisilpo ti pakabilangan.",
        "authmanager-link-not-in-progress": "Saan nga agprogprogreso ti panangisilpo ti pakabilangan wenno napukaw ti datos ti sesion. Pangngaasi a mangrugi manen iti pagrugian.",
-       "authmanager-authplugin-setpass-failed-title": "Napaay ti panagbaliw ti kontrasenias",
-       "authmanager-authplugin-setpass-failed-message": "Ti plugin ti pammasingked ket di nangipalubos ti panagbaliw ti kontrasenias.",
-       "authmanager-authplugin-create-fail": "Ti plugin ti pammasingked ket di nangipalubos ti panagpartuat ti pakabilangan.",
-       "authmanager-authplugin-setpass-denied": "Ti plugin ti pammasingked ket saan a mangipalubos iti panagbaliw kadagiti kontrasenias.",
-       "authmanager-authplugin-setpass-bad-domain": "Imbalido a dominio.",
        "authmanager-autocreate-noperm": "Saan a maipalubos ti automatiko a panagpartuat ti pakabilangan.",
        "authmanager-autocreate-exception": "Temporario a nabaldado ti automatiko a panagpartuat iti pakabilangan gapu kadagiti dati a biddut.",
        "authmanager-userdoesnotexist": "Ti pakabilangan ti agar-aramat ni \"$1\" ket saan a nakarehistro.",
index 96fd566..301ba80 100644 (file)
@@ -78,9 +78,9 @@
        "sat": "шоатта",
        "january": "АгIой ''(январь)''",
        "february": "Саь-кур ''(февраль)''",
-       "march": "Мутт-хьал ''(март)''",
-       "april": "Тушол ''(апрель)''",
-       "may_long": "Села ''(май)''",
+       "march": "Мутт-хьал",
+       "april": "Тушол",
+       "may_long": "села",
        "june": "Этинга ''(июнь)''",
        "july": "Баьцамеа",
        "august": "Мяцхали",
@@ -90,9 +90,9 @@
        "december": "Чан-тар",
        "january-gen": "АгIой ''(январь)'' бетта",
        "february-gen": "Саь-кур ''(февраль)'' бетта",
-       "march-gen": "Мутт-хьал ''(март)'' бетта",
-       "april-gen": "Тушол ''(апрель)'' бетта",
-       "may-gen": "Села ''(май)'' бетта",
+       "march-gen": "Мутт-хьал",
+       "april-gen": "Тушол",
+       "may-gen": "Села",
        "june-gen": "Этинга ''(июнь)'' бетта",
        "july-gen": "Баьцамеа",
        "august-gen": "Мяцхали",
        "december-gen": "Чан-тар",
        "jan": "АгIой ''(янв)''",
        "feb": "Саь-кур ''(фев)''",
-       "mar": "Ð\9cÑ\83Ñ\82Ñ\82\85Ñ\8cал ''(маÑ\80)''",
+       "mar": "мÑ\83Ñ\82Ñ\82\85Ñ\8cал",
        "apr": "Tушоли",
-       "may": "Села ''(май)''",
+       "may": "села",
        "jun": "Этинга ''(июн)''",
        "jul": "Баьцамеа",
        "aug": "Мяцхали",
        "dec": "Чан-тар",
        "january-date": "АгIой ''(Январь)'' $1",
        "february-date": "Саь-кур ''(февраль)'' $1",
-       "march-date": "Мутт-хьал ''(март)'' $1",
-       "april-date": "Тушол ''(апрель)'' $1",
-       "may-date": "Села ''(май)'' $1",
+       "march-date": "Мутт-хьал $1",
+       "april-date": "Тушол $1",
+       "may-date": "Села $1",
        "june-date": "Этинга ''(июнь)'' $1",
        "july-date": "Баьцамеа $1",
        "august-date": "Мяцхали $1",
        "minoredit": "ЗӀамига хувцам",
        "watchthis": "Зем бе укх оагӀонна",
        "savearticle": "ОагӀув дIаязъе",
+       "savechanges": "ДIаязъе оагӀув",
+       "publishchanges": "ДIаязъе оагӀув",
+       "publishchanges-start": "ДIаязъе оагӀув…",
        "preview": "Хьалххе бIаргтохар",
        "showpreview": "Хьалххе бIаргтохар",
        "showdiff": "Даь дола хувцамаш",
        "namespacesall": "деррига",
        "monthsall": "деррига",
        "confirm-purge-title": "Укх оагIон кэш ӀоцIенъе",
-       "confirm_purge_button": "Мега",
+       "confirm_purge_button": "Мег",
        "confirm-purge-top": "Укх оагӀон кэш ӀоцIенъйой?",
        "confirm-purge-bottom": "Кэш ӀоцӀенъячул тӀехьагIа оагIон тӀехьара эрш хьахьокхаргья.",
        "imgmultipagenext": "тӀехьайоагӀа оагӀув →",
index 99d48b8..623c04a 100644 (file)
        "anontalk": "Diskuto relatant ad ica IP",
        "navigation": "Navigado",
        "and": "&#32;ed",
-       "faq": "Maxim komuna questioni",
+       "faq": "Dubi maxim frequa (FAQ)",
        "actions": "Agi",
        "namespaces": "Nomari",
        "variants": "Varianti",
        "help": "Helpo",
        "help-mediawiki": "Helpo pri MediaWiki",
        "search": "Sercho",
-       "search-ignored-headings": " #<!-- mantenez ica lineo sen modifiki --> <pre>\n# Tituli qui ignoresos per la sistemo di serchado.\n# Modifiki en ca parto efikeskos balde pos la titulo di la pagino adicionesos a l'indexo.\n# Tu povas acelerar la riindexigo di la pagino facante nihila editado.\n# La sintaxo esas quale infre:\n#   * Omna texti qui finas kun la signo \"#\" fine de la lineo, esas komentaro.\n#   * Omna lineo ne blanka - to esas: skriptata -, esas l'exakta titulo por ignorar la diferi inter mayuskula e minuskula literi, ed altra.\nReferi\nExtera ligili\nVidez anke\n #</pre> <!-- mantenez ica lineo sen modifiki -->",
+       "search-ignored-headings": " #<!-- mantenez ica lineo sen modifiki --> <pre>\n# Tituli qui ignoresos dal sistemo di serchado.\n# Modifiki en ca parto efikeskos balde pos la titulo di la pagino adicionesos a l'indexo.\n# Tu povas acelerar la riindexigo di la pagino facante nihila editado.\n# La sintaxo esas quale infre:\n#   * Omna texti qui finas kun la signo \"#\" fine de la lineo, esas komentaro.\n#   * Omna lineo ne blanka - to esas: skriptata -, esas l'exakta titulo por ignorar la diferi inter mayuskula e minuskula literi, ed altra.\nReferi\nExtera ligili\nVidez anke\n #</pre> <!-- mantenez ica lineo sen modifiki -->",
        "searchbutton": "Serchez",
        "go": "Irar",
        "searcharticle": "Irez",
        "undelete_short": "Restaurar {{PLURAL:$1|1 redakto|$1 redakti}}",
        "viewdeleted_short": "Vidar {{PLURAL:$1|1 redakto efacita|$1 redakti efacita}}",
        "protect": "Protektar",
-       "protect_change": "chanjar",
+       "protect_change": "modifikar",
        "unprotect": "Desprotektar",
        "newpage": "Nova pagino",
        "talkpagelinktext": "Diskutez",
        "defaultmessagetext": "Ordinara mesajo-texto",
        "invalid-content-data": "Nevalida kontenajo",
        "content-model-wikitext": "texto Wiki",
+       "content-model-text": "simpla texto",
        "content-model-javascript": "JavaScript",
        "content-json-empty-object": "vakua objekto",
        "content-json-empty-array": "vakua tabelo",
        "deprecated-self-close-category": "Pagini qui uzas nevalida etiketi HTML por klozajo",
        "duplicate-args-category": "Pagini kun argumenti duopligita che shabloni",
+       "language-converter-depth-warning": "La limito di profundeso dil linguo-konvertilo superiresis ($1)",
+       "node-count-exceeded-warning": "La pagino superiras la maxima nombro di nodi permisebla",
        "parser-unstrip-loop-warning": "Renkontresis nefinita procedo ('loop') en la funciono \"Unstrip\"",
        "undo-success": "La redakto ne povas desfacesar.\nVerifikez adinfre per komparo inter la du versioni se to esas fakte quon vu deziras facar; pose 'salvez' la modifiki por kompletigar la redakto.",
        "undo-failure": "Ne povis nuligar la redakto pro konflikti kun intermeza redakti.",
        "undo-summary-username-hidden": "Desfacar revizo $1 facita da celita uzero",
        "cantcreateaccount-text": "La kreo di konto de ica adreso IP (<strong>$1</strong>) blokusesis da [[User:$3|$3]].\n\nLa motivo, segun $3, esas <em>$2</em>",
+       "cantcreateaccount-range-text": "La kreo di konti de IP-adresi de <strong>$1</strong>, qua inkluzas vua IP-adreso (<strong>$4</strong>), blokusesis dal uzero [[User:$3|$3]].\n\nLa motivo quon $3 informis por la blokuso esis <em>$2</em>",
        "viewpagelogs": "Videz registrari por ca pagino",
        "nohistory": "Ne esas redakto-historio por ica pagino.",
        "currentrev": "Nuna versiono",
        "rev-showdeleted": "montrar",
        "revisiondelete": "Efacar/Restaurar revizi",
        "revdelete-show-file-submit": "Yes",
+       "revdelete-text-text": "Versioni efacata duros aparar en la pagino-historio, tamen parto ek lia kontenaji ne restos publike videbla.",
        "revdelete-hide-image": "Celar kontenajo dil arkivo",
        "revdelete-hide-comment": "Rezumo di redakto",
        "revdelete-hide-user": "uzeronomo di redaktanto/IP-adreso",
        "right-suppressrevision": "Vidar, celar e deskovrar specifika revizi di pagini de irga uzero",
        "right-blockemail": "Blokusar uzero pri sendar e-posto",
        "right-unblockself": "Desblokusar su",
+       "right-protect": "Modifikar la protekto-nivelo e la pagini protektata en serio",
        "right-viewmywatchlist": "Vidar vua propra atenco-listo",
        "right-editmyoptions": "Modifikar vua propra preferaji",
        "right-rollback": "Rapide retrorular la redakti da la lasta uzero qua redaktis specigita pagino",
        "uploaddisabled": "Pardonez, la adkargo esas desaktiva.",
        "uploaddisabledtext": "Ne permisesas sendar arkivi.",
        "upload-maxfilesize": "Maxima grandeso dil arkivo: $1",
+       "upload-description": "Deskripto dil arkivo",
        "watchthisupload": "Surveyar ica arkivo",
        "filewasdeleted": "Altr arkivo kun ca sama nomo sendesis antee, e pose efacesis.\nAnte probar risendar ol, vu mustas ante verifikar $1.",
        "upload-file-error": "Interna eroro",
        "revertpage": "Desfacita redakti da [[Special:Contributions/$2|$2]] ([[User talk:$2|Debato]]) e rekuperita la lasta redakto da [[User:$1|$1]]",
        "rollback-success": "Desfacis redakti da $1;\nrestauris ad lasta versiono da $2.",
        "sessionfailure": "Semblas ke eventis problemo kun vua sesiono di 'login';\nta agado abrogesis, quale presorgo kontre sequestro di sesiono ('hijacking').\nVoluntez risendar la formulario, plenigita.",
+       "changecontentmodel": "Chanjar la konteno-modelo di (u)la pagino",
+       "changecontentmodel-title-label": "Titulo di la pagino",
+       "changecontentmodel-submit": "Modifikar",
+       "log-name-contentmodel": "Registro di la modifikuri en la modelo pri kontenajo",
        "logentry-contentmodel-change-revertlink": "restaurar",
        "logentry-contentmodel-change-revert": "restaurar",
        "protectlogpage": "Protekto-registraro",
        "ipblocklist-submit": "Serchar",
        "ipblocklist-otherblocks": "Altra {{PLURAL:$1|blokuso|blokusi}}",
        "infiniteblock": "nefinita",
+       "expiringblock": "finas ye $2 kloki, en $1",
        "emailblock": "e-posto blokusita",
        "blocklist-nousertalk": "ne povas redaktar lua propra diskuto-pagino",
        "blocklink": "blokusar",
        "blocklog-showlog": "Ica uzero ja blokusesis antee.\nInfre esas l'informo pri la blokuso, por vua konoco:",
        "blocklogentry": "blokusis [[$1]] dum periodo di $2 $3",
        "reblock-logentry": "modifikis la tempo di blokuso [[$1]] por durado di $2 $3",
+       "blocklogtext": "Ca esas protokolo pri agadi di blokuso o desblokuso.\nL'adresi IP automatale blokusata ne montresas che la listo.\nVidez la [[Special:BlockList|listo pri blokuso]] por la nuna listo pri blokusi e proskriptadi.",
        "unblocklogentry": "desblokusis \"$1\"",
+       "block-log-flags-anononly": "nur anonima uzeri",
        "block-log-flags-nocreate": "ne povas krear konto",
        "block-log-flags-noautoblock": "automatala blokuso nekapabligata",
        "block-log-flags-noemail": "e-posto blokusita",
        "block-log-flags-nousertalk": "ne povas redaktar lua propra diskuto-pagino",
+       "range_block_disabled": "Ne permisesas al administrero blokusar grupi di IP.",
        "ipb_expiry_invalid": "Nevalida expiro-tempo.",
        "ipb-needreblock": "$1 ja esas blokusata. Ka vu deziras modifikar la selekti?",
        "ipb-otherblocks-header": "Altra {{PLURAL:$1|blokuso|blokusi}}",
        "delete_and_move_reason": "Efacita por permisar la chanjo di la nomo di la pagino \"[[$1]]\"",
        "move-leave-redirect": "Mantenez ridirektilo inter la du",
        "export": "Exportacar pagini",
+       "exporttext": "Vu povas exportacar la texto e historio pri redakto de ula pagino o grupo di pagini envelopata en ula XML.\nCa povas importacar por altra wiki tra l'uzo di MediaWiki, per la [[Special:Import|pagino di importaco]].\n\nPor exportar pagini, mencionez la titulo en la texto-buxo adinfre, un titulo per singla lineo, e selektez se vu deziras vidar la nuna ed anke l'antea redakturi (singla antea revizo en singla lineo), o nur vidar la nuna revizo e l'informi pri ol.\n\nIn the latter case you can also use a link, for example [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] for the page \"[[{{MediaWiki:Mainpage}}]]\".",
        "exportcuronly": "On inkluzas nur la nuna revizo, ne la kompleta versionaro",
        "export-addcattext": "Adjuntar pagini ek kategorio:",
        "export-addcat": "Adjuntar",
        "allmessagescurrent": "Nuna texti di mesajo",
        "allmessagestext": "Yen listo pri omna sistemo-mesaji disponebla en la MediaWiki nomaro.\nVizitez [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Lokizado] e [https://translatewiki.net translatewiki.net] se vu volos kontributar ad generala MediaWiki lokizado.",
        "allmessages-language": "Linguo:",
-       "thumbnail-more": "Grandigar",
+       "thumbnail-more": "Plugrandigar",
        "thumbnail_error": "Ne sucesas krear imajeto: $1",
        "import": "Importacar pagini",
        "import-comment": "Komento:",
        "tooltip-n-recentchanges": "Listo di recenta chanji en la wiki.",
        "tooltip-n-randompage": "Vizitez hazarda pagino",
        "tooltip-n-help": "La loko por trovar ulo.",
-       "tooltip-t-whatlinkshere": "Listo di omna Wikipagini qui ligesas adhike",
+       "tooltip-t-whatlinkshere": "Listo pri omna Wikipagini qui ligesas adhike",
        "tooltip-t-recentchangeslinked": "Recenta chanji di pagini ligita de ca pagino",
        "tooltip-feed-rss": "RSS provizero por ica pagino",
        "tooltip-feed-atom": "Atom provizero por ica pagino",
        "version-parser-function-hooks": "Funcioni \"hooks\" dil sintaxal analizilo (parser)",
        "version-version": "($1)",
        "version-license": "MediaWiki Licenco",
+       "version-ext-colheader-description": "Deskripto",
        "version-software-product": "Produkturo",
        "version-software-version": "Versiono",
+       "version-libraries-description": "Deskripto",
        "redirect": "Redirekti segun arkivo, uzanto, pagino, revizo-numero, o protokolo (log ID)",
        "redirect-summary": "Ica pagino specala ridirektas a: arkivo (se indikesas lua nomo); pagino (se indikesas l'identifiko di la revizo o di la pagino), ad uzanto-pagino (se indikesas la nomo dil uzanto), o protokolo-eniro ('log entry', se indikesas l'identifikilo dil 'log'). Exempli pli l'uzo: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], o [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Irez",
        "tags-create-submit": "Krear",
        "tags-create-no-name": "Mu mustas specifikar nomo por l'etiketo.",
        "tags-create-warnings-above": "La sequanta {{PLURAL:$2|avizo|avizi}} renkontresis, probante kreir l'etiketo \"$1\":",
+       "tags-delete-explanation-active": "<strong>L'etiketo \"$1\" duras esar aktiva, e duros uzesor future.</strong> Por preventar to, irez a la loko/loki ube ol povos aplikesar, e impedez to ibe.",
        "tags-delete-reason": "Motivo:",
        "tags-delete-not-found": "L'etiketo \"$1\" ne existas.",
-       "tags-delete-too-many-uses": "L'etiketo \"$1\" uzesas en plua kam $2 {{PLURAL:$2|revizo|revizi}}, do ol ne povas eskartesar.",
-       "tags-delete-warnings-after-delete": "L'etiketo \"$1\" efacesis, ma la sequanta {{PLURAL:$2|avizo|avizi}} renkontresis:",
+       "tags-delete-too-many-uses": "L'etiketo \"$1\" uzesas en plu kam $2 {{PLURAL:$2|revizo|revizi}}, do ol ne povas eskartesar.",
+       "tags-delete-warnings-after-delete": "L'etiketo \"$1\" efacesis, ma la sequanta {{PLURAL:$2|avizo|avizi}} trovesis:",
        "tags-activate-reason": "Motivo:",
        "tags-activate-not-found": "L'etiketo \"$1\" ne existas.",
        "tags-deactivate-reason": "Motivo:",
        "expand_templates_output": "Rezulto",
        "expand_templates_ok": "O.K.",
        "expand_templates_preview": "Previdar",
+       "pagelanguage": "Modifikar la linguo di la pagino",
        "pagelang-language": "Linguo",
+       "right-pagelang": "Modifikar l'idiomo di la pagino",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 bicoko*|$1 bicoki*}} ($2; $3%)",
        "special-characters-group-latin": "Latina",
        "special-characters-group-latinextended": "Latina extensita",
        "log-action-filter-delete": "Tipo di efacado:",
        "log-action-filter-all": "Omno",
        "log-action-filter-contentmodel-change": "Modifiko di la kontenajo di ula modelo",
-       "log-action-filter-suppress-reblock": "User suppression by reblock"
+       "log-action-filter-suppress-reblock": "User suppression by reblock",
+       "authprovider-resetpass-skip-label": "Preterpasar"
 }
index c812ef3..1c6b41b 100644 (file)
        "botpasswords-label-cancel": "Hætta við",
        "botpasswords-label-delete": "Eyða",
        "botpasswords-label-resetpassword": "Endurstilla lykilorðið",
+       "botpasswords-label-grants": "Tiltækar heimildir:",
        "botpasswords-bad-appid": "Vélmennanafnið „$1“ er ógilt.",
        "botpasswords-created-title": "Vélmennalykilorð var búið til",
        "botpasswords-updated-title": "Vélmennalykilorð var uppfært",
        "prefs-help-prefershttps": "Þessi stilling tekur gildi í næsta skiptið sem þú skráir þig inn.",
        "prefswarning-warning": "Þú hefur gert breytingar á kjörstillingum þínum sem ekki er búið að vista.\nEf þú ferð af þessari síðu án þess að smella á \"$1\" verða kjörstillingar þínar ekki uppfærðar.",
        "prefs-tabs-navigation-hint": "Ábending: Þú getur notað vinstri og hægri örvalyklana til að flakka á milli flipa í flipalistanum.",
-       "userrights": "Notandaréttindi",
+       "userrights": "Réttindi notenda",
        "userrights-lookup-user": "Velja notanda",
        "userrights-user-editname": "Skráðu notandanafn:",
        "editusergroup": "Hlaða inn notanda hópum",
        "speciallogtitlelabel": "Beinist að (titill eða {{ns:user}}:notandanafn fyrir notanda):",
        "log": "Aðgerðaskrár",
        "logeventslist-submit": "Birta",
+       "logeventslist-patrol-log": "Yfirferðarskrá",
+       "logeventslist-tag-log": "Aðgerðaskrá yfir merki",
        "all-logs-page": "Allar aðgerðir",
        "alllogstext": "Safn allra aðgerðaskráa {{SITENAME}}.\nÞú getur takmarkað listann með því að velja tegund aðgerðaskráar, notandanafn, eða síðu.",
        "logempty": "Engin slík aðgerð fannst.",
        "listgrouprights-namespaceprotection-header": "Takmarkanir nafnrýmis",
        "listgrouprights-namespaceprotection-namespace": "Nafnrými",
        "listgrouprights-namespaceprotection-restrictedto": "Réttindi sem leyfa notanda að breyta",
+       "listgrants": "Veittar heimildir",
        "listgrants-rights": "Réttindi",
        "listgrants-grant-display": "$1 <code>($2)</code>",
        "trackingcategories-name": "Heiti skilaboða",
        "revertpage": "Tók aftur breytingar [[Special:Contributions/$2|$2]] ([[User talk:$2|spjall]]), breytt til síðustu útgáfu [[User:$1|$1]]",
        "revertpage-nouser": "Tók aftur breytingar falins notanda til síðustu útgáfu {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Tók til baka breytingar eftir {{GENDER:$3|$1}};\nsetti yfir á síðustu útgáfu eftir {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Tók aftur breytingar $1;\nbreytti í síðustu útgafu $2. [$3 Sýna breytingar]",
        "sessionfailure-title": "Mistök í setu",
        "sessionfailure": "Líklega er vandamál með innskráningarsetuna þína;\nhætt hefur verið við þessa aðgerð sem vörn gegn mögulegu samskiptaráni setunar.\nReyndu að senda upplýsingarnar aftur inn.",
        "changecontentmodel": "Breyta efnislíkani síðu",
        "specialpages-group-highuse": "Mest notuðu síðurnar",
        "specialpages-group-pages": "Listar yfir síður",
        "specialpages-group-pagetools": "Síðuverkfæri",
-       "specialpages-group-wiki": "Gögn og tól",
+       "specialpages-group-wiki": "Gögn og verkfæri",
        "specialpages-group-redirects": "Tilvísaðar kerfissíður",
        "specialpages-group-spam": "Amasendingasíur",
        "specialpages-group-developer": "Forritaratól",
        "randomrootpage": "Handahófsvalin rótarsíða",
        "log-action-filter-all": "Allt",
        "log-action-filter-delete-delete": "Eyðing síðu",
-       "authmanager-authplugin-setpass-bad-domain": "Ógilt lén.",
        "authmanager-email-label": "Tölvupóstur",
        "authmanager-email-help": "Tölvupóstfang",
        "authmanager-realname-label": "Raunverulegt nafn",
index d614642..01dcb64 100644 (file)
        "tog-norollbackdiff": "Non mostrare il confronto tra versioni dopo aver effettuato un rollback",
        "tog-useeditwarning": "Avvisa quando si esce da una pagina di modifica con modifiche non salvate",
        "tog-prefershttps": "Usa sempre una connessione sicura quando si effettua l'accesso",
+       "tog-showrollbackconfirmation": "Mostra una richiesta di conferma quando si clicca su un link di rollback",
        "underline-always": "Sempre",
        "underline-never": "Mai",
        "underline-default": "Impostazioni predefinite del browser o del tema",
        "returnto": "Torna a $1.",
        "tagline": "Da {{SITENAME}}.",
        "help": "Aiuto",
+       "help-mediawiki": "Aiuto su MediaWiki",
        "search": "Ricerca",
        "search-ignored-headings": " #<!-- lascia questa riga esattamente come è --> <pre>\n# Elenco delle intestazioni che saranno ignorate dalla ricerca.\n# Le modifiche a questa pagina saranno effettive non appena la pagina sarà indicizzata.\n# Puoi forzare la re-indicizzazione di una pagina effettuando una modifica nulla.\n# La sintassi è la seguente:\n#   * Tutto dal carattere \"#\" alla fine della riga è un commento\n#   * Tutte le righe non vuote sono le intestazioni esatte da ignorare, maiuscolo/minuscolo e tutto\nNote\nVoci correlate\nCollegamenti esterni\n #</pre> <!-- lascia questa riga esattamente come è -->",
        "searchbutton": "Ricerca",
        "badarticleerror": "Operazione non consentita per questa pagina.",
        "cannotdelete": "Non è stato possibile cancellare la pagina o il file \"$1\".\nPotrebbe essere stato già cancellato da qualcun altro.",
        "cannotdelete-title": "Impossibile cancellare la pagina \"$1\"",
+       "delete-scheduled": "La pagina \"$1\" è stata programmata per la cancellazione.\nAbbi pazienza.",
        "delete-hook-aborted": "La cancellazione è stata annullata dall'hook.\nNon è stata restituita alcuna spiegazione.",
        "no-null-revision": "Non è stato possibile creare una versione nulla per la pagina \"$1\"",
        "badtitle": "Titolo non corretto",
        "ns-specialprotected": "Le pagine speciali non possono essere modificate.",
        "titleprotected": "La creazione di una pagina con questo titolo è stata bloccata da [[User:$1|$1]].\nLa motivazione è la seguente: <em>$2</em>.",
        "filereadonlyerror": "Non è stato possibile modificare il file \"$1\" poiché il repository di file \"$2\" è in modalità di sola lettura.\n\nL'amministratore di sistema che lo ha bloccato ha fornito questa motivazione: \"$3\".",
+       "invalidtitle": "Titolo non valido",
        "invalidtitle-knownnamespace": "Titolo non valido con namespace \"$2\" e testo \"$3\"",
        "invalidtitle-unknownnamespace": "Titolo non valido con namespace sconosciuto \"$1\" e testo \"$2\"",
        "exception-nologin": "Accesso non effettuato",
        "badretype": "Le password inserite non coincidono tra loro.",
        "usernameinprogress": "La creazione di account con questo nome utente è già in corso.\nSi prega di attendere.",
        "userexists": "Il nome utente inserito è già utilizzato.\nScegli un nome utente diverso.",
+       "createacct-normalization": "Il tuo nome utente sarà corretto in \"$2\" a causa di restrizioni tecniche.",
        "loginerror": "Errore durante l'accesso",
        "createacct-error": "Errore durante la creazione dell'utenza",
        "createaccounterror": "Impossibile creare l'account: $1",
        "invalidemailaddress": "L'indirizzo e-mail indicato ha un formato non valido. Inserire un indirizzo valido o svuotare la casella.",
        "cannotchangeemail": "Gli indirizzi e-mail non possono essere modificati in questo wiki.",
        "emaildisabled": "Questo sito non può inviare messaggi di posta elettronica.",
-       "accountcreated": "Accesso creato",
+       "accountcreated": "Utenza creata",
        "accountcreatedtext": "È stata creata un'utenza per [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|msg]]).",
        "createaccount-title": "Creazione di un accesso a {{SITENAME}}",
        "createaccount-text": "Qualcuno ha creato un accesso a {{SITENAME}} ($4) a nome di $2, associato a questo indirizzo di posta elettronica. La password per l'utente \"$2\" è impostata a \"$3\".\nÈ opportuno eseguire un accesso quanto prima e cambiare la password immediatamente.\n\nSe l'accesso è stato creato per errore, si può ignorare questo messaggio.",
        "botpasswords-restriction-failed": "Le restrizioni di password bot impediscono questo accesso.",
        "botpasswords-invalid-name": "Il nome utente indicato non contiene il separatore per password bot (\"$1\").",
        "botpasswords-not-exist": "L'utente \"$1\" non dispone di una password bot chiamata \"$2\".",
+       "botpasswords-needs-reset": "La password per il bot di nome \"$2\" {{GENDER:$1|dell'utente}} \"$1\" deve essere reimpostata.",
+       "botpasswords-locked": "Non puoi accedere con una password bot poiché la tua utenza è bloccata.",
        "resetpass_forbidden": "Non è possibile modificare le password",
        "resetpass_forbidden-reason": "Non è possibile modificare le password: $1",
        "resetpass-no-info": "Devi aver effettuato l'accesso per accedere a questa pagina direttamente.",
        "userpage-userdoesnotexist-view": "L'utenza \"$1\" non è registrata.",
        "blocked-notice-logextract": "Questo utente è attualmente bloccato.\nL'ultimo elemento del registro dei blocchi è riportato di seguito per informazione:",
        "clearyourcache": "<strong>Nota:</strong> dopo aver salvato, potrebbe essere necessario pulire la cache del proprio browser per vedere i cambiamenti. \n*<strong>Firefox / Safari:</strong> tenere premuto il tasto delle maiuscole <em>Shift</em> e fare clic su <em>Ricarica</em>, oppure premere <em>Ctrl-F5</em> o <em>Ctrl-R</em> (<em>⌘-R</em> su Mac)\n*<strong>Google Chrome:</strong> premere <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> su un Mac)\n*<strong>Internet Explorer:</strong> tenere premuto il tasto <em>Ctrl</em> e fare clic su <em>Aggiorna</em>, oppure premere <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Vai nel <em>Menu → Impostazioni</em> (<em>Opera → Preferenze</em> su un Mac) e poi in <em>Privacy & sicurezza → Pulisci dati del browser → Immagini e file nella cache</em>.",
-       "usercssyoucanpreview": "'''Suggerimento:''' usa il pulsante 'Visualizza anteprima' per provare il tuo nuovo CSS prima di salvarlo.",
-       "userjsyoucanpreview": "'''Suggerimento:''' usa il pulsante 'Visualizza anteprima' per provare il tuo nuovo JavaScript prima di salvarlo.",
+       "usercssyoucanpreview": "<strong>Suggerimento:<strong> usa il pulsante \"{{int:showpreview}}\" per provare il tuo nuovo CSS prima di salvarlo.",
+       "userjsonyoucanpreview": "<strong>Suggerimento:<strong> usa il pulsante \"{{int:showpreview}}\" per provare il tuo nuovo JSON prima di salvarlo.",
+       "userjsyoucanpreview": "<strong>Suggerimento:<strong> usa il pulsante \"{{int:showpreview}}\" per provare il tuo nuovo JavaScript prima di salvarlo.",
        "usercsspreview": "'''Questa è solo un'anteprima del proprio CSS personale. Le modifiche non sono ancora state salvate!'''",
        "userjsonpreview": "<strong>Questa è solo un'anteprima per provare il proprio JSON personale; le modifiche non sono ancora state salvate!</strong>",
        "userjspreview": "'''Questa è solo un'anteprima per provare il proprio JavaScript personale; le modifiche non sono ancora state salvate!'''",
        "page_first": "prima",
        "page_last": "ultima",
        "histlegend": "Confronto tra versioni: selezionare le caselle corrispondenti alle versioni desiderate e premere Invio o il pulsante in basso.\n\nLegenda: '''({{int:cur}})''' = differenze con la versione attuale, '''({{int:last}})''' = differenze con la versione precedente, '''{{int:minoreditletter}}''' = modifica minore",
-       "history-fieldset-title": "Ricerca per versioni",
+       "history-fieldset-title": "Filtra versioni",
        "history-show-deleted": "Solo versioni cancellate",
        "histfirst": "prima",
        "histlast": "ultima",
        "historysize": "({{PLURAL:$1|1 byte|$1 byte}})",
-       "historyempty": "(vuota)",
+       "historyempty": "vuota",
        "history-feed-title": "Cronologia",
        "history-feed-description": "Cronologia della pagina su questo sito",
        "history-feed-item-nocomment": "$1 il $2",
        "right-reupload-own": "Sovrascrive un file esistente caricato dallo stesso utente",
        "right-reupload-shared": "Sovrascrive localmente file presenti nell'archivio condiviso",
        "right-upload_by_url": "Carica un file da un indirizzo URL",
-       "right-purge": "Pulisce la cache del sito senza conferma",
+       "right-purge": "Pulisce la cache del sito per una pagina",
        "right-autoconfirmed": "Non soggetto al limite di azioni per IP",
        "right-bot": "Da trattare come processo automatico",
        "right-nominornewtalk": "Fa sì che le modifiche minori alle pagine di discussione non facciano comparire l'avviso di nuovo messaggio",
        "right-editusercss": "Modifica i file CSS di altri utenti",
        "right-edituserjson": "Modifica i file JSON di altri utenti",
        "right-edituserjs": "Modifica i file JS di altri utenti",
+       "right-editsitecss": "Modifica CSS del sito",
+       "right-editsitejson": "Modifica JSON del sito",
+       "right-editsitejs": "Modifica JavaScript del sito",
        "right-editmyusercss": "Modifica il file CSS del proprio utente",
        "right-editmyuserjson": "Modifica il file JSON del proprio utente",
        "right-editmyuserjs": "Modifica il file JavaScript del proprio utente",
        "rcfilters-activefilters-hide": "Nascondi",
        "rcfilters-activefilters-show": "Mostra",
        "rcfilters-activefilters-hide-tooltip": "Nascondi area dei filtri attivi",
+       "rcfilters-activefilters-show-tooltip": "Mostra area dei filtri attivi",
        "rcfilters-advancedfilters": "Filtri avanzati",
        "rcfilters-limit-title": "Risultati da mostrare",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|modifica|modifiche}}, $2",
        "delete-confirm": "Cancella \"$1\"",
        "delete-legend": "Cancella",
        "historywarning": "'''Attenzione:''' La pagina che stai per cancellare ha una cronologia con $1 {{PLURAL:$1|versione|versioni}}:",
-       "historyaction-submit": "Mostra",
+       "historyaction-submit": "Mostra versioni",
        "confirmdeletetext": "Stai per cancellare una pagina con tutta la sua cronologia. Per cortesia, conferma che è tua intenzione procedere a tale cancellazione, che hai piena consapevolezza delle conseguenze della tua azione e che essa è conforme alle linee guida stabilite in [[{{MediaWiki:Policy-url}}]].",
        "actioncomplete": "Azione completata",
        "actionfailed": "Azione fallita",
        "deleting-backlinks-warning": "<strong>Attenzione:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|altre pagine]] contengono collegamenti o inclusioni alla pagina che stai per cancellare.",
        "deleting-subpages-warning": "<strong>Attenzione:</strong> la pagina che stai per cancellare ha [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|una sotto-pagina|$1 sotto-pagine|51=più di 50 sotto-pagine}}]].",
        "rollback": "Annulla le modifiche",
+       "rollback-confirmation-confirm": "Per favore conferma:",
+       "rollback-confirmation-yes": "Rollback",
+       "rollback-confirmation-no": "Annulla",
        "rollbacklink": "rollback",
        "rollbacklinkcount": "rollback di {{PLURAL:$1|una modifica|$1 modifiche}}",
        "rollbacklinkcount-morethan": "rollback di più di {{PLURAL:$1|una modifica|$1 modifiche}}",
        "revertpage": "Annullate le modifiche di [[Special:Contributions/$2|$2]] ([[User talk:$2|discussione]]), riportata alla versione precedente di [[User:$1|$1]]",
        "revertpage-nouser": "Annullate le modifiche di un utente nascosto, riportata alla versione precedente di {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Annullate le modifiche di {{GENDER:$3|$1}}; pagina riportata all'ultima versione di {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Annullate le modifiche di $1;\npagina riportata all'ultima revisione di $2. [$3 Mostra le modifiche]",
        "sessionfailure-title": "Sessione fallita",
        "sessionfailure": "Si è verificato un problema nella sessione che identifica l'accesso; il sistema non ha eseguito il comando impartito per precauzione. Invia nuovamente il modulo.",
        "changecontentmodel": "Modifica il modello di contenuto di una pagina",
        "mycontris": "contributi",
        "anoncontribs": "contributi",
        "contribsub2": "Per {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Per {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "L'utenza \"$1\" non è registrata.",
        "negative-namespace-not-supported": "I namespace con valori negativi non sono supportati.",
        "nocontribs": "Non sono state trovate modifiche che soddisfino i criteri di ricerca.",
        "ipb-confirm": "Conferma il blocco",
        "ipb-sitewide": "Completo",
        "ipb-partial": "Parziale",
+       "ipb-sitewide-help": "Ogni pagina sul wiki e tutte le altre azioni di contribuzione.",
+       "ipb-partial-help": "Specifiche pagine o namespace.",
        "ipb-pages-label": "Pagine",
        "ipb-namespaces-label": "Namespace",
        "badipaddress": "Indirizzo IP non valido.",
        "move-watch": "Aggiungi la pagina agli osservati speciali",
        "movepagebtn": "Sposta la pagina",
        "pagemovedsub": "Spostamento effettuato con successo",
+       "cannotmove": "La pagina non può essere spostata {{PLURAL:$1|per la seguente ragione|per le seguenti ragioni}}:",
        "movepage-moved": "'''\"$1\" è stata spostata a \"$2\"'''",
        "movepage-moved-redirect": "È stato creato un redirect.",
        "movepage-moved-noredirect": "La creazione di un redirect è stata soppressa.",
        "confirm-unwatch-button": "OK",
        "confirm-unwatch-top": "Rimuovere questa pagina dalla tua lista degli osservati speciali?",
        "confirm-rollback-button": "OK",
-       "confirm-rollback-top": "Ripristinare le modifiche di questa pagina?",
+       "confirm-rollback-top": "Annullare le modifiche a questa pagina?",
+       "confirm-rollback-bottom": "Questa azione annullerà istantaneamente le modifiche selezionate a questa pagina.",
        "confirm-mcrrestore-title": "Ripristina una versione",
        "confirm-mcrundo-title": "Annulla una modifica",
        "mcrundofailed": "Annullamento fallito",
        "logentry-rights-autopromote": "$1 è {{GENDER:$2|stato promosso|stata promossa|stato/a promosso/a}} automaticamente da $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|ha caricato}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha caricato}} una nuova versione di $3.",
-       "logentry-upload-revert": "$1 {{GENDER:$2|ha caricato}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|ha ripristinato}} $3 ad una vecchia versione",
        "log-name-managetags": "Gestione etichette",
        "log-description-managetags": "Questa pagina elenca le azioni di gestione relative alle [[Special:Tags|etichette]]. Il registro contiene solo le azioni effettuate manualmente da un amministratore; le etichette potrebbero essere create o cancellate dal programma wiki senza che ciò venga registrato qui.",
        "logentry-managetags-create": "$1 {{GENERE:$2|ha creato}} il tag \"$4\"",
        "log-action-filter-suppress-reblock": "Soppressione utente da ri-blocco",
        "log-action-filter-upload-upload": "Nuovo caricamento",
        "log-action-filter-upload-overwrite": "Ricaricamento",
+       "log-action-filter-upload-revert": "Ripristina",
        "authmanager-authn-not-in-progress": "L'autenticazione non è in corso o i dati della sessione sono andati persi. Si prega di ricominciare dall'inizio.",
        "authmanager-authn-no-primary": "Le credenziali fornite non possono essere autenticate.",
        "authmanager-authn-no-local-user": "Le credenziali fornite non sono associate a nessun utente di questo wiki.",
        "authmanager-create-no-primary": "Le credenziali fornite non possono essere utilizzate per la creazione dell'utenza.",
        "authmanager-link-no-primary": "Le credenziali fornite non possono essere utilizzate per il collegamento dell'utenza.",
        "authmanager-link-not-in-progress": "Il collegamento dell'utenza non è in corso o i dati della sessione sono andati persi. Si prega di ricominciare dall'inizio.",
-       "authmanager-authplugin-setpass-failed-title": "Modifica della password fallita",
-       "authmanager-authplugin-setpass-failed-message": "Il plugin di autenticazione ha impedito la modifica della password.",
-       "authmanager-authplugin-create-fail": "Il plugin di autenticazione ha impedito la creazione dell'utenza.",
-       "authmanager-authplugin-setpass-denied": "Il plugin di autenticazione non consente di cambiare le password.",
-       "authmanager-authplugin-setpass-bad-domain": "Dominio non valido.",
        "authmanager-autocreate-noperm": "La creazione automatica dell'utenza non è permessa.",
        "authmanager-autocreate-exception": "La creazione automatica di utenze è temporaneamente disabilitata a causa di errori precedenti.",
        "authmanager-userdoesnotexist": "L'utenza \"$1\" non è registrata.",
index 83d1e70..6f86888 100644 (file)
@@ -94,7 +94,8 @@
                        "Oxbqskeptzwizkgdcxakhnrb",
                        "Suyama",
                        "고솜",
-                       "Wat"
+                       "Wat",
+                       "Puntti ja"
                ]
        },
        "tog-underline": "リンクの下線:",
        "botpasswords-existing": "既存のボット用パスワード",
        "botpasswords-createnew": "ボット用パスワードの新規作成",
        "botpasswords-editexisting": "既存のボットのパスワードを編集",
-       "botpasswords-label-needsreset": "(パスワードをリセットする必要があります)",
+       "botpasswords-label-needsreset": "(パスワードのリセットが必要です)",
        "botpasswords-label-appid": "ボット名:",
        "botpasswords-label-create": "作成",
        "botpasswords-label-update": "更新",
        "botpasswords-invalid-name": "指定された利用者名には、ボット用パスワードの区切りである「$1」 が含まれていません。",
        "botpasswords-not-exist": "利用者「$1」はボット「$2」のパスワードを所持していません。",
        "botpasswords-needs-reset": "{{GENDER:$1|利用者}}「$1」のボット名「$2」のためのパスワードはリセットする必要があります。",
-       "botpasswords-locked": "アカウントがロックされているため、bot用パスワードではログインできません。",
+       "botpasswords-locked": "アカウントがロックされているため、ボット用パスワードでログインできません。",
        "resetpass_forbidden": "パスワードは変更できません",
        "resetpass_forbidden-reason": "パスワードは変更できません: $1",
        "resetpass-no-info": "このページに直接アクセスするためにはログインしている必要があります。",
        "changeemail-no-info": "このページに直接アクセスするためにはログインしている必要があります。",
        "changeemail-oldemail": "現在のメールアドレス:",
        "changeemail-newemail": "新しいメールアドレス:",
-       "changeemail-newemail-help": "あなたのメールアドレスを削除したい場合は、このフィールドを空白のままにする必要があります。あなたは忘れてしまったパスワードをリセットすることができず、また、電子メールアドレスが削除された場合は、このウィキからのメールを受信しません。",
+       "changeemail-newemail-help": "あなたのメールアドレスを削除したい場合は、このフィールドを空白のままにする必要があります。あなたは忘れてしまったパスワードをリセットすることができず、また、メールアドレスが削除された場合は、このウィキからのメールを受信しません。",
        "changeemail-none": "(なし)",
        "changeemail-password": "{{SITENAME}}のパスワード:",
        "changeemail-submit": "メールアドレスを変更",
        "histfirst": "最古",
        "histlast": "最新",
        "historysize": "({{PLURAL:$1|$1バイト}})",
-       "historyempty": "(空)",
+       "historyempty": "",
        "history-feed-title": "版の履歴",
        "history-feed-description": "このウィキのこのページに関する変更履歴",
        "history-feed-item-nocomment": "$2に$1による",
        "right-reupload-own": "自身がアップロードした既存のファイルに上書き",
        "right-reupload-shared": "共有メディアリポジトリ上のファイルにローカルで上書き",
        "right-upload_by_url": "URL からファイルをアップロード",
-       "right-purge": "確認なしでサイト上のページ・キャッシュを破棄",
+       "right-purge": "サイト上のページ キャッシュを破棄",
        "right-autoconfirmed": "IPベースの速度制限を受けない",
        "right-bot": "自動処理と認識させる",
        "right-nominornewtalk": "議論ページの細部の編集をした際に、新着メッセージとして通知しない",
        "right-override-export-depth": "リンク先ページを5階層まで含めて書き出す",
        "right-sendemail": "他の利用者にメールを送信",
        "right-managechangetags": "[[Special:Tags|タグ]]の作成、有効化および無効化",
-       "right-applychangetags": "自分の編集に[[Special:Tags|タグ]]を適用する",
+       "right-applychangetags": "自身の編集に[[Special:Tags|タグ]]を適用",
        "right-changetags": "個々の版と記録項目の任意の[[Special:Tags|タグ]]の追加と削除",
        "right-deletechangetags": "データベースから[[Special:Tags|タグ]]を削除",
        "grant-generic": "「$1」の権限バンドル",
        "grant-uploadfile": "新しいファイルをアップロード",
        "grant-basic": "基礎的な権限",
        "grant-viewdeleted": "削除されたファイルとページを閲覧",
-       "grant-viewmywatchlist": "自身のウォッチリストを閲覧",
+       "grant-viewmywatchlist": "あなたのウォッチリストを閲覧",
        "grant-viewrestrictedlogs": "制限されたログを表示する",
        "newuserlogpage": "アカウント作成記録",
        "newuserlogpagetext": "以下はアカウント作成の記録です。",
        "action-createpage": "このページの作成",
        "action-createtalk": "この議論ページの作成",
        "action-createaccount": "この利用者アカウントの作成",
-       "action-autocreateaccount": "ã\81\93ã\81®å¤\96é\83¨å\88©ç\94¨è\80\85ã\82¢ã\82«ã\82¦ã\83³ã\83\88ã\82\92è\87ªå\8b\95ç\9a\84ã\81«作成",
+       "action-autocreateaccount": "ã\81\93ã\81®å¤\96é\83¨å\88©ç\94¨è\80\85ã\82¢ã\82«ã\82¦ã\83³ã\83\88ã\81®è\87ªå\8b\95作成",
        "action-history": "このページの履歴の閲覧",
        "action-minoredit": "細部の編集の印を付ける",
        "action-move": "このページの移動",
        "action-userrights-interwiki": "他のウィキの利用者の利用者権限変更",
        "action-siteadmin": "データベースのロックまたはロック解除",
        "action-sendemail": "メールの送信",
-       "action-editmyoptions": "あなたの個人設定を編集",
-       "action-editmywatchlist": "自のウォッチリストの編集",
-       "action-viewmywatchlist": "自のウォッチリストの閲覧",
+       "action-editmyoptions": "自分の個人設定の編集",
+       "action-editmywatchlist": "自のウォッチリストの編集",
+       "action-viewmywatchlist": "自のウォッチリストの閲覧",
        "action-viewmyprivateinfo": "自分の非公開情報の閲覧",
        "action-editmyprivateinfo": "自分の非公開情報の編集",
-       "action-editcontentmodel": "ã\83\9aã\83¼ã\82¸ã\81®ã\82³ã\83³ã\83\86ã\83³ã\83\84ã\83¢ã\83\87ã\83«ã\82\92編集",
+       "action-editcontentmodel": "ã\83\9aã\83¼ã\82¸ã\81®ã\82³ã\83³ã\83\86ã\83³ã\83\84ã\83¢ã\83\87ã\83«ã\81®編集",
        "action-managechangetags": "タグの作成、有効化および無効化",
-       "action-applychangetags": "è\87ªå\88\86ã\81®ç·¨é\9b\86ã\81«ã\82¿ã\82°ã\82\92é\81©ç\94¨ã\81\99ã\82\8b",
+       "action-applychangetags": "è\87ªå\88\86ã\81®ç·¨é\9b\86ã\81¸ã\81®ã\82¿ã\82°ã\81®é\81©ç\94¨",
        "action-changetags": "個々の版および記録項目への任意のタグの追加と除去",
        "action-deletechangetags": "データベースからタグの削除",
        "action-purge": "このページのキャッシュ破棄",
        "rcfilters-show-new-changes": "最新の変更を表示",
        "rcfilters-search-placeholder": "絞り込みを行う(メニューから選択、またはフィルター名で検索)",
        "rcfilters-invalid-filter": "無効なフィルター",
-       "rcfilters-empty-filter": "絞り込みは行われていません。全ての項目が表示さます。",
+       "rcfilters-empty-filter": "çµ\9eã\82\8aè¾¼ã\81¿ã\81¯è¡\8cã\82\8fã\82\8cã\81¦ã\81\84ã\81¾ã\81\9bã\82\93ã\80\82å\85¨ã\81¦ã\81®é \85ç\9b®ã\81\8c表示ã\81\95ã\82\8cã\81¾ã\81\99ã\80\82",
        "rcfilters-filterlist-title": "フィルター",
        "rcfilters-filterlist-whatsthis": "これらはどのように機能しますか?",
        "rcfilters-filterlist-feedbacklink": "絞り込み機能に関するフィードバック",
        "rcfilters-view-tags-help-icon-tooltip": "タグ付けされた編集とは",
        "rcfilters-liveupdates-button": "自動読み込み",
        "rcfilters-liveupdates-button-title-on": "自動読み込みを停止",
-       "rcfilters-liveupdates-button-title-off": "æ\96°ã\81\97ã\81\84ç·¨é\9b\86ã\82\92å\8d³åº§ã\81«èª­ã\81¿è¡¨ç¤ºã\81\99ã\82\8b",
+       "rcfilters-liveupdates-button-title-off": "新しい編集を即座に表示する",
        "rcfilters-watchlist-markseen-button": "すべての変更を訪問済みにする",
        "rcfilters-watchlist-edit-watchlist-button": "ウォッチリストを編集",
        "rcfilters-watchlist-showupdated": "最終訪問以降に変更されたページは、塗りつぶされた丸印と一緒に、<strong>太字</strong>で表示されます。",
        "upload-form-label-infoform-description-tooltip": "この作品に対して特筆すべきことをすべて説明します。\n写真であれば、主に何が写っているのか、いつ、どこで撮ったものなのかについて述べてください。",
        "upload-form-label-usage-title": "使用法",
        "upload-form-label-usage-filename": "ファイル名",
-       "upload-form-label-own-work": "ã\81\93ã\82\8cã\81¯ã\81\82ã\81ªã\81\9fè\87ªèº«ã\81«ã\82\88ã\82\8bä½\9c業です",
+       "upload-form-label-own-work": "ã\81\93ã\82\8cã\81¯ã\82\8fã\81\9fã\81\97è\87ªèº«ã\81«ã\82\88ã\82\8bä½\9cå\93\81です",
        "upload-form-label-infoform-categories": "カテゴリ",
        "upload-form-label-infoform-date": "日付",
        "upload-form-label-own-work-message-generic-local": "私は {{SITENAME}} 上での以下の利用規約とライセンス方針で、このファイルをアップロードしていることを確認します。",
        "move": "移動",
        "movethispage": "このページを移動",
        "unusedimagestext": "以下のファイルは、存在しますがどのページにも埋め込まれていません。\nただし、他のウェブサイトがURLでファイルに直接リンクする場合があることに注意してください。以下のファイル一覧には、そのような形で利用中のファイルが含まれている場合があります。",
+       "unusedimagestext-categorizedimgisused": "以下のファイルは存在していますがどのページにも含まれていません。カテゴライズされた画像ファイルは他のどのページにも含まれていないにもかかわらず、使用されているものと扱われています。\nまた、他のウェブサイトがファイルのURLを直接リンクすることで使用しているため、実際には使用されている画像がリストアップされていると言う可能性もあることを考慮してください。",
        "unusedcategoriestext": "以下のカテゴリはページが存在しますが、他のどのページおよびカテゴリでも使用されていません。",
        "notargettitle": "対象が存在しません",
        "notargettext": "この機能の実行対象となるページまたは利用者が指定されていません。",
        "delete-confirm": "「$1」の削除",
        "delete-legend": "削除",
        "historywarning": "<strong>警告:</strong> 削除しようとしているページには、$1版の履歴があります:",
-       "historyaction-submit": "表示",
+       "historyaction-submit": "更新の表示",
        "confirmdeletetext": "ページをすべての履歴とともに削除しようとしています。\n本当にこの操作を行いたいか、操作の結果を理解しているか、およびこの操作が[[{{MediaWiki:Policy-url}}|方針]]に従っているかどうか、確認してください。",
        "actioncomplete": "操作を完了しました",
        "actionfailed": "操作に失敗しました",
        "delete-warning-toobig": "このページには、 $1版を超える編集履歴があります。\n削除すると、{{SITENAME}}のデータベース処理に大きな負荷がかかります。\n十分に注意してください。",
        "deleteprotected": "このページは保護されているため削除できません。",
        "deleting-backlinks-warning": "<strong>警告:</strong> 削除しようとしているページは、[[Special:WhatLinksHere/{{FULLPAGENAME}}|他のページ]]からリンクまたは参照読み込みされています。",
-       "deleting-subpages-warning": "<strong>警告:</strong>削除しようとしているページは、[[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|サブページ|$1 個のサブページ|51=50 個以上のサブページ}}]]があります。",
+       "deleting-subpages-warning": "<strong>警告:</strong> 削除しようとしているページには、[[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|下位ページ|$1 件の下位ページ|51=50 件以上の下位ページ}}]]があります。",
        "rollback": "編集を巻き戻し",
+       "rollback-confirmation-yes": "巻き戻し",
+       "rollback-confirmation-no": "キャンセル",
        "rollbacklink": "巻き戻し",
        "rollbacklinkcount": "$1{{PLURAL:$1|編集}}を巻き戻し",
        "rollbacklinkcount-morethan": "$1{{PLURAL:$1|編集}}以上を巻き戻し",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|トーク]]) による編集を [[User:$1|$1]] による直前の版へ差し戻しました",
        "revertpage-nouser": "非表示の利用者による編集を {{GENDER:$1|[[User:$1|$1]]}} による直前の版へ差し戻しました",
        "rollback-success": "{{GENDER:$3|$1}}による編集を差し戻しました。\n{{GENDER:$4|$2}}による直前の版へ変更されました。",
-       "rollback-success-notify": "$1による編集を差し戻しました。\n$2による直前の版へ変更されました。[$3 変更を表示]",
        "sessionfailure-title": "セッションの失敗",
        "sessionfailure": "ログインのセッションに問題が発生しました。\nセッション乗っ取りを防ぐため、操作を取り消しました。\nフォームを再送信してください。",
        "changecontentmodel": "ページのコンテンツ・モデルの変更",
        "anoncontribs": "投稿記録",
        "contribsub2": "利用者: {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "利用者アカウント「$1」は登録されていません。",
+       "negative-namespace-not-supported": "負の値で指定される名前空間はサポートされていません。",
        "nocontribs": "これらの条件に一致する変更は見つかりませんでした。",
        "uctop": "最新",
        "month": "この月以前:",
        "ipb-confirm": "ブロックの確認",
        "ipb-sitewide": "サイト全体",
        "ipb-partial": "部分的",
+       "ipb-partial-help": "特定のページまたは名前空間。",
        "ipb-pages-label": "ページ",
        "ipb-namespaces-label": "名前空間",
        "badipaddress": "無効なIPアドレス",
        "blocklist-nousertalk": "自分のトークページも編集禁止",
        "blocklist-editing": "編集",
        "blocklist-editing-sitewide": "編集(サイト全体)",
+       "blocklist-editing-page": "ページ",
        "blocklist-editing-ns": "名前空間",
        "ipblocklist-empty": "ブロック一覧は空です。",
        "ipblocklist-no-results": "指定されたIPアドレスまたは利用者名はブロックされていません。",
        "ipb_expiry_old": "有効期限が過去の時刻です。",
        "ipb_expiry_temp": "利用者名秘匿のブロックは、無期限ブロックになります。",
        "ipb_hide_invalid": "このアカウントを秘匿できません。編集回数が{{PLURAL:$1|$1回}}を超えています。",
+       "ipb_hide_partial": "ユーザー名を秘匿してのブロックは完全なブロックである必要があります。",
        "ipb_already_blocked": "「$1」は既にブロックされています。",
        "ipb-needreblock": "$1 は既にブロックされています。設定を変更しますか?",
        "ipb-otherblocks-header": "その他の{{PLURAL:$1|ブロック}}",
        "cant-move-category-page": "カテゴリのページを移動させる権限がありません。",
        "cant-move-to-category-page": "ページをカテゴリのページに移動させる権限がありません。",
        "cant-move-subpages": "下位のページを移動する権限がありません。",
-       "namespace-nosubpages": "名前空間「$1」はサブページが許可されていません。",
+       "namespace-nosubpages": "名前空間「$1」は下位ページが許可されていません。",
        "newtitle": "新しいページ名:",
        "move-watch": "移動元と移動先ページをウォッチ",
        "movepagebtn": "ページを移動",
        "movepage-moved": "<strong>「$1」は「$2」へ移動されました</strong>",
        "movepage-moved-redirect": "転送ページを作成しました。",
        "movepage-moved-noredirect": "転送ページは作成されませんでした。",
+       "movepage-delete-first": "送り先のページには多くの版があり、移動操作の行程の1つとしての削除はできません。まず、ページを手動で削除してから操作を行ってください。",
        "articleexists": "指定された移動先には既にページが存在するか、名前が不適切です。\n別の名前を選択してください。",
        "cantmove-titleprotected": "新しいページ名が作成保護されているため、この場所にページを移動できません",
        "movetalk": "付随するトークページも移動",
        "specialpages-group-developer": "開発者用ツール",
        "blankpage": "白紙ページ",
        "intentionallyblankpage": "このページは意図的に白紙にされています。",
+       "disabledspecialpage-disabled": "このページはシステム管理者により無効化されています。",
        "external_image_whitelist": "  #この行はこのままにしておいてください<pre>\n#この下に正規表現 (//の間に入る記述) を置いてください\n#外部の (ホットリンクされている) 画像の URL と一致するか検査されます\n#一致する場合は画像として、一致しない場合は画像へのリンクとして表示されます\n#行の頭に # を付けるとコメントとして扱われます\n#大文字と小文字は区別されません\n\n#正規表現はすべてこの行の上に置いてください。この行はこのままにしておいてください</pre>",
        "tags": "有効な変更タグ",
        "tag-filter": "[[Special:Tags|タグ]]絞り込み:",
        "logentry-rights-autopromote": "$1 が $4 から $5 に自動的に{{GENDER:$2|昇格しました}}",
        "logentry-upload-upload": "$1 が $3 を {{GENDER:$2|アップロードしました}}",
        "logentry-upload-overwrite": "$1 が $3 の新しいバージョンを {{GENDER:$2|アップロードしました}}",
-       "logentry-upload-revert": "$1 が $3 を {{GENDER:$2|アップロードしました}}",
+       "logentry-upload-revert": "$1 が $3 を元の版に {{GENDER:$2|巻き戻しました}}",
        "log-name-managetags": "タグ管理記録",
        "log-description-managetags": "このページは[[Special:Tags|タグ]]に関係する管理タスクをリストアップしています。ログには管理者によって手動で実行された操作の記録しか記載されていません。ウィキ・ソフトウェアによって、ログを残さずにタグが作成・削除されている場合があります。",
        "logentry-managetags-create": "$1 がタグ「$4」を{{GENDER:$2|作成しました}}",
        "log-action-filter-suppress-reblock": "再ブロックによる利用者の秘匿",
        "log-action-filter-upload-upload": "新規アップロード",
        "log-action-filter-upload-overwrite": "再アップロード",
+       "log-action-filter-upload-revert": "差し戻し",
        "authmanager-authn-not-in-progress": "認証が行われていない、またはセッションデータが失われました。最初からやり直してください。",
        "authmanager-authn-no-primary": "指定された証明情報を認証できませんでした。",
        "authmanager-authn-no-local-user": "指定された証明情報は、このウィキのどの利用者にも関連付けられていません。",
        "authmanager-create-no-primary": "指定された証明情報は、アカウントの作成に使用できませんでした。",
        "authmanager-link-no-primary": "指定された証明情報は、アカウントの関連付けに使用できませんでした。",
        "authmanager-link-not-in-progress": "アカウントの関連付けが処理されていないか、セッションデータが失われています。最初からやり直してください。",
-       "authmanager-authplugin-setpass-failed-title": "パスワードの変更に失敗しました",
-       "authmanager-authplugin-setpass-failed-message": "パスワードの変更は、認証プラグインによって拒否されました。",
-       "authmanager-authplugin-create-fail": "アカウントの作成は、認証プラグインによって拒否されました。",
-       "authmanager-authplugin-setpass-denied": "パスワードの変更は、認証プラグインによって許可されていません。",
-       "authmanager-authplugin-setpass-bad-domain": "無効なドメインです。",
        "authmanager-autocreate-noperm": "アカウントの自動作成は許可されていません。",
        "authmanager-autocreate-exception": "自動アカウント作成は、以前のエラーにより一時的に無効になっています。",
        "authmanager-userdoesnotexist": "利用者アカウント「$1」は登録されていません。",
        "unlinkaccounts": "アカウントの関連付け解除",
        "unlinkaccounts-success": "アカウントの関連付けが解除されました。",
        "authenticationdatachange-ignored": "認証データの変更は処理されませんでした。プロバイダーが設定されていない可能性があります。",
-       "userjsispublic": "注意: JavaScript のサブページは第三者が閲覧可能なため、機微な情報を含めないでください。",
-       "userjsonispublic": "注意: JSON のサブページは第三者が閲覧可能なため、機微な情報を含めないでください。",
-       "usercssispublic": "注意: CSS のサブページは第三者が閲覧可能なため、機微な情報を含めないでください。",
+       "userjsispublic": "注意: JavaScript の下位ページは第三者が閲覧可能なため、機微な情報を含めないでください。",
+       "userjsonispublic": "注意: JSON の下位ページは第三者が閲覧可能なため、機微な情報を含めないでください。",
+       "usercssispublic": "注意: CSS の下位ページは第三者が閲覧可能なため、機微な情報を含めないでください。",
        "restrictionsfield-badip": "無効な IP アドレス、またはその範囲: $1",
        "restrictionsfield-label": "許可する IP の範囲:",
        "restrictionsfield-help": "一行につき、単一の IP アドレス、もしくは CIDR による範囲。全帯域からの接続を許可する場合: <pre>0.0.0.0/0\n::/0</pre>",
        "undelete-cantedit": "このページを編集する許可がないため復元できません。",
        "undelete-cantcreate": "同名のページが存在せず、このページを作成する許可がないため復元できません。",
        "pagedata-title": "ページ・データ",
-       "pagedata-text": "このページは、ページへのデータインターフェースを提供します。サブページの構文を使用して、URLにページタイトルを入力してください。\n* コンテンツのネゴシエーションは、クライアントのAcceptヘッダーに基づいて適用されます。つまり、ページデータはクライアントが優先する形式で提供されます。",
+       "pagedata-text": "このページは、ページへのデータインターフェースを提供します。下位ページの構文を使用して、URLにページ名を入力してください。\n* コンテンツのネゴシエーションは、クライアントのAcceptヘッダーに基づいて適用されます。つまり、ページデータはクライアントが優先する形式で提供されます。",
        "pagedata-not-acceptable": "該当する形式が見つかりません。対応している MIME タイプ: $1",
        "pagedata-bad-title": "「$1」は無効なページ名です。",
-       "unregistered-user-config": "セキュリティ上の理由から、JavaScript、CSSおよびJSONの利用者サブページは、登録されていない利用者に対しては読み込みできません。",
+       "unregistered-user-config": "セキュリティ上の理由から、JavaScript、CSSおよびJSONの利用者下位ページは、登録されていない利用者に対しては読み込みできません。",
        "passwordpolicies": "パスワードポリシー",
        "passwordpolicies-summary": "これは、このウィキで定義されている利用者グループの有効なパスワードポリシーの一覧です。",
        "passwordpolicies-group": "グループ",
        "passwordpolicies-policy-maximalpasswordlength": "パスワードは$1{{PLURAL:$1|文字}}以下でなければなりません",
        "passwordpolicies-policy-passwordcannotbepopular": "パスワードは{{PLURAL:$1|一般的なものにすることはできません|一般的な$1個のパスワードのリストと一致するものにすることはできません}}",
        "easydeflate-invaliddeflate": "提供されたコンテンツが適切に圧縮されていません",
-       "unprotected-js": "ã\82»ã\82­ã\83¥ã\83ªã\83\86ã\82£ä¸\8aã\81®ç\90\86ç\94±ã\81\8bã\82\89ã\80\81JavaScriptã\81¯ä¿\9dè­·ã\81\95ã\82\8cã\81¦ã\81\84ã\81ªã\81\84ã\83\9aã\83¼ã\82¸ã\81\8bã\82\89ã\83­ã\83¼ã\83\89ã\81\99ã\82\8bã\81\93ã\81¨ã\81¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82MediaWiki: å\90\8då\89\8d空é\96\93å\86\85ã\80\81ã\81¾ã\81\9fã\81¯å\88©ç\94¨è\80\85ã\82µã\83\96ã\83\9aã\83¼ã\82¸ã\81¨ã\81\97ã\81¦のみjavascriptを作成してください。"
+       "unprotected-js": "ã\82»ã\82­ã\83¥ã\83ªã\83\86ã\82£ä¸\8aã\81®ç\90\86ç\94±ã\81\8bã\82\89ã\80\81JavaScriptã\81¯ä¿\9dè­·ã\81\95ã\82\8cã\81¦ã\81\84ã\81ªã\81\84ã\83\9aã\83¼ã\82¸ã\81\8bã\82\89ã\81¯èª­ã\81¿è¾¼ã\81¿ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82MediaWiki: å\90\8då\89\8d空é\96\93å\86\85ã\80\81å\88©ç\94¨è\80\85ä¸\8bä½\8dã\83\9aã\83¼ã\82¸ã\81®ã\81\84ã\81\9aã\82\8cã\81\8bã\81§のみjavascriptを作成してください。"
 }
index 301708a..b81c415 100644 (file)
        "returnto": "Bali menyang $1.",
        "tagline": "Saka {{SITENAME}}",
        "help": "Pitulung",
+       "help-mediawiki": "Pitulung bab MediaWiki",
        "search": "Golèk",
        "search-ignored-headings": " #<!-- lirwakaké waé larik iki kaya asliné --> <pre>\n# Sesirah kang bakal dilirwakaké déning golèkan.\n# Owahan tumrap iki bakal katon nalika sesirahé wis diindhèks.\n# Panjenengan bisa meksa ngindhèks ulang kaca kanthi ngayahi besutan kosong.\n# Sintaksisé kaya mangkéné:\n#   * Samubarang saka karakter \"#\" tumeka pungkasané larik iku minangka tanggepan.\n#   * Saben larik kang ora kosong iku sesirah kang kudu dilirwakaké lan samubarangé.\nRujukan\nPranala njaba\nUga delengen\n #</pre> <!-- lirwakaké baé larik iki kaya asliné -->",
        "searchbutton": "Golèk",
        "view": "Deleng",
        "view-foreign": "Deleng ing $1",
        "edit": "Besut",
-       "edit-local": "Besut andharan enggon-enggonan",
+       "edit-local": "Besut wedharan enggonan",
        "create": "Gawé",
-       "create-local": "Tambah panyadra enggon-enggonan",
+       "create-local": "Wuwuhi wedharan enggonan",
        "delete": "Busak",
        "undelete_short": "Wurung busak {{PLURAL:$1|sabesutan|$1 besutan}}",
        "viewdeleted_short": "Deleng {{PLURAL:$1|sabesutan kabusak|$1 besutan kabusak}}",
        "botpasswords-label-cancel": "Wurung",
        "botpasswords-label-delete": "Busak",
        "botpasswords-label-resetpassword": "Balèni gawé tembung wadi",
+       "botpasswords-bad-appid": "Jeneng bot \"$1\" ora trep.",
+       "botpasswords-insert-failed": "Wurung nambah jeneng bot \"$1\". Apa wis tinambahaké sadurungé?",
        "resetpass_forbidden": "Tembung wadi ora bisa diganti",
        "resetpass-no-info": "Panjenengan kudu mlebu log saperlu langsung ngaksès kaca iki.",
        "resetpass-submit-loggedin": "Ganti tembung wadi",
        "editpage-invalidcontentmodel-text": "Modhèl kontèn \"$1\" ora sinengkuyung.",
        "editpage-notsupportedcontentformat-title": "Formal kontèn ora sinengkuyung",
        "editpage-notsupportedcontentformat-text": "Format kontèn $1 ora disengkuyung modhèl kontèn $2.",
+       "slot-name-main": "Pokok",
        "content-model-wikitext": "tulisan wiki",
        "content-model-text": "tulisan barès",
        "content-model-javascript": "JavaScript",
        "mycontris": "Pasumbang",
        "anoncontribs": "Pasumbang",
        "contribsub2": "Kanggo {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Marang {{GENDER:$3|$1}}",
        "nocontribs": "Owah-owahan kang cocog karo wewaton mangkono ora tinemu.",
        "uctop": "saiki",
        "month": "Saka wulan (lan sadurungé):",
        "authmanager-authn-autocreate-failed": "Gawéan otomatis akun lokal wurung: $1",
        "authmanager-create-disabled": "Gawéan akun dipatèni.",
        "authmanager-create-from-login": "Saperlu nggawé akun, panjenengan mangga ngisi babagan-babagan ing ngisor iki.",
-       "authmanager-authplugin-setpass-bad-domain": "Dhomain ora trep.",
        "authmanager-autocreate-noperm": "Gawéan akun otomatis ora diidinaké.",
        "authmanager-autocreate-exception": "Gawéan akun otomatis sawetara dipatèni amarga masalah sadurungé.",
        "authmanager-userdoesnotexist": "Akun panganggo \"$1\" ora kadhaftar.",
        "authmanager-provider-password": "Otèntifikasi adhedhasar tembung wadi",
        "authmanager-provider-password-domain": "Otèntifikasi adhedhasar tembung wadi lan dhomain",
        "authmanager-provider-temporarypassword": "Tembung wadi sauntara",
-       "authprovider-resetpass-skip-label": "Langkahi",
+       "authprovider-resetpass-skip-label": "Lumpati",
        "credentialsform-account": "Jeneng akun:",
        "cannotlink-no-provider-title": "Ora ana akun kang bisa digayutaké",
        "cannotlink-no-provider": "Ora ana akun kang bisa digayutaké.",
index e255997..4bae059 100644 (file)
        "rev-delundel": "ჩვენება/დამალვა",
        "rev-showdeleted": "ჩვენება",
        "revisiondelete": "ცვლილებების წაშლა/დაბრუნება",
-       "revdelete-nooldid-title": "á\83¡á\83\90á\83\9bá\83\98á\83\96á\83\9cá\83\9d ვერსია არ არის მითითებული",
-       "revdelete-nooldid-text": "á\83\97á\83¥á\83\95á\83\94á\83\9c á\83\90á\83  á\83\93á\83\90á\83\92á\83\98á\83\9cá\83\98á\83¨á\83\9cá\83\98á\83\90á\83\97 á\83¡á\83\90á\83\9bá\83\98á\83\96á\83\9cá\83\9d ვერსია (ვერსიები) ამ ფუნქციის გასახორციებლად.",
+       "revdelete-nooldid-title": "á\83¡á\83\90á\83\9bá\83\98á\83\96á\83\9cá\83\94 ვერსია არ არის მითითებული",
+       "revdelete-nooldid-text": "á\83\97á\83¥á\83\95á\83\94á\83\9c á\83\90á\83  á\83\93á\83\90á\83\92á\83\98á\83\9cá\83\98á\83¨á\83\9cá\83\98á\83\90á\83\97 á\83¡á\83\90á\83\9bá\83\98á\83\96á\83\9cá\83\94 ვერსია (ვერსიები) ამ ფუნქციის გასახორციებლად.",
        "revdelete-no-file": "მოთხოვნილი ფაილი არ არსებობს.",
        "revdelete-show-file-confirm": "დარწმუნებული ხართ, რომ გსურთ ამ ფაილის წაშლილი ვერსიის ნახვა, „<nowiki>$1</nowiki>“ $2, $3-დან ?",
        "revdelete-show-file-submit": "ჰო",
        "notargettitle": "სამიზნე არაა",
        "notargettext": "თქვენ არ მიუთითეთ სამიზნე გვერდი ან მომხმარებელი\nამ ფუნქციის შესასრულებლად.",
        "nopagetitle": "ამგვარი სამიზნე გვერდი არ არსებობს",
-       "nopagetext": "á\83\9bá\83\9dá\83ªá\83\94á\83\9bá\83£á\83\9aá\83\98 á\83¡á\83\90á\83\9bá\83\98á\83\96á\83\9cá\83\9d გვერდი არ არის მიითებული.",
+       "nopagetext": "á\83\9bá\83\9dá\83ªá\83\94á\83\9bá\83£á\83\9aá\83\98 á\83¡á\83\90á\83\9bá\83\98á\83\96á\83\9cá\83\94 გვერდი არ არის მიითებული.",
        "pager-newer-n": "{{PLURAL:$1|უახლესი 1|უახლესი $1}}",
        "pager-older-n": "{{PLURAL:$1|უფრო ძველი 1|უფრო ძველი $1}}",
        "suppress": "ჩახშობა",
        "revertpage": "[[Special:Contributions/$2|$2]]-ის რედაქტირება გაუქმდა; აღდგა ბოლოს [[User:$1|$1]]-ის მიერ რედაქტირებული ვერსია",
        "revertpage-nouser": "მომხმარებლის (მომხმარებლის სახელი დამალულია) ცვლილებები დაბრუნებულია ვერსიაზე {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "გაუქმდა რედაქტირება {{GENDER:$3|$1}}-ის მიერ;\nდაბრუნდა ვერსიაზე, რომელიც განახორციელა {{GENDER:$4|$2}}-მ.",
-       "rollback-success-notify": "გაუმქდა $1-ის მიერ განხორციელებული რედაქტირებები;\nდაბრუნდე ვერსიაზე, რომელიც განახორციელა $2-მ. [$3 ცვლილებების ნახვა]",
        "sessionfailure-title": "სეანსის შეცდომა",
        "sessionfailure": "ჩანს, რომ პრობლემაა თქვენი რეგისტრაციის სესიისათვის;\nეს მოქმედება შეჩერდა თქვენი სესიაში შემოჭრის თავიდან ასაცილებლად.\nგთხოვთ, დააწკაპუნოთ ღილაკს „უკან“ და თავიდან ჩართოთ გვერდი, რომლიდანაც შემოხვედით და სცადოთ განმეორებით.",
        "changecontentmodel": "გვერდის კონტენტური მოდელის შეცვლა",
        "authmanager-create-no-primary": "მოწოდებული მონაცემები არ გამოდგა ანგარიშის შესაქმნელად.",
        "authmanager-link-no-primary": "მოწოდებული მონაცემები არ გამოდგა ანგარიშის დასაკავშირებლად.",
        "authmanager-link-not-in-progress": "ანგარიშის დაკავშირება არ მიმდინარეობს ან სესიის მონაცემი დაიკარგა. გთხოვთ დაიწყეთ თავიდან.",
-       "authmanager-authplugin-setpass-failed-title": "პაროლის ცვლილება ვერ განხორციელდა",
-       "authmanager-authplugin-setpass-failed-message": "აუთენთიფიკაციის პლაგინმა უარყო პაროლის ცვლილება.",
-       "authmanager-authplugin-create-fail": "აუთენთიფიკაციის პლაგინმა უარყო ანგარიშის შექმნა.",
-       "authmanager-authplugin-setpass-denied": "აუთენთიფიკაციის პლაგინი არ იძლევა პაროლების გამოცვლის უფლებას.",
-       "authmanager-authplugin-setpass-bad-domain": "არასწორი დომეინი.",
        "authmanager-autocreate-noperm": "ავტომატური ანგარიშის შექმნა არ არის ნებადართული.",
        "authmanager-autocreate-exception": "ავტომატური ანგარიშის შექმნა დროებით გათიშულია ადრინდელი ხარვეზების გამო.",
        "authmanager-userdoesnotexist": "მომხმარებლის ანგარიში „$1“ არ არის რეგისტრირებული",
index 9598e0b..759c803 100644 (file)
        "tooltip-recreate": "Na pele esterıte bo ki, nae oncia bıaferne",
        "tooltip-upload": "Dest be bar-kerdene ke",
        "tooltip-rollback": "\"Peyser biya\" ebe jü tık pela iştırakunê peyênu peyser ano.",
-       "tooltip-undo": "\"Peyser\" ni vurnaişi peyser ano u modusê verqayt de vurnaisê formi keno ra.\nTêser-kerdena jü sebebi rê xulasa de imkan dano cı.",
+       "tooltip-undo": "\"Peyser\" ni vurnayişi peyser ano u modusê verqayti de vurnayisê formi keno ra. Têserkerdena jü sebebi rê xulasa de imkan dano cı.",
        "tooltip-summary": "Xulasê da kılme cı kuye",
        "common.css": "/* CSSo ke itaro, serba çermu pêroine gurenino */",
        "pageinfo-contentpage-yes": "Heya",
index 5aa3258..0fc8435 100644 (file)
@@ -74,7 +74,8 @@
                        "Jay94ks",
                        "Ryuch",
                        "Delim",
-                       "Comjun04"
+                       "Comjun04",
+                       "Son77391"
                ]
        },
        "tog-underline": "링크에 밑줄 긋기:",
        "tog-norollbackdiff": "되돌리기 후 차이를 보지 않기",
        "tog-useeditwarning": "바꾼 내용을 저장하지 않고 편집 페이지를 벗어날 때 내게 알리기",
        "tog-prefershttps": "로그인하는 동안 항상 보안 연결 사용",
+       "tog-showrollbackconfirmation": "롤백 링크를 클릭할 때 확인 프롬프트를 표시합니다",
        "underline-always": "항상",
        "underline-never": "항상 긋지 않기",
        "underline-default": "스킨 또는 브라우저 기본값",
        "page_first": "처음",
        "page_last": "마지막",
        "histlegend": "차이 선택: 비교하려는 판의 라디오 상자를 선택한 다음 엔터나 아래의 버튼을 누르세요.<br />\n설명: <strong>({{int:cur}})</strong> = 최신 판과 비교, <strong>({{int:last}})</strong> = 이전 판과 비교, <strong>{{int:minoreditletter}}</strong>= 사소한 편집",
-       "history-fieldset-title": "특정판 검색",
+       "history-fieldset-title": "특정판 필터링",
        "history-show-deleted": "특정판이 삭제된 것만",
        "histfirst": "오래됨",
        "histlast": "최신",
        "historysize": "({{PLURAL:$1|1 바이트|$1 바이트}})",
-       "historyempty": "(비었음)",
+       "historyempty": "비었음",
        "history-feed-title": "편집 역사",
        "history-feed-description": "이 문서의 편집 역사",
        "history-feed-item-nocomment": "$2에 $1님의 편집",
        "right-reupload-own": "자신이 이미 올린 파일 덮어쓰기",
        "right-reupload-shared": "공용의 파일을 무시하고 로컬에서 파일 올리기",
        "right-upload_by_url": "URL 주소에서 파일 올리기",
-       "right-purge": "확인 없이 문서의 캐시를 새로 고침",
+       "right-purge": "문서의 사이트 캐시를 새로 고침",
        "right-autoconfirmed": "IP 기반의 속도 제한에 영향을 받지 않음",
        "right-bot": "봇의 편집으로 취급",
        "right-nominornewtalk": "토론 문서에서 사소한 편집으로 새 메시지 알림을 보내지 않기",
        "delete-confirm": "\"$1\" 삭제",
        "delete-legend": "삭제",
        "historywarning": "<strong>경고:</strong> 삭제하려고 하는 문서에 {{PLURAL:$1|판}} $1개의 역사가 있습니다:",
-       "historyaction-submit": "보이기",
+       "historyaction-submit": "판 보이기",
        "confirmdeletetext": "문서와 문서 역사를 삭제하려고 합니다.\n삭제하려는 문서가 맞는지, 이 문서를 삭제하는 것이 [[{{MediaWiki:Policy-url}}|정책]]에 맞는 행동인지를 확인해 주세요.",
        "actioncomplete": "동작 완료",
        "actionfailed": "명령 실패",
        "deleting-backlinks-warning": "<strong>경고:</strong> 삭제하려는 문서가 [[Special:WhatLinksHere/{{FULLPAGENAME}}|다른 문서]]에 링크되어 있거나 끼워져 있습니다.",
        "deleting-subpages-warning": "<strong>경고:</strong> 삭제하려는 문서에 [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|하나의 하위 문서|$1개의 하위 문서|51=50개 이상의 하위 문서}}]]가 있습니다.",
        "rollback": "편집 되돌리기",
+       "rollback-confirmation-confirm": "확인해 주십시오:",
+       "rollback-confirmation-yes": "되돌리기",
+       "rollback-confirmation-no": "취소",
        "rollbacklink": "되돌리기",
        "rollbacklinkcount": "{{PLURAL:$1|편집}} $1회 되돌리기",
        "rollbacklinkcount-morethan": "{{PLURAL:$1|편집}} $1회 이상 되돌리기",
        "revertpage": "[[Special:Contributions/$2|$2]]([[User talk:$2|토론]])의 편집을 [[User:$1|$1]]의 마지막 판으로 되돌림",
        "revertpage-nouser": "숨긴 사용자의 편집을 {{GENDER:$1|[[User:$1|$1]]}}의 마지막 판으로 되돌림",
        "rollback-success": "{{GENDER:$3|$1}}의 편집을 되돌렸습니다.\n{{GENDER:$4|$2}}의 마지막 판으로 바뀌었습니다.",
-       "rollback-success-notify": "$1의 편집을 되돌렸습니다.\n$2의 마지막 판으로 바뀌었습니다. [$3 차이 보기]",
        "sessionfailure-title": "세션 실패",
        "sessionfailure": "로그인 세션에 문제가 발생한 것 같습니다.\n세션 하이재킹을 막기 위해 동작이 취소되었습니다.\n양식을 다시 제출해 주십시오.",
        "changecontentmodel": "문서의 콘텐츠 모델을 변경",
        "ipb-confirm": "차단 확인",
        "ipb-sitewide": "사이트 전체",
        "ipb-partial": "부분",
+       "ipb-partial-help": "특정 문서 또는 이름공간입니다.",
        "ipb-pages-label": "문서",
        "ipb-namespaces-label": "이름공간",
        "badipaddress": "잘못된 IP 주소",
        "blocklist-nousertalk": "자신의 토론 문서 편집 불가",
        "blocklist-editing": "편집 중",
        "blocklist-editing-sitewide": "편집 중 (사이트 전체)",
+       "blocklist-editing-page": "문서",
        "blocklist-editing-ns": "이름공간",
        "ipblocklist-empty": "차단 목록이 비어 있습니다.",
        "ipblocklist-no-results": "요청한 IP 주소나 사용자는 차단되지 않았습니다.",
        "confirmemail_body_set": "당신일 수도 있는 $1 IP 주소를 사용하는 사용자가\n{{SITENAME}}의 \"$2\" 계정의 이메일 주소를 지정하였습니다.\n\n이 계정이 당신의 계정이고 {{SITENAME}}에서 이메일 기능을\n활성화하려면 아래 주소를 열어서 이메일 인증을 해 주세요:\n\n$3\n\n당신의 계정이 아니라면,\n이메일 인증 신청을 취소하기 위해 아래의 주소를 열어주세요:\n\n$5\n\n인증 코드는 $4에 만료됩니다.",
        "confirmemail_invalidated": "이메일 확인이 취소됨",
        "invalidateemail": "이메일 확인 취소",
-       "notificationemail_subject_changed": "{{SITENAME}}ì\9d\98 등록된 이메일 주소가 변경되었습니다",
-       "notificationemail_subject_removed": "{{SITENAME}}ì\9d\98 등록된 이메일 주소가 제거되었습니다",
+       "notificationemail_subject_changed": "{{SITENAME}}ì\97\90 등록된 이메일 주소가 변경되었습니다",
+       "notificationemail_subject_removed": "{{SITENAME}}ì\97\90 등록된 이메일 주소가 제거되었습니다",
        "notificationemail_body_changed": "당신일 수도 있는 IP 주소 $1에 속하는 사용자가\n{{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 \"$3\"(으)로 바꾸었습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
        "notificationemail_body_removed": "당신일 수도 있는 IP 주소 $1에 속하는 사용자가 {{SITENAME}}의 사용자 \"$2\" 계정의 이메일 주소를 제거하였습니다.\n\n지금 이 글을 보고 계신 사용자로 추정되지만 만약 본인이 아닌 경우, 지금 바로 사이트 관리자에게 문의하십시오.",
        "scarytranscludedisabled": "[인터위키가 비활성되어 있습니다]",
        "logentry-rights-autopromote": "$1님이 권한을 자동으로 $4에서 $5(으)로 {{GENDER:$2|바꾸었습니다}}",
        "logentry-upload-upload": "$1님이 $3 파일을 {{GENDER:$2|올렸습니다}}",
        "logentry-upload-overwrite": "$1님이 $3의 새 판을 {{GENDER:$2|올렸습니다}}",
-       "logentry-upload-revert": "$1님이 $3 파일을 {{GENDER:$2|올렸습니다}}",
+       "logentry-upload-revert": "$1님이 $3 파일을 오래된 판으로 {{GENDER:$2|되돌렸습니다}}",
        "log-name-managetags": "태그 관리 기록",
        "log-description-managetags": "이 문서는 [[Special:Tags|태그]]에 관한 관리 작업의 목록입니다. 이 기록에는 관리자가 직접 실행한 동작만이 기록되며, 위키 소프트웨어에 의해 태그가 생성 및 삭제되는 경우는 기록되지 않습니다.",
        "logentry-managetags-create": "$1님이 \"$4\" 태그를 {{GENDER:$2|만들었습니다}}",
        "log-action-filter-suppress-reblock": "재차단을 통한 사용자 숨기기",
        "log-action-filter-upload-upload": "새로 업로드",
        "log-action-filter-upload-overwrite": "다시 업로드",
+       "log-action-filter-upload-revert": "되돌리기",
        "authmanager-authn-not-in-progress": "인증이 진행 중이 아니거나 세션 데이터를 분실했습니다. 처음부터 다시 시작해 주십시오.",
        "authmanager-authn-no-primary": "제공된 자격 증명으로 인증할 수 없습니다.",
        "authmanager-authn-no-local-user": "자격 증명으로 이 위키의 어느 사용자로도 로그인할 수 없습니다.",
        "authmanager-create-no-primary": "제공된 자격 증명은 계정 생성에 쓰일 수 없습니다.",
        "authmanager-link-no-primary": "제공된 자격 증명은 계정을 연결하는 데 쓰일 수 없습니다.",
        "authmanager-link-not-in-progress": "계정 연결이 진행 중이 아니거나 세션 데이터를 분실했습니다. 처음부터 다시 시작해 주십시오.",
-       "authmanager-authplugin-setpass-failed-title": "비밀번호 변경 실패",
-       "authmanager-authplugin-setpass-failed-message": "인증 플러그인이 비밀번호 변경을 거부했습니다.",
-       "authmanager-authplugin-create-fail": "인증 플러그인이 계정 만들기를 거부했습니다.",
-       "authmanager-authplugin-setpass-denied": "인증 플러그인이 비밀번호 변경을 허용하지 않습니다.",
-       "authmanager-authplugin-setpass-bad-domain": "잘못된 도메인.",
        "authmanager-autocreate-noperm": "자동 계정 만들기는 허용되지 않습니다.",
        "authmanager-autocreate-exception": "이전의 오류들로 인해 자동 계정 만들기를 일시적으로 사용할 수 없습니다.",
        "authmanager-userdoesnotexist": "\"$1\" 사용자 계정은 등록되어 있지 않습니다.",
        "passwordpolicies-policy-maximalpasswordlength": "비밀번호는 적어도 $1 {{PLURAL:$1|자}} 미만이어야 합니다",
        "passwordpolicies-policy-passwordcannotbepopular": "비밀번호는 {{PLURAL:$1|저명한 비밀번호가 될|$1개의 저명한 비밀번호에 속할}} 수 없습니다",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "비밀번호는 가장 흔히 쓰이는 비밀번호 100,000개 목록에 속할 수 없습니다.",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "로그인할 때 변경 제안",
        "easydeflate-invaliddeflate": "주어진 컨텐츠가 적절히 압축되지 않았습니다",
        "unprotected-js": "보안 상의 이유로 자바스크립트는 보호되지 않은 문서로부터 불러올 수 없습니다. 미디어위키: 이름공간이나 사용자의 하위 문서에서만 자바스크립트를 만들어 주십시오."
 }
index c392b49..da4f7ae 100644 (file)
        "revertpage": "Änderunge vun däm Metmaacher „[[Special:Contributions/$2|$2]]“ ([[User talk:$2|däm sing Klaafsigg]]) fottjeschmeße, un doför de lätzde Väsjohn vum „[[User:$1|$1]]“ widder zeröckjehollt",
        "revertpage-nouser": "Änderunge vun enem Metmaacher, däm singe Name vershtoche es, retuur jemaat op de letzte Version {{GENDER:$1|vum|vum|vumm Metmaacher|vun dä|vum}} [[User:$1|$1]]",
        "rollback-success": "De Änderungen vum $1 zeröckjenumme, un dobei de letzte Version vum $2 widder jehollt.",
-       "rollback-success-notify": "Änderonge {{GENDER:$1|vum|vum|vumm Metmaacher|vun dä|vum}} „$1“ sin zerök jenumme un di Sigg es op der Schtand vun doför {{GENDER:$2|vum|vum|vumm Metmaacher|vun dä|vum}} „$2“ jesaz. [$3 Belohr, wat derbeij veränndert wood]",
        "sessionfailure-title": "Fähler met dä Daate vum Enlogge",
        "sessionfailure": "Et jov wall e täschnesch Problehm met Dingem Login. Dröm ham_mer dat us Vörseesch jäz nix jemaht, domet mer nit velleich Ding Änderong däm verkihrte Metmaacher ongerjubele. Jangk zeröck un versöhk et noch ens.",
        "changecontentmodel": "Et Modäll vum Ennhald vun ene Sigg verändere",
        "authmanager-authn-autocreate-failed": "Automattesch ene Zojang för heh et Wikki hät nit jeflup: $1",
        "authmanager-create-disabled": "Neu Aanmelde es afjeschalldt",
        "authmanager-create-from-login": "Öm Der ene Zohjang aanzelähje, bes esu johd, un föll heh di Fällder us:",
-       "authmanager-authplugin-setpass-failed-title": "Dat Paßwoot ze änndere hät nit jeflupp",
-       "authmanager-authplugin-setpass-bad-domain": "Onjöltijje Domäijn",
        "authmanager-autocreate-noperm": "Automattesch Zohjäng aanzelähje es nit zohjelohße.",
        "authmanager-autocreate-exception": "Automattesch Zohjäng aanzelähje es wähje verjange Fähler för en Zigg nit zohjelohße.",
        "authmanager-userdoesnotexist": "Ene Metmaacher mem Nahme „$1“ es nit ennjedrahre.",
index 74d96bb..574636f 100644 (file)
@@ -64,7 +64,9 @@
        "tog-norollbackdiff": "Ciyawaziyê piştî şûndekirinê nîşan nede",
        "underline-always": "Hertim",
        "underline-never": "Qet",
-       "underline-default": "Tercîhên lêgerokê",
+       "underline-default": "Tercîhên lêgerok an jî xuyangê",
+       "editfont-style": "Şêwaza curetîpê ya qada sererastkirinê:",
+       "editfont-monospace": "Curetîpa yek-navberî",
        "editfont-sansserif": "Fonta Sans-serif'ê",
        "editfont-serif": "Fonta Serif'ê",
        "sunday": "yekşem",
        "returnto": "Vegere $1.",
        "tagline": "Ji {{SITENAME}}",
        "help": "Alîkarî",
+       "help-mediawiki": "Alîkariya di derbarê MedyaWîkiyê de",
        "search": "Lêgerîn",
        "searchbutton": "Lêgerîn",
        "go": "Here",
        "log-action-filter-all": "Hemû",
        "log-action-filter-block-block": "Asteng bike",
        "log-action-filter-upload-upload": "Barkirina nû",
+       "log-action-filter-upload-revert": "Şûnde vegerîne",
        "authmanager-email-label": "E-name",
        "authmanager-email-help": "Navnîşana e-nameyê"
 }
index 6cdee09..848847b 100644 (file)
        "page_first": "биринчи",
        "page_last": "ахырынчы",
        "histlegend": "Тюзлевлерден сайлав: тенглешдирмеге сюеген бары тюрлерин белгилеп '''{{int:compare-submit}}''' бас.<br />\nАчыкълавлар: '''({{int:cur}})''' — гьалиги тюрюнден башгъалыкъ; '''({{int:last}})''' — алдагъы тюрюнден башгъалыкъ; '''{{int:minoreditletter}}''' — увакъ тюзелтив.",
-       "history-fieldset-title": "Тюзлевлеге излев",
+       "history-fieldset-title": "Тюзлев сюзгюч",
        "histfirst": "инг эсгилер",
        "histlast": "инг янгылар",
-       "historyempty": "(бош)",
+       "historyempty": "бош",
        "history-feed-title": "Тюзлевлер тарихи",
        "history-feed-description": "Бу сагьифаны викиде тюзлев тарихи",
        "history-feed-item-nocomment": "$1 $2 заманда",
        "watchlist-options": "Тергев тизмени кюйлевлери",
        "enotif_reset": "Бары да сагьифаланы къаралгъандай белгилемек",
        "dellogpage": "Тайдырыв гюнделиги",
+       "rollback-confirmation-no": "Гери алмакъ",
        "rollbacklink": "гери алмакъ",
        "rollbacklinkcount": "$1 {{PLURAL:$1|тюзлевню}} къайтармакъ",
        "protectlogpage": "Якълав гюнделиги",
index a16b610..d4b3e7f 100644 (file)
        "histfirst": "eelst",
        "histlast": "neist",
        "historysize": "({{PLURAL:$1|1 Byte|$1 Byten}})",
-       "historyempty": "(eidel)",
+       "historyempty": "eidel",
        "history-feed-title": "Historique vun de Versiounen",
        "history-feed-description": "Versiounshistorique fir dës Säit op der Wiki",
        "history-feed-item-nocomment": "$1 ëm $2",
        "timezonelegend": "Zäitzon:",
        "localtime": "Lokalzäit:",
        "timezoneuseserverdefault": "De Standardwäert vun der Wiki ($1) benotzen",
-       "timezoneuseoffset": "Aner (Differenz uginn)",
+       "timezoneuseoffset": "Aner (Differenz hei drënner uginn)",
        "servertime": "Serverzäit:",
        "guesstimezone": "Vum Browser iwwerhuelen",
        "timezoneregion-africa": "Afrika",
        "right-reupload-own": "E Fichier iwwerschreiwen deen Dir selwer eropgelueden hutt",
        "right-reupload-shared": "Lokalt Iwwerschreiwe vun engem Fichier deen an engem gemeinsam benotzte Repertoire steet",
        "right-upload_by_url": "Fichiere vun enger URL-Adress eroplueden",
-       "right-purge": "De Säitecache eidel maachen ouni nozefroen",
+       "right-purge": "De Säitecache fir eng Säit eidel maachen",
        "right-autoconfirmed": "Net betraff vun IP-baséierten Zäitlimiten",
        "right-bot": "Als automatesche Prozess behandelen (Bot)",
        "right-nominornewtalk": "Kleng Ännerungen op Diskussiounssäite léisen de Banner vun de neie Messagen net aus",
        "grant-createaccount": "Benotzerkonten opmaachen",
        "grant-createeditmovepage": "Säiten uleeën, änneren a réckelen",
        "grant-delete": "Säiten, Versiounen a Rubriken a Logbicher läschen",
-       "grant-editinterface": "MediaWiki-Nummraum a Benotzer CSS/JSON/JavaScript änneren",
+       "grant-editinterface": "De MediaWiki-Nummraum an de Benotzer CSS/JSON/JavaScript vum ganze wiki-Site änneren",
        "grant-editmycssjs": "Äre Benotzer CSS/JSON/JavaScript änneren",
-       "grant-editmyoptions": "Ännert Är Benotzerastellungen",
+       "grant-editmyoptions": "Ännert Är Benotzerastellungen an d'JSON-Konfiguratioun",
        "grant-editmywatchlist": "Ännert Är Iwwerwaachungslëscht",
        "grant-editpage": "Säiten déi et gëtt änneren",
        "grant-editprotected": "Gespaart Säiten änneren",
        "filehist-comment": "Bemierkung",
        "imagelinks": "Benotze vu Fichieren",
        "linkstoimage": "Dës {{PLURAL:$1|Säit benotzt|Säite benotzen}} dëse Fichier:",
-       "linkstoimage-more": "Méi wéi {{PLURAL:$1|eng Säit ass|$1 Säite si}} mat dësem Fichier verlinkt.\nDës Lëscht weist nëmmen {{PLURAL:$1|den éischte Link|déi éischt $1 Linken}} op dëse Fichier.\nEng [[Special:WhatLinksHere/$2|komplett Lëscht]] ass disponibel.",
+       "linkstoimage-more": "Méi wéi {{PLURAL:$1|eng Säit|$1 Säite}} benotzen dëse Fichier.\nDës Lëscht weist {{PLURAL:$1|déi éischte Säit|déi éischt $1 Säiten}} déi nëmmen dëse Fichier benotzen.\nEng [[Special:WhatLinksHere/$2|komplett Lëscht]] ass disponibel.",
        "nolinkstoimage": "Et gëtt keng Säiten déi dëse Fichier benotzen.",
        "morelinkstoimage": "Weis [[Special:WhatLinksHere/$1|méi Linken]] op dëse Fichier.",
        "linkstoimage-redirect": "$1 (Fichier-Viruleedung) $2",
        "speciallogtitlelabel": "Zil (Titel oder {{ns:user}}:Benotzernumm fir e Benotzer):",
        "log": "Logbicher",
        "logeventslist-submit": "Weisen",
-       "logeventslist-more-filters": "Méi Filteren:",
+       "logeventslist-more-filters": "Méi Logbicher weisen:",
        "all-logs-page": "All ëffentlech Logbicher",
        "alllogstext": "Dëst ass eng kombinéiert Lëscht vu Logbicher op {{SITENAME}}.\nDir kënnt d'Siche limitéiere wann Dir e Log-Typ, e Benotzernumm (case-senisitive) oder déi gefrot Säit (och case-senisitive) agitt.",
        "logempty": "Näischt fonnt.",
        "delete-confirm": "Läsche vu(n) \"$1\"",
        "delete-legend": "Läschen",
        "historywarning": "<strong>Opgepasst:</strong> D'Säit déi Dir läsche wëllt huet en Historique mat $1 {{PLURAL:$1|Versioun|Versiounen}}:",
-       "historyaction-submit": "Weisen",
+       "historyaction-submit": "Versioune weisen",
        "confirmdeletetext": "Dir sidd am Gaang, eng Säit mat hirem kompletten Historique vollstänneg aus der Datebank ze läschen.\nW.e.g. confirméiert, datt Dir dëst wierklech wëllt, datt Dir d'Konsequenze verstitt, an datt dat Ganzt am Aklang mat de [[{{MediaWiki:Policy-url}}|Richtlinne]] geschitt.",
        "actioncomplete": "Aktioun ofgeschloss",
        "actionfailed": "Aktioun huet net funktionéiert",
        "deleting-backlinks-warning": "<strong>Opgepasst:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Aner Säite]] linken op déi Säit déi Dir am Gaang sidd ze läschen oder déi Säit Déi Dir am Gaang sidd ze läschen ass an aner Säiten agebonn.",
        "deleting-subpages-warning": "<strong>Opgepasst:</strong> D'Säit, déi Dir läsche wëllt, huet [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|eng Ënnersäit|$1 Ënnersäiten|51=méi wéi 50 Ënnersäiten}}]].",
        "rollback": "Ännerungen zrécksetzen",
+       "rollback-confirmation-confirm": "W.e.g. Konfirméieren",
+       "rollback-confirmation-yes": "Zrécksetzen",
+       "rollback-confirmation-no": "Ofbriechen",
        "rollbacklink": "Zrécksetzen",
        "rollbacklinkcount": "{{PLURAL:$1|Eng Ännerung|$1 Ännerungen}} zrécksetzen",
        "rollbacklinkcount-morethan": "méi wéi {{PLURAL:$1|Eng Ännerung|$1 Ännerungen}} zrécksetzen",
        "revertpage": "Ännerunge vum [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussioun]]) zréckgesat op déi lescht Versioun vum [[User:$1|$1]]",
        "revertpage-nouser": "Zréckgesaten Ännerungen duerch e verstoppte Benotzer op déi lescht Versioun vum {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "D'Ännerunge vum {{GENDER:$3|$1}} goufen zréckgesat op déi lescht Versioun vum {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Zréckgesat Ännerunge vum $1:\nzréckgeännert op déi lescht Versioun vum $2. [$3 Ännerunge weisen]",
        "sessionfailure-title": "Setzungsfeeler",
        "sessionfailure": "Et schéngt e Problem mat Ärer Sessioun ze ginn;\nDës Aktioun gouf aus Sécherheetsgrënn ofgebrach, fir ze verhënneren datt Är Sessioun piratéiert ka ginn.\nSchéckt de Formulaire w.e.g. nach eng Kéier.",
        "changecontentmodel": "De Modell vum Inhalt vun enger Säit änneren",
        "ipbreason-dropdown": "*Heefeg Ursaache fir Benotzer ze spären:\n**Bewosst falsch Informatiounen an eng oder méi Säite gesat\n**Ouni Grond Inhalt vu Säite geläscht\n**Spam-Verknëppunge mat externe Säiten\n**Topereien an d'Säite gesat\n**Beleidegt oder bedreet aner Mataarbechter\n**Mëssbrauch vu verschiddene Benotzernimm\n**Net akzeptabele Benotzernumm",
        "ipb-hardblock": "Verhënneren datt ageloggt Benotzer vun dëser IP-Adress aus Ännerunge maache kënnen",
        "ipbcreateaccount": "Benotzerkont opmaachen",
-       "ipbemailban": "Verhënneren datt de Benotzer E-Maile verschéckt",
+       "ipbemailban": "E-Maile verschécken",
        "ipbenableautoblock": "Automatesch déi lescht IP-Adress spären déi vun dësem Benotzer benotzt gouf, an all IP-Adresse vun denen dëse Benotzer versicht Ännerunge virzehuelen",
        "ipbsubmit": "Dës IP-Adress resp dëse Benotzer spären",
        "ipbother": "Aner Dauer:",
        "ipb-change-block": "De Benotzer mat dese Parameteren nees spären",
        "ipb-confirm": "Spär confirméieren",
        "ipb-partial": "Partiell",
+       "ipb-partial-help": "Spezifesch Säiten oder Nimmräim.",
        "ipb-pages-label": "Säiten",
        "ipb-namespaces-label": "Nummraim",
        "badipaddress": "D'IP-Adress huet dat falscht Format.",
        "previousdiff": "← Méi al Ännerung",
        "nextdiff": "Méi nei Ännerung →",
        "mediawarning": "<strong>Warnung:</strong> Dës Zort vu Fichier kann e béiswëllege Programmcode enthalen.\nDuerch d'Opmaache vum Fichier kann Äre System beschiedegt ginn.",
-       "imagemaxsize": "Maximal Gréisst fir Biller:<br />''(fir Billerbeschreiwungssäiten)''",
+       "imagemaxsize": "Maximal Gréisst fir Biller op Beschreiwungssäite fir Fichieren:",
        "thumbsize": "Gréisst vun der Miniatur:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|Säit|Säiten}}",
        "file-info": "Fichiersgréisst: $1, MIME-Typ: $2",
        "logentry-rights-autopromote": "De Benotzer $1 {{GENDER:$2|krut}} d'Benotzerrechter automatesch vu(n) $4 op $5 geännert",
        "logentry-upload-upload": "$1 huet $3 {{GENDER:$2|eropgelueden}}",
        "logentry-upload-overwrite": "$1 huet eng nei Versioun vu(n) $3 {{GENDER:$2|eropgelueden}}",
-       "logentry-upload-revert": "$1 huet $3 {{GENDER:$2|eropgelueden}}",
+       "logentry-upload-revert": "$1 huet $3 {{GENDER:$2|zréckgesat}} op eng al Versioun",
        "logentry-tag-update-add-revision": "$1 {{GENDER:$2|huet}} d'{{PLURAL:$7|Markéierung|Markéierunge(n)}} $6 op d'Versioun $4 vun der Säit $3 dobäigesat",
        "rightsnone": "(keen)",
        "rightslogentry-temporary-group": "$1 (temporär, bis $2)",
        "log-action-filter-upload-overwrite": "Nees eroplueden",
        "authmanager-create-disabled": "D'Opmaache vu Benotzerkonten ass gespaart.",
        "authmanager-create-from-login": "Fir Äre Benotzerkont unzeleeën fëllt w.e.g. d'Felder aus.",
-       "authmanager-authplugin-setpass-failed-title": "Änner vum Passwuert huet net funktionéiert",
-       "authmanager-authplugin-setpass-bad-domain": "Net valabelen Domain.",
        "authmanager-autocreate-noperm": "Automatescht Uleeë vu Benotzerkonten ass net erlaabt.",
        "authmanager-autocreate-exception": "Automatescht Uleeë vu Benotzerkonte gouf op Grond vu fréiere Feeler temporär ausgeschalt.",
        "authmanager-userdoesnotexist": "De Benotzerkont \"$1\" ass net registréiert.",
index 7c415a8..2324641 100644 (file)
        "revertpage": "Editas par [[Special:Contributions/$2|$2]] ([[User talk:$2|discute]]) ia es reversada a la revisa la plu resente par [[User:$1|$1]]",
        "revertpage-nouser": "Editas par un usor ascondeda ia es reversada a la revisa la plu resente par [[User:$1|$1]]",
        "rollback-success": "Editas par {{GENDER:$3|$1}} ia es reversada e cambiada a la revisa la plu resente par {{GENDER:$4|$2}}",
-       "rollback-success-notify": "Editas par $1 ia es reversada e cambiada a la revisa la plu resente par $2. [$3 Mostra cambias]",
        "sessionfailure-title": "Fali de sesion",
        "sessionfailure": "Lo pare ce tua sesion de autentici ave un problem; esta ata ia es canselada per proteje contra saisis de sesion. Reenvia la formulario, per favore.",
        "changecontentmodel": "Cambia model de contenida de un paje",
        "authmanager-create-no-primary": "La identia furnida no pote es usada per crea un conta.",
        "authmanager-link-no-primary": "La identia furnida no pote es usada per junta de conta.",
        "authmanager-link-not-in-progress": "Junta de conta no aveni, o datos de sesion es perdeda. Per favore, comensa denova.",
-       "authmanager-authplugin-setpass-failed-title": "Cambia de clave ia fali",
-       "authmanager-authplugin-setpass-failed-message": "La estendente de autentici ia rejeta la cambia de clave.",
-       "authmanager-authplugin-create-fail": "La estendente de autentici ia rejeta la crea de conta.",
-       "authmanager-authplugin-setpass-denied": "La estendente de autentici no permete cambia claves.",
-       "authmanager-authplugin-setpass-bad-domain": "Domina nonvalida.",
        "authmanager-autocreate-noperm": "La crea automata de contas no es permeteda.",
        "authmanager-autocreate-exception": "La crea automata de contas es tempora descomutada par causa de eras presedente.",
        "authmanager-userdoesnotexist": "Conta de usor \"$1\" no es rejistrada.",
index be4b046..8475cbd 100644 (file)
        "revertpage": "Wieziginge door [[Special:Contributions/$2|$2]] ([[User talk:$2|Euverlik]]) trukgedriejd tot de lètste versie door [[User:$1|$1]]",
        "revertpage-nouser": "Verangeringe door 'ne verstaoke gebroeker trökgedrejd nao de litste versie van {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Verangeringe door {{GENDER:$3|$1}} trökgedrejd;\nlitste versie van {{GENDER:$4|$2}} herstèld.",
-       "rollback-success-notify": "De verangeringe door $1 zint trökgedrejd;\nde litste versie van $2 is herstèld. [$3 Tuin verangeringe]",
        "sessionfailure-title": "Sessiefout",
        "sessionfailure": "'t Liek op det se e perbleem höbs mit dien aanmeldingssessie;\ndees hanjeling is aafgebraoke oet veurzörg taenge 'nen hack.\nVersjik estebleef 't formeleer.",
        "changecontentmodel": "Bewirk inhawdsmodel van pagina",
        "authmanager-create-no-primary": "De ingeveurde aanmeljgegaeves kóste neet waere gebroek veur 't aanmake van de konto.",
        "authmanager-link-no-primary": "De ingeveurde aanmeljgegaeves kóste neet waere gebroek veur de konto te koppele.",
        "authmanager-link-not-in-progress": "Konto-koppeling is neet in behanjeling of de sessiegegaeves zint verlaore gegange. Begin gans oppernuuj van begins aaf aan.",
-       "authmanager-authplugin-setpass-failed-title": "Verangere wachwaord mislök",
-       "authmanager-authplugin-setpass-failed-message": "De verificatie-inveugtoepassing haet 't verangere van 't wachwaord taengegehaje.",
-       "authmanager-authplugin-create-fail": "De verificatie-inveugtoepassing haet 't aanmake van diene konto taengegehaje.",
-       "authmanager-authplugin-setpass-denied": "De verificatie-inveugtoepassing steit 't verangere van 't wachwaord neet toe.",
-       "authmanager-authplugin-setpass-bad-domain": "Óngeljig demien.",
        "authmanager-autocreate-noperm": "De verificatie-inveugtoepassing steit 't aanmake van konto's neet toe.",
        "authmanager-autocreate-exception": "'t Automatisch aanmake van konto's is tiedelik oetgezat door ierder foute.",
        "authmanager-userdoesnotexist": "Gebroeker \"$1\" is neet geregistreerd.",
index 75c2b40..e68770b 100644 (file)
        "revertpage": "Annullou e modiffiche de [[Special:Contributions/$2|$2]] ([[User talk:$2|discuscion]]), riportâ a-a verscion precedente de [[User:$1|$1]]",
        "revertpage-nouser": "Annullou e modiffiche de un utente ascoso, riportâ a-a verscion precedente de {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Annullou e modiffiche de {{GENDER:$3|$1}}; paggina riportâ a l'urtima verscion de {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Annullou e modiffiche de $1;\npaggina riportâ a l'urtima revixon de $2. [$3 Mostra e modiffiche]",
        "sessionfailure-title": "Sescion fallia",
        "sessionfailure": "S'è veificou un problema inta sescion ch'a l'identiffica l'accesso; o scistema o no l'ha eseguio o comando impartio pe precauçion. Torna a-a paggina precedente co-o tasto 'Inderê' do to browser, recarega a paggina e riproeuva.",
        "changecontentmodel": "Cangia o modello de contegnuo de 'na paggina",
        "authmanager-create-no-primary": "E credençiæ fornie no poeuan ese doeuviæ pe-a creaçion de l'utença.",
        "authmanager-link-no-primary": "E credençiæ fornie no pœuan ese dœuviæ pe conligâ l'utença.",
        "authmanager-link-not-in-progress": "O conligamento de l'utença o no procede ò i dæti da sescion so-anæti perdui. Se prega de recomençâ da cavo.",
-       "authmanager-authplugin-setpass-failed-title": "Modiffica da password fallia",
-       "authmanager-authplugin-setpass-failed-message": "O plugin d'aotenticaçion o l'ha impedio a modiffica da password.",
-       "authmanager-authplugin-create-fail": "O plugin d'aotenticaçion o l'ha impedio a creaçion de l'utença.",
-       "authmanager-authplugin-setpass-denied": "O plugin d'aotenticaçion o no consente de cangiâ e password.",
-       "authmanager-authplugin-setpass-bad-domain": "Dominnio non vallido.",
        "authmanager-autocreate-noperm": "A creaçion aotomattica del'utença a no l'è permissa.",
        "authmanager-autocreate-exception": "A creaçion aotomattica di utençe a l'è temporaniamente disabilitâ a caosa di erroî precedenti.",
        "authmanager-userdoesnotexist": "L'utença \"$1\" a no l'è registrâ.",
index f2e9de3..31b169e 100644 (file)
@@ -22,7 +22,7 @@
        "tog-hidecategorization": "قام کئردئن جأرغە کاری بألگە یا",
        "tog-extendwatchlist": "سئیل بأرگە نە سی نئشوٙ دأئن تأموٙم آلئشتیا ڤا کو نە فأقأط سی بیشتئر تازە باڤیا.",
        "tog-usenewrc": "دأسە بأنی آلئشتیا ڤا بألگە د آلئشتیا تازە و سئیل بأرگ",
-       "tog-numberheadings": "سأربأÙ\84Ú¯Û\95 Ø®Ù\88د Ø´Ù\85ارئشت کو",
+       "tog-numberheadings": "سربٱÙ\84Ú¯Ù± Ø®Ù\88د Ø´Ù\85ارشت کو",
        "tog-editondblclick": "بألگە یا نە ڤا د نۊ پوٙرنیئن ڤیرایئشت بأکیت",
        "tog-editsectiononrightclick": "بأرجا ڤیرایئشت نە ڤا راس پوٙرنییئن د بأرجا داسوٙنیا کونئشتگأر کو",
        "tog-watchcreations": "بألگە یایی کئ مئ رأڤأندیاری کئمە و جانیایی کئ مئ سوڤار کئمە ئضاف کو د سئیل بأرگە مئ",
@@ -66,7 +66,7 @@
        "monday": "دۏشٱمٱ",
        "tuesday": "ساْ شٱمٱ",
        "wednesday": "چارشٱمٱ",
-       "thursday": "پٱن شمٱ",
+       "thursday": "پٱÙ\86 Ø´Ù±Ù\85Ù±",
        "friday": "جۏمٱ",
        "saturday": "شٱمٱ",
        "sun": "یاٛشٱمٱ",
        "thu": "پٱن شٱمٱ",
        "fri": "جۏمٱ",
        "sat": "شٱمٱ",
-       "january": "جانڤیٱ",
+       "january": "ژانڤیٱ",
        "february": "فڤریٱ",
        "march": "مارس",
        "april": "آڤریل",
        "may_long": "ماٛی",
-       "june": "جوئٱن",
+       "june": "ژوئٱن",
        "july": "جۊلای",
        "august": "آگوست",
        "september": "سپتامر",
        "february-gen": "فڤریٱ",
        "march-gen": "مارس",
        "april-gen": "آڤریل",
-       "may-gen": "Ù\85ئی",
-       "june-gen": "جۊٱن",
+       "may-gen": "Ù\85اÙ\9bی",
+       "june-gen": "ژوئٱن",
        "july-gen": "جۊلای",
        "august-gen": "آگوست",
        "september-gen": "سپتامر",
        "october-gen": "اوکتوبر",
        "november-gen": "نوڤامر",
        "december-gen": "دسامر",
-       "jan": "جانڤیٱ",
+       "jan": "ژانڤیٱ",
        "feb": "فڤریٱ",
        "mar": "مارس",
        "apr": "آڤریل",
        "may": "ماٛی",
-       "jun": "جوئٱن",
+       "jun": "ژوئٱن",
        "jul": "جۊلای",
        "aug": "آگوست",
        "sep": "سپتامر",
        "category_header": "بٱلگٱیا مؽن دٱسٱ \"$1\"",
        "subcategories": "زؽر دٱسٱیا",
        "category-media-header": "ڤارسگٱر د دٱسٱ \"$1\"",
-       "category-empty": "ای دٱسٱ د راستٱکی د ڤٱرگرتٱ هیچ بٱلگٱ یا ڤارسگٱری نی",
+       "category-empty": "اؽ دٱسٱ د راستٱکی د ڤٱرگرتٱ هیچ بٱلگٱ یا ڤارسگٱری نؽ",
        "hidden-categories": "{{PLURAL:$1|دٱسٱ قایم بیٱ|دٱسٱیا قایم بیٱ}}",
        "hidden-category-category": "دأسە یا قام بییە",
        "category-subcat-count": "{{PLURAL:$2|اؽ دٱسٱ فقٱت زؽر دٱسٱیا دماگر هان دش.اؽ دٱسٱ {{PLURAL:$1|زؽردٱسٱ|$1 زؽردٱسٱیا}} ٱ , ڤ دٱر د $2 کولٛ.}}",
        "category-subcat-count-limited": "ئی دأسە ها د {{PLURAL:$1|زیردأسە|$1 زیردأسە یا}} یی کئ ها ڤئ دومئشوٙ",
        "category-article-count": "{{PLURAL:$2|اؽ دٱسٱ د ڤٱرگرتٱ بٱلگٱ نهاییٱ.| {{PLURAL:$1| بٱلگٱ هؽ|$1 بٱلگٱیا هؽسن}} د اؽ دٱسٱ، ڤ دٱر د $2 کولٛ.}}",
        "category-article-count-limited": "نئها {{PLURAL:$1|بألگە هی|$1بألگە یا هئن}} د دأسە ئیسئنی.",
-       "category-file-count": "{{PLURAL:$2|اÛ\8c Ø¯Ù±Ø³Ù± Ù\81Ù±Ù\82ٱت Ø¯ Ú¤Ù±Ø±Ú¯Ø±ØªÙ± Ø¬Ø§Ù\86Û\8cا Ù\86ئÙ\87اÛ\8cÛ\8cÙ±.| Ù\86ئÙ\87اÛ\8cÛ\8c {{PLURAL:$1|جاÙ\86Û\8cا Ù\87Û\8c|$1 Ø¬Ø§Ù\86Û\8cاÛ\8cا Ù\87Û\8cÙ\86}} Ø¯ Ø§Û\8c Ø¯Ù±Ø³Ù±Ø\8c Ú¤ Ø¯Ù±Ø± Ø¯ Ú©Ù\88Ù\84 $2 .}}",
+       "category-file-count": "{{PLURAL:$2|اÛ\8c Ø¯Ù±Ø³Ù± Ù\81Ù\82ٱت Ø¯ Ú¤Ù±Ø±Ú¯Ø±ØªÙ± Ø¬Ø§Ù\86ؽا Ù\86Ù\87اÛ\8cÛ\8cÙ±.| Ù\86Ù\87اÛ\8cÛ\8c {{PLURAL:$1|جاÙ\86ؽا Ù\87ؽ|$1 Ø¬Ø§Ù\86Û\8cاÛ\8cا Ù\87ؽسÙ\86}} Ø¯ Ø§Ø½ Ø¯Ù±Ø³Ù±Ø\8c Ú¤ Ø¯Ù±Ø± Ø¯ Ú©Ù\88Ù\84Ù\9b $2 .}}",
        "category-file-count-limited": " {{PLURAL:$1|[جانیا هی|1$جانیایا هین}} نئهایی هان د دأسە ئیسئنی.",
        "listingcontinuesabbrev": "دومالٱ",
        "index-category": "بألگە یا سیاە دار",
-       "noindex-category": "بÙ\84Ú¯Ù±Û\8cا Ø¨Û\8c Ø³Û\8cائٱ",
-       "broken-file-category": "بألگە یایی کئ هوم پئیڤأند جانیایا ئشگئسئ نە دارئن",
+       "noindex-category": "بٱÙ\84Ú¯Ù±Û\8cا Ø¨Ø½ Ø³Ø½Ø§Ù\87ٱ",
+       "broken-file-category": "بٱلگٱیایی کاْ هوم پاٛڤٱن جانؽایا اْشگس ناْ دارٱن",
        "categoryviewer-pagedlinks": "($1) ($2)",
-       "about": "دئبارە",
+       "about": "دٱربارٱ",
        "article": "مینوٙنە یا بألگە",
        "newwindow": "(د یاٛ نیمدری تازٱ ڤازش کو)",
        "cancel": "ٱنجوم شیڤسن",
        "morenotlisted": "ئی نومگە کامئل بییە.",
        "mypage": "بألگە",
        "mytalk": "چٱک چنٱ",
-       "anontalk": "دئبارە تیرنئشوٙن ئی آی پی قئسە بأکیت",
+       "anontalk": "چٱک چنٱ",
        "navigation": "ناڤجۊری",
        "and": "&#32;ۉ",
        "faq": "ئف ئی کیوٙ",
        "history": "ڤیرگار بٱلگٱ",
        "history_short": "ڤیرگار",
        "updatedmarker": "د آخئری دییئن مئنە ڤئ هنگوم کو",
-       "printableversion": "نۏسخٱ پلا بینی",
+       "printableversion": "نۏسخٱ پلا بیئنی",
        "permalink": "هوم پاٛڤٱن هٱمیشاٛیی",
        "print": "چاپ گئرئتئن",
        "view": "دیئن",
        "view-foreign": "د $1 ناْ بونؽت",
        "edit": "ڤیرایش",
-       "edit-local": "توضی ڤولات نئشینی نە ڤیرایئشت بأکیت",
-       "create": "راس Ù\83ئردئن",
+       "edit-local": "تۉزی ڤلات نشینی نٱ آلشدکاری بٱکؽت",
+       "create": "دÛ\8fرس Ú©Ø±Ø¯ن",
        "create-local": "یاٛ تۉزی ڤلات نشینی اْزاف بٱکؽت",
-       "delete": "پاکسا Ú©Ø¦Ø±Ø¯Ø¦ن",
+       "delete": "پاکسا Ú©Ø±Ø¯ن",
        "undelete_short": "ناپاکسا کئردئن {{PLURAL:$1|یئ گئل ڤیرایئشت|$1 ڤیرایئشتیا}}",
        "viewdeleted_short": "{{PLURAL:$1|}}سئیل بأکیت{{[PLURAL:$1|یئ گئل ڤیرایئشت پاکسا بییە|$1ڤیرایئشتیا پاکسا بیینە}}",
-       "protect": "پأر Ù\88 Ù¾Û\8cÙ\85 Ø¨Ø£Ú©Û\8cت",
-       "protect_change": "Ø¢Ù\84ئشت Ø¨Ø£Ú©Û\8cت",
+       "protect": "پر Û\89 Ù¾Û\8cÙ\85 Ø¨Ù±Ú©Ø½ت",
+       "protect_change": "Ø¢Ù\84شت Ø¨Ù±Ú©Û\8cÙ\9bت",
        "unprotect": "آلئشت دأئن پأر و پیم کاری",
        "newpage": "بٱلگٱ نۊ",
        "talkpagelinktext": "چٱک چنٱ",
        "toolbox": "ٱڤزارؽا",
        "imagepage": "ديئن بألگە جانیا",
        "mediawikipage": "ديئن بألگە پئيغوم",
-       "templatepage": "دیئن بٱلگٱ چۊٱ",
+       "templatepage": "دیئن بٱلگٱ چۊئٱ",
        "viewhelppage": "ديئن بألگە هومیاری",
        "categorypage": "ديئن بألگە دأسە بأنی",
        "viewtalkpage": "دیئن چأک چئنە یا",
        "pool-errorunknown": "خأطا نادیار",
        "pool-servererror": "پوٙل ئشمار خئذمأتگە د دأسرئس نی($1).",
        "poolcounter-usage-error": "خأطا ڤئ کار گئرئتئن:$1",
-       "aboutsite": "دبارٱ {{SITENAME}}",
-       "aboutpage": "Project:دبارٱ",
+       "aboutsite": "دٱربارٱ {{SITENAME}}",
+       "aboutpage": "Project:دٱربارٱ",
        "copyright": "مینۊنٱیا هان د دٱسرس $1 مٱر یٱ کاٛ ڤ یاٛ گاٛل شیڤاٛ هٱنی نیسٱنٱ بۊٱ.",
        "copyrightpage": "{{ns:project}}:کوپی رایت",
-       "currentevents": "روخ ڤنؽا ایسنی",
-       "currentevents-url": "Project:روخ ڤنؽا ایسنی",
+       "currentevents": "رÙ\88Ø® Ú¤Ù±Ù\86ؽا Ø§Û\8cسÙ\86Û\8c",
+       "currentevents-url": "Project:رÙ\88Ø® Ú¤Ù±Ù\86ؽا Ø§Û\8cسÙ\86Û\8c",
        "disclaimers": "تیٱپۊشکاریٛا",
-       "disclaimerpage": "پرۉژٱ: تیٱپوشی کردن همٱگیر",
+       "disclaimerpage": "پروژٱ: تیٱپۊشی کردن همٱگیر",
        "edithelp": "هومياری سی ڤیرایش",
        "helppage-top-gethelp": "هومياری",
        "mainpage": "سرآسونٱ",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "د نۊ زنٱ بیٱ د\"$1\"",
-       "youhavenewmessages": "{{PLURAL:$3|Ø´Ù\88Ù\85ا Ø¯Ø§Ø±Û\8cت}} $1 ($2).",
-       "youhavenewmessagesfromusers": "{{PLURAL:$4|Ø´Ù\88Ù\85ا}} $1 Ø¯ {{PLURAL:$3|کارÛ\8cار Ù\87Ù±Ù\86Û\8c|$3 Ú©Ø§Ø±Û\8cارÛ\8cا}}دارÛ\8cت($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Ø´Ù\85ا Ø¯Ø§Ø±Ø½ت}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Ø´Ù\85ا}} $1 Ø¯ {{PLURAL:$3|کارÛ\8cار Ù\87Ù\86Û\8c|$3 Ú©Ø§Ø±Û\8cارؽا}}دارؽت($2).",
        "youhavenewmessagesmanyusers": "شوما د $1 فئرە کاریار داریت($2).",
-       "newmessageslinkplural": "{{PLURAL:$1|Û\8cئ Ú¯Ø¦Ù\84 Ù¾Ø¦Û\8cغÙ\88Ù\85 ØªØ§Ø²Û\95|999=پئÛ\8cغÙ\88Ù\85Û\8cا ØªØ§Ø²Û\95}}",
-       "newmessagesdifflinkplural": "آخئر {{PLURAL:$1|Ø¢Ù\84ئشت|Ø¢Ù\84ئشتÛ\8cا}}",
+       "newmessageslinkplural": "{{PLURAL:$1|Û\8cاÙ\9b Ù¾Ø§Ù\9bغÙ\88Ù\85 ØªØ§Ø²Ù±|999=پاÙ\9bغÙ\88Ù\85ؽا ØªØ§Ø²Ù±}}",
+       "newmessagesdifflinkplural": "آخر {{PLURAL:$1|Ø¢Ù\84شت|Ø¢Ù\84شتؽا}}",
        "youhavenewmessagesmulti": "شوما یئ گئل پئیغوم تازە د $1 داریت",
        "editsection": "آلشدکاری",
        "editold": "ڤیرایش",
-       "viewsourceold": "سئÛ\8cÙ\84 Ø¯ Ø³Ø£Ø±Ú\86ئشÙ\85Û\95 Ø¨Ø£Ú©Û\8cت",
+       "viewsourceold": "ساÙ\9bÙ\84Ù\9b Ø¯ Ø³Ø±Ú\86Ø´Ù\85Ù± Ø¨Ù±Ú©Ø½ت",
        "editlink": "ڤیرایش",
        "viewsourcelink": "ساٛلٛ د سرچشمٱ بٱکؽت",
-       "editsectionhint": "ڤیرایش یاٛ بٱرجا:$1",
+       "editsectionhint": "Ú¤Û\8cراÛ\8cØ´ Û\8cاÙ\9b Ø¨Ù±Ø¦Ø±Ø¬Ø§:$1",
        "toc": "مؽنونٱیا",
        "showtoc": "نئشوٙ دأئن",
        "hidetoc": "قام کئردئن",
        "nstab-user": "بٱلگٱ کاریار",
        "nstab-media": "بألگە ڤارئسگأر",
        "nstab-special": "بٱلگٱیا ڤیژٱ",
-       "nstab-project": "بألگە پوروجە",
+       "nstab-project": "بٱلگٱ پرۉژٱ",
        "nstab-image": "جانؽا",
-       "nstab-mediawiki": "پئÛ\8cغÙ\88Ù\99م",
-       "nstab-template": "چۊٱ",
+       "nstab-mediawiki": "پاÙ\9bغÙ\88م",
+       "nstab-template": "چۊئٱ",
        "nstab-help": "بألگە هومیاری",
        "nstab-category": "دٱسٱ",
        "mainpage-nstab": "سرآسونٱ",
        "nosuchaction": "چئنی کونئشتگأری نییئش",
        "nosuchactiontext": "کاری کئ ڤا یوٙ آر ئل تیار بییە نادیارە.\nگاسی شوما یوٙ آر ئل نە دوروس نأنیسأنیتە، یا یئ گئل هوم پئیڤأند ئشتئڤا ڤارئد بییە.\nڤئ گاسی یئ گئل سیسئریک د نأرم أفزاز ڤئ کار گئرئتە بییە ڤا {{SITENAME}} ئشارە بأکە.",
-       "nosuchspecialpage": "چئنی بألگە ڤیجە یی نییئش",
-       "nospecialpagetext": "<strong>Ø´Ù\88Ù\85ا Û\8cئ Ú¯Ø¦Ù\84 Ø¨Ø£Ù\84Ú¯Û\95 Ù\86ادÛ\8cار Ù\86Û\95 Ù\87استÛ\8cتÛ\95.</strong>\nگاسÛ\8c Û\8cئ Ú¯Ø¦Ù\84 Ù\86Ù\88Ù\85Ú¯Û\95 Ø³Û\8c Ø¯Û\8cارÛ\8c Ø¯Ø£Ø¦Ù\86 Ø¯ Ø¨Ø£Ù\84Ú¯Û\95 Û\8cا Ø¨Ø§Û\8cأد Ø¯ [[Special:SpecialPages|{{int:specialpages}}]] Ø¯Û\8cارÛ\8c Ø¨Ø£Ú©Û\95.",
+       "nosuchspecialpage": "چنی بٱلگاٛ ڤیژاٛیی نؽسش",
+       "nospecialpagetext": "<strong>Ø´Ù\85ا Û\8cاÙ\9b Ø¨Ù±Ù\84Ú¯Ù± Ù\86ادؽار Ù\86اÙ\92 Ù\87استؽتٱ.</strong>\nگاسÛ\8c Û\8cاÙ\9b Ù\86Ù\88Ù\85Ú¯Ù± Ø³Û\8c Ø¯Ø½Ø§Ø±Û\8c Ø¯Ø§Ù\9bئÙ\86 Ø¯ Ø¨Ù±Ù\84Ú¯Ù±Û\8cا Ø¨Ø§Û\8cٱد Ø¯ [[Special:SpecialPages|{{int:specialpages}}]] Ø¯Ø½Ø§Ø±Û\8c Ø¨Ù±Ú©Ù±.",
        "error": "خأطا",
        "databaseerror": "خأطا د رئسینە گا",
        "databaseerror-text": "یئ گئل خأطا جوست کاری د رئسینە گا دیاری کئردە.گاسی یە یئ گل سیسئریک د کار گئرئتئن نأرم أفزار راس بأکە.",
        "cannotdelete-title": "نأبوٙە بألگە $1 پاکسا با",
        "delete-hook-aborted": "پاکسا کاری ڤا قولاڤ نئها گئری بیە.\nهیچ توضیی سیش نی.",
        "no-null-revision": "سی بألگە $1 ڤانیأری خومثا نە راس بأکیت",
-       "badtitle": "داسوٙن گأن",
+       "badtitle": "داسوݩ گٱن",
        "badtitletext": "داسوݩ بٱلگٱ هاستنی نادؽارٱ، یٱ یاٛ داسوݩ مؽنجا زڤونی یا مؽنجا ڤیکی اْشتبائٱ.\nگاسؽ یٱ د ڤٱر گرتٱ یاٛ کاراکتر یا چٱن تا کاراکتر با کاْ نمۊئٱ د داسونؽا ڤ کارشو گرت.",
        "title-invalid-empty": "داسوٙن بألگە هاستئنی حالیە یا فأقأط مینوٙنە دار یئ گئل نوٙم یا نوٙم جاە.",
        "title-invalid-utf8": "داسوٙن بألگە هاستئنی مینوٙنە دار یئ گئل نئماجا UTF-8 نادیارە.",
        "perfcachedts": "رئسینە یا نئهایی د ڤیرگە قام بییە موٙکیس بینە و گاسی هأنی ڤئ هئنگوم سازی نأبینە.بیشتئروٙنە {{PLURAL:$4|یئ گئل نأتیجە|$4 یئ گئل نأتیجە}} د ڤیرگە قام بییە هان د دأسرئس.",
        "querypage-no-updates": "نأبوٙە ئی بألگە ڤئ هئنگوم سازی با.\nرئسینە یا ئیچئ تازە کاری نأبینە.",
        "viewsource": "ساٛلٛ د سرچشمٱ بٱکؽت",
-       "viewsource-title": "سئÛ\8cÙ\84 Ø¯ Ø³Ø£Ø±Ú\86ئشÙ\85Û\95 $1 Ø¨Ø£Ú©Û\8cت",
+       "viewsource-title": "ساÙ\9bÙ\84Ù\9b Ø¯ Ø³Ø±Ú\86Ø´Ù\85Ù± $1 Ø¨Ù±Ú©Ø½ت",
        "actionthrottled": "کونئشتکاری نئهاگئری بییە",
        "actionthrottledtext": "سی نئهاگئری د دأرتیچ بییئن ئسپأم نأبوٙە کئ شوما چئنی کاری نە د یئ گاتی کوٙتا چأن گئل أنجوم بئییت.\nلوطف بأکیت د چأن دئیقە هأنی د نۊ تئلاش بأکیت.",
        "protectedpagetext": "نأبوٙە د ئی بألگە ڤیرایئشت کاریا کاریاریا هأنی نە سئیل بأکیت.",
-       "viewsourcetext": "Ø´Ù\88Ù\85ا Ù\85Û\8c ØªÛ\8aÙ\86Û\8cت Ø³Ø±Ú\86Ø´Ù\85Ù± Ø§Û\8c Ø¨Ù\84Ú¯Ù± Ù\86اÙ\9b Ø³Ø§Ù\9bÛ\8cÙ\84 Ø¨Ù±Ú©Û\8cت Ù\88 Ø¯Ø§Ù\9bØ´ Û\8bردارÛ\8cت:",
+       "viewsourcetext": "Ø´Ù\85ا Ù\85ؽ ØªÙ\88Ù\86ؽت Ø³Ø±Ú\86Ø´Ù\85Ù± Ø§Ø½ Ø¨Ù±Ù\84Ú¯Ù± Ù\86اÙ\92 Ø³Ø§Ù\9bÙ\84Ù\9b Ø¨Ù±Ú©Ø½Øª Û\89 Ø¯Ø´ Ú¤Ø±Ø¯Ø§Ø±Ø½ت:",
        "viewyourtext": "شوما می توٙنیت سأرچئشمە ڤیرایئشتیا توٙنە د ئی بألگە سئیل بأکیت و دئشوٙ ڤئرداریت:",
        "protectedinterface": "ئی بألگە سی نأرم أفزار کئ ها د ئی ڤیکی نیسئسە آمادە میکە،و ڤئ د موزاحئمە ت کاری پأر و پیم کاری بیە\nسی ئضاف کئردئن یا آلئشت دأئن د هأمە ڤیکی یا لوطف بأکیت [https://translatewiki.net/ translatewiki.net] نە ڤئ کار بئیریت، پوروجە ڤولات نئشین سازی ڤیکیمئدیا.",
        "editinginterface": "<strong>ڤارئسکاری کئردئن:</strong> شوما داریت یئ گئل بألگە نە کئ سی یئ گئل نیسئسە یا نأرم أفزار پئیڤأندکار ڤئ کار گئرئتە بیە ڤیرایئشت میکیت.\nآلئشت دأئن ئی بألگە ری رئخت و بارت پئیڤأندکاری کئ کاریاری هأنی ڤئ نە ڤئ کار مئیرئن کارگئرایی دارە.",
        "filereadonlyerror": "نأبوٙە جانیا \"$1\" نە آلئشت کاری بأکیت سی یە کئ ئمایە جا \"$2\" ئیسئ ها د حال و بال حأنئن.\n\nدیڤوٙنداری کئ ڤئ نە قولف کئردە ها د حال و بال گوتە دیاری \"$3\" .",
        "invalidtitle-knownnamespace": "داسوٙن نادیار سی نوم جا \"$2\" و نیسئسە \"$3\"",
        "invalidtitle-unknownnamespace": "داسوٙن نادیار سی شومارە نادیار نوم جا \"$2\" و نیسئسە \"$3\"",
-       "exception-nologin": "ڤامین نیوٙماە",
+       "exception-nologin": "هنی نۏمایتٱ ڤامیٛن",
        "exception-nologin-text": "لوطف بأکیت بیایت ڤامین سی یە کئ د ئی بألگە یا کونئشتکاری دأسرئسی داشتوٙییت.",
        "exception-nologin-text-manual": "لوطف بأکیت ڤئ $1 صئلا بئیتوٙ کئ د ئی بألگە یا کونئشتکاری دأسرئسی داشتوٙە.",
        "virus-badscanner": "سازڤارە گأن:ڤیروٙس نادیار:<em>$1</em>",
        "yourpassword": "رازینە گوڤاردئن:",
        "userlogin-yourpassword": "رازینٱ گوڤاردن",
        "userlogin-yourpassword-ph": "رازینٱ گوئارسناْ بٱزاْ",
-       "createacct-yourpassword-ph": "رازینە گوڤاردئن نە بأزە",
+       "createacct-yourpassword-ph": "رازینٱ گوئاردن ناْ بٱزاْ",
        "yourpasswordagain": "یئ گئل هأنی رازینە گوڤاردئن نە بأزە",
-       "createacct-yourpasswordagain": "رازینە گوڤاردئن نە پوشت راس کو",
-       "createacct-yourpasswordagain-ph": "یاٛ گاٛل هٱنی رازینٱ گوڤاردن بٱزٱ",
-       "userlogin-remembermypassword": "مئنە د ساموٙنە ڤادار",
+       "createacct-yourpasswordagain": "رازینٱ گوئاردن ناْ پوشت دۏرس کو",
+       "createacct-yourpasswordagain-ph": "یاٛ گلٛ هنی رازینٱ گوئاردن بٱزٱ",
+       "userlogin-remembermypassword": "مناْ د سامونٱ ڤادار",
        "userlogin-signwithsecure": "ڤأصل بییئن أمن نە ڤئ کار بئیر",
        "yourdomainname": "پوشگئر شوما:",
        "password-change-forbidden": "شوما نئمی توٙنیت رازینە گوڤاردئن خوتوٙنە د ئی ڤیکی آلئشت بأکیت.",
        "nav-login-createaccount": " ڤامین ئوٙمائن/راس کئردئن حئساڤ",
        "logout": "د ساموٙنە دئرئوٙمائن",
        "userlogout": "د ساموٙنە دئرئوٙمائن",
-       "notloggedin": "Ù\86أبÙ\88Ù\99Ø£ Ø¨Û\8cائÛ\8cت Ú¤Ø§Ù\85Û\8cن",
-       "userlogin-noaccount": "Û\8cئ Ú¯Ø¦Ù\84 Ø­Ø¦Ø³Ø§Ú¤ Ù\86ارÛ\8cت؟",
-       "userlogin-joinproject": "أندوم دیارگە {{SITENAME}} بوٙئیت",
+       "notloggedin": "Ù\87Ù\86Û\8c Ù\86Û\8fÙ\85اÛ\8cتٱ Ú¤Ø§Ù\85Û\8cÙ\9bن",
+       "userlogin-noaccount": "Û\8cاÙ\9b Ù\87ساÙ\88 Ù\86ارؽت؟",
+       "userlogin-joinproject": "ٱندوم دؽارگٱ {{SITENAME}} بۊئؽت",
        "createaccount": "هساو دۏرس بٱکؽت",
        "userlogin-resetpassword-link": "رازینٱ گوئارسن تو د ڤیرتو رٱتٱ؟",
-       "userlogin-helplink2": "Ù\87Ù\88Ù\85Û\8cارÛ\8c Ú©Ø¦Ø±Ø¯Ø¦Ù\86 Ø¯ Ø·Ø£Ø±Û\8cÙ\82 Ú¤Ø§Ù\85Û\8cÙ\86 Ø¦Ù\88Ù\99Ù\85ائن",
+       "userlogin-helplink2": "Ù\87Ù\88Ù\85Û\8cارÛ\8c Ú©Ø±Ø¯Ù\86 Ø¯ ØªÙ±Ø±Û\8cÙ\82 Ú¤Ø§Ù\85ؽÙ\86 Ø§Ù\88Ù\85اÛ\8cن",
        "userlogin-loggedin": "شوما ئیسئ چی یئ گئل {{GENDER:$1|$1}} ئوٙمایتە ڤامین.نوم بألگە هاری نە سی ڤامین ئوٙمائن چی یئ گئل کاریار هأنی بلگه هاری سی وا مین اومائن چی یه گل کاریار هنی ڤئ کار بئیریت.",
        "userlogin-createanother": "یئ گئل حئساڤ هأنی راس بأکیت",
        "createacct-emailrequired": "تیرنئشوٙن أنجومانامە",
-       "createacct-emailoptional": "تیرنشۊن ٱنجومانامٱ",
-       "createacct-email-ph": "تیرنشون انجومانامه تونه وارد بكيت",
+       "createacct-emailoptional": "تیرنشوݩ ٱنجومانامٱ",
+       "createacct-email-ph": "تیرنشوݩ ٱنجومانامٱ توناْ ڤارد بٱكؽت",
        "createacct-another-email-ph": "تیرنئشوٙن أنجومانامە توٙنە بأزأنیت",
        "createaccountmail": "یئ گئل رازینە گوڤاردئن موڤأقأتینە ڤئ کار بئیریت و ڤئ نەسی یئ گئل تیرنئشوٙن أنجومانامە تیار بییە کئل بأکیت.",
        "createacct-realname": "نوم راستأکی(مأژبوٙری نی)",
        "createacct-reason": "دألیل",
        "createacct-reason-ph": "سی چی شوما داریت یئ گئل حئساڤ هأنی راس میکید",
-       "createacct-submit": "حئسأڤ خوتوٙنە راس بأکیت",
+       "createacct-submit": "هساو خوتوناْ دۏرس بٱکؽت",
        "createacct-another-submit": "یئ گئل حئساڤ هأنی راس بأکیت",
-       "createacct-benefit-heading": "{{SITENAME}}  ڤئ دأس خألکی چی شوما رأڤأندیاری بییە.",
-       "createacct-benefit-body1": "{{PLURAL:$1|Ú¤Û\8cراÛ\8cئشت|Ú¤Û\8cراÛ\8cئشتÛ\8cا}}",
-       "createacct-benefit-body2": "{{PLURAL:$1|بألگە|بألگە یا}}",
-       "createacct-benefit-body3": "تازە{{PLURAL:$1|هومیار|ھومیاریا}}",
+       "createacct-benefit-heading": "{{SITENAME}}  ڤ دٱس کٱسؽایؽ چی شما رٱڤٱندؽاری بیٱ.",
+       "createacct-benefit-body1": "{{PLURAL:$1|Ú¤Û\8cراÛ\8cØ´|Ú¤Û\8cراÛ\8cشؽا}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|بٱلگٱ|بٱلگٱیا}}",
+       "createacct-benefit-body3": "تازٱ{{PLURAL:$1|هومیار|ھومیاریا}}",
        "badretype": "رازینە گوڤاردئنی کئ شمأ دأییتە هومدأنگی نارە.",
        "usernameinprogress": "رأرڤأندیاری یئ گئل حئساڤ سی ئی نوم کاریاری ھا د پیشکئرد. یئ گوری آھئرە داری بأکیت.",
        "userexists": "نوم کاریاری دە بییە ئیسئنی ڤئ کار گئرئتە بییە.\nلوطف بأکیت یئ گئل نوم هأنی نە ڤئرداریت.",
        "suspicious-userlogout": "د حاست ڤئ دأر رأتئن شوما تیە پوشی بییە سی یە کئ ڤئ نأظأر یما کئ ڤئ سی یئ گئل دوڤارتە نیأر گأن یا یئ گئل پوروکسی کئ ها د ڤیرگە کأش کئل بییە.",
        "createacct-another-realname-tip": "نوم راستأکی دئل ڤئ حاییە.\nأر شوما ڤئنە نئها ئمایە بأکیت، یە سی هوم نئسبأت دأئن کاریاری سی کاریاش ڤئ کار گئرئتئ بوٙە.",
        "pt-login": "ڤا مؽن اوماین",
-       "pt-login-button": "ڤامین ئوٙمائن",
+       "pt-login-button": "ڤامؽن اوماین",
        "pt-createaccount": "هساو دۏرس بٱکؽت",
        "pt-userlogout": "د سامونٱ دروماین",
        "php-mail-error-unknown": "خأطا نادیار د آلئشتگئر PHP's mail()",
        "resetpass-expired": "گات دیاری رازینە گوڤاردئن شوما تأموم بییە. لوطف بأکیت یئ گئل رازینە گوڤاردئن هأنی نە سی ڤامین ئوٙمائن میزوٙنکاری بأکیت.",
        "resetpass-expired-soft": "گات دیاری رازینە گوڤاردئن شوما تأموم بییە و باس د نۊ زئنە با. لوطف بأکیت یئ گئل رازینە گوڤاردئن هأنی نە ئنتئخاڤ بأکیت، یا سی د نۊ زئنە کئردئن د نئهاتئر د ئیچئ \"{{int:authprovider-resetpass-skip-label}}\" بأپوٙرنیت.",
        "resetpass-validity-soft": "رازینە گوڤاردئن توٙ نادیاره:$1\n\n لوطف بأکیت یئ گئل رازینە گوڤاردئن هأنی نە ئنتئخاڤ بأکیت، یا سی د نۊ زئنە کئردئن د نئهاتئر د ئیچئ \"{{int:authprovider-resetpass-skip-label}}\" بأپوٙرنیت.",
-       "passwordreset": "د Ù\86Û\8a Ø¯Ø£Ø¦Ù\86 Ø±Ø§Ø²Û\8cÙ\86Û\95 Ú¯Ù\88ڤاردئن",
+       "passwordreset": "د Ù\86Û\8a Ø¯Ø§Ù\9bئÙ\86 Ø±Ø§Ø²Û\8cÙ± Ú¯Ù\88ئاردن",
        "passwordreset-text-one": "ئی نوم بألگە نە سی گئرئتئن یئ گئل رازینە گوڤاردئن موڤأقأت ڤا أنجومانامە توٙ پور بأکیت.",
        "passwordreset-text-many": "{{PLURAL:$1|یئ گئل د جاگە یا نە سی گئرئتئن رازینە گوڤاردئن موڤأقأتی نە ڤا أنجومانامە گئرئتە بوٙأ پور بأکیت.}}",
        "passwordreset-disabled": "نۊ کئردئن رازینە گوڤاردئن د ئی ڤیکی ناکونئشگأر بییە.",
        "minoredit": "یٱ یاٛ ڤیرایش کوچکٱ",
        "watchthis": "دیئن اؽ بٱلگٱ",
        "savearticle": "آمادٱ کردن بٱلگٱ",
-       "preview": "Ù¾Ù\8aØ´ Ø³Ø¦Ù\8aÙ\84",
+       "preview": "Ù¾Ù\8aØ´ Ø³Ø§Ù\9bÙ\84Ù\9b",
        "showpreview": "نشوݩ داٛئن پیش ساٛلٛ",
        "showdiff": "نشوݩ داٛین آلشتکاریا",
        "blankarticle": "<strong>زنئار:</strong> بلگه ای که شما دروس کردیته حالیه.\nار شما د نو ری \"$1\" بپورنیت, بلگه وه شکل که هیچ مینونه ای دش نبا دروس بوئه.",
        "subject-preview": "داسوٙن/پیش سئیل سأرخأط:",
        "previewerrortext": "یئ گئل خأطا د گاتی کئ شوما میهاستیت یئ گئل پیش سئل د آلئشتیاتوٙ داشتوٙین پیش ئوٙماە.",
        "blockedtitle": "کاریار نئهاگئری بی",
-       "blockedtext": "<strong>Ù\86Ù\88Ù\85 Ú©Ø§Ø±Û\8cارÛ\8c Ø´Ù\85ا Û\8cا ØªÛ\8cرÙ\86Ø´Ù\88Ý© Ø¢Û\8c Ù¾Û\8c Ø´Ù\85ا Ù\86Ù\87اگرÛ\8c Ø¨Û\8cÙ±.</strong>\n\n\n$1 Ú¤Ù\86Ù± Ù\86Ù\87اگرÛ\8c Ú©Ø±Ø¯Ù±.\nدÙ\84Ù\9bÛ\8cÙ\84Ù\9bØ´ Ù\87ا Ø¯ Ø§Û\8cÚ\86اÙ\92<em>$2</em>.\n\nشرÛ\8a Ø¯ Ù\86Ù\87اگرÛ\8c:$8\nآخر Ù\86Ù\87اگرÛ\8c:$6\nکارÛ\8cارÛ\8c Ú©Ø§Ù\92 Ù\87ا Ú¤Ù±Ø±ØªÛ\8cÙ± Û\89 Ù\86Ù\87اگرÛ\8c Ø¨Û\8cÙ±:$7\n\nØ´Ù\85ا Ù\85ؽ ØªÙ\88Ù\86ؽت Ú¤Ø§ $1 Û\8cا [[{{MediaWiki:Grouppage-sysop}}|سردÛ\8cÚ¤Ù\88Ù\86کار]] Ù\87Ù\86Û\8c Ù¾Ø§Ù\9bÚ¤Ù±Ù\86 Ø¨Ø§Ù\9bÛ\8cرؽت Û\89 Ø³Û\8c Ù\86Ù\87اگرÛ\8c Ú¤Ø§ Ú¤Ù± Ú\86Ù±Ú© Ú\86Ù\86Ù± Ú©Ø§Ø±Û\8c Ø¨Ù±Ú©Ø½Øª.\nÙ±Ù\84ڤٱت Ø¯ Ú¤Û\8cر Ø¯Ø§Ø´ØªÛ\8aؽت Ú©Ø§Ù\92 Ø´Ù\85ا Ù\86Ù\85ؽ ØªÙ\88Ù\86ؽت Ú\86Û\8cا Ù±Ù\86جÙ\88Ù\85 Ù\86اÙ\85Ù± Ú©Ù\84Ù\9b Ú©Ø±Ø¯Ù\86 Ø³Û\8c Ø§Ø½ Ú©Ø§Ø±Û\8cار Ù\86اÙ\92 Ú¤ Ú©Ø§Ø± Ø¨Ø§Ù\9bÛ\8cرؽتØ\8c Ù\85ٱر Û\8cÙ± Ú©Ø§Ù\92 Û\8cاÙ\9b ØªÛ\8cرÙ\86Ø´Ù\88Ý© Ù±Ù\86جÙ\88Ù\85 Ù\86اÙ\85Ù± Ù\86ازار Ù\86Ù± [[Special:Preferences|تٱرجÛ\8cÛ\8cات Ú©Ø§Ø±Û\8cارÛ\8c]] Ø®Ù\88تÙ\88 Ø¯Ø½Ø§Ø±Û\8c Ú©Ø±Ø¯Û\8aؽت Û\89 ØªÙ\88Ù\86سÛ\8aؽت Ú¤Ù±Ù\86اÙ\92 Ú¤ Ú©Ø§Ø± Ø¨Ø§Ù\9bÛ\8cرؽت .\nتÛ\8cرÙ\86Ø´Ù\88Ý© Ø¢Û\8c Ù¾Û\8c Ø§Û\8cسÙ\86Û\8c Ø´Ù\85ا $3 Ù±Ø\8c Û\89 Ù\86Ù\88Ù\85 Ø¯Ø½Ø§Ø±Ú©Ù\88Ý© Ù\86Ù\87اگری #$5 ٱ.\nلوتف بٱکؽت همٱ چیاناْ د هٱر هاستاٛیؽ کاْ دارؽت بۉؽت.",
+       "blockedtext": "<strong>Ù\86Ù\88Ù\85 Ú©Ø§Ø±Û\8cارÛ\8c Ø´Ù\85ا Û\8cا ØªÛ\8cرÙ\86Ø´Ù\88Ý© Ø¢Û\8c Ù¾Û\8c Ø´Ù\85ا Ù\86Ù\88ئاگÛ\8cرÛ\8c Ø¨Û\8cÙ±.</strong>\n\n\n$1 Ú¤Ù\86Ù± Ù\86Ù\88ئاگÛ\8cرÛ\8c Ú©Ø±Ø¯Ù±.\nدÙ\84Ù\9bÛ\8cÙ\84Ù\9bØ´ Ù\87ا Ø¯ Ø§Û\8cÚ\86اÙ\92<em>$2</em>.\n\nشرÛ\8a Ø¯ Ù\86Ù\88ئاگÛ\8cرÛ\8c:$8\nآخر Ù\86Ù\88ئاگÛ\8cرÛ\8c:$6\nکارÛ\8cارÛ\8c Ú©Ø§Ù\92 Ù\87ا Ú¤Ù±Ø±ØªÛ\8cÙ± Û\89 Ù\86Ù\88ئاگÛ\8cرÛ\8c Ø¨Û\8cÙ±:$7\n\nØ´Ù\85ا Ù\85ؽ ØªÙ\88Ù\86ؽت Ú¤Ø§ $1 Û\8cا [[{{MediaWiki:Grouppage-sysop}}|سٱردÛ\8cÚ¤Ù\88Ù\86کار]] Ù\87Ù\86Û\8c Ù¾Ø§Ù\9bÚ¤Ù±Ù\86 Ø¨Ø§Ù\9bÛ\8cرؽت Û\89 Ø³Û\8c Ù\86Ù\88ئاگÛ\8cرÛ\8c Ú¤Ø§ Ú¤Ù± Ú\86Ù±Ú© Ú\86Ù\86Ù± Ú©Ø§Ø±Û\8c Ø¨Ù±Ú©Ø½Øª.\nÙ±Ù\84ڤٱت Ø¯ Ú¤Û\8cر Ø¯Ø§Ø´ØªÛ\8aؽت Ú©Ø§Ù\92 Ø´Ù\85ا Ù\86Ù\85ؽ ØªÙ\88Ù\86ؽت Ú\86Û\8cا Ù±Ù\86جÙ\88Ù\85 Ù\86اÙ\85Ù± Ú©Ù\84Ù\9b Ú©Ø±Ø¯Ù\86 Ø³Û\8c Ø§Ø½ Ú©Ø§Ø±Û\8cار Ù\86اÙ\92 Ú¤ Ú©Ø§Ø± Ø¨Ø§Ù\9bÛ\8cرؽتØ\8c Ù\85ٱر Û\8cÙ± Ú©Ø§Ù\92 Û\8cاÙ\9b ØªÛ\8cرÙ\86Ø´Ù\88Ý© Ù±Ù\86جÙ\88Ù\85 Ù\86اÙ\85Ù± Ù\86ازار Ù\86Ù± [[Special:Preferences|تٱرجÛ\8cÛ\8cات Ú©Ø§Ø±Û\8cارÛ\8c]] Ø®Ù\88تÙ\88 Ø¯Ø½Ø§Ø±Û\8c Ú©Ø±Ø¯Û\8aؽت Û\89 ØªÙ\88Ù\86سÛ\8aؽت Ú¤Ù±Ù\86اÙ\92 Ú¤ Ú©Ø§Ø± Ø¨Ø§Ù\9bÛ\8cرؽت .\nتÛ\8cرÙ\86Ø´Ù\88Ý© Ø¢Û\8c Ù¾Û\8c Ø§Û\8cسÙ\86Û\8c Ø´Ù\85ا $3 Ù±Ø\8c Û\89 Ù\86Ù\88Ù\85 Ø¯Ø½Ø§Ø±Ú©Ù\88Ý© Ù\86Ù\88ئاگÛ\8cری #$5 ٱ.\nلوتف بٱکؽت همٱ چیاناْ د هٱر هاستاٛیؽ کاْ دارؽت بۉؽت.",
        "autoblockedtext": "<strong>نوم کاریاری شوما یا تیرنئشوٙن آی پی شوما سی یە کئ یئ گئل کاریاری هأنی ڤئ نە ڤئ کار گئرئتە خودأنجومأن ڤئ دأس $1 نئهاگئری بییە.</strong>\n\n\n$1 ڤئنە نئهاگئری کئردە.\nدألیلئش ها د ئیچئ\n<em>$2</em>.\n\nشوروٙ د نئهاگئری:$8\nآخئر نئهاگئری:$6\nکاریاری کئ ها ڤأرتیە و نئهاگئری بییە:$7\n\nشوما می توٙنیت ڤا $1 یا [[{{MediaWiki:Grouppage-sysop}}|سأردیڤوٙنکار]] هأنی پئیڤأند بئیریت و سی نئهاگئری ڤا ڤئ چأک چئنە کاری بأکیت.\nألڤأت د ڤیر داشتوٙئیت کئ شوما نئمی توٙنیت خوصۉصیأت أنجومانامە کئل کئردئن سی ئی کاریار نە ڤئ کار بئیریت، مأر یە کئ یئ گئل تیرنئشوٙن أنجومانامە نازار نە [[Special:Preferences|تأرجیحات کاریاری]] خوتوٙ دیاری کئردئوٙیت و توٙنئستوٙیت ڤئ نە ڤئ کار بئیریت .\nتیرنئشوٙن آی پی ئیسئنی شوما $3ە، و نوم دیارکون نئهاگئری #$5 ە.\nلوطف بأکیت هأمە چیانە د هأر حاستە یی کئ داریت بوٙئیت.",
        "blockednoreason": "هیچ دألیلی گوتە نأبییە",
        "whitelistedittext": "$1 لوطف بأکیت بألگە یا نە ڤیرایئشت کاری بأکیت.",
        "accmailtitle": "رازینە گوڤاردئن کئل بی",
        "accmailtext": "یئ گئل رازینە گوڤاردئن شامسأکی سی[[User talk:$1|$1]] سی $2 کئل بییە.بوٙە ڤئنە د گات ڤئ کار گئرئتئن بألگە ڤامین ئوٙمائن <em>[[Special:آلئشت دأئن رازینە گوڤاردئن|آلئشت دأئن رازینە گوڤاردئن]]</em> آلئشت کاری با.",
        "newarticle": "تازە",
-       "newarticletext": "Ø´Ù\88Ù\85ا Ù\87اÛ\8cÛ\8cÙ\86 Ú¤Ø§ Ø¯Ø¦Ù\85ا Ù\87Ù\88Ù\85 Ù¾Ø¦Û\8cڤأÙ\86دÛ\8c Ú©Ø¦ Ú¤Ù\88جÙ\88Ù\99د Ù\86ارÛ\95.\nسÛ\8c Ø±Ø£Ú¤Ø£Ù\86دÛ\8cارÛ\8c Ø¨Ø£Ù\84Ú¯Û\95.Ø´Ù\88رÙ\88Ù\99 Ø¨Ø£Ú©Û\8cت Ù\85Û\8cÙ\86ئ Ø¬Ø£Ú¤Û\95 Ù\87ارÛ\8c Ø¨Ø£Ù\86Û\8cسÛ\8cت (سÛ\8c Ø¯Ù\88Ù\99Ù\86ئسئÙ\86 Ø¨Û\8cشتئر Ø³Ø¦Û\8cÙ\84 [$1 ] Ø¨Ø£Ú©Û\8cت).\nأر Ø´Ù\88Ù\85ا Ø³Û\8c Ø¦Ø´ØªØ¦Ú¤Ø§ Ú©Ø¦Ø±Ø¯Ø¦Ù\86 Ù\87ائÛ\8cت Ø¦Û\8cÚ\86ئØ\8c Ø±Û\8c Ø¯Ù\88Ú¯Ù\85Û\95 Ú¤Ø§Ø¯Ø¦Ù\85ا Ø±Ø£ØªØ¦Ù\86 Ø¯Ù\88ڤارتÛ\95 Ù\86Û\8cأر Ø¨Ø£Ù¾Ù\88Ù\99رÙ\86Û\8cت.",
+       "newarticletext": "Ø´Ù\85ا Ù\87ائؽت Ú¤Ø§ Ø¯Ù\85ا Ù\87Ù\88Ù\85 Ù¾Ø§Ù\9bÚ¤Ù±Ù\86ؽ Ø§Ù\92 Ú¤Ù\88جÛ\8aد Ù\86ارٱ.\nسÛ\8c Ø±Ù±Ú¤Ù±Ù\86دؽارÛ\8c Ø¨Ù±Ù\84Ú¯Ù±.شرÛ\8a Ø¨Ù±Ú©Ø½Øª Ù\85ؽÙ\86 Ø¬Ù±Ú¤Ù± Ù\87Ù\88رÛ\8c Ø¨Ù±Ù\86Û\8cسؽت (سÛ\8c Ø¯Ù\88Ù\86سÙ\86 Ø¨Ø½Ø´ØªØ± Ø³Ø§Ù\9bÙ\84Ù\9b [$1 ] Ø¨Ù±Ú©Ø½Øª).\nٱر Ø´Ù\85ا Ø³Û\8c Ø§Ù\92شتبا Ú©Ø±Ø¯Ù\86 Ù\87ائؽت Ø§Û\8cÚ\86اÙ\92Ø\8c Ø±Û\8c Ø¯Û\8fÚ¯Ù\85Ù± Ú¤Ø§Ø¯Ù\85ا Ø±Ù±ØªÙ\86 Ø¯Ù\88ئارتٱ Ù\86Û\8cٱر Ø¨Ù±Ù¾Û\8aرÙ\86ؽت.",
        "anontalkpagetext": "----",
        "noarticletext": "د ایسنؽا اؽ بٱلگٱ نیسسٱ ڤجۊد ناشتٱ.\nشما مؽ تونؽت د[[Special:Search/{{PAGENAME}}|بٱگٱردؽد]] د اؽ بٱلگٱ اؽ د بٱلگٱ هنی یا <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} د نۊ پاٛجۊری بۊئٱ]</span>، <span class=\"plainlinks\">[{{fullurl:{{FULLPAGENAME}}|action=edit}} یا ای بٱلگٱ ناْ ڤیرایش بٱکؽت]</span>.",
        "noarticletext-nopermission": "د ایسنؽا اؽ بٱلگٱ نیسساٛیؽ ڤجۊد ناشتٱ.\nشما مؽ تونؽت د[[Special:Search/{{PAGENAME}}|بٱگردؽد]] د اؽ بٱلگٱیا د بٱلگٱ هنی یا <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} د نۊ پاٛجۊری بۊئٱ]</span>، <span class=\"plainlinks\">[{{fullurl:{{FULLPAGENAME}}|action=edit}}</span>.ڤلی شما سلا یٱناْ کاْ اؽ بٱلگٱ ناْ دۏرس بٱکؽت نارؽت.",
        "userpage-userdoesnotexist": "حئساڤ کاریاری \"$1\" ثأڤت نأم نأبییە.\nأر میھایت ئی بألگە نئ بأسازیت یا ڤیرایئشت کاری بأکیت یئ گئل ڤارئسی أنجوم بئیتوٙ.",
        "userpage-userdoesnotexist-view": "هساو کاریاری \"$1\" سٱبت ناٛییٱ.",
        "blocked-notice-logextract": "ئی کاریار د ئیسئنی نئھاگئری بییە.\nآخئری پئرئستنوٙمە نئھاگئری ڤامین یاریا د ھار سی سأرچئشمە آمادە کاری بییە:",
-       "clearyourcache": "<strong>Ú¤ Ú¤Û\8cر Ø¯Ø§Ø´ØªÛ\8aؽت:</strong> Ù\86Ù\88ئا Ø¢Ù\85اÛ\8cÙ± Ú©Ø§Ø±Û\8cØ\8cگاسؽ Ø´Ù\85ا Ù\85ٱجبÛ\8aر Ø¯ Ú¤ Ú©Ø§Ø± Ú¤Ù±Ù\86Ù\86 Ú¤Û\8cرگٱ Ù\82اÛ\8cÙ\85 Ø¨Û\8cÙ± Ø¯Ù\88ئارتٱ Ù\86Û\8cÛ\8cٱر Ø®Ù\88تÙ\88Ý© Ø³Û\8c Ø¯Û\8cÛ\8cÙ\86 Ø§Ø½ Ø¢Ù\84شتکارÛ\8c Ø¨Û\8aÛ\8cؽت.\n* <strong>Ù\81اÛ\8cرÙ\81اکس/ Ø³Ù±Ù\81ٱرÛ\8c:</strong> Ø¨Ù±Ù¾Û\8aرÙ\86ؽت Ø±Û\8c<em>Ø´Û\8cÙ\81ت</em> Ø§Û\8aساÙ\92 Ú©Ø§Ù\92 Ø½ Ù¾Û\8aرÙ\86ؽت <em> Ú¤Ù± Ø¯ Ù\86Û\8a Ø³Ú¤Ø§Ø± Ù\85Û\8aئٱ </em>Û\8cا Ú¾Ù\86Û\8c Ø±Û\8c <em>Ctrl-F5</em> Ø¨Ù±Ù¾Û\8aرÙ\86ؽت Û\8cا<em>Ctrl-R</em> (<em>â\8c\98-R</em> Ø¯ Ø³Ø§Ù\85Ù\88Ù\99Ù\86Û\95 Ù\85Ø£Ú©)\n* <strong>Ú¯Û\8aÚ¯Ù\84 Ú©Ø±Ù\88Ù\85:</ strong>بٱپÛ\8aرÙ\86ؽت Ø±Û\8c <em>Ctrl-Shift-R</em> (<em>â\8c\98-Shift-R</em> Û\8cا Ø¯ Ø³Ø§Ù\85Ù\88Ù\86Ù±)\n* <strong>اÛ\8cÙ\86ترÙ\86ت Ø§Ù\92کسپÙ\84Ù\88رر:</strong> <em>Ctrl</em> Ù\86اÙ\92 Ú¤Ø§Ø¯Ø§Ø±Ø½Øª Ø§Û\8aساÙ\92 Ú©Ø§Ù\92 Ù\85ؽپÛ\8aÙ\86ؽت <em>رÛ\8c Ú©Ù\84Ù\9bÛ\8cÙ\84Ù\9b Ø±Ù\81رش</em>Ø\8cÛ\8cا Ú¤Ø§Ø¯Ø§Ø´ØªÛ\8cتٱ<em>Ctrl-F5</em>\n* <strong>اÙ\88پرا:</strong> Ú¤Û\8cرگٱ Ù\82اÛ\8cÙ\85 Ø¨Û\8cÛ\8cÙ± Ø¯ <em>أڤزارؽاâ\86\92 Ø¢Ù\88Ù\84ٱڤؽٱتؽاÙ\86اÙ\92 Ù¾Ø§Ú©Ø³Ø§ Ø¨Ù±Ú©Ø½Øªت</em>",
+       "clearyourcache": "<strong>Ú¤ Ú¤Û\8cر Ø¯Ø§Ø´ØªÛ\8aئؽت:</strong> Ù\86Ù\88ئا Ø¢Ù\85اÛ\8cÙ± Ú©Ø§Ø±Û\8cØ\8cگاسؽ Ø´Ù\85ا Ù\85ٱجبÛ\8aر Ø¯ Ú¤ Ú©Ø§Ø± Ú¤Ù±Ù\86Ù\86 Ú¤Û\8cرگٱ Ù\82اÛ\8cÙ\85 Ø¨Û\8cÙ± Ø¯Ù\88ئارتٱ Ù\86Û\8cÛ\8cٱر Ø®Ù\88تÙ\88Ý© Ø³Û\8c Ø¯Û\8cئÙ\86 Ø§Ø½ Ø¢Ù\84شتکارÛ\8c Ø¨Û\8aÛ\8cؽت.\n* <strong>Ù\81اÛ\8cرÙ\81اکس/ Ø³Ù±Ù\81ٱرÛ\8c:</strong> Ø¨Ù±Ù¾Û\8aرÙ\86ؽت Ø±Û\8c<em>Ø´Û\8cÙ\81ت</em> Ø§Û\8aساÙ\92 Ú©Ø§Ù\92 Ø½ Ù¾Û\8aرÙ\86ؽت <em> Ú¤Ù± Ø¯ Ù\86Û\8a Ø³Ú¤Ø§Ø± Ù\85Û\8aئٱ </em>Û\8cا Ú¾Ù\86Û\8c Ø±Û\8c <em>Ctrl-F5</em> Ø¨Ù±Ù¾Û\8aرÙ\86ؽت Û\8cا<em>Ctrl-R</em> (<em>â\8c\98-R</em> Ø¯ Ø³Ø§Ù\85Ù\88Ù\86Ù± Ù\85Ù±Ú©)\n* <strong>Ú¯Û\8aÚ¯Ù\84 Ú©Ø±Ù\88Ù\85:</ strong>بٱپÛ\8aرÙ\86ؽت Ø±Û\8c <em>Ctrl-Shift-R</em> (<em>â\8c\98-Shift-R</em> Û\8cا Ø¯ Ø³Ø§Ù\85Ù\88Ù\86Ù±)\n* <strong>اÛ\8cÙ\86ترÙ\86ت Ø§Ù\92کسپÙ\84Ù\88رر:</strong> <em>Ctrl</em> Ù\86اÙ\92 Ú¤Ø§Ø¯Ø§Ø±Ø½Øª Ø§Û\8aساÙ\92 Ú©Ø§Ù\92 Ù\85ؽپÛ\8aÙ\86ؽت <em>رÛ\8c Ú©Ù\84Ù\9bÛ\8cÙ\84Ù\9b Ø±Ù\81رش</em>Ø\8cÛ\8cا Ú¤Ø§Ø¯Ø§Ø´ØªÛ\8cتٱ<em>Ctrl-F5</em>\n* <strong>اÙ\88پرا:</strong> Ú¤Û\8cرگٱ Ù\82اÛ\8cÙ\85 Ø¨Û\8cÙ± Ø¯ <em>أڤزارؽاâ\86\92 Ø¢Ù\88Ù\84ٱڤؽٱتؽاÙ\86اÙ\92 Ù¾Ø§Ú©Ø³Ø§ Ø¨Ù±Ú©Ø½ت</em>",
        "usercssyoucanpreview": "<strong>چی ڤأرتیە گئر:</strong>  دوگمە\"{{int:showpreview}}\" سی ئزماشت کاری سی ئس ئس تازە دئما ئمایە کاری ڤئ کار بئیریت.",
        "userjsyoucanpreview": "<strong>چی ڤأرتیە گئر:</strong>  دوگمە\"{{int:showpreview}}\" سی ئزماشت کاری جاڤا ئسکئریپت تازە دئما ئمایە کاری ڤئ کار بئیریت.",
        "usercsspreview": "<strong>د ڤیر داشتوٙئیت کئ شوما فأقأط می توٙنیت سی ئس ئس کاریاری توٙنە پیش سئیل بأکیت. ڤئ ئیسئنی ئمایە نأبییە!</strong>",
        "userinvalidconfigtitle": "<strong>زئنار:</strong> پوٙسە \"$1\" نیئش.\nسی ئس ئس جاڤأنە و بألگە یا جاڤا ئسکئریپت سأربألگ ڤا حأرفیا کوچئک نە ڤئ کار گئرئتە، ھأمچئنی {{ns:کاریار}}:فو/ڤئکتور.سی ئس ئس چی د ری ڤئ ری {{ns:کاریار}}:فو/ڤئکتور. سی ئس ئسە.",
        "updated": "(ڤئ هئنگوم سازی بییە)",
        "note": "'''نیسأنئن:'''",
-       "previewnote": "فأقأط ئی پیش سئیل د ڤیرتوٙ با.\nآلئشت کاریاتوٙ ھأنی ئمایە نأبینە",
-       "continue-editing": "رو د راساگە ڤیرایئشت کاری",
+       "previewnote": "فقٱت اؽ پیش ساٛلٛ ڤ ڤیرتو با.\nآلشت کاریاتو ھنی آمایٱ ناٛیٱ",
+       "continue-editing": "رۉ د راساگٱ ڤیرایش کاری",
        "previewconflict": "ڤئرگأشت پیش سئیل د نیسئسە د راساگە ڤارو ڤیرایئشت کاری چی شئکل دیار بییئن بوٙەأر شوما  ڤئ نە سی ئمایە کئردئن ئنتئخاڤ بأکیت.",
        "session_fail_preview": "<strong>د بأخت گأن سی یە کئ رئسینە یا نئشأسجا نە د دأس دأئیمە نئمی توٙنیم کار پأردازئشت ڤیرایئشت کاری شومانە أنجوم بئمینوٙ.</strong>\nلوطف بأکیت یئ گئل ھأنی تئلاش بأکیت.\nأر ھأنی ڤئ دوروس کار نأکئرد،[[Special:UserLogout|ئوٙمائن ڤئ دأر]] نە ئزمایئشت بأکیت و د نۊ بیائیت ڤامین.",
        "session_fail_preview_html": "<strong>د بأخت گأن سی یە کئ رئسینە یا نئشأسجا نە د دأس دأئیمە نئمی توٙنیم کار پأردازئشت ڤیرایئشت کاری شومانە أنجوم بئمینوٙ.</strong>\n\n\n<em>سی یە کئ {{SITENAME}} یئ گئل رأگ ئچ تی ئم ئل کونئشتکار بییە دارە، پیش سئیل سی یە کئ د دأس چول کاریا جاڤا ئسکئریپت لیز داشتوٙە نئھوٙ بییە..</em>\n\nلوطف بأکیت یئ گئل ھأنی تئلاش بأکیت.\nأر ھأنی ڤئ دوروس کار نأکئرد،[[Special:UserLogout|ئوٙمائن ڤئ دأر]] نە ئزمایئشت بأکیت و د نۊ بیائیت ڤامین.",
        "token_suffix_mismatch": "<strong>ڤیرایئشتیا شوما سی یە کئ دوڤارتە نیأر شوما نیسئسە یا نوقطە نیائن نە د رازینە أمینیأتی ڤیرایئشت د یأک تیچئسە رأد میکە.</strong>\nڤیرایئشت سی یە کئ د خئراڤ بییئن نیسئسە بألگە نئھاگئری با رأد بییە.\nئی روخ ڤأن د گاتیایی پیش میا کئ شوما یئ گئل  رئسینە جا پوروکسی نە ڤئ کار بئیریت.",
        "edit_form_incomplete": "<strong>پارە یی د ڤیرایئشتیا ڤئ رئسینە جا نئمی رئسئن، د نۊ ڤارئسی بأکیت سی یە کئ د خوٙ بییئن ڤیرایئشتیا خوتوٙ ڤارئسیاری بأکیت و د نۊ تئلاش بأکیت.</strong>",
-       "editing": "د حال و بال ڤیرایئشت $1",
-       "creating": "راس Ú©Ø¦Ø±Ø¯Ø¦ن $1",
-       "editingsection": "د حال و بال ڤیرایئشت $1 (بأرجا$1)",
+       "editing": "د هال ۉ بال ڤیرایش $1",
+       "creating": "دÛ\8fرس Ú©Ø±Ø¯ن $1",
+       "editingsection": "د هال ۉ بال ڤیرایش $1 (بٱرجا$1)",
        "editingcomment": "د حال و بال ڤیرایئشت $1 (بأرجا تازە)",
        "editconflict": "ری ڤئ ری کاری د ڤیرایئشت: $1",
        "explainconflict": "د گاتی کئ شوما شوروٙ د ڤیرایئشت کاری د بألگە کئردیتە، یئ کأس ھأنی ئی بألگە نئ آلئشت دئە.\nراساگە ڤارو نیسئسە بألگە، نیسئسە نە چی یە کئ ڤوجوٙد داشتوٙە د ڤأر گئرئتە.\nآلئشتکاریا شوم د نیسئسە ھاری دیاری میکە.\nشوما بایأد آلئشت کاریاتوٙنە د نیسئسە یی کئ ھیش سأریأک بأکیت.\nفأقأط نیسئسە یی کئ ھا د ڤارو د گاتی کئ شوما\"$1\" نە گوزارئشت میکیت ئمایە بوٙە.",
        "semiprotectedpagewarning": "<strong>د ڤیر داشتوٙئیت:</strong> ئی بألگە سی یە کئ فأقأط کاریاریا ثأڤتئنام کئردە تونئسوٙئن دئش ڤیراشتکار بأکأن پأر و پیم بییە.\nآخئری پئھرئستنوٙمە دأئە بییە سی سأرچئشمە ھاری نئھا ئمایە بییە:",
        "cascadeprotectedwarning": "<strong>زئنار:</strong> ئی بألگە ڤئ دأس کاریاریایی کئ صئلا سأردیڤوٙنکاری دارن می توٙنە ڤیرایئشت کاری بوٙە سی یە کئ ئی بألگە ڤئ رأڤئشت تاف نئمایی پأر و پیم کاری بییە {{PLURAL:$1|بألگە|بألگە یا}}:",
        "titleprotectedwarning": "<strong>زئنار:ئی بألگە پأر و پیم بییە سی یە کئ [[Special:نومگە حوقوٙق کاریاری جأرغە|حوقوٙق ڤیجە]] بایأد ڤئنە رأڤأندیاری بأکأن.</strong>\nآخئری پئھرئستنوٙمە دأ بییە سی سأرچئشمە دأئن نئھا ئمایە بییە:",
-       "templatesused": "{{PLURAL:$1|چۊٱ|چۊٱ یا}} ڤ کار گرتٱ بیٱ د اؽ بٱلگٱ:",
-       "templatesusedpreview": "{{PLURAL:$1| چۊٱ|چۊٱ یا}} ڤ کار گرتٱ بیٱ د پیش ساٛلٛ :",
-       "templatesusedsection": "{{PLURAL:$1|چوٙأ|چوٙأ یا}} ڤئ کار گئرئتە بییە د ئی بأرجا:",
-       "template-protected": "(پٱر ۉ پیم بیٱ)",
+       "templatesused": "{{PLURAL:$1|چۊئٱ|چۊئٱ یا}} ڤ کار گرتٱ بیٱ د اؽ بٱلگٱ:",
+       "templatesusedpreview": "{{PLURAL:$1| چۊئٱ|چۊئٱ یا}} ڤ کار گرتٱ بیٱ د پیش ساٛلٛ :",
+       "templatesusedsection": "{{PLURAL:$1|چۊئٱ|چۊئٱ یا}} ڤ کار گرتٱ بیٱ د اؽ بٱلگٱ:",
+       "template-protected": "(پر ۉ پیم بیٱ)",
        "template-semiprotected": "(نسم ۉ نیمٱ پٱر ۉ پیم بیٱ)",
-       "hiddencategories": "اؽ بٱلگٱ یٱکؽ د ٱندومیائٱ {{PLURAL:$1|1 hidden category|$1 hidden categories}} :",
+       "hiddencategories": "اؽ بٱلگٱ یٱکؽ د ٱندومؽا ٱ {{PLURAL:$1|1 hidden category|$1 hidden categories}} :",
        "edittools-upload": "-",
        "nocreatetext": "{{SITENAME}} سی رأڤأندیاری بألگە یا تازە نئھاگئری بییە.\nشوما می توٙنیت روئیت ڤادئما و بألگە ئی کئ بییشە ڤیرایئشت کاری بأکیت،[[Special:ڤامین ئوٙمائن کاریار|بیائیت ڤامین یا یە کئ یئ گئل حئساڤ دوروس بأکیت]].",
        "nocreate-loggedin": "شوما صئلا راس کئردئن بألگە تازە نە ناریت.",
        "sectioneditnotsupported-title": "شوما صئلا ڤیرایئشت کاری بأرجایا نە ناریت.",
        "sectioneditnotsupported-text": "ڤیرایئشت بأرجایی د ئی بألگە نیئش.",
-       "permissionserrors": "خأطا صئلا دأئن",
+       "permissionserrors": "خٱتا سلا داٛئن",
        "permissionserrorstext": "شوما حأق ناریت ڤئنە أنجوم بئیت، سی{{PLURAL:$1|دألیل|دألیلیا}} نئھایی:",
-       "permissionserrorstext-withaction": "Ø´Ù\88Ù\85ا Ø³Û\8c $2 ØµØ¦Ù\84ا \nÙ\86ئھاگئرÛ\8c Ù\86ارÛ\8cت {{PLURAL:$1|دأÙ\84Û\8cÙ\84|دأÙ\84Û\8cÙ\84Û\8cا}}:",
-       "recreate-moveddeleted-warn": "'''د ڤیرئتوٙ با:شوما بألگە یی کئ ھا ڤادئما و پاکسا بییە د نۊ راس کئردیتە.'''\nبایأد د ڤیرئتوٙ با کئ آیا ھأنی نئھاگئری ڤیرایئشت ئی بألگە خوٙأ.\nپاکسا کاری و جا ڤئ جا کاری ئی بألگە سی حال و بال آسایئشت شوما آمادە بییە:",
-       "moveddeleted-notice": "ای بلگٱ پاکسا بیٱ.\nپاکسا کاری و جا ۋ جا کاری ای بلگٱ سی هال و بال آسایشت شوما آمادٱ بیٱ.",
+       "permissionserrorstext-withaction": "Ø´Ù\85ا Ø³Û\8c $2 Ø³Ù\84ا \nÙ\86ھاگرÛ\8c Ù\86ارؽت {{PLURAL:$1|دÙ\84Ù\9bÛ\8cÙ\84Ù\9b|دÙ\84Ù\9bÛ\8cÙ\84Ù\9bؽا}}:",
+       "recreate-moveddeleted-warn": "'''ڤ ڤیرتو با:شما بٱلگاٛیی کاْ ھا ڤادما ۉ پاکسا بیٱ د نۊ دۏرس کردؽتٱ.'''\nبایٱد د ڤیرتو با کاْ آیا ھنی نوئاگیری ڤیرایش اؽ بٱلگٱ خۊئٱ.\nپاکسا کاری ۉ جا ڤ جا کاری اؽ بٱلگٱ سی هال ۉ بال پٱلٛٱمار شما آمادٱ بیٱ:",
+       "moveddeleted-notice": "اؽ بٱلگٱ پاکسا بیٱ.\nپاکسا کاری ۉ جا ڤ جا کاری اؽ بٱلگٱ سی هال ۉ بال پٱلٛٱمار شما آمادٱ بیٱ.",
        "log-fulllog": "دیئن هأمە پئهئرستنوٙمە یا",
        "edit-hook-aborted": "ڤیرایئشت ڤا قولاڤ نئھاگئری بییە.\nھیچ توضیی سیش نی.",
        "edit-gone-missing": "نأبوٙە ئی بألگە نە ڤئ ھئنگوم بأکیت.\nچئنی ڤئ نأظأر میا کئ ڤئ پاکسا بییە.",
        "editwarning-warning": "أر ئی بألگە نئ ڤئل بأکیت ھأر آلئشتی کئ أنجوم دأئیتە پاک بوٙە.\nأر شوما ھائیت ڤامین، شوما می توٙنیت ب زئنار نە د \"{{int:prefs-editing}}\" کئ ھا د بأرجا چیا نازار شوما ناکونئشتگأر بأکیت.",
        "editpage-notsupportedcontentformat-title": "شئکل مینوٙنە حامینداری نأبییە",
        "editpage-notsupportedcontentformat-text": "حال و بال مینوٙنە $1 د مودئل مینوٙنە $2 حامینداری نأبوٙە.",
-       "content-model-wikitext": "Ú¤Û\8cÚ©Û\8c Ù\86Û\8cسئسÛ\95",
+       "content-model-wikitext": "Ú¤Û\8cÚ©Û\8c Ù\86Û\8cسسٱ",
        "content-model-text": "نیسئسە سادە",
        "content-model-javascript": "جاڤا ئسکئریپت",
        "content-model-css": "سی اس اس",
        "unstrip-depth-warning": "د بیشترونه د سرچشمه رئتن د دستور Unstrip واروتر رئتیته($1)",
        "converter-manual-rule-error": "خطا د قانون والرشتن دسی زون",
        "undo-success": "نبوئه ویرایشت نه انجومشیو بکیت.\nلطفا ای فرخی که ها د هار نه وارسی بکیت تا یه کاریه که میهات انجوم بئیت، و اوسه آلشتیا هار نه اماییه بکیت سی یه که خمثی کردن ویرایشت نه انجوم بئیت.",
-       "undo-failure": "سی ری به ری بیئن ای ویرایشت وا ویرایشتیا مینجایی، نبوئه ای ویرایشت نه خومثی بکیت.",
+       "undo-failure": "سی ری ڤ ری بیئن اؽ ڤیرایش ڤا ڤیرایشؽا مؽنجایی، نمۊئٱ اؽ ڤیرایش ناْ خونسا بٱکؽت.",
        "undo-norev": "نبوئه ای ویرایشت نه خومثی بکیت سی یه که یا وجود ناره یا پاکسا بیه.",
        "undo-nochange": "وه نظر میا که ای ویرایشت د ایسنیا خومثی بیه.",
        "undo-summary": "خومثی بیئن وانئری وا $1 [[Special:Contributions/$2|$2]] ([[User talk:$2|چک چنه]])",
        "undo-summary-username-hidden": "خومثی بیئن وانئری $1 وا یه گل کاریار قام بیه",
        "cantcreateaccount-text": "حساو دروس بیه و ا ای تیرنشون آی پی(<strong>$1</strong>) وه دس ای [[کاریار:$3|$3]] قلف بیه.\n\n\nدلیل دئه بیه وا $3 ها د<em>$2</em>",
        "cantcreateaccount-range-text": "حساو دروس بیه وا تیرنشون آی پی که د پوشینه <strong>$1</strong> ، که وه ئم مینونه دار تیرنشون آی پی شما ئم هئ(<strong>$4</strong>)، وه دس [[کاریار:$3|$3]]قلف بیه.\n\nدلیل دئه بیه وا $3، \"$2\" ئه.",
-       "viewpagelogs": "سئÛ\8cÙ\84 Ù¾Ø¦Ø±Ø¦Ø³ØªÙ\86Ù\88Ù\99Ù\85Û\95 Û\8cا Ø¦Û\8c Ø¨Ø£Ù\84Ú¯Û\95 Ø¨Ø£Ú©Û\8cت",
+       "viewpagelogs": "ساÙ\9bÙ\84Ù\9b Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù±Û\8cا Ø§Ø¨ Ø¨Ù±Ù\84Ú¯Ù± Ø¨Ù±Ú©Ø½ت",
        "nohistory": "هیچ ویرگار ویرایشتی د ای بلگه نئ.",
        "currentrev": "آخرین دوواره دیئن",
-       "currentrev-asof": "آخري وانئری چی $1",
+       "currentrev-asof": "آخری ڤانری چی $1",
        "revisionasof": "دوئرٱ دیئن $1",
-       "revision-info": "دوواره سیل بیه چی $1 وا $2",
+       "revision-info": "دوئارٱ ساٛلٛ بیٱ چی $1 ڤا $2",
        "previousrevision": "ڤانیٱری زیتری ←",
-       "nextrevision": "ڤانیٱری تازٱتر",
-       "currentrevisionlink": "آخری ڤانیٱری",
+       "nextrevision": "ڤانؽٱری تازٱتر",
+       "currentrevisionlink": "آخری ڤانؽٱری",
        "cur": "تازٱ باو",
        "next": "نئهایی",
        "last": "دمایی",
        "page_first": "أڤئلی",
        "page_last": "آخئر",
-       "histlegend": "اÙ\86تخاÙ\88 Ù\81رخدار:جعÙ\88Û\8cا Ø±Ø§Ø¯Û\8cÙ\88 Ù\86Ù\87 Ø³Û\8c Ø¯Ù\88Ù\88ارÙ\87 Ø¯Û\8cئÙ\86 Ù\88 Ù\88ارسÛ\8c Ù\86Ø´Ù\88 Ø¯Ø§Ø± Ø¨Ú©Û\8cد Ù\88 Û\8cا Ø±Û\8c Ø±Ø¦ØªÙ\86 Ú©Ù\84Û\8cÚ© Ø¨Ú©Û\8cد .<br />\nشرح Ù\86Ù\88شتÙ\87: '''({{int:cur}})''' = Ù\88ا Ø¢Ø®Ø±Û\8c Ø¯Ù\88Ù\88ارÙ\87 Ø¯Û\8cئÙ\86 Ù\81رخ Ø¯Ø§Ø±Ù\87 '''({{ int:last}})'''= Ù\88ا Ø¯Ù\88ارÙ\87 Ø¯Û\8cئÙ\86 Ø§Ù\86جÙ\88Ù\85 Ø¯Ø¦Ù\86Û\8c Ù\81رخ Ø¯Ø§Ø±Ù\87  '''{{int:minoreditletter}}''' =Ù\88Û\8cراÛ\8cشت Ú©Ø¤چک.",
-       "history-fieldset-title": "ڤیرگار دوڤارٱ نیٱری",
+       "histlegend": "اÙ\92Ù\86تخاب Ù\81ٱرخدار:جٱڤٱÛ\8cا Ø±Ø§Ø¯Û\8cÙ\88 Ù\86اÙ\92 Ø³Û\8c Ø¯Ù\88ئارٱ Ø¯Û\8cئÙ\86 Û\89 Ú¤Ø§Ø±Ø³Û\8c Ù\86Ø´Ù\88Ý© Ø¯Ø§Ø± Ø¨Ù±Ú©Ø½Øª Û\89 Û\8cا Ø±Û\8c Ø±Ù±ØªÙ\86 Ú©Ù\84Ù\9bÛ\8cÚ© Ø¨Ù±Ú©Ø½Øª .<br />\nشرح Ù\86Ù\88شتÙ\87: '''({{int:cur}})''' = Ú¤Ø§ Ø¢Ø®Ø±Û\8c Ø¯Ù\88ئارٱ Ø¯Û\8cئÙ\86 Ù\81ٱرخ Ø¯Ø§Ø±Ù± '''({{ int:last}})'''= Ú¤Ø§ Ø¯Ù\88ئارٱ Ø¯Û\8cئÙ\86 Ù±Ù\86جÙ\88Ù\85 Ø¯Ø§Ù\9bئÙ\86Û\8c Ù\81ٱرخ Ø¯Ø§Ø±Ù±  '''{{int:minoreditletter}}''' =Ú¤Û\8cراÛ\8cØ´ Ú©Ù\88چک.",
+       "history-fieldset-title": "ڤیرگار دوئارٱ نیٱری",
        "history-show-deleted": "فقط پاكسا بيه",
        "histfirst": "قاٛیمی تریݩ",
        "histlast": "ایسنی تریݩ",
        "historysize": "({{PLURAL:$1|1 بایت|$1 بایتیا}})",
        "historyempty": "(حالی)",
-       "history-feed-title": "ڤیرگار دوڤارٱ دیاٛن",
-       "history-feed-description": "دوڤارٱ دیاٛن ڤیرگار سی بلگٱ د ڤیکی",
+       "history-feed-title": "ڤیرگار دوئارٱ دیئن",
+       "history-feed-description": "دوئارٱ دیئن ڤیرگار سی بٱلگٱ د ڤیکی",
        "history-feed-item-nocomment": "$1 د\n$2",
        "history-feed-empty": "بلگه حاسته بیه وجود ناره.\nشایت وه د ویکی پاکسا بیه، یا نومش آلشت بیه.\nسی بلگیا مرتوط تازه [[ویجه:پی جوری|پی جوری د ویکی]] کوششت بکید.",
        "history-edit-tags": "ڤیرایئشت کاری ڤانئیأریا گولئ ڤورچی بییە",
        "mergehistory-same-destination": "سرچشمه و بلگه یا مقصد نبوئه یکی بوئن",
        "mergehistory-reason": "دأليل:",
        "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
-       "mergelog": "سریک سازی پهرستنومه",
+       "mergelog": "سٱریٱک سازی پهرستنومٱ",
        "revertmerge": "بی لوئه",
        "mergelogpagetext": "شما د هار نوم گه آخرین چیا وه یک شیوسن ویرگار یه بلگه نه د بلگه تر میئنیت.",
-       "history-title": "دوڤارٱ دیاٛن ڤیرگار $1",
-       "difference-title": "فرخ مینجا وانیریا \"$1\"",
+       "history-title": "دوئارٱ دیئن ڤیرگار $1",
+       "difference-title": "فٱرخ مؽنجا ڤانیرؽا \"$1\"",
        "difference-title-multipage": "فرخ مینجا بلگه یا \"$1\" و \"$2\"",
        "difference-multipage": "(فرخ مینجا بلگه یا)",
        "lineno": "خٱت $1:",
        "compareselectedversions": "دوئارٱ دی ینؽایؽ کاْ اْنتخاو بینٱ ناْ موقایسٱ بٱکؽت",
        "showhideselectedversions": "شلک دیئن وانیریا انتخاو بیه نه آلشت بکید",
        "editundo": "ناٱنجومگر کردن",
-       "diff-empty": "(بی فرق)",
-       "diff-multi-sameuser": "({{PLURAL:$1|یه گل نسقه مینجایی|$1 نسقه یا مینجایی}} وه دس{{PLURAL:$2|کاریاری تر|$2 کاریاریا}} نشو دئه نبیه)",
-       "diff-multi-otherusers": "({{PLURAL:$1|یه گل نسقه مینجایی|$1 نسقه یا مینجایی}} وه دس{{PLURAL:$2|کاریاری تر|$2 کاریاریا}} نشو دئه نبیه)",
+       "diff-empty": "(بؽ فٱرق)",
+       "diff-multi-sameuser": "({{PLURAL:$1|یاٛ نۏسخٱ مؽنجایی|$1 نۏسخٱیا مؽنجایی}} ڤ دٱس{{PLURAL:$2|کاریارؽ تر|$2 کاریارؽا}} نشوݩ داٛئٱ ناٛیٱ)",
+       "diff-multi-otherusers": "({{PLURAL:$1|یاٛ نۏسخٱ مؽنجایی|$1 نۏسخٱیا مؽنجایی}} ڤ دٱس{{PLURAL:$2|کاریاری تر|$2 کاریارؽا}} نشوݩ داٛئٱ ناٛیٱ)",
        "diff-multi-manyusers": "({{PLURAL:$1|یه گل وانیری مینجاگرته|$1وانیریا مینجا گرته}} بیشتر د $2 {{PLURAL:$2|کاریار|کاریاریا}} نشو دئه نبیه)",
        "difference-missing-revision": "{{PLURAL:$2|یه گل ویرایشت|$2 ویرایشت}} د فرق مینجا($1) {{PLURAL:$2|پیدا نبی|پیدا نبینه}}.\n\nشایت بانی جاونه وه وا یه گل ویرگار وه هنگوم نبیه که د یه گل بلگه پاکسا بیه هوم پیوند بیه بوئه.\nشایت جزئیات د   [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]  پیدا بوئن.",
        "searchresults": "نتيجٱیا پاٛ جۊری",
        "nextn": "نوئایی {{PLURAL:$1|$1}}",
        "prev-page": "بلگه دمايی",
        "next-page": "بلگه نهایی",
-       "prevn-title": "پيشتر $1 {{PLURAL:$1|نتيجه|نتيجيا}}",
+       "prevn-title": "زیتر $1 {{PLURAL:$1|نٱتیجٱ|نٱتيجٱيا}}",
        "nextn-title": "دمایی $1 {{PLURAL:$1|نتيجٱ|نتيجيا}}",
-       "shown-title": "نشوݩ داٛین $1 {{PLURAL:$1|نتیجٱ|نتیجٱیا}} سی هار بٱلگٱ",
+       "shown-title": "نشوݩ داٛین $1 {{PLURAL:$1|نتیجٱ|نتیجٱیا}} سی هٱر بٱلگٱ",
        "viewprevnext": "ديین ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-exists": "'''ایچه بلگه ای هئ وه نوم\"[[:$1]]\" که ها د ای ویکی'''",
+       "searchmenu-exists": "'''ایچاْ بٱلگاٛیؽ هؽ ڤ نوم\"[[:$1]]\" کاْ ها د اؽ ڤیکی'''",
        "searchmenu-new": "'''اؽ بٱلگٱ ناْ دۏرس كو \"[[:$1]]\" د اؽ ڤیکی!'''",
        "searchprofile-articles": "بٱلگٱيا مؽنونٱ دار",
-       "searchprofile-images": "ڤارسگرؽا خلکمن",
+       "searchprofile-images": "ڤارسگرؽا Ø®Ù\84Ú©Ù\85Ù±Ù\86",
        "searchprofile-everything": "همٱ چی",
        "searchprofile-advanced": "پیشکردٱ",
        "searchprofile-articles-tooltip": "بٱگٱرد مؽن $1",
-       "searchprofile-images-tooltip": "جانؽایاناْ پاٛ جۊری کو",
-       "searchprofile-everything-tooltip": "همٱ مؽنونٱیا ناْ پۊ جۊری كو (شاملاْ بٱلگٱيا چٱک چنٱ)",
+       "searchprofile-images-tooltip": "جانؽایا ناْ پاٛ جۊری کو",
+       "searchprofile-everything-tooltip": "همٱ مؽنونٱیا ناْ پاٛ جۊری كو (شامل بٱلگٱيا چٱک چنٱ)",
        "searchprofile-advanced-tooltip": "نوم جايا نوم دؽار بٱگٱرد",
        "search-result-size": "$1 ({{PLURAL:$2|1 کلٱمٱ|$2 کلٱمٱیا}})",
-       "search-result-category-size": "{{PLURAL:$1|1 ٱندوم|$1 ٱندومؽا}} ({{PLURAL:$2|1 زؽردٱسٱ|$2 زؽردٱسٱیا}}، {{PLURAL:$3|1 جانیا|$3 جانیایا}}",
+       "search-result-category-size": "{{PLURAL:$1|1 ٱندوم|$1 ٱندومؽا}} ({{PLURAL:$2|1 زؽردٱسٱ|$2 زؽردٱسٱیا}}، {{PLURAL:$3|1 جانؽا|$3 جانؽایا}}",
        "search-redirect": "(ڤرگٱشتن سی $1)",
        "search-section": "(بٱئرجا $1)",
        "search-category": "(دسه $1)",
-       "search-file-match": "(یکی کردن مینونه جانیا)",
-       "search-suggest": "Ù\85Ù\86ظÙ\88رت Ù\8aÙ\87 بی:$1",
+       "search-file-match": "(یٱکؽ کردن مؽنونٱ جانؽا)",
+       "search-suggest": "Ù\85Ù±Ù\86زÛ\8aرت Ù\8aÙ± بی:$1",
        "search-rewritten": "نئشوٙ دأئن نأتیجە یا سی $1. سی نئموٙنە بأگأردیت سی $2.",
        "search-interwiki-caption": "پروجه یا خوئر",
        "search-interwiki-default": "$1 نتیجه یا:",
        "group": "جأرغە",
        "group-user": "کاریاریا",
        "group-autoconfirmed": "کاریاریا خود پوشت راس بییە",
-       "group-bot": "بوتیا",
-       "group-sysop": "سأردیڤوٙنکاریا",
+       "group-bot": "بوتؽا",
+       "group-sysop": "سٱردیڤونکارؽا",
        "group-bureaucrat": "بوروکراتیا",
        "group-suppress": "تیە پایا",
        "group-all": "(هأمە)",
        "group-suppress-member": "{{GENDER:$1|تیە پا}}",
        "grouppage-user": "{{ns:project}}:کاریاریا",
        "grouppage-autoconfirmed": "{{ns:project}}:کاریار خودأنجومکار",
-       "grouppage-bot": "{{ns:project}}:بÙ\88ت Û\8cا",
-       "grouppage-sysop": "{{ns:project}}:دÛ\8cÚ¤Ù\88Ù\99Ù\86دارÛ\8cا",
+       "grouppage-bot": "{{ns:project}}:رباتâ\80\8cÙ\87ا",
+       "grouppage-sysop": "{{ns:project}}:دÛ\8cÚ¤Ù\88Ù\86دارؽا",
        "grouppage-bureaucrat": "{{ns:project}}:دیڤوٙنداریا",
        "grouppage-suppress": "{{ns:project}}:تیە پا",
        "right-read": "حأنئن بألگە یا",
        "right-changetags": "Add and remove arbitrary [[Special:Tags|tags]] on individual revisions and log entries",
        "newuserlogpage": "دۏرس بیٱ ڤا کاریار",
        "newuserlogpagetext": "یه پهرستنومه راس بیئن کاریاره",
-       "rightslog": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87 Ø­Ù\82Ù\88ق کاریار",
+       "rightslog": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù± Ù\87Ù\88Ù\82Û\8aق کاریار",
        "rightslogtext": "یه پهرستنومه آلشتیا حقوق کاریاره.",
        "action-read": "ای بلگه نه بحو",
-       "action-edit": "ای بلگه نه ويرايشت بكيد",
+       "action-edit": "اؽ بٱلگٱ ناْ ڤيرايش بٱكیت",
        "action-createpage": "راس کردن بلگیا",
        "action-createtalk": "بلگه یا چک چنه نه راس بکید",
-       "action-createaccount": "حساو ای کاریار نه راس بکید",
+       "action-createaccount": "هساو اؽ کاریار ناْ دۏرس بٱکؽت",
        "action-history": "ویرگار ای بلگه نه بوینیت",
        "action-minoredit": "ای ویرایشت نه چی یه حیرده ویرایشت نشو بیئت",
        "action-move": "لی بلگه جا وه جا کو",
        "enhancedrc-history": "ڤیرگار",
        "recentchanges": "آلشتؽا ایسنی",
        "recentchanges-legend": "گوزینٱیا آلشتؽا ایسنی",
-       "recentchanges-summary": "دۏ بؽشتر آلشتؽا تازباو ناْ د ڤیکی ناْ د اؽ بٱلگٱ پاٛجۊری کو.",
-       "recentchanges-noresult": "Ù\87Û\8cÚ\98 Ø¢Ù\84شتÛ\8c Ø¯ Ø¯Ø±Ø§Ø²Ø§ Ø¯Ù\88رÙ\87 Ø¯Û\8cار Ø¨Û\8cÙ\87 Ù\88ا Ø§Û\8c Ù\85عÛ\8cارÛ\8cا Û\8cÚ©Û\8c Ù\86بی.",
-       "recentchanges-feed-description": "دو بیشتر آلشتیا تازباو نه د ویکی که ها د هوال حون پیگری کو.",
+       "recentchanges-summary": "دۏ بؽشتر آلشتؽا تازباو ناْ د ڤیکی د اؽ بٱلگٱ پاٛجۊری کو.",
+       "recentchanges-noresult": "Ù\87Û\8cÚ\86 Ø¢Ù\84شتؽ Ø¯ Ø¯Ø±Ø§Ø²Ø§ Ø¯Û\89رٱ Ø¯Ø½Ø§Ø± Ø¨Û\8cÙ± Ú¤Ø§ Ø§Ø½ Ù\85اÙ\9bعÛ\8cاؽا Û\8cÙ±Ú©Û\8c Ù\86اÙ\9bی.",
+       "recentchanges-feed-description": "دۏ بؽشتر آلشتؽا تازباو ناْ د ڤیکی کا ها د هڤال هون پاٛگیری کو.",
        "recentchanges-label-newpage": "اؽ ڤیرایش یاٛ بٱلگٱ تازٱ دۏرس کردٱ.",
        "recentchanges-label-minor": "یٱ یاٛ ڤیرایش کوچکٱ",
        "recentchanges-label-bot": "اؽ ڤيرايش ناْ ياٛ بوت ٱنجوم داٛیٱ",
        "recentchanges-legend-heading": "<strong>میرات:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همچنو باٛینؽت [[ڤیژٱ:بٱلگٱیا تازٱ|نوم گٱ بٱلگٱیا تازٱ]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
-       "rcnotefrom": "د هار آلشتیا د $2 هیئن(د بال د $1 نشون دئه بیه)",
+       "rcnotefrom": "د هار آلشتؽا د $2 هؽسن(د بال د $1 نشوݩ داٛئٱ بیٱ)",
        "rclistfrom": "آلشتؽا تازاٛیؽ کاْ ڤا $3 $2 شرۊ بیٱ نشونش باٛیٱ",
        "rcshowhideminor": "ڤیرایشؽا فرٱ کوچک $1",
-       "rcshowhideminor-show": "نشو دئن",
+       "rcshowhideminor-show": "نشوݩ داٛئن",
        "rcshowhideminor-hide": "قایم کردن",
        "rcshowhidebots": "$1 روباتؽا یا بوتؽا",
        "rcshowhidebots-show": "نشوݩ داٛین",
-       "rcshowhidebots-hide": "قام کردن",
+       "rcshowhidebots-hide": "قایم کردن",
        "rcshowhideliu": "$1 کاریاریا سٱبت نوم کردٱ",
-       "rcshowhideliu-show": "نشۊ دٱئن",
+       "rcshowhideliu-show": "نشوݩ داٛئن",
        "rcshowhideliu-hide": "قایم کردن",
        "rcshowhideanons": "کاریار نادؽار $1",
-       "rcshowhideanons-show": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£ئن",
+       "rcshowhideanons-show": "Ù\86Ø´Ù\88Ý© Ø¯Ø§Ù\9bئن",
        "rcshowhideanons-hide": "قایم کردن",
-       "rcshowhidepatr": "$1 ویرایشتیا تیه پرس بیه",
+       "rcshowhidepatr": "$1 ڤیرایشیا تیٱ پرس بیٱ",
        "rcshowhidepatr-show": "نئشوٙ دأئن",
        "rcshowhidepatr-hide": "قام کئردئن",
        "rcshowhidemine": "ڤیرایشؽا ماْ $1",
-       "rcshowhidemine-show": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£ئن",
+       "rcshowhidemine-show": "Ù\86Ø´Ù\88Ý© Ø¯Ø§Ù\9bئن",
        "rcshowhidemine-hide": "قایم کردن",
        "rcshowhidecategorization": "جأرغە کاری بألگە $1",
        "rcshowhidecategorization-show": "نئشوٙ دأئن",
        "rc-enhanced-hide": "جزياته قام كو",
        "rc-old-title": "ذاتا چی \"$1\" راس بیه",
        "recentchangeslinked": "آلشتؽا تاٛ یٱکؽ",
-       "recentchangeslinked-feed": "آلشتیا تی یکی",
+       "recentchangeslinked-feed": "آلشتؽا تاٛ یٱک",
        "recentchangeslinked-toolbox": "آلشتؽا تاٛ یٱک",
        "recentchangeslinked-title": "آلشتؽا تاٛ یٱکؽ د $1",
        "recentchangeslinked-summary": "اؽ نوم بٱلگٱ تازٱ د بٱلگٱیایی کاْ ڤا بٱلگٱیا ڤیژٱ هوم پاٛڤٱن بینٱ آلشت بیٱ(یا سی ٱندومؽا دٱسٱ بٱنی بیٱ)\nبٱلگٱیایی کاْ هان د [[Special:Watchlist|your watchlist]]ۉ گٱپ بینٱ",
        "uploadbtn": "سوڤار کئردئن جانیا",
        "reuploaddesc": "سوار کردن نه انجوم شیو بکیت و د ورئردیت جابلگ سوارکرد",
        "upload-tryagain": "کل کردن توضیحیا آلشت دئیه بیه جانیا",
-       "uploadnologin": "Ù\88ارد Ù\86بÛ\8cÙ\87",
+       "uploadnologin": "Ù\87Ù\86Û\8c Ù\86Û\8fÙ\85اÛ\8cتٱ Ú¤Ø§Ù\85Û\8cÙ\9bÙ\86",
        "uploadnologintext": "لطفن $1 سی سوارکرد جانیایا.",
        "upload_directory_missing": "نشونگه سوارکرد ($1) وجود ناره و نبوئه دروسش بکی.",
        "upload_directory_read_only": "نشونگه سوارکرد($1) د لا سرور قاول نیسنن نئ.",
        "upload-permitted": "جوٙرا صئلادار جانیا {{PLURAL:$2|جوٙر|جوٙرا}}:$1 .",
        "upload-preferred": "جوٙرا حاستئنی جانیا {{PLURAL:$2|جوٙر|جوٙرا}}:$1 .",
        "upload-prohibited": "جورا جانیا صلادار:$1{{PLURAL:$2|.}}",
-       "uploadlogpage": "سوارکرد",
+       "uploadlogpage": "سڤارکرد",
        "uploadlogpagetext": "نومگه هاری یه گل نومگه د آخری سوارکرد جانیایا هئ.\nسی د نو سیل کردن[[Special:NewFiles|عسگدونی جانیایا تازه نه]] به ونیت.",
        "filename": "نوم جانیا",
        "filedesc": "چکسٱ",
        "upload-curl-error28": "تموم بیئن مئلت سی سوار کرد",
        "upload-curl-error28-text": "ای دیارگه فره دیر دتو واکنشت نشو دئه.\nلطف بکیت سی یه که دیارگه کنشگتر و ری خطه یه گل وارسی بکیت، اوسه یه گر واستید و هنی تلاش بکیت.\nشایت بیتر با که د گات خلوتری هنی تلاش بکیت.",
        "license": "ليانس دار بيئن",
-       "license-header": "د هال ۉ بال للیسانس دار بیین",
+       "license-header": "د هال ۉ بال لیسانس دار بیئن",
        "nolicense": "هیچی انتخاو نبیه",
        "licenses-edit": "گزینه یا مجوز ویرایشت",
        "license-nopreview": "(پیش سیل د دسرس نئ)",
        "listfiles-summary": "ای بلگه یا ویجه همه جانیایا سوار بیه نه نشو می ئین.",
        "listfiles_search_for": "پی جوری سی نوم رسانه:",
        "listfiles-userdoesnotexist": "حساو کاریاری «$1» ثوت نام نبیه.",
-       "imgfile": "جانیا",
-       "listfiles": "نومگە جانیا",
+       "imgfile": "جانؽا",
+       "listfiles": "نومگٱ جانؽا",
        "listfiles_thumb": "بأن کئلئکی",
        "listfiles_date": "گات",
        "listfiles_name": "نوم",
        "filehist-help": "ری  ڤيرگارؽا بٱپۊرنؽت تا نۏسخٱ مٱربۊتاْ باٛینؽت.",
        "filehist-deleteall": "هأمە نئ پاکسا کو",
        "filehist-deleteone": "پاکسا کئردئن",
-       "filehist-revert": "لئرنیئن",
+       "filehist-revert": "لٛرنیئن",
        "filehist-current": "تازٱ با",
        "filehist-datetime": "ڤيرگار/ڤٱخت",
-       "filehist-thumb": "عٱسک کوچک بیٱ",
+       "filehist-thumb": "عٱسگ کوچک بیٱ",
        "filehist-thumbtext": "كوچک کردن سی نۏسخٱ چی $1",
-       "filehist-nothumb": "هیچ بن کلیکی نئ",
+       "filehist-nothumb": "بؽ بٱن کلٛکی",
        "filehist-user": "کاریار",
        "filehist-dimensions": "اۊیٱکؽا",
        "filehist-filesize": "انازه فایل",
        "linkstoimage-more": "بؽشتر د $1 بٱلگٱ د اؽ جانؽا هوم پاٛڤٱن {{PLURAL:$1|بٱ|بینٱ}}.\nنومگٱ هاری تٱنڳؽا{{PLURAL:$1|ٱڤلی هوم پاٛڤٱن|ٱڤلی $1 هوم پاٛڤٱن}} د ؽ بٱلگٱ ناْ نشوݩ مؽ یٱ.\n[[Special:WhatLinksHere/$2|نومگٱ کامل]] ٱم هؽسش.",
        "nolinkstoimage": "ایچاْ هیچ بٱلگاٛیی سی هوم پیاٛڤٱن بیین ڤا اؽ جانؽا نؽ",
        "morelinkstoimage": " [[ویجه:چه هوم پیوندی ها ایچه/$1|هوم پیوندیا هنی]]سی ای جانیا نه بونیت.",
-       "linkstoimage-redirect": "$1 (واگردونی جانیا) $2",
+       "linkstoimage-redirect": "$1 (ڤاگٱردونی جانؽا) $2",
        "duplicatesoffile": "{{PLURAL:$1|جانیا|جانیایا}} هاری نسقه تکراری ای جانیا {{PLURAL:$1|هئ|هئن}} ([[Special:FileDuplicateSearch/$2|دونسمنیا هنی]]):",
        "sharedupload": "ای جانیا که د $1 هئ شایت د پروجه یا هنی استفاده بیه.",
        "sharedupload-desc-there": "ای جانیا ها د $1و شایت د پروجه یا هنی وه کار گرته بوئه.\nسی دونسمنیا هنی لطفن [$2 بلگه توضیحیا جانیا] نه سیل بکیت.",
        "sharedupload-desc-here": "فایلٛؽ کاْ د $1 شایٱد د مؽن پرۉژٱیا هنی اْستفادٱ بیٱ.\nتۉزیی دبارٱ[$2 file description page] د هار نشوݩ داٛئٱ بیٱ",
        "sharedupload-desc-edit": "ای جانیا د $1 ئه و می تونه د پروجه یا هنی وه کار گرت بوئه.\nار حاستیت می تونیت توضیحیا حانیا نه د [$2 بلگه توضیحیا خوش] د اوچه ویرایشت بکیت.",
        "sharedupload-desc-create": "ای جانیا د $1 ئه و می تونه د پروجه یا هنی وه کار گرت بوئه.\nار حاستیت می تونیت توضیحیا حانیا نه د [$2 بلگه توضیحیا خوش] د اوچه ویرایشت بکیت.",
-       "filepage-nofile": "چنو فایلی وا ای نوم نئ.",
+       "filepage-nofile": "چنو فایلٛی ڤا اؽ نوم نؽ.",
        "filepage-nofile-link": "جانیایی د ای نوم نیئش، اما شما تونیت ونه د [$1 سوار بکیت].",
        "uploadnewversion-linktext": "یه گل نسقه تازه د ای جانیا سوار بکید",
        "shared-repo-from": "د $1",
        "randomincategory-submit": "رو",
        "randomredirect": "واگردونی بختکی",
        "randomredirect-nopages": "هیچ واگردونی د نومجا \"$1\" نئ.",
-       "statistics": "آماريا",
+       "statistics": "آمارؽا",
        "statistics-header-pages": "بلگه آماریا",
        "statistics-header-edits": "آماریا نه ویرایشت بکید",
        "statistics-header-users": "آماریا کاریار",
        "doubleredirectstext": "ای بلگه نومگه ای د بلگه واگردونی نه نشو می یه که وه یه گل بلگه واگردونی هنی هشاره می کن.\nهر خط مینونه دار هوم پیوندیا واگردونی اول و دویم و همچنو مقصد واگردونی دویمه، که معمولند بلگه مقصد راستکی یه و اولین واگردونی واس د وه هشاره بکه.\nچیا <del>خط حرده</del> دروس بینه.",
        "double-redirect-fixed-move": "[[$1]]جا وه جا بیه .\nوه خودکارونه وه روز بیه و ایسه وه د[[$2]] واگردونی بیه.",
        "double-redirect-fixed-maintenance": "برطرف بیین خودانجوم دوتای د [[$1]] وه [[$2]] د مسیر واداشت.",
-       "double-redirect-fixer": "تعمیر کننه واگردونی",
+       "double-redirect-fixer": "تٱمیر کننٱ ڤاگٱردونی",
        "brokenredirects": "واگردونیا بی سرانجوم",
        "brokenredirectstext": "واگردونیا نهاتر د بلگه یایی که وجود نارن هوم پیوند بینه.",
        "brokenredirects-edit": "ڤیرایئشت",
        "ncategories": "$1{{PLURAL:$1|دسه|دسه يا}}",
        "ninterwikis": "$1 {{PLURAL:$1|مئن ویکی|مئن ویکیا}}",
        "nlinks": "$1 {{PLURAL:$1|هوم پیوند|هوم پیوندیا}}",
-       "nmembers": "$1 {{PLURAL:$1|اندوم|اندوميا}}",
+       "nmembers": "$1 {{PLURAL:$1|ٱندوم|ٱندومؽا}}",
        "nmemberschanged": "$1 → $2 {{PLURAL:$2|اندوم|اندومیا}}",
        "nrevisions": "$1 {{جمس:$1|وانئری|وانئریا}}",
        "nimagelinks": "$1 {{PLURAL:$1|بلگه|بلگيا}} استفاده بیه",
        "mostimages": "فایلیایی که بیشتر هوم پیوند بینه",
        "mostinterwikis": "بلگه یایی که بیشتری مینجا ویکی نه دارن",
        "mostrevisions": "بلگه یایی که بیشتری وانئری نه دارن",
-       "prefixindex": "Ù\87Ù\85Ù\87 Ø¨Ù\84Ú¯Ù\8aا Ù\88ا Ù¾Ù\8aØ´Ù\88ن",
+       "prefixindex": "Ù\87Ù\85Ù± Ø¨Ù±Ù\84Ú¯Ù±Û\8cا Ú¤Ø§ Ù¾Ù\8aØ´Ú¤Ù±ن",
        "prefixindex-namespace": "تموم بلگه یا وا دماون(نومجا $1)",
        "prefixindex-strip": "پاکسا کردن دماون د نومگه",
        "shortpages": "بلگه یا کؤچک",
        "protectedtitles": "سرونیا پر و پیم بیه",
        "protectedtitles-summary": "د ای بلگه نومگه بلگه یایی هیئن که د ایسنی پر و پیم بینه. سی نومگه سرونیا که نبوئه دروس بان، سیل[[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]]  بکیت.",
        "protectedtitlesempty": "د ایسنی هیچ سرونی وا ای پارامتریا پر و پیم نبیه",
-       "listusers": "نومگە کاریار",
+       "listusers": "نومگٱ کاریار",
        "listusers-editsonly": "فأقأط کاریاریایی کئ ڤیرایئشت کاری می کأن دیار بان",
        "listusers-creationsort": "سرجاخودگری د اساس گات دروس بیین",
        "listusers-desc": "سرجاخودگری د اساس گپ د کؤچک",
        "newpages": "بٱلگٱیا نۊ",
        "newpages-username": "نوم کاریاری:",
        "ancientpages": "بلگه یا نهاتر",
-       "move": "جاوه جا بوئيت",
+       "move": "جا ڤ جا بۊئؽت",
        "movethispage": "ای بگله نه جا وه جا كو",
        "unusedimagestext": "جانیایا هاری هئشو اما د هیچ بلگه ای وه کار گرته نبینه.\nلطفن د ویرتو با که دیارگه یا هنی شایت وا یه گل تیرنشون اینترنتی مستقیم وه یه گل جانیا هوم پیوند بان و وا یه که د وه کار گرتن کنشتگر هیئن د ایچه نومگه بان.",
        "unusedcategoriestext": "ای دسه یا هیئشو ولی د ایسنی هیچ گوتار یا دسه ای ونونه وه کار نمی بنه.",
        "notargettext": "شما بلگه یا کاریاری مقصدی سی انجوم دئن ای کنشت ریش انتخاو نکردیته.",
        "nopagetitle": "چنی بلگه ای نیئش",
        "nopagetext": "بلگه حاستنی که شما دیاری کردیته وجود ناره.",
-       "pager-newer-n": "{{PLURAL:$1|وانها تر 1وانها تر $1}}",
-       "pager-older-n": "{{PLURAL:$1|گپساÙ\84تر 1|Ú¯پسالتر $1}}",
+       "pager-newer-n": "{{PLURAL:$1|ڤانوئاتر 1ڤانوئاتر $1}}",
+       "pager-older-n": "{{PLURAL:$1|گٱپساÙ\84تر 1|Ú¯Ù±پسالتر $1}}",
        "suppress": "پائیئن",
        "querypage-disabled": "ای بلگه ویجه سی دلیلیا انجومکاری ناکشتگر بیه.",
        "apihelp": "هومیاری آی پی آی",
        "apihelp-no-such-module": "ماجول \"$1\" پیدا نبی.",
        "booksources": "سرچشمٱیا کتاو",
-       "booksources-search-legend": "پاٛ جۊری سی سٱرچشمٱیا کتاو",
+       "booksources-search-legend": "پاٛ جۊری سی سرچشمٱیا کتاو",
        "booksources-isbn": "آی اس بی ان:",
        "booksources-search": "پاٛ جۊری",
        "booksources-text": "د هار نومگه ای د هوم پیوندیا د دیارگه یا هنی اومائه که کتاویا نو و دس دوئم می فروشن، و همچنو شایت دونسمنیا بیشتری راجع وه کتاو حاستنی شما داشتوئن:",
        "booksources-invalid-isbn": "شازک که دئه بیه معتور نئ؛ وارسی خطایا د گات ؤرداشتن د سرچشمه اولی وه کار گرته بوئه.",
-       "specialloguserlabel": "انجومکار:",
-       "speciallogtitlelabel": "حاستئنی(داسوٙن یا نوم کاریاری سی کاریار):",
+       "specialloguserlabel": "ٱنجومکار:",
+       "speciallogtitlelabel": "هاستنی(داسون یا نوم کاریاری سی کاریار):",
        "log": "پهرستنومٱیا",
-       "all-logs-page": "Ù\87Ù\85Ù\87 Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87 Û\8cا Ø¹Ù\85Ù\88می",
-       "alllogstext": "نماشت یه جا همه پهرستنومه یا که هان د{{SITENAME}}.\nمی تونید وا انتخاو نوع پهرستنومه، نوم کاریاری(حساس وه کؤچکی و گپی حرفیا) و بلگه یا آلشت کرده(حساس و گپی و کؤچکی حرنیا) نمایشت نه دیر د ویرتر بکیت.\n\n{{SITENAME}}.",
-       "logempty": "او چی ای که شما میهایت د پهرستنومه نیئش.",
+       "all-logs-page": "Ù\87Ù\85Ù± Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù±Û\8cا Ø¹Ù\88Ù\85Û\8aمی",
+       "alllogstext": "نمایش یٱ جا همٱ پهرستنومٱیا کاْ هان د{{SITENAME}}.\nمؽ تونؽت ڤا اْنتخاو نۉع پهرستنومٱ، نوم کاریاری(هٱساس ڤ کوچکی ۉ گٱپی هرفؽا) ۉ بٱلگٱیا آلشت کردٱ(هٱساس ۉ گٱپی ۉ کوچکی هرنیا) نمایش ناْ دیر د ڤیرتر بٱکؽت.\n\n{{SITENAME}}.",
+       "logempty": "او چی کاْ شما مؽهایت د پهرستنومٱ نؽسش.",
        "log-title-wildcard": "بلگه یایی نه پی جوری کو که وا ای سرون شرو موئن",
        "showhideselectedlogentries": "آلشت دئن ورتیه گر پهرستنومه یا انتخاو بیه",
        "log-edit-tags": "ویرایشت سردیسیایی که پهرستنومه شو گل گر بیه",
-       "allpages": "Ù\87Ù\85Ù\87 Ø¨Ù\84Ú¯يا",
+       "allpages": "Ù\87Ù\85Ù± Ø¨Ù±Ù\84Ú¯Ù±يا",
        "nextpage": "بلگه نهایی($1)",
        "prevpage": "بلگه دمایی($1)",
        "allpagesfrom": "بلگه یای که د شرو بینه نشو بیه:",
        "allpagesprefix": "بلگه یایی که پس نوم دارن نشو بیه:",
        "allpagesbadtitle": "عنوان بلگه حاسته بیه معتور نی،یا  یه گل مئن زونی یا مئن ویکی عنوان غلطه.\nیه شایت شومل یکی با یا بیشتر کاراکتریا نبوئه که سی ای موضوعیا استفاده بوئن",
        "allpages-bad-ns": "{{نوم دیارگه}} د ای نوم جا نئ \"$1\".",
-       "allpages-hide-redirects": "واگردونیا قام بیه",
+       "allpages-hide-redirects": "ڤاگٱردونیا قایم بیٱ",
        "cachedspecial-viewing-cached-ttl": "شما د حال و بار دیئن یه گل نسقه ای د ای بلگه که ها د مینجاگیر هیئت که شایت سی $1 دماتر با.",
        "cachedspecial-viewing-cached-ts": "شما داریت یه گل نسقه د ای بلگه نه که ها د مینجاگر سیل می کیت، و ای نسقه شایت کاملند راستکی نبا.",
        "cachedspecial-refresh-now": "دیئن آخری.",
        "listgrouprights-group": "دسه",
        "listgrouprights-rights": "حقوقیا",
        "listgrouprights-helppage": "هومیاری:حقوق گرو",
-       "listgrouprights-members": "(نوم گه اندومیا)",
+       "listgrouprights-members": "(نومگٱ ٱندومؽا)",
        "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code dir=\"ltr\">($2)</code></span>",
        "listgrouprights-right-revoked": "<span class=\"listgrouprights-revoked\">$1 <code>($2)</code></span>",
        "listgrouprights-addgroup": "{{PLURAL:$2|جأرغە|جأرغە یا}} نە ئضاف بأکیت: $1",
        "trackingcategories-disabled": "دسه ناکشتگر بیه",
        "mailnologin": "هیپچ نشونی یی کل نبیه",
        "mailnologintext": "سی کل کردن انجومانامه وه کاریاریا هنی واس [[Special:UserLogin|بیایت وامین سامونه]] و تیرنشون انجومانامه معتوری د [[Special:Preferences|ترجیحات]] خوتو داشتوئیت.",
-       "emailuser": "ئÛ\8c Ú©Ø§Ø±Û\8cار Ù\86Û\95 Ø£Ù\86جÙ\88Ù\85اÙ\86اÙ\85Û\95 کاری کو",
+       "emailuser": "اؽ Ú©Ø§Ø±Û\8cار Ù\86اÙ\92 Ù±Ù\86جÙ\88Ù\85Ù\86اÙ\85Ù± کاری کو",
        "emailuser-title-target": "أنجومانامە سی ئی {{GENDER:$1|کاریار}}",
        "emailuser-title-notarget": "أنجومانامە کاریار",
        "emailpagetext": "شما می تونیت  نوم بلگه هار نه سی کل کردن یه گل انجومانامه وه ای  {{GENDER:$1|کاریار}} وه کار بئیرت.\nتیرنشون انجومانامه یی که د [[Special:Preferences|ترجیحات کاریارتو]] دئیه ته د تیرنشون کلکار انجومانامه میا، سی یه که گیرنه بتونه جواوش بیه.",
        "emailsenttext": "پیغوم ایمیلی تو کل بیه.",
        "emailuserfooter": "ئی أنجومانامە ڤا ڤئ کار گئرئتنئ د خوصوٙصیأت \"کئل کئردئن نومە د ئی کاریار\"{{SITENAME}} ڤئ دأس $1 د $2 کئل بی.",
        "usermessage-summary": "رئتن د سامونه پیغوم",
-       "usermessage-editor": "پیغوم فرسن سیستم",
+       "usermessage-editor": "پاٛغوم کلٛ کردن سیستم",
        "usermessage-template": "ویکی وارسگر:پیغوم کاریار",
-       "watchlist": "سئÛ\8cÙ\84 Ø¨رگ",
+       "watchlist": "ساÙ\9bÙ\84Ù\9b Ø¨Ù±رگ",
        "mywatchlist": "ساٛلٛ بٱرگ",
-       "watchlistfor2": "سي $1 $2",
+       "watchlistfor2": "سی $1 $2",
        "nowatchlist": "شما هیچی د سیل برگ خوتو ناریت",
        "watchlistanontext": "لطفن بیایت وامین و ویرایشتیا نه د سیل برگتو سیل بکیت.",
-       "watchnologin": "ھأنی نیوٙماە ڤامین",
+       "watchnologin": "هنی نۏمایتٱ ڤامیٛن",
        "addwatch": "ئضاف کئردئن د سئیل بأرگ",
        "addedwatchtext": "بألگە «[[:$1]]» د [[Special:Watchlist|سئیل بأرگ]] شوما ئضاف بی.\nآلئشتیا ئی بألگە د بألگە چأک چئنە ری ڤئ ریشت د نئھاتئر د ئیچئ نومگە کاری با.",
        "addedwatchtext-short": "بلگه \"$1\" وه سیل برگ شما اضاف بیه.",
        "removewatch": "جا ڤئ جا کئردئن د سئیل بأرگ",
        "removedwatchtext": "بألگە \"[[:$1]]\" د [[Special:سئیل بأرگ|سئیل بأرگ خوتوٙ]] جا ڤئ جا بییە.",
        "removedwatchtext-short": "بلگه \"$1\" د سیل برگ جا وه جا بیه.",
-       "watch": "سئÛ\8cÙ\84 Ú©Ø¦Ø±Ø¯Ø¦ن",
+       "watch": "ساÙ\9bÙ\84Ù\9b Ú©Ø±Ø¯ن",
        "watchthispage": "دیئن ئی بألگە",
-       "unwatch": "دیە نأبییە",
+       "unwatch": "دیئٱ ناٛییٱ",
        "unwatchthispage": "نئھاگئری دیئن",
        "notanarticle": "ھیچ بألگە مینوٙنە داری نی",
        "notvisiblerev": "آخری وانئری که د دس یه کاریار هنی انجوم بیه پاکسا بیه.",
-       "watchlist-details": "{{PLURAL:$1|$1 بلگٱ|$1 بلگٱیا}} د ساٛیل برگتۊ هیچ بلگٱ قساٛ کردنی نی.",
+       "watchlist-details": "{{PLURAL:$1|$1 بلگٱ|$1 بلگٱیا}} د ساٛلٛ بٱرگتو هیچ بٱلگٱ قسٱ کردنی نؽ.",
        "wlheader-enotif": "ڤارئسیاری أنجومانامە کونئشتکار بییە.",
-       "wlheader-showupdated": "بÙ\84Ú¯Ù± Û\8cاÛ\8cÛ\8c Ú©Ø§Ù\9b Ø¯ Ø¢Ø®Ø±Û\8cÙ\86 Ø¨Ø§Ø±Û\8c Ú©Ø§Ù\9b Ú©Ù\87 Ø´Ù\85ا Ø³Ø§Ù\9bÛ\8cÙ\84Ø´Û\8a Ú©Ø±Ø¯Û\8cتٱ Ø¯ <strong>تÛ\8aÙ¾Ù\88ر</strong>Ù\86Ø´Û\8aÙ\86 Ø¯Ø¦Ù± Ø¨Û\8aاÙ\9bن",
-       "wlnote": "د هار {{PLURAL:$1|آلشت|<strong>$1</strong> آلشتی}} که د {{PLURAL:$2|ساعت|<strong>$2</strong> ساعت}} دماتر انجوم بیه هیئش، ویرگار آخرین واجوری انجام شده موجود است، ویرگار آخری واجوری: $3، $4",
-       "wlshowlast": "آخرین$1 ساعتیا $2و روزیا  نشو بیئه",
+       "wlheader-showupdated": "بٱÙ\84Ú¯Ù±Û\8cاÛ\8cÛ\8c Ú©Ø§Ù\9b Ø¯ Ø¢Ø®Ø±Û\8c Ú¯Ù\84Ù\9bؽ Ú©Ø§Ù\92 Ú©Ø§Ù\92 Ø´Ù\85ا Ø³Ø§Ù\9bÛ\8cÙ\84Ù\9bØ´Ù\88 Ú©Ø±Ø¯Ø½ØªÙ± Ø¯ <strong>تÛ\8aÙ¾Ù\88ر</strong>Ù\86Ø´Ù\88Ý© Ø¯Ø§Ù\9bئٱ Ø¨Û\8aئٱن",
+       "wlnote": "د هار {{PLURAL:$1|آلشت|<strong>$1</strong> آلشتؽ}} کاْ د {{PLURAL:$2|ساعت|<strong>$2</strong> ساعٱت}} دماتر ٱنجوم بیٱ هؽسش، ڤیرگار آخری ڤاجۊری ٱنجوم بیٱ هؽسش، ڤیرگار آخری ڤاجۊری: $3، $4",
+       "wlshowlast": "آخری$1 ساعٱتؽا $2ۉ رۊزؽا نشوݩ باٛیٱ",
        "wlshowtime": "نئشوٙ دأئن د آخأر",
        "wlshowhideminor": "ڤیرایئشتیا فئرە کوچئک",
        "wlshowhidebots": "بوتیا",
        "wlshowhideanons": "کاریار نادیار",
        "wlshowhidepatr": "تیە پایی د ڤیرایئشتیا",
        "wlshowhidemine": "ڤیرایئشتیا مئ",
-       "watchlist-options": "چیا ساٛیل برگ",
+       "watchlist-options": "چیا ساٛلٛ بٱرگ",
        "watching": "د حال و بال دیئن...",
        "unwatching": "د حال ندیئن...",
        "watcherrortext": "یه گل اشگال د گات آلشت کردن میزونکاری نومگه سیل برگتو سی «$1» پیش اوما.",
-       "enotif_reset": "Ù\87Ù\85Ù\87 Ø¨Ù\84Ú¯Ù\87 Û\8cا Ø¯Û\8cئÙ\87 Ø¨Û\8cÙ\86Ù\87 Ù\86Ø´Ù\88دار Ø¨Ú©Û\8cد",
+       "enotif_reset": "Ù\87Ù\85Ù± Ø¨Ù±Ù\84Ú¯Ù±Û\8cا Ø¯Û\8cئٱ Ø¨Û\8cئٱ Ù\86اÙ\92 Ù\86Ø´Ù\88دار Ø¨Ù±Ú©Ø½Øª",
        "enotif_impersonal_salutation": "{{نوم سیلجا}} کارور",
        "enotif_subject_deleted": "{{SITENAME}} بلگه$1 وه دس{{gender:$2|$2}} پاکسا بیه.",
        "enotif_subject_created": "{{SITENAME}} بلگه$1 وه دس{{gender:$2|$2}} دروس بیه.",
        "actioncomplete": "عملكرد كامل بيه",
        "actionfailed": "عملكرد شكست حرده",
        "deletedtext": "«$1» پاکسا بیه.\nسی نهاتری پاکساگریا ایسنی وه $2 سرکشی بکیت.",
-       "dellogpage": "پاکسا Ú©Ø±Ø¯Ù\86 Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87",
+       "dellogpage": "پاکسا Ú©Ø±Ø¯Ù\86 Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù±",
        "dellogpagetext": "نومگه هاری یه گل نومگه د آخری چیا پاکسا بیه هئ.",
        "deletionlog": "پهرستنومه پاک بیئن",
        "reverted": "لرسه د نزیکترین وانئری",
        "deleting-backlinks-warning": "''' هشدار:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|بلگه یا هنی]] ین که وه بلگه یی که شما د حال و بار پاکسا کردن ونیت پیوند دارن یا د وه پرگنجایشت کاری بیینه.",
        "rollback": "چواشه کردن ویرایشتیا",
        "rollbacklink": "ڤرگٱشتن",
-       "rollbacklinkcount": "Ú\86Ù\88اشÙ\87 Ú©Ø±Ø¯Ù\86 $1 {{PLURAL:$1|Ù\88Û\8cراÛ\8cشت|Ù\88Û\8cراÛ\8cشتÛ\8cا}}",
+       "rollbacklinkcount": "Ú\86Ù\88ئارشٱ Ú©Ø±Ø¯Ù\86 $1 {{PLURAL:$1|Ú¤Û\8cراÛ\8cØ´|Ú¤Û\8cراÛ\8cشؽا}}",
        "rollbacklinkcount-morethan": "چواشه کردن بیشتر د$1 {{PLURAL:$1|ویرایشت|ویرایشتیا}}",
        "rollbackfailed": "چواشه کردن د خوئی انجوم نبی",
        "cantrollback": "نبوئه ویرایشت نه پاکساگری بکیت:\nآخری هومیار تئنا نیسنه ای گوتاره.",
        "changecontentmodel-success-title": "حال و بال مینوٙنە آلئشتکاری بی",
        "logentry-contentmodel-change-revertlink": "لئرنیئن",
        "logentry-contentmodel-change-revert": "لئرنیئن",
-       "protectlogpage": "پأر و پیم کاری پئرئستنوٙمە",
+       "protectlogpage": "پٱر ۉ پیم کاری پهرستنومٱ",
        "protectlogtext": "د ھار یئ گئل نومگە د آلئشتیا ریتئراز پأر و پیم کاری بألگە یا ئوٙماە.\n[[Special:ProtectedPages|نومگە بألگە یا پأر و پیم کاری بییە]] نە سی دیئن نومگە پأر و پیم کاری کارگئرا بألگە یا نە سئیل بأکیت.",
        "protectedarticle": "پأر و پیم کاری بییە [[$1]]",
-       "modifiedarticleprotection": "ریتراز حفاظت د \"[[$1]]\" آلشت بیه",
+       "modifiedarticleprotection": "ریتراز هفازٱت د \"[[$1]]\" آلشت بیٱ",
        "unprotectedarticle": "بلگه«[[$1]]» نه د پر و پیم دراورد",
        "movedarticleprotection": "میزونکاری پر و پیم بیین د «[[$2]]» وه «[[$1]]» جا وه جا بیه",
        "protect-title": "ریتراز حفاظت د \"$1\" آلشت بیه",
        "minimum-size": "انازه کمترونه",
        "maximum-size": "انازه بیشترونه",
        "pagesize": "(بایتیا)",
-       "restriction-edit": "ڤیرایشت",
-       "restriction-move": "جاوه جا بوئيت",
+       "restriction-edit": "ڤیرایش",
+       "restriction-move": "جا ڤ جا بۊئؽت",
        "restriction-create": "راس كردن",
        "restriction-upload": "سوار کرد",
        "restriction-level-sysop": "کلا پر و پیم بیه",
        "undelete-show-file-confirm": "آیا یه دل بئیته که میهایت یه گل نسقه پاکسا بیه د جانیا \"<nowiki>$1</nowiki>\" که ها د ویرگار $2 ساعت $3 نه سیل بکیت؟",
        "undelete-show-file-submit": "هأری",
        "namespace": "نوم جا",
-       "invert": "Ú¯Ù\84Ù\9bٱڤرÚ\86Û\8c Ø¨Û\8cئÙ\86 Ø¨Ù±Ø±Ø¹Ù±Ø³Ú© بۊئٱ",
+       "invert": "Ú¯Ù\84Ù\9bٱڤرÚ\86Û\8c Ø¨Û\8cئÙ\86 Ø¨Ù±Ø±Ø¹Ù±Ø³Ú¯ بۊئٱ",
        "tooltip-invert": "د ری اؽ جٱڤٱ بٱپۊرنؽت ۉ آلشتؽایؽ ناْ کاْ د مؽنجا نوم ڤرگٱ اْنتخاو بیٱ ٱنجوم بینٱ قایم بٱکؽت(ۉ ٱر نوم ڤرگٱ شریکی ڤارسی بیٱ)",
        "tooltip-whatlinkshere-invert": "ای جعون نه سی نهو کردن هوم پیوند بلگه یایی که نوم جاشو انتخاو بیه، انتخاو بکیت.",
        "namespace_association": "نوم جایا یٱکاگرتٱ",
        "contributions-title": "ھومیاری كاریار سی $1",
        "mycontris": "هومياریا",
        "anoncontribs": "هومیاریا",
-       "contribsub2": "سي {{جنسيت:$3|$1}} ($2)",
+       "contribsub2": "سی {{جنسيٱت:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "کاریار \"$1\" ثوت نام نکرده.",
-       "nocontribs": "هیچ آلشتی وا ای مشقصات دیاری نکرد.",
-       "uctop": "تازÙ\87 Ø¨Ø§Ù\88",
+       "nocontribs": "هیچ آلشتؽ ڤا اؽ موشٱخٱسؽا دؽاری نٱکرد.",
+       "uctop": "تازٱ Ø¨Û\8a",
        "month": "د ما(یا زیتر)",
        "year": "د سال",
        "sp-contributions-newbies": "فقٱت هومیارؽایؽ کاْ د هساو تازٱ بیٱ نشوݩ باٛیٱ",
        "sp-contributions-newbies-sub": "سی حساویا تازه",
        "sp-contributions-newbies-title": "هومیاریا کاریار سی حساویا تازه",
-       "sp-contributions-blocklog": "پهرستنۊمٱ قولف بیٱ",
+       "sp-contributions-blocklog": "پهرستنومٱ قولف بیٱ",
        "sp-contributions-suppresslog": "پاکساگری کردن هومیاریا کاریار",
        "sp-contributions-deleted": "هومیاریا پاکسا بیه کاریار",
-       "sp-contributions-uploads": "سواركرديا",
-       "sp-contributions-logs": "Ù\86Û\8cسÙ\86Ù\86 Ø±Ø® Ù\88Ù\86Û\8cا",
+       "sp-contributions-uploads": "سڤاركردؽا",
+       "sp-contributions-logs": "Ù\86Û\8cسٱÙ\86Ù\86 Ø±Ù\88Ø® Ú¤Ù±Ù\86ؽا",
        "sp-contributions-talk": "چٱک چنٱ",
        "sp-contributions-userrights": "دیوونداری حقوق کاریار",
        "sp-contributions-blocked-notice": "د دسرسی ای کاریا د ایسنی نهاگری بیه.\nآخری برشت د پهرستنومه نهاگری ها د سرچشمه هاری:",
        "whatlinkshere-title": "بٱلگاٛؽ کاْ د $1 هوم پاٛڤٱن بیٱ",
        "whatlinkshere-page": "بٱلگٱ",
        "linkshere": "بٱلگٱیا نوئایی د '''$2''' هوم پاٛڤٱن بیٱ",
-       "nolinkshere": "Ù\87Û\8cÚ\98 Ø¨Ú¯Ù\84Ù\87 Ø§Û\8c Ø¯  '''$2''' Ù\87Ù\88Ù\85 Ù¾Û\8cÙ\88Ù\86د Ù\86بÛ\8cÙ\87",
+       "nolinkshere": "Ù\87Û\8cÚ\86 Ø¨Ù±Ú¯Ù\84اÙ\9bÛ\8cؽ Ø¯  '''$2''' Ù\87Ù\88Ù\85 Ù¾Ø§Ù\9bÚ¤Ù±Ù\86 Ù\86اÙ\9bÛ\8cÛ\8cÙ±",
        "nolinkshere-ns": "هیچ بلگه ای د نومجا انتخاو بیه وه'''$2''' هوم پیوند ناره.",
        "isredirect": "بٱلگٱ دوئارٱ ڤرگٱشتن",
        "istemplate": "نشونی داٛئن",
        "whatlinkshere-hideredirs": "$1 ڤرگٱردونیا",
        "whatlinkshere-hidetrans": "$1 چٱن نتیجاٛیی",
        "whatlinkshere-hidelinks": "هوم پاٛڤٱنؽا $1",
-       "whatlinkshere-hideimages": "جانیا هوم پیۋندیا $1",
+       "whatlinkshere-hideimages": "جانؽا هوم پاٛڤٱنؽا $1",
        "whatlinkshere-filters": "فيلٛترؽا",
        "autoblockid": "خود نهاگری #$1",
        "block": "منع کارور",
        "ipblocklist-submit": "پی جوری",
        "ipblocklist-localblock": "نهاگری ولات نشینی",
        "ipblocklist-otherblocks": "هنی{{PLURAL:$1|نهاگرتن|نهاگرتنیا}}",
-       "infiniteblock": "بی زمون",
+       "infiniteblock": "بؽ زموݩ",
        "expiringblock": "د $1 ساعت $2 تموم موئه",
        "anononlyblock": "فقط کاریاریا نادیار",
        "noautoblockblock": "بستن خودانجوم ناکشتگر بیه",
        "blocklist-nousertalk": "نبوئه بلگه چک چنه خوتونه ویرایشت بکید",
        "ipblocklist-empty": "جاگه نوم گه حالیه",
        "ipblocklist-no-results": "دسرسی نوم کاریاری یا تیرنشون آی پی حاسته بیه نهاگری نبیه.",
-       "blocklink": "نوئاگری بۊئٱ",
+       "blocklink": "نوئاگیری بۊئٱ",
        "unblocklink": "بی قطی",
        "change-blocklink": "اجازه نديئن سی  آلشت",
-       "contribslink": "هومیاریا",
+       "contribslink": "هومیاریٛا",
        "emaillink": "انجومانامه نه کل کو",
        "autoblocker": "وه خود انجومن بسه بی سی یه که آی پی شما د ایسنی وه دس کاریار «[[User:$1|$1]]» وه کار گرته بیه.\nدلیل نهاگری $1 ینه \"$2\"",
        "blocklogpage": "قلف",
        "blocklog-showlog": "تیرنشون ای آی پی دماتر نهاگیری بیه.\nنهاگری ای پهرستنومه وا سرچشمه هاری دروس بیه:",
        "blocklog-showsuppresslog": "تیرنشون ای آی پی دماتر نهاگیری بیه.\nنهاگری ای پهرستنومه وا سرچشمه هاری دروس بیه:",
-       "blocklogentry": " [[$1]] وا یه گل وخت تموم بیئن $2 و $3  قلف بیه",
+       "blocklogentry": " [[$1]] ڤا یاٛ ڤٱخت تموم بیئن $2 ۉ $3  قلف بییٱ",
        "reblock-logentry": "میزوکاری سی نهاگری[[$1]] آلشت بیه سی آخر نهاگری د $2 $3",
        "blocklogtext": "ای پهرستنومه سی نهاگری یا واز کردن دسرسی کاریاریائه.\nتیرنشونیا آی پی که خود انجومن نهاگری بینه د ایسنی نومگه کاری نبینه.\nسی نومگه نهاگریا و بسه بینیا د ایسنی روئیت د [[Special:BlockList|نومگه نهاگری بیه یا]].",
        "unblocklogentry": "وا کردن قلف $1",
        "block-log-flags-anononly": "فقط کاریاریایی که نادیارن",
-       "block-log-flags-nocreate": "حساو راس کردن عاجز بیه.",
+       "block-log-flags-nocreate": "هساو دۏرس کردن عاجز بیٱ.",
        "block-log-flags-noautoblock": "بستن خودانجوم ناکشتگر بیه",
        "block-log-flags-noemail": "انجومانامه ناکشتگر بیه",
        "block-log-flags-nousertalk": "نبوئه بلگه چک چنه خوتونه ویرایشت بکید",
        "ipb_blocked_as_range": "خطا: تیرنشون آی‌ پی $1 سر راست نهاگری نبیه و نبوئه وازش بکیت.\nای تیرنشون واگرد پوشگر $ نهاگری بیه و بوئه وازش بکی.",
        "ip_range_invalid": "پوشگر نامعتور آی پی",
        "ip_range_toolarge": "نهاگری پوشینه یا گپتر $1/ مجاز نئ.",
-       "proxyblocker": "Ù\82Ù\84Ù\81 Ú©Ù\86Ù\86Ù\87 پروکسی",
+       "proxyblocker": "Ù\82Ù\84Ù\81 Ú©Ù\86Ù\86Ù± پروکسی",
        "proxyblockreason": "تیرنشون آی پی شما نهاگری بیه سی یه مال یه گل پروکسی آزاده.\nلطف بکیت وا انجومکار اینترنتی خوتو یا حامینکار کسمی خوتو پیوند بگریت و ونونه د مشگل امنتی گن خوتو وارسیار بکیت.",
        "sorbs": "دی ان اس بی ال",
        "sorbsreason": "تیرنشون آی پی شما وه دس DNSBL  وه کار گرته وه دس {{SITENAME}} چی یه گل پروکسی آزاد گزارشت بیه.",
        "movepage-page-moved": "بلگه $1 د $2 جا وه جا بیه",
        "movepage-page-unmoved": "نبوئه بلگه $1 د $2 جا وه جا بوئه",
        "movepage-max-pages": "بیشترونه انازه بلگه یا شایت سی ($1 {{PLURAL:$1|بلگه|بلگه یا}}) یی که بوئه جا وه جاکاری بوئن، جا وه جاکاری بیه و بلگه یا هنی نه نبوئه و شکل خودانجوم جا وه جاکاری کرد.",
-       "movelogpage": "جاوه جا کردن",
+       "movelogpage": "جا ڤ جا کردن",
        "movelogpagetext": "د هار یه گل نوم گه د جا وه جایی یا بلگه هئ",
        "movesubpage": "{{PLURAL:$1|زیر بلگه|زیر بلگه یا}}",
        "movesubpagetext": "ای بلگه $1 زیربلگه داره که د زیر نشو {{PLURAL:|نشو دئه بیه|دئه بینه}}.",
        "import-options-wrong": "{{PLURAL:$2|جزئیات|جزئیات}} اشتوا: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "ریشه دئه بیه د بلگه یه گل سرون نامعتوره.",
        "import-rootpage-nosubpage": "نومجا \"$1\" بلگه پایه صلا زیر بلگه نه نمی یه.",
-       "importlogpage": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87 دئن",
+       "importlogpage": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù± دئن",
        "importlogpagetext": "وامین اوردن بلگه یا وا ویرگارچه ویرایشت ونو د ویکی یا هنی",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|وانئری|وانئریا}} وامین اومانه",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|وانئری|وانئریا}} د $2 وامین اومائنه",
        "tooltip-ca-addsection": "د یاٛ بهرجا هنی شرۊ بٱک",
        "tooltip-ca-viewsource": "اؽ بٱلگٱ پر ۉ پیم بیٱ.\nشما مؽ تونؽت سرچشمٱشاْ باٛینؽت",
        "tooltip-ca-history": "دوئرٱ دیئن اؽ بٱلگٱ",
-       "tooltip-ca-protect": "ای بلگه نه حفاظت بكيد",
+       "tooltip-ca-protect": "اؽ بٱلگٱ ناْ ڤیردار بٱکؽت",
        "tooltip-ca-unprotect": "پر و پیم گیری د ای بلگه نه آلشت بکیت",
        "tooltip-ca-delete": "ای بلگه نه پاکسا کو",
        "tooltip-ca-undelete": "د نو زنه کردن ویرایشتیا ری ای بلگه دما یه که پاکساگری بان",
-       "tooltip-ca-move": "ای بگله نه جا وه جا كو",
+       "tooltip-ca-move": "اؽ بٱلگٱ ناْ جا ڤ جا كو",
        "tooltip-ca-watch": "اْزاف کردن اؽ بٱلگٱ ڤ نوم نڤشت پاٛگیریاتو",
-       "tooltip-ca-unwatch": "ورداشتن ای بلگه وه نوم نوشت پیگئریاتو",
+       "tooltip-ca-unwatch": "ڤرداشتن اؽ بٱلگٱ ڤ نوم نڤشت پاٛگیریاتو",
        "tooltip-search": "پاٛ جۊری {{SITENAME}}",
-       "tooltip-search-go": "رۉ د بٱلگاٛیؽ کاْ یٱ نوم روسی ها مؽنش ٱلڤٱت ٱر دش بۊئٱ",
+       "tooltip-search-go": "رۉ د بٱلگاٛیؽ کاْ یٱ نوم راسی ها مؽنش ٱلڤٱت ٱر دش بۊئٱ",
        "tooltip-search-fulltext": "بٱلگٱیاناْ سی چنی نیسساٛیؽ پاٛ جۊری بٱکو.",
        "tooltip-p-logo": "ساٛلٛ سرآسونٱ بٱکؽت",
        "tooltip-n-mainpage": "سرآسونٱ ناْ ساٛلٛ بٱکؽت",
        "tooltip-n-mainpage-description": "سرآسونٱ ناْ ساٛلٛ بٱکؽت",
        "tooltip-n-portal": "دبارٱ پرۉژٱ؛ شما مؽ تونؽت چؽ بٱکؽت؛ د کوجا اؽ چیاناْ بٱجۊرؽت.",
-       "tooltip-n-currentevents": "ساڤÙ\86د Ø¯Ù\88Ù\86سÙ\85Ù\86Û\8cاÛ\8cؽ Ú©Ø§ Ù\87اÙ\86 Ø¯ Ø±Ù\88Ø® Ú¤Ù\86ؽا ØªØ§Ø²Ù± Ø¨Ø§Ú¤ دؽاری بٱک",
+       "tooltip-n-currentevents": "ساڤٱÙ\86 Ø¯Ù\88Ù\86سÙ\85Ù\86Û\8cاÛ\8cؽ Ú©Ø§ Ù\87اÙ\86 Ø¯ Ø±Ù\88Ø® Ú¤Ù±Ù\86ؽا ØªØ§Ø²Ù± Ø¨Û\8a دؽاری بٱک",
        "tooltip-n-recentchanges": "یاٛ نومگٱ سی آلشتکاریا د ڤیکی",
        "tooltip-n-randompage": "سڤار کرد بٱلگٱ بٱختٱکی",
        "tooltip-n-help": "یاٛ جاگٱ سی فٱمسن",
        "tooltip-feed-rss": "هوال حون آر اس اس سی ای بلگه",
        "tooltip-feed-atom": "هڤال هۊن ٱتومی سی اؽ بٱلگٱ",
        "tooltip-t-contributions": "یاٛ سیائٱ هومیاری سی {{GENDER:$1|اؽ کاریار}}",
-       "tooltip-t-emailuser": "سی اؽ كاریار ايماٛیل کلٛ كو",
+       "tooltip-t-emailuser": "سی اؽ كاریار ايماٛیلٛ کلٛ كو",
        "tooltip-t-info": "دونسمنیا بیشتر دباره ای بلگه",
        "tooltip-t-upload": "سڤار کردن جانؽایا",
        "tooltip-t-specialpages": "مؽناْ هٱمٱ بٱلگٱیا ڤیژٱ",
-       "tooltip-t-print": "نۏسخٱ پاٛلا بی ینی سی اؽ بٱلگٱ",
+       "tooltip-t-print": "نۏسخٱ پاٛلا بیئی سی اؽ بٱلگٱ",
        "tooltip-t-permalink": "هوم پاٛڤٱن همیشاٛیی سی دوئارٱ دیئن اؽ بٱلگٱ",
        "tooltip-ca-nstab-main": "ديئن مؽنونٱ بٱلگٱ",
-       "tooltip-ca-nstab-user": "دیین بٱلگٱ کاریار",
+       "tooltip-ca-nstab-user": "دیئن بٱلگٱ کاریار",
        "tooltip-ca-nstab-media": "دیئن بلگه وارسگر",
        "tooltip-ca-nstab-special": "یٱ یاٛ بٱلگٱ ڤیژٱ آ؛ نمۊئٱ ڤیرایشش بٱکؽت",
-       "tooltip-ca-nstab-project": "دÙ\8aئÙ\86 Ø¨Ù\84Ú¯Ù\87 Ù¾Ø±Ù\88جÙ\87",
+       "tooltip-ca-nstab-project": "دÙ\8aئÙ\86 Ø¨Ù±Ù\84Ú¯Ù± Ù¾Ø±Û\89Ú\98Ù±",
        "tooltip-ca-nstab-image": "دیئن بٱلگٱ جانؽا",
-       "tooltip-ca-nstab-mediawiki": "دÛ\8cاÙ\9bÙ\86 Ù¾Û\8cغÙ\88Ù\85 Ø³Ø§Ù\85Û\8aنٱ",
-       "tooltip-ca-nstab-template": "ديئن چۊٱ",
+       "tooltip-ca-nstab-mediawiki": "دÛ\8cئÙ\86 Ù¾Ø§Ù\9bغÙ\88Ù\85 Ø³Ø§Ù\85Ù\88نٱ",
+       "tooltip-ca-nstab-template": "ديئن چۊئٱ",
        "tooltip-ca-nstab-help": "ديئن بلگه هومیاری",
        "tooltip-ca-nstab-category": "دیئن بٱلگٱ دٱسٱ بٱنی",
-       "tooltip-minoredit": "Û\8cÙ\87 Ù\86Ù\87 Ø¯ Ø¹Ù\86Ù\88اÙ\86 Ø­Û\8cردÙ\87 Ù\88Û\8cراÛ\8cشت Ø«Ù\88ت کو",
+       "tooltip-minoredit": "Û\8cÙ± Ù\86اÙ\92 Ú¤ Ø¹Ù\88Ù\86ڤاÙ\86 Ù\87Û\8cردٱ Ú¤Û\8cراÛ\8cØ´ Ø³Ù±Ø¨ت کو",
        "tooltip-save": "آلشتؽا توناْ آمادٱ بٱکؽت",
        "tooltip-preview": "پیش ساٛلٛ آلشتؽاتو، لوتف بٱکؽت ڤنوناْ دما د آمایٱ کاریشو ڤ کار باٛیرؽت!",
        "tooltip-diff": "آلشتؽا ناْ کاْ شما د ای مٱتن دۏرس کردؽتٱ نشوݩ باٛیٱ",
-       "tooltip-compareselectedversions": "فرخیا مینجا د تا د دو بار دیاٛن ای بلگٱ نٱ بۉنیت",
-       "tooltip-watch": "ای بلگه نه د سیل برگتو اضاف بکید",
+       "tooltip-compareselectedversions": "فٱرخؽا مؽنجا د تا د دۏ بار دیئن اؽ بٱلگٱ ناْ بونؽت",
+       "tooltip-watch": "اؽ بٱلگٱ ناْ د ساٛلٛ بٱرگتو اْزاف بٱکؽت",
        "tooltip-watchlistedit-normal-submit": "ؤرداشتن سرونیا",
        "tooltip-watchlistedit-raw-submit": "وه هنگوم سازی سیل برگ",
        "tooltip-recreate": "د نو راس کردن بلگه بی یه که و پاکساگری دماتر وه سیل بکیم",
        "tooltip-upload": "شرو د سوار کرد",
-       "tooltip-rollback": "\"ڤرگٱشتن\" لٛرسن د هال و بال ٱڤٱل سی اؽ بٱلگٱ سی یٱ کاْ هومیاری نؽایی بؽتر کاری بیٱ ڤا یاٛ پۊرنین.",
+       "tooltip-rollback": "\"ڤرگٱشتن\" لٛرسن د هال و بار ٱڤٱل سی اؽ بٱلگٱ سی یٱ کاْ هومیاری نؽایی بؽتر کاری بیٱ ڤا یاٛ پۊرنیئن.",
        "tooltip-undo": "ٱنجوم نٱگرتن اؽ ڤیرایش. ڤرگٱرد ۉ هٱمٱ فورمؽا ڤیرایشؽاناْ د هالٱت پیش ساٛلٛ ڤاکو.یٱ اْجازٱ ماٛئٱ سی اْزاف کردن یاٛ دٱلٛیلٛ د چکسٱ.",
        "tooltip-preferences-save": "اولويتيا نه ذخيره بكيد",
        "tooltip-summary": "ياٛ چكسٱ کوچک ڤارد بٱکؽت",
        "simpleantispam-label": "ڤارسی ری ڤ ری کاری اْسپٱم.\nاؽ \"جاگٱ\" ناْ پور نٱکؽت!",
        "pageinfo-title": "دونسمنیا سی \"$1\"",
        "pageinfo-not-current": "د بدبختی،نبوئه که ای دونسمنیا نه سی وانئریا دماتری نهااماییه بکیت.",
-       "pageinfo-header-basic": "دÙ\88Ù\86سÙ\85Ù\86Û\8cا Ù¾Ø§Û\8cÙ\87",
-       "pageinfo-header-edits": "Ú¤Û\8cراÛ\8cئشت ڤیرگار",
-       "pageinfo-header-restrictions": "پر و پیم کردن بلگه",
-       "pageinfo-header-properties": "Ú\86Û\8cا Ø¨Ù\84Ú¯Ù\87",
-       "pageinfo-display-title": "نشو دئن سرون",
-       "pageinfo-default-sort": "کلیت سرجا یک کن پیش فرض",
-       "pageinfo-length": "انازه بلگه(وه بایت)",
-       "pageinfo-article-id": "نوم دیار کن بلگه",
-       "pageinfo-language": "بÙ\84Ú¯Ù\87 Ù\85Û\8cÙ\86Ù\88Ù\86Ù\87 Ø²ون",
-       "pageinfo-content-model": "Ø´Ù\84Ú¯ Ù\85Û\8cÙ\86Ù\88Ù\86Ù\87 Ø¨Ù\84Ú¯Ù\87",
-       "pageinfo-robot-policy": "Ù\86Ù\88Ù\85Ú¯Ù\87 Ú©Ø§Ø±Û\8c Ù\88ا Ø±Ø¨Ø§ØªÛ\8cا",
-       "pageinfo-robot-index": "صلادار",
-       "pageinfo-robot-noindex": "بی صلا",
-       "pageinfo-watchers": "Ø´Ù\85ارÙ\87 Ø³Û\8cÙ\84 Ú©Ù\86Ù\86Ù\87 Ø¨Ù\84Ú¯Ù\87 یا",
-       "pageinfo-few-watchers": "Ú©Ù\85تر Ø¯ $1 {{PLURAL:$1|سÛ\8cÙ\84 Ú©Ù\86Ù\86Ù\87|سÛ\8cÙ\84 Ú©Ù\86Ù\86Ù\87 Û\8cا}}",
-       "pageinfo-redirects-name": "Ø´Ù\85ارÙ\87 Ù\88اگردÙ\88Ù\86Û\8cا Ø§Û\8c Ø¨Ù\84Ú¯Ù\87",
+       "pageinfo-header-basic": "دÙ\88Ù\86سÙ\85Ù\86Û\8cا Ù¾Ø§Û\8cÙ±",
+       "pageinfo-header-edits": "Ú¤Û\8cراÛ\8cØ´ ڤیرگار",
+       "pageinfo-header-restrictions": "پر ۉ پیم کردن بٱلگٱ",
+       "pageinfo-header-properties": "Ú\86Û\8cا Ø¨Ù±Ù\84Ú¯Ù±",
+       "pageinfo-display-title": "نشوݩ داٛئن سرڤٱن",
+       "pageinfo-default-sort": "کلٛیلٛ سٱرجا یٱک کن پیش فٱرز",
+       "pageinfo-length": "ٱندازٱ بٱلگٱ(ڤ بایت)",
+       "pageinfo-article-id": "نوم دؽار کن بٱلگٱ",
+       "pageinfo-language": "بÙ\84Ú¯Ù± Ù\85Û\8cÙ\86Ù\88Ù\86Ù± Ø²Ú¤ون",
+       "pageinfo-content-model": "Ø´Ù\84Ú© Ù\85Û\8cÙ\86Ù\88Ù\86Ù± Ø¨Ù±Ù\84Ú¯Ù±",
+       "pageinfo-robot-policy": "Ù\86Ù\88Ù\85Ú¯Ù± Ú©Ø§Ø±Û\8c Ú¤Ø§ Ø±Ù\88باتؽا",
+       "pageinfo-robot-index": "سلادار",
+       "pageinfo-robot-noindex": "بؽ سلا",
+       "pageinfo-watchers": "Ø´Ù\85ارٱ Ø³Ø§Ù\9bÙ\84Ù\9b Ú©Ù\86Ù\86Ù± Ø¨Ù±Ù\84Ú¯Ù±یا",
+       "pageinfo-few-watchers": "Ú©Ù±Ù\85تر Ø¯ $1 {{PLURAL:$1|ساÙ\9bÙ\84Ù\9b Ú©Ù\86|ساÙ\9bÙ\84Ù\9b Ú©Ù\86ؽا}}",
+       "pageinfo-redirects-name": "Ø´Ù\85ارٱ Ú¤Ø§Ú¯Ù±Ø±Ø¯Ù\88Ù\86Û\8cا Ø§Ø½ Ø¨Ù±Ù\84Ú¯Ù±",
        "pageinfo-redirects-value": "$1",
-       "pageinfo-subpages-name": "انازه زیربلگه یا ای بلگه",
-       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|واگردونی|واگردونیا}}; $3 {{PLURAL:$3|بی واگردونی|بی واگردونیا}})",
-       "pageinfo-firstuser": "بÙ\84Ú¯Ù\87 Ø±Ø§س کن",
-       "pageinfo-firsttime": "گات دروس بیین بلگه",
-       "pageinfo-lastuser": "آخری ڤیرایشتکار",
-       "pageinfo-lasttime": "گات آخری ڤیرایشت",
-       "pageinfo-edits": "Ø´Ù\85ارÙ\87 Ù\87Ù\85Ù\87 Ù\88Û\8cراÛ\8cشتÛ\8cا",
-       "pageinfo-authors": "Ø´Ù\85ارÙ\87 Ú©Ù\84Û\8c Ù\86Ù\88Û\8cسÙ\86Ù\87 Û\8cا Û\8cÚ©Ù\88Ù\86Ù\87",
-       "pageinfo-recent-edits": "Ø´Ù\85ارÙ\87 Ù\88Û\8cراÛ\8cشتÛ\8cا ایسنی (د $1 دماتر)",
-       "pageinfo-recent-authors": "Ø´Ù\85ارÙ\87 Ú©Ù\84Û\8c Ù\86Ù\88Û\8cسÙ\86Ù\87 Û\8cا Û\8cÚ©Ù\88Ù\86Ù\87",
-       "pageinfo-magic-words": "جادویی{{PLURAL:$1|کلیمه|کلیمه یا}} ($1)",
-       "pageinfo-hidden-categories": "$1{{PLURAL:$1|دسه|دسه يا}} قام بیه",
-       "pageinfo-templates": "{{PLURAL:$1|چۊٱ|چۊٱ یا}} ڤ کار گرتٱ بیٱ ($1)",
+       "pageinfo-subpages-name": "ٱندازٱ زؽر بٱلگٱیا اؽ بٱلگٱ",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|ڤاگٱردونی|ڤاگٱردونیا}}; $3 {{PLURAL:$3|بؽ ڤاگٱردونی|بؽ ڤاگٱردونیا}})",
+       "pageinfo-firstuser": "بٱÙ\84Ú¯Ù± Ø¯Û\8fرس کن",
+       "pageinfo-firsttime": "گات دۏرس بیئن بٱلگٱ",
+       "pageinfo-lastuser": "آخری ڤیرایشکار",
+       "pageinfo-lasttime": "گات آخری ڤیرایش",
+       "pageinfo-edits": "Ø´Ù\85ارٱ Ù\87Ù\85Ù± Ú¤Û\8cراÛ\8cشؽا",
+       "pageinfo-authors": "Ø´Ù\85ارٱ Ú©Ù\88Ù\84Ù\9bÛ\8c Ù\86Ú¤Û\8cسٱÛ\8cا Û\8cÙ±Ú©Ù\88Ù\86Ù±",
+       "pageinfo-recent-edits": "Ø´Ù\85ارٱ Ú¤Û\8cراÛ\8cشؽا ایسنی (د $1 دماتر)",
+       "pageinfo-recent-authors": "Ø´Ù\85ارٱ Ú©Ù\88Ù\84Ù\9bÛ\8c Ù\86Ú¤Û\8cسٱÛ\8cا Û\8cÙ±Ú©Ù\88Ù\86Ù±",
+       "pageinfo-magic-words": "جادۊیی{{PLURAL:$1|کلٱمٱ|کلٱمٱیا}} ($1)",
+       "pageinfo-hidden-categories": "$1{{PLURAL:$1|دٱسٱ|دٱسٱيا}} قایم بیٱ",
+       "pageinfo-templates": "{{PLURAL:$1|چۊئٱ|چۊئٱ یا}} ڤ کار گرتٱ بیٱ ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|بلگه|بلگه یا}} وه کار گرته بیه د ($1)",
        "pageinfo-toolboxlink": "دونسمٱنیٛا بٱلگٱ",
        "pageinfo-redirectsto": "واگردونی سی",
        "pageinfo-redirectsto-info": "دونسمنیا",
-       "pageinfo-contentpage": "اشÙ\85اردÙ\87 Ø¨Û\8cÙ\87 Ù\88Ù\87 Ø¹Ù\86Ù\88اÙ\86 Ù\85Û\8cÙ\86Ù\88Ù\86Ù\87 Ø¨Ù\84Ú¯Ù\87",
-       "pageinfo-contentpage-yes": "ٱ",
+       "pageinfo-contentpage": "Ø´Ù\85اردٱ Ø¨Û\8cÙ± Ú¤ Ø¹Ù\88Ù\86ڤاÙ\86 Ù\85ؽÙ\86Ù\88Ù\86Ù± Ø¨Ù±Ù\84Ú¯Ù±",
+       "pageinfo-contentpage-yes": "عٱ",
        "pageinfo-protect-cascading": "پر و پیم بیین تافنمایی د ایچه",
        "pageinfo-protect-cascading-yes": "هری",
        "pageinfo-protect-cascading-from": "پر و پیم بیین تافنمایی د",
        "markedaspatrollederror-noautopatrol": "شما صلا یه نه که آلشتیا خوتونه چی یه که سردیاری کرده بان ناریت.",
        "markedaspatrollednotify": "آلشتیایی که مال $1 چی یه گل چی سردیاری کرده نشودار بینه.",
        "markedaspatrollederrornotify": "نشودار کردن چی نشودار بیه شکست حرده",
-       "patrol-log-page": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87 Ú¯شتن",
+       "patrol-log-page": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù± Ú¯Ù±شتن",
        "patrol-log-header": "یه پهرستنومه وانئریا سردیاری کرده هئ.",
        "deletedrevision": "وانئری دماتری پاکسابیه د $1",
        "filedeleteerror-short": "خطا پاک نبیئن جانیا:$1",
        "filedelete-old-unregistered": "وانئری جانیا تیارکرده \"$1\" د رسینه جا وجود ناره.",
        "filedelete-current-unregistered": "جانیا تیارکرده \"$1\" د رسینه جا نئیش.",
        "filedelete-archive-read-only": "نشونگه مال دیارکردن ($1) د لا سرور قاول نیسنن نئ.",
-       "previousdiff": "← ويرايشت كۈهنه تر",
-       "nextdiff": "ويرايشت تازه تر",
+       "previousdiff": "← ڤیرایش کۏنٱتر",
+       "nextdiff": "ڤیرایش تازٱ تر",
        "mediawarning": "'''هشدار''': شایت ای جانیا د خوش رازینه یا گن داشتوئه.\nشایت وا اجرا وه انجومیار شما آسیو دینه.",
        "imagemaxsize": "انازه عسگ:<br /><em>(سی شرح جانیا بلگه یا)</em>",
        "thumbsize": "انازه بن کلکی:",
        "widthheight": "$1 × $2",
-       "widthheightpage": "$1 Ã\97 $2, $3 {{PLURAL:$3|بÙ\84Ú¯Ù\87|بÙ\84Ú¯Ù\87 یا}}",
+       "widthheightpage": "$1 Ã\97 $2, $3 {{PLURAL:$3|بٱÙ\84Ú¯Ù±|بٱÙ\84Ú¯Ù±یا}}",
        "file-info": "انازه جانیا: $1, MIME type: $2",
        "file-info-size": "$1 × $2 پیکسل, ٱندازٱ فایل: $3, MIME نوع: $4",
-       "file-info-size-pages": "$1 × $2 pixels, انازه جانیا: $3, MIME type: $4, $5 {{PLURAL:$5|بلگه|بلگه یا}}",
+       "file-info-size-pages": "$1 × $2 pixels, ٱندازٱ جانؽا: $3, MIME type: $4, $5 {{PLURAL:$5|بٱلگٱ|بٱلگٱیا}}",
        "file-nohires": "عٱسک ڤٱن بالاترؽ دش نؽ",
-       "svg-long-desc": "جانیا اٛس ۋی جی, نومی $1 × $2 پیکسل, ٱنازٱ جانیا: $3",
+       "svg-long-desc": "جانؽا اْس ڤی جی, نومی $1 × $2 پیکسل, ٱندازٱ جانؽا: $3",
        "svg-long-desc-animated": "جانیا جمشدار اس وی جی .نومنا $1 × $2 پيكسل،انازه جانیا:$3",
        "svg-long-error": "جانیا اس وی جی نامعتور:$1",
        "show-big-image": "جانؽا ٱسلی",
        "brackets": "[$1]",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "بلگه دمايی",
-       "imgmultipagenext": "بÙ\84Ú¯Ù\87 Ù\86Ù\87ایی",
-       "imgmultigo": "رؤ!",
-       "imgmultigoto": "رو د بلگه $1",
+       "imgmultipagenext": "بٱÙ\84Ú¯Ù± Ø¯Ù\85ایی",
+       "imgmultigo": "رۉ!",
+       "imgmultigoto": "رۉ ڤ بٱلگٱ $1",
        "img-lang-opt": "$2 ($1)",
        "img-lang-default": "(زون پیش زمینه)",
        "img-lang-info": "اوردن ای عسگ د $1 .  $2",
        "watchlistedit-clear-done": "سیل برگتون وه پاک بیه.",
        "watchlistedit-clear-removed": "$1 داسون پاکسا {{PLURAL:$1|بی|بیین}}:",
        "watchlistedit-too-many": "ایچه بلگه یا فره ای سی نشو دئن هئ.",
-       "watchlisttools-clear": "پاک کردن سیل برگ",
-       "watchlisttools-view": "آلشتیا مرتوط نه بوینیت",
-       "watchlisttools-edit": "سیل برگ بوینیتو و ویرایشت بکید",
-       "watchlisttools-raw": "سیل برگ نه ردیفی ویرایشت کو",
+       "watchlisttools-clear": "پاک کردن ساٛلٛ بٱرگ",
+       "watchlisttools-view": "آلشتؽا مٱربوت ناْ بونؽت",
+       "watchlisttools-edit": "ساٛلٛ بٱرگ بوینؽتو ۉ ڤیرایش بٱکؽت",
+       "watchlisttools-raw": "ساٛلٛ بٱرگ ناْ ردیفی ڤیرایش کو",
        "iranian-calendar-m1": "فروردین",
        "iranian-calendar-m2": "اردیبهشت",
        "iranian-calendar-m3": "خرداد",
        "version-libraries-version": "نسقه",
        "redirect": "ڤاگردونی ڤا جانؽا،بٱلگٱیا ڤانیری نوم دؽارکوݩ",
        "redirect-summary": "اؽ بٱلگٱ ڤیژٱ ڤا جانؽا (نوم جانؽا هؽسش)، بٱلگٱ (شمارٱ شناسیار بٱلگٱ یا شمارٱ نۏسخٱ دؽار بیٱ) یا بٱلگٱ کاریاری (شناسؽار عدٱدی کاریاری دؽار بیٱ) ڤاگٱردونی بۊئٱ. تٱرز ڤ کار گرتن: [[{{#Special:Redirect}}/file/Example.jpg]]، \n[[{{#Special:Redirect}}/page/64308]]، [[{{#Special:Redirect}}/revision/328429]] یا [[{{#Special:Redirect}}/user/101]].",
-       "redirect-submit": "رو",
-       "redirect-lookup": "پی جوری:",
-       "redirect-value": "ارزایشت:",
-       "redirect-user": "نوم دياركن کاریار:",
-       "redirect-page": "نوم دیار کن بلگه",
-       "redirect-revision": "وانئری بلگه",
-       "redirect-file": "نوم جانیا",
+       "redirect-submit": "رۉ",
+       "redirect-lookup": "پاٛ جۊرؽ:",
+       "redirect-value": "ٱرزایش:",
+       "redirect-user": "نوم دؽاركن کاریار:",
+       "redirect-page": "نوم دؽار کن بٱلگٱ",
+       "redirect-revision": "ڤانری بٱلگٱ",
+       "redirect-file": "نوم جانؽا",
        "redirect-not-exists": "انازه که پیدا نبی",
        "fileduplicatesearch": "پی جوری سی جانیایا دوکونه",
        "fileduplicatesearch-summary": "پی جوری سی جانیایا تکراری د پایه انازه د یک شیوسه ونو انجومگر بوئه.",
        "tags-active-header": "کنشتگره؟",
        "tags-hitcount-header": "آلشتیا سردیس دار",
        "tags-actions-header": "کنشتکاریا",
-       "tags-active-yes": "هری",
-       "tags-active-no": "Ù\86Ù\87",
+       "tags-active-yes": "عٱ",
+       "tags-active-no": "Ù\86Ù±",
        "tags-source-extension": "تعریف بیه د اساس دمادیس",
        "tags-source-manual": "وه کار گرته بیه وه شکل دسی وا کاریاریا یا بوتیا",
        "tags-source-none": "تر وه کار گرته نموئه",
        "tags-delete": "پاکسا کردن",
        "tags-activate": "کنشتیاری کردن",
        "tags-deactivate": "ناکنشتیاری کردن",
-       "tags-hitcount": "$1 {{PLURAL:$1|آلشت|آلشتیا}}",
+       "tags-hitcount": "$1 {{PLURAL:$1|آلشت|آلشتؽا}}",
        "tags-manage-no-permission": "شما صلا یه نه که آلشت دئن سردیسیا نه دیوونداری بکیت ناریت.",
        "tags-create-heading": "راس کردن یه گل سردیس تازه",
        "tags-create-explanation": "د شکل پیش فرض، سردیسیا تازه ره وندیاری بیه سی وه کار گرتن کاریاریا و رباتیا هان د دسرس.",
        "htmlform-cloner-delete": "ؤرداشتن",
        "htmlform-cloner-required": "سی کمترونه یه گل ارزایشت لازمه",
        "logentry-delete-delete": "$1 بٱلگٱ {{GENDER:$2|پاکسا بیٱ}} $3",
-       "logentry-delete-restore": "$1 {{GENDER:$2|}} Ø¨Ù\84Ú¯Ù± $3 Ø¯ Ù\86Û\8f Ø²Ø§Ù\9bنٱ بیٱ",
+       "logentry-delete-restore": "$1 {{GENDER:$2|}} Ø¨Ù±Ù\84Ú¯Ù± $3 Ø¯ Ù\86Û\8a Ø²نٱ بیٱ",
        "logentry-delete-event": "$1 دیاری {{PLURAL:$5|یه گل رخ ون د پهرستنومه|$5 رخ ونیا د پهرستنومه}} نه $3 {{GENDER:$2|آلشتکاری کرد}}: $4",
-       "logentry-delete-revision": "$1 دیاری {{PLURAL:$5|یه گل وانئری|$5 وانئریا}} نه $3 {{GENDER:$2|آلشتکاری کرد}}: $4",
+       "logentry-delete-revision": "$1 دؽاری {{PLURAL:$5|یاٛ ڤانری|$5 ڤانرؽا}} ناْ $3 {{GENDER:$2|آلشتکاری کرد}}: $4",
        "logentry-delete-event-legacy": "$1 دیاری پهرستنومه رخ ونیا نه د $3 {{GENDER:$2|آلشت ده}}",
        "logentry-delete-revision-legacy": "$1 دیاری وانئریا نه د بلگه $3 {{GENDER:$2|آلشت ده}}",
        "logentry-suppress-delete": "$1 $3 نه {{GENDER:$2| پاکساکاری کرد}}",
        "logentry-suppress-revision": "{{GENDER:$2|$1 دیاری {{PLURAL:$5|یه گل وانئری|$5 وانئریا}} نه د $3 نهونی {{GENDER:$2|آلشتکاری کرد}}: $4}}",
        "logentry-suppress-event-legacy": "$1 دیاری پهرستنومه رخ ونیا نه د $3 نهونی {{GENDER:$2|آلشت ده}}",
        "logentry-suppress-revision-legacy": "$1 دیاری نسقه یا $3 نه نهونی {{GENDER:$2|آلشت ده}}",
-       "revdelete-content-hid": "Ù\85Û\8cÙ\86Ù\88Ù\86Ù\87 Ù\82اÙ\85 Ø¨Û\8cÙ\87",
+       "revdelete-content-hid": "Ù\85Û\8cÙ\86Ù\88Ù\86Ù± Ù\82اÛ\8cÙ\85 Ø¨Û\8cÙ±",
        "revdelete-summary-hid": "چکسته ویرایشت قام بیه",
        "revdelete-uname-hid": "نوم کاروری قام بیه",
        "revdelete-content-unhid": "مینونه قام نبیه",
        "logentry-import-interwiki": "$1 $3 نه د یه گل ویکی هنی {{GENDER:$2|وامین اورد}}",
        "logentry-merge-merge": "$1  $3  نه د $4 {{GENDER:$2| سریک سازی کرد}} (نسقه تا  $5)",
        "logentry-move-move": "$1 {{GENDER:$2|جا ڤ جا کردن}} بٱلگٱ $3 ناْ سی $4",
-       "logentry-move-move-noredirect": "$1 Ø¨Ù\84Ú¯Ù\87 $3 Ù\86Ù\87 Ø¨Û\8c Û\8cÙ\87 Ú©Ù\87 Û\8cÙ\87 Ú¯Ù\84 Ù\88اگردÙ\88Ù\86Û\8c Ø¯Ø§Ø´Ù\88ئÙ\87 Ø¯ $4 {{GENDER:$2|جا Ù\88Ù\87 Ø¬Ø§کاری کرد}}",
-       "logentry-move-move_redir": "$1 Ø¨Ù\84Ú¯Ù\87 $3 Ù\86Ù\87 Ø¯ $4 Ú©Ù\87 Ù\88اگردÙ\88Ù\86Û\8c Ø¨Û\8c {{GENDER:$2|جا Ù\88Ù\87 جاکاری کرد}}",
+       "logentry-move-move-noredirect": "$1 Ø¨Ù±Ù\84Ú¯Ù± $3 Ù\86اÙ\92 Ø¨Ø½ Û\8cÙ± Ú©Ø§Ù\92 Û\8cاÙ\9b Ú¤Ø§Ú¯Ù±Ø±Ø¯Ù\88Ù\86Û\8c Ø¯Ø§Ø´ØªÛ\8aئÛ\89 Ø¯ $4 {{GENDER:$2|جا Ú¤ Ø¬Ø§ کاری کرد}}",
+       "logentry-move-move_redir": "$1 Ø¨Ù±Ù\84Ú¯Ù± $3 Ù\86اÙ\92 Ø¯ $4 Ø§Ù\92 Ú¤Ø§Ú¯Ù±Ø±Ø¯Ù\88Ù\86Û\8c Ø¨Û\8c {{GENDER:$2|جا Ú¤ جاکاری کرد}}",
        "logentry-move-move_redir-noredirect": "$1 بلگه $3 نه بی یه که یه گل واگردونی د $4 داشتوئه که یه خوش واگردونی بی {{GENDER:$2|جا وه جاکاری کرد}}",
        "logentry-patrol-patrol": "$1 نسقه $4 بلگه $3 نه چی یه گل چی تیه نئری بیه {{GENDER:$2|نشودار کرد}}",
-       "logentry-patrol-patrol-auto": "$1 نسقه $4 بلگه $3 نه وه حال و بار خودانجوم چی یه گل بلگه تیه نیئر بیه {{GENDER:$2|نشودار کرد}}",
+       "logentry-patrol-patrol-auto": "$1 نۏسخٱ $4 بٱلگٱ $3 ناْ ڤ هال ۉ بار خودٱنجوم چی یاٛ بٱلگٱ تیٱ نیر بیٱ {{GENDER:$2|نشودار کرد}}",
        "logentry-newusers-newusers": "حساو کاریاری $1 {{GENDER:$2|دروس بیه}}",
        "logentry-newusers-create": "هساو کاربٱری $1 {{GENDER:$2|دۏرس بی}}",
        "logentry-newusers-create2": "حساو کاریاری $3،وه دس $1 {{GENDER:$2|دروس بی}}",
        "logentry-newusers-byemail": "حساو کاریاری $3 وه دس $1 {{GENDER:$2|ره وندیاری بی}} و رازینه گواردن وا انجومانام کل بی",
-       "logentry-newusers-autocreate": "حساو $1  خودانجومن {{GENDER:$2|دروس بی}}",
+       "logentry-newusers-autocreate": "هساو $1  خودٱنجومٱن {{GENDER:$2|دۏرس بی}}",
        "logentry-rights-rights": "$1 اندوم بیین $3 نه د گرو $4 د $5 {{GENDER:$2|آلشت ده}}",
        "logentry-rights-rights-legacy": "$1 اندوم بیین $3 د گرو نه {{GENDER:$2|آلشت ده}}",
        "logentry-rights-autopromote": "$1 وه شکل خودانجوم $4 نه د $5 {{GENDER:$2|برد واروتر}}",
-       "logentry-upload-upload": "$1 {{GENDER:$2|سوار کرده}} $3",
-       "logentry-upload-overwrite": "$1 یه گل نسقه تازه د $3 نه {{GENDER:$2|سوار کرد}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|سڤار کردٱ}} $3",
+       "logentry-upload-overwrite": "$1 یاٛ نۏسخٱ تازٱ د $3 ناْ {{GENDER:$2|سڤار کرد}}",
        "logentry-upload-revert": "$1 $3 نه {{GENDER:$2|سوارکرد}}",
        "log-name-managetags": "سردیس دیوونداری کردن پهرستنومه",
        "log-description-managetags": "ای بلگه امور دیوونداری مربوط د [[Special:Tags|سردیسیا]] نه نومگه کاری می که. پهرستونمه فقط مینونه داری کنشتکاریاییه که وه دس یه گل دیوونداری و شکل دسی انجوم گرته بان؛شایت سردیسیا وه دس نرم افزار ویکی ره وندیاری بیه بان یا پاکسا بان بی یه که هیچ ورودی د ای پهرستنومه ثبت با.",
        "duration-seconds": "$1 {{PLURAL:$1|ثانیه|ثانیه یا}}",
        "duration-minutes": "$1 {{PLURAL:$1|دیقه|دیقه یا}}",
        "duration-hours": "$1 {{PLURAL:$1|ساعت |ساعتیا}}",
-       "duration-days": "$1{{PLURAL:$1|روز|روزیا}}",
+       "duration-days": "$1{{PLURAL:$1|رۊز|رۊزؽا}}",
        "duration-weeks": "$1 {{PLURAL:$1|هفته|هفته یا}}",
        "duration-years": "$1{{PLURAL:$1| سال|سالیا}}",
        "duration-decades": "$1 {{PLURAL:$1|دأھە|دأھە یا}}",
        "special-characters-title-endash": "خط فاصله",
        "special-characters-title-emdash": "خط فاصله",
        "special-characters-title-minus": "نشون کم کردن",
-       "mw-widgets-titleinput-description-new-page": "بلگه نیئش"
+       "mw-widgets-titleinput-description-new-page": "بلگه نیئش",
+       "randomrootpage": "بٱلگٱ بونچٱک تٱسادوفی"
 }
index ecddfc3..72d86c1 100644 (file)
        "revertpage": "Atmestas [[Special:Contributions/$2|$2]] ([[User talk:$2|Aptarimas]]) pakeitimas; sugrąžinta [[User:$1|$1]] versija",
        "revertpage-nouser": "Atversti pakeitimai paslėpto vartotojo, grąžino prieš tai buvusią versiją {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Atmesti {{GENDER:$3|$1}} pakeitimai;\ngrąžinta prieš tai buvusi {{GENDER:$4|$2}} versija.",
-       "rollback-success-notify": "Atmesti $1 pakeitimai;\ngrąžinta prieš tai buvusi $2 versija. [$3 Rodyti skirtumus]",
        "sessionfailure-title": "Sesijos klaida",
        "sessionfailure": "Atrodo yra problemų su jūsų prisijungimo sesija; šis veiksmas buvo atšauktas kaip atsargumo priemonė prieš sesijos vogimą.\nPrašome iš naujo pateikti formą.",
        "changecontentmodel": "Keisti puslapio turinio modelį",
        "namespace_association": "Susijusi vardų sritis",
        "tooltip-namespace_association": "Įjunkite šią parinktį, kad taip pat įtrauktumėte aptarimų arba temos sritį, susijusią su pasirinkta sritimi",
        "blanknamespace": "(Pagrindinis)",
-       "contributions": "{{GENDER:$1|Naudotojo}} indėlis",
+       "contributions": "{{GENDER:$1|Naudotojo|Naudotojos}} indėlis",
        "contributions-title": "{{GENDER:$1|Naudotojo|Naudotojos}} $1 indėlis",
        "mycontris": "Indėlis",
        "anoncontribs": "Indėlis",
        "contribsub2": "Naudotojas: {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "{{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Naudotojo paskyra „$1“ neužregistruota.",
        "nocontribs": "Jokie keitimai neatitiko šių kriterijų.",
        "uctop": "dabartinis",
        "tooltip-t-recentchangeslinked": "Paskutiniai keitimai puslapiuose, pasiekiamuose iš šio puslapio",
        "tooltip-feed-rss": "Šio puslapio RSS šaltinis",
        "tooltip-feed-atom": "Šio puslapio Atom šaltinis",
-       "tooltip-t-contributions": "Rodyti {{GENDER:$1|šio naudotojo}} keitimų sąrašą",
+       "tooltip-t-contributions": "Rodyti {{GENDER:$1|šio naudotojo|šios naudotojos}} keitimų sąrašą",
        "tooltip-t-emailuser": "Siųsti laišką {{GENDER:$1|šiam naudotojui}}",
        "tooltip-t-info": "Daugiau žinių apie šį puslapį",
        "tooltip-t-upload": "Įkelti rinkmenas",
        "logentry-delete-delete_redir": "$1 pervadindamas {{GENDER:$2|ištrynė}} buvusį nukreipimą $3",
        "logentry-delete-restore": "$1 atkūrė puslapį $3 ($4)",
        "logentry-delete-restore-nocount": "$1 {{GENDER:$2|atkūrė}} puslapį $3",
-       "restore-count-revisions": "{{PLURAL:$1|1 versija|versijų: $1}}",
+       "restore-count-revisions": "{{PLURAL:$1|$1 versija|$1 versijos|$1 versijų}}",
        "restore-count-files": "{{PLURAL:$1|1 failas|$1 failai}}",
        "logentry-delete-event": "$1 {{GENDER:$2|pakeitė}} matomumą {{PLURAL:$5|žurnalo įvykio|$5 žurnalo įvykių}} $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|pakeitė}} matomumą {{PLURAL:$5|versijos|$5 versijų}} puslapyje $3: $4",
        "authmanager-create-from-login": "Norėdami sukurti savo paskyrą užpildykite laukelius žemiau.",
        "authmanager-create-not-in-progress": "Paskyros kūrimas nevyksta arba buvo prarasti sesijos duomenys. Prašome pradėti iš naujo.",
        "authmanager-link-not-in-progress": "Paskyrų susiejimas nevyksta arba buvo prarasti sesijos duomenys. Prašome pradėti iš naujo.",
-       "authmanager-authplugin-setpass-failed-title": "Slaptažodžio keitimas nepavyko",
-       "authmanager-authplugin-setpass-bad-domain": "Negalimas domenas.",
        "authmanager-autocreate-noperm": "Automatinis paskyros kūrimas neleidžiamas.",
        "authmanager-autocreate-exception": "Automatinis paskyros kūrimas laikinai neleidžiamas dėl ankstesnių klaidų.",
        "authmanager-userdoesnotexist": "Vartotojo paskyrą „$1“ nėra registruota.",
index 73ff960..6d328e6 100644 (file)
        "index-category": "Indeksētās lapas",
        "noindex-category": "Neindeksētās lapas",
        "broken-file-category": "Lapas, kurās ir bojātas failu saites",
+       "categoryviewer-pagedlinks": "($1) ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "Par",
        "article": "Raksts",
        "newwindow": "(atveras jaunā logā)",
        "versionrequired": "Nepieciešamā ''MediaWiki'' versija: $1.",
        "versionrequiredtext": "Lai lietotu šo lapu, nepieciešama ''MediaWiki'' versija $1. Sk. [[Special:Version|versija]].",
        "ok": "Labi",
+       "pagetitle": "$1 — {{SITENAME}}",
+       "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "← $1",
        "retrievedfrom": "Saturs iegūts no \"$1\"",
        "youhavenewmessages": "Tev ir $1 (skatīt $2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Jums ir}} $1 no {{PLURAL:$3|cita dalībnieka|$3 dalībniekiem}} ($2).",
        "site-atom-feed": "$1 Atom padeve",
        "page-rss-feed": "\"$1\" RSS barotne",
        "page-atom-feed": "\"$1\" Atom barotne",
+       "feed-atom": "Atom",
+       "feed-rss": "RSS",
        "red-link-title": "$1 (lapa nepastāv)",
        "sort-descending": "Kārtot dilstošā secībā",
        "sort-ascending": "Kārtot augošā secībā",
        "createaccounterror": "Neizdevās izveidot kontu: $1",
        "nocookiesnew": "Lietotājvārds tika izveidots, bet tu neesi iegājis iekšā. {{SITENAME}} izmanto sīkdatnes (<i>cookies</i>), lai lietotāji varētu tajā ieiet. Tavs pārlūks nepieņem tās. Lūdzu, atļauj to pieņemšanu un tad nāc iekšā ar savu lietotājvārdu un paroli.",
        "nocookieslogin": "{{SITENAME}} izmanto sīkdatnes (<i>cookies</i>), lai lietotāji varētu ieiet tajā. Diemžēl tavs pārlūks tos nepieņem. Lūdzu, atļauj to pieņemšanu un mēģini vēlreiz.",
+       "nocookiesforlogin": "{{int:nocookieslogin}}",
        "noname": "Tu neesi norādījis derīgu lietotāja vārdu.",
        "loginsuccesstitle": "Pieteikšanās veiksmīga",
        "loginsuccess": "Tu esi ienācis {{grammar:lokatīvs|{{SITENAME}}}} kā \"$1\".",
        "user-mail-no-body": "Mēģināja sūtīt e-pastu ar tukšu vai nepamatoti īsu pamata daļu.",
        "changepassword": "Mainīt paroli",
        "resetpass_announce": "Lai pabeigtu pieslēgšanos, tev ir jāuzstāda jauna parole.",
+       "resetpass_text": "<!-- Šeit pievieno tekstu -->",
        "resetpass_header": "Mainīt konta paroli",
        "oldpassword": "Vecā parole",
        "newpassword": "Jaunā parole",
        "changeemail-none": "(nav)",
        "changeemail-password": "Jūsu {{SITENAME}} parole:",
        "changeemail-submit": "Mainīt e-pastu",
+       "changeemail-throttled": "Tu esi veicis pārāk daudz pieslēgšanās mēģinājumus.\nLūdzu, uzgaidi $1, pirms mēģini vēlreiz.",
        "changeemail-nochange": "Lūdzu, ievadi atšķirīgu jauno e-pasta adresi.",
        "resettokens-tokens": "Marķieri:",
        "resettokens-token-label": "$1 (šībrīža vērtība: $2)",
        "histfirst": "Senākās",
        "histlast": "Jaunākās",
        "historysize": "({{PLURAL:$1|$1 baiti|1 baits|$1 baiti}})",
-       "historyempty": "(tukša)",
+       "historyempty": "tukša",
        "history-feed-title": "Versiju hronoloģija",
        "history-feed-description": "Šīs wiki lapas versiju hronoloģija",
        "history-feed-item-nocomment": "$1 : $2",
        "localtime": "Vietējais laiks:",
        "timezoneuseserverdefault": "Lietot viki noklusēto ($1)",
        "timezoneuseoffset": "Cita (norādi starpību zemāk)",
+       "timezone-useoffset-placeholder": "Vērtības piemēri: \"-07:00\" vai \"01:00\"",
        "servertime": "Servera laiks šobrīd:",
        "guesstimezone": "Izmantot datora sistēmas laiku",
        "timezoneregion-africa": "Āfrika",
        "group-autoconfirmed": "Automātiski apstiprinātie dalībnieki",
        "group-bot": "Boti",
        "group-sysop": "Administratori",
-       "group-interface-admin": "Interfeisa administrators",
+       "group-interface-admin": "Interfeisa administratori",
        "group-bureaucrat": "Birokrāti",
        "group-suppress": "Cenzētāji",
        "group-all": "(visi)",
        "rcfilters-filter-humans-label": "Cilvēki (ne boti)",
        "rcfilters-filter-humans-description": "Cilvēku veikti labojumi.",
        "rcfilters-filtergroup-reviewstatus": "Pārskatīšanas statuss",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Labojumi, kas nav manuāli vai automātiski atzīmēti kā pārbaudīti.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Nepārbaudīti",
+       "rcfilters-filter-reviewstatus-manual-description": "Labojumi, kas manuāli atzīmēti kā pārbaudīti.",
        "rcfilters-filter-reviewstatus-manual-label": "Manuāli pārbaudīti",
+       "rcfilters-filter-reviewstatus-auto-description": "Pieredzējušu dalībnieku labojumi, kuru devums tiek automātiski atzīmēts kā pārbaudīts.",
        "rcfilters-filter-reviewstatus-auto-label": "Automātiski pārbaudīti",
        "rcfilters-filtergroup-significance": "Nozīmīgums",
        "rcfilters-filter-minor-label": "Maznozīmīgi labojumi",
        "delete-confirm": "Dzēst \"$1\"",
        "delete-legend": "Dzēšana",
        "historywarning": "'''Brīdinājums:''' Lapai, ko tu gatavojies dzēst, ir vēsture ar aptuveni $1 {{PLURAL:$1|versijām|versiju|versijām}}:",
-       "historyaction-submit": "Rādīt",
+       "historyaction-submit": "Rādīt versijas",
        "confirmdeletetext": "Tu tūlīt no datubāzes dzēsīsi lapu vai attēlu, kā arī to iepriekšējās versijas. Lūdzu, apstiprini, ka tu tiešām to vēlies darīt, ka tu apzinies sekas un ka tu to dari saskaņā ar [[{{MediaWiki:Policy-url}}|vadlīnijām]].",
        "actioncomplete": "Darbība pabeigta",
        "actionfailed": "Darbība neizdevās",
        "delete-toobig": "Šai lapai ir liela izmaiņu hronoloģija, vairāk nekā $1 {{PLURAL:$1|versijas|versija|versijas}}.\nŠādu lapu dzēšana ir atslēgta, lai novērstu nejaušus traucējumus {{grammar:lokatīvs|{{SITENAME}}}}.",
        "deleting-backlinks-warning": "'''Brīdinājums:''' uz lapu, ko grasies izdzēst, ved [[Special:WhatLinksHere/{{FULLPAGENAME}}|saites no citām lapām]].",
        "rollback": "Novērst labojumus",
+       "rollback-confirmation-no": "Atcelt",
        "rollbacklink": "novērst",
        "rollbacklinkcount": "atcelt $1 {{PLURAL:$1|labojumus|labojumu|labojumus}}",
        "rollbacklinkcount-morethan": "atcelt vairāk kā $1 {{PLURAL:$1|labojumus|labojumu|labojumus}}",
        "logentry-protect-protect": "$1 {{GENDER:$2|aizsargāja}} $3 $4",
        "logentry-upload-upload": "$1 {{GENDER:$2|augšupielādēja}} $3",
        "logentry-upload-overwrite": "$1 augšupielādēja jaunu $3 versiju",
-       "logentry-upload-revert": "$1 {{GENDER:$2|augšupielādēja}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|atjaunoja}} $3 uz vecāku versiju",
        "logentry-managetags-create": "$1 {{GENDER:$2|izveidoja}} iezīmi \"$4\"",
        "log-name-tag": "Iezīmju žurnāls",
        "rightsnone": "(nav)",
        "log-action-filter-upload-upload": "Jauna augšupielāde",
        "log-action-filter-upload-overwrite": "Atkārtota augšupielāde",
        "authmanager-create-disabled": "Kontu veidošana ir atspējota.",
-       "authmanager-authplugin-setpass-bad-domain": "Nederīgs domēns.",
        "authmanager-email-label": "E-pasts",
        "authmanager-email-help": "E-pasta adrese",
        "authmanager-realname-label": "Tavs īstais vārds",
index 0cda762..5e8ff1a 100644 (file)
        "revertpage": "सम्पादन आपस कएल गेल [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]]) सँ अन्तिम संशोधन धरि एकरा द्वारा [[User:$1|$1]]।",
        "revertpage-nouser": "(प्रयोक्ताक नाम हटा देल गेल अछि) द्वारा केल गेल संपादनकेँ फेरसँ पुरान स्थितिमे आनि कऽ एकर पहिलुक [[User:$1|$1]] सँ बनल संस्करणकेँ फेरसँ ताजा संस्करण बनाऊ।",
        "rollback-success": "{{GENDER:$3|$1}} क संपादन हटाबी;\n{{GENDER:$4|$2}} द्वारा संपादित अन्तिम अवतरण क पुनर्स्थापित करू।",
-       "rollback-success-notify": "$1द्वारा पूर्ववत सम्पादन;\n$2द्वारा केल अन्तिम अवतरण पर वापस। [$3 परिवर्तन देखाबी]",
        "sessionfailure-title": "सत्र विफल भ गेल",
        "sessionfailure": "एहन लागैत अछि जे अहां के लागिन सत्र में कोनो त्रुटि अछि. सत्र अपहरण से बचाबय  सं सावधानीक लेल अहां के अहि क्रियाकलाप क रद्द क देल गेल. अहां पाछां के पृष्ठ पर जौउ आ पृष्ठ के फेर सं लोड क दोबारा कोशिश करू.",
        "changecontentmodel": "पृष्ठ सामग्री मोडल परिवर्तन करी",
        "log-action-filter-upload-upload": "नया अपलोड",
        "log-action-filter-upload-overwrite": "फैनसे अपलोड",
        "authmanager-create-disabled": "लेखा निर्माण अशक्त कएल",
-       "authmanager-authplugin-setpass-bad-domain": "अमान्य जालस्थल।",
        "authmanager-userdoesnotexist": "प्रयोक्ता खाता \"$1\" पंजीकृत नै अछि।",
        "authmanager-email-label": "इमेल",
        "authmanager-email-help": "ई-पत्र ठेगान:",
index 66dc8ab..873ac47 100644 (file)
        "revertpage": "Suntingane [[Special:Contributions/$2|$2]] ([[User talk:$2|dhiskusi]]) dibalekna maring versi pungkasan sekang [[User:$1|$1]]",
        "revertpage-nouser": "Mbalekna suntingan sekang (jeneng panganggo dibusek) ming revisi pungkasan sekang [[User:$1|$1]]",
        "rollback-success": "Mbalekna suntingane $1;\ndibalekna ming revisi pungkasan sekang $2.",
-       "rollback-success-notify": "Mbalekna besutan sekang $1; owah mbalik nggo revisi mburi sekang $2. [$3 Deleng owahane]",
        "sessionfailure-title": "Sèsi gagal",
        "sessionfailure": "Ketone lagi ana masalah karo sesi log-e Rika;\nloge Rika wis dibatalna nggo nyegah pambajakan.\nMonggo mbalik ming kaca sedurunge, dibaleni gole muatna kaca (reload) lan jajal diunggahna maning.",
        "protectlogpage": "Log pangreksan",
index 0b3a7fa..d4e3e7c 100644 (file)
        "badarticleerror": "Tsy azo atao eto amin'ity pejy ity io asa io.",
        "cannotdelete": "Tsy afaka fafàna ny pejy na ny rakitra « $1 ».\nMety efa nataon'ny hafa angamba ny famafàna.",
        "cannotdelete-title": "Tsy afaka mamafa ny pejy \"$1\"",
+       "delete-scheduled": "Nokasaina hofafàna ny pejy \"$1\". Andraso azafady.",
        "delete-hook-aborted": "Famafana nofoanan'ny itatra.\nTsy nanome fanazavana.",
        "no-null-revision": "Tsy nahaforona famerenana poaka aty ho an'ny pejy \"$1\"",
        "badtitle": "Tsy mety ny lohateny",
        "customcssprotected": "Tsy afaka manova ity pejy CSS ity ianao satria misy ny safidy manokan'ny mpikambana hafa.",
        "customjsonprotected": "Tsy manana alalalana manova ity pejy JSON ity ianao satria misy ny safidin'olon-kafa izy ity.",
        "customjsprotected": "Tsy afaka manova ity pejy JavaScript ity inaao satria misy ny safidin'ny mpikambana hafa.",
+       "sitecssprotected": "Tsy manana alalana manova ity pejy CSS ity ianao satria mety mahakasika ny mpitsidika rehetra izany fiovana izany.",
+       "sitejsonprotected": "Tsy manana alalana manova ity pejy JSON ity ianao satria mety mahakasika ny mpitsidika rehetra izany fiovana izany.",
+       "sitejsprotected": "Tsy manana alalana manova ity pejy JavaScript ity ianao satria mety mahakasika ny mpitsidika rehetra izany fiovana izany.",
        "mycustomcssprotected": "Tsy manana ny alalana ahafahana manova ity pejy CSS ity ianao.",
        "mycustomjsonprotected": "Tsy manana alalana manova ity pejy JSON ity ianao.",
        "mycustomjsprotected": "Tsy manana ny alalana ahafahana manova ity pejy JavaScript ity ianao.",
        "ns-specialprotected": "Tsy afaka ovaina ny pejy anatin'ny toeran'anarana « {{ns:special}} » .",
        "titleprotected": "Voaaron'i [[User:$1|$1]] ity lohateny ity mba tsy hamorona pejy mitondra ity anarana ity.\nNy antony napetraka dia : <em>$2</em>.",
        "filereadonlyerror": "Tsy afaka manova ny rakitra \"$1\" satria famakiana ihany no azo atao amin'i \"$2\".\n\nNy antony nomen'ny mpandrindra nanidy azy: \"$3\".",
+       "invalidtitle": "Lohateny tsy manarak'endrika",
        "invalidtitle-knownnamespace": "Lohateny tsy miady amin'ny fepetra miaraka amin'ny anaram-balam-pejy \"$2\" ary soratra \"$3\"",
        "invalidtitle-unknownnamespace": "Lohateny tsy ekena miaraka amin'ny laharana anaran-tsehatra $1 ary soratra \"$2\"",
        "exception-nologin": "Tsy tafiditra",
        "badretype": "Tsy mitovy ny tenimiafina nampidirinao.",
        "usernameinprogress": "Efa am-panatanterahana ny famoronan-kaonty amin'ity anaram-pikambana ity.\nMiandrasa azafady.",
        "userexists": "Efa miasa io anaram-pikambana natsofokao io.\nAnarana hafa safidiana.",
+       "createacct-normalization": "Novaina ho \"$2\" ny anaram-pikambanao noho ny fetra ara-teknika.",
        "loginerror": "Tsy fetezana teo amin'ny fidirana",
        "createacct-error": "Hadisoana tam-pamoronana ny kaonty",
        "createaccounterror": "Tsy afaka mamorona kaonty : $1",
        "passwordtooshort": "{{PLURAL:}}Fohy loatra io tenimiafina io.\nFarafahakeliny tokony hisy litera $1 ny tenimiafina.",
        "passwordtoolong": "Tsy azo atao ho lava noho ny soratra {{PLURAL:$1|iray|$1}} ny tenimiafina.",
        "passwordtoopopular": "Tsy azo ampiasana ny tenimiafina ampiasaina matetika. Misafidiana tenimiafina sarotra vinavinaina kokoa.",
+       "passwordinlargeblacklist": "Anaty lisitra tenimiafina tena ampiasaina matetika ilay tenimiafina natsofokao. Mampiasà tenimiafina tokana kokoa azafady.",
        "password-name-match": "Tsy maintsy samihafa ny solonanaranao sy ny tenimiafinao tompoko.",
        "password-login-forbidden": "Norarana ny fampiasana io anaram-pikambana ary io tenimiafina io.",
        "mailmypassword": "Hamerina ny tenimiafina",
        "postedit-confirmation-created": "Voaforona ilay pejy.",
        "postedit-confirmation-restored": "Tafaverina ilay pejy.",
        "postedit-confirmation-saved": "Voatahiry ny fanovanao.",
+       "postedit-confirmation-published": "Voatahiry ny fiovana nataonao.",
        "edit-already-exists": "Tsy afaka amboarina ilay pejy vaovao.\nEfa misy izy.",
        "defaultmessagetext": "Hafatra raha tsy misy",
        "content-failed-to-parse": "Tsy naha-parse ny votoatin'i $2 ho an'ny modely $1 : $3",
        "editpage-invalidcontentmodel-text": "Andrefim-botoatiny \"$1\" tsy zaka.",
        "editpage-notsupportedcontentformat-title": "Tsy zaka io andrefim-botoatiny io",
        "editpage-notsupportedcontentformat-text": "Tsy zakan'ny maodelim-botoatiny $1 ny firafi-botoatiny $1",
+       "slot-name-main": "Loha",
        "content-model-wikitext": "wiki-soratra",
        "content-model-text": "soratra tsotra",
        "content-model-javascript": "JavaScript",
        "post-expand-template-argument-warning": "Tandremo : Manana mpihazaka endrika tsy afaka ampidirina ity pejy ity.\nAo aorian'ny fivelarana, mety namoaka valy lava loatra angamba izy, ary tsy nampidirina tato noho izany antony izany.",
        "post-expand-template-argument-category": "Pejy misy parametatra endrika hadino",
        "parser-template-loop-warning": "endrika vono hita tao : [[$1]]",
+       "template-loop-category": "Pejy ahitana endrika mitsingerina",
+       "template-loop-category-desc": "Ahitana endrika mifanondro ity pejy ity, izany hoe misy endrika miantso ny tenany amin'ny fomba rekiorsiva",
+       "template-loop-warning": "<strong>Tandremo</strong>: Ity pejy ity dia miandro an'i [[:$1]] izay mahatonga fifanondroan-tena (antso rekiorsiva tsy misy fahataperana).",
        "parser-template-recursion-depth-warning": "Fetran'ny halalin'ny fiantsoana endrika voahoatra ($1).",
        "language-converter-depth-warning": "Mihoatra ny fetran-kalalin'ny mpamadika teny ($1)",
        "node-count-exceeded-category": "Pejy izay ahitana fihoatran'ny isam-patotra (node)",
        "revdelete-submit": "Hampiharina amin'ny versiona nofidiana {{PLURAL:$1}}",
        "revdelete-success": "'''Voaova soa aman-tsara ny fahitana ny versiona.'''",
        "revdelete-failure": "'''Ny fisehon'ity versiona ity dia tsy afaka natao update'''\n$1",
-       "logdelete-success": "Voaova soa aman-tsara ny fisehon'ny laogy.",
+       "logdelete-success": "Voaova ny fahitan'ny laogy.",
        "logdelete-failure": "Tsy afaka novaina ny fisehon'ny laogy\n$1",
        "revdel-restore": "Ovay ny fahitàna",
        "pagehist": "Tantaran'ilay pejy",
        "diff-multi-manyusers": "Tsy naseho ny antiôna $1{{PLURAL:}} nataon'ny mpikambana $2.",
        "difference-missing-revision": "Tsy hita ny versiona $2{{PLURAL:$2||}} ny fahasamihafanna ($1) an'ity pejy ity.\n\nVokatry ny fanarahana rohy fampitahana lany daty mankany amy pejy efa voafafa izan . Ho hita eo amin'ny [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} laogim-pamafàna] ny antsipirihany.",
        "searchresults": "Valim-pikarohana",
+       "search-filter-title-prefix-reset": "Hikaroka ny pejy rehetra",
        "searchresults-title": "Valim-pikarohana ho an'ny « $1 »",
        "titlematches": "Mifanitsy amin'ny lohatenin'ny lahatsoratra",
        "textmatches": "Mifanitsy amin'ny votoatin'ny pejy",
        "search-file-match": "(miady amin'ny votoatin-drakitra)",
        "search-suggest": "Andramo : $1",
        "search-rewritten": "Maneho vokam-pikarohana ho an'i $1. Hisolo ary hikaroka momba an'i $2.",
-       "search-interwiki-caption": "zandri-tetikasa",
+       "search-interwiki-caption": "Valiny avy amin'ny tetikasa rahavavy",
        "search-interwiki-default": "Valiny amin'ny $1 :",
        "search-interwiki-more": "(be kokoa)",
        "search-interwiki-more-results": "Valiny be kokoa",
        "showingresultsinrange": "Maneho hatramin'ny {{PLURAL:$1|valim-pikarohana <strong>1</strong> |valim-pikarohana <strong>$1</strong>}} amin'ny elanelana #<strong>$2</strong> hatramin'i #<strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Valim-pikarohana <strong>$1</strong> amin'ny <strong>$3</strong>| Valim-pikarohana <strong>$1 - $2</strong> amin'ny <strong>$3</strong>}}",
        "search-nonefound": "Tsy nahitana valiny ilay fanontaniana.",
+       "search-nonefound-thiswiki": "Tsy nisy valiny miady amin'ny hataka eto amin'ity tranonkala ity.",
        "powersearch-legend": "Fikarohana havanana",
        "powersearch-ns": "Hitady anatin'ny anaran-tsehatra :",
        "powersearch-togglelabel": "Marihana:",
        "prefs-editwatchlist-clear": "Handio ny lisitra arahanao",
        "prefs-watchlist-days": "Isa ny andro haseho anatin'ny lisitra ny pejy arahana-maso",
        "prefs-watchlist-days-max": "$1 {{PLURAL:$1|}} andro farafahabetsany",
-       "prefs-watchlist-edits": "Isa ny fanovana aseho eo amin'ny fanaraha-maso navelatra:",
+       "prefs-watchlist-edits": "Isan'ny fiovana lehibe indrindra aseho amin'ny pejy arahana:",
        "prefs-watchlist-edits-max": "Isa fara-fahabetsany : 1000",
        "prefs-watchlist-token": "token ho an'ny lisitry ny pejy arahi-maso:",
+       "prefs-watchlist-managetokens": "Hikirakira token",
        "prefs-misc": "Hafa",
        "prefs-resetpass": "Hanova tenimiafina",
-       "prefs-changeemail": "Hanova ny adiresy imailaka",
+       "prefs-changeemail": "Hanova na hanala adiresy mailaka",
        "prefs-setemail": "Hampiditra adiresy imailaka",
        "prefs-email": "Safidy mikasika ny imailaka",
        "prefs-rendering": "Fampisehoana",
        "default": "tsipalotra",
        "prefs-files": "Rakitra",
        "prefs-custom-css": "CSS manokana",
+       "prefs-custom-json": "JSON manokana",
        "prefs-custom-js": "Javascript manokana",
        "prefs-common-config": "JavaScript ary CSS zaraina ho an'ny fiankanjoana rehetra:",
        "prefs-reset-intro": "Azonao ampiasaina ity pejy ity mba hamerina ny safidinao amin'izay safidy tsipalotr'ilay sehatra. Tsy azo averina io.",
        "prefs-dateformat": "Endriky ny daty",
        "prefs-timeoffset": "Elanelana ora",
        "prefs-advancedediting": "Antsipirihan-tsafidy",
+       "prefs-developertools": "Fitaovam-panitatra",
        "prefs-editor": "Mpanova",
        "prefs-preview": "Topi-maso",
        "prefs-advancedrc": "Antsipirihan-tsafidy",
        "prefs-advancedwatchlist": "Antsipirihan-tsafidy",
        "prefs-displayrc": "safidim-tseho",
        "prefs-displaywatchlist": "Safidin-tseho",
+       "prefs-changesrc": "Fiovana aseho",
+       "prefs-changeswatchlist": "Fiovana aseho",
+       "prefs-pageswatchlist": "Pejy arahana",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Diff",
        "prefs-help-prefershttps": "Hihatra amin'ny fidiranao manaraka ity safidy ity.",
        "prefswarning-warning": "Efa nanova tamin'ny safidinao tsy mbola voatahiry ianao. Raha miala amin'ity pejy ity amin'ny alalan'ny fanindriana an'i \"$1\" ianao dia tsy ho voavao ny safidinao.",
        "prefs-tabs-navigation-hint": "Torohevitra: afaka mampiasa ny zana-tsipika havia ary havanana ianao ho an'ny fitetezana ny vakizoro ao amin'ny lisi-bakizoro",
-       "userrights": "Fandrindràna ny fahefahan'ny mpikambana",
+       "userrights": "Zo sy alalan'ny mpikambana",
        "userrights-lookup-user": "Hisafidy mpikambana",
        "userrights-user-editname": "Manomeza solonanarana:",
        "editusergroup": "Hampiditra vondrom-pikambana",
        "group-autoconfirmed": "Mpikambana voamarina",
        "group-bot": "Mpikambana rôbô",
        "group-sysop": "Mpandrindra",
+       "group-interface-admin": "Mpandrindra ny interfasy",
        "group-bureaucrat": "Borôkraty",
        "group-suppress": "Mpametra",
        "group-all": "(izy rehetra)",
        "group-autoconfirmed-member": "{{GENDER:$1|Mpikambana voamarina ho azy}}",
        "group-bot-member": "{{GENDER:$1|Mpikambana rôbô}}",
        "group-sysop-member": "{{GENDER:$1|Mpandrindra}}",
+       "group-interface-admin-member": "mpandrindra amin'ny interfasy$1",
        "group-bureaucrat-member": "{{GENDER:$1|Borôkraty}}",
        "group-suppress-member": "{{GENDER:$1|mpamafa}}",
        "grouppage-user": "{{ns:project}}:Mpikambana",
        "grouppage-autoconfirmed": "{{ns:project}}:Mpikambana Voamafy",
        "grouppage-bot": "{{ns:project}}:Mpikambana rôbô",
        "grouppage-sysop": "{{ns:project}}:Mpandrindra",
+       "grouppage-interface-admin": "{{ns:project}}:Mpandrindra amin'ny interfasy",
        "grouppage-bureaucrat": "{{ns:project}}:Borôkraty",
        "grouppage-suppress": "{{ns:project}}:Mpamafa",
        "right-read": "Mamaky ny pejy",
-       "right-edit": "Manova ny pejy",
+       "right-edit": "Manova pejy",
        "right-createpage": "Manamboatra pejy (tsy pejin-dresaka)",
        "right-createtalk": "Mamorona pejin-dresaka",
        "right-createaccount": "Manamboatra kaonty",
        "right-editusercss": "Manova ny rakitra CSS ny mpikambana hafa",
        "right-edituserjson": "Manova ny rakitra JSON an'ny mpikambana hafa",
        "right-edituserjs": "Manova ny rakitra JS an'ny mpikambana hafa",
+       "right-editsitecss": "Manova CSS ampiasaina maneran-tranonkala",
+       "right-editsitejson": "Manova JSON ampiasaina maneran-tranonkala",
+       "right-editsitejs": "Manova JavaScript ampiasaina maneran-tranonkala",
        "right-editmyusercss": "Manova ny rakitra CSS-nao",
        "right-editmyuserjson": "Manova ny rakitra JSON-nao",
        "right-editmyuserjs": "Manova ny rakitra JavaScript-nao",
        "right-siteadmin": "Manidy sy manokatra ny banky angona",
        "right-override-export-depth": "Mamoaka ny pejy miaraka amin'ny zana-pejy hatramin'ny ambaratonga fahadimy",
        "right-sendemail": "Mandefa imailaka any amin'ny mpikambana hafa",
-       "right-managechangetags": "Mamorona ary mamafa [[Special:Tags|balizy]] ao amin'ny banky angona",
+       "right-managechangetags": "Mamorona ary mampiasa na manajanona ny fampiasana [[Special:Balizy|balizy]]",
        "grant-generic": "\"$1\" vondron-jo",
        "grant-group-page-interaction": "Mifanakalo amin'ny pejy",
        "grant-group-file-interaction": "Mifanakalo amin'ny hainoamanjery",
        "grant-editmycssjs": "Manova CSS/Javascript anao",
        "grant-editmyoptions": "Hanova ny safidim-pikambanao",
        "grant-editmywatchlist": "Manova ny lisitry ny pejy arahana",
+       "grant-editsiteconfig": "Manova CSS/JS ampiasaina maneran-tranonkala ary amim-pikambana manokana",
        "grant-editpage": "Manova ny pejy efa misy",
        "grant-editprotected": "Manova ny pejy voaaro",
        "grant-highvolume": "Manova pejy ambongadiny",
        "recentchanges-legend-heading": "<strong>Maribolana:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (jereo koa ny [[Special:NewPage|lisitry ny pejy vaovao]])",
        "recentchanges-submit": "Aseho",
+       "rcfilters-tag-remove": "Hanala '$1'",
+       "rcfilters-legend-heading": "<strong>Lisitry ny fanafohezan-teny:</strong>",
        "rcfilters-activefilters": "Sivana miasa",
+       "rcfilters-activefilters-hide": "Afenina",
+       "rcfilters-activefilters-show": "Aseho",
        "rcfilters-activefilters-hide-tooltip": "Hanafina ny faritry ny sivana miasa",
        "rcfilters-advancedfilters": "Sivana havanana kokoa",
        "rcfilters-days-title": "Andro vao haingana",
+       "rcfilters-hours-title": "Ora vao haingana",
        "rcfilters-quickfilters": "Sivana notehirizina",
        "rcfilters-quickfilters-placeholder-title": "Tsy mbola misy sivana notehirizina",
        "rcfilters-savedqueries-defaultlabel": "Sivana voatahiry",
        "rcfilters-savedqueries-rename": "Hanova ny anarana",
        "rcfilters-savedqueries-setdefault": "Ampiasaina ho solon'ny tsy misy",
-       "rcfilters-savedqueries-remove": "Esorina",
+       "rcfilters-savedqueries-remove": "Fafàna",
        "rcfilters-savedqueries-new-name-label": "Anarana",
        "rcfilters-savedqueries-new-name-placeholder": "Visavisao eto ny tanjon'ilay sivana",
-       "rcfilters-savedqueries-apply-label": "Hamorona rohy haingana",
+       "rcfilters-savedqueries-apply-label": "Hamorona sivana",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Hamorona sivana solon'ny tsy misy",
        "rcfilters-savedqueries-cancel-label": "Avela",
+       "rcfilters-savedqueries-add-new-title": "Hitahiry ny parametatry ny sivana ankehitriny",
        "rcfilters-savedqueries-already-saved": "Efa voatahiry ireo sivana ireo. Ovay ny parametatra hamoronana sivana voatahiry vaovao.",
        "rcfilters-restore-default-filters": "Hamerina sivana ampiasaina raha tsy misy",
        "rcfilters-clear-all-filters": "Hamafa ny sivana rehetra",
+       "rcfilters-show-new-changes": "Hijery ny fiovana vao haingana",
        "rcfilters-search-placeholder": "Hanivana ny fiovana farany (tetezo na manomboha manoratra)",
        "rcfilters-invalid-filter": "Sivana tsy azo raisina",
        "rcfilters-empty-filter": "Tsy misy sivana miasa. Aseho avokoa ireo fandraisan'anjara.",
        "rcfilters-filterlist-title": "Sivana",
-       "rcfilters-filterlist-whatsthis": "Inona ity?",
-       "rcfilters-filterlist-feedbacklink": "Mamoaka hevitra mikasika ny sivana vaovao (beta)",
+       "rcfilters-filterlist-whatsthis": "Maneha ahoana ity?",
+       "rcfilters-filterlist-feedbacklink": "Lazao naay izay hevitrao momba ireo fitaovam-panivanana ireo",
        "rcfilters-highlightbutton-title": "Hampibaribary ny valiny",
        "rcfilters-highlightmenu-title": "Hisafidy loko",
        "rcfilters-highlightmenu-help": "Misafidy loko hampanabaribariana ilay tondro",
        "rcfilters-filterlist-noresults": "Tsy nahitana sivana",
        "rcfilters-noresults-conflict": "Tsy nahitana valiny satria tsy mifanaraka ny mason-tsivana",
        "rcfilters-filtergroup-authorship": "Manova ny tompon-tsoratra",
-       "rcfilters-filter-editsbyself-label": "Ny fiovanao",
-       "rcfilters-filter-editsbyself-description": "Fiovana nataonao",
-       "rcfilters-filter-editsbyother-label": "Fiovana nataon'ny hafa",
-       "rcfilters-filter-editsbyother-description": "Fiovana noforonin'ny mpikambana hafa (tsy ianao).",
+       "rcfilters-filter-editsbyself-label": "Fiovana nataonao",
+       "rcfilters-filter-editsbyself-description": "Ny fandraisan'anjaranao.",
+       "rcfilters-filter-editsbyother-label": "Ny fiovana nataon'ny sasany",
+       "rcfilters-filter-editsbyother-description": "Fiovana rehetra afa-tsy ny anao.",
        "rcfilters-filtergroup-userExpLevel": "Lentan'ny traikefa (ho an'ireo mpikambana nisoratra anarana ihany)",
        "rcfilters-filter-user-experience-level-registered-label": "Nisoratra anarana",
        "rcfilters-filter-user-experience-level-registered-description": "Mpanova tafiditra.",
        "log-action-filter-protect-protect": "Fiarovana",
        "log-action-filter-protect-unprotect": "Fanalana fiarovana",
        "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.",
index c0b5156..cf2bde4 100644 (file)
                        "아라",
                        "Sergey Ivanov",
                        "Irus",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Сергей Иванов"
                ]
        },
-       "tog-underline": "Ð\9aÑ\83зе ÐºÑ\8bлвеÑ\80-влакÑ\8bм Ó±Ð»Ñ\8bÑ\87Ñ\8bн Ñ\83дÑ\8bÑ\80алаÑ\88?",
-       "tog-hideminor": "Ð\9fÑ\8bÑ\82аÑ\80Ñ\82Ñ\8bÑ\88 Ñ\82Ó§Ñ\80лаÑ\82Ñ\8bмаÑ\88-влак Ñ\80адам Ð³Ñ\8bÑ\87 Ð¸Ð·Ð¸ Ñ\82Ó§Ñ\80лаÑ\82Ñ\8bмаÑ\88-влакÑ\8bм ÐºÐ¾Ñ\80аҥдаш",
-       "tog-hidepatrolled": "Тергыме тӧрлатымаш-влакым пытартыш тӧрлатымаш лӱмерыште шылташ",
+       "tog-underline": "Ð\9aÑ\8bлвеÑ\80лам Ó±Ð»Ñ\8bÑ\87 Ñ\83дÑ\8bÑ\80алмаÑ\88:",
+       "tog-hideminor": "У Ñ\82Ó§Ñ\80лаÑ\82Ñ\8bмаÑ\88-влак Ñ\80адам Ð³Ñ\8bÑ\87 Ð¸Ð·Ð¸ Ñ\82Ó§Ñ\80лаÑ\82Ñ\8bмаÑ\88-влакÑ\8bм Ñ\88Ñ\8bлÑ\82аш",
+       "tog-hidepatrolled": "Тергыме тӧрлатымаш-влакым у тӧрлатымаш лӱмерыште шылташ",
        "tog-newpageshidepatrolled": "Тергыме лаштык-влакым у лаштык лӱмерыште шылташ",
        "tog-hidecategorization": "Лаштык категоризацийым шылташ",
        "tog-extendwatchlist": "Чыла вашталтышым, а пытартыш гына огылым ончыкташлан эскерыме лӱмерым кугемдаш",
        "underline-always": "Кеч-кунам",
        "underline-never": "Нигунам",
        "underline-default": "Браузерысе келыштарымаш дене пайдаланаш",
-       "sunday": "Рушарня",
-       "monday": "Шочмо",
-       "tuesday": "Ð\9aушкыжмо",
-       "wednesday": "Ð\92ӱргече",
-       "thursday": "Ð\98зарня",
-       "friday": "Ð\9aугарня",
-       "saturday": "Шуматкече",
+       "sunday": "рушарня",
+       "monday": "шочмо",
+       "tuesday": "кушкыжмо",
+       "wednesday": "вӱргече",
+       "thursday": "изарня",
+       "friday": "кугарня",
+       "saturday": "шуматкече",
        "sun": "Рш",
        "mon": "Шч",
        "tue": "Кш",
        "thu": "Из",
        "fri": "Кг",
        "sat": "Шм",
-       "january": "Шорыкйол",
-       "february": "Ð\9fургыж",
-       "march": "Ó°ярня",
-       "april": "Ð\92ӱдшор",
-       "may_long": "Ð\90га",
-       "june": "Ð\9fеледыш",
-       "july": "Сӱрем",
-       "august": "Сорла",
-       "september": "Ð\98дым",
-       "october": "Шыжа",
-       "november": "Ð\9aылме",
-       "december": "Теле",
-       "january-gen": "Шорыкйол",
-       "february-gen": "Ð\9fургыж",
-       "march-gen": "Ó°ярня",
-       "april-gen": "Ð\92ӱдшор",
-       "may-gen": "Ð\90га",
-       "june-gen": "Ð\9fеледыш",
-       "july-gen": "Сӱрем",
-       "august-gen": "Сорла",
-       "september-gen": "Ð\98дым",
-       "october-gen": "Шыжа",
-       "november-gen": "Ð\9aылме",
-       "december-gen": "Теле",
-       "jan": "Шорыкйол",
-       "feb": "Ð\9fÑ\83Ñ\80гÑ\8bж",
-       "mar": "Ó°Ñ\8fÑ\80нÑ\8f",
-       "apr": "Ð\92ӱдÑ\88оÑ\80",
-       "may": "Ð\90га",
-       "jun": "Ð\9fеледÑ\8bÑ\88",
-       "jul": "Сӱрем",
-       "aug": "Сорла",
-       "sep": "Ð\98дÑ\8bм",
-       "oct": "Шыжа",
-       "nov": "Ð\9aÑ\8bлме",
-       "dec": "Теле",
+       "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": "пÑ\80г",
+       "mar": "Ó±Ñ\80н",
+       "apr": "вдÑ\88",
+       "may": "ага",
+       "jun": "плд",
+       "jul": "срм",
+       "aug": "срл",
+       "sep": "идм",
+       "oct": "шыж",
+       "nov": "клм",
+       "dec": "тел",
        "pagecategories": "{{PLURAL:$1|Категорий|Категорий-влак}}",
        "category_header": "\"$1\" категорийыште лаштык-влак",
        "subcategories": "Ӱлылкатегорий-влак",
        "timezoneregion-asia": "Азий",
        "timezoneregion-atlantic": "Атлантик таптеҥыз",
        "timezoneregion-australia": "Австралий",
-       "timezoneregion-europe": "Ð\95вÑ\80опо",
+       "timezoneregion-europe": "Ð\95вÑ\80опа",
        "timezoneregion-indian": "Индий таптеҥыз",
        "allowemail": "Вес ушнышо-влак деч электрон почтым налаш кӧнаш",
        "prefs-searchoptions": "Кычалаш",
        "newpages": "У лаштык-влак",
        "newpages-username": "Пайдаланышын лӱмжӧ:",
        "ancientpages": "Пытартыш тӧрталтымаш-влак почеш ойырымо статья-влак",
-       "move": "Лӱмым вашталташ",
+       "move": "Лаштык лӱмым вашталташ",
        "movethispage": "Тиде лаштыкын лӱмжым вашталташ",
        "pager-newer-n": "{{PLURAL:$1|1=вес|вес}}",
        "pager-older-n": "{{PLURAL:$1|1=ончычсо|ончычсо}}",
        "watch": "Эскераш",
        "watchthispage": "Тиде лаштыкым эскераш",
        "unwatch": "Эскерыман огыл",
-       "unwatchthispage": "ЭÑ\81кеÑ\80Ñ\8bмÑ\8bм Ñ\87аÑ\80наÑ\88",
+       "unwatchthispage": "Эскерымым чараш",
        "watchlist-details": "Эскерымаш лӱмерыштет $1 {{PLURAL:$1|лаштык}}, каҥашымаш лаштык-влакым шотлыде",
        "wlshowlast": "Пытартыш $1 шагат $2 кечылан  ончыкташ",
        "wlshowhidecategorization": "лаштык категоризацийым",
        "protect-cantedit": "Тый тиде лаштыкын шыгыремдымашыжым тӧрлатен от керт, тидлан тылат кертеж пуалтын огыл.",
        "protect-otherreason": "Вес/ешартыш амал:",
        "protect-otherreason-op": "вес/ешартыш амал",
-       "restriction-type": "Ð\9aеÑ\80Ñ\82еж:",
-       "restriction-level": "ТÑ\8bгай Ñ\88Ñ\8bгÑ\8bÑ\80емдаÑ\88:",
+       "restriction-type": "Ð\9fÑ\80ава-влак:",
+       "restriction-level": "Ð\9fÑ\8bÑ\80аÑ\88 Ð»Ð¸Ð¹Ð¼Ðµ ÐºÓ±ÐºÑ\88Ñ\8bÑ\82:",
        "undeletelink": "ончалаш/тӧрлатен шындаш",
        "undeleteviewlink": "ончыкташ",
        "undelete-search-submit": "Кычал",
index 8f7c4a2..1f0dc81 100644 (file)
                        "Ardzun",
                        "Amjad Khan",
                        "Zakiy",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "S Kartika"
                ]
        },
-       "tog-underline": "Garibawahi tautan:",
-       "tog-hideminor": "Suruakan suntiangan ketek di parubahan baru",
-       "tog-hidepatrolled": "Suruakan suntiangan nan lah dipatroli di parubahan tabaru",
-       "tog-newpageshidepatrolled": "Suruakan laman nan lah dipatroli dari daftar laman baru",
-       "tog-hidecategorization": "Suruakan pankgategorian halaman",
-       "tog-extendwatchlist": "Kambangan daftar pantau untuak mancaliak kasado parubahan, indak nan baru se",
+       "tog-underline": "Garisbawahi tautan:",
+       "tog-hideminor": "Suruakkan suntiangan ketek di parubahan baru",
+       "tog-hidepatrolled": "Suruakkan suntiangan nan lah dipatroli di parubahan tabaru",
+       "tog-newpageshidepatrolled": "Suruakkan laman nan lah dipatroli dari daftar laman baru",
+       "tog-hidecategorization": "Suruakkan pangkategorian laman",
+       "tog-extendwatchlist": "Kambangan daftar pantau untuak mancaliak kasado parubahan, bukan nan baru se",
        "tog-usenewrc": "Kalompokkan suntiangan di tampilan parubahan paliang baru jo daftar pantauan badasarkan halaman",
        "tog-numberheadings": "Agiah nomor judul sacaro otomatis",
        "tog-editondblclick": "Suntiang laman jo klik duo kali (paralu JavaScript)",
-       "tog-editsectiononrightclick": "Aktipan bagian panyuntiangan jo mangklik kanan pado judul bagian",
+       "tog-editsectiononrightclick": "Aktifkan bagian panyuntiangan dengan caro mangklik kanan pado judul bagian",
        "tog-watchcreations": "Tambahan laman nan den buek jo gambar nan den unggah ka daftar pantau",
        "tog-watchdefault": "Tambahan laman jo gambar nan den suntiang ka daftar pantau",
        "tog-watchmoves": "Tambahan laman jo gambar nan den pindah ka daftar pantau",
        "tog-watchlisthideminor": "Suruakan suntiangan ketek pado daftar pantau",
        "tog-watchlisthideliu": "Suruakan suntiangan pangguno masuak log pado daftar pantau",
        "tog-watchlistreloadautomatically": "Muek ulang daftar pantauan sacaro otomatih katiko sabuah sariangan baubah (paralu JavaScript)",
+       "tog-watchlistunwatchlinks": "Tambahkan panando pantau/indak pantau ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) untuak mamantau laman nan diubah (JavaScript diparaluan untuak manggunoan tombol ko)",
        "tog-watchlisthideanons": "Suruakan suntiangan pangguno anonim pado daftar pantau",
        "tog-watchlisthidepatrolled": "Suruakan suntiangan tapatroli pado daftar pantau",
+       "tog-watchlisthidecategorization": "Suruakan kategorisasi laman",
        "tog-ccmeonemails": "Kiriman Ambo salinan surel nan dikiriman ka urang lain",
        "tog-diffonly": "Jan tampilan isi laman di bawah pabedoan suntiangan",
        "tog-showhiddencats": "Tunjuakan kategori tasuruak",
        "tog-norollbackdiff": "Jan tampilan pabedoan sasudah malakukan pangambalian",
        "tog-useeditwarning": "Ingekan denai kok denai maninggakan laman suntiang sabalun manyimpan parubahan",
+       "tog-prefershttps": "Selalu gunokan koneksi aman katiko masuak log",
        "underline-always": "Taruih",
        "underline-never": "Indak pernah",
        "underline-default": "Kulik atau pangaturan paramban web",
        "newwindow": "(bukak di jendela baru)",
        "cancel": "Batalkan",
        "moredotdotdot": "Lainnyo...",
-       "morenotlisted": "Salabiahnyo...",
+       "morenotlisted": "Daftar ko mungkin indak langkok.",
        "mypage": "Laman",
        "mytalk": "Maota",
        "anontalk": "Rundiang IP ko",
        "searcharticle": "Tuju",
        "history": "Riwayaik laman",
        "history_short": "Riwayaik",
+       "history_small": "riwayaik",
        "updatedmarker": "diubah samanjak kunjuangan tarakhia ambo",
        "printableversion": "Versi cetak",
        "permalink": "Pautan parmanen",
        "view": "Baco",
        "view-foreign": "Caliak di $1",
        "edit": "Suntiang",
+       "edit-local": "Suntiang sumber deskripsi lokal",
        "create": "Buek",
        "create-local": "Tambah sumber deskripsi lokal",
        "delete": "Hapuih",
        "talk": "Rundiang",
        "views": "Caliak",
        "toolbox": "Pakakeh",
+       "tool-link-userrights": "Ubah kalompok {{GENDER:$1|user}}",
+       "tool-link-userrights-readonly": "Caliak kalompok {{GENDER:$1|user}}",
+       "tool-link-emailuser": "Kirim surel ka {{GENDER:$1|panggun}} ko",
        "imagepage": "Caliak laman berkas",
        "mediawikipage": "Caliak laman pasan",
        "templatepage": "Caliak laman templat",
        "jumptonavigation": "navigasi",
        "jumptosearch": "cari",
        "view-pool-error": "Maaf, server sadang kalabiahan baban.\nBanyak bana nan barusaho mancaliak laman ko.\nTunggu santa koq nio mancubo baliak ka laman ko.\n\n$1",
+       "generic-pool-error": "Maaf, server sadang kalabiahan baban.\nBanyak bana nan barusaho mancaliak laman ko.\nTunggu santa kok nio mancubo baliak ka laman ko.",
        "pool-timeout": "Abih wakatu",
        "pool-queuefull": "Antrian panuah",
        "pool-errorunknown": "Kasalahan indak jaleh",
+       "pool-servererror": "Layanan penghitung pool ini tidak tersedia ($1).",
+       "poolcounter-usage-error": "Galat penggunaan: $1",
        "aboutsite": "Tantang {{SITENAME}}",
        "aboutpage": "Project:Tantang_{{SITENAME}}",
        "copyright": "Isi tasadio dalam $1",
        "disclaimers": "Sanggahan umum",
        "disclaimerpage": "Project:Sanggahan umum",
        "edithelp": "Bantuan suntiangan",
+       "helppage-top-gethelp": "Bantuan",
        "mainpage": "Palanta",
        "mainpage-description": "Palanta",
        "policy-url": "Project:Kabijakan jo padoman",
        "hidetoc": "suruakan",
        "collapsible-collapse": "Ketekan",
        "collapsible-expand": "Kambangan",
+       "confirmable-confirm": "Lai yakin {{GENDER:$1|you}}?",
+       "confirmable-yes": "Yo",
+       "confirmable-no": "Indak",
        "thisisdeleted": "Caliak atau kambalian $1?",
        "viewdeleted": "Caliak $1?",
        "restorelink": "{{PLURAL:$1|$1 suntiangan}} lah dihapuih",
        "nospecialpagetext": "<strong>Sanak mamintak laman istimewa nan indak sah.</strong>\n\nDaftar laman istimewa nan sah dapek dicaliak di [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Kasalahan",
        "databaseerror": "Kasalahan basis data",
+       "databaseerror-function": "Fungsi: $1",
        "databaseerror-error": "تېروتنه: $1",
+       "transaction-duration-limit-exceeded": "Untuak mancagah panundoan replikasi yang tinggi, pangiriman ko dibatalan karano lamo panulihan $1 malabiahi bateh $2.\nJiko sanak nio maubah banyak hal dalam sakali ubah, cubo lakuan dalam operasi yang labiah ketek.",
        "laggedslavemode": "Paringatan: Laman mungkin indak barisi parubahan tabaru.",
        "readonly": "Basis data dikunci",
        "enterlockreason": "Masuakkan alasan panguncian, tamasuak pakiraan bilo kunci akan dibuka",
        "missingarticle-rev": "(revisi#: $1)",
        "missingarticle-diff": "(Bedo: $1, $2)",
        "readonly_lag": "Basis data alah dikunci otomatis salagi basis data sakunder malakukan sinkronisasi jo basis data utamo",
+       "nonwrite-api-promise-error": "Kapalo HTTP 'Promise-Non-Write-API-Action' alah dikirim tapi permintaan dibuek untuak model panulihan API.",
        "internalerror": "Kasalahan internal",
        "internalerror_info": "Kasalahan internal: $1",
+       "internalerror-fatal-exception": "Pangacualian fatal dalam mangetik \"$1\"",
        "filecopyerror": "Indak dapek manyalin berkas \"$1\" ke \"$2\".",
        "filerenameerror": "Indak dapek maubah namo berkas \"$1\" manjadi \"$2\".",
        "filedeleteerror": "Indak dapek mahapuih berkas \"$1\".",
        "directorycreateerror": "Indak dapek mambuek direktori \"$1\".",
+       "directoryreadonlyerror": "Direktori \"$1\" hanyo-dibaco.",
+       "directorynotreadableerror": "Direktori \"$1\" indak bisa dibaco.",
        "filenotfound": "Indak dapek manamukan berkas \"$1\".",
        "unexpected": "Nilai di lua jangkauan: \"$1\"=\"$2\".",
        "formerror": "Kasalahan: Indak dapek mangiriman formulir",
        "badarticleerror": "Tindakan iko indak dapek dilaksanakan di laman iko.",
        "cannotdelete": "Laman atau berkas \"$1\" indak dapek dihapuih.\nMungkin alah dihapuih jo urang lain.",
        "cannotdelete-title": "Indak dapek mangapuih laman \"$1\"",
+       "delete-scheduled": "Laman \"$1\" dijadwalan untuak diapuih. Mohon basaba.",
        "delete-hook-aborted": "Pengapusan batal jo hook.\nIndak ado keterangan.",
        "badtitle": "Judul indak sah",
        "badtitletext": "Pamintaan judul laman indak sah, kosong, atau antarbaso atau antarwiki nan salah sambuang. Mungkin juo ado kandungan karakter nan indak buliah digunoan untuak judul.",
+       "title-invalid-empty": "Judul halaman yang dimintak kosong atau hanyo barisi namo sabuah ruang namo.",
+       "title-invalid-utf8": "Judul halaman yang dimintak barisi rangkaian UTF-8 yang indak sah.",
+       "title-invalid-interwiki": "Judul laman yang dimintak barisi pranala diantaro wiki yang indak bisa digunoan dalam judul.",
+       "title-invalid-talk-namespace": "Judul laman yang dimintak marujuak ka halaman pambicaroan yang indak dapek tasadio.",
+       "title-invalid-characters": "Judul laman yang dimintak barisi karakter yang indak sah:\"$1\".",
+       "title-invalid-relative": "Judul manganduang alaman relatif. Halaman relatif (./, ../) indak sah, karano dapek mangalami kagagalan katiko ditangani dek paramban pangguno.",
+       "title-invalid-magic-tilde": "Judul halaman manganduang rangkaian tilda yang indak sah (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": "Judul halaman panjang bana. Harusnyo indak buliah labiah dari $1 {{PLURAL:$1|byte|bytes}} di pangodean UTF-8.",
+       "title-invalid-leading-colon": "Judul laman yang dimintak dimulai dek tando titiak duo tu indak sah.",
        "perfcached": "Data barikuik ko diambiak dari singgahan dan mungkin indak data nan baru. Nan tabanyak dari {{PLURAL:$1|$1 hasilnyo}} ado di singgahan.",
        "perfcachedts": "Data barikuik ko singgahan, dan tarakhia dipabarui tanggal $1. Nan tabanyak dari tanggal {{PLURAL:$1|$1}}, hasilnyo ado di singgahan.",
        "querypage-no-updates": "Pamutakhiran dari laman ko sadang dimatian. Data nan ado di siko kini ko indak akan dimuaik ulang.",
        "viewyourtext": "Sanak dapek mancaliak jo mangkopi sumber untuak \"suntiangan sanak\" ka laman ko",
        "protectedinterface": "Laman ko baisi teks antarmuko untuak digunoan dek parangkaik lunak di wiki ko sajo, dan alah dikunci untuak maindaan kasalahan. \nUntuak manambah atau maubah tajamahan di kasado wiki, harap gunoan [https://translatewiki.net/ translatewiki.net], yaitu proyek palokalan MediaWiki.",
        "editinginterface": "'''Paringatan:''' Sanak manyuntiang laman nan digunoan untuak manyadiokan teks antarmuko untuak parangkaik lunak.\nParubahan teks ko akan mampangaruhi tampilan pado antarmuko pangguno untuak pangguno lain.\nUntuak tajamahan, harap gunoan [https://translatewiki.net/wiki/Main_Page?setlang=min translatewiki.net], proyek palokalan MediaWiki.",
+       "translateinterface": "Untuak manambah atau maubah sadolah wiki, mohon gunoan [https://translatewiki.net/ translatewiki.net], proyek palokalan MediaWiki.",
        "cascadeprotected": "Laman iko alah dilindungi dari panyuntiangan karano disartokan di {{PLURAL:$1|laman}} barikuik nan alah dilindungi jo opsi \"runtun\":\n$2",
        "namespaceprotected": "Sanak indak mampunyoi hak akses untuak manyuntiang laman di ruang namo '''$1'''.",
        "customcssprotected": "Sanak indak mampunyoi izin untuak maubah laman CSS iko, karano manganduang pangaturan pribadi pangguno lain.",
+       "customjsonprotected": "Sanak indak mampunyoi izin untuak maubah laman JSON ko karano barisi pangaturan pribadi pangguno lain.",
        "customjsprotected": "Sanak ndak mampunyo izin untuak maubah laman JavaScript iko, karano manganduang pangaturan pribadi pangguno lain.",
+       "sitecssprotected": "Sanak indak mampunyoi izin untuak maubah halaman CSS ko karano bisa mampangaruhi sadolah pangunjuang.",
+       "sitejsonprotected": "Sanak indak mampunyoi izin untuak maubah halaman JSON ko karano mampangaruhi sadolah pangunjuang.",
+       "sitejsprotected": "Sanak indak mampunyoi izin untuak maubah halaman JavaScript karano mampangaruhi sadolah pangunjuang.",
+       "mycustomcssprotected": "Sanak indak mampunyoi izin untuak maubah halaman CSS ko.",
+       "mycustomjsonprotected": "Sanak indak mampunyoi izin untuak manyuntiang halaman JSON ko.",
+       "mycustomjsprotected": "Sanak indak mampunyoi izin untuak manyuntiang halaman JavaScript ko.",
+       "myprivateinfoprotected": "Sanak indak mampunyoi izin untuak manyuntiang informasi pribadi Sanak.",
+       "mypreferencesprotected": "Sanak indak mampunyoi izin untuak manyuntiang preferensi Sanak.",
        "ns-specialprotected": "Laman istimewa indak dapek disuntiang.",
        "titleprotected": "Judul ko dilinduangi dari dibuek jo [[User:$1|$1]].\nAlasannyo adolah <em>$2</em>.",
-       "filereadonlyerror": "Indak bisa mangubah berkas \"$1\" karano repositori berkas \"$2\" dalam mode baco-sajo.\n\nPangurus nan manguncinyo manawarkan panjalehan: \"$3\"",
+       "filereadonlyerror": "Indak bisa mangubah berkas \"$1\" karano repositori berkas \"$2\" dalam mode baco-sajo.\n\nPanguruih nan manguncinyo manawarkan panjalehan: \"$3\"",
+       "invalidtitle": "Judul indak sah",
        "invalidtitle-knownnamespace": "↓Judul nan indak sah jo ruangnamo \"$2\" dan teks \"$3\"",
        "invalidtitle-unknownnamespace": "Judul nan tak sah jo nomor ruang namo indak diketahui $1 dan teks \"$2\"",
        "exception-nologin": "Indak masuak log",
        "exception-nologin-text": "Laman ko hanyo dapek disuntiang dek pangguno nan mandaftar.",
+       "exception-nologin-text-manual": "Silakan $1 untuak mangakses halaman atau tindakan ko.",
        "virus-badscanner": "Kasalahan konfigurasi: pamindai virus indak dikenal: ''$1''",
        "virus-scanfailed": "Pamindaian gagal (kode $1)",
        "virus-unknownscanner": "Antivirus indak dikenal:",
        "logouttext": "'''Sanak alah kalua log dari sistem.'''\n\nSanak dapek taruih manggunoan {{SITENAME}} sacaro anonim, atau Sanak dapek <span class='plainlinks'>[$1 masuak log liak]</span> sabagai pangguno nan samo atau pangguno nan lain.\nParhatian bahawa bara laman mungkin masih taruih manunjukkan bahawa Sanak masih masuak log sampai Sanak mambarasihan singgahan panjelajah web Sanak.",
+       "cannotlogoutnow-title": "Indak bisa kalua kini",
+       "cannotlogoutnow-text": "Indak bisa kalua katiko manggunoan $1.",
        "welcomeuser": "Salamaik datang, $1!",
        "welcomecreation-msg": "Akun Sanak alah dibuek. Jan lupo maubah [[Special:Preferences|pangaturan {{SITENAME}}]] Sanak.",
        "yourname": "Namo pangguno:",
        "userlogin-yourname": "Namo pangguno",
        "userlogin-yourname-ph": "Masuakan namo pangguno",
+       "createacct-another-username-ph": "Masuakan namo pangguno",
        "yourpassword": "Kato sandi:",
        "userlogin-yourpassword": "Kato sandi",
        "userlogin-yourpassword-ph": "Masuakan kato sandi",
        "createacct-yourpasswordagain-ph": "Masuakan lai kato sandi",
        "userlogin-remembermypassword": "Biakan ambo tetap masuak",
        "userlogin-signwithsecure": "Gunoan server aman",
+       "cannotlogin-title": "Indak bisa masuak",
+       "cannotlogin-text": "Indak mamungkinkan untuak masuak.",
+       "cannotloginnow-title": "Indak bisa masuak kini",
+       "cannotloginnow-text": "Indak bisa masuak katiko manggunoan $1.",
+       "cannotcreateaccount-title": "Indak bisa mambuek akun",
+       "cannotcreateaccount-text": "Mambuek akun sacaro langsuang indak diaktifan di wiki ko.",
        "yourdomainname": "Domain Sanak:",
        "password-change-forbidden": "Sanak indak dapek maubah kato sandi di wiki ko.",
        "externaldberror": "Alah tajadi kasalahan otentikasi basis data eksternal atau Sanak indak diizinan malakuan pabaruan tahadok akun eksternal Sanak.",
        "login": "Masuak log",
+       "login-security": "Buktian indentitas sanak",
        "nav-login-createaccount": "Masuak log / buek akun",
        "logout": "Kalua log",
        "userlogout": "Kalua log",
        "createaccount": "Buek akun",
        "userlogin-resetpassword-link": "Lupo kato sandi Sanak?",
        "userlogin-helplink2": "Bantuan masuak log",
+       "userlogin-loggedin": "Sanak alah masuak sabagai {{GENDER:$1|$1}}. Gunoan formulir di bawah untuak masuak sabagai pangguno lain.",
+       "userlogin-reauth": "Sanak harus masuak baliak untuk mambuktian Sanak adolah {{GENDER:$1|$1}}.",
+       "userlogin-createanother": "Buek akun yang lain",
        "createacct-emailrequired": "Alamaik surel",
        "createacct-emailoptional": "Alamaik surel (opsional)",
        "createacct-email-ph": "Masuakan alamaik surel Sanak",
+       "createacct-another-email-ph": "Masuakan alamaik surel",
        "createaccountmail": "Pakai kato sandi sumbarang samantaro, lalu kirim ka alamaik surel nan di bawah ko",
+       "createaccountmail-help": "Indak dapek digunoan untuak mambuek akun urang lain tanpa tau kato sandinyo.",
        "createacct-realname": "Namo asli (opsional)",
        "createacct-reason": "Alasan",
        "createacct-reason-ph": "Manga Sanak mambuek akun lain",
        "createacct-submit": "Buek akun Sanak",
        "createacct-another-submit": "ګڼون جوړول",
+       "createacct-continue-submit": "Lanjuikan mambuek akun",
+       "createacct-another-continue-submit": "Lanjuikan mambuek akun",
        "createacct-benefit-heading": "{{SITENAME}} dibuek dek urang-urang saroman Sanak.",
        "createacct-benefit-body1": "{{PLURAL:$1|suntiangan}}",
        "createacct-benefit-body2": "{{PLURAL:$1|laman}}",
        "createacct-benefit-body3": "{{PLURAL:$1|panyuntiang}} tarakhia",
        "badretype": "Kato sandi nan Sanak masuakan salah.",
        "userexists": "Namo pangguno nan dipiliah alah tapakai.\nPiliah namo nan lain.",
+       "createacct-normalization": "Namo pangguno sanak akan disasuaian manjadi \"$2\" karano batasan teknis.",
        "loginerror": "Kasalahan masuak log",
        "createacct-error": "Pambuatan akun gagal",
        "createaccounterror": "Indak dapek mambuek akun: $1",
        "nocookiesnew": "Akun pangguno alah dibuek, tapi Sanak alun masuak log.\n{{SITENAME}} manggunokan cookies untuak log pangguno.\nPangaturan cookie Sanak nonaktif.\nAktifan dulu, sasudah tu baru masuak log jo namo pangguno dan kato sandi baru Sanak.",
        "nocookieslogin": "{{SITENAME}} manggunokan cookies untuak log pangguno.\nPangaturan cookie paramban Sanak nonaktif.\nAktifan dulu dan cubo baliak.",
        "nocookiesfornew": "Akun pangguno indak dibuek karano kami indak dapek mamastian sumbernyo.\nPastian Sanak alah mangaktifan cokies, lalu muek ulang laman ko dan cubo baliak.",
+       "createacct-loginerror": "Akun alah salasai dibuek tapi Sanak indak dapek langsuang masuak sacaro otomatis. Mohon taruihan ka [[Special:UserLogin|manual login]].",
        "noname": "Namo pangguno nan Sanak masuakan indak sah.",
        "loginsuccesstitle": "Bahasil masuak log",
        "loginsuccess": "'''Sanak kini lah masuak log di {{SITENAME}} sabagai \"$1\".'''",
        "wrongpassword": "Kato sandi nan Sanak masuakan salah. Cubolah baliak.",
        "wrongpasswordempty": "Sanak indak mamasuakan kato sandi. Cubolah baliak.",
        "passwordtooshort": "Kato sandi paliang indak harus tadiri dari {{PLURAL:$1|$1 karakter}}.",
+       "passwordtoolong": "Kato sandi indak buliah labiah dari {{PLURAL:$1|1 character|$1 characters}}.",
+       "passwordtoopopular": "Kato sandi yang umum indak dapek digunoan. Mohon piliah kato sandi yang labiah sulik untuak ditakok.",
+       "passwordinlargeblacklist": "Kato sandi yang dimasuakan adolah kato sandi yang umum. Mohon gunoan kato sandi yang labiah unik.",
        "password-name-match": "Kato sandi Sanak harus babedo dari namo pangguno Sanak.",
        "password-login-forbidden": "Panggunoan namo pangguno dan sandi ko alah dilarang.",
        "mailmypassword": "Kirim kato sandi baru",
        "createaccount-text": "Sasaurang alah mambuek sabuah akun untuak alamaik surel Sanak di {{SITENAME}} ($4) jo namo \"$2\" dan kato sandi \"$3\". Sanak dianjuakan untuak masuak log dan mangganti kato sandi Sanak kini.\n\nSanak dapek mangacuahkan pasan ko jikok akun ko dibuek dek ado kasalahan.",
        "login-throttled": "Sanak alah bakali-kali mancubo masuak log.\nTunggulah sabanta sabalun mancubo baliak.",
        "login-abort-generic": "Proses masuak Sanak indak barasil - Dibatalan",
+       "login-migrated-generic": "Akun sanak alah dipindahan, namo pangguno Sanak alah indak tadaftar ini wiki ko.",
        "loginlanguagelabel": "Baso: $1",
        "suspicious-userlogout": "Pamintaan Sanak untuak kalua log ditulak karano tampaknyo dikirim oleh paramban nan rusak atau proksi panyinggah.",
        "pt-login": "Masuak log",
        "pt-login-button": "Masuak log",
+       "pt-login-continue-button": "Lanjuikan masuak log",
        "pt-createaccount": "Buek akun",
        "pt-userlogout": "Kalua log",
        "php-mail-error-unknown": "Kasalahan nan indak jaleh dalam fungsi mail() PHP",
        "user-mail-no-addy": "Mancubo mangirim surel tanpa alamaik surel.",
        "user-mail-no-body": "Mancubo mangirim surel kosong atau pasan talalu pendek",
        "changepassword": "Tuka kato sandi",
-       "resetpass_announce": "Sanak alah masauk log jo kode samantaro nan dikirim malalui surel. Untuak malanjuikan, Sanak harus mamasuakan kato sandi baru di siko:",
+       "resetpass_announce": "Untuak manyalasaian masuak log, Sanak harus mamasuakan kato sandi baru.",
        "resetpass_header": "Tuka kato sandi akun",
        "oldpassword": "Kato sandi lamo:",
        "newpassword": "Kato sandi baharu:",
        "retypenew": "Ketik ulang kato sandi baharu:",
        "resetpass_submit": "Atua kato sandi dan masuak log",
-       "changepassword-success": "Kato sandi Sanak alah berhasil dituka!\nKini mamproses masuak log Sanak...",
+       "changepassword-success": "Kato sandi Sanak alah berhasil dituka!",
+       "changepassword-throttled": "Sanak alah acok bana mancubo masuak log. Mohon tunggu $1 sabalun mancubo baliak.",
+       "botpasswords": "Kato sandi bot",
+       "botpasswords-disabled": "Kato sandi bot indak diaktifan.",
+       "botpasswords-no-central-id": "Untuak manggunoan kato sandi bot, Sanak harus masuak log ka akun yang alah disentralisasi.",
+       "botpasswords-existing": "Kato sandi bot tasadio",
+       "botpasswords-createnew": "Buek kato sandi bot yang baru",
+       "botpasswords-editexisting": "Ubah kato sandi bot yang alah ado",
+       "botpasswords-label-needsreset": "(kato sandi paralu di atua ulang)",
+       "botpasswords-label-appid": "Namo bot:",
+       "botpasswords-label-create": "Buek",
+       "botpasswords-label-update": "Pabarui",
+       "botpasswords-label-cancel": "Batalan",
+       "botpasswords-label-delete": "Hapuih",
+       "botpasswords-label-resetpassword": "Setel ulang kato sandi",
+       "botpasswords-bad-appid": "Namo bot \"$1\" indak sah.",
+       "botpasswords-insert-failed": "Gagal manambah namo bot \"$1\". Alah ditambahan sabalun iko?",
+       "botpasswords-update-failed": "Gagal mampabarui namo bot \"$1\". Pernah dihapuih sabalunnyo?",
+       "botpasswords-created-title": "Kato sandi bot alah dibuek",
+       "botpasswords-created-body": "Kato sandi untuak bot \"$1\" dari {{GENDER:$2|user}} \"$2\" berhasil dibuek.",
+       "botpasswords-updated-title": "Kato sandi bot alah dipabarui",
+       "botpasswords-updated-body": "Kato sandi untuak bot \"$1\" dari {{GENDER:$2|user}} \"$2\" alah dipabarui.",
+       "botpasswords-deleted-title": "Kato sandi bot dihapuih",
+       "botpasswords-deleted-body": "Kato sandi untuak bot \"$1\" dari {{GENDER:$2|user}} \"$2\" berhasil dihapuih.",
+       "botpasswords-restriction-failed": "Bateh dalam kato sandi mangahalangi masuak log ko.",
+       "botpasswords-invalid-name": "Namo pangguno yang diaagiah indak manganduang pamisah kato sandi bot (\"$1\").",
+       "botpasswords-not-exist": "Pangguno \"$1\" indak mampunyoi kato sandi bot banamo \"$2\".",
+       "botpasswords-needs-reset": "Kato sandi untuak bot \"$2\" dari {{GENDER:$1|user}} \"$1\" harus di atur ulang.",
+       "botpasswords-locked": "Sanak indak dapek masuak log jo kato sando bot karano akun Sanak dikunci.",
        "resetpass_forbidden": "Kato sandi indak dapek dituka",
+       "resetpass_forbidden-reason": "Kato sandi indak dapek dituka:$1",
        "resetpass-no-info": "Sanak harus masuak log untuak mangakses laman iko sacara langsuang.",
        "resetpass-submit-loggedin": "Tuka kato sandi",
        "resetpass-submit-cancel": "Batalkan",
        "resetpass-wrong-oldpass": "Kato sandi indak sah.\nSanak mungkin alah berhasil mangganti kato sandi Sanak atau alah maminto kato sandi samantaro nan baharu.",
+       "resetpass-recycled": "Mohon ubah kato sandi Sanak jo nan lain dari kato sandi kini ko.",
+       "resetpass-temp-emailed": "Sanak masuak log jo kode samantaro yang disurelan. Untuak manyalasaian masuak log, atur ulang kato sandi baru disiko:",
        "resetpass-temp-password": "Kato sandi samantaro:",
        "resetpass-abort-generic": "Parubahan kato sandi alah dibatalan dek ekstensi.",
+       "resetpass-expired": "Kato sandi sanak alah kadaluarsa. Mohon atur ulang kato sandi baru untuak masuak log.",
+       "resetpass-expired-soft": "Kato sandi sanak alah kadaluarsa jo paralu diubah. Mohon piliah kato sandi baru, atau takan \"{{int:authprovider-resetpass-skip-label}}\" untuak maatur ulang di wakatu lain.",
+       "resetpass-validity": "Kato sandi Sanak indak sah:$1",
+       "resetpass-validity-soft": "Kato sandi sanak indak sah:$1\n\nMohon piliah kato sandi baru, atau takan \"{{int:authprovider-resetpass-skip-label}}\" untuak maubah di wakatu nan lain.",
        "passwordreset": "Setel ulang kato sandi",
        "passwordreset-text-one": "Lengkapkan formulir ko untuak manuka baliak kato sandi Sanak.",
        "passwordreset-text-many": "{{PLURAL:$1|Masuakan data di bawah ko untuak manuka baliak kato sandi Sanak.}}",
        "passwordreset-emailtext-ip": "Sasaurang (mungkin Sanak, dari alamaik IP $1) mamintak parubahan kato sandi untuak {{SITENAME}} ($4). {{PLURAL:$3|Akun}} barikuik takaik jo alamaik surel ko:\n\n$2\n\n{{PLURAL:$3|Sandi samantaro}} barikuik akan habih masonyo dalam {{PLURAL:$5|$5 ari}}.\nSanak harus masuak dan mamiliah sandi baru. Jikok urang lain mambuek pamintaan ko atau jikok Sanak ingek sandi awal dan indak nio maubahnyo, Sanak dapek mangacuahkan pasan ko dan taruih manggunoan kato sandi lamo.",
        "passwordreset-emailtext-user": "Sasaurang (mungkin Sanak, dari alamaik IP $1) mamintak parubahan kato sandi untuak {{SITENAME}} ($4).\n{{PLURAL:$3|Akun}} barikuik takaik jo alamaik surel ko:\n\n$2\n\n{{PLURAL:$3|Sandi samantaro}} barikuik akan habih masonyo dalam {{PLURAL:$5|$5 ari}}.\nSanak harus masuak dan mamiliah sandi baru. Jikok urang lain mambuek pamintaan ko atau jikok Sanak ingek sandi awal dan indak nio maubahnyo, Sanak dapek mangacuahkan pasan ko dan taruih manggunoan kato sandi lamo.",
        "passwordreset-emailelement": "Namo pangguno: \n$1\n\nSandi samantaro: \n$2",
-       "passwordreset-emailsentemail": "Surel parubahan kato sandi alah dikirim.",
-       "changeemail": "Tuka alamaik surel.",
-       "changeemail-header": "Ganti alamaik surel.",
+       "passwordreset-emailsentemail": "Jiko alamaik surel ko bahubuangan jo akun Sanak, surel parubahan kato sandi akan dikirim.",
+       "passwordreset-emailsentusername": "Jiko ado alamaik surel yang bahubuangan jo namo pangguno ko, surel untuak ma atur ulang kato sandi akan dikirim.",
+       "passwordreset-invalidemail": "Alamaik surel indak sah",
+       "passwordreset-nodata": "Namo pangguno ataupun alamai surel indak diaagiahan",
+       "changeemail": "Tuka atau hapuih alamaik surel.",
+       "changeemail-header": "Langkoki formulir ko untuak maubah alamaik surel Sanak. Jiko nio mahapuih sadolah alamaik surel yang bahubuangan jo akun Sanak, kosongan alamaik surek katiko maisi formulir.",
        "changeemail-no-info": "Sanak harus masuak log untuak mangakses laman ko.",
        "changeemail-oldemail": "Alamat surel kini:",
        "changeemail-newemail": "Alamat surel baru:",
+       "changeemail-newemail-help": "Kolom ko harus dikosongan jiko Sanak nio mahapuih alamaik surel. Sanak indak dapek maatur ulang kato sandi yang talupo jo indak dapek manarimo surel dari wiki ko jiko alamaik surel dihapuih.",
        "changeemail-none": "(indak ado)",
        "changeemail-password": "Sandi {{SITENAME}} Sanak:",
        "changeemail-submit": "Ganti surel.",
+       "changeemail-throttled": "Sanak alah acok bana mancubo masuak log. Mohon tunggu $1 sabalun mancubo baliak.",
+       "changeemail-nochange": "Mohon masuakan alamaik surel yang lain.",
+       "resettokens": "Ubah token",
+       "resettokens-token-label": "$1 (nilai saat ini:$2)",
        "bold_sample": "Teks taba",
        "bold_tip": "Teks taba",
        "italic_sample": "Teks miriang",
        "sig_tip": "Tandotangan sanak jo wakatu",
        "hr_tip": "Garih mandata",
        "summary": "Ikhtisar:",
-       "subject": "Subjek/judul:",
+       "subject": "Perihal:",
        "minoredit": "Suntiangan ketek",
        "watchthis": "Pantau laman ko",
        "savearticle": "Simpan",
+       "savechanges": "Simpan parubahan",
        "publishpage": "Tabikan laman",
        "publishchanges": "Tabikan parubahan",
+       "savearticle-start": "Simpan laman...",
+       "savechanges-start": "Simpan parubahan...",
+       "publishpage-start": "Tabikan laman...",
+       "publishchanges-start": "Tabikan parubahan...",
        "preview": "Caliak",
        "showpreview": "Pratonton",
        "showdiff": "Parubahan",
+       "blankarticle": "\"{{int:authprovider-resetpass-skip-label}}\"Paringatan:</strong> Laman yang Sanak buek kosong.\nJiko Sanak manakan \"$1\" baliak, laman tu akan dibuek tanpa ado isinyo.",
        "anoneditwarning": "'''Ingek:''' Sanak alun masuak log.\nAlamat IP sanak tacatat pado riwayaik suntiangan laman ko. Kok Sanak <strong>[$1 log in]</strong> atau <strong>[$2 mambuek akun]</strong>, suantiang Sanak ka didistribusian kapado namo pangguno Sanak, sarato baragam kauntuangan lainnyo.",
        "anonpreviewwarning": "''Sanak alun masuak log. Manyimpan laman akan manyababkan alamaik IP Sanak tacatat pado riwayat suntiangan laman iko.''",
        "missingsummary": "'''Paringatan:''' Sanak indak mamasuakan ringkasan panyuntiangan. Jikok Sanak baliak manakan tombol Simpan, suntiangan Sanak akan disimpan tanpa ringkasan panyuntiangan.",
-       "missingcommenttext": "Masuakan komentar Sanak di bawah ko.",
+       "selfredirect": "<strong>Paringatan:</strong> Sanak mangalihan halaman ko ka halaman samulo. Sanak bisa jadi maagiah tujuan pangalihan yang salah, atau manyuntiang halaman yang salah.\nJiko Sanak manakan \"$1\" baliak, halaman pangaliahan akan dibuek.",
+       "missingcommenttext": "Masuakan komentar Sanak.",
        "missingcommentheader": "'''Paringatan:''' Sanak alun maagihan subjek atau judul untuak komenta Sanak. Jikok Sanak baliak manakan \"$1\", suntiangan Sanak akan disimpan tanpa komenta tasabuik.",
        "summary-preview": "Ringkasan pratayang:",
        "subject-preview": "Pratayang subyek/judul:",
+       "previewerrortext": "Ado yang salah wakatu manunjuakan pratayang parubahan Sanak.",
        "blockedtitle": "Pangguno diblokir",
+       "blocked-email-user": "<strong>Namo pangguno Sanak diblokir untuak mangirim surel. Sanak masih bisa manyuntiang halaman lain di wiki ko. </strong> Sanak bisa mancaliak parincian pamblokiran  pado [[Special:MyContributions|account contributions]].\n\nPamblokiran dilakuan dek $1.\n\nAlasannyo adolah <em>$2</em>.\n\n* Diblokir sajak: $8\n* Blokir kadaluarsa pado: $6\n* Sasaran pamblokiran: $7\n* ID pamblokiran #$5",
        "blockedtext": "'''Namo pangguno atau alamaik IP Sanak alah kanai sakek.'''\n\nSakek dibuek dek $1.\nAlasan nan diagiahan adolah ''$2''.\n\n* Kanai sakek sajak: $8\n* Maso sakek habih pado: $6\n* Sasaran nan disakek: $7\n\nSanak dapek manghubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|panguruih lainnyo]] untuak mambicarokan hal iko.\n\nSanak indak dapek manggunoan fitua 'Kirim surel ka pangguna iko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|pangaturan akun]] dan Sanak indak sadang disakek untuak manggunoannyo.\n\nAlamaik IP Sanak adolah $3, dan ID panyakek adolah $5.\nTolong saratoan informasi di ateh pado satiok patanyaan nan Sanak buek.",
        "autoblockedtext": "Alamaik IP Sanak alah kanai sakek sacaro otomatis dek digunoan jo pangguno lain, nan sakek dek $1. Panyakek ko dibuek dek alasan:\n\n:''$2''\n\n* Kanai sakek sajak: $8\n* Maso sakek habih pado: $6\n* Sasaran nan disakek: $7\n\nSanak dapek mahubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|penguruih lainnya]] untuak mambicarokan hal iko.\n\nSanak indak dapek manggunoan fitua 'Kirim surel ka pangguna iko' kacuali Sanak alah mamasuakan alamaik surel nan sah di [[Special:Preferences|pangaturan akun]] dan Sanak indak sadang disakek untuak manggunoannyo.\n\nAlamaik IP Sanak adolah $3, dan ID panyakek adolah $5.\nTolong saratoan informasi di ateh pado satiok patanyaan nan Sanak buek.",
        "blockednoreason": "indak ado alasan nan diagiah.",
        "blocked-notice-logextract": "Pangguno ko tangah diblokir.\nEntri log pamblokiran tabaru disadioan di bawah ko untuak referensi:",
        "clearyourcache": "<strong>Catatan:</strong> Sasudah manyimpan, Sanak mungkin harus meminteh singgahan paramban Sanak untuak maliek parubahan.\n* <strong>Firefox / Safari:</strong> Tahan <em>Shift</em> sambia mangklik <em>Reload</em>, atau takan <em>Ctrl-F5</em> atau <em>Ctrl-R</em> (<em>⌘-R</em> di Mac)\n* <strong>Google Chrome:</strong> Takan <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> di Mac)\n* <strong>Internet Explorer:</strong> Tahan <em>Ctrl</em> sambia mangklik <em>Refresh</em>, atau takan <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Pai ka <em>Menu → Settings </em> (<em>Opera → Preferences</em> di Mac) lalu ka <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "'''Tips:''' Gunoan tombol \"{{int:showpreview}}\" untuak mauji CSS baharu Sanak sabalun manyimpannyo.",
+       "userjsonyoucanpreview": "<strong>Tip:</strong> Gunoan tombol \"{{int:showpreview}}\" untuak mauji JSON baharu Sanak sabalun manyimpannyo.",
        "userjsyoucanpreview": "'''Tips:''' Gunoan tombol \"{{int:showpreview}}\" untuak mauji JS baharu Sanak sabalun manyimpannyo.",
        "usercsspreview": "'''Ingeklah bahawa Sanak sadang manampilan pratayang dari CSS Sanak.\nPratayang iko alun disimpan!'''",
        "userjspreview": "'''Ingeklah bahawa nan Sanak liek hanyolah pratayang JavaScript Sanak, dan bahawa pratayang tasabuik alun disimpan!'''",
        "sitecsspreview": "'''Ingeklah bahawa Sanak hanyo manampilan pratayang dari CSS iko.'''\n'''Parubahan alun disimpan!'''",
+       "sitejsonpreview": "<strong>Ingeklah bahwa Sanak hanyo manampilan pratonton konfigurasi JSON ko. Parubahan alun basimpan!</strong>",
        "sitejspreview": "<strong>Ingek! Sanak hanyo manampilan pratonton kode JavaScript ko. Parubahan alun basimpan!</strong>",
        "userinvalidconfigtitle": "'''Paringatan:''' Kulik \"$1\" indak ditamuan. Harap diingek bahawa laman .css dan .js manggunokan huruf kecil, contoh {{ns:user}}:Foo/vector.css dan bukannyo {{ns:user}}:Foo/Vector.css.",
        "updated": "(Dipabaharui)",
        "yourdiff": "Pambedoan",
        "copyrightwarning": "Untuak diingek bahaso apo nan disumbang kapado {{SITENAME}} dianggap lah dilapeh di bawah $2 (caliak $1 untuak langkoknyo).\nJikok awak indak ingin apo nan ditulih tu disuntiang dan disebaran, jan dikirim tulisan tu ka siko.<br />\nAwak musti bajanji juo bahaso iko adolah asia karya awak surang, atau disalin dari sumber miliak basamo atau sumber bebas lainnyo.\n'''Jan dikirim karya bahak cipta nan indak baizin!'''",
        "copyrightwarning2": "Parhatikan bahawa sadoalah kontribusi terhadap {{SITENAME}} dapek disuntiang, diubah, atau dihapuih oleh panyumbang lainnyo. Jikok Sanak indak ingin tulisan Sanak disuntiang urang lain, jan kiriman ka siko.<br />Sanak jua bajanji bahawa iko adolah hasil karyo Sanak surang, atau disalin dari sumber miliak umum atau sumber bebas nan lain (liek $1 untuak informasi labiah lanjuik). '''JAN KIRIMAN KARYO NAN DILINDUNGI HAK CIPTA TANPA IJIN!'''",
+       "editpage-cannot-use-custom-model": "Model konten ko indak dapek diubah.",
        "longpageerror": "'''Kasalahan: Teks nan Sanak kiriman sagadang {{PLURAL:$1|$1 kilobita}}, barati labiah gadang dari jumlah maksimum {{PLURAL:$2|$2 kilobita}}. Teks indak dapek disimpan.'''",
        "readonlywarning": "'''PARINGATAN: Basis data sadang dikunci untuak pamaliharaan, sahinggo saat iko Sanak indak dapek manyimpan hasil suntiangan.''' \nSanak mungkin paralu manyalin teks suntiangan Sanak ko dan simpankan ka sabuah berkas teks guno mamuekannyo baliak kundian.\n\nPanguruih nan mangunci basis data maagiahan panjalehan barikuik: $1",
        "protectedpagewarning": "'''Paringatan: Laman iko sadang dilinduangi sahinggo hanyo pangguno jo hak akses pangurus nan dapek manyuntiangnyo.'''\nEntri catatan tarakhir disadioan di bawah untuak referensi:",
        "permissionserrors": "Kasalahan Hak Akses",
        "permissionserrorstext": "Sanak indak ado hak untuak malakuannyo dek {{PLURAL:$1|alasan}} barikuik:",
        "permissionserrorstext-withaction": "Sanak indak punyo hak akses untuak $2, dek {{PLURAL:$1|alasan}} barikuik:",
+       "contentmodelediterror": "Sanak indak dapek manyuntiang revisi ko karano isi model <code>$1</code>, beda dari isi model laman kini <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Ingek: Sanak mambuek ulang suatu laman nan alah dihapuih.'''\n\nHarap ditimbang apo rancak malanjuikan suntiangan Sanak.\nBarikuik ko log pangapuihan jo pamindahan dari laman ko:",
        "moveddeleted-notice": "Laman ko alah dihapuih.\nSabagai referensi, barikuik adolah log pangapuihan jo pamindahannyo.",
+       "moveddeleted-notice-recent": "Maaf, halaman ko baru sajo dihapuih (dalam rantang wakatu 24 jam). Log panghapuiah, palinduangan, jo pamindahan halaman tu tasadio di bawah sabagai referensi.",
        "log-fulllog": "Liek saluruah log",
        "edit-hook-aborted": "Suntiangan dibatalan samo kait parser\ntanpa ado katarangan.",
        "edit-gone-missing": "Indak dapek mampabarui laman.\nMungkin alah dihapuih.",
        "edit-conflict": "Konflik suntingan.",
        "edit-no-change": "Suntiangan sanak ditulak, karano indak ado parubahan nan tajadi ka teks.",
+       "edit-slots-cannot-add": "{{PLURAL:$1|slot is|slots are}} barikuik indak didukuang disiko: $2.",
+       "edit-slots-cannot-remove": "{{PLURAL:$1|slot is|slots are}} wajib dan indak  buliah dihapuih: $2.",
+       "postedit-confirmation-created": "Halaman alah dibuek.",
+       "postedit-confirmation-restored": "Halaman alah dipulihan.",
+       "postedit-confirmation-saved": "Suntiangan Sanak alah tasimpan.",
+       "postedit-confirmation-published": "Suntiangan Sanak alah ditabikan.",
        "edit-already-exists": "Indak dapek mambuek aman baru.\nNyo alah ado.",
        "defaultmessagetext": "Teks baku.",
        "content-failed-to-parse": "Gagal manjabarkan konten $2 untuak model $1: $3",
        "invalid-content-data": "Data kanduangan indak valid.",
        "content-not-allowed-here": "Konten \"$1\" indak diizinan di laman [[:$2]]",
        "editwarning-warning": "Maninggakan laman ko dapek maakibaikan parubahan nan dibuek hilang. Jikok Sanak lah masuak log, dapek mamatian pasan ko malalui bagian \"Panyuntiangan\" pado laman pangaturan.",
+       "slot-name-main": "Utamo",
        "content-model-wikitext": "Teks wiki",
        "content-model-text": "Teks kosong",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
+       "content-json-empty-object": "Objek kosong",
+       "content-json-empty-array": "Lariak kosong",
+       "deprecated-self-close-category": "Halaman yang menggunoan tag HTML tatutuik-surang indak sah",
        "expensive-parserfunction-warning": "'''Paringatan:''' Laman ko manganduang talalu banyak panggilan fungsi parser.\n\nSeharusnyo kurang dari $2 {{PLURAL:$2|panggilan}}, tapi {{PLURAL:$1|kini ado $1 panggilan}}.",
        "expensive-parserfunction-category": "Laman nan talalu banyak panggilan fungsi parser",
        "post-expand-template-inclusion-warning": "'''Peringatan:''' Ukuran templat talalu gadang.\nBabarapo templat akan diabaikan.",
        "post-expand-template-argument-warning": "Paringatan: Laman ko barisi satidaknyo ciek uraian templat na ukuran ekspansinyo talalu gadang. \nUraian-uraian tu alah diabaikan.",
        "post-expand-template-argument-category": "Laman nan barisi uraian templat nan diabaikan",
        "parser-template-loop-warning": "Hubungan barulang templat tadeteksi: [[$1]]",
+       "template-loop-category": "Halaman dengan templat barulang",
        "parser-template-recursion-depth-warning": "Limit kadalaman hubungan barulang templat lah talampau ($1)",
        "language-converter-depth-warning": "Bateh kadalaman pangonversi bahaso lah talampau ($1)",
        "node-count-exceeded-category": "Laman dimano hitungan-node talampaui",
        "revdel-restore": "ganti tampilan",
        "pagehist": "Riwayaik laman",
        "deletedhist": "Riwayaik pangapuihan",
+       "revdelete-hide-current": "Gagal manyambunyian parubahan tanggal $2, $1: iko adolah parubahan paliang baru.\nParubahan ko indak dapek disambunyian.",
+       "revdelete-show-no-access": "Gagal manampilan parubahan tanggal $2, $1: parubahan ko alah ditandoi ''tabateh''.\nSanak indak punyo akses ka parubahan ko.",
+       "revdelete-modify-no-access": "Gagal maubah parubahan tanggal $2, $1: parubahan ko alah ditandoi ''tabateh''.\nSanak indak punyo akses ka parubahan ko.",
+       "revdelete-modify-missing": "Gagal maubah parubahan ID $1: parubahan ko indak ado di basis data!",
+       "revdelete-no-change": "<strong>Paringatan:</strong>Parubahan tanggal $2, $1 alah punyo aturan panyambunyian.",
+       "revdelete-concurrent-change": "Gagal maubah parubahan tanggal $2, $1: statusnyo mungkin alah diubah pangguno lain basamoan jo Sanak.\nCubo pareso catatan log.",
+       "revdelete-only-restricted": "Ado yang salah wakatu manyambunyian item tanggal $2, $1: Sanak indak dapek manyambunyiannyo dari panguruih tanpa mamiliah salah satu opsi panyambunyian lainnyo.",
        "revdelete-reason-dropdown": "*Alasan pangapuihan umum\n** Palanggaran hak cipta\n** Komentar atau informasi paribadi nan indak patuik\n** Namo pangguno nan indak patuik\n** Bapotensi mancemarkan namo baiak",
        "revdelete-otherreason": "Alasan lain/tambahan:",
        "revdelete-reasonotherlist": "Alasan lain",
        "revdelete-edit-reasonlist": "Alasan mangapuih laman",
        "revdelete-offender": "Pambuek reviri:",
        "suppressionlog": "Log pambanaman",
+       "suppressionlogtext": "Dibawah ko adolah daftar panghapuihan jo pamblokiran, tamasuak isi yang disambunyian dari panguruih.\nCaliak [[Special:BlockList|block list]] untuak daftar yang paliang baru.",
+       "mergehistory": "Riwayaik panggabuangan sajarah halaman",
+       "mergehistory-box": "Gabuang parubahan-parubahan dari duo halaman:",
+       "mergehistory-from": "Halaman sumber:",
+       "mergehistory-into": "Halaman tujuan:",
+       "mergehistory-go": "Tampilan suntiangan yang dapek digabuang",
+       "mergehistory-submit": "Gabuang revisi",
+       "mergehistory-empty": "Indak ado parubahan yang dapek digabuang.",
+       "mergehistory-done": "$3 {{PLURAL:$3|revision|revisions}} dari $1 {{PLURAL:$3|was|were}} berhasil digabuangan ka [[:$2]].",
+       "mergehistory-fail": "Indak dapek digabuang, mohon pareso baliak halaman jo parameter waktu.",
+       "mergehistory-fail-invalid-source": "Halaman asal indak sah.",
+       "mergehistory-fail-invalid-dest": "Halaman tujuan indak sah.",
+       "mergehistory-fail-self-merge": "Halaman sumber jo tujuannyo samo.",
        "mergehistory-reason": "Alasan:",
        "mergelog": "Log panggabuangan",
        "revertmerge": "Batal gabuang",
index 88a1aea..5c127b9 100644 (file)
@@ -45,7 +45,7 @@
        "tog-watchrollback": "Додај ги страниците сум ги отповикал во набљудувани",
        "tog-minordefault": "Обележувај ги сите уредувања како ситни по основно",
        "tog-previewontop": "Прикажи го прегледот пред кутијата за уредување",
-       "tog-previewonfirst": "Ð\9fÑ\80икажи Ð¿Ñ\80еглед Ð½Ð° првото уредување",
+       "tog-previewonfirst": "Ð\9fÑ\80икажи Ð¿Ñ\80еглед Ð¿Ñ\80и првото уредување",
        "tog-enotifwatchlistpages": "Испраќај ми е-пошта при промена на страница или податотека од мојот список на набљудувања",
        "tog-enotifusertalkpages": "Испраќај ми е-пошта при промена на мојата разговорна страница",
        "tog-enotifminoredits": "Испраќај ми е-пошта и за ситни промени во страниците и податотеките",
@@ -70,6 +70,7 @@
        "tog-norollbackdiff": "Не ја покажувај разликата по извршено отповикување",
        "tog-useeditwarning": "Предупреди ме кога сакам да напуштам страница за уредување без да ги имам зачувано промените",
        "tog-prefershttps": "Секогаш најавувај ме преку безбедна врска",
+       "tog-showrollbackconfirmation": "Прикажи потврдница при стискање на врската за отповикување",
        "underline-always": "Секогаш",
        "underline-never": "Никогаш",
        "underline-default": "Според рувото или прелистувачот",
        "viewsourceold": "преглед на кодот",
        "editlink": "уреди",
        "viewsourcelink": "преглед на кодот",
-       "editsectionhint": "УÑ\80еди Ð³Ð¾ Ð¿Ð°Ñ\81Ñ\83Ñ\81оÑ\82: $1",
+       "editsectionhint": "УÑ\80еди Ð³Ð¾ Ð¾Ð´Ð´ÐµÐ»Ð¾Ñ\82 â\80\9e$1â\80\9c",
        "toc": "Содржина",
        "showtoc": "прикажи",
        "hidetoc": "скриј",
        "laggedslavemode": "Предупредување: Страницата може да не ги содржи скорешните поднови.",
        "readonly": "Базата е заклучена",
        "enterlockreason": "Внесете причина за заклучувањето, вклучувајќи и приближно време на отклучување",
-       "readonlytext": "Базата е моментално заклучена за нови статии и други измени, најверојатно како рутинска проверка, по што ќе се врати во нормална состојба. Администраторот кој ја заклучи го понуди следното образложение: <p>$1",
+       "readonlytext": "Базата е моментално заклучена за нови статии и други измени, најверојатно како рутинска проверка, по што ќе се врати во нормална состојба.\n\nАдминистраторот кој ја заклучи го понуди следното образложение: $1",
        "missing-article": "Базата на податоци не го пронајде текстот на страницата кој требаше да го пронајде, именуван „$1“ $2.\n\nОва најчесто е предизвикано од застарена разл. или врска до историја на страница која била избришана.\n\nАко не е таков случај, можеби сте наишле грешка во програмската опрема.\nПријавете го ова на некој [[Special:ListUsers/sysop|администратор]], давајќи врска до URL адресата.",
        "missingarticle-rev": "(измена#: $1)",
        "missingarticle-diff": "(разлика: $1, $2)",
        "readonly_lag": "Базата е автоматски заклучена додека помошните опслужувачи не се усогласат",
-       "nonwrite-api-promise-error": "HTTP-заглавието „Promise-Non-Write-API-Action“ беше испратено, но барањето беше упатено кон записен модул на извршникот.",
+       "nonwrite-api-promise-error": "HTTP-заглавието „Promise-Non-Write-API-Action“ беше испратено, но барањето беше упатено кон записен модул на API.",
        "internalerror": "Внатрешна грешка",
        "internalerror_info": "Внатрешна грешка: $1",
        "internalerror-fatal-exception": "Кобен исклучок на типот „$1“",
        "createacct-benefit-body2": "{{PLURAL:$1|страница|страници}}",
        "createacct-benefit-body3": "{{PLURAL:$1|скорешен учесник|скорешни учесници}}",
        "badretype": "Внесените лозинки не се совпаѓаат.",
-       "usernameinprogress": "Создавањето на сметката за овој корисни е веќе во тек.",
+       "usernameinprogress": "Создавањето на сметката за овој корисник е веќе во тек.\nПочекајте.",
        "userexists": "Корисничкото име што го внесовте е зафатено.\nИзберете друго име.",
+       "createacct-normalization": "Вашето корисничко име ќе биде прилагодено во „$2“ поради техничките ограничувања.",
        "loginerror": "Грешка при најавувањето",
        "createacct-error": "Грешка во создавањето на сметката",
        "createaccounterror": "Не можам да ја создадам сметката: $1",
        "createacct-loginerror": "Сметката е успешно создадена но не можев да ве најавам автоматски. Појдеете да се [[Special:UserLogin|најавите рачно]].",
        "noname": "Внесовте погрешно корисничко име.",
        "loginsuccesstitle": "Најавени сте",
-       "loginsuccess": "Сега сте најавени на {{SITENAME}} како „$1“.",
+       "loginsuccess": "<strong>Сега сте најавени на {{SITENAME}} како „$1“.</strong>",
        "nosuchuser": "Нема корисник со името „$1“.\nКорисничките имиња разликуваат мали и големи букви.\nПроверете да не сте направиле грешка во пишувањето, или [[Special:CreateAccount|создајте нова корисничка сметка]].",
        "nosuchusershort": "Нема корисник со името „$1“.\nПроверете дали правилно сте напишале.",
        "nouserspecified": "Мора да наведете корисничко име.",
        "accountcreatedtext": "Корисничката сметка за [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|разговор]]) е направена.",
        "createaccount-title": "Создавање на сметка за {{SITENAME}}",
        "createaccount-text": "Некој направил сметка со вашата е-поштенска адреса на {{SITENAME}} ($4) со име „$2“ и  лозинка „$3“.\nБи требало сега да се пријавите и да ја промените вашата лозинка.\n\nМожете да ја занемарите оваа порака ако сметката била направена по грешка.",
-       "login-throttled": "Ð\98маÑ\82е Ð¿Ñ\80емногÑ\83 Ð¾Ð±Ð¸Ð´Ð¸ Ð·Ð° Ð½Ð°Ñ\98ава Ð·Ð° ÐºÑ\80аÑ\82ко Ð²Ñ\80еме.\nПочекајте $1 пред да се обидете повторно.",
+       "login-throttled": "Ð\9dапÑ\80авивÑ\82е Ð¿Ñ\80емногÑ\83 Ð¾Ð±Ð¸Ð´Ð¸ Ð·Ð° Ð½Ð°Ñ\98ава.\nПочекајте $1 пред да се обидете повторно.",
        "login-abort-generic": "Најавата е неуспешна — Откажано",
        "login-migrated-generic": "Вашата сметка е пренесена и корисничкото име веќе не постои на ова вики.",
        "loginlanguagelabel": "Јазик: $1",
        "changepassword-success": "Вашата лозинка е сменета!",
        "changepassword-throttled": "Имате премногу обиди за најава за кратко време.\nПочекајте $1 пред да се обидете повторно.",
        "botpasswords": "Ботовски лозинки",
-       "botpasswords-summary": "<em>Ботовските лозинки</em> даваат пристап до корисничка сметка преку приложникот без да се користат главните најавни податоци на сметката. Корисничките права може да се ограничени кога се најавувате на овој начин.\n\nДоколку не знаете за што ова би ви послужило, подобро не го правете ова. Никој никогаш не треба да ви побара да направите ваква лозинка и да му ја дадете.",
+       "botpasswords-summary": "<em>Ботовските лозинки</em> даваат пристап до корисничка сметка преку API без да се користат главните најавни податоци на сметката. Корисничките права може да се ограничени кога се најавувате на овој начин.\n\nДоколку не знаете за што ова би ви послужило, подобро не го правете ова. Никој никогаш не треба да ви побара да направите ваква лозинка и да му ја дадете.",
        "botpasswords-disabled": "Ботовските лозинки се оневозможени.",
        "botpasswords-no-central-id": "За да користите ботовски лозинки, мора да сте најавени со централизирана сметка.",
        "botpasswords-existing": "Постоечки ботовски лозинки",
        "resetpass-no-info": "Мора да сте најавени ако сакате да имате директен пристап до оваа страница.",
        "resetpass-submit-loggedin": "Смени лозинка",
        "resetpass-submit-cancel": "Откажи",
-       "resetpass-wrong-oldpass": "Погрешна привремена или тековна лозинка.\nМожеби веќе ја имате успешно променето вашата лизинка или сте побарале нова привремена лозинка.",
+       "resetpass-wrong-oldpass": "Погрешна привремена или тековна лозинка.\nМожеби веќе ја имате променето вашата лозинка или сте побарале нова привремена лозинка.",
        "resetpass-recycled": "Задајте друга лозинка, поинаква од сегашната.",
        "resetpass-temp-emailed": "Се највивте со привремен код што ви го дадовме по е-пошта.\nЗа да ја довршите најавата, ќе мора тука да зададете нова лозинка:",
        "resetpass-temp-password": "Привремена лозинка:",
        "subject-preview": "Преглед на насловот:",
        "previewerrortext": "Се појави грешка при обидот да се прегледаат промените.",
        "blockedtitle": "Корисникот е блокиран",
-       "blocked-email-user": "<strong><strong>На вашето корисничко име му е забрането да праќа е-пошта. Можете сепак да уредувате други страници на ова вики.</strong> Сите поединости за забраната ќе ги најдете во [[Special:MyContributions|придонесите на сметката]].\n\nЗабраната ја дал $1.\n\nНаведената причина гласи <em>$2</em>.\n\n* Почеток на забраната: $8\n* Истек на забраната: $6\n* Предвиден забраненик: $7\n* Назнака на забраната #$5",
+       "blocked-email-user": "<strong>На вашето корисничко име му е забрането да праќа е-пошта. Можете сепак да уредувате други страници на ова вики.</strong> Сите поединости за забраната ќе ги најдете во [[Special:MyContributions|придонесите на сметката]].\n\nЗабраната ја дал $1.\n\nНаведената причина гласи <em>$2</em>.\n\n* Почеток на забраната: $8\n* Истек на забраната: $6\n* Предвиден забраненик: $7\n* Назнака на забраната #$5",
        "blockedtext-partial": "<strong>На вашето корисничко име или IP-адреса му е забрането да прави измени на страницава. Можете сепак да уредувате други страници на ова вики.</strong> Сите поединости за забраната ќе ги најдете во [[Special:MyContributions|придонесите на сметката]].\n\nЗабраната ја дал $1.\n\nНаведената причина гласи <em>$2</em>.\n\n* Почеток на забраната: $8\n* Истек на забраната: $6\n* Предвиден забраненик: $7\n* Назнака на забраната #$5",
        "blockedtext": "<strong>Вашето корисничко име или IP-адреса е блокирано.</strong>\n\nБлокирањето е направено од страна на $1.\nДаденото образложение е <em>$2</em>.\n\n* Почеток на блокирањето: $8\n* Истекување на блокирањето: $6\n* Корисникот што требало да биде блокиран: $7\n\nМоже да контактирате со $1 или некој друг [[{{MediaWiki:Grouppage-sysop}}|администратор]] за да разговарате во врска со блокирањето.\nМожете да ја искористите можноста „{{int:emailuser}}“ ако е назначена важечка е-поштенска адреса во [[Special:Preferences|вашите нагодувања]] и не ви е забрането да ја користите.\nВашата сегашна IP-адреса е $3, а назнака на блокирањето гласи #$5.\nВе молиме наведете ги сите подробности прикажани погоре, во вашата евентуална реакција.",
        "autoblockedtext": "Вашата IP-адреса е автоматски блокирана бидејќи била користена од страна на друг корисник, кој бил блокиран од $1.\nДаденото образложение е следново:\n\n:<em>$2</em>\n\n* Почеток на блокирањето: $8\n* Истекување на блокирањето: $6\n* Со намера да се блокира: $7\n\nМоже да контактирате со $1 или некој друг [[{{MediaWiki:Grouppage-sysop}}|администратор]] за да разговарате во врска со ова блокирање.\n\nИмајте предвид дека можеби нема да можете да ја искористите можноста „{{int:emailuser}}“ доколку не е назначена важечка е-поштенска адреса во [[Special:Preferences|вашите нагодувања]] и ви е забрането користење на истата.\n\nВашата IP-адреса е $3, a назнака на блокирањетo е $5.\nВе молиме наведете ги овие подробности доколку реагирате на блокирањето.",
        "usercssyoucanpreview": "'''Совет:''' Употребете го копчето „{{int:showpreview}}“ за да го испробате вашиот нов CSS пред да зачувате.",
        "userjsonyoucanpreview": "'''Совет:''' Употребете го копчето „{{int:showpreview}}“ за да го испробате вашиот нов JSON пред да зачувате.",
        "userjsyoucanpreview": "'''Совет:''' Употребете го копчето „{{int:showpreview}}“ за да ја испробате вашата нова JavaScript  пред да зачувате.",
-       "usercsspreview": "'''Запомнете дека ова е само преглед на вашиот кориснички CSS код, страницата сè уште не е зачувана!'''",
+       "usercsspreview": "<strong>Запомнете дека ова е само преглед на вашиот кориснички CSS код.\nСтраницата сè уште не е зачувана!</strong>",
        "userjsonpreview": "<strong>Запомнете дека ова е само испробување/преглед на поставеноста на вашиот JSON. \nСтраницата сè уште не е зачувана!</strong>",
-       "userjspreview": "'''Запомнете дека ова е само преглед на вашиот JavaScript код, страницата сè уште не е зачувана!'''",
+       "userjspreview": "<strong>Запомнете дека ова е само преглед на вашиот JavaScript код.\nСтраницата сè уште не е зачувана!</strong>",
        "sitecsspreview": "'''Запомнете дека ова е само преглед на овој CSS-код.'''\n'''Сè уште не е зачуван!'''",
        "sitejsonpreview": "<strong>Запомнете дека ова е само преглед на оваа поставеност на JSON. Сè уште не е зачуван!</strong>",
        "sitejspreview": "'''Запомнете дека ова е само преглед на овој JavaScript-код.'''\n'''Сè уште не е зачуван!'''",
        "continue-editing": "Оди на полето за уредување",
        "previewconflict": "Овој преглед прикажува како ќе изгледа текстот внесен во горниот дел откако ќе се зачува страницата.",
        "session_fail_preview": "За жал, не можев да го обработам уредувањето поради загуба на седнички податоци.\n\nМожеби сте биле одјавени. <strong>Проверете дали сè уште сте најавени и обидете се повторно</strong>.\nАко проблемот продолжи да се јавува, [[Special:UserLogout|одјавете се]] и повторно најавете се, и проверете дали прелистувачот дозволува колачиња од ова мрежно место.",
-       "session_fail_preview_html": "'''Жалиме, но Вашето уредување не можеше да се обработи поради загува на податоците од седницата.'''\n\n''{{SITENAME}} има овозможено чист HTML, па прегледот е скриен како мерка за заштита од JavaScript-напади.''\n\n'''Ако ова е разумен обид за уредување, тогаш обидете се повторно.'''\nАко и ова не го реши проблемот, обидете се со [[Special:UserLogout|одјавување]] и повторно најавување, и проверете дали прелистувачот дозволува колачиња од ова мрежно место.",
+       "session_fail_preview_html": "Жалиме, но Вашето уредување не можеше да се обработи поради загува на податоците од седницата.\n\n<em>{{SITENAME}} има овозможено чист HTML, па прегледот е скриен како мерка за заштита од JavaScript-напади.</em>\n\n<strong>Ако ова е разумен обид за уредување, тогаш обидете се повторно.</strong>\nАко и ова не го реши проблемот, обидете се со [[Special:UserLogout|одјавување]] и повторно најавување, и проверете дали прелистувачот дозволува колачиња од ова мрежно место.",
        "token_suffix_mismatch": "'''Вашето уредување е одбиено затоа што вашиот пребарувач направил проблеми со интерпукциските знаци во шифрата на уредувањето.\nУредувањето не е прифатено за да се спречи несакана промена на текстот на страницата.\nОва понекогаш се случува кога користите неисправна мрежна анонимна застапничка (proxy) служба.'''",
        "edit_form_incomplete": "'''Некои делови од образецот за уредување не стасаа до опслужувачот. Внимателно проверете дали уреденото не е пореметено и обидете се поввторно.'''",
        "editing": "Уредување на $1",
        "permissionserrorstext-withaction": "Немате дозвола за $2, од {{PLURAL:$1|следнава причина|следниве причини}}:",
        "contentmodelediterror": "Не можете да ја измените оваа преработка бидејќи нејзиниот содржински модел е <code>$1</code>, што се разликува од тековниот содржински модел на страницата <code>$2</code>.",
        "recreate-moveddeleted-warn": "Внимание: Повторно создавате страница што претходно била бришена.'''\n\nРазмислете дали е правилно да продолжите со уредување на оваа страница.\nПодолу е прикажан дневникот на бришења и преместувања на оваа страница:",
-       "moveddeleted-notice": "Оваа страница е избришана.\nДневникот на бришења и преместувања за оваа страница е прикажан подолу.",
+       "moveddeleted-notice": "Оваа страница е избришана.\nДневникот на бришења, заштитувања и преместувања за оваа страница е прикажан подолу.",
        "moveddeleted-notice-recent": "За жал, страницава беше неодамна избришана (во последниве 24 часа).\nПодолу можете да го погледате дневникот на бришења, заштити и преместувања.",
        "log-fulllog": "Преглед на целиот дневник",
        "edit-hook-aborted": "Уредувањето е прекинато со пресретник.\nНе е дадено никакво образложение.",
        "editpage-invalidcontentmodel-title": "Содржинскиот модел не е поддржан",
        "editpage-invalidcontentmodel-text": "Содржинскиот модел „$1“ не е поддржан.",
        "editpage-notsupportedcontentformat-title": "Форматот на содржината не е поддржан",
-       "editpage-notsupportedcontentformat-text": "ФоÑ\80маÑ\82оÑ\82 $1 is не е поддржан од содржинскиот модел $2.",
+       "editpage-notsupportedcontentformat-text": "СодÑ\80жинÑ\81киоÑ\82 Ñ\84оÑ\80маÑ\82 $1 не е поддржан од содржинскиот модел $2.",
        "slot-name-main": "Главна",
        "content-model-wikitext": "викитекст",
        "content-model-text": "прост текст",
        "content-json-empty-object": "Празен објект",
        "content-json-empty-array": "Празна низа",
        "deprecated-self-close-category": "Страници со неважечки самозатворени HTML-ознаки",
-       "deprecated-self-close-category-desc": "Страницава содржи неважечки самозатворени HTML-ознаки, како што се <code>&lt;b/></code> или <code>&lt;span/></code>. Нивното поведение наскоро ќе биде сменето, за да бидат во склад со определбите на HTML5. Ова значи дека се застарени и не треба да се употребуваат во викитекст.",
+       "deprecated-self-close-category-desc": "Страницата содржи неважечки самозатворени HTML-ознаки, како што се <code>&lt;b/></code> или <code>&lt;span/></code>. Нивното поведение наскоро ќе биде сменето, за да бидат во склад со определбите на HTML5. Ова значи дека се застарени и не треба да се употребуваат во викитекст.",
        "duplicate-args-warning": "<strong>Предупредување:</strong> [[:$1]] го повикува [[:$2]] со повеќе од една вредност за параметарот „$3“. Ќе се употреби само последната вредност.",
        "duplicate-args-category": "Страници што користат дуплирани аргументи во повикувања на шаблони",
        "duplicate-args-category-desc": "Страницава содржи повикувања на шаблони кои се дупликати на аргументи, како што се <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> или <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "post-expand-template-argument-category": "Страници кои содржат изземени аргументи на шаблони",
        "parser-template-loop-warning": "Пронајдена е јамка во шаблонот: [[$1]]",
        "template-loop-category": "Страници со шаблонски јамки",
-       "template-loop-category-desc": "Страницава содржи шаблонска јамка, т.е. шаблон кој повторливо се самоповикува",
+       "template-loop-category-desc": "Страницата содржи шаблонска јамка, т.е. шаблон кој повторливо се самоповикува.",
        "template-loop-warning": "<strong>Предупредување:</strong> Страницава го повикува [[:$1]], што предизвикува јамка во шаблонот (бесконечно повторлив повик).",
        "parser-template-recursion-depth-warning": "Пречекорена е границата на длабочината на рекурзијата во шаблонот ($1)",
        "language-converter-depth-warning": "Пречекорена е границата на длабочината на јазичниот претворач ($1)",
        "page_first": "прв",
        "page_last": "последен",
        "histlegend": "Разлика помеѓу преработките: Означете ги преработките што сакате да ги споредите и притиснете на Enter или копчето на дното од страницата.<br />\nЛегенда: '''({{int:cur}})''' = разлика со последна преработка, '''({{int:last}})''' = разлика со претходна преработка, '''{{int:minoreditletter}}''' = ситна промена.",
-       "history-fieldset-title": "Ð\9fÑ\80ебарај преработки",
+       "history-fieldset-title": "ФилÑ\82Ñ\80ирај преработки",
        "history-show-deleted": "Само избришани преработки",
        "histfirst": "најстари",
        "histlast": "најнови",
        "historysize": "({{PLURAL:$1|1 бајт|$1 бајти}})",
-       "historyempty": "(празно)",
+       "historyempty": "празно",
        "history-feed-title": "Историја на измените",
        "history-feed-description": "Историја на измените на оваа страница на викито",
        "history-feed-item-nocomment": "$1 на $2",
        "history-feed-empty": "Бараната страница не постои.\nМоже била избришана од викито или преименувана.\nОбидете се да [[Special:Search|пребарате низ викито]] за релевантни нови страници.",
-       "history-edit-tags": "Ð\98змени Ð¾Ð·Ð½Ð°ÐºÐ¸ Ð½Ð° Ð¾Ð´Ñ\80едени преработки",
+       "history-edit-tags": "Ð\98змени Ð¾Ð·Ð½Ð°ÐºÐ¸ Ð½Ð° Ð¸Ð·Ð±Ñ\80аниÑ\82е преработки",
        "rev-deleted-comment": "(избришан опис на промени)",
        "rev-deleted-user": "(избришано корисничко име)",
        "rev-deleted-event": "(избришани податоци од дневникот)",
        "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": "пÑ\80икажи/Ñ\81кÑ\80иÑ\98",
+       "rev-delundel": "измени Ð²Ð¸Ð´Ð»Ð¸Ð²Ð¾Ñ\81Ñ\82",
        "rev-showdeleted": "прикажи",
        "revisiondelete": "Избриши/врати преработки",
-       "revdelete-nooldid-title": "Ð\91аÑ\80анаÑ\82а Ð¸Ð·Ð¼ÐµÐ½Ð° Ð½Ðµ Ð¿Ð¾Ñ\81Ñ\82ои",
-       "revdelete-nooldid-text": "Немате укажано ниедна целна преработка врз која треба да се изврши оваа функикја, сте укажале преработка која не постои, или пак се обидувате да ја скриете тековната преработка.",
+       "revdelete-nooldid-title": "Ð\9dеважеÑ\87ка Ñ\86елна Ð¸Ð·Ð¼ÐµÐ½Ð°",
+       "revdelete-nooldid-text": "Немате укажано ниедна целна преработка врз која треба да се изврши оваа функција, сте укажале преработка која не постои, или пак се обидувате да ја скриете тековната преработка.",
        "revdelete-no-file": "Наведената податотека не постои.",
        "revdelete-show-file-confirm": "Дали сакате да ја погледнете избришаната преработка на податотеката „<nowiki>$1</nowiki>“ од $2 во $3?",
        "revdelete-show-file-submit": "Да",
        "revdelete-suppress": "Притајувај податоци и од администраторите",
        "revdelete-unsuppress": "Отстрани ограничувања на обновени преработки",
        "revdelete-log": "Причина:",
-       "revdelete-submit": "Ð\9fÑ\80имени Ð²Ñ\80з {{PLURAL:$1|одбÑ\80ана Ð¿Ñ\80еÑ\80абоÑ\82ка|одбÑ\80ани преработки}}",
+       "revdelete-submit": "Ð\9fÑ\80имени Ð²Ñ\80з {{PLURAL:$1|избÑ\80анаÑ\82а Ð¿Ñ\80еÑ\80абоÑ\82ка|избÑ\80аниÑ\82е преработки}}",
        "revdelete-success": "Видливоста на преработката е изменета.",
        "revdelete-failure": "'''Видливоста на преработката не можеше да се измени:'''\n$1",
        "logdelete-success": "Дневникот на видливост е поставен.",
        "revdel-restore": "Промена на видливост",
        "pagehist": "Историја на страницата",
        "deletedhist": "Историја на бришења",
-       "revdelete-hide-current": "Грешка при сокривањето на ставката од $2, $1: Ова е тековната преработка.",
-       "revdelete-show-no-access": "Грешка при прикажување на ставката датирана на $2, $1: оваа ставка е означена како „ограничена“. Немате пристап до неа.",
-       "revdelete-modify-no-access": "Грешка при промена на ставката датирана на $2, $1: оваа ставка била означена како „ограничена“. Немате пристап до неа.",
+       "revdelete-hide-current": "Грешка при сокривањето на ставката од $2, $1: Ова е тековната преработка.\nТаа не може да се скрива.",
+       "revdelete-show-no-access": "Грешка при прикажување на ставката датирана на $2, $1: оваа ставка е означена како „ограничена“.\nНемате пристап до неа.",
+       "revdelete-modify-no-access": "Грешка при промена на ставката датирана на $2, $1: оваа ставка била означена како „ограничена“.\nНемате пристап до неа.",
        "revdelete-modify-missing": "Грешка при промена на ставка со број $1: ја нема во базата на податоци!",
        "revdelete-no-change": "'''Предупредување:''' ставката датирана на $2, $1 веќе ги има бараните нагодувања за видливост.",
        "revdelete-concurrent-change": "Грешка при промена на ставката датирана на $2, $1: нејзиниот статус изгледа дека бил изменет од некој друг додека вие се обидувавте да го направите тоа. Ве молиме проверете во дневниците.",
        "mergehistory-from": "Изворна страница:",
        "mergehistory-into": "Целна страница:",
        "mergehistory-list": "Спојлива историја на уредување",
-       "mergehistory-merge": "СледниÑ\82е Ð¿Ñ\80еÑ\80абоÑ\82ки Ð½Ð° [[:$1]] Ð¼Ð¾Ð¶Ð°Ñ\82 Ð´Ð° Ñ\81е Ñ\81поÑ\98аÑ\82 Ð²Ð¾ [[:$2]].\nÐ\98збеÑ\80еÑ\82е Ð³Ð¸ Ñ\81амо Ð¾Ð½Ð¸Ðµ Ð¿Ñ\80еÑ\80абоÑ\82ки ÐºÐ¾Ð¸ Ñ\81е Ñ\81оздадени Ð¿Ñ\80ед Ð½Ð°Ð·Ð½Ð°Ñ\87еноÑ\82о Ð²Ñ\80еме.\nÐ\9fÑ\80едÑ\83пÑ\80едÑ\83ваме Ð´ÐµÐºÐ° Ð°ÐºÐ¾ Ð³Ð¸ ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ð½Ð°Ð²Ð¸Ð³Ð°Ñ\86ионите врски, изборот ќе се изгуби.",
+       "mergehistory-merge": "СледниÑ\82е Ð¿Ñ\80еÑ\80абоÑ\82ки Ð½Ð° [[:$1]] Ð¼Ð¾Ð¶Ð°Ñ\82 Ð´Ð° Ñ\81е Ñ\81поÑ\98аÑ\82 Ð²Ð¾ [[:$2]].\nÐ\98збеÑ\80еÑ\82е Ð³Ð¸ Ñ\81амо Ð¾Ð½Ð¸Ðµ Ð¿Ñ\80еÑ\80абоÑ\82ки ÐºÐ¾Ð¸ Ñ\81е Ñ\81оздадени Ð¿Ñ\80ед Ð½Ð°Ð·Ð½Ð°Ñ\87еноÑ\82о Ð²Ñ\80еме.\nÐ\9fÑ\80едÑ\83пÑ\80едÑ\83ваме Ð´ÐµÐºÐ° Ð°ÐºÐ¾ Ð³Ð¸ ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ð¿Ñ\80егелдниÑ\87ките врски, изборот ќе се изгуби.",
        "mergehistory-go": "Приказ на уредувања кои можат да се спојат",
        "mergehistory-submit": "Спојување на преработки",
        "mergehistory-empty": "Нема преработки кои можат да се спојат.",
        "difference-multipage": "(Разлики помеѓу страници)",
        "lineno": "Ред $1:",
        "compareselectedversions": "Спореди ги избраните преработки",
-       "showhideselectedversions": "Ð\9fÑ\80икажи/Ñ\81кÑ\80иÑ\98 Ð³Ð¸ избраните преработки",
+       "showhideselectedversions": "Ð\98змени Ð²Ð¸Ð´Ð»Ð¸Ð²Ð¾Ñ\81Ñ\82 Ð½Ð° избраните преработки",
        "editundo": "откажи",
        "diff-empty": "(нема разлика)",
        "diff-multi-sameuser": "({{PLURAL:$1|Не е прикажана една меѓувремена преработка|Не се прикажани $1 меѓувремени преработки}} од истиот корисник)",
        "recentchangescount": "Бројот на уредувања за приказ во скорешните промени, историите на страниците и во дневници. По основно:",
        "prefs-help-recentchangescount": "Највеќе: 1000",
        "prefs-help-watchlist-token2": "Ова е тајна шифра за тековникот на вашите набљудувања.\nСекој што ја знае ќе може да ја чита, па затоа ви препорачуваме да не ја кажувате никому.\nАко е потребно, [[Special:ResetTokens|можете да ставите нова]].",
-       "prefs-help-tokenmanagement": "Можете да го погледате и одново зададете тајниот клуч з авашата сметка со кој се пристапува до семрежниот тековник на вашите набљудувани. Секој еден што го знае клучот може да ви ги ги чита набљудуваните — затоа не го кажувајте никому.",
+       "prefs-help-tokenmanagement": "Можете да го погледате и одново зададете тајниот клуч за вашата сметка со кој се пристапува до семрежниот тековник на вашите набљудувани. Секој еден што го знае клучот може да ви ги чита набљудуваните — затоа не го кажувајте никому.",
        "savedprefs": "Вашите нагодувања се зачувани.",
        "savedrights": "Корисничките групи на {{GENDER:$1|$1}} се зачувани.",
        "timezonelegend": "Часовен појас:",
        "prefs-custom-json": "Прилагоден JSON",
        "prefs-custom-js": "Посебно JS",
        "prefs-common-config": "Заеднички CSS/JSON/JavaScript за сите рува:",
-       "prefs-reset-intro": "Може да ја користите оваа страница за враќање на вашите нагодувања на основно-зададените нагодувања на викито. Ова дејство е неповратно.",
+       "prefs-reset-intro": "Може да ја користите оваа страница за враќање на вашите нагодувања на стандардните нагодувања на мрежното место.\nОва дејство е неповратно.",
        "prefs-emailconfirm-label": "Потврда на е-пошта:",
        "youremail": "Е-пошта:",
        "username": "{{GENDER:$1|Корисничко име}}:",
        "saveusergroups": "Зачувај ги {{GENDER:$1|корисничките}} групи",
        "userrights-groupsmember": "Член на:",
        "userrights-groupsmember-auto": "Подразбран член на:",
-       "userrights-groups-help": "Можете да измените на кои групи припаѓа корисник:\n* Штиклирано — корисникот е во таа група.\n* Нештиклирано — корисникот не припаѓа на групата.\n* Ѕвездичка (*) — не можете да ја отстраните групата откако сте ја додале (и обратно).\n* Тараба (#) — можете само да го вратите истекот на членството во групава, но не можете да го поместите нанапред.",
+       "userrights-groups-help": "Можете да измените на кои групи припаѓа корисник:\n* Штиклирано — корисникот е во таа група.\n* Нештиклирано — корисникот не припаѓа на групата.\n* Ѕвездичка (*) — не можете да ја отстраните групата откако сте ја додале (и обратно).\n* Тараба (#) — можете само да го вратите истекот на членството во групата, но не можете да го поместите нанапред.",
        "userrights-reason": "Причина:",
        "userrights-no-interwiki": "Немате дозвола за уредување на кориснички права на други викија.",
        "userrights-nodatabase": "Базата на податоци $1 не постои или не е месна.",
        "right-reupload-own": "Преснимување на постоечка податотека подигната од вас",
        "right-reupload-shared": "Презапис на едни податотеки врз други на заедничкото мултимедијално складиште месно",
        "right-upload_by_url": "Подигање на податотека од URL-адреса",
-       "right-purge": "Ð\91Ñ\80иÑ\88еÑ\9aе Ð¾Ð´ Ð¾Ð¿Ñ\81лÑ\83жÑ\83ваÑ\87ки Ð¼ÐµÑ\93Ñ\83Ñ\81клад Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а Ð±ÐµÐ· Ð±Ð°Ñ\80аÑ\9aе Ð¿Ð¾Ñ\82вÑ\80да Ð·Ð° Ñ\82оа",
+       "right-purge": "Ð\91Ñ\80иÑ\88еÑ\9aе Ð½Ð° Ð¼ÐµÑ\93Ñ\83Ñ\81клад Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а",
        "right-autoconfirmed": "Без ограничувања на стапки за IP-адреса",
        "right-bot": "Третиран како автоматски процес",
        "right-nominornewtalk": "Ситните уредувања на разговорни страници да не поттикнуваат потсетник за нова порака",
        "grant-delete": "Бришење страници, преработки и дневнички записи",
        "grant-editinterface": "Уредување на именскиот простор „МедијаВики“ и JSON за цело вики/за корисник",
        "grant-editmycssjs": "Уредување на вашиот кориснички CSS/JSON/JavaScript",
-       "grant-editmyoptions": "Уредување на вашите кориснички нагодувања и поставеноста на JSON",
+       "grant-editmyoptions": "Уредување на вашите кориснички нагодувања и JSON-конфигурацијата",
        "grant-editmywatchlist": "Уредување на вашите набљудувани",
        "grant-editsiteconfig": "Уредување на CSS/JS за цело вики и за корисник",
        "grant-editpage": "Менување постоечки страници",
        "grant-oversight": "Скривање на корисници и преработки",
        "grant-patrol": "Патрола на промени во страници",
        "grant-privateinfo": "Пристап до лични информации",
-       "grant-protect": "Заштита на незаштитени страници",
+       "grant-protect": "Заштитување и одзаштитување страници",
        "grant-rollback": "Отповикување на промени во страници",
        "grant-sendemail": "Испраќање на е-пошта до други корисници",
        "grant-uploadeditmovefile": "Подигање, замена и преместување на податотеки",
        "grant-basic": "Основни права",
        "grant-viewdeleted": "Преглед на избришани податотеки и страници",
        "grant-viewmywatchlist": "Преглед на вашите набљудувања",
-       "grant-viewrestrictedlogs": "Преглед на ограничени дневнички ставки",
+       "grant-viewrestrictedlogs": "Преглед на ограничени дневнички записи",
        "newuserlogpage": "Дневник на регистрирања на корисници",
        "newuserlogpagetext": "Ова е дневник на регистрирани корисници.",
        "rightslog": "Дневник на корисничките права",
        "rightslogtext": "Ова е дневник на промени на кориснички права.",
        "action-read": "читање на оваа страница",
        "action-edit": "уредување на оваа страница",
-       "action-createpage": "создавање страници",
+       "action-createpage": "создавање на оваа страница",
        "action-createtalk": "создавање на оваа разговорна страница",
-       "action-createaccount": "создај ја оваа корисничка сметка",
+       "action-createaccount": "создавање на оваа корисничка сметка",
        "action-autocreateaccount": "автоматско создавање на оваа надворешна корисничка сметка",
        "action-history": "преглед на историјата на оваа страница",
        "action-minoredit": "означување на ова уредување како ситно",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (погл. и [[Special:NewPages|списокот на нови страници]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Прикажи",
-       "rcfilters-tag-remove": "Отстрани го „$1“",
+       "rcfilters-tag-remove": "Отстрани „$1“",
        "rcfilters-legend-heading": "<strong>Список на кратенки:</strong>",
        "rcfilters-other-review-tools": "Други алатки за проверка",
        "rcfilters-group-results-by-page": "Групен исход по страница",
        "rcfilters-restore-default-filters": "Поврати основни филтри",
        "rcfilters-clear-all-filters": "Тргни ги сите филтри",
        "rcfilters-show-new-changes": "Погл. најнови промени",
-       "rcfilters-search-placeholder": "Филтрирање на промени (со менито или пребарајте назив на филтер)",
+       "rcfilters-search-placeholder": "Филтрирање на промени (користете го менито или пребарајте назив на филтер)",
        "rcfilters-invalid-filter": "Неважечки филтер",
        "rcfilters-empty-filter": "Нема активни филтри. Прикажани се сите придонеси.",
        "rcfilters-filterlist-title": "Филтри",
        "windows-nonascii-filename": "Опслужувачот не поддржува податотечни имиња со псоебни знаци.",
        "fileexists": "Податотека со ова име веќе постои. Проверете <strong>[[:$1]]</strong> ако не {{GENDER:|сте}} сигурни дали сакате да ја промените.\n[[$1|thumb]]",
        "filepageexists": "Описната страница на оваа податотека е веќе создадена на <strong>[[:$1]]</strong>, но не постои податотека со тоа име.\nОписот кој го внесовте нема да стои на описната страница.\nДоколку сакате описот да стои тука, ќе морате да го уредите рачно.\n[[$1|thumb]]",
-       "fileexists-extension": "Податотека со слично име веќе постои: [[$2|thumb]]\n* Име на податотека која се подигнува: <strong>[[:$1]]</strong>\n* Име на постоечката податотека: <strong>[[:$2]]</strong>\nДали можеби би сакале да користите покарактеристично име.",
+       "fileexists-extension": "Податотека со слично име веќе постои: [[$2|thumb]]\n* Име на податотека која се подигнува: <strong>[[:$1]]</strong>\n* Име на постоечката податотека: <strong>[[:$2]]</strong>\nДали можеби би сакале да користите покарактеристично име?",
        "fileexists-thumbnail-yes": "Се чини дека податотеката е слика со намалена големина ''(минијатура)''. [[$1|thumb]]\nПроверете ја податотеката <strong>[[:$1]]</strong>.\nАко податотеката која ја проверувате е истата слика во својата изворна големина тогаш не мора да ја подигате дополнително.",
        "file-thumbnail-no": "Името на податотеката почнува со <strong>$1</strong>.\nИзгледа дека е слика со намалена големина ''(мини, thumbnail)''.\nАко ја имате оваа слика во изворна големина, подигнете ја неја. Во спротивно сменете го името на податотеката.",
        "fileexists-forbidden": "Податотека со тоа име веќе постои и не може да биде заменета.\nАко и понатаму сакате да ја подигнете вашата податотеката, ве молиме вратете се назад и подигнете ја под друго име. [[File:$1|thumb|center|$1]]",
        "upload-form-label-own-work": "Ова е мое дело",
        "upload-form-label-infoform-categories": "Категории",
        "upload-form-label-infoform-date": "Датум",
-       "upload-form-label-own-work-message-generic-local": "Потврдувам дека податотекава ја подигам во согласност со условите на користење и правилата за лиценцирање на {{SITENAME}}.",
+       "upload-form-label-own-work-message-generic-local": "Потврдувам дека ја подигам податотекава во согласност со условите на користење и правилата за лиценцирање на {{SITENAME}}.",
        "upload-form-label-not-own-work-message-generic-local": "Ако не сте во можност да ја подигнете податотекава согласно правилата на {{SITENAME}}, затворете го дијалогов и обидете се на друг начин.",
        "upload-form-label-not-own-work-local-generic-local": "Можете да ја пробате и [[Special:Upload|стандардната страница за подигање]].",
        "upload-form-label-own-work-message-generic-foreign": "Разбирам дека ја подигам податотекава на заедничко складиште. Потврдувам дека со тоа ги почитувам тамошните услови на користење и лиценцните правила.",
        "uncategorizedtemplates": "Некатегоризирани преуредувања",
        "uncategorized-categories-exceptionlist": " # Содржи список на категории кои не треба да се споменуваат во Special:UncategorizedCategories. По една во секој нов ред што почнува со „*“. Редовите што почнуваат со друг знак (заклучно со празни места) ќе се занемарат. Користете „#“ за прибелешки.",
        "unusedcategories": "Неискористени категории",
-       "unusedimages": "Неискористени слики",
+       "unusedimages": "Неискористени податотеки",
        "wantedcategories": "Потребни категории",
        "wantedpages": "Потребни страници",
        "wantedpages-summary": "Список на непостоечки страници со највеќе врски што водат до нив, исклучувајќи страниците до кои водат само пренасочувања. Список на непостоечки страници до кои водат пренасочувања ќе најдете на [[{{#special:BrokenRedirects}}|списокот на прекинати пренасочувања]].",
        "ancientpages": "Најстари статии",
        "move": "Премести",
        "movethispage": "Премести ја страницава",
-       "unusedimagestext": "Следниве Ð¿Ð¾Ð´Ð°Ñ\82оÑ\82еки Ð¿Ð¾Ñ\81Ñ\82оÑ\98аÑ\82, Ð½Ð¾ Ð½Ðµ Ñ\81е Ð²Ð¼ÐµÑ\82наÑ\82и Ð²Ð¾ Ð½Ð¸ÐµÐ´Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а.\nÐ\98маÑ\98Ñ\82е Ð¿Ñ\80едвид Ð´ÐµÐºÐ° Ð´Ñ\80Ñ\83ги Ð¼Ñ\80ежни Ð¼ÐµÑ\81Ñ\82а Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ñ\81Ñ\82авааÑ\82 Ð²Ñ\80Ñ\81ки Ð´Ð¾ Ð½Ðµа со непосредна URL-адреса, и затоа може да е наведена овде и покрај тоа што е во активна употреба.",
+       "unusedimagestext": "Следниве Ð¿Ð¾Ð´Ð°Ñ\82оÑ\82еки Ð¿Ð¾Ñ\81Ñ\82оÑ\98аÑ\82, Ð½Ð¾ Ð½Ðµ Ñ\81е Ð²Ð¼ÐµÑ\82наÑ\82и Ð²Ð¾ Ð½Ð¸ÐµÐ´Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а.\nÐ\98маÑ\98Ñ\82е Ð¿Ñ\80едвид Ð´ÐµÐºÐ° Ð´Ñ\80Ñ\83ги Ð¼Ñ\80ежни Ð¼ÐµÑ\81Ñ\82а Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ñ\81Ñ\82авааÑ\82 Ð²Ñ\80Ñ\81ки Ð´Ð¾ Ð¿Ð¾Ð´Ð°Ñ\82оÑ\82ека со непосредна URL-адреса, и затоа може да е наведена овде и покрај тоа што е во активна употреба.",
        "unusedimagestext-categorizedimgisused": "Следниве податотеки постојат, но не се вметнати во нидна страница. Категоризираните слики се сметаат за употребени, иако не се присутни на ниедна страница.\nИмајте на ум дека други мрежни места може да се повикуваат на податотеката со непосредна URL, и така може да се наведени овде иако се во активна употреба.",
        "unusedcategoriestext": "Следните категории постојат и покрај тоа што ниедна статија и категорија не ги користи.",
        "notargettitle": "Нема цел",
        "notanarticle": "Не е статија",
        "notvisiblerev": "Преработката била избришана",
        "watchlist-details": "Во вашите набљудувани имате {{PLURAL:$1|$1 страница|$1 страници}} (не броејќи ги разговорните страници).",
-       "wlheader-enotif": "Ð\98звеÑ\81Ñ\82Ñ\83ваÑ\9aеÑ\82о Ð¿Ð¾ Ðµ-поÑ\88Ñ\82а Ðµ Ð²ÐºÐ»Ñ\83Ñ\87ено.",
-       "wlheader-showupdated": "Страниците што се изменети од вашата последна посета се прикажани со '''задебелени''' букви",
+       "wlheader-enotif": "Ð\98звеÑ\81Ñ\82Ñ\83ваÑ\9aеÑ\82о Ð¿Ð¾ Ðµ-поÑ\88Ñ\82а Ðµ Ð¾Ð²Ð¾Ð·Ð¼Ð¾Ð¶ено.",
+       "wlheader-showupdated": "Страниците кои се променети од вашата последна посета се прикажани со <strong>задебелени</strong> букви.",
        "wlnote": "Подолу {{PLURAL:$1|е прикажана последната промена|се прикажани последните <strong>$1</strong> промени}} во {{PLURAL:$2|последниов час|последниве <strong>$2</strong> часа}}, заклучно со $3, $4 ч.",
-       "wlshowlast": "Прикажи ги последните $1 часа, $2 дена,",
+       "wlshowlast": "Прикажи ги последните $1 часа, $2 дена",
        "watchlist-hide": "Скриј",
        "watchlist-submit": "Прикажи",
        "wlshowtime": "Период за приказ:",
        "delete-confirm": "Бришење на „$1“",
        "delete-legend": "Бришење",
        "historywarning": "<strong>Предупредување:</strong> Страницата што сакате да ја избришете има историја со {{PLURAL:$1|една преработка|$1 преработки}}:",
-       "historyaction-submit": "Прикажи",
+       "historyaction-submit": "Прикажи преработки",
        "confirmdeletetext": "На пат сте трајно да избришете страница заедно со нејзината историја.\nПотврдете дека имате намера да го направите ова, дека ги разбирате последиците од тоа и дека го правите во согласност со [[{{MediaWiki:Policy-url}}|правилата]].",
        "actioncomplete": "Дејството е извршено",
        "actionfailed": "Неуспешно дејство",
        "deleting-backlinks-warning": "<strong>Предупредување:</strong>  До страницата што сакате да ја избришете водат [[Special:WhatLinksHere/{{FULLPAGENAME}}|други страници]] или пак се превметнуваат во неа.",
        "deleting-subpages-warning": "<strong>Предупредување:</strong> Страницата што сакате да ја избришете има [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|потстраница|$1 потстраници|51=преку 50 потстраници}}]].",
        "rollback": "Отповикај промени",
+       "rollback-confirmation-confirm": "Потврдете:",
+       "rollback-confirmation-yes": "Отповикај",
+       "rollback-confirmation-no": "Откажи",
        "rollbacklink": "отповикај",
        "rollbacklinkcount": "отповикај $1 {{PLURAL:$1|уредување|уредувања}}",
        "rollbacklinkcount-morethan": "отповикај повеќе од $1 {{PLURAL:$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": "Откажани уредувањата на {{GENDER:$3|$1}};; вратено на последната верзија на {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Откажани уредувањата на $1;\nвратено на последната преработка на $2. [$3 Пок. промени]",
+       "rollback-success": "Откажани уредувањата на {{GENDER:$3|$1}};\nвратено на последната верзија на {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Седницата не успеа",
        "sessionfailure": "Се јави проблем со најавната седница;\nова дејство е откажано за да се спречи нејзина кражба.\nПоднесете го образецот повторно.",
        "changecontentmodel": "Промена на содржинскиот модел на страница",
        "undeletepagetext": "{{PLURAL:$1|Следната страница била избришана но сè уште е во архивот и може да биде вратена.|Следните $1 страници биле избришани но сè уште се во архивот и можат да бидат вратени.}}\nАрхивот може периодично да се чисти.",
        "undelete-fieldset-title": "Врати преработки",
        "undeleteextrahelp": "За да вратите целосна историја на една страница, отштиклирајте ги сите полиња и притиснете на „'''{{int:undeletebtn}}'''“.\nЗа да извршите делумно враќање, штиклирајте ги соодветните преработки за враќање и притиснете на „'''{{int:undeletebtn}}'''“.",
-       "undeleterevisions": "${{PLURAL:$1|Избришана една преработка|Избришани $1 преработки}}",
+       "undeleterevisions": "{{PLURAL:$1|Избришана една преработка|Избришани $1 преработки}}",
        "undeletehistory": "Ако ја обновите страницата, сите преработки ќе бидат вратени во историјата.\nАко нова страница со исто име е создадена по бришењето, обновените преработки ќе се појават во претходната историја.",
        "undeleterevdel": "Избришаното нема да биде вратено ако тоа значи дека со тоа најгорната страница или преработката на податотеката делумно ќе се избрише.\nВо такви случаи, морате да ја отштиклирате или откриете (ако е скриена) најновата избришана преработка.",
        "undeletehistorynoadmin": "Оваа статија е избришана. Причината за бришењето е наведена подолу,\nзаедно со информации за корисникот кој ја уредувал страницата пред бришењето. Целиот текст\nод избришаните верзии е достапен само за администраторите.",
        "mycontris": "придонеси",
        "anoncontribs": "Придонеси",
        "contribsub2": "За {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "За {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Корисничката сметка „$1“ не е регистрирана.",
        "negative-namespace-not-supported": "Не се поддржани именски простори со негативни вредности.",
        "nocontribs": "Не се пронајдени промени што одговараат на овој критериум.",
        "ipb-confirm": "Потврди блок",
        "ipb-sitewide": "Насекаде",
        "ipb-partial": "Делумно",
+       "ipb-sitewide-help": "Секоја страница на викито и сите други придонесувачки дејства.",
+       "ipb-partial-help": "Поединечни страници или именски простори.",
        "ipb-pages-label": "Страници",
        "ipb-namespaces-label": "Именски простори",
        "badipaddress": "Неважечка IP-адреса",
        "import-interwiki-templates": "Вклучи ги сите шаблони",
        "import-interwiki-submit": "Увези",
        "import-mapping-default": "Увези во стандардните места",
-       "import-mapping-namespace": "Увези во именскиот простор:",
+       "import-mapping-namespace": "Увези во именски простор:",
        "import-mapping-subpage": "Увези како потстраници на следнава страница:",
        "import-upload-filename": "Податотека:",
        "import-upload-username-prefix": "Меѓувики-претставка:",
        "pageinfo-category-files": "Број на податотеки",
        "pageinfo-user-id": "Корисничка назнака",
        "pageinfo-file-hash": "Тарабна вредност",
-       "pageinfo-view-protect-log": "Погл. дневникот на заштити за страницава.",
+       "pageinfo-view-protect-log": "Преглед на дневникот на заштити за страницава.",
        "markaspatrolleddiff": "Означи како проверена верзија",
        "markaspatrolledtext": "Означи ја верзијата како проверена",
        "markaspatrolledtext-file": "Означи ја верзијава како испатролирана",
        "confirm-unwatch-top": "Да ја отстранам страницава од набљудуваните?",
        "confirm-rollback-button": "ОК",
        "confirm-rollback-top": "Да ги отповикам уредувањата на страницава?",
+       "confirm-rollback-bottom": "Ова дејство веднаш ќе ги отповика избраните промени на страницава.",
        "confirm-mcrrestore-title": "Поврати преработка",
        "confirm-mcrundo-title": "Откажи промена",
        "mcrundofailed": "Откажувањето не успеа",
        "tag-mw-contentmodelchange": "измена на содржинскиот модел",
        "tag-mw-contentmodelchange-description": "Уредувања што го [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel менуваат содржинскиот модел] на една страница",
        "tag-mw-new-redirect": "Ново пренасочување",
-       "tag-mw-new-redirect-description": "Уредувањата што направат ново пренасочување или да сменат страница во пренасочување",
+       "tag-mw-new-redirect-description": "Уредувања што направат ново пренасочување или да сменат страница во пренасочување",
        "tag-mw-removed-redirect": "Отстрането пренасочување",
        "tag-mw-removed-redirect-description": "Уредувања што менуваат постоечко пренасочување во непренасочување",
        "tag-mw-changed-redirect-target": "Сменета целната страница на пренасочувањето",
-       "tag-mw-changed-redirect-target-description": "Уредувања што ја менуваат целната страница на пренасочувањето",
+       "tag-mw-changed-redirect-target-description": "Уредувања што ја менуваат целната страница на пренасочување",
        "tag-mw-blank": "Испразнување",
        "tag-mw-blank-description": "Уредувања што испразнуваат страница",
        "tag-mw-replace": "Заменето",
        "tags-manage-no-permission": "Немате дозвола за раководење со ознаки за промени.",
        "tags-manage-blocked": "Не можете да раководите со ознаки за промени додека {{GENDER:$1|сте}} блокирани.",
        "tags-create-heading": "Создај нова ознака",
-       "tags-create-explanation": "Новосоздадните ознаки по основно ќе се стават на располагање за употреба од корисници и ботови.",
+       "tags-create-explanation": "Ð\9dовоÑ\81оздадениÑ\82е Ð¾Ð·Ð½Ð°ÐºÐ¸ Ð¿Ð¾ Ð¾Ñ\81новно Ñ\9cе Ñ\81е Ñ\81Ñ\82аваÑ\82 Ð½Ð° Ñ\80аÑ\81полагаÑ\9aе Ð·Ð° Ñ\83поÑ\82Ñ\80еба Ð¾Ð´ ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¸ Ð±Ð¾Ñ\82ови.",
        "tags-create-tag-name": "Име на ознаката:",
        "tags-create-reason": "Причина:",
        "tags-create-submit": "Создај",
        "tags-edit-chosen-placeholder": "Одберете некои ознаки",
        "tags-edit-chosen-no-results": "Не пронајдов одговарачки ознаки",
        "tags-edit-reason": "Причина:",
-       "tags-edit-revision-submit": "Ð\9fÑ\80имени Ð¸Ð·Ð¼ÐµÐ½Ð¸ Ð²Ñ\80з {{PLURAL:$1|пÑ\80еÑ\80абоÑ\82кава|$1 преработки}}",
+       "tags-edit-revision-submit": "Ð\9fÑ\80имени Ð¸Ð·Ð¼ÐµÐ½Ð¸ Ð²Ñ\80з {{PLURAL:$1|оваа Ð¿Ñ\80еÑ\80абоÑ\82ка|$1 преработки}}",
        "tags-edit-logentry-submit": "Примени измени врз {{PLURAL:$1|овој дневнички запис|$1 дневнички записи}}",
        "tags-edit-success": "Измените се применети.",
        "tags-edit-failure": "Не можев да ги применам измените:\n$1",
        "logentry-rights-autopromote": "$1 автоматски {{GENDER:$2|унапреден|унапредена}} од $4 во $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|ја подигна}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|подигна}} нова верзија на $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|Ñ\98а Ð¿Ð¾Ð´Ð¸Ð³Ð½Ð°}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|Ñ\98а Ð²Ñ\80аÑ\82и}} $3 Ð½Ð° Ð¿Ð¾Ñ\81Ñ\82аÑ\80а Ð²ÐµÑ\80зиÑ\98а",
        "log-name-managetags": "Дневник на раководство со ознаки",
        "log-description-managetags": "На страницава се наведени раководните задачи што се однесуваат на [[Special:Tags|ознаки]]. Дневникот содржи само дејства извршени рачно од администратор; ознаките можат да се создаваат и бришат од википрограмот без да се заведуваат во дневников.",
        "logentry-managetags-create": "$1 {{GENDER:$2|ја создаде}} ознаката „$4“",
        "duration-hours": "{{PLURAL:$1|еден час|$1 часа}}",
        "duration-days": "{{PLURAL:$1|еден ден|$1 дена}}",
        "duration-weeks": "$1 {{PLURAL:$1|недела|недели}}",
-       "duration-years": "{{PLURAL:$1|$1 година|$1 години}}",
+       "duration-years": "$1 {{PLURAL:$1|година|години}}",
        "duration-decades": "$1 {{PLURAL:$1|деценија|децении}}",
        "duration-centuries": "$1 {{PLURAL:$1|век|века}}",
        "duration-millennia": "$1 {{PLURAL:$1|милениум|милениуми}}",
        "mediastatistics-summary": "Статистики за подигнати типови податотеки. Се зема предвид само последната верзија на податотеката. Старите и избришаните верзии не се бројат.",
        "mediastatistics-nfiles": "$1 ($2 %)",
        "mediastatistics-nbytes": "{{PLURAL:$1|Еден бајт|$1 бајти}} ($2; $3%)",
-       "mediastatistics-bytespertype": "Ð\92кÑ\83пен Ð¾Ð±ÐµÐ¼ Ð½Ð° Ð¿Ð°Ñ\81Ñ\83Ñ\81от: {{PLURAL:$1|$1 бајт|$1 бајти}} ($2; $3%).",
+       "mediastatistics-bytespertype": "Ð\92кÑ\83пен Ð¾Ð±ÐµÐ¼ Ð½Ð° Ð¾Ð´Ð´ÐµÐ»от: {{PLURAL:$1|$1 бајт|$1 бајти}} ($2; $3%).",
        "mediastatistics-allbytes": "Вкупен обем на сите податотеки: {{PLURAL:$1|$1 бајт|$1 бајти}} ($2).",
        "mediastatistics-table-mimetype": "MIME-тип",
        "mediastatistics-table-extensions": "Можни додатоци",
        "log-action-filter-move-move": "Преместување без запис врз пренасочувања",
        "log-action-filter-move-move_redir": "Преместување со запис врз пренасочувања",
        "log-action-filter-newusers-create": "Создавање од анонимен корисник",
-       "log-action-filter-newusers-create2": "Создавање од анонимен корисник",
+       "log-action-filter-newusers-create2": "Создавање од регистриран корисник",
        "log-action-filter-newusers-autocreate": "Автоматско создавање",
        "log-action-filter-newusers-byemail": "Создавање со лозинка испратена по е-пошта",
        "log-action-filter-patrol-patrol": "Рачна патрола",
        "log-action-filter-suppress-reblock": "Притајување на корисникот преку преблокирање",
        "log-action-filter-upload-upload": "Ново подигање",
        "log-action-filter-upload-overwrite": "Преподигање",
+       "log-action-filter-upload-revert": "Отповикај",
        "authmanager-authn-not-in-progress": "Заверката не е во тек, или има губиток на седничките податоци. Почнете одново.",
        "authmanager-authn-no-primary": "Укажаните најавни податоци не можат да се заверат.",
        "authmanager-authn-no-local-user": "Укажаните најавни податоци не се поврзани со ниеден корисник на ова вики.",
        "authmanager-create-no-primary": "Укажаните најавни податоци не можат да се употребат во создавање на сметка.",
        "authmanager-link-no-primary": "Укажаните најавни податоци не можат да се употребат во поврзување на сметка.",
        "authmanager-link-not-in-progress": "Поврзувањето на сметката не е во тек, или има губиток на седничките податоци. Почнете одново.",
-       "authmanager-authplugin-setpass-failed-title": "Промената на лозинката не успеа",
-       "authmanager-authplugin-setpass-failed-message": "Приклучокот за заверка ја одби промената на лозинката.",
-       "authmanager-authplugin-create-fail": "Приклучокот за заверка го одби создавањето на сметката.",
-       "authmanager-authplugin-setpass-denied": "Приклучокот за заверка не допушта менување на лозинки.",
-       "authmanager-authplugin-setpass-bad-domain": "Неважечки домен.",
        "authmanager-autocreate-noperm": "Автоматското создавање на сметки не е дозволено.",
        "authmanager-autocreate-exception": "Автоматското создавање на сметки е привремено оневозможено поради претходни грешки.",
        "authmanager-userdoesnotexist": "Корисничката сметка „$1“ не е регистрирана.",
        "gotointerwiki": "Го напуштате {{SITENAME}}",
        "gotointerwiki-invalid": "Укажаниот наслов е неважечки.",
        "gotointerwiki-external": "Го напуштате {{SITENAME}} упатени кон [[$2]], кое е посебно мрежно место.\n\n'''[$1 Продолжете кон $1]'''",
-       "undelete-cantedit": "Ð\9dе Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ñ\98а Ð²Ñ\80аÑ\82иÑ\82е Ð¸Ð·Ð±Ñ\80иÑ\88анаÑ\82а страница бидејќи уредувањето на страницава не ви е дозволено.",
+       "undelete-cantedit": "Ð\9dе Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ñ\98а Ð²Ñ\80аÑ\82иÑ\82е Ð¾Ð²Ð°а страница бидејќи уредувањето на страницава не ви е дозволено.",
        "undelete-cantcreate": "Не можете да ја вратите страницава бидејќи не постои страница со таков назив и не ви е дозволено да ја создадете.",
        "pagedata-title": "Податоци за страницата",
        "pagedata-text": "Страницава дава посредник за податоци за страниците. Укажете го насловот на страницата во URL-то, користејќи ја синтаксата за потстраници.\n* Префрлањето на содржината се заснова на заглавието Прифати на вашиот клиент. Ова значи дека податоците за страницата ќе бидат ставени во форматот кој го претпочита вашиот клиент.",
        "passwordpolicies-policy-maximalpasswordlength": "Лозинката не треба да има повеќе од $1 {{PLURAL:$1|знак|знаци}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Лозинката не треба да биде {{PLURAL:$1|најзастапената|од списокот на $1 најзастапени лозинки}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинката не може да биде меѓу 100.000-те најчести лозинки.",
+       "passwordpolicies-policyflag-forcechange": "мора да се промени при најава",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "предложи измена при најава",
        "easydeflate-invaliddeflate": "Содржината не е соодветно прочистена",
        "unprotected-js": "JavaScript не може да се вчита од незаштитени страници од безбедносни причини. Создавајте JavaScript само во именскиот простор МедијаВики: или како корисничка потстраница"
 }
index b513eee..a6dc7e4 100644 (file)
@@ -31,7 +31,8 @@
                        "Viswaprabha",
                        "Nesi",
                        "Macofe",
-                       "Jameela P."
+                       "Jameela P.",
+                       "Adithyak1997"
                ]
        },
        "tog-underline": "കണ്ണികൾക്ക് അടിവരയിടുക:",
@@ -77,7 +78,8 @@
        "tog-norollbackdiff": "റോൾബാക്കിനു ശേഷം വ്യത്യാസം കാണിക്കാതിരിക്കുക",
        "tog-useeditwarning": "സേവ് ചെയ്യാത്ത മാറ്റങ്ങളോടു കൂടിയ തിരുത്തൽ താളിൽ നിന്നും പോകുമ്പോൾ എന്നെ അറിയിക്കുക",
        "tog-prefershttps": "പ്രവേശിച്ചിരിക്കുമ്പോൾ എപ്പോഴും സുരക്ഷിതമായ കണൿഷൻ ഉപയോഗിക്കുക",
-       "underline-always": "എല്ലായ്പ്പോഴും",
+       "tog-showrollbackconfirmation": "തിരിച്ചാക്കാനുള്ള കണ്ണി ഞെക്കുമ്പോൾ, അത് സ്ഥിരീകരിക്കാനുള്ള ചോദ്യം പ്രദർശിപ്പിക്കുക",
+       "underline-always": "എല്ലായ്‌പ്പോഴും",
        "underline-never": "ഒരിക്കലും അരുത്",
        "underline-default": "ദൃശ്യരൂപത്തിൽ അഥവാ ബ്രൗസറിൽ സ്വതേയുള്ള സ്വഭാവം",
        "editfont-style": "തിരുത്തൽ മേഖലയിലെ ഫോണ്ടിന്റെ ശൈലി:",
        "and": "&#32;ഒപ്പം",
        "faq": "പതിവുചോദ്യങ്ങൾ",
        "actions": "നടപടികൾ",
-       "namespaces": "നാമമേഖല",
+       "namespaces": "നാമമേഖലകൾ",
        "variants": "രൂപഭേദങ്ങൾ",
        "navigation-heading": "ഗമന വഴികാട്ടി",
        "errorpagetitle": "പിഴവ്",
        "history": "നാൾവഴി",
        "history_short": "നാൾവഴി",
        "history_small": "നാൾവഴി",
-       "updatedmarker": "à´\95à´´à´¿à´\9eàµ\8dà´\9e à´¸à´¨àµ\8dദർശനതàµ\8dതിനàµ\81 ശേഷം മാറ്റം വന്നത്",
+       "updatedmarker": "à´\95à´´à´¿à´\9eàµ\8dà´\9e à´¸à´¨àµ\8dദർശനതàµ\8dതിനàµ\8d ശേഷം മാറ്റം വന്നത്",
        "printableversion": "അച്ചടിരൂപം",
        "permalink": "സ്ഥിരംകണ്ണി",
        "print": "അച്ചടിയ്ക്കുക",
        "viewdeleted_short": "{{PLURAL:$1|മായ്ക്കപ്പെട്ട ഒരു തിരുത്തൽ|മായ്ക്കപ്പെട്ട $1 തിരുത്തലുകൾ}} കാണുക",
        "protect": "സം‌രക്ഷിക്കുക",
        "protect_change": "സംരക്ഷണമാനത്തിൽ മാറ്റം വരുത്തുക",
-       "unprotect": "à´¸à´\82à´°à´\95àµ\8dà´·à´£à´\82",
+       "unprotect": "à´¸à´\82à´°à´\95àµ\8dഷണതàµ\8dതിൽ à´®à´¾à´±àµ\8dà´±à´\82വരàµ\81à´¤àµ\8dà´¤àµ\81à´\95",
        "newpage": "പുതിയ താൾ",
        "talkpagelinktext": "സംവാദം",
        "specialpage": "പ്രത്യേക താൾ",
-       "personaltools": "à´¸àµ\8dà´µà´\95ാരàµ\8dയതാളàµ\81à´\95ൾ",
+       "personaltools": "à´µàµ\8dà´¯à´\95àµ\8dതിà´\97à´¤ à´\89à´ªà´\95à´°à´£à´\99àµ\8dà´\99ൾ",
        "talk": "സംവാദം",
        "views": "ദർശനീയത",
        "toolbox": "ഉപകരണങ്ങൾ",
        "versionrequired": "മീഡിയാവിക്കിയുടെ പതിപ്പ് $1 ആവശ്യമാണ്",
        "versionrequiredtext": "ഈ താൾ ഉപയോഗിക്കാൻ മീഡിയവിക്കി പതിപ്പ് $1 ആവശ്യമാണ്. കൂടുതൽ വിവരങ്ങൾക്ക് [[Special:Version|മീഡിയാവിക്കി പതിപ്പ് താൾ]] കാണുക.",
        "ok": "ശരി",
-       "retrievedfrom": "\"$1\" à´\8eà´¨àµ\8dà´¨ à´¤à´¾à´³à´¿àµ½à´¨à´¿à´¨àµ\8dà´¨àµ\81 ശേഖരിച്ചത്",
+       "retrievedfrom": "\"$1\" à´\8eà´¨àµ\8dà´¨ à´¤à´¾à´³à´¿àµ½à´¨à´¿à´¨àµ\8dà´¨àµ\8d ശേഖരിച്ചത്",
        "youhavenewmessages": "താങ്കൾക്ക് $1 ഉണ്ട് ($2).",
        "youhavenewmessagesfromusers": "താങ്കൾക്ക് {{PLURAL:$3|ഒരു ഉപയോക്താവ്|$3 ഉപയോക്താക്കൾ}} $1 ചേർത്തിട്ടുണ്ട് ($2).",
        "youhavenewmessagesmanyusers": "താങ്കൾക്ക് പലർ $1 ചേർത്തിട്ടുണ്ട് ($2).",
        "red-link-title": "$1 (ഇതുവരെ എഴുതപ്പെട്ടിട്ടില്ല)",
        "sort-descending": "അവരോഹണമായി ക്രമപ്പെടുത്തുക",
        "sort-ascending": "ആരോഹണമായി ക്രമപ്പെടുത്തുക",
-       "nstab-main": "à´²àµ\87à´\96à´¨à´\82",
+       "nstab-main": "താൾ",
        "nstab-user": "ഉപയോക്തൃതാൾ",
        "nstab-media": "മീഡിയാ താൾ",
        "nstab-special": "പ്രത്യേക താൾ",
        "badretype": "താങ്കൾ നൽകിയ രഹസ്യവാക്കുകൾ ഒത്തുപോകുന്നില്ല.",
        "usernameinprogress": "ഈ ഉപയോക്തൃനാമത്തിലുള്ള അംഗത്വ നിർമ്മിതി നടന്നുകൊണ്ടിരിക്കുന്നു.\nദയവായി കാത്തിരിക്കുക.",
        "userexists": "നൽകിയ ഉപയോക്തൃനാമം മുമ്പേ നിലവിലുണ്ട്.\nദയവായി മറ്റൊരു ഉപയോക്തൃനാമം തിരഞ്ഞെടുക്കുക.",
+       "createacct-normalization": "സാങ്കേതിക കാരണങ്ങളാൽ താങ്കളുടെ ഉപയോക്തൃനാമം \"$2\" എന്നാക്കി മാറ്റുന്നതാണ്.",
        "loginerror": "പ്രവേശനം സാധിച്ചില്ല",
        "createacct-error": "അംഗത്വസൃഷ്ടിക്കിടെ പിഴവുണ്ടായി",
        "createaccounterror": "അംഗത്വമെടുക്കാൻ കഴിഞ്ഞില്ല:$1",
        "changepassword-throttled": "കുറഞ്ഞ സമയത്തിനുള്ളിൽ താങ്കൾ നിരവധി തവണ പ്രവേശിക്കാൻ ശ്രമിച്ചിരിക്കുന്നു.\nവീണ്ടും ശ്രമിക്കുന്നതിനു മുമ്പ് ദയവായി $1 കാത്തിരിക്കുക.",
        "botpasswords": "യന്ത്രത്തിനുള്ള രഹസ്യവാക്കുകൾ",
        "botpasswords-disabled": "യാന്ത്രിക രഹസ്യവാക്കുകൾ അനുവദനീയമല്ല.",
+       "botpasswords-existing": "നിലവിലുള്ള ബോട്ട് രഹസ്യവാക്കുകൾ",
+       "botpasswords-createnew": "പുതിയ ബോട്ട് രഹസ്യവാക്ക് സൃഷ്ടിക്കുക",
+       "botpasswords-editexisting": "നിലവിലുള്ള ബോട്ട് രഹസ്യവാക്ക് തിരുത്തുക",
        "botpasswords-label-needsreset": "(രഹസ്യവാക്ക് പുനഃസജ്ജീകരിക്കേണ്ടതുണ്ട്)",
        "botpasswords-label-appid": "യന്ത്രത്തിന്റെ പേര്:",
        "botpasswords-label-create": "സൃഷ്ടിക്കുക",
        "botpasswords-label-resetpassword": "രഹസ്യവാക്ക് പുനഃക്രമീകരിക്കുക",
        "botpasswords-label-grants": "ബാധകമായ അനുമതികൾ:",
        "botpasswords-label-grants-column": "അനുവദിച്ചിരിക്കുന്നവ",
+       "botpasswords-bad-appid": "\"$1\" എന്ന ബോട്ട് നാമം സാധുവല്ല.",
+       "botpasswords-created-title": "ബോട്ടിന്റെ രഹസ്യവാക്ക് സൃഷ്ടിച്ചു",
+       "botpasswords-updated-title": "ബോട്ട് രഹസ്യവാക്ക് പുതുക്കി",
+       "botpasswords-deleted-title": "ബോട്ടിന്റെ രഹസ്യവാക്ക് ഒഴിവാക്കി",
        "resetpass_forbidden": "രഹസ്യവാക്കുകൾ മാറ്റുന്നത് അനുവദിക്കുന്നില്ല",
        "resetpass_forbidden-reason": "രഹസ്യവാക്കുകൾ മാറ്റാൻ കഴിയില്ല: $1",
        "resetpass-no-info": "ഈ താൾ നേരിട്ടു കാണുന്നതിന് താങ്കൾ ലോഗിൻ ചെയ്തിരിക്കണം.",
        "passwordreset-emailelement": "ഉപയോക്തൃനാമം: \n$1\n\nതാത്കാലിക രഹസ്യവാക്ക്: \n$2",
        "passwordreset-emailsentemail": "താങ്കളുടെ അംഗത്വത്തിന് നൽകിയിട്ടുള്ള ഇമെയിൽ വിലാസം ഇതാണെങ്കിൽ,  രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയക്കുന്നതാണ്.",
        "passwordreset-emailsentusername": "ഈ ഉപയോക്തൃനാമത്തിന് ഒരു ഇമെയിൽ വിലാസം ചേർത്തിട്ടുണ്ടെങ്കിൽ,  രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയക്കുന്നതാണ്.",
+       "passwordreset-nocaller": "ഒരു കോളറിനെ ചേർക്കണം",
+       "passwordreset-nosuchcaller": "കോളർ $1 നിലവിലില്ല",
        "passwordreset-invalidemail": "അസാധുവായ ഇമെയിൽ വിലാസം",
        "passwordreset-nodata": "ഉപയോക്തൃനാമമോ ഇമെയിൽ വിലാസമോ നൽകിയിട്ടില്ല",
        "changeemail": "ഇമെയിൽ വിലാസം മാറ്റുക അല്ലെങ്കിൽ നീക്കംചെയ്യുക",
        "content-model-text": "വെറും എഴുത്ത്",
        "content-model-javascript": "ജാവാസ്ക്രിപ്റ്റ്",
        "content-model-css": "സി.എസ്.എസ്.",
+       "content-json-empty-object": "ശൂന്യമായ ഒബ്‌ജെക്റ്റ്",
+       "content-json-empty-array": "അറേ ശൂന്യമാണ്",
+       "deprecated-self-close-category": "അസാധുവായ സ്വയം-അടയ്ക്കൽ എച്ച്.റ്റി.എം.എൽ. റ്റാഗുകൾ ഉപയോഗിക്കുന്ന താളുകൾ",
        "duplicate-args-warning": "<strong>മുന്നറിയിപ്പ്:</strong> [[:$1]], [[:$2]] എന്നതിനെ വിളിക്കുമ്പോൾ \"$3\" എന്ന ചരത്തിന് ഒന്നിലധികം വിലകൾ നൽകിയിട്ടുണ്ട്. നൽകിയ വിലകളിൽ അവസാനത്തേതുമാത്രം ഉപയോഗിക്കുന്നതാണ്.",
        "duplicate-args-category": "ഫലകങ്ങൾ വിളിക്കുമ്പോൾ ചരങ്ങൾ ആവർത്തിച്ചുപയോഗിക്കുന്ന താളുകൾ",
        "duplicate-args-category-desc": "താളിൽ ഫലകങ്ങൾ വിളിക്കുമ്പോൾ ചരങ്ങൾ അതായത് <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> അല്ലെങ്കിൽ <code><nowiki>{{foo|bar|1=baz}}</nowiki></code> എന്ന രീതിയിൽ.",
        "post-expand-template-argument-warning": "'''അറിയിപ്പ്:''' ഈ താളിൽ വളരെയധികം വികസിപ്പിക്കപ്പെട്ടേക്കാവുന്ന ഒരു ഫലകമെങ്കിലും ഉണ്ട്.\nഅതിനായുള്ള ഘടകങ്ങൾ ഒഴിവാക്കിയിരിക്കുന്നു.",
        "post-expand-template-argument-category": "താൾ ഫലകത്തിന്റെ ഘടകങ്ങളിൽ ഒഴിവാക്കിയവ ഉൾക്കൊള്ളുന്നു",
        "parser-template-loop-warning": "ഫലകക്കുരുക്ക് കണ്ടെത്തിയിരിക്കുന്നു: [[$1]]",
+       "template-loop-category": "ഫലക പുനരാവർത്തന പ്രശ്നമുള്ള താളുകൾ",
+       "template-loop-category-desc": "താളിൽ ഫലകം പുനരാവർത്തിക്കുന്നുണ്ട്, അതായത് ഒരു ഫലകം അതിനെ തന്നെ ആവർത്തിച്ചു വിളിച്ചുകൊണ്ടിരിക്കുന്നു.",
+       "template-loop-warning": "<strong>മുന്നറിയിപ്പ്:</strong> ഈ താൾ [[:$1]] ഫലകത്തെ വിളിക്കുന്നു, അതുവഴി ഫലക പുനരാവർത്തനം ഉണ്ടാകുന്നുണ്ട് (അനന്തമായ ആവർത്തിക്കൽ).",
        "parser-template-recursion-depth-warning": "ഫലകത്തിന്റെ പുനരാവർത്തന ആഴത്തിന്റെ പരിധി കഴിഞ്ഞിരിക്കുന്നു ($1)",
        "language-converter-depth-warning": "ഭാഷ മാറ്റൽ ഉപകരണത്തിന്റെ ആഴത്തിന്റെ പരിധി കവിഞ്ഞിരിക്കുന്നു ($1)",
        "node-count-exceeded-category": "നോഡ്-എണ്ണം അധികരിച്ച താളുകൾ",
        "histfirst": "ഏറ്റവും പഴയവ",
        "histlast": "ഏറ്റവും പുതിയവ",
        "historysize": "({{PLURAL:$1|1 ബൈറ്റ്|$1 ബൈറ്റുകൾ}})",
-       "historyempty": "(ശൂന്യം)",
+       "historyempty": "ശൂന്യം",
        "history-feed-title": "നാൾവഴി",
        "history-feed-description": "വിക്കിയിൽ ഈ താളിന്റെ നാൾവഴി",
        "history-feed-item-nocomment": "$2 സമയത്ത് $1",
        "diff-multi-sameuser": "(ഒരേ ഉപയോക്താവ് ചെയ്ത {{PLURAL:$1|ഇടയ്ക്കുള്ള ഒരു നാൾപ്പതിപ്പ്|ഇടയ്ക്കുള്ള $1 നാൾപ്പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല)",
        "diff-multi-otherusers": "({{PLURAL:$2|മറ്റൊരു ഉപയോക്താവ്|$2 ഉപയോക്താക്കൾ}} ചെയ്ത {{PLURAL:$1|ഇടയ്ക്കുള്ള ഒരു നാൾപ്പതിപ്പ്|ഇടയ്ക്കുള്ള $1 നാൾപ്പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല)",
        "diff-multi-manyusers": "(ഇടയ്ക്ക് {{PLURAL:$2|ഒന്നിലധികം|$2 എണ്ണത്തിലധികം}} ഉപയോക്താക്കൾ ചെയ്തിട്ടുള്ള {{PLURAL:$1|ഒരു പതിപ്പ്|$1 പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല.)",
+       "diff-paragraph-moved-tonew": "ഖണ്ഡിക മാറ്റിയിരിക്കുന്നു. പുതിയ സ്ഥാനത്തേക്ക് ചെല്ലാൻ ഞെക്കുക.",
+       "diff-paragraph-moved-toold": "ഖണ്ഡിക മാറ്റിയിരിക്കുന്നു. പഴയ സ്ഥാനത്തേക്ക് ചെല്ലാൻ ഞെക്കുക.",
        "difference-missing-revision": "ഈ വ്യത്യാസത്തിൽ ($1) {{PLURAL:$2|ഒരു നാൾപ്പതിപ്പ്|$2 നാൾപ്പതിപ്പുകൾ}} കാണാനായില്ല.\n\nമായ്ക്കപ്പെട്ട താളിന്റെ കാലഹരണപ്പെട്ട നാൾവഴി കണ്ണി ഉപയോഗിച്ചാലാണ് സാധാരണ ഇങ്ങനെ സംഭവിക്കുക.\nകൂടുതൽ വിവരങ്ങൾ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} മായ്ക്കൽ രേഖയിൽ] കാണാവുന്നതാണ്.",
        "searchresults": "തിരച്ചിലിന്റെ ഫലം",
+       "search-filter-title-prefix": "\"$1\" എന്ന് തലക്കെട്ട് തുടങ്ങുന്ന താളുകളിൽ മാത്രം തിരയുന്നു",
        "search-filter-title-prefix-reset": "എല്ലാ താളുകളും തിരയുക",
        "searchresults-title": "\"$1\" എന്നു തിരഞ്ഞതിനു ലഭ്യമായ ഫലങ്ങൾ",
        "titlematches": "താളിന്റെ തലക്കെട്ടുമായി യോജിക്കുന്ന ഫലങ്ങൾ",
        "right-reupload-own": "സ്വയം അപ്‌ലോഡ് ചെയ്ത പ്രമാണങ്ങൾക്കു മുകളിലേയ്ക്ക് പ്രമാണങ്ങൾ അപ്‌ലോഡ് ചെയ്യുക",
        "right-reupload-shared": "പങ്ക് വെയ്ക്കപ്പെട്ട മീഡിയ സംഭരണിയെ പ്രാദേശികമായി അതിലംഘിക്കുക",
        "right-upload_by_url": "യു.ആർ.എല്ലിൽ നിന്നും പ്രമാണങ്ങൾ അപ്‌ലോഡ് ചെയ്യുക",
-       "right-purge": "à´¸àµ\8dഥിരàµ\80à´\95à´°à´£à´\82 à´\92à´¨àµ\8dà´¨àµ\81à´\82 à´\87à´²àµ\8dലാതàµ\86 à´¸àµ\88à´±àµ\8dറിനàµ\8dà´±àµ\86 à´\95ാഷàµ\86 à´\92à´°àµ\81 à´¤à´¾à´³à´¿à´¨à´¾à´¯à´¿ à´ªàµ¼à´\9càµ\8d à´\9aàµ\86à´¯àµ\8dà´¯àµ\81à´\95",
+       "right-purge": "സൈറ്റിന്റെ കാഷെ ഒരു താളിനായി പർജ് ചെയ്യുക",
        "right-autoconfirmed": "ഐ.പി. അധിഷ്ഠിത പരിധികൾ ബാധകമല്ല",
        "right-bot": "യാന്ത്രിക പ്രവൃത്തിയായി കണക്കാക്കപ്പെടുന്നു",
        "right-nominornewtalk": "സംവാദം താളുകളിലെ ചെറുതിരുത്തലുകൾ പുതിയ സന്ദേശങ്ങളുണ്ടെന്ന അറിയിപ്പിനു കാരണമാകരുത്",
        "rcfilters-activefilters": "സജീവ അരിപ്പകൾ",
        "rcfilters-activefilters-hide": "മറയ്ക്കുക",
        "rcfilters-activefilters-show": "പ്രദർശിപ്പിക്കുക",
+       "rcfilters-activefilters-hide-tooltip": "സജീവ അരിപ്പകൾ സ്ഥലം മറയ്ക്കുക",
+       "rcfilters-activefilters-show-tooltip": "സജീവ അരിപ്പകൾ സ്ഥലം പ്രദർശിപ്പിക്കുക",
        "rcfilters-advancedfilters": "വിപുല അരിപ്പകൾ",
        "rcfilters-limit-title": "പ്രദർശിപ്പിക്കേണ്ട ഫലങ്ങൾ",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|ഒരു മാറ്റം|$1 മാറ്റങ്ങൾ}}, $2",
        "rcfilters-savedqueries-apply-and-setdefault-label": "സ്വതേയുള്ള അരിപ്പ സൃഷ്ടിക്കുക",
        "rcfilters-savedqueries-cancel-label": "റദ്ദാക്കുക",
        "rcfilters-savedqueries-add-new-title": "നിലവിലുള്ള അരിപ്പ സജ്ജീകരണം സേവ് ചെയ്യുക",
+       "rcfilters-savedqueries-already-saved": "ഈ അരിപ്പകൾ മുമ്പേ തന്നെ സേവ് ചെയ്തിട്ടുണ്ട്. പുതിയ സേവ് ചെയ്യാനുള്ള അരിപ്പ സൃഷ്ടിക്കാൻ താങ്കളുടെ സജ്ജീകരണങ്ങളിൽ മാറ്റം വരുത്തുക.",
        "rcfilters-restore-default-filters": "സ്വതേയുള്ള അരിപ്പകൾ പുനഃസ്ഥാപിക്കുക",
        "rcfilters-clear-all-filters": "എല്ലാ അരിപ്പകളും ഒഴിവാക്കുക",
        "rcfilters-show-new-changes": "ഏറ്റവും പുതിയ മാറ്റങ്ങൾ കാണുക",
        "rcfilters-filter-humans-description": "മനുഷ്യലേഖകർ ചെയ്ത തിരുത്തുകൾ",
        "rcfilters-filtergroup-reviewstatus": "സംശോധന സ്ഥിതി",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "റോന്ത് ചുറ്റപ്പെടാത്തവ",
+       "rcfilters-filter-reviewstatus-auto-label": "സ്വതേ റോന്തുചുറ്റിയവ",
        "rcfilters-filtergroup-significance": "പ്രാധാന്യം",
        "rcfilters-filter-minor-label": "ചെറുതിരുത്തുകൾ",
        "rcfilters-filter-minor-description": "ലേഖകൻ ചെറുതെന്ന് അടയാളപ്പെടുത്തിയ തിരുത്തുകൾ.",
        "uploadstash-errclear": "പ്രമാണങ്ങൾ ശൂന്യമാക്കൽ പരാജയപ്പെട്ടു.",
        "uploadstash-refresh": "പ്രമാണങ്ങളുടെ പട്ടിക പുതുക്കുക",
        "uploadstash-thumbnail": "ലഘുചിത്രം കാണുക",
+       "uploadstash-bad-path-invalid": "പാത്ത് അസാധുവാണ്.",
        "uploadstash-bad-path-unknown-type": "അപരിചിതമായ തരം \"$1\".",
        "uploadstash-file-not-found-no-thumb": "ലഘുചിത്രം സംഘടിപ്പിക്കാൻ കഴിഞ്ഞില്ല.",
        "uploadstash-file-not-found-no-remote-thumb": "ലഘുചിത്രം എടുക്കൽ പരാജയപ്പെട്ടു: $1\nയു.ആർ.എൽ.= $2",
        "uploadstash-no-extension": "എക്സ്റ്റെൻഷൻ ശൂന്യമാണ്.",
+       "uploadstash-zero-length": "പ്രമാണത്തിന്റെ നീളം ശൂന്യമാണ്.",
        "img-auth-accessdenied": "പ്രവേശനമില്ല",
        "img-auth-nopathinfo": "പാത്ത് വിവരങ്ങൾ ലഭ്യമല്ല.\nതാങ്കളുടെ സെർവർ REQUEST_URI ഒപ്പം/അല്ലെങ്കിൽ PATH_INFO കൈമാറ്റം ചെയ്യാൻ കഴിയുന്നതായി സജ്ജീകരിച്ചിരിക്കേണ്ടതുണ്ട്.\nഅങ്ങനെ ചെയ്തിട്ടുണ്ടെങ്കിൽ $wgUsePathInfo സജ്ജമാക്കുക.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization കാണുക.",
        "img-auth-notindir": "ആവശ്യപ്പെട്ട പാത അപ്‌‌ലോഡ് ഡയറക്റ്ററിയിൽ സജ്ജീകരിച്ചു നൽകിയിട്ടില്ല.",
        "apisandbox-submit-invalid-fields-title": "ചില മണ്ഡലങ്ങൾ അസാധുവാണ്",
        "apisandbox-results": "ഫലങ്ങൾ",
        "apisandbox-request-url-label": "അഭ്യർത്ഥനാ യൂ.ആർ.എൽ.:",
+       "apisandbox-request-json-label": "ജെസൺ അപേക്ഷിക്കുക:",
        "apisandbox-request-time": "അഭ്യർത്ഥനയുടെ സമയം: {{PLURAL:$1|$1 മി.സെ.}}",
        "apisandbox-results-fixtoken": "ചീട്ട് ശരിയാക്കിയ ശേഷം വീണ്ടും സമർപ്പിക്കുക",
+       "apisandbox-results-fixtoken-fail": "\"$1\" ചീട്ട് എടുക്കുന്നത്‌ പരാജയപെട്ടു.",
+       "apisandbox-alert-page": "ഈ താളിലെ ഫീൽഡുകൾ അസാധുവാണ്.",
        "apisandbox-continue": "തുടരുക",
        "apisandbox-continue-clear": "ശൂന്യമാക്കുക",
        "apisandbox-multivalue-all-namespaces": "$1 (എല്ലാ നാമമേഖലകളും)",
        "booksources-search": "തിരയുക",
        "booksources-text": "പുതിയതും ഉപയോഗിച്ചതുമായ പുസ്തകങ്ങൾ വിൽക്കുന്ന സൈറ്റുകളിലേക്കുള്ള ലിങ്കുകളുടെ പട്ടിക ആണ്‌ താഴെ. താങ്കൾ തിരയുന്ന പുസ്തകത്തെ പറ്റിയുള്ള കൂടുതൽ വിവരങ്ങൾ ഈ പട്ടികയിൽ നിന്നു ലഭിച്ചേക്കാം:",
        "booksources-invalid-isbn": "തന്നിരിക്കുന്ന ഐ.എസ്.ബി.എൻ. സാധുവാണെന്നു തോന്നുന്നില്ല; യഥാർത്ഥ സ്രോതസ്സിൽ നിന്നും പകർത്തിയപ്പോൾ തെറ്റുപറ്റിയോ എന്നു പരിശോധിക്കുക",
+       "magiclink-tracking-rfc": "RFC മാജിക് കണ്ണികൾ ഉപയോഗിക്കുന്ന താളുകൾ",
+       "magiclink-tracking-pmid": "PMID മാജിക് കണ്ണികൾ ഉപയോഗിക്കുന്ന താളുകൾ",
+       "magiclink-tracking-isbn": "ISBN മാജിക് കണ്ണികൾ ഉപയോഗിക്കുന്ന താളുകൾ",
        "specialloguserlabel": "നടപ്പിലാക്കിയയാൾ:",
        "speciallogtitlelabel": "ലക്ഷ്യം (തലക്കെട്ട് അല്ലെങ്കിൽ ഉപയോക്താവിനെ തിരയാനുള്ള {{ns:user}}:ഉപയോക്തൃനാമം) :",
        "log": "പ്രവർത്തനരേഖകൾ",
        "watchnologin": "ലോഗിൻ ചെയ്തിട്ടില്ല",
        "addwatch": "ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിലേക്കു ചേർക്കുക",
        "addedwatchtext": "താങ്കൾ [[Special:Watchlist|ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിലേക്ക്]] \"[[:$1]]\" എന്ന ഈ താളും അതിന്റെ സംവാദത്താളും ചേർത്തിരിക്കുന്നു.",
+       "addedwatchtext-talk": "\"[[:$1]]\" ഒപ്പം ഇതിന്റെ ബന്ധപ്പെട്ട താളും താങ്കൾ [[Special:Watchlist|ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിലേക്ക്]] ചേർത്തിരിക്കുന്നു.",
        "addedwatchtext-short": "\"$1\" എന്ന താൾ താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിലേക്ക് ചേർത്തു.",
        "removewatch": "ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽ നിന്നും ഒഴിവാക്കുക",
        "removedwatchtext": "താങ്കൾ [[Special:Watchlist|ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽ]] നിന്നും \"[[:$1]]\" എന്ന താളും അതിന്റെ സംവാദത്താളും നീക്കം ചെയ്തിരിക്കുന്നു.",
+       "removedwatchtext-talk": "\"[[:$1]]\" ഒപ്പം ഇതിന്റെ ബന്ധപ്പെട്ട താളും താങ്കൾ [[Special:Watchlist|ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിൽ]] നിന്ന് ഒഴിവാക്കിയിരിക്കുന്നു.",
        "removedwatchtext-short": "\"$1\" എന്ന താൾ താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിൽ നിന്ന് നീക്കി.",
        "watch": "മാറ്റങ്ങൾ ശ്രദ്ധിക്കുക",
        "watchthispage": "ഈ താൾ ശ്രദ്ധിക്കുക",
        "deleting-backlinks-warning": "<strong>മുന്നറിയിപ്പ്:</strong> മറ്റു താളുകളിൽ നിന്നും [[Special:WhatLinksHere/{{FULLPAGENAME}}|താളിലേയ്ക്കുള്ള കണ്ണികൾ]] അല്ലെങ്കിൽ ഉൾപ്പെടുത്തിയിട്ടുള്ള താളുകൾ താങ്കൾ മായ്ക്കാൻ പോവുകയാണ്.",
        "deleting-subpages-warning": "<strong>മുന്നറിയിപ്പ്:</strong> താങ്കൾ മായ്ക്കാൻ പോകുന്ന താളിന് [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|ഒരു ഉപതാൾ|$1 ഉപതാളുകൾ|51=അമ്പതിലധികം ഉപതാളുകൾ}}]] ഉണ്ട്.",
        "rollback": "തിരുത്തുകൾ റോൾബാക്ക് ചെയ്യുക",
+       "rollback-confirmation-confirm": "ദയവായി സ്ഥിരീകരിക്കുക:",
+       "rollback-confirmation-yes": "റോൾബാക്ക്",
+       "rollback-confirmation-no": "റദ്ദാക്കുക",
        "rollbacklink": "റോൾബാക്ക്",
        "rollbacklinkcount": "{{PLURAL:$1|ഒരു തിരുത്ത്|$1 തിരുത്തുകൾ}} മുൻപ്രാപനം ചെയ്യുക",
        "rollbacklinkcount-morethan": "{{PLURAL:$1|ഒന്നിലധികം തിരുത്തുകൾ|$1 എണ്ണത്തിലധികം തിരുത്തുകൾ}} മുൻപ്രാപനം ചെയ്യുക",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|സംവാദം]]) നടത്തിയ തിരുത്തലുകൾ നീക്കം ചെയ്തിരിക്കുന്നു; നിലവിലുള്ള പതിപ്പ് [[User:$1|$1]] സൃഷ്ടിച്ചതാണ്",
        "revertpage-nouser": "മറയ്ക്കപ്പെട്ട ഉപയോക്താവ് നടത്തിയ തിരുത്തലുകൾ {{GENDER:$1|[[User:$1|$1]]}} സൃഷ്ടിച്ച അവസാന പതിപ്പിലേയ്ക്ക് മുൻപ്രാപനം ചെയ്തിരിക്കുന്നു",
        "rollback-success": "{{GENDER:$3|$1}} ചെയ്ത തിരുത്ത് തിരസ്ക്കരിച്ചിരിക്കുന്നു; {{GENDER:$4|$2}} ചെയ്ത തൊട്ടു മുൻപത്തെ പതിപ്പിലേക്ക് സേവ് ചെയ്യുന്നു.",
-       "rollback-success-notify": "$1 ചെയ്ത തിരുത്തുകൾ തിരസ്ക്കരിച്ചിരിക്കുന്നു; $2 ചെയ്ത തൊട്ടു മുൻപത്തെ പതിപ്പിലേക്ക് സേവ് ചെയ്യുന്നു. [$3 മാറ്റങ്ങൾ കാണിക്കുക]",
        "sessionfailure-title": "സെഷൻ പരാജയപ്പെട്ടിരിക്കുന്നു",
        "sessionfailure": "താങ്കളുടെ ലോഗിൻ സെഷനിൽ പ്രശ്നങ്ങളുള്ളതായി കാണുന്നു;\nസെഷൻ തട്ടിയെടുക്കൽ ഒഴിവാക്കാനുള്ള മുൻകരുതലായി ഈ പ്രവൃത്തി റദ്ദാക്കിയിരിക്കുന്നു.\nദയവായി ഫോം വീണ്ടും സമർപ്പിക്കുക.",
        "changecontentmodel": "താളിന്റെ ഉള്ളടക്ക രീതി തിരുത്തുക",
        "ipb-confirm": "തടയൽ സ്ഥിരീകരിക്കുക",
        "ipb-sitewide": "സൈറ്റ്-വ്യാപകം",
        "ipb-partial": "ഭാഗികം",
+       "ipb-partial-help": "പ്രത്യേക താളുകൾ അല്ലെങ്കിൽ നാമമേഖലകൾ.",
        "ipb-pages-label": "താളുകൾ",
        "ipb-namespaces-label": "നാമമേഖലകൾ",
        "badipaddress": "അസാധുവായ ഐ.പി. വിലാസം.",
        "imgmultipagenext": "അടുത്ത താൾ →",
        "imgmultigo": "പോകൂ!",
        "imgmultigoto": "$1 താളിലേക്ക് പോകുക",
-       "img-lang-default": "(സ്വതേ വേണ്ട ഭാഷ)",
+       "img-lang-default": "(സ്വതേയുള്ള ഭാഷ)",
        "img-lang-info": "ഈ ചിത്രം ഈ ഭാഷയിൽ കാണിക്കുക: $1. $2",
        "img-lang-go": "പോകൂ",
        "ascending_abbrev": "ആരോഹണം",
        "htmlform-date-invalid": "താങ്കൾ നൽകിയ വില തീയതിയായി കണക്കാക്കാനാകുന്നില്ല. വവവവ-മാമാ-തീതീ ഘടന ഉപയോഗിച്ചുനോക്കുക",
        "htmlform-time-invalid": "താങ്കൾ നൽകിയ വില സമയമായി കണക്കാക്കാനാകുന്നില്ല. മമ:മിമി:സെസെ ഘടന ഉപയോഗിച്ചുനോക്കുക",
        "htmlform-datetime-invalid": "താങ്കൾ നൽകിയ വില തീയതിയും സമയവുമായി കണക്കാക്കാനാകുന്നില്ല. വവവവ-മാമാ-തീതീ മമ:മിമി:സെസെ ഘടന ഉപയോഗിച്ചുനോക്കുക",
+       "htmlform-date-toohigh": "$1 എന്ന അനുവദനീയമായ തിയതിക്ക് ശേഷമുള്ളതാണ് താങ്കൾ കൊടുത്തിരിക്കുന്ന തീയതി.",
+       "htmlform-time-toolow": "$1 എന്ന അനുവദനീയമായ തിയതിക്ക് മുൻപുള്ള തീയതിയാണ് താങ്കൾ കൊടുത്തിരിക്കുന്നത്.",
        "htmlform-title-badnamespace": "[[:$1]] ഉള്ളത് \"{{ns:$2}}\" നാമമേഖലയിലല്ല.",
        "htmlform-title-not-creatable": "\"$1\" സൃഷ്ടിക്കാനാവുന്ന തലക്കെട്ടല്ല.",
        "htmlform-title-not-exists": "$1 നിലവിലില്ല.",
        "logentry-rights-autopromote": "$1 എന്ന ഉപയോക്താവ് $4 എന്നതിൽ നിന്നും $5 എന്നതിലേയ്ക്ക് സ്വയമേവ {{GENDER:$2|ഉയർത്തപ്പെട്ടിരിക്കുന്നു}}",
        "logentry-upload-upload": "$1 $3 {{GENDER:$2|അപ്‌ലോഡ് ചെയ്തു}}",
        "logentry-upload-overwrite": "$1 ഒരു പുതിയ പതിപ്പ് $3 {{GENDER:$2|അപ്‌ലോഡ് ചെയ്തു}}",
-       "logentry-upload-revert": "$1 $3 {{GENDER:$2|അപ്‌ലോഡ് ചെയ്തു}}",
+       "logentry-upload-revert": "$3 പഴയ പതിപ്പിലേക്ക് $1 {{GENDER:$2|തിരിച്ചാക്കി}}",
        "log-name-managetags": "ടാഗ് കൈകാര്യ രേഖ",
        "log-description-managetags": "ഈ താളിൽ [[Special:Tags|ടാഗുകളുമായി]] ബന്ധപ്പെട്ട പ്രവൃത്തികളുടെ കാര്യനിർവഹണം ഉൾപ്പെടുത്തിയിരിക്കുന്നു. രേഖയിൽ ഒരു കാര്യനിർവ്വാഹക(ൻ) നടത്തിയ പ്രവൃത്തികൾ മാത്രമേ ഉൾപ്പെടുന്നുള്ളു; വിക്കി സോഫ്റ്റ്‌വേർ സൃഷ്ടിച്ചതോ നീക്കംചെയ്തതോ ആയ ടാഗുകൾ ഈ രേഖയിൽ ശേഖരിക്കുന്നില്ല.",
        "logentry-managetags-create": "\"$4\" എന്ന ടാഗ് $1 {{GENDER:$2|സൃഷ്ടിച്ചിരിക്കുന്നു}}",
        "log-action-filter-suppress-delete": "താൾ ഒതുക്കൽ",
        "log-action-filter-upload-upload": "പുതിയ അപ്‌ലോഡ്",
        "log-action-filter-upload-overwrite": "പുനർ അപ്‌ലോഡ്",
+       "log-action-filter-upload-revert": "തിരിച്ചാക്കൽ",
        "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-bad-domain": "അസാധുവായ ഡൊമൈൻ.",
        "authmanager-userdoesnotexist": "\"$1\" എന്ന ഉപയോക്തൃ അം‌ഗത്വം നിലവിലില്ല.",
        "authmanager-userlogin-remembermypassword-help": "രഹസ്യവാക്ക് സെഷൻ കാലയളവിലധികം ഓർത്തുവെക്കണോ.",
        "authmanager-username-help": "രഹസ്യവാക്ക് ഉപയോഗിച്ചുള്ള സാധൂകരണം.",
        "authmanager-provider-password": "രഹസ്യവാക്ക്-അധിഷ്ഠിത സാധൂകരണം",
        "authmanager-provider-password-domain": "രഹസ്യവാക്ക്-ഡൊമൈൻ-അധിഷ്ഠിത സാധൂകരണം",
        "authmanager-provider-temporarypassword": "താത്കാലിക രഹസ്യവാക്ക്",
+       "authprovider-confirmlink-success-line": "$1: വിജയകരമായി കണ്ണി ചേർത്തു.",
        "authprovider-resetpass-skip-label": "മറികടക്കുക",
+       "authform-newtoken": "ചീട്ട് കാണുന്നില്ല. $1",
+       "authform-notoken": "ചീട്ട് കാണുന്നില്ല",
+       "authform-wrongtoken": "തെറ്റായ ചീട്ട്",
        "specialpage-securitylevel-not-allowed-title": "അനുവദിച്ചിട്ടില്ല",
        "specialpage-securitylevel-not-allowed": "താങ്കളുടെ വ്യക്തിത്വം പരിശോധിക്കാൻ കഴിയാഞ്ഞതിനാൽ ഈ താൾ ഉപയോഗിക്കാൻ താങ്കളെ അനുവദിക്കാനാവില്ല.",
        "authpage-cannot-login": "പ്രവേശനം തുടങ്ങാൻ സാധിക്കുന്നില്ല.",
        "linkaccounts-submit": "അംഗത്വങ്ങൾ കണ്ണി ചേർക്കുക",
        "unlinkaccounts": "അംഗത്വങ്ങൾ കണ്ണി മാറ്റുക",
        "unlinkaccounts-success": "അംഗത്വം കണ്ണി മാറ്റി.",
+       "userjsispublic": "ദയവായി ശ്രദ്ധിക്കുക: ജാവാസ്ക്രിപ്റ്റ് ഉപതാളുകൾ മറ്റ് ഉപയോക്താക്കൾക്ക് കാണാൻ കഴിയും, അവയിൽ സ്വകാര്യവിവരങ്ങൾ ചേർക്കാതിരിക്കുക.",
+       "userjsonispublic": "ദയവായി ശ്രദ്ധിക്കുക: ജെസൺ ഉപതാളുകൾ മറ്റ് ഉപയോക്താക്കൾക്ക് കാണാൻ കഴിയും, അവയിൽ സ്വകാര്യവിവരങ്ങൾ ചേർക്കാതിരിക്കുക.",
+       "usercssispublic": "ദയവായി ശ്രദ്ധിക്കുക: സി.എസ്.എസ്. ഉപതാളുകൾ മറ്റ് ഉപയോക്താക്കൾക്ക് കാണാൻ കഴിയും, അവയിൽ സ്വകാര്യവിവരങ്ങൾ ചേർക്കാതിരിക്കുക.",
        "restrictionsfield-badip": "അസാധുവായ ഐ.പി. വിലാസം അല്ലെങ്കിൽ പരിധി:$1",
        "restrictionsfield-label": "അനുവദിച്ചിട്ടുള്ള ഐ.പി. പരിധികൾ:",
        "edit-error-short": "പിഴവ്: $1",
        "edit-error-long": "പിഴവുകൾ:\n\n$1",
        "revid": "നാൾപ്പതിപ്പ് $1",
        "pageid": "താൾ ഐ.ഡി. $1",
+       "interfaceadmin-info": "$1\n\nസൈറ്റ്‌വ്യാപക സി.എസ്.എസ്./ജെ.എസ്./ജെസൺ പ്രമാണങ്ങൾ തിരുത്താനുള്ള അവകാശം സമീപകാലത്ത് <code>editinterface</code> അവകാശത്തിൽനിന്നും വേർപെടുത്തിയതാണ്. ഈ പിഴവ് എന്തുകൊണ്ടാണ് പ്രദർശിക്കപ്പെടുന്നതെന്ന് താങ്കൾക്ക് മനസ്സിലാകുന്നില്ലെങ്കിൽ [[mw:MediaWiki_1.32/interface-admin]] കാണുക.",
        "rawhtml-notallowed": "&lt;html&gt; ടാഗുകൾ സാധാരണ താളുകൾക്ക്പുറത്ത് ഉപയോഗിക്കാനാകില്ല.",
        "gotointerwiki": "{{SITENAME}} സംരംഭത്തിൽ നിന്നും പോകുകയാണ്",
        "gotointerwiki-invalid": "നൽകിയിരിക്കുന്ന തലക്കെട്ട് അസാധുവാണ്.",
        "passwordpolicies-policy-passwordcannotmatchusername": "ഉപയോക്തൃനാമം തന്നെ രഹസ്യവാക്ക് ആകാൻ പാടില്ല",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "രഹസ്യവാക്ക് കരിമ്പട്ടികയിൽ ഉള്ള രഹസ്യവാക്കുകൾക്ക് സമാനമാകരുത്",
        "passwordpolicies-policy-maximalpasswordlength": "രഹസ്യവാക്കിന് കുറഞ്ഞത് $1 {{PLURAL:$1|അക്ഷരം|അക്ഷരങ്ങൾ}} നീളമുണ്ടാവണം",
-       "passwordpolicies-policy-passwordcannotbepopular": "രഹസ്യവാക്ക് {{PLURAL:$1|പ്രചുരപ്രചാരത്തിൽ ഉള്ളത്|പ്രചുരപ്രചാരത്തിലുള്ള $1 രഹസ്യവാക്കുകളുടെ പട്ടികയിൽ ഉള്ളത്}} ആകരുത്."
+       "passwordpolicies-policy-passwordcannotbepopular": "രഹസ്യവാക്ക് {{PLURAL:$1|പ്രചുരപ്രചാരത്തിൽ ഉള്ളത്|പ്രചുരപ്രചാരത്തിലുള്ള $1 രഹസ്യവാക്കുകളുടെ പട്ടികയിൽ ഉള്ളത്}} ആകരുത്.",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "രഹസ്യവാക്ക്, പരക്കെ ഉപയോഗിക്കപ്പെടുന്ന 1,00,000 രഹസ്യവാക്കുകളുടെ പട്ടികയിൽ ഉള്ളതാവരുത്.",
+       "passwordpolicies-policyflag-forcechange": "ലോഗിൻ മാറ്റിയിരിക്കണം",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "ലോഗിൻ മാറ്റാൻ നിർദ്ദേശിക്കുന്നു",
+       "unprotected-js": "സുരക്ഷാകാരണങ്ങളാൽ സംരക്ഷണമില്ലാത്ത താളുകളിൽ നിന്നും ജാവാസ്ക്രിപ്റ്റ് എടുത്തുപയോഗിക്കാൻ കഴിയില്ല. ജാവാസ്ക്രിപ്റ്റ് താളുകൾ മീഡിയവിക്കി: നാമമേഖലയിലോ ഉപയോക്തൃ ഉപതാളായോ മാത്രം സൃഷ്ടിക്കുക"
 }
index 5c16e4d..61d40cb 100644 (file)
        "accmailtext": "Kata laluan janaan rawak untuk [[User talk:$1|$1]] telah dikirim kepada $2. Anda boleh menukarnya di halaman ''[[Special:ChangePassword|tukar kata laluan]]'' sebaik sahaja log masuk.",
        "newarticle": "(Baru)",
        "newarticletext": "Anda telah mengikuti pautan ke laman yang belum wujud.\nUntuk mencipta laman ini, sila taip dalam kotak di bawah\n(lihat [$1 laman bantuan] untuk maklumat lanjut).\nJika anda tiba di sini secara tak sengaja, hanya klik butang '''back''' pada pelayar anda.",
-       "anontalkpagetext": "<em>Ini ialah laman perbincangan bagi pengguna tanpa nama yang belum membuka akaun atau tidak menggunakannya.</em>\nOleh itu, kami terpaksa menggunakan alamat IP angka untuk mengenal pasti pengguna tersebut. Alamat IP ini boleh dikongsi oleh ramai pengguna.\nSekiranya anda ialah seorang pengguna tanpa nama dan berasa bahawa komen yang tidak relevan telah ditujukan kepada anda, sila [[Special:CreateAccount|buka akaun baru]] atau [[Special:UserLogin|log masuk]] untuk mengelakkan sebarang kekeliruan dengan pengguna tanpa nama yang lain.",
+       "anontalkpagetext": "----\n<em>Ini laman perbincangan bagi pengguna tanpa nama yang belum cipta akaun lagi, atau yang tudaj menggunakannya.</em>\nOleh itu, kami perlu menggunakan alamat IP berangka untuk mengecam mereka^.\nAlamat IP sebegini boleh dikongsi oleh beberapa pengguna.\nJika anda ini pengguna tanpa nama dan rasa bahawa ulasan tiada kaitan telah ditujukan kepada anda, sila [[Special:CreateAccount|cipta akaun]] atau [[Special:UserLogin|log masuk]] untuk mengelakkan kekeliruan kelak dengan pengguna tanpa nama yang lain.",
        "noarticletext": "Laman ini tiada teks buat masa sekarang.\nAnda boleh [[Special:Search/{{PAGENAME}}|cari tajuk bagi laman ini]] di laman-laman lain, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} cari log-log yang berkaitan], atau [{{fullurl:{{FULLPAGENAME}}|action=edit}} sunting laman ini]</span>.",
        "noarticletext-nopermission": "Tiada teks dalam laman ini ketika ini.\nAnda boleh [[Special:Search/{{PAGENAME}}|mencari tajuk laman ini]] dalam laman lain,\natau <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mencari log yang berkaitan]</span>.",
        "missing-revision": "Semakan #$1 pada halaman \"{{FULLPAGENAME}}\" tidak wujud.\n\nHal ini biasanya disebabkan oleh pautan sejarah yang lapuk ke halaman yang sudah dihapuskan.\nButirannya boleh didapati di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapusan].",
        "editpage-invalidcontentmodel-text": "Model kandungan \"$1\" tidak disokong.",
        "editpage-notsupportedcontentformat-title": "Format kandungan tidak disokong",
        "editpage-notsupportedcontentformat-text": "Format kandungan $1 tidak disokong oleh model kandungan $2.",
+       "slot-name-main": "Utama",
        "content-model-wikitext": "wikiteks",
        "content-model-text": "teks biasa",
        "content-model-javascript": "JavaScript",
        "right-managechangetags": "Mencipta dan menghapuskan [[Special:Tags|teg]] dari pangkalan data",
        "right-applychangetags": "Mengenakan [[Special:Tags|teg]] di samping suntingan seseorang",
        "right-changetags": "Menambah dan menggugurkan [[Special:Tags|teg]] yang dikenakan sembarangan pada semakan dan entri log individu",
+       "grant-group-email": "Hantar e-mel",
+       "grant-createaccount": "Cipta akaun",
+       "grant-createeditmovepage": "Cipta, sunting dan pindah laman",
        "grant-editmywatchlist": "Sunting senarai pantau anda",
        "grant-editpage": "Sunting laman sedia ada",
        "grant-editprotected": "Sunting laman yang dilindungi",
+       "grant-sendemail": "Hantar e-mel ke pengguna lain",
        "grant-uploadfile": "Muat naik fail baru",
        "grant-basic": "Hak-hak asas",
        "newuserlogpage": "Log akaun baru",
        "rightslogtext": "Ini ialah log perubahan terhadap hak pengguna.",
        "action-read": "membaca laman ini",
        "action-edit": "menyunting laman ini",
-       "action-createpage": "mencipta laman",
-       "action-createtalk": "mencipta laman perbincangan",
+       "action-createpage": "ciptakan laman ini",
+       "action-createtalk": "ciptakan laman perbincangan ini",
        "action-createaccount": "mencipta akaun pengguna ini",
        "action-history": "melihat sejarah halaman ini",
        "action-minoredit": "menanda suntingan ini sebagai suntingan kecil",
        "filehist-comment": "Komen",
        "imagelinks": "Penggunaan fail",
        "linkstoimage": "{{PLURAL:$1|Laman|$1 buah laman}} berikut menggunakan fail ini:",
-       "linkstoimage-more": "Lebih daripada $1 laman mengandungi pautan ke fail ini.\nYang berikut ialah {{PLURAL:$1||$1}} pautan pertama ke fail ini.\nAnda boleh melihat [[Special:WhatLinksHere/$2|senarai penuh]].",
+       "linkstoimage-more": "Lebih daripada $1 {{PLURAL:$1|laman menggunakan|laman menggunakan}} fail ini.\nYang berikut ialah {{PLURAL:$1|laman pertama|laman $1 pertama}} yang menggunakan fail ini sahaja.\nTerdapat [[Special:WhatLinksHere/$2|senarai penuh]] tersedia.",
        "nolinkstoimage": "Tiada laman yang menggunakan fail ini.",
        "morelinkstoimage": "Lihat [[Special:WhatLinksHere/$1|semua pautan]] ke fail ini.",
        "linkstoimage-redirect": "$1 (lencongan fail) $2",
        "unwatchthispage": "Berhenti memantau",
        "notanarticle": "Bukan laman kandungan",
        "notvisiblerev": "Semakan ini telah dihapuskan",
-       "watchlist-details": "$1 laman dipantau ,tidak termasuk laman perbincangan.",
+       "watchlist-details": "{{PLURAL:$1|$1 laman|$1 laman}} di Senarai Pantau anda (termasuk laman perbincangan).",
        "wlheader-enotif": "Pemberitahuan melalui e-mel dibolehkan.",
        "wlheader-showupdated": "Laman-laman yang telah diubah sejak kunjungan terakhir anda dipaparkan dalam '''teks tebal'''.",
        "wlnote": "Yang berikut ialah <strong>$1</strong> perubahan terakhir sejak $2 jam yang lalu, sehingga $3, $4.",
        "tooltip-feed-rss": "Suapan RSS bagi laman ini",
        "tooltip-feed-atom": "Suapan Atom bagi laman ini",
        "tooltip-t-contributions": "Senarai sumbangan {{GENDER:$1|pengguna ini}}",
-       "tooltip-t-emailuser": "Kirim e-mel kepada pengguna ini",
+       "tooltip-t-emailuser": "Kirim e-mel kepada {{GENDER:$1|pengguna ini}}",
        "tooltip-t-info": "Maklumat lanjut mengenai laman ini",
        "tooltip-t-upload": "Muat naik imej atau fail media",
        "tooltip-t-specialpages": "Senarai laman khas",
        "version-libraries-license": "Lesen",
        "version-libraries-description": "Keterangan",
        "version-libraries-authors": "Pengarang",
-       "redirect": "Lencongkan mengikut ID fail, pengguna, halaman atau semakan",
+       "redirect": "Lencongkan mengikut fail, pengguna, laman, semakan, atau ID log",
        "redirect-summary": "Halaman khas ini melencong kepada fail (dengan nama fail), halaman (dengan ID semakan atau ID halaman) atau halaman pengguna (dengan ID pengguna berangka), atau entri log (dengan ID log). Kegunaan: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], atau [[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "Pergi",
        "redirect-lookup": "Cari:",
        "htmlform-cloner-delete": "Buang",
        "htmlform-cloner-required": "Sekurang-kurangnya satu nilai diperlukan.",
        "logentry-delete-delete": "$1 telah {{GENDER:$2|menghapuskan}} laman $3",
-       "logentry-delete-restore": "$1 telah {{GENDER:$2|memulihkan}} laman $3",
+       "logentry-delete-restore": "$1 telah {{GENDER:$2|memulihkan}} laman $3 ($4)",
        "logentry-delete-event": "$1 telah {{GENDER:$2|mengubah}} keterlihatan $5 peristiwa log di $3: $4",
        "logentry-delete-revision": "$1 telah {{GENDER:$2|mengubah}} keterlihatan $5 semakan di halaman $3: $4",
        "logentry-delete-event-legacy": "$1 telah {{GENDER:$2|mengubah}} keterlihatan peristiwa log di $3",
index a303e4a..6d8f5e6 100644 (file)
@@ -72,6 +72,7 @@
        "tog-norollbackdiff": "နောက်ပြန်ပြင်ဆင်ခြင်း လုပ်ဆောင်ပြီးပါက ကွဲပြားမှုကိုမပြပါနှင့်။",
        "tog-useeditwarning": "မသိမ်းရသေးသော ပြောင်းလဲမှုများ နှင့် တည်းဖြတ်ဆဲစာမျက်နှာမှ ထွက်သွားလျှင် သတိပေးပါ",
        "tog-prefershttps": "လော့ဂ်အင်ဝင်ချိန်တွင် လုံခြုံသော ဆက်သွယ်မှုကို အမြဲတမ်း အသုံးပြုရန်",
+       "tog-showrollbackconfirmation": "နောက်ပြန် ပြန်သွားရန်လင့်ခ်ကို နှိပ်သောအခါ အတည်ပြုချက်တောင်းခံပုံအား ပြသရန်",
        "underline-always": "အမြဲ",
        "underline-never": "ဘယ်သောအခါမျှ",
        "underline-default": "ဘရောက်ဆာ သို့ Skin default အတိုင်း",
        "copyrightwarning": "{{SITENAME}} တွင် ရေးသားမှုအားလုံးကို $2 အောက်တွင် ဖြန့်ဝေရန် ဆုံးဖြတ်ပြီး ဖြစ်သည်ကို ကျေးဇူးပြု၍ သတိပြုပါ။။ (အသေးစိတ်ကို $1 တွင်ကြည့်ပါ။)\nအကယ်၍ သင့်ရေးသားချက်များကို အညှာအတာမရှိ တည်းဖြတ်ခံရခြင်း၊ စိတ်တိုင်းကျ ဖြန့်ဝေခံရခြင်းတို့ကို အလိုမရှိပါက ဤနေရာတွင် မတင်ပါနှင့်။<br />\nသင်သည် ဤဆောင်းပါးကို သင်ကိုယ်တိုင်ရေးသားခြင်း၊ သို့မဟုတ် အများပြည်သူဆိုင်ရာဒိုမိန်းများ၊ ယင်းကဲ့သို့ လွတ်လပ်သည့် ရင်းမြစ်မှ ကူးယူထားခြင်း ဖြစ်ကြောင်းလည်း ဝန်ခံ ကတိပြုပါသည်။\n<strong>မူပိုင်ခွင့်ရှိသော စာ၊ပုံများကို ခွင့်ပြုချက်မရှိဘဲ မတင်ပါနှင့်။</strong>",
        "copyrightwarning2": "{{SITENAME}} တွင် ရေးသားမှုအားလုံးသည် အခြားပုံပိုးသူများ၏ တည်းဖြတ်၊ ပြောင်းလဲ၊ ဖယ်ရှားခံရနိုင်သည်ကို သတိပြုပါ။\nအကယ်၍ သင့်ရေးသားချက်များကို အညှာအတာမရှိ တည်းဖြတ်ခံရခြင်း၊ စိတ်တိုင်းကျ ဖြန့်ဝေခံရခြင်းတို့ကို အလိုမရှိပါက ဤနေရာတွင် မတင်ပါနှင့်။<br />\nသင်သည် ဤဆောင်းပါးကို သင်ကိုယ်တိုင်ရေးသားခြင်း၊ သို့မဟုတ် အများပြည်သူဆိုင်ရာဒိုမိန်းများ၊ ယင်းကဲ့သို့ လွတ်လပ်သည့် ရင်းမြစ်မှ ကူးယူထားခြင်း ဖြစ်ကြောင်းလည်း ဝန်ခံ ကတိပြုပါသည် (အသေးစိတ်ကို $1 တွင်ကြည့်ပါ)။\n<strong>မူပိုင်ခွင့်ရှိသော စာ၊ပုံများကို ခွင့်ပြုချက်မရှိဘဲ မတင်ပါနှင့်။</strong>",
        "editpage-cannot-use-custom-model": "ဤစာမျက်နှာ၏ မာတိကာမော်ဒယ်ကို မပြောင်းလဲနိုင်ခဲ့ပါ။",
+       "readonlywarning": "<strong>သတိပေးချက်: ပြုပြင်ထိန်းသိမ်းရေးအတွက် ဒေတာဘေ့စ်ကို ပိတ်ထားလိုက်ပါပြီ၊ ယခုလက်ရှိ တည်းဖြတ်နိုင်တာ့မည် မဟုတ်ပါ။</strong>\n\n\nယင်းအားပိတ်ခဲ့သည့် စနစ်အက်ဒမင်က ဤရှင်းပြချက်ကို ပေးထားပါသည်: $1",
        "protectedpagewarning": "<strong>သတိပေးချက်။ ဤစာမျက်နှာအား စီမံခန့်ခွဲသူအဆင့်ရှိသူများသာ ပြင်ဆင်နိုင်ရန် ကာကွယ်ထားသည်။</strong>\nနောက်ဆုံးမှတ်တမ်းအား ကိုးကားနိုင်ရန် အောက်တွင် ဖော်ပြထားသည်။",
        "semiprotectedpagewarning": "<strong>မှတ်ချက်။</strong> ဤစာမျက်နှာအား အလိုအလျောက် အတည်ပြုထားသော အသုံးပြုသူအဆင့်ရှိသူများသာ တည်းဖြတ်နိုင်ရန် ကာကွယ်ထားသည်။\nနောက်ဆုံးမှတ်တမ်းအား ကိုးကားနိုင်ရန် အောက်တွင် ဖော်ပြထားသည်။",
        "titleprotectedwarning": "<strong>သတိပေးချက်။ ဤစာမျက်နှာကို ကာကွယ်ထားပြီး ဖန်တီးနိုင်ရန်အတွက် [[Special:ListGroupRights|အထူး အခွင့်အရေးများ]]ရှိထားရန် လိုအပ်သည်။</strong>\nနောက်ဆုံးမှတ်တမ်းအား ကိုးကားနိုင်ရန် အောက်တွင် ဖော်ပြထားသည်။",
        "editpage-invalidcontentmodel-text": "မာတိကာမော်ဒယ် \"$1\" သည် မထောက်ပံ့ထားပါ။",
        "editpage-notsupportedcontentformat-title": "မာတိကာပုံစံသည် မထောက်ပံ့ထားပါ",
        "editpage-notsupportedcontentformat-text": "မာတိကာပုံစံ $1 အား မာတိကာမော်ဒယ် $2 မှ မထောက်ပံ့ထားပါ။",
+       "slot-name-main": "ပင်မ",
        "content-model-wikitext": "ဝီကီစာသား",
        "duplicate-args-category": "တမ်းပလိတ်တွင်းရှိ arguments ထပ်နေသော စာမျက်နှာများ",
        "post-expand-template-inclusion-warning": "'''သတိပေးချက် -''' တမ်းပလိတ်အရွယ်အစား ကြီးလွန်းနေသည်။\nအချို့တမ်းပလိတ်တို့ ပါဝင်မည်မဟုတ်။",
        "histfirst": "အဟောင်းဆုံး",
        "histlast": "အသစ်ဆုံး",
        "historysize": "({{PLURAL:$1|1 ဘိုက်|$1 ဘိုက်}})",
-       "historyempty": "(ဘာမှမရှိ)",
+       "historyempty": "ဘာမှမရှိ",
        "history-feed-title": "မူရာဇဝင်မှတ်တမ်း",
        "history-feed-description": "ဝီကီပေါ်ရှိ ဤစာမျက်နှာ၏ တည်းဖြတ်မှုရာဇဝင်",
        "history-feed-item-nocomment": "$2 က $1",
        "deleting-backlinks-warning": "<strong>သတိပေးချက်။</strong> သင်ဖျက်ပစ်တော့မည့် စာမျက်နှာအား [[Special:WhatLinksHere/{{FULLPAGENAME}}|အခြားစာမျက်နှာများမှ]] ချိတ်ဆက်ထားခြင်း သို့မဟုတ် ထည့်သွင်းထားခြင်း ရှိနေသည်။",
        "deleting-subpages-warning": "<strong>သတိပေးချက်။</strong> သင်ဖျက်တော့မည့် စာမျက်နှာတွင် [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|စာမျက်နှာခွဲ တစ်ခု|စာမျက်နှာခွဲ $1 ခု|51=စာမျက်နှာခွဲ ၅၀ ကျော်}}]] ရှိနေသည်။",
        "rollback": "နောက်ပြန်ပြင် တည်းဖြတ်မှုများ",
+       "rollback-confirmation-yes": "နောက်ပြန် ပြန်သွားရန်",
+       "rollback-confirmation-no": "မလုပ်တော့ပါ",
        "rollbacklink": "နောက်ပြန် ပြန်သွားရန်",
        "rollbacklinkcount": "{{PLURAL:$1|တည်းဖြတ်မှု|တည်းဖြတ်မှုများ}} $1 ကို နောက်ပြန်ပြင်ရန်",
        "rollbacklinkcount-morethan": "$1 ထက်ပိုသော {{PLURAL:$1|တည်းဖြတ်မှု|တည်းဖြတ်မှုများ}}ကို နောက်ပြန်ပြင်ရန်",
        "log-action-filter-rights-rights": "လူဖြင့် ပြောင်းလဲမှု",
        "log-action-filter-rights-autopromote": "အလိုအလျောက် ပြောင်းလဲမှု",
        "authmanager-create-disabled": "အကောင့်ဖန်တီးခြင်းကို ပိတ်ထားသည်။",
-       "authmanager-authplugin-setpass-failed-title": "စကားဝှက်ပြောင်းလဲမှု မအောင်မြင်ပါ",
        "authmanager-autocreate-noperm": "အလိုအလျာက် အကောင့်ဖန်တီးခြင်းကို ခွင့်မပြုပါ။",
        "authmanager-autocreate-exception": "ရှေ့ကအမှားများကြောင့် အလိုအလျာက် အကောင့်ဖန်တီးခြင်းကို ယာယီပိတ်ထားသည်။",
        "authmanager-userdoesnotexist": "အသုံးပြုသူအကောင့် \"$1\" သည် မှတ်ပုံမတင်ထားပါ။",
index 89ea2a3..ff71467 100644 (file)
        "cantrollback": "Bô-hoat-tō· kā siu-kái ká-tńg--khì; téng ūi kòng-hiàn-chiá sī chit ia̍h î-it ê chok-chiá.",
        "alreadyrolled": "Bô-hoat-tō· kā [[User:$2|$2]] ([[User talk:$2|Thó-lūn]]) tùi [[:$1]] ê siu-kái ká-tńg-khì; í-keng ū lâng siu-kái a̍h-sī ká-tńg chit ia̍h. Téng 1 ūi siu-kái-chiá sī [[User:$3|$3]] ([[User talk:$3|Thó-lūn]]).",
        "editcomment": "Siu-kái phêng-lūn sī: <em>$1</em>.",
-       "protectedarticle": "pó-hō͘ \"[[$1]]\"",
+       "protectedarticle": "pó-hō͘ liáu \"[[$1]]\"",
        "protect-title": "Kái-piàn \"$1\" ê pó-hō͘ chân-kip",
        "prot_1movedto2": "[[$1]] sóa khì tī [[$2]]",
        "protect-legend": "Khak-tēng beh pó-hō·",
        "protectcomment": "Lí-iû:",
-       "protect-level-autoconfirmed": "Chí ín-chún chū-tōng khak-jīn iōng-chiá",
-       "protect-level-sysop": "Chí ín-chún koán-lí jîn-oân",
+       "protect-level-autoconfirmed": "Ta ín-chún chū-tōng khak-jīn iōng-chiá",
+       "protect-level-sysop": "Ta ín-chún koán-lí jîn-oân",
+       "protect-expiring": "chì $1 (UTC) kòe-kî",
+       "protect-expiring-local": "chì $1 kòe-kî",
        "protect-cascade": "Cascading protection - pó-hō͘ jīm-hô pau-hâm tī chit ia̍h ê ia̍h.",
        "restriction-edit": "Siu-kái",
        "restriction-move": "Sóa khì",
index 88f933d..8a393a9 100644 (file)
        "revertpage": "Cangiaje 'e cagnamiénte 'e [[Special:Contributions/$2|$2]] ([[User talk:$2|discussione]]), cu â verzione 'e pprimma 'e  [[User:$1|$1]]",
        "revertpage-nouser": "Annullate 'e cagnamiente 'e n'utente annascunnuto, è stata ripigliata ll'urdema verzione 'e {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Cagnamiente annullate 'a {{GENDER:$3|$1}};\ns'è turnato arreto a l'urdema verzione 'e {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Cagnamiente annullate 'a $1;\ns'è turnat arreto a l'urdema verzione 'e $2. [$3 Fà vedé 'e cagnamiente]",
        "sessionfailure-title": "Sessione fallita",
        "sessionfailure": "Pare ca stanno probbleme cu 'a sessiona toja;\nst'azione è stata fermata pe' precauzione annanz' 'e cavall' 'e troia;\nPe' piacere turnate arreto, carrecate n'ata vota 'a paggena pe pruvate n'ata vota.",
        "changecontentmodel": "Cagna 'o mudello 'e cuntenute 'e na paggena",
        "authmanager-create-no-primary": "Le credenziali date nun se ponno ausà pe' puté crià n'utenza.",
        "authmanager-link-no-primary": "'E credenziale date nun se ponno ausà p' 'o cullegamento 'utenza.",
        "authmanager-link-not-in-progress": "'O cullegamento 'e cunte nun è 'ncurzo o 'e date d' 'a sessione so' ghiute pierze. Verite 'accummincià n'ata vota a 'o prencipio.",
-       "authmanager-authplugin-setpass-failed-title": "'O cagnamento d' 'a password è ghiuto malamente",
-       "authmanager-authplugin-setpass-failed-message": "'O plugin 'autenticazione nun ave lassato 'o cagnamento d' 'a password.",
-       "authmanager-authplugin-create-fail": "'O plugin autenticazione nun lassaie crià ll'utenza.",
-       "authmanager-authplugin-setpass-denied": "'O plugin autenticazione nun premmettesse 'e cagnà 'e password.",
-       "authmanager-authplugin-setpass-bad-domain": "Dominio invalido.",
        "authmanager-autocreate-noperm": "'A criazione automatica 'e ll'utenza nun fosse premmessa.",
        "authmanager-autocreate-exception": "Criazione 'e cunte automatica stutata pe nu poc'ê tiempo pe vvìa 'e ll'errure precedenti.",
        "authmanager-userdoesnotexist": "'O cunto utente \"$1\" nun è riggistrato.",
index 7e64536..e0afd43 100644 (file)
@@ -99,6 +99,7 @@
        "tog-norollbackdiff": "Ikke vis diff etter tilbakestilling",
        "tog-useeditwarning": "Si ifra dersom jeg forlater en side uten å lagre den.",
        "tog-prefershttps": "Bruk alltid en trygg forbindelse når du er innlogget",
+       "tog-showrollbackconfirmation": "Be om bekreftelse når man klikker på en tilbakestillingslenke",
        "underline-always": "Alltid",
        "underline-never": "Aldri",
        "underline-default": "Drakta eller nettleserens standardinnstillinger",
        "badretype": "Passordene samsvarte ikke.",
        "usernameinprogress": "Opprettelsesprosessen for dette brukernavnet er igang.\nVennligst vent.",
        "userexists": "Brukernavnet er allerede i bruk.\nVelg et annet brukernavn.",
+       "createacct-normalization": "Brukernavnet ditt vil bli endret til «$2» på grunn av tekniske begrensninger.",
        "loginerror": "Innloggingsfeil",
        "createacct-error": "Feil med kontoppretting",
        "createaccounterror": "Kunne ikke opprette konto: $1",
        "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 {{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 handlingen ble avbrutt av sikkerhetshensyn. Vennlgist prøv å sende skjemaet en gang til.",
        "changecontentmodel": "Endre innholdsmodell for en side",
        "anoncontribs": "Bidrag",
        "contribsub2": "For {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Brukerkontoen «$1» er ikke registrert.",
+       "negative-namespace-not-supported": "Navnerom med negative verdier støttes ikke.",
        "nocontribs": "Ingen endringer er funnet som passer disse kriteriene.",
        "uctop": "siste",
        "month": "Fra måned (og tidligere):",
        "ipb-confirm": "Bekreft blokkering",
        "ipb-sitewide": "Hele nettstedet",
        "ipb-partial": "Delvis",
+       "ipb-sitewide-help": "Alle sider på wikien og alle andre bidragshandlinger.",
+       "ipb-partial-help": "Spesifikke sider eller navnerom.",
        "ipb-pages-label": "Sider",
        "ipb-namespaces-label": "Navnerom",
        "badipaddress": "Ugyldig IP-adresse.",
        "logentry-rights-autopromote": "$1 ble automatisk {{GENDER:$2|forfremmet}} fra $4 til $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|lastet opp}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|lastet opp}} en ny versjon av $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|lastet opp}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|tilbakestilte}} $3 til en gammel versjon",
        "log-name-managetags": "Taggbehandlingslogg",
        "log-description-managetags": "Denne siden lister opp behandlingsoppgaver i forbindelse med [[Special:Tags|tagger]]. Loggen inneholder bare handlinger som er blitt gjort manuelt av en administrator; tagger kan opprettes eller slettes av programvaren uten at det kommer et oppslag i denne loggen.",
        "logentry-managetags-create": "$1 {{GENDER:$2|opprettet}} taggen «$4»",
        "log-action-filter-suppress-reblock": "Brukerundertrykking ved gjenblokkering",
        "log-action-filter-upload-upload": "Ny opplasting",
        "log-action-filter-upload-overwrite": "Gjenopplasting",
+       "log-action-filter-upload-revert": "Tilbakestilling",
        "authmanager-authn-not-in-progress": "Autentisering foregår ikke eller sesjonsdata er tapt. Start igjen fra begynnelsen.",
        "authmanager-authn-no-primary": "De oppgitte akkreditivene kunne ikke autentiseres.",
        "authmanager-authn-no-local-user": "De oppgitte akkreditivene tilhører ingen bruker på denne wikien.",
        "authmanager-create-no-primary": "De oppgitte akkreditivene kunne ikke brukes for kontooppretting.",
        "authmanager-link-no-primary": "De oppgitte akkreditivene kunne ikke brukes for kontolenking.",
        "authmanager-link-not-in-progress": "Kontolenking foregår ikke eller sesjonsdata er tapt. Start igjen fra begynnelsen.",
-       "authmanager-authplugin-setpass-failed-title": "Passordendring mislyktes",
-       "authmanager-authplugin-setpass-failed-message": "Autentiseringspluginen avviste passordendringen.",
-       "authmanager-authplugin-create-fail": "Autentiseringspluginen avviste kontoopprettelsen.",
-       "authmanager-authplugin-setpass-denied": "Autentiseringspluginen tillater ikke endring av passord.",
-       "authmanager-authplugin-setpass-bad-domain": "Ugyldig domene.",
        "authmanager-autocreate-noperm": "Automatisk kontoopprettelse tillates ikke.",
        "authmanager-autocreate-exception": "Automatisk kontoopprettelse er midlertidig deaktivert på grunn av tidligere feil.",
        "authmanager-userdoesnotexist": "Brukerkontoen «$1» er ikke registrert.",
        "passwordpolicies-policy-maximalpasswordlength": "Passordet kan maksimalt være på $1 {{PLURAL:$1|tegn}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Passordet kan ikke være {{PLURAL:$1|det populære passordet|i lista over $1 populære passord}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Passord kan ikke være i listen over de vanligste 100&nbsp;000 passordene.",
+       "passwordpolicies-policyflag-forcechange": "må endres ved innlogging",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "foreslå endring ved innlogging",
        "easydeflate-invaliddeflate": "Det gitte innholdet er ikke riktig komprimert",
        "unprotected-js": "Av sikkerhetsårsaker kan ikke JavaScript lastes fra ubeskyttede sider. Bare skap JavaScript i MediaWiki-navnerommet eller som en brukerunderside"
 }
index 0af4704..f1ec37d 100644 (file)
        "and": "&#32;en",
        "faq": "Vragen die vake esteld wörden",
        "actions": "Haandeling",
-       "namespaces": "Naamruumtes",
+       "namespaces": "Naamrüümdes",
        "variants": "Variaanten",
        "navigation-heading": "Navigasiemenu",
        "errorpagetitle": "Foutmelding",
        "rcfilters-restore-default-filters": "Standardfilters weerummezetten",
        "rcfilters-clear-all-filters": "Alle filters vortdoon",
        "rcfilters-show-new-changes": "Låt nyste wysigingen seen",
-       "rcfilters-search-placeholder": "Filter wysigingen (gebruuk et menu of söök up filtername)",
+       "rcfilters-search-placeholder": "Filter wysigingen (gebrüük et menü of söök up filtername)",
        "rcfilters-filterlist-feedbacklink": "Låt uns weaten wat jy van disse (nye) filterhülpmiddels vinden",
        "rcfilters-highlightbutton-title": "Resultåten markeren",
        "rcfilters-highlightmenu-title": "Kies n kleur",
        "undelete-error-long": "Fouten bie t herstellen van t bestaand:\n\n$1",
        "undelete-show-file-confirm": "Bi'j der wisse van da'j n vortedaone versie van t bestaand \"<nowiki>$1</nowiki>\" van $2 um $3 bekieken willen?",
        "undelete-show-file-submit": "Ja",
-       "namespace": "Naamruumte:",
+       "namespace": "Naamrüümde:",
        "invert": "Seleksie ummekeren",
        "tooltip-invert": "Vink dit vakjen an um wiezigingen an ziejen binnen de ekeuzen naamruumte te verbargen (en de biebeheurende naamruumte as dat an-evinkt is)",
        "namespace_association": "Naamruumte die hieran ekoppeld is",
index 8d1c704..2e25acc 100644 (file)
        "group-autoconfirmed": "स्वत निश्चित गरिएका प्रयोगकर्ताहरू",
        "group-bot": "बोटहरू",
        "group-sysop": "प्रवन्धकहरू",
+       "group-interface-admin": "अन्तरमोहडा सम्पादक",
        "group-bureaucrat": "प्रशासकहरू",
        "group-suppress": "अतिदृष्टिहरू",
        "group-all": "(सबै)",
index e566d41..489fba6 100644 (file)
@@ -95,7 +95,8 @@
                        "Jeroen N",
                        "Bdijkstra",
                        "KlaasZ4usV",
-                       "Elroy"
+                       "Elroy",
+                       "PiefPafPier"
                ]
        },
        "tog-underline": "Verwijzingen onderstrepen:",
        "tog-norollbackdiff": "Wijzigingen weglaten na terugdraaien",
        "tog-useeditwarning": "Waarschuwen als u een bewerkte pagina wilt verlaten die nog niet is opgeslagen",
        "tog-prefershttps": "Altijd een beveiligde verbinding gebruiken wanneer u bent aangemeld",
+       "tog-showrollbackconfirmation": "Toon een bevestigingsvenster wanneer er op een terugdraaien koppeling wordt geklikt.",
        "underline-always": "Altijd",
        "underline-never": "Nooit",
        "underline-default": "Standaardgedrag van vormgeving of webbrowser",
        "badretype": "De ingevoerde wachtwoorden verschillen van elkaar.",
        "usernameinprogress": "Het aanmaken van een account met die naam is al in behandeling.\nEven geduld alstublieft.",
        "userexists": "De gekozen gebruikersnaam is al in gebruik.\nKies een andere naam.",
+       "createacct-normalization": "Uw gebruikersnaam zal worden aangepast naar \"$2\" vanwege technische beperkingen.",
        "loginerror": "Aanmeldfout",
        "createacct-error": "Fout tijdens aanmaken account",
        "createaccounterror": "Het was niet mogelijk het account aan te maken: $1",
        "userpage-userdoesnotexist": "Gebruikersaccount \"$1\" bestaat niet.\nControleer of u deze pagina wel wilt aanmaken/bewerken.",
        "userpage-userdoesnotexist-view": "Gebruikersaccount \"$1\" bestaat niet.",
        "blocked-notice-logextract": "Deze gebruiker is momenteel geblokkeerd.\nDe laatste regel uit het blokkeerlogboek wordt hieronder ter referentie weergegeven:",
-       "clearyourcache": "<strong>Opmerking:</strong> nadat u de wijzigingen hebt opgeslagen is het wellicht nodig uw browsercache te legen.\n* <strong>Firefox / Safari:</strong> houd <em>Shift</em> ingedrukt terwijl u op <em>Vernieuwen</em> klikt of druk op <em>Ctrl-F5</em> of <em>Ctrl-R</em> (<em>⌘-Shift-R</em> op een Mac)\n* <strong>Google Chrome:</strong> druk op <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> op een Mac)\n* <strong>Internet Explorer:</strong> houd <em>Ctrl</em> ingedrukt terwijl u op <em>Vernieuwen</em> klikt of druk op <em>Ctrl-F5</em>\n* '''Opera:''' ga naar <em>Menu → Instellingen</em> (<em>Opera → Voorkeuren</em> op een Mac) en daarna naar <em>Privacy & beveiliging → Browsegegevens wissen... →  Tijdelijk opgeslgen afbeeldingen en bestanden</em>.",
+       "clearyourcache": "<strong>Opmerking:</strong> nadat u de wijzigingen hebt opgeslagen is het wellicht nodig uw browsercache te legen.\n* <strong>Firefox / Safari:</strong> houd <em>Shift</em> ingedrukt terwijl u op <em>Vernieuwen</em> klikt of druk op <em>Ctrl-F5</em> of <em>Ctrl-R</em> (<em>⌘-Shift-R</em> op een Mac)\n* <strong>Google Chrome:</strong> druk op <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> op een Mac)\n* <strong>Internet Explorer:</strong> houd <em>Ctrl</em> ingedrukt terwijl u op <em>Vernieuwen</em> klikt of druk op <em>Ctrl-F5</em>\n* '''Opera:''' ga naar <em>Menu → Instellingen</em> (<em>Opera → Voorkeuren</em> op een Mac) en daarna naar <em>Privacy & beveiliging → Browsegegevens wissen... →  Tijdelijk opgeslagen afbeeldingen en bestanden</em>.",
        "usercssyoucanpreview": "'''Tip:''' gebruik de knop \"{{int:showpreview}}\" om uw nieuwe CSS te testen alvorens op te slaan.",
        "userjsonyoucanpreview": "'''Tip:''' gebruik de knop \"{{int:showpreview}}\" om uw nieuwe JSON te testen alvorens op te slaan.",
        "userjsyoucanpreview": "'''Tip:''' gebruik de knop \"{{int:showpreview}}\" om uw nieuwe JavaScript te testen alvorens op te slaan.",
        "histfirst": "oudste",
        "histlast": "nieuwste",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
-       "historyempty": "(leeg)",
+       "historyempty": "leeg",
        "history-feed-title": "Bewerkingsoverzicht",
        "history-feed-description": "Bewerkingsoverzicht voor deze pagina op de wiki",
        "history-feed-item-nocomment": "$1 op $3 om $4",
        "searchall": "alle",
        "showingresults": "Hieronder {{PLURAL:$1|staat '''1''' resultaat|staan '''$1''' resultaten}} vanaf #'''$2'''.",
        "showingresultsinrange": "Hieronder {{PLURAL:$1|wordt|worden}} maximaal {{PLURAL:$1|<strong>1</strong> resultaat|<strong>$1 </strong>resultaten}} weergegeven in het bereik #<strong>$2</strong> tot #<strong>$3</strong>.",
-       "search-showingresults": "{{PLURAL:$4|Resultaat <strong>$1</strong> van <strong>$2</strong>|Resultaten <strong>$1 - $2</strong> van <strong>$3</strong>}}",
+       "search-showingresults": "{{PLURAL:$4|Resultaat <strong>$1</strong> van <strong>$2</strong>|Resultaten <strong>$1$2</strong> van <strong>$3</strong>}}",
        "search-nonefound": "Er zijn geen resultaten voor uw zoekopdracht.",
        "search-nonefound-thiswiki": "Er zijn voor uw zoekopdracht geen resultaten op deze site.",
        "powersearch-legend": "Uitgebreid zoeken",
        "right-reupload-own": "Eigen bestandsuploads overschrijven",
        "right-reupload-shared": "Media uit de gedeelde mediadatabank lokaal overschrijven",
        "right-upload_by_url": "Bestanden uploaden via een URL",
-       "right-purge": "De cache van een pagina verversen zonder bevestiging",
+       "right-purge": "De cache van een pagina verversen",
        "right-autoconfirmed": "Uitgezonderd van IP-adresgebaseerde tijdsafhankelijke beperkingen",
        "right-bot": "Behandeld worden als een geautomatiseerd proces",
        "right-nominornewtalk": "Kleine bewerkingen aan een overlegpagina leiden niet tot een melding 'nieuwe berichten'",
        "recentchanges-label-unpatrolled": "Deze bewerking is nog niet gecontroleerd",
        "recentchanges-label-plusminus": "Deze paginagrootte is met dit aantal bytes gewijzigd",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (zie ook de [[Special:NewPages|lijst met nieuwe pagina's]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}}<br />(zie ook de [[Special:NewPages|lijst met nieuwe pagina's]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Weergeven",
        "rcfilters-tag-remove": "Verwijder '$1'",
        "delete-confirm": "\"$1\" verwijderen",
        "delete-legend": "Verwijderen",
        "historywarning": "<strong>Waarschuwing:</strong> de pagina die u wilt verwijderen heeft ongeveer $1 {{PLURAL:$1|versie|versies}}:",
-       "historyaction-submit": "Weergeven",
+       "historyaction-submit": "Versies weergeven",
        "confirmdeletetext": "U staat op het punt een pagina te verwijderen, inclusief de geschiedenis.\nBevestig hieronder dat dit inderdaad uw bedoeling is, dat u de gevolgen begrijpt en dat de verwijdering overeenstemt met het [[{{MediaWiki:Policy-url}}|beleid]].",
        "actioncomplete": "Handeling voltooid",
        "actionfailed": "Handeling mislukt",
        "deleting-backlinks-warning": "<strong>Waarschuwing:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|andere pagina's]] gebruiken of verwijzen naar de pagina die u wilt verwijderen.",
        "deleting-subpages-warning": "<strong>Waarschuwing:</strong>De pagina die u wilt verwijderen heeft [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|een deelpagina|$1 deelpagina's|51=meer dan 50 deelpagina's}}]].",
        "rollback": "Wijzigingen ongedaan maken",
+       "rollback-confirmation-confirm": "Bevestig:",
+       "rollback-confirmation-yes": "Terugdraaien",
+       "rollback-confirmation-no": "Annuleren",
        "rollbacklink": "terugdraaien",
        "rollbacklinkcount": "{{PLURAL:$1|één bewerking|$1 bewerkingen}} terugdraaien",
        "rollbacklinkcount-morethan": "Meer dan {{PLURAL:$1|één bewerking|$1 bewerkingen}} terugdraaien",
        "revertpage": "Wijzigingen door [[Special:Contributions/$2|$2]] ([[User talk:$2|Overleg]]) hersteld tot de laatste versie door [[User:$1|$1]]",
        "revertpage-nouser": "Wijzigingen door een verborgen gebruiker teruggedraaid naar de laatste versie door {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Wijzigingen door {{GENDER:$3|$1}} ongedaan gemaakt;\nlaatste versie van {{GENDER:$4|$2}} hersteld.",
-       "rollback-success-notify": "De wijzigingen door $1 zijn teruggedraaid;\nde laatste versie van $2 is hersteld. [$3 Wijzigingen weergeven]",
        "sessionfailure-title": "Sessiefout",
        "sessionfailure": "Er lijkt een probleem te zijn met uw aanmeldsessie.\nUw handeling is gestopt uit voorzorg tegen een beveiligingsrisico (dat bestaat uit mogelijke \"hijacking\" van deze sessie).\nProbeer het formulier opnieuw te versturen.",
        "changecontentmodel": "Inhoudsmodel van pagina bewerken",
        "mycontris": "Bijdragen",
        "anoncontribs": "Bijdragen",
        "contribsub2": "Voor {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Voor {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Gebruikersaccount \"$1\" bestaat niet.",
        "negative-namespace-not-supported": "Naamruimten met negatieve waarden worden niet ondersteund.",
        "nocontribs": "Geen wijzigingen gevonden die aan de gestelde criteria voldoen.",
        "ipb-confirm": "Blokkade bevestigen",
        "ipb-sitewide": "Van de hele site",
        "ipb-partial": "Gedeeltelijk",
+       "ipb-partial-help": "Specifieke pagina's of naamruimten.",
        "ipb-pages-label": "Pagina's",
        "ipb-namespaces-label": "Naamruimten",
        "badipaddress": "Geen geldig IP-adres",
        "confirm-unwatch-top": "Deze pagina verwijderen uit uw volglijst?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Bewerkingen op deze pagina ongedaan maken?",
+       "confirm-rollback-bottom": "Hierdoor zullen de geselecteerde wijzigingen meteen terugdraaien.",
        "confirm-mcrrestore-title": "Een versie terugplaatsen",
        "confirm-mcrundo-title": "Een wijziging ongedaan maken",
        "mcrundofailed": "Ongedaan maken mislukt",
        "htmlform-int-toolow": "De opgegeven waarde ligt onder de minimumwaarde van $1",
        "htmlform-int-toohigh": "De opgegeven waarde ligt boven de maximumwaarde van $1",
        "htmlform-required": "Deze waarde is verplicht",
-       "htmlform-submit": "Opslaan",
+       "htmlform-submit": "Verzenden",
        "htmlform-reset": "Wijzigingen ongedaan maken",
        "htmlform-selectorother-other": "Anders",
        "htmlform-no": "Nee",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|is}} automatisch gepromoveerd van $4 naar $5",
        "logentry-upload-upload": "$1 heeft $3 {{GENDER:$2|geüpload}}",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|heeft}} een nieuwe versie van $3 geüpload",
-       "logentry-upload-revert": "$1 heeft $3 {{GENDER:$2|geupload}}",
+       "logentry-upload-revert": "$1 heeft $3 naar een oudere versie {{GENDER:$2|teruggedraaid}}",
        "log-name-managetags": "Labelbeheerlogboek",
        "log-description-managetags": "Deze pagina geeft een overzicht van managementtaken met betrekking tot [[Special:Tags|labels]]. Het logboek bevat alleen activiteiten die handmatig zijn uitgevoerd door een beheerder. Labels kunnen door de wikisoftware worden gemaakt of verwijderd zonder dat er een vermelding is opgenomen in dit logboek.",
        "logentry-managetags-create": "$1 heeft het label \"$4\" {{GENDER:$2|aangemaakt}}",
        "log-action-filter-suppress-reblock": "Verbergen van gebruiker tijdens wijzigen blokkade",
        "log-action-filter-upload-upload": "Nieuwe upload",
        "log-action-filter-upload-overwrite": "Herupload",
+       "log-action-filter-upload-revert": "Terugdraaiing",
        "authmanager-authn-not-in-progress": "Verificatie is niet in behandeling, of de sessiegegevens zijn verloren gegaan. Start opnieuw vanaf het begin.",
        "authmanager-authn-no-primary": "De ingevoerde inloggegevens kunnen niet worden geverifieerd.",
        "authmanager-authn-no-local-user": "De ingevoerde inloggegevens zijn niet gekoppeld aan een gebruiker op deze wiki.",
        "authmanager-create-no-primary": "De ingevoerde inloggegevens kunnen niet worden gebruikt voor het aanmaken van het account.",
        "authmanager-link-no-primary": "De ingevoerde inloggegevens kunnen niet worden gebruikt om het account te koppelen.",
        "authmanager-link-not-in-progress": "Het koppelen van het account is niet in behandeling, of de sessiegegevens zijn verloren gegaan. Start opnieuw vanaf het begin.",
-       "authmanager-authplugin-setpass-failed-title": "Wachtwoord wijzigen is mislukt",
-       "authmanager-authplugin-setpass-failed-message": "De verificatie-invoegtoepassing heeft het wijzigen van het wachtwoord geweigerd.",
-       "authmanager-authplugin-create-fail": "De verificatie-invoegtoepassing heeft geweigerd uw account aan te maken.",
-       "authmanager-authplugin-setpass-denied": "De verificatie-invoegtoepassing staat het wijzigen van wachtwoorden niet toe.",
-       "authmanager-authplugin-setpass-bad-domain": "Ongeldig domein.",
        "authmanager-autocreate-noperm": "Het automatisch aanmaken van accounts is niet toegestaan.",
        "authmanager-autocreate-exception": "Het automatisch aanmaken van accounts is tijdelijk uitgeschakelijk vanwege eerdere fouten.",
        "authmanager-userdoesnotexist": "Gebruikersaccount \"$1\" is niet geregistreerd.",
        "passwordpolicies-policy-maximalpasswordlength": "Wachtwoord moet minder dan $1 {{PLURAL:$1|teken|tekens}} bevatten",
        "passwordpolicies-policy-passwordcannotbepopular": "Watchwoord mag niet {{PLURAL:$1|overeenkomen met het bekende wachtwoord|voorkomen in de lijst met $1 bekende wachtwoorden}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Wachtwoorden mogen niet voorkomen in de lijst met 100.000 veelvoorkomende wachtwoorden.",
+       "passwordpolicies-policyflag-forcechange": "moet gewijzigd worden bij het aanmelden",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "raad wijzigen aan bij het aanmelden",
        "unprotected-js": "Vanwege veiligheidsredenen kan er geen JavaScript geladen worden vanaf onbeveiligde pagina's. Gelieve alleen JavaScript pagina's aan te maken in de MediaWiki: naamruimte of als een subpagina van een gebruikerspagina."
 }
index 15e3e0d..6e14ad1 100644 (file)
        "right-override-export-depth": "Eksporter sider inkludert lenkte sider til ei djupn på 5",
        "right-sendemail": "Senda e-post til andre brukarar",
        "grant-group-page-interaction": "Verka inn på sider",
+       "grant-group-file-interaction": "Verka inn på filer",
+       "grant-group-watchlist-interaction": "Verka inn på overvakingslista di",
        "grant-group-high-volume": "Utføra høgvolumaktivitet",
        "grant-group-administration": "Utføra administrative handlingar",
        "grant-blockusers": "Blokkera og avblokkera brukarar",
        "grant-createeditmovepage": "Oppretta, endra og flytta sider",
        "grant-delete": "Sletta sider, versjonar og loggoppføringar",
        "grant-editinterface": "Gjera endringar i MediaWiki-namnerommet og i CSS/JavaScript for brukarkontoen",
+       "grant-editmywatchlist": "Endra overvakingslista di",
        "grant-editpage": "Endra oppretta sider",
+       "grant-editprotected": "Endra verna sider",
        "grant-highvolume": "Høgvolumendring",
+       "grant-patrol": "Patruljera sideendringar",
        "grant-protect": "Verna og avverna sider",
        "grant-rollback": "Rulla attende endringar på sider",
        "grant-sendemail": "Senda e-post til andre brukarar",
        "ipb-unblock": "Opphev blokkeringa av eit brukarnamn eller ei IP-adresse",
        "ipb-blocklist": "Vis gjeldande blokkeringar",
        "ipb-blocklist-contribs": "Bidrag frå $1",
+       "block-actions": "Handlingar som skal blokkerast:",
        "block-expiry": "Opphøyrstid:",
        "unblockip": "Opphev blokkering",
        "unblockiptext": "Bruk skjemaet nedanfor for å oppheve blokkeringa av ein tidlegare blokkert brukar.",
index 3634caf..3647af5 100644 (file)
        "log-action-filter-upload-overwrite": "Tornar mandar",
        "authmanager-authn-autocreate-failed": "La creacion automatica d’un compte local a fracassat : $1",
        "authmanager-create-disabled": "La creacion de compte es desactivada.",
-       "authmanager-authplugin-setpass-bad-domain": "Domeni invalid.",
        "authmanager-autocreate-noperm": "La creacion automatica de compte es pas autorizada.",
        "authmanager-password-help": "Senhal per l'autentificacion.",
        "authmanager-domain-help": "Domeni per l'autentificacion extèrna.",
index c51e5a0..1ad96b0 100644 (file)
        "log-action-filter-all": "ਸਾਰੇ",
        "log-action-filter-block-block": "ਪਾਬੰਦੀ",
        "log-action-filter-block-unblock": "ਪਾਬੰਦੀ ਹਟਾਈ",
-       "authmanager-authplugin-setpass-bad-domain": "ਗਲਤ ਡੋਮੇਨ",
        "authmanager-password-help": "ਪ੍ਰਮਾਣਿਕਤਾ ਲਈ ਪਛਾਣ-ਸ਼ਬਦ।",
        "authmanager-email-label": "ਈਮੇਲ",
        "authmanager-email-help": "ਈਮੇਲ ਪਤਾ",
index bfaf6d8..a862c18 100644 (file)
        "tog-norollbackdiff": "Nie pokazuj zmian po użyciu funkcji „cofnij”",
        "tog-useeditwarning": "Ostrzegaj mnie, gdy opuszczam stronę edycji bez zapisania zmian",
        "tog-prefershttps": "Zawsze używaj bezpiecznego połączenia po zalogowaniu",
+       "tog-showrollbackconfirmation": "Wyświetl komunikat potwierdzający kliknięcie linku wycofującego edycje",
        "underline-always": "Zawsze",
        "underline-never": "Nigdy",
        "underline-default": "według ustawień skórki lub przeglądarki",
        "badretype": "Wprowadzone hasła różnią się między sobą.",
        "usernameinprogress": "Tworzenie konta dla tej nazwy użytkownika jest już w toku.\nProszę czekać.",
        "userexists": "Wybrana przez Ciebie nazwa użytkownika jest już zajęta.\nWybierz inną nazwę użytkownika.",
+       "createacct-normalization": "Twoja nazwa użytkownika zostanie zmieniona na „$2” ze względu na ograniczenia techniczne.",
        "loginerror": "Błąd logowania",
        "createacct-error": "Błąd tworzenia konta",
        "createaccounterror": "Nie można utworzyć konta: $1",
        "previewerrortext": "Wystąpił błąd podczas próby podglądu Twoich zmian.",
        "blockedtitle": "Użytkownik jest zablokowany",
        "blocked-email-user": "<strong>Twoje konto zostało wyłączone z wysyłania wiadomości emaili innym użytkownikom. Wciąż możesz edytować inne strony na wiki.</strong> Więcej szczegółów na temat blokady znajdziesz na swojej [[Special:MyContributions|stroni wkładu]].\n\nBlokada została nałożona przez $1.\n\nPodany powód to: <em>$2</em>.\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n* Identyfikator blokady: #$5",
-       "blockedtext-partial": "<strong>Twoje konto lub adres IP zostało wyłączone z dokonywania zmian na tej stronie. Wciąż możesz edytować inne strony na wiki.</strong> Więcej szczegółów na temat blokady znajdziesz na swojej [[Special:MyContributions|stroni wkładu]].\n\nBlokada została nałożona przez $1.\n\nPodany powód to: <em>$2</em>.\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n* Identyfikator blokady: #$5",
+       "blockedtext-partial": "<strong>Twoje konto lub adres IP zostało wyłączone z dokonywania zmian na tej stronie. Wciąż możesz edytować inne strony na wiki.</strong> Więcej szczegółów na temat blokady znajdziesz na swojej [[Special:MyContributions|stronie swojego wkładu]].\n\nBlokada została nałożona przez $1.\n\nPodany powód to: <em>$2</em>.\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n* Identyfikator blokady: #$5",
        "blockedtext": "<strong>Twoje konto lub adres IP zostały zablokowane.</strong>\n\nBlokada została nałożona przez $1.\nPodany powód to: <em>$2</em>.\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n\nW celu wyjaśnienia przyczyny zablokowania możesz się skontaktować z $1 lub innym [[{{MediaWiki:Grouppage-sysop}}|administratorem]].\nNie możesz użyć funkcji „{{int:emailuser}}”, jeśli brak jest poprawnego adresu e‐mail w Twoich [[Special:Preferences|preferencjach]] lub jeśli taka możliwość została Ci zablokowana.\nTwój obecny adres IP to $3, a numer identyfikacyjny blokady to #$5.\nProsimy o podanie obu tych informacji przy wyjaśnianiu blokady.",
        "autoblockedtext": "Ten adres IP został zablokowany automatycznie, gdyż korzysta z niego inny użytkownik, zablokowany przez administratora $1.\nPowód blokady:\n\n:<em>$2</em>\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zablokowany został: $7\n\nMożesz skontaktować się z $1 lub jednym z pozostałych [[{{MediaWiki:Grouppage-sysop}}|administratorów]] w celu uzyskania informacji o blokadzie.\n\nNie możesz użyć funkcji „{{int:emailuser}}”, jeśli brak jest poprawnego adresu e‐mail w Twoich [[Special:Preferences|preferencjach]] lub jeśli taka możliwość została Ci zablokowana.\n\nTwój obecny adres IP to $3, a numer identyfikacyjny blokady to #$5.\nProsimy o podanie obu tych numerów przy wyjaśnianiu blokady.",
        "systemblockedtext": "Twoja nazwa użytkownika lub adres IP zostały automatycznie zablokowane przez MediaWiki.\nPodany powód to:\n\n:<em>$2</em>\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zamierzano zablokować: $7\n\nTwój obecny adres IP to $3.\nProsimy o dołączenie powyższych szczegółów w jakichkolwiek zadawanych pytaniach.",
        "page_first": "początek",
        "page_last": "koniec",
        "histlegend": "Wybór porównania – zaznacz kropeczkami dwie wersje do porównania i wciśnij enter lub przycisk ''Porównaj wybrane wersje''.<br />\nLegenda: (bież.) – pokaż zmiany od tej wersji do bieżącej,\n(poprz.) – pokaż zmiany od wersji poprzedzającej, m – mała (drobna) zmiana",
-       "history-fieldset-title": "Szukaj wersji",
+       "history-fieldset-title": "Filtruj wersje",
        "history-show-deleted": "Tylko usunięte edycje",
        "histfirst": "od najstarszych",
        "histlast": "od najnowszych",
        "historysize": "({{PLURAL:$1|1 bajt|$1 bajty|$1 bajtów}})",
-       "historyempty": "(pusta)",
+       "historyempty": "pusta",
        "history-feed-title": "Historia wersji",
        "history-feed-description": "Historia wersji tej strony wiki",
        "history-feed-item-nocomment": "$1 o $2",
        "right-reupload-own": "Nadpisywanie wcześniej przesłanego pliku",
        "right-reupload-shared": "Lokalne nadpisywanie pliku istniejącego w repozytorium mediów",
        "right-upload_by_url": "Przesyłanie plików z adresu URL",
-       "right-purge": "Czyszczenie pamięci podręcznej stron bez pytania o potwierdzenie",
+       "right-purge": "Czyszczenie pamięci podręcznej stron",
        "right-autoconfirmed": "Wyłączenie z ograniczeń prędkości zakładanych na IP",
        "right-bot": "Oznaczanie edycji jako wykonanych automatycznie",
        "right-nominornewtalk": "Drobne zmiany na stronach dyskusji użytkowników nie włączają powiadomienia o nowej wiadomości",
        "delete-confirm": "Usuwanie „$1”",
        "delete-legend": "Usuń",
        "historywarning": "<strong>Uwaga:</strong> Strona, którą chcesz usunąć, ma {{PLURAL:$1|jedną starszą wersję|$1 starsze wersje|$1 starszych wersji}}:",
-       "historyaction-submit": "Pokaż",
+       "historyaction-submit": "Pokaż wersje",
        "confirmdeletetext": "Zamierzasz usunąć stronę razem z całą dotyczącą jej historią.\nUpewnij się, czy na pewno chcesz to zrobić, że rozumiesz konsekwencje i że robisz to w zgodzie z [[{{MediaWiki:Policy-url}}|zasadami]].",
        "actioncomplete": "Operacja wykonana",
        "actionfailed": "Operacja się nie powiodła",
        "deleting-backlinks-warning": "<strong>Uwaga:</strong> Do strony, którą masz zamiar usunąć, odwołują się [[Special:WhatLinksHere/{{FULLPAGENAME}}|inne strony]].",
        "deleting-subpages-warning": "<strong>Ostrzeżenie:</strong> Strona którą chcesz usunąć ma [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|jedną podstronę|$1 podstrony|$1 podstron|51=ponad 50 podstron}}]].",
        "rollback": "Cofnij edycję",
+       "rollback-confirmation-confirm": "Potwierdź:",
+       "rollback-confirmation-yes": "Wycofaj",
+       "rollback-confirmation-no": "Anuluj",
        "rollbacklink": "cofnij",
        "rollbacklinkcount": "cofnij $1 {{PLURAL:$1|edycję|edycje|edycji}}",
        "rollbacklinkcount-morethan": "cofnij więcej niż $1 {{PLURAL:$1|edycję|edycje|edycji}}",
        "revertpage": "Wycofano edycje użytkownika [[Special:Contributions/$2|$2]] ([[User talk:$2|dyskusja]]). Autor przywróconej wersji to [[User:$1|$1]].",
        "revertpage-nouser": "Wycofano edycje ukrytego użytkownika. Autor przywróconej wersji to {{GENDER:$1|[[User:$1|$1]]}}.",
        "rollback-success": "Wycofano edycje {{GENDER:$3|użytkownika|użytkowniczki}} $1;\nprzywrócono ostatnią wersję autorstwa {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Wycofano edycje użytkownika $1;\nprzywrócono ostatnią wersję autorstwa $2. [$3 Pokaż zmiany]",
        "sessionfailure-title": "Błąd sesji",
        "sessionfailure": "Wydaje się, że wystąpił błąd z Twoją sesją zalogowania;\nto działanie zostało anulowane, aby uniknąć przechwycenia sesji.\nPrześlij formularz jeszcze raz.",
        "changecontentmodel": "Edycja modelu zawartości strony",
        "mycontris": "Edycje",
        "anoncontribs": "Edycje",
        "contribsub2": "Dla {{GENDER:$3|użytkownika|użytkowniczki}} $1 ($2)",
+       "contributions-subtitle": "Dla {{GENDER:$3|użytkownika|użytkowniczki}} $1",
        "contributions-userdoesnotexist": "Konto użytkownika „$1” nie jest zarejestrowane.",
        "negative-namespace-not-supported": "Przestrzenie nazw z negatywnymi wartościami nie są wspierane.",
        "nocontribs": "Brak zmian odpowiadających tym kryteriom.",
        "ipb-confirm": "Potwierdzam blokadę",
        "ipb-sitewide": "Całkowita",
        "ipb-partial": "Częściowa",
+       "ipb-sitewide-help": "Wszystkie strony na wiki i wszystkie akcje inne edycyjne.",
+       "ipb-partial-help": "Konkretne strony lub przestrzenie nazw.",
        "ipb-pages-label": "Strony",
        "ipb-namespaces-label": "Przestrzenie nazw",
        "badipaddress": "Niepoprawny adres IP",
        "confirm-unwatch-top": "Usunąć tę stronę z listy obserwowanych?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Wycofać edycje tej strony?",
+       "confirm-rollback-bottom": "Ta akcja natychmiastowo wycofa wybrane zmiany wykonane na tej stronie.",
        "confirm-mcrrestore-title": "Odtwórz wersję",
        "confirm-mcrundo-title": "Cofnij zmianę",
        "mcrundofailed": "Cofnięcie nie powiodło się",
        "logentry-block-block": "$1 {{GENDER:$2|zablokował|zablokowała|zablokował(a)}} {{GENDER:$4|$3}}, czas blokady: $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|zdjął|zdjęła}} blokadę z {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|zmienił|zmieniła}} ustawienia blokady dla {{GENDER:$4|$3}}, czas blokady: $5 $6",
-       "logentry-partialblock-block-page": "{{PLURAL:$1|strony|stron}}: $2",
-       "logentry-partialblock-block-ns": "przestrzeni nazw{{PLURAL:$1|:|}} $2",
+       "logentry-partialblock-block-page": "{{PLURAL:$1|strony|stron:}} $2",
+       "logentry-partialblock-block-ns": "przestrzeni {{PLURAL:$1|nazw:|nazw}} $2",
        "logentry-partialblock-block": "$1 {{GENDER:$2|wyłączył|wyłączyła}} {{GENDER:$4|$3}} z edytowania $7, czas blokady: $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|zmienił|zmieniła}} ustawienia wyłączenia {{GENDER:$4|$3}} z edytowania $7, czas blokady: $5 $6",
        "logentry-non-editing-block-block": "$1 {{GENDER:$2|zablokował|zablokowała}} {{GENDER:$4|$3}} wykonywanie określonych operacji nieedycyjnych, czas blokady: $5 $6",
        "logentry-rights-autopromote": "$1 automatycznie {{GENDER:$2|zmienił|zmieniła}} przynależność z $4 do $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|przesłał|przesłała}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|przesłał|przesłała}} nową wersję $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|przesłał|przesłała}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|przywrócił|przywróciła}} starszą wersję $3",
        "log-name-managetags": "Rejestr zarządzania znacznikami",
        "log-description-managetags": "Na tej stronie są wymienione zadania związane z zarządzaniem [[Special:Tags|znacznikami]]. Dziennik (log) zawiera tylko działania wykonane ręcznie przez administratora; znaczniki mogą być tworzone lub usuwane przez oprogramowanie wiki bez dodawania wpisów w dzienniku (logu).",
        "logentry-managetags-create": "$1 {{GENDER:$2|utworzył|utworzyła}} znacznik „$4”",
        "log-action-filter-suppress-reblock": "Ukrycie użytkownika poprzez ponowną blokadę",
        "log-action-filter-upload-upload": "Nowe przesłane",
        "log-action-filter-upload-overwrite": "Przesłane ponownie",
+       "log-action-filter-upload-revert": "Przywrócenie poprzedniej wersji",
        "authmanager-authn-not-in-progress": "Tworzenie konta nie jest wykonywane lub dane sesji zostały utracone. Zacznij od początku.",
        "authmanager-authn-no-primary": "Podane dane nie mogą być użyte do kontroli poświadczeń.",
        "authmanager-authn-no-local-user": "Żaden użytkownik nie korzysta z tych danych.",
        "authmanager-create-no-primary": "Podanych danych uwierzytelniających nie można użyć do utworzenia konta.",
        "authmanager-link-no-primary": "Podanych danych uwierzytelniających nie można użyć do powiązania konta.",
        "authmanager-link-not-in-progress": "Tworzenie konta nie jest wykonywane lub dane sesji zostały utracone. Zacznij od początku.",
-       "authmanager-authplugin-setpass-failed-title": "Zmiana hasła nie powiodła się",
-       "authmanager-authplugin-setpass-failed-message": "Wtyczka do uwierzytelniania uniemożliwiła zmianę hasła.",
-       "authmanager-authplugin-create-fail": "Wtyczka do uwierzytelniania uniemożliwiła utworzenie konta.",
-       "authmanager-authplugin-setpass-denied": "Wtyczka uwierzytelniania nie zezwala na zmianę haseł.",
-       "authmanager-authplugin-setpass-bad-domain": "Niepoprawna domena.",
        "authmanager-autocreate-noperm": "Automatyczne tworzenie konta jest niedozwolone.",
        "authmanager-autocreate-exception": "Automatyczne tworzenie konta tymczasowo wyłączone z powodu wcześniejszych błędów.",
        "authmanager-userdoesnotexist": "Konto użytkownika „$1” nie jest zarejestrowane.",
        "passwordpolicies-policy-maximalpasswordlength": "Hasło musi mieć mniej niż $1 {{PLURAL:$1|znak|znaki|znaków}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Hasło nie może być {{PLURAL:$1|popularne|na liście $1 popularnych haseł}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Hasło nie może znajdować się na liście 100 000 najczęściej używanych haseł.",
+       "passwordpolicies-policyflag-forcechange": "musi zmienić po zalogowaniu",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "sugerowana zmiana po zalogowaniu",
        "easydeflate-invaliddeflate": "Dostarczona zawartość nie jest poprawnie skompresowana",
        "unprotected-js": "Ze względów bezpieczeństwa kod JavaScript nie może zostać załadowany z niezabezpieczonych stron. Prosimy dodawać JavaScript w przestrzeni MediaWiki lub jako podstronę strony użytkownika."
 }
index 077d77e..5f4aa25 100644 (file)
        "badretype": "Le doe ciav che a l'ha scrivù a resto diferente antra 'd lor.",
        "usernameinprogress": "Na creassion ëd cont për së stranòm a l'é già an cors. Ch'a l'abia passiensa.",
        "userexists": "Lë stranòm anserì a l'é già dovrà.\nPër piasì ch'a serna në stranòm diferent.",
+       "createacct-normalization": "Sò stranòm a sarà modificà a «$2» për dle contrente técniche.",
        "loginerror": "Eror ën rintrand ant ël sistema",
        "createacct-error": "Eror durant la creassion dël cont",
        "createaccounterror": "A l'é nen podusse creé ël cont: $1",
index 31203e0..7148e91 100644 (file)
        "authmanager-create-no-primary": "د ورکړل شوي کړني اعتبار نه شي کولی چي د حساب جوړولو لپاره وکارول شي.",
        "authmanager-link-no-primary": "د ورکړل شوي تایید وړتیا د حساب کولو لپاره نه کارول کیدی.",
        "authmanager-link-not-in-progress": "تایید په پرمختګ کې ندي یا د ناستې ډاټا ورک شوی. لطفا د پیل څخه بیا شروع وکړئ.",
-       "authmanager-authplugin-setpass-failed-title": "د پټنوم بدلون ترسره نشو",
-       "authmanager-authplugin-setpass-failed-message": "د تایید کولو پلگ ان د پاسورډ بدلون رد کړ.",
-       "authmanager-authplugin-create-fail": "د تایید کولو پلگ ان د حساب جوړولو انکار رد کړ.",
-       "authmanager-authplugin-setpass-denied": "د تاییدولو فلګن بدل شوي پټنوم اجازه نلري.",
-       "authmanager-authplugin-setpass-bad-domain": "ناباوره ډومین.",
        "authmanager-autocreate-noperm": "د اتوماتيک حساب جوړولو جوړولو اجازه نشته.",
        "authmanager-autocreate-exception": "د پخوانیو غلطیو له امله د اتوماتیک حساب ورکولو جوړول په عارضي ډول معیوب شوی.",
        "authmanager-userdoesnotexist": "د \"$1\" گڼون نه دی ثبت شوی.",
index f6e49f1..3d75859 100644 (file)
        "tog-norollbackdiff": "Omitir diferenças após fazer uma reversão",
        "tog-useeditwarning": "Avisar-me quando eu deixar uma janela de edição sem ter salvo as alterações",
        "tog-prefershttps": "Usar sempre uma conexão segura enquanto estiver conectado",
+       "tog-showrollbackconfirmation": "Mostrar um aviso de confirmação ao clicar em um link de reversão",
        "underline-always": "Sempre",
        "underline-never": "Nunca",
        "underline-default": "Padrão do navegador/tema",
        "badretype": "As senhas que você digitou não são iguais.",
        "usernameinprogress": "Uma criação da conta para este nome de usuário já está em andamento.\nPor favor, aguarde.",
        "userexists": "O nome de usuário fornecido já está em uso.\nEscolha um nome diferente.",
+       "createacct-normalization": "O seu nome de usuário será ajustado para \"$2\" devido a restrições técnicas.",
        "loginerror": "Erro de autenticação",
        "createacct-error": "Erro ao criar a conta",
        "createaccounterror": "Não foi possível criar a conta: $1",
        "page_first": "primeira",
        "page_last": "última",
        "histlegend": "Como selecionar: marque as caixas de seleção das versões que deseja comparar e pressione enter ou clique no botão na parte inferior do formulário.<br />\nLegenda: <strong>({{int:cur}})</strong> = diferenças em relação a última versão, <strong>({{int:last}})</strong> = diferenças em relação a versão anterior, <strong>{{int:minoreditletter}}</strong> = edição menor.",
-       "history-fieldset-title": "Pesquisar revisões",
+       "history-fieldset-title": "Filtrar revisões",
        "history-show-deleted": "Apenas as revisões excluídas",
        "histfirst": "Mais antigas",
        "histlast": "Mais novas",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
-       "historyempty": "(vazio)",
+       "historyempty": "vazio",
        "history-feed-title": "Histórico de revisão",
        "history-feed-description": "Histórico de revisões para esta página neste wiki",
        "history-feed-item-nocomment": "$1 em $2",
        "right-reupload-own": "Sobrescrever um arquivo existente enviado pelo mesmo usuário",
        "right-reupload-shared": "Sobrescrever localmente arquivos no repositório partilhado de mídias",
        "right-upload_by_url": "Enviar um arquivo por um URL",
-       "right-purge": "Carregar a cache de uma página no site sem página de confirmação",
+       "right-purge": "Limpar o cache do site para uma página",
        "right-autoconfirmed": "Não ser afetado pelos limites de frequência baseados no número de IP",
        "right-bot": "Ser tratado como um processo automatizado",
        "right-nominornewtalk": "Não ter o aviso de novas mensagens despoletado quando são feitas edições menores a páginas de discussão",
        "enotif_lastvisited": "Consulte $1 para todas as alterações efetuadas desde a sua última visita.",
        "enotif_lastdiff": "Acesse $1 para ver esta alteração.",
        "enotif_anon_editor": "usuário anônimo $1",
-       "enotif_body": "{{GENDER:$WATCHINGUSERNAME|Caro|Cara|Caro(a)}},\n\n$PAGEINTRO $NEWPAGE\n\nResumo do editor: $PAGESUMMARY $PAGEMINOREDIT\n\nContate o editor:\ne-mail: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nAté que visite esta página, você não receberá mais notificações das alterações futuras.\nVocê pode também reativar as notificações para todas páginas na sua lista de páginas vigiadas.\n\nO seu sistema de notificação amigável da {{SITENAME}}\n\n--\nPara alterar as suas preferências das notificações por correio electrônico, visite\n{{canonicalurl:{{#special:Preferences}}}}\n\nPara alterar as suas preferências das páginas vigiadas, visite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPara retirar a página da lista de páginas vigiadas, visite\n$UNWATCHURL\n\nPara comentários e pedidos de ajuda:\n$HELPPAGE",
+       "enotif_body": "{{GENDER:$WATCHINGUSERNAME|Caro|Cara|Caro(a)}},\n\n$PAGEINTRO $NEWPAGE\n\nResumo do editor: $PAGESUMMARY $PAGEMINOREDIT\n\nContate o editor:\ne-mail: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nAté que visite esta página, você não receberá mais notificações das alterações futuras.\nVocê pode também reativar as notificações para todas páginas na sua lista de páginas vigiadas.\n\nO seu sistema de notificação amigável da {{SITENAME}}\n\n--\nPara alterar as suas preferências das notificações por correio eletrônico, visite\n{{canonicalurl:{{#special:Preferences}}}}\n\nPara alterar as suas preferências das páginas vigiadas, visite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPara retirar a página da lista de páginas vigiadas, visite\n$UNWATCHURL\n\nPara comentários e pedidos de ajuda:\n$HELPPAGE",
        "enotif_minoredit": "Esta é uma edição menor",
        "created": "criada",
        "changed": "alterada",
        "delete-confirm": "Eliminar \"$1\"",
        "delete-legend": "Eliminar",
        "historywarning": "<strong>Aviso:</strong> A página que está prestes a eliminar tem um histórico com aproximadamente $1 {{PLURAL:$1|revisão|revisões}}:",
-       "historyaction-submit": "Exibir",
+       "historyaction-submit": "Mostrar revisões",
        "confirmdeletetext": "Encontra-se prestes a eliminar uma página juntamente com todo o seu histórico.\nPor favor, confirme que possui a intenção de fazer isto, que compreende as consequências e que encontra-se a fazer isto de acordo com as [[{{MediaWiki:Policy-url}}|políticas]] do projeto.",
        "actioncomplete": "Ação efetuada com sucesso",
        "actionfailed": "Falha na ação",
        "deleting-backlinks-warning": "'''Cuidado:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|outras páginas]] ligam ou redirecionam para a página que você está prestes a eliminar.",
        "deleting-subpages-warning": "<strong>Aviso:</strong> A página que você está prestes a excluir tem [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|uma subpágina|$1 subpáginas|51=mais de 50 subpáginas}}]].",
        "rollback": "Reverter edições",
+       "rollback-confirmation-confirm": "Por favor confirme:",
+       "rollback-confirmation-yes": "Reverter",
+       "rollback-confirmation-no": "Cancelar",
        "rollbacklink": "reverter",
        "rollbacklinkcount": "reverter $1 {{PLURAL:$1|edição|edições}}",
        "rollbacklinkcount-morethan": "reverter mais de $1 {{PLURAL:$1|edição|edições}}",
        "revertpage": "Foram revertidas as edições de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc]]) para a última versão por [[User:$1|$1]]",
        "revertpage-nouser": "Revertidas as edições de um usuário oculto para a última revisão de {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Edições revertidas por {{GENDER:$3|$1}};\nalterado para a última revisão por {{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": "Parece haver um problema com sua sessão de login;\nEsta ação foi cancelada como uma precaução contra o seqüestro de sessão.\nPor favor, reenvie o formulário.",
        "changecontentmodel": "Alterar o modelo de conteúdo de uma página",
        "mycontris": "Contribuições",
        "anoncontribs": "Contribuições",
        "contribsub2": "Para {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Para {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "A conta de usuário \"$1\" não está registrada.",
        "negative-namespace-not-supported": "Namespaces com valores negativos não são suportados.",
        "nocontribs": "Não foram encontradas mudanças com este critério.",
        "ipb-confirm": "Confirmar bloqueio",
        "ipb-sitewide": "Em todo o site",
        "ipb-partial": "Parcial",
+       "ipb-sitewide-help": "Cada página na wiki e todas as outras ações de contribuição.",
+       "ipb-partial-help": "Páginas ou espaços nominais específicos.",
        "ipb-pages-label": "Páginas",
        "ipb-namespaces-label": "Espaços nominais",
        "badipaddress": "Endereço de IP inválido",
        "confirm-unwatch-top": "Remover esta página das páginas vigiadas?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Reverter edições nesta página?",
+       "confirm-rollback-bottom": "Essa ação reverterá instantaneamente as alterações selecionadas para esta página.",
        "confirm-mcrrestore-title": "Restaurar uma revisão",
        "confirm-mcrundo-title": "Desfazer uma mudança",
        "mcrundofailed": "A reversão falhou",
        "logentry-rights-autopromote": "$1 foi promovido automaticamente de $4 para $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|carregou}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|carregada}} uma nova versão de $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|carregado}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|revertido}} $3 para uma versão antiga",
        "log-name-managetags": "Registo de gestão de etiquetas",
        "log-description-managetags": "Esta página lista as tarefas de gestão relacionadas a [[Special:Tags|etiquetas]]. O registro contém apenas ações realizadas manualmente por um administrador; etiquetas podem ser criadas ou apagadas pelo software da wiki sem uma entrada a ser gravada neste registro.",
        "logentry-managetags-create": "$1 {{GENDER:$2|criada}} a etiqueta \"$4\"",
        "log-action-filter-suppress-reblock": "Supressão de usuário por rebloqueio",
        "log-action-filter-upload-upload": "Novo Upload",
        "log-action-filter-upload-overwrite": "Recarregar",
+       "log-action-filter-upload-revert": "Reverter",
        "authmanager-authn-not-in-progress": "A autenticação não está em andamento ou os dados da sessão foram perdidos. Por favor, comece novamente desde o início.",
        "authmanager-authn-no-primary": "As credenciais fornecidas não puderam ser autenticadas.",
        "authmanager-authn-no-local-user": "As credenciais fornecidas não estão associadas a nenhum usuário neste wiki.",
        "authmanager-create-no-primary": "As credenciais fornecidas não puderam ser usadas para criação de conta.",
        "authmanager-link-no-primary": "As credenciais fornecidas não puderam ser usadas para vinculação de contas.",
        "authmanager-link-not-in-progress": "A associação de contas não está em andamento ou os dados da sessão foram perdidos. Por favor, comece novamente desde o início.",
-       "authmanager-authplugin-setpass-failed-title": "Falha na alteração da senha",
-       "authmanager-authplugin-setpass-failed-message": "O plugin de autenticação negou a alteração da senha.",
-       "authmanager-authplugin-create-fail": "O plugin de autenticação negou a criação da conta.",
-       "authmanager-authplugin-setpass-denied": "O plugin de autenticação não permite alterar senhas.",
-       "authmanager-authplugin-setpass-bad-domain": "Domínio inválido.",
        "authmanager-autocreate-noperm": "A criação automática de conta não é permitida.",
        "authmanager-autocreate-exception": "Criação automática de conta temporariamente desativada devido a erros anteriores.",
        "authmanager-userdoesnotexist": "A conta de usuário \"$1\" não está registrada.",
        "passwordpolicies-policy-maximalpasswordlength": "A senha deve ser menor que $1 {{PLURAL:$1|caráter|caracteres}}",
        "passwordpolicies-policy-passwordcannotbepopular": "A senha não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "A senha não pode estar na lista de 100.000 senhas mais usadas.",
+       "passwordpolicies-policyflag-forcechange": "deve mudar no login",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "sugerir mudança na entrada",
        "easydeflate-invaliddeflate": "O conteúdo fornecido não está devidamente comprimido",
        "unprotected-js": "Por razões de segurança o JavaScript não pode ser carregado de páginas desprotegidas. Por favor, crie apenas javascript no MediaWiki: namespace ou como uma subpágina do usuário"
 }
index 1a03d55..1a026b6 100644 (file)
@@ -78,7 +78,8 @@
                        "MokaAkashiyaPT",
                        "Athena in Wonderland",
                        "Fitoschido",
-                       "Ldacosta"
+                       "Ldacosta",
+                       "CaiusSPQR"
                ]
        },
        "tog-underline": "Sublinhar hiperligações:",
        "tog-norollbackdiff": "Não mostrar diferenças depois de reverter edições em bloco",
        "tog-useeditwarning": "Avisar-me ao abandonar uma página editada sem gravar as alterações",
        "tog-prefershttps": "Usar sempre uma ligação segura enquanto tiver sessão iniciada",
+       "tog-showrollbackconfirmation": "Mostrar um pedido de confirmação ao clicar numa hiperligação de reversão",
        "underline-always": "Sempre",
        "underline-never": "Nunca",
        "underline-default": "Usar opção padrão do tema ou do navegador",
        "badretype": "As palavras-passe que introduziu não coincidem.",
        "usernameinprogress": "Já está a ser criada uma conta para este nome de utilizador.\nAguarde, por favor.",
        "userexists": "O nome de utilizador introduzido já existe.\nEscolha um nome diferente, por favor.",
+       "createacct-normalization": "O seu nome de utilizador será ajustado para \"$2\" devido a restrições técnicas.",
        "loginerror": "Erro ao iniciar sessão",
        "createacct-error": "Erro na criação da conta",
        "createaccounterror": "Não foi possível criar a conta: $1",
        "histfirst": "Mais antigas",
        "histlast": "Mais novas",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
-       "historyempty": "(vazia)",
+       "historyempty": "vazia",
        "history-feed-title": "Histórico de revisões",
        "history-feed-description": "Histórico de edições para esta página nesta wiki",
        "history-feed-item-nocomment": "$1 em $2",
        "right-reupload-own": "Sobrescrever um ficheiro existente carregado pelo mesmo utilizador",
        "right-reupload-shared": "Sobrescrever localmente ficheiros no repositório partilhado de imagens",
        "right-upload_by_url": "Carregar um ficheiro de um endereço URL",
-       "right-purge": "Limpar a cache de uma página no servidor sem confirmação",
+       "right-purge": "Purgar a cache de uma página no servidor",
        "right-autoconfirmed": "Não ser afetado pelos limites de frequência de edição baseados em endereços IP",
        "right-bot": "Ser tratado como um processo automatizado",
        "right-nominornewtalk": "Não desencadear o aviso de mensagens novas ao fazer edições menores a páginas de discussão",
        "trackingcategories-summary": "Esta página lista as categorias de monitorização geradas automaticamente pelo software MediaWiki. Os nomes das categorias podem ser alterados modificando as mensagens de sistema relevantes no domínio {{ns:8}}.",
        "trackingcategories-msg": "Categoria monitorada",
        "trackingcategories-name": "Nome da mensagem",
-       "trackingcategories-desc": "Critérios de inclusão",
+       "trackingcategories-desc": "Critérios de inclusão da categoria",
        "restricted-displaytitle-ignored": "Páginas com títulos de apresentação ignorados",
        "restricted-displaytitle-ignored-desc": "Esta página tem um <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> ignorado porque não é equivalente ao título verdadeiro da página.",
        "noindex-category-desc": "A página não é indexada por robôs porque contém a palavra mágica <code><nowiki>__NOINDEX__</nowiki></code> e está num espaço nominal onde esta palavra mágica é permitida.",
        "deleting-backlinks-warning": "<strong>Aviso:</strong> Existem [[Special:WhatLinksHere/{{FULLPAGENAME}}|páginas]] que contêm ligações para a página que está prestes a eliminar ou que a transcluem.",
        "deleting-subpages-warning": "<strong>Aviso:</strong> A página que está prestes a eliminar tem [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|uma subpágina|$1 subpáginas|51=mais de 50 subpáginas}}]].",
        "rollback": "Reverter edições",
+       "rollback-confirmation-confirm": "Confirme, por favor:",
+       "rollback-confirmation-yes": "Reverter",
+       "rollback-confirmation-no": "Cancelar",
        "rollbacklink": "reverter",
        "rollbacklinkcount": "reverter $1 {{PLURAL:$1|edição|edições}}",
        "rollbacklinkcount-morethan": "reverter mais do que $1 {{PLURAL:$1|edição|edições}}",
        "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 {{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 detetados problemas com a sua sessão;\na operação foi cancelada como medida de proteção contra a intercetação de sessões.\nReenvie o formulário, por favor.",
        "changecontentmodel": "Alterar modelo de conteúdo de uma página",
        "mycontris": "Contribuições",
        "anoncontribs": "Contribuições",
        "contribsub2": "Para {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "De {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "A conta de utilizador \"$1\" não está registada.",
        "negative-namespace-not-supported": "Não são suportados espaços nominais com valores negativos.",
        "nocontribs": "Não foram encontradas alterações com este critério.",
        "nolinkshere": "Não existem afluentes para <strong>$2</strong> com as condições especificadas.",
        "nolinkshere-ns": "Não existem afluentes para <strong>$2</strong> no espaço nominal selecionado.",
        "isredirect": "página de redirecionamento",
-       "istemplate": "inclusão",
+       "istemplate": "transclusão",
        "isimage": "hiperligação para ficheiro",
        "whatlinkshere-prev": "{{PLURAL:$1|anterior|$1 anteriores}}",
        "whatlinkshere-next": "{{PLURAL:$1|próximo|próximos $1}}",
        "ipb-confirm": "Confirmar o bloqueio",
        "ipb-sitewide": "Em todo o site",
        "ipb-partial": "Parcial",
+       "ipb-sitewide-help": "Todas as páginas da wiki e todos as outras operações de participação.",
+       "ipb-partial-help": "Páginas ou espaços nominais específicos.",
        "ipb-pages-label": "Páginas",
        "ipb-namespaces-label": "Espaços nominais",
        "badipaddress": "Endereço IP inválido",
        "confirm-unwatch-top": "Remover esta página da lista de páginas vigiadas?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Reverter as edições desta página?",
+       "confirm-rollback-bottom": "Essa operação reverterá instantaneamente as mudanças selecionadas desta página.",
        "confirm-mcrrestore-title": "Restaurar uma revisão",
        "confirm-mcrundo-title": "Desfazer uma mudança",
        "mcrundofailed": "A reversão falhou",
        "logentry-rights-autopromote": "$1 foi automaticamente {{GENDER:$2|promovido|promovida}} de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|carregou}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|carregou}} uma nova versão de $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|carregou}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|reverteu}} $3 para uma versão antiga",
        "log-name-managetags": "Registo de gestão de etiquetas",
        "log-description-managetags": "Esta página lista as tarefas de gestão relacionadas com [[Special:Tags|etiquetas]]. O registo contém apenas ações realizadas manualmente por um administrador; etiquetas podem ser criadas ou eliminadas pelo ''software'' da wiki sem uma entrada a ser gravada neste registo.",
        "logentry-managetags-create": "$1 {{GENDER:$2|criou}} a etiqueta \"$4\"",
        "log-action-filter-suppress-reblock": "Supressão de utilizador por rebloqueio",
        "log-action-filter-upload-upload": "Novo carregamento",
        "log-action-filter-upload-overwrite": "Recarregamento",
+       "log-action-filter-upload-revert": "Reverter",
        "authmanager-authn-not-in-progress": "A autenticação não está em curso ou os dados da sessão foram perdidos. Comece novamente desde o princípio, por favor.",
        "authmanager-authn-no-primary": "As informações de identificação fornecidas não podem ser autenticadas.",
        "authmanager-authn-no-local-user": "As credenciais fornecidas não estão associadas a nenhum utilizador nesta wiki.",
        "authmanager-create-no-primary": "Não foi possível criar uma conta com as credenciais fornecidas.",
        "authmanager-link-no-primary": "Não foi possível ligar a conta usando as credenciais fornecidas.",
        "authmanager-link-not-in-progress": "A ligação da conta não está em curso ou os dados da sessão foram perdidos. Comece novamente desde o princípio, por favor.",
-       "authmanager-authplugin-setpass-failed-title": "A alteração de palavra-passe falhou",
-       "authmanager-authplugin-setpass-failed-message": "O plugin de autenticação negou a alteração de palavra-passe.",
-       "authmanager-authplugin-create-fail": "O plugin de autenticação negou a criação de conta.",
-       "authmanager-authplugin-setpass-denied": "O plugin de autenticação não permite a alteração de palavras-passe.",
-       "authmanager-authplugin-setpass-bad-domain": "Domínio inválido.",
        "authmanager-autocreate-noperm": "A criação automática de contas não é permitida.",
        "authmanager-autocreate-exception": "A criação automática de contas foi temporariamente desativada devido a erros prévios.",
        "authmanager-userdoesnotexist": "A conta de utilizador(a) \"$1\" não está registada.",
        "passwordpolicies-policy-maximalpasswordlength": "A palavra-passe tem de ter menos de $1 {{PLURAL:$1|carácter|caracteres}}",
        "passwordpolicies-policy-passwordcannotbepopular": "A palavra-passe não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "A palavra-passe não pode constar na lista das 100 000 palavras-passe usadas com mais frequência.",
+       "passwordpolicies-policyflag-forcechange": "deve mudar ao iniciar sessão",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "sugerir alteração ao iniciar sessão",
        "easydeflate-invaliddeflate": "O conteúdo fornecido não está devidamente comprimido",
        "unprotected-js": "Por motivos de segurança o JavaScript de páginas desprotegidas não pode ser carregado. Crie javascript só no espaço nominal/domínio MediaWiki: ou numa subpágina do utilizador"
 }
index 6860220..5065bb6 100644 (file)
        "tog-norollbackdiff": "Option in [[Special:Preferences]], 'Misc' tab. Only shown for users with the rollback right. By default a diff is shown below the return screen of a rollback. Checking this preference toggle will suppress that. {{Gender}}\n{{Identical|Rollback}}",
        "tog-useeditwarning": "Used as label for the checkbox in [[Special:Preferences#mw-prefsection-editing|Special:Preferences]].",
        "tog-prefershttps": "Toggle option used in [[Special:Preferences]] that indicates if the user wants to use a secure connection when logged in",
+       "tog-showrollbackconfirmation": "Toggle option used in [[Special:Preferences]] to enable/disable rollback confirmation prompt. Should be visible only to users with rollback rights.",
        "underline-always": "Used in [[Special:Preferences#mw-prefsection-rendering|Preferences]].\n\nThis option means \"always underline links\", there are also options {{msg-mw|Underline-never}} and {{msg-mw|Underline-default}}.\n\n{{Gender}}\n{{Identical|Always}}",
        "underline-never": "Used in [[Special:Preferences#mw-prefsection-rendering|Preferences]].\n\nThis option means \"never underline links\", there are also options {{msg-mw|Underline-always}} and {{msg-mw|Underline-default}}.\n\n{{Gender}}\n{{Identical|Never}}",
        "underline-default": "Used in [[Special:Preferences#mw-prefsection-rendering|Preferences]].\n\nThis option means \"underline links as in your user skin or your browser\", there are also options {{msg-mw|Underline-never}} and {{msg-mw|Underline-always}}.\n\n{{Gender}}\n{{Identical|Browser default}}",
        "feed-invalid": "Result of check whether feed type is valid or not.",
        "feed-unavailable": "This message is displayed when a user tries to use an RSS or Atom feed on a wiki where such feeds have been disabled.",
        "site-rss-feed": "Used in the HTML header of a wiki's RSS feed.\nHTML markup cannot be used.\n\nParameters:\n* $1 - <nowiki>{{SITENAME}}</nowiki>\n{{Identical|S1 RSS/Atom feed}}",
-       "site-atom-feed": "Used in the HTML header of a wiki's Atom feed.\nHTML markup cannot be used.\n\nParameters:\n* $1 - <nowiki>{{SITENAME}}</nowiki>\n{{Identical|S1 RSS/Atom feed}}",
+       "site-atom-feed": "Used in the HTML header of a wiki's Atom feed. HTML markup cannot be used.\n\n\"Atom\" is a technology for automated updates. See [[w:en:Atom (standard)]].\n\nA \"feed\" refers to [[:w:en:Web feed|web feed]] - a technology that shows new information about a topic.\n\nParameters:\n* $1 - <nowiki>{{SITENAME}}</nowiki>\n{{Identical|S1 RSS/Atom feed}}",
        "page-rss-feed": "Parameters:\n* $1 - page title\nSee also:\n* {{msg-mw|Page-atom-feed}}\n{{Identical|S1 RSS/Atom feed}}",
-       "page-atom-feed": "Parameters:\n* $1 - page title\nSee also:\n* {{msg-mw|Page-rss-feed}}\n{{Identical|S1 RSS/Atom feed}}",
+       "page-atom-feed": "Used as the \"title\" attribute in the <link rel=\"alternate\" type=\"application/atom+xml\"> element of the HTML source of the page. Not rendered in the web page.\n\n\"Atom\" is a technology for automated updates. See [[w:en:Atom (standard)]].\n\nA \"feed\" refers to [[:w:en:Web feed|web feed]] - a technology that shows new information about a topic.\n\nParameters:\n* $1 - page title\nSee also:\n* {{msg-mw|Page-rss-feed}}\n{{Identical|S1 RSS/Atom feed}}",
        "feed-atom": "{{optional}}\nSee also:\n* {{msg-mw|Feed-atom}}\n* {{msg-mw|Accesskey-feed-atom}}\n* {{msg-mw|Tooltip-feed-atom}}",
        "feed-rss": "{{optional}}\nSee also:\n* {{msg-mw|Feed-rss}}\n* {{msg-mw|Accesskey-feed-rss}}\n* {{msg-mw|Tooltip-feed-rss}}",
        "sitenotice": "{{Notranslate}}\n\nMediaWiki:Sitenotice is displayed above the page title for all users if it is defined, unless it is superseded by another notice. 'Defined' means it exists and has content other than the single character '-'.\n\nManual: [[mw:Manual:Interface/Sitenotice]]",
        "badretype": "Used as error message when the new password and its retype do not match.",
        "usernameinprogress": "Used as error message in creating a user account.",
        "userexists": "Used as error message in creating a user account.",
+       "createacct-normalization": "Used as warning message on account creation when user name is adjusted silently due to technical restrictions (e.g. first letter capitalized, underscores converted to spaces).\nParameters:\n* $1 - the old username\n* $2 - the new username",
        "loginerror": "Used as title of error message.\n{{Identical|Login error}}",
        "createacct-error": "Used as heading for the error message.",
        "createaccounterror": "Parameters:\n* $1 - an error message",
        "page_first": "This is part of the navigation message on the top and bottom of Special pages which are lists of things in alphabetical order, e.g. the '[[Special:Categories|Categories]]' special page. It is followed by the message {{msg-mw|Viewprevnext}}.\n{{Identical|First}}",
        "page_last": "This is part of the navigation message on the top and bottom of Special pages which are lists of things in alphabetical order, e.g. the '[[Special:Categories|Categories]]' special page. It is followed by the message {{msg-mw|Viewprevnext}}.\n\n{{Identical|Last}}",
        "histlegend": "Text in history page.\n\nSee also:\n* {{msg-mw|Cur}}\n* {{msg-mw|Last}}\n* {{msg-mw|Minoreditletter}}",
-       "history-fieldset-title": "Fieldset label in the edit history pages.",
+       "history-fieldset-title": "Form legend label in the edit history page.",
        "history-show-deleted": "CheckBox to show only per [[mw:Manual:RevisionDelete|RevisionDelete]] deleted versions.\n\nUsed in History and [[Special:Contributions]].",
        "history_copyright": "{{notranslate}}",
        "histfirst": "This is part of the navigation message on the top and bottom of Page History pages which are lists of things in date order, e.g. [{{canonicalurl:Support|action=history}} Page History of Support].\n\nIt is followed by the message {{msg-mw|Viewprevnext}}.\n{{Identical|Oldest}}",
        "histlast": "This is part of the navigation message on the top and bottom of Page History pages which are lists of things in date order, e.g. [{{canonicalurl:Support|action=history}} Page History of Support].\n\nIt is followed by the message {{msg-mw|Viewprevnext}}.\n{{Identical|Newest}}",
        "historysize": "Parameters:\n* $1 - byte count, for PLURAL support",
        "historyempty": "Text in page history for empty page revisions\n\n{{Identical|Empty}}",
-       "history-feed-title": "Used as title of the RSS/Atom feed for a page history. See [{{canonicalurl:Main_Page|feed=atom&action=history}} example].",
-       "history-feed-description": "Used as subtitle (description) of the RSS/Atom feed for a page history. See [{{canonicalurl:Main_Page|feed=atom&action=history}} example].",
-       "history-feed-item-nocomment": "Title for each revision when viewing the RSS/Atom feed for a page history.\n\nParameters:\n* $1 - username\n* $2 - date/time\n* $3 - (Optional) date\n* $4 - (Optional) time",
+       "history-feed-title": "Used as title of the RSS/Atom [[:w:en:web feed|feed]] for a page history. See [{{canonicalurl:Main_Page|feed=atom&action=history}} example].",
+       "history-feed-description": "Used as subtitle (description) of the RSS/Atom [[:w:en:web feed|feed]] for a page history. See [{{canonicalurl:Main_Page|feed=atom&action=history}} example].",
+       "history-feed-item-nocomment": "Title for each revision when viewing the RSS/Atom [[:w:en:web feed|feed]] for a page history.\n\nParameters:\n* $1 - username\n* $2 - date/time\n* $3 - (Optional) date\n* $4 - (Optional) time",
        "history-feed-empty": "Used as summary of the RSS/Atom feed for a page history when the feed is empty.\nSee [{{canonicalurl:x|feed=atom&action=history}} example].",
        "history-edit-tags": "Text of button used to access change tagging interface. For more information on tags see [[mw:Manual:Tags]].",
        "rev-deleted-comment": "Apparently this can also be about the reason of a log action, not only an edit summary. See also:\n*{{msg-mw|revdelete-hide-comment}}",
        "right-reupload-own": "{{doc-right|reupload-own}}\nRight to upload a file under a file name that already exists, and that the same user has uploaded.\n\nRelated messages:\n* {{msg-mw|right-upload}}\n* {{msg-mw|right-reupload}}",
        "right-reupload-shared": "{{doc-right|reupload-shared}}\nThe right to upload a file locally under a file name that already exists in a shared database (for example Commons).\n\nRelated messages:\n* {{msg-mw|right-upload}}\n* {{msg-mw|right-reupload}}",
        "right-upload_by_url": "{{doc-right|upload_by_url}}",
-       "right-purge": "{{doc-right|purge}}\nThe right to use <code>&action=purge</code> in the URL, without needing to confirm it (by default, anonymous users need to confirm it).",
+       "right-purge": "{{doc-right|purge}}\nThe right to use <code>&action=purge</code> in the URL.",
        "right-autoconfirmed": "{{doc-right|autoconfirmed}}\nIf your account is older than [[mw:Manual:$wgAutoConfirmAge|wgAutoConfirmAge]] and if you have at least [[mw:Manual:$wgAutoConfirmCount|$wgAutoConfirmCount]] edits, you are in the '''group \"autoconfirmed\"''' (note that you can't see this group at [[Special:ListUsers]]).\nIf you are in that group, you have (by default) the '''right \"autoconfirmed\"''', which exempts you from certain rate limits (those based on your IP address or otherwise intended solely for new users). Other rate limits may still apply; see {{msg-mw|right-noratelimit}}.",
        "right-bot": "{{doc-right|bot}}",
        "right-nominornewtalk": "{{doc-right|nominornewtalk}}\nIf someone with this right (bots by default) edits a user talk page and marks it as minor (requires {{msg-mw|right-minoredit}}), the user will not get a notification \"You have new messages\".",
        "action-changetags": "{{doc-action|changetags}}",
        "action-deletechangetags": "{{doc-action|deletechangetags}}",
        "action-purge": "{{doc-action|purge}}",
+       "action-apihighlimits": "{{doct|apihighlimits}}",
+       "action-autoconfirmed": "{{doc-action|autoconfirmed}}",
+       "action-bigdelete": "{{doc-action|bigdelete}}",
+       "action-blockemail": "{{doc-action|blockemail}}",
+       "action-bot": "{{doc-action|bot}}",
+       "action-editprotected": "{{doc-action|editprotected}}",
+       "action-editsemiprotected": "{{doc-action|editsemiprotected}}",
+       "action-editinterface": "{{doc-action|editinterface}}",
+       "action-editusercss": "{{doc-action|editusercss}}",
+       "action-edituserjson": "{{doc-action|edituserjson}}",
+       "action-edituserjs": "{{doc-action|edituserjs}}",
+       "action-editsitecss": "{{doc-action|editsitecss}}",
+       "action-editsitejson": "{{doc-action|editsitejson}}",
+       "action-editsitejs": "{{doc-action|editsitejs}}",
+       "action-editmyusercss": "{{doc-action|editmyusercss}}",
+       "action-editmyuserjson": "{{doc-action|editmyuserjson}}",
+       "action-editmyuserjs": "{{doc-action|editmyuserjs}}",
+       "action-viewsuppressed": "{{doc-action|viewsuppressed}}",
+       "action-hideuser": "{{doc-action|hideuser}}",
+       "action-ipblock-exempt": "{{doc-action|ipblock-exempt}}",
+       "action-unblockself": "{{doc-action|unblockself}}",
+       "action-noratelimit": "{{doc-action|noratelimit}}",
+       "action-reupload-own": "{{doc-action|reupload-own}}",
+       "action-nominornewtalk": "{{doc-action|nominornewtalk}}",
+       "action-markbotedits": "{{doc-action|markbotedits}}",
+       "action-patrolmarks": "{{doc-action|patrolmarks}}",
+       "action-override-export-depth": "{{doc-action|override-export-depth}}",
+       "action-suppressredirect": "{{doc-action|suppressredirect}}",
        "nchanges": "Appears on enhanced watchlist and recent changes when page has more than one change on given date, linking to a diff of the changes.\n\nParameters:\n* $1 - the number of changes on that day (2 or more)\nThree messages are shown side-by-side: ({{msg-mw|Nchanges}} | {{msg-mw|Enhancedrc-since-last-visit}} | {{msg-mw|Enhancedrc-history}}).",
        "ntimes": "Used to indicate how many times an event occurred (eg. on enhanced recent change when a user did more than one change to the page). Parameters:\n* $1 - number (integer)",
        "enhancedrc-since-last-visit": "Appears on enhanced watchlist and recent changes when page has more than one change on given date and at least one that the user hasn't seen yet, linking to a diff of the unviewed changes.\n\nParameters:\n* $1 - the number of unviewed changes (1 or more)\nThree messages are shown side-by-side: ({{msg-mw|nchanges}} | {{msg-mw|enhancedrc-since-last-visit}} | {{msg-mw|enhancedrc-history}}).",
        "recentchanges-timeout": "Used in [[Special:RecentChanges]], [[Special:RecentChangesLinked]], and [[Special:Watchlist]] when a query times out.",
        "recentchanges-network": "Used in [[Special:RecentChanges]], [[Special:RecentChangesLinked]] and [[Special:Watchlist]] when network error occurs.",
        "recentchanges-notargetpage": "Used in [[Special:RecentChangesLinked]] to explain why no results are shown when no target page is specified.",
-       "recentchanges-feed-description": "Used in feed of RecentChanges. See example [{{canonicalurl:Special:RecentChanges|feed=atom}} feed].",
+       "recentchanges-feed-description": "Used in feed of RecentChanges. See example [{{canonicalurl:Special:RecentChanges|feed=atom}} feed].\n\nA \"feed\" refers to [[:w:en:Web feed|web feed]] - a technology that shows new information about a topic.",
        "recentchanges-label-newpage": "# Used as tooltip for {{msg-mw|Newpageletter}}.\n# Also used as legend. Preceded by {{msg-mw|Newpageletter}} and followed by {{msg-mw|Recentchanges-legend-newpage}}.",
        "recentchanges-label-minor": "# Used as tooltip for {{msg-mw|Minoreditletter}}\n# Also used as legend. Preceded by {{msg-mw|Minoreditletter}}",
        "recentchanges-label-bot": "# Used as tooltip for {{msg-mw|Boteditletter}}\n# Also used as legend. Preceded by {{msg-mw|Boteditletter}}",
        "rc-enhanced-hide": "See also:\n* {{msg-mw|Rc-enhanced-expand}}\n{{Identical|Hide details}}",
        "rc-old-title": "Text that shows the original title of a page, $1 is the original title text",
        "recentchangeslinked": "{{doc-special|RecentChangesLinked}}\nSee also:\n* {{msg-mw|Recentchangeslinked}}\n* {{msg-mw|Accesskey-t-recentchangeslinked}}\n* {{msg-mw|Tooltip-t-recentchangeslinked}}",
-       "recentchangeslinked-feed": "Used in the feed object.\n\nThis message follows the message {{msg-mw|Recentchangeslinked-title}}.",
+       "recentchangeslinked-feed": "Used in the [[:w:en:web feed|feed]] object.\n\nThis message follows the message {{msg-mw|Recentchangeslinked-title}}.",
        "recentchangeslinked-toolbox": "Used as link text, and also used as link text in the common toolbox.\n\nThese links point to [[Special:RecentChangesLinked]].",
        "recentchangeslinked-title": "Message used as title and page header on [[Special:RecentChangesLinked]] (needs an argument like \"/Main Page\").\n\nRelated changes are all recent change to pages that are linked from ''this page''.\n\nThis message is followed by {{msg-mw|Recentchangeslinked-feed}}.\n\nParameters:\n* $1 - the name of the page for which related changes are shown",
        "recentchangeslinked-summary": "Summary of [[Special:RecentChangesLinked]]. \"Pages on your watchlist\" refers to pages that ''also'' appear on the user's watchlist.",
        "delete-confirm": "Used as page title. Parameters:\n* $1 - the page title\n{{Identical|Delete}}",
        "delete-legend": "{{Identical|Delete}}",
        "historywarning": "Warning when about to delete a page that has history.\n\nFollowed by a link which points to the history page.\n\nParameters:\n* $1 - the number of revisions that the page has",
-       "historyaction-submit": "Submit button on history pages\n{{Identical|Show}}",
+       "historyaction-submit": "Submit button to show revisions on revision history pages",
        "confirmdeletetext": "Introduction shown when deleting a page.\n\nRefers to {{msg-mw|Policy-url}}.",
        "actioncomplete": "Used in several situations, for example when a page has been deleted.\n\nSee also:\n* {{msg-mw|Actionfailed|page title}}",
        "actionfailed": "Used as page title when the submit operation failed, in [[Special:RevisionDelete]].\n\nSee also:\n* {{msg-mw|Actioncomplete|page title}}",
        "deleting-backlinks-warning": "A warning shown when a page that is being deleted has at least one link to it or is transcluded in at least one page.",
        "deleting-subpages-warning": "A warning shown when a page that is being deleted has at least one subpage. $1 is the number of subpages of the page. For any number of subpages over 50, $1 will be 51.\nSee also:\n* {{msg-mw|Deleting-backlinks-warning}}",
        "rollback": "{{Identical|Rollback}}",
+       "rollback-confirmation-confirm": "Prompt which asks the user to confirm that they want to really perform the rollback action after clicking on the rollback button.",
+       "rollback-confirmation-yes": "Button text to confirm that a rollback should be executed.",
+       "rollback-confirmation-no": "Button text to cancel a rollback instead of executing it.\n{{Identical|Cancel}}",
        "rollbacklink": "{{Doc-actionlink}}\nThis link text appears on the recent changes page to users who have the \"rollback\" right.\nThis message has a tooltip {{msg-mw|tooltip-rollback}}\n{{Identical|Rollback}}",
        "rollbacklinkcount": "{{doc-actionlink}}\nText of the rollback link showing the number of edits to be rolled back. See also {{msg-mw|rollbacklink}}.\n\nParameters:\n* $1 - the number of edits that will be rolled back. If $1 is over the value of <code>$wgShowRollbackEditCount</code> (default: 10) {{msg-mw|rollbacklinkcount-morethan}} is used.\n\nThe rollback link is displayed with a tooltip {{msg-mw|Tooltip-rollback}}",
        "rollbacklinkcount-morethan": "{{doc-actionlink}}\nText of the rollback link when a greater number of edits is to be rolled back. See also {{msg-mw|rollbacklink}}.\n\nWhen the number of edits rolled back is smaller than [[mw:Special:MyLanguage/Manual:$wgShowRollbackEditCount|$wgShowRollbackEditCount]], {{msg-mw|rollbacklinkcount}} is used instead.\n\nParameters:\n* $1 - number of edits",
        "revertpage": "Parameters:\n* $1 - username 1\n* $2 - username 2\n* $3 - (Optional) revision ID of the revision reverted to\n* $4 - (Optional) timestamp of the revision reverted to\n* $5 - (Optional) revision ID of the revision reverted from\n* $6 - (Optional) timestamp of the revision reverted from\nSee also:\n* {{msg-mw|Revertpage-nouser}}\n{{Identical|Revert}}",
        "revertpage-nouser": "This is a confirmation message a user sees after reverting, when the username of the version is hidden with RevisionDelete.\n\nIn other cases the message {{msg-mw|Revertpage}} is used.\n\nParameters:\n* $1 - username 1, can be used for GENDER\n* $2 - (Optional) username 2\n* $3 - (Optional) revision ID of the revision reverted to\n* $4 - (Optional) timestamp of the revision reverted to\n* $5 - (Optional) revision ID of the revision reverted from\n* $6 - (Optional) timestamp of the revision reverted from",
        "rollback-success": "This message shows up on screen after successful revert (generally visible only to admins). Parameters:\n* $1 - user whose changes have been reverted\n* $2 - user who produced version, which replaces reverted version\n* $3 - the first user's name, can be used for GENDER\n* $4 - the second user's name, can be used for GENDER\n{{Identical|Revert}}\n{{Identical|Rollback}}",
-       "rollback-success-notify": "Notification shown after a successful revert.\n* $1 - User whose changes have been reverted\n* $2 - User that made the edit that was restored\n* $3 - Url to the diff of the rollback\nSee also:\n* {{msg-mw|showdiff}}\n{{related|rollback-success}}\n{{Format|jquerymsg}}",
        "sessionfailure-title": "Used as title of the error message {{msg-mw|Sessionfailure}}.",
        "sessionfailure": "Used as error message.\n\nThe title for this error message is {{msg-mw|Sessionfailure-title}}.",
        "changecontentmodel": "Title of the change content model special page",
        "mycontris": "In the personal urls page section - right upper corner.\n\nSee also:\n* {{msg-mw|Mycontris}}\n* {{msg-mw|Accesskey-pt-mycontris}}\n* {{msg-mw|Tooltip-pt-mycontris}}\n{{Identical|Contribution}}",
        "anoncontribs": "Same as {{msg-mw|mycontris}} but used for non-logged-in users.\n\nSee also:\n* {{msg-mw|Accesskey-pt-anoncontribs}}\n* {{msg-mw|Tooltip-pt-anoncontribs}}\n{{Identical|Contribution}}",
        "contribsub2": "Contributions for \"user\" (links). Parameters:\n* $1 is an IP address or a username, with a link which points to the user page (if registered user).\n* $2 is list of tool links. The list contains a link which has text {{msg-mw|Sp-contributions-talk}}.\n* $3 is a plain text username used for GENDER.\n{{Identical|For $1}}",
+       "contributions-subtitle": "Successor to {{msg-mw|contribsub2}}. Contributions for \"user\". Parameters:\n* $1 is an IP address or a username, with a link which points to the user page (if registered user).",
        "contributions-userdoesnotexist": "This message is used in [[Special:Contributions]]. It is used to tell the user that the name he searched for doesn't exist.\n\nParameters:\n* $1 - a username\n{{Identical|Userdoesnotexist}}",
        "negative-namespace-not-supported": "This message is used in [[Special:Contributions]] to tell users that use namespaces with negative value. It not supported as associated namespace(s) doesn't exist.",
        "nocontribs": "Used in [[Special:Contributions]] and [[Special:DeletedContributions]].\n\nSee examples: [[Special:Contributions/x]] and [[Special:DeletedContributions/x]].\n\nParameters:\n* $1 - (Unused) the user name",
        "ipb-confirm": "Used as hidden field in the form on [[Special:Block]].",
        "ipb-sitewide": "A type of block the user can select from on [[Special:Block]].",
        "ipb-partial": "A type of block the user can select from on [[Special:Block]].",
+       "ipb-sitewide-help": "Help text describing the effects of a sitewide block on [[Special:Block]]",
+       "ipb-partial-help": "Help text describing the effects of a partial block on  [[Special:Block]]",
        "ipb-pages-label": "The label for an autocomplete text field to specify pages to block a user from editing on [[Special:Block]].",
        "ipb-namespaces-label": "The label for an autocomplete text field to specify namespaces to block a user from editing on [[Special:Block]].",
        "badipaddress": "An error message shown when one entered an invalid IP address in blocking page.",
        "ip_range_toolarge": "Used as error message in [[Special:Block]]. Parameters:\n* $1 - a number from 0 to 32 for IPv4 (from 0 to 128 for IPv6); a part of CIDR (Classless Inter-Domain Routing) notation.\nSee also:\n* {{msg-mw|Range block disabled}}\n* {{msg-mw|Ip range invalid}}\n* {{msg-mw|Ip range toolarge}}",
        "ip_range_exceeded": "Used as error message in HTMLUserTextField when an IP range exceeds its maximum amount. See {{msg-mw|ip_range_toolarge}} for parameter.\n/$1 is the width as a number of bits.",
        "ip_range_toolow": "Used as error message in HTMLUserTextField, if effectively no IP ranges are interpreted as valid (IPv4 CIDR range /32 or IPv6 /128).",
-       "proxyblocker": "Used in [[Special:BlockMe]].\n\nSee also:\n* {{msg-mw|proxyblocker-disabled}}\n* {{msg-mw|proxyblockreason}}\n* {{msg-mw|proxyblocksuccess}}",
-       "proxyblockreason": "Used as explanation of the reason in [[Special:BlockMe]].\n\nSee also:\n* {{msg-mw|proxyblocker-disabled}}\n* {{msg-mw|proxyblocker}}\n* {{msg-mw|proxyblocksuccess}}",
+       "proxyblocker": "Username for blocking IP addresses listed in [[mw:Manual:$wgProxyList|$wgProxyList]].\n\nSee also:\n* {{msg-mw|proxyblockreason}}",
+       "proxyblockreason": "Reason for blocking IP addresses listed in [[mw:Manual:$wgProxyList|$wgProxyList]].\n\nSee also:\n* {{msg-mw|proxyblocker}}",
        "sorbs": "{{optional}}",
        "sorbsreason": "See also:\n* {{msg-mw|Sorbsreason}}\n* {{msg-mw|Sorbs create account_reason}}",
        "sorbs_create_account_reason": "Used in [[Special:UserLogin]] when creating an account.\n\nSee also:\n* {{msg-mw|Sorbsreason}}\n* {{msg-mw|Sorbs create account_reason}}",
        "tooltip-t-whatlinkshere": "Tooltip shown when hovering over the {{msg-mw|whatlinkshere}} message in the toolbox.\n\nSee also:\n* {{msg-mw|Whatlinkshere}}\n* {{msg-mw|Accesskey-t-whatlinkshere}}\n* {{msg-mw|Tooltip-t-whatlinkshere}}",
        "tooltip-t-recentchangeslinked": "Used as tooltip for the link {{msg-mw|Recentchangeslinked}}.\n\nSee also:\n* {{msg-mw|Recentchangeslinked}}\n* {{msg-mw|Accesskey-t-recentchangeslinked}}\n* {{msg-mw|Tooltip-t-recentchangeslinked}}",
        "tooltip-feed-rss": "Used as tooltip for RSS feed link.\n\nSee also:\n* {{msg-mw|Feed-rss}}\n* {{msg-mw|Accesskey-feed-rss}}\n* {{msg-mw|Tooltip-feed-rss}}",
-       "tooltip-feed-atom": "Used as tooltip for Atom feed link.\n\n\"Atom\" is a technology for automated updates. See [[w:en:Atom (standard)]].\n\nSee also:\n* {{msg-mw|Feed-atom}}\n* {{msg-mw|Accesskey-feed-atom}}\n* {{msg-mw|Tooltip-feed-atom}}",
+       "tooltip-feed-atom": "Used as tooltip for Atom feed link.\n\n\"Atom\" is a technology for automated updates. See [[w:en:Atom (standard)]].\n\nA \"feed\" refers to [[:w:en:Web feed|web feed]] - a technology that shows new information about a topic.\n\nSee also:\n* {{msg-mw|Feed-atom}}\n* {{msg-mw|Accesskey-feed-atom}}\n* {{msg-mw|Tooltip-feed-atom}}",
        "tooltip-t-contributions": "Tooltip shown when hovering over {{msg-mw|Contributions}} in the toolbox.\n\nParameters:\n* $1 - Name of the user\n\nSee also:\n* {{msg-mw|Contributions}}\n* {{msg-mw|Accesskey-t-contributions}}\n* {{msg-mw|Tooltip-t-contributions}}",
        "tooltip-t-emailuser": "Tooltip shown when hovering over the {{msg-mw|Emailuser}} link in the toolbox (sidebar, below).\n\nParameters:\n* $1 - Name of the user\n\nSee also:\n* {{msg-mw|Emailuser}}\n* {{msg-mw|Accesskey-t-emailuser}}\n* {{msg-mw|Tooltip-t-emailuser}}",
        "tooltip-t-info": "Tooltip shown when hovering over the {{msg-mw|pageinfo-toolboxlink}} link in the toolbox (sidebar, below).",
        "confirm-unwatch-top": "Used as confirmation message.",
        "confirm-rollback-button": "Used as Submit button text.\n{{Identical|OK}}",
        "confirm-rollback-top": "Used as confirmation message.",
+       "confirm-rollback-bottom": "Used to describe the rollback action to the user.",
        "confirm-mcrrestore-title": "Title for the editless restore form.",
        "confirm-mcrundo-title": "Title for the editless undo form.",
        "mcrundofailed": "Title of the error page when an editless undo fails.",
        "mediastatistics-header-3d": "Header on [[Special:MediaStatistics]] for file types that are in the 3D category. Includes STL files.",
        "mediastatistics-header-total": "Header on [[Special:MediaStatistics]] for a summary of all file types.",
        "json-warn-trailing-comma": "A warning message notifying that JSON text was automatically corrected by removing erroneous commas.\n\nParameters:\n* $1 - number of commas that were removed\n{{Related|Json-error}}",
-       "json-error-unknown": "User error message when there’s an unknown error.\n\nThis error is shown if we received an unexpected value from PHP. See https://secure.php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code\n{{Related|Json-error}}",
-       "json-error-depth": "User error message when the maximum stack depth is exceeded.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-state-mismatch": "User error message when underflow or the modes mismatch.\n\n'''Underflow''': A data-processing error arising when the absolute value of a computed quantity is smaller than the limits of precision of the computing device, retaining at least one significant digit.\n\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-ctrl-char": "User error message when an unexpected control character has been found.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-syntax": "User error message when there is a syntax error; a malformed JSON.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}\n{{Identical|Syntax error}}",
-       "json-error-utf8": "User error message when there are malformed UTF-8 characters, possibly incorrectly encoded.\nSee https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-recursion": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-inf-or-nan": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
-       "json-error-unsupported-type": "PHP JSON encoding/decoding error. See https://secure.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-unknown": "User error message when there’s an unknown error.\n\nThis error is shown if we received an unexpected value from PHP. See https://www.php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code\n{{Related|Json-error}}",
+       "json-error-depth": "User error message when the maximum stack depth is exceeded.\nSee https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-state-mismatch": "User error message when underflow or the modes mismatch.\n\n'''Underflow''': A data-processing error arising when the absolute value of a computed quantity is smaller than the limits of precision of the computing device, retaining at least one significant digit.\n\nSee https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-ctrl-char": "User error message when an unexpected control character has been found.\nSee https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-syntax": "User error message when there is a syntax error; a malformed JSON.\nSee https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}\n{{Identical|Syntax error}}",
+       "json-error-utf8": "User error message when there are malformed UTF-8 characters, possibly incorrectly encoded.\nSee https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-recursion": "PHP JSON encoding/decoding error. See https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-inf-or-nan": "PHP JSON encoding/decoding error. See https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
+       "json-error-unsupported-type": "PHP JSON encoding/decoding error. See https://www.php.net/manual/en/function.json-last-error.php\n{{Related|Json-error}}",
        "headline-anchor-title": "Title tooltip for the section anchor symbol, which is a link to the current section. Can be interpreted both as a noun (\"this is a link\") or as a verb (\"use this to link\").",
        "special-characters-group-latin": "This is the name of a script, or alphabet, not a language.",
        "special-characters-group-latinextended": "The name of the Latin Extended character set.",
        "log-action-filter-suppress-reblock": "{{doc-log-action-filter-action|suppress|reblock}}",
        "log-action-filter-upload-upload": "{{doc-log-action-filter-action|upload|upload}}",
        "log-action-filter-upload-overwrite": "{{doc-log-action-filter-action|upload|overwrite}}",
+       "log-action-filter-upload-revert": "{{doc-log-action-filter-action|upload|revert}}",
        "authmanager-authn-not-in-progress": "Error message when AuthManager session data is lost during authentication, or the user hits the \"continue\" endpoint without an active authentication attempt.",
        "authmanager-authn-no-primary": "Error message when no AuthenticationProvider handles the AuthenticationRequests for login. This might mean the user needs to fill out all the form fields.",
        "authmanager-authn-no-local-user": "Error message when authentication somehow succeeds without a username being known. This probably should never happen.",
        "authmanager-create-no-primary": "Error message when no AuthenticationProvider handles the AuthenticationRequests for account creation. This might mean the user needs to fill out all the form fields.",
        "authmanager-link-no-primary": "Error message when no AuthenticationProvider handles the AuthenticationRequests for account linking. This might mean the user needs to fill out all the form fields.",
        "authmanager-link-not-in-progress": "Error message when AuthManager session data is lost during account linking, or the user hits the \"continue\" endpoint without an active account link attempt.",
-       "authmanager-authplugin-setpass-failed-title": "Title of error page from AuthManager if AuthPlugin returns false from its setPassword() method.",
-       "authmanager-authplugin-setpass-failed-message": "Text of error page from AuthManager if AuthPlugin returns false from its setPassword() method.",
-       "authmanager-authplugin-create-fail": "Error message from AuthManager if the AuthPlugin returns false from its addUser() method.",
-       "authmanager-authplugin-setpass-denied": "Error message from AuthManager if the AuthPlugin returns false from its allowPasswordChange() method.",
-       "authmanager-authplugin-setpass-bad-domain": "Error message from AuthManager if the AuthPlugin rejects the passed domain.",
        "authmanager-autocreate-noperm": "Error message when auto-creation fails due to lack of permission.",
        "authmanager-autocreate-exception": "Error message when auto-creation fails because we tried recently and an exception was thrown, so we're not going to try again yet.",
        "authmanager-userdoesnotexist": "Error message when a user account does not exist. Parameters:\n* $1 - User name.",
        "passwordpolicies-summary": "The description used on [[Special:PasswordPolicies]].\n\nRefers to {{msg-mw|Passwordpolicies-helppage}}.",
        "passwordpolicies-group": "The title of the column in the table, about user groups (like you are in the ''translator'' group).\n\n{{Identical|Group}}\n{{Related|Passwordpolicies}}",
        "passwordpolicies-policies": "The title of the column in the table, about password policies.\n{{Related|Passwordpolicies}}",
-       "passwordpolicies-policy-display": "{{optional}}\nParameters:\n* $1 - the text from the \"passwordpolicies-policy-...\" messages, i.e. {{msg-mw|passwordpolicies-policy-minimalpasswordlength}}\n* $2 - the name of this password policy",
+       "passwordpolicies-policy-display": "{{optional}}\nParameters:\n* $1 - the text from the \"passwordpolicies-policy-...\" messages, e.g. {{msg-mw|passwordpolicies-policy-minimalpasswordlength}}\n* $2 - the name of this password policy",
+       "passwordpolicies-policy-displaywithflags": "{{optional}}\nParameters:\n* $1 - the text from the \"passwordpolicies-policy-...\" messages, i.e. {{msg-mw|passwordpolicies-policy-minimalpasswordlength}}\n* $2 - the name of this password policy\n* $3 - comma-separated list of the text from the \"passwordpolicies-policyflag-...\" messages, e.g. {{msg-mw|passwordpolicies-policyflag-forcechange}}",
        "passwordpolicies-policy-minimalpasswordlength": "Password policy that enforces a minimum number of characters a password must be. $1 - minimum number of characters that a password can be",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "Password policy that enforces a minimum number of characters a password must be to be able to login to the wiki. $1 - minimum number of characters that a password can be to be able to login",
        "passwordpolicies-policy-passwordcannotmatchusername": "Password policy that enforces that the password of the account cannot be the same as the username",
        "passwordpolicies-policy-maximalpasswordlength": "Password policy that enforces a maximum number of characters a password must be. $1 - maximum number of characters that a password can be",
        "passwordpolicies-policy-passwordcannotbepopular": "Password policy that enforces that a password is not in a list of $1 number of \"popular\" passwords. $1 - number of popular passwords the password will be checked against",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Password policy that enforces that a password is not in a list of 100,000 number of \"popular\" passwords.",
+       "passwordpolicies-policyflag-forcechange": "Password policy flag that enforces changing invalid passwords on login.",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "Password policy flag that suggests changing invalid passwords on login.",
        "easydeflate-invaliddeflate": "Error message if the content passed to easydeflate was not deflated (compressed) properly",
        "unprotected-js": "Error message shown when trying to load javascript via action=raw that is not protected"
 }
index 45b86eb..99f2a77 100644 (file)
        "grant-privateinfo": "Accesați informații confidențiale",
        "grant-protect": "Protejați și deprotejați pagini",
        "grant-rollback": "Reveniți asupra modificărilor paginilor",
-       "grant-sendemail": "Trimite-ți e-mail altor utilizatori",
+       "grant-sendemail": "Trimiteți e-mail altor utilizatori",
        "grant-uploadeditmovefile": "Încărcați, înlocuiți și mutați fișiere",
        "grant-uploadfile": "Încărcați fișiere noi",
        "grant-basic": "Drepturi de bază",
        "querypage-disabled": "Această pagină specială este dezactivată din motive de performanță.",
        "apihelp": "Ajutor API",
        "apihelp-no-such-module": "Modulul „$1” nu a fost găsit.",
-       "apisandbox": "Cutia cu nisip pentru API",
-       "apisandbox-jsonly": "Este nevoie de JavaScript pentru a folosi Cutia cu nisip pentru API.",
+       "apisandbox": "Pagina de teste pentru API",
+       "apisandbox-jsonly": "Este nevoie de JavaScript pentru a folosi pagina de teste pentru API.",
        "apisandbox-api-disabled": "API este dezactivat pe acest site.",
        "apisandbox-intro": "Folosiți această pagină pentru a experimenta cu <strong>API-ul MediaWiki</strong>. Citiți [[mw:API:Main page|documentația API-ului]] pentru mai multe detalii de utilizare. Exemplu: [https://www.mediawiki.org/wiki/API#A_simple_example obțineți conținutul paginii principale]. Selectați o acțiune pentru a vedea mai multe exemple.",
        "apisandbox-submit": "Efectuați cererea",
        "apisandbox-sending-request": "Se trimite solicitarea API...",
        "apisandbox-loading-results": "Se obțin rezultatele API...",
        "apisandbox-results-error": "A apărut o eroare la încărcarea răspunsului solicitării API: $1.",
-       "apisandbox-results-login-suppressed": "Această cerere a fost procesată ca venind din partea unui utilizator neautentificat deoarece poate fi folosită pentru a evita verificările cu privire la originea comună făcute de browser. Metoda automată de administrare a token-urilor din groapa cu nisip pentru APU nu funcționează corect cu aceste cereri, vă rugăm să le completați manual.",
+       "apisandbox-results-login-suppressed": "Această cerere a fost procesată ca venind din partea unui utilizator neautentificat deoarece poate fi folosită pentru a evita verificările cu privire la originea comună făcute de browser. Metoda automată de administrare a token-urilor din pagina de teste pentru API nu funcționează corect cu aceste cereri, vă rugăm să le completați manual.",
        "apisandbox-request-selectformat-label": "Afișați datele solicitate ca:",
        "apisandbox-request-format-url-label": "Șir de interogări URL",
        "apisandbox-request-url-label": "URL cerere:",
        "trackingcategories-nodesc": "Nicio descriere disponibilă.",
        "trackingcategories-disabled": "Categoria este dezactivată",
        "mailnologin": "Nu există adresă de trimitere",
-       "mailnologintext": "Trebuie să fii [[Special:UserLogin|autentificat]] și să ai o adresă validă de e-mail în [[Special:Preferences|preferințe]] pentru a trimite e-mail altor utilizatori.",
+       "mailnologintext": "Trebuie să fiți [[Special:UserLogin|autentificat]] și să aveți o adresă validă de e-mail în [[Special:Preferences|preferințe]] pentru a trimite e-mail altor utilizatori.",
        "emailuser": "Trimite-i un e-mail",
        "emailuser-title-target": "E-mail către {{GENDER:$1|acest utilizator|această utilizatoare}}",
        "emailuser-title-notarget": "E-mail către utilizator",
        "revertpage": "Anularea modificărilor efectuate de către [[Special:Contributions/$2|$2]] ([[User talk:$2|discuție]]) și revenire la ultima versiune de către [[User:$1|$1]]",
        "revertpage-nouser": "Anularea modificărilor efectuate de un utilizator ascuns și revenirea la ultima modificare de către {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Modificările făcute de {{GENDER:$3|$1}} au fost anulate;\nam revenit la ultima versiune de {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "S-a revenit asupra schimbărilor făcute de $1;\nam revenit la ultima versiune de $2. [$3 Arată schimbările]",
        "sessionfailure-title": "Eroare de sesiune",
        "sessionfailure": "Se pare că este o problemă cu sesiunea de autentificare; această acțiune a fost oprită ca o precauție împotriva furtului sesiunii. Vă rugăm să trimiteți formularul din nou.",
        "changecontentmodel": "Modificare model de conținut al unei pagini",
        "block-log-flags-anononly": "doar utilizatori anonimi",
        "block-log-flags-nocreate": "fără drept de a crea conturi",
        "block-log-flags-noautoblock": "fără blocare automată",
-       "block-log-flags-noemail": "fără drept de a trimite e-mail",
+       "block-log-flags-noemail": "e-mail dezactivat",
        "block-log-flags-nousertalk": "fără drept de modificare a propriei pagini de discuții",
        "block-log-flags-angry-autoblock": "autoblocarea avansată activată",
        "block-log-flags-hiddenname": "nume de utilizator ascuns",
        "authmanager-create-no-primary": "Credețialele folosite nu au putut fi folosite pentru crearea de conturi.",
        "authmanager-link-no-primary": "Credențialele folosite nu au putut fi folosite pentru conectarea conturilor.",
        "authmanager-link-not-in-progress": "Conectarea conturilor nu este în progres sau datele sesiunii au fost pierdute. Vă rugăm să începeți de la început.",
-       "authmanager-authplugin-setpass-failed-title": "Schimbarea parolei a eșuat",
-       "authmanager-authplugin-setpass-failed-message": "Pluginul de autentificare a respins modificarea parolei.",
-       "authmanager-authplugin-create-fail": "Pluginul de autentificare a respins crearea contului.",
-       "authmanager-authplugin-setpass-denied": "Pluginul de autentificare nu permite schimbarea parolei.",
-       "authmanager-authplugin-setpass-bad-domain": "Domeniu invalid.",
        "authmanager-autocreate-noperm": "Crearea automată de conturi nu este permisă.",
        "authmanager-autocreate-exception": "Crearea automată de conturi este temporar oprită din cauza erorilor anterioare.",
        "authmanager-userdoesnotexist": "Contul de utilizator „$1” nu este înregistrat.",
index 24ef596..534d0a4 100644 (file)
@@ -58,6 +58,7 @@
        "tog-norollbackdiff": "Non sce penzanne a le differenze apprisse l'esecuzione de 'nu rollback",
        "tog-useeditwarning": "Avvisave quanne jie lasse 'na pàgene cangiate senze ca agghie sarvate le cangiaminde",
        "tog-prefershttps": "Ause sembre 'na connessione secure quanne trase",
+       "tog-showrollbackconfirmation": "Fà 'ndrucà 'na richieste de conferme quanne ste cazze sus a 'nu collegamende de annullamende",
        "underline-always": "Sembre",
        "underline-never": "Maje",
        "underline-default": "Valore de default d'u browser o scheme",
        "badretype": "Le passuord ca è scritte non ge sonde uguale.",
        "usernameinprogress": "'Na ccrejazzione de 'nu cunde pe stu nome utende ste già in esecuzione.\nPe piacere, aspitte.",
        "userexists": "'U nome de l'utende ca è scritte jè già ausate.\nPe piacere scacchiane n'otre.",
+       "createacct-normalization": "'U nome utende tune avène corrette jndr'à \"$2\" purcé stonne de le restriziune tecniche.",
        "loginerror": "Errore de collegamende",
        "createacct-error": "Errore sus 'a ccrejazione d'u cunde",
        "createaccounterror": "Non ge puè ccrejà 'u cunde utende: $1",
        "page_first": "prime",
        "page_last": "urteme",
        "histlegend": "Differenze de selezione: signe le radio box de le versiune ca vuè cu combronde e cazze ''invio'' o 'u buttone ca ste sotte.<br />\nLeggenda: (cur) = differenze cu 'a versiona corrende,\n(last) = differenze ca 'a versione precedende, M = cangiaminde stuédeche.",
-       "history-fieldset-title": "cirche pe revisiune",
+       "history-fieldset-title": "Filtre le revisiune",
        "history-show-deleted": "Sule le revisiune scangellate",
        "histfirst": "Prime",
        "histlast": "Urteme",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
-       "historyempty": "(vacande)",
+       "historyempty": "vacande",
        "history-feed-title": "Storie de le revisiune",
        "history-feed-description": "Storie de le revisiune oe sta pàgene sus 'a le Uicchipèdie",
        "history-feed-item-nocomment": "$1 a $2",
        "right-reupload-own": "Sovrascrive 'nu file esistende carichete da quacchedune",
        "right-reupload-shared": "Sovrascrive le file sus a 'u repository de le media condivise locale",
        "right-upload_by_url": "Careche 'nu file da l'indirizze URL",
-       "right-purge": "Sdevache 'a cache d'u site pe 'na pàgene senza conferme",
+       "right-purge": "Sdevache 'a cache d'u site pe 'na pàgene",
        "right-autoconfirmed": "Cange le pàggene prutette a metà",
        "right-bot": "Adda essere trattate cumme a nu processe automateche",
        "right-nominornewtalk": "No scè ausanne le cangiaminde stuèdeche jndr'à le pàggene de le 'ngazzaminde quanne lasse messagge nuève",
        "delete-confirm": "Scangille \"$1\"",
        "delete-legend": "Scangille",
        "historywarning": "<strong>Vide Bbuene:</strong> 'A pàgene ca ste scangille tène 'na storie de cangiaminde cu cchiù o mene $1 {{PLURAL:$1|revisione|revisiune}}:",
-       "historyaction-submit": "Fà 'ndrucà",
+       "historyaction-submit": "Fà 'ndrucà le revisiune",
        "confirmdeletetext": "Vide Bbuene, vide ca ste scangille 'na pàgene ca tène pure nu sbuenne de cangiaminde.\nConferme quidde ca ste face, ce si sicure ca è capite quidde ca ste cumbine e ce è corrette rispette a [[{{MediaWiki:Policy-url}}|le regole de scangellazione]], ce no statte quiete.",
        "actioncomplete": "Aziona Combletete",
        "actionfailed": "Aziona fallite",
        "deleteprotected": "Non ge puè scangellà sta pàgene purcé ha state protette.",
        "deleting-backlinks-warning": "<strong>Attenziò:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Otre pàggene]] appondene o vonne 'a pàgene ca tu vue ccù scangìlle.",
        "rollback": "Annulle le cangiaminde",
+       "rollback-confirmation-confirm": "Pe piacere conferme:",
        "rollbacklink": "annulle 'u cangiaminde",
        "rollbacklinkcount": "annulle $1 {{PLURAL:$1|cangiamende|cangiaminde}}",
        "rollbacklinkcount-morethan": "annulle cchiù de $1 {{PLURAL:$1|cangiamende|cangiaminde}}",
        "logentry-rights-autopromote": "$1 ha state {{GENDER:$2|promosse}} automaticamende da $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|carecate}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|carecate}} 'na versiona nove de $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|carecate}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|turnate}} $3 a 'na versiona vecchie",
        "log-name-managetags": "Archivije d'a gestione de le tag",
        "log-description-managetags": "Sta pàgene elenghe le combite de gestione collegate a le [[Special:Tags|tags]]. L'archivije téne sulamende aziune fatte a màne da 'n'amministratore; le tag ponne essere ccrejate o scangellate da software de uicchi senze ca 'na vôsce avène scritte jndr'à l'archivije.",
        "logentry-managetags-create": "$1 {{GENDER:$2|ccrejate}} 'u tag \"$4\"",
        "log-action-filter-suppress-reblock": "Soppressione de l'utende da ri-blocche",
        "log-action-filter-upload-upload": "Carecamende nuève",
        "log-action-filter-upload-overwrite": "Recareche",
-       "authmanager-authplugin-setpass-failed-title": "Cangiamende d'a passuord fallite",
-       "authmanager-authplugin-setpass-bad-domain": "Dominie invalide.",
+       "log-action-filter-upload-revert": "Turnate",
        "authmanager-email-label": "Email",
        "authmanager-email-help": "Indirizze e-mail",
        "authmanager-realname-label": "Nome vere",
index fa121b4..a7d26b1 100644 (file)
                        "Infovarius",
                        "Cronolio",
                        "Nk88",
-                       "Edward Chernenko"
+                       "Edward Chernenko",
+                       "Romanko Mikhail",
+                       "Diralik"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "tog-hidepatrolled": "Скрывать патрулированные правки в списке свежих правок",
        "tog-newpageshidepatrolled": "Скрывать отпатрулированные страницы в списке новых страниц",
        "tog-hidecategorization": "Скрывать категоризацию страниц",
-       "tog-extendwatchlist": "Расширить список наблюдения, включая все изменения, а не только последние <small>(они могут быть сгруппированы настройкой на вкладке «[[Служебная:Настройки#mw-prefsection-rc|Свежие правки]]»)</small>",
+       "tog-extendwatchlist": "Расширить список наблюдения, включая все изменения, а не только последние",
        "tog-usenewrc": "Группировать изменения в свежих правках и списке наблюдения",
        "tog-numberheadings": "Автоматически нумеровать заголовки",
        "tog-editondblclick": "Править страницы по двойному щелчку",
        "tog-watchdeletion": "Добавлять в список наблюдения удалённые мной страницы и файлы",
        "tog-watchuploads": "Добавлять загруженные мною файлы в список наблюдения",
        "tog-watchrollback": "Добавлять страницы, где я выполнил откат, в мой список наблюдения",
-       "tog-minordefault": "По умолчанию помечать правки как малые",
+       "tog-minordefault": "Ð\9fо Ñ\83молÑ\87аниÑ\8e Ð¿Ð¾Ð¼ÐµÑ\87аÑ\82Ñ\8c Ð²Ñ\81е Ð¿Ñ\80авки ÐºÐ°Ðº Ð¼Ð°Ð»Ñ\8bе",
        "tog-previewontop": "Помещать предпросмотр перед окном редактирования",
        "tog-previewonfirst": "Показывать предпросмотр при переходе к редактированию",
        "tog-enotifwatchlistpages": "Уведомлять по электронной почте об изменениях страниц и файлов из списка наблюдения",
        "tog-norollbackdiff": "Не показывать разницу версий после выполнения отката",
        "tog-useeditwarning": "Предупреждать, когда я покидаю страницу с несохранёнными изменениями",
        "tog-prefershttps": "Всегда использовать защищённое соединение после представления системе",
+       "tog-showrollbackconfirmation": "Показывать подтверждение при нажатии ссылки для отката",
        "underline-always": "Всегда",
        "underline-never": "Никогда",
        "underline-default": "Использовать настройки браузера",
        "title-invalid-interwiki": "Запрашиваемое название страницы содержит интервики-ссылку, которая не может быть использована в названиях.",
        "title-invalid-talk-namespace": "Запрашиваемое название страницы ссылается на страницу обсуждения, которая не может существовать.",
        "title-invalid-characters": "Запрашиваемое название страницы содержит недопустимые символы: «$1».",
-       "title-invalid-relative": "Заголовок имеет относительный путь. Заголовки страниц с относительным путем (/,../) являются недействительными, так как они часто недоступны, когда обрабатываются браузером пользователя.",
+       "title-invalid-relative": "Заголовок имеет относительный путь. Заголовки страниц с относительным путём (/,../) являются недействительными, так как они часто недоступны, когда обрабатываются браузером пользователя.",
        "title-invalid-magic-tilde": "Запрашиваемый заголовок страницы содержит недопустимую последовательность тильды (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "Запрашиваемый заголовок страницы слишком длинен. Он должен быть не более $1 {{PLURAL:$1|1=байта|байт}} в кодировке UTF-8.",
        "title-invalid-leading-colon": "Запрашиваемое название страницы содержит недопустимое двоеточие в начале.",
        "titleprotected": "Создание страницы с таким заголовком было запрещено участником [[User:$1|$1]].\nУказана следующая причина: <em>$2</em>.",
        "filereadonlyerror": "Не удаётся изменить файл «$1», так как хранилище «$2» находится в режиме «только для чтения».\n\nСистемный администратор, заблокировавший базу, оставил следующее объяснение: «$3».",
        "invalidtitle": "Недопустимое название",
-       "invalidtitle-knownnamespace": "Недопустимый заголовок с пространством имен «$2» и текстом «$3»",
+       "invalidtitle-knownnamespace": "Недопустимый заголовок с пространством имён «$2» и текстом «$3»",
        "invalidtitle-unknownnamespace": "Недопустимый заголовок с неизвестным номером пространства $1 и текстом «$2»",
        "exception-nologin": "Вы не представились системе",
        "exception-nologin-text": "Необходимо представиться, чтобы иметь доступ к этой странице или действию.",
        "cannotloginnow-title": "Невозможно войти прямо сейчас",
        "cannotloginnow-text": "Нельзя войти во время использования $1.",
        "cannotcreateaccount-title": "Невозможно создать учётные записи",
-       "cannotcreateaccount-text": "Прямое создание учетных записей не включено в этой вики.",
+       "cannotcreateaccount-text": "Прямое создание учётных записей не включено в этой вики.",
        "yourdomainname": "Ваш домен:",
        "password-change-forbidden": "Вы не можете изменить пароль в этой вики.",
        "externaldberror": "Произошла ошибка при аутентификации с помощью внешней базы данных или у вас недостаточно прав для внесения изменений в свою внешнюю учётную запись.",
        "createacct-email-ph": "Введите свой адрес электронной почты",
        "createacct-another-email-ph": "Введите адрес электронной почты",
        "createaccountmail": "Использовать сгенерированный случайным образом временный пароль и выслать его на указанный адрес электронной почты",
-       "createaccountmail-help": "Может использоваться, чтобы создать учетную запись для другого лица, не узнавая пароль.",
+       "createaccountmail-help": "Может использоваться, чтобы создать учётную запись для другого лица, не узнавая пароль.",
        "createacct-realname": "Настоящее имя (необязательно)",
        "createacct-reason": "Причина",
        "createacct-reason-ph": "Зачем вы создаёте другую учётную запись",
        "badretype": "Введённые вами пароли не совпадают.",
        "usernameinprogress": "Создание учётной записи для данного имени участника уже выполняется.\nПожалуйста, подождите.",
        "userexists": "Введённое имя участника уже используется.\nПожалуйста, выберите другое имя.",
+       "createacct-normalization": "Ваше имя участника будет исправлено на «$2» из-за технических ограничений.",
        "loginerror": "Ошибка опознавания участника",
        "createacct-error": "Ошибка создания учётной записи",
        "createaccounterror": "Невозможно создать учётную запись: $1",
        "nosuchuser": "Участника с именем «$1» не существует.\nИмена участников чувствительны к регистру букв.\nПроверьте правильность написания имени или [[Special:CreateAccount|создайте новую учётную запись]].",
        "nosuchusershort": "Не существует участника с именем «$1». Проверьте написание имени.",
        "nouserspecified": "Вы должны указать имя участника.",
-       "login-userblocked": "Участник заблокирован. Вход в систему запрещен.",
+       "login-userblocked": "Участник заблокирован. Вход в систему запрещён.",
        "wrongpassword": "Введены неверные имя участника или пароль.\nПопробуйте ещё раз.",
        "wrongpasswordempty": "Пожалуйста, введите непустой пароль.",
        "passwordtooshort": "Пароль должен состоять не менее, чем из $1 {{PLURAL:$1|символа|символов}}.",
        "histfirst": "старейшие",
        "histlast": "новейшие",
        "historysize": "($1 {{PLURAL:$1|байт|байта|байт}})",
-       "historyempty": "(пусто)",
+       "historyempty": "пусто",
        "history-feed-title": "История изменений",
        "history-feed-description": "История изменений этой страницы в вики",
        "history-feed-item-nocomment": "$1 в $2",
        "revdelete-selected-text": "{{PLURAL:$1|Выбранная версия|Выбранные версии}} [[:$2]]:",
        "revdelete-selected-file": "{{PLURAL:$1|Выбранная версия файла|Выбранные версии файла}} [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|1=Выбранная запись|Выбранные записи}} журнала:",
-       "revdelete-text-text": "Удалённые версии будут по-прежнему видны в истории страницы, но определенные части их содержимого будут недоступны для участников.",
-       "revdelete-text-file": "Удалённые версии файла будут по-прежнему видны в истории страницы, но определенные части их содержимого будут недоступны для участников.",
-       "logdelete-text": "Удалённые события будут по-прежнему видны в журналах, но определенные части их содержимого будут недоступны для участников.",
+       "revdelete-text-text": "Удалённые версии будут по-прежнему видны в истории страницы, но определённые части их содержимого будут недоступны для участников.",
+       "revdelete-text-file": "Удалённые версии файла будут по-прежнему видны в истории страницы, но определённые части их содержимого будут недоступны для участников.",
+       "logdelete-text": "Удалённые события будут по-прежнему видны в журналах, но определённые части их содержимого будут недоступны для участников.",
        "revdelete-text-others": "Другие администраторы по-прежнему будут иметь возможность доступа к скрытому содержимому и смогут восстановить его, если не установлены дополнительные ограничения.",
        "revdelete-confirm": "Пожалуйста, подтвердите, что вы действительно желаете совершить это действие, осознаёте последствия, делаете это в соответствии с [[{{MediaWiki:Policy-url}}|правилами]].",
        "revdelete-suppress-text": "Сокрытие может производиться <strong>только</strong> в следующих случаях:\n* потенциально клеветническая информация\n* неуместная личная информация\n*: <em>домашний адрес, номера телефонов, номер паспорта и т. д.</em>",
        "diff-multi-otherusers": "(не {{PLURAL:$1|показана $1 промежуточная версия|показаны $1 промежуточные версии|показано $1 промежуточных версий}} {{PLURAL:$2|$2 участника|$2 участников}})",
        "diff-multi-manyusers": "({{PLURAL:$1|не показана $1 промежуточная версия, сделанная|не показаны $1 промежуточные версии, сделанные|не показано $1 промежуточных версий, сделанных}} более чем {{PLURAL:$2|$2 участником|$2 участниками}})",
        "diff-paragraph-moved-tonew": "Параграф был перемещён. Нажмите, чтобы перейти к новому местоположению.",
-       "diff-paragraph-moved-toold": "Пункт был перемещен. Нажмите, чтобы перейти к старому местоположению.",
+       "diff-paragraph-moved-toold": "Пункт был перемещён. Нажмите, чтобы перейти к старому местоположению.",
        "difference-missing-revision": "Не {{PLURAL:$2|1=найдена|найдены}} {{PLURAL:$2|$2 версия|$2 версий|$2 версии|1=одна из версий}} для этого сравнения ($1).\n\nТакое обычно случается при переходе по устаревшей ссылке сравнения версий для страницы, которая была удалена.\nПодробности могут быть в [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале удалений].",
        "searchresults": "Результаты поиска",
        "search-filter-title-prefix": "Искать только на страницах, название которых начинается с «$1»",
        "right-reupload-own": "Перезапись файлов, загруженных тем же участником",
        "right-reupload-shared": "Замена файлов из общих хранилищ локальными",
        "right-upload_by_url": "Загрузка файлов с адреса URL",
-       "right-purge": "Очистка кэша страниц без подтверждения",
+       "right-purge": "Очистка кэша страницы",
        "right-autoconfirmed": "Обход ограничений скорости на IP-адрес",
        "right-bot": "Автоматический процесс",
        "right-nominornewtalk": "Малые правки на страницах обсуждений участников не создают для них уведомление о новом сообщении",
        "rcfilters-filter-newpages-label": "Создания страниц",
        "rcfilters-filter-newpages-description": "Правки, приводящие к созданию новых страниц.",
        "rcfilters-filter-categorization-label": "Изменения категорий",
-       "rcfilters-filter-categorization-description": "Записи о страницах, добавленных или удаленных из категорий.",
+       "rcfilters-filter-categorization-description": "Записи о страницах, добавленных или удалённых из категорий.",
        "rcfilters-filter-logactions-label": "Протоколируемые действия",
        "rcfilters-filter-logactions-description": "Административные действия, создания учётных записей, удаления страниц, загрузки файлов…",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Фильтр \"малые правки\" конфликтует с одним или несколькими фильтрами, поскольку некоторые типы правок не могут быть названы малыми. Конфликтные фильтры отмечены вверху, в области Активных фильтров.",
        "upload_directory_missing": "Директория для загрузок ($1) отсутствует и не может быть создана веб-сервером.",
        "upload_directory_read_only": "Веб-сервер не имеет прав записи в папку ($1), в которой предполагается хранить загружаемые файлы.",
        "uploaderror": "Ошибка загрузки файла",
-       "upload-recreate-warning": "<strong>Внимание: файл с таким именем был удален или переименован.</strong>\n\nНиже представлены журналы удалений и переименований этой страницы:",
+       "upload-recreate-warning": "<strong>Внимание: файл с таким именем был удалён или переименован.</strong>\n\nНиже представлены журналы удалений и переименований этой страницы:",
        "uploadtext": "Воспользуйтесь этой формой для загрузки файлов на сервер.\nЧтобы просмотреть ранее загруженные файлы, обратитесь к [[Special:FileList|списку загруженных файлов]]. Загрузка файлов также записывается в [[Special:Log/upload|журнал загрузок]]; данные об удалённых файлах можно найти в [[Special:Log/delete|журнале удалений]].\n\nДля включения файла в статью вы можете использовать строки вида:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code></strong> для вставки полной версии файла;\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|описание]]</nowiki></code></strong> для вставки слева от текста уменьшенной до 200 пикселей по ширине версии файла с выводом под ним указанного описания;\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> для вставки ссылки на файл, без отображения его содержимого на странице.",
        "upload-permitted": "{{PLURAL:$2|Разрешённый тип|Разрешённые типы}} файлов: $1.",
        "upload-preferred": "{{PLURAL:$2|Предпочтительный тип|Предпочтительные типы}} файлов: $1.",
        "apihelp-no-such-module": "Модуль «$1» не найден.",
        "apisandbox": "Песочница API",
        "apisandbox-jsonly": "Для использования API-песочницы требуется JavaScript.",
-       "apisandbox-api-disabled": "API отключен на этом сайте.",
+       "apisandbox-api-disabled": "API отключён на этом сайте.",
        "apisandbox-intro": "Используйте эту страницу для экспериментов с <strong>MediaWiki API</strong>.\nОбратитесь к документации API ([https://ru.wikipedia.org/w/api.php встроенной] или [[mw:API:Main page|внешней]]) для получения дополнительной информации об использовании API. Например, о том, [https://www.mediawiki.org/wiki/API#A_simple_example как получить содержание Заглавной страницы]. Выберите действие, чтобы увидеть другие примеры.\nОбратите внимание, что, хотя это и песочница, действия, выполненные на этой странице, могут внести изменения в вики.",
        "apisandbox-submit": "Сделать запрос",
        "apisandbox-reset": "Очистить",
        "deleting-backlinks-warning": "<strong>Предупреждение:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Другие страницы]] ссылаются на страницу, которую вы собираетесь удалить, или содержат её.",
        "deleting-subpages-warning": "<strong>Предупреждение:</strong> У страницы, которую вы собираетесь удалить, имеется [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1 подстраница|$1 подстраницы|$1 подстраниц|51=более 50 подстраниц}}]].",
        "rollback": "Откатить изменения",
+       "rollback-confirmation-confirm": "Пожалуйста, подтвердите:",
+       "rollback-confirmation-yes": "Откатить",
+       "rollback-confirmation-no": "Отмена",
        "rollbacklink": "откатить",
        "rollbacklinkcount": "откатить $1 {{PLURAL:$1|правку|правки|правок}}",
        "rollbacklinkcount-morethan": "откатить более $1 {{PLURAL:$1|правки|правок}}",
        "revertpage": "Откат правок [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) к версии [[User:$1|$1]]",
        "revertpage-nouser": "Откат правок (имя участника скрыто) к версии {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Откачены правки {{GENDER:$3|$1}}; возвращена последняя версия {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Откачены правки $1; возвращена последняя версия $2. [$3 Показать изменения]",
        "sessionfailure-title": "Ошибка сеанса",
        "sessionfailure": "Похоже, возникли проблемы с текущим сеансом работы;\nэто действие было отменено в целях предотвращения «захвата сеанса».\nПожалуйста, переотправьте форму.",
        "changecontentmodel": "Редактирование контентной модели страницы",
        "namespace": "Пространство имён:",
        "invert": "Обратить выбранное",
        "tooltip-invert": "Установите эту отметку, чтобы скрыть изменения на страницах, в пределах выбранного пространства имён (и связанных пространств имён, если указано)",
-       "tooltip-whatlinkshere-invert": "Установите этот флажок, чтобы Скрыть ссылки от страниц в выбранном пространстве имен.",
+       "tooltip-whatlinkshere-invert": "Установите этот флажок, чтобы скрыть ссылки от страниц в выбранном пространстве имён.",
        "namespace_association": "Связанное пространство",
        "tooltip-namespace_association": "Установите эту отметку, чтобы также включить пространство имён обсуждения (или предметное), связанное с выбранным пространством имён",
        "blanknamespace": "(Основное)",
        "mycontris": "Вклад",
        "anoncontribs": "Вклад",
        "contribsub2": "Вклад {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Для {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Не зарегистрировано учётной записи «$1».",
+       "negative-namespace-not-supported": "Пространства имён с отрицательными значениями не поддерживаются.",
        "nocontribs": "Изменений, соответствующих заданным условиям, не найдено.",
        "uctop": "текущая",
        "month": "С месяца (и ранее):",
        "ipb-confirm": "Подтвердить блокировку",
        "ipb-sitewide": "Во всём проекте",
        "ipb-partial": "Частичная",
+       "ipb-sitewide-help": "Каждая страница вики и все другие действия вклада.",
+       "ipb-partial-help": "Конкретные страницы или пространства имён.",
        "ipb-pages-label": "Страницы",
        "ipb-namespaces-label": "Пространства имён",
        "badipaddress": "IP-адрес записан в неправильном формате, или участника с таким именем не существует.",
        "interlanguage-link-title": "$1 — $2",
        "common.css": "/* Размещённый здесь CSS будет применяться ко всем темам оформления */",
        "print.css": "/* Размещённый здесь CSS будет применяться к версии для печати */",
-       "noscript.css": "/* Размещённый здесь CSS будет применяться для участников с отключенным JavaScript  */",
+       "noscript.css": "/* Размещённый здесь CSS будет применяться для участников с отключённым JavaScript  */",
        "group-autoconfirmed.css": "/* Размещённый здесь CSS будет применяться для автоподтверждённых участников */",
        "group-user.css": "/* Размещённый здесь CSS будет применяться только для зарегистрированных пользователей */",
        "group-bot.css": "/* Размещённый здесь CSS будет применяться только для ботов */",
        "confirmemail_invalidated": "Подтверждение адреса электронной почты отменено.",
        "invalidateemail": "Отмена подтверждения адреса электронной почты",
        "notificationemail_subject_changed": "Адрес электронной почты для {{SITENAME}} был изменён",
-       "notificationemail_subject_removed": "{{SITENAME}} зарегистрированный адрес электронной почты был удален",
-       "notificationemail_body_changed": "Кто-то (вероятно, вы) с IP-адреса $1,\nизменил адрес электронной почты учетной записи «$2» на «$3» на {{SITENAME}}.\n\nЕсли это были не вы, обратитесь к администратору сайта немедленно.",
+       "notificationemail_subject_removed": "{{SITENAME}} зарегистрированный адрес электронной почты был удалён",
+       "notificationemail_body_changed": "Кто-то (вероятно, вы) с IP-адреса $1,\nизменил адрес электронной почты учётной записи «$2» на «$3» на {{SITENAME}}.\n\nЕсли это были не вы, обратитесь к администратору сайта немедленно.",
        "notificationemail_body_removed": "Кто-то (вероятно, вы) с IP-адреса $1\nудалил адрес электронной почты учётной записи «$2» на {{SITENAME}}.\n\nЕсли это были не вы, обратитесь к администратору сайта немедленно.",
        "scarytranscludedisabled": "[Интервики-включение отключено]",
        "scarytranscludefailed": "[Ошибка обращения к шаблону $1]",
        "confirm-unwatch-top": "Удалить эту страницу из вашего списка наблюдения?",
        "confirm-rollback-button": "ОК",
        "confirm-rollback-top": "Откатить правки на этой странице?",
+       "confirm-rollback-bottom": "Это действие немедленно откатит выбранные изменения этой страницы.",
        "confirm-mcrrestore-title": "Восстановить версию",
        "confirm-mcrundo-title": "Отменить изменение",
        "mcrundofailed": "Отменить не удалось",
        "logentry-rights-autopromote": "$1 был{{GENDER:$2||а}} автоматически переведен{{GENDER:$2||а}} из $4 в $5",
        "logentry-upload-upload": "$1 загрузил{{GENDER:$2||а}} $3",
        "logentry-upload-overwrite": "$1 загрузил{{GENDER:$2||а}} новую версию $3",
-       "logentry-upload-revert": "$1 Ð·Ð°Ð³Ñ\80Ñ\83зил{{GENDER:$2||а}} $3",
+       "logentry-upload-revert": "$1 Ð¾Ñ\82каÑ\82ил{{GENDER:$2||а}} $3 Ðº Ñ\81Ñ\82аÑ\80ой Ð²ÐµÑ\80Ñ\81ии",
        "log-name-managetags": "Журнал управления метками",
        "log-description-managetags": "На этой странице перечислены задачи, связанные с управлением [[Special:Tags|метками]]. Журнал содержит только действия, выполненные администратором вручную. Метки могут быть созданы или удалены с помощью программного обеспечения вики без добавления записей в этот журнал.",
        "logentry-managetags-create": "$1 создал{{GENDER:$2||а}} метку «$4»",
        "expand_templates_generate_rawhtml": "Показать HTML",
        "expand_templates_preview": "Предпросмотр",
        "expand_templates_preview_fail_html": "<em>Так как {{SITENAME}} разрешает использовать чистый HTML, предварительный просмотр отключён в качестве меры предотвращения JavaScript-атак.</em>\n\n<strong>Если это добросовестная попытка редактирования, пожалуйста, попробуйте ещё раз.</strong>\nЕсли не получается повторная правка, попробуйте [[Special:UserLogout|завершить сеанс]] работы, заново представиться и проверить, что ваш браузер разрешает использовать cookies на этом сайте.",
-       "expand_templates_preview_fail_html_anon": "<em>Поскольку на сайте {{SITENAME}} включен «сырой» HTML, а вы не авторизовались, предварительный просмотр скрыт в качестве меры предосторожности против JavaScript-атак.</em>\n\n<strong>Если это правомерная попытка предварительного просмотра, пожалуйста, [[Special:UserLogin|войдите]] и попробуйте ещё раз.",
+       "expand_templates_preview_fail_html_anon": "<em>Поскольку на сайте {{SITENAME}} включён «сырой» HTML, а вы не авторизовались, предварительный просмотр скрыт в качестве меры предосторожности против JavaScript-атак.</em>\n\n<strong>Если это правомерная попытка предварительного просмотра, пожалуйста, [[Special:UserLogin|войдите]] и попробуйте ещё раз.",
        "expand_templates_input_missing": "Вы должны вставить хоть какой-то текст.",
        "pagelanguage": "Изменение языка страницы",
        "pagelang-name": "Страница",
        "log-action-filter-suppress-reblock": "Сокрытие пользователя через повторное блокирование",
        "log-action-filter-upload-upload": "Новая загрузка",
        "log-action-filter-upload-overwrite": "Повторно загрузить",
+       "log-action-filter-upload-revert": "Откатить",
        "authmanager-authn-not-in-progress": "Проверка подлинности не выполняется или данные сессии были утеряны. Пожалуйста, начните снова с самого начала.",
        "authmanager-authn-no-primary": "Предоставленные учётные данные не могут быть проверены на подлинность.",
        "authmanager-authn-no-local-user": "Предоставленные учётные данные не связаны ни с одним участником этой вики.",
-       "authmanager-authn-no-local-user-link": "Предоставленные учётные данные корректны, но не связаны ни с одни участником этой вики. Войдите с помощью какого-то другого способа или создайте новую учётную запись, и у вас появится возможность привязать свои предыдущие учётные данные к этой учетной записи.",
+       "authmanager-authn-no-local-user-link": "Предоставленные учётные данные корректны, но не связаны ни с одни участником этой вики. Войдите с помощью какого-то другого способа или создайте новую учётную запись, и у вас появится возможность привязать свои предыдущие учётные данные к этой учётной записи.",
        "authmanager-authn-autocreate-failed": "Автоматическое создание локальной учётной записи не удалось: $1",
        "authmanager-change-not-supported": "Предоставленные учётные данные не могут быть изменены, так как они не будут использованы.",
        "authmanager-create-disabled": "Создание учётных записей отключено.",
        "authmanager-create-no-primary": "Предоставленные учётные данные не могут быть использованы для создания учётной записи.",
        "authmanager-link-no-primary": "Предоставленные учётные данные не могут быть использованы для связывания учётных записей.",
        "authmanager-link-not-in-progress": "Связывание учётной записи не выполняется или данные сессии были утеряны. Пожалуйста, начните снова с самого начала.",
-       "authmanager-authplugin-setpass-failed-title": "Ошибка изменения пароля",
-       "authmanager-authplugin-setpass-failed-message": "Плагин аутентификации запрещает смену пароля.",
-       "authmanager-authplugin-create-fail": "Плагин аутентификации запрещает создание учётных записей.",
-       "authmanager-authplugin-setpass-denied": "Плагин аутентификации не позволяет изменять пароли.",
-       "authmanager-authplugin-setpass-bad-domain": "Неверный домен.",
        "authmanager-autocreate-noperm": "Автоматическое создание учётных записей не разрешено.",
        "authmanager-autocreate-exception": "Автоматическое создание учётной записи временно отключено из-за предыдущих ошибок.",
        "authmanager-userdoesnotexist": "Не зарегистрировано учётной записи «$1».",
        "cannotlink-no-provider-title": "Нет связываемых учётных записей",
        "cannotlink-no-provider": "Нет связываемых учётных записей.",
        "linkaccounts": "Связать учётные записи",
-       "linkaccounts-success-text": "Учетная запись была связана.",
+       "linkaccounts-success-text": "Учётная запись была связана.",
        "linkaccounts-submit": "Связать учётные записи",
        "unlinkaccounts": "Отвязать учётные записи",
-       "unlinkaccounts-success": "Учетная запись была отвязан.",
+       "unlinkaccounts-success": "Учётная запись была отвязан.",
        "authenticationdatachange-ignored": "Изменение данных для проверки подлинности не было обработано. Может быть, не был настроен ни один провайдер?",
        "userjsispublic": "Обратите внимание: подстраницы JavaScript не должны содержать конфиденциальные сведения, поскольку они доступны для просмотра другим участникам.",
        "userjsonispublic": "Обратите внимание: подстраницы JSON не должны содержать конфиденциальных данных, поскольку они доступны для просмотра другими участниками.",
        "gotointerwiki": "Покидаем {{grammar:accusative|{{SITENAME}}}}...",
        "gotointerwiki-invalid": "Указан некорректный заголовок.",
        "gotointerwiki-external": "Вы покидаете {{grammar:accusative|{{SITENAME}}}} для посещения стороннего сайта [[$2]].\n\n'''[$1 Перейти на $1]'''",
-       "undelete-cantedit": "Вы не можете восстановить эту страницу, поскольку у вас недостаточно прав для ее редактирования.",
-       "undelete-cantcreate": "Вы не можете восстановить эту страницу, поскольку она не существует, а у вас недостаточно прав для ее создания.",
+       "undelete-cantedit": "Вы не можете восстановить эту страницу, поскольку у вас недостаточно прав для её редактирования.",
+       "undelete-cantcreate": "Вы не можете восстановить эту страницу, поскольку она не существует, а у вас недостаточно прав для её создания.",
        "pagedata-title": "Данные страницы",
        "pagedata-text": "Эта страница предоставляет интерфейс к данным страниц. Пожалуйста, введите заголовок страницы в URL, используя синтаксис подстраниц.\n* Согласование содержимого применяется основываясь на заголовке Accept вашего клиента. Это означает, что данные страницы будут предоставлены в формате, предпочитаемом вашим клиентом.",
        "pagedata-not-acceptable": "Соответствующий формат не найден. Поддерживаемые MIME-типы: $1",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль должен быть короче $1 {{PLURAL:$1|символа|символов}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Пароль не может соответствовать {{PLURAL:$1|самому часто используемому паролю|какому-либо из $1 самых часто используемых паролей}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль не может соответствовать какому-либо из 100 000 самых часто используемых паролей.",
+       "passwordpolicies-policyflag-forcechange": "необходимо изменить при входе",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "предложить изменение при входе",
        "easydeflate-invaliddeflate": "Предоставленное содержимое не спущено надлежащим образом",
-       "unprotected-js": "По соображениям безопасности JavaScript нельзя загружать с незащищенных страниц. Пожалуйста, создавайте скрипты только в пространстве имён MediaWiki: или как подстраницы участника."
+       "unprotected-js": "По соображениям безопасности JavaScript нельзя загружать с незащищённых страниц. Пожалуйста, создавайте скрипты только в пространстве имён MediaWiki: или как подстраницы участника."
 }
index d5e5473..fb18ded 100644 (file)
        "view": "Видіти",
        "view-foreign": "Видіти на $1",
        "edit": "Едітовати",
+       "edit-local": "Едітовати локальный опис",
        "create": "Створити",
+       "create-local": "Придати локальный опис",
        "delete": "Вымазати",
        "undelete_short": "Обновити $1 {{PLURAL:$1|верзію|верзії|верзії}}",
        "viewdeleted_short": "Видїти {{PLURAL:$1|змазанов едітаціёв|$1 змазаны едітації|$1 змазаных едітацій}}",
        "jumptonavigation": "навіґація",
        "jumptosearch": "Найти",
        "view-pool-error": "Перебачте, серверы суть теперь переладованы.\nТоту сторінку собі теперь пoзерать много хоснователїв.\nПросиме Вас, почекайте і спробуйте доступность пізнїше.\n\n$1",
+       "generic-pool-error": "Перебачте, серверы суть теперь переладованы.\nТоту сторінку собі теперь пoзерать много хоснователїв.\nПросиме Вас, почекайте і спробуйте доступность пізнїше.",
        "pool-timeout": "Час скінчіня чекать про замок",
        "pool-queuefull": "Фронта є повна",
        "pool-errorunknown": "Незнама хыба",
        "ns-specialprotected": "Шпеціалны сторінкы не є можне едітовати.",
        "titleprotected": "Створїня сторінкы з таков назвов было заборонене хоснователём [[User:$1|$1]] з причінов: <em>$2</em>.",
        "filereadonlyerror": "Не годно змінити файл „$1“, бо архів файлів „$2“ є теперь лем на чітаня.\n\nАдміністратор сервера, котрый архів заблоковав, додав тото пояснїня: „''$3''“.",
+       "invalidtitle": "Неприпустна назва",
        "invalidtitle-knownnamespace": "Непряавилна назва в просторї назв „$2“ і текстом „$3“",
        "invalidtitle-unknownnamespace": "Неправилна назва з незнамым чіслом простору назв $1 і текстом „$2“",
        "exception-nologin": "Не сьте приголошеный(а)",
        "resetpass_submit": "Наставити гесло і приголосити ся",
        "changepassword-success": "Ваше гесло было змінено!",
        "changepassword-throttled": "Зробили сьте дуже много спроб о приголошіня.\nПросиме Вас, почекайте $1 перед далшов спробов.",
+       "botpasswords-label-create": "Створити",
+       "botpasswords-label-update": "Обновити",
+       "botpasswords-label-cancel": "Зрушыти",
+       "botpasswords-label-delete": "Вымазати",
        "resetpass_forbidden": "Гесла не є можне змінити",
        "resetpass_forbidden-reason": "Гесла не є можне змінити: $1",
        "resetpass-no-info": "Ку тій сторінцї мають прямый приступ лем приголошены хоснователї.",
        "action-createpage": "створити тоту сторінку",
        "action-createtalk": "створити тоту діскузну сторінку",
        "action-createaccount": "Вытворїня того конта хоснователя",
+       "action-history": "зобразити історію той сторінкы",
        "action-minoredit": "означіти тото едітованя як мале",
        "action-move": "Переменовати тоту сторінку",
        "action-move-subpages": "переменованя той сторінкы зо вшыткыма єй підсторінками",
        "action-upload_by_url": "наладовати тот файл з URL адресы",
        "action-writeapi": "хосновати API про писаня",
        "action-delete": "Вымазати тоту сторінку",
-       "action-deleterevision": "вымазати тоту ревізію сторінкы",
-       "action-deletedhistory": "зобразити історію змазаных ревізій той сторінкы",
+       "action-deleterevision": "вымазаня ревізій",
+       "action-deletedhistory": "зобразити історію змазаных ревізій сторінкы",
+       "action-deletedtext": "зобразити змазаны тексты ревізії",
        "action-browsearchive": "глядати змазаны сторінкы",
        "action-undelete": "обновити тоту сторінку",
-       "action-suppressrevision": "Ñ\81конÑ\82Ñ\80олÑ\91ваÑ\82и Ñ\96 Ð¾Ð±Ð½Ð¾Ð²Ð¸Ñ\82и Ñ\82оÑ\82Ñ\83 Ñ\81Ñ\85ованÑ\83 Ñ\80евÑ\96зÑ\96Ñ\8e",
+       "action-suppressrevision": "Ñ\81конÑ\82Ñ\80олÑ\91ваÑ\82и Ñ\96 Ð¾Ð±Ð½Ð¾Ð²Ð¸Ñ\82и Ñ\81Ñ\85ованÑ\8b Ñ\80евÑ\96зÑ\96Ñ\97",
        "action-suppressionlog": "перегляд того пріватного лоґу",
        "action-block": "блокованя того хоснователя",
        "action-protect": "змінити рівень охраны той сторінкы",
        "action-rollback": "швыдко вернути управы послїднёго хоснователя едітуючого дану сторінку",
-       "action-import": "Ñ\96мпоÑ\80Ñ\82 Ñ\82ой Ñ\81Ñ\82оÑ\80Ñ\96нкÑ\8b з іншой вікі",
-       "action-importupload": "Ñ\96мпоÑ\80Ñ\82 Ñ\82ой Ñ\81Ñ\82оÑ\80Ñ\96нкÑ\8b Ð· файлу",
+       "action-import": "Ñ\96мпоÑ\80Ñ\82 Ñ\81Ñ\82оÑ\80Ñ\96нок з іншой вікі",
+       "action-importupload": "Ñ\96мпоÑ\80Ñ\82 Ñ\81Ñ\82оÑ\80Ñ\96нок Ð· Ð½Ð°Ð»Ð°Ð´Ð¾Ð²Ð°Ð½Ñ\8f файлу",
        "action-patrol": "позначіти чуджі едітованя як перевірены",
        "action-autopatrol": "означіти властных едітовань як патролованы",
        "action-unwatchedpages": "зображіня списку неслїдованых сторінок",
        "action-viewmywatchlist": "перезерати ваш список слїдованых сторінок",
        "action-viewmyprivateinfo": "перезерати вашы пріватны даны",
        "action-editmyprivateinfo": "едітовати вашы пріватны інформації",
+       "action-editcontentmodel": "едітовати модел обсягу сторінкы",
        "nchanges": "$1 {{PLURAL:$1|зміна|зміны|змін}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|од остатнёй навщівы}}",
        "enhancedrc-history": "історія",
        "uploaderror": "Під час ладованя ся притрафила хыба",
        "upload-recreate-warning": "'''Увага: Файл з тов назвов быв оперед змазаный ці переменованый.'''\n\nТу є про перегляд зображеный список мазаня і переменованя той сторінкы:",
        "uploadtext": "Ниже даный формуларь служыть на наладовованя файлів. Уж наладованы файлы собі можете перезерати і глядати помочов [[Special:FileList|списку наладованых файлів]], кажде наладованя ся тыж зазначує до [[Special:Log/upload|книгы наладованя]], змазаня суть в [[Special:Log/delete|книзї змазаных сторінок]].\n\nПро вложіня образчіка до сторінкы хоснуйте єден із слїдуючіх способів запису:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Файл.jpg]]</nowiki></code>''' до сторінкы вложыть цїлый образок,\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Файл.png|thumb|left|Попис]]</nowiki></code>''' вложыть нагляд в рамику зарівнанім на лівый бік, з пописом „Попис“,\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Файл.ogg]]</nowiki></code>''' вложыть дірект одказ на файл, без того жебы ся зобразив на сторінцї.",
-       "upload-permitted": "Дозволены тіпы  файлів: $1.",
-       "upload-preferred": "Преферованы тіпы файлів: $1",
-       "upload-prohibited": "Заказаны тіпы файлів: $1.",
+       "upload-permitted": "{{PLURAL:$2|Дозволеный формат|Дозволены форматы}} файлів: $1.",
+       "upload-preferred": "{{PLURAL:$2|Преферованый формат|Преферованы форматы}} файлів: $1.",
+       "upload-prohibited": "{{PLURAL:$2|Заказаный формат|Заказаны форматы}} файлів: $1.",
        "uploadlogpage": "Лоґ наладованых файлів",
        "uploadlogpagetext": "Ниже найдете список найновшых файлів. Смотьте [[Special:NewFiles|ґалерію новых образків]] про веце візуалного нагляду.",
        "filename": "Назва файлу:",
        "largefileserver": "Розмір файлу є векшый як ліміт наставленый на сервері.",
        "emptyfile": "Файл, котрый сьте вложыли ся видить быти порожнїй. Могла то запричінити хыба в назві файлу. Просиме, перевірте ці сьте справды хотїли вложыти тот файл.",
        "windows-nonascii-filename": "Тота вікі не підпорує назвы файлів з шпеціалныма сімболами.",
-       "fileexists": "Файл з тов назвов уж екзістує, просиме посмотьте ся на <strong>[[:$1]]</strong>, покы не знаєте напевно, ці хочете тот файл нагородити.\n[[$1|thumb]]",
+       "fileexists": "Файл з тов назвов уж екзістує, просиме сконтролёвати <strong>[[:$1]]</strong>, покы не знаєте напевно, ці хочете тот файл нагородити.\n[[$1|thumb]]",
        "filepageexists": "Пописова сторінка про файл з тов назвов уж была на  <strong>[[:$1]]</strong> створена, але одповідаючій файл дотеперь не екзістує.\nЗгорнутя, котре ту зазначіте, ся на пописовій сторінцї не зобразить.\nКідь там хочете своє згорнутя зобразити, будете мусити дану сторінку едітовати мануално. [[$1|thumb]]",
        "fileexists-extension": "Уже екзістує файл з подобным іменом: [[$2|thumb]]\n* Назва наладованого файлу: <strong>[[:$1]]</strong>\n* Назва екзістуючого файлу: <strong>[[:$2]]</strong>\nВыберте іншу назву.",
        "fileexists-thumbnail-yes": "Тот файл є асі образчік в зменшеній великости ''(нагляд)''. [[$1|thumb]]\nПеревірте файл <strong>[[:$1]]</strong>.\nКідь є вказаный файл векшый, але інакше єднакый, не треба окремо наладовати ёго зменшену верзію.",
        "upload-too-many-redirects": "URL обсягує барз велё напрямлінь",
        "upload-http-error": "Стала ся хыба HTTP: $1",
        "upload-copy-upload-invalid-domain": "Наладовованя копірованём негодно з той домены.",
+       "upload-dialog-title": "Наладовати файл",
+       "upload-dialog-button-cancel": "Зрушыти",
+       "upload-dialog-button-back": "Назад",
+       "upload-dialog-button-done": "Готово",
+       "upload-dialog-button-save": "Уложыти",
+       "upload-dialog-button-upload": "Наладовати",
+       "upload-form-label-infoform-title": "Детайлы",
+       "upload-form-label-infoform-name": "Назва",
+       "upload-form-label-infoform-name-tooltip": "Куртый унікатный тітулок того файлу, котрый буде служыти як ёго назва. Можете хосновати обычайный текст і з павзами. Не вказуйте росшырїня файлу.",
+       "upload-form-label-infoform-description": "Опис",
+       "upload-form-label-infoform-description-tooltip": "Курто попиште вшыткы важны інформації о дїли.\nУ фотоґрафіях спомяните головны зображены обєкты, місце і окацію.",
+       "upload-form-label-usage-title": "Хоснованя",
+       "upload-form-label-infoform-categories": "Катеґорії",
+       "upload-form-label-infoform-date": "Датум",
        "backend-fail-stream": "Не вдало ся транслёвати файл $1.",
        "backend-fail-backup": "Не вдало ся створити резервну копію файлу $1.",
        "backend-fail-notexists": "Файл $1 не існує.",
index daec2ac..fbbfed5 100644 (file)
        "userlogout": "Тахсыы",
        "notloggedin": "Ааккын эппэтиҥ",
        "userlogin-noaccount": "Бэлиэтэнэ иликкин дуо?",
-       "userlogin-joinproject": "{{SITENAME}} Ñ\81иÑ\82им-Ñ\81иÑ\80гÑ\8d ÐºÐ¸Ð¸Ñ\80ии",
+       "userlogin-joinproject": "{{SITENAME}} Ñ\81иÑ\82им-Ñ\81иÑ\80гÑ\8d Ð±Ñ\8dлиÑ\8dÑ\82Ñ\8dнии",
        "createaccount": "Бэлиэтэнии",
        "userlogin-resetpassword-link": "Аһарык тылгын санаттараҕын дуо?",
        "userlogin-helplink2": "Киирэргэ көмө",
        "publishchanges": "Бигэргэт",
        "savearticle-start": "Сирэйи бигэргэт...",
        "savechanges-start": "Уларытыылары бигэргэтии...",
+       "publishpage-start": "Сирэйи бэчээттииргэ...",
+       "publishchanges-start": "Уларытыылары бэчээттииргэ...",
        "preview": "Холоон көрүү",
        "showpreview": "Уларытыах иннинэ көрүү",
        "showdiff": "Уларытыылар",
        "subject-preview": "Аата маннык көстүөҕэ:",
        "previewerrortext": "Уларытыыгын бигэргэтиэх иннинэ көрдөрөргө алҕас таҕыста.",
        "blockedtitle": "Кыттааччы уларытар кыаҕа быһылынна",
-       "blockedtext": "'''Эн Ð°Ð°Ñ\82Ñ\8bÒ¥ Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 IP-аадÑ\8bÑ\80Ñ\8bÒ»Ñ\8bÒ¥ Ð±Ð¾Ð±Ñ\83лÑ\83ннÑ\83лаÑ\80.'''\n\nÐ\91оппÑ\83Ñ\82 ÐºÐ¸Ò»Ð¸ $1.\nТөÑ\80Ò¯Ó©Ñ\82Ñ\8d: ''«$2»''.\n\n*Ð\91обÑ\83ллÑ\83бÑ\83Ñ\82: $8\n*Ð\91обÑ\83Ñ\83 Ð±Ð¾Ð»Ð´Ñ\8cоÒ\95о: $6\n*Ð\91обÑ\83лÑ\83нна: $7\n\nЭн $1 Ð´Ð¸Ñ\8dн ÐºÐ¸Ò»Ð¸Ñ\8dÑ\85Ñ\8d Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ð°Ñ\82Ñ\8bн [[{{MediaWiki:Grouppage-sysop}}|админиÑ\81Ñ\82Ñ\80ааÑ\82аÑ\80га]] Ñ\81Ñ\83Ñ\80Ñ\83йан Ð±Ñ\8bһааÑ\80Ñ\81Ñ\8bаÑ\85Ñ\85Ñ\8bн Ñ\81өп.\nÐ\91олÒ\95ой, Ó©Ñ\81кө Ñ\80егиÑ\81Ñ\82Ñ\80аÑ\86иÑ\8fламмаÑ\82аÑ\85 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна, Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ñ\8dл. Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bÑ\81кÑ\8bн [[Special:Preferences|бигÑ\8dÑ\80гÑ\8dппÑ\8dÑ\82Ñ\8dÑ\85]] Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна, Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ñ\81Ñ\83Ñ\80Ñ\83к Ñ\81Ñ\83Ñ\80Ñ\83йаÑ\80Ñ\8bÒ¥ Ð±Ð¾Ð±Ñ\83ллÑ\83бÑ\83Ñ\82 Ð±Ñ\83оллаÒ\95Ñ\8bна Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80ааÑ\82аÑ\80га Ñ\81Ñ\83Ñ\80Ñ\83йаÑ\80 ÐºÑ\8bаÒ\95Ñ\8bÒ¥ Ñ\81Ñ\83оÑ\85.\nЭн IP-аадÑ\8bÑ\80Ñ\8bÒ»Ñ\8bÒ¥ â\80\94 $3, Ð±Ð¾Ð±Ñ\83Ñ\83 Ð½Ò¯Ó©Ð¼Ñ\8dÑ\80Ñ\8d â\80\94 #$5.\nÐ\9eнÑ\83 Ñ\81Ñ\83Ñ\80Ñ\83ккаÑ\80 ÐºÐ¸Ð»Ð»Ñ\8dÑ\80Ñ\8dÑ\8dр.",
+       "blockedtext": "'''Эн Ð±Ñ\8dлиÑ\8d-ааÑ\82Ñ\8bÒ¥ Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 IP-аадÑ\8bÑ\80Ñ\8bÒ»Ñ\8bÒ¥ Ð±Ð¾Ð±Ñ\83ллÑ\83бÑ\83Ñ\82Ñ\82аÑ\80.'''\n\nÐ\91оппÑ\83Ñ\82 Ð´Ñ\8cаһабÑ\8bл - $1.\nТөÑ\80Ò¯Ó©Ñ\82үн Ð¼Ð°Ð½Ñ\8b Ñ\8bйÑ\8bбÑ\8bÑ\82: <em>$2</em>.\n\n*Ð\91обÑ\83ллÑ\83бÑ\83Ñ\82 ÐºÒ¯Ð½Ñ\8d\8bйа: $8\n*Ð\91обÑ\83Ñ\83 Ð±Ð¾Ð»Ð´Ñ\8cоÒ\95о: $6\n*Ð\91обÑ\83Ñ\83 Ñ\81оÑ\80Ñ\83га: $7\n\nЭн $1 Ð´Ð¸Ñ\8dн ÐºÐ¸Ò»Ð¸Ñ\8dÑ\85Ñ\8d Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ð°Ñ\82Ñ\8bн [[{{MediaWiki:Grouppage-sysop}}|дÑ\8cаһабÑ\8bлга]] Ñ\81Ñ\83Ñ\80Ñ\83йан, Ð±Ñ\8bһааÑ\80Ñ\81Ñ\8bаÑ\85Ñ\85Ñ\8bн Ñ\81өп.\nÐ\91олÒ\95ой, Ó©Ñ\81көÑ\82Ó© Ñ\8dл. Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bÑ\81кÑ\8bн [[Special:Preferences|Ñ\82Ñ\83Ñ\80Ñ\83оÑ\80Ñ\83Ñ\83лаÑ\80гаÑ\80]] Ñ\8dппÑ\8dÑ\82Ñ\8dÑ\85 Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ð±Ð¸Ð³Ñ\8dÑ\80гÑ\8dппÑ\8dÑ\82Ñ\8dÑ\85 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна, Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ð±Ð¾Ð¿Ð¿Ñ\83Ñ\82 ÐºÐ¸Ò»Ð¸ Ñ\81Ñ\83Ñ\80Ñ\83к Ñ\81Ñ\83Ñ\80Ñ\83йаÑ\80гÑ\8bн Ð±Ð¾Ð¿Ð¿Ñ\83Ñ\82 Ð±Ñ\83оллаÒ\95Ñ\8bна, \"{{int:emailuser}}\" Ñ\84Ñ\83нкÑ\86иÑ\8fнÑ\8b Ñ\82Ñ\83һанаÑ\80 ÐºÑ\8bаÒ\95Ñ\8bÒ¥ Ñ\81Ñ\83оÑ\85.\nЭн IP-аадÑ\8bÑ\80Ñ\8bÒ»Ñ\8bÒ¥ â\80\94 $3, Ð±Ð¾Ð±Ñ\83Ñ\83 Ð½Ò¯Ó©Ð¼Ñ\8dÑ\80Ñ\8d â\80\94 #$5.\nÐ\9cанÑ\8b Ñ\81Ñ\83Ñ\80Ñ\83ккаÑ\80 Ñ\8bйаар.",
        "autoblockedtext": "Эн IP-аадырыскын ханнык эрэ бу бырайыакка кыттара бобуллубут киһи туһана сылдьыбыт, онон бу IP-аадырыс бобуулаах. Боппут администраатар ($1) ол төрүөтүн маннык суруйбут:\n\n:''$2''\n\n*Бобуллубут: $8\n*Бобуу болдьоҕо: $6\n*Бобулунна: $7\n\nЭн $1 диэн киһиэхэ эбэтэр атын [[{{MediaWiki:Grouppage-sysop}}|администраатарга]] сурук суруйан быһаарсыаххын сөп.\n\nБолҕой, өскө регистрацияламматах буоллаххына, эбэтэр эл. аадырыскын [[Special:Preferences|бигэргэппэтэх]]  буоллаххына, эбэтэр сурук суруйарыҥ бобуллубут буоллаҕына администраатарга суруйар кыаҕыҥ суох.\n\nIP-аадырыһыҥ $3, бобуу нүөмэрэ — #$5.\nОну суруккар киллэрээр.",
        "systemblockedtext": "Бэлиэ-ааккын эбэтэр IP-аадырыскын MediaWiki хааччахтаабыт.\nЫйыллыбыт төрүөтэ:\n\n:<em>$2</em>\n\n* Хааччах саҕаланыыта: $8\n* Хааччах уһуллуута: $6\n* Бүөлээһин соруга: $7\n\nЭн билиҥҥи IP-аадырыһыҥ $3.\nБыһаарсар буоллаххына, бу сибидиэнньэлэри этээр дуу.",
        "blockednoreason": "биир да биричиинэ сөп түбэспэт",
        "accmailtext": "[[User talk:$1|$1]] кыттааччыга түбэспиччэ бэлиэлэртэн оҥоһуллубут аһарык тыл бу аадырыска $2 ыытылынна.\nТиһиккэ бэлиэтэнэн баран аһарыккын ''[[Special:ChangePassword|уларытыаххын]]'' сөп.",
        "newarticle": "(Саҥа ыстатыйа)",
        "newarticletext": "Эн суох сирэйгэ киирэ сатаатыҥ.\nМаннык ааттаах саҥа ыстатыйаны оҥорор буоллаххына, аллара баар түннүккэ суруй\n(сиһ. [$1 көмөнү] көрүөххүн сөп).\nӨскө манна сыыһа киирбит буоллаххына интэриниэтиҥ бырагыраамматын \"төнүн\" диэххин сөп.",
-       "anontalkpagetext": "----\n<em>Бу аатын эппэтэх, бэлиэтэнэ илик эбэтэр бэлиэтэниэн баҕарбат кыттааччы сирэйэ.</em>\nОл иһин кинини чопчулаары IP-аадырыһын туттабыт.\nБу аадырыһы атын кыттааччылар эмиэ туһаныахтарын сөп.\nӨскөтө Эн ааккын эппэтэх кыттааччы Эйиэхэ туһуламматах суругу туттум дии саныыр буоллаххына, бука диэн, [[Special:CreateAccount|бэлиэтэн]] биитэр [[Special:UserLogin|урут бэлиэтэммит ааккынан киир]]. Оччоҕо булкуур тахсыа суоҕа.",
+       "anontalkpagetext": "----\n<em>Бу аатын эппэтэх, бэлиэтэнэ илик эбэтэр бэлиэтэниэн баҕарбат кыттааччы сирэйэ.</em>\nОл иһин кинини чопчулаары IP-аадырыһын туттабыт.\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}}|ааты атын сирэйдэргэ көрдөөн көрүөххүн]] сөп,\nэбэтэр <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} сурунаалларга манна сыһыаннаах суруктары булуоххун сөп].</span> Бу сирэйи айар кыаҕыҥ суох.",
        "missing-revision": "«{{FULLPAGENAME}}» сирэй $1 барыла суох.\n\nМаннык үксүн хайыы-үйэ сотуллубут билэҕэ эргэрбит сигэнэн бардахха буолааччы.\nСиһилии баҕар [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} сотуу сурунаалыгар] баара буолуо.",
        "editpage-invalidcontentmodel-text": "«$1» иһинээҕитин мадьыала өйөммөт эбит.",
        "editpage-notsupportedcontentformat-title": "Иһинээҕитин формаата өйөммөт эбит",
        "editpage-notsupportedcontentformat-text": "$2 иһинээҕитин модела $1 иһинээҕитин формаатын өйөөбөт эбит.",
+       "slot-name-main": "Сүрүн",
        "content-model-wikitext": "биики-тиэкис",
        "content-model-text": "көннөрү тиэкис",
        "content-model-javascript": "JavaScript",
        "diff-paragraph-moved-toold": "Параграф көһөрүллүбүт. Баттаан урукку сиригэр көс.",
        "difference-missing-revision": "$2 барыл бу тэҥнээһиҥҥэ ($1) көстүбэтэ.\n\nБу үксүн хайыы-үйэ сотуллубут сирэйи кытта тэҥнээри эргэрбит сигэнэн кэллэххэ баар буолааччы.\nСиһилии баҕар [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} сотуу сурунаалыгар] баара буолуо.",
        "searchresults": "Булулунна",
+       "search-filter-title-prefix-reset": "Сирэйдэри барытын көрдөөһүн",
        "searchresults-title": "Көрдөөһүн түмүгэ \"$1\"",
        "titlematches": "Ыстатыйалар ааттара хоһулаһар",
        "textmatches": "Ыстатыйалар истэрэ хатыланар",
        "prefs-watchlist-edits": "Кэтээбил тиһигэр уларытыы көстүүтүн муҥутуур ахсаана:",
        "prefs-watchlist-edits-max": "Улааппыта: 1000",
        "prefs-watchlist-token": "Кэтэбил тиһигин бэлиэтэ (токен):",
+       "prefs-watchlist-managetokens": "Токеннары салайыы",
        "prefs-misc": "Атын туруоруулар",
        "prefs-resetpass": "Кирии тылы уларытыы",
        "prefs-changeemail": "Аадырыһы уларытыы уонна сотуу",
        "prefs-dateformat": "Күн-дьыл көрүҥэ (формаата)",
        "prefs-timeoffset": "Кэм уратыта",
        "prefs-advancedediting": "Сүрүн туруоруулар",
+       "prefs-developertools": "Оҥорооччу тэриллэрэ",
        "prefs-editor": "Эрэдээктэр",
        "prefs-preview": "Инники көрүү",
        "prefs-advancedrc": "Дириҥэтиллибит туруоруулар",
        "prefs-advancedwatchlist": "Дириҥэтиллибит туруоруулар",
        "prefs-displayrc": "Туруоруулары көрдөр",
        "prefs-displaywatchlist": "Көстүүтүн туруоруулара",
+       "prefs-changesrc": "Көстүбүт уларытыылар",
+       "prefs-changeswatchlist": "Көрдөр;ллэр уларытыылар",
        "prefs-tokenwatchlist": "Токен",
        "prefs-diffs": "Уратылара",
        "prefs-help-prefershttps": "Аныгыскы киириигэр үлэлиир буолуо.",
        "recentchangeslinked-feed": "Сигэнэр уларытыылар",
        "recentchangeslinked-toolbox": "Сигэнэр уларытыылар",
        "recentchangeslinked-title": "\"$1\" кытта сибээстээх уларытыылар",
-       "recentchangeslinked-summary": "Сирэй аатын суруйдаххына киниэхэ эбэтэр кини сигэнэр сирэйдэрин уларытыы көстүөҕэ. (Категорияҕа киирэрэ сирэйдэри көрөргө маннык суруй: Category:Категория аата). [[Special:Watchlist|Кэтиир сирэйдэриҥ]] уларыйыыта <strong>модьу бичигинэн</strong> бэлиэтэммит.",
+       "recentchangeslinked-summary": "Сирэй аатын суруйдаххына киниэхэ эбэтэр кини сигэнэр сирэйдэрин уларытыы көстүөҕэ. (Категорияҕа киирэр сирэйдэри көрөргө маннык суруй: {{ns:category}}:Категория аата). [[Special:Watchlist|Кэтиир сирэйдэриҥ]] уларыйыыта <strong>модьу бичигинэн</strong> бэлиэтэнэр.",
        "recentchangeslinked-page": "Сирэй аата:",
        "recentchangeslinked-to": "Төттөрүтүн, ыйыллыбыт сирэйгэ сигэнэр сирэйдэри көрдөр",
        "recentchanges-page-added-to-category": "[[:$1]] категорияҕа эбилиннэ",
        "filehist-filesize": "Билэ кээмэйэ",
        "filehist-comment": "Хос быһаарыы",
        "imagelinks": "Билэни туттуу",
-       "linkstoimage": "Бу билэҕэ маннык атын {{PLURAL:$1|сирэй сигэнэр|$1 сирэйдэр сигэнэллэр}}:",
-       "linkstoimage-more": "$1 {{PLURAL:$1|сирэйтэн|сирэйтэн}} элбэх сирэй бу билэҕэ сигэнэр.\nОнтон бу тиһиккэ {{PLURAL:$1|$1 эрэ сигэ көһүннэ|$1 сигэ эрэ көһүннэ}}.\nӨссө [[Special:WhatLinksHere/$2|толору тиһиги]] көрүөххүн сөп.",
-       "nolinkstoimage": "Атын сирэйдэр бу билэҕэ сигэммэттэр.",
+       "linkstoimage": "Бу билэни бу {{PLURAL:$1|сирэй туһанар|$1 сирэйдэр туһаналлар}}:",
+       "linkstoimage-more": "$1 {{PLURAL:$1|сирэйтэн|сирэйтэн}} элбэх сирэй бу билэни туһанар.\nБу испииһэккэ {{PLURAL:$1|$1 эрэ туһанар сирэй көрдөрүлүннэ|$1 эрэ туһанар сирэй көрдөрүлүннэ}}.\nЭбии [[Special:WhatLinksHere/$2|толору испииһэги]] көрүөххүн сөп.",
+       "nolinkstoimage": "Атын сирэйдэр бу билэни туһамматтар.",
        "morelinkstoimage": "Бу билэҕэ [[Special:WhatLinksHere/$1|атын сигэлэри]] көрөргө.",
        "linkstoimage-redirect": "$1 (утаарыы-билэ) $2",
        "duplicatesoffile": "Бу билэ {{PLURAL:$1|дубликаата манна көстөр|$1 дубликаата манна көстөллөр}} ([[Special:FileDuplicateSearch/$2|сиһилии]]):",
        "revertpage": "([[User talk:$2|Ырытыы]]) көннөрүүлэрэ: [[Special:Contributions/$2|$2]] бу торумҥа: [[User:$1|$1]] төннөрүлүннүлэр",
        "revertpage-nouser": "Аата кистэммит киһи уларытыылара суох оҥоһуллан, ыстатыйа бу киһи барылыгар төннөрүлүннэ: {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "{{GENDER:$3|$1}} көннөрүүтэ сотулунна; {{GENDER:$4|$2}} барылыгар төннөрүлүннэ.",
-       "rollback-success-notify": "$1 уларытыылара сотулуннулар; \n$2 тиһэх торумугар төннөрүлүннэ. [$3 Уларытыыны көрдөр]",
        "sessionfailure-title": "Сиэссийэ алҕаһа",
        "sessionfailure": "Арааһа туох эрэ сатаммата, дьайыыҥ оҥоһуллубата. Браузергар \"Төнүн\" тимэҕи баттаа уонна бу иннинээҕи сирэйгин иккистээн киллэрэн көр.",
        "changecontentmodel": "Сирэй ис тутулун киэбин уларытыы",
        "authmanager-create-no-primary": "Эппит сибидиэнньэҕин туһанан бэлиэтэнэр сатаммат эбит.",
        "authmanager-link-no-primary": "Эппит сибидиэнньэҕин туһанан бэлиэ ааттары холбуур сатаммат эбит.",
        "authmanager-link-not-in-progress": "Бэлиэ ааттары холбуур сатаммата эбэтэр сиэссийэ быстан хаалла. Саҥаттан хатылаан көр.",
-       "authmanager-authplugin-setpass-failed-title": "Аһарыгы уларытар табыллыбата",
-       "authmanager-authplugin-setpass-failed-message": "Аутентификация былаҕыына аһарыгы уларытары бобор.",
-       "authmanager-authplugin-create-fail": "Аутентификация былаҕыына бэлиэтэнэри бобор.",
-       "authmanager-authplugin-setpass-denied": "Аутентификация былаҕыына аһарыгы уларытары бобор.",
-       "authmanager-authplugin-setpass-bad-domain": "Алҕастаах домен.",
        "authmanager-autocreate-noperm": "Аптамаатынан бэлиэтэнии көҥүллэммэт.",
        "authmanager-autocreate-exception": "Аптамаатынан бэлиэтэнии урут тахсыбыт алҕастартан сылтаан араарыллыбыт.",
        "authmanager-userdoesnotexist": "Маннык аат «$1» суох.",
index 11e4303..f6a73cc 100644 (file)
@@ -20,7 +20,8 @@
                        "Fagunkoyel Hansdah",
                        "Subasmurmu",
                        "Amire80",
-                       "Dulal Kisku"
+                       "Dulal Kisku",
+                       "Rocky 734"
                ]
        },
        "tog-underline": "ᱡᱚᱱᱚᱲ ᱞᱟᱛᱟᱨᱨᱮ ᱫᱟᱜᱽ ᱩᱫᱩᱜᱽᱢᱮ:",
        "login-throttled": "ᱟᱢ ᱫᱚ ᱢᱤᱫᱜᱷᱟᱹᱲᱤ ᱞᱟᱦᱟᱨᱮ ᱟᱭᱢᱟ ᱫᱷᱟᱣ ᱵᱚᱞᱚᱜᱮᱢ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱠᱮᱫᱟ᱾ \nᱟᱨᱦᱚᱸ ᱠᱩᱨᱩᱢᱩᱴᱩᱭ ᱞᱟᱦᱟᱨᱮ ᱫᱟᱭᱟᱠᱟᱛᱮ $1 ᱛᱟᱸᱜᱤᱭᱢᱮ᱾",
        "login-abort-generic": "ᱟᱢᱟᱜ ᱵᱷᱤᱛᱨᱤ ᱵᱚᱠᱟᱜ ᱫᱚ ᱵᱟᱝ ᱦᱩᱭᱞᱮᱱᱟ - ᱵᱟᱫᱽᱱᱟ",
        "loginlanguagelabel": "ᱯᱟᱹᱨᱥᱤ: $1",
-       "pt-login": "á±µá±\9aá±\9eá±\9aá±\9c ᱫᱩᱣᱟᱹᱨ",
+       "pt-login": "á±µá±\9aá±\9eá±\9aá±± ᱫᱩᱣᱟᱹᱨ",
        "pt-login-button": "ᱵᱚᱞᱚᱜ ᱢᱮ",
        "pt-login-continue-button": "ᱞᱮᱛᱟᱲ ᱵᱚᱞᱚ ᱠᱚᱜᱼᱢᱮ",
        "pt-createaccount": "ᱮᱠᱟᱶᱩᱴ ᱛᱮᱭᱟᱨᱢᱮ",
        "histfirst": "ᱢᱟᱨᱮᱱᱟᱜ",
        "histlast": "ᱱᱟᱣᱟᱱᱟᱜ",
        "historysize": "({{PLURAL:$1 1 ᱵᱟᱭᱤᱴ $1 ᱵᱟᱭᱤᱴᱥ}})",
-       "historyempty": "(ᱠᱷᱟᱹᱞᱤ)",
+       "historyempty": "ᱠᱷᱟᱹᱞᱤ",
        "history-feed-title": "ᱥᱩᱫᱷᱨᱟᱹᱣ ᱱᱟᱜᱟᱢ",
        "history-feed-description": "ᱣᱤᱠᱤᱨᱮ ᱱᱤᱭᱟᱹ ᱥᱟᱦᱴᱟ ᱵᱚᱫᱚᱞ ᱨᱮᱱᱟᱜ ᱱᱟᱜᱟᱢ",
        "history-feed-item-nocomment": "$2 ᱨᱮ $1",
        "enhancedrc-history": "ᱱᱟᱜᱟᱢ",
        "recentchanges": "ᱨᱚᱠᱟ ᱵᱚᱫᱚᱞᱠᱚ",
        "recentchanges-legend": "ᱱᱟᱣᱟᱱᱟ ᱵᱚᱫᱚᱞ ᱛᱮᱭᱟᱜᱠᱚ",
-       "recentchanges-summary": "á±±á±\9aá±£á±\9f á±¥á±\9fᱦᱴá±\9fᱨᱮ á±©á±­á± á±¤ á±¨á±®á±­á±\9fá±\9c á±¡á±\9aá±\9bá±\9a á± á±·á±\9aá±± á±±á±\9fá±£á±\9f á±µá±\9aᱫá±\9aá±\9eá± á±\9a á±¯á±\9fᱸᱡá±\9fᱸᱭᱢᱮ᱾",
+       "recentchanges-summary": "á±±á±\9aᱶá±\9f á±¥á±\9fᱦᱴá±\9fᱨᱮ á±£á±¤á± á±¤ á±¨á±®á±­á±\9fá±\9c á±¡á±\9aá±\9bá±\9a á± á±·á±\9aá±± á±¨á±\9aá± á±\9f á±µá±\9aᱫá±\9aá±\9eá± á±\9a á±¯á±\9fᱸᱡá±\9fᱸᱭᱢᱮ ᱾",
        "recentchanges-noresult": "ᱮᱢᱞᱮᱱ ᱥᱚᱢᱚᱭ ᱵᱷᱤᱛᱤᱨ ᱨᱮ ᱵᱚᱫᱚᱞᱟᱜ ᱠᱚ ᱵᱟᱭ ᱢᱤᱫᱩᱜ ᱠᱟᱱᱟ ᱾",
-       "recentchanges-feed-description": "ᱱᱚᱣᱟ feed ᱨᱮ ᱩᱭᱠᱤ ᱨᱮᱭᱟᱜ ᱡᱚᱛᱚ ᱠᱷᱚᱱ ᱱᱟᱣᱟ ᱵᱚᱫᱚᱞᱠᱚ ᱯᱟᱸᱡᱟᱸᱭᱢᱮ᱾",
+       "recentchanges-feed-description": "ᱱᱚᱣᱟ ᱯᱷᱤᱰ ᱨᱮ ᱣᱤᱠᱤ ᱨᱮᱭᱟᱜ ᱡᱚᱛᱚ ᱠᱷᱚᱱ ᱱᱟᱣᱟ ᱵᱚᱫᱚᱞᱠᱚ ᱯᱟᱸᱡᱟᱸᱭᱢᱮ᱾",
        "recentchanges-label-newpage": "ᱱᱚᱣᱟ ᱥᱟᱯᱲᱟᱣ ᱢᱤᱫᱴᱮᱱ ᱱᱟᱣᱟ ᱥᱟᱦᱴᱟᱭ ᱛᱮᱭᱟᱨᱠᱮᱫᱟ",
        "recentchanges-label-minor": "ᱱᱚᱣᱟ ᱫᱚ ᱦᱩᱰᱤᱧ ᱥᱟᱯᱲᱟᱣ ᱠᱟᱱᱟ",
        "recentchanges-label-bot": "ᱱᱚᱣᱟ ᱥᱟᱯᱲᱟᱣ ᱫᱚ ᱵᱚᱴ ᱮ ᱠᱚᱨᱟᱣᱠᱟᱫᱟ",
index 13ebce5..6eda32b 100644 (file)
@@ -10,7 +10,8 @@
                        "Via maxima",
                        "Uharteko",
                        "Taxandru",
-                       "Macofe"
+                       "Macofe",
+                       "Zoranzoki21"
                ]
        },
        "tog-underline": "Sutalìnia sos ligòngios",
        "disclaimers": "Avertèntzias",
        "disclaimerpage": "Project:Avertèntzias generales",
        "edithelp": "Agiudu pro su càmbiu o s'iscritura",
+       "helppage-top-gethelp": "Agiudu",
        "mainpage": "Pàgina Base",
        "mainpage-description": "Pàgina printzipale",
        "policy-url": "Project:Polìticas",
index 3f598fb..c1c3cb9 100644 (file)
@@ -95,7 +95,7 @@
        "thu": "Thu",
        "fri": "Fri",
        "sat": "Sat",
-       "january": "Januair",
+       "january": "Januar",
        "february": "Febuair",
        "march": "Mairch",
        "april": "Apryle",
index aa7443b..4df56ae 100644 (file)
@@ -21,6 +21,7 @@
        "tog-extendwatchlist": "تازه ترين بدران سموريون تبديليون ڏيکارڻ لاءِ زير نظر فهرست کي وسيع ڪريو.",
        "tog-numberheadings": "سُرخين کي خودڪاراً نمبر ڏيو",
        "tog-editondblclick": "ٻٽي ڪلڪ تي صفحا سنواريو",
+       "tog-editsectiononrightclick": "ڀاڱن جي عنوان کي رائيٽ ڪلڪ ڪري ترميم ڪرڻ واري سهولت کي ڪارگر بڻايو.",
        "tog-watchcreations": "منھنجا سرجيل صفحا ۽ منھنجا چاڙھيل فائيل منھنجي نظر ۾ فھرست تي رکو",
        "tog-watchdefault": "منھنجا ترميميل صفحا ۽ فائيل  منھنجي نظر ۾ فھرست ۾ رکو",
        "tog-watchmoves": "جيڪي صفحا ۽ فائيل آءُٗ چوريان، سي منهنجي نظر ۾ فھرست ۾ شامل ڪريو",
index c24b779..24f9472 100644 (file)
        "editcomment": "Padėrbėma paāškėnėms bova: <em>$1</em>.",
        "revertpage": "Atmests [[Special:Contributions/$2|$2]] ([[User talk:$2|aptarėms]]) pakeitėms; sogrōžints atmains, katron padėrba nauduotuos [[User:$1|$1]]",
        "rollback-success": "Atmestė $1 padėrbtė keitėmā; grōžints $2 padėrbts atmains.",
-       "rollback-success-notify": "Atmestė $1 padėrbtė keitėmā; grōžints $2 padėrbts atmains. [$3 ruodītė keitėmus]",
        "sessionfailure-title": "Sesėjės klaida",
        "sessionfailure": "Atruod ka īr biedū so Tamstas prėsėjongėmo; tas vēksmos bova grōžints kāp atsargoma prėimonė nu sesėjės vuogėma.\nPrašoum mīgtė „atgal“ ėr parkrautė poslapi ėš katruo atiejėt, ė pamieginkėt apent.",
        "changecontentmodel-title-label": "Poslapė pavadėnėms",
index 0324e2d..a5e2487 100644 (file)
@@ -27,6 +27,7 @@
        "tog-hideminor": "Sakrij manje izmjene u spisku nedavnih izmjena",
        "tog-hidepatrolled": "Sakrij patrolirane izmjene u nedavnim promjenama",
        "tog-newpageshidepatrolled": "Sakrij patrolirane stranice sa spiska novih stranica",
+       "tog-hidecategorization": "Sakrij kategorizaciju stranica",
        "tog-extendwatchlist": "Proširi spisak praćenja za pogled svih izmjena, ne samo nedavnih",
        "tog-usenewrc": "Promene u grupi po stranici u spisku nedavnih izmhena i nadgledanih stranica (zahtijeva JavaScript)",
        "tog-numberheadings": "Automatski numeriši podnaslove",
@@ -36,6 +37,7 @@
        "tog-watchdefault": "Dodaj stranice i datoteke koje izmijenim u spisak praćenja",
        "tog-watchmoves": "Dodaj stranice i datoteke koje premjestim na moj spisak praćenja",
        "tog-watchdeletion": "Dodaj stranice i datoteke koje izbrišem na moj spisak praćenja",
+       "tog-watchuploads": "Dodaj datoteke koje postavim na moj spisak praćenja",
        "tog-watchrollback": "Dodaj stranice na kojima sam vratio uređivanja na popis praćenja",
        "tog-minordefault": "Označi da su sve izmjene u pravilu manje",
        "tog-previewontop": "Prikaži pretpregled prije kutije za uređivanje",
        "tog-enotifminoredits": "Pošalji mi e-mail i kod manjih izmjena stranica i datoteka",
        "tog-enotifrevealaddr": "Otkrij adresu moje e-pošte u porukama obaviještenja",
        "tog-shownumberswatching": "Prikaži broj korisnika koji prate",
-       "tog-oldsig": "Postojeći potpis:",
+       "tog-oldsig": "Vaš postojeći potpis:",
        "tog-fancysig": "Smatraj potpis kao wikitekst (bez automatskog linka)",
-       "tog-uselivepreview": "Koristi pretpregled uživo",
+       "tog-uselivepreview": "Pretpregledi uživo bez preučitavanja stranice",
        "tog-forceeditsummary": "Opomeni me pri unosu praznog sažetka",
-       "tog-watchlisthideown": "Sakrij moje izmjene sa spiska praćenih članaka",
-       "tog-watchlisthidebots": "Sakrij izmjene botova sa spiska praćenih članaka",
+       "tog-watchlisthideown": "Sakrij moje izmjene s praćenih",
+       "tog-watchlisthidebots": "Sakrij izmjene botova s praćenih",
        "tog-watchlisthideminor": "Sakrij manje izmjene sa spiska praćenja",
        "tog-watchlisthideliu": "Sakrij izmjene prijavljenih korisnika sa liste praćenja",
+       "tog-watchlistreloadautomatically": "Preučitavaj spisak praćenja kad god se izmijeni filter (potreban JavaScript)",
+       "tog-watchlistunwatchlinks": "Dodaj neposredni beležnici za prekid/stavljanje u praćenih ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) praćenim stranicama sa promjenama (prebacivanje zahtjeva JavaScript)",
        "tog-watchlisthideanons": "Sakrij izmjene anonimnih korisnika sa liste praćenja",
        "tog-watchlisthidepatrolled": "Sakrij patrolirane izmjene sa spiska praćenja",
        "tog-watchlisthidecategorization": "Sakrij kategorizaciju stranica",
        "tog-ccmeonemails": "Pošalji mi kopije emailova koje šaljem drugim korisnicima",
        "tog-diffonly": "Ne prikazuj sadržaj stranice ispod prikaza razlika",
        "tog-showhiddencats": "Prikaži skrivene kategorije",
-       "tog-norollbackdiff": "Nakon povrata zanemari prikaz razlika",
+       "tog-norollbackdiff": "Ne prikazuj razliku nakon izvršenog vraćanja",
        "tog-useeditwarning": "Upozori me kad napuštam stranicu za uređivanje bez snimanja izmjena",
-       "tog-prefershttps": "Uvijek koristi sigurnu vezu kod prijave",
+       "tog-prefershttps": "Uvijek koristi sigurnu vezu dok sam prijavljen",
+       "tog-showrollbackconfirmation": "Prikaži potvrdnicu kada kliknete vezu za opoziv",
        "underline-always": "Uvijek",
        "underline-never": "Nikad",
        "underline-default": "prema skinu ili postavkama preglednika",
        "october-date": "$1. oktobra",
        "november-date": "$1. novembra",
        "december-date": "$1. decembra",
+       "period-am": "prepodne",
+       "period-pm": "popodne",
        "pagecategories": "{{PLURAL:$1|Kategorija|Kategorije}}",
        "category_header": "Stranice u kategoriji \"$1\"",
        "subcategories": "Potkategorije",
        "index-category": "Indeksirane stranice",
        "noindex-category": "Neindeksirane stranice",
        "broken-file-category": "Stranice sa neispravnim linkovima do datoteka",
+       "categoryviewer-pagedlinks": "$1 ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "O...",
        "article": "Stranica sadržaja",
        "newwindow": "(otvara se u novom prozoru)",
        "cancel": "Otkaži",
        "moredotdotdot": "Još...",
-       "morenotlisted": "Ovaj spisak nije kompletan.",
-       "mypage": "Moja stranica",
+       "morenotlisted": "Ovaj spisak možda nije potpun.",
+       "mypage": "Stranica",
        "mytalk": "Razgovor",
        "anontalk": "Razgovor",
        "navigation": "Navigacija - Навигација",
        "returnto": "Povratak na $1.",
        "tagline": "Iz {{SITENAME}}",
        "help": "Pomoć",
+       "help-mediawiki": "Pomoć o MediaWikiju",
        "search": "Traži / Тражи",
        "searchbutton": "Traži",
        "go": "Idi / Иди",
        "searcharticle": "Idi",
        "history": "Historija stranice",
        "history_short": "Historija",
+       "history_small": "historija",
        "updatedmarker": "promjene od moje zadnje posjete",
        "printableversion": "Verzija za ispis",
        "permalink": "Trajni link",
        "talk": "Razgovor",
        "views": "Pregledi",
        "toolbox": "Alati",
+       "tool-link-userrights": "Promijeni {{GENDER:$1|korisničke}} grupe",
+       "tool-link-userrights-readonly": "Vidi {{GENDER:$1|korisničke}} grupe",
+       "tool-link-emailuser": "Pošalji e-poruku {{GENDER:$1|korisniku|korisnici}}",
        "imagepage": "Vidi stranicu datoteke/fajla",
        "mediawikipage": "Pogledaj stranicu s porukom",
        "templatepage": "Pogledajte stranicu sa šablonom",
        "redirectedfrom": "(Preusmjereno sa $1)",
        "redirectpagesub": "Preusmjeri stranicu",
        "redirectto": "Preusmjerenje na:",
-       "lastmodifiedat": "Ova stranica je posljednji put izmijenjena $1, $2.",
+       "lastmodifiedat": "Ova stranica je posljednji put izmijenjena $1 u $2.",
        "viewcount": "Ovoj stranici je pristupljeno {{PLURAL:$1|$1 put|$1 puta}}.",
        "protectedpage": "Zaštićena stranica",
        "jumpto": "Skoči na:",
        "jumptosearch": "pretraga",
        "view-pool-error": "Žao nam je, serveri su trenutno preopterećeni.\nPreviše korisnika pokušava da pregleda ovu stranicu.\nMolimo pričekajte trenutak prije nego što ponovno pokušate pristupiti ovoj stranici.\n\n$1",
        "generic-pool-error": "Žao nam je, serveri su trenutno preopterećeni.\nPreviše korisnika pokušava da pregleda ovu stranicu.\nMolimo pričekajte trenutak prije nego što ponovno pokušate pristupiti ovoj stranici.",
-       "pool-timeout": "Zaustavi čekanje za zaključavanje",
+       "pool-timeout": "Istek vremena čeka na zaključavanje",
        "pool-queuefull": "Red na pool je prenapunjen",
-       "pool-errorunknown": "nepoznata greška",
+       "pool-errorunknown": "Nepoznata greška",
        "pool-servererror": "Usluga brojača poola nije dostupna ($1).",
        "poolcounter-usage-error": "Greška pri upotrebi: $1",
        "aboutsite": "O projektu {{SITENAME}}",
        "databaseerror-query": "Upit: $1",
        "databaseerror-function": "Funkcija: $1",
        "databaseerror-error": "Greška: $1",
+       "transaction-duration-limit-exceeded": "Da se izbjegne veliko zaostajanje replikacije, transakcija je prekinuta zato što je trajanje zapisivanja ($1) prekoračilo ograničenje od {{PLURAL:$2|jedne sekunde|$2 sekunde|$2 sekundi}}.\nAko mijenjate mnogo stavki odjednom, uradite to u više navrata.",
        "laggedslavemode": "'''Upozorenje''': Stranica ne mora sadržavati posljednja ažuriranja.",
        "readonly": "Baza podataka je zaključana",
        "enterlockreason": "Unesite razlog za zaključavanje, uključujući procjenu vremena otključavanja",
-       "readonlytext": "Baza je trenutno zaključana za nove unose i ostale izmjene, vjerovatno zbog rutinskog održavanja, posle čega će biti vraćena u uobičajeno stanje.\n\nAdministrator koji ju je zaključao je ponudio ovo objašnjenje: $1",
+       "readonlytext": "Baza je trenutno zaključana za nove unose i ostale izmjene, vjerovatno zbog rutinskog održavanja, posle čega će biti vraćena u uobičajeno stanje.\n\nSistemski administrator koji ju je zaključao je ponudio ovo objašnjenje: $1",
        "missing-article": "U bazi podataka nije pronađen tekst stranice tražen pod nazivom \"$1\" $2.\n\nDo ovoga dolazi kada se prati premještaj ili historija linka za stranicu koja je pobrisana.\n\nU slučaju da se ne radi o gore navedenom, moguće je da ste pronašli grešku u programu.\nMolimo Vas da ovo prijavite [[Special:ListUsers/sysop|administratoru]] sa navođenjem tačne adrese stranice",
        "missingarticle-rev": "(izmjena#: $1)",
        "missingarticle-diff": "(razlika: $1, $2)",
        "readonly_lag": "Baza podataka je zaključana dok se sekundarne baze podataka na serveru ne sastave sa glavnom.",
+       "nonwrite-api-promise-error": "HTTP-zaglavlje \"Promise-Non-Write-API-Action\" je poslano, ali je upućeno zapisnom modulu izvršnika.",
        "internalerror": "Interna pogreška",
        "internalerror_info": "Interna greška: $1",
        "internalerror-fatal-exception": "Fatalna greška tipa \"$1\"",
-       "filecopyerror": "Ne može se kopirati \"$1\" na \"$2\".",
+       "filecopyerror": "Ne mogu kopirati datoteku \"$1\" na \"$2\".",
        "filerenameerror": "Ne mogu preimenovati datoteku \"$1\" u \"$2\".",
        "filedeleteerror": "Ne može se izbrisati datoteka \"$1\".",
        "directorycreateerror": "Nije moguće napraviti direktorijum \"$1\".",
        "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 drugi već obrisao.",
        "cannotdelete-title": "Brisanje stranice \"$1\" nije moguće",
+       "delete-scheduled": "Stranica \"$1\" je predviđena za brisanje.\nBudite strpljivi.",
        "delete-hook-aborted": "Brisanje prekinuto softverskim priključkom (hook).\nNema obrazloženja ili poruke o grešci.",
        "no-null-revision": "Nije se mogla stvoriti nova ništavna revizija za stranicu \"$1\"",
        "badtitle": "Loš naslov",
        "cascadeprotected": "Uređivanje ove stranice zabranjeno je jer se koristi u {{PLURAL:$1|sljedećoj stranici, koja je zaštićena|sljedećim stranicama, koje su zaštićene}} prenosivom zaštitom:\n$2",
        "namespaceprotected": "Nemate dozvolu uređivati stranice imenskog prostora '''$1'''.",
        "customcssprotected": "Nemate dozvolu za mijenjanje ove CSS stranice jer sadrži osobne postavke nekog drugog korisnika.",
+       "customjsonprotected": "Nemate dozvolu za mijenjanje ove JSON stranice jer sadrži osobne postavke nekog drugog korisnika.",
        "customjsprotected": "Nemate dozvolu za mijenjanje ove JavaScript stranice jer sadrži osobne postavke nekog drugog korisnika.",
-       "mycustomcssprotected": "Nemate ovlasti za uređivanje ove CSS stranice.",
+       "sitecssprotected": "Nemate dozvolu za mijenjanje ove CSS stranice jer to može utjecati na sve posjetitelje.",
+       "sitejsonprotected": "Nemate dozvolu za mijenjanje ove JSON stranice jer to može utjecati na sve posjetitelje.",
+       "sitejsprotected": "Nemate dozvolu za mijenjanje ove JavaScript stranice jer to može utjecati na sve posjetitelje.",
+       "mycustomcssprotected": "Nemate ovlasti za uređivanje ove kaskadne stilske stranice (CSS).",
+       "mycustomjsonprotected": "Nemate dozvolu da uređujete ovu stranicu sa JSONom.",
        "mycustomjsprotected": "Nemate dozvolu da uređujete ovu stranicu sa JavaScriptom.",
        "myprivateinfoprotected": "Nemate dozvolu da uređujete svoje privatne informacije.",
        "mypreferencesprotected": "Nemate dozvolu da uređujete svoje postavke.",
        "ns-specialprotected": "Posebne stranice se ne mogu uređivati.",
        "titleprotected": "Naslov stranice je zaštićen od postavljanja od strane korisnika [[User:$1|$1]].\nKao razlog je naveden <em>$2</em>.",
-       "filereadonlyerror": "Ne mogu da izmenim datoteku „$1“ jer je riznica „$2“ u režimu za čitanje.\n\nAdministrator koji ju je zaključao ponudio je sledeće objašnjenje: „$3“.",
+       "filereadonlyerror": "Ne mogu izmijeniti datoteku „$1“ jer je spremište „$2“ u režimu za čitanje.\n\nAdministrator koji ju je zaključao ponudio je sledeće objašnjenje: „''$3''“.",
+       "invalidtitle": "Neispravan naslov",
        "invalidtitle-knownnamespace": "Neispravan naslov s imenskim prostorom „$2“ i tekstom „$3“",
        "invalidtitle-unknownnamespace": "Neispravan naslov s imenskim prostorom br. $1 i tekstom „$2“",
        "exception-nologin": "Niste prijavljeni",
        "exception-nologin-text": "Molimo prijavite se ako želite pristup ovoj stranici ili djelovanje.",
        "exception-nologin-text-manual": "Molimo $1 da biste pristupili ovoj stranici ili radnji.",
-       "virus-badscanner": "Loša konfiguracija: nepoznati anti-virus program: ''$1''",
+       "virus-badscanner": "Loša postavka: nepoznati provjeritelj za viruse: ''$1''",
        "virus-scanfailed": "skeniranje nije uspjelo (code $1)",
        "virus-unknownscanner": "nepoznati anti-virus program:",
        "logouttext": "'''Sad ste odjavljeni.'''\n\nObratite pažnju da neke stranice mogu nastaviti da se prikazuju kao da ste još uvijek prijavljeni, dok ne očistite keš svog preglednika.",
+       "cannotlogoutnow-title": "Odjava trenutno nije moguća",
+       "cannotlogoutnow-text": "Odjava nije moguća tijekom uporabe $1.",
        "welcomeuser": "Dobro došli, $1!",
-       "welcomecreation-msg": "Vaš korisnički račun je napravljen.\nNe zaboravite izmijeniti vlastite [[Special:Preferences|{{SITENAME}} postavke]].",
+       "welcomecreation-msg": "Vaš korisnički račun je napravljen.\nNe zaboravite izmijeniti vlastita [[Special:Preferences|{{SITENAME}} podešavanja]].",
        "yourname": "Vaše korisničko ime / Ваше корисничко име",
        "userlogin-yourname": "Korisničko ime",
        "userlogin-yourname-ph": "Unesite svoje korisničko ime",
        "createacct-yourpasswordagain-ph": "Unesite lozinku/zaporku ponovno",
        "userlogin-remembermypassword": "Zapamti prijavu",
        "userlogin-signwithsecure": "Koristite sigurnu vezu",
+       "cannotlogin-title": "Prijava nije moguća",
+       "cannotlogin-text": "Prijava nija moguća.",
+       "cannotloginnow-title": "Prijava trenutno nije moguća.",
+       "cannotloginnow-text": "Prijava nije moguća tijekom uporabe $1.",
+       "cannotcreateaccount-title": "Nije moguće stvoriti račune",
+       "cannotcreateaccount-text": "Direktno pravljenje računa nije omogućeno na ovom wikiju.",
        "yourdomainname": "Vaš domen:",
        "password-change-forbidden": "Ne možete da promenite lozinku na ovom vikiju.",
        "externaldberror": "Došlo je do greške pri vanjskoj autorizaciji baze podataka ili vam nije dopušteno osvježavanje Vašeg vanjskog korisničkog računa.",
        "login": "Prijava / Пријава",
+       "login-security": "Potvrdite svoj identitet",
        "nav-login-createaccount": "Prijavi se / Registruj se",
        "logout": "Odjava",
        "userlogout": "Odjava / Одјава",
        "userlogin-resetpassword-link": "Zaboravili ste lozinku?",
        "userlogin-helplink2": "Pomoć pri prijavljivanju",
        "userlogin-loggedin": "Već ste prijavljeni kao {{GENDER:$1|$1}}.\nKoristite donji obrazac da biste se prijavili kao drugi korisnik.",
+       "userlogin-reauth": "Morate se ponovo prijaviti da biste potvrdili da ste {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Izradi drugi račun",
        "createacct-emailrequired": "E-mail adresa",
        "createacct-emailoptional": "E-mail adresa (opcionalno)",
        "createacct-email-ph": "Unesite svoju E-mail adresu",
        "createacct-another-email-ph": "Postavite E-mail adresu",
-       "createaccountmail": "Koristite privremenu, slučajno stvorenu šifru/lozinku i pošaljite na navedenu adrеsu e-pošte",
+       "createaccountmail": "Daj privremenu nasumičnu lozinku i pošalji na navedenu adresu",
+       "createaccountmail-help": "Može se koristiti za stvaranje računa u tuđem imenu bez da se sazna lozinka.",
        "createacct-realname": "Stvarno ime (opcionalno)",
        "createacct-reason": "Razlog",
        "createacct-reason-ph": "Zašto stvarate novi račun",
+       "createacct-reason-help": "Poruka koja se prikazuje u zapisniku stvaranja korisničkih računa",
        "createacct-submit": "Stvorite svoj račun",
        "createacct-another-submit": "Izradi račun",
+       "createacct-continue-submit": "Nastavi sa stvaranjem računa",
+       "createacct-another-continue-submit": "Nastavi sa stvaranjem računa",
        "createacct-benefit-heading": "{{SITENAME}} se stvara od ljudi poput vas.",
        "createacct-benefit-body1": "$1 {{PLURAL:$1|izmjena|izmjene}}",
        "createacct-benefit-body2": "$1 {{PLURAL:$1|stranica|stranice|stranica}}",
        "badretype": "Lozinke koje ste unijeli se ne poklapaju.",
        "usernameinprogress": "Stvaranje računa za ovog korisnika je već u toku.\nMolimo sačekajte.",
        "userexists": "Uneseno korisničko ime već je u upotrebi.\nUnesite neko drugo ime.",
+       "createacct-normalization": "Vaše će korisničko ime biti prilagođeno u \"$2\" zbog tehničkih ograničenja.",
        "loginerror": "Greška pri prijavljivanju",
        "createacct-error": "Pogreška u stvaranju računa",
        "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 onemogućili kolačiće na Vašem računaru.\nMolimo Vas da ih omogućite, a onda se prijavite sa svojim novim korisničkim imenom i šifrom.",
        "nocookieslogin": "{{SITENAME}} koristi kolačiće (''cookies'') da bi se korisnici prijavili.\nVi ste onemogućili kolačiće na Vašem kompjuteru.\nMolimo Vas da ih omogućite i da pokušate ponovo sa prijavom.",
        "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. Pređite na [[Special:UserLogin|ručno prijavljivanje]].",
        "noname": "Niste izabrali ispravno korisničko ime.",
-       "loginsuccesstitle": "Prijavljivanje uspješno",
-       "loginsuccess": "Trenutno ste prijavljeni na {{SITENAME}} kao \"$1\".",
-       "nosuchuser": "Ne postoji korisnik sa imenom \"$1\".\nKorisnička imena razlikuju velika i mala slova.\nProvjerite vaše kucanje ili [[Special:CreateAccount|napravite novi korisnički račun]].",
+       "loginsuccesstitle": "Prijava uspješna",
+       "loginsuccess": "<strong>Trenutno ste prijavljeni na {{SITENAME}} kao \"$1\".</strong>",
+       "nosuchuser": "Ne postoji korisnik sa imenom \"$1\".\nKorisnička imena razlikuju velika i mala slova.\nProvjerite jeste li ga tačno upisali ili [[Special:CreateAccount|napravite novi korisnički račun]].",
        "nosuchusershort": "Ne postoji korisnik sa imenom \"$1\".\nProvjerite da li ste dobro ukucali.",
        "nouserspecified": "Morate izabrati korisničko ime.",
        "login-userblocked": "Ovaj korisnik je blokiran. Prijava nije dozvoljena.",
-       "wrongpassword": "Šifra koju ste uneli je neodgovarajuće. Molimo, upišite je ponovo.\n\nШифра коју сте унели је неодговарајућа. Молимо, упишите је поново.",
-       "wrongpasswordempty": "Unesena šifra je bila prazna.\nMolimo Vas da pokušate ponovno.",
+       "wrongpassword": "Uneli ste pogrešno korisničko ime ili lozinku.\nPokušajte ponovo.",
+       "wrongpasswordempty": "Unesena lozinka je bila prazna.\nPokušajte ponovno.",
        "passwordtooshort": "Lozinka mora imati najmanje {{PLURAL:$1|1 znak|$1 znakova}}.",
        "passwordtoolong": "Šifre/lozinke/zaporke ne mogu biti duže od {{PLURAL:$1|jednog znaka|$1 znaka|$1 znakova}}.",
+       "passwordtoopopular": "Nije moguće koristiti često odabrane lozinke. Odaberite lozinku koju je teže pogoditi.",
+       "passwordinlargeblacklist": "Unesena zaporka je jedna od najčešće korištenih. Izaberite drugačiju.",
        "password-name-match": "Vaša lozinka mora biti različita od Vašeg korisničkog imena.",
        "password-login-forbidden": "Korištenje ovog korisničkog imena i lozinke je zabranjeo.",
        "mailmypassword": "Resetiraj lozinku/zaporku",
        "passwordremindertitle": "Nova privremena lozinka za {{SITENAME}}",
-       "passwordremindertext": "Neko (vjerovatno Vi, sa IP adrese $1) je zahtjevao da vam pošaljemo novu šifru za {{SITENAME}}  ($4). Privremena šifra za korisnika \"$2\" je napravljena i glasi \"$3\". Ako ste to željeli, sad treba da se prijavite i promjenite šifru.\nVaša privremena šifra će isteči za {{PLURAL:$5|$5 dan|$5 dana}}.\n\nAko je neko drugi napravio ovaj zahtjev ili ako ste se sjetili vaše šifre i ne želite više da je promjenite, možete da ignorišete ovu poruku i da nastavite koristeći vašu staru šifru.",
+       "passwordremindertext": "Neko (sa IP adrese $1) je zatražio novu lozinku za {{SITENAME}}  ($4).\nStvorena je privremena lozinka \"$3\" za korisnički račun \"$2\".\nAko ste to željeli, sad treba da se prijavite i postavite novu lozinku.\nVaša privremena lozinka ističe za {{PLURAL:$5|jedan dan|$5 dana}}.\n\nAko je neko drugi napravio ovaj zahtjev ili ako ste se sjetili vaše lozinke i ne želite više da je promjenite, možete da zanemarite ovu poruku i da nastavite koristeći vašu staru lozinku.",
        "noemail": "Ne postoji adresa e-maila za korisnika \"$1\".",
        "noemailcreate": "Morate da navedete valjanu e-mail adresu",
        "passwordsent": "Nova šifra je poslata na e-mail adresu korisnika \"$1\".\nMolimo Vas da se prijavite pošto je primite.",
-       "blocked-mailpassword": "Da bi se spriječila nedozvoljena akcija, Vašoj IP adresi je onemogućeno uređivanje stranica kao i mogućnost zahtijevanje nove šifre.",
+       "blocked-mailpassword": "Vaša IP adresa ima zabranu uređivanja. Da bi se spriječila zloupotreba, nije dopušteno povratak lozinke od nje.",
        "eauthentsent": "Na navedenu adresu poslana je e-poruka s potvrdom.\nPrije nego što pošaljemo daljnje poruke, pratite uputstva s e-pošte da biste potvrdili da je račun zaista Vaš.",
        "throttled-mailpassword": "Već Vam je poslan e-mail za promjenu šifre u {{PLURAL:$1|zadnjih sat vremena|zadnja $1 sata|zadnjih $1 sati}}.\nDa bi se spriječila zloupotreba, može se poslati samo jedan e-mail za promjenu šifre {{PLURAL:$1|svakih sat vremena|svaka $1 sata|svakih $1 sati}}.",
        "mailerror": "Greška pri slanju e-pošte: $1",
-       "acct_creation_throttle_hit": "Posjetioci na ovoj wiki koji koriste Vašu IP adresu su već napravili {{PLURAL:$1|$1 račun|$1 računa}} u zadnjih nekoliko dana, što je najveći broj dopuštenih napravljenih računa za ovaj period.\nKao rezultat, posjetioci koji koriste ovu IP adresu ne mogu trenutno praviti više računa.",
+       "acct_creation_throttle_hit": "Posjetioci na ovoj wiki koji koriste Vašu IP adresu su već napravili {{PLURAL:$1|$1 račun|$1 računa}} u zadnjih $2, što je najveći broj dopuštenih napravljenih računa za ovaj period.\nKao rezultat, posjetioci koji koriste ovu IP adresu ne mogu trenutno praviti više računa.",
        "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.",
        "createaccount-title": "Pravljenje korisničkog računa za {{SITENAME}}",
        "createaccount-text": "Neko je napravio korisnički račun za vašu e-mail adresu na {{SITENAME}} ($4) sa imenom \"$2\", i sa šifrom \"$3\".\nTrebali biste se prijaviti i promjeniti šifru.\n\nMožete ignorisati ovu poruku, ako je korisnički račun napravljen greškom.",
        "login-throttled": "Previše puta ste se pokušali prijaviti.\nMolimo Vas da sačekate $1 prije nego što pokušate ponovo.",
-       "login-abort-generic": "Vaša prijava nije bila uspješna – Prekinuto",
+       "login-abort-generic": "Neuspješna prijava – Prekinuto",
        "login-migrated-generic": "Vaš se korisnički račun preselio, te Vaše korisničko ime više ne postoji na ovom wikiju.",
        "loginlanguagelabel": "Jezik: $1",
        "suspicious-userlogout": "Vaš zahtjev za odjavu je odbijen jer je poslan preko pokvarenog preglednika ili keširanog proksija.",
        "createacct-another-realname-tip": "Pravo ime nije obavezno.\nAko izaberete da date ime, biće korišteno za pripisivanje za vaš rad.",
        "pt-login": "Prijava",
        "pt-login-button": "Prijavi me / Пријави ме",
+       "pt-login-continue-button": "Nastavi prijavu",
        "pt-createaccount": "Izradi račun",
        "pt-userlogout": "Odjava",
        "php-mail-error-unknown": "Nepoznata greška u PHP funkciji mail()",
        "newpassword": "Nova šifra:",
        "retypenew": "Ukucajte ponovo novu šifru:",
        "resetpass_submit": "Odredi lozinku i prijavi se",
-       "changepassword-success": "Vaša šifra je uspiješno promjenjena! Prijava u toku...",
-       "changepassword-throttled": "Previše puta ste se pokušali prijaviti.\nMolimo Vas da sačekate $1 prije nego što pokušate ponovo.",
+       "changepassword-success": "Vaša lozinka je smijenjena!",
+       "changepassword-throttled": "Imate previše pokušaja prijave u kratkom vremenu.\nPričekajte $1 prije nego što pokušate ponovno.",
+       "botpasswords": "Botovske lozinke",
+       "botpasswords-summary": "<em>Lozinke botova</em> daju pristup korisničkom računu preko priložnika bez da se koriste podaci o prijavi glavnog računa. Korisnička prava mogla bi biti ograničena kada se prijavite na ovaj način.\n\nUkoliko ne znate kako bi Vam ovo poslužilo, vjerovatno to ne biste trebali raditi. Niko nikada ne treba od Vas tražiti da napravite ovakve lozinke i da mu ih date.",
+       "botpasswords-disabled": "Lozinke botova su onemogućene.",
+       "botpasswords-no-central-id": "Da biste koristili botovske lozinke, morate biti prijavljeni na središnji račun.",
+       "botpasswords-existing": "Postojeće lozinke botova",
+       "botpasswords-createnew": "Napravi novu lozinku bota",
+       "botpasswords-editexisting": "Promijeni postojeću lozinku bota",
+       "botpasswords-label-needsreset": "(lozinku treba resetovati)",
+       "botpasswords-label-appid": "Ime bota:",
+       "botpasswords-label-create": "Stvori",
+       "botpasswords-label-update": "Ažuriraj",
        "botpasswords-label-cancel": "Otkaži",
+       "botpasswords-label-delete": "Izbriši",
+       "botpasswords-label-resetpassword": "Stavite novu lozinku",
+       "botpasswords-label-grants": "Primjenjive dozvole:",
+       "botpasswords-help-grants": "Dozvole vam daje pristup pravima koja već imaju vaš račun. Omogućavanjem dodjele ovdje nećete primati prava koja više nemaju račun. Više informacija možete pronaći na [[Special:ListGrants|tablici dozvole]].",
+       "botpasswords-label-grants-column": "Odobreno",
+       "botpasswords-bad-appid": "Ime bota \"$1\" nije ispravno.",
+       "botpasswords-insert-failed": "Neuspjelo dodavanje imena bota \"$1\". Možda je već dodano?",
+       "botpasswords-update-failed": "Neuspjelo ažuriranje bota s imenom \"$1\". Možda je obrisan?",
+       "botpasswords-created-title": "Lozinka bota je napravljena",
+       "botpasswords-created-body": "Lozinka za bota \"$1\" {{GENDER:$2|korisnika|korisnice}} \"$2\" je napravljena.",
+       "botpasswords-updated-title": "Lozinka bota je izmjenjena",
+       "botpasswords-updated-body": "Lozinka za bota \"$1\" {{GENDER:$2|korisnika|korisnice}} \"$2\" je izmjenjena.",
+       "botpasswords-deleted-title": "Lozinka bota je obrisana",
+       "botpasswords-deleted-body": "Lozinka za bota \"$1\" {{GENDER:$2|korisnika|korisnice}} \"$2\" je obrisana.",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider nije dostupan.",
+       "botpasswords-restriction-failed": "Ne možete se prijaviti zbog ograničenja lozinki za botove.",
+       "botpasswords-invalid-name": "Navedeno korisničko ime ne sadrži rastavni znak za lozinke botova (\"$1\").",
+       "botpasswords-not-exist": "Korisnik \"$1\" nema lozinku bota \"$2\".",
+       "botpasswords-needs-reset": "Lozinka za bota \"$2\" {{GENDER:$1|korisnika|korisnice}} \"$2\" mora se obnoviti.",
+       "botpasswords-locked": "Ne možete da se prijavite s botovskim lozinkom jer je vaš nalog zaključan.",
        "resetpass_forbidden": "Šifre ne mogu biti promjenjene",
+       "resetpass_forbidden-reason": "Lozinke ne mogu biti promijenjene: $1",
        "resetpass-no-info": "Morate biti prijavljeni da bi ste pristupili ovoj stranici direktno.",
        "resetpass-submit-loggedin": "Promijeni lozinku",
        "resetpass-submit-cancel": "Otkaži",
-       "resetpass-wrong-oldpass": "Privremena ili trenutna lozinka nije valjana.\nMožda ste već uspješno promijenili Vašu lozinku ili ste tražili novu privremenu lozinku.",
-       "resetpass-recycled": "Molimo resetirajte vašu lozinku/zaporku u nešto drugo od vaše trenutne lozinke/zaporke.",
+       "resetpass-wrong-oldpass": "Pogrešna privremena ili trenutna lozinka.\nMožda ste već promijenili Vašu lozinku ili ste tražili novu privremenu lozinku.",
+       "resetpass-recycled": "Molimo zadajte drugu lozinku/zaporku, drugačiju od trenutačne.",
        "resetpass-temp-emailed": "Prijavili ste se sa privremenim kodom iz e-pošte.\nDa biste završili prijavljivanje morate postaviti novu lozinku ovde:",
        "resetpass-temp-password": "Privremena lozinka:",
        "resetpass-abort-generic": "Promjenu lozinke/zaporke je prekinula ekstenzija.",
        "resetpass-expired": "Vaša lozinka je istekla. Postavite novu lozinku da biste se prijavili.",
-       "resetpass-expired-soft": "Vaša lozinka je istekla i morate postaviti novu. Postavite novu lozinku ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da je postavite kasnije.",
-       "resetpass-validity-soft": "Vaša loznika nije valjana: $1\n\nMolimo da sada odaberete novu lozinku ili kliknete \"{{int:authprovider-resetpass-skip-label}}\" kako bi je resetirali kasnije.",
+       "resetpass-expired-soft": "Vaša lozinka je istekla i morate je smijeniti. Postavite je sada ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da je smijenite kasnije.",
+       "resetpass-validity": "Vaša lozinka nije važeća: $1\n\nZadajte novu lozinku da biste se prijavili.",
+       "resetpass-validity-soft": "Vaša loznika nije važeća: $1\n\nIzaberite drugu sada ili kliknete \"{{int:authprovider-resetpass-skip-label}}\" kako bi je smijenili kasnije.",
        "passwordreset": "Ponovno postavi lozinku",
        "passwordreset-text-one": "Dovršite ovaj obrazac kako biste resetirali svoju lozinku/zaporku.",
        "passwordreset-text-many": "{{PLURAL:$1|Ispunite jedno od polja kako bi ste resetirali svoju lozinku/zaporku.}}",
        "passwordreset-emailtext-ip": "Netko (vjerovatno Vi, s IP adrese $1) je zatražio resetiranje vaše lozinke/zaporke {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|račun korisnika je|računi korisnika su}}\npovezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ako je neko drugi napravio ovaj\nzahtjev, ili ako ste se sjetili Vaše početne lozinke, a ne želite je promijeniti, \nmožete zanemariti ovu poruku i nastaviti koristiti staru lozinku.",
        "passwordreset-emailtext-user": "Korisnik $1 na {{SITENAME}} je zatražio resetiranje vaše lozinke/zaporke za {{SITENAME}}\n($4). Sljedeći {{PLURAL:$3|korisnički račun je|korisnički računi su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ako je neko drugi napravio ovaj\nzahtjev, ili ako ste se sjetili Vaše originalne lozinke, a ne želite je više promijeniti, \nmožete zanemariti ovu poruku i nastaviti koristiti staru lozinku.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena šifra: \n$2",
-       "passwordreset-emailsentemail": "Ako je ovo adresa e-pošte s kojom ste registrirali ovaj račun, podsjetnik šifre/lozinke/zaporke će vam biti poslan na vašu adresu e-pošte.",
+       "passwordreset-emailsentemail": "Ako je ova adresa e-pošte povezana s Vašim računom, na nju će biti poslan podsjetnik zadavanja nove lozinke.",
+       "passwordreset-emailsentusername": "Ako postoji odgovarajuća registrirana adresa e-pošte povezana s ovim korisničkim imenom, bit će vam poslana poruka o promjeni zaporke.",
+       "passwordreset-nocaller": "Mora se navesti pozivalac",
+       "passwordreset-nosuchcaller": "Pozivalac ne postoji: $1",
+       "passwordreset-ignored": "Mijenjanje lozinke nije uspjelo. Možda nije postavljen poslužilac?",
+       "passwordreset-invalidemail": "Neispravna adresa e-pošte",
+       "passwordreset-nodata": "Niste naveli ni korisničko ime, a ni adresu e-pošte.",
        "changeemail": "Promeni ili ukloni e-adresu",
        "changeemail-header": "Ispunite sljedeći formular da biste promijenili adresu e-pošte. Ako želite ukloniti postojeću adresu e-pošte s vašeg korisničkog računa, pri ispunjavanju formulara, polje nove adrese e-pošte ostavite prazno.",
        "changeemail-no-info": "Morate biti prijavljeni da biste izravno pristupili ovoj stranici.",
        "savechanges": "Sačuvaj - Сачувај",
        "publishpage": "Objavi stranicu",
        "publishchanges": "Objavi izmjene",
+       "savearticle-start": "Sačuvaj stranicu...",
+       "savechanges-start": "Spremi promjene...",
+       "publishpage-start": "Objavi stranicu...",
+       "publishchanges-start": "Objavi promjene…",
        "preview": "Pregled",
        "showpreview": "Prikaži pregled",
        "showdiff": "Prikaži izmjene",
        "anonpreviewwarning": "''Niste prijavljeni. Vaša IP adresa će biti zabilježena u historiji ove stranice.''",
        "missingsummary": "'''Podsjećanje:''' Niste unijeli sažetak izmjene.\nAko kliknete na Sačuvaj/Snimi, Vaša izmjena će biti snimljena bez sažetka.",
        "selfredirect": "<strong>Upozorenje:</strong> Preusmjeravate stranicu na samu sebe.\nMožda ste naveli pogrešan cilj preusmjeravanja ili ste uređivali pogrešnu stranicu.\nAko ponovno kliknete \"$1\", ipak će nastati preusmjerenje.",
-       "missingcommenttext": "Molimo unesite komentar ispod.",
+       "missingcommenttext": "Molimo unesite komentar.",
        "missingcommentheader": "<strong>Podsjetnik:</strong> Niste napisali temu za ovaj komentar.\nAko ponovo kliknete na \"$1\", vaša izmjena će biti sačuvana bez teme/naslova.",
        "summary-preview": "Pretpregled sažetka:",
-       "subject-preview": "Pretpregled teme:",
+       "subject-preview": "Pretpregled naslova:",
        "previewerrortext": "Dogodila se greška prilikom prikazivanja vaših izmjena.",
        "blockedtitle": "Korisnik je blokiran",
        "blockedtext": "'''Vaše korisničko ime ili IP adresa je blokirana.'''\n\nBlokada izvršena od strane $1.\nDati razlog je slijedeći: ''$2''.\n\n*Početak blokade: $8\n*Kraj perioda blokade: $6\n*Ime blokiranog korisnika: $7\n\nMožete kontaktirati $1 ili nekog drugog [[{{MediaWiki:Grouppage-sysop}}|administratora]] da biste razgovarali o blokadi.\n\nNe možete koristiti opciju ''Pošalji e-mail korisniku'' osim ako niste unijeli e-mail adresu u [[Special:Preferences|Vaše postavke]].\nVaša trenutna IP adresa je $3, a oznaka blokade je #$5.\nMolimo Vas da navedete gornje podatke u zahtjevu za deblokadu.",
        "newarticle": "(Novi)",
        "newarticletext": "Preko linka ste došli na stranicu koja još uvijek ne postoji.\n* Ako želite stvoriti stranicu, počnite tipkati u okviru dolje (v. [$1 stranicu za pomoć] za više informacija).\n* Ukoliko ste došli greškom, pritisnike dugme '''Nazad''' ('''back''') na vašem pregledniku.",
        "anontalkpagetext": "----''Ovo je stranica za razgovor za anonimnog korisnika koji još nije napravio račun ili ga ne koristi.\nZbog toga moramo da koristimo brojčanu IP adresu kako bismo identifikovali njega ili nju.\nTakvu adresu može dijeliti više korisnika.\nAko ste anonimni korisnik i mislite da su vam upućene nebitne primjedbe, molimo Vas da [[Special:CreateAccount|napravite račun]] ili se [[Special:UserLogin|prijavite]] da biste izbjegli buduću zabunu sa ostalim anonimnim korisnicima.''",
-       "noarticletext": "Na ovoj stranici trenutno nema teksta.\nMožete [[Special:Search/{{PAGENAME}}|tražiti naslov ove stranice]] u drugim stranicama,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretraživati srodne registre],\nili [{{fullurl:{{FULLPAGENAME}}|action=edit}} urediti ovu stranicu]</span>.",
+       "noarticletext": "Na ovoj stranici trenutno nema teksta.\nMožete [[Special:Search/{{PAGENAME}}|tražiti naslov ove stranice]] u drugim stranicama,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretraživati srodne registre],\nili [{{fullurl:{{FULLPAGENAME}}|action=edit}} napraviti ovu stranicu]</span>.",
        "noarticletext-nopermission": "Trenutno nema teksta na ovoj stranici.\nMožete [[Special:Search/{{PAGENAME}}|tražiti ovaj naslov stranice]] na drugim stranicama ili <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti povezane registre]</span>. alio nemate dozvolu za stvaranje ove stranice.",
        "missing-revision": "Ne mogu da pronađem izmenu br. $1 na stranici pod nazivom „{{FULLPAGENAME}}“.\n\nOvo se obično dešava kada pratite zastarjelu vezu do stranice koja je obrisana.\nViše informacija možete pronaći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} evidenciji brisanja].",
        "userpage-userdoesnotexist": "Korisnički račun \"<nowiki>$1</nowiki>\" nije registrovan.\nMolimo provjerite da li želite napraviti/izmijeniti ovu stranicu.",
        "userpage-userdoesnotexist-view": "Korisnički račun \"$1\" nije registrovan.",
        "blocked-notice-logextract": "Ovaj korisnik je trenutno blokiran.\nPosljednje stavke evidencije blokiranja možete pogledati ispod:",
        "clearyourcache": "'''Napomena:''' Nakon snimanja možda ćete trebate očistiti cache svog preglednika kako biste vidjeli promjene.\n* '''Firefox / Safari:''' držite ''Shift'' i pritisnite ''Reload'', ili pritisnite bilo ''Ctrl-F5'' ili ''Ctrl-R'' (''Command-R'' na Macu)\n* '''Google Chrome:''' pritisnite ''Ctrl-Shift-R'' (''Command-Shift-R'' na Macu)\n* '''Internet Explorer:''' držite ''Ctrl'' i kliknite ''Refresh'', ili pritisnite ''Ctrl-F5''\n* '''Opera:''' očistite međuspremnik u ''Tools → Preferences''",
-       "usercssyoucanpreview": "'''Sugestija:''' Koristite 'Prikaži izgled' dugme da testirate svoj novi CSS prije nego što ga snimite.",
-       "userjsyoucanpreview": "'''Sugestija:''' Koristite 'Prikaži izgled' dugme da testirate svoj novi JS prije nego što ga snimite.",
+       "usercssyoucanpreview": "'''Sugestija:''' Koristite dugme \"{{int:showpreview}}\" da testirate svoj novi CSS prije nego što sačuvate.",
+       "userjsonyoucanpreview": "'''Sugestija:''' Koristite dugme \"{{int:showpreview}}\" da testirate svoj novi JSON prije nego što sačuvate.",
+       "userjsyoucanpreview": "'''Sugestija:''' 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'''Još uvijek nije snimljen!'''",
+       "userjsonpreview": "<strong>Zapamite da je ovo samo test/pretpregled postavljenosti Vašeg JSON-a.\nJoš uvijek nije snimljena!</strong>",
        "userjspreview": "'''Zapamite da je ovo samo test/pretpregled Vaše JavaScript-e.'''\n'''Još uvijek nije snimljena!'''",
        "sitecsspreview": "'''Zapamtite ovo je samo izgled Vašeg CSS-a.'''\n'''Još uvijek nije snimljen!'''",
+       "sitejsonpreview": "<strong>Zapamtite ovo je samo izgled ove postavljenosti JSON-a. Još uvijek nije snimljen!</strong>",
        "sitejspreview": "'''Zapamtite ovo je samo izgled ovog koda JavaScripte.'''\n'''Još uvijek nije snimljen!'''",
-       "userinvalidconfigtitle": "'''Upozorenje:''' Nema skina pod imenom \"$1\".\nUpamtite da korisničke .css i .js stranice koriste naslov s malim slovom, npr. {{ns:user}}:Foo/monobook.css umjesto {{ns:user}}:Foo/Monobook.css.",
+       "userinvalidconfigtitle": "<strong>Upozorenje:</strong> Nema skina pod imenom \"$1\".\nUpamtite da korisničke .css, .json i .js stranice koriste naslov s malim slovom, npr. {{ns:user}}:Foo/vector.css umjesto {{ns:user}}:Foo/Vector.css.",
        "updated": "(Osvježeno)",
        "note": "'''Napomena:'''",
        "previewnote": "<strong>Ne zaboravite da je ovo samo pregled</strong>\nIzmjene stranice nisu još sačuvane!",
        "continue-editing": "Idi na područje uređivanja",
        "previewconflict": "Ovaj pretpregled reflektuje tekst u gornjem polju\nkako će izgledati ako pritisnete \"Snimi stranicu\".",
-       "session_fail_preview": "'''Izvinjavamo se! Nismo mogli obraditi vašu izmjenu zbog gubitka podataka o prijavi. Molimo pokušajte ponovno. Ako i dalje ne bude radilo, pokušajte se [[Special:UserLogout|odjaviti]] i ponovno prijaviti.'''",
+       "session_fail_preview": "Nažalost, nisam mogao obraditi izmjenu zbog gubitka podataka o sesiji.\n\nMožda ste odjavljeni. <strong>Provjerite jeste li i dalje prijavljeni i pokušajte ponovno.<strong>\nAko se problem nastavi pojavljivati, [[Special:UserLogout|odjavite se]] i ponovno prijavite, te provjerite da preglednik dopušta kolačiće s ovog sajta.",
        "session_fail_preview_html": "'''Žao nam je! Nismo mogli da obradimo vašu izmjenu zbog gubitka podataka.'''\n\n''Zbog toga što {{SITENAME}} ima omogućen izvorni HTML, predpregled je sakriven kao predostrožnost protiv JavaScript napada.''\n\n'''Ako ste pokušali da napravite pravu izmjenu, molimo pokušajte ponovo. Ako i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite.'''",
        "token_suffix_mismatch": "'''Vaša izmjena nije prihvaćena jer je Vaš web preglednik ubacio znakove interpunkcije u token uređivanja.'''\nIzmjena je odbačena da bi se spriječilo uništavanje teksta stranice.\nTo se događa ponekad kad korisite problematični anonimni proxy koji je baziran na web-u.",
        "edit_form_incomplete": "'''Neki dijelovi uređivačkog obrasca nisu došli do servera; dvaput provjerite da su vaše izmjene nepromjenjene i pokušajte ponovno.'''",
        "yourtext": "Vaš tekst / Ваш текст",
        "storedversion": "Uskladištena verzija",
        "editingold": "'''PAŽNJA:  Vi mijenjate stariju reviziju ove stranice.\nAko je snimite, sve promjene učinjene od ove revizije će biti izgubljene.'''",
+       "unicode-support-fail": "Vaš preglednik ne podržava Unicode. On je neophodan za uređivanje stranica, pa zato neću moći sačuvati izmjenu.",
        "yourdiff": "Razlike / Разлике",
        "copyrightwarning": "Molimo da uzmete u obzir kako se smatra da su svi doprinosi u {{SITENAME}} izdani pod $2 (v. $1 za detalje).\nUkoliko ne želite da vaše pisanje bude nemilosrdno uređivano i redistribuirano po tuđoj volji, onda ga nemojte ovdje objavljivati.<br />\nTakođer obećavate kako ste ga napisali sami ili kopirali iz izvora u javnoj domeni ili sličnog slobodnog izvora.\n'''NEMOJTE SLATI RAD ZAŠTIĆEN AUTORSKIM PRAVIMA BEZ DOZVOLE!'''",
        "copyrightwarning2": "Zapamtite da svaki doprinos na stranici {{SITENAME}} može biti izmijenjen, promijenjen ili uklonjen od strane ostalih korisnika. Ako ne želite da ovo desi sa Vašim tekstom, onda ga nemojte slati ovdje.<br />\nTakođer nam garantujete da ste ovo Vi napisali, ili da ste ga kopirali iz javne domene ili sličnog slobodnog izvora informacija (pogledajte $1 za više detalja).\n'''NE ŠALJITE DJELA ZAŠTIĆENA AUTORSKIM PRAVOM BEZ DOZVOLE!'''",
        "longpageerror": "'''Greška: tekst koji ste uneli je veličine {{PLURAL:$1|jedan kilobajt|$1 kilobajta|$1 kilobajta}}, što je veće od {{PLURAL:$2|dozvoljenog jednog kilobajta|dozvoljena $2 kilobajta|dozvoljenih $2 kilobajta}}.'''\nStranica ne može biti sačuvana.",
        "readonlywarning": "<strong>Upozorenje: baza podataka je zaključana radi održavanja, tako da trenutno nećete moći da sačuvate izmene.</strong>\nMožda biste želeli sačuvati tekst za kasnije u nekoj tekstualnoj datoteci.\n\nAdministrator koji je zaključao bazu dao je sledeće objašnjenje: $1",
        "protectedpagewarning": "'''PAŽNJA: Ova stranica je zaključana tako da samo korisnici sa administratorskim privilegijama mogu da je mijenjaju.'''\nPosljednja stavka u registru je prikazana ispod kao referenca:",
-       "semiprotectedpagewarning": "'''Pažnja:''' Ova stranica je zaključana tako da je samo registrovani korisnici mogu uređivati.\nPosljednja stavka registra je prikazana ispod kao referenca:",
-       "cascadeprotectedwarning": "<strong>Upozorenje:</strong> Ova stranica je zaključana tako da je samo administratori mogu mijenjati, jer je ona uključena u {{PLURAL:$1|ovu, lančanu povezanu, zaštićenu stranicu|sljedeće, prenosivo povezane, zaštićene stranice}}:",
-       "titleprotectedwarning": "'''UPOZORENJE: Ova stranica je zaključana tako da su potrebna [[Special:ListGroupRights|posebna prava]] da se ona napravi.'''\nPosljednja stavka registra je prikazana ispod kao referenca:",
+       "semiprotectedpagewarning": "<strong>Pažnja:</strong> Ova stranica je zaključana tako da je samo automatski potvrđeni korisnici mogu uređivati.\nPosljednja stavka registra je prikazana ispod kao referenca:",
+       "cascadeprotectedwarning": "<strong>Upozorenje:</strong> Ova stranica je zaključana tako da je samo korisnici sa [[Special:ListGroupRights|određenim pravima]] mogu mijenjati, jer je ona uključena u {{PLURAL:$1|sljedeću, prenosivo zaštićenu stranicu|sljedeće, prenosivo zaštićene stranice}}:",
+       "titleprotectedwarning": "<strong>Upozorenje: Ova stranica je zaključana tako da su potrebna [[Special:ListGroupRights|posebna prava]] da se ona napravi.</strong>\nPosljednja stavka registra je prikazana ispod kao referenca:",
        "templatesused": "{{PLURAL:$1|Šablon|Šabloni}} koji su upotrebljeni na ovoj stranici:",
        "templatesusedpreview": "{{PLURAL:$1|Šablon|Šabloni}} prikazani u ovom pregledu:",
        "templatesusedsection": "{{PLURAL:$1|Šablon|Šabloni}} korišteni u ovoj sekciji:",
        "permissionserrors": "Greška pri odobrenju",
        "permissionserrorstext": "Nemate dopuštenje da to uradite, iz {{PLURAL:$1|slijedećeg razloga|slijedećih razloga}}:",
        "permissionserrorstext-withaction": "Nemate dozvolu za $2, zbog {{PLURAL:$1|sljedećeg|sljedećih}} razloga:",
-       "contentmodelediterror": "Ne možete urediti ovu izmjenu jer je model sadržaja <code>$1</code>, a trenutni model sadržaja stranice je <code>$2</code>.",
+       "contentmodelediterror": "Ne možete urediti ovu izmjenu jer je njen sadržajni model <code>$1</code>, što se razlikuje od trenutnog sadržajnog modela stranice <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Upozorenje: Postavljate stranicu koja je prethodno brisana.'''\n\nRazmotrite da li je nastavljanje uređivanja ove stranice u skladu s pravilima.\nOvdje je naveden registar brisanja i premještanja s obrazloženjem:",
-       "moveddeleted-notice": "Ova stranica je obrisana.\nRegistar brisanja i premještanja stranice je prikazan ispod kao referenca.",
-       "moveddeleted-notice-recent": "Žao nam je, ova stranica je izbrisana u prošla 24 sata. \nNiže je navedena evidencija brisanja i premještanja.",
+       "moveddeleted-notice": "Ova stranica je obrisana.\nRegistar brisanja, zaštite i premještanja stranice je prikazan ispod.",
+       "moveddeleted-notice-recent": "Žao nam je, ova stranica je nedavno izbrisana (u prošla 24 sata). \nNiže je navedena evidencija brisanja, zaštite i premještanja.",
        "log-fulllog": "Vidi potpuni registar",
        "edit-hook-aborted": "Izmjena je poništena putem interfejsa.\nNije ponuđeno nikakvo objašnjenje.",
        "edit-gone-missing": "Stranica se nije mogla osvježiti.\nIzgleda da je obrisana.",
        "postedit-confirmation-created": "Stranica je stvorena.",
        "postedit-confirmation-restored": "Stranica je obnovljena.",
        "postedit-confirmation-saved": "Vaša izmjena je snimljena.",
+       "postedit-confirmation-published": "Vaša izmjena je objavljena.",
        "edit-already-exists": "Stranica nije mogla biti kreirana.\nIzgleda da već postoji.",
        "defaultmessagetext": "Uobičajeni tekst poruke",
        "content-failed-to-parse": "Ne mogu da raščlanim sadržaj tipa $2 za model $1: $3",
        "invalid-content-data": "Neispravni podaci sadržaja",
        "content-not-allowed-here": "Sadržaj modela „$1“ nije dozvoljen na stranici [[:$2]]",
        "editwarning-warning": "Ako napustite ovu stranicu, izgubićete sve izmene koje ste napravili.\nAko ste prijavljeni, možete onemogućiti ovo upozorenje u svojim podešavanjima, u odeljku \"{{int:prefs-editing}}\".",
+       "editpage-invalidcontentmodel-title": "Sadržajni model nije podržan",
+       "editpage-invalidcontentmodel-text": "Sadržajni model \"$1\" nije podržan.",
        "editpage-notsupportedcontentformat-title": "Format sadržaja nije podržan",
        "editpage-notsupportedcontentformat-text": "Format sadržaja $1 nije podržan modelom sadržaja $2.",
+       "slot-name-main": "Glavna",
        "content-model-wikitext": "wikitekst",
        "content-model-text": "obični tekst",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "content-json-empty-object": "Prazan objekat",
        "content-json-empty-array": "Prazan niz",
+       "deprecated-self-close-category": "Stranice s neispravnim samozatvorenim HTML oznakama",
+       "deprecated-self-close-category-desc": "Stranica sadrži neispravne samozatvorene HTML oznake, kao što su <code>&lt;b/></code> ili <code>&lt;span/></code>. Njihovo funkcioniranje uskoro će se promijeniti da bude u skladu sa specifikacijama za HTML5. Ovo znači da su zastarjeli i ne bi se trebali upotrebljavati u wikitekstu.",
        "duplicate-args-warning": "<strong>Upozorenje:</strong> [[:$1]] poziva na [[:$2]] sa više od jedne vrijednosti za parametar \"$3\". Koristit će se samo posljednja navedena vrijednost.",
        "duplicate-args-category": "Stranice sa istim argumentima kod poziva šablona",
        "duplicate-args-category-desc": "Stranica sadrži pozive šablona koji koriste argumente dvojnike, kao što su <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ili <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "post-expand-template-argument-warning": "'''Upozorenje:''' Ova stranica sadrži najmanje jedan argument u šablonu koji ima preveliku veličinu.\nOvakvi argumenti se trebaju izbjegavati.",
        "post-expand-template-argument-category": "Stranice koje sadrže nedostajuće argumente u šablonu",
        "parser-template-loop-warning": "Otkrivena kružna greška u šablonu: [[$1]]",
+       "template-loop-category": "Stranice sa šablonskim petljama",
        "parser-template-recursion-depth-warning": "Dubina uključivanja šablona prekoračena ($1)",
        "language-converter-depth-warning": "Prekoračena granica dubine jezičkog pretvarača ($1)",
        "node-count-exceeded-category": "Stranice sa prekoračenim brojem čvorova",
        "page_first": "prva",
        "page_last": "zadnja",
        "histlegend": "Odabir razlika: označite radio dugme verzija za usporedbu i pritisnite enter ili dugme na dnu.<br />\nObjašnjenje: '''({{int:cur}})''' = razlika sa trenutnom verzijom,\n'''({{int:last}})''' = razlika sa prethodnom verzijom, '''{{int:minoreditletter}}''' = manja izmjena.",
-       "history-fieldset-title": "Pretraga historije",
-       "history-show-deleted": "Samo obrisane",
+       "history-fieldset-title": "Pretraga izmjena",
+       "history-show-deleted": "Samo obrisane izmjene",
        "histfirst": "najstarije",
        "histlast": "najnovije",
        "historysize": "({{PLURAL:$1|1 bajt|$1 bajta|$1 bajtova}})",
-       "historyempty": "(prazno)",
+       "historyempty": "prazno",
        "history-feed-title": "Historija izmjena",
        "history-feed-description": "Historija promjena ove stranice na wikiju",
        "history-feed-item-nocomment": "$1 u $2",
        "rev-suppressed-unhide-diff": "Jedna od izmjena ove razlike je '''sakrivena'''.\nDetalji se nalaze u [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registru sakrivanja].\nIpak možete [$1 vidjeti ovu razliku] ako želite nastaviti.",
        "rev-deleted-diff-view": "Izmjena ove stranice je '''obrisana'''.\nMožete je pogledati; više detalja možete naći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registru brisanja].",
        "rev-suppressed-diff-view": "Izmena ove stranice je '''sakrivena'''.\nMožete je pogledati; više detalja možete naći u [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registru sakrivanja].",
-       "rev-delundel": "pokaži/sakrij",
+       "rev-delundel": "promijeni vidljivost",
        "rev-showdeleted": "Pokaži",
        "revisiondelete": "Obriši/vrati revizije",
-       "revdelete-nooldid-title": "Nije unesena tačna revizija",
+       "revdelete-nooldid-title": "Nevažeća odredišna izmjena",
        "revdelete-nooldid-text": "Niste odredili odredišnu verziju da se izvrši ova funkcija, ili ta verzija ne postoji, ili pokušavate sakriti trenutnu verziju.",
        "revdelete-no-file": "Navedena datoteka ne postoji.",
        "revdelete-show-file-confirm": "Da li ste sigurni da želite pogledati obrisanu reviziju datoteke \"<nowiki>$1</nowiki>\" od $2 u $3?",
        "revdelete-unsuppress": "Ukloni ograničenja na vraćenim revizijama",
        "revdelete-log": "Razlog:",
        "revdelete-submit": "Primijeni na odabrane {{PLURAL:$1|izmjena|izmjene}}",
-       "revdelete-success": "'''Vidljivost revizije uspješno postavljena.'''",
-       "revdelete-failure": "'''Zapisnik vidljivosti nije mogao biti postavljen:'''\n$1",
-       "logdelete-success": "'''Vidljivost evidencije uspješno postavljena.'''",
-       "logdelete-failure": "'''Registar vidljivosti nije mogao biti postavljen:'''\n$1",
-       "revdel-restore": "promijeni dostupnost",
+       "revdelete-success": "Vidljivost izmjene je ažurirana.",
+       "revdelete-failure": "Nije moguće ažurirati vidljivost izmjene:\n$1",
+       "logdelete-success": "Vidljivost evidencije postavljena.",
+       "logdelete-failure": "Registar vidljivosti nije mogao biti postavljen:\n$1",
+       "revdel-restore": "promijeni vidljivost",
        "pagehist": "Historija stranice",
        "deletedhist": "Izbrisana historija",
        "revdelete-hide-current": "Greška pri sakrivanju stavke od $2, $1: ovo je trenutna revizija.\nNe može biti sakrivena.",
        "mergehistory-empty": "Nema revizija za spajanje.",
        "mergehistory-done": "$3 {{PLURAL:$3|revizija|revizije|revizija}} stranice $1 uspješno spojeno u [[:$2]].",
        "mergehistory-fail": "Ne može se izvršiti spajanje historije, molimo provjerite opet stranicu i parametre vremena.",
+       "mergehistory-fail-bad-timestamp": "Vremenska oznaka je nevažeća.",
+       "mergehistory-fail-invalid-source": "Izvorna stranica nije važeća.",
+       "mergehistory-fail-invalid-dest": "Odredišna stranica je nevažeća.",
+       "mergehistory-fail-no-change": "Spajanje historije nije spojilo nijednu izmjenu. Provjerite stranicu i vremenski parametri.",
+       "mergehistory-fail-permission": "Nemate dopuštenje da spojite historiju.",
+       "mergehistory-fail-self-merge": "Izvorna i odredišna stranica su iste.",
+       "mergehistory-fail-timestamps-overlap": "Izvorne izmjene se preklapaju ili dolaze nakon odredišnih izmjena.",
        "mergehistory-fail-toobig": "Ne može se izvršiti spajanje historije jer će se više premjestiti više od ograničenja od $1 {{PLURAL:$1|revizije|revizija}}.",
        "mergehistory-no-source": "Izvorna stranica $1 ne postoji.",
        "mergehistory-no-destination": "Odredišna stranica $1 ne postoji.",
        "mergehistory-comment": "Spojeno [[:$1]] u [[:$2]]: $3",
        "mergehistory-same-destination": "Izvorne i odredišne stranice ne mogu biti iste",
        "mergehistory-reason": "Razlog:",
-       "mergelog": "Registar spajanja",
+       "mergelog": "Evidencija spajanja",
        "revertmerge": "Ukini spajanje",
        "mergelogpagetext": "Ispod je spisak nedavnih spajanja historija stranica.",
        "history-title": "Historija izmjena stranice \"$1\"",
        "difference-multipage": "(Razlika između stranica)",
        "lineno": "Linija $1:",
        "compareselectedversions": "Uporedi označene verzije",
-       "showhideselectedversions": "Pokaži/sakrij odabrane verzije",
+       "showhideselectedversions": "Promijeni vidljivost izabranih izmjena",
        "editundo": "ukloni ovu izmjenu - уклони ову измену",
        "diff-empty": "(nema razlike)",
        "diff-multi-sameuser": "({{PLURAL:$1|Nije prikazana jedna međuverzija|Nisu prikazane $1 međuverzije|Nije prikazano $1 međuverzija}} istog korisnika)",
        "diff-multi-otherusers": "({{PLURAL:$1|Nije prikazana jedna međuverzija|Nisu prikazane $1 međuverzije|Nije prikazano $1 međuverzija}} {{PLURAL:$2|jednog|$2}} korisnika)",
        "diff-multi-manyusers": "({{PLURAL:$1|Nije prikazana jedna međuverzija|Nisu prikazane $1 međuverzije|Nije prikazano $1 međuverzija}}) od strane {{PLURAL:$2|korisnika|korisnika}}",
+       "diff-paragraph-moved-tonew": "Pasus je premješten. Kliknite da pređete na njegovo novo mjesto.",
+       "diff-paragraph-moved-toold": "Pasus je premješten. Kliknite da pređete na njegovo staro mjesto.",
        "difference-missing-revision": "Ne mogu da pronađem {{PLURAL:$2|jednu izmenu|$2 izmene|$2 izmena}} od ove razlike ($1).\n\nOvo se obično dešava kada pratite zastarjelu vezu do stranice koja je obrisana.\nViše informacija možete pronaći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} evidenciji brisanja].",
-       "searchresults": "Rezultati pretrage",
-       "searchresults-title": "Rezultati pretrage za \"$1\"",
+       "searchresults": "Ishod pretrage",
+       "search-filter-title-prefix": "Traži stranice čiji naslov počinje s \"$1\"",
+       "search-filter-title-prefix-reset": "Pretraži sve stranice",
+       "searchresults-title": "Ishod pretrage za \"$1\"",
        "titlematches": "Naslov članka odgovara",
        "textmatches": "Tekst stranice odgovara",
        "notextmatches": "Tekst stranice ne odgovara",
        "nextn": "{{PLURAL:$1|slijedeći $1|slijedećih $1}}",
        "prev-page": "prethodna stranica",
        "next-page": "sljedeća stranica",
-       "prevn-title": "{{PLURAL:$1|Prethodni $1 rezultat|Prethodna $1 rezultata|Prethodnih $1 rezultata}}",
-       "nextn-title": "{{PLURAL:$1|Slijedeći $1 rezultat|Slijedeća $1 rezultata|Slijedećih $1 rezultata}}",
-       "shown-title": "Pokaži $1 {{PLURAL:$1|rezultat|rezultata}} po stranici",
+       "prevn-title": "{{PLURAL:$1|Prethodna $1 stavka|Prethodne $1 stavke|Prethodnih $1 stavka}}",
+       "nextn-title": "{{PLURAL:$1|Slijedeća $1 stavka|Slijedeće $1 stavke|Slijedećih $1 stavka}}",
+       "shown-title": "Pokaži $1 {{PLURAL:$1|stavku|stavka}} po stranici",
        "viewprevnext": "Pogledaj ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Postoji stranica pod nazivom \"[[:$1]]\" na ovoj wiki'''",
        "searchmenu-new": "<strong>Napravi stranicu \"[[:$1]]\" na ovoj wiki!</strong> {{PLURAL:$2|0=|Pogledajte također straniu pronađenu vašom pretragom.|Pogledajte također i vaše rezultate pretrage.}}",
        "searchprofile-advanced-tooltip": "Traži u ostalim imenskim prostorima",
        "search-result-size": "$1 ({{PLURAL:$2|1 riječ|$2 riječi}})",
        "search-result-category-size": "{{PLURAL:$1|1 član|$1 člana|$1 članova}} ({{PLURAL:$2|1 podkategorija|$2 podkategorije|$2 podkategorija}}, {{PLURAL:$3|1 datoteka|$3 datoteke|$3 datoteka}})",
-       "search-redirect": "(preusmjeravanje $1)",
+       "search-redirect": "(preusmjerenje sa $1)",
        "search-section": "(sekcija $1)",
        "search-category": "(kategorija $1)",
        "search-file-match": "(odgovara sadržaju datoteke)",
        "search-suggest": "Da li ste mislili: $1",
-       "search-rewritten": "Prikazuju se rezultati za $1. Umjesto toga pretraži $2.",
-       "search-interwiki-caption": "Srodni projekti",
+       "search-rewritten": "Ishod iz $1. Ili potražite ga $2.",
+       "search-interwiki-caption": "Ishod s bratskih projekata",
        "search-interwiki-default": "Rezultati od $1:",
        "search-interwiki-more": "(više)",
+       "search-interwiki-more-results": "više stavka",
        "search-relatedarticle": "Povezano",
        "searchrelated": "povezano",
        "searchall": "sve",
-       "showingresults": "Dole {{PLURAL:$1|je prikazan '''1''' rezultat|su prikazana '''$1''' rezultata|je prikazano '''$1''' rezultata}} počev od '''$2'''.",
-       "showingresultsinrange": "Ispod {{PLURAL:$1|je prikazan <strong>1</strong> rezultat|su prikazana <strong>$1</strong> rezultata|je prikazano <strong>$1</strong> rezultata}}, u rasponu od <strong>$2</strong> do <strong>$3</strong>.",
-       "search-showingresults": "{{PLURAL:$4|Rezultat <strong>$1</strong> od <strong>$3</strong>|Rezultati <strong>$1 - $2</strong> od <strong>$3</strong>}}",
-       "search-nonefound": "Nisu pronađeni rezultati koji odgovaraju upitu.",
-       "search-nonefound-thiswiki": "Nisu pronađeni rezultati koji odgovaraju upitu na ovom sajtu.",
+       "showingresults": "Dole {{PLURAL:$1|je prikazana <strong>1</strong> stavka|su prikazane <strong>$1</strong> stavke|je prikazano <strong>$1</strong> stavka}} počev od <strong>$2</strong>.",
+       "showingresultsinrange": "Ispod {{PLURAL:$1|je prikazana <strong>1</strong> stavka|su prikazane <strong>$1</strong> stavke|je prikazano <strong>$1</strong> stavka}}, u rasponu od <strong>$2</strong> do <strong>$3</strong>.",
+       "search-showingresults": "{{PLURAL:$4|Stavka <strong>$1</strong> od <strong>$3</strong>|Stavke <strong>$1 - $2</strong> od <strong>$3</strong>}}",
+       "search-nonefound": "Nisu pronađene ishodne stavke koji odgovaraju upitu.",
+       "search-nonefound-thiswiki": "Nisu pronađene stavke koji odgovaraju upitu na ovom sajtu.",
        "powersearch-legend": "Napredna pretraga",
        "powersearch-ns": "Pretraga u imenskim prostorima:",
        "powersearch-togglelabel": "Označi:",
        "search-external": "Vanjska/spoljna pretraga",
        "searchdisabled": "Pretraga teksta na ovoj Wiki je trenutno onemogućena.\nU međuvremenu možete pretraživati preko Googlea.\nUzmite u obzir da njegovi indeksi za ovu Wiki ne moraju biti ažurirani.",
        "search-error": "Dogodila se pogreška prilikom pretraživanja: $1",
+       "search-warning": "Došlo je do upozorenja prilikom pretraživanja: $1",
        "preferences": "Postavke",
        "mypreferences": "Postavke",
        "prefs-edits": "Broj izmjena:",
        "prefs-skin": "Izgled (skin)",
        "skin-preview": "Pregled",
        "datedefault": "Bez preferenci",
-       "prefs-labs": "Eksperimentalne mogućnosti",
+       "prefs-labs": "Probne mogućnosti",
        "prefs-user-pages": "Korisničke stranice",
        "prefs-personal": "Korisnički profil",
-       "prefs-rc": "Podešavanje nedavnih izmjena",
+       "prefs-rc": "Nedavne izmjene",
        "prefs-watchlist": "Lista praćenja",
        "prefs-editwatchlist": "Uredi popis praćenja",
        "prefs-editwatchlist-label": "Uredi unose na popisu praćenja:",
        "prefs-editwatchlist-clear": "očisti listu praćenja",
        "prefs-watchlist-days": "Broj dana za prikaz u spisku praćenja:",
        "prefs-watchlist-days-max": "(najviše $1 {{PLURAL:$1|dan|dana}})",
-       "prefs-watchlist-edits": "Najveći broj izmjena za prikaz u proširenom spisku praćenja:",
+       "prefs-watchlist-edits": "Najviše prikazanih izmjena na spisku praćenja:",
        "prefs-watchlist-edits-max": "Maksimalni broj: 1000",
        "prefs-watchlist-token": "Token spiska za praćenje:",
+       "prefs-watchlist-managetokens": "Upravljanje tokenima",
        "prefs-misc": "Razno / Разно",
        "prefs-resetpass": "Promijeni lozinku",
        "prefs-changeemail": "Promijeni ili ukloni adresu e-pošte",
        "stub-threshold-disabled": "Isključen/a",
        "recentchangesdays": "Broj dana za prikaz u nedavnim izmjenama:",
        "recentchangesdays-max": "(najviše $1 {{PLURAL:$1|dan|dana}})",
-       "recentchangescount": "Broj uređivanja za prikaz po pretpostavkama:",
-       "prefs-help-recentchangescount": "Ovo uključuje nedavne izmjene, historije stranice i registre.",
+       "recentchangescount": "Podrazumevani broj izmjena za prikaz u skorašnjim izmjenama, istorijama stranica i dnevnicima:",
+       "prefs-help-recentchangescount": "Najveći broj: 1000",
        "prefs-help-watchlist-token2": "Ovo je tajni ključ prema sažetku Vašeg popisa praćenja. Svaki suradnik kojem je poznat, moći će čitati Vaš popis praćenih stranica. Ne dijelite ga ni s kim. [[Special:ResetTokens|Kliknite ovdje ako ga želite ponovo postaviti]].",
        "savedprefs": "Vaša postavke su snimljene.",
-       "savedrights": "Korisnička prava {{GENDER:$1|korisnika|korisnice}} su snimljena.",
+       "savedrights": "Korisnička prava {{GENDER:$1|$1}} su snimljena.",
        "timezonelegend": "Vremenska zona / Временска зона",
        "localtime": "Lokalno vrijeme:",
        "timezoneuseserverdefault": "Koristi postavke wikija ($1)",
-       "timezoneuseoffset": "Ostalo (odredi odstupanje)",
+       "timezoneuseoffset": "Ostalo (odredi odstupanje ispod)",
+       "timezone-useoffset-placeholder": "Primjerne vrednosti: „-07:00” ili „01:00”",
        "servertime": "Vrijeme na serveru:",
        "guesstimezone": "Popuni iz preglednika",
        "timezoneregion-africa": "Afrika",
        "timezoneregion-indian": "Indijski okean",
        "timezoneregion-pacific": "Tihi okean",
        "allowemail": "Dozvoli e-mail od ostalih korisnika",
+       "email-allow-new-users-label": "Dozvoli e-mail od potpuno novih korisnika",
+       "email-blacklist-label": "Zabrani e-mail od sljedećih korisnika:",
        "prefs-searchoptions": "Pretraga",
        "prefs-namespaces": "Imenski prostori",
        "default": "standardno",
        "prefs-files": "Datoteke",
        "prefs-custom-css": "Prilagođeni CSS",
+       "prefs-custom-json": "Prilagođeni JSON",
        "prefs-custom-js": "Prilagođeni JS",
-       "prefs-common-config": "Zajednički CSS/JS za sve izglede (skinove):",
-       "prefs-reset-intro": "Možete koristiti ovu stranicu da poništite Vaše postavke na ovom sajtu na pretpostavljene vrijednosti.\nOvo se ne može vratiti unazad.",
+       "prefs-common-config": "Zajednički CSS/JSON/JavaScript za sve izglede (skinove):",
+       "prefs-reset-intro": "Možete koristiti ovu stranicu da poništite Vaše postavke na ovom wikiju na pretpostavljene vrijednosti.\nOvo se ne može vratiti unazad.",
        "prefs-emailconfirm-label": "E-mail potvrda:",
        "youremail": "Vaša e-pošta / Ваша е-пошта*",
        "username": "Ime {{GENDER:$1|korisnika|korisnice}}:",
        "prefs-memberingroups": "{{GENDER:$2|Korisnik|Korisnica}} je član {{PLURAL:$1|grupe|grupâ}}:",
+       "group-membership-link-with-expiry": "$1 (do $2)",
        "prefs-registration": "Vrijeme registracije:",
        "yourrealname": "Vaše ime / Ваше име*",
        "yourlanguage": "Jezik interfejsa / Језик интерфејса",
        "prefs-help-email-others": "Također možete da odaberete da vas drugi kontaktiraju putem vaše korisničke stranice ili stranice za razgovor bez otkrivanja vašeg identiteta.",
        "prefs-help-email-required": "Neophodno je navesti e-mail adresu.",
        "prefs-info": "Osnovne informacije",
-       "prefs-i18n": "Internacionalizacije",
+       "prefs-i18n": "Internacionalizacija",
        "prefs-signature": "Potpis",
        "prefs-dateformat": "Format datuma",
        "prefs-timeoffset": "Vremenska razlika",
        "prefs-advancedediting": "Opće opcije",
+       "prefs-developertools": "Razvojni alati",
        "prefs-editor": "Uređivač",
        "prefs-preview": "Pregled",
        "prefs-advancedrc": "Napredne opcije",
        "prefs-advancedwatchlist": "Napredne opcije",
        "prefs-displayrc": "Postavke displeja",
        "prefs-displaywatchlist": "Postavke prikaza",
+       "prefs-changesrc": "Prikazivanje izmjena",
+       "prefs-changeswatchlist": "Prikazivanje izmjena",
+       "prefs-pageswatchlist": "Praćene stranice",
        "prefs-tokenwatchlist": "Žeton",
        "prefs-diffs": "Razlike",
        "prefs-help-prefershttps": "Ova mogućnost će stupiti na snagu kod vaše sljedeće prijave.",
        "prefswarning-warning": "Napravili ste promjene u vašim postavkama koje još uvijek nisu sačuvane. Ako napustite ovu stranicu bez da pritisnete na \"$1\", postavke neće biti ažurirane.",
        "prefs-tabs-navigation-hint": "Savjet: Možete koristi lijevu i desnu navigacijsku tipku kako biste se kretali između tabova u popisu tabova.",
-       "userrights": "Postavke korisničkih prava",
-       "userrights-lookup-user": "Menadžment korisničkih prava",
+       "userrights": "Korisnička prava",
+       "userrights-lookup-user": "Izaberite korisnika",
        "userrights-user-editname": "Unesi korisničko ime:",
        "editusergroup": "Učitaj korisničke grupe",
        "editinguser": "Mijenjate korisnička prava {{GENDER:$1|korisnika|korisnice}} <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "Uredi korisničke grupe",
-       "saveusergroups": "Snimi korisničke grupe",
+       "viewinguserrights": "Pogled korisničkih prava {{GENDER:$1|korisnika|korisnice}} <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-editusergroup": "Uredi {{GENDER:$1|korisničke}} grupe",
+       "userrights-viewusergroup": "Pregled {{GENDER:$1|korisničkih}} grupa",
+       "saveusergroups": "Snimi {{GENDER:$1|korisničke}} grupe",
        "userrights-groupsmember": "Član:",
-       "userrights-groupsmember-auto": "Uključeni član od:",
-       "userrights-groups-help": "Možete promijeniti grupe kojima ovaj korisnik pripada:\n* Označeni kvadratić znači da je korisnik u toj grupi.\n* Neoznačen kvadratić znači da korisnik nije u toj grupi.\n* Oznaka * (zvjezdica) označava da Vi ne možete izbrisati ovu grupu ako je dodate i obrnutno.",
+       "userrights-groupsmember-auto": "Implicitan član od:",
+       "userrights-groups-help": "Možete promijeniti grupe kojima ovaj korisnik pripada:\n* Označeni kvadratić znači da je korisnik u toj grupi.\n* Neoznačen kvadratić znači da korisnik nije u toj grupi.\n* Zvjezdica (*) označava da ne možete izbrisati ovu grupu ako je dodate i obrnutno.\n* Taraba (#) označava da jedino možete odložiti vrijeme isteka članstva u ovoj grupi, ali ne možete ga ubrzati.",
        "userrights-reason": "Razlog:",
        "userrights-no-interwiki": "Nemate dopuštenja da uređujete korisnička prava na drugim wikijima.",
        "userrights-nodatabase": "Baza podataka $1 ne postoji ili nije lokalna baza.",
        "userrights-changeable-col": "Grupe koje možete mijenjati",
        "userrights-unchangeable-col": "Grupe koje ne možete mijenjati",
+       "userrights-expiry-current": "Ističe $1",
+       "userrights-expiry-none": "Ne ističe",
+       "userrights-expiry": "Ističe:",
+       "userrights-expiry-existing": "Postojeće vrijeme isticanja: $3, $2",
+       "userrights-expiry-othertime": "Drugo vrijeme:",
+       "userrights-invalid-expiry": "Vrijeme isticanja grupe \"$1\" nije ispravno.",
+       "userrights-expiry-in-past": "Vrijeme isticanja grupe \"$1\" je u prošlosti.",
+       "userrights-cannot-shorten-expiry": "Ne možete ubrzati istek članstva u grupi \"$1\". To mogu učiniti samo korisnici s dozvolom za dodavanje ili uklanjanje ove grupe.",
        "userrights-conflict": "Sukob u izmjeni korisničkih prava! Molimo da razmotrite i potvrdite Vaše promjene.",
        "group": "Grupa:",
        "group-user": "Korisnici",
        "group-autoconfirmed": "Potvrđeni korisnici",
        "group-bot": "Botovi",
        "group-sysop": "Administratori",
+       "group-interface-admin": "Administratori interfejsa",
        "group-bureaucrat": "Birokrati",
        "group-suppress": "Skrivači",
        "group-all": "(svi)",
        "group-autoconfirmed-member": "{{GENDER:$1|automatski potvrđen korisnik|automatski potvrđena korisnica|automatski potvrđen korisnik}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrator|administratorka|administrator}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrator interfejsa|administratorica interfejsa}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrat|birokratica|birokrat}}",
        "group-suppress-member": "{{GENDER:$1|skrivač|skrivačica}}",
        "grouppage-user": "{{ns:project}}:Korisnici",
        "grouppage-autoconfirmed": "{{ns:project}}:Potvrđeni korisnici",
        "grouppage-bot": "{{ns:project}}:Botovi",
        "grouppage-sysop": "{{ns:project}}:Administratori",
+       "grouppage-interface-admin": "{{ns:project}}:Administratori interfejsa",
        "grouppage-bureaucrat": "{{ns:project}}:Birokrati",
        "grouppage-suppress": "{{ns:project}}:Skrivač",
        "right-read": "Čitanje stranica",
        "right-createpage": "Pravljenje stranica (ne uključujući stranice za razgovor)",
        "right-createtalk": "Pravljenje stranica za razgovor",
        "right-createaccount": "Pravljenje korisničkog računa",
+       "right-autocreateaccount": "Automatska prijava s vanjskim korisničkim računom",
        "right-minoredit": "Označavanje izmjena kao malih",
        "right-move": "Premještanje stranica",
        "right-move-subpages": "Premještanje stranica sa svim podstranicama",
-       "right-move-rootuserpages": "Premještanje stranica osnovnih korisnika",
+       "right-move-rootuserpages": "Premještanje osnovnih korisničkih stranica",
        "right-move-categorypages": "Premještanje stranica kategorija",
        "right-movefile": "Premještanje datoteka",
-       "right-suppressredirect": "Ne pravi preusmjeravanje sa starog imena pri preusmjeravanju stranica",
+       "right-suppressredirect": "Ne pravi preusmjeravanje sa starog imena pri premještanju stranica",
        "right-upload": "Postavljanje datoteka",
        "right-reupload": "Postavljanje nove verzije datoteke",
        "right-reupload-own": "Postavljanje nove verzije datoteke koju je postavio korisnik",
        "right-reupload-shared": "Postavljanje novih lokalnih verzija datoteka identičnih onima u zajedničkoj ostavi",
        "right-upload_by_url": "Postavljanje datoteke sa URL adrese",
-       "right-purge": "Osvježavanje keša za stranice bez potvrde",
+       "right-purge": "Osvježavanje keša stranice",
        "right-autoconfirmed": "Izbjegavanje ograničenja stopa temeljenih na IP-u",
        "right-bot": "Postavljen kao automatski proces",
        "right-nominornewtalk": "Male izmjene na stranicama za razgovor ne uzrokuju obavještenje o novim porukama",
        "right-editsitejson": "Uređivanje JSON-a za cijelo wiki",
        "right-editsitejs": "Uređivanje JavaScripta za cijelo wiki",
        "right-editmyusercss": "Uredite svoje vlastite CSS datoteke",
+       "right-editmyuserjson": "Uređivanje vlastitih JSON datoteka",
        "right-editmyuserjs": "Uredite vlastite korisničke JavaScript datoteke",
        "right-viewmywatchlist": "Pregled vlastitog popisa praćenih stranica",
-       "right-editmywatchlist": "Uredite vlastiti spisak praćenja. Obratite pažnju da će neke akcije dodati stranice čak bez ovog prava.",
-       "right-viewmyprivateinfo": "Vidite svoje privatne podatke (npr. adresu e-pošte, stvarno ime)",
-       "right-editmyprivateinfo": "Uredite svoje privatne podatke (npr. adresa e-pošte, stvarno ime)",
-       "right-editmyoptions": "Uredite svoje postavke",
-       "right-rollback": "Brzo vraćanje izmjena na zadnjeg korisnika koji je uređivao određenu stranicu",
+       "right-editmywatchlist": "Uređivanje vlastitih praćenih. Obratite pažnju da će neke akcije dodati stranice čak bez ovog prava.",
+       "right-viewmyprivateinfo": "Pregledanje vlastitih ličnih podataka (npr. adresa e-pošte, stvarno ime)",
+       "right-editmyprivateinfo": "Uređivanje vlastitih ličnih podataka (npr. adresa e-pošte, stvarno ime)",
+       "right-editmyoptions": "Uređivanje vlastitih postavki",
+       "right-rollback": "Brzo vraćanje izmjena posljednjeg korisnika koji je uređivao određenu stranicu",
        "right-markbotedits": "Označavanje vraćenih izmjena kao izmjene bota",
        "right-noratelimit": "Izbjegavanje ograničenja uzrokovanih brzinom",
        "right-import": "Uvoz stranica iz drugih wikija",
        "right-override-export-depth": "Izvoz stranica uključujući povezane stranice do dubine od 5 linkova",
        "right-sendemail": "Slanje e-maila drugim korisnicima",
        "right-managechangetags": "Pravljenje i (de)aktiviranje [[Special:Tags|oznaka]]",
-       "right-applychangetags": "Primijeni [[Special:Tags|oznake]] na nečije izmjene",
+       "right-applychangetags": "Primjenjivanje [[Special:Tags|oznaka]] na nečije izmjene",
        "right-changetags": "Dodavanje ili uklanjanje raznih [[Special:Tags|oznaka]] na pojedinačnim verzijama i unosima zapisnika",
+       "right-deletechangetags": "Brisanje [[Special:Tags|oznaka]] iz baze podataka",
+       "grant-generic": "Zbir prava \"$1\"",
+       "grant-group-page-interaction": "Interakcija sa stranicama",
+       "grant-group-file-interaction": "Interakcija sa slikama i snimkama",
+       "grant-group-watchlist-interaction": "Interakcija s praćenima",
+       "grant-group-email": "Slanje e-pošte",
+       "grant-group-high-volume": "Izvršavanje velikog broja radnji",
+       "grant-group-customization": "Prilagodbe i postavke",
+       "grant-group-administration": "Izvršavanje administrativnih radnji",
+       "grant-group-private-information": "Pristupanje vašim ličnim podacima",
+       "grant-group-other": "Razne aktivnosti",
+       "grant-blockusers": "Blokiranje i deblokiranje korisnika",
+       "grant-createaccount": "Stvaranje računa",
+       "grant-createeditmovepage": "Pravljenje, uređivanje i premještanje stranica",
+       "grant-delete": "Brisanje stranica, izmjena i unosa u zapisnicima",
        "grant-editinterface": "Uređivanje imenskog prostora \"MediaWiki\" i JSON za cijelo wiki/za korisnika",
        "grant-editmycssjs": "Uređivanje Vašeg korisničkog CSS/JSON/JavaScripta",
+       "grant-editmyoptions": "Uređivanje vaših korisničkih podešavanja i JSON konfiguracije",
+       "grant-editmywatchlist": "Uređivanje Vaših praćenih",
        "grant-editsiteconfig": "Uređivanje CSS/JS za cijelo wiki i za korisnika",
-       "newuserlogpage": "Registar novih korisnika",
+       "grant-editpage": "Uređivanje postojećih stranica",
+       "grant-editprotected": "Uređivanje zaštićenih stranica",
+       "grant-highvolume": "Veliki broj izmjena",
+       "grant-oversight": "Skrivanje korisnika i izmjena",
+       "grant-patrol": "Patroliranje izmjena stranica",
+       "grant-privateinfo": "Pristupanje ličnim podacima",
+       "grant-protect": "Dodavanje i uklanjanje zaštita sa stranica",
+       "grant-rollback": "Vraćanje izmjena na stranicama",
+       "grant-sendemail": "Slanje e-maila drugim korisnicima",
+       "grant-uploadeditmovefile": "Postavljanje, zamjena i premještanje datoteka",
+       "grant-uploadfile": "Postavljanje novih datoteka",
+       "grant-basic": "Osnovna prava",
+       "grant-viewdeleted": "Pregled obrisanih datoteka i stranica",
+       "grant-viewmywatchlist": "Pregled vaših praćenja",
+       "grant-viewrestrictedlogs": "Pregledanje ograničenih unosa u zapisniku",
+       "newuserlogpage": "Evidencija novih korisnika",
        "newuserlogpagetext": "Ovo je evidencija registracije novih korisnika.",
        "rightslog": "Evidencija korisničkih prava",
        "rightslogtext": "Ovo je evidencija izmjene korisničkih prava.",
        "action-read": "čitanje ove stranice",
        "action-edit": "uređujete ovu stranicu",
-       "action-createpage": "stvaranje stranica",
-       "action-createtalk": "stvaranje stranica za razgovor",
+       "action-createpage": "stvaranje ove stranice",
+       "action-createtalk": "stvaranje ove stranice za razgovor",
        "action-createaccount": "stvaranje ovog korisničkog računa",
+       "action-autocreateaccount": "automatski napravite ovaj vanjski korisnički račun",
        "action-history": "gledate historiju ove stranice",
        "action-minoredit": "označavanje ove izmjene kao manje",
        "action-move": "premještanje ove stranice",
        "action-move-subpages": "premještanje ove stranice, i njenih podstranica",
        "action-move-rootuserpages": "premještanje osnovne stranice korisnika",
-       "action-move-categorypages": "pomakni stranice kategorije",
+       "action-move-categorypages": "premještanje kategorije",
        "action-movefile": "premjesti ovu datoteku",
        "action-upload": "postavljate ovu datoteku",
        "action-reupload": "postavljanje nove verzije datoteke",
        "action-upload_by_url": "postavljanje ove datoteke preko URL adrese",
        "action-writeapi": "korištenje ''write API'' opcije",
        "action-delete": "brisanje ove stranice",
-       "action-deleterevision": "brisanje ove izmjene",
+       "action-deleterevision": "brisanje izmjena",
+       "action-deletelogentry": "brisanje dnevničkih unosa",
        "action-deletedhistory": "gledanje obrisane historije ove stranice",
+       "action-deletedtext": "pregled teksta obrisanih izmjena",
        "action-browsearchive": "pretraživanje obrisanih stranica",
-       "action-undelete": "vraćanje ove stranice",
-       "action-suppressrevision": "pregledavanje i vraćanje ove skrivene izmjene",
+       "action-undelete": "vraćanje stranica",
+       "action-suppressrevision": "pregledavanje i vraćanje sakrivenih izmjena",
        "action-suppressionlog": "gledanje ove privatne evidencije",
        "action-block": "blokiranje uređivanja ovog korisnika",
        "action-protect": "promijeniti nivo zaštite ove stranice",
        "action-userrights-interwiki": "uređivanje korisničkih prava na drugim wikijima",
        "action-siteadmin": "zaključavanje i otključavanje baze podataka",
        "action-sendemail": "pošalji e-poštu",
-       "action-editmywatchlist": "uredite svoj spisak praćenja",
-       "action-viewmywatchlist": "pogledajte svoj spisak praćenja",
-       "action-viewmyprivateinfo": "pogledajte svoje privatne informacije",
-       "action-editmyprivateinfo": "uredite svoje privatne informacije",
-       "action-editcontentmodel": "uredi model sadržaja stranice",
-       "action-managechangetags": "napravite i uklonite oznake iz baze podataka",
+       "action-editmyoptions": "uređivanje vlastitih podešavanja",
+       "action-editmywatchlist": "uređivanje mojih praćenih",
+       "action-viewmywatchlist": "pregled vašeg spiska praćenja",
+       "action-viewmyprivateinfo": "pregled vaših ličnih podataka",
+       "action-editmyprivateinfo": "uređivanje vaših ličnih podataka",
+       "action-editcontentmodel": "uređivanje modela sadržaja stranice",
+       "action-managechangetags": "pravljenje ili (de)aktiviranje oznaka",
        "action-applychangetags": "dodajte oznake uz vaše izmjene",
        "action-changetags": "dodajte ili uklonite razne oznake na pojedinačnim verzijama i unosima u zapisnicima",
+       "action-deletechangetags": "brišete oznake iz baze podataka",
+       "action-purge": "preučitavanje ove stranice",
        "nchanges": "$1 {{PLURAL:$1|izmjena|izmjene|izmjena}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|izmjena od Vaše posljedne posjete}}",
        "enhancedrc-history": "historija",
        "recentchanges-legend": "Postavke za Nedavne promjene",
        "recentchanges-summary": "Na ovoj stranici možete pratiti nedavne izmjene.",
        "recentchanges-noresult": "Bez promjena tokom cijelog perioda koji ispunjava ove kriterije.",
+       "recentchanges-timeout": "Ovo pretraživanje je isteklo. Probajte s drugačijm parametrima.",
+       "recentchanges-network": "Zbog tehničke greške nisam mogao učitati ishod. Ponovo učitajte stranicu.",
+       "recentchanges-notargetpage": "Iznad unesite stranicu da biste vidjeli promjene povezane s njom.",
        "recentchanges-feed-description": "Praćenje nedavnih izmjena na ovom wikiju u ovom feedu.",
        "recentchanges-label-newpage": "Ovom izmjenom je stvorena nova stranica",
        "recentchanges-label-minor": "Ovo je manja izmjena",
        "recentchanges-label-bot": "Ovu je izmjenu učinio bot",
-       "recentchanges-label-unpatrolled": "Ova izmjena još nije patrolirana",
-       "recentchanges-label-plusminus": "Veličina stranice promijenila se za ovoliko bajtova",
+       "recentchanges-label-unpatrolled": "Ova izmjena još nije ispatrolirana",
+       "recentchanges-label-plusminus": "Promjena veličine stranice u bajtovima",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (također pogledajte [[Special:NewPages|spisak novih stranica]])",
+       "recentchanges-submit": "Prikaži",
+       "rcfilters-tag-remove": "Ukloni '$1'",
+       "rcfilters-legend-heading": "<strong>Spisak skraćenica:</strong>",
+       "rcfilters-other-review-tools": "Drugi alati za pregled",
+       "rcfilters-group-results-by-page": "Grupni ishod po stranicama",
+       "rcfilters-activefilters": "Aktivni filteri",
+       "rcfilters-activefilters-hide": "Sakrij",
+       "rcfilters-activefilters-show": "Prikaži",
+       "rcfilters-activefilters-hide-tooltip": "Sakrij područje aktivnih filtara",
+       "rcfilters-activefilters-show-tooltip": "Prikaži područje aktivnih filtara",
+       "rcfilters-advancedfilters": "Napredni filteri",
+       "rcfilters-limit-title": "Stavki za prikaz",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|izmjena|izmjene|izmjena}}, $2",
+       "rcfilters-date-popup-title": "Vremenski period za pretragu",
+       "rcfilters-days-title": "Nedavni dani",
+       "rcfilters-hours-title": "Nedavni sati",
+       "rcfilters-days-show-days": "{{PLURAL:$1|jedan dan|$1 dana}}",
+       "rcfilters-days-show-hours": "{{PLURAL:$1|jedan sat|$1 sata|$1 sati}}",
+       "rcfilters-highlighted-filters-list": "Istaknuto: $1",
+       "rcfilters-quickfilters": "Sačuvani filteri",
+       "rcfilters-quickfilters-placeholder-title": "Još nema sačuvanih filtera",
+       "rcfilters-quickfilters-placeholder-description": "Da biste sačuvali filterske psotavke kako biste ih koristili ponovo, kliknite ikonu notepad u području \"Aktivni filteri\" ispod.",
+       "rcfilters-savedqueries-defaultlabel": "Sačuvani filteri",
+       "rcfilters-savedqueries-rename": "Preimenuj",
+       "rcfilters-savedqueries-setdefault": "Postavi kao podrazumevano",
+       "rcfilters-savedqueries-unsetdefault": "Ukloni od podrazumevano",
+       "rcfilters-savedqueries-remove": "Izbriši",
+       "rcfilters-savedqueries-new-name-label": "Naziv",
+       "rcfilters-savedqueries-new-name-placeholder": "Opišite svrhu filtera",
+       "rcfilters-savedqueries-apply-label": "Napravi filter",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Napravi podrazumevani filter",
+       "rcfilters-savedqueries-cancel-label": "Otkaži",
+       "rcfilters-savedqueries-add-new-title": "Sačuvaj trenutne filterske postavke",
+       "rcfilters-savedqueries-already-saved": "Ovi filteri su već sačuvani. Promenite postavke da biste napravili novi sačuvan filter.",
+       "rcfilters-restore-default-filters": "Vrati podrazumevane filtere",
+       "rcfilters-clear-all-filters": "Očisti sve filtre",
+       "rcfilters-show-new-changes": "Pogl. najnovije izmjene",
+       "rcfilters-search-placeholder": "Filtriranje promene (koristite meni ili potražite za naziv filtera)",
+       "rcfilters-invalid-filter": "Nevažeći filter",
+       "rcfilters-empty-filter": "Nema aktivnih filtera. Prikazani su svi doprinosi.",
+       "rcfilters-filterlist-title": "Filteri",
+       "rcfilters-filterlist-whatsthis": "Kako ovo radi?",
+       "rcfilters-filterlist-feedbacklink": "Recite nam Vaše mišljenje o ovim filterskim alatkama",
+       "rcfilters-highlightbutton-title": "Istaćavanje ishoda",
+       "rcfilters-highlightmenu-title": "Izaberite boju",
+       "rcfilters-highlightmenu-help": "Izaberite boju da biste istaknuli ovo svojstvo",
+       "rcfilters-filterlist-noresults": "Nije pronađen nijedan filtar",
+       "rcfilters-noresults-conflict": "Nisam ništa našao jer su kriteriji pretrage sukobljeni.",
+       "rcfilters-state-message-subset": "Filter ne radi jer je njegov ishod već sadržan u {{PLURAL:$2|slijedećim sveobuhvatnijim filteru|slijedećim sveobuhvatnijim filterima}} (istaknite ga da biste ih raspoznali): $1",
+       "rcfilters-state-message-fullcoverage": "Odabir svih filtera u grupi isti je kao da niste odabrali nijedan, tako da ovaj filtar ne radi. Grupa uključuje: $1",
+       "rcfilters-filtergroup-authorship": "Autorstvo doprinosa",
+       "rcfilters-filter-editsbyself-label": "Vaše promjene",
+       "rcfilters-filter-editsbyself-description": "Vaši vlastiti doprinosi.",
+       "rcfilters-filter-editsbyother-label": "Tuđe promjene",
+       "rcfilters-filter-editsbyother-description": "Sve promjene osim Vaših.",
+       "rcfilters-filtergroup-userExpLevel": "Korisnička registracija i iskustvo",
+       "rcfilters-filter-user-experience-level-registered-label": "Registrirani",
+       "rcfilters-filter-user-experience-level-registered-description": "Prijavljeni urednici.",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Neregistrirani",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Urednici koji nisu prijavljeni.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Novajlije",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Registrovani urednici koji imaju manje od 10 izmjena ili 4 dana aktivnosti.",
+       "rcfilters-filter-user-experience-level-learner-label": "Učenici",
+       "rcfilters-filter-user-experience-level-learner-description": "Registrirani urednici čije je iskustvo između \"novajlija\" i \"iskusnih suradnika\".",
+       "rcfilters-filter-user-experience-level-experienced-label": "Iskusni korisnici",
+       "rcfilters-filter-user-experience-level-experienced-description": "Registrirani urednici s više od 500 izmjena i 30 dana aktivnosti.",
+       "rcfilters-filtergroup-automated": "Automatizirani doprinosi",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Izmjene napravljene automatiziranim alatima.",
+       "rcfilters-filter-humans-label": "Čovjek (ne bot)",
+       "rcfilters-filter-humans-description": "Izmjene koje su napravili ljudi.",
+       "rcfilters-filtergroup-reviewstatus": "Pregledanost",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Izmjene koje nisu ručno ili automatski označene patroliranim.",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "Nepatrolirano",
+       "rcfilters-filter-reviewstatus-manual-description": "Izmjene koje su ručno označene patroliranim.",
+       "rcfilters-filter-reviewstatus-manual-label": "Ručno patrolirano",
+       "rcfilters-filter-reviewstatus-auto-description": "Izmene naprednih korisnika čiji je rad automatski označen patroliranim.",
+       "rcfilters-filter-reviewstatus-auto-label": "Autopatrolirani",
+       "rcfilters-filtergroup-significance": "Značaj",
+       "rcfilters-filter-minor-label": "Manje izmjene",
+       "rcfilters-filter-minor-description": "Izmjene koje je autor označio kao manje.",
+       "rcfilters-filter-major-label": "Nemanje izmjene",
+       "rcfilters-filter-major-description": "Izmjene koje nisu označene kao manje.",
+       "rcfilters-filtergroup-watchlist": "Praćene stranice",
+       "rcfilters-filter-watchlist-watched-label": "Na popisu praćenja",
+       "rcfilters-filter-watchlist-watched-description": "Izmjene na stranicama iz praćenih.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nove promjene na praćenih",
+       "rcfilters-filter-watchlist-watchednew-description": "Izmjene praćenih stranica koje niste posjetili od vremena učinjenih izmjena.",
+       "rcfilters-filter-watchlist-notwatched-label": "Izvan praćenih",
+       "rcfilters-filter-watchlist-notwatched-description": "Sve osim promjena na stranicama koje pratite.",
+       "rcfilters-filtergroup-watchlistactivity": "Aktivnost u praćenih",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Neviđene promjene",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Promjene na stranicama koje niste posjetili otkako su napravljene.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Viđene izmjene",
+       "rcfilters-filter-watchlistactivity-seen-description": "Promjene na stranicama koje ste posjetili otkako su napravljene.",
+       "rcfilters-filtergroup-changetype": "Vrsta promjene",
+       "rcfilters-filter-pageedits-label": "Izmjene stranica",
+       "rcfilters-filter-pageedits-description": "Uređivanja wikisadržaja, rasprave, opisi kategorija...",
+       "rcfilters-filter-newpages-label": "Stvaranje stranica",
+       "rcfilters-filter-newpages-description": "Uređivanja kojima se stvaraju nove stranice.",
+       "rcfilters-filter-categorization-label": "Promjene kategorija",
+       "rcfilters-filter-categorization-description": "Zapisi iz stavljanja stranica u kategorije ili njihovo uklanjanje iz njih.",
+       "rcfilters-filter-logactions-label": "Zapisane radnje",
+       "rcfilters-filter-logactions-description": "Administrativni postupci, pravljenje računa, brisanje stranica, otpremanje...",
+       "rcfilters-filtergroup-lastRevision": "Posljednje revizije",
+       "rcfilters-filter-lastrevision-label": "Posljednja revizija",
+       "rcfilters-filter-lastrevision-description": "Samo najnovije revizije u stranici.",
+       "rcfilters-filter-previousrevision-label": "Nije posljednja revizija",
+       "rcfilters-filter-previousrevision-description": "Sve promjene koje nisu „poslednje revizije”.",
+       "rcfilters-filter-excluded": "Izuzeto",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:ne</strong> $1",
+       "rcfilters-exclude-button-off": "Izuzmi izabrano",
+       "rcfilters-exclude-button-on": "Izuzmi izabrano",
+       "rcfilters-view-tags": "Označena uređivanja",
+       "rcfilters-view-namespaces-tooltip": "Filtriraj ishod prema imenskom prostoru",
+       "rcfilters-view-tags-tooltip": "Filtriraj ishod prema uredničkoj oznaci",
+       "rcfilters-view-return-to-default-tooltip": "Nazad na glavni filterski meni",
+       "rcfilters-view-tags-help-icon-tooltip": "Saznajte više o Označenim izmjenama",
+       "rcfilters-liveupdates-button": "Ažuriranja uživo",
+       "rcfilters-liveupdates-button-title-on": "Isključi ažuriranja uživo",
+       "rcfilters-liveupdates-button-title-off": "Prikaži nove promjene uživo",
+       "rcfilters-watchlist-markseen-button": "Označi sve promjene viđenim",
+       "rcfilters-watchlist-edit-watchlist-button": "Uredi nadgledane",
+       "rcfilters-watchlist-showupdated": "Promjene na stranicama koje niste posjetili otkako su se izmjene dogodile su <strong>podebljanim slovima</strong>.",
+       "rcfilters-preference-label": "Koristi posrednik bez JavaScript-a",
+       "rcfilters-preference-help": "Učitavanje nedavnih promjena bez filterske pretrage ili mogućnosti isticanja.",
+       "rcfilters-watchlist-preference-label": "Koristi posrednik bez JavaScript-a",
+       "rcfilters-watchlist-preference-help": "Učitavanje praćenih bez filterske pretrage ili mogućnosti isticanja.",
+       "rcfilters-filter-showlinkedfrom-label": "Prikaži promjene na stranicama sa kojih dolaze veze",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Stranice sa kojih dolaze veze do</strong> izabrane stranice",
+       "rcfilters-filter-showlinkedto-label": "Prikaži promjene na stranicama ka kojima vode veze",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Stranice ka kojima vode veze sa</strong> izabrane stranice",
+       "rcfilters-target-page-placeholder": "Unesite ime stranice (ili kategorije)",
        "rcnotefrom": "Ispod {{PLURAL:$5|je izmjena|su izmjene}} od <strong>$3, $4</strong> (do <strong>$1</strong> prikazano).",
+       "rclistfromreset": "Resetiraj izbor datuma",
        "rclistfrom": "Prikaži nove poruke od / Прикажи нове поруке од $3 $2",
        "rcshowhideminor": "$1 male izmjene / мале измене",
        "rcshowhideminor-show": "Pokaži",
        "recentchangeslinked-feed": "Vezane izmjene",
        "recentchangeslinked-toolbox": "Vezane izmjene",
        "recentchangeslinked-title": "Izmjene vezane s \"$1\"",
-       "recentchangeslinked-summary": "Ova posebna stranica prikazuje promjene na povezanim stranicama.\nStranice koje su na vašem [[Special:Watchlist|spisku praćenja]] su '''podebljane'''.",
+       "recentchangeslinked-summary": "Unesite stranicu da biste vidjeli promjene na stranicama povezanim s ovom ili s nje. (Da biste vidjeli članove kategorije, unesite {{ns:category}}:Ime kategorije). Izmjene na stranicama na [[Special:Watchlist|praćenih]] su <strong>podebljane</strong>.",
        "recentchangeslinked-page": "Naslov stranice:",
        "recentchangeslinked-to": "Pokaži promjene stranica koji su povezane sa datom stranicom",
        "recentchanges-page-added-to-category": "[[:$1]] pridodano kategoriji",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] i [[Special:WhatLinksHere/$1|{{PLURAL:$2|stranica|$2 stranica}} {{PLURAL:$2|pridodana|pridodane}}]] kategoriji",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] stavljena u kategoriju, [[Special:WhatLinksHere/$1|ova stranica je uključena u druge stranice]]",
        "recentchanges-page-removed-from-category": "[[:$1]] uklonjeno iz kategorije",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] i {{PLURAL:$2|stranica|$2 stranica}} {{PLURAL:$2|uklonjena|uklonjenne}} iz kategorije",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] uklonjena iz kategorije, [[Special:WhatLinksHere/$1|ova stranica je uključena u druge stranice]]",
        "autochange-username": "MediaWiki automatska promjena",
        "upload": "Postavi datoteku",
        "uploadbtn": "Postavi datoteku",
        "reuploaddesc": "Vratite se na upitnik za slanje",
        "upload-tryagain": "Pošaljite izmijenjeni opis datoteke",
+       "upload-tryagain-nostash": "Pošalji preotpremljenu datoteku i izmenjen opis",
        "uploadnologin": "Niste prijavljeni / Нисте пријављени",
        "uploadnologintext": "Morate biti $1 da bi ste slali datoteke.",
        "upload_directory_missing": "Folder za postavljanje ($1) nedostaje i webserver ga ne može napraviti.",
        "upload-permitted": "{{PLURAL:$2|Podržana vrsta|Podržane vrste}} datoteka: $1.",
        "upload-preferred": "{{PLURAL:$2|Preferirana vrsta|Preferirane vrste}} datoteka: $1.",
        "upload-prohibited": "{{PLURAL:$2|Zabranjena vrsta|Zabranjene vrste}} datoteka: $1.",
-       "uploadlogpage": "Registar postavljanja",
+       "uploadlogpage": "Evidencija postavljanja",
        "uploadlogpagetext": "Ispod je popis najnovijih postavljanja datoteka.\nVidi [[Special:NewFiles|galeriju novih datoteka]] za slikovitiji pregled.",
        "filename": "Ime fajla / Име датотеке",
        "filedesc": "Sažetak - Опис",
        "file-thumbnail-no": "Naziv datoteke počinje sa <strong>$1</strong>.\nIzgleda da se radi o smanjenoj slici ''(\"thumbnail\")''.\nAko imate ovu sliku u punoj rezoluciji, postavite nju; ili promijenite naslov ove datoteke.",
        "fileexists-forbidden": "Datoteka sa ovim imenom već postoji i ne može biti presnimljena.\nAko i dalje želite da postavite ovu datoteku, molimo Vas da se vratite i pošaljete ovu datoteku pod novim imenom. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Datoteka sa ovim imenom već postoji u zajedničkoj ostavi; molimo Vas da se vratite i pošaljete ovu datoteku pod novim imenom. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "Datoteka je duplikat trenutne verzije <strong>[[:$1]]</strong>.",
+       "fileexists-duplicate-version": "Datoteka je duplikat {{PLURAL:$2|starije verzije|starijih verzija}} <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Ova datoteka je dvojnik {{PLURAL:$1|slijedećoj datoteci|slijedećim datotekama}}:",
        "file-deleted-duplicate": "Datoteka koje je identična ovoj datoteci ([[:$1]]) je ranije bila obrisana. Trebate provjeriti historiju brisanja te datoteke prije nego što nastavite sa njenim ponovnim postavljanjem.",
        "file-deleted-duplicate-notitle": "Datoteka identična ovoj datoteci je prethodno bila izbrisana, a naslov je bio sakriven.\nPrije nego što nastavite ponovno postavljanje trebali biste pitati nekoga sa mogućnošću pregleda sakrivenih podataka o datotekama.",
        "uploadwarning": "Upozorenje pri slanju",
        "uploadwarning-text": "Molimo izmijeniti opis datoteke ispod i pokušajte kasnije.",
+       "uploadwarning-text-nostash": "Preotpremite datoteku, izmijenite opis ispod i pokušajte ponovo.",
        "savefile": "Snimi datoteku",
        "uploaddisabled": "Slanje fajlova je isključeno",
        "copyuploaddisabled": "Postavljanje putem URL nije omogućeno.",
        "php-uploaddisabledtext": "Postavljanje datoteka preko PHP je onemogućeno. \nMolimo provjerite postavku za postavljanje datoteka.",
        "uploadscripted": "Ova datoteka sadrži HTML ili skriptni kod koji može izazvati grešku kod internet preglednika.",
        "upload-scripted-pi-callback": "Datoteka koja sadrži instrukcije za obradu XML stilskog oblika se ne može postaviti.",
+       "upload-scripted-dtd": "Nije moguće otpremanje SVG datoteka koje sadrže nestandardnu DTD deklaraciju.",
        "uploaded-script-svg": "Pronađen skriptni element \"$1\" u postavljenoj SVG datoteci.",
        "uploaded-hostile-svg": "Pronađen nesiguran CSS u stilskom elementu postavljene SVG datoteke.",
        "uploaded-event-handler-on-svg": "Nije dozvoljeno postavljanje atributa koji kontroliraju događaje <code>$1=\"$2\"</code> u SVG datotekama.",
-       "uploaded-href-unsafe-target-svg": "Pronađen href sa nesigurnom metom <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
+       "uploaded-href-attribute-svg": "<a> elementi se mogu povezati (href) samo s data: (umetnuta datoteka), http:// ili https://, ili pak odredištima koja su fragment (#, isti dokument). Za ostale elemente kao <image> dopušteni su samo data: i fragment. Umetnite slike prilikom izvoza SVG-a. Pronađeno je <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Našao sam href s nesigurnim podacima: URI-svrhu <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploaded-animate-svg": "Pronađena \"animate\" oznaka koja možda mijenja href koristeći se \"from\" atributom <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploaded-setting-event-handler-svg": "Postavljanje kontrole događaja je blokirano, pronađeno <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploaded-setting-href-svg": "Blokirano je korištenje \"set\" oznake kako bi se dodao \"href\" atribut glavnom elementu.",
        "upload-too-many-redirects": "URL sadrži previše preusmjerenja",
        "upload-http-error": "Desila se HTTP greška: $1",
        "upload-copy-upload-invalid-domain": "Kopije postavljanja nisu dostupni na ovom domenu.",
+       "upload-foreign-cant-upload": "Ovaj wiki nije postavljen za otpermanje datoteka u traženi vanjski repozitorij.",
+       "upload-foreign-cant-load-config": "Nisam mogao učitati postavljenost otpremanja datoteka na vanjska spremišta.",
+       "upload-dialog-disabled": "Otpremanja datoteka korišćenjem ovog dijaloga su onemogućena na ovom wikiju.",
        "upload-dialog-title": "Postavi datoteku",
        "upload-dialog-button-cancel": "Otkaži",
+       "upload-dialog-button-back": "Nazad",
        "upload-dialog-button-done": "Urađeno",
        "upload-dialog-button-save": "Snimi",
        "upload-dialog-button-upload": "Postavi",
        "backend-fail-read": "Ne mogu da pročitam datoteku $1.",
        "backend-fail-create": "Ne mogu snimiti datoteku $1.",
        "backend-fail-maxsize": "Ne mogu snimiti datoteku $1 jer je veća od {{PLURAL:$2|$2 bajta|$2 bajta|$2 bajtova}}.",
-       "backend-fail-readonly": "Skladišna osnova „$1“ trenutno ne može da se zapisuje. Navedeni razlog glasi: „$2“",
+       "backend-fail-readonly": "Skladišna osnova „$1“ trenutno ne može da se zapisuje. Navedeni razlog glasi: <em>$2</em>",
        "backend-fail-synced": "Datoteka „$1“ je nedosledna između unutrašnjih skladišnih osnova",
        "backend-fail-connect": "Ne mogu da se povežem sa skladišnom osnovom „$1“.",
        "backend-fail-internal": "Došlo je do nepoznate greške u skladišnoj osnovi „$1“.",
        "lockmanager-fail-closelock": "Ne mogu da zatvorim katanac za „$1“.",
        "lockmanager-fail-deletelock": "Ne mogu da obrišem katanac za „$1“.",
        "lockmanager-fail-acquirelock": "Ne mogu da dobijem katanac za „$1“.",
-       "lockmanager-fail-openlock": "Ne mogu da otvorim katanac za „$1“.",
+       "lockmanager-fail-openlock": "Nisam mogao da otvorim katanac za „$1“. Provjerite je li direktorij za otpremanje ispravno postavljen i vaš svemrežni poslužitelj ima dozvolu za snimanje. Za više informacija posjetite https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
        "lockmanager-fail-releaselock": "Ne mogu da oslobodim katanac za „$1“.",
        "lockmanager-fail-db-bucket": "Ne mogu da kontaktiram s dovoljno katanaca u kanti $1.",
        "lockmanager-fail-db-release": "Ne mogu da oslobodim katance u bazi $1.",
        "uploadstash-summary": "Ova stranica daje pristup datotekama koje su postavljene (ili su u postupku postavljanja) ali još nisu objavljene na wiki. Ove datoteke nisu vidljive nikom osim korisniku koji ih je postavio.",
        "uploadstash-clear": "Očisti niz datoteka",
        "uploadstash-nofiles": "Nemate neobjavljenih datoteka",
-       "uploadstash-badtoken": "Izvršavanje ove akcije je bilo neuspješno, možda zato što su vaša uređivačka odobrenja istekla. Pokušajte ponovo.",
-       "uploadstash-errclear": "Brisanje neobjavljenih datoteka nije uspjelo.",
+       "uploadstash-badtoken": "Nisam uspio izvršiti zatraženu akciju, možda zato što su vaša sigurnosna šifra istekla. Pokušajte ponovo.",
+       "uploadstash-errclear": "Brisanje datoteka nije uspjelo.",
        "uploadstash-refresh": "Osvježi spisak datoteka",
+       "uploadstash-thumbnail": "pogl. minijaturu",
+       "uploadstash-exception": "Nisam mogao spremiti datoteku u spremište ($1): \"$2\".",
+       "uploadstash-bad-path": "Putanja ne postoji.",
+       "uploadstash-bad-path-invalid": "Putanja nije ispravna.",
+       "uploadstash-bad-path-unknown-type": "Nepoznata vrsta \"$1\".",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Neprepoznato ime minijature.",
+       "uploadstash-bad-path-no-handler": "Nisam našao obrad MIME tipa $1 datoteke $2.",
+       "uploadstash-bad-path-bad-format": "Ključ \"$1\" nije u odgovarajućem formatu.",
+       "uploadstash-file-not-found": "Ključ \"$1\" nije pronađen u skladištu.",
+       "uploadstash-file-not-found-no-thumb": "Nisam mogao dobiti minijaturu.",
+       "uploadstash-file-not-found-no-local-path": "Nema mjesne putanje za umanjeni element.",
+       "uploadstash-file-not-found-no-object": "Ne mogu napraviti mjesni datotečni objekat za minijaturu.",
+       "uploadstash-file-not-found-no-remote-thumb": "Nije uspjelo dobavljanje minijature: $1\nurl = $2",
+       "uploadstash-file-not-found-missing-content-type": "Nedostaje zaglavlje za sadržajni tip.",
+       "uploadstash-file-not-found-not-exists": "Nisam mogao pronaći putanju ili prostu datoteku.",
+       "uploadstash-file-too-large": "Ne mogu poslužiti datoteku veću od $1 {{PLURAL:$1|bajta|bajtova}}.",
+       "uploadstash-not-logged-in": "Nije prijavljen korisnik. Datoteke moraju pripadati korisnicima.",
+       "uploadstash-wrong-owner": "Ova datoteka ($1) ne pripada trenutnom korisniku.",
+       "uploadstash-no-such-key": "Nema takvog ključa ($1). Ne mogu ukloniti.",
+       "uploadstash-no-extension": "Nastavka je prazna.",
+       "uploadstash-zero-length": "Datoteka ima nultu dužinu.",
        "invalid-chunk-offset": "Nevaljana točka nastavka snimanja",
        "img-auth-accessdenied": "Pristup onemogućen",
-       "img-auth-nopathinfo": "Nedostaje PATH_INFO.\nVaš server nije podešen da prosleđuje ovakve podatke.\nMožda je zasnovan na CGI-ju koji ne podržava img_auth.\nPogledajte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Nedostaje informacija o putanji.\nVaš server mora biti namjesten da prosleđuje varijable REQUEST_URI i/ili PATH_INFO.\nAko je već namjesten, omogućite $wgUsePathInfo.\nPogl. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Zahtjevana putanja nije u direktorijumu podešenom za postavljanje.",
        "img-auth-badtitle": "Ne mogu napraviti valjani naslov iz \"$1\".",
        "img-auth-nologinnWL": "Niste prijavljeni i \"$1\" nije na spisku dozvoljenih.",
        "http-timed-out": "Istekao HTTP zahtjev.",
        "http-curl-error": "Greška pri otvaranju URLa: $1",
        "http-bad-status": "Nastao je problem tokom HTTP zahtjeva: $1 $2",
+       "http-internal-error": "Interna greška s HTMLom.",
        "upload-curl-error6": "Ovaj URL nije bilo moguće otvoriti",
        "upload-curl-error6-text": "URL koji je naveden nije dostupan.\nMolimo ponovno provjerite da li je URL ispravan i da li stranica radi.",
        "upload-curl-error28": "Vrijeme postavljanja isteklo",
        "listfiles_size": "Veličina",
        "listfiles_description": "Opis",
        "listfiles_count": "Verzije",
-       "listfiles-show-all": "Uključi starije verzije slika",
+       "listfiles-show-all": "Davaj i starije verzije datoteka",
        "listfiles-latestversion": "Trenutna verzija",
        "listfiles-latestversion-yes": "Da",
        "listfiles-latestversion-no": "Ne",
        "filehist-filesize": "Veličina datoteke",
        "filehist-comment": "Komentar",
        "imagelinks": "Upotreba datoteke",
-       "linkstoimage": "{{PLURAL:$1|Sljedeća stranica koristi|Sljedećih $1 stranica koriste}} ovu sliku:",
-       "linkstoimage-more": "Više od $1 {{PLURAL:$1|stranice povezuje|stranica povezuje}} na ovu datoteku.\nSlijedeći popis prikazuje {{PLURAL:$1|stranice koje|prvih $1 stranica koje}} vode na ovu datoteku.\n[[Special:WhatLinksHere/$2|Ovdje se nalazi]] potpuni popis.",
+       "linkstoimage": "{{PLURAL:$1|Sljedeća stranica koristi|Sljedećih $1 stranica koriste}} ovu datoteku:",
+       "linkstoimage-more": "Više od $1 {{PLURAL:$1|stranica koristi|stranice koriste|stranica koristi}} ovu datoteku.\nSlijedeći popis prikazuje {{PLURAL:$1|prvu stranicu koja koristi|prve $1 stranice koje koriste|prvih $1 stranica koje koriste}} datoteku.\nPotpuni popis naći ćete [[Special:WhatLinksHere/$2|ovdje]].",
        "nolinkstoimage": "Nema stranica koje koriste ovu datoteku.",
        "morelinkstoimage": "Vidi [[Special:WhatLinksHere/$1|ostale linkove]] prema ovoj datoteci.",
        "linkstoimage-redirect": "$1 (preusmjerenje datoteke) $2",
        "filerevert-submit": "Vrati",
        "filerevert-success": "'''Datoteka [[Media:$1|$1]]''' je vraćena na [$4 verziju od $3, $2].",
        "filerevert-badversion": "Ne postoji ranija lokalna verzija ove datoteke sa navedenim vremenskim podacima.",
+       "filerevert-identical": "Trenutna verzija datoteke identična je izabranoj.",
        "filedelete": "Obriši $1",
        "filedelete-legend": "Obriši datoteku",
        "filedelete-intro": "Brišete datoteku '''[[Media:$1|$1]]''' zajedno sa svom njenom historijom.",
        "pageswithprop-legend": "Stranice sa svojstvom stranice",
        "pageswithprop-text": "Ova stranica navodi stranice sa specifičnim svojstvom stranice.",
        "pageswithprop-prop": "Naziv svojstva:",
+       "pageswithprop-reverse": "Poređaj u suprotnom redosledu",
+       "pageswithprop-sortbyvalue": "Sortiraj po vrijednosti svojstva",
        "pageswithprop-submit": "Idi",
        "pageswithprop-prophidden-long": "vrijednost svojstva dugog teksta sakrivena ($1)",
        "pageswithprop-prophidden-binary": "vrijednost binarnog svojstva sakrivena ($1)",
        "doubleredirects": "Dvostruka preusmjerenja",
        "doubleredirectstext": "Ova stranica prikazuje stranice koje preusmjeravaju na druga preusmjerenja.\nSvaki red sadrži veze na prvo i drugo preusmjerenje, kao i na prvu liniju teksta drugog preusmjerenja, što obično daje \"pravi\" ciljni članak, na koji bi prvo preusmjerenje i trebalo da pokazuje.\n<del>Precrtane</del> stavke su riješene.",
        "double-redirect-fixed-move": "[[$1]] je bio premješten.\nAutomatski je ažuriran i sada preusmjeruje na [[$2]]",
-       "double-redirect-fixed-maintenance": "Automatski popravak dvostrukih datoteka od [[$1]] do [[$2]] u poslu održavanja.",
+       "double-redirect-fixed-maintenance": "Samopopravak dvostrukih preusmjerenja od [[$1]] do [[$2]] u poslu održavanja",
        "double-redirect-fixer": "Popravljač preusmjerenja",
        "brokenredirects": "Pokvarena preusmjerenja",
        "brokenredirectstext": "Slijedeća preusmjerenja vode na nepostojeće stranice:",
        "nrevisions": "$1 {{PLURAL:$1|revizija|revizije|revizija}}",
        "nimagelinks": "Koristi se na $1 {{PLURAL:$1|stranici|stranice|stranica}}",
        "ntransclusions": "koristi se na $1 {{PLURAL:$1|stranici|stranice|stranica}}",
-       "specialpage-empty": "Ne postoje rezultati za ovaj izvještaj.",
+       "specialpage-empty": "Pretraživanje ovog izvještaja nije dalo ništa.",
        "lonelypages": "Stranice - siročići",
        "lonelypagestext": "Slijedeće stranice nemaju linkove na ostalim stranicama na ovoj {{SITENAME}}.",
        "uncategorizedpages": "Nekategorisane stranice / Некатегорисане странице",
        "uncategorizedcategories": "Nekategorisane kategorije / Некатегорисане категорије",
        "uncategorizedimages": "Slike bez kategorije",
        "uncategorizedtemplates": "Šabloni bez kategorije",
+       "uncategorized-categories-exceptionlist": " # Sadrži popis kategorija koje se ne smiju spominjati u Special:UncategorizedCategories. Jedna u svakoj novoj liniji što počinje s \"*\". Redovi koji počinju drugim znakom (uključujući prazna mjesta) bit će zanemareni. Koristite \"#\" za pribjeleške.",
        "unusedcategories": "Neiskorištene kategorije",
        "unusedimages": "Neiskorišćene slike / Неискоришћене слике",
        "wantedcategories": "Tražene kategorije",
        "mostrevisions": "Stranice sa najviše izmjena",
        "prefixindex": "Sve stranice sa prefiksom",
        "prefixindex-namespace": "Sve stranice s predmetkom (imenski prostor $1)",
-       "prefixindex-strip": "Sakrij prefiks u spisku",
+       "prefixindex-submit": "Prikaži",
+       "prefixindex-strip": "Sakrij prefiks u ishodu",
        "shortpages": "Kratke stranice",
        "longpages": "Duge stranice / Дуге странице",
        "deadendpages": "Članci bez internih linkova / Чланци без интерних линкова",
        "deadendpagestext": "Slijedeće stranice nisu povezane s drugim stranicama na {{SITENAME}}.",
        "protectedpages": "Zaštićene stranice / Заштићене странице",
+       "protectedpages-filters": "Filteri:",
        "protectedpages-indef": "Samo neograničena zaštićenja",
        "protectedpages-summary": "Ovaj stranica navodi popis postojećih stranica koje su trenutno zaštićene. Za popis stranica zaštićenih od stvaranja, vidi [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Samo prenosive zaštite",
        "protectedpages-performer": "Zaštitio/la",
        "protectedpages-params": "Nivo zaštite",
        "protectedpages-reason": "Razlog",
+       "protectedpages-submit": "Prikaži stranice",
        "protectedpages-unknown-timestamp": "Nepoznato",
        "protectedpages-unknown-performer": "Nepoznati korisnik",
        "protectedtitles": "Zaštićeni naslovi",
        "protectedtitles-summary": "Na ovoj stranici se nalazi spisak trenutno zaštićenih naslova. Za spisak trenutno zaštićenih stranica vidi [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Nema naslova zaštićenih članaka sa ovim parametrima.",
+       "protectedtitles-submit": "Prikaži naslove",
        "listusers": "Spisak korisnika",
        "listusers-editsonly": "Pokaži samo korisnike koji su uređivali",
+       "listusers-temporarygroupsonly": "Prikaži samo korisnike u privremenim korisničkim grupama",
        "listusers-creationsort": "Sortiraj po datumu pravljenja",
        "listusers-desc": "Sortiraj u opadajućem redoslijedu",
        "usereditcount": "$1 {{PLURAL:$1|izmjena|izmjene}}",
        "usercreated": "{{GENDER:$3|je napravio|je napravila|je napravio}} dana $1 u $2",
        "newpages": "Nove stranice / Нове странице",
+       "newpages-submit": "Prikaži",
        "newpages-username": "Korisničko ime:",
        "ancientpages": "Najstarije stranice / Најстарије странице",
        "move": "Premjesti",
        "movethispage": "Premjesti ovu stranicu",
        "unusedimagestext": "Slijedeće datoteke postoje ali nisu uključene ni u jednu stranicu.\nMolimo obratite pažnju da druge web stranice mogu biti povezane s datotekom putem direktnog URLa, tako da i pored toga mogu biti prikazane ovdje pored aktivne upotrebe.",
+       "unusedimagestext-categorizedimgisused": "Sljedeće datoteke postoje, ali one nisu umetnute na nijednoj stranici. Kategorizirane slike smatraju se korištenim, iako nisu prisutne na bilo kojoj stranici.\nImajte na umu da druge web-lokacije mogu upućivati ​​na datoteku s neposrednim URL-om, pa se mogu navesti ovdje, iako se aktivno koriste.",
        "unusedcategoriestext": "Slijedeće stranice kategorija postoje iako ih ni jedan drugi članak ili kategorija ne koriste.",
        "notargettitle": "Nema cilja",
        "notargettext": "Niste naveli ciljnu stranicu ili korisnika\nna kome bi se izvela ova funkcija.",
        "querypage-disabled": "Ova posebna stranica je onemogućena jer smanjuje performanse.",
        "apihelp": "Pomoć s prilogom",
        "apihelp-no-such-module": "Modul \"$1\" nije pronađen.",
+       "apisandbox-intro": "Stranica služi za eksperimentiranje s <strong>API-jem MediaWiki</strong>.\n\nViše o korištenju ovog API-ja možete pronaći na [[mw:API:Main page|njegovoj dokumentaciji]]. Primjer: [https://www.mediawiki.org/wiki/API#A_simple_example preuzimanje sadržaja glavne stranice]. Odaberite radnju da biste vidjeli više primjera.\n\nImajte na umu da se ono što radite na ovoj stranici može odraziti na wikiju, iako je to pješčanik.",
+       "apisandbox-submit": "Napravi zahtjev",
+       "apisandbox-reset": "Očisti",
+       "apisandbox-retry": "Pokušaj ponovo",
        "booksources": "Književni izvori",
        "booksources-search-legend": "Traži književne izvore",
        "booksources-search": "Traži",
        "booksources-text": "Ispod se nalazi spisak vanjskih linkova na ostale stranice koje prodaju nove ili korištene knjige kao i stranice koje mogu da imaju važnije podatke o knjigama koje tražite:",
        "booksources-invalid-isbn": "Navedeni ISBN broj nije validan; molimo da provjerite da li je došlo do greške pri kopiranju iz prvobitnog izvora.",
+       "magiclink-tracking-rfc": "Stranice sa čarobnim vezama za zahtjeve za komentare",
+       "magiclink-tracking-rfc-desc": "Stranica koristi čarobne veze za zahtjeve za komentare (RFC). Pogl. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] kako biste saznali kako ih premjestiti.",
+       "magiclink-tracking-pmid": "Stranice sa sa čarobnim vezama za PMID",
+       "magiclink-tracking-pmid-desc": "Stranica koristi čarobne veze za PMID. Pogl. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] kako biste saznali kako ih premjestiti.",
+       "magiclink-tracking-isbn": "Stranice sa čarobnim vezama za ISBN",
+       "magiclink-tracking-isbn-desc": "Stranica koristi čarobne veze za ISBN. Pogl. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] kako biste saznali kako ih premjestiti.",
        "specialloguserlabel": "Izvršilac:",
        "speciallogtitlelabel": "Cilj (naslov ili {{ns:user}}:korisničko ime):",
        "log": "Evidencije",
+       "logeventslist-submit": "Prikaži",
+       "logeventslist-more-filters": "Prikaži dodatne evidencije:",
+       "logeventslist-patrol-log": "Evidencija patroliranja",
+       "logeventslist-tag-log": "Evidencija oznaka",
        "all-logs-page": "Sve evidencije - Све евиденције",
        "alllogstext": "Zajednički prikaz svih dostupnih evidencija sa {{SITENAME}}.\nMožete specificirati prikaz izabiranjem specifičnog spiska, korisničkog imena ili promjenjenog članka (razlikovati velika slova).",
-       "logempty": "Ne postoji takav zapis.",
+       "logempty": "Nema pronađenih stavki u evidenciji.",
        "log-title-wildcard": "Traži naslove koji počinju s ovim tekstom",
        "showhideselectedlogentries": "Prikaži/sakrij izabrane zapise u evidenciji",
        "log-edit-tags": "Uredi oznake izabranih zapisničkih unosa",
+       "checkbox-select": "Izbor: $1",
+       "checkbox-all": "Sve",
+       "checkbox-none": "Ništa",
+       "checkbox-invert": "Izaberi obrnuto",
        "allpages": "Sve stranice / Све странице",
        "nextpage": "Sljedeća strana ($1)",
        "prevpage": "Prethodna stranica ($1)",
        "cachedspecial-viewing-cached-ts": "Gledate keširanu verziju ove stranice, koja možda nije potpuno aktualna.",
        "cachedspecial-refresh-now": "Pogledaj najnoviju.",
        "categories": "Kategorije",
-       "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]].",
+       "categories-submit": "Prikaži",
+       "categoriespagetext": "Na wikiju {{PLURAL:$1|postoji sljedeća kategorija, i ista može biti neiskorištena|postoju sljedeće kategorije, i iste može biti neiskorištene}}.\nTakođer pogledajte [[Special:WantedCategories|tražene kategorije]].",
        "categoriesfrom": "Prikaži kategorije počev od:",
        "deletedcontributions": "Obrisani doprinosi korisnika",
        "deletedcontributions-title": "Obrisani doprinosi korisnika",
        "activeusers-intro": "Ovo je spisak korisnika koji su napravili neku aktivnost u {{PLURAL:$1|zadnji $1 dan|zadnja $1 dana|zadnjih $1 dana}}.",
        "activeusers-count": "{{PLURAL:$1|$1 izmjena|$1 izmjene|$1 izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 dana}}",
        "activeusers-from": "Prikaži korisnike koji počinju sa:",
+       "activeusers-groups": "Prikaži korisnike koji su članovi grupa:",
+       "activeusers-excludegroups": "Izuzmi korisnike koji su članovi grupa:",
        "activeusers-noresult": "Nije pronađen korisnik.",
+       "activeusers-submit": "Prikaži aktivne korisnike",
        "listgrouprights": "Prava korisničkih grupa",
        "listgrouprights-summary": "Slijedi spisak korisničkih grupa na ovoj wiki, s njihovim pravima pristupa.\nO svakoj od njih postoje i [[{{MediaWiki:Listgrouprights-helppage}}|dodatne informacije]].",
        "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Dodano pravo</span>\n* <span class=\"listgrouprights-revoked\">Uklonjeno pravo</span>",
        "listgrouprights-namespaceprotection-header": "Ograničenja imenskog prostora",
        "listgrouprights-namespaceprotection-namespace": "Imenski prostor",
        "listgrouprights-namespaceprotection-restrictedto": "Prava kojima se dozvoljava korisniku da uređuje",
+       "listgrants": "Dozvole",
        "listgrants-summary": "Ovo je popis dozvola, svaka sa svojim pravima. Korisnici mogu autorizirati prilozi koji će koristiti račun, ali uz ograničena prava u zavisnosti od tog koju dozvolu im korisnik omogući. Međutim, prilog koji djeluje u ime korisnika ograničen je na prava samog korisnika. Moguće je da postoje [[{{MediaWiki:Listgrouprights-helppage}}|dodatne informacije]] o pojedinim pravima.",
+       "listgrants-grant": "Dozvola",
+       "listgrants-rights": "Prava",
        "trackingcategories": "Praćenje kategorija",
        "trackingcategories-summary": "Ova stranica prikazuje prateće kategorije koje MediaWiki softver automatski popunjava. Njihovi nazivi se mogu promijeniti izmjenom odgovarajućih sistemskih poruka u imenskom prostoru {{ns:8}}.",
        "trackingcategories-msg": "Praćenje kategorije",
        "trackingcategories-name": "Ime poruke",
        "trackingcategories-desc": "Kriterij uključenja kategorije",
+       "restricted-displaytitle-ignored": "Stranice sa zanemarenim naslovima za prikaz",
+       "restricted-displaytitle-ignored-desc": "Stranica ima zanemaren <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> jer ne odgovara stvarnom naslovu stranice.",
        "noindex-category-desc": "Roboti ne indeksiraju stranicu jer u sebi ima magičnu riječ <code><nowiki>__NOINDEX__</nowiki></code>, te je u imenskom prostoru u kome ta oznaka nije dozvoljena.",
        "index-category-desc": "Stranica ima u sebi <code><nowiki>__INDEX__</nowiki></code> (te se nalazi u imenskom prostoru gdje je ta oznaka dozvoljena) pa je, samim tim, roboti indeksiraju.",
        "post-expand-template-inclusion-category-desc": "Veličina stranice prelazi <code>$wgMaxArticleSize</code> nakon proširenja svih šablona, te zbog toga neki šabloni nisu prošireni.",
        "emailccsubject": "Kopiranje Vaše poruke za $1: $2",
        "emailsent": "E-mail poruka poslata",
        "emailsenttext": "Vaša poruka je poslata e-poštom.",
-       "emailuserfooter": "Ovu e-poruku {{GENDER:$1|poslao|poslala}} je $1 {{GENDER:$2|korisniku|korisnici}} $2 pomoću funkcije \"{{int:emailuser}}\" s projekta {{SITENAME}}.",
+       "emailuserfooter": "Ovu e-poruku {{GENDER:$1|poslao|poslala}} je $1 {{GENDER:$2|korisniku|korisnici}} $2 pomoću funkcije \"{{int:emailuser}}\" na projektu {{SITENAME}}. Ako {{GENDER:$2|odgovorite}} na ovu e-poruku, {{GENDER:$2|Vaša}} će se poruka poslati pravo {{GENDER:$1|originalnom pošiljaocu|originalnoj pošiljatejici}} i otkrit ćete {{GENDER:$1|mu|joj}} {{GENDER:$2|svoju}} adresu.",
        "usermessage-summary": "Ostavljanje sistemske poruke.",
        "usermessage-editor": "Sistem za poruke",
        "watchlist": "Lista praćenja",
        "mywatchlist": "Lista 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 kako biste vidjeli ili uređivali svoje praćene.",
        "watchnologin": "Niste logovani / Нисте логовани",
        "addwatch": "Dodaj u popis praćenja",
        "addedwatchtext": "Stranica \"[[:$1]]\" i njena stranica za razgovor dodani su na vaš [[Special:Watchlist|spisak praćenja]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" i njena pridružena stranica dodane su na vaš [[Special:Watchlist|spisak praćenja]].",
        "addedwatchtext-short": "Stranica \"$1\" je dodana na vaš spisak praćenja.",
        "removewatch": "Ukloni sa spiska praćenja",
        "removedwatchtext": "Stranica „[[:$1]]“ i njena stranica za razgovor je uklonjena s vašeg [[Special:Watchlist|spiska nadgledanja]].",
+       "removedwatchtext-talk": "\"[[:$1]]\" i njena 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",
        "watchthispage": "Prati ovu stranicu",
        "unwatchthispage": "Prestani pratiti",
        "notanarticle": "Nije stranica sadržaja",
        "notvisiblerev": "Posljednja izmjena drugog korisnika je bila izbrisana",
-       "watchlist-details": "{{PLURAL:$1|$1 stranica|$1 stranice|$1 stranica }} na vašem spisku praćenja, ne računajući posebno stranice za razgovor.",
+       "watchlist-details": "Na vaših praćenih imate {{PLURAL:$1|$1 stranica|$1 stranice|$1 stranica}} (ne računajući stranice za razgovor).",
        "wlheader-enotif": "* Obavještavanje e-poštom je omogućeno.",
        "wlheader-showupdated": "* Stranice koje su izmijenjene od kad ste ih posljednji put posjetili su prikazane '''podebljanim slovima'''",
        "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.",
        "wlshowlast": "Prikaži posljednjih $1 sati $2 dana",
+       "watchlist-hide": "Sakrij",
+       "watchlist-submit": "Prikaži",
+       "wlshowtime": "Period za prikaz:",
+       "wlshowhideminor": "manje izmjene",
+       "wlshowhidebots": "botovi",
+       "wlshowhideliu": "registrovane korisnike",
+       "wlshowhideanons": "anonimne korisnike",
+       "wlshowhidepatr": "patrolirane izmjene",
+       "wlshowhidemine": "moje izmjene",
+       "wlshowhidecategorization": "kategorizaciju stranica",
        "watchlist-options": "Opcije liste praćenja",
        "watching": "Pratim... / Додавање на списак надгледања...",
        "unwatching": "Ne pratim…",
        "enotif_body_intro_moved": "{{SITENAME}} stranica $1 je premještena na $PAGEEDITDATE od {{GENDER:|korisnika|korisnice|korisnika}} $2, v. $3 za trenutnu verziju.",
        "enotif_body_intro_restored": "{{SITENAME}} stranica $1 je obnovljena na $PAGEEDITDATE od {{GENDER:|korisnika|korisnice|korisnika}} $2, v. $3 za trenutnu verziju.",
        "enotif_body_intro_changed": "{{SITENAME}} stranica $1 je izmijenjena na $PAGEEDITDATE od {{GENDER:|korisnika|korisnice|korisnika}} $2, v. $3 za trenutnu verziju.",
-       "enotif_lastvisited": "Pogledajte $1 za sve izmjene od vaše posljednje posjete.",
-       "enotif_lastdiff": "Vidi $1 da pregledate ovu promjenu.",
+       "enotif_lastvisited": "Sve promjene od vaše posljednje posjete naći ćete na $1",
+       "enotif_lastdiff": "Ovu promjenu možete vidjeti na $1",
        "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",
+       "enotif_minoredit": "Ovo je manja izmjena",
        "created": "Napravljen - Направљен",
        "changed": "promijenjena",
        "deletepage": "Izbrišite stranicu",
        "delete-confirm": "Brisanje \"$1\"",
        "delete-legend": "Obriši",
        "historywarning": "<strong>Upozorenje</strong>: Stranica koju želite da obrišete ima historiju sa otprilike $1 {{PLURAL:$1|revizijom|revizije|revizija}}:",
+       "historyaction-submit": "Prikaži",
        "confirmdeletetext": "Upravo ćete obrisati stranicu sa svom njenom historijom.\nMolimo da potvrdite da ćete to učiniti, da razumijete posljedice te da to činite u skladu sa [[{{MediaWiki:Policy-url}}|pravilima]].",
        "actioncomplete": "Radnja završena\n\nРадња завршена",
        "actionfailed": "Akcija nije uspjela",
        "dellogpage": "Evidencija brisanja",
        "dellogpagetext": "Ispod je spisak najskorijih brisanja.",
        "deletionlog": "Evidencija brisanja",
+       "log-name-create": "Evidencija stvaranja stranica",
+       "log-description-create": "Ispod se nalazi spisak najnovije stvaranja.",
+       "logentry-create-create": "$1 {{GENDER:$2|stvorio je|stvorila je}} stranicu $3",
        "reverted": "Vraćeno na prijašnju reviziju",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Ostali/dodatni razlog/zi:",
        "delete-toobig": "Ova stranica ima veliku historiju promjena, preko $1 {{PLURAL:$1|revizije|revizija}}.\nBrisanje takvih stranica nije dopušteno da bi se spriječilo slučajno preopterećenje servera na kojem je {{SITENAME}}.",
        "delete-warning-toobig": "Ova stranica ima veliku historiju izmjena, preko $1 {{PLURAL:$1|izmjene|izmjena}}.\nNjeno brisanje može dovesti do opterećenja operacione baze na {{SITENAME}};\nnastavite s oprezom.",
        "deleteprotected": "Ne možete obrisati ovu stranicu jer je zaštićena.",
-       "deleting-backlinks-warning": "'''Upozorenje:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Druge stranice]] sadrže link ili vode na stranicu koju brišete.",
+       "deleting-backlinks-warning": "<strong>Upozorenje:</strong>  Na stranicu koju želite izbrisati vode [[Special:WhatLinksHere/{{FULLPAGENAME}}|ostale stranice]] ili pak su uključene u nju.",
+       "deleting-subpages-warning": "<strong>Upozorenje:</strong> Stranica koju želite izbrisati ima [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|podstranicu|$1 podstranice|$1 podstranica|51=preko 50 podstranica}}]].",
        "rollback": "Vrati izmjene",
        "rollbacklink": "vrati",
        "rollbacklinkcount": "vrati $1 {{PLURAL:$1|izmjenu|izmjene|izmjena}}",
        "rollbacklinkcount-morethan": "vrati više od $1 {{PLURAL:$1|izmjene|izmjene|izmjena}}",
        "rollbackfailed": "Vraćanje nije uspjelo",
+       "rollback-missingparam": "Nedostaje potreban parametar za zahtjev.",
+       "rollback-missingrevision": "Ne mogu učitati podatke o izmjeni.",
        "cantrollback": "Nemoguće je vratiti izmjenu;\nposljednji kontributor je jedini na ovoj stranici.",
        "alreadyrolled": "Ne može se vratiti posljednja izmjena [[:$1]] od korisnika [[User:$2|$2]] ([[User talk:$2|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); neko drugi je već izmjenio ili vratio članak.\n\nPosljednja izmjena je bila od korisnika [[User:$3|$3]] ([[User talk:$3|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Sažetak izmjene je bio: <em>$1</em>.",
        "revertpage": "Vraćene izmjene [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]]) na posljednju izmjenu korisnika [[User:$1|$1]]",
        "revertpage-nouser": "Vraćene izmjene skrivenog korisnika na posljednju reviziju, koju je {{GENDER:$1|napravio|napravila}} [[User:$1|$1]]",
-       "rollback-success": "Vraćene su izmjene korisnika $1;\nvraćeno na posljednju verziju koju je snimio $2.",
+       "rollback-success": "Vraćene su izmjene korisnika {{GENDER:$3|$1}};\nvraćeno na posljednju verziju koju je snimio {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Greška u sesiji",
        "sessionfailure": "Izgleda da postoji problem sa vašom sesijom; ova akcija je otkazana kao prevencija protiv napadanja sesija. Kliknite \"back\" (''nazad'') i osvježite stranicu sa koje ste došli, i opet pokušajte.",
        "changecontentmodel": "Promijeni model sadržaja stranice",
        "changecontentmodel-title-label": "Naslov stranice",
        "changecontentmodel-model-label": "Novi model sadržaja",
        "changecontentmodel-reason-label": "Razlog:",
+       "changecontentmodel-submit": "Smijeni",
        "changecontentmodel-success-title": "Model sadržaja je promijenjen",
        "changecontentmodel-success-text": "Model sadržaja stranice [[:$1]] je promijenjen.",
        "changecontentmodel-cannot-convert": "Model sadržaja stranice [[:$1]] se ne može pretvoriti u vrstu $2.",
        "changecontentmodel-nodirectediting": "Model sadržaja $1 ne podržava izravno uređivanje",
-       "log-name-contentmodel": "Zapisnik promjene modela sadržaja",
-       "log-description-contentmodel": "Događaji koji su povezani s modelom sadržaja stranice",
+       "changecontentmodel-emptymodels-title": "Nema dostupnih modela sadržaja",
+       "changecontentmodel-emptymodels-text": "Model sadržaja stranice [[:$1]] se ne može pretvoriti ni u jedan drugi tip.",
+       "log-name-contentmodel": "Evidencija promjene modela sadržaja",
+       "log-description-contentmodel": "Ova stranica navodi promjene u modelu sadržaja stranica, kao i stranice stvorene s modelom sadržaja koji se razlikuje od predodređenog.",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|napravio je|napravila je}} stranicu $3 s nestandardnim modelom sadržaja \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|promijenio|promijenila}} je model sadržaja stranice $3 iz \"$4\" u \"$5\"",
        "logentry-contentmodel-change-revertlink": "vrati",
        "logentry-contentmodel-change-revert": "vrati",
        "modifiedarticleprotection": "promijenjen nivo zaštite za \"[[$1]]\"",
        "unprotectedarticle": "uklonjena zaštita za \"[[$1]]\"",
        "movedarticleprotection": "podešavanja zaštite premještena sa \"[[$2]]\" na \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Zaštićena}} stranica \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Izmijenjen nivo zaštite}} za \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Uklonjena zaštita}} sa stranice \"[[$1]]\"",
        "protect-title": "Promjena nivoa zaštite za \"$1\"",
        "protect-title-notallowed": "Pregled nivoa zaštite za „$1“",
        "prot_1movedto2": "[[$1]] premješten na [[$2]]",
        "undeletepagetext": "{{PLURAL:$1|Slijedeća $1 stranica je obrisana|Slijedeće $1 stranice su obrisane|Slijedećih $1 je obrisano}} ali su još uvijek u arhivi i mogu biti vraćene.\nArhiva moše biti periodično čišćena.",
        "undelete-fieldset-title": "Vraćanje revizija",
        "undeleteextrahelp": "Da vratite cijelu historiju članka, ostavite sve kutijice neoznačene i kliknite '''''{{int:undeletebtn}}'''''.\nDa bi izvršili selektivno vraćanje, odaberite kutijice koje odgovaraju revizijama koje želite vratiti, i kliknite '''''{{int:undeletebtn}}'''''.",
-       "undeleterevisions": "izmjena {{PLURAL:$1|izbrisana|izbrisane|izbrisano}}",
+       "undeleterevisions": "$1 {{PLURAL:$1|izmjena je obrisana|izmjene su obrisane|izmjena je obrisano}}",
        "undeletehistory": "Ako vratite stranicu, sve revizije će biti vraćene njenoj historiji.\nAko je nova stranica istog imena napravljena od brisanja, vraćene revizije će se pojaviti u njenoj ranijoj historiji.",
        "undeleterevdel": "Vraćanje obrisanog se neće izvršiti ako bi rezultiralo da zaglavlje stranice ili revizija datoteke bude djelimično obrisano.\nU takvim slučajevima, morate ukloniti označene ili otkriti sakrivene najskorije obrisane revizije.",
        "undeletehistorynoadmin": "Ova stranica je izbrisana.  \nRazlog za brisanje se nalazi ispod u sažetku, zajedno sa detaljima korisnika koji su uređivali ovu stranicu prije brisanja.  \nTekst izbrisane stranice je vidljiv samo administratorima.",
        "undelete-revision": "Obrisana revizija stranice $1 (dana $4, u $5) od strane $3:",
        "undeleterevision-missing": "Nevaljana ili nedostajuća revizija.\nMožda ste unijeli pogrešan link, ili je revizija vraćena ili uklonjena iz arhive.",
+       "undeleterevision-duplicate-revid": "Nisam mogao povratiti {{PLURAL:$1|jednu izmjenu|$1 izmjene|$1 izmjena}} jer se {{PLURAL:$1|njen|njihov}} <code>rev_id</code> već koristi.",
        "undelete-nodiff": "Nije pronađena ranija revizija.",
        "undeletebtn": "Vrati",
        "undeletelink": "pogledaj/vrati",
        "undelete-search-title": "Pretraga obrisanih stranica",
        "undelete-search-box": "Pretraga obrisanih stranica",
        "undelete-search-prefix": "Prikaži stranice koje počinju sa:",
+       "undelete-search-full": "Prikaži stranice koje sadrže:",
        "undelete-search-submit": "Traži",
        "undelete-no-results": "Nije pronađena odgovarajuća stranica u arhivi brisanja.",
        "undelete-filename-mismatch": "Ne može se vratiti revizija datoteke od $1: pogrešno ime datoteke",
        "anoncontribs": "Doprinosi",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Korisnički račun \"$1\" nije registrovan.",
+       "negative-namespace-not-supported": "Nisu podržani imenski prostori s negativnim vrijednostima.",
        "nocontribs": "Nisu nađene promjene koje zadovoljavaju ove uslove.",
        "uctop": "trenutno",
        "month": "Od mjeseca (i ranije):",
        "year": "Od godine (i ranije):",
+       "date": "Od datuma (i ranije):",
        "sp-contributions-newbies": "Pokaži doprinose samo novih korisnika",
        "sp-contributions-newbies-sub": "Prikaži samo doprinose novih korisnika",
        "sp-contributions-newbies-title": "Doprinosi novih korisnika",
        "sp-contributions-uploads": "postavljanja",
        "sp-contributions-logs": "registri",
        "sp-contributions-talk": "razgovor",
-       "sp-contributions-userrights": "postavke korisničkih prava",
+       "sp-contributions-userrights": "upravljanje pravima {{GENDER:$1|korisnika|korisnice}}",
        "sp-contributions-blocked-notice": "Ovaj korisnik je trenutno blokiran. \nPosljednje stavke evidencije blokiranja možete pogledati ispod:",
        "sp-contributions-blocked-notice-anon": "Ova IP adresa je trenutno blokirana.\nPosljednje stavke zapisnika blokiranja možete pogledati ispod:",
        "sp-contributions-search": "Pretraga doprinosa",
        "sp-contributions-username": "IP adresa ili korisničko ime:",
        "sp-contributions-toponly": "Prikaži samo izmjene koje su posljednje revizije",
        "sp-contributions-newonly": "Prikaži samo izmjene kojima su napravljene nove stranice",
+       "sp-contributions-hideminor": "Sakrij manje izmjene",
        "sp-contributions-submit": "Traži",
+       "sp-contributions-outofrange": "Nije moguće prikazati ishod. Traženi raspon IP adresa veći je od dopuštenog /$1 u CIDR-u.",
        "whatlinkshere": "Što upućuje ovamo",
        "whatlinkshere-title": "Stranice koje vode / Странице које воде до $1",
        "whatlinkshere-page": "Stranica:",
        "whatlinkshere-links": "← linkovi",
        "whatlinkshere-hideredirs": "$1 preusmjerenja",
        "whatlinkshere-hidetrans": "$1 uključenja",
-       "whatlinkshere-hidelinks": "$1 linkove",
+       "whatlinkshere-hidelinks": "$1 veze",
        "whatlinkshere-hideimages": "$1 veze do datoteke",
        "whatlinkshere-filters": "Filteri",
+       "whatlinkshere-submit": "Daj",
        "autoblockid": "Automatska blokada #$1",
        "block": "Blokiraj korisnika",
        "unblock": "Odblokiraj korisnika",
        "ipbreason": "Razlog:",
        "ipbreason-dropdown": "*Najčešći razlozi blokiranja\n**Unošenje netačnih informacija\n**Uklanjanje sadržaja stranica\n**Postavljanje spam vanjskih linkova\n**Ubacivanje gluposti/grafita\n**Osobni napadi (ili napadačko ponašanje)\n**Čarapare (zloupotreba više korisničkih računa)\n**Neprihvatljivo korisničko ime",
        "ipb-hardblock": "Onemogući prijavljene korisnike da uređuju sa ove IP adrese",
-       "ipbcreateaccount": "Onemogući stvaranje računa",
-       "ipbemailban": "Onemogući korisnika da šalje e-mail",
+       "ipbcreateaccount": "Stvaranje računa",
+       "ipbemailban": "Slanje e-pošte",
        "ipbenableautoblock": "Automatski blokiraj zadnju IP adresu koju je koristio ovaj korisnik i sve druge IP adrese s kojih je on pokušao uređivati",
        "ipbsubmit": "Blokirajte ovog korisnika",
        "ipbother": "Ostali period:",
        "ipboptions": "2 sata:2 hours,1 dan:1 day,3 dana:3 days,1 sedmica:1 week,2 sedmice:2 weeks,1 mjesec:1 month,3 mjeseca:3 months,6 mjeseci:6 months,1 godine:1 year,zauvijek:infinite",
        "ipbhidename": "Sakrij korisničko ime iz uređivanja i spiskova",
        "ipbwatchuser": "Prati korisničku stranicu i stranicu za razgovor ovog korisnika",
-       "ipb-disableusertalk": "Onemogući ovog korisnika da uređuje svoju vlastitu stranicu za razgovor dok je blokiran",
+       "ipb-disableusertalk": "Uređivanje vlastite stranice za razgovor",
        "ipb-change-block": "Ponovno blokiraj korisnika sa ovim postavkama",
        "ipb-confirm": "Potvrdite blokiranje",
+       "ipb-sitewide": "Na celom sajtu",
+       "ipb-partial": "Delimično",
+       "ipb-sitewide-help": "Svaka stranica wikija i sve druge doprinosačke akcije.",
+       "ipb-partial-help": "Pojedinačne stranice ili imenski prostori.",
+       "ipb-pages-label": "Stranice",
+       "ipb-namespaces-label": "Imenski prostori",
        "badipaddress": "Neodgovarajuća IP adresa / Неодговарајућа IP адреса",
        "blockipsuccesssub": "Blokiranje je uspjelo",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] je {{GENDER:$1|blokiran|blokirana|blokiran}}.<br />\nBlokiranja možete da pogledate [[Special:BlockList|ovde]].",
        "ipb-unblock": "Deblokiraj korisničko ime ili IP adresu",
        "ipb-blocklist": "Vidi postojeće blokade",
        "ipb-blocklist-contribs": "Doprinosi za {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "preostalo: $1",
+       "block-actions": "Radnje za blokiranje:",
        "block-expiry": "Ističe:",
+       "block-options": "Dodatne mogućnosti:",
+       "block-prevent-edit": "Uređivanje",
+       "block-reason": "Razlog:",
+       "block-target": "Korisničko ime ili IP adresa:",
        "unblockip": "Odblokiraj korisnika / Одблокирај корисника",
        "unblockiptext": "Upotrebite donji upitnik da bi ste vratili pravo pisanja ranije blokiranoj IP adresi ili korisničkom imenu.",
        "ipusubmit": "Ukloni ovu blokadu",
        "unblocked-id": "Blokada ID oznake $1 je uklonjena",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] je deblokiran.",
        "blocklist": "Blokirani korisnici",
+       "autoblocklist": "Autoblokovi",
+       "autoblocklist-submit": "Pretraži",
+       "autoblocklist-legend": "Ispis autoblokova",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Mjesni autoblok|Mjesni autoblokovi}}",
+       "autoblocklist-total-autoblocks": "Ukupno autoblokova: $1",
+       "autoblocklist-empty": "Spisak autoblokova je prazan.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Drugi autoblok|Drugi autoblokovi}}",
        "ipblocklist": "Blokirani korisnici",
        "ipblocklist-legend": "Traži blokiranog korisnika",
        "blocklist-userblocks": "Sakrij blokade računa",
        "createaccountblock": "blokirano stvaranje računa",
        "emailblock": "e-mail blokiran",
        "blocklist-nousertalk": "ne može uređivati vlastitu stranicu za razgovor",
+       "blocklist-editing": "uređivanje",
+       "blocklist-editing-sitewide": "uređivanje (na celom wikiju)",
+       "blocklist-editing-page": "stranice",
+       "blocklist-editing-ns": "imenski prostori",
        "ipblocklist-empty": "Spisak blokiranja je prazan.",
        "ipblocklist-no-results": "Tražena IP adresa ili korisničko ime nisu blokirani.",
        "blocklink": "blokiraj",
        "block-log-flags-hiddenname": "korisničko ime sakriveno",
        "range_block_disabled": "Administratorska mogućnost da blokira grupe je isključena.",
        "ipb_expiry_invalid": "Nevaljano vrijeme trajanja.",
+       "ipb_expiry_old": "Vrijeme isteka je u prošlosti.",
        "ipb_expiry_temp": "Sakrivene blokade korisničkih imena moraju biti stalne.",
        "ipb_hide_invalid": "Ne može se onemogućiti ovaj račun; on ima više od {{PLURAL:$1|jedne izmjene|$1 izmjena}}.",
+       "ipb_hide_partial": "Skrivene zabrane korisničkih imena moraju biti valjane za cjelo wiki.",
        "ipb_already_blocked": "\"$1\" je već blokiran",
        "ipb-needreblock": "$1 je već blokiran. \nDa li želite promijeniti postavke?",
        "ipb-otherblocks-header": "Ostale {{PLURAL:$1|blokada|blokade}}",
        "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 može deblokirati.",
        "ip_range_invalid": "Netačan raspon IP adresa.",
        "ip_range_toolarge": "Grupne blokade veće od /$1 nisu dozvoljene.",
+       "ip_range_exceeded": "IP-opseg prekoračuje gornju granicu. Dozvoljeni opseg: /$1.",
+       "ip_range_toolow": "IP-opsezi nisu dozvoljeni.",
        "proxyblocker": "Bloker proksija",
        "proxyblockreason": "Vaša IP adresa je blokirana jer je ona otvoreni proksi.  \nMolimo vas da kontaktirate vašeg davatelja internetskih usluga (Internet Service Provider-a) ili tehničku podršku i obavijestite ih o ovom ozbiljnom sigurnosnom problemu.",
        "sorbsreason": "Vaša IP adresa je prikazana kao otvoreni proxy u DNSBL koji koristi {{SITENAME}}.",
        "sorbs_create_account_reason": "Vaša IP adresa je prikazana kao otvoreni proxy u DNSBL korišten od {{SITENAME}}.\nNe možete napraviti račun",
+       "softblockrangesreason": "Anonimni doprinosi ne su dozvoljene iz vaše IP adrese ($1). Prijavite se.",
        "xffblockreason": "IP adresa koja postoji u zagljavlju X-Forwarded-For, ili Vaša ili od proxy servera koji koristite, je blokirana. Originalni razlog za blokiranje je bio: $1",
        "cant-see-hidden-user": "Korisnik kojeg pokušavate blokirati je već blokiran i sakriven. \nPoš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",
        "lockdbsuccesstext": "Baza podataka je zaključana.<br />\nSjetite se da je [[Special:UnlockDB|otključate]] nakon što dovršite održavanje.",
        "unlockdbsuccesstext": "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.",
+       "databaselocked": "Baza podataka već je zaključana.",
        "databasenotlocked": "Baza podataka nije zaključana.",
        "lockedbyandtime": "(od $1 dana $2 u $3)",
        "move-page": "Premještanje $1",
        "move-page-legend": "Premjesti stranicu",
        "movepagetext": "Korištenjem ovog formulara možete preimenovati stranicu, premještajući cijelu historiju na novo ime.\nČlanak pod starim imenom će postati stranica koja preusmjerava na članak pod novim imenom. \nMožete automatski izmjeniti preusmjerenje do izvornog naslova.\nAko se ne odlučite na to, provjerite [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|neispravna preusmjeravanja]].\nDužni ste provjeriti da svi linkovi i dalje nastave voditi na prave stranice.\n\nImajte na umu da članak '''neće''' biti preusmjeren ukoliko već postoji članak pod imenom na koje namjeravate da preusmjerite osim u slučaju stranice za preusmjeravanje koja nema nikakvih starih izmjena.\nTo znači da možete vratiti stranicu na prethodno mjesto ako pogriješite, ali ne možete zamijeniti postojeću stranicu.\n\n'''Pažnja!'''\nOvo može biti drastična i neočekivana promjena kad su u pitanju popularne stranice;\nMolimo dobro razmislite prije nego što preimenujete stranicu.",
        "movepagetext-noredirectfixer": "Koristeći obrazac ispod ćete preimenovati stranicu i premjestiti cijelu njenu historiju na novi naziv.\nStari naziv će postati preusmjerenje na novi naziv.\nMolimo provjerite da li postoje [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|nedovršena preusmjerenja]].\nVi ste za to odgovorni te morate provjeriti da li su linkovi ispravni i da li vode tamo gdje bi trebali.\n\nImajte na umu da stranica <strong>neće</strong> biti premještena ako već postoji stranica s tim imenom, osim ako je prazna ili je preusmjerenje ili nema ranije historije.\nOvo znali da možete preimenovati stranicu nazad gdje je ranije bila preimenovana ako ste pogriješili a ne možete ponovo preimenovati postojeću stranicu.\n\n<strong>Napomena:</strong>\nImajte na umu da premještanje popularnog članka može biti\ndrastična i neočekivana promjena za korisnike; molimo budite sigurni da ste shvatili posljedice prije nego što nastavite.",
-       "movepagetalktext": "Ako označite ovu kutijucu, pridružena stranica za razgovor će se automatski premjestiti na novi naslov, ukoliko ne-prazna stranica razgovor sa istim imenom već postoji. U tom slučaju ćete morati, ako želite, ručno premjestiti ili spojiti stranicu.",
+       "movepagetalktext": "Ako označite ovu kutijucu, pridružena stranica za razgovor će se automatski premjestiti na novi naslov, ukoliko ne-prazna stranica razgovor sa istim imenom već postoji. U tom slučaju ćete morati, ako želite, ručno premjestiti ili spojiti stranicu.\n\nU tom slučaju, morat ćete ručno premjestiti ili spojiti stranicu ako to želite.",
        "moveuserpage-warning": "'''Upozorenje:''' Premještate korisničku stranicu. Molimo da zapamtite da će se samo stranica premjestiti a korisnik se ''neće'' preimenovati.",
        "movecategorypage-warning": "<strong>Upozorenje:</strong> Premještate stranicu kategorije. Imajte na umu da će samo stranica biti premještena i da sve stranice u staroj kategoriji <em>neće</em> biti ponovo kategorirane u novu kategoriju.",
        "movenologintext": "Morate se registrovati ili [[Special:Userlogin|prijaviti]] kako biste premjestili članak.<br>\nМорате се регистровати или [[Special:Userlogin|пријавити]] како бисте преместили чланак.",
        "cant-move-to-user-page": "Nemate dopuštenje da premjestite stranicu na korisničku stranicu (osim na korisničku podstranicu).",
        "cant-move-category-page": "Nemate dopuštene da premještate stranice kategorija.",
        "cant-move-to-category-page": "Nemate dopuštenje da premjestite stranicu na stranicu kategorije.",
+       "cant-move-subpages": "Nemate dopuštenje da premještate podstranice.",
+       "namespace-nosubpages": "Imenski prostor \"$1\" ne dozvoljava podstranice.",
        "newtitle": "Novi naslov:",
        "move-watch": "Prati izvornu i ciljnu stranicu",
        "movepagebtn": "Premjesti stranicu",
        "pagemovedsub": "Premještanje uspjelo",
+       "cannotmove": "Stranica se ne može premjestiti s {{PLURAL:$1|sljedećeg razloga|sljedećih razloga}}:",
        "movepage-moved": "'''\"$1\" je premještena na \"$2\"'''",
        "movepage-moved-redirect": "Preusmjerenje je napravljeno.",
        "movepage-moved-noredirect": "Pravljenje preusmjerenja je onemogućeno.",
+       "movepage-delete-first": "Ciljna stranica ima previše izmjena za brisanje kao dio premještanja stranice. Prvo ručno izbrišite stranicu, pa pokušajte ponovo.",
        "articleexists": "Stranica pod tim imenom već postoji, ili je ime koje ste izabrali neispravno.\nMolimo Vas da izaberete drugo ime.",
        "cantmove-titleprotected": "Ne možete premjestiti stranicu na ovu lokaciju, jer je novi naslov zaštićen od pravljenja",
        "movetalk": "Premjesti pridruženu stranicu za razgovor",
        "movelogpagetext": "Ispod je spisak stranica koje su premještene.",
        "movesubpage": "{{PLURAL:$1|Podstranica|Podstranice}}",
        "movesubpagetext": "Ova stranica ima $1 {{PLURAL:$1|podstranicu|podstranice|podstranica}} prikazanih ispod.",
+       "movesubpagetalktext": "Ova stranica ima $1 {{PLURAL:$1|podstranicu prikazanu|podstranice prikazane|podstranica prikazanih}} ispod.",
        "movenosubpage": "Ova stranica nema podstranica.",
        "movereason": "Razlog:",
        "revertmove": "vrati - врати",
-       "delete_and_move_text": "==Brisanje neophodno==\nOdredišna stranica \"[[:$1]]\" već postoji.\nDa li je želite obrisati kako bi ste mogli izvršiti premještanje?",
+       "delete_and_move_text": "Odredišna stranica \"[[:$1]]\" već postoji.\nŽelite li je obrisati da biste oslobodili mjesto za premještanje?",
        "delete_and_move_confirm": "Da, izbriši stranicu - Да, избриши страницу",
        "delete_and_move_reason": "Obrisano da se oslobodi mjesto za premještanje iz „[[$1]]“",
-       "selfmove": "Izvorni i ciljani naziv su isti; strana ne može da se premjesti preko same sebe.",
+       "selfmove": "Naslov je istovetan;\nne mogu ga premjestiti preko same sebe.",
        "immobile-source-namespace": "Ne mogu premjestiti stranice u imenski prostor \"$1\"",
        "immobile-target-namespace": "Ne mogu se premjestiti stranice u imenski prostor \"$1\"",
        "immobile-target-namespace-iw": "Međuwiki link nije valjano odredište premještanja stranice.",
        "fix-double-redirects": "Ažuriraj sva preusmjerenja koja vode na originalni naslov",
        "move-leave-redirect": "Ostavi preusmjerenje",
        "protectedpagemovewarning": "'''Upozorenje:''' Ova stranica je zaključana tako da je mogu premještati samo korisnici sa ovlastima administratora.\nPosljednja stavka evidencije je prikazana ispod kao referenca:",
-       "semiprotectedpagemovewarning": "'''Napomena:''' Ova stranica je zaključana tako da je mogu uređivati samo registrovani korisnici.\nPosljednja stavka evidencije je prikazana ispod kao referenca:",
-       "move-over-sharedrepo": "== Datoteka postoji ==\n[[:$1]] postoji na dijeljenom repozitorijumu. Premještanje datoteke na ovaj naslov će prepisati dijeljenu datoteku.",
+       "semiprotectedpagemovewarning": "<strong>Napomena:</strong> Ova stranica je zaštićena, tako da je mogu premjestiti samo automatski potvrđeni korisnici.\nPosljednja stavka evidencije je prikazana ispod kao referenca:",
+       "move-over-sharedrepo": "[[:$1]] postoji na dijeljenom repozitorijumu. Ako datoteku premjestite na ovaj naslov, ona će spriječiti dijeljenu datoteku.",
        "file-exists-sharedrepo": "Ime datoteke koje ste odabrali je već korišteno u dijeljenom repozitorijumu.\nMolimo odaberite drugo ime.",
        "export": "Izvezite stranice",
        "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}}]].",
        "export-download": "Spremi kao datoteku",
        "export-templates": "Uključi šablone",
        "export-pagelinks": "Uključi povezane stranice do dubine od:",
+       "export-manual": "Dodajte stranice ručno:",
        "allmessages": "Sistemske poruke / Системске поруке",
        "allmessagesname": "Naziv",
        "allmessagesdefault": "Uobičajeni tekst",
        "thumbnail_dest_directory": "Ne može se napraviti odredišni folder",
        "thumbnail_image-type": "Tip slike nije podržan",
        "thumbnail_gd-library": "Nekompletna konfiguracija GD biblioteke: nedostaje funkcija $1",
+       "thumbnail_image-size-zero": "Veličina slike je nula.",
        "thumbnail_image-missing": "Čini se da datoteka nedostaje: $1",
        "thumbnail_image-failure-limit": "Bilo je previše nedavnih greška ($1 ili više) pri pravljenju umanjene slike. Ponovo pokušajte kasnije.",
        "import": "Uvoz stranica",
        "import-interwiki-history": "Kopiraj sve verzije historije za ovu stranicu",
        "import-interwiki-templates": "Uključi sve šablone",
        "import-interwiki-submit": "Uvezi - Увези",
+       "import-mapping-default": "Uvezi u predodređena mjesta",
+       "import-mapping-namespace": "Uvezi u imenski prostor:",
+       "import-mapping-subpage": "Uvezi kao podstranice sljedeće stranice:",
        "import-upload-filename": "Naziv datoteke:",
+       "import-upload-username-prefix": "Međuwiki-prefiks:",
+       "import-assign-known-users": "Dodijeli izmjene mjesnim korisnicima gde imenovani korisnik postoji mjesno",
        "import-comment": "Komentar:",
        "importtext": "Molimo Vas da izvezete datoteku iz izvornog wikija koristeći [[Special:Export|alat za izvoz]].\nSnimite je na Vašem računaru i pošaljite ovdje.",
        "importstart": "Uvoženje stranica…",
        "imported-log-entries": "{{PLURAL:$1|Uvezena $1 stavka registra|Uvezene $1 stavke registra|Uvezeno $1 stavki registra}}.",
        "importfailed": "Uvoz nije uspio: <nowiki>$1</nowiki>",
        "importunknownsource": "Nepoznat izvorni tip uvoza",
+       "importnoprefix": "Nema ukazanog međuwiki-prefiksa",
        "importcantopen": "Ne može se otvoriti uvozna datoteka",
        "importbadinterwiki": "Loš interwiki link",
        "importsuccess": "Uvoz dovršen!",
-       "importnosources": "Nisu definirani izvori za transwiki uvoz i neposredna postavljanja historije su onemogućena.",
+       "importnosources": "Nije definiran izvor za uvoz i neposredna postavljanja historije su onemogućena.",
        "importnofile": "Uvozna datoteka nije postavljena.",
        "importuploaderrorsize": "Postavljanje uvozne datoteke nije uspjelo.\nDatoteka je veća od dozvoljene veličine za postavljanje.",
        "importuploaderrorpartial": "Postavljanje uvozne datoteke nije uspjelo.\nDatoteka je samo djelomično postavljena.",
        "importuploaderrortemp": "Postavljanje uvozne datoteke nije uspjelo.\nNedostaje privremeni folder.",
        "import-parse-failure": "Greška pri parsiranju XML uvoza",
        "import-noarticle": "Nema stranice za uvoz!",
-       "import-nonewrevisions": "Sve revizije su prethodno uvežene.",
+       "import-nonewrevisions": "Nesam uvezio nijednu reviziju (sve su već prisutne ili izostavljene zbog grešaka)",
        "xml-error-string": "$1 na liniji $2, kolona $3 (bajt $4): $5",
        "import-upload": "Postavljanje XML podataka",
-       "import-token-mismatch": "Izgubljeni podaci sesije.\nMolimo pokušajte ponovno.",
+       "import-token-mismatch": "Izgubljeni podaci sesije.\n\nMožda ste odjavljeni. '''Molimo provjerite da li ste još uvijek prijavljeni i pokušajte ponovo'''.\nAko se problem i dalje pojavljuje, [[Special:UserLogout|odjavite se]] i ponovo prijavite se, i provjerite da li vaš pretraživač dozvoljava kolačiće sa ovog sajta.",
        "import-invalid-interwiki": "Ne može se uvesti iz navedenog wikija.",
-       "import-error-edit": "Stranica „$1“ nije uvezena jer vam nije dozvoljeno da je uređujete.",
-       "import-error-create": "Stranica „$1“ nije uvezena jer vam nije dozvoljeno da je napravite.",
-       "import-error-interwiki": "Ne mogu da uvezem stranicu „$1“ jer je njen naziv rezervisan za spoljno povezivanje (interwiki).",
-       "import-error-special": "Ne mogu da uvezem stranicu „$1“ jer ona pripada posebnom imenskom prostoru koje ne prihvata stranice.",
-       "import-error-invalid": "Ne mogu da uvezem stranicu „$1“ jer je njen naziv neispravan.",
+       "import-error-edit": "Stranica „$1“ nije uvezena jer vam nije dopušteno da je uređujete.",
+       "import-error-create": "Stranica „$1“ nije uvezena jer vam nije dopušteno da je napravite.",
+       "import-error-interwiki": "Stranica „$1“ nije uvezena jer je ime rezervirano za vanjske veze (međuprojektne).",
+       "import-error-special": "Stranica „$1” nije uvezena jer pripada posebnom imenskom prostoru koje ne prihvata stranice.",
+       "import-error-invalid": "Stranica „$1“ nije uvezena jer je ime nevažeće na ovom wikiju.",
        "import-error-unserialize": "Verzija $2 stranice \"$1\" ne može biti pročitana/uvezena. Zapisano je da verzija koristi $3 tip sadržaja u $4 formatu.",
+       "import-error-bad-location": "Verzija $2 koja koristi sadržajni model $3 ne može se skladirati na \"$1\" ovog wikija, jer taj model nije podržan na toj stranici.",
        "import-options-wrong": "{{PLURAL:$2|Pogrešna opcija|Pogrešne opcije}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Navedena osnovna stranica ima neispravan naslov.",
        "import-rootpage-nosubpage": "Imenski prostor „$1“ osnovne stranice ne dozvoljava podstranice.",
        "importlogpage": "Evidencija uvoza stranica",
        "importlogpagetext": "Administrativni uvozi stranica s historijom izmjena sa drugih wikija.",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|revizija|revizije|revizija}}",
-       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|revizija|revizije|revizija}} sa $2",
+       "import-logentry-upload-detail": "{{PLURAL:$1|Uvezena je jedna revizija|Uvezene su $1 revizije|Uvezeno su $1 revizija}}",
+       "import-logentry-interwiki-detail": "{{PLURAL:$1|Uvezena je jedna revizija|Uvezene su $1 revizije|Uvezeno su $1 revizija}} sa $2",
        "javascripttest": "Javaskript test",
+       "javascripttest-pagetext-unknownaction": "Nepoznata radnja „$1“.",
        "javascripttest-qunit-intro": "Pogledajte [$1 dokumentaciju za testiranje] na mediawiki.org.",
        "tooltip-pt-userpage": "{{GENDER:|Vaša korisnička}} stranica",
        "tooltip-pt-anonuserpage": "Korisnička stranica za ip koju Vi uređujete kao",
        "tooltip-pt-mycontris": "Lista {{GENDER:|vaših}} doprinosa",
        "tooltip-pt-anoncontribs": "Lista uređenja napravljenih s ove IP adrese",
        "tooltip-pt-login": "Predlažem da se prijavite; međutim, to nije obavezno",
+       "tooltip-pt-login-private": "Morate se prijaviti da biste koristili wiki",
        "tooltip-pt-logout": "Odjavite se",
        "tooltip-pt-createaccount": "Predlažemo vam da izradite račun i prijavite se, iako to nije obavezno",
        "tooltip-ca-talk": "Diskusija o stranici sadržaja",
        "tooltip-feed-rss": "RSS feed za ovu stranicu",
        "tooltip-feed-atom": "Atom feed za ovu stranicu",
        "tooltip-t-contributions": "Lista doprinosa {{GENDER:$1|ovog korisnika}}",
-       "tooltip-t-emailuser": "Pošaljite e-mail ovom korisniku",
+       "tooltip-t-emailuser": "Pošalji e-mail {{GENDER:$1|ovom korisniku|ovoj korisnici}}",
+       "tooltip-t-info": "Više informacija o ovoj stranici",
        "tooltip-t-upload": "Postavi datoteke",
        "tooltip-t-specialpages": "Lista svih posebnih stranica",
        "tooltip-t-print": "Verzija ove stranice za ispis",
        "tooltip-undo": "Vraća ovu izmjenu i otvara formu uređivanja u modu pretpregleda.\nDozvoljava unošenje razloga za to u sažetku.",
        "tooltip-preferences-save": "Snimi postavke",
        "tooltip-summary": "Unesite kratki sažetak",
+       "common.json": "/* JSON postavljen ovde će se koristiti za sve korisnike pri otvaranju svake stranice. */",
        "anonymous": "{{PLURAL:$1|Anonimni korisnik|$1 anonimna korisnika|$1 anonimnih korisnika}} projekta {{SITENAME}}",
        "siteuser": "{{SITENAME}} korisnik $1",
        "anonuser": "{{SITENAME}} anonimni korisnik $1",
        "lastmodifiedatby": "Ovu stranicu je posljednji put promjenio $3, u $2, $1",
        "othercontribs": "Bazirano na radu od strane korisnika $1.",
        "others": "ostali",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|korisnik|korisnika}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|korisnik}}|korisnika}} $1",
        "anonusers": "{{SITENAME}} {{PLURAL:$2|anonimni korisnik|anonimni korisnici}} $1",
        "creditspage": "Autori stranice",
        "nocredits": "Autori ove stranice nisu navedeni.",
        "pageinfo-display-title": "Prikaži naslov",
        "pageinfo-default-sort": "Podrazumijevani ključ sortiranja",
        "pageinfo-length": "Dužina stranice (u bajtovima)",
+       "pageinfo-namespace": "Imenski prostor",
        "pageinfo-article-id": "ID stranice",
        "pageinfo-language": "Jezik sadržaja stranice",
-       "pageinfo-robot-policy": "Status tražilice",
-       "pageinfo-robot-index": "Stranicu je moguće indeksirati",
-       "pageinfo-robot-noindex": "Ne može se indeksirati",
+       "pageinfo-language-change": "smijeni",
+       "pageinfo-content-model": "Model sadržaja stranice",
+       "pageinfo-content-model-change": "smijeni",
+       "pageinfo-robot-policy": "Indeksiranje od strane robota",
+       "pageinfo-robot-index": "Dozvoljeno",
+       "pageinfo-robot-noindex": "Nije dozvoljeno",
        "pageinfo-watchers": "Broj pratitelja stranice",
+       "pageinfo-visiting-watchers": "Broj pratilaca stranice što su posjetili nedavne izmjene",
        "pageinfo-few-watchers": "Manje od $1 {{PLURAL:$1|pratioca|pratilaca}}",
+       "pageinfo-few-visiting-watchers": "Ne znaje se je li promatrač posjećivao nedavne izmjene",
        "pageinfo-redirects-name": "Preusmjeravanja na ovu stranicu",
        "pageinfo-subpages-name": "Podstranice ove stranice",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|preusmjerenje|preusmjerenja|preusmjerenja}}; $3 {{PLURAL:$3|nepreusmjerenje|nepreusmjerenja|nepreusmjerenja}})",
        "pageinfo-protect-cascading-yes": "Da",
        "pageinfo-protect-cascading-from": "Stranice sa prenosivom zaštitom od",
        "pageinfo-category-info": "Informacije o kategoriji",
+       "pageinfo-category-total": "Ukupan broj članova",
        "pageinfo-category-pages": "Broj stranica",
        "pageinfo-category-subcats": "Broj potkategorija",
        "pageinfo-category-files": "Broj datoteka",
+       "pageinfo-user-id": "Korisnička naznaka",
+       "pageinfo-file-hash": "Tarabna vrijednost",
+       "pageinfo-view-protect-log": "Vidi evidenciju zaštićivanja ove stranice.",
        "markaspatrolleddiff": "Označi kao patrolirano",
        "markaspatrolledtext": "Označi ovu stranicu kao patroliranu",
+       "markaspatrolledtext-file": "Označi ovu verziju kao ispatroliranu",
        "markedaspatrolled": "Označeno kao patrolirano",
        "markedaspatrolledtext": "Izabrana revizija [[:$1]] je bila označena kao patrolirana.",
        "rcpatroldisabled": "Patroliranje nedavnih izmjena onemogućeno",
        "markedaspatrollederrornotify": "Nije uspjelo označavanje ove stranice kao patrolirane.",
        "patrol-log-page": "Evidencija patroliranja",
        "patrol-log-header": "Ovdje se nalazi evidencija patroliranih revizija.",
+       "confirm-markpatrolled-button": "U redu",
+       "confirm-markpatrolled-top": "Označiti izmjenu $3 stranice $2 ispatroliranom?",
        "deletedrevision": "Obrisana stara revizija $1",
        "filedeleteerror-short": "Greška pri brisanju datoteke: $1",
        "filedeleteerror-long": "Desile su se greške pri brisanju datoteke:\n\n$1",
        "previousdiff": "← Starija izmjena",
        "nextdiff": "Novija izmjena →",
        "mediawarning": "'''Upozorenje''': Ova datoteka sadrži loš kod.\nNjegovim izvršavanjem možete da ugrozite Vaš sistem.",
-       "imagemaxsize": "Ograničenje veličine slike:<br />''(za stranice opisa datoteke)''",
+       "imagemaxsize": "Ograničenje veličine slika na njihovim opisnim stranicama:",
        "thumbsize": "Veličina umanjenog prikaza:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|stranica|stranice|stranica}}",
        "file-info": "veličina datoteke: $1, MIME tip: $2",
        "svg-long-error": "Nevaljana SVG datoteka: $1",
        "show-big-image": "Izvorna datoteka",
        "show-big-image-preview": "Veličina ovog prikaza: $1.",
+       "show-big-image-preview-differ": "Veličina ovog $3-pregleda ove $2-datoteke: $1.",
        "show-big-image-other": "{{PLURAL:$2|Druga rezolucija|Druge rezolucije}}: $1.",
        "show-big-image-size": "$1 × $2 piksela",
        "file-info-gif-looped": "stalno iznova",
        "newimages-summary": "Ova posebna stranica prikazuje posljednje postavljene datoteke.",
        "newimages-legend": "Filter",
        "newimages-label": "Ime datoteke (ili dio imena):",
+       "newimages-user": "IP adresa ili korisničko ime",
+       "newimages-newbies": "Prikaži samo doprinose novih računa",
+       "newimages-showbots": "Prikaži otpremanja botova",
+       "newimages-hidepatrolled": "Sakrij ispatrolirana otpremanja",
+       "newimages-mediatype": "Tip medija:",
        "noimages": "Ništa za prikazati.",
+       "gallery-slideshow-toggle": "Prijelaz na minijature",
        "ilsubmit": "Traži / Тражи",
        "bydate": "po datumu",
        "sp-newimages-showfrom": "Prikaz novih datoteka počev od $2, $1",
        "confirmemail_body_set": "Netko, vjerovatno Vi, sa IP adrese $1,\nje postavio e-mail adresu za račun \"$2\" na ovoj adresi za {{SITENAME}}.\n\nDa potvrdite kako ovaj račun uistinu pripada Vama i reaktivirate\ne-mail postavke na {{SITENAME}}, otvoriti ovaj link u vašem pregledniku:\n\n$3\n\nAko račun *ne* pripada Vama, pratite ovaj link\nkako bi poništili potvrdu e-mail adrese:\n\n$5\n\nOvaj kod za potvrdu će isteći u $4.",
        "confirmemail_invalidated": "Potvrda e-mail adrese otkazana",
        "invalidateemail": "Odustani od e-mail potvrde",
+       "notificationemail_subject_changed": "Registrirana adresa e-pošte na projektu {{SITENAME}} je smijenjena",
+       "notificationemail_subject_removed": "Registrirana adresa e-pošte na projektu {{SITENAME}} je uklonjena",
+       "notificationemail_body_changed": "Neko, vjerovatno Vi, s IP-adrese $1,\nsmijenio je adresu e-pošte računa \"$2\" na projektu {{SITENAME}} u \"$3\".\n\nAko ovo niste bili Vi, odmah se obratite administratoru sajta.",
+       "notificationemail_body_removed": "Neko, vjerovatno Vi, s IP-adrese $1,\nuklonio je adresu e-pošte računa \"$2\" na projektu {{SITENAME}}.\n\nAko ovo niste bili Vi, odmah se obratite administratoru sajta.",
        "scarytranscludedisabled": "[Međuwiki umetanje je isključeno]",
        "scarytranscludefailed": "[Neuspješno preusmjerenje šablona na $1]",
        "scarytranscludefailed-httpstatus": "[Ne mogu da preuzmem šablon $1: HTTP $2]",
        "scarytranscludetoolong": "[URL je predugačak]",
        "deletedwhileediting": "'''Upozorenje''': Ova stranica je obrisana prije nego što ste počeli uređivati!",
-       "confirmrecreate": "Korisnik [[User:$1|$1]] ([[User talk:$1|razgovor]]) je obrisao ovaj članak pošto ste počeli uređivanje sa razlogom:\n: ''$2''\n\nMolimo Vas da potvrdite da stvarno želite da ponovo napravite ovaj članak.",
-       "confirmrecreate-noreason": "Korisnik [[User:$1|$1]] ([[User talk:$1|razgovor]]) je obrisao ovaj članak pošto ste ga počeli uređivati. Molimo Vas da potvrdite da stvarno želite da ponovo napravite ovaj članak.",
+       "confirmrecreate": "{{GENDER:$1|Korisnik|Korisnica}} [[User:$1|$1]] ([[User talk:$1|razgovor]]) {{GENDER:$1|obrisao je|obrisala je}} ovu stranicu pošto ste počeli uređivanje, sa razlogom:\n: ''$2''\n\nPotvrdite da stvarno želite da ponovo napravite stranicu.",
+       "confirmrecreate-noreason": "{{GENDER:$1|Korisnik|Korisnica}} [[User:$1|$1]] ([[User talk:$1|razgovor]]) {{GENDER:$1|obrisao je|obrisala je}} ovu stranicu pošto ste je počeli uređivati.  Potvrdite da stvarno želite da ponovo napravite stranicu.",
        "recreate": "Ponovno napravi",
+       "confirm-purge-title": "Preučitaj ovu stranicu",
        "confirm_purge_button": "U redu",
        "confirm-purge-top": "Da li želite obrisati keš (''cache'') ove stranice?",
        "confirm-purge-bottom": "Ispražnjava keš stranice i prikazuje najsvježiju verziju.",
        "confirm-watch-top": "Dodati ovu stranicu na Vaš spisak praćenja?",
        "confirm-unwatch-button": "U redu",
        "confirm-unwatch-top": "Izbrisati ovu stranicu sa Vašeg spiska praćenja?",
+       "confirm-rollback-button": "U redu",
+       "confirm-rollback-top": "Ukloniti uređivanja na ovoj stranici?",
+       "confirm-mcrrestore-title": "Povrati reviziju",
+       "confirm-mcrundo-title": "Otkaži promjenu",
+       "mcrundofailed": "Otkazivanje nije uspjelo",
+       "mcrundo-missingparam": "Nedostaje potreban parametar za zahtjev.",
+       "mcrundo-changed": "Stranica je izmijenjena dok ste gledali razlike. Pregledajte novu promenu.",
+       "mcrundo-parse-failed": "Nisam uspio raščlaniti novu izmjenu: $1",
+       "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← prethodna stranica",
        "imgmultipagenext": "sljedeća stranica →",
        "imgmultigo": "Idi!",
        "imgmultigoto": "Idi na stranicu $1",
+       "img-lang-default": "(podrazumijevani jezik)",
+       "img-lang-info": "Ispiši sliku na $1. $2",
+       "img-lang-go": "Prikaži",
        "ascending_abbrev": "rast",
        "descending_abbrev": "opad",
        "table_pager_next": "Sljedeća stranica",
        "autosumm-blank": "Uklanjanje svog sadržaja stranice",
        "autosumm-replace": "Zamjena stranice sa '$1'",
        "autoredircomment": "Preusmjereno na [[$1]]",
+       "autosumm-removed-redirect": "Uklonjeno preusmjerenje na [[$1]]",
+       "autosumm-changed-redirect-target": "Smijenjeno odredište preusmjerenja sa [[$1]] na [[$2]]",
        "autosumm-new": "Napravljena stranica sa '$1'",
+       "autosumm-newblank": "Napravljena prazna stranica",
        "lag-warn-normal": "Promjene načinjene prije manje od $1 {{PLURAL:$1|sekunde|sekunde|sekundi}} možda neće biti prikazane na ovom spisku.",
        "lag-warn-high": "Zbog dužeg zastoja baze podataka na serveru, izmjene novije od $1 {{PLURAL:$1|sekunde|sekunde|sekundi}} možda neće biti prikazane na ovom spisku.",
        "watchlistedit-normal-title": "Uredi spisak praćenja",
        "watchlistedit-raw-done": "Vaš spisak praćenja je ažuriran.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 naslov je dodan|$1 naslova su dodana|$1 naslova je dodano}}:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova je uklonjeno}}:",
+       "watchlistedit-clear-title": "Očisti praćene",
        "watchlistedit-clear-legend": "Obriši spisak praćenja",
+       "watchlistedit-clear-explain": "Svi naslovi će biti uklonjeni iz praćenih",
+       "watchlistedit-clear-titles": "Naslovi:",
+       "watchlistedit-clear-submit": "Očisti praćene (Ovo je nepovratno!)",
        "watchlistedit-clear-done": "Vaš spisak praćenja je obrisan. Svi naslovi su uklonjeni.",
+       "watchlistedit-clear-jobqueue": "Vaša praćenja će biti očišćena. Ovo može potrajati!",
+       "watchlistedit-clear-removed": "{{PLURAL:$1|Obrisan je jedan naslov|Obrisano je $1 naslova}}:",
+       "watchlistedit-too-many": "Ima previše stranica tako da se mogu ovdje prikazati.",
+       "watchlisttools-clear": "Očisti praćene",
        "watchlisttools-view": "Vidi relevantne promjene",
        "watchlisttools-edit": "Vidi i uredi listu praćenja",
        "watchlisttools-raw": "Uredi grubu listu praćenja",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|razgovor]])",
+       "timezone-local": "Lokalno",
        "duplicate-defaultsort": "'''Upozorenje''': Postavljeni ključ sortiranja \"$2\" zamjenjuje raniji ključ \"$1\".",
+       "duplicate-displaytitle": "<strong>Upozorenje:</strong> Prikazni naslov \"$2\" zameniće prethodnito prikazan naslov \"$1\".",
+       "restricted-displaytitle": "<strong>Upozorenje:</strong> Naslov za prikaz \"$1\" zanemaren je jer nije istovetan stvarnom naslovu stranice.",
+       "invalid-indicator-name": "<strong>Greška:</strong> Atribut <code>name</code> što prikazuje status stranice ne može biti prazna.",
        "version": "Verzija / Верзија",
        "version-extensions": "Instalirana proširenja (ekstenzije)",
-       "version-skins": "Izgledi (skinovi)",
+       "version-skins": "Uspostavljeni izgledi",
        "version-specialpages": "Posebne stranice",
        "version-parserhooks": "Kuke parsera",
        "version-variables": "Promjenjive",
+       "version-editors": "Urednici",
        "version-antispam": "Sprečavanje spama",
        "version-api": "Prilozi",
        "version-other": "Ostalo",
        "version-hook-name": "Naziv kuke",
        "version-hook-subscribedby": "Pretplaćeno od",
        "version-version": "($1)",
-       "version-license": "Licenca",
+       "version-no-ext-name": "[nema imena]",
+       "version-license": "MediaWiki licenca",
+       "version-ext-license": "Licenca",
+       "version-ext-colheader-name": "Dodatak",
+       "version-skin-colheader-name": "Izgled",
+       "version-ext-colheader-version": "Verzija",
+       "version-ext-colheader-license": "Licenca",
+       "version-ext-colheader-description": "Opis",
+       "version-ext-colheader-credits": "Autori",
+       "version-license-title": "Licenca za $1",
+       "version-license-not-found": "Za ovaj dodatak nisam našao detaljne informacije o licenci.",
+       "version-credits-title": "Zasluge za $1",
+       "version-credits-not-found": "Za ovaj dodatak nisam našao detaljne informacije o zaslugama.",
        "version-poweredby-credits": "Ova wiki je zasnovana na '''[https://www.mediawiki.org/ MediaWiki]''', autorska prava zadržana © 2001-$1 $2.",
        "version-poweredby-others": "ostali",
+       "version-poweredby-translators": "translatewiki.net prevodioci",
        "version-credits-summary": "Htjeli bismo da zahvalimo sljedećim osobama na njihovom doprinosu [[Special:Version|MediaWiki]].",
        "version-license-info": "Mediawiki je slobodni softver, možete ga redistribuirati i/ili mijenjati pod uslovima GNU opće javne licence kao što je objavljeno od strane Fondacije Slobodnog Softvera, bilo u verziji 2 licence, ili (po vašoj volji) nekoj od kasniji verzija.\n\nMediawiki se distriburia u nadi da će biti korisna, ali BEZ IKAKVIH GARANCIJA, čak i bez ikakvih posrednih garancija o KOMERCIJALNOSTI ili DOSTUPNOSTI ZA ODREĐENU SVRHU. Pogledajte GNU opću javnu licencu za više detalja.\n\nTrebali biste dobiti [{{SERVER}}{{SCRIPTPATH}}/KOPIJU GNU opće javne licence] zajedno s ovim programom, ako niste, pišite Fondaciji Slobodnog Softvera na adresu  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ili je pročitajte [//www.gnu.org/licenses/old-licenses/gpl-2.0.html online].",
        "version-software": "Instalirani softver",
        "version-entrypoints": "URL adresa instalacije",
        "version-entrypoints-header-entrypoint": "Ulazna tačka",
        "version-entrypoints-header-url": "URL",
-       "redirect": "Preusmjeravanje preko datoteke, korisnika ili ID-a izmjene",
-       "redirect-summary": "Ova posebna stranica preusmjerava na datoteku (ako je navedeno ime datoteke), stranicu (ako postoji ID revizije) ili korisničku stranicu (ako postoji brojčani ID korisnika).",
+       "version-libraries": "Uspostavljene biblioteke",
+       "version-libraries-library": "Biblioteka",
+       "version-libraries-version": "Verzija",
+       "version-libraries-license": "Licenca",
+       "version-libraries-description": "Opis",
+       "version-libraries-authors": "Autori",
+       "redirect": "Preusmjerenje na naznaku datoteke, korisnika, stranice, izmjene ili dnevnika",
+       "redirect-summary": "Ova posebna stranica preusmjerava na datoteku (datog imena), stranicu (date oznake izmjene), korisničku strancu (datog numeričkog identifikatora korisnika) ili dnevnički unos (datog identifikatora zapisa). Upotreba: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] ili [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Idi",
        "redirect-lookup": "Pregled:",
        "redirect-value": "Vrijednost:",
        "redirect-user": "Korisnički ID",
+       "redirect-page": "Naznaka stranice",
        "redirect-revision": "Izmjena stranice",
        "redirect-file": "Naziv datoteke",
+       "redirect-logid": "Naznaka dnevnika",
        "redirect-not-exists": "Vrijednost nije pronađena",
+       "redirect-not-numeric": "Vrijednost nije numerička",
        "fileduplicatesearch": "Potraga za duplim datotekama",
        "fileduplicatesearch-summary": "Pretraga duplih datoteka na bazi njihove haš vrijednosti.",
        "fileduplicatesearch-filename": "Ime datoteke:",
        "fileduplicatesearch-result-n": "Datoteka \"$1\" ima {{PLURAL:$2|1 identičnog|$2 identična|$2 identičnih}} dvojnika.",
        "fileduplicatesearch-noresults": "Nije pronađena datoteka sa imenom \"$1\".",
        "specialpages": "Posebne stranice",
-       "specialpages-note-restricted": "* Normalne posebne stranice.\n* <span class=\"mw-specialpagerestricted\">Ograničene posebne stranice.</span>\n* <span class=\"mw-specialpagecached\">Keširane posebne stranice (mogu biti zastarjele).</span>",
+       "specialpages-note-top": "Legenda",
+       "specialpages-note-restricted": "* Normalne posebne stranice.\n* <span class=\"mw-specialpagerestricted\">Ograničene posebne stranice.</span>",
        "specialpages-group-maintenance": "Izvještaji o održavanju / Извјештаји о одржавању",
        "specialpages-group-other": "Ostale posebne stranice - Остале посебне странице",
        "specialpages-group-login": "Prijava / Пријава",
        "specialpages-group-wiki": "Wiki podaci i alati - Вики подаци и алати",
        "specialpages-group-redirects": "Posebne stranice za preusmjeravanje / Посебне стране за преусмеравање",
        "specialpages-group-spam": "Spam alati",
+       "specialpages-group-developer": "Razvojni alati",
        "blankpage": "Prazna stranica",
        "intentionallyblankpage": "Ova je stranica namjerno ostavljena praznom.",
+       "disabledspecialpage-disabled": "Ovu stranicu onemogućio je sistemski administrator.",
        "external_image_whitelist": " #Ostavite ovu liniju onakva kakva je<pre>\n#Stavite obične fragmente opisa (samo dio koji ide između //) ispod\n#Ovi će biti spojeni sa URLovima sa vanjskih (eksternih) slika\n#One koji se spoje biće prikazane kao slike, u suprotnom će se prikazati samo link\n#Linije koje počinju sa # se tretiraju kao komentari\n#Ovo ne razlikuje velika i mala slova\n\n#Stavite sve regex fragmente iznad ove linije. Ostavite ovu liniju onakvu kakva je</pre>",
        "tags": "Oznake valjane izmjene",
        "tag-filter": "Filter [[Special:Tags|oznaka]]:",
        "tag-filter-submit": "Filter",
        "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|tag|tagova}}]]: $2",
+       "tag-mw-contentmodelchange": "izmjena sadržajnog modela",
+       "tag-mw-contentmodelchange-description": "Uređivanja što [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel mijenjaju sadržajni model] jedne stranice",
+       "tag-mw-new-redirect": "novo preusmjerenje",
+       "tag-mw-new-redirect-description": "Izmene kojima se stvara novo preusmjeravanje ili mijenja stranica u preusmjerenje",
+       "tag-mw-removed-redirect": "uklonjeno preusmjerenje",
+       "tag-mw-removed-redirect-description": "Izmene što menjaju postojeće preusmerenje u nepreusmerenje",
+       "tag-mw-changed-redirect-target": "izmijenjena odredišna stranica preusmjerenja",
+       "tag-mw-changed-redirect-target-description": "Uređivanja koja mijenjaju odredište preusmjerenja",
+       "tag-mw-blank": "pražnjenje",
+       "tag-mw-replace": "zamijenjeno",
+       "tag-mw-replace-description": "Uređivanja što uklanjaju preko 90 % sadržaja jedne stranice",
+       "tag-mw-rollback": "vraćanje",
+       "tag-mw-rollback-description": "Uređivanja što vraćaju prethodne izmjene pomoću odgovarajuće veze",
+       "tag-mw-undo": "poništenje",
+       "tag-mw-undo-description": "Uređivanja što vraćaju prethodne izmjene koristeći vezu za tu svrhu",
        "tags-title": "Oznake",
        "tags-intro": "Ova stranica prikazuje spisak oznaka (tagova) koje softver može staviti na svaku izmjenu i njihovo značenje.",
        "tags-tag": "Naziv oznake",
        "tags-display-header": "Vidljivost na spisku izmjena",
        "tags-description-header": "Puni opis značenja",
+       "tags-source-header": "Izvor",
+       "tags-active-header": "Aktivno?",
        "tags-hitcount-header": "Označene izmjene",
+       "tags-actions-header": "Radnje",
+       "tags-active-yes": "Da",
+       "tags-active-no": "Ne",
+       "tags-source-extension": "Definirano softverom",
+       "tags-source-manual": "Ručno je dodaju korisnici i botovi",
+       "tags-source-none": "Van upotrebe",
        "tags-edit": "uređivanje",
+       "tags-delete": "obriši",
+       "tags-activate": "aktiviraj",
+       "tags-deactivate": "deaktiviraj",
        "tags-hitcount": "$1 {{PLURAL:$1|izmjena|izmjene|izmjena}}",
+       "tags-manage-no-permission": "Nemate dopuštenje upravljati promjenama oznaka.",
+       "tags-manage-blocked": "Ne možete mijenjati oznake za promjenu dok {{GENDER:$1|ste}} blokirani.",
+       "tags-create-heading": "Napravi novu oznaku",
+       "tags-create-explanation": "Novonapravljene oznake predoređeno bit će dostupne korisnicima i robotima.",
+       "tags-create-tag-name": "Ime oznake:",
+       "tags-create-reason": "Razlog:",
+       "tags-create-submit": "Napravi",
+       "tags-create-no-name": "Morate navesti ime oznake.",
+       "tags-create-invalid-chars": "Nazivi oznaka ne smiju sadržavati zareze (<code>,</code>), uspravne (<code>|</code>) ni kose crte (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Imena oznaka ne smiju sadržavati znakove što se ne mogu koristiti u naslovima stranica.",
+       "tags-create-already-exists": "Oznaka \"$1\" već postoji.",
        "comparepages": "Usporedi stranice",
        "compare-page1": "Stranica 1",
        "compare-page2": "Stranica 2",
        "compare-invalid-title": "Naslov koji ste unijeli je nevaljan.",
        "compare-title-not-exists": "Navedeni naslov ne postoji.",
        "compare-revision-not-exists": "Navedena revizija ne postoji.",
+       "diff-form": "Razlike / Разлике",
+       "diff-form-oldid": "Naznaka stare izmjene (neobav.)",
+       "diff-form-revid": "Naznaka izmjene",
+       "diff-form-submit": "Prik. razlike",
+       "permanentlink": "Trajni link",
+       "permanentlink-revid": "Naznaka izmjene",
+       "permanentlink-submit": "Idi na izmjenu",
        "dberr-problems": "Žao nam je! Ova stranica ima tehničke poteškoće.",
        "dberr-again": "Pokušajte pričekati nekoliko minuta i ponovno učitati.",
-       "dberr-info": "(Ne može se spojiti server baze podataka: $1)",
+       "dberr-info": "(Ne mogu pristupiti bazi podataka: $1)",
+       "dberr-info-hidden": "(Ne mogu pristupiti bazi podataka)",
        "htmlform-invalid-input": "Postoje određeni problemi sa Vašim unosom",
        "htmlform-select-badoption": "Vrijednost koju ste unijeli nije valjana opcija.",
        "htmlform-int-invalid": "Vrijednost koju ste unijeli nije cijeli broj.",
        "htmlform-no": "Ne",
        "htmlform-yes": "Da",
        "htmlform-chosen-placeholder": "Odaberi opciju",
+       "htmlform-cloner-create": "Dodaj još",
+       "htmlform-cloner-delete": "Ukloni",
+       "htmlform-cloner-required": "Potrebna je barem jedna vrijednost.",
+       "htmlform-date-placeholder": "GGGG-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "GGGG-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "Ne mogu prepoznati unesenu vrijednost. Koristite format GGGG-MM-DD.",
+       "htmlform-time-invalid": "Ne mogu prepoznati unesenu vrijednost vremena. Koristite format HH:MM:SS.",
+       "htmlform-datetime-invalid": "Ne mogu prepoznati unesenu vrijednost za datum i vrijeme. Koristite format GGGG-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "Navedena vrijednost je prije najranijeg dopuštenog datuma – $1.",
+       "htmlform-date-toohigh": "Navedena vrijednost je poslije krajnjeg dopuštenog datuma – $1.",
+       "htmlform-time-toolow": "Navedena vrijednost je prije najranijeg dopuštenog vremena – $1.",
+       "htmlform-time-toohigh": "Navedena vrijednost je poslije krajnjeg dopuštenog vremena – $1.",
+       "htmlform-datetime-toolow": "Navedena vrijednost je prije najranijeg dopuštenog datuma i vremena – $1.",
+       "htmlform-datetime-toohigh": "Navedena vrijednost je poslije krajnjeg dopuštenog datuma i vremena – $1.",
+       "htmlform-title-badnamespace": "[[:$1]] ne nalazi se imenskom prostoru \"{{ns:$2}}\".",
+       "htmlform-title-not-creatable": "Naslov \"$1\" se ne može napraviti",
+       "htmlform-title-not-exists": "$1 ne postoji.",
+       "htmlform-user-not-exists": "<strong>$1</strong> ne postoji.",
+       "htmlform-user-not-valid": "<strong>$1</strong> ne predstavlja validno korisničko ime.",
        "logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
-       "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
+       "logentry-delete-delete_redir": "$1 {{GENDER:$2|obrisao|obrisala}} je preusmjerenje $3 presnimavanjem",
+       "logentry-delete-restore": "$1 {{GENDER:$2|vratio je|vratila je}} stranicu $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|vratio je|vratila je}} stranicu $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 izmjena|$1 izmjene|$1 izmjena}}",
+       "restore-count-files": "{{PLURAL:$1|1 datoteka|$1 datoteke|$1 datoteka}}",
        "logentry-delete-event": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u evidenciji na $3: $4",
        "logentry-delete-revision": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|izmjene|$5 izmjene|$5 izmjena}} na stranici $3: $4",
        "logentry-delete-event-legacy": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost događaja u evidenciji na $3",
        "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 je|blokirala je}} {{GENDER:$4|$3}} u trajanju od $5 $6",
+       "logentry-block-unblock": "$1 {{GENDER:$2|deblokirao je|deblokirala je}} {{GENDER:$4|$3}}",
+       "logentry-block-reblock": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} blok {{GENDER:$4|korisnika|korisnice}} {{GENDER:$4|$3}} u trajanju od $5 $6",
+       "logentry-partialblock-block-page": "{{PLURAL:$1|stranica|stranice}} $2",
+       "logentry-partialblock-block-ns": "{{PLURAL:$1|imenski prostor|imenski prostori}} $2",
+       "logentry-partialblock-block": "$1 {{GENDER:$2|blokirao je|blokirala je}} {{GENDER:$4|$3}} od uređivanja $7 u trajanju od $5 $6",
+       "logentry-partialblock-reblock": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} blokovske postavke za {{GENDER:$4|$3}}, sprečavanje uređivanja $7 u trajanju od $5 $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokirao je|blokirala je}} {{GENDER:$4|$3}} od navedenih neuređivačkih radnji u trajanju od $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} blokovske postavke za {{GENDER:$4|$3}} za navedene neuređivačke radnje u trajanju od $5 $6",
+       "logentry-suppress-block": "$1 {{GENDER:$2|blokirao je|blokirala je}} {{GENDER:$4|$3}} u trajanju od $5 $6",
+       "logentry-suppress-reblock": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} blok {{GENDER:$4|korisnika|korisnice}} {{GENDER:$4|$3}} u trajanju od $5 $6",
+       "logentry-import-upload": "$1 {{GENDER:$2|je uvezao|je uvezla}} $3 otpremanjem datoteke",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|je uvezao|je uvezla}} $3 otpremanjem datoteke ($4 {{PLURAL:$4|izmjena|izmjene|izmjena}})",
+       "logentry-import-interwiki": "$1 {{GENDER:$2|je uvezao|je uvezla}} $3 s drugog wikija",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|je uvezao|je uvezla}} $3 sa $5 ($4 {{PLURAL:$4|izmjena|izmjene|izmjena}})",
+       "logentry-merge-merge": "$1 {{GENDER:$2|je pripojio|je pripojila}} $3 u $4 (sve do izmjene $5)",
        "logentry-move-move": "$1 je {{GENDER:$2|premjestio|premjestila}} stranicu $3 na $4",
        "logentry-move-move-noredirect": "$1 je {{GENDER:$2|premjestio|premjestila}} stranicu $3 na $4 bez ostavljanja preusmjerenja",
        "logentry-move-move_redir": "$1 je {{GENDER:$2|premjestio|premjestila}} stranicu $3 na $4 preko preusmjeravanja",
        "logentry-newusers-create2": "Korisnički račun $3 {{GENDER:$2|je napravio|je napravila|je napravio}} $1",
        "logentry-newusers-byemail": "Korisnički račun $3 je {{GENDER:$2|napravio|napravila}} $1 i lozinka/šifra je poslana putem e-maila",
        "logentry-newusers-autocreate": "Korisnički račun $1 je automatski {{GENDER:$2|napravljen}}",
-       "logentry-rights-rights": "$1 je {{GENDER:$2|promijenio|promijenila|promijenio}} članstvo grupe za $3 iz $4 u $5",
+       "logentry-protect-move_prot": "$1 {{GENDER:$2|premjestio|premjestila}} je zaštitne postavke sa $4 na $3",
+       "logentry-protect-unprotect": "$1 {{GENDER:$2|uklonio je|uklonila je}} zaštitu sa stranice $3",
+       "logentry-protect-protect": "$1 {{GENDER:$2|stavio zaštitu|stavila zaštitu}} $3 $4",
+       "logentry-protect-protect-cascade": "$1 {{GENDER:$2|stavio zaštitu|stavila zaštitu}} $3 $4 [prenosiva zaštita]",
+       "logentry-protect-modify": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} stepen zaštite za $3 $4",
+       "logentry-protect-modify-cascade": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} stepen zaštite za $3 $4 [prenosiva zaštita]",
+       "logentry-rights-rights": "$1 {{GENDER:$2|izmijenio je|izmijenila je}} grupno članstvo {{GENDER:$6|korisnika|korisnice}} $3 iz $4 u $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|je promijenio|je promijenila|je promijenio}} članstvo grupe za $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|je automatski unaprijeđen|je automatski unaprijeđena}} iz $4 u $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|postavio|postavila}} je $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|postavio|postavila}} је novu verziju $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|je postavio|je postavila}} $3 na stariju inačicu",
+       "log-name-managetags": "Evidencija upravljanja oznakama",
+       "log-description-managetags": "Na ovoj stranici nalaze se upraviteljski zadaci što se odnose na [[Special:Tags|oznake]]. Evidencija sadrži samo radnje koje je ručno izvršili administratori; oznake se mogu stvoriti i izbrisati iz wikiprograma i ne nalaze se u evidenciju.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|napravio je|napravila je}} oznaku \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|obrisao je|obrisala je}} oznaku \"$4\" (uklonjena iz {{PLURAL:$5|jedne izmjene ili zapisničkog unosa|$5 izmjena i/ili zapisničkih unosa}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|aktivirao je|aktivirala je}} oznaku \"$4\" za upotrebu od strane korisnika i botova",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|deaktivirao je|deaktivirala je}} oznaku \"$4\" za upotrebu od strane korisnika i botova",
+       "log-name-tag": "Evidencija oznaka",
+       "log-description-tag": "Ova stranica prikazuje dodavanja i brisanja [[Special:Tags|oznake]] iz pojedinačnih verzija ili zapisničkih unosa. Time se ne bilježe oznake napravljene kao dio uređivanja, brisanja i sličnih radnji.",
+       "logentry-tag-update-add-revision": "$1 {{GENDER:$2|dodao|dodala}} je {{PLURAL:$7|oznaku|oznaka}} $6 u verziji $4 stranice $3",
+       "logentry-tag-update-add-logentry": "$1 {{GENDER:$2|dodao|dodala}} je {{PLURAL:$7|oznaku|oznaka}} $6 u zapisničkom unosu $5 stranice $3",
+       "logentry-tag-update-remove-revision": "$1 {{GENDER:$2|uklonio|uklonila}} je {{PLURAL:$9|oznaku|oznaka}} $8 sa verzije $4 stranice $3",
+       "logentry-tag-update-remove-logentry": "$1 {{GENDER:$2|uklonio|uklonila}} je {{PLURAL:$9|oznaku|oznake}} $8 sa zapisničkog unosa $5 stranice $3",
+       "logentry-tag-update-revision": "$1 {{GENDER:$2|obnovio|obnovila}} je oznake u verziji $4 strane $3 ({{PLURAL:$7|dodana|dodanih}} $6; {{PLURAL:$9|uklonjena|uklonjenih}} $8)",
+       "logentry-tag-update-logentry": "$1 {{GENDER:$2|obnovio|obnovila}} je oznake u zapisničkom unosu $5 strane $3 ({{PLURAL:$7|dodana|dodanih}} $6; {{PLURAL:$9|uklonjena|uklonjenih}} $8)",
        "rightsnone": "(nema)",
+       "rightslogentry-temporary-group": "$1 (privremeno, do $2)",
        "feedback-adding": "Dodajem povratne informacije na stranicu...",
+       "feedback-back": "Nazad",
        "feedback-bugcheck": "Izvrsno! Molimo provjerite da se ne radi o nekom [$1 poznatom \"bugu\"].",
        "feedback-bugnew": "Provereno. Prijavi novu grešku",
        "feedback-bugornote": "Ako ste spremni da detaljno opišete tehnički problem, onda [$1 prijavite grešku].\nU suprotnom, poslužite se jednostavnim obrascem ispod. Vaš komentar će stajati na stranici „[$3 $2]“, zajedno s korisničkim imenom i pregledačem koji koristite.",
        "feedback-cancel": "Otkaži",
        "feedback-close": "Gotovo",
+       "feedback-external-bug-report-button": "Podnesi tehnički zadatak",
+       "feedback-dialog-title": "Podnesi povratne informacije",
+       "feedback-dialog-intro": "Poslužite se s jednostavnim obrazcom ispod da biste poslali svoje mišljenje. Komentar će biti dodan na stranicu \"$1\", zajedno s vašim korisničkim imenom.",
        "feedback-error1": "Greška: neprepoznat rezultat od API-ja",
        "feedback-error2": "Greška: Uređivanje nije uspjelo",
        "feedback-error3": "Greška: nema odgovora od API-ja",
+       "feedback-error4": "Greška: Nije moguće objaviti na dati naslov",
        "feedback-message": "Poruka:",
        "feedback-subject": "Tema:",
        "feedback-submit": "Unesi",
        "feedback-thanks": "Hvala! Vaša povratna informacija je postavljena na stranicu „[$2 $1]“.",
+       "feedback-thanks-title": "Hvala vam!",
+       "feedback-useragent": "Korisnički vršitelj:",
        "searchsuggest-search": "Traži {{GRAMMAR:akuzativ|{{SITENAME}}}}",
        "searchsuggest-containing": "sadrži...",
        "api-error-badtoken": "Unutrašnja greška: token nije ispravan.",
        "api-error-emptypage": "Stvaranje novih praznih stranica nije dozvoljeno.",
        "api-error-publishfailed": "Unutrašnja greška: server nije mogao da spremi privremenu datoteku.",
        "api-error-stashfailed": "Unutrašnja greška: server nije mogao da spremi privremenu datoteku.",
-       "api-error-unknown-warning": "Nepoznato upozorenje: $1",
+       "api-error-unknown-warning": "Nepoznato upozorenje: \"$1\".",
        "api-error-unknownerror": "Nepoznata greška: \"$1\"",
        "duration-seconds": "$1 {{PLURAL:$1|sekunda|sekunde}}",
        "duration-minutes": "$1 {{PLURAL:$1|minuta|minuta}}",
        "duration-centuries": "$1 {{PLURAL:$1|vijek|vijekova}}",
        "duration-millennia": "$1 {{PLURAL:$1|milenijum|milenijuma}}",
        "rotate-comment": "Slika rotirana za $1 {{PLURAL:$1|stepeni}} u smjeru kazaljke na satu",
-       "expand_templates_input": "Unos - Унос",
+       "limitreport-title": "Profilni raščlanjivački podaci:",
+       "limitreport-cputime": "Uporaba procesorskog vremena",
+       "limitreport-cputime-value": "{{PLURAL:$1|jedan sekund|$1 sekunde|$1 sekundi}}",
+       "limitreport-walltime": "Uporaba u realnom vremenu",
+       "limitreport-walltime-value": "{{PLURAL:$1|jedan sekund|$1 sekunde|$1 sekundi}}",
+       "limitreport-ppvisitednodes": "Br. posjećenih čvorova iz pretprocesora",
+       "limitreport-ppgeneratednodes": "Br. stvorenih čvorova iz pretprocesora",
+       "limitreport-postexpandincludesize": "Veličina uključenoga nakon proširenja",
+       "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|bajt|bajta|bajtova}}",
+       "limitreport-templateargumentsize": "Veličina argumenta u šablonu",
+       "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|bajt|bajta|bajtova}}",
+       "limitreport-expansiondepth": "Najveća dubina proširenja",
+       "limitreport-expensivefunctioncount": "Br. složenih raščlanjivačkih funkcija",
+       "limitreport-unstrip-depth": "Unstrip dubina povratljivosti",
+       "limitreport-unstrip-size": "Unstrip veličina nakon proširenja",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|bajt|bajta|bajtova}}",
+       "expandtemplates": "Proširi šablone",
+       "expand_templates_title": "Naslov konteksta, za {{FULLPAGENAME}} itd.:",
+       "expand_templates_input": "Ulazni wikitekst:",
+       "expand_templates_output": "Izvod",
+       "expand_templates_xml_output": "XML izlaz",
+       "expand_templates_html_output": "Sirov HTML-izlaz",
+       "expand_templates_ok": "U redu",
+       "expand_templates_remove_comments": "Ukloni komentare",
+       "expand_templates_remove_nowiki": "Pritaji <nowiki> oznake u ishodu",
+       "expand_templates_generate_xml": "Prikaži XML stablo za raščlanjivanje",
+       "expand_templates_generate_rawhtml": "Prikazivaj neobrađeni HTML",
        "expand_templates_preview": "Pregled",
-       "mw-widgets-abandonedit": "Da li ste sigurni da želite napustiti mod uređivanja prije nego što snimite?",
-       "mw-widgets-abandonedit-discard": "Odbaci izmjene",
+       "expand_templates_input_missing": "Morate unjeti neki wikitekst.",
+       "pagelanguage": "Promena jezika stranice",
+       "pagelang-name": "Stranica",
+       "pagelang-language": "Jezik",
+       "pagelang-use-default": "Koristi podrazumijevani jezik",
+       "pagelang-select-lang": "Odaberite jezik",
+       "pagelang-reason": "Razlog",
+       "pagelang-submit": "Pošalji",
+       "pagelang-nonexistent-page": "Stranica $1 ne postoji.",
+       "pagelang-unchanged-language": "Stranica $1 već je namjestena na jezik $2.",
+       "pagelang-unchanged-language-default": "Stranica $1 već je namjestena na matični sadržajni jezik wikija.",
+       "pagelang-db-failed": "Baza podataka nije uspjela smijeniti sadržajni jezik.",
+       "right-pagelang": "Mijenjanje jezika stranice",
+       "action-pagelang": "mijenjanje jezika stranice",
+       "log-name-pagelang": "Evidencija mijenjanja jezika",
+       "log-description-pagelang": "Ovo je evidencija promjena jezika stranica.",
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|smijenio je|smijenila je}} jezik stranice $3 iz $4 u $5.",
+       "default-skin-not-found": "Nažalost, predodređena tema vašeg wikija ddefinirana u <code dir=\"ltr\">$wgDefaultSkin</code> kao <code>$1</code> nije dostupna.\n\nVaša uspostava sadrži {{PLURAL:$4|sljedeću temu|sljedeće teme}}. Pogledajte [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priručnik: Podešavanje tema] da biste saznali kako ih uključiti i kako odabrati osnovnu.\n\n$2\n\n; Ako ste upravo uspostavili MediaWiki:\n: Vjerovatno ste je uspostavili sa gita, ili pak neposredno sa izvornog koda koristeći se nekom drugom metodom. Ovo je za očekivati. Pokušajte uspostaviti neku temu sa [https://www.mediawiki.org/wiki/Category:All_skins kataloga tema] tako što ćete:\n:* Sa preuzimanjem [https://www.mediawiki.org/wiki/Download tarball-uspostavljača], koji sami sadrži nekoliko tema i proširenja. Možete prekopirati folder <code>skins/</code> iz njega.\n:* Preuzimanje tarball-i za teme sa [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org]. \n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Koristeći Git kako biste preuzeli teme].\n: Ovo ne bi trebalo utjecati na vaše git skladište ako ste MediaWiki razvijatelj.\n\n; Ako ste upravo nadogradili MediaWiki:\n: MediaWiki 1.24 i više verzije više ne automatski uključuju uspostavljene teme (pogl. [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Priručni: Samoistraživanje tema]). Možete prekopirati {{PLURAL:$5|sljedeći red kǒda|sljedeće redove kǒda}} u <code>LocalSettings.php</code> kako biste uključili {{PLURAL:$5|uspostavljenu temu|sve uspostavljene teme}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Ako ste upravo izmijenili datoteku <code>LocalSettings.php</code>:\n: Provjerite je li ispravno napisani nazivi tema.",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (uključena)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>isključena</strong>)",
+       "mediastatistics": "Statistike za slike i snimke",
+       "mediastatistics-summary": "Statistike o poslanih tipovima datoteka. Ovdje su uračunate samo najnovije verzije datoteka. Stare i obrisane verzije nisu uračunate.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|Jedan bajt|$1 bajta|$1 bajtova}} ($2; $3%)",
+       "mediastatistics-bytespertype": "Ukupni obuhvat pasusa: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2; $3%).",
+       "mediastatistics-allbytes": "Ukupni obuhvat svih datoteka: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2).",
+       "mediastatistics-table-mimetype": "MIME tip",
+       "mediastatistics-table-extensions": "Mogući dodaci",
+       "mediastatistics-table-count": "Broj datoteka",
+       "mediastatistics-table-totalbytes": "Ukupna veličina",
+       "mediastatistics-header-unknown": "Nepoznato",
+       "mediastatistics-header-bitmap": "Bitmap-slika",
+       "mediastatistics-header-drawing": "Crteži (vektorske slike)",
+       "mediastatistics-header-audio": "Zvuk",
+       "mediastatistics-header-video": "Videa",
+       "mediastatistics-header-multimedia": "Obogaćeni snimci",
+       "mediastatistics-header-office": "Birotehničke",
+       "mediastatistics-header-text": "Tekstualne",
+       "mediastatistics-header-executable": "Izvršne",
+       "mediastatistics-header-archive": "Zbijeni formati",
+       "mediastatistics-header-total": "Sve datoteke",
+       "json-warn-trailing-comma": "{{PLURAL:$1|Uklonjena je jedna prateća tačka|Uklonjene su $1 prateća tačka|Uklonjeno je $1 pratećih tački}} iz JSON-a",
+       "json-error-unknown": "Dogodio se problem s JSON-om. Greška: $1",
+       "json-error-depth": "Prekoračena je najveća dozvoljena dubina plasta",
+       "json-error-state-mismatch": "Nevažeći ili pokvareni JSON",
+       "json-error-ctrl-char": "Greška u kontrolnom simbolu. Moguće je da je neispravno enkodiran",
+       "json-error-syntax": "Sintaksna greška",
+       "json-error-utf8": "Pokvareni UTF-8 znaci. Moguće je da su neispravno enkodirani",
+       "json-error-recursion": "Postoji jedna ili više povtorljivih referenci u vrijednosti koju treba enkodirati",
+       "json-error-inf-or-nan": "Postoji jedna ili više NAN- ili INF-vrijednosti što treba enkodirati",
+       "json-error-unsupported-type": "Data je vrijednost tipa što se ne može enkodirati",
+       "headline-anchor-title": "Veza do ovog podnaslova",
+       "special-characters-group-latin": "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-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": "Perzijski",
+       "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-canadianaboriginal": "Kanadski domorodni",
+       "special-characters-title-endash": "crtica",
+       "special-characters-title-emdash": "duga crta",
+       "special-characters-title-minus": "minus",
+       "mw-widgets-abandonedit": "Da li ste sigurni da želite napustiti mod uređivanja bez snimanja izmjena?",
+       "mw-widgets-abandonedit-discard": "Odbaci uređivanja",
        "mw-widgets-abandonedit-keep": "Nastavi s uređivanjem",
-       "mw-widgets-abandonedit-title": "Da li ste sigurni?"
+       "mw-widgets-abandonedit-title": "Da li ste sigurni?",
+       "mw-widgets-dateinput-no-date": "Datum nije izabran",
+       "mw-widgets-mediasearch-input-placeholder": "Pretražite slike/snimke",
+       "mw-widgets-mediasearch-noresults": "Nisam pronašao ništa.",
+       "mw-widgets-titleinput-description-new-page": "stranica još ne postoji",
+       "mw-widgets-titleinput-description-redirect": "preusmjerava na $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Dodaj kategoriju...",
+       "mw-widgets-usersmultiselect-placeholder": "Dodaj još...",
+       "mw-widgets-titlesmultiselect-placeholder": "Dodaj još...",
+       "date-range-from": "Od datuma:",
+       "date-range-to": "Do datuma:",
+       "sessionmanager-tie": "Ne možete istovremeno koristiti nekoliko vrsta provjera autentičnosti: $1.",
+       "sessionprovider-generic": "$1 sesije",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "sesije s kolačićima",
+       "sessionprovider-nocookies": "Kolačići su možda onemogućeni. Ako je tako, uključite ih, i počnite ponovo.",
+       "randomrootpage": "Slučajna korijenska stranica",
+       "log-action-filter-block": "Tip bloka:",
+       "log-action-filter-contentmodel": "Tip promjene sadržajnog modela:",
+       "log-action-filter-delete": "Tip brisanja:",
+       "log-action-filter-import": "Tip uvoza:",
+       "log-action-filter-managetags": "Tip radnje upravljanja oznakama:",
+       "log-action-filter-move": "Tip premještanja:",
+       "log-action-filter-newusers": "Tip stvaranja računa:",
+       "log-action-filter-patrol": "Tip patroliranja:",
+       "log-action-filter-protect": "Tip zaštite:",
+       "log-action-filter-rights": "Tip promjene u pravima:",
+       "log-action-filter-suppress": "Tip skrivanja:",
+       "log-action-filter-upload": "Tip postavljanja:",
+       "log-action-filter-all": "Sve",
+       "log-action-filter-block-block": "blokiranje",
+       "log-action-filter-block-reblock": "Izmjena bloka",
+       "log-action-filter-block-unblock": "Deblokiranje",
+       "log-action-filter-contentmodel-change": "Promjena sadržajnog modela",
+       "log-action-filter-contentmodel-new": "Pravljenje stranice s nestandardnim sadržajnim modelom",
+       "log-action-filter-delete-delete": "Brisanje stranice",
+       "log-action-filter-delete-delete_redir": "Presnimavanje preusmjerenja",
+       "log-action-filter-delete-restore": "Povratak stranice",
+       "log-action-filter-delete-event": "Brisanje evidencije",
+       "log-action-filter-delete-revision": "Brisanje izmjene",
+       "log-action-filter-import-interwiki": "Prekowiki-uvoz",
+       "log-action-filter-import-upload": "Uvoz postavljanjem XML-a",
+       "log-action-filter-managetags-create": "Stvaranje oznake",
+       "log-action-filter-managetags-delete": "Brisanje oznake",
+       "log-action-filter-managetags-activate": "Aktiviranje oznake",
+       "log-action-filter-managetags-deactivate": "Deaktiviranje oznake",
+       "log-action-filter-move-move": "Premještanje bez presnimavanja preusmjerenja",
+       "log-action-filter-move-move_redir": "Premještanje s presnimavanjem preusmjerenja",
+       "log-action-filter-newusers-create": "Stvorio anonimni korisnik",
+       "log-action-filter-newusers-create2": "Stvorio registrirani korisnik",
+       "log-action-filter-newusers-autocreate": "Automatski stvoren",
+       "log-action-filter-newusers-byemail": "Stvoren lozinkom poslanom na adresu e-pošte",
+       "log-action-filter-patrol-patrol": "Ručno patrolirano",
+       "log-action-filter-patrol-autopatrol": "Automatski patrolirano",
+       "log-action-filter-protect-protect": "Zaštita",
+       "log-action-filter-protect-modify": "Izmjena zaštite",
+       "log-action-filter-protect-unprotect": "Odzaštita",
+       "log-action-filter-protect-move_prot": "Premještanje zaštite",
+       "log-action-filter-rights-rights": "Ručna promjena",
+       "log-action-filter-rights-autopromote": "Automatska promjena",
+       "log-action-filter-suppress-event": "Skrivanje zapisa u evidenciji",
+       "log-action-filter-suppress-revision": "Skrivanje izmjene",
+       "log-action-filter-suppress-delete": "Skrivanje stranice",
+       "log-action-filter-suppress-block": "Skrivanje korisnikota preko blokiranja",
+       "log-action-filter-suppress-reblock": "Skrivanje korisnikota preko preblokiranja",
+       "log-action-filter-upload-upload": "Novo postavljanje",
+       "log-action-filter-upload-overwrite": "Prepostavljanje",
+       "log-action-filter-upload-revert": "Vrati",
+       "authmanager-authn-not-in-progress": "Verifikacija nije u toku, ili ima gubitak podataka o sesiji. Počnite ispočetka.",
+       "authmanager-authn-no-primary": "Pruženi akreditivi ne mogu se verificirati.",
+       "authmanager-authn-no-local-user": "Pruženi akreditivi nisu povezani ni s jednim korisnikom na ovom wikiju.",
+       "authmanager-authn-no-local-user-link": "Pruženi akreditivi su važeći, ali nisu povezani ni s jednim korisnikom na ovom wikiju. Prijavite se na drugačiji način, ili napravite novi korisnički račun, što će vam dati mogućnost da svežete prethodne akreditive na novi račun.",
+       "authmanager-authn-autocreate-failed": "Automatsko stvaranje mjesnog računa nije uspjelo: $1",
+       "authmanager-change-not-supported": "Pružene akreditive ne mogu se mijenjati, jer ih ništa ne bi koristilo.",
+       "authmanager-create-disabled": "Onemogućeno pravljenje računa.",
+       "authmanager-create-from-login": "Popunite polja da biste napravili račun.",
+       "authmanager-create-not-in-progress": "Pravljenje računa nije u toku, ili ima gubitak podataka o sesiji. Počnite ispočetka.",
+       "authmanager-create-no-primary": "Pružene akreditive ne mogu se uporabiti za otvaranje naloga.",
+       "authmanager-link-no-primary": "Pružene akreditive ne mogu se uporabiti u povezivanju naloga.",
+       "authmanager-link-not-in-progress": "Spajanje naloga nije u toku, ili ima gubitak podataka o sesiji. Počnite ispočetka.",
+       "authmanager-autocreate-noperm": "Automatsko pravljenje računa nije dozvoljeno.",
+       "authmanager-autocreate-exception": "Automatsko pravljenje računa privremeno je onemogućeno zbog prijašnjih greški.",
+       "authmanager-userdoesnotexist": "Korisnički račun \"$1\" nije registrovan.",
+       "userjsispublic": "Napomena: podstranice s JavaScriptom ne bi trebale sadržavati povjerljive podatke budući da ih drugi korisnici mogu vidjeti.",
+       "userjsonispublic": "Imajte na umu: Podstranice s JSONom ne bi trebale sadržavati povjerljive podatke budući da su vidljive drugim korisnicima.",
+       "usercssispublic": "Napomena: podstranice s CSS-om ne bi trebale sadržavati povjerljive podatke budući da ih drugi korisnici mogu vidjeti.",
+       "restrictionsfield-badip": "Nevažeća IP adresa ili opseg: $1",
+       "restrictionsfield-label": "Dozvoljeni IP-opsezi:",
+       "restrictionsfield-help": "Jedna IP-adresa ili CIDR-opseg po redu. Da omogućite sve, koristite<br /><code>0.0.0.0/0</code><br /><code>::/0</code>",
+       "edit-error-short": "Greška: $1",
+       "edit-error-long": "Greške:\n\n$1",
+       "revid": "izmjena $1",
+       "pageid": "ID stranice $1",
+       "interfaceadmin-info": "$1\n\nDozvole za uređivanje CSS/JS/JSON datoteka preko cijelog wikija nedavno su odvojene od prava <code>editinterface</code>. Ako ne razumijete zašto ste dobili ovu grešku, pogl. [[mw:MediaWiki_1.32/interface-admin]].",
+       "rawhtml-notallowed": "&lt;html&gt;-oznake ne mogu se koristiti van normalnih stranica.",
+       "gotointerwiki": "Napuštate projekt {{SITENAME}}",
+       "gotointerwiki-invalid": "Navedeni naslov je nevalidan.",
+       "gotointerwiki-external": "Napuštate projekt {{SITENAME}} da biste posjetili zasebno mrežno mjesto [[$2]].\n\n<strong>[$1 Nastavljate na $1]</strong>",
+       "undelete-cantedit": "Ne možete vratiti ovu stranicu jer Vam nije dozvoljeno da je uređujete.",
+       "undelete-cantcreate": "Ne možete vratiti stranicu jer ne postoji stranica s tim nazivom i nije Vam dozvoljeno da je napravite.",
+       "pagedata-title": "Podaci o stranici",
+       "pagedata-text": "Stranica pruža posrednik za podaci za stranice. Navedite naslov stranice u URL-u pomoću sintakse podstranice.\n* Prebacivanje sadržaja temelji se na zaglavlju Prihvati vašeg klijenta. To znači da će podaci stranice biti stavljeni u formatu koji preferira vaš klijent.",
+       "pagedata-not-acceptable": "Nisam našao odgovarajući format. Podržane MIME-vrste: $1",
+       "pagedata-bad-title": "Nevalidan naslov: $1.",
+       "unregistered-user-config": "Iz bezbednosnih razloga JavaScript, CSS i JSON korisničke podstranice ne mogu biti učitane za neregistrovane korisnike.",
+       "passwordpolicies": "Pravila za lozinke",
+       "passwordpolicies-summary": "Ovo je popis djelotvornih pravila za zaporke za korisničke grupe određene na ovom wikiju.",
+       "passwordpolicies-group": "Grupa",
+       "passwordpolicies-policies": "Pravila",
+       "passwordpolicies-policy-minimalpasswordlength": "Lozinka mora da ima najmanje $1 {{PLURAL:$1|znak|znaka|znakova}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Lozinka mora da ima najmanje $1 {{PLURAL:$1|znak|znaka|znakova}} da bi ste mogli da se prijavite",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Lozinka ne može biti ista što i korisničko ime",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Lozinka ne smije biti iz onih na crnom spisku",
+       "passwordpolicies-policy-maximalpasswordlength": "Lozinka ne mora biti više od $1 {{PLURAL:$1|znaka|znakova}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Lozinka ne može da bude {{PLURAL:$1|popularna|iz spiska $1 popularnih lozinki}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Lozinka ne može biti na listi 100.000 najčešće korišćenih lozinki.",
+       "passwordpolicies-policyflag-forcechange": "mora se promjeniti pri prijavi",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "predloži izmjenu pri prijavi",
+       "easydeflate-invaliddeflate": "Sadržaj nije ispravno pročišćen",
+       "unprotected-js": "JavaScript ne može da se učita sa nezaštićenih stranica iz bezbednosnih razloga. Samo napravite JavaScript u imenskom prostoru MediaWiki: ili kao korisničku podstranicu"
 }
index e825d4b..546fa8b 100644 (file)
@@ -39,7 +39,8 @@
                        "Pmikolas44",
                        "Fitoschido",
                        "Matěj Suchánek",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "Robert Važan"
                ]
        },
        "tog-underline": "Podčiarkovať odkazy:",
@@ -88,7 +89,7 @@
        "underline-always": "Vždy",
        "underline-never": "Nikdy",
        "underline-default": "Podľa nastavení prehliadača alebo témy vzhľadu",
-       "editfont-style": "Štýl písma oblasti na úpravy:",
+       "editfont-style": "Štýl písma v editore:",
        "editfont-monospace": "S pevnou šírkou znaku",
        "editfont-sansserif": "Bezpätkové písmo",
        "editfont-serif": "Pätkové písmo",
        "resetpass-expired": "Platnosť vášho hesla vypršala. Pre prihlásenie si nastavte nové heslo.",
        "resetpass-expired-soft": "Platnosť vášho hesla vypršala, musíte si nastaviť nové. Zvoľte si nové heslo nebo kliknite na „{{int:authprovider-resetpass-skip-label}}“ a nastavte si ho neskôr.",
        "resetpass-validity-soft": "Vaše heslo je neplatné: $1\n\nVyberte si nové heslo, alebo kliknite na „{{int:authprovider-resetpass-skip-label}}“ a nastavte si ho neskôr.",
-       "passwordreset": "Reset hesla",
+       "passwordreset": "Obnova hesla",
        "passwordreset-text-one": "Pre získanie nového hesla vyplňte tento formulár.",
        "passwordreset-text-many": "{{PLURAL:$1|Pre získanie nového hesla e-mailom, zadajte jeden z údajov.}}",
        "passwordreset-disabled": "Obnovenie hesla bolo na tejto wiki zakázané.",
        "changeemail-submit": "Zmeniť e-mail",
        "changeemail-throttled": "Uskutočnili ste príliš mnoho neúspešných pokusov o prihlásenie. Prosím, počkajte $1 predtým, než to skúsite znova.",
        "changeemail-nochange": "Zadajte prosím odlišnú e-mailovú adresu.",
-       "resettokens": "Obnoviť tokeny",
+       "resettokens": "Reinicializovať kľúče",
        "resettokens-text": "Tu môžete obnoviť tokeny, ktoré umožňujú prístup k určitým súkromným údajom spojeným s vaším účtom.\n\nMali by ste to urobiť, ak ste ich omylom niekomu poskytli alebo ak bolo vaše konto zneužité.",
        "resettokens-no-tokens": "Neexistujú žiadne tokeny, ktoré by bolo možné obnoviť.",
        "resettokens-tokens": "Tokeny:",
        "prefs-watchlist-days-max": "Najviac $1 {{PLURAL:$1|deň|dni|dní}}",
        "prefs-watchlist-edits": "Počet úprav, ktorý sa zobrazí v rozšírenom zozname sledovaných:",
        "prefs-watchlist-edits-max": "Maximum: 1000",
-       "prefs-watchlist-token": "Token zoznamu sledovaných?",
+       "prefs-watchlist-token": "Kľúč pre sledovanie stránok",
+       "prefs-watchlist-managetokens": "Správa kľúčov",
        "prefs-misc": "Rôzne",
        "prefs-resetpass": "Zmeniť heslo",
        "prefs-changeemail": "Zmeniť alebo odstrániť e-mailovú adresu",
        "recentchangescount": "Štandardne zobrazovaný počet úprav:",
        "prefs-help-recentchangescount": "Toto sa týka posledných úprav, histórií stránok a záznamov.",
        "prefs-help-watchlist-token2": "Toto je tajný kľúč k webovému kanálu vášho zoznamu sledovaných stránok.\nkaždý, kto ho pozná si bude môcť prečítať váš zoznam sledovaných stránok, preto ho nezverejňujte.\n[[Special:ResetTokens|Kliknite sem, ak potrebujete vytvoriť nový]].",
+       "prefs-help-tokenmanagement": "Môžete vidieť a reinicializovať tajný kľúč k vašemu účtu, ktorý poskytuje prístup k webovému kanálu vášho zoznamu sledovaných stránok. Ktokoľvek, kto pozná tento kľúč, môže čítať váš zoznam sledovaných stránok, tak kľúč nezdieľajte.",
        "savedprefs": "Vaše nastavenia boli uložené.",
        "savedrights": "Práva {{GENDER:$1|používateľa|používateľky}} $1 boli uložené.",
        "timezonelegend": "Časové pásmo:",
        "prefs-common-config": "Spoločné CSS/JS pre všetky témy:",
        "prefs-reset-intro": "Túto stránku môžete použiť na vrátenie predvolených hodnôt vašich nastavení.\nTúto operáciu nemožno vrátiť.",
        "prefs-emailconfirm-label": "Overenie e-mailu:",
-       "youremail": "Váš e-mail²",
+       "youremail": "Email:",
        "username": "{{GENDER:$1|Používateľské meno}}:",
        "prefs-memberingroups": "{{GENDER:$2|Člen|Členovia}} {{PLURAL:$1|skupiny|skupín}}:",
        "group-membership-link-with-expiry": "$1 (do $2)",
        "prefs-timeoffset": "Časový posun",
        "prefs-advancedediting": "Všeobecné možnosti",
        "prefs-developertools": "Vývojárske nástroje",
-       "prefs-editor": "Používateľ",
+       "prefs-editor": "Editor",
        "prefs-preview": "Náhľad",
        "prefs-advancedrc": "Rozšírené možnosti",
        "prefs-advancedrendering": "Rozšírené možnosti",
        "prefs-advancedwatchlist": "Rozšírené možnosti",
        "prefs-displayrc": "Možnosti zobrazenia",
        "prefs-displaywatchlist": "Možnosti zobrazenia",
-       "prefs-tokenwatchlist": "Token",
+       "prefs-changeswatchlist": "Zobrazené zmeny",
+       "prefs-pageswatchlist": "Sledované stránky",
+       "prefs-tokenwatchlist": "Kľúč",
        "prefs-diffs": "Rozdiely",
        "prefs-help-prefershttps": "Táto voľba sa prejaví pri vašom ďalšom prihlásení.",
        "prefswarning-warning": "Vykonali ste zmeny v nastaveniach, ktoré zatiaľ nie sú uložené. Ak túto stránku opustíte bez kliknutia na „$1“, vaše nastavenia sa neaktualizujú.",
        "rcfilters-other-review-tools": "Ďalšie kontrolné nástroje",
        "rcfilters-group-results-by-page": "Zoskupiť výsledky podľa stránky",
        "rcfilters-activefilters": "Aktívne filtre",
+       "rcfilters-activefilters-hide": "Skryť",
        "rcfilters-advancedfilters": "Pokročilé filtre",
        "rcfilters-limit-title": "Zobraziť zmeny",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|Jedna úprava|$1 úpravy|$1 úprav}}, $2",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Vytvoriť predvolený filter",
        "rcfilters-savedqueries-cancel-label": "Zrušiť",
        "rcfilters-savedqueries-add-new-title": "Uložiť súčasné nastavenie filtrov",
+       "rcfilters-savedqueries-already-saved": "Tieto filtre sú už uložené. Zmeňte niektoré nastavenia, ak chcete vytvoriť nový uložený filter.",
        "rcfilters-restore-default-filters": "Obnoviť predvolené filtre",
        "rcfilters-clear-all-filters": "Zrušiť všetky filtre",
        "rcfilters-show-new-changes": "Zobraziť najnovšie zmeny",
        "recentchangeslinked-feed": "Súvisiace úpravy",
        "recentchangeslinked-toolbox": "Súvisiace úpravy",
        "recentchangeslinked-title": "Zmeny týkajúce sa „$1”",
-       "recentchangeslinked-summary": "Vložte názov článku, aby ste videli zmeny stránok, na ktoré odkazuje alebo ktoré odkazujú na danú stránku (aby ste videli články v kategórii, zadajte Kategória:Názov kategórie).\nStránky, ktoré sa nachádzajú vo vašom [[Special:Watchlist|zozname sledovaných]] sú vyznačené <strong>hrubo</strong>.",
+       "recentchangeslinked-summary": "Vložte názov stránky, aby ste videli zmeny iných stránok, na ktoré odkazuje alebo ktoré odkazujú na danú stránku. (Ak chcete vidieť stránky v kategórii, zadajte {{ns:category}}:Názov kategórie).\nStránky, ktoré sa nachádzajú vo vašom [[Special:Watchlist|zozname sledovaných]] sú vyznačené <strong>hrubo</strong>.",
        "recentchangeslinked-page": "Názov stránky:",
        "recentchangeslinked-to": "Zobraziť zmeny na stránkach, ''ktoré odkazujú na'' zadanú stránku",
        "recentchanges-page-added-to-category": "[[:$1]] zaradená do kategórie",
        "filehist-filesize": "veľkosť súboru",
        "filehist-comment": "komentár",
        "imagelinks": "Použitie súboru",
-       "linkstoimage": "Na tento obrázok {{PLURAL:$1|odkazuje nasledujúca stránka|odkazujú nasledujúce $1 stránky|odkazuje nasledujúcich $1 stránok}}:",
+       "linkstoimage": "Na tento súbor {{PLURAL:$1|odkazuje nasledujúca stránka|odkazujú nasledujúce $1 stránky|odkazuje nasledujúcich $1 stránok}}:",
        "linkstoimage-more": "Viac ako $1 {{PLURAL:$1|stránka odkazuje|stránky odkazujú|stránok odkazuje}} na tento súbor.\nNasledovný zoznam zobrazuje {{PLURAL:$1|prvú stránku odkazujúcu|prvé $1 stránky odkazujúce|prvých $1 stránok odkazujúcich}} iba na tento súbor.\nMôžete si pozrieť [[Special:WhatLinksHere/$2|úplný zoznam]].",
-       "nolinkstoimage": "Žiadne stránky neobsahujú odkazy na tento obrázok.",
+       "nolinkstoimage": "Žiadne stránky neobsahujú odkazy na tento súbor.",
        "morelinkstoimage": "Zobraziť [[Special:WhatLinksHere/$1|ďalšie odkazy]] na tento súbor.",
        "linkstoimage-redirect": "$1 (presmerovanie súboru) $2",
        "duplicatesoffile": "{{PLURAL:$1|Nasledujúci súbor je duplikát|Nasledujúce $1 súbory sú duplikáty||Nasledujúcich $1 súborov sú duplikáty}} tohto súboru ([[Special:FileDuplicateSearch/$2|podrobnosti]]):",
        "speciallogtitlelabel": "Cieľ (názov alebo {{ns:user}}:Používateľské meno):",
        "log": "Záznamy",
        "logeventslist-submit": "Zobraziť",
+       "logeventslist-patrol-log": "Kniha preverených úprav",
+       "logeventslist-tag-log": "Kniha značiek",
        "all-logs-page": "Všetky verejné záznamy",
        "alllogstext": "Kombinované zobrazenie všetkých dostupných záznamov {{GRAMMAR:genitív|{{SITENAME}}}}.\nMôžete zúžiť rozsah, ak zvolíte typ záznamu, používateľské meno alebo dotyčnú stránku (záleží na veľkosti písmen).",
        "logempty": "V zázname neboli nájdené zodpovedajúce položky.",
        "listgrouprights-namespaceprotection-header": "Obmedzenia menných priestorov",
        "listgrouprights-namespaceprotection-namespace": "Menný priestor",
        "listgrouprights-namespaceprotection-restrictedto": "Práva umožňujúce redaktorovi upravovať",
+       "listgrants": "Skupiny oprávnení",
        "trackingcategories": "Sledovacie kategórie",
        "trackingcategories-summary": "Táto stránka obsahuje zoznam sledovacích kategórií, ktoré automaticky pridáva softvér MediaWiki. Ich mená je možné zmeniť úpravou príslušných systémových hlásení v mennom priestore {{ns:8}}.",
        "trackingcategories-msg": "Sledovacia kategória",
        "deletionlog": "záznam zmazaní",
        "log-name-create": "Záznam vytvorení stránok",
        "log-description-create": "Toto je zoznam posledných vytvorených stránok.",
+       "logentry-create-create": "$1 {{GENDER:$2|vytvoril|vytvorila|vytvoril(a)}} stránku $3",
        "reverted": "Obnovené na skoršiu verziu",
        "deletecomment": "Dôvod:",
        "deleteotherreason": "Iný/ďalší dôvod:",
        "revertpage": "Posledné úpravy používateľa [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusia]]) vrátené; bola obnovená posledná úprava $1",
        "revertpage-nouser": "Vrátené úpravy od skrytého používateľa na poslednú revíziu od {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Úpravy $1 vrátené; obnovená posledná verzia od $2.",
-       "rollback-success-notify": "Úpravy používateľa $1 boli vrátené;\nobnovená posledná revízia od používateľa $2. [$3 Zobraziť zmeny]",
        "sessionfailure-title": "Chyba relácie",
        "sessionfailure": "Zdá sa, že je problém s vašou prihlasovacou reláciou;\ntáto akcia bola zrušená ako prevencia proti zneužitiu relácie (session).\nProsím, stlačte \"naspäť\", obnovte stránku, z ktorej ste sa sem dostali, a skúste to znova.",
        "changecontentmodel": "Zmeniť model obsahu stránky",
        "pageinfo-display-title": "Zobrazovaný názov",
        "pageinfo-default-sort": "Predvolený kľúč zoraďovania:",
        "pageinfo-length": "Dĺžka stránky (v bajtoch)",
+       "pageinfo-namespace": "Menný priestor",
        "pageinfo-article-id": "ID stránky",
        "pageinfo-language": "Jazyk obsahu stránky",
        "pageinfo-language-change": "zmeniť",
        "pageinfo-category-subcats": "Počet podkategórií",
        "pageinfo-category-files": "Počet súborov",
        "pageinfo-user-id": "ID používateľa",
+       "pageinfo-view-protect-log": "Zobraziť knihu zamknutí tejto stránky.",
        "markaspatrolleddiff": "Označiť ako preverené",
        "markaspatrolledtext": "Označiť túto stránku ako preverenú",
        "markaspatrolledtext-file": "Označiť túto revíziu súboru ako preverenú",
        "specialpages": "Špeciálne stránky",
        "specialpages-note-top": "Legenda",
        "specialpages-note-restricted": "* Bežné špeciálne stránky.\n* <strong class=\"mw-specialpagerestricted\">Špeciálne stránky s obmedzeným prístupom.</strong>",
-       "specialpages-group-maintenance": "Údržbové správy",
+       "specialpages-group-maintenance": "Údržba",
        "specialpages-group-other": "Iné špeciálne stránky",
        "specialpages-group-login": "Prihlásenie / registrácia",
        "specialpages-group-changes": "Posledné úpravy a záznamy",
        "compare-invalid-title": "Názov, ktorý ste zadali nie je platný.",
        "compare-title-not-exists": "Názov, ktorý ste zadali neexistuje.",
        "compare-revision-not-exists": "Revízia, ktorú ste zadali, neexistuje.",
-       "diff-form": "'''formulár'''",
+       "diff-form": "Rozdiely",
        "dberr-problems": "Prepáčte! Táto stránka má práve technické problémy.",
        "dberr-again": "Skúste niekoľko minút počkať a potom opäť načítať stránku.",
        "dberr-info": "(Spojenie s databázovým serverom neúspešné: $1)",
        "json-error-unsupported-type": "Odovzdaná hodnota nekódovateľného typu",
        "headline-anchor-title": "Odkaz na túto sekciu",
        "special-characters-group-latin": "Latinka",
-       "special-characters-group-latinextended": "Latina rozšírené",
+       "special-characters-group-latinextended": "Rozšírenie latinky",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Symboly",
        "special-characters-group-greek": "Grécke",
        "special-characters-group-thai": "Thajské",
        "special-characters-group-lao": "Laoské",
        "special-characters-group-khmer": "Khmer",
+       "special-characters-group-canadianaboriginal": "Písmo pôvodných obyvateľov Kanady",
        "special-characters-title-endash": "pomlčka",
        "special-characters-title-emdash": "dlhá pomlčka",
        "special-characters-title-minus": "mínus",
        "changecredentials": "Zmena prihlasovacích údajov",
        "removecredentials": "Odstránenie prihlasovacích údajov",
        "userjsispublic": "Uvedomte si prosím, že podstránky s JavaScriptom by nemali obsahovať tajné údaje, pretože sú viditeľné ostatným používateľom.",
-       "usercssispublic": "Uvedomte si prosím, že podstránky s CSS by nemali obsahovať tajné údaje, pretože sú viditeľné ostatným používateľom."
+       "usercssispublic": "Uvedomte si prosím, že podstránky s CSS by nemali obsahovať tajné údaje, pretože sú viditeľné ostatným používateľom.",
+       "passwordpolicies": "Pravidlá pre heslá"
 }
index 807ddd5..1adcdf5 100644 (file)
        "mainpage": "پہلا پرت",
        "mainpage-description": "پہلا پرت",
        "policy-url": "Project:پالیسی",
-       "portal": "بیٹھک",
+       "portal": "برادری دا پھاٹک",
        "portal-url": "Project:دیوان عام",
        "privacy": "پرائیویسی پالیسی",
        "privacypage": "Project:پرائیویسی پالیسی",
        "history-fieldset-title": "دہرائی کیتے لبھت",
        "histfirst": "قدیم ترین",
        "histlast": "تازہ ترین",
-       "historyempty": "(خالی)",
+       "historyempty": "خالی",
        "history-feed-title": "ریویژن رکارڈ",
        "history-feed-description": "وکی تے ایں ورقے دی ریویژن ہسٹری",
        "history-feed-item-nocomment": "$2 کوں $1",
index 3cfa36b..41224ce 100644 (file)
@@ -63,6 +63,7 @@
        "tog-norollbackdiff": "Po izvedeni vrnitvi ne prikaži primerjave",
        "tog-useeditwarning": "Opozori me, ko skušam zapreti urejevalno polje z neshranjenimi spremembami",
        "tog-prefershttps": "Med prijavo vedno uporabljaj varno povezavo",
+       "tog-showrollbackconfirmation": "Pokaži potrditveno okno ob kliku na povezavo za vrnitev",
        "underline-always": "Vedno",
        "underline-never": "Nikoli",
        "underline-default": "Koža ali privzeto v brskalniku",
        "badretype": "Gesli, ki ste ju vnesli, se ne ujemata.",
        "usernameinprogress": "Ustvarjanje računa za to uporabniško ime je že v teku. Prosimo, počakajte.",
        "userexists": "Uporabniško ime, ki ste ga vnesli, je že zasedeno.\nProsimo, izberite drugo.",
+       "createacct-normalization": "Vaše uporabniško ime bomo spremenili na »$2« zaradi tehničnih omejitev.",
        "loginerror": "Napaka ob prijavi",
        "createacct-error": "Napaka pri ustvarjanju računa",
        "createaccounterror": "Ne morem ustvariti računa: $1",
        "histfirst": "najstarejše",
        "histlast": "najnovejše",
        "historysize": "({{PLURAL:$1|$1 zlog|$1 zloga|$1 zlogi|$1 zlogov}})",
-       "historyempty": "(prazno)",
+       "historyempty": "prazno",
        "history-feed-title": "Zgodovina strani",
        "history-feed-description": "Zgodovina navedene strani {{GRAMMAR:rodilnik|{{SITENAME}}}}",
        "history-feed-item-nocomment": "$1 ob $2",
        "right-reupload-own": "Nadomeščanje obstoječih lastnih datotek",
        "right-reupload-shared": "Nalaganje lokalnih zamenjav za datoteke iz skupnih večpredstavnostnih skladišč",
        "right-upload_by_url": "Nalaganje datotek iz naslova URL",
-       "right-purge": "Osvežitev predpomnilnika strani, brez potrditve",
+       "right-purge": "Osvežitev predpomnilnika strani",
        "right-autoconfirmed": "Brez vplivov omejitev dejavnosti glede na IP",
        "right-bot": "Naj bo obravnavan kot avtomatiziran postopek",
        "right-nominornewtalk": "Urejanja pogovornih strani, ki niso označena kot manjša, sprožijo obvestilo o novem sporočilu",
        "delete-confirm": "Brisanje »$1«",
        "delete-legend": "Izbriši",
        "historywarning": "<strong>Opozorilo:</strong> Stran, ki jo nameravate izbrisati, ima zgodovino s približno $1 {{PLURAL:$1|redakcijo|redakcijama|redakcijami}}:",
-       "historyaction-submit": "Prikaži",
+       "historyaction-submit": "Pokaži redakcije",
        "confirmdeletetext": "Iz zbirke podatkov boste izbrisali stran ali sliko skupaj z vso njeno zgodovino.\nProsimo, '''potrdite''', da to resnično želite, da razumete posledice dejanja in da se ravnate po [[{{MediaWiki:Policy-url}}|pravilih]].",
        "actioncomplete": "Poseg je končan",
        "actionfailed": "Dejanje spodletelo",
-       "deletedtext": "Stran »$1« je izbrisana.\nZa zapise nedavnih brisanj glej $2.",
+       "deletedtext": "Stran »$1« je izbrisana.\nZa zapise o pred kratkim opravljenih izbrisih glejte $2.",
        "dellogpage": "Dnevnik brisanja",
        "dellogpagetext": "Spodaj je prikazan seznam nedavnih brisanj.",
        "deletionlog": "dnevnik brisanja",
        "deleting-backlinks-warning": "<strong>Opozorilo:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Druge strani]] se povezujejo na ali vključujejo stran, ki jo nameravate izbrisati.",
        "deleting-subpages-warning": "<strong>Opozorilo:</strong> Stran, ki jo nameravate izbrisati, ima [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|podstran|$1 podstrani|51=več kot 50 podstrani}}]].",
        "rollback": "Vrni spremembe",
+       "rollback-confirmation-confirm": "Prosimo, potrdite:",
+       "rollback-confirmation-yes": "Vrni",
+       "rollback-confirmation-no": "Prekliči",
        "rollbacklink": "vrni",
        "rollbacklinkcount": "vrni $1 {{PLURAL:$1|urejanje|urejanji|urejanja|urejanj}}",
        "rollbacklinkcount-morethan": "vrni več kot $1 {{PLURAL:$1|urejanje|urejanji|urejanja|urejanj}}",
        "revertpage": "vrnitev sprememb uporabnika [[Special:Contributions/$2|$2]] ([[User talk:$2|pogovor]]) na zadnje urejanje uporabnika [[User:$1|$1]]",
        "revertpage-nouser": "vrnitev sprememb skritega uporabnika na zadnjo redakcijo {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Razveljavljene spremembe {{GENDER:$3|uporabnika|uporabnice}} $1;\nvrnjeno na urejanje {{GENDER:$4|uporabnika|uporabnice}} $2.",
-       "rollback-success-notify": "Povrnili smo urejanja $1;\nspremenjeno nazaj na zadnjo redakcijo $2. [$3 Prikaži spremembe]",
        "sessionfailure-title": "Neuspeh seje",
        "sessionfailure": "Zdi se, da z vašo sejo prijave obstaja težava;\nto dejanje smo preklicali, da bi preprečili morebitno ugrabitev seje. Prosimo, ponovno potrdite obrazec.",
        "changecontentmodel": "Spremeni model vsebine strani",
        "mycontris": "Prispevki",
        "anoncontribs": "Prispevki",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Za {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Uporabniški račun »$1« ni registriran.",
        "negative-namespace-not-supported": "Imenski prostori z negativnimi vrednostmi niso podprti.",
        "nocontribs": "Ne najdem nobene merilom ustrezajoče spremembe.",
        "ipb-confirm": "Potrdi blokado",
        "ipb-sitewide": "Po celotni strani",
        "ipb-partial": "Delno",
+       "ipb-sitewide-help": "Vsaka stran na wikiju in vsa druga dejanja prispevanja.",
+       "ipb-partial-help": "Določene strani ali imenski prostori.",
        "ipb-pages-label": "Strani",
        "ipb-namespaces-label": "Imenski prostori",
        "badipaddress": "Neveljaven IP-naslov ali uporabniško ime.",
        "confirm-unwatch-top": "Odstranim stran z vašega spiska nadzorov?",
        "confirm-rollback-button": "V redu",
        "confirm-rollback-top": "Povrnemo urejanja te strani?",
+       "confirm-rollback-bottom": "Dejanje bo v trenutku vrnilo izbrane spremembe na strani.",
        "confirm-mcrrestore-title": "Obnovi redakcijo",
        "confirm-mcrundo-title": "Razveljavi spremembo",
        "mcrundofailed": "Razveljavitev ni uspela",
        "logentry-rights-autopromote": "$1 je {{GENDER:$2|bil samodejno povišan|bila samodejno povišana|bil(-a) samodejno povišan(-a)}} z $4 na $5",
        "logentry-upload-upload": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} $3",
        "logentry-upload-overwrite": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} novo različico $3",
-       "logentry-upload-revert": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} $3",
+       "logentry-upload-revert": "$1 je {{GENDER:$2|vrnil|vrnila|vrnil(-a)}} $3 na starejšo različico",
        "log-name-managetags": "Dnevnik upravljanja oznak",
        "log-description-managetags": "Stran navaja opravila upravljanja, povezana z [[Special:Tags|oznakami]]. Dnevnik vsebuje samo dejanja, ki so jih ročno izvedli administratorji; oznake je lahko ustvarilo ali izbrisalo tudi programje wiki brez zabeleženega vnosa v tem dnevniku.",
        "logentry-managetags-create": "$1 je {{GENDER:$2|ustvaril|ustvarila|ustvaril(-a)}} oznako »$4«",
        "log-action-filter-suppress-reblock": "Zatrtje uporabnika s ponovno blokado",
        "log-action-filter-upload-upload": "Novo nalaganje",
        "log-action-filter-upload-overwrite": "Ponovno nalaganje",
+       "log-action-filter-upload-revert": "Vrni",
        "authmanager-authn-not-in-progress": "Overjanje ni v teku ali pa smo izgubili podatke seje. Prosimo, pričnite znova od začetka.",
        "authmanager-authn-no-primary": "Navedenih poverilnic nismo mogli overiti.",
        "authmanager-authn-no-local-user": "Navedene poverilnice niso povezane z nobenim uporabnikom na wikiju.",
        "authmanager-create-no-primary": "Navedenih poverilnic ne moremo uporabiti za ustvarjanje računa.",
        "authmanager-link-no-primary": "Navedenih poverilnic ne moremo uporabiti za povezovanje računa.",
        "authmanager-link-not-in-progress": "Povezovanje računa ni v teku ali pa smo izgubili podatke seje. Prosimo, pričnite znova od začetka.",
-       "authmanager-authplugin-setpass-failed-title": "Sprememba gesla je spodletela",
-       "authmanager-authplugin-setpass-failed-message": "Vtičnik za overitev je zavrnil spremembo gesla.",
-       "authmanager-authplugin-create-fail": "Vtičnik za overitev je zavrnil ustvarjanje računa.",
-       "authmanager-authplugin-setpass-denied": "Vtičnik za overitev ne dovoljuje spreminjanje gesel.",
-       "authmanager-authplugin-setpass-bad-domain": "Neveljavna domena.",
        "authmanager-autocreate-noperm": "Samodejno ustvarjanje računov ni dovoljeno.",
        "authmanager-autocreate-exception": "Samodejno ustvarjanje računov smo začasno onemogočili zaradi predhodnih napak.",
        "authmanager-userdoesnotexist": "Uporabniški račun »$1« ni registriran.",
        "passwordpolicies-policy-maximalpasswordlength": "Geslo ne sme biti daljše od $1 {{PLURAL:$1|znak|znaka|znake|znakov}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Geslo ne sme biti {{PLURAL:$1|1=popularno geslo|na seznamu $1 popularnih gesel}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Geslo ne more biti na seznamu 100.000 najpogosteje uporabljenih gesel.",
+       "passwordpolicies-policyflag-forcechange": "treba spremeniti ob prijavi",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "predlagaj zamenjavo ob prijavi",
        "easydeflate-invaliddeflate": "Dana vsebina ni pravilno stisnjena",
        "unprotected-js": "Iz varnostnih razlogov JavaScripta ni možno naložiti z nezaščitenih strani. Prosimo, da JavaScript ustvarite samo v imenskem prostoru MediaWiki ali kot uporabniško podstran."
 }
index 4288c4a..cc9ea07 100644 (file)
@@ -6,7 +6,8 @@
                        "Mimursal",
                        "Yariiska",
                        "아라",
-                       "Macofe"
+                       "Macofe",
+                       "Amire80"
                ]
        },
        "tog-underline": "Linkiga hoos ka calaamadeysan:",
        "version-poweredby-others": "kuwa kale",
        "redirect-file": "Magaca faylka",
        "fileduplicatesearch-submit": "Raadi",
-       "specialpages": "bogagga khaaska ah",
+       "specialpages": "Bogagga khaaska ah",
        "specialpages-note-top": "Furaha",
        "specialpages-group-pages": "liiska maqaalada",
        "blankpage": "Bog masaxan",
index 51e4c49..22eca1b 100644 (file)
        "authmanager-create-no-primary": "Kredencialet e dhëna nuk mund të përdoreshin për krijim të llogarisë.",
        "authmanager-link-no-primary": "Kredencialet e dhëna nuk mund të përdoreshin për lidhje të llogarive.",
        "authmanager-link-not-in-progress": "Lidhja e llogarive nuk është në progres ose të dhënat e sesionit janë humbur. Ju lutem filloni nga fillimi.",
-       "authmanager-authplugin-setpass-failed-title": "Ndryshimi i fjalëkalimit dështoi",
-       "authmanager-authplugin-setpass-failed-message": "Plugin-i i autentikimit mohoi ndërrimin e fjalëkalimit.",
-       "authmanager-authplugin-create-fail": "Plugin-i i autentikimit mohoi krijimin e llogarisë.",
-       "authmanager-authplugin-setpass-denied": "Plugin-i i autentikimit nuk lejon ndërrimin e fjalëkalimeve.",
-       "authmanager-authplugin-setpass-bad-domain": "Domen i pavlefshëm.",
        "authmanager-autocreate-noperm": "Krijimi automatik i llogarive nuk lejohet.",
        "authmanager-autocreate-exception": "Krijimi automatik i llogarive përkohësisht i pamundësuar për shkak të gabimeve.",
        "authmanager-userdoesnotexist": "Llogaria e përdoruesit \"$1\" nuk është e regjistruar.",
index 51cd6df..fe737be 100644 (file)
        "tog-numberheadings": "Аутоматски нумериши наслове",
        "tog-editondblclick": "Омогући уређивање страница двоструким кликом",
        "tog-editsectiononrightclick": "Омогући уређивање одељака десним кликом на њихове наслове",
-       "tog-watchcreations": "Додај странице које направим и датотеке које отпремим на мој списак надгледања",
-       "tog-watchdefault": "Додај странице и датотеке које уредим на мој списак надгледања",
-       "tog-watchmoves": "Додај странице и датотеке које преместим на мој списак надгледања",
-       "tog-watchdeletion": "Додај странице и датотеке које избришем на мој списак надгледања",
-       "tog-watchuploads": "Додај нове датотеке које отпремим на мој списак надгледања",
-       "tog-watchrollback": "Додај странице на којима сам извршио враћање измена на мој списак надгледања",
+       "tog-watchcreations": "Додаји странице које направим и датотеке које отпремим на мој списак надгледања",
+       "tog-watchdefault": "Додаји странице и датотеке које уредим на мој списак надгледања",
+       "tog-watchmoves": "Додаји странице и датотеке које преместим на мој списак надгледања",
+       "tog-watchdeletion": "Додаји странице и датотеке које избришем на мој списак надгледања",
+       "tog-watchuploads": "Додаји нове датотеке које отпремим на мој списак надгледања",
+       "tog-watchrollback": "Додаји странице на којима сам извршио враћање измена на мој списак надгледања",
        "tog-minordefault": "Подразумевано означавај све измене као мање",
        "tog-previewontop": "Приказуј претпреглед пре оквира за уређивање",
        "tog-previewonfirst": "Приказуј претпреглед при првој измени",
-       "tog-enotifwatchlistpages": "Ð\9fоÑ\88аљи ми е-поруку када се промени страница или датотека са мог списка надгледања",
+       "tog-enotifwatchlistpages": "Шаљи ми е-поруку када се промени страница или датотека са мог списка надгледања",
        "tog-enotifusertalkpages": "Пошаљи ми е-поруку кад се промени моја корисничка страница за разговор",
-       "tog-enotifminoredits": "Ð\9fоÑ\88аљи ми е-поруку и код мањих измена страница и датотека",
-       "tog-enotifrevealaddr": "Ð\9eÑ\82кÑ\80иÑ\98 Ð¼Ð¾Ñ\98Ñ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е у е-порукама за обавештавање",
+       "tog-enotifminoredits": "Шаљи ми е-поруку и код мањих измена страница и датотека",
+       "tog-enotifrevealaddr": "Ð\9eÑ\82кÑ\80иÑ\98 Ð¼Ð¾Ñ\98Ñ\83 Ðµ-адÑ\80еÑ\81Ñ\83 у е-порукама за обавештавање",
        "tog-shownumberswatching": "Прикажи број корисника који надгледају",
        "tog-oldsig": "Ваш постојећи потпис:",
        "tog-fancysig": "Сматрај потпис као викитекст (без аутоматског повезивања)",
        "tog-uselivepreview": "Приказуј претпреглед без поновног учитавања странице",
-       "tog-forceeditsummary": "УпозоÑ\80и ме када не унесем опис измене",
+       "tog-forceeditsummary": "УпозоÑ\80аваÑ\98 ме када не унесем опис измене",
        "tog-watchlisthideown": "Сакривај моје измене са списка надгледања",
        "tog-watchlisthidebots": "Сакривај измене ботова са списка надгледања",
        "tog-watchlisthideminor": "Сакривај мање измене са списка надгледања",
        "tog-watchlisthideliu": "Сакривај измене пријављених корисника са списка надгледања",
        "tog-watchlistreloadautomatically": "Аутоматски поново учитај списак надгледања кад год се филтер промени (потребан JavaScript)",
-       "tog-watchlistunwatchlinks": "Додај означиваче за прекид надгледања/нагледање ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) на надгледане странице са променама (за функционалност пребацивања је потребан JavaScript)",
+       "tog-watchlistunwatchlinks": "Додаји означиваче за прекид надгледања/нагледање ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) на надгледане странице са променама (за функционалност пребацивања је потребан JavaScript)",
        "tog-watchlisthideanons": "Сакривај измене анонимних корисника са списка надгледања",
        "tog-watchlisthidepatrolled": "Сакривај патролиране измене са списка надгледања",
        "tog-watchlisthidecategorization": "Сакривај категоризацију страница",
-       "tog-ccmeonemails": "Ð\9fоÑ\88аљи ми копије е-порука које пошаљем другим корисницима",
+       "tog-ccmeonemails": "Шаљи ми копије е-порука које пошаљем другим корисницима",
        "tog-diffonly": "Не приказуј садржај странице испод разлика",
        "tog-showhiddencats": "Приказуј скривене категорије",
        "tog-norollbackdiff": "Не приказуј разлику након извршеног враћања",
-       "tog-useeditwarning": "УпозоÑ\80и ме када напуштам страницу за уређивање са несачуваним променама",
+       "tog-useeditwarning": "УпозоÑ\80аваÑ\98 ме када напуштам страницу за уређивање са несачуваним променама",
        "tog-prefershttps": "Увек користи безбедну везу док сам пријављен/а.",
-       "underline-always": "Увек",
-       "underline-never": "Ð\9dикад",
-       "underline-default": "Ð\9fрема теми или прегледачу",
+       "underline-always": "увек",
+       "underline-never": "никад",
+       "underline-default": "према теми или прегледачу",
        "editfont-style": "Стил фонта у оквиру за уређивање:",
-       "editfont-monospace": "Сразмерно широк фонт",
-       "editfont-sansserif": "Ð\91есерифни фонт",
-       "editfont-serif": "Серифни фонт",
+       "editfont-monospace": "сразмерно широк фонт",
+       "editfont-sansserif": "бесерифни фонт",
+       "editfont-serif": "серифни фонт",
        "sunday": "недеља",
        "monday": "понедељак",
        "tuesday": "уторак",
        "viewdeleted": "Приказати $1?",
        "restorelink": "{{PLURAL:$1|једну избрисану измену|$1 избрисане измене|$1 избрисаних измена}}",
        "feedlinks": "Фид:",
-       "feed-invalid": "Ð\9dеважеÑ\9bи Ñ\82ип Ð¿Ñ\80иÑ\98аве Ð½Ð° Ñ\84ид.",
+       "feed-invalid": "Ð\9dеважеÑ\9bа Ð²Ñ\80Ñ\81Ñ\82а Ð¿Ñ\80иÑ\98аве Ð½Ð° Ð´Ð¾Ð²Ð¾д.",
        "feed-unavailable": "Фидови синдикације нису доступни",
        "site-rss-feed": "$1 – RSS фид",
        "site-atom-feed": "$1 – Atom фид",
        "feed-atom": "Atom",
        "feed-rss": "RSS",
        "red-link-title": "$1 (страница не постоји)",
-       "sort-descending": "СоÑ\80Ñ\82иÑ\80ај опадајуће",
-       "sort-ascending": "СоÑ\80Ñ\82иÑ\80ај растуће",
+       "sort-descending": "Ð\9fоÑ\80еÑ\92ај опадајуће",
+       "sort-ascending": "Ð\9fоÑ\80еÑ\92ај растуће",
        "nstab-main": "Страница",
        "nstab-user": "{{GENDER:{{BASEPAGENAME}}|Корисник|Корисница}}",
        "nstab-media": "Медији",
        "nstab-category": "Категорија",
        "mainpage-nstab": "Главна страна",
        "nosuchaction": "Нема такве радње",
-       "nosuchactiontext": "Радња која је наведена у URL адреси није важећа.\nМожда сте откуцали погрешан URL-а или сте пратили покварену везу.\nОво такође може да указује на грешку у софтверу који користи {{SITENAME}}.",
+       "nosuchactiontext": "Радња која је наведена у УРЛ-у није важећа.\nМожда сте погрешно откуцали УРЛ или сте следили покварену везу.\nОво такође може да указује на грешку у софтверу који користи {{SITENAME}}.",
        "nosuchspecialpage": "Нема такве посебне странице",
-       "nospecialpagetext": "<strong>Ð\97аÑ\85Ñ\82евали Ñ\81Ñ\82е Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ñ\83 Ð¿Ð¾Ñ\81ебнÑ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83.</strong>\n\nСпиÑ\81ак Ð²Ð°Ð»Ð¸Ð´Ð½Ð¸Ñ\85 Ð¿Ð¾Ñ\81ебниÑ\85 Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ñ\81е Ð¿Ñ\80онаÑ\92е на „[[Special:SpecialPages|{{int:specialpages}}]]”.",
+       "nospecialpagetext": "<strong>ТÑ\80ажили Ñ\81Ñ\82е Ð½ÐµÐ²Ð°Ð¶ÐµÑ\9bÑ\83 Ð¿Ð¾Ñ\81ебнÑ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83.</strong>\n\nСпиÑ\81ак Ð²Ð°Ð¶ÐµÑ\9bиÑ\85 Ð¼Ð¾Ð¶Ðµ Ñ\81е Ð¿Ñ\80онаÑ\92и на „[[Special:SpecialPages|{{int:specialpages}}]]”.",
        "error": "Грешка",
        "databaseerror": "Грешка у бази података",
        "databaseerror-text": "Дошло је до грешке у упиту базе података. \nОво може да указује на грешку у софтверу.",
        "readonly_lag": "База података је аутоматски закључана да би се секундарни сервери базе података ускладили с главним.",
        "internalerror": "Унутрашња грешка",
        "internalerror_info": "Унутрашња грешка: $1",
-       "internalerror-fatal-exception": "Грешка необрађеног изузетка типа „$1“",
+       "internalerror-fatal-exception": "Грешка необрађеног изузетка врсте „$1”",
        "filecopyerror": "Није могуће копирати датотеку „$1” у „$2”.",
        "filerenameerror": "Није могуће преименовати датотеку „$1” у „$2”.",
        "filedeleteerror": "Није могуће избрисати датотеку „$1”.",
        "translateinterface": "Да бисте додали или променили преводе за све викије, посетите [https://translatewiki.net/ translatewiki.net], пројекат за локализацију Медијавикија.",
        "cascadeprotected": "Ова страница је закључана јер садржи {{PLURAL:$1|следећу страницу која је заштићена|следеће странице које су заштићене}} „преносивом“ заштитом:\n$2",
        "namespaceprotected": "Немате дозволу да уређујете странице у именском простору: <strong>$1</strong>.",
-       "customcssprotected": "Немате дозволу да мењате ову CSS страницу јер садржи лична подешавања другог корисника.",
-       "customjsonprotected": "Немате дозволу да мењате ову JSON страницу зато што садржи лична подешавања другог корисника.",
-       "customjsprotected": "Немате дозволу да мењате ову JavaScript страницу јер садржи лична подешавања другог корисника.",
-       "sitecssprotected": "Немате дозволу да мењате ову CSS страницу зато што може утицати на све посетиоце.",
-       "sitejsonprotected": "Немате дозволу да мењате ову JSON страницу зато што може утицати на све посетиоце.",
-       "sitejsprotected": "Немате дозволу да мењате ову JavaScript страницу зато што може утицати на све посетиоце.",
-       "mycustomcssprotected": "Немате дозволу да уређујете ову CSS страницу.",
-       "mycustomjsonprotected": "Немате дозволу да уређујете ову JSON страницу.",
-       "mycustomjsprotected": "Ð\9dемаÑ\82е Ð´Ð¾Ð·Ð²Ð¾Ð»Ñ\83 Ð´Ð° Ñ\83Ñ\80еÑ\92Ñ\83Ñ\98еÑ\82е Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ñ\81 Ñ\98аваÑ\81кÑ\80ипÑ\82ом.",
+       "customcssprotected": "Немате дозволу да мењате ову Це-Ес-Ес страницу јер садржи лична подешавања другог корисника.",
+       "customjsonprotected": "Немате дозволу да мењате ову ЈСОН страницу зато што садржи лична подешавања другог корисника.",
+       "customjsprotected": "Немате дозволу да мењате ову јаваскрипт страницу јер садржи лична подешавања другог корисника.",
+       "sitecssprotected": "Немате дозволу да мењате ову Це-Ес-Ес страницу зато што може утицати на све посетиоце.",
+       "sitejsonprotected": "Немате дозволу да мењате ову ЈСОН страницу зато што може утицати на све посетиоце.",
+       "sitejsprotected": "Немате дозволу да мењате ову јаваскрипт страницу зато што може утицати на све посетиоце.",
+       "mycustomcssprotected": "Немате дозволу да уређујете ову Це-Ес-Ес страницу.",
+       "mycustomjsonprotected": "Немате дозволу да уређујете ову ЈСОН страницу.",
+       "mycustomjsprotected": "Ð\9dемаÑ\82е Ð´Ð¾Ð·Ð²Ð¾Ð»Ñ\83 Ð´Ð° Ñ\83Ñ\80еÑ\92Ñ\83Ñ\98еÑ\82е Ð¾Ð²Ñ\83 Ñ\98аваÑ\81кÑ\80ипÑ\82 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83.",
        "myprivateinfoprotected": "Немате дозволу да уређујете своје приватне информације.",
        "mypreferencesprotected": "Немате дозволу да уређујете своја подешавања.",
        "ns-specialprotected": "Није могуће уређивати посебне странице.",
        "userlogin-loggedin": "Већ сте пријављени као {{GENDER:$1|$1}}.\nКористите доњи образац да бисте се пријавили као други корисник.",
        "userlogin-reauth": "Морате да се поново пријавите да бисте верификовали да сте {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Отвори још један налог",
-       "createacct-emailrequired": "Ð\90дÑ\80еÑ\81а Ðµ-поÑ\88Ñ\82е",
-       "createacct-emailoptional": "Ð\90дÑ\80еÑ\81а Ðµ-поÑ\88Ñ\82е (опционално)",
-       "createacct-email-ph": "УнеÑ\81иÑ\82е Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е",
-       "createacct-another-email-ph": "УнеÑ\81иÑ\82е Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е",
-       "createaccountmail": "Ð\9aоÑ\80иÑ\81Ñ\82и Ð¿Ñ\80ивÑ\80еменÑ\83, Ð½Ð°Ñ\81Ñ\83миÑ\87нÑ\83 Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83 Ð¸ Ð¿Ð¾Ñ\88аÑ\99и Ñ\98е Ð½Ð° Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ñ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е",
+       "createacct-emailrequired": "Ð\95-адÑ\80еÑ\81а",
+       "createacct-emailoptional": "Ð\95-адÑ\80еÑ\81а (опционално)",
+       "createacct-email-ph": "УнеÑ\81иÑ\82е Ðµ-адÑ\80еÑ\81Ñ\83",
+       "createacct-another-email-ph": "УнеÑ\81иÑ\82е Ðµ-адÑ\80еÑ\81Ñ\83",
+       "createaccountmail": "Ð\9aоÑ\80иÑ\81Ñ\82и Ð¿Ñ\80ивÑ\80еменÑ\83, Ð½Ð°Ñ\81Ñ\83миÑ\87нÑ\83 Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83 Ð¸ Ð¿Ð¾Ñ\88аÑ\99и Ñ\98е Ð½Ð° Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ñ\83 Ðµ-адÑ\80еÑ\81Ñ\83",
        "createaccountmail-help": "Може се користити да се некоме отвори налог без сазнања лозинке.",
        "createacct-realname": "Право име (опционално)",
        "createacct-reason": "Разлог",
        "passwordtooshort": "Лозинка мора имати најмање {{PLURAL:$1|један знак|$1 знака|$1 знакова}}.",
        "passwordtoolong": "Лозинке не могу бити дуже од {{PLURAL:$1|$1 знака|$1 знакова}}.",
        "passwordtoopopular": "Није могуће користити често одабране лозинке. Одаберите лозинку коју је теже погодити.",
-       "passwordinlargeblacklist": "Унесена лозинка је на листи веома често коришћених лозинки. Одаберите јединственију лозинку.",
+       "passwordinlargeblacklist": "Унесена лозинка је на списку веома често коришћених лозинки. Одаберите јединственију лозинку.",
        "password-name-match": "Лозинка се мора разликовати од корисничког имена.",
        "password-login-forbidden": "Коришћење овог корисничког имена и лозинке је забрањено.",
        "mailmypassword": "Ресетуј лозинку",
        "passwordremindertitle": "{{SITENAME}} — привремена лозинка",
        "passwordremindertext": "Неко са IP адресе $1 је затражио нову лозинку на викију {{SITENAME}} ($4).\nСтворена је привремена лозинка за {{GENDER:$2|корисника|корисницу|корисника}} $2 која гласи $3.\nУколико је ово ваш захтев, сада се пријавите и поставите нову лозинку.\nПривремена лозинка истиче за {{PLURAL:$5|један дан|$5 дана}}.\n\nАко је неко други затражио промену лозинке, или сте се сетили ваше лозинке и не желите да је мењате, занемарите ову поруку.",
-       "noemail": "{{GENDER:$1|Ð\9aоÑ\80иÑ\81ник â\80\9e$1â\80\9d Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ¾|Ð\9aоÑ\80иÑ\81ниÑ\86а â\80\9e$1â\80\9d Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ»Ð°|Ð\9aоÑ\80иÑ\81ник/Ñ\86а â\80\9e$1â\80\9d Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ¾/ла}} Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е.",
-       "noemailcreate": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ð½Ð°Ð²ÐµÐ´ÐµÑ\82е Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е.",
-       "passwordsent": "Ð\9dова Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82а Ð½Ð° Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е {{GENDER:$1|корисника|кориснице|корисника/це}} $1.\nПоново се пријавите након што је примите.",
+       "noemail": "{{GENDER:$1|Ð\9aоÑ\80иÑ\81ник â\80\9e$1â\80\9d Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ¾|Ð\9aоÑ\80иÑ\81ниÑ\86а â\80\9e$1â\80\9d Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ»Ð°|Ð\9aоÑ\80иÑ\81ник/Ñ\86а â\80\9e$1â\80\9d Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ¾/ла}} Ðµ-адÑ\80еÑ\81Ñ\83.",
+       "noemailcreate": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ð½Ð°Ð²ÐµÐ´ÐµÑ\82е Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ðµ-адÑ\80еÑ\81Ñ\83.",
+       "passwordsent": "Ð\9dова Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82а Ð½Ð° Ðµ-адÑ\80еÑ\81Ñ\83 {{GENDER:$1|корисника|кориснице|корисника/це}} $1.\nПоново се пријавите након што је примите.",
        "blocked-mailpassword": "Уређивање са ваше IP адресе је блокирано. Ради спречавања злоупотребе, забрањена је и функција враћања лозинке са ње.",
-       "eauthentsent": "Е-порука о потврди је послата на наведену адресу е-поште.\nПре било којих других слања е-порука на налог, мораћете пратити упутства у е-поруци да бисте потврдили да је налог заиста ваш.",
+       "eauthentsent": "Е-порука са потврдом је послата на наведену е-адресу.\nПре било којих других слања е-порука на налог, мораћете пратити упутства у е-поруци да бисте потврдили да је налог заиста ваш.",
        "throttled-mailpassword": "Порука за промену лозинке је послата у {{PLURAL:$1|1=последњих сат времена|последња $1 сата|последњих $1 сати}}.\nДа бисмо спречили злоупотребу, подсетник шаљемо само једном у року од {{PLURAL:$1|1=сат времена|$1 сата|$1 сати}}.",
        "mailerror": "Грешка при слању поруке: $1",
-       "acct_creation_throttle_hit": "Посетиоци овог викија који користе вашу IP адресу су отворили {{PLURAL:$1|1=један налог|$1 налога}} у претходних $2, што је највећа дозвољена вредност у овом временском периоду.\nКао резултат тога, ти посетиоци тренутно не могу отварати више налога.",
-       "emailauthenticated": "Ð\92аÑ\88а Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е је потврђена на дан $2 у $3 ч.",
-       "emailnotauthenticated": "Ð\92аÑ\88а Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е још није потврђена.\nНиједна е-порука неће бити послата ни у једном од следећих случајева.",
-       "noemailprefs": "Ð\9dаведиÑ\82е Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е у подешавањима за оспособљавање ових функција.",
-       "emailconfirmlink": "Ð\9fоÑ\82вÑ\80диÑ\82е Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е",
-       "invalidemailaddress": "Ð\9dиÑ\98е Ð¼Ð¾Ð³Ñ\83Ñ\9bе Ð¿Ñ\80иÑ\85ваÑ\82иÑ\82и Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е јер је у неважећем формату.\nУнесите добро форматирану адресу или оставите празно поље.",
-       "cannotchangeemail": "Ð\90дÑ\80еÑ\81е Ðµ-поÑ\88Ñ\82е налога не могу се променити на овом викију.",
+       "acct_creation_throttle_hit": "Посетиоци овог викија који користе вашу Ај-Пи адресу су отворили {{PLURAL:$1|1=један налог|$1 налога}} у претходних $2, што је највећа дозвољена вредност у овом временском периоду.\nКао резултат тога, ти посетиоци тренутно не могу отварати више налога.",
+       "emailauthenticated": "Ð\92аÑ\88а Ðµ-адÑ\80еÑ\81а је потврђена на дан $2 у $3 ч.",
+       "emailnotauthenticated": "Ð\92аÑ\88а Ðµ-адÑ\80еÑ\81а још није потврђена.\nНиједна е-порука неће бити послата ни у једном од следећих случајева.",
+       "noemailprefs": "Ð\9dаведиÑ\82е Ðµ-адÑ\80еÑ\81Ñ\83 у подешавањима за оспособљавање ових функција.",
+       "emailconfirmlink": "Ð\9fоÑ\82вÑ\80диÑ\82е Ðµ-адÑ\80еÑ\81Ñ\83",
+       "invalidemailaddress": "Ð\9dиÑ\98е Ð¼Ð¾Ð³Ñ\83Ñ\9bе Ð¿Ñ\80иÑ\85ваÑ\82иÑ\82и Ðµ-адÑ\80еÑ\81Ñ\83 јер је у неважећем формату.\nУнесите добро форматирану адресу или оставите празно поље.",
+       "cannotchangeemail": "Ð\95-адÑ\80еÑ\81е налога не могу се променити на овом викију.",
        "emaildisabled": "Ова локација не може да шаље е-поруке.",
        "accountcreated": "Налог је отворен",
        "accountcreatedtext": "Кориснички налог [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) је отворен.",
        "createaccount-title": "Отварање корисничког налога за {{SITENAME}}",
-       "createaccount-text": "Ð\9dеко Ñ\98е Ð¾Ñ\82воÑ\80ио Ð½Ð°Ð»Ð¾Ð³ Ñ\81а Ð²Ð°Ñ\88ом Ð°Ð´Ñ\80еÑ\81ом Ðµ-поÑ\88Ñ\82е на пројекту {{SITENAME}} ($4) под именом „$2” и са лозинком „$3”.\nОдмах требате да се пријавите и промените своју лозинку.\n\nМожете да занемарите ову поруку, ако је овај налог отворен грешком.",
+       "createaccount-text": "Ð\9dеко Ñ\98е Ð¾Ñ\82воÑ\80ио Ð½Ð°Ð»Ð¾Ð³ Ñ\81а Ð²Ð°Ñ\88ом Ðµ-адÑ\80еÑ\81ом на пројекту {{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": "Ð\9fÑ\80аво Ð¸Ð¼Ðµ Ñ\98е Ð¾Ð¿Ñ\86ионално.\nÐ\90ко Ð¾Ð´Ð°Ð±ÐµÑ\80еÑ\82е Ð´Ð° Ð³Ð° Ð½Ð°Ð²ÐµÐ´Ðµте, биће коришћено за приписивање вашег рада.",
+       "createacct-another-realname-tip": "Ð\9fÑ\80аво Ð¸Ð¼Ðµ Ñ\98е Ð¾Ð¿Ñ\86ионално.\nÐ\90ко Ð¾Ð´Ð°Ð±ÐµÑ\80еÑ\82е Ð´Ð° Ð³Ð° Ð¿Ñ\80Ñ\83жите, биће коришћено за приписивање вашег рада.",
        "pt-login": "Пријава",
        "pt-login-button": "Пријави ме",
        "pt-login-continue-button": "Настави пријављивање",
        "pt-createaccount": "Отварање налога",
        "pt-userlogout": "Одјави ме",
        "php-mail-error-unknown": "Непозната грешка у функцији PHP mail().",
-       "user-mail-no-addy": "Ð\9fокÑ\83Ñ\88али Ñ\81Ñ\82е Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99еÑ\82е Ðµ-поÑ\80Ñ\83кÑ\83 Ð±ÐµÐ· Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е.",
+       "user-mail-no-addy": "Ð\9fокÑ\83Ñ\88али Ñ\81Ñ\82е Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99еÑ\82е Ðµ-поÑ\80Ñ\83кÑ\83 Ð±ÐµÐ· Ðµ-адÑ\80еÑ\81е.",
        "user-mail-no-body": "Покушали сте да пошаљете е-поруку са празним или неразумно кратким садржајем.",
-       "changepassword": "Ð\9fÑ\80омена Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ",
+       "changepassword": "Ð\9fÑ\80омениÑ\82е Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83",
        "resetpass_announce": "Да бисте завршили пријаву, подесите нову лозинку овде.",
        "resetpass_text": "<!-- Овде унесите текст -->",
        "resetpass_header": "Промена лозинке налога",
        "passwordreset-emaildisabled": "Функција е-поште је онемогућена на овом викију.",
        "passwordreset-username": "Корисничко име:",
        "passwordreset-domain": "Домен:",
-       "passwordreset-email": "Ð\90дÑ\80еÑ\81а Ðµ-поÑ\88Ñ\82е:",
+       "passwordreset-email": "Ð\95-адÑ\80еÑ\81а:",
        "passwordreset-emailtitle": "Детаљи налога на викију {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Ð\9dеко (веÑ\80оваÑ\82но Ð²Ð¸, Ñ\81а IP Ð°Ð´Ñ\80еÑ\81е $1) Ð·Ð°Ñ\82Ñ\80ажио Ñ\98е Ñ\80еÑ\81еÑ\82оваÑ\9aе Ð²Ð°Ñ\88е \nлозинке Ð·Ð° Ð¿Ñ\80оÑ\98екаÑ\82 {{SITENAME}} ($4). Ð¡Ð»ÐµÐ´ÐµÑ\9bи ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки {{PLURAL:$3|налог Ñ\98е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½|налози Ñ\81Ñ\83 Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð¸}} \nÑ\81а Ð¾Ð²Ð¾Ð¼ Ð°Ð´Ñ\80еÑ\81ом Ðµ-поÑ\88Ñ\82е:\n\n$2\n\n{{PLURAL:$3|Ова привремена лозинка|Ове привремене лозинке}} истећи ће за {{PLURAL:$5|један дан|$5 дана}}.\nОдмах требате да се пријавите и одаберите нову лозинку. \nАко је неко други направио овај захтев или сте се сетили \nоригиналне лозинке, а не желите да је промените, \nможете да занемарите ову поруку и наставите да \nкористите своју стару лозинку.",
+       "passwordreset-emailtext-ip": "Ð\9dеко (веÑ\80оваÑ\82но Ð²Ð¸, Ñ\81а IP Ð°Ð´Ñ\80еÑ\81е $1) Ð·Ð°Ñ\82Ñ\80ажио Ñ\98е Ñ\80еÑ\81еÑ\82оваÑ\9aе Ð²Ð°Ñ\88е \nлозинке Ð·Ð° Ð¿Ñ\80оÑ\98екаÑ\82 {{SITENAME}} ($4). Ð¡Ð»ÐµÐ´ÐµÑ\9bи ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки {{PLURAL:$3|налог Ñ\98е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½|налози Ñ\81Ñ\83 Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð¸}} \nÑ\81а Ð¾Ð²Ð¾Ð¼ Ðµ-адÑ\80еÑ\81ом:\n\n$2\n\n{{PLURAL:$3|Ова привремена лозинка|Ове привремене лозинке}} истећи ће за {{PLURAL:$5|један дан|$5 дана}}.\nОдмах требате да се пријавите и одаберите нову лозинку. \nАко је неко други направио овај захтев или сте се сетили \nоригиналне лозинке, а не желите да је промените, \nможете да занемарите ову поруку и наставите да \nкористите своју стару лозинку.",
        "passwordreset-emailtext-user": "Корисник/ца $1 затражио/ла је ресетовање ваше лозинке на пројекту {{SITENAME}} ($4).\nСледећи кориснички {{PLURAL:$3|налог је повезан|налози су повезани}} са овом адресом е-поште:\n\n$2\n\n{{PLURAL:$3|Привремена лозинка истиче|Привремене лозинке истичу}} за {{PLURAL:$5|један дан|$5 дана}}.\nОдмах требате да се пријавите и одаберите нову лозинку. \nАко је неко други направио овај захтев или сте се сетили \nоригиналне лозинке, а не желите да је промените, \nможете да занемарите ову поруку и наставите да \nкористите своју стару лозинку.",
        "passwordreset-emailelement": "Корисничко име: \n$1\n\nПривремена лозинка: \n$2",
-       "passwordreset-emailsentemail": "Ð\90ко Ñ\98е Ð¾Ð²Ð° Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е повезана са вашим налогом, онда ће е-порука о ресетовању лозинке бити послата.",
-       "passwordreset-emailsentusername": "Ð\90ко Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е повезана са овим корисничким именом, онда ће е-порука о ресетовању лозинке бити послата.",
+       "passwordreset-emailsentemail": "Ð\90ко Ñ\98е Ð¾Ð²Ð° Ðµ-адÑ\80еÑ\81а повезана са вашим налогом, онда ће е-порука о ресетовању лозинке бити послата.",
+       "passwordreset-emailsentusername": "Ð\90ко Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ðµ-адÑ\80еÑ\81а повезана са овим корисничким именом, онда ће е-порука о ресетовању лозинке бити послата.",
        "passwordreset-nocaller": "Позивалац се мора навести",
        "passwordreset-nosuchcaller": "Позивалац не постоји: $1",
        "passwordreset-ignored": "Ресетовање лозинке није успело. Можда послужилац није конфигурисан?",
-       "passwordreset-invalidemail": "Ð\9dеважеÑ\9bа Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е",
-       "passwordreset-nodata": "Ð\9aоÑ\80иÑ\81ниÑ\87ко Ð¸Ð¼Ðµ Ð¸ Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е нису наведени",
-       "changeemail": "Ð\9fÑ\80омена Ð¸Ð»Ð¸ Ñ\83клаÑ\9aаÑ\9aе Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е",
-       "changeemail-header": "Ð\94овÑ\80Ñ\88иÑ\82е Ð¾Ð²Ð°Ñ\98 Ð¾Ð±Ñ\80азаÑ\86 Ð´Ð° Ð±Ð¸ Ñ\81Ñ\82е Ð¿Ñ\80оменили Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е. Ð\90ко Ð±Ð¸Ñ\81Ñ\82е Ð¶ÐµÐ»ÐµÐ»Ð¸ Ð´Ð° Ñ\83клониÑ\82е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð¾Ñ\81Ñ\82 Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ\98е Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е Ñ\81а Ð²Ð°Ñ\88ег Ð½Ð°Ð»Ð¾Ð³Ð°, Ð¾Ñ\81Ñ\82авиÑ\82е Ð¿Ñ\80азно Ð¿Ð¾Ñ\99е Ð·Ð° Ð½Ð¾Ð²Ñ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е када шаљете образац.",
+       "passwordreset-invalidemail": "Ð\9dеважеÑ\9bа Ðµ-адÑ\80еÑ\81а",
+       "passwordreset-nodata": "Ð\9aоÑ\80иÑ\81ниÑ\87ко Ð¸Ð¼Ðµ Ð¸ Ðµ-адÑ\80еÑ\81а нису наведени",
+       "changeemail": "Ð\9fÑ\80омена Ð¸Ð»Ð¸ Ñ\83клаÑ\9aаÑ\9aе Ðµ-адÑ\80еÑ\81е",
+       "changeemail-header": "Ð\94овÑ\80Ñ\88иÑ\82е Ð¾Ð²Ð°Ñ\98 Ð¾Ð±Ñ\80азаÑ\86 Ð´Ð° Ð±Ð¸ Ñ\81Ñ\82е Ð¿Ñ\80оменили Ðµ-адÑ\80еÑ\81Ñ\83. Ð\90ко Ð±Ð¸Ñ\81Ñ\82е Ð¶ÐµÐ»ÐµÐ»Ð¸ Ð´Ð° Ñ\83клониÑ\82е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð¾Ñ\81Ñ\82 Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ\98е Ðµ-адÑ\80еÑ\81е Ñ\81а Ð²Ð°Ñ\88ег Ð½Ð°Ð»Ð¾Ð³Ð°, Ð¾Ñ\81Ñ\82авиÑ\82е Ð¿Ñ\80азно Ð¿Ð¾Ñ\99е Ð·Ð° Ð½Ð¾Ð²Ñ\83 Ðµ-адÑ\80еÑ\81Ñ\83 када шаљете образац.",
        "changeemail-no-info": "Морате бити пријављени да бисте приступили овој страници.",
-       "changeemail-oldemail": "ТÑ\80енÑ\83Ñ\82на Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е:",
-       "changeemail-newemail": "Ð\9dова Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е:",
-       "changeemail-newemail-help": "Ð\9eво Ð¿Ð¾Ñ\99е Ñ\82Ñ\80еба Ð´Ð° Ð¾Ñ\81Ñ\82авиÑ\82е Ð¿Ñ\80азно Ð°ÐºÐ¾ Ð¶ÐµÐ»Ð¸Ñ\82е Ð´Ð° Ñ\83клониÑ\82е Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е. Ð\9dеÑ\9bеÑ\82е Ð±Ð¸Ñ\82и Ñ\83 Ð¼Ð¾Ð³Ñ\83Ñ\9bноÑ\81Ñ\82и Ð´Ð° Ñ\80еÑ\81еÑ\82Ñ\83Ñ\98еÑ\82е Ð·Ð°Ð±Ð¾Ñ\80авÑ\99енÑ\83 Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83 Ð¸ Ð½ÐµÑ\9bеÑ\82е Ð¿Ñ\80имаÑ\82и Ðµ-поÑ\80Ñ\83ке Ñ\81а Ð¾Ð²Ð¾Ð³ Ð²Ð¸ÐºÐ¸Ñ\98а Ð°ÐºÐ¾ Ñ\98е Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е уклоњена.",
+       "changeemail-oldemail": "ТÑ\80енÑ\83Ñ\82на Ðµ-адÑ\80еÑ\81а:",
+       "changeemail-newemail": "Ð\9dова Ðµ-адÑ\80еÑ\81а:",
+       "changeemail-newemail-help": "Ð\9eво Ð¿Ð¾Ñ\99е Ñ\82Ñ\80еба Ð´Ð° Ð¾Ñ\81Ñ\82авиÑ\82е Ð¿Ñ\80азно Ð°ÐºÐ¾ Ð¶ÐµÐ»Ð¸Ñ\82е Ð´Ð° Ñ\83клониÑ\82е Ðµ-адÑ\80еÑ\81Ñ\83. Ð\9dеÑ\9bеÑ\82е Ð±Ð¸Ñ\82и Ñ\83 Ð¼Ð¾Ð³Ñ\83Ñ\9bноÑ\81Ñ\82и Ð´Ð° Ñ\80еÑ\81еÑ\82Ñ\83Ñ\98еÑ\82е Ð·Ð°Ð±Ð¾Ñ\80авÑ\99енÑ\83 Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83 Ð¸ Ð½ÐµÑ\9bеÑ\82е Ð¿Ñ\80имаÑ\82и Ðµ-поÑ\80Ñ\83ке Ñ\81а Ð¾Ð²Ð¾Ð³ Ð²Ð¸ÐºÐ¸Ñ\98а Ð°ÐºÐ¾ Ñ\98е Ðµ-адÑ\80еÑ\81а уклоњена.",
        "changeemail-none": "(ништа)",
        "changeemail-password": "Ваша лозинка за пројекат {{SITENAME}}:",
        "changeemail-submit": "Промени е-пошту",
        "changeemail-throttled": "Превише пута сте покушали да се пријавите.\nМолимо вас да сачекате $1 пре него што покушате поново.",
-       "changeemail-nochange": "УнеÑ\81иÑ\82е Ð´Ñ\80Ñ\83гÑ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е.",
+       "changeemail-nochange": "УнеÑ\81иÑ\82е Ð´Ñ\80Ñ\83гÑ\83 Ðµ-адÑ\80еÑ\81Ñ\83.",
        "resettokens": "Ресетовање токена",
        "resettokens-text": "Овде можете да ресетујете токене који омогућавају приступ одређеним приватним подацима повезаним са вашим налогом.\n\nТребали бисте то урадити ако их случајно поделите са неким или ако је ваш налог угрожен.",
        "resettokens-no-tokens": "Нема жетона за ресетовање.",
        "blockedtitle": "Корисник је блокиран",
        "blocked-email-user": "<strong>Вашем корисничком имену је блокирано слање е-порука. Још увек можете да уређујете друге странице на овом викију.</strong> Можете да видите потпуне детаље блокаде на [[Special:MyContributions|доприносима налога]].\n\nБлокаду је извршио/ла $1.\n\nНаведен је следећи разлог: <em>$2</em>.\n\n* Почетак блокаде: $8\n* Истек блокаде: $6\n* Намењена кориснику/ци или IP адреси: $7\n* ID блокаде #$5",
        "blockedtext-partial": "<strong>Вашем корисничком имену или IP адреси је блокирано прављење промена на овој страници. Још увек можете да уређујете друге странице на овом викију.</strong> Можете да видите потпуне детаље блокаде на [[Special:MyContributions|доприносима налога]].\n\nБлокаду је извршио/ла $1.\n\nНаведен је следећи разлог: <em>$2</em>.\n\n* Почетак блокаде: $8\n* Истек блокаде: $6\n* Намењена кориснику/ци или IP адреси: $7\n* ID блокаде #$5",
-       "blockedtext": "<strong>Ваше корисничко име или IP адреса је блокирана.</strong>\n\nБлокирање је {{GENDER:$4|извршио|извршила}} $1.\nРазлог је <em>$2</em>.\n\n* Почетак блокирања: $8\n* Истек блокирања: $6\n* Блокирани: $7\n\nМожете да се обратите {{GENDER:$4|кориснику|корисници}} $1 или [[{{MediaWiki:Grouppage-sysop}}|администратору]] ради дискусије о блокирању.\nНе можете да користите могућност „{{int:emailuser}}” осим ако сте унели валидну имејл адресу у својим [[Special:Preferences|подешавањима]] налога и нисте блокирани од коришћења исте.\nВаша тренутна IP адреса је $3, а ID блокирања #$5.\nНаведите све информације одозго при стварању било каквих упита.",
-       "autoblockedtext": "Ð\92аÑ\88а IP Ð°Ð´Ñ\80еÑ\81а Ñ\98е Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана Ñ\98еÑ\80 Ñ\98Ñ\83 Ñ\98е ÐºÐ¾Ñ\80иÑ\81Ñ\82ио Ð´Ñ\80Ñ\83ги ÐºÐ¾Ñ\80иÑ\81ник, ÐºÐ¾Ð³Ð° Ñ\98е {{GENDER:$4|блокиÑ\80ао|блокиÑ\80ала|блокиÑ\80ао/ла}} $1.\nРазлог:\n\n:<em>$2</em>\n\n* Ð\9fоÑ\87еÑ\82ак Ð±Ð»Ð¾ÐºÐ°Ð´Ðµ: $8\n* Ð\9aÑ\80аÑ\98 Ð±Ð»Ð¾ÐºÐ°Ð´Ðµ: $6\n* Ð\98ме ÐºÐ¾Ñ\80иÑ\81ника: $7\n\nÐ\9cожеÑ\82е Ð´Ð° ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\82е {{GENDER:$4|коÑ\80иÑ\81ника|коÑ\80иÑ\81ниÑ\86Ñ\83|коÑ\80иÑ\81ника/Ñ\86Ñ\83}} $1 Ð¸Ð»Ð¸ Ð´Ñ\80Ñ\83гог [[{{MediaWiki:Grouppage-sysop}}|админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80а]] Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\80аÑ\81пÑ\80авÑ\99али Ð¾ Ð±Ð»Ð¾ÐºÐ°Ð´Ð¸.\n\nÐ\97апамÑ\82иÑ\82е Ð´Ð° Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ñ\84Ñ\83нкÑ\86иÑ\98Ñ\83 â\80\9e{{int:emailuser}}â\80\9c Ð¾Ñ\81им Ð°ÐºÐ¾ Ñ\81Ñ\82е Ð½Ð°Ð²ÐµÐ»Ð¸ Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е у [[Special:Preferences|подешавањима]].\n\nВаша тренутна IP адреса је $3, а ID блокаде $5.\nУкључите све горње детаље при прављењу било каквих упита.",
+       "blockedtext": "<strong>Ваше корисничко име или IP адреса је блокирана.</strong>\n\nБлокирање је {{GENDER:$4|извршио|извршила}} $1.\nРазлог је <em>$2</em>.\n\n* Почетак блокирања: $8\n* Истек блокирања: $6\n* Блокирани: $7\n\nМожете да се обратите {{GENDER:$4|кориснику|корисници}} $1 или [[{{MediaWiki:Grouppage-sysop}}|администратору]] ради дискусије о блокирању.\nНе можете да користите функцију „{{int:emailuser}}” осим ако сте унели важећу е-адресу у својим [[Special:Preferences|подешавањима]] налога и нисте блокирани од коришћења исте.\nВаша тренутна IP адреса је $3, а ID блокирања #$5.\nНаведите све информације одозго при стварању било каквих упита.",
+       "autoblockedtext": "Ð\92аÑ\88а IP Ð°Ð´Ñ\80еÑ\81а Ñ\98е Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана Ñ\98еÑ\80 Ñ\98Ñ\83 Ñ\98е ÐºÐ¾Ñ\80иÑ\81Ñ\82ио Ð´Ñ\80Ñ\83ги ÐºÐ¾Ñ\80иÑ\81ник, ÐºÐ¾Ð³Ð° Ñ\98е {{GENDER:$4|блокиÑ\80ао|блокиÑ\80ала|блокиÑ\80ао/ла}} $1.\nРазлог:\n\n:<em>$2</em>\n\n* Ð\9fоÑ\87еÑ\82ак Ð±Ð»Ð¾ÐºÐ°Ð´Ðµ: $8\n* Ð\9aÑ\80аÑ\98 Ð±Ð»Ð¾ÐºÐ°Ð´Ðµ: $6\n* Ð\98ме ÐºÐ¾Ñ\80иÑ\81ника: $7\n\nÐ\9cожеÑ\82е Ð´Ð° ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\82е {{GENDER:$4|коÑ\80иÑ\81ника|коÑ\80иÑ\81ниÑ\86Ñ\83|коÑ\80иÑ\81ника/Ñ\86Ñ\83}} $1 Ð¸Ð»Ð¸ Ð´Ñ\80Ñ\83гог [[{{MediaWiki:Grouppage-sysop}}|админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80а]] Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\80аÑ\81пÑ\80авÑ\99али Ð¾ Ð±Ð»Ð¾ÐºÐ°Ð´Ð¸.\n\nÐ\97апамÑ\82иÑ\82е Ð´Ð° Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ñ\84Ñ\83нкÑ\86иÑ\98Ñ\83 â\80\9e{{int:emailuser}}â\80\9c Ð¾Ñ\81им Ð°ÐºÐ¾ Ñ\81Ñ\82е Ð½Ð°Ð²ÐµÐ»Ð¸ Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ðµ-адÑ\80еÑ\81Ñ\83 у [[Special:Preferences|подешавањима]].\n\nВаша тренутна IP адреса је $3, а ID блокаде $5.\nУкључите све горње детаље при прављењу било каквих упита.",
        "blockednoreason": "разлог није наведен",
        "whitelistedittext": "$1 да бисте уређивали странице.",
-       "confirmedittext": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ð¿Ð¾Ñ\82вÑ\80диÑ\82е Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е пре уређивања страница.\nПоставите и проверите ваљаност адресе преко [[Special:Preferences|подешавања]].",
+       "confirmedittext": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ð¿Ð¾Ñ\82вÑ\80диÑ\82е Ðµ-адÑ\80еÑ\81Ñ\83 пре уређивања страница.\nПоставите и проверите ваљаност адресе преко [[Special:Preferences|подешавања]].",
        "nosuchsectiontitle": "Није могуће пронаћи одељак",
        "nosuchsectiontext": "Покушали сте да уредите одељак који не постоји.\nМожда је премештен или избрисан док сте прегледали страницу.",
        "loginreqtitle": "Потребна је пријава",
        "loginreqlink": "Пријавите се",
        "loginreqpagetext": "$1 да бисте видели друге странице.",
        "accmailtitle": "Лозинка је послата.",
-       "accmailtext": "Насумично генерисана лозинка за корисника [[User talk:$1|$1]] послата је на $2. Након пријаве, лозинка може да се промени на страници <em>[[Special:ChangePassword|Промена лозинке]]</em>.",
+       "accmailtext": "Насумично створена лозинка за корисника [[User talk:$1|$1]] послата је на $2. Након пријаве, лозинка може да се промени на страници <em>[[Special:ChangePassword|Промена лозинке]]</em>.",
        "newarticle": "(нови)",
        "newarticletext": "Дошли сте на страницу која још не постоји.\nДа бисте је направили, почните да куцате у прозор испод овог текста (погледајте [$1 страницу за помоћ]).\nАко сте овде дошли грешком, вратите се на претходну страницу.",
        "anontalkpagetext": "----\n<em>Ово је страница за разговор с анонимним корисником који још нема налог или га не користи.</em>\nЗбог тога морамо да користимо бројчану IP адресу како бисмо га препознали.\nТакву адресу може делити више корисника.\nАко сте анонимни корисник и мислите да су вам упућене примедбе, [[Special:CreateAccount|отворите налог]] или се [[Special:UserLogin|пријавите]] да бисте избегли будућу забуну с осталим анонимним корисницима.",
        "userpage-userdoesnotexist": "Кориснички налог „<nowiki>$1</nowiki>” није регистрован.\nРазмислите желите ли заиста да направите/уредите ову страницу.",
        "userpage-userdoesnotexist-view": "Кориснички налог „$1“ није отворен.",
        "blocked-notice-logextract": "Овај корисник је тренутно блокиран.\nНајновији унос у дневнику блокирања је наведен испод као референца:",
-       "clearyourcache": "<strong>Ð\9dапомена:</strong> Ð\9dакон Ñ\87Ñ\83ваÑ\9aа, Ð¼Ð¾Ð¶Ð´Ð° Ñ\9bеÑ\82е Ð¼Ð¾Ñ\80аÑ\82и Ð´Ð° Ð¾Ð±Ñ\80иÑ\88еÑ\82е ÐºÐµÑ\88 Ð¿Ñ\80егледаÑ\87а ÐºÐ°ÐºÐ¾ Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¿Ñ\80омене.\n* <strong>ФаÑ\98еÑ\80Ñ\84окÑ\81 / Ð¡Ð°Ñ\84аÑ\80и:</strong> Ð\94Ñ\80жиÑ\82е <em>Shift</em> Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ\82е Ð½Ð° <em>Ð\9eÑ\81вежи</em> Ð¸Ð»Ð¸ Ð¿Ñ\80иÑ\82иÑ\81ниÑ\82е <em>Ctrl-F5</em> Ð¸Ð»Ð¸ <em>Ctrl-R</em> (<em>â\8c\98-R</em> Ð½Ð° Ð\9cекÑ\83)\n* <strong>Ð\93Ñ\83гл ÐºÑ\80оÑ\83м:</strong> Ð\9fÑ\80иÑ\82иÑ\81ниÑ\82е <em>Ctrl-Shift-R</em> (<em>â\8c\98-Shift-R</em> Ð½Ð° Ð\9cекÑ\83)\n* <strong>Ð\98нÑ\82еÑ\80неÑ\82 ÐµÐºÑ\81плоÑ\80еÑ\80:</strong> Ð\94Ñ\80жиÑ\82е <em>Ctrl</em> Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ\82е Ð½Ð° <em>Ð\9eÑ\81вежи</em> Ð¸Ð»Ð¸ Ð¿Ñ\80иÑ\82иÑ\81ниÑ\82е <em>Ctrl-F5</em>\n* <strong>Ð\9eпеÑ\80а:</strong> Ð\98диÑ\82е Ð½Ð° <em>Ð\90лаÑ\82ке â\86\92 Ð\9fодеÑ\88аваÑ\9aа</em> (<em>Ð\9eпеÑ\80а â\86\92 Ð\9fодеÑ\88аваÑ\9aа</em> Ð½Ð° Ð\9cеку) и затим <em>Приватност и безбедност → Очистите податке о прегледима → Кеширане слике и датотеке</em>.",
-       "usercssyoucanpreview": "<strong>СавеÑ\82:<strong> Ð\9aоÑ\80иÑ\81иÑ\82иÑ\82е Ð´Ñ\83гме â\80\9e{{int:showpreview}}â\80\9c Ð´Ð° Ð¸Ñ\81пÑ\80обаÑ\82е Ñ\81воÑ\98 Ð½Ð¾Ð²Ð¸ CSS пре него што га сачувате.",
-       "userjsonyoucanpreview": "<strong>Савет:</strong> Користите дугме \"{{int:showpreview}}\" да испробате свој нови JSON пре него што га сачувате.",
-       "userjsyoucanpreview": "<strong>СавеÑ\82:</strong> Ð\9aоÑ\80иÑ\81иÑ\82иÑ\82е Ð´Ñ\83гме â\80\9e{{int:showpreview}}â\80\9c Ð´Ð° Ð¸Ñ\81пÑ\80обаÑ\82е Ñ\81воÑ\98 нови јаваскрипт пре него што га сачувате.",
-       "usercsspreview": "<strong>Ð\9eво Ñ\98е Ñ\81амо Ð¿Ñ\80еглед CSS-а.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана!</strong>",
-       "userjsonpreview": "<strong>Ð\97апамÑ\82иÑ\82е Ð´Ð° Ñ\81амо Ñ\82еÑ\81Ñ\82иÑ\80аÑ\82е/пÑ\80егледаваÑ\82е Ð²Ð°Ñ\88Ñ\83 ÐºÐ¾Ñ\80иÑ\81ниÑ\87кÑ\83 JSON ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80аÑ\86иÑ\98Ñ\83.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана!</strong>",
-       "userjspreview": "<strong>Ð\97апамÑ\82иÑ\82е Ð´Ð° Ñ\81амо Ñ\82еÑ\81Ñ\82иÑ\80аÑ\82е/пÑ\80егледаваÑ\82е Ð²Ð°Ñ\88 ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки Ñ\98аваÑ\81кÑ\80ипÑ\82.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана!</strong>",
-       "sitecsspreview": "<strong>Запамтите да је ово само преглед CSS-а.\nСтраница још није сачувана!</strong>",
-       "sitejsonpreview": "<strong>Запамтите да је ово само преглед JSON-а.\nСтраница још није сачувана!</strong>",
-       "sitejspreview": "<strong>Ð\9eво Ñ\98е Ñ\81амо Ð¿Ñ\80еглед Ñ\98аваÑ\81кÑ\80ипÑ\82а.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана!</strong>",
-       "userinvalidconfigtitle": "<strong>УпозоÑ\80еÑ\9aе:</strong> Ð½Ðµ Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ñ\82ема â\80\9e$1â\80\9c.\nÐ\9fÑ\80илагоÑ\92ене Ñ\81Ñ\82Ñ\80аниÑ\86е CSS, JSON Ð¸ Ð\88аваÑ\81кÑ\80ипÑ\82 Ð¿Ð¾Ñ\87иÑ\9aÑ\83 Ð¼Ð°Ð»Ð¸Ð¼ Ñ\81ловом, Ð½Ð¿Ñ\80. {{ns:user}}:Foo/vector.css, Ð° Ð½Ðµ {{ns:user}}:Foo/Vector.css.",
+       "clearyourcache": "<strong>Ð\9dапомена:</strong> Ð\9dакон Ñ\87Ñ\83ваÑ\9aа, Ð¼Ð¾Ð¶Ð´Ð° Ñ\9bеÑ\82е Ð¼Ð¾Ñ\80аÑ\82и Ð´Ð° Ð¾Ð±Ñ\80иÑ\88еÑ\82е ÐºÐµÑ\88 Ð¿Ñ\80егледаÑ\87а ÐºÐ°ÐºÐ¾ Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¿Ñ\80омене.\n* <strong>ФаÑ\98еÑ\80Ñ\84окÑ\81 / Ð¡Ð°Ñ\84аÑ\80и:</strong> Ð\94Ñ\80жиÑ\82е <em>Shift</em> Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ\82е Ð½Ð° <em>Ð\9eÑ\81вежи</em> Ð¸Ð»Ð¸ Ð¿Ñ\80иÑ\82иÑ\81ниÑ\82е <em>Ctrl-F5</em> Ð¸Ð»Ð¸ <em>Ctrl-R</em> (<em>â\8c\98-R</em> Ð½Ð° Ð\9cакÑ\83)\n* <strong>Ð\93Ñ\83гл ÐºÑ\80оÑ\83м:</strong> Ð\9fÑ\80иÑ\82иÑ\81ниÑ\82е <em>Ctrl-Shift-R</em> (<em>â\8c\98-Shift-R</em> Ð½Ð° Ð\9cакÑ\83)\n* <strong>Ð\98нÑ\82еÑ\80неÑ\82 ÐµÐºÑ\81плоÑ\80еÑ\80:</strong> Ð\94Ñ\80жиÑ\82е <em>Ctrl</em> Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ\82е Ð½Ð° <em>Ð\9eÑ\81вежи</em> Ð¸Ð»Ð¸ Ð¿Ñ\80иÑ\82иÑ\81ниÑ\82е <em>Ctrl-F5</em>\n* <strong>Ð\9eпеÑ\80а:</strong> Ð\98диÑ\82е Ð½Ð° <em>Ð\90лаÑ\82ке â\86\92 Ð\9fодеÑ\88аваÑ\9aа</em> (<em>Ð\9eпеÑ\80а â\86\92 Ð\9fодеÑ\88аваÑ\9aа</em> Ð½Ð° Ð\9cаку) и затим <em>Приватност и безбедност → Очистите податке о прегледима → Кеширане слике и датотеке</em>.",
+       "usercssyoucanpreview": "<strong>СавеÑ\82:<strong> Ð\9aоÑ\80иÑ\81иÑ\82иÑ\82е Ð´Ñ\83гме â\80\9e{{int:showpreview}}â\80\9d Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¸Ñ\81пÑ\80обали Ð½Ð¾Ð²Ð¸ Ð¦Ðµ-Ð\95Ñ\81\95Ñ\81 пре него што га сачувате.",
+       "userjsonyoucanpreview": "<strong>Савет:</strong> Користите дугме „{{int:showpreview}}” да бисте испробали нови ЈСОН пре него што га сачувате.",
+       "userjsyoucanpreview": "<strong>СавеÑ\82:</strong> Ð\9aоÑ\80иÑ\81иÑ\82иÑ\82е Ð´Ñ\83гме â\80\9e{{int:showpreview}}â\80\9d Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¸Ñ\81пÑ\80обали нови јаваскрипт пре него што га сачувате.",
+       "usercsspreview": "<strong>Ð\97апамÑ\82иÑ\82е Ð´Ð° Ñ\98е Ð¾Ð²Ð¾ Ñ\81амо Ð¿Ñ\80еглед Ð¦Ðµ-Ð\95Ñ\81\95Ñ\81а.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана.</strong>",
+       "userjsonpreview": "<strong>Ð\97апамÑ\82иÑ\82е Ð´Ð° Ñ\81амо Ñ\82еÑ\81Ñ\82иÑ\80аÑ\82е/пÑ\80егледаваÑ\82е ÐºÐ¾Ñ\80иÑ\81ниÑ\87ке Ð\88СÐ\9eÐ\9d Ð¿Ð¾Ñ\81Ñ\82авке.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана.</strong>",
+       "userjspreview": "<strong>Ð\97апамÑ\82иÑ\82е Ð´Ð° Ñ\81амо Ñ\82еÑ\81Ñ\82иÑ\80аÑ\82е/пÑ\80егледаваÑ\82е ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки Ñ\98аваÑ\81кÑ\80ипÑ\82.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана.</strong>",
+       "sitecsspreview": "<strong>Запамтите да је ово само преглед Це-Ес-Еса.\nСтраница још није сачувана.</strong>",
+       "sitejsonpreview": "<strong>Запамтите да је ово само преглед ЈСОН-а.\nСтраница још није сачувана.</strong>",
+       "sitejspreview": "<strong>Ð\97апамÑ\82иÑ\82е Ð´Ð° Ñ\98е Ð¾Ð²Ð¾ Ñ\81амо Ð¿Ñ\80еглед Ñ\98аваÑ\81кÑ\80ипÑ\82 ÐºÐ¾Ð´Ð°.\nСÑ\82Ñ\80аниÑ\86а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ñ\81аÑ\87Ñ\83вана.</strong>",
+       "userinvalidconfigtitle": "<strong>УпозоÑ\80еÑ\9aе:</strong> Ð\9dе Ð¿Ð¾Ñ\81Ñ\82оÑ\98и Ñ\82ема â\80\9e$1â\80\9c.\nÐ\9fÑ\80илагоÑ\92ене Ñ\81Ñ\82Ñ\80аниÑ\86е .css, .json Ð¸ .js Ð¿Ð¾Ñ\87иÑ\9aÑ\83 Ð¼Ð°Ð»Ð¸Ð¼ Ñ\81ловом, Ð½Ð¿Ñ\80. {{ns:user}}:Ð\91лабла/vector.css, Ð° Ð½Ðµ {{ns:user}}:Ð\91лабла/Vector.css.",
        "updated": "(ажурирано)",
        "note": "<strong>Напомена:</strong>",
        "previewnote": "<strong>Не заборавите да је ово само претпреглед.</strong>\nВаше промене још нису сачуване!",
-       "continue-editing": "Ð\9fÑ\80еÑ\92и Ð½Ð° Ð¾Ð±Ð°Ñ\81Ñ\82 Ñ\83Ñ\80еÑ\92иваÑ\9aа",
+       "continue-editing": "Ð\9fÑ\80еÑ\92и Ð½Ð° Ð¾Ð±Ð»Ð°Ñ\81Ñ\82 Ð·Ð° Ñ\83Ñ\80еÑ\92иваÑ\9aе",
        "previewconflict": "Овај преглед осликава како ће изгледати текст у текстуалном оквиру.",
        "session_fail_preview": "Извињавамо се! Нисмо могли да обрадимо вашу измену због губитка података сесије.\n\nМожда сте одјављени. <strong>Проверите да ли сте пријављени и покушајте поново</strong>.\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите, те проверите да ли су на вашем претраживачу дозвољени колачићи са овог сајта.",
        "session_fail_preview_html": "Нисмо могли да обрадимо вашу измену због губитка података сесије.\n\n<em>Будући да је на овом викију омогућен унос HTML ознака, преглед је сакривен као мера предострожности против напада преко јаваскрипта.</em>\n\n<strong>Ако сте покушали да направите праву измену, покушајте поново.<strong>\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите и проверите да ли ваш прегледач дозвољава колачиће са овог сајта.",
        "postedit-confirmation-published": "Ваша измена је објављена.",
        "edit-already-exists": "Није могуће направити нову страницу.\nИзгледа да она већ постоји.",
        "defaultmessagetext": "Подразумевани текст поруке",
-       "content-failed-to-parse": "РаÑ\88Ñ\87лаÑ\9aиваÑ\9aе Ñ\81адÑ\80жаÑ\98а Ñ\82ипа $2 Ð·Ð° Ð¼Ð¾Ð´ÐµÐ» $1 Ð½Ð¸Ñ\98е Ñ\83Ñ\81пело: $3",
+       "content-failed-to-parse": "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\80аÑ\88Ñ\87ланим Ñ\81адÑ\80жаÑ\98 Ð²Ñ\80Ñ\81Ñ\82е $2 Ð·Ð° Ð¼Ð¾Ð´ÐµÐ» $1: $3",
        "invalid-content-data": "Неважећи подаци садржаја",
        "content-not-allowed-here": "Садржај $1 није дозвољен на страници [[:$2]] у слоту „$3”",
        "editwarning-warning": "Ако напустите ову страницу, изгубићете све измене које сте направили. Ако сте пријављени, можете онемогућити ово упозорење у својим подешавањима, у одељку „{{int:prefs-editing}}“.",
        "slot-name-main": "Главни",
        "content-model-wikitext": "викитекста",
        "content-model-text": "чистог текста",
-       "content-model-javascript": "JavaScript-а",
-       "content-model-css": "CSS-а",
-       "content-model-json": "JSON-а",
+       "content-model-javascript": "јаваскрипта",
+       "content-model-css": "Це-Ес-Еса",
+       "content-model-json": "ЈСОН-а",
        "content-json-empty-object": "Празан објекат",
        "content-json-empty-array": "Празан низ",
        "deprecated-self-close-category": "Странице које користе невалидне самозатварајуће HTML тагове",
        "revdelete-edit-reasonlist": "Уреди разлоге за брисање",
        "revdelete-offender": "Аутор измене:",
        "suppressionlog": "Дневник сакривања",
-       "suppressionlogtext": "Испод се налази списак брисања и блокирања који укључује садржај сакривен од администратора. Погледајте [[Special:BlockList|списак блокирања]] за списак тренутних операција забрана и блокирања.",
+       "suppressionlogtext": "Испод се налази списак брисања и блокирања који укључује садржај сакривен од администратора. Погледајте [[Special:BlockList|списак блокирања]] за списак текућих забрана и блокирања.",
        "mergehistory": "Обједињавање историја странице",
        "mergehistory-header": "Ова страница вам допушта да обједините историју измена неке изворне странице у новију страницу.\nУверите се да ће ова промена оставити непромењен садржај историје странице.",
        "mergehistory-box": "Обједини измене двеју страница:",
        "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "Дневник обједињавања",
        "revertmerge": "растави",
-       "mergelogpagetext": "Ð\98Ñ\81под Ñ\98е списак најновијих обједињавања историја једне странице у другу.",
+       "mergelogpagetext": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ списак најновијих обједињавања историја једне странице у другу.",
        "history-title": "Историја измена странице „$1”",
        "difference-title": "Разлика између измена на страници „$1”",
        "difference-title-multipage": "Разлика између страница „$1“ и „$2“",
        "prefs-rc": "Скорашње измене",
        "prefs-watchlist": "Списак надгледања",
        "prefs-editwatchlist": "Уређивање списка надгледања",
-       "prefs-editwatchlist-label": "Уреди уносе на списку надгледања:",
-       "prefs-editwatchlist-edit": "Приказ и уклањање наслова са списка надгледања",
-       "prefs-editwatchlist-raw": "Уређивање необрађеног списка надгледања",
-       "prefs-editwatchlist-clear": "ЧиÑ\88Ñ\9bеÑ\9aе Ñ\81пиÑ\81ка надгледања",
+       "prefs-editwatchlist-label": "Уредите уносе на списку надгледања:",
+       "prefs-editwatchlist-edit": "Погледајте и уклоните наслове са списка надгледања",
+       "prefs-editwatchlist-raw": "Уредите необрађен списак надгледања",
+       "prefs-editwatchlist-clear": "Ð\9eÑ\87иÑ\81Ñ\82иÑ\82е Ñ\81пиÑ\81ак надгледања",
        "prefs-watchlist-days": "Број дана у списку надгледања:",
        "prefs-watchlist-days-max": "Највише $1 {{PLURAL:$1|дан|дана|дана}}",
        "prefs-watchlist-edits": "Највећи број промена приказаних на списку надгледања:",
        "prefs-watchlist-edits-max": "Највећи број: 1000",
        "prefs-watchlist-token": "Токен списка надгледања:",
-       "prefs-watchlist-managetokens": "УпÑ\80авÑ\99аÑ\9aе токенима",
+       "prefs-watchlist-managetokens": "УпÑ\80авÑ\99аÑ\98 токенима",
        "prefs-misc": "Разно",
        "prefs-resetpass": "Промена лозинке",
-       "prefs-changeemail": "Ð\9fÑ\80омена Ð¸Ð»Ð¸ Ñ\83клаÑ\9aаÑ\9aе Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е",
-       "prefs-setemail": "Ð\9fоÑ\81Ñ\82авÑ\99аÑ\9aе Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е",
+       "prefs-changeemail": "Ð\9fÑ\80омениÑ\82е Ð¸Ð»Ð¸ Ñ\83клониÑ\82е Ðµ-адÑ\80еÑ\81Ñ\83",
+       "prefs-setemail": "Ð\9fоÑ\81Ñ\82авÑ\99аÑ\9aе Ðµ-адÑ\80еÑ\81е",
        "prefs-email": "Опције е-поште",
        "prefs-rendering": "Изглед",
        "saveprefs": "Сачувај",
        "searchresultshead": "Претрага",
        "stub-threshold": "Праг за форматирање веза као клице ($1):",
        "stub-threshold-sample-link": "пример",
-       "stub-threshold-disabled": "Ð\9eнемогућено",
+       "stub-threshold-disabled": "онемогућено",
        "recentchangesdays": "Број дана у скорашњим изменама:",
        "recentchangesdays-max": "Највише $1 {{PLURAL:$1|дан|дана}}",
        "recentchangescount": "Подразумевани број измена за приказ у скорашњим изменама, историјама страница и дневницима:",
        "savedrights": "Корисничке групе {{GENDER:$1|корисника|кориснице}} $1 су сачуване.",
        "timezonelegend": "Временска зона:",
        "localtime": "Локално време:",
-       "timezoneuseserverdefault": "Ð\9aористи подразумеване вредности викија ($1)",
-       "timezoneuseoffset": "Ð\94руго (наведите одступање испод)",
+       "timezoneuseserverdefault": "користи подразумеване вредности викија ($1)",
+       "timezoneuseoffset": "друго (наведите одступање испод)",
        "timezone-useoffset-placeholder": "Примери вредности: „-07:00” или „01:00”",
        "servertime": "Време на серверу:",
-       "guesstimezone": "Ð\9fопуни из прегледача",
+       "guesstimezone": "попуни из прегледача",
        "timezoneregion-africa": "Африка",
        "timezoneregion-america": "Америка",
        "timezoneregion-antarctica": "Антарктик",
        "timezoneregion-europe": "Европа",
        "timezoneregion-indian": "Индијски океан",
        "timezoneregion-pacific": "Тихи океан",
-       "allowemail": "Дозволи другим корисницима да ми шаљу е-поруке",
-       "email-allow-new-users-label": "Дозволи примање е-порука од новајлија",
-       "email-blacklist-label": "Забрани овим корисницима да ми шаљу е-поруке:",
+       "allowemail": "Дозвољавај другим корисницима да ми шаљу е-поруке",
+       "email-allow-new-users-label": "Дозвољавај е-поруке од потпуно нових корисника",
+       "email-blacklist-label": "Забрањуј следећим корисницима да ми шаљу е-поруке:",
        "prefs-searchoptions": "Претрага",
        "prefs-namespaces": "Именски простори",
        "default": "подразумевано",
        "prefs-files": "Датотеке",
        "prefs-custom-css": "прилагођени CSS",
-       "prefs-custom-json": "Прилагођени JSON",
+       "prefs-custom-json": "Прилагођени ЈСОН",
        "prefs-custom-js": "прилагођени JavaScript",
        "prefs-common-config": "Дељени CSS/JSON/JavaScript за све теме:",
        "prefs-reset-intro": "Можете користити ову страницу да поново поставите своја подешавања на подразумеване вредности сајта.\nОво се не може опозвати.",
        "badsig": "Неважећи необрађени потпис.\nПроверите HTML тагове.",
        "badsiglength": "Ваш потпис је предугачак.\nНе сме бити дужи од $1 {{PLURAL:$1|знака|знака|знакова}}.",
        "yourgender": "Како желите да се представите?",
-       "gender-unknown": "Кад вас спомиње, софтвер ће користити родно неутралне речи кад год је то могуће",
+       "gender-unknown": "Кад вас помиње, софтвер ће користити родно неутралне речи кад год је то могуће",
        "gender-male": "Он уређује вики странице",
        "gender-female": "Она уређује вики странице",
-       "prefs-help-gender": "Постављање овог подешавања је опционално.\nСофтвер користи дату вредност да би вам се обратио и споменуо вас другима користећи одговарајући граматички род.\nОва информација ће бити јавна.",
+       "prefs-help-gender": "Постављање овог подешавања је опционално.\nСофтвер користи дату вредност да би вам се обратио и поменуо вас другима користећи одговарајући граматички род.\nОва информација ће бити јавна.",
        "email": "Е-пошта",
-       "prefs-help-realname": "Ð\9fÑ\80аво Ð¸Ð¼Ðµ Ñ\98е Ð¾Ð¿Ñ\86ионално.\nÐ\90ко Ñ\98е Ð½Ð°Ð²ÐµÐ´ено, биће коришћено за приписивање вашег рада.",
-       "prefs-help-email": "Ð\90дÑ\80еÑ\81а Ðµ-поÑ\88Ñ\82е је опционална, али је потребна за ресетовање лозинке, ако је заборавите.",
-       "prefs-help-email-others": "ТакоÑ\92е Ð¼Ð¾Ð¶ÐµÑ\82е Ð¾Ð°Ð±Ñ\80аÑ\82и Ð´Ð° Ð´Ð¾Ð¿Ñ\83Ñ\81Ñ\82иÑ\82е Ð´Ñ\80Ñ\83гима Ð´Ð° Ð²Ð°Ñ\81 ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\98Ñ\83 Ð¿Ñ\80еко Ðµ-поÑ\88Ñ\82е Ð¿Ñ\83Ñ\82ем Ð²ÐµÐ·Ðµ Ð½Ð° Ð²Ð°Ñ\88оÑ\98 ÐºÐ¾Ñ\80иÑ\81ниÑ\87коÑ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ð¸Ð»Ð¸ Ñ\81Ñ\82Ñ\80аниÑ\86и Ð·Ð° Ñ\80азговоÑ\80.\nÐ\92аÑ\88а Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е неће бити приказана другим корисницима који вас контактирају.",
-       "prefs-help-email-required": "Ð\9fоÑ\82Ñ\80ебна Ñ\98е Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е.",
+       "prefs-help-realname": "Ð\9fÑ\80аво Ð¸Ð¼Ðµ Ñ\98е Ð¾Ð¿Ñ\86ионално.\nÐ\90ко Ñ\98е Ð¿Ñ\80Ñ\83жено, биће коришћено за приписивање вашег рада.",
+       "prefs-help-email": "Ð\95-адÑ\80еÑ\81а је опционална, али је потребна за ресетовање лозинке, ако је заборавите.",
+       "prefs-help-email-others": "ТакоÑ\92е Ð¼Ð¾Ð¶ÐµÑ\82е Ð¾Ð´Ð°Ð±Ñ\80аÑ\82и Ð´Ð° Ð´Ð¾Ð¿Ñ\83Ñ\81Ñ\82иÑ\82е Ð´Ñ\80Ñ\83гима Ð´Ð° Ð²Ð°Ñ\81 ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\98Ñ\83 Ð¿Ñ\83Ñ\82ем Ðµ-поÑ\88Ñ\82е Ð¿Ñ\80еко Ð²ÐµÐ·Ðµ Ð½Ð° Ð²Ð°Ñ\88оÑ\98 ÐºÐ¾Ñ\80иÑ\81ниÑ\87коÑ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ð¸Ð»Ð¸ Ñ\81Ñ\82Ñ\80аниÑ\86и Ð·Ð° Ñ\80азговоÑ\80.\nÐ\92аÑ\88а Ðµ-адÑ\80еÑ\81а неће бити приказана другим корисницима који вас контактирају.",
+       "prefs-help-email-required": "Ð\9fоÑ\82Ñ\80ебна Ñ\98е Ðµ-адÑ\80еÑ\81а.",
        "prefs-info": "Основне информације",
        "prefs-i18n": "Интернационализација",
        "prefs-signature": "Потпис",
        "prefs-diffs": "Разлике",
        "prefs-help-prefershttps": "Ова подешавања ће ступити на снагу при следећој пријави.",
        "prefswarning-warning": "Направили сте промене у подешавањима које још увек нису сачуване.\nАко напустите ову страницу без клика на „$1“, подешавања неће да буду ажурирана.",
-       "prefs-tabs-navigation-hint": "СавеÑ\82: Ð¼Ð¾Ð¶ÐµÑ\82е ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82и Ñ\82ипке Ñ\81а Ð»ÐµÐ²Ð¾Ð¼ Ð¸ Ð´ÐµÑ\81ном Ñ\81Ñ\82Ñ\80елиÑ\86ом Ð·Ð° ÐºÑ\80еÑ\82аÑ\9aе ÐºÑ\80оз ÐºÐ°Ñ\80Ñ\82иÑ\86е.",
+       "prefs-tabs-navigation-hint": "СавеÑ\82: Ð\9cожеÑ\82е ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82и Ñ\82аÑ\81Ñ\82еÑ\80 Ñ\81а Ð»ÐµÐ²Ð¾Ð¼ Ð¸ Ð´ÐµÑ\81ном Ñ\81Ñ\82Ñ\80елиÑ\86ом Ð·Ð° ÐºÑ\80еÑ\82аÑ\9aе ÐºÑ\80оз ÐºÐ°Ñ\80Ñ\82иÑ\86е Ð½Ð° Ñ\81пиÑ\81кÑ\83.",
        "userrights": "Корисничка права",
        "userrights-lookup-user": "Избор корисника",
        "userrights-user-editname": "Корисничко име:",
        "right-reupload": "замењивање постојећих датотека",
        "right-reupload-own": "замењивање сопствених датотека",
        "right-reupload-shared": "локално замењивање датотека на дељеном спремишту медија",
-       "right-upload_by_url": "отпремање датотека са URL адресе",
+       "right-upload_by_url": "отпремање датотека са УРЛ-а",
        "right-purge": "чишћење кеш меморије странице без потврде",
        "right-autoconfirmed": "без ограничавања ставки за IP адресе",
        "right-bot": "сматрање измена као аутоматски процес",
        "right-editsemiprotected": "уређивање страница под заштитом „{{int:protect-level-autoconfirmed}}“",
        "right-editcontentmodel": "мењање модела садржаја странице",
        "right-editinterface": "уређивање корисничког окружења",
-       "right-editusercss": "уређивање туђих CSS датотека",
-       "right-edituserjson": "уређивање туђих JSON датотека",
-       "right-edituserjs": "уређивање туђих JavaScript датотека",
-       "right-editmyusercss": "уређивање сопствених CSS датотека",
-       "right-editmyuserjson": "уређивање сопствених JSON датотека",
-       "right-editmyuserjs": "уређивање сопствених JavaScript датотека",
+       "right-editusercss": "уређивање туђих Це-Ес-Ес датотека",
+       "right-edituserjson": "уређивање туђих ЈСОН датотека",
+       "right-edituserjs": "уређивање туђих јаваскрипт датотека",
+       "right-editmyusercss": "уређивање сопствених Це-Ес-Ес датотека",
+       "right-editmyuserjson": "уређивање сопствених ЈСОН датотека",
+       "right-editmyuserjs": "уређивање сопствених јаваскрипт датотека",
        "right-viewmywatchlist": "преглед сопственог списка надгледања",
        "right-editmywatchlist": "уређивање сопственог списка надгледања; неке предузете радње ће свеједно додати странице на списак и без овог права",
-       "right-viewmyprivateinfo": "пÑ\80еглед Ñ\81опÑ\81Ñ\82вениÑ\85 Ð¿Ñ\80иваÑ\82ниÑ\85 Ð¿Ð¾Ð´Ð°Ñ\82ака (нпÑ\80. Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е, Ð¿Ñ\80аво Ð¸Ð¼Ðµ)",
-       "right-editmyprivateinfo": "Ñ\83Ñ\80еÑ\92иваÑ\9aе Ñ\81опÑ\81Ñ\82вениÑ\85 Ð¿Ñ\80иваÑ\82ниÑ\85 Ð¿Ð¾Ð´Ð°Ñ\82ака (нпÑ\80. Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е, правог имена)",
+       "right-viewmyprivateinfo": "пÑ\80еглед Ñ\81опÑ\81Ñ\82вениÑ\85 Ð¿Ñ\80иваÑ\82ниÑ\85 Ð¿Ð¾Ð´Ð°Ñ\82ака (нпÑ\80. Ðµ-адÑ\80еÑ\81е, Ð¿Ñ\80авог Ð¸Ð¼ÐµÐ½Ð°)",
+       "right-editmyprivateinfo": "Ñ\83Ñ\80еÑ\92иваÑ\9aе Ñ\81опÑ\81Ñ\82вениÑ\85 Ð¿Ñ\80иваÑ\82ниÑ\85 Ð¿Ð¾Ð´Ð°Ñ\82ака (нпÑ\80. Ðµ-адÑ\80еÑ\81е, правог имена)",
        "right-editmyoptions": "уређивање сопствених подешавања",
        "right-rollback": "брзо враћање измена последњег корисника који је мењао одређену страницу",
        "right-markbotedits": "означавање враћених измена као измене бота",
        "grant-createaccount": "Отварање налога",
        "grant-createeditmovepage": "Прављење, уређивање и премештање страница",
        "grant-delete": "Брисање страница, измена и уноса у дневницима",
-       "grant-editinterface": "Уређивање именског простора Медијавики и JSON-а сајта/корисника",
-       "grant-editmycssjs": "Уређивање вашег CSS/JSON/Јаваскрипта",
-       "grant-editmyoptions": "Уређивање ваших корисничких подешавања и JSON конфигурације",
+       "grant-editinterface": "Уређивање именског простора Медијавики и ЈСОН-а сајта/корисника",
+       "grant-editmycssjs": "Уређивање вашег корисничког Це-Ес-Еса/ЈСОН-а/јаваскрипта",
+       "grant-editmyoptions": "Уређивање ваших корисничких подешавања и ЈСОН поставке",
        "grant-editmywatchlist": "Уређивање вашег списка надгледања",
        "grant-editpage": "Уређивање постојећих страница",
        "grant-editprotected": "Уређивање заштићених страница",
        "action-upload": "отпремите ову датотеку",
        "action-reupload": "замењујете ову постојећу датотеку",
        "action-reupload-shared": "премостите ову датотеку са заједничког складишта",
-       "action-upload_by_url": "отпремите ову датотеку са URL адресе",
+       "action-upload_by_url": "отпремите ову датотеку са УРЛ-а",
        "action-writeapi": "користите API за писање",
        "action-delete": "избришете ову страницу",
        "action-deleterevision": "бришете измене",
        "rcfilters-watchlist-markseen-button": "Означи све промене као виђене",
        "rcfilters-watchlist-edit-watchlist-button": "Уреди списак надгледаних страница",
        "rcfilters-watchlist-showupdated": "Промене на страницама које нисте посетили од када је измена извршена су <strong>подебљане</strong>, с испуњеним ознакама.",
-       "rcfilters-preference-label": "Користи интерфејс без JavaScript-а",
+       "rcfilters-preference-label": "Користи интерфејс без јаваскрипта",
        "rcfilters-preference-help": "Учитава скорашње измене без претраге филтера или функционалности истицања.",
-       "rcfilters-watchlist-preference-label": "Користи интерфејс без JavaScript-а",
+       "rcfilters-watchlist-preference-label": "Користи интерфејс без јаваскрипта",
        "rcfilters-watchlist-preference-help": "Учитава списак надгледања без претраге филтера или функционалности истицања.",
        "rcfilters-filter-showlinkedfrom-label": "Прикажи промене на страницама са којих долазе везе",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Странице са којих долазе везе до</strong> изабране странице",
        "upload-preferred": "Препоручени {{PLURAL:$2|тип|типови}} датотека: $1.",
        "upload-prohibited": "Забрањени {{PLURAL:$2|тип|типови}} датотека: $1.",
        "uploadlogpage": "Дневник отпремања",
-       "uploadlogpagetext": "Ð\98Ñ\81под Ñ\98е Ñ\81пиÑ\81ак Ð½ÐµÐ´Ð°Ð²Ð½Ð¸Ñ\85 Ð¾Ñ\82пÑ\80емаÑ\9aа.\nÐ\9fогледаÑ\98Ñ\82е [[Special:NewFiles|галеÑ\80иÑ\98Ñ\83 Ð½Ð¾Ð²Ð¸Ñ\85 Ð´Ð°Ñ\82оÑ\82ека]] Ð·Ð° Ð»ÐµÐ¿Ñ\88и преглед.",
+       "uploadlogpagetext": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð½Ð°Ñ\98новиÑ\98иÑ\85 Ð¾Ñ\82пÑ\80емаÑ\9aа.\nÐ\9fогледаÑ\98Ñ\82е [[Special:NewFiles|галеÑ\80иÑ\98Ñ\83 Ð½Ð¾Ð²Ð¸Ñ\85 Ð´Ð°Ñ\82оÑ\82ека]] Ð·Ð° Ð²Ð¸Ð·Ñ\83елниÑ\98и преглед.",
        "filename": "Назив датотеке",
        "filedesc": "Опис измене",
        "fileuploadsummary": "Опис измене:",
        "illegalfilename": "Име датотеке „$1“ садржи знакове који нису дозвољени у насловима страница.\nПреименујте датотеку и покушате да је поново отпремите.",
        "filename-toolong": "Називи датотека могу имати највише 240 бајтова.",
        "badfilename": "Име датотеке је промењено у „$1“.",
-       "filetype-mime-mismatch": "Ð\9fÑ\80оÑ\88иÑ\80еÑ\9aе Ð´Ð°Ñ\82оÑ\82еке â\80\9e.$1â\80\9c Ð½Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð°Ñ\80а Ð¿Ñ\80епознаÑ\82ом Ñ\82ипÑ\83 MIME датотеке ($2).",
-       "filetype-badmime": "Ð\94аÑ\82оÑ\82еке MIME Ñ\82ипа â\80\9e$1â\80\9c Ð½Ð¸Ñ\98е Ð´Ð¾Ð·Ð²Ð¾Ñ\99ено Ñ\81лаÑ\82и.",
-       "filetype-bad-ie-mime": "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð¾Ñ\82пÑ\80емим Ð¾Ð²Ñ\83 Ð´Ð°Ñ\82оÑ\82екÑ\83 Ñ\98еÑ\80 Ð±Ð¸ Ñ\98е Ð\98нÑ\82еÑ\80неÑ\82 ÐµÐºÑ\81плоÑ\80еÑ\80 Ð¿Ñ\80епознао ÐºÐ°Ð¾ â\80\9e$1â\80\9c, Ñ\88Ñ\82о Ñ\98е Ð½ÐµÐ´Ð¾Ð·Ð²Ð¾Ñ\99ен Ð¸ Ð¿Ð¾Ñ\82енÑ\86иÑ\98ално Ð¾Ð¿Ð°Ñ\81ан Ñ\82ип датотеке.",
+       "filetype-mime-mismatch": "Ð\9fÑ\80оÑ\88иÑ\80еÑ\9aе Ð´Ð°Ñ\82оÑ\82еке â\80\9e.$1â\80\9d Ð½Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð°Ñ\80а Ð¿Ñ\80епознаÑ\82оÑ\98 Ð²Ñ\80Ñ\81Ñ\82и Ð\9cÐ\98Ð\9cÐ\95 датотеке ($2).",
+       "filetype-badmime": "Ð\9dиÑ\98е Ð´Ð¾Ð·Ð²Ð¾Ñ\99ено Ð¾Ñ\82пÑ\80емаÑ\82и Ð´Ð°Ñ\82оÑ\82еке Ð²Ñ\80Ñ\81Ñ\82е Ð\9cÐ\98Ð\9cÐ\95 â\80\9e$1â\80\9d.",
+       "filetype-bad-ie-mime": "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð¾Ñ\82пÑ\80емим Ð¾Ð²Ñ\83 Ð´Ð°Ñ\82оÑ\82екÑ\83 Ñ\98еÑ\80 Ð±Ð¸ Ñ\98е Ð\98нÑ\82еÑ\80неÑ\82 ÐµÐºÑ\81плоÑ\80еÑ\80 Ð¿Ñ\80епознао ÐºÐ°Ð¾ â\80\9e$1â\80\9d, Ñ\88Ñ\82о Ñ\98е Ð½ÐµÐ´Ð¾Ð·Ð²Ð¾Ñ\99ена Ð¸ Ð¿Ð¾Ñ\82енÑ\86иÑ\98ално Ð¾Ð¿Ð°Ñ\81на Ð²Ñ\80Ñ\81Ñ\82а датотеке.",
        "filetype-unwanted-type": "<strong>„.$1“</strong> је непожељан тип датотеке.\n{{PLURAL:$3|Пожељан тип датотеке је|Пожељни типови датотека су}} $2.",
        "filetype-banned-type": "<strong>„.$1“</strong> {{PLURAL:$4|није допуштен тип датотеке|нису допуштени типови датотека}}.\n{{PLURAL:$3|Дозвољен тип датотеке је|Дозвољени типови датотека су}} $2.",
        "filetype-missing": "Ова датотека нема проширење (нпр. „.jpg“).",
        "uploadwarning-text-nostash": "Ре-отпремите датотеку, измените опис испод и покушајте поново.",
        "savefile": "Сачувај датотеку",
        "uploaddisabled": "Отпремање је онемогућено.",
-       "copyuploaddisabled": "Отпремање са URL адресе је онемогућено.",
+       "copyuploaddisabled": "Отпремање са УРЛ-а је онемогућено.",
        "uploaddisabledtext": "Отпремање датотека је онемогућено.",
        "php-uploaddisabledtext": "Отпремање датотека је онемогућено у PHP-у.\nПроверите подешавања file_uploads.",
        "uploadscripted": "Датотека садржи HTML или скриптни код који може бити погрешно протумачен од стране прегледача.",
        "upload-scripted-pi-callback": "Датотека која садржи инструкције за обраду XML стилског облика се не може отпремити.",
        "upload-scripted-dtd": "Није могуће отпремање SVG датотека које садрже нестандардну DTD декларацију.",
        "uploaded-script-svg": "Пронађен скриптни елеменат „$1“ у постављеној SVG датотеци.",
-       "uploaded-hostile-svg": "Пронађен небезбедан CSS у стилском елементу постављене SVG датотеке.",
+       "uploaded-hostile-svg": "Пронађен је небезбедан Це-Ес-Ес у стилском елементу отпремљене СВГ датотеке.",
        "uploaded-event-handler-on-svg": "Није дозвољено постављање атрибута који контролишу догађаје <code>$1=\"$2\"</code> у SVG датотекама.",
        "uploaded-href-unsafe-target-svg": "Пронађен href са несигурним подацима: URI одредиште <code>&lt;$1 $2=\"$3\"&gt;</code> у постављеној SVG датотеци.",
        "uploaded-animate-svg": "Пронађена „animate“ ознака која можда мења href користећи се „from“ атрибутом <code>&lt;$1 $2=\"$3\"&gt;</code> у постављеној SVG датотеци.",
        "uploadjava": "Датотека је формата ZIP који садржи јава .class елемент.\nСлање јава датотека није дозвољено јер оне могу изазвати заобилажење сигурносних ограничења.",
        "upload-source": "Изворна датотека",
        "sourcefilename": "Назив изворне датотеке:",
-       "sourceurl": "URL адреса извора:",
+       "sourceurl": "УРЛ извора:",
        "destfilename": "Назив:",
        "upload-maxfilesize": "Максимална величина датотеке: $1",
        "upload-description": "Опис датотеке",
        "filename-bad-prefix": "Назив датотеке коју шаљете почиње са <strong>„$1“</strong>, а њега обично додељују дигитални фотоапарати.\nИзаберите назив датотеке који описује њен садржај.",
        "filename-prefix-blacklist": " #<!-- оставите овај ред онаквим какав јесте --> <pre>\n# Синтакса је следећа:\n#   * Све од тарабе па до краја реда је коментар\n#   * Сваки ред означава префикс типичних назива датотека које додељивају дигитални апарати\nCIMG # Касио\nDSC_ # Никон\nDSCF # Фуџи\nDSCN # Никон\nDUW # неки мобилни телефони\nIMG # опште\nJD # Џеноптик\nMGP # Пентакс\nPICT # разно\n #</pre> <!-- оставите овај ред онаквим какав јесте -->",
        "upload-proto-error": "Неважећи протокол",
-       "upload-proto-error-text": "Удаљено отпремање захтева URL адресе које почињу са <code>http://</code> или <code>ftp://</code>.",
+       "upload-proto-error-text": "Удаљено отпремање захтева УРЛ-ове које почињу са <code>http://</code> или <code>ftp://</code>.",
        "upload-file-error": "Унутрашња грешка",
        "upload-file-error-text": "Дошло је до унутрашње грешке при отварању привремене датотеке на серверу.\nКонтактирајте [[Special:ListUsers/sysop|администратора]].",
        "upload-misc-error": "Непозната грешка при слању датотеке",
-       "upload-misc-error-text": "Ð\9dепознаÑ\82а Ð³Ñ\80еÑ\88ка Ð¿Ñ\80и Ð¾Ñ\82пÑ\80емаÑ\9aÑ\83 Ð´Ð°Ñ\82оÑ\82еке.\nÐ\9fÑ\80овеÑ\80иÑ\82е Ð´Ð° Ð»Ð¸ Ñ\98е Ð°Ð´Ñ\80еÑ\81а Ð²Ð°Ð»Ð¸Ð´Ð½Ð° Ð¸ Ð¿Ð¾ÐºÑ\83Ñ\88аÑ\98Ñ\82е Ð¿Ð¾Ð½Ð¾Ð²Ð¾.\nÐ\90ко Ñ\81е Ð¿Ñ\80облем Ð½Ðµ Ñ\80еÑ\88и, ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\98Ñ\82е [[Special:ListUsers/sysop|админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80а]].",
-       "upload-too-many-redirects": "Адреса садржи превише преусмерења",
+       "upload-misc-error-text": "Ð\94оÑ\88ло Ñ\98е Ð´Ð¾ Ð½ÐµÐ¿Ð¾Ð·Ð½Ð°Ñ\82е Ð³Ñ\80еÑ\88ке Ð¿Ñ\80и Ð¾Ñ\82пÑ\80емаÑ\9aÑ\83 Ð´Ð°Ñ\82оÑ\82еке.\nÐ\9fÑ\80овеÑ\80иÑ\82е Ð´Ð° Ð»Ð¸ Ñ\98е Ð£Ð Ð\9b Ð²Ð°Ð¶ÐµÑ\9bи Ð¸ Ð´Ð¾Ñ\81Ñ\82Ñ\83пан, Ð¿Ð° Ð¿Ð¾ÐºÑ\83Ñ\88аÑ\98Ñ\82е Ð¿Ð¾Ð½Ð¾Ð²Ð¾.\nÐ\90ко Ñ\81е Ð¿Ñ\80облем Ð±Ñ\83де Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ñ\98авио, Ð¾Ð±Ñ\80аÑ\82иÑ\82е Ñ\81е [[Special:ListUsers/sysop|админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]].",
+       "upload-too-many-redirects": "URL садржи превише преусмерења",
        "upload-http-error": "Дошло је до HTTP грешке: $1",
        "upload-copy-upload-invalid-domain": "Примерци отпремања нису доступни на овом домену.",
        "upload-dialog-disabled": "Отпремања датотека коришћењем овог дијалога су онемогућена на овом викију.",
        "uploadstash-nofiles": "Немате сакривене датотеке.",
        "uploadstash-badtoken": "Извршавање ове радње није успело, разлог томе може бити истек времена за уређивање. Покушајте поново.",
        "uploadstash-errclear": "Брисање датотека није успело.",
-       "uploadstash-refresh": "Освежи списак датотека",
+       "uploadstash-refresh": "Освежи листу датотека",
        "uploadstash-thumbnail": "прикажи сличицу",
        "uploadstash-exception": "Не могу сачувати датотеку у складиште ($1): „$2“.",
        "uploadstash-bad-path": "Путања не постоји.",
-       "uploadstash-bad-path-invalid": "Ð\9fÑ\83Ñ\82аÑ\9aа Ð½Ð¸Ñ\98е Ð²Ð°Ð»Ð¸Ð´Ð½а.",
+       "uploadstash-bad-path-invalid": "Ð\9fÑ\83Ñ\82аÑ\9aа Ð½Ð¸Ñ\98е Ð²Ð°Ð¶ÐµÑ\9bа.",
        "uploadstash-bad-path-unknown-type": "Непознат тип „$1“.",
        "uploadstash-bad-path-unrecognized-thumb-name": "Непрепознато име минијатуре.",
        "uploadstash-bad-path-bad-format": "Кључ „$1“ није у одговарајућем облику.",
        "uploadstash-file-not-found-no-thumb": "Није могуће прибавити сличицу.",
        "uploadstash-file-not-found-no-local-path": "Нема локалне путање за умањену ставку.",
        "uploadstash-file-not-found-no-object": "Није могуће направити локални датотечни објекат за сличицу.",
-       "uploadstash-file-not-found-no-remote-thumb": "Ð\94обавÑ\99аÑ\9aе Ñ\81лиÑ\87иÑ\86е Ð½Ð¸Ñ\98е Ñ\83Ñ\81пело: $1\nURL Ð°Ð´Ñ\80еÑ\81а = $2",
+       "uploadstash-file-not-found-no-remote-thumb": "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð´Ð¾Ð±Ð°Ð²Ð¸Ð¼ Ñ\81лиÑ\87иÑ\86Ñ\83: $1\nУРÐ\9b = $2",
        "uploadstash-file-not-found-missing-content-type": "Недостаје заглавље за тип садржаја.",
        "uploadstash-file-not-found-not-exists": "Не могу наћи путању или ово није обична датотека.",
        "uploadstash-file-too-large": "Не могу послужити датотеку већу од $1 {{PLURAL:$1|бајта|бајтова}}",
        "img-auth-streaming": "Учитавам „$1“...",
        "img-auth-public": "Сврха img_auth.php је да прослеђује датотеке из приватних викија.\nОвај вики је постављен као јавни.\nРади сигурности, img_auth.php је онемогућен.",
        "img-auth-noread": "Корисник нема приступ за читање „$1“.",
-       "http-invalid-url": "Ð\9dеважеÑ\9bа URL Ð°Ð´Ñ\80еÑ\81а: $1",
-       "http-invalid-scheme": "Адресе са шемом „$1“ нису подржане.",
+       "http-invalid-url": "Ð\9dеважеÑ\9bи Ð£Ð Ð\9b: $1",
+       "http-invalid-scheme": "URL-ови са шемом „$1” нису подржани.",
        "http-request-error": "HTTP захтев није прошао због непознате грешке.",
        "http-read-error": "HTTP грешка при читању.",
        "http-timed-out": "Захтев HTTP је истекао.",
-       "http-curl-error": "Грешка при добављању URL адресе: $1",
+       "http-curl-error": "Грешка при добављању УРЛ-а: $1",
        "http-bad-status": "Дошло је до проблема током захтева HTTP: $1 $2",
        "http-internal-error": "HTTP интерна грешка.",
-       "upload-curl-error6": "Ð\9dиÑ\98е Ð¼Ð¾Ð³Ñ\83Ñ\9bе Ð¿Ñ\80иÑ\81Ñ\82Ñ\83пиÑ\82и URL Ð°Ð´Ñ\80еÑ\81и",
-       "upload-curl-error6-text": "Ð\9dиÑ\98е Ð¼Ð¾Ð³Ñ\83Ñ\9bе Ð¿Ñ\80иÑ\81Ñ\82Ñ\83пиÑ\82и Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ñ\98 URL Ð°Ð´Ñ\80еÑ\81и.\nÐ\9fоново Ð¿Ñ\80овеÑ\80иÑ\82е Ð´Ð° Ð»Ð¸ Ñ\98е Ð¸Ñ\81пÑ\80авна и да ли сајт ради.",
+       "upload-curl-error6": "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð¿Ñ\80иÑ\81Ñ\82Ñ\83пим Ð£Ð Ð\9b\83",
+       "upload-curl-error6-text": "Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð¿Ñ\80иÑ\81Ñ\82Ñ\83пим Ð¿Ñ\80Ñ\83женом Ð£Ð Ð\9b\83.\nÐ\9fоново Ð¿Ñ\80овеÑ\80иÑ\82е Ð´Ð° Ð»Ð¸ Ñ\98е Ð¸Ñ\81пÑ\80аван и да ли сајт ради.",
        "upload-curl-error28": "Отпремање је истекло",
        "upload-curl-error28-text": "Сервер не одговара на упит.\nПроверите да ли сајт ради, мало осачекајте и покушајте поново.\nПробајте касније када буде мање оптерећење.",
        "license": "Лиценца:",
        "nolicense": "Није изабрано",
        "licenses-edit": "Уреди избор лиценци",
        "license-nopreview": "(преглед није доступан)",
-       "upload_source_url": "(ваÑ\88а Ð¾Ð´Ð°Ð±Ñ\80ана Ð´Ð°Ñ\82оÑ\82ека Ð¾Ð´ Ð²Ð°Ð¶ÐµÑ\9bиÑ\85, Ñ\98авно Ð´Ð¾Ñ\81Ñ\82Ñ\83пниÑ\85 URL Ð°Ð´Ñ\80еÑ\81а)",
+       "upload_source_url": "(ваÑ\88а Ð¾Ð´Ð°Ð±Ñ\80ана Ð´Ð°Ñ\82оÑ\82ека Ð¸Ð· Ð²Ð°Ð¶ÐµÑ\9bег, Ñ\98авно Ð´Ð¾Ñ\81Ñ\82Ñ\83пног Ð£Ð Ð\9b-а)",
        "upload_source_file": "(ваша одабрана датотека са рачунара)",
        "listfiles-delete": "избриши",
        "listfiles-summary": "Ова посебна страница приказује све отпремљене датотеке.",
        "filedelete-maintenance-title": "Није могуће избрисати датотеку",
        "mimesearch": "MIME претрага",
        "mimesearch-summary": "Ова страница омогућава филтрирање датотека према њиховим MIME типовима.\nУлазни подаци: contenttype/subtype или contenttype/*, нпр. <code>image/jpeg</code>.",
-       "mimetype": "MIME тип:",
+       "mimetype": "МИМЕ врста:",
        "download": "преузми",
        "unwatchedpages": "Ненадгледане странице",
        "listredirects": "Списак преусмерења",
        "listduplicatedfiles": "Списак датотека са дупликатима",
-       "listduplicatedfiles-summary": "Ово је списак датотека које су дупликат неких других датотека. Само локалне датотеке су приказане.",
+       "listduplicatedfiles-summary": "Ово је списак датотека чија је најновија верзија дупликат неких других датотека. Само локалне датотеке су приказане.",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] има [[$3|{{PLURAL:$2|један дупликат|$2 дупликата}}]].",
        "unusedtemplates": "Некоришћени шаблони",
        "unusedtemplatestext": "Ова страница наводи све странице у именском простору {{ns:template}} које нису укључене ни на једној другој страници.\nПре брисања проверите да ли друге странице воде до тих шаблона.",
        "pageswithprop-text": "Ова страна излистава стране које имају одређену особину",
        "pageswithprop-prop": "Име особине:",
        "pageswithprop-reverse": "Поређај у супротном редоследу",
-       "pageswithprop-sortbyvalue": "СоÑ\80Ñ\82иÑ\80ај по вредности својства",
+       "pageswithprop-sortbyvalue": "Ð\9fоÑ\80еÑ\92ај по вредности својства",
        "pageswithprop-submit": "Иди",
        "pageswithprop-prophidden-long": "сакривено дуго текстуално својство ($1)",
        "pageswithprop-prophidden-binary": "сакривено дуго бинарно својство ($1)",
        "unusedimages": "Некоришћене датотеке",
        "wantedcategories": "Тражене категорије",
        "wantedpages": "Тражене странице",
-       "wantedpages-summary": "СпиÑ\81ак Ð½ÐµÐ¿Ð¾Ñ\81Ñ\82оÑ\98еÑ\9bиÑ\85 Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81а Ð½Ð°Ñ\98виÑ\88е Ð²ÐµÐ·Ð° Ð´Ð¾ Ñ\9aиÑ\85, Ð½Ð° Ð¾Ð²Ð¾Ð¼ Ñ\81пиÑ\81кÑ\83 Ñ\81е Ð½Ðµ Ð½Ð°Ð»Ð°Ð·Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð´Ð¾ ÐºÐ¾Ñ\98иÑ\85 Ð²Ð¾Ð´Ðµ Ð¿Ñ\80еÑ\83Ñ\81меÑ\80еÑ\9aа. Ð\97а Ñ\81пиÑ\81ак Ð¿Ð¾ÐºÐ²Ð°Ñ\80ениÑ\85 Ð¿Ñ\80еÑ\83Ñ\81меÑ\80еÑ\9aа погледајте [[{{#special:BrokenRedirects}}|списак покварених преусмерења]].",
+       "wantedpages-summary": "СпиÑ\81ак Ð½ÐµÐ¿Ð¾Ñ\81Ñ\82оÑ\98еÑ\9bиÑ\85 Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81а Ð½Ð°Ñ\98виÑ\88е Ð²ÐµÐ·Ð° Ð½Ð° Ñ\9aиÑ\85, Ð½Ð° Ð¾Ð²Ð¾Ð¼ Ñ\81пиÑ\81кÑ\83 Ñ\81е Ð½Ðµ Ð½Ð°Ð»Ð°Ð·Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð´Ð¾ ÐºÐ¾Ñ\98иÑ\85 Ð²Ð¾Ð´Ðµ Ð¿Ñ\80еÑ\83Ñ\81меÑ\80еÑ\9aа. Ð\97а Ñ\81пиÑ\81ак Ð¿Ð¾ÐºÐ²Ð°Ñ\80ениÑ\85 Ð¿Ñ\80еÑ\83Ñ\81меÑ\80еÑ\9aа, погледајте [[{{#special:BrokenRedirects}}|списак покварених преусмерења]].",
        "wantedpages-badtitle": "Невалидан наслов у скупу резултата: $1",
        "wantedfiles": "Тражене датотеке",
        "wantedfiletext-cat": "Следеће датотеке се користе, али не постоје. Датотеке из других ризница могу бити наведене иако не постоје. Такве датотеке ће бити <del>поништене</del> са списка. Поред тога, странице које садрже непостојеће датотеке се налазе [[:$1|овде]].",
        "protectedpages": "Заштићене странице",
        "protectedpages-filters": "Филтери:",
        "protectedpages-indef": "Само неограничене заштите",
-       "protectedpages-summary": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð¿Ð¾Ñ\81Ñ\82оÑ\98еÑ\9bиÑ\85 Ñ\81Ñ\82Ñ\80аниÑ\86а ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ñ\82Ñ\80енÑ\83Ñ\82но Ð·Ð°Ñ\88Ñ\82иÑ\9bене. Ð\97а Ñ\81пиÑ\81ак наслова који су заштићени од прављења, погледајте [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+       "protectedpages-summary": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ð½Ð°Ð²Ð¾Ð´Ð¸ Ð¿Ð¾Ñ\81Ñ\82оÑ\98еÑ\9bе Ñ\81Ñ\82Ñ\80аниÑ\86е ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ñ\82Ñ\80енÑ\83Ñ\82но Ð·Ð°Ñ\88Ñ\82иÑ\9bене. Ð\97а Ð»Ð¸Ñ\81Ñ\82Ñ\83 наслова који су заштићени од прављења, погледајте [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Само преносиве заштите",
        "protectedpages-noredirect": "Сакриј преусмерења",
        "protectedpagesempty": "Нема заштићених страница с овим параметрима.",
        "protectedpages-unknown-timestamp": "нема",
        "protectedpages-unknown-performer": "нема",
        "protectedtitles": "Заштићени наслови",
-       "protectedtitles-summary": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\81е Ð½Ð°Ð»Ð°Ð·Ðµ Ð½Ð°Ñ\81лови ÐºÐ¾Ñ\98и Ñ\81Ñ\83 Ñ\82Ñ\80енÑ\83Ñ\82но Ð·Ð°Ñ\88Ñ\82иÑ\9bени Ð¾Ð´ Ð¿Ñ\80авÑ\99еÑ\9aа. Ð\97а Ñ\81пиÑ\81ак постојећих страница које су заштићене, погледајте [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
+       "protectedtitles-summary": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ð½Ð°Ð²Ð¾Ð´Ð¸ Ð½Ð°Ñ\81лове ÐºÐ¾Ñ\98и Ñ\81Ñ\83 Ñ\82Ñ\80енÑ\83Ñ\82но Ð·Ð°Ñ\88Ñ\82иÑ\9bени Ð¾Ð´ Ð¿Ñ\80авÑ\99еÑ\9aа. Ð\97а Ð»Ð¸Ñ\81Ñ\82Ñ\83 постојећих страница које су заштићене, погледајте [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Нема заштићених наслова с овим параметрима.",
        "protectedtitles-submit": "Прикажи наслове",
        "listusers": "Списак корисника",
        "listusers-editsonly": "Прикажи само кориснике који су уређивали",
        "listusers-temporarygroupsonly": "Прикажи само кориснике у привременим корисничким групама",
-       "listusers-creationsort": "СоÑ\80Ñ\82иÑ\80аÑ\98 Ð¿Ð¾ Ð´Ð°Ñ\82Ñ\83мÑ\83 Ð¿Ñ\80авÑ\99еÑ\9aа",
+       "listusers-creationsort": "Ð\9fоÑ\80еÑ\92аÑ\98 Ð¿Ð¾ Ð´Ð°Ñ\82Ñ\83мÑ\83 Ð¾Ñ\82ваÑ\80аÑ\9aа Ð½Ð°Ð»Ð¾Ð³а",
        "listusers-desc": "Поређај у опадајућем редоследу",
        "usereditcount": "$1 {{PLURAL:$1|измена|измене|измена}}",
        "usercreated": "{{GENDER:$3|је направио|је направила|је направио}} дана $1 у $2",
        "apihelp": "API помоћ",
        "apihelp-no-such-module": "Модул „$1“ није пронађен.",
        "apisandbox": "API песак",
-       "apisandbox-jsonly": "JavaScript је неопходан за коришћење API песка.",
+       "apisandbox-jsonly": "Јаваскрипт је неопходан за коришћење АПИ песка.",
        "apisandbox-api-disabled": "АПИ је онемогућен на овом сајту.",
        "apisandbox-submit": "Пошаљи захтев",
        "apisandbox-reset": "Обриши",
        "apisandbox-deprecated-parameters": "Застарели параметри",
        "apisandbox-fetch-token": "Аутоматски испуни токен",
        "apisandbox-add-multi": "Додај",
-       "apisandbox-submit-invalid-fields-title": "Ð\9dека Ð¿Ð¾Ñ\99а Ð½Ð¸Ñ\81Ñ\83 Ð²Ð°Ð»Ð¸Ð´Ð½а",
+       "apisandbox-submit-invalid-fields-title": "Ð\9dека Ð¿Ð¾Ñ\99а Ð½Ð¸Ñ\81Ñ\83 Ð²Ð°Ð¶ÐµÑ\9bа",
        "apisandbox-submit-invalid-fields-message": "Молимо Вас поправите означена поља и покушајте поново.",
        "apisandbox-results": "Резултати",
        "apisandbox-sending-request": "Шаљем API захтев…",
        "apisandbox-loading-results": "Пријем API резултата...",
        "apisandbox-results-error": "Дошло је до грешке приликом учитавања резултата API упита: $1.",
        "apisandbox-request-selectformat-label": "Прикажи сахтеване податке као:",
-       "apisandbox-request-url-label": "URL адреса захтева:",
+       "apisandbox-request-url-label": "УРЛ захтева:",
        "apisandbox-request-format-json-label": "JSON",
-       "apisandbox-request-json-label": "Затражите JSON:",
+       "apisandbox-request-json-label": "Затражите ЈСОН:",
        "apisandbox-request-time": "Време за извршавање захтјева: {{PLURAL:$1|$1 милисекунда|$1 милисекунде|$1 милисекунди}}",
        "apisandbox-results-fixtoken": "Исправи токен и пошаљи поново",
        "apisandbox-results-fixtoken-fail": "Неуспело добијање „$1“ токена.",
        "booksources-search-legend": "Претражи штампане изворе",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Претражи",
-       "booksources-text": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð²ÐµÐ·Ð° ÐºÐ° Ñ\81аÑ\98Ñ\82овима који се баве продајом нових и половних књига, а који би могли имати додатне податке о књигама које тражите:",
+       "booksources-text": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð²ÐµÐ·Ð° Ð½Ð° Ð´Ñ\80Ñ\83ге Ñ\81аÑ\98Ñ\82ове који се баве продајом нових и половних књига, а који би могли имати додатне податке о књигама које тражите:",
        "booksources-invalid-isbn": "Наведени ISBN број није валидан. Проверите да није дошло до грешке при копирању из првобитног извора.",
        "magiclink-tracking-rfc": "Странице са чаробним RFC везама",
        "magiclink-tracking-pmid": "Странице са чаробним PMID везама",
        "activeusers-noresult": "Корисник није пронађен.",
        "activeusers-submit": "Прикажи активне кориснике",
        "listgrouprights": "Права корисничких група",
-       "listgrouprights-summary": "Следи списак корисничких група на овом викију, заједно с правима приступа.\nПогледајте [[{{MediaWiki:Listgrouprights-helppage}}|више детаља]] о појединачним правима.",
+       "listgrouprights-summary": "Следи листа корисничких група дефинисаних на овом викију, заједно са повезаним правима приступа.\nМожда постоји [[{{MediaWiki:Listgrouprights-helppage}}|више информација]] о појединачним правима.",
        "listgrouprights-key": "Легенда:\n* <span class=\"listgrouprights-granted\">Додељено право</span>\n* <span class=\"listgrouprights-revoked\">Укинуто право</span>",
        "listgrouprights-group": "Група",
        "listgrouprights-rights": "Права",
        "listgrants-rights": "Права",
        "listgrants-grant-display": "$1 <code>($2)</code>",
        "trackingcategories": "Категорије за праћење",
-       "trackingcategories-summary": "Ова посебна страница је списак категорија које су део Медијавикија, оне се аутоматски ажурирају и њихови називи се могу мењати уређивањем системских порука у именском простору {{ns:8}}.",
+       "trackingcategories-summary": "Ова страница наводи категорије за праћење које аутоматски попуњава софтвер Медијавики. Њихова имена се могу променити изменом одговарајућих системских порука у именском простору {{ns:8}}.",
        "trackingcategories-msg": "Категорије за праћење",
        "trackingcategories-name": "Име поруке",
        "trackingcategories-desc": "Које странице се налазе у категорији",
        "trackingcategories-nodesc": "Опис није доступан.",
        "trackingcategories-disabled": "Категорија је онемогућена",
        "mailnologin": "Нема адресе за слање",
-       "mailnologintext": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ñ\81е [[Special:UserLogin|пÑ\80иÑ\98авиÑ\82е]] Ð¸ Ð¸Ð¼Ð°Ñ\82е Ð²Ð°Ð¶ÐµÑ\9bи Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е у [[Special:Preferences|подешавањима]] да бисте слали е-поруке другим корисницима.",
+       "mailnologintext": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ñ\81е [[Special:UserLogin|пÑ\80иÑ\98авиÑ\82е]] Ð¸ Ð¸Ð¼Ð°Ñ\82е Ð²Ð°Ð¶ÐµÑ\9bи Ðµ-адÑ\80еÑ\81Ñ\83 у [[Special:Preferences|подешавањима]] да бисте слали е-поруке другим корисницима.",
        "emailuser": "Пошаљи е-поруку овом кориснику/ци",
        "emailuser-title-target": "Слање е-поруке {{GENDER:$1|кориснику|корисници|кориснику/ци}}",
-       "emailuser-title-notarget": "СлаÑ\9aе Ð¸Ð¼ÐµÑ\98ла кориснику",
-       "emailpagetext": "Ð\9cожеÑ\82е Ð´Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ð´Ð¾Ñ\9aи Ð¾Ð±Ñ\80азаÑ\86 Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99еÑ\82е Ð¸Ð¼ÐµÑ\98л {{GENDER:$1|овом ÐºÐ¾Ñ\80иÑ\81никÑ\83|овоÑ\98 ÐºÐ¾Ñ\80иÑ\81ниÑ\86и}}.\nÐ\98меÑ\98л ÐºÐ¾Ñ\98и Ñ\81Ñ\82е Ñ\83нели Ñ\83 Ð²Ð°Ñ\88им [[Special:Preferences|подеÑ\88аваÑ\9aима]] Ñ\9bе Ñ\81е Ð¿Ñ\80иказаÑ\82и Ñ\83 Ð¿Ð¾Ñ\99Ñ\83 â\80\9eÐ\9eдâ\80\9c, тако да ће прималац моћи да вам одговори директно.",
+       "emailuser-title-notarget": "СлаÑ\9aе Ðµ-поÑ\80Ñ\83ке кориснику",
+       "emailpagetext": "Ð\9cожеÑ\82е Ð´Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ð´Ð¾Ñ\9aи Ð¾Ð±Ñ\80азаÑ\86 Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99еÑ\82е Ðµ-поÑ\80Ñ\83кÑ\83 {{GENDER:$1|овом ÐºÐ¾Ñ\80иÑ\81никÑ\83|овоÑ\98 ÐºÐ¾Ñ\80иÑ\81ниÑ\86и}}.\nÐ\95-адÑ\80еÑ\81а ÐºÐ¾Ñ\98и Ñ\81Ñ\82е Ñ\83нели Ñ\83 Ð²Ð°Ñ\88им [[Special:Preferences|подеÑ\88аваÑ\9aима]] Ñ\9bе Ñ\81е Ð¿Ñ\80иказаÑ\82и Ñ\83 Ð¿Ð¾Ñ\99Ñ\83 â\80\9eÐ\9eдâ\80\9d, тако да ће прималац моћи да вам одговори директно.",
        "defemailsubject": "{{SITENAME}} — е-порука од {{GENDER:$1|корисника|кориснице|корисника/це}} „$1”",
        "usermaildisabled": "Корисничка е-пошта је онемогућена",
        "usermaildisabledtext": "Не можете да шаљете е-поруке другим корисницима на овом викију",
-       "noemailtitle": "Ð\9dема Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е",
-       "noemailtext": "Ð\9eваÑ\98 ÐºÐ¾Ñ\80иÑ\81ник Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ¾ Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е.",
+       "noemailtitle": "Ð\9dема Ðµ-адÑ\80еÑ\81е",
+       "noemailtext": "Ð\9eваÑ\98 ÐºÐ¾Ñ\80иÑ\81ник Ð½Ð¸Ñ\98е Ð½Ð°Ð²ÐµÐ¾ Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ðµ-адÑ\80еÑ\81Ñ\83.",
        "nowikiemailtext": "Овај корисник је одабрао да не прима е-поруке од других корисника.",
        "emailnotarget": "Непостојеће или наважеће корисничко име примаоца.",
        "emailtarget": "Унос корисничког имена примаоца",
        "emailccsubject": "Копија поруке кориснику/ци $1: $2",
        "emailsent": "Е-порука је послата",
        "emailsenttext": "Ваша е-порука је послата.",
-       "emailuserfooter": "Ð\9eвÑ\83 Ðµ-поÑ\80Ñ\83кÑ\83 Ñ\98е {{GENDER:$1|поÑ\81лао|поÑ\81лала|поÑ\81лао/ла}} $1 {{GENDER:$2|коÑ\80иÑ\81никÑ\83|коÑ\80иÑ\81ниÑ\86и|коÑ\80иÑ\81никÑ\83\86и}} $2 Ð¿Ð¾Ð¼Ð¾Ñ\9bÑ\83 Ð¾Ð¿Ñ\86иÑ\98е â\80\9e{{int:emailuser}}â\80\9d Ð½Ð° Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}. Ð\90ко Ð¾Ð´Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82е Ð½Ð° Ð¾Ð²Ñ\83 Ðµ-поÑ\80Ñ\83кÑ\83, {{GENDER:$2|ваÑ\88а}} Ðµ-поÑ\80Ñ\83ка Ð±Ð¸Ñ\9bе Ð½ÐµÐ¿Ð¾Ñ\81Ñ\80едно Ð¿Ñ\80оÑ\81леÑ\92ена ÐºÐ° {{GENDER:$1|оÑ\80игиналном Ð¿Ð¾Ñ\88иÑ\99аоÑ\86Ñ\83}}, Ñ\87име Ñ\9bеÑ\82е {{GENDER:$2|мÑ\83\98оÑ\98}} Ð¾Ñ\82кÑ\80иÑ\82и {{GENDER:$2|адÑ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е}}.",
+       "emailuserfooter": "Ð\9eвÑ\83 Ðµ-поÑ\80Ñ\83кÑ\83 Ñ\98е {{GENDER:$1|поÑ\81лао|поÑ\81лала|поÑ\81лао/ла}} $1 {{GENDER:$2|коÑ\80иÑ\81никÑ\83|коÑ\80иÑ\81ниÑ\86и|коÑ\80иÑ\81никÑ\83\86и}} $2 Ð¿Ð¾Ð¼Ð¾Ñ\9bÑ\83 Ð¾Ð¿Ñ\86иÑ\98е â\80\9e{{int:emailuser}}â\80\9d Ð½Ð° Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}. Ð\90ко Ð¾Ð´Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82е Ð½Ð° Ð¾Ð²Ñ\83 Ðµ-поÑ\80Ñ\83кÑ\83, {{GENDER:$2|ваÑ\88а}} Ðµ-поÑ\80Ñ\83ка Ð±Ð¸Ñ\9bе Ð½ÐµÐ¿Ð¾Ñ\81Ñ\80едно Ð¿Ñ\80оÑ\81леÑ\92ена ÐºÐ° {{GENDER:$1|оÑ\80игиналном Ð¿Ð¾Ñ\88иÑ\99аоÑ\86Ñ\83}}, Ñ\87име Ñ\9bеÑ\82е {{GENDER:$2|мÑ\83\98оÑ\98}} Ð¾Ñ\82кÑ\80иÑ\82и {{GENDER:$2|е-адÑ\80еÑ\81Ñ\83}}.",
        "usermessage-summary": "Слање системске поруке.",
        "usermessage-editor": "Уређивач системских порука",
        "usermessage-template": "MediaWiki:UserMessage",
        "addwatch": "Додавање на списак надгледања",
        "addedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је додата на ваш [[Special:Watchlist|списак надгледања]].",
        "addedwatchtext-talk": "Страница „[[:$1]]” и њена придружена страница је додата на ваш [[Special:Watchlist|списак надгледања]]",
-       "addedwatchtext-short": "СÑ\82Ñ\80аниÑ\86а â\80\9e$1â\80\9c Ñ\98е Ð´Ð¾Ð´Ð°Ñ\82а Ð½Ð° Ð²Ð°Ñ\88 списак надгледања.",
+       "addedwatchtext-short": "СÑ\82Ñ\80аниÑ\86а â\80\9e$1â\80\9d Ñ\98е Ð´Ð¾Ð´Ð°Ñ\82а Ð½Ð° списак надгледања.",
        "removewatch": "Уклони са списка надгледања",
        "removedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је уклоњена са вашег [[Special:Watchlist|списка надгледања]].",
        "removedwatchtext-talk": "\"[[:$1]]\" и његове повезане странице су уклоњене са вашег [[Special:Watchlist|списка надгледања]].",
        "enotif_lastvisited": "За све промене од последње посете, погледајте $1.",
        "enotif_lastdiff": "Да бисте видели ову промену, погледајте $1.",
        "enotif_anon_editor": "анониман корисник $1",
-       "enotif_body": "Ð\9fоÑ\88Ñ\82овани $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nРезиме Ñ\83Ñ\80еÑ\92иваÑ\87а: $PAGESUMMARY $PAGEMINOREDIT\n\nÐ\9aонÑ\82акÑ\82:\nмеÑ\98л: $PAGEEDITOR_EMAIL\nвики: $PAGEEDITOR_WIKI\n\nÐ\9dеÑ\9bе Ð±Ð¸Ñ\82и Ð´Ñ\80Ñ\83гиÑ\85 Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ñ\83 Ñ\81лÑ\83Ñ\87аÑ\98Ñ\83 Ð´Ð°Ñ\99иÑ\85 Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\83колико Ð½Ðµ Ð¿Ð¾Ñ\81еÑ\82иÑ\82е Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ð´Ð° Ñ\81Ñ\82е Ð¿Ñ\80иÑ\98авÑ\99ени.\nÐ\9cожеÑ\82е Ð¸ Ð´Ð° Ð¿Ð¾Ð½Ð¸Ñ\88Ñ\82иÑ\82е Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ð·Ð° Ñ\81ве Ñ\81Ñ\82Ñ\80аниÑ\86е Ñ\83 Ð²Ð°Ñ\88ем Ñ\81пиÑ\81кÑ\83 Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа.\n\nСÑ\80даÑ\87ан Ð¿Ð¾Ð·Ð´Ñ\80ав, {{SITENAME}}\n\n--\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ñ\80оменили Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа Ð¸Ð¼ÐµÑ\98л Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа, посетите\n{{canonicalurl:{{#special:Preferences}}}}\n\nДа бисте променили подешавања списка надгледања, посетите\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nДа бисте уклонили ову страницу са списка надгледања, посетите\n$UNWATCHURL\n\nПодршка и даља помоћ:\n$HELPPAGE",
+       "enotif_body": "Ð\9fоÑ\88Ñ\82овани $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nРезиме Ñ\83Ñ\80еÑ\92иваÑ\87а: $PAGESUMMARY $PAGEMINOREDIT\n\nÐ\9aонÑ\82акÑ\82:\nпоÑ\88Ñ\82а: $PAGEEDITOR_EMAIL\nвики: $PAGEEDITOR_WIKI\n\nÐ\9dеÑ\9bе Ð±Ð¸Ñ\82и Ð´Ñ\80Ñ\83гиÑ\85 Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ñ\83 Ñ\81лÑ\83Ñ\87аÑ\98Ñ\83 Ð´Ð°Ñ\99иÑ\85 Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\83колико Ð½Ðµ Ð¿Ð¾Ñ\81еÑ\82иÑ\82е Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ð´Ð° Ñ\81Ñ\82е Ð¿Ñ\80иÑ\98авÑ\99ени.\nÐ\9cожеÑ\82е Ð¸ Ð´Ð° Ð¿Ð¾Ð½Ð¸Ñ\88Ñ\82иÑ\82е Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ð·Ð° Ñ\81ве Ñ\81Ñ\82Ñ\80аниÑ\86е Ñ\83 Ð²Ð°Ñ\88ем Ñ\81пиÑ\81кÑ\83 Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа.\n\nСÑ\80даÑ\87ан Ð¿Ð¾Ð·Ð´Ñ\80ав, {{SITENAME}}\n\n--\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ñ\80оменили Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82аваÑ\9aа Ð¿Ñ\83Ñ\82ем Ðµ-поÑ\88Ñ\82е, посетите\n{{canonicalurl:{{#special:Preferences}}}}\n\nДа бисте променили подешавања списка надгледања, посетите\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nДа бисте уклонили ову страницу са списка надгледања, посетите\n$UNWATCHURL\n\nПодршка и даља помоћ:\n$HELPPAGE",
        "enotif_minoredit": "Ово је мања измена",
        "created": "направљена",
        "changed": "измењена",
        "actionfailed": "Радња није успела",
        "deletedtext": "Страница „$1“ је избрисана.\nПогледајте $2 за запис недавних брисања.",
        "dellogpage": "Дневник брисања",
-       "dellogpagetext": "Ð\98Ñ\81под Ñ\98е Ñ\81пиÑ\81ак Ð½ÐµÐ´Ð°Ð²Ð½их брисања.",
+       "dellogpagetext": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð½Ð°Ñ\98новиÑ\98их брисања.",
        "deletionlog": "дневник брисања",
        "log-name-create": "Дневник прављења страница",
-       "log-description-create": "Ð\98Ñ\81под Ñ\98е Ñ\81пиÑ\81ак Ð½ÐµÐ´Ð°Ð²Ð½их прављења страница.",
+       "log-description-create": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð½Ð°Ñ\98новиÑ\98их прављења страница.",
        "logentry-create-create": "$1 је {{GENDER:$2|направио|направила}} страницу $3",
        "reverted": "Враћено на ранију измену",
        "deletecomment": "Разлог:",
        "deleting-backlinks-warning": "<strong>Упозорење:</strong> бришете страницу која је укључена у [[Special:WhatLinksHere/{{FULLPAGENAME}}|друге странице]] или друге странице воде на њу.",
        "deleting-subpages-warning": "<strong>Упозорење:</strong> Страница коју желите избрисати има [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|подстраницу|$1 подстранице|$1 подстраница|51=преко 50 подстраница}}]].",
        "rollback": "Врати измене",
+       "rollback-confirmation-confirm": "Потврдите:",
        "rollbacklink": "врати",
        "rollbacklinkcount": "врати $1 {{PLURAL:$1|измену|измене|измена}}",
        "rollbacklinkcount-morethan": "врати више од $1 {{PLURAL:$1|измене|измене|измена}}",
        "revertpage": "Враћене измене {{GENDER:$2|корисника|кориснице}} [[Special:Contributions/$2|$2]] ([[User talk:$2|разговор]]) на последњу измену {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
        "revertpage-nouser": "Враћене измене скривеног корисника на последњу измену {{GENDER:$1|корисника|кориснице}} [[User:$1|$1]]",
        "rollback-success": "Враћене измене {{GENDER:$1|корисника|кориснице}} {{GENDER:$3|$1}}  на последњу измену {{GENDER:$2|корисника|кориснице}} {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Враћене измене корисника $1;\nвраћено на последњу измену корисника $2. [$3 Прикажи промене]",
        "sessionfailure-title": "Сесија је окончана",
        "sessionfailure": "Изгледа да постоји проблем с вашом сесијом;\nова радња је отказана да би се избегла злоупотреба.\nМолимо, поново пошаљите образац.",
        "changecontentmodel": "Промена модела садржаја странице",
        "logentry-contentmodel-change-revertlink": "врати",
        "logentry-contentmodel-change-revert": "врати",
        "protectlogpage": "Дневник заштите",
-       "protectlogtext": "Ð\98Ñ\81под Ñ\98е Ñ\81пиÑ\81ак Ð·Ð°Ñ\88Ñ\82иÑ\9bениÑ\85 Ñ\81Ñ\82Ñ\80аниÑ\86а.\nÐ\9fогледаÑ\98Ñ\82е [[Special:ProtectedPages|Ñ\81пиÑ\81ак Ð·Ð°Ñ\88Ñ\82иÑ\9bениÑ\85 Ñ\81Ñ\82Ñ\80аниÑ\86а]] Ð·Ð° Ð²Ð¸Ñ\88е Ð´ÐµÑ\82аÑ\99а.",
+       "protectlogtext": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð¿Ñ\80омена Ð·Ð°Ñ\88Ñ\82иÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а.\nÐ\9fогледаÑ\98Ñ\82е [[Special:ProtectedPages|Ñ\81пиÑ\81ак Ð·Ð°Ñ\88Ñ\82иÑ\9bениÑ\85 Ñ\81Ñ\82Ñ\80аниÑ\86а]] Ð·Ð° Ñ\82екÑ\83Ñ\9bе Ð·Ð°Ñ\88Ñ\82иÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а.",
        "protectedarticle": "је {{GENDER:|заштитио|заштитила}} страницу „[[$1]]“",
        "modifiedarticleprotection": "је {{GENDER:|променио|променила}} ниво заштите странице „[[$1]]“",
        "unprotectedarticle": "је скинуо заштиту са странице „[[$1]]“",
        "blocklog-showsuppresslog": "{{GENDER:$1|Овај корисник је раније блокиран и сакривен|Ова корисница је раније блокирана и сакривена}}.\nДневник сакривања је наведен испод као референца:",
        "blocklogentry": "је блокирао [[$1]] са временом истицања од $2 $3",
        "reblock-logentry": "је {{GENDER:|променио|променила}} подешавања блокирања за {{GENDER:$1|корисника|корисницу}} [[$1]] са временом истека од $2 ($3)",
-       "blocklogtext": "Ð\9eво Ñ\98е Ð´Ð½ÐµÐ²Ð½Ð¸Ðº Ñ\80адÑ\9aи Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа Ð¸ Ð´ÐµÐ±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа ÐºÐ¾Ñ\80иÑ\81ника.\nÐ\90Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð±Ð»Ð¾ÐºÐ¸Ñ\80ане IP Ð°Ð´Ñ\80еÑ\81е Ð½Ð¸Ñ\81Ñ\83 Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ðµ.\nÐ\9fогледаÑ\98Ñ\82е [[Special:BlockList|Ñ\81пиÑ\81ак Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа]] Ð·Ð° Ñ\81пиÑ\81ак Ñ\82Ñ\80енÑ\83Ñ\82ниÑ\85 Ð¾Ð¿ÐµÑ\80аÑ\86иÑ\98а Ð·Ð°Ð±Ñ\80ана и блокирања.",
+       "blocklogtext": "Ð\9eво Ñ\98е ÐµÐ²Ð¸Ð´ÐµÐ½Ñ\86иÑ\98а Ñ\80адÑ\9aи Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа Ð¸ Ð´ÐµÐ±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа ÐºÐ¾Ñ\80иÑ\81ника.\nÐ\90Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð±Ð»Ð¾ÐºÐ¸Ñ\80ане IP Ð°Ð´Ñ\80еÑ\81е Ð½Ð¸Ñ\81Ñ\83 Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ðµ.\nÐ\9fогледаÑ\98Ñ\82е [[Special:BlockList|лиÑ\81Ñ\82Ñ\83 Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа]] Ð·Ð° Ñ\82Ñ\80енÑ\83Ñ\82но Ð¾Ð¿ÐµÑ\80аÑ\82ивне Ð·Ð°Ð±Ñ\80ане и блокирања.",
        "unblocklogentry": "је деблокирао $1",
        "block-log-flags-anononly": "само анонимни корисници",
        "block-log-flags-nocreate": "онемогућено отварање налога",
        "movepage-page-unmoved": "Страница $1 не може да се премести на $2.",
        "movepage-max-pages": "Највише $1 {{PLURAL:$1|страница је премештена|странице су премештене|страница је премештено}} и више не може да буде аутоматски премештено.",
        "movelogpage": "Дневник премештања",
-       "movelogpagetext": "Испод се налази списак премештања страница.",
+       "movelogpagetext": "Испод се налази списак свих премештања страница.",
        "movesubpage": "{{PLURAL:$1|Подстраница|Подстранице}}",
        "movesubpagetext": "Ова страница има $1 {{PLURAL:$1|подстраницу приказану|подстранице приказане|подстраница приказаних}} испод.",
        "movenosubpage": "Ова страница нема подстрана.",
        "exportall": "Извези све странице",
        "exportcuronly": "Укључи само тренутну измену, не целу историју",
        "exportnohistory": "----\n'''Напомена:''' извоз пуне историје страница преко овог обрасца је онемогућено из техничких разлога.",
-       "exportlistauthors": "Укључи целокупан списак доприносилаца за сваку страницу",
+       "exportlistauthors": "Укључи потпуну листу доприносилаца за сваку страницу",
        "export-submit": "Извези",
        "export-addcattext": "Додај странице из категорије:",
        "export-addcat": "Додај",
        "allmessagesname": "Назив",
        "allmessagesdefault": "Подразумевани текст",
        "allmessagescurrent": "Актуелни текст поруке",
-       "allmessagestext": "Ð\9eво Ñ\98е Ñ\81пиÑ\81ак Ñ\81иÑ\81Ñ\82емÑ\81киÑ\85 Ð¿Ð¾Ñ\80Ñ\83ка Ð´Ð¾Ñ\81Ñ\82Ñ\83пниÑ\85 Ñ\83 Ð¸Ð¼ÐµÐ½Ñ\81ком Ð¿Ñ\80оÑ\81Ñ\82оÑ\80Ñ\83 â\80\9eÐ\9cедиÑ\98авикиâ\80\9c.\nÐ\9fоÑ\81еÑ\82иÑ\82е [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation Ð\9cедиÑ\98авики Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ\86иÑ\98Ñ\83] и [https://translatewiki.net translatewiki.net] ако желите да допринесете општој локализацији Медијавикија.",
+       "allmessagestext": "Ð\9eво Ñ\98е Ñ\81пиÑ\81ак Ñ\81иÑ\81Ñ\82емÑ\81киÑ\85 Ð¿Ð¾Ñ\80Ñ\83ка Ð´Ð¾Ñ\81Ñ\82Ñ\83пниÑ\85 Ñ\83 Ð¸Ð¼ÐµÐ½Ñ\81ком Ð¿Ñ\80оÑ\81Ñ\82оÑ\80Ñ\83 â\80\9eÐ\9cедиÑ\98авикиâ\80\9d.\nÐ\9fоÑ\81еÑ\82иÑ\82е [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ\86иÑ\98Ñ\83 Ð\9cедиÑ\98авикиÑ\98а] и [https://translatewiki.net translatewiki.net] ако желите да допринесете општој локализацији Медијавикија.",
        "allmessagesnotsupportedDB": "Ова страница не може да се користи јер је '''$wgUseDatabaseMessages''' онемогућен.",
        "allmessages-filter-legend": "Филтер",
        "allmessages-filter": "Филтрирај по стању:",
        "tooltip-ca-watch": "Додајте ову страницу на списак надгледања",
        "tooltip-ca-unwatch": "Уклоните ову страницу са списка надгледања",
        "tooltip-search": "Претражите пројекат {{SITENAME}}",
-       "tooltip-search-go": "Идите на страницу са тачно овим именом ако постоји",
+       "tooltip-search-go": "Идите на страницу са тачно овим именом, ако постоји",
        "tooltip-search-fulltext": "Претражите странице са овим текстом",
        "tooltip-p-logo": "Посетите главну страну",
        "tooltip-n-mainpage": "Посетите главну страну",
        "group-bot.css": "/* CSS постављен овде ће утицати само на ботове */",
        "group-sysop.css": "/* CSS постављен овде ће утицати само на системске операторе */",
        "group-bureaucrat.css": "/* CSS постављен овде ће утицати само на бирократе */",
-       "common.json": "/* JSON постављен овде ће се користити за све кориснике при отварању сваке странице. */",
+       "common.json": "/* ЈСОН постављен овде ће се користити за све кориснике при отварању сваке странице. */",
        "common.js": "/* Јаваскрипт постављен овде ће се користити за све кориснике при отварању сваке странице. */",
        "group-autoconfirmed.js": "/* Јаваскрипт постављен овде ће се учитати за самопотврђене кориснике */",
        "group-user.js": "/* Јаваскрипт постављен овде ће се учитати за регистроване кориснике */",
        "pageinfo-header-restrictions": "Заштита странице",
        "pageinfo-header-properties": "Својства странице",
        "pageinfo-display-title": "Наслов за приказ",
-       "pageinfo-default-sort": "Ð\9fодÑ\80азÑ\83мевани ÐºÑ\99Ñ\83Ñ\87 Ñ\81оÑ\80Ñ\82иÑ\80ања",
+       "pageinfo-default-sort": "Ð\9fодÑ\80азÑ\83мевани ÐºÑ\99Ñ\83Ñ\87 Ñ\80еÑ\92ања",
        "pageinfo-length": "Дужина странице (у бајтовима)",
        "pageinfo-namespace": "Именски простор",
        "pageinfo-article-id": "ID странице",
        "file-no-thumb-animation": "<strong>Напомена: Због техничких ограничења, сличице ове датотеке неће да се анимирају.</strong>",
        "file-no-thumb-animation-gif": "'''Напомена: због техничких ограничења, минијатуре GIF слика високе резолуције као што је ова неће се анимирати.'''",
        "newimages": "Галерија нових датотека",
-       "imagelisttext": "Ð\98Ñ\81под Ñ\98е Ñ\81пиÑ\81ак Ð¾Ð´ '''$1''' {{PLURAL:$1|датотеке|датотеке|датотека}} поређаних $2.",
+       "imagelisttext": "Ð\98Ñ\81под Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð¾Ð´ <strong>$1</strong> {{PLURAL:$1|датотеке|датотеке|датотека}} поређаних $2.",
        "newimages-summary": "Ова посебна страница приказује последње отпремљене датотеке.",
        "newimages-legend": "Филтер",
        "newimages-label": "Назив датотеке (или њен део):",
        "newimages-newbies": "Прикажи само доприносе нових налога",
        "newimages-showbots": "Прикажи отпремања ботова",
        "newimages-hidepatrolled": "Сакриј патролирана отпремања",
-       "newimages-mediatype": "Тип Ð¼ÐµÐ´Ð¸Ñ\98а:",
+       "newimages-mediatype": "Ð\92Ñ\80Ñ\81Ñ\82а Ð¼ÐµÐ´Ð¸Ñ\98Ñ\83ма:",
        "noimages": "Нема ништа.",
        "gallery-slideshow-toggle": "сличице",
        "ilsubmit": "Претражи",
        "metadata-langitem-default": "$1",
        "namespacesall": "сви",
        "monthsall": "све",
-       "confirmemail": "Ð\9fоÑ\82вÑ\80да Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е",
-       "confirmemail_noemail": "Ð\9dиÑ\81Ñ\82е Ð¿Ð¾Ñ\81Ñ\82авили Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е у [[Special:Preferences|корисничким подешавањима]].",
-       "confirmemail_text": "{{SITENAME}} Ð·Ð°Ñ\85Ñ\82ева Ð´Ð° Ð¿Ñ\80овеÑ\80иÑ\82е Ð²Ð°Ñ\99аноÑ\81Ñ\82 Ð¸Ð¼ÐµÑ\98л-адÑ\80еÑ\81е Ð¿Ñ\80е Ð½ÐµÐ³Ð¾ Ñ\88Ñ\82о Ð¿Ð¾Ñ\87неÑ\82е Ð´Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ñ\84Ñ\83нкÑ\86иÑ\98Ñ\83 Ð¸Ð¼ÐµÑ\98ла.\nÐ\90кÑ\82ивиÑ\80аÑ\98Ñ\82е Ð´Ñ\83гме Ð¸Ñ\81под Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\81лали Ð¼ÐµÑ\98л Ð·Ð° Ð¿Ð¾Ñ\82вÑ\80дÑ\83 Ð½Ð° Ñ\81воÑ\98Ñ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83.\nÐ\9cеÑ\98л Ñ\9bе Ñ\83кÑ\99Ñ\83Ñ\87иваÑ\82и Ð²ÐµÐ·Ñ\83 Ñ\81а ÐºÐ¾Ð´Ð¾Ð¼;\nÑ\83Ñ\87иÑ\82аÑ\98Ñ\82е Ð²ÐµÐ·Ñ\83 Ñ\83 Ñ\81вом Ð¿Ñ\80егледаÑ\87Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ð´Ð° Ñ\98е Ð²Ð°Ñ\88а Ð¸Ð¼ÐµÑ\98л-адреса важећа.",
-       "confirmemail_pending": "Ð\9aод Ð·Ð° Ð¿Ð¾Ñ\82вÑ\80дÑ\83 Ð²Ð°Ð¼ Ñ\98е Ð²ÐµÑ\9b Ð¿Ð¾Ñ\81лаÑ\82 Ð¸Ð¼ÐµÑ\98лом.\nАко сте недавно отворили налог, можда треба да сачекате неколико минута да пристигне пре него што поново затражите нови код.",
+       "confirmemail": "Ð\9fоÑ\82вÑ\80да Ðµ-адÑ\80еÑ\81е",
+       "confirmemail_noemail": "Ð\9dиÑ\81Ñ\82е Ð¿Ð¾Ñ\81Ñ\82авили Ð²Ð°Ð¶ÐµÑ\9bÑ\83 Ðµ-адÑ\80еÑ\81Ñ\83 у [[Special:Preferences|корисничким подешавањима]].",
+       "confirmemail_text": "{{SITENAME}} Ð·Ð°Ñ\85Ñ\82ева Ð´Ð° Ð¿Ñ\80овеÑ\80иÑ\82е Ð²Ð°Ñ\99аноÑ\81Ñ\82 Ðµ-адÑ\80еÑ\81е Ð¿Ñ\80е Ð½ÐµÐ³Ð¾ Ñ\88Ñ\82о Ð¿Ð¾Ñ\87неÑ\82е Ð´Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ñ\84Ñ\83нкÑ\86иÑ\98Ñ\83 Ðµ-поÑ\88Ñ\82е.\nÐ\90кÑ\82ивиÑ\80аÑ\98Ñ\82е Ð´Ñ\83гме Ð¸Ñ\81под Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\81лали Ð¿Ð¾Ñ\80Ñ\83кÑ\83â\80\82Ñ\81а Ð¿Ð¾Ñ\82вÑ\80дом Ð½Ð° Ñ\81воÑ\98Ñ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83.\nÐ\9fоÑ\80Ñ\83ка Ñ\9bе Ñ\83кÑ\99Ñ\83Ñ\87иваÑ\82и Ð²ÐµÐ·Ñ\83 Ñ\81а ÐºÐ¾Ð´Ð¾Ð¼;\nÑ\83Ñ\87иÑ\82аÑ\98Ñ\82е Ð²ÐµÐ·Ñ\83 Ñ\83 Ñ\81вом Ð¿Ñ\80егледаÑ\87Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ð´Ð° Ñ\98е Ð²Ð°Ñ\88а Ðµ-адреса важећа.",
+       "confirmemail_pending": "Ð\9aод Ð·Ð° Ð¿Ð¾Ñ\82вÑ\80дÑ\83 Ð²Ð°Ð¼ Ñ\98е Ð²ÐµÑ\9b Ð¿Ð¾Ñ\81лаÑ\82 Ðµ-поÑ\88Ñ\82ом.\nАко сте недавно отворили налог, можда треба да сачекате неколико минута да пристигне пре него што поново затражите нови код.",
        "confirmemail_send": "Пошаљи код за потврду",
        "confirmemail_sent": "Потврдна порука је послата.",
-       "confirmemail_oncreate": "Ð\9aôд Ð·Ð° Ð¿Ð¾Ñ\82вÑ\80дÑ\83 Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82 Ð½Ð° Ð²Ð°Ñ\88Ñ\83 Ð¸Ð¼ÐµÑ\98л-адÑ\80еÑ\81Ñ\83.\nÐ\9eваÑ\98 ÐºÃ´Ð´ Ð½Ð¸Ñ\98е Ð½ÐµÐ¾Ð¿Ñ\85одан Ð·Ð° Ð¿Ñ\80иÑ\98авÑ\99иваÑ\9aе, Ð°Ð»Ð¸ Ñ\9bеÑ\82е Ð¼Ð¾Ñ\80аÑ\82и Ð´Ð° Ð³Ð° Ð½Ð°Ð²ÐµÐ´ÐµÑ\82е Ð¿Ñ\80е Ð¾Ð¼Ð¾Ð³Ñ\83Ñ\9bаваÑ\9aа Ð±Ð¸Ð»Ð¾ ÐºÐ°ÐºÐ²Ð¸Ñ\85 Ñ\84Ñ\83нкÑ\86иÑ\98а Ð·Ð°Ñ\81нованиÑ\85 Ð½Ð° Ð¸Ð¼ÐµÑ\98лÑ\83 на викију.",
-       "confirmemail_sendfailed": "{{SITENAME}} Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99е Ðµ-поÑ\80Ñ\83кÑ\83 Ð·Ð° Ð¿Ð¾Ñ\82вÑ\80дÑ\83.\nÐ\9fÑ\80овеÑ\80иÑ\82е Ð´Ð° Ð»Ð¸ Ñ\98е Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е Ñ\81адÑ\80жи Ð½ÐµÐ²Ð°Ð¶ÐµÑ\9bе Ð·Ð½Ð°Ðºе.\n\nПошиљалац је вратио грешку: $1",
+       "confirmemail_oncreate": "Ð\9aôд Ð·Ð° Ð¿Ð¾Ñ\82вÑ\80дÑ\83 Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82 Ð½Ð° Ð²Ð°Ñ\88Ñ\83 Ðµ-адÑ\80еÑ\81Ñ\83.\nÐ\9eваÑ\98 ÐºÃ´Ð´ Ð½Ð¸Ñ\98е Ð½ÐµÐ¾Ð¿Ñ\85одан Ð·Ð° Ð¿Ñ\80иÑ\98авÑ\99иваÑ\9aе, Ð°Ð»Ð¸ Ñ\9bеÑ\82е Ð¼Ð¾Ñ\80аÑ\82и Ð´Ð° Ð³Ð° Ð½Ð°Ð²ÐµÐ´ÐµÑ\82е Ð¿Ñ\80е Ð¾Ð¼Ð¾Ð³Ñ\83Ñ\9bаваÑ\9aа Ð±Ð¸Ð»Ð¾ ÐºÐ°ÐºÐ²Ð¸Ñ\85 Ñ\84Ñ\83нкÑ\86иÑ\98а Ð·Ð°Ñ\81нованиÑ\85 Ð½Ð° Ðµ-поÑ\88Ñ\82и на викију.",
+       "confirmemail_sendfailed": "{{SITENAME}} Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99е Ð¿Ð¾Ñ\80Ñ\83кÑ\83 Ñ\81а Ð¿Ð¾Ñ\82вÑ\80дом.\nÐ\9fÑ\80овеÑ\80иÑ\82е Ð´Ð° Ð»Ð¸ Ðµ-адÑ\80еÑ\81а Ñ\81адÑ\80жи Ð½ÐµÐ²Ð°Ð¶ÐµÑ\9bе Ð·Ð½Ð°ÐºÐ¾Ð²е.\n\nПошиљалац је вратио грешку: $1",
        "confirmemail_invalid": "Неважећи код за потврду.\nКод је можда истекао.",
-       "confirmemail_needlogin": "$1 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е.",
-       "confirmemail_success": "Ð\92аÑ\88а Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е је потврђена.\nСада можете да се [[Special:UserLogin|пријавите]] и уживате у викију.",
-       "confirmemail_loggedin": "Ð\92аÑ\88а Ð°Ð´Ñ\80еÑ\81а Ðµ-поÑ\88Ñ\82е је сада потврђена.",
-       "confirmemail_subject": "{{SITENAME}} â\80\93 Ð¿Ð¾Ñ\82вÑ\80да Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е",
-       "confirmemail_body": "Ð\9dеко, Ð²ÐµÑ\80оваÑ\82но Ð\92и, Ñ\81а IP Ð°Ð´Ñ\80еÑ\81е $1,\nÑ\80егиÑ\81Ñ\82Ñ\80овао Ñ\98е Ð½Ð°Ð»Ð¾Ð³ â\80\9e$2â\80\9c Ñ\81а Ð¾Ð²Ð¾Ð¼ Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81ом Ð½Ð° Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}.\n\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ð´Ð° Ð¾Ð²Ð°Ñ\98 Ð½Ð°Ð»Ð¾Ð³ Ñ\81Ñ\82ваÑ\80но Ð¿Ñ\80ипада Ð²Ð°Ð¼Ð° Ð¸ Ð°ÐºÑ\82ивиÑ\80али Ñ\84Ñ\83нкÑ\86иÑ\98Ñ\83 Ð¸Ð¼ÐµÑ\98ла Ð½Ð° Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}, Ð¾Ñ\82воÑ\80иÑ\82е Ð¾Ð²Ð° Ñ\83 Ð¿Ñ\80егледаÑ\87Ñ\83:\n\n$3\n\nÐ\90ко Ð²Ð¸ *ниÑ\81Ñ\82е* Ñ\80егиÑ\81Ñ\82Ñ\80овали Ð½Ð°Ð»Ð¾Ð³, Ð¿Ñ\80аÑ\82иÑ\82е Ð¾Ð²Ñ\83 Ð²ÐµÐ·Ñ\83\nда Ð±Ð¸Ñ\81Ñ\82е Ð¾Ñ\82казали Ð¿Ð¾Ñ\82вÑ\80дÑ\83 Ð¸Ð¼ÐµÑ\98л адресе:\n\n$5\n\nОвај код за потврду истиче у $4.",
-       "confirmemail_body_changed": "Неко, вероватно Ви, с IP адресе $1,\nпроменио је имејл адресу налога „$2“ у ову адресу на пројекту {{SITENAME}}.\n\nДа бисте потврдили да овај налог стварно припада вама и поново активирали функцију имејла, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду имејл адресе:\n\n$5\n\nОвај код за потврду истиче $6 у $7",
-       "confirmemail_body_set": "Неко, вероватно Ви, с IP адресе $1,\nпроменио је имејл адресу налога „$2“ у ову адресу на {{SITENAME}}.\n\nДа бисмо потврдили да овај налог стварно припада вама и поново активирали\nфункцију имејла на {{SITENAME}}, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду имејл адресе:\n\n$5\n\nОвај код за потврду истиче $4.",
-       "confirmemail_invalidated": "Ð\9fоÑ\82вÑ\80да Ð°Ð´Ñ\80еÑ\81е Ðµ-поÑ\88Ñ\82е је отказана",
+       "confirmemail_needlogin": "$1 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ðµ-адÑ\80еÑ\81Ñ\83.",
+       "confirmemail_success": "Ð\92аÑ\88а Ðµ-адÑ\80еÑ\81а је потврђена.\nСада можете да се [[Special:UserLogin|пријавите]] и уживате у викију.",
+       "confirmemail_loggedin": "Ð\92аÑ\88а Ðµ-адÑ\80еÑ\81а је сада потврђена.",
+       "confirmemail_subject": "{{SITENAME}} â\80\93 Ð¿Ð¾Ñ\82вÑ\80да Ðµ-адÑ\80еÑ\81е",
+       "confirmemail_body": "Ð\9dеко, Ð²ÐµÑ\80оваÑ\82но Ð\92и, Ñ\81а IP Ð°Ð´Ñ\80еÑ\81е $1,\nÑ\80егиÑ\81Ñ\82Ñ\80овао Ñ\98е Ð½Ð°Ð»Ð¾Ð³ â\80\9e$2â\80\9c Ñ\81а Ð¾Ð²Ð¾Ð¼ Ðµ-адÑ\80еÑ\81ом Ð½Ð° Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}.\n\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ð´Ð° Ð¾Ð²Ð°Ñ\98 Ð½Ð°Ð»Ð¾Ð³ Ñ\81Ñ\82ваÑ\80но Ð¿Ñ\80ипада Ð²Ð°Ð¼Ð° Ð¸ Ð°ÐºÑ\82ивиÑ\80али Ñ\84Ñ\83нкÑ\86иÑ\98е Ðµ-поÑ\88Ñ\82е Ð½Ð° Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}, Ð¾Ñ\82воÑ\80иÑ\82е Ð¾Ð²Ñ\83 Ð²ÐµÐ·Ñ\83 Ñ\83 Ð¿Ñ\80егледаÑ\87Ñ\83:\n\n$3\n\nÐ\90ко Ð²Ð¸ *ниÑ\81Ñ\82е* Ñ\80егиÑ\81Ñ\82Ñ\80овали Ð½Ð°Ð»Ð¾Ð³, Ð¿Ñ\80аÑ\82иÑ\82е Ð¾Ð²Ñ\83 Ð²ÐµÐ·Ñ\83\nда Ð±Ð¸Ñ\81Ñ\82е Ð¾Ñ\82казали Ð¿Ð¾Ñ\82вÑ\80дÑ\83 Ðµ-адресе:\n\n$5\n\nОвај код за потврду истиче у $4.",
+       "confirmemail_body_changed": "Неко, вероватно Ви, са IP адресе $1,\nпроменио је е-адресу налога „$2” у ову адресу на пројекту {{SITENAME}}.\n\nДа бисте потврдили да овај налог стварно припада вама и поново активирали функције е-поште, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду е-адресе:\n\n$5\n\nОвај код за потврду истиче $6 у $7",
+       "confirmemail_body_set": "Неко, вероватно Ви, са IP адресе $1,\nпроменио је е-адресу налога „$2” у ову адресу на {{SITENAME}}.\n\nДа бисмо потврдили да овај налог стварно припада вама и поново активирали\nфункције е-поште на пројекту {{SITENAME}}, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду е-адресе:\n\n$5\n\nОвај код за потврду истиче $4.",
+       "confirmemail_invalidated": "Ð\9fоÑ\82вÑ\80да Ðµ-адÑ\80еÑ\81е је отказана",
        "invalidateemail": "Отказивање потврде е-поште",
-       "notificationemail_subject_changed": "РегиÑ\81Ñ\82Ñ\80ована Ð¸Ð¼ÐµÑ\98л адреса на пројекту {{SITENAME}} је промењена",
-       "notificationemail_subject_removed": "РегиÑ\81Ñ\82Ñ\80ована Ð¸Ð¼ÐµÑ\98л адреса на пројекту {{SITENAME}} је уклоњена",
-       "notificationemail_body_changed": "Неко, вероватно Ви је променио имејл адресу налога из $2“ у „$3“ са IP адресе $1 на сајту {{SITENAME}}.\n\nАко ово нисте били Ви, одмах обавестите администраторе сајта.",
-       "notificationemail_body_removed": "Неко, вероватно Ви, с IP адресе $1, \nуклонио је имејл адресу за налог „$2“ на {{SITENAME}}.\n\nАко ово нисте били Ви, контактирајте администраторе сајта одмах.",
+       "notificationemail_subject_changed": "РегиÑ\81Ñ\82Ñ\80ована Ðµ-адреса на пројекту {{SITENAME}} је промењена",
+       "notificationemail_subject_removed": "РегиÑ\81Ñ\82Ñ\80ована Ðµ-адреса на пројекту {{SITENAME}} је уклоњена",
+       "notificationemail_body_changed": "Неко, вероватно Ви, са IP адресе $1,\nпроменио је е-адресу налога из „$2” у „$3” на пројекту {{SITENAME}}.\n\nАко ово нисте били Ви, одмах се обратите администратору сајта.",
+       "notificationemail_body_removed": "Неко, вероватно Ви, са IP адресе $1, \nуклонио је е-адресу налога „$2” на пројекту {{SITENAME}}.\n\nАко ово нисте били Ви, одмах се обратите администратору сајта.",
        "scarytranscludedisabled": "[Међувики укључивање шаблона је онемогућено]",
        "scarytranscludefailed": "[Добављање шаблона за $1 није успело]",
        "scarytranscludefailed-httpstatus": "[Не могу да преузмем шаблон $1: HTTP $2]",
-       "scarytranscludetoolong": "[URL адреса је предугачка]",
+       "scarytranscludetoolong": "[УРЛ је предугачак]",
        "deletedwhileediting": "<strong>Упозорење</strong>: Ова страница је избрисана након што сте почели са уређивањем!",
        "confirmrecreate": "{{GENDER:$1|Корисник|Корисница}} [[User:$1|$1]] ([[User talk:$1|разговор]]) је {{GENDER:$1|избрисао|избрисала}} ову страницу након што сте почели да је уређујете из следећег разлога:\n: <em>$2</em>\nПотврдите да стварно желите да направите страницу.",
        "confirmrecreate-noreason": "{{GENDER:$1|Корисник|Корисница}} [[User:$1|$1]] ([[User talk:$1|разговор]]) је {{GENDER:$1|избрисао|избрисала}} ову страницу након што сте почели да је уређујете. Потврдите да стварно желите да поново направите ову страницу.",
        "quotation-marks": "„$1“",
        "imgmultipageprev": "← претходна страница",
        "imgmultipagenext": "следећа страница →",
-       "imgmultigo": "Иди!",
+       "imgmultigo": "Иди",
        "imgmultigoto": "Пређи на страницу $1",
        "img-lang-opt": "$2 ($1)",
        "img-lang-default": "(подразумевани језик)",
        "version-software": "Инсталирани софтвер",
        "version-software-product": "Производ",
        "version-software-version": "Верзија",
-       "version-entrypoints": "URL адресе улазне тачке",
+       "version-entrypoints": "УРЛ-ови улазне тачке",
        "version-entrypoints-header-entrypoint": "Улазна тачка",
-       "version-entrypoints-header-url": "URL адреса",
+       "version-entrypoints-header-url": "УРЛ",
        "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Путања до чланка]",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Путања до скрипте]",
        "version-libraries": "Инсталиране библиотеке",
        "version-libraries-license": "Лиценца",
        "version-libraries-description": "Опис",
        "version-libraries-authors": "Аутори",
-       "redirect": "Ð\9fÑ\80еÑ\83Ñ\81меÑ\80еÑ\9aе Ð½Ð° Ð´Ð°Ñ\82оÑ\82екÑ\83, ÐºÐ¾Ñ\80иÑ\81ника, Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83, Ð¸Ð·Ð¼ÐµÐ½Ñ\83 Ð¸Ð»Ð¸ Ð´Ð½ÐµÐ²Ð½Ð¸Ðº (ID)",
-       "redirect-summary": "Ð\9eва Ð¿Ð¾Ñ\81ебна Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¿Ñ\80еÑ\83Ñ\81меÑ\80ава Ð´Ð¾ Ð´Ð°Ñ\82оÑ\82еке (Ñ\81 Ð´Ð°Ñ\82им Ð¸Ð¼ÐµÐ½Ð¾Ð¼ Ð´Ð°Ñ\82оÑ\82еке), Ñ\81Ñ\82Ñ\80аниÑ\86е (Ñ\81 Ð´Ð°Ñ\82им ID-ом Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¸Ð»Ð¸ ID-ом Ñ\81Ñ\82Ñ\80аниÑ\86е), ÐºÐ¾Ñ\80иÑ\81ниÑ\87ке Ñ\81Ñ\82Ñ\80аниÑ\86е (Ñ\81 Ð´Ð°Ñ\82им Ð½Ñ\83меÑ\80иÑ\87ким ÐºÐ¾Ñ\80иÑ\81ниÑ\87ким ID-ом), Ð¸Ð»Ð¸ Ñ\83ноÑ\81а Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 (Ñ\81 Ð´Ð°Ñ\82им Ð´Ð½ÐµÐ²Ð½Ð¸Ñ\87ким ID-ом). Ð£Ð¿Ð¾Ñ\82Ñ\80еба: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].",
+       "redirect": "Ð\9fÑ\80еÑ\83Ñ\81меÑ\80еÑ\9aе Ð½Ð° Ð´Ð°Ñ\82оÑ\82екÑ\83, Ð¸Ð´ÐµÐ½Ñ\82иÑ\84. ÐºÐ¾Ñ\80иÑ\81ника, Ñ\81Ñ\82Ñ\80аниÑ\86е, Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¸Ð»Ð¸ Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÐ°",
+       "redirect-summary": "Ð\9eва Ð¿Ð¾Ñ\81ебна Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¿Ñ\80еÑ\83Ñ\81меÑ\80ава Ð½Ð° Ð´Ð°Ñ\82оÑ\82екÑ\83 (даÑ\82ог Ð¸Ð¼ÐµÐ½Ð°), Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 (даÑ\82ог Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\82оÑ\80а Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¸Ð»Ð¸ Ñ\81Ñ\82Ñ\80аниÑ\86е), ÐºÐ¾Ñ\80иÑ\81ниÑ\87кÑ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 (даÑ\82ог Ð±Ñ\80оÑ\98Ñ\87аног Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\82оÑ\80а) Ð¸Ð»Ð¸ Ñ\83ноÑ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 (даÑ\82ог Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\82оÑ\80а). Ð£Ð¿Ð¾Ñ\82Ñ\80еба: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] Ð¸Ð»Ð¸ [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Иди",
-       "redirect-lookup": "Тип вредности:",
+       "redirect-lookup": "Тражи:",
        "redirect-value": "Вредност:",
-       "redirect-user": "Ð\9aоÑ\80иÑ\81ниÑ\87ки ID",
-       "redirect-page": "ID странице",
-       "redirect-revision": "РевизиÑ\98а странице",
-       "redirect-file": "Ð\9dазив датотеке",
-       "redirect-logid": "ID дневника",
+       "redirect-user": "коÑ\80иÑ\81ниÑ\87ки Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\82оÑ\80",
+       "redirect-page": "идентификатор странице",
+       "redirect-revision": "изменÑ\83 странице",
+       "redirect-file": "име датотеке",
+       "redirect-logid": "идентификатор дневника",
        "redirect-not-exists": "Вредност није пронађена",
        "redirect-not-numeric": "Вредност није нумеричка",
        "fileduplicatesearch": "Претрага дупликата датотека",
        "tag-mw-undo": "поништење",
        "tag-mw-undo-description": "Измене које поништавају претходне измене",
        "tags-title": "Ознаке",
-       "tags-intro": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\98е Ð½Ð°Ð²ÐµÐ´ÐµÐ½ Ñ\81пиÑ\81ак Ð¾Ð·Ð½Ð°ÐºÐ° Ñ\81 ÐºÐ¾Ñ\98има Ð¿Ñ\80огÑ\80ам Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð¾Ð·Ð½Ð°Ñ\87и Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¸ Ñ\9aегово значење.",
-       "tags-tag": "Ð\9dазив ознаке",
+       "tags-intro": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ð½Ð°Ð²Ð¾Ð´Ð¸ Ð¾Ð·Ð½Ð°ÐºÐµ ÐºÐ¾Ñ\98има Ñ\81оÑ\84Ñ\82веÑ\80 Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð¾Ð·Ð½Ð°Ñ\87и Ð¸Ð·Ð¼ÐµÐ½Ðµ, Ñ\82е Ñ\9aиÑ\85ово значење.",
+       "tags-tag": "Ð\98ме ознаке",
        "tags-display-header": "Изглед на списковима промена",
        "tags-description-header": "Опис значења",
        "tags-source-header": "Извор",
        "tags-delete-explanation-warning": "Ова радња је <strong>неповратна</strong> и <strong>не може да се поништи</strong>. Ово не могу да ураде чак ни администратори базе података. Будите сигурни да је ово ознака коју желите избрисати.",
        "tags-delete-reason": "Разлог:",
        "tags-delete-submit": "Неповратно избриши ову ознаку",
-       "tags-delete-not-allowed": "Ð\9eзнаке ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð´ÐµÑ\84иниÑ\81ане ÐµÐºÑ\81Ñ\82ензиÑ\98ом Ð½Ðµ Ð¼Ð¾Ð³Ñ\83 Ñ\81е Ð¸Ð·Ð±Ñ\80иÑ\81аÑ\82и Ð¾Ñ\81им Ð°ÐºÐ¾ Ð¸Ñ\85 ÐµÐºÑ\81Ñ\82ензиÑ\98а Ð½Ðµ Ð´Ð¾Ð·Ð²Ð¾Ñ\99ава.",
+       "tags-delete-not-allowed": "Ð\9eзнаке ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð¾Ð´Ñ\80еÑ\92ене Ð¿Ñ\80оÑ\88иÑ\80еÑ\9aем Ð½Ðµ Ð¼Ð¾Ð³Ñ\83 Ñ\81е Ð¸Ð·Ð±Ñ\80иÑ\81аÑ\82и Ð¾Ñ\81им Ð°ÐºÐ¾ Ð¸Ð¼ Ñ\82о Ð¿Ñ\80оÑ\88иÑ\80еÑ\9aе Ð½Ðµ Ð´Ð¾Ð·Ð²Ð¾Ð»Ð¸.",
        "tags-delete-not-found": "Ознака „$1“ не постоји.",
        "tags-delete-too-many-uses": "Ознака „$1” је примењена на више од $2 {{PLURAL:$2|измене|измена}}, што значи да се не може избрисати.",
        "tags-delete-no-permission": "Немате дозволу да бришете ознаке промена.",
        "dberr-info": "(Не могу приступити бази података: $1)",
        "dberr-info-hidden": "(Не могу приступити бази података)",
        "htmlform-invalid-input": "Постоје проблеми са неким од ваших уноса.",
-       "htmlform-select-badoption": "Ð\92Ñ\80едноÑ\81Ñ\82 ÐºÐ¾Ñ\98Ñ\83 Ñ\81Ñ\82е Ð½Ð°Ð²ÐµÐ»Ð¸ Ð½Ð¸Ñ\98е Ð²Ð°Ð»Ð¸Ð´Ð½а опција.",
+       "htmlform-select-badoption": "Ð\92Ñ\80едноÑ\81Ñ\82 ÐºÐ¾Ñ\98Ñ\83 Ñ\81Ñ\82е Ð½Ð°Ð²ÐµÐ»Ð¸ Ð½Ð¸Ñ\98е Ð²Ð°Ð¶ÐµÑ\9bа опција.",
        "htmlform-int-invalid": "Наведена вредност није цели број.",
        "htmlform-float-invalid": "Наведена вредност није број.",
        "htmlform-int-toolow": "Наведена вредност је испод минимума од $1",
        "htmlform-title-not-creatable": "Страница „$1“ се не може направити",
        "htmlform-title-not-exists": "$1 не постоји.",
        "htmlform-user-not-exists": "<strong>$1</strong> не постоји.",
-       "htmlform-user-not-valid": "<strong>$1</strong> Ð½Ð¸Ñ\98е Ð²Ð°Ð»Ð¸Ð´Ð½Ð¾ корисничко име.",
+       "htmlform-user-not-valid": "<strong>$1</strong> Ð½Ð¸Ñ\98е Ð²Ð°Ð¶ÐµÑ\9bе корисничко име.",
        "logentry-delete-delete": "$1 је {{GENDER:$2|избрисао|избрисала}} страницу $3",
        "logentry-delete-delete_redir": "$1 је {{GENDER:$2|избрисао|избрисала}} преусмерење $3 преписивањем",
        "logentry-delete-restore": "$1 је {{GENDER:$2|вратио|вратила}} страницу $3 ($4)",
        "logentry-block-block": "$1 је {{GENDER:$2|блокирао|блокирала}} {{GENDER:$4|$3}} у трајању од $5 $6",
        "logentry-block-unblock": "$1 је {{GENDER:$2|деблокирао|деблокирала}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 је {{GENDER:$2|променио|променила}} подешавања за блокирање {{GENDER:$4|корисника|кориснице}} {{GENDER:$4|$3}} у трајању од $5 $6",
-       "logentry-partialblock-block": "$1 је {{GENDER:$2|блокирао|блокирала}} уређивање {{PLURAL:$8|странице|страница}} $7 {{GENDER:$4|кориснику|корисници|кориснику/ци}} $3 са временом истека од $5 $6",
+       "logentry-partialblock-block-page": "{{PLURAL:$1|странице|страница}} $2",
+       "logentry-partialblock-block": "$1 је {{GENDER:$2|блокирао|блокирала}} уређивање $7 {{GENDER:$4|кориснику|корисници|кориснику/ци}} $3 са временом истека од $5 $6",
        "logentry-non-editing-block-block": "$1 је {{GENDER:$2|блокирао|блокирала}} одређене неуређивачке радње {{GENDER:$4|кориснику|корисници|кориснику/ци}} $3 са временом истека од $5 $6",
        "logentry-non-editing-block-reblock": "$1 је {{GENDER:$2|променио|променила}} подешавања блокаде одређених неуређивачких радњи {{GENDER:$4|кориснику|корисници|кориснику/ци}} $3 са временом истека од $5 $6",
        "logentry-suppress-block": "$1 је {{GENDER:$2|блокирао|блокирала}} {{GENDER:$4|$3}} у трајању од $5 $6",
        "logentry-newusers-newusers": "$1 је {{GENDER:$2|отворио|отворила}} кориснички налог",
        "logentry-newusers-create": "$1 је {{GENDER:$2|отворио|отворила}} кориснички налог",
        "logentry-newusers-create2": "$1 је {{GENDER:$2|отворио|отворила}} кориснички налог $3",
-       "logentry-newusers-byemail": "$1 Ñ\98е {{GENDER:$2|оÑ\82воÑ\80ио|оÑ\82воÑ\80ила}} ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки Ð½Ð°Ð»Ð¾Ð³ $3 Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82а Ð½Ð° Ð¸Ð¼ÐµÑ\98л",
+       "logentry-newusers-byemail": "$1 Ñ\98е {{GENDER:$2|оÑ\82воÑ\80ио|оÑ\82воÑ\80ила}} ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки Ð½Ð°Ð»Ð¾Ð³ $3 Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82а Ð½Ð° Ðµ-поÑ\88Ñ\82Ñ\83",
        "logentry-newusers-autocreate": "$1 је аутоматски {{GENDER:$2|отворио|отворила}} кориснички налог",
        "logentry-protect-move_prot": "$1 је {{GENDER:$2|преместио|преместила}} подешавања заштите са $4 на $3",
        "logentry-protect-unprotect": "$1 je {{GENDER:$2|скинуо|скинула}} заштиту са странице $3",
        "logentry-rights-autopromote": "$1 је аутоматски {{GENDER:$2|унапређен|унапређена}} из $4 у $5",
        "logentry-upload-upload": "$1 је {{GENDER:$2|отпремио|отпремила}} $3",
        "logentry-upload-overwrite": "$1 је {{GENDER:$2|отпремио|отпремила}} нову верзију датотеке $3",
-       "logentry-upload-revert": "$1 Ñ\98е {{GENDER:$2|оÑ\82пÑ\80емио|оÑ\82пÑ\80емила}} $3",
+       "logentry-upload-revert": "$1 Ñ\98е {{GENDER:$2|вÑ\80аÑ\82ио|вÑ\80аÑ\82ила}} Ð´Ð°Ñ\82оÑ\82екÑ\83 $3 Ð½Ð° Ñ\81Ñ\82аÑ\80иÑ\98Ñ\83 Ð²ÐµÑ\80зиÑ\98Ñ\83",
        "log-name-managetags": "Дневник управљања ознакама",
-       "log-description-managetags": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\81е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81пиÑ\81ак Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\83 Ð²ÐµÐ·Ð¸ [[Special:Tags|ознака]]. Ð\94невник Ñ\81адÑ\80жи Ñ\81амо Ñ\80адÑ\9aе ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ñ\80Ñ\83Ñ\87но Ð¸Ð·Ð²Ñ\80Ñ\88или Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80и; Ñ\83ноÑ\81и Ð·Ð° Ð¾Ð·Ð½Ð°ÐºÐµ ÐºÐ¾Ñ\98е Ñ\98е Ð½Ð°Ð¿Ñ\80авио Ð¸Ð»Ð¸ Ð¸Ð·Ð±Ñ\80иÑ\81ао Ð²Ð¸ÐºÐ¸ Ñ\81оÑ\84Ñ\82веÑ\80, Ð° Ð½Ðµ Ð½Ð°Ð»Ð°Ð·Ðµ Ñ\81е Ñ\83 Ð¾Ð²Ð¾Ð¼ Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83.",
+       "log-description-managetags": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ð½Ð°Ð²Ð¾Ð´Ð¸ Ð·Ð°Ð´Ð°Ñ\82ке Ñ\83пÑ\80авÑ\99аÑ\9aа Ñ\83 Ð²ÐµÐ·Ð¸ Ñ\81а [[Special:Tags|ознакама]]. Ð\95виденÑ\86иÑ\98а Ñ\81адÑ\80жи Ñ\81амо Ñ\80адÑ\9aе ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ñ\80Ñ\83Ñ\87но Ð¸Ð·Ð²Ñ\80Ñ\88или Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80и; Ñ\83ноÑ\81и Ð·Ð° Ð¾Ð·Ð½Ð°ÐºÐµ ÐºÐ¾Ñ\98е Ñ\98е Ð½Ð°Ð¿Ñ\80авио Ð¸Ð»Ð¸ Ð¸Ð·Ð±Ñ\80иÑ\81ао Ð²Ð¸ÐºÐ¸ Ñ\81оÑ\84Ñ\82веÑ\80, Ð° Ð½Ðµ Ð½Ð°Ð»Ð°Ð·Ðµ Ñ\81е Ñ\83 Ð¾Ð²Ð¾Ñ\98 ÐµÐ²Ð¸Ð´ÐµÐ½Ñ\86иÑ\98и.",
        "logentry-managetags-create": "$1 је {{GENDER:$2|направио|направила}} ознаку „$4“",
        "logentry-managetags-delete": "$1 је {{GENDER:$2|избрисао|избрисала}} ознаку „$4” (уклоњена је из $5 {{PLURAL:$5|измене или уноса у дневнику|измена и/или уноса у дневнику}})",
        "logentry-managetags-activate": "$1 је {{GENDER:$2|активирао|активирала}} ознаку „$4“ за употребу од стране корисника и ботова",
        "limitreport-walltime-value": "$1 {{PLURAL:$1|секунд|секунда|секунди}}",
        "limitreport-ppvisitednodes": "Број предпроцесираних посећених нодова",
        "limitreport-ppvisitednodes-value": "$1/$2",
-       "limitreport-ppgeneratednodes": "Број предпроцесираних генерисаних нодова",
+       "limitreport-ppgeneratednodes": "Број створених чворова од предобрађивача",
        "limitreport-ppgeneratednodes-value": "$1/$2",
        "limitreport-postexpandincludesize": "Укључена величина након проширења",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|бајт|бајта|бајтова}}",
        "mediastatistics-header-archive": "Компресовани формати",
        "mediastatistics-header-3d": "3D",
        "mediastatistics-header-total": "Све датотеке",
-       "json-warn-trailing-comma": "$1 {{PLURAL:$1|пратећа тачка је уклоњена|пратеће тачке су уклоњене|пратећих тачки је уклоњено}} из JSON-a",
-       "json-error-unknown": "Догодио се проблем с JSON-ом. Грешка: $1",
+       "json-warn-trailing-comma": "$1 {{PLURAL:$1|пратећа тачка је уклоњена|пратеће тачке су уклоњене|пратећих тачки је уклоњено}} из ЈСОН-a",
+       "json-error-unknown": "Дошло је до проблема са ЈСОН-ом. Грешка: $1",
        "json-error-depth": "Прекорачена је највећа дубина",
-       "json-error-state-mismatch": "Ð\9dеважеÑ\9bи Ð¸Ð»Ð¸ Ð¿Ð¾ÐºÐ²Ð°Ñ\80ени JSON",
+       "json-error-state-mismatch": "Ð\9dеважеÑ\9bи Ð¸Ð»Ð¸ Ð¿Ð¾Ð³Ñ\80еÑ\88но Ñ\83облиÑ\87ен Ð\88СÐ\9eÐ\9d",
        "json-error-ctrl-char": "Грешка контролног симбола, могуће је да је неисправно енкодиран",
        "json-error-syntax": "Грешка у синтакси",
        "json-error-utf8": "Малформирани UTF-8 знаци, могуће је да су неисправно енкодирани",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "сесије са колачићима",
        "sessionprovider-nocookies": "Колачићи су можда онемогућени. Уверите се да имате колачиће омогућене и почните поново.",
        "randomrootpage": "Случајна коренска страница",
-       "log-action-filter-block": "Тип Ð±Ð»Ð¾ÐºÐ°Ð´Ðµ:",
-       "log-action-filter-contentmodel": "Тип промене модела садржаја:",
-       "log-action-filter-delete": "Тип брисања:",
-       "log-action-filter-import": "Тип увоза:",
-       "log-action-filter-managetags": "Тип радње управљања ознакама:",
-       "log-action-filter-move": "Тип премештања:",
-       "log-action-filter-newusers": "Тип отварања налога:",
-       "log-action-filter-patrol": "Тип патролирања:",
-       "log-action-filter-protect": "Тип заштите:",
-       "log-action-filter-rights": "Тип промене корисничких права:",
+       "log-action-filter-block": "Ð\92Ñ\80Ñ\81Ñ\82а Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа:",
+       "log-action-filter-contentmodel": "Ð\92Ñ\80Ñ\81Ñ\82а промене модела садржаја:",
+       "log-action-filter-delete": "Ð\92Ñ\80Ñ\81Ñ\82а брисања:",
+       "log-action-filter-import": "Ð\92Ñ\80Ñ\81Ñ\82а увоза:",
+       "log-action-filter-managetags": "Ð\92Ñ\80Ñ\81Ñ\82а радње управљања ознакама:",
+       "log-action-filter-move": "Ð\92Ñ\80Ñ\81Ñ\82а премештања:",
+       "log-action-filter-newusers": "Ð\92Ñ\80Ñ\81Ñ\82а отварања налога:",
+       "log-action-filter-patrol": "Ð\92Ñ\80Ñ\81Ñ\82а патролирања:",
+       "log-action-filter-protect": "Ð\92Ñ\80Ñ\81Ñ\82а заштите:",
+       "log-action-filter-rights": "Ð\92Ñ\80Ñ\81Ñ\82а промене корисничких права:",
        "log-action-filter-suppress": "Тип скривања:",
        "log-action-filter-upload": "Тип отпремања:",
        "log-action-filter-all": "Све",
        "log-action-filter-suppress-reblock": "Скривање корисника поновним блокирањем",
        "log-action-filter-upload-upload": "ново отпремање",
        "log-action-filter-upload-overwrite": "промена постојећег",
+       "log-action-filter-upload-revert": "Враћа",
        "authmanager-authn-not-in-progress": "Потврда идентитета није у току или је дошло до губитка података о сесији. Почните испочетка.",
        "authmanager-authn-no-primary": "Није могуће потврдити пружене акредитиве.",
        "authmanager-authn-no-local-user": "Пружени акредитиви нису повезани ни са једним корисником на овом викију.",
        "authmanager-create-no-primary": "Не могу да искористим пружене акредитиве за отварање налога.",
        "authmanager-link-no-primary": "Не могу да искористим пружене акредитиве за спајање налога.",
        "authmanager-link-not-in-progress": "Спајање налога није у току или је дошло до губитка података о сесији. Почните испочетка.",
-       "authmanager-authplugin-setpass-failed-title": "Неуспешна промена лозинке",
-       "authmanager-authplugin-setpass-failed-message": "Додатак за потврду идентитета је одбио промену лозинке.",
-       "authmanager-authplugin-create-fail": "Додатак за потврду идентитета је одбио отварање налога.",
-       "authmanager-authplugin-setpass-denied": "Додатак за потврду идентитета не дозвољава мењање лозику.",
-       "authmanager-authplugin-setpass-bad-domain": "Неважећи домен.",
        "authmanager-autocreate-noperm": "Аутоматско отварање налога није дозвољено.",
        "authmanager-autocreate-exception": "Аутоматско креирање налога је привремено онемогућено због претходних грешака.",
        "authmanager-userdoesnotexist": "Кориснички налог „$1“ није отворен.",
        "authmanager-domain-help": "Домен за спољашњу потврду идентитета.",
        "authmanager-retype-help": "Поновите лозинку да би сте потврдили.",
        "authmanager-email-label": "Е-пошта",
-       "authmanager-email-help": "Ð\90дÑ\80еÑ\81а Ðµ-поÑ\88Ñ\82е:",
+       "authmanager-email-help": "Ð\95-адÑ\80еÑ\81а",
        "authmanager-realname-label": "Право име",
        "authmanager-realname-help": "Право име корисника",
        "authmanager-provider-password": "Потврда идентитета лозинком",
        "unlinkaccounts": "Раздвајање налога",
        "unlinkaccounts-success": "Налог је обједињен.",
        "authenticationdatachange-ignored": "Промена података аутенификације није обрађена. Можда ниједан провајдер није конфигурисан?",
-       "userjsispublic": "Напомена: JavaScript подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
-       "userjsonispublic": "Напомена: JSON подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
-       "usercssispublic": "Напомена: CSS подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
+       "userjsispublic": "Напомена: Јаваскрипт подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
+       "userjsonispublic": "Напомена: ЈСОН подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
+       "usercssispublic": "Напомена: Це-Ес-Ес подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
        "restrictionsfield-badip": "Неважећа IP адреса или опсег: $1",
        "restrictionsfield-label": "Дозвољени IP опсези:",
        "edit-error-short": "Грешка: $1",
        "pagedata-title": "Подаци странице",
        "pagedata-not-acceptable": "Није пронађен одговарајући облик. Подржане MIME-врсте: $1",
        "pagedata-bad-title": "Невалидан наслов: $1.",
-       "unregistered-user-config": "Из безбедоносних разлога JavaScript, CSS и JSON корисничке подстранице не могу бити учитане за нерегистроване кориснике.",
+       "unregistered-user-config": "Из безбедоносних разлога, јаваскрипт, Це-Ес-Ес и ЈСОН корисничке подстранице не могу бити учитане за нерегистроване кориснике.",
        "passwordpolicies": "Правила за лозинке",
-       "passwordpolicies-summary": "Ð\9eво Ñ\98е Ñ\81пиÑ\81ак ÐµÑ\84икаÑ\81них смерница за лозинке за корисничке групе дефинисане на овом викију.",
+       "passwordpolicies-summary": "Ð\9eво Ñ\98е Ñ\81пиÑ\81ак Ð´ÐµÐ»Ð¾Ñ\82воÑ\80них смерница за лозинке за корисничке групе дефинисане на овом викију.",
        "passwordpolicies-group": "Група",
        "passwordpolicies-policies": "Правила",
        "passwordpolicies-policy-display": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span>",
        "passwordpolicies-policy-minimalpasswordlength": "Лозинка мора да има најмање {{PLURAL:$1|један знак|$1 знака|$1 знакова}}",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "Лозинка мора садржати најмање $1 {{PLURAL:$1|карактер|карактера}} да би сте могли да се пријавите.",
-       "passwordpolicies-policy-passwordcannotmatchusername": "Лозинка не може да буде иста као корисничко име",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Лозинка не сме бити иста као корисничко име",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинка се не може подударати са лозинкама на црном списку",
        "passwordpolicies-policy-maximalpasswordlength": "Лозинка мора да буде краћа од $1 {{PLURAL:$1|знака|знакова}}",
-       "passwordpolicies-policy-passwordcannotbepopular": "Лозинка не може да буде {{PLURAL:$1|популарна лозинка|на списку $1 популарних лозинки}}",
-       "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинка не може да буде на листи 100.000 најчешће коришћених лозинки.",
-       "unprotected-js": "Из безбедносних разлога, JavaScript не може да се учита са незаштићене странице. Само направите JavaScript у именском простору „Медијавики:” или као корисничку подстраницу"
+       "passwordpolicies-policy-passwordcannotbepopular": "Лозинка не сме бити {{PLURAL:$1|позната лозинка|на списку $1 познатих лозинки}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинка не сме бити на списку 100.000 најчешће коришћених лозинки.",
+       "unprotected-js": "Из безбедносних разлога, јаваскрипт не може да се учита са незаштићене странице. Само направите јаваскрипт у именском простору „Медијавики:” или као корисничку подстраницу"
 }
index fc5afb5..889c449 100644 (file)
        "revertpage": "Vraćene izmene {{GENDER:$2|korisnika|korisnice}} [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]]) na poslednju izmenu {{GENDER:$1|korisnika|korisnice}} [[User:$1|$1]]",
        "revertpage-nouser": "Vraćene izmene skrivenog korisnika na poslednju izmenu {{GENDER:$1|korisnika|korisnice}} [[User:$1|$1]]",
        "rollback-success": "Vraćene izmene {{GENDER:$1|korisnika|korisnice}} {{GENDER:$3|$1}}  na poslednju izmenu {{GENDER:$2|korisnika|korisnice}} {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Vraćene izmene korisnika $1;\nvraćeno na poslednju izmenu korisnika $2. [$3 Prikaži promene]",
        "sessionfailure-title": "Sesija je okončana",
        "sessionfailure": "Izgleda da postoji problem s vašom sesijom;\nova radnja je otkazana da bi se izbegla zloupotreba.\nMolimo, ponovo pošaljite obrazac.",
        "changecontentmodel": "Promena modela sadržaja stranice",
        "authmanager-create-no-primary": "Ne mogu da iskoristim pružene akreditive za otvaranje naloga.",
        "authmanager-link-no-primary": "Ne mogu da iskoristim pružene akreditive za spajanje naloga.",
        "authmanager-link-not-in-progress": "Spajanje naloga nije u toku ili je došlo do gubitka podataka o sesiji. Počnite ispočetka.",
-       "authmanager-authplugin-setpass-failed-title": "Neuspešna promena lozinke",
-       "authmanager-authplugin-setpass-failed-message": "Dodatak za potvrdu identiteta je odbio promenu lozinke.",
-       "authmanager-authplugin-create-fail": "Dodatak za potvrdu identiteta je odbio otvaranje naloga.",
-       "authmanager-authplugin-setpass-denied": "Dodatak za potvrdu identiteta ne dozvoljava menjanje loziku.",
-       "authmanager-authplugin-setpass-bad-domain": "Nevažeći domen.",
        "authmanager-autocreate-noperm": "Automatsko otvaranje naloga nije dozvoljeno.",
        "authmanager-autocreate-exception": "Automatsko kreiranje naloga je privremeno onemogućeno zbog prethodnih grešaka.",
        "authmanager-userdoesnotexist": "Korisnički nalog „$1“ nije otvoren.",
index 5d51493..a81ab20 100644 (file)
        "log-action-filter-upload-overwrite": "Unjal deui",
        "authmanager-create-disabled": "Panyieunan akun ditumpurkeun",
        "authmanager-create-from-login": "Pikeun nyieun akun, mangga eusi ieu kolom di handap.",
-       "authmanager-authplugin-setpass-failed-title": "Parobahan kecap sandi gagal",
-       "authmanager-authplugin-setpass-bad-domain": "Domain teu sah.",
        "authmanager-autocreate-noperm": "Panyieunan akun otomatis teu diidinan.",
        "authmanager-userdoesnotexist": "Akun pamaké \"$1\" teu kadaptar.",
        "authmanager-username-help": "Sandiasma pikeun oténtikasi.",
index 8e808d4..cb2de8b 100644 (file)
        "tog-norollbackdiff": "Visa inte diff efter tillbakarullning",
        "tog-useeditwarning": "Varna mig om jag lämnar en redigeringssida med osparade ändringar",
        "tog-prefershttps": "Använd alltid en säker anslutning medan jag är inloggad",
+       "tog-showrollbackconfirmation": "Visa en bekräftelsedialog när man klickar på en tillbakarullningslänk",
        "underline-always": "Alltid",
        "underline-never": "Aldrig",
        "underline-default": "Webbläsarens eller utseendets standardinställning",
        "badretype": "De lösenord du uppgett överensstämmer inte med varandra.",
        "usernameinprogress": "Kontoskapandet för detta användarnamn är redan i full gång.\nVänligen vänta.",
        "userexists": "Det valda användarnamnet används redan.\nVar god välj ett annat namn.",
+       "createacct-normalization": "Ditt användarnamn kommer att justeras till \"$2\" p.g.a. tekniska begränsningar.",
        "loginerror": "Inloggningsproblem",
        "createacct-error": "Fel när konto skulle skapas",
        "createaccounterror": "Kunde inte skapa konto: $1",
        "histfirst": "äldsta",
        "histlast": "nyaste",
        "historysize": "({{PLURAL:$1|1 byte|$1 byte}})",
-       "historyempty": "(tom)",
+       "historyempty": "tom",
        "history-feed-title": "Versionshistorik",
        "history-feed-description": "Versionshistorik för denna sida på wikin",
        "history-feed-item-nocomment": "$1 den $2",
        "right-reupload-own": "Skriv över egna filer",
        "right-reupload-shared": "Skriv över delade filer lokalt",
        "right-upload_by_url": "Ladda upp en fil genom en webbadress",
-       "right-purge": "Rensa cachen för en sida utan att bekräfta",
+       "right-purge": "Rensa webbplatscachen för en sida",
        "right-autoconfirmed": "Påverkas inte av IP-baserade hastighetsgränser",
        "right-bot": "Behandlas som en automatisk process",
        "right-nominornewtalk": "Mindre ändringar på diskussionssidor ger inte besked om nya meddelanden",
        "deleting-backlinks-warning": "<strong>Varning:</strong>\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|Andra sidor]] länkar till eller inkluderar sidan som du är på väg att radera.",
        "deleting-subpages-warning": "<strong>Varning:</strong> Sidan du håller på att radera har [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|en undersida|$1 undersidor|51=över 50 undersidor}}]].",
        "rollback": "Rulla tillbaka ändringar",
+       "rollback-confirmation-confirm": "Var god bekräfta:",
+       "rollback-confirmation-yes": "Rulla tillbaka",
+       "rollback-confirmation-no": "Avbryt",
        "rollbacklink": "rulla tillbaka",
        "rollbacklinkcount": "rulla tillbaka $1 {{PLURAL:$1|redigering|redigeringar}}",
        "rollbacklinkcount-morethan": "rulla tillbaka mer än $1 {{PLURAL:$1|redigering|redigeringar}}",
        "revertpage": "Återställde redigeringar av  [[Special:Contributions/$2|$2]] ([[User talk:$2|användardiskussion]]) till senaste versionen av [[User:$1|$1]]",
        "revertpage-nouser": "Återställde redigeringar av en dold användare till den senaste versionen av {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Återställde ändringar av {{GENDER:$3|$1}};\nändrade tillbaka till senaste versionen av {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Återställde ändringar av $1;\nändrade tillbaka till senaste sidversion av $2. [$3 Visa ändringar]",
        "sessionfailure-title": "Sessionsfel",
        "sessionfailure": "Någonting med din inloggningssession är på tok;\ndin begärda åtgärd har avbrutits för att förhindra att någon kapar din session.\nSkicka formuläret igen.",
        "changecontentmodel": "Ändra innehållsmodell för en sida",
        "mycontris": "Bidrag",
        "anoncontribs": "Bidrag",
        "contribsub2": "För {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "För {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Användarkontot \"$1\" är inte registrerat.",
        "negative-namespace-not-supported": "Namnrymder med negativa värden stöds inte.",
        "nocontribs": "Inga ändringar som motsvarar dessa kriterier hittades.",
        "ipb-confirm": "Bekräfta blockering",
        "ipb-sitewide": "Hela webbplatsen",
        "ipb-partial": "Partiell",
+       "ipb-sitewide-help": "Alla sidor på wikin och alla andra bidragsåtgärder.",
+       "ipb-partial-help": "Specifika sidor eller namnrymder.",
        "ipb-pages-label": "Sidor",
        "ipb-namespaces-label": "Namnrymder",
        "badipaddress": "Du har inte skrivit IP-adressen korrekt.",
        "confirm-unwatch-top": "Ta bort denna sida från din bevakningslista?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Återställ redigeringar på denna sida?",
+       "confirm-rollback-bottom": "Denna åtgärd kommer rulla tillbaka de markerade ändringarna på denna sida direkt.",
        "confirm-mcrrestore-title": "Återställ en sidversion",
        "confirm-mcrundo-title": "Ångra en ändring",
        "mcrundofailed": "Misslyckades att ångra",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|befordrades}} automatiskt från $4 till $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|laddade upp}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|laddade upp}} en ny version av $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|laddade upp}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|återställde}} $3 till en gammal version",
        "log-name-managetags": "Märkeshanteringslogg",
        "log-description-managetags": "Denna sida innehåller administrativa [[Special:Tags|märke]]srelaterade uppgifter. Loggen innehåller bara åtgärder som utförts manuellt av en administratör; märken kan skapas eller raderas av wikins mjukvara utan att en post registreras i loggen.",
        "logentry-managetags-create": "$1 {{GENDER:$2|skapade}} märket \"$4\"",
        "log-action-filter-suppress-reblock": "Användarcensur efter återblockering",
        "log-action-filter-upload-upload": "Ny uppladdning",
        "log-action-filter-upload-overwrite": "Återuppladdning",
+       "log-action-filter-upload-revert": "Återställ",
        "authmanager-authn-not-in-progress": "Autentiseringen pågår inte eller så har sessionsdata förlorats. Var god börja om från början igen.",
        "authmanager-authn-no-primary": "De angivna inloggningsuppgifterna kunde inte autentiseras.",
        "authmanager-authn-no-local-user": "De angivna inloggningsuppgifterna är inte associerade med någon användare på denna wiki.",
        "authmanager-create-no-primary": "De angivna inloggningsuppgifterna kunde inte användas för att skapa ett konto.",
        "authmanager-link-no-primary": "De angivna inloggningsuppgifterna kunde inte användas för att länka ett konto.",
        "authmanager-link-not-in-progress": "Kontolänkning pågår inte eller så har sessionsdata förlorats. Var god börja om från början igen.",
-       "authmanager-authplugin-setpass-failed-title": "Kunde inte ändra lösenordet",
-       "authmanager-authplugin-setpass-failed-message": "Insticksmodulen för autentisering nekade lösenordsändringen.",
-       "authmanager-authplugin-create-fail": "Insticksmodulen för autentisering nekade skapande av konto.",
-       "authmanager-authplugin-setpass-denied": "Insticksmodulen för autentisering tillåter inte ändring av lösenord.",
-       "authmanager-authplugin-setpass-bad-domain": "Ogiltig domän.",
        "authmanager-autocreate-noperm": "Det är inte tillåtet att skapa konton automatiskt.",
        "authmanager-autocreate-exception": "P.g.a. tidigare fel har automatiskt skapande av konton inaktiverats.",
        "authmanager-userdoesnotexist": "Användarkontot \"$1\" är inte registrerat.",
        "passwordpolicies-policy-maximalpasswordlength": "Lösenordet måste vara högst $1 {{PLURAL:$1|tecken}} långt",
        "passwordpolicies-policy-passwordcannotbepopular": "Lösenordet kan inte vara {{PLURAL:$1|det populäraste lösenordet|i listan över de $1 populäraste lösenorden}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Lösenordet kan inte vara med i listan över de 100 000 vanligaste lösenorden.",
+       "passwordpolicies-policyflag-forcechange": "måste ändras vid inloggning",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "föreslå ändring vid inloggning",
        "easydeflate-invaliddeflate": "Innehåll som tillhandahålls är inte helt komprimerat",
        "unprotected-js": "Av säkerhetsskäl kan inte JavaScript läsas in från oskyddade sidor. Skapa endast JavaScript i namnrymden MediaWiki: eller som en användarundersida."
 }
index 51935ea..70b956d 100644 (file)
        "log-action-filter-suppress-delete": "Laxiy pkt’aniy quw zngazyan",
        "log-action-filter-upload-upload": "Misan sni’",
        "log-action-filter-upload-overwrite": "T’aring lawziy pawsa’ sa kktan",
-       "authmanager-authplugin-setpass-failed-title": "Wal yaqih quw sinbah sa mima’",
-       "authmanager-authplugin-setpass-bad-domain": "Ungat zyuwaw na wangyu’.",
        "authmanager-email-label": "e-meyo’",
        "authmanager-email-help": "Zyusyo na e-meyo’",
        "authmanager-realname-label": "Spzyang balay lalu’",
index 9675e6e..82a5cdd 100644 (file)
        "badretype": "ಈರ್ ಕೊರ್ನ ಪ್ರವೇಶ ಪದೆ ಬೇತೆ ಬೇತೆ ಅತ್ಂಡ್",
        "usernameinprogress": "ಈ ಬಳಕೆದಾರೆ ಪುದರುದ ಖಾತೆ ರಚನೆ ಪ್ರಗತಿಡು ಉಂಡು. ದಯಮಲ್ತ್ ವಂತೆ ಕಾಪುಲೆ.",
        "userexists": "ಈರ್ ಕೊರ್ನ ಸದಸ್ಯರ ಪುದರ್ ಬಳಕೆಡ್ ಉಂಡು. ದಯದೀದ್ ಬೇತೆ ಪುದರ್ ಕೊರ್ಲೆ",
+       "createacct-normalization": "ತಾಂತ್ರಿಕ ನಿರ್ಬಂದೊಲೆಗಾದ್, ಇರೆನ ಬಳಕೆಪುದರುನು $2 ಕ್ ಸರಿಮಲ್ಪುಂಡು",
        "loginerror": "ಲಾಗಿನ್ ದೋಷ",
        "createacct-error": "ಕಾತೆ ನಿರ್ಮಾಣೊ ದೋಸೊ",
        "createaccounterror": "ಕಾತೆ ನಿರ್ಮಾಣೊ ಮಲ್ಪೆರೆ ಆವೊಂದಿದ್ದಿ: $1",
        "diff-multi-manyusers": "({{PLURAL:$1|ಒಂಜಿ ನಡುತ ಪಡಿಪಾಟ|$1 ನಡುತ ಪಡಿಪಾಟೊಲು}}  $2 ಡುದು ಎಚ್ಚದ {{PLURAL:$2|ಬಳಕೆದಾರೆ|ಬಳಕೆದಾರೆರ್}} ತೋಜಾದಿಜಿ)",
        "diff-paragraph-moved-tonew": "ವಾಕ್ಯಪಂಕ್ತಿ ಚಲನೆ ಆತ್ಂಡ್. ಪೊಸ ಜಾಗೊಗು ನೆಗೆಪರೆ ಒತ್ತುಲೆ.",
        "diff-paragraph-moved-toold": "ವಾಕ್ಯಪಂಕ್ತಿ ಚಲನೆ ಆತ್ಂಡ್. ದುಂಬುಇತ್ತಿನ ಜಾಗೊಗು ನೆಗೆಪರೆ ಒತ್ತುಲೆ.",
+       "difference-missing-revision": "{{PLURAL:$2|ಒಂಜಿ ಪಡಿಪಾಟ|$2 ಪಡಿಪಾಟೊಲು}} ಈ ವ್ಯತ್ಯಾಸ ($1) {{PLURAL:$2|ವು|ಲು}} ತಿಕ್ಕುಜಿ.\nಉಂದು ಸಾಮಾನ್ಯವಾದ್ ಒಂಜಿ ಮಾಜಾಯಿನ ಪುಟೊತ ಒಂಜಿ ಕಾಲಕರಿನ ವ್ಯತ್ಯ ಕೊಂಡಿದ ಕಾರಣೊಡು ಆಪಿನವು.\nವಿವರೊಲು [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ಮಾಜಾಯಿನ ಗಮನಿ].ಡು ತಿಕ್ಕುಂಡು.",
        "searchresults": "ನಾಡ್‍ಪತ್ತ್‌ನೆತ ಪಲಿತಾಂಸೊಲು",
+       "search-filter-title-prefix": "ತರೆಬರವು $1 ರ್ದ್ ಸುರುವಾಪಿನ ಪುಟೊಲೆನ್  ಮಾತ್ರಾ ನಾಡುಂಡು",
+       "search-filter-title-prefix-reset": "ಮಾತಾ ಪುಟೊಲೆನ್ ನಾಡ್'ಲೆ.",
        "searchresults-title": "\"$1\"ಕ್ ನಾಡ್‍ಪತ್ತ್‌ನೆತ ಪಲಿತಾಂಸೊಲು",
+       "titlematches": "ಪುಟ ತೆರಬರವು ಸದೃಶ ಆದುಂಡು.",
+       "textmatches": "ಪುಟತ ಪಟ್ಯ ಸದೃಶ ಆದುಂಡು.",
        "notextmatches": "ವಾ ಪುಟೊತ ಪಠ್ಯೊಡುಲಾ ಹೋಲಿಕೆ ಇಜ್ಜಿ",
        "prevn": "ದುಂಬುದ {{PLURAL:$1|$1}}",
        "nextn": "ಬೊಕ್ಕದ {{PLURAL:$1|$1}}",
        "search-category": "(ವರ್ಗ $1)",
        "search-file-match": "ಫೈಲ್‍ಡಿತ್ತಿ ವಿಸಯೊಗು ಸರಿ ಒಂಬುಂಡು",
        "search-suggest": "ಇಂದೆನ್ ನಾಡೊಂದುಲ್ಲರೆ: $1",
+       "search-rewritten": "ತೋಜಾವುನು $1 ತ ಫಲಿತಾಂಶೊಲು. ಬದಲಾದ್ $2 ಕ್ ನಾಡುಲೆ.",
        "search-interwiki-caption": "ಸೋದರಿ ಯೋಜನೆಲೆನ ಫಲಿತಾಂಶೊಲು",
        "search-interwiki-default": "$1 ಫಲಿತಾಂಶೊಲು:",
        "search-interwiki-more": "(ಮಸ್ತ್)",
        "search-relatedarticle": "ಸ೦ಬ೦ದ ಇತ್ತಿನ",
        "searchrelated": "ಸ೦ಬ೦ಧ ಇತ್ತಿನ",
        "searchall": "ಮಾತ",
+       "showingresults": "#<strong>$2</strong>ರ್ದ್ ಸುರುವಾಪಿನ,  {{PLURAL:$1|<strong>1</strong> ಫಲಿತಾಂಶ|<strong>$1</strong>ಫಲಿತಾಂಶೊಲು}} ಮುಟ್ಟದವೆನ್ ಈ  ತಿರ್ತ್ ತೋಜಾವುಂಡು .",
+       "showingresultsinrange": "#<strong>$2</strong>ರ್ದ್  #<strong>$3</strong>.ವ್ಯಾಪ್ತಿದ,  {{PLURAL:$1|<strong>1</strong> ಫಲಿತಾಂಶ|<strong>$1</strong>ಫಲಿತಾಂಶೊಲು}} ಮುಟ್ಟದವೆನ್ ಈ  ತಿರ್ತ್ ತೋಜಾವುಂಡು .",
        "search-showingresults": "{{PLURAL:$4|<strong>$3</strong>ಟ್ <strong>$1</strong> ಫಲಿತಾಂಸೊ|<strong>$3</strong>ಟ್ <strong>$1 - $2</strong> ಫಲಿತಾಂಸೊಲು}}",
        "search-nonefound": "ಈರೆನ ವಿಚಾರಣೆಗ್ ತಕ್ಕಂದಿನ ಪಲಿತಾಂಸೊಲು ಇಜ್ಜಿ.",
        "search-nonefound-thiswiki": "ಈ ಸೈಟ್‍ಡ್ ಪ್ರಸ್ನೆನೆದ ಪಲಿತಾಂಸೊ ಕೂಡೊಂದಿಜ್ಜಿ",
        "powersearch-togglelabel": "ಪರೀಕ್ಷಿಸಲೆ:",
        "powersearch-toggleall": "ಮಾತಾ",
        "powersearch-togglenone": "ಇದ್ದಿ",
+       "powersearch-remember": "ಮುಂಗಾಲದ (ಭವಿಷದ) ನಾಡುನವೆಕ್  ಪೆಜಿದಿನೆನ್ ನೆನಪುದೀಲೆ",
        "search-external": "ಬಾಹ್ಯೊ ಹುಡುಕಾಟೊ",
+       "searchdisabled": "{{SITENAME}} ನಾಡುನವು ನಿಷ್ಕ್ರಿಯ ಆತ್ಂಡ್.  ಈನಡುವೆ ಈರ್ ಗೂಗಲ್ಡ್ ನಾಡೊಲಿ.\nಗಮನಕೊರುಲೆ: ಅಕಲೆನ {{SITENAME}} ವಿಷಯದ ಅನುಕ್ರಮಸೂಚಿಲು ಕಾಲಕರಿನವು ಆದಿಪ್ಪು.",
+       "search-error": "$1: ನಾಡುನಗ ಒಂಜಿ ದೋಷ ಆಂಡ್",
+       "search-warning": "$1: ನಾಡುನಗ ಒಂಜಿ ಎಚ್ಚರಿಗೆ ಉಂಡಾಂಡ್.",
        "preferences": "ಪ್ರಾಶಸ್ತ್ಯೊಲು",
        "mypreferences": "ಪ್ರಾಸಸ್ತ್ಯೊಲು",
        "prefs-edits": "ಸಂಪಾದನೆಲೆನ ಸಂಕೆ:",
+       "prefsnologintext2": "ಇರೆನ ಇಷ್ಟಾಯ್ಕೆಲೆನ್  ಬದಲಾರೆ ದಯಮಲ್ತ್ ಉಳಗಮನ ಮಲ್ಪುಲೆ.",
        "prefs-skin": "ಸ್ಕಿನ್",
        "skin-preview": "ಮುನ್ನೋಟೊ",
        "datedefault": "ಒವ್ವೇ ಪ್ರಾಸಸ್ತ್ಯೊ ಇದ್ದಿ",
+       "prefs-labs": "ಪ್ರಯೋಗಸಾಲೆ ಗುಣವಿಶೇಷೊಲು",
        "prefs-user-pages": "ಸದಸ್ಯೆರೆನ ಪುಟೊ",
        "prefs-personal": "ಸದಸ್ಯೆರ್ನ ಬಗ್ಗೆ",
        "prefs-rc": "ಇಂಚಿಪದ ಬದಲಾವಣೆಲು",
        "prefs-watchlist": "ವೀಕ್ಷಣಾಪಟ್ಟಿ",
+       "prefs-editwatchlist": "ತೂಪಿಪಟ್ಟಿ ಸಂಪಾದಿಲೆ",
+       "prefs-editwatchlist-label": "ಇರೆನ ತೂಪಿಪಟ್ಟಿ ಸೇರಿಕೆಲೆನ್ ಸಂಪಾದಿಲೆ:",
+       "prefs-editwatchlist-edit": "ಇರೆನ ತೂಪಿಪಟ್ಟಿಡ್ ತರೆಬರವುಲೆನ್ ತೂಲೆ ಬೊಕ ದೆಪ್ಪುಲೆ.",
+       "prefs-editwatchlist-raw": "ಪಜ್ಜಿ ತೂಪಿಪಟ್ಟಿ ಸಂಪಾದಿಲೆ.",
+       "prefs-editwatchlist-clear": "ಇರೆನ ತೂಪಿಪಟ್ಟಿನ್ ಖಾಲಿ ಮಲ್ಪುಲೆ.",
+       "prefs-watchlist-days": "ತೂಪಿಪಟ್ಟಿಡ್ ತೋಜಾವುನ ದಿನೊಲು",
+       "prefs-watchlist-days-max": "ಗರಿಷ್ಟ $1 {{PLURAL:$1|ದಿನ|ದಿನೊಲು}}",
+       "prefs-watchlist-edits": "Maximum number of changes to show in watchlist:\nತೂಪಿಪಟ್ಟಿಡ್ ತೋಜಾವುನ ಗರಿಷ್ಟ ಬದಲಾವಣೆ ಸಂಕೆಲು",
+       "prefs-watchlist-edits-max": "ಗರಿಷ್ಟ ಸಂಕೆ:1000",
+       "prefs-watchlist-token": "ತೂಪಿಪಟ್ಟಿ ಬಿಲ್ಲೆ:",
+       "prefs-watchlist-managetokens": "ಬಿಲ್ಲೆಲೆನ್ ತೂವೊನುಲೆ.",
+       "prefs-misc": "ಇತರೆ",
        "prefs-resetpass": "ಪ್ರವೇಶಪದೊನ್ ಬದಲಾವಣೆ ಮಲ್ಪುಲೆ",
        "prefs-changeemail": "ಇ-ಅಂಚೆ ವಿಳಾಸೊನು ಬದಲಾವಣೆ ಮಲ್ಪುಲೆ ಅತ್ತಂಡ ದೆಪ್ಪುಲೆ",
        "prefs-setemail": "ಇ-ಅಂಚೆ ವಿಳಾಸೊನು ಸ್ತಾಪನೆ ಮಲ್ಪು",
        "prefs-email": "ಇ-ಮೈಲ್ ಆಯ್ಕೆಲು",
        "prefs-rendering": "ಗೋಚರೊ",
        "saveprefs": "ಒರಿಪಾಲೆ",
+       "restoreprefs": "ಮಾತಾ ಸಮಸ್ಥಿತಿ ಅಟ್ಟಣೆಲೆನ್ ಪಿರತಾಪನೆ ಮಲ್ಪುಲೆ (ಮಾತಾ ವಿಭಾಗೊಲೆಡ್)",
        "prefs-editing": "ಸಂಪೊಲಿಪು",
        "searchresultshead": " \nನಾಡ್’ಲೆ",
+       "stub-threshold": "ಮೋಟು ಕೊಂಡಿ ರೂಪನೊಗು ತಡ್ಯ ($1):",
        "stub-threshold-sample-link": "ಸಾಂಪಲ್",
        "stub-threshold-disabled": "ಕ್ರಿಯೆ ಉಂತ್‍ದ್ಂಡ್",
        "recentchangesdays": "ಇಂಚಿಪೊದ ಬದಲಾವಣೆಡ್ ತೋಜ್ಪಾವೊಡಾಯಿನ ದಿನೊಕುಲು:",
+       "recentchangesdays-max": "ಗರಿಷ್ಟ $1 {{PLURAL:$1|ದಿನ|ದಿನೊಲು}}",
+       "recentchangescount": "ಇಂಚೊದ ಬದಲಾವಣೆಲು, ಪುಟ ಚರಿತ್ರೆಲು ಬೊಕ ಗಮನಿಲೆಡ್, ಸಮಸ್ಥಿತಿಟ್  ತೋಜಾವುನ ಸಂಪಾದಿ ಸಂಕೆಲು:",
+       "prefs-help-recentchangescount": "ಗರಿಷ್ಟ ಸಂಕೆ:1000",
+       "prefs-help-watchlist-token2": "ಇರೆನ ತೂಪಿಪಟ್ಟಿದ ಜಾಲ ಆಹಾರೊಗು ಉಂದೇ ಗುಪಿತ ಕೀಲಿ ಆದುಂಡು.\nಏರ್ಲಾ ಗೊತ್ತಿತ್ತಿನಾಯಗ್ ಇರೆನ ತೂಪಿಪಟ್ಟಿನ್ ಓದರೆ ಆಪುಂಡು,ಅಂಚಾದ್ ಅವೆನ್ ಪಟ್ಟೊರ್ಚಿ.\nಬೋಡಾಂಡಾ, [[Special:ResetTokens|you can reset it]].",
+       "prefs-help-tokenmanagement": "ಇರೆನ ತೂಪಿಪಟ್ಟಿದ ಜಾಲಾಹಾರೊಗು ಸಾದಿ ಉಪ್ಪುನ ಇರೆನ ಖಾತೆದ ಗುಪಿತ ಕೀಲಿನ್ ಈರ್ ತೂದ್ ಪಿರತಾಪನೆ ಮಲ್ಪೊಲಿ. ಏರ್ಲಾ ಗೊತ್ತಿತ್ತಿನಾಯಗ್ ಇರೆನ ತೂಪಿಪಟ್ಟಿನ್ ಓದರೆ ಆಪುಂಡು, ಅಂಚಾದ್ ಅವೆನ್ ಪಟ್ಟೊರ್ಚಿ.",
+       "savedprefs": "ಇರೆನ ಇಷ್ಟಾಯ್ಕೆಲೆನ್ ಒರಿಪಾದುಂಡು.",
+       "savedrights": "{{GENDER:$1|$1}} ಬಳಕೆದಾರೆ ಗುಂಪುಲೆನ್ ಒರಿಪಾದುಂಡು.",
        "timezonelegend": "ಸಮಯೊದ ವಲಯೊ:",
        "localtime": "ಸ್ಥಳೀಯ ಸಮಯ:",
+       "timezoneuseserverdefault": "ವಿಕಿ ಸಮಸ್ಥಿತಿ ($1)ನ್ ಬಳಕೆ ಮಲ್ಪುಲೆ.",
+       "timezoneuseoffset": "ಇತರೆ (ಪರತಾಪನೆ ತಿರ್ತ್ ಸೂಚಿಸಾಲೆ)",
+       "timezone-useoffset-placeholder": "ಉದರ್ಮೆಗ್ ಮೌಲ್ಯೊಲು: \"-07:00\" ಇಜಿಂಡ \"01:00\"",
        "servertime": "ಸರ್ವರ್‌ದ ಕಾಲೊ:",
        "guesstimezone": "ಬ್ರೌಸರ್‌ಡ್ದ ದಿಂಜವು",
        "timezoneregion-africa": "ಆಫ್ರಿಕ",
        "timezoneregion-indian": "ಹಿಂದೂ ಮಹಾಸಾಗರೊ",
        "timezoneregion-pacific": "ಪೆಸಿಫಿಕ್ ಮಹಾಸಾಗರೊ",
        "allowemail": "ಎಂಕ್ ಇ-ಅಂಚೆ ಮಲ್ಪರೆ ಬೇತೆ ಸದಸ್ಯೆರೆಗ್ ಅನುಮತಿ ಕೊರುಲೆ.",
+       "email-allow-new-users-label": "ಪಚ್ಚ-ಪೊಸ ಬಳಕೆದಾರೆರೆನ ಇಮೇಲುಲೆಗ್ ಎಡೆಕೊರುಲೆ",
+       "email-blacklist-label": "ಈ ಬಳಕೆದಾರೆರ್ ಎಂಕ್ ಇಮೇಲ್ ಕಡಪುಡುನೆನ್ ತಡೆಪುಲೆ:",
        "prefs-searchoptions": "ನಾಡ್‍ಲ",
        "prefs-namespaces": "ಪುದರ್‍ದ ವರ್ಗೊಲು",
        "default": "ಮೂಲೊಸ್ಥಿತಿ",
        "prefs-files": "ಕಡತೊಲು",
        "prefs-custom-css": "ಕಸ್ಟಮ್ ಸಿಎಸ್ಎಸ್",
+       "prefs-custom-json": "ನಿಷ್ಟ ಜೆಎಸ್ಒಎನ್ JSON",
        "prefs-custom-js": "ಕಸ್ಟಮ್ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್",
+       "prefs-common-config": "ಮಾತಾ ಚೋಲಿಲೆಗ್ ಪಟ್ಟಿನ  ಸಿಎಸ್ಎಸ್ CSS/ ಜೆಎಸ್ಒಎನ್ JSON/ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ JavaScript :",
+       "prefs-reset-intro": "ತಾನ ಸಮಸ್ಥಿತಿಲೆಗ್ ಇರೆನ ಇಷ್ಟಾಯ್ಕೆಲೆನ್ ಪಿರತಾಪನೆಗ್ ಈ ಪುಟೊನು ಈರ್ ಬಳಕೆ ಮಲ್ಪೊಲಿ. ಉಂದೆನ್ ಪಿರಮಲ್ಪರೆ ಆಪುಜಿ.",
        "prefs-emailconfirm-label": "ಈ-ಮೈಲ್‍ದ ಒಪ್ಪಿಗೆ:",
        "youremail": "ಇ-ಮೈಲ್",
        "username": "{{GENDER:$1|ಸದಸ್ಯತ್ವೊದ ಪುದರ್}}:",
        "prefs-memberingroups": "{{GENDER:$2|ಸದಸ್ಯೆರ್}} ಆದುಪ್ಪುನ {{PLURAL:$1|ಗುಂಪು|ಗುಂಪುಲು}}:",
+       "group-membership-link-with-expiry": "$1 ( $2 ಮುಟ್ಟ)",
        "prefs-registration": "ನೋಂದಣಿದ ಸಮಯ:",
        "yourrealname": "ನಿಜವಾಯಿನ ಪುದರ್",
        "yourlanguage": "ಬಾಸೆ:",
        "prefs-i18n": "ಅಂತರರಾಷ್ಟ್ರೀಕರಣ",
        "prefs-signature": "ದಸ್ಕತ್ತ್",
        "prefs-dateformat": "ತಾರೋಕ್‍ದ ಸೈಲಿ",
+       "prefs-timeoffset": "ಕಾಲ ಪರತಾಪನೆ",
        "prefs-advancedediting": "ಸಾಮಾನ್ಯೊ ಆಯ್ಕೆಲು",
+       "prefs-developertools": "ಬುಳೇರ ಉಪಕರಣೊಲು",
        "prefs-editor": "ಸಂಪಾದಕೆ",
        "prefs-preview": "ಮುನ್ನೋಟೊ",
        "prefs-advancedrc": "ಪರಿಣತ ಇಚ್ಛೆಲು",
        "prefs-changeswatchlist": "ತೋಜಾಯಿನ ಬದಲಾವಣೆಲು",
        "prefs-pageswatchlist": "ವೀಕ್ಷಿತ (ತೂಯಿನ) ಪುಟೊಲು",
        "prefs-tokenwatchlist": "ಟೊಕನ್",
+       "prefs-diffs": "ವ್ಯತ್ಯಲು",
+       "prefs-help-prefershttps": "ಈ ಇಷ್ಟಾಯ್ಕೆ ಇರೆನ ದುಂಬುದ ಉಳಗಮನೊಡು ಪರಿಣಾಮೊಗು ಬರ್ಪುಂಡು.",
+       "prefswarning-warning": "ಈರ್ ಇರೆನ ಇಷ್ಟಾಯ್ಕೆಲೆಗ್  ಬದಲಾವಣೆ ಮಲ್ದರ್, ಅವೆನ್ ನನಲಾ ಒರಿಪಾದಿಜರ್. ಈರ್ $1 ಒತ್ತಂದೆ ಈ ಪುಟೊನು ಬುಡುದು ಪೋಯರ್ಡ, ಇರೆನ ಇಷ್ಟಾಯ್ಕೆಲು ಕಾಲನವಿ ಆಪುಜಾ.",
+       "prefs-tabs-navigation-hint": "ಕೊಡಿ: ಕಿರ್ಪಟ ಪಟ್ಟಿದ ಕಿರ್ಪಟೊಲೆಡ್ ಪರಿಮಾರರೆ ಈರ್ ದತ್ತ ಬೊಕ ಬಲತ್ತ ಬಾಣ ಕೀಲಿಲೆನ್ ಬಳಕೆ ಮಲ್ಪೊಲಿ.",
        "userrights": "ಸದಸ್ಯೆರೆ ಹಕ್ಕುಲು",
        "userrights-lookup-user": "ಒರಿ ಬಳಕೆದಾರೆನ್ ಆಯ್ಕೆ ಮಲ್ಪುಲೆ",
        "userrights-user-editname": "ಒಂಜಿ ಸದಸ್ಯ ಪುದರ್ ಬರೆಲೆ",
+       "editusergroup": "ಬಳಕೆದಾರೆ ಗುಂಪುಲೆನ್ ದಿಂಜಾಲೆ",
+       "editinguser": "{{GENDER:$1|ಬಳಕೆದಾರೆ}}ಬಳಕೆದಾರೆ ಹಕ್ಕುಲೆನ್ <strong>[[User:$1|$1]]</strong> $2 ಬದಲಾವುನು",
+       "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* ಒಂಜಿ * ಇನ್ನಗ ಈರ್ ಗುಂಪುನು ಸೇರಾಯಿನ ಬೊಕ ಅವೆನ್  ದೆಪ್ಪರೆ ಆಪುಜಿ ಇಜಿಂಡ ಅಯಿತ ಉಲ್ಟಾ ಇಂದ್\n* ಒಂಜಿ # ಇನ್ನಗ ಈರ್ ಗುಂಪು ಸದಸ್ಯತ್ವದ ಮುಗಿಕಾಲೊನು ಪಿರ ಪಾಡೆರೆ ಮಾತ್ರಾ ಆಪುಂಡು;  ಅವೆನ್  ದುಂಬು ಕಣರೆ ಆಪುಜಿ ಇಂದ್",
        "userrights-reason": "ಕಾರಣೊ:",
+       "userrights-no-interwiki": "ಇತರೆ ವಿಕಿಲೆಡ್ ಬಳಕೆದಾರೆ ಹಕ್ಕುಲೆನ್ ಸಂಪಾದೆರೆ ಇರೆಗ್ ಅನುಮತಿ ಇಜ್ಜಿ.",
+       "userrights-nodatabase": "ದತ್ತಸಂಚಯ $1 ಇಜ್ಜಿ, ಇಜಿಂಡ ಅವು ಸ್ಥಳಿಯ ಅತ್ತ್.",
+       "userrights-changeable-col": "ಇರೆಗ್ ಬದಲಾವರೆ ಆಪಿನ ಗುಂಪುಲು",
+       "userrights-unchangeable-col": "ಇರೆಗ್ ಬದಲಾವರೆ ಆವಂದಿನ ಗುಂಪುಲು",
+       "userrights-expiry-current": "$1 ಮುಗಿವುಂಡು",
+       "userrights-expiry-none": "ಮುಗಿಯುಜಿ",
+       "userrights-expiry": "ಮುಗಿವುಂಡು:",
+       "userrights-expiry-existing": "ಉಪ್ಪುನ ಮುಗಿಕಾಲ: $3, $2",
+       "userrights-expiry-othertime": "ಇತರೆ ಕಾಲ:",
+       "userrights-expiry-options": "1 ದಿನ:1 ದಿನ,1 ವಾರ:1 ವಾರ,1 ತಿಂಗೊಲು:1 ತಿಂಗೊಲು,3 ತಿಂಗೊಲುಲು:3 ತಿಂಗೊಲುಲು,6 ತಿಂಗೊಲುಲು:6 ತಿಂಗೊಲುಲು,1 ವರ್ಷ:1 ವರ್ಷ",
+       "userrights-invalid-expiry": "\"$1\" ಗುಂಪುದ ಮುಗಿಕಾಲ ಅಮಾನ್ಯ ಆದುಂಡು.",
+       "userrights-expiry-in-past": "\"$1\" ಗುಂಪುದ ಮುಗಿಕಾಲ ಭೂತಕಾಲೊಡು ಉಂಡು.",
+       "userrights-cannot-shorten-expiry": "ಗುಂಪು $1 ದ ಸದಸ್ಯತ್ವದ ಮುಗಿಕಾಲೊನು ಈರ್ ದುಂಬು ಕಣರೆ ಆಪುಜಿ. ಈ ಗುಂಪುನು ಸೇರಾರೆ ಬೊಕ ದೆಪ್ಪರೆ ಅನುಮತಿ ಉಪ್ಪುನ ಬಳಕೆದಾರೆರ್ ಮಾತ್ರಾ ಮುಗಿಕಾಲೊಲೆನ್ ದುಂಬು ಕಣವೊಲಿ.",
+       "userrights-conflict": "ಬಳಕೆದಾರೆ ಹಕ್ಕುಲೆ  ಬದಲಾವಣೆಲೆನ ಸಂಘರ್ಷ! ದಯಮಲ್ತ್  ಪಿರಾತೂದ್  ಇರೆನ  ಬದಲಾವಣೆಲೆನ್ ದೃಡ ಮಲ್ಪುಲೆ.",
        "group": "ಗುಂಪುಲು:",
        "group-user": "ಬಳಕೆದಾರೆರ್",
+       "group-autoconfirmed": "ಸ್ವಯಂದೃಡೀಕೃತ ಬಳಕೆದಾರೆರ್",
        "group-bot": "ಬಾಟ್ಸ್",
        "group-sysop": "ನಿರ್ವಾಹಕೆರ್",
+       "group-interface-admin": "ಅಂತರಮುಕ ನಿರ್ವಾಹಕೆರ್",
+       "group-bureaucrat": "ಅಧಿಕಾರಶಾಹಿಲು",
+       "group-suppress": "ದಮನಕೆರ್",
        "group-all": "ಮಾತಾ",
        "group-user-member": "{{GENDER:$1|ಸದರ್ಸೆ}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|ಸ್ವಯಂದೃಡೀಕೃತ ಬಳಕೆದಾರೆ}}",
+       "group-bot-member": "{{GENDER:$1|ಬೊಟ್}}",
+       "group-sysop-member": "{{GENDER:$1|ನಿರ್ವಾಹಕೆ}}",
+       "group-interface-admin-member": "{{GENDER:$1|ಅಂತರಮುಕ ನಿರ್ವಾಹಕೆ}}",
+       "group-bureaucrat-member": "{{GENDER:$1|ಅಧಿಕಾರಶಾಹಿ}}",
+       "group-suppress-member": "{{GENDER:$1|ದಮನಕಾರೆ}}",
+       "grouppage-user": "{{ns:project}}:ಬಳಕೆದಾರೆರ್",
+       "grouppage-autoconfirmed": "{{ns:project}}:ಸ್ವಯಂದೃಡೀಕೃತ ಬಳಕೆದಾರೆರ್",
        "grouppage-bot": "{{ns:project}}:ಬಾಟ್ಸ್",
        "grouppage-sysop": "{{ns:project}}:ನಿರ್ವಾಹಕೆರ್",
+       "grouppage-interface-admin": "{{ns:project}}:ಅಂತರಮುಕ ನಿರ್ವಾಹಕೆರ್",
+       "grouppage-bureaucrat": "{{ns:project}}:ಅಧಿಕಾರಶಾಹಿಲು",
+       "grouppage-suppress": "{{ns:project}}:ದಮನಿಸಾಲೆ",
        "right-read": "ಪುಟಕ್‍ಲೆನ್ ಓದುಲೆ",
        "right-edit": "ಪುಟೊಲೆನ್ ಸಂಪಾದಿಸಾಲೆ",
+       "right-createpage": " ಪುಟೊಲೆನ್ ರಚಿಸಾಲೆ (ಚರ್ಚಾಪುಟೊಲು ಅತ್ತಾಂದಿನವೆನ್)",
+       "right-createtalk": "ಚರ್ಚಾಪುಟೊಲೆನ್ ರಚಿಸಾಲೆ",
+       "right-createaccount": "ಪೊಸ ಬಳಕೆದಾರೆ ಖಾತೆಲೆನ್ ರಚಿಸಾಲೆ",
+       "right-autocreateaccount": "ಒಂಜಿ ಬಾಹ್ಯ ಬಳಕೆದಾರೆ ಖಾತೆರ್ದ್ ಸ್ವಯಂಕೃತ ಉಳಗಮನ",
+       "right-minoredit": "ಸಂಪಾದಿಲು ಕಿನ್ಯ ಇಂದ್ ಗುರ್ತಿಸಾಲೆ",
        "right-move": "ಪುಟೊನ್",
+       "right-move-subpages": "ಪುಟೊಲು ಅಯಿತ ಉಪಪುಟೊಲೆ ಸಮೇತ ಪಂದಾಲೆ.",
+       "right-move-rootuserpages": "ಮೂಲ ಬಳಕೆದಾರೆ ಪುಟೊಲೆನ್ ಪಂದಾಲೆ",
+       "right-move-categorypages": "ವರ್ಗ ಪುಟೊಲೆನ್ ಪಂದಾಲೆ",
+       "right-movefile": "ಕಡತೊಲೆನ್ ಪಂದಾಲೆ",
+       "right-suppressredirect": "ಪುಟೊಲೆನ್ ಪಂದಾನಗ ಮೂಲ ಪುಟೊರ್ದು ಪಿರರವಾನೆ ರಚನೆ ಇಜ್ಜಿ",
+       "right-upload": "ಕಡತೊಲೆನ್ ಮಿತೇರಾಲೆ",
+       "right-reupload": "ಇತ್ತಿನ ಕಡತೊಲೆನ ಮಿತ್'ಬರೇಲೆ",
+       "right-reupload-own": "ಒರಿ ಮಿತೇರಾದ್  ಇತ್ತಿನ ಕಡತೊಲೆನ  ಮಿತ್'ಬರೇಲೆ",
+       "right-reupload-shared": "ಪಟ್ಟಿನ  ಸ್ಥಳೀಯ ಮಾಧ್ಯಮ ಸಂಚಯದ ಕಡತೊಲೆನ ಮಿತ್ಸವಾರಿ ಮಲ್ಪುಲೆ.",
+       "right-upload_by_url": "ಒಂಜಿ ಯುಆರ್'ಎಲ್'ರ್ದ್ URL  ಕಡತೊಲೆನ್ ಮಿತೇರಾಲೆ",
+       "right-purge": "ಒಂಜಿ ದೃಡೀಕರಣ ದಾಂತಿನ ಪುಟತ ತಾನ ನೆನಕೂಟನು  ಉರ್ಚಾಲೆ.",
+       "right-autoconfirmed": "ಐಪಿ ಆಧಾರಿತ ದರ ಮಿತಿಲೆರ್ದ್  ಪರಿಣಾಮ ಆವಂದ್",
+       "right-bot": "ಒಂಜಿ ಸ್ವಯಂಕೃತ ಪ್ರಕ್ರಿಯೆ ಇಂದ್ ಪರಿಗಣಿಸಾಲೆ",
+       "right-nominornewtalk": "ಚರ್ಚಾ ಪುಟೊಲೆನ ಕಿನ್ಯ ಸಂಪಾದಿಲು ಪೊಸ ಸಂದೇಶಲೆನ ಚೋದಿ ಕಡಪುಡುಜಾ",
+       "right-apihighlimits": "ಎಪಿಐ API ಕೇಣಿಲೆಡ್ ಪರಮ ಮಿತಿಲೆನ್ ಬಳಕೆ ಮಲ್ಪುಲೆ.",
        "right-writeapi": "ಬರವು ಎ.ಪಿ.ಐ. ದ ಉಪಯೋಗೊ",
        "right-delete": "ಪುಟೊಕುಲೆನ್ ಮಾಜಾಲೆ",
+       "right-bigdelete": "ಮಲ್ಲ ಚರಿತ್ರೆಲು ಇತ್ತಿನ ಪುಟೊಲೆನ್ ಮಾಜಾಲೆ.",
+       "right-deletelogentry": "ವಿಸೂಚಿತ ಗಮನಿ ಸೇರಿಕೆಲೆನ್ ಮಾಜಾಲೆ ಬೊಕ ಅ-ಮಾಜಾಲೆ",
+       "right-deleterevision": "ವಿಸೂಚಿತ ಪುಟ ಪಡಿಪಾಟೊಲೆನ್ ಮಾಜಾಲೆ ಬೊಕ ಅ-ಮಾಜಾಲೆ",
+       "right-deletedhistory": "ಮಾಜಾಯಿನ ಚರಿತ್ರೆ ಸೇರಿಕೆಲೆನ್ , ಅಯಿತ ಸಹಕ್ರಮ ಪಟ್ಯ ದಾಂತೆ, ತೂಲೆ.",
+       "right-deletedtext": "ಮಾಜಾಯಿನ ಪಟ್ಯ ಬೊಕ ಮಾಜಾಯಿನ ಪಡಿಪಾಟೊಲೆನ ನಡುತ ಬದಲಾವಣೆಲೆನ್ ತೂಲೆ",
+       "right-browsearchive": "ಮಾಜಾಯಿನ ಪುಟೊಲೆನ್ ನಾಡುಲೆ",
        "right-undelete": "ಪುಟೊನ್ ಮಾಜಾವಡೆ",
+       "right-suppressrevision": "ಒವ್ವೆ ಬಳಕೆದಾರೆನ ಪುಟೊತ ವಿಸೂಚಿತ ಪಡಿಪಾಟೊಲೆನ್ ತೂಲೆ,ದೆಂಗಾಲೆ ಬೊಕ ಅ-ದೆಂಗಾಲೆ.",
+       "right-viewsuppressed": "ಒವ್ವೆ ಬಳಕೆದಾರೆರ್ದ್ ದೆಂಗಾಯಿನ ಪಡಿಪಾಟೊಲೆನ್ ತೂಲೆ",
+       "right-suppressionlog": "ಖಾಸಗಿ ಗಮನಿಲೆನ್ ತೂಲೆ",
+       "right-block": "ಇತರೆ ಬಳಕೆದಾರೆರ್ ಸಂಪಾದಿಸಂಚ ತಡೆಪುಲೆ",
+       "right-blockemail": "ಒಂಜಿ ಬಳಕೆದಾರೆ ಇಮೇಲ್ ಕಡಪುಡದಿನಂಚ ತಡೆಪುಲೆ",
+       "right-hideuser": "ಒಂಜಿ ಬಳಕೆಪುರುನು ತಡೆಪುಲೆ, ಅವೆನ್ ಸಾರ್ವಜನಿಕೊರ್ದು ದೆಂಗಾಲೆ.",
+       "right-ipblock-exempt": "ಐಪಿ ತಡೆಲು,ಸ್ವಯಂ-ತಡೆಲು ಬೊಕ ವ್ಯಾಪ್ತಿ ತಡೆಲೆನ್ ಮೀರ್ದ್ ಪೋಲೆ.",
+       "right-unblockself": "ಒರಿಯನ ಅ-ತಡೆ",
+       "right-protect": "ರಕ್ಷಣ ಮಜಲುಲೆನ್ ಬದಲಾದ್ ಬೊಕ ಸೋಪಾನ-ರಕ್ಷಿತ ಪುಟೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-editprotected": "\"{{int:protect-level-sysop}}\"ಇಂದ್ ರಕ್ಷಿತ ಪುಟೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-editsemiprotected": "\"{{int:protect-level-autoconfirmed}}\"ಇಂದ್ ರಕ್ಷಿತ ಪುಟೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-editcontentmodel": "ಒಂಜಿ ಪುಟೊತ  ವಿಷಯ ಮಾದರಿನ್ ಸಂಪಾದಿಲೆ",
+       "right-editinterface": "ಬಳಕೆದಾರೆ ಅಂತರಮುಕೊನು ಸಂಪಾದಿಲೆ",
+       "right-editusercss": "ಇತರೆ ಬಳಕೆದಾರೆರೆನ ಸಿಎಸ್ಎಸ್ ಕಡತೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-edituserjson": "ಇತರೆ ಬಳಕೆದಾರೆರೆನ ಜೆಎಸ್ಒಎನ್ ಕಡತೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-edituserjs": "ಇತರೆ ಬಳಕೆದಾರೆರೆನ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್  ಕಡತೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-editsitecss": "ತಾನ-ಅಗೆಲದ ಸಿಎಸ್ಎಸ್  ಸಂಪಾದಿಲೆ",
+       "right-editsitejson": "ತಾನ-ಅಗೆಲದ  ಜೆಎಸ್ಒಎನ್  ಸಂಪಾದಿಲೆ",
+       "right-editsitejs": "ತಾನ-ಅಗೆಲದ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್  ಸಂಪಾದಿಲೆ",
+       "right-editmyusercss": "ಇರೆನ ಸ್ವಂತದ  ಬಳಕೆದಾರೆ ಸಿಎಸ್ಎಸ್  ಕಡತೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-editmyuserjson": "ಇರೆನ ಸ್ವಂತದ  ಬಳಕೆದಾರೆ ಜೆಎಸ್ಒಎನ್  ಕಡತೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-editmyuserjs": "ಇರೆನ ಸ್ವಂತದ  ಬಳಕೆದಾರೆ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್  ಕಡತೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-viewmywatchlist": "ಇರೆನ ಸ್ವಂತದ  ತೂಪಿಪಟ್ಟಿನ್ ತೂಲೆ",
+       "right-editmywatchlist": "ಇರೆನ ಸ್ವಂತದ  ತೂಪಿಪಟ್ಟಿನ್ ಸಂಪಾದಿಲೆ. ಸಮತೂಲೆ:  ಈ ಹಕ್ಕು ದಾಂತೆ ಇತ್ತಂಡಲಾ ಕೆಲವು ಕ್ರಿಯೆಲು ನನಲಾ ಪುಟೊಲೆನ್ ಕೂಡಾವಾ.",
+       "right-viewmyprivateinfo": "ಇರೆನ ಸ್ವಂತದ ಖಾಸಗಿ ದತ್ತಾಂಶೊನು ತೂಲೆ (ಉದರ್ಮೆಗ್: ಇಮೇಲ್ ವಿಳಾಸ, ನಿಜಪುದರು)",
+       "right-editmyprivateinfo": "ಇರೆನ ಸ್ವಂತದ ಖಾಸಗಿ ದತ್ತಾಂಶೊನು ಸಂಪಾದಿಲೆ (ಉದರ್ಮೆಗ್: ಇಮೇಲ್ ವಿಳಾಸ, ನಿಜಪುದರು)",
+       "right-editmyoptions": "ಇರೆನ ಸ್ವಂತದ ಇಷ್ಟಾಯ್ಕೆಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-rollback": "ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಪುಟೊನು ಸಂಪಾದಿನ, ಕಡೆತ ಬಳಕೆದಾರೆನ ಸಂಪಾದಿಲೆನ್, ಬೇಗ ಪಿರತಿರ್ಗಾಲೆ.",
+       "right-markbotedits": "ಪಿರ-ತಿರ್ಗಾಯಿನ ಸಂಪಾದಿಲೆನ್ ಬೊಟ್ ಸಂಪಾದಿಲು ಇಂದ್ ಗುರುತು ಮಲ್ಪುಲೆ",
+       "right-noratelimit": "ದರ ಮಿತಿಲೆರ್ದ್ ಪರಿಣಾಮ ಆವಂದ್",
+       "right-import": "ಇತರೆ ವಿಕಿಲೆರ್ದ್ ಪುಟೊಲೆನ್ ಉಳಯಿ-ಕಣಲೆ",
+       "right-importupload": "ಒಂಜಿ ಕಡತ ಮಿತೇರಾಯಿನ ಪುಟೊಲೆನ್ ಉಳಯಿ-ಕಣಲೆ",
+       "right-patrol": "ಇತರೆರನ ಸಂಪಾದಿಲೆನ್ ಕಾಪಿನವೆಂದ್ ಗುರುತುಮಲ್ಪುಲೆ.",
+       "right-autopatrol": "ತನ್ನ ಸ್ವಂತ ಸಂಪಾದಿಲೆನ್  ಸ್ವಯಂಕೃತವಾದ್  ಕಾಪಿನವೆಂದ್ ಗುರುತುಮಲ್ಪುಲೆ.",
+       "right-patrolmarks": "ಇಂಚೊದ ಬದಲಾವಣೆಲೆನ್ ಕಾಪಿನ ಗುರುತುಲೆನ್ ತೂಲೆ",
+       "right-unwatchedpages": "ಅವೀಕ್ಷಿತ ಪುಟೊಕುಲೆನ ಪಟ್ಟಿ ತೂಲೆ",
+       "right-mergehistory": "ಪುಟೊಲೆನ ಚರಿತ್ರೆ ಸಮ್ಮಿಲಾಲೆ",
+       "right-userrights": "ಮಾತಾ ಬಳಕೆದಾರೆ ಹಕ್ಕುಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-userrights-interwiki": "ಇತರೆ ವಿಕಿಲೆಡ್  ಬಳಕೆದಾರೆರೆನ ಬಳಕೆ ಹಕ್ಕುಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "right-siteadmin": "ದತ್ತಾಂಶೊಗು ಬೀಗ ಪಾಡ್'ದು ಬೊಕ ಬೀಗದೆಪ್ಪುಲೆ",
+       "right-override-export-depth": "5 ಗಾಂತ್'ದ ಮುಟ್ಟದ ಪುಟೊ ಬೊಕ ಗೋಡಿನ ಪುಟೊಲೆನ್ ಪಿದಯಿಕಡಪುಡುಲೆ",
+       "right-sendemail": "ಇತರೆ ಬಳಕೆದಾರೆರೆಗ್ ಇಮೇಲ್ ಕಡಪುಡುಲೆ",
+       "right-managechangetags": " [[Special:Tags|tags]] ರಚಿಸಾಲೆ ಬೊಕ (ನ)ಕ್ರಿಯೆಮಲ್ಪಾಲೆ",
+       "right-applychangetags": "[[Special:Tags|tags]]  ತನ್ನ ಬದಲಾವಣೆಲೆನ ಒಟ್ಟುಗು ಅನ್ವಯ ಮಲ್ಪುಲೆ",
+       "right-changetags": "ವೈಯಕ್ತಿಕ ಪಡಿಪಾಟೊಲು ಬೊಕ ಗಮನಿ ಸೇರಿಕೆಲೆಡ್ ವಿನಾಕ್ರಮ [[Special:Tags|tags]] ಸೇರಾಲೆ ಬೊಕ ದೆಪ್ಪುಲೆ",
+       "right-deletechangetags": " ದತ್ತಸಂಚಯೊರ್ದು  [[Special:Tags|tags]] ಮಾಜಾಲೆ",
+       "grant-generic": "\"$1\"  ಹಕ್ಕುಲೆನ ರಾಶಿ",
+       "grant-group-page-interaction": "ಪುಟೊಲೆಗ್ ಅಂತರಕ್ರಿಯೆ ಮಲ್ಪುಲೆ",
+       "grant-group-file-interaction": "ಮಾಧ್ಯಮೊಟ್ಟುಗು ಅಂತರಕ್ರಿಯೆ ಮಲ್ಪುಲೆ",
+       "grant-group-watchlist-interaction": "ಇರೆನ ತೂಪಿಪಟ್ಟಿಡ್ ಅಂತರಕ್ರಿಯೆ ಮಲ್ಪುಲೆ",
        "grant-group-email": "ಇ-ಅಂಚೆ ಕಡಪುಡುಲೆ",
+       "grant-group-high-volume": "ಪರಮ ಪ್ರಮಾಣದ ಕ್ರಿಯೆ ಮಲ್ಪುಲೆ",
+       "grant-group-customization": "ನಿಷ್ಟಕರಣ ಬೊಕ ಇಷ್ಟಾಯ್ಕೆಲು",
+       "grant-group-administration": "ಆಡಳಿತಾತ್ಮಕ ಕ್ರಿಯೆಲೆನ್ ಮಲ್ಪುಲೆ",
+       "grant-group-private-information": "ಇರೆನ ಖಾಸಗಿ ದತ್ತಾಂಶ ದೆತೊನುಲೆ",
+       "grant-group-other": "ಇತರೆ ಕ್ರಿಯೆಲು",
+       "grant-blockusers": "ಬಳಕೆದಾರೆರೆನ್ ತಡೆಪುಲೆ ಬೊಕ ಅತಡೆಪುಲೆ",
        "grant-createaccount": "ಪೊಸ ಕಾತೆ ಸುರು ಮಲ್ಪುಲೆ",
+       "grant-createeditmovepage": "ಪುಟೊಲೆನ್ ರಚಿಸಾದ್, ಸಂಪಾದಿದ್ ಬೊಕ ಪಂದಾಲೆ",
+       "grant-delete": "ಪುಟೊಲು,ಪಡಿಪಾಟೊಲು ಬೊಕ ಗಮನಿ ಸೇರಿಕೆಲೆನ್ ಮಾಜಾಲೆ",
+       "grant-editinterface": "ಮಿಡಿಯಾವಿಕಿ ಪುದರಜಾಗ ಬೊಕ ತಾನಅಗೆಲ/ಬಳಕೆದಾರೆ ಜೆಎಸ್ಒಎನ್ ಸಂಪಾದಿಲೆ",
+       "grant-editmycssjs": "ಇರೆನ ಬಳಕೆದಾರೆ  ಸಿಎಸ್ಎಸ್/ ಜೆಎಸ್ಒಎನ್ /ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಸಂಪಾದಿಲೆ",
+       "grant-editmyoptions": "ಇರೆನ ಬಳಕೆದಾರೆ  ಇಷ್ಟಾಯ್ಕೆಲು ಬೊಕ ಜೆಎಸ್ಒಎನ್ ಸಂರಚನೆನ್ ಸಂಪಾದಿಲೆ",
+       "grant-editmywatchlist": "ಇರೆನ ತೂಪಿಪಟ್ಟಿನ್ ಸಂಪಾದಿಲೆ",
+       "grant-editsiteconfig": "ತಾನ-ಅಗೆಲದ ಬೊಕ ಬಳಕೆದಾರೆ  ಸಿಎಸ್ಎಸ್/ ಜೆಎಸ್  ಸಂಪಾದಿಲೆ",
+       "grant-editpage": "ಉಪ್ಪುನ ಪುಟೊಲೆನ್  ಸಂಪಾದಿಲೆ",
+       "grant-editprotected": "ರಕ್ಷಿತ ಪುಟೊಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "grant-highvolume": "ಭಾರೀ ಪ್ರಮಾಣದ ಸಂಪಾದಿಕೆ",
+       "grant-oversight": "ಬಳಕೆದಾರೆರೆನ್ ದೆಂಗಾಲೆ ಬೊಕ ಪಡಿಪಾಟೊಲೆನ್ ದಮನಿಸಾಲೆ",
+       "grant-patrol": "ಪುಟೊಲೆನ ಕಾಪಿನ ಬದಲಾವಣೆಲು",
+       "grant-privateinfo": "ಖಾಸಗಿ ಮಾಹಿತಿ ದೆತೊನುಲೆ",
+       "grant-protect": "ಪುಟೊಲೆನ್ ರಕ್ಷಿಸಾಲೆ ಬೊಕ ಅರಕ್ಷಿಸಾಲೆ",
+       "grant-rollback": "ಪುಟೊಲೆನ ಬದಲಾವಣೆಲೆನ್ ಪಿರತಿರ್ಗಾಲೆ",
+       "grant-sendemail": "ಇತರೆ ಬಳಕೆದಾರೆರೆಗ್ ಇಮೇಲ್ ಕಡಪುಡುಲೆ",
+       "grant-uploadeditmovefile": "ಕಡತೊಲೆನ್ ಮಿತೇರಾಲೆ,ಪಿರಪಲ್ಲಟ ಮಲ್ಪಿ ಬೊಕ ಪಂದಾಲೆ",
+       "grant-uploadfile": "ಪೊಸ ಕಡತೊಲೆನ್ ಮಿತೇರಾಲೆ",
+       "grant-basic": "ಮೂಲ ಹಕ್ಕುಲು",
+       "grant-viewdeleted": "ಮಾಜಾಯಿನ ಕಡತೊಲು ಬೊಕ ಪುಟೊಲೆನ್ ತೂಲೆ",
+       "grant-viewmywatchlist": "ಇರೆನ ತೂಪಿಪಟ್ಟಿನ್ ತೂಲೆ",
+       "grant-viewrestrictedlogs": "ನಿರ್ಬಂದಿತ ಗಮನಿ ಸೇರಿಕೆಲೆನ್ ತೂಲೆ",
        "newuserlogpage": "ಸದಸ್ಯೆರೆ ಉಂಡುಮಲ್ತಿನ ದಾಕಲೆ",
+       "newuserlogpagetext": "ಉಂದು ಬಳಕೆದಾರೆರೆ ರಚನೆಲೆನ ಒಂಜಿ ಗಮನಿ",
        "rightslog": "ಸದಸ್ಯೆರ್ನ ಹಕ್ಕ್ ದಾಖಲೆ",
+       "rightslogtext": "ಉಂದು ಬಳಕೆದಾರ ಹಕ್ಕುಲೆನ ಬದಲಾವಣೆಲೆನ ಒಂಜಿ ಗಮನಿ",
        "action-read": "ಈ ಪುಟೊನು ಓದುಲೆ",
        "action-edit": "ಈ ಪುಟೊನು ಸಂಪೊಲಿಪುಲೆ",
        "action-createpage": "ಈ ಪುಟೊನು ಸೃಷ್ಟಿಸಾಲೆ",
        "action-createtalk": "ಚರ್ಚಾ ಪುಟೊನ್ ಸೃಷ್ಟಿಸಾಲೆ",
        "action-createaccount": "ಈ ಸದಸ್ಯೆರನ ಖಾತೆನ್ ಉಂಡುಮಲ್ಪುಲೆ",
+       "action-autocreateaccount": "ಈ ಬಾಹ್ಯ ಬಳಕೆದಾರೆ ಖಾತೆನ್ ಸ್ವಯಂಕೃತವಾದ್ ರಚಿಸಾಲೆ",
+       "action-history": "ಈ ಪುಟೊತ ಚರಿತ್ರೆನ್ ತೂಲೆ",
        "action-minoredit": "ಉದೊಂಜಿ ಎಲ್ಯ  ಬದಲಾವಣೆ",
        "action-move": "ಈ ಪೂಟೊನು ಮೂವ್(ಸ್ಥಳಾಂತರ) ಮಲ್ಪುಲೆ",
+       "action-move-subpages": "ಈ ಪುಟೊನು ಬೊಕ ಅಯಿತ ಉಪಪುಟೊಲೆನ್ ಪಂದಾಲೆ",
+       "action-move-rootuserpages": "ಮೂಲ ಬಳಕೆದಾರೆ ಪುಟೊಲೆನ್ ಪಂದಾಲೆ",
+       "action-move-categorypages": "ವರ್ಗ ಪುಟೊಲೆನ್ ಪಂದಾಲೆ",
        "action-movefile": "ಈ ಫೈಲ್‘ನ್ ಸ್ಥಳಾಂತರ ಮಲ್ಪುಲೆ",
        "action-upload": "ಈ ಫೈಲ್‘ನ್ ಅಪ್‘ಲೋಡ್ ಮಲ್ಪುಲೆ",
+       "action-reupload": "ಉಪ್ಪುನ  ಕಡತದ ಮಿತ್'ಬರೇಲೆ",
+       "action-reupload-shared": " ಈ ಕಡತೊನು ಪಟ್ಟಿನ ಸಂಚಯೊಡು ಮೇಲ್ಸವಾರಿ ಮಲ್ಪುಲೆ",
+       "action-upload_by_url": "ಈ ಕಡತೊನು ಒಂಜಿ ಯುಆರ್'ಎಲ್' ರ್ದ್ ಮಿತೇರಾಲೆ",
+       "action-writeapi": "ಬರೆಪಿ ಎಪಿಐ'ನ್ ಬಳಸಿಲೆ.",
        "action-delete": "ಈ ಪುಟೊನ್ ಮಾಜಾಲೆ",
        "action-deleterevision": "ಈ ಆವೃತ್ತಿನ್ ಮಾಜಾಲೆ",
+       "action-deletelogentry": "ಗಮನಿ ಸೇರಿಕೆಲೆನ್ ಮಾಜಾಲೆ.",
+       "action-deletedhistory": "ಒಂಜಿ ಪುಟತ ಮಾಜಾಯಿನ ಚರಿತ್ರೆನ್ ತೂಲೆ",
+       "action-deletedtext": "ಮಾಜಾಯಿನ ಪಡಿಪಾಟ ಪಟ್ಯೊನು ತೂಲೆ",
        "action-browsearchive": "ಮಜಾಯಿನಾ ಪುಟೋನ್ ನಡ್ಲೆ",
        "action-undelete": "ಪುಟೊಲೆನ್ ಮಾಜಾವಂದೆ ದೀಲೆ",
+       "action-suppressrevision": "ದೆಂಗಿನ ಪಡಿಪಾಟೊಲೆನ್ ಪಿರತೂದ್ ಬೊಕ ಪಿರತಾಪಿಸಾಲೆ",
+       "action-suppressionlog": "ಈ ಖಾಸಗಿ ಗಮನಿನ್ ತೂಲೆ",
+       "action-block": "ಈ ಬಳಕೆದಾರೆ ಸಂಪಾದಿಸನಂಚ ತಡೆಪುಲೆ",
+       "action-protect": "ಈ ಪುಟೊಕು ರಕ್ಷಣಾ ಮಜಲುಲೆನ್ ಬದಲಾಲೆ",
+       "action-rollback": "ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಪುಟೊನು ಸಂಪಾದಿನ, ಕಡೇತ ಬಳಕೆದಾರೆನ ಸಂಪಾದಿಲೆನ್, ಬೇಗ ಪಿರತಿರ್ಗಾಲೆ.",
+       "action-import": "ನನೊಂಜಿ  ವಿಕಿರ್ದ್ ಪುಟೊಲೆನ್ ಉಳಯಿ-ಕಣಲೆ",
+       "action-importupload": "ಒಂಜಿ ಕಡತ ಮಿತೇರಾಯಿನ ಪುಟೊಲೆನ್ ಉಳಯಿ-ಕಣಲೆ",
+       "action-patrol": "ಇತರೆರೆನ ಸಂಪಾದಿಲೆನ್ ಕಾಪಿನವೆಂದ್ ಗುರುತುಮಲ್ಪುಲೆ.",
+       "action-autopatrol": "ಇರೆನ ಸಂಪಾದಿನ್ ಕಾಪಿನವು ಇಂದ್ ಗುರುತುಮಲ್ಪುಲೆ",
+       "action-unwatchedpages": "ಅವೀಕ್ಷಿತ ಪುಟೊಲೆನ ಪಟ್ಟಿನ್ ತೂಲೆ",
+       "action-mergehistory": "ಈ ಪುಟೊತ ಚರಿತ್ರೆನ್ ಸಮ್ಮಿಲಾಲೆ",
+       "action-userrights": "ಮಾತಾ ಬಳಕೆದಾರೆ ಹಕ್ಕುಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "action-userrights-interwiki": "ಇತರೆ ವಿಕಿಲೆಡ್  ಬಳಕೆದಾರೆರೆನ ಬಳಕೆ ಹಕ್ಕುಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "action-siteadmin": "ದತ್ತಸಂಚಯೊಗು  ಬೀಗಪಾಡ್'ಲೆ  ಇಜಿಂಡ  ಬೀಗದೆಪ್ಪುಲೆ",
        "action-sendemail": "ಇ-ಅಂಚೆ ಕಡಪುಡುಲೆ",
+       "action-editmyoptions": "ಇರೆನ  ಇಷ್ಟಾಯ್ಕೆಲೆನ್ ಸಂಪಾದಿಲೆ",
+       "action-editmywatchlist": "ಇರೆನ ತೂಪಿಪಟ್ಟಿನ್ ಸಂಪಾದಿಲೆ",
+       "action-viewmywatchlist": "ಇರೆನ ತೂಪಿಪಟ್ಟಿನ್ ತೂಲೆ",
+       "action-viewmyprivateinfo": "ಇರೆನ ಖಾಸಗಿ ಮಾಹಿತಿನ್ ತೂಲೆ",
+       "action-editmyprivateinfo": "ಇರೆನ ಖಾಸಗಿ ಮಾಹಿತಿನ್ ಸಂಪಾದಿಲೆ",
+       "action-editcontentmodel": "ಒಂಜಿ ಪುಟೊತ  ವಿಷಯ ಮಾದರಿನ್ ಸಂಪಾದಿಲೆ",
+       "action-managechangetags": "ಕುಚ್ಚಿಲೆನ್ ರಚಿಸಾಲೆ ಬೊಕ (ನ)ಕ್ರಿಯಾ ಮಲ್ಪುಲೆ",
+       "action-applychangetags": "ಇರೆನ ಬದಲಾವಣೆದೊಟ್ಟುಗು ಕುಚ್ಚಿಲೆನ್ ಅನ್ವಯಿಸಾಲೆ",
+       "action-changetags": "ವೈಯಕ್ತಿಕ  ಪಡಿಪಾಟೊಲು  ಬೊಕ ಗಮನಿ ಸೇರಿಕೆಲೆಡ್, ವಿನಾಕ್ರಮ  ಕುಚ್ಚಿಲೆನ್ ಸೇರಾಲೆ ಬೊಕ ದೆಪ್ಪುಲೆ",
+       "action-deletechangetags": "ದತ್ತಸಂಚಯೊದ  ಕುಚ್ಚಿಲೆನ್  ಮಾಜಾಲೆ",
+       "action-purge": "ಈ ಪುಟೊನು ಉರ್ಚಾಲೆ",
        "nchanges": "$1 {{PLURAL:$1|ಬದಲಾವಣೆ|ಬದಲಾವಣೆಲು}}",
+       "enhancedrc-since-last-visit": "$1 {{PLURAL:$1| ಕಡೆತ ಸಂದರ್ಶನೊರ್ದು ಇಂಚಿಗ್ }}",
        "enhancedrc-history": "ಇತಿಹಾಸೊ",
        "recentchanges": "ಇಂಚಿಪೊದ ಬದಲಾವಣೆಲು",
        "recentchanges-legend": "ಇಂಚಿಪೊದ ಬದಲಾವಣೆಲೆ ಆಯ್ಕೆಲು",
        "recentchanges-summary": "ಈ ವಿಕಿಟ್ ಇಂಚಿಪ್ಪ ಮಲ್ತ್‌ನ ಬದಲಾವಣೆನ್ ಈ ಪುಟೊಡು ಈರ್ ತೂವೊಲಿ",
        "recentchanges-noresult": "ಈ ಮಾನದಂಡೊಲೆಗ್ ಸರಿ ಒಂಬುನ ಬದಲಾವಣೆಲು ಕೊರಿನ ಪೊರ್ತುಡು ಇಜ್ಜಿ",
+       "recentchanges-timeout": "ಈ ನಾಡುನ ಕಾಲ ಕರಿಂಡ್. ಈರ್ ಬೇತೆ ನಾಡುನ ಪರಿಮಾನೊಲೆನ್ ಯತ್ನಿಸಾವರೆ ಬಯಸೊಲಿ.",
+       "recentchanges-network": "ಒಂಜಿ ತಾಂತ್ರಿಕ ದೋಷದ ಕಾರಣ, ಒವ್ವೆ ಫಲಿತಾಂಶೊಲೆನ್ ದಿಂಜಾವರೆ ಆತಿಜಿ. ದಯಮಲ್ತ್ ಪುಟೊನು ಪಿರಚೇತನ ಮಲ್ಪರೆ ಯತ್ನಿಸಾಲೆ.",
+       "recentchanges-notargetpage": "ಮಿತ್ತ್ ಒಂಜಿ ಪುಟತ ಪುದರ್ ಸೇರಾಲೆ, ಆ ಪುಟ ಸಮ್ಮಂದದ ಬದಲಾವಣೆಲೆನ್ ತೂವರೆಗಾದ್",
        "recentchanges-feed-description": "ಈ ಫೀಡ್‌ಡ್ ವಿಕಿಕ್ ಇಂಚಿಪ್ಪ ಆತಿನಂಚಿನ ಬದಲಾವಣೆಲೆನ್ ತೂವೊಂದುಪ್ಪೊಲಿ.",
        "recentchanges-label-newpage": "ಈ ಬದಲಾವಣೆ ಒಂಜಿ ಪೊಸ ಪುಟೊನು ಉಂಡು ಮಲ್ತ್‌ಂಡ್.",
        "recentchanges-label-minor": "ಉಂದು ಕಿಞ್ಞ ಬದಲಾವಣೆ",
        "recentchanges-legend-heading": "<strong>ಪರಿವಿಡಿ:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|ಪೊಸ ಪುಟೊಕ್ಲೆನ ಪಟ್ಟಿ]]ನ್ಲಾ ತೂಲೆ)",
        "recentchanges-submit": "ತೋಜಾಲೆ",
+       "rcfilters-tag-remove": " '$1' ದೆಪ್ಪುಲೆ",
+       "rcfilters-legend-heading": "<strong>ಸಂಕ್ಷೇಪೊಲೆನ ಪಟ್ಟಿ:</strong>",
+       "rcfilters-other-review-tools": "ಇತರೆ ಪಿರತೂಪಿನ ಉಪಕರಣೊಲು",
+       "rcfilters-group-results-by-page": "ಪುಟ ಅನುಸಾರ ಗುಂಪು ಫಲಿತಾಂಶೊಲು",
+       "rcfilters-activefilters": "ಸಕ್ರಿಯ ಅರಿಪೆಲು",
+       "rcfilters-activefilters-hide": "ದೆಂಗಾಲೆ",
+       "rcfilters-activefilters-show": "ತೋಜಾಲೆ",
+       "rcfilters-activefilters-hide-tooltip": "ಸಕ್ರಿಯ ಅರಿಪೆಲೆನ ಜಾಗ ದೆಂಗಾಲೆ",
+       "rcfilters-activefilters-show-tooltip": "ಸಕ್ರಿಯ ಅರಿಪೆಲೆನ ಜಾಗ ತೋಜಾಲೆ",
+       "rcfilters-advancedfilters": "ಮುಂದರಿನ ಅರಿಪೆಲು",
+       "rcfilters-limit-title": "ತೋಜಾರೆ ಫಲಿತಾಂಶೊಲು",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|ಬದಲಾವಣೆ|ಬದಲಾವಣೆಲು}}, $2",
+       "rcfilters-date-popup-title": "ನಾಡರೆ ಕಾಲಾವಧಿ",
+       "rcfilters-days-title": "ಇಂಚೊದ ದಿನೊಲು",
+       "rcfilters-hours-title": "ಇಂಚೊದ ಗಂಟೆಲು",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|ದಿನ|ದಿನೊಲು}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|ಗಂಟೆ|ಗಂಟೆಲು}}",
+       "rcfilters-highlighted-filters-list": "ಅತಿಪ್ರಕಾಶಿತ: $1",
        "rcfilters-quickfilters": "ಅರಿತ್ನ ವಿಸಯೊನ್ ಒರಿಪಾಲೆ",
+       "rcfilters-quickfilters-placeholder-title": "ಒವ್ವೆ ಅರಿಪೆಲೆನ್ ನನಲಾ ಒರಿಪಾದಿಜಿ.",
+       "rcfilters-quickfilters-placeholder-description": "ಇರೆನ ಅರಿಪೆ ಅಟ್ಟಣೆಲೆನ್ ಒರಿಪಾದ್ ಬೊಕ ಅವೆನ್ ಪಿರಬಳಕೆ ಮಲ್ಪರೆ, ತಿರ್ತ್'ದ  ಸಕ್ರಿಯ ಅರಿಪೆಲೆನ ಜಾಗೊಡು, ಪುಸ್ತಕಗುರ್ತುದ ಕಿನ್ನೆನ್ ಒತ್ತುಲೆ",
+       "rcfilters-savedqueries-defaultlabel": "ಒರಿಪಾಯಿನ ಅರಿಪೆಲು",
        "rcfilters-savedqueries-rename": "ಪೊಸ ಪುದರ್",
+       "rcfilters-savedqueries-setdefault": "ಸಮಸ್ಥಿತಿರೂಪೊದ ಅಟ್ಟಣೆ ಮಲ್ಪುಲೆ",
+       "rcfilters-savedqueries-unsetdefault": "ಸಮಸ್ಥಿತಿರೂಪೊ ದೆಪ್ಪುಲೆ",
        "rcfilters-savedqueries-remove": "ಮಾಜಾಲೆ",
        "rcfilters-savedqueries-new-name-label": "ಪುದರ್",
+       "rcfilters-savedqueries-new-name-placeholder": "ಅರಿಪೆದ ಉದ್ದೇಶ ವಿವರಿಸಾಲೆ",
+       "rcfilters-savedqueries-apply-label": "ಅರಿಪೆ ರಚಿಸಾಲೆ",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "ಸಮಸ್ಥಿತಿ ಅರಿಪೆ ರಚಿಸಾಲೆ",
        "rcfilters-savedqueries-cancel-label": "ವಜಾ ಮಲ್ಪುಲೆ",
+       "rcfilters-savedqueries-add-new-title": "ಇತ್ತೆದ ಅರಿಪೆ ಅಟ್ಟಣೆಲೆನ್ ಒರಿಪಾಲೆ",
+       "rcfilters-savedqueries-already-saved": "ಇಂಚಿತ್ತಿ  ಅರಿಪೆಲೆನ್  ಇದಮುಟ್ಟನೆ ಒರಿಪಾದುಂಡು. ಒಂಜಿ ಪೊಸ ಒರಿಪಾಯಿನ ಅರಿಪೆ ರಚಿಸಾರೆ, ಇರೆನ ಅಟ್ಟಣೆಲೆನ್ ಬದಲಾಲೆ.",
+       "rcfilters-restore-default-filters": "ಸಮಸ್ಥಿತಿ ಅರಿಪೆಲೆನ್ ಪಿರತಾಪಿಸಾಲೆ",
+       "rcfilters-clear-all-filters": "ಮಾತಾ ಅರಿಪೆಲೆನ್ ಖಾಲಿ ಮಲ್ಪುಲೆ.",
+       "rcfilters-show-new-changes": "ಪೊಚ್ಚಪೊಸ ಬದಲಾವಣೆಲೆನ್ ತೂಲೆ",
+       "rcfilters-search-placeholder": "ಅರಿಪೆ ಬದಲಾವಣೆಲು (ಯಾದಿ ಬಳಕೆ ಮಲ್ಪುಲೆ ಇಜಿಂಡ ಅರಿಪೆ ಪುದರುಡು ನಾಡ್'ಲೆ )",
+       "rcfilters-invalid-filter": "ಅಮಾನ್ಯ ಅರಿಪೆ",
+       "rcfilters-empty-filter": "ಸಕ್ರಿಯ ಅರಿಪೆಲು ಇಜ್ಜಿ.  ಮಾತಾ ಕಾಣಿಕೆಲೆನ್ ತೋಜಾದುಂಡು.",
+       "rcfilters-filterlist-title": "ಅರಿಪೆಲು",
        "rcfilters-filterlist-whatsthis": "ಉಂದು ಎಂಚ ಬೇಲೆ ಮಲ್ಪುಂಡು?",
+       "rcfilters-filterlist-feedbacklink": "ಇಂಚಿನ  ಅರಿಪೆ ಉಪಕರಣೆಲೆನ ಮಿತ್ತ್ ಈರ್ ದಾದ ಎಣ್ಣುವರ್ ಇಂದ್ ಎಂಕಲೆಗ್ ತೆರಿಪಾಲೆ.",
+       "rcfilters-highlightbutton-title": "ಫಲಿತಾಂಶೊಲೆನ್  ಅತಿಪ್ರಕಾಶಿಸಾಲೆ.",
+       "rcfilters-highlightmenu-title": "ಒಂಜಿ ಬಣ್ಣೊನು ಪೆಜಿಲೆ.",
+       "rcfilters-highlightmenu-help": "ಈ ಗುಣೊನು ಅತಿಪ್ರಕಾಶಿಸಾರೆ ಒಂಜಿ ಬಣ್ಣೊನು ಪೆಜಿಲೆ.",
+       "rcfilters-filterlist-noresults": "ಒವ್ವೆ ಅರಿಪೆಲು ತಿಕ್ಕುಜಿ.",
+       "rcfilters-noresults-conflict": "ಒವ್ವೆ ಫಲಿತಾಂಶೊಲು ತಿಕ್ಕುಜಾ ಕಾರಣ ನಾಡುನ ಮಾನಕೊಲು ಸಂಘರ್ಷೊಡು ಉಲ್ಲಾ.",
+       "rcfilters-state-message-subset": "ಈ ಅರಿಪೆಗ್ ಒವ್ವೆ ಪರಿಣಾಮ ಇಜ್ಜಿ, ಕಾರಣ ಅಯಿತ ಫಲಿತಾಂಶೊಲು ಈ ತಿರತ್'ದೊಟ್ಟುಗು ಸೇರೊಂದಾ,\nವಿಶಾಲವಾದ್ {{PLURAL:$2|ಅರಿಪೆ|ಅರಿಪೆಲು}} (ಅವೆನ್ ಪ್ರಶಸ್ತ ಮಲ್ಪರೆ ಅತಿಪ್ರಕಾಶಿಸಾವರೆ ಯತ್ನಿಸಾಲೆ): $1",
+       "rcfilters-state-message-fullcoverage": "ಈ ಗುಂಪುದ ಮಾತಾ ಅರಿಪೆಲೆನ್ ಪೆಜುನವು ಒಂಜೆನ್ಲಾ ಪೆಜಂದಿನೆಕ್ ಸಮಾ, ಆಯಿನೆರ್ದಾವರಾ ಈ ಅರಿಪೆಗ್ ಪರಿಣಾಮ ಇಜ್ಜಿ. ಗುಂಪುಡು $1 ಸೇರ್ದುಂಡು.",
+       "rcfilters-filtergroup-authorship": "ಕಾಣಿಕೆ ಲೇಖಕತ್ವ",
+       "rcfilters-filter-editsbyself-label": "ಈರ್ ಮಲ್ತಿನ ಬದಲಾವಣೆಲು",
+       "rcfilters-filter-editsbyself-description": "ಇರೆನ ಸ್ವಂತದ ಕಾಣಿಕೆಲು",
+       "rcfilters-filter-editsbyother-label": "ಇತರೆರ್ ಮಲ್ತಿನ ಬದಲಾವಣೆಲು",
+       "rcfilters-filter-editsbyother-description": "ಇರೆನ ಸ್ವಂತದ ಬುಡುದು, ಮಾತಾ ಬದಲಾವಣೆಲು",
+       "rcfilters-filtergroup-userExpLevel": "ಬಳಕೆದಾರೆ ನೊಂದಣಿ ಬೊಕ ಅನುಭವ",
+       "rcfilters-filter-user-experience-level-registered-label": "ನೋಂದಾಯಿನ",
+       "rcfilters-filter-user-experience-level-registered-description": "ಉಳಗಮನ ಆತಿನ ಸಂಪಾದಕೆರ್",
+       "rcfilters-filter-user-experience-level-unregistered-label": "ಅನೊಂದಾಯಿತ",
+       "rcfilters-filter-user-experience-level-unregistered-description": "ಉಳಗಮನ ಆವಂದಿನ ಸಂಪಾದಕೆರ್",
+       "rcfilters-filter-user-experience-level-newcomer-label": "ಪೊಸತ್'ಬತ್ತಿನಕುಲು",
+       "rcfilters-filter-user-experience-level-newcomer-description": "10 ಸಂಪಾದಿಲೆರ್ದ್ ಕಡಿಮೆ, ಇಜಿಂಡ 4 ದಿನತ ಸಕ್ರಿಯೆ ಇತ್ತಿನ, ನೊಂದಾಯಿನ ಸಂಪಾದಕೆರ್",
        "rcfilters-filter-user-experience-level-learner-label": "ಕಲ್ಪುನರ್",
+       "rcfilters-filter-user-experience-level-learner-description": " \"ಪೊಸತ್'ಬತ್ತಿನಕುಲು\" ಬೊಕ \"ಅನುಭವಿ ಬಳಕೆದಾರೆರ್\"  ಈ ನಡುಟು ಬೂರುನ ಅನುಭವ ಇತ್ತಿನ ನೊಂದಾಯಿನ ಸಂಪಾದಕೆರ್",
+       "rcfilters-filter-user-experience-level-experienced-label": "ಅನುಭವಿ ಬಳಕೆದಾರೆರ್",
+       "rcfilters-filter-user-experience-level-experienced-description": "500 ಸಂಪಾದಿಲೆರ್ದ್ ಹೆಚ್ಚ ಬೊಕ 30 ದಿನೊತ ಸಕ್ರಿಯೆ ಇತ್ತಿನ ನೋಂದಾಯಿನ ಸಂಪಾದಕೆರ್",
+       "rcfilters-filtergroup-automated": "ಸ್ವಯಂಕೃತ ಕಾಣಿಕೆಲು",
+       "rcfilters-filter-bots-label": "ಬೊಟ್",
+       "rcfilters-filter-bots-description": "ಸ್ವಯಂಕೃತ ಉಪಕರಣೊಲು ಮಲ್ತಿನ ಸಂಪಾದಿಲು",
+       "rcfilters-filter-humans-label": "ಮಾನವೆ(ಬೊಟ್ ಅತ್ತ್)",
+       "rcfilters-filter-humans-description": "ಮಾನವ ಸಂಪಾದಕೆರ್ ಮಲ್ತಿನ ಸಂಪಾದಿಲು.",
+       "rcfilters-filtergroup-reviewstatus": "ಸ್ಥಿತಿನ್ ಪಿರತೂಲೆ.",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "ಅಂಗಿಕವಾದಾತ್ತಾಂದೆ ಇಜಿಂಡ ಸ್ವಯಂಕೃತವಾದ್ ಕಾಪಿನವು ಇಂದ್ ಗುರುತುಪಾಡಿನ ಸಂಪಾದಿಲು",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "ಕಾಪಂದಿನವು",
+       "rcfilters-filter-reviewstatus-manual-description": "ಅಂಗಿಕವಾದ್ ಕಾಪಿನವು ಇಂದ್ ಗುರುತುಪಾಡಿನ ಸಂಪಾದಿಲು",
+       "rcfilters-filter-reviewstatus-manual-label": "ಅಂಗಿಕವಾದ್ ಕಾಪಿನವು",
+       "rcfilters-filter-reviewstatus-auto-description": " ಕಾಯಕ ಸ್ವಯಂಕೃತವಾದ್ ಕಾಪಿನವು ಇಂದ್ ಗುರುತಾಯಿನ ಮುಂದರಿನ ಬಳಕೆದಾರೆರೆನ, ಸಂಪಾದಿಲು",
+       "rcfilters-filter-reviewstatus-auto-label": "ಸ್ವಯಂ-ಕಾಪಿನವು",
+       "rcfilters-filtergroup-significance": "ವಿಶಿಷ್ಟತೆ",
+       "rcfilters-filter-minor-label": "ಕಿನ್ಯ ಸಂಪಾದಿಲು",
+       "rcfilters-filter-minor-description": "ಲೇಖಕೆ ಕಿನ್ಯ ಇಂದ್ ಪುದರ್ಪಟ್ಟಿ ಪಾಡಿನ ಸಂಪಾದಿಲು",
+       "rcfilters-filter-major-label": "ಕಿನ್ಯ-ಅತ್ತಾಂದಿನ ಸಂಪಾದಿಲು",
+       "rcfilters-filter-major-description": "ಕಿನ್ಯ ಇಂದ್ ಪುದರ್ಪಟ್ಟಿ ಪಾಡಂದಿನ  ಸಂಪಾದಿಲು",
+       "rcfilters-filtergroup-watchlist": "ತೂಪಿಪಟ್ಟಿಯಾತಿನ ಪುಟೊಲು",
+       "rcfilters-filter-watchlist-watched-label": "ತೂಪಿಪಟ್ಟಿಡ್",
+       "rcfilters-filter-watchlist-watched-description": "ಇರೆನ ತೂಪಿಪಟ್ಟಿದ ಪುಟೊಲೆಡ್ ಬದಲಾವಣೆಲು",
+       "rcfilters-filter-watchlist-watchednew-label": "ಪೊಸ ತೂಪಿಪಟ್ಟಿದ ಬದಲಾವಣೆಲು",
+       "rcfilters-filter-watchlist-watchednew-description": "ತೂಪಿಪಟ್ಟಿದ ಪುಟೊಲೆಡ್ ಬದಲಾವಣೆಲು, ಬದಲಾವಣೆ ಆಯಿಬೊಕ ಈರ್ ತೂವಂದಿನವು.",
+       "rcfilters-filter-watchlist-notwatched-label": "ತೂಪಿಪಟ್ಟಿಡ್ ಇಜ್ಜಿ",
+       "rcfilters-filter-watchlist-notwatched-description": "ಇರೆನ ತೂಪಿಪಟ್ಟಿದ ಪುಟೊಲೆಡ್ ಬದಲಾವಣೆಲೆನ್ ಬುಡುದು ಮಾತಾ",
+       "rcfilters-filtergroup-watchlistactivity": "ತೂಪಿಪಟ್ಟಿದ ಕ್ರಿಯೆ",
+       "rcfilters-filter-watchlistactivity-unseen-label": "ತೂವಂದಿನ ಬದಲಾವಣೆಲು",
+       "rcfilters-filter-watchlistactivity-unseen-description": "ಪುಟೊಲೆಡ್ ಬದಲಾವಣೆಲು, ಬದಲಾವಣೆ ಆಯಿಬೊಕ ಈರ್ ತೂವಂದಿನವು.",
+       "rcfilters-filter-watchlistactivity-seen-label": "ತೂಯಿನ ಬದಲಾವಣೆಲು",
+       "rcfilters-filter-watchlistactivity-seen-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": "ನಿರ್ವಾಹಕ ಕಾರ್ಯೊಲು, ಖಾತೆ ರಚನೆಲು, ಪುಟ ಮಾಜಿಕೆಲು, ಮಿತೇರಾಯಿನವು ....",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "\"ಕಿನ್ಯ ಸಂಪಾದಿಲು\" ಅರಿಪೆ ಒಂಜಿ ಇಜಿಂಡ ಹೆಚ್ಚಿನ ಅರಿಪೆಲ ಒಟ್ಟುಗು ಸಂಘರ್ಷೊಡು ಉಂಡು, ಕಾರಣ ಕೆಲ ಬಗೆತ ಬದಲಾವಣೆಲೆನ್ \" ಕಿನ್ಯ \" ಇಂದ್ ಪಣೆರೆ ಆಪುಜಿ. ಸಂಘರ್ಷದ ಅರಿಪೆಲೆನ್,  ಮಿತ್ತ್'ದ  ಸಕ್ರಿಯ ಅರಿಪೆಲೆನ ಜಾಗೊಡು ಗುರುತು ಮಲ್ಪುಂಡು.",
+       "rcfilters-hideminor-conflicts-typeofchange": " ಕೆಲ ಬಗೆತ ಬದಲಾವಣೆಲೆನ್ \" ಕಿನ್ಯ \" ಇಂದ್ ಪಣೆರೆ ಆಪುಜಿ. ಅಂಚಾದ್  ಈ  ಅರಿಪೆ,  ಈ ದುಂಬುದ  $1 ಅರಿಪೆಲೆನ ಬದಲಾವಣೆಡ್ ಸಂಘರ್ಷ ಮಲ್ಪುಂಡು:",
+       "rcfilters-typeofchange-conflicts-hideminor": "ಈ ಬಗೆತ  ಅರಿಪೆಲೆನ ಬದಲಾವಣೆ \"ಕಿನ್ಯ ಸಂಪಾದಿಲು\" ಅರಿಪೆದ ಒಟ್ಟುಗು ಸಂಘರ್ಷ ಮಲ್ಪುಂಡು: ಕೆಲ ಬಗೆತ ಬದಲಾವಣೆಲೆನ್ \" ಕಿನ್ಯ \" ಇಂದ್ ಪಣೆರೆ ಆಪುಜಿ.",
+       "rcfilters-filtergroup-lastRevision": "ಇಂಚೊದ ಪಡಿಪಾಟೊಲು",
+       "rcfilters-filter-lastrevision-label": "ಇಂಚೊದ ಪಡಿಪಾಟ",
+       "rcfilters-filter-lastrevision-description": "ಒಂಜಿ ಪುಟೊಕು ಅತಿ ಇಂಚೊದ ಬದಲಾವಣೆ ಮಾತ್ರಾ",
+       "rcfilters-filter-previousrevision-label": "ಇಂಚೊದ ಪಡಿಪಾಟ ಅತ್ತ್",
+       "rcfilters-filter-previousrevision-description": "\"ಇಂಚೊದ ಪಡಿಪಾಟ\" ಅತ್ತಾಂದಿನ ಮಾತಾ ಬದಲಾವಣೆಲು",
+       "rcfilters-filter-excluded": "ಬುಡುದ್",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:ಅತ್ತ್</strong> $1",
+       "rcfilters-exclude-button-off": "ಪೆಜಿನೆನ್ ಬುಡುಲೆ",
+       "rcfilters-exclude-button-on": "ಪೆಜಿನೆನ್ ಬುಡುದು",
+       "rcfilters-view-tags": "ಕುಚ್ಚಿದ ಸಂಪಾದಿಲು",
+       "rcfilters-view-namespaces-tooltip": "ಪುದರ್'ಜಾಗದ  ಪ್ರಕಾರ  ಫಲಿತಾಂಶೊಲೆನ್  ಅರಿಪುಲೆ",
+       "rcfilters-view-tags-tooltip": "ಸಂಪಾದಿ ಕುಚ್ಚಿಲೆನ್ ಬಳಸ್'ದ್  ಫಲಿತಾಂಶೊಲೆನ್  ಅರಿಪುಲೆ",
+       "rcfilters-view-return-to-default-tooltip": "ಪ್ರಮುಖ ಅರಿಪೆ ಯಾದಿಗ್ ಪಿರಬಲೆ",
+       "rcfilters-view-tags-help-icon-tooltip": "ಕುಚ್ಚಿದ ಸಂಪಾದಿಲೆನ ಮಿತ್ತ್  ನನಾತ್  ಕಲ್ಪುಲೆ",
+       "rcfilters-liveupdates-button": "ಜೀವಂತ ಕಾಲನವಿ'ಲು",
+       "rcfilters-liveupdates-button-title-on": "ಜೀವಂತ ಕಾಲನವಿಲೆನ್ ಉಂತಾಲೆ",
+       "rcfilters-liveupdates-button-title-off": "ಪೊಸ ಬದಲಾವಣೆಲು  ಆವೊಂದಿತ್ತಿನ ಅಪಗನೆ ತೋಜಾಲೆ",
+       "rcfilters-watchlist-markseen-button": "ಮಾತಾ ಬದಲಾವಣೆಲು ತೂತಿನವು ಇಂದ್ ಗುರುತು ಮಲ್ಪುಲೆ",
+       "rcfilters-watchlist-edit-watchlist-button": "ಇರೆನ ತೂತಿನ ಪುಟೊಲೆನ  ಪಟ್ಟಿನ್ ಸಂಪಾದಿಲೆ",
+       "rcfilters-watchlist-showupdated": "ಬದಲಾವಣೆಲು ಆಯಿಬೊಕ ಈರ್ ತೂವಂದಿನ ಪುಟತ ಬದಲಾವಣೆಲು  <strong>ದಪ್ಪ</strong>, ಘನ ಗುರ್ತಿಕೆಡ್ ಉಂಡು.",
+       "rcfilters-preference-label": "ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅತ್ತಾಂದಿನ  ಅಂತರಮುಕ ಬಳಸಿಲೆ.",
+       "rcfilters-preference-help": "ಅರಿಪೆ ನಾಡುನ ಇಜಿಂಡ ಅತಿಪ್ರಕಾಶದ ಕಾರ್ಯಶೀಲತೆ ದಾಂತೆನೆ, ಇಂಚೊದ-ಬದಲಾವಣೆಲು ಏರಾವುಂಡು,",
+       "rcfilters-watchlist-preference-label": "ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅತ್ತಾಂದಿನ  ಅಂತರಮುಕ ಬಳಸಿಲೆ",
+       "rcfilters-watchlist-preference-help": "ಅರಿಪೆ ನಾಡುನ ಇಜಿಂಡ ಅತಿಪ್ರಕಾಶದ ಕಾರ್ಯಶೀಲತೆ ದಾಂತೆನೆ, ತೂಪಿಪಟ್ಟಿನ್  ಏರಾವುಂಡು,",
+       "rcfilters-filter-showlinkedfrom-label": " ಕೊಂಡಿದ ಪುಟೊಲೆನ ಬದಲಾವಣೆ ತೋಜಾಲೆ",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>ಕೊಂಡಿದ ಪುಟ</strong> ಪೆಜಿದಿನ ಪುಟ",
+       "rcfilters-filter-showlinkedto-label": "ಕೊಂಡಿದ ಪುಟೊಲೆಡ್ ಬದಲಾವಣೆಲೆನ್ ತೋಜಾಲೆ",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>ಕೊಂಡಿ ಕೂಡಿನ ಪುಟೊಲು</strong> ಪೆಜಿದಿನ ಪುಟ",
+       "rcfilters-target-page-placeholder": "ಒಂಜಿ ಪುಟತ ಪುದರ್  (ಇಜಿಂಡ ವರ್ಗ) ಸೇರಾಲೆ",
        "rcnotefrom": "<strong>$3, $4</strong> ಡ್ದ್ ಆತಿನ {{PLURAL:$5|ಬದಲಾವಣೆ|ಬದಲಾವಣೆಲು}} ತಿರ್ತ್ ಉಂಡು (ಒಟ್ಟುಗು <strong>$1</strong>  ತೋಜೊಂದುಂಡು).",
+       "rclistfromreset": "ದಿನಾಂಕ ಆಯ್ಕೆನ್ ಪಿರತಾಪಿಸಾಲೆ",
        "rclistfrom": "$2, $3 ಡ್ದ್ ಸುರುವಾತಿನ ಪೊಸ ಬದಲಾವಣೆಲೆನ್ ತೊಜ್ಪಾವು",
        "rcshowhideminor": "$1 ಎಲ್ಯೆಲ್ಯ ಬದಲಾವಣೆಲು",
        "rcshowhideminor-show": "ತೋಜಾಲೆ",
        "rcshowhidemine": "ಎನ್ನ ಸಂಪಾದನೆಲೆನ್ $1",
        "rcshowhidemine-show": "ತೋಜಾಲೆ",
        "rcshowhidemine-hide": "ಅಡೆಂಗಾವು",
+       "rcshowhidecategorization": "$1  ಪುಟ ವರ್ಗೀಕರಣ",
        "rcshowhidecategorization-show": "ತೋಜಾಲೆ",
        "rcshowhidecategorization-hide": "ಅಡೆಂಗಾವು",
        "rclinks": "ಕರಿನ $2 ದಿನೊಲೆಡ್ ಮಲ್ತಿನ ಕಡೆತ್ತ $1 ಬದಲಾವಣೆಲೆನ್ ತೂಲೆ",
        "minoreditletter": "ಕಿ",
        "newpageletter": "ಪೊ",
        "boteditletter": "ಬಾ",
+       "number_of_watching_users_pageview": "[$1 ತೂಪಿನ {{PLURAL:$1|ಬಳಕೆದಾರೆ|ಬಳಕೆದಾರೆರ್}}]",
        "rc-change-size-new": "$1 {{PLURAL:$1|ಬೈಟ್|ಬೈಟ್‍ಲು}}ಬದಲಾವಣೆಡ್ದ್ ಬುಕ್ಕೊ",
        "newsectionsummary": "\n/* $1 */ಪೊಸ ವಿಭಾಗ",
        "rc-enhanced-expand": "ವಿವರೊಲೆನ್ ತೊಜಾವ್",
        "recentchangeslinked-summary": "ಒಂಜಿ ನಿರ್ದಿಸ್ಟೊ ಪುಟೊರ್ದು ಸಂಪರ್ಕೊ ಉಪ್ಪುನ ಪುಟೊಕುಲೆಗ್ (ಅತ್ತಂಡ ನಿರ್ದಿಸ್ಟೊ ವರ್ಗೊಗು ಸೇರ್ದಿನ ಸದಸ್ಯೆರೆಗ್) ಇಂಚಿಪ ಮಲ್ತಿನಂಚಿನ ಬದಲಾವಣೆಲೆನ್ ತಿರ್ತ್ ಪಟ್ಟಿ ಮಲ್ತ್‌ದ್ಂಡ್.\n[[Special:Watchlist|ಇರೆನ ವೀಕ್ಷಣೆ ಪಟ್ಟಿಡ್]] ಉಪ್ಪುನ ಪುಟೊಕುಲು ''ದಪ್ಪ ಅಕ್ಷರೊಡು\" ಉಂಡು.",
        "recentchangeslinked-page": "ಪುಟೊತ ಪುದರ್:",
        "recentchangeslinked-to": "ಇಂದೆತ ಬದಲ್‍ಗ್ ಕೊರ್ತ್‍ನ ಪುಟೊಗು ಕೊಂಡಿ ಉಪ್ಪುನಂಚಿನ ಪುಟೊಲೆದ ಬದಲಾವಣೆಲೆನ್ ತೋಜಾವು",
+       "recentchanges-page-added-to-category": "[[:$1]] ವರ್ಗೊಗು ಸೇರಾದುಂಡು",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] ವರ್ಗೊಗು ಸೇರಾದುಂಡು, [[Special:WhatLinksHere/$1|ಈ ಪುಟೊ ಇತರೆ ಪುಟೊಲೆಡ್ ಸೇರಿಕೆ ಆತ್ಂಡ್]]",
+       "recentchanges-page-removed-from-category": "[[:$1]] ವರ್ಗೊರ್ದು  ದೆತ್'ದ್ಂಡ್.",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] ವರ್ಗೊರ್ದು ದೆತ್ತುದುಂಡು, [[Special:WhatLinksHere/$1|ಈ ಪುಟೊ ಇತರೆ ಪುಟೊಲೆಡ್ ಸೇರಿಕೆ ಆತ್ಂಡ್]]",
+       "autochange-username": "ಮೀಡಿಯಾವಿಕಿ  ಸ್ವಯಂಕೃತ  ಬದಲಾವಣೆ",
        "upload": "ಫೈಲ್’ನ್ ಅಪ್ಲೋಡ್ ಮಲ್ಪುಲೆ",
        "uploadbtn": "ಫೈಲ್’ನ್ ಅಪ್ಲೋಡ್ ಮಲ್ಪುಲೆ",
+       "reuploaddesc": "ಮಿತೇರಾವುನ  ರದ್ದು ಮಲ್ತ್'ದ್  ಬೊಕ  ಮಿತೇರಾವುನ ರೂಪತ್ರೊಗು ಪಿರಪೋಲೆ",
+       "upload-tryagain": "ತಿದ್ದಿಪಾಡಿನ ಕಡತದ ವಿವರೊನು ಸಲ್ಲಿಸಾಲೆ",
+       "upload-tryagain-nostash": "ಪಿರ-ಮಿತೇರಾಯಿನ ಕಡತ ಬೊಕ ತಿದ್ದಿಪಾಡಿನ ವಿವರಣೆ ಸಲ್ಲಿಸಾಲೆ",
        "uploadnologin": "ಲಾಗಿನ್ ಆತ್‘ಜ್ಜರ್",
+       "uploadnologintext": "ಕಡತ ಮಿತೇರಾವರೆ ದಯಮಲ್ತ್  $1.",
+       "upload_directory_missing": "ಮಿತೇರಿಕೆದ ನಿರ್ದೇಶಿಕೆ ($1)  ತಿಕ್ಕುಜಿ, ಬೊಕ  ಜಾಲಸೇವಕೊಗ್ ಅವೆನ್ ರಚಿಸಾವರೆ ಆವೊಂದಿಜ್ಜಿ.",
+       "upload_directory_read_only": "ಮಿತೇರಿಕೆದ ನಿರ್ದೇಶಿಕೆ ($1) ಜಾಲಸೇವಕೊಗು ಬರೆವರೆ ಆಪಿನವತ್ತ್",
+       "uploaderror": "ಮಿತೇರಿಕೆ ದೋಷ",
+       "upload-recreate-warning": "<strong>ಎಚ್ಚರಿಗೆ:  ಆ ಪುರುದ ಒಂಜಿ  ಕಡತ  ಮಾಜಿದ್ಂಡ್  ಇಜ್ಜಾ  ಪಂದಾದ್ಂಡ್</strong>\nಈ ಪುಟತ ಮಾಜಿಕೆ ಬೊಕ ಪಂದಿಕೆದ ಗಮನಿನ್ ಸೌಕರ್ಯಗಾದ್ ಮುಲ್ಪ ಕೊರ್ತುಂಡು:",
+       "uploadtext": " ಕಡತೊಲೆನ್ ಮಿತೇರಾವರೆ ತಿರ್ತ್'ದ ರೂಪತ್ರೊನು ಬಳಸಿಲೆ.\nನೆಟ್ದ್ ದುಂಬು ಮಿತೇರಾಯಿನ ಕಡತೊಲೆನ್ ತೂವರೆ ಇಜಿಂಡ ನಾಡರೆ ಇಡೆಗ್  [[Special:FileList| ಮಿತೇರಾಯಿನ ಕಡತೊಲೆನ ಪಟ್ಟಿ]] ಪೋಲೆ. (ಪಿರ)ಮಿತೇರಿಕೆಲುಲಾ   [[Special:Log/upload|uಮಿತೇರಿಕೆ ಗಮನಿ]] ಡ್ ಉಂಡು, ಮಾಜಿಕೆಲು  [[Special:Log/delete|ಮಾಜಿಕೆ ಗಮನಿ]] ಡು ಉಂಡು.\nಒಂಜಿ ಪುಟೊಟು ಒಂಜಿ ಕಡತೊನು ಸೇರಾರೆ,ಈ ತಿರ್ತ್'ದ ರೂಪತ್ರಲೆಡ್ ಒಂಜಿ ಕೊಂಡಿನ್ ಬಳಸಿಲೆ:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code></strong> ಕಡತದ ಪೂರ್ಣ ಆವೃತ್ತಿನ್ ಬಳಕೆ ಮಲ್ಪರೆ\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|alt text]]</nowiki></code></strong> ದತ್ತ ಕರೆತ ಪೆಟ್ಟಿಡ್ \"alt ಪಟ್ಯ\" ಇನ್ಪಿನ ವಿವರಣೆದೊಟ್ಟುಗು ಒಂಜಿ 200 ಪಿಕ್ಸೆಲ್ ಅಗೆಲದ ಚಿತ್ರಾರ್ಪಣ ಬಳಸರೆ\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> ಕಡತೊನು ತೋಜಾವಂದೆ ಕಡತೊಗು ಸರ್ತವಾದ್ ಗೋಡಿಸಾರೆ",
+       "upload-permitted": "ಅನುಮತಿದ ಕಡತ{{PLURAL:$2|ನಮೂನೆ|ನಮೂನೆಲು}}: $1.",
+       "upload-preferred": "ಇಷ್ಟಾಯ್ಕೆದ ಕಡತ{{PLURAL:$2|ನಮೂನೆ|ನಮೂನೆಲು}}: $1.",
+       "upload-prohibited": "ನಿರ್ಬಂದದ ಕಡತ{{PLURAL:$2|ನಮೂನೆ|ನಮೂನೆಲು}}: $1.",
        "uploadlogpage": "ಅಪ್ಲೋಡ್ ದಾಕಲೆ",
+       "uploadlogpagetext": "ತಿರತ್ ಒಂಜಿ ಅತಿ ಇಂಚೊಗು ಮಿತೇರಾಯಿನ ಕಡತೊಲೆನ ಪಟ್ಟಿ ಉಂಡು.\nಹೆಚ್ಚಿನ ಒಂಜಿ ಸದೃಶ್ಯ ಮೇಲ್ನೋಟೊಗು [[Special:NewFiles| ಪೊಸ ಕಡತೊಲೆನ ಚಿತ್ರದರ್ಶಿನಿ]] ತೂಲೆ.",
        "filename": "ಕಡತದ ಪುದರ್",
        "filedesc": "ಸಾರಾಂಸೊ",
        "fileuploadsummary": "ಸಾರಾಂಸೊ:",
+       "filereuploadsummary": "ಕಡತ ಬದಲಾವಣೆಲು:",
+       "filestatus": "ಕೃತಿಸ್ವಾಮ್ಯದ  ಸ್ಥಿತಿ:",
        "filesource": "ಮೂಲ",
+       "ignorewarning": "ಎಚ್ಚರಿಗೆ ಆಲಕ್ಷಿಸಾದ್ ಬೊಕ ಎಂಚಿತಿನ ಕಡತ ಒರಿಪಾಲೆ",
+       "ignorewarnings": "ಒವ್ವೆ ಎಚ್ಚರಿಗೆಲೆನ್ ಆಲಕ್ಷಿಸಾಲೆ",
+       "minlength1": "ಕಡತಪುದರುಲು  ಕನಿಷ್ಟ  ಒಂಜಿ ಅಕ್ಷರದವು ಆದಿಪ್ಪೊಡು.",
+       "illegalfilename": "ಕಡತಪುದರ್ \"$1\" ಡು ಪುಟತ ತರೆಬರವುಲೆಡ್  ಒಪ್ಪಂದಿನ ಅಕ್ಷರೊಲು ಉಂಡು. ದಯಮಲ್ತ್  ಕಡತೊಗು ಪಿರಪುದರು  ಕೊರ್ದು  ಬೊಕ  ಕುಡ ಮಿತೇರಾವರೆ  ಯತ್ನ ಮಲ್ಪುಲೆ.",
+       "filename-toolong": "ಕಡತಪುದರುಲು 240 ಬೈಟುಲೆರ್ದ್ ಉದ್ದ ಆವರೆ ಬಲ್ಲಿ.",
+       "badfilename": "ಕಡತಪುದರು $1 ಗು ಬದಲಾತ್ಂಡ್.",
+       "filetype-mime-mismatch": "ಕಡತ ವಿಸ್ತರಣ \"$1\" ಪತ್ತೆ ಯಾಯಿನ ಮೈಮ್  (MIME)  ನಮೂನೆದ ಕಡತೊಗು $2 ಪೋಲಿಕೆ ಆಪುಜಿ.",
+       "filetype-badmime": "ಮೈಮ್ (MIME) ನಮೂನೆದ $1 ಕಡತೊಲೆನ್ ಮಿತೇರಾವರೆ ಒಪ್ಪಿಗೆ ಇಜ್ಜಿ.",
+       "filetype-bad-ie-mime": "ಈ ಕಡತೊನು  ಮಿತೇರಾವರೆ  ಆತಿಜಿ, ಕಾರಣ ಇಂಟರ್'ನೆಟ್ ಎಕ್ಸ್'ಪ್ಲೋರರ್ ಅವೆನ್ $1 ಇಂದ್ ಪತ್ತೆ ಮಲ್ಪುಂಡು, ಅವು  ಒಂಜಿ  ಒಪ್ಪಿಗೆದಾಂತಿನ  ಬೊಕ  ಅಪಾಯಕಾರಿ  ಕಡತ ನಮೂನೆ ಆದುಂಡು.",
+       "filetype-unwanted-type": "<strong>\".$1\"</strong> ಉಂದೊಂಜಿ ಬೊಡ್ಚಾಯಿನ ಕಡತ ನಮೂನೆ.\nಇಷ್ಟಾಯ್ಕೆದ {{PLURAL:$3|ಕಡತ ನಮೂನೆ|ಕಡತ ನಮೂನೆಲು}} $2.",
+       "filetype-banned-type": "<strong>\".$1\"</strong> {{PLURAL:$4|ಉಂದೊಂಜಿ ಒಪ್ಪಂದಿನ ಕಡತ ನಮೂನೆ|ಉಂದು ಒಪ್ಪಂದಿನ ಕಡತ ನಮೂನೆಲು}}.\nಅನುಮತಿ ಇತ್ತಿನ {{PLURAL:$3|ಕಡತ ನಮೂನೆ|ಕಡತ ನಮೂನೆಲು}} $2.",
+       "filetype-missing": "ಕಡತೊಗು ವಿಸ್ತರಣ ಇಜ್ಜಿ  (ಉದರ್ಮೆಗ್ \".jpg\").",
+       "empty-file": "ಈರ್ ಸಲ್ಲಿಸಾಯಿನ ಕಡತ ಖಾಲಿ ಆದಿತ್ತ್ಂಡ್.",
+       "file-too-large": "ಈರ್ ಸಲ್ಲಿಸಾಯಿನ ಕಡತ ಬಾರೀ ಮಲ್ಲ ಆದಿತ್ತ್ಂಡ್.",
+       "filename-tooshort": "ಕಡತಪುರು ಮಸ್ತ್ ಕುದ್ಯ ಆಂಡ್.",
+       "filetype-banned": "ಈ ನಮೂನೆದ ಕಡತ ನಿಷಿದ್ದ ಆತ್ಂಡ್.",
+       "verification-error": "ಈ ಕಡತ ಕಡತ ಪರಿಶೀಲನೊಡು ನಪಾಸಾಂಡ್.",
+       "hookaborted": "ಈರ್ ತಿದ್ದುಪಾಟ ಮಲ್ಪರೆ ಯತ್ನ ಮಲ್ತಿವು, ಒಂಜಿ ವಿಸ್ತರಣೊರ್ದು ವಿಫಲವಾಂಡ್.",
+       "illegal-filename": "ಕಡತಪುದರು ಒಪ್ಪಿಗೆ ಇಜ್ಜಿ.",
+       "overwrite": "ಒಂಜಿ ಉಪ್ಪುನ ಕಡತದ ಮಿತ್ತ್'ಬರೆಪಿನೆಕ್  ಒಪ್ಪಿಗೆ ಇಜ್ಜಿ.",
+       "unknown-error": "ಒಂಜಿ ಗೊತ್ತಾಂತಿನ ದೋಷ ಉಂಡಾಂಡ್.",
+       "tmp-create-error": "ಹಂಗಾಮಿ ಕಡತ ರಚಿಸಾವರೆ ಆತಿಜಿ.",
+       "tmp-write-error": "ಹಂಗಾಮಿ ಕಡತ ಬರೆನಗ ದೋಷ.",
+       "large-file": "ಕಡತೊಲು $1 ರ್ದ್ ಉದ್ದ ಆವರೆ ಬಲ್ಲಿಂದ್ ಶಿಫಾರಸು ಮಲ್ದ್ಂಡ್. \nಈ ಕಡತ $2 ಆದುಂಡು.",
+       "largefileserver": "ಈ ಕಡತ ಜಾಲಸೇವಕ ಸಂರಚನೆಡ್ ಒಪ್ಪಿಗೆ ಆಪಿನೆರ್ದ್ ಮಲ್ಲೆ ಉಂಡು.",
+       "emptyfile": "ಈರ್ ಮಿತೇರಾಯಿನ ಕಡತ ಖಾಲಿ ಇಂದ್ ತೋಜುಂಡು.\nಉಂದು ಕಡತಪುರುಡು ಇತ್ತಿನ ಬರೆಪಿದೋಷದ ಕಾರಣ ಆದಿಪ್ಪು.\nಈರ್ ದಯಮಲ್ತ್ ಈ ಕಡತೊನು  ನಿಜವಾದ್ಲಾ  ಮಿತೇರಾವೊಡೆ ಇಂದ್ ಸಮಾತೂಲೆ.",
+       "windows-nonascii-filename": "ಈ ವಿಕಿ ವಿಶೇಷ ಅಕ್ಷರೊಲು ಉಪ್ಪುನ ಕಡತಪುರುಲೆಗ್ ಬೆರಿಬಲ ಕೊರ್ಪುಜಿ.",
+       "fileexists": "ಈ ಪುದರುದ ಒಂಜಿ ಕಡತ ಇದಗನೆ ಉಂಡು, ದಯಮಲ್ತ್ ಸಮಾತೂಲೆ <strong>[[:$1]]</strong> ಒಂಜಿ ವೇಳೆ {{GENDER:|ಈರ್}} ನಿಜವಾದ್ಲಾ ಅವೆನ್ ಬದಲಾವರೆ ದೃಡ ಮಲ್ದರ್ಡ.\n[[$1|thumb]]",
+       "filepageexists": "ಈ ಕಡತದ ವಿವರಣ ಪುಟ ಅದಗನೆ <strong>[[:$1]]</strong> ಡು  ರಚನೆ ಆತ್ಂಡ್ , ಆಂಡ ಈ ಪುದರುದ ಒವ್ವೆ ಕಡತ  ಇತ್ತೆ  ಅಸ್ತಿತ್ವೊಡು ಇಜ್ಜಿ.\nಈರ್ ಸೇರಾಯಿನ ಸಾರಾಂಶ ವಿವರಣ ಪುಟೊಟು ತೋಜಂದ್.\nಇರೆನ ಸಾರಾಂಶ ಮುಲ್ಪ ತೋಜರೆ ಈರ್ ಅವೆನ್ ಅಂಗಿಕವಾದ್ ಸಂಪಾದಿಸೊಡು.\n[[$1|thumb]]",
+       "fileexists-extension": "ಒಂಜಿ ಸಮಾನ ಪುದರುದ ಕಡತ ಉಂಡು:[[$2|thumb]]\n* ಮಿತೇರಾವುನ ಕಡತದ ಪುದರು: <strong>[[:$1]]</strong>\n* ಉಪ್ಪುನ ಕಡತದ ಪುದರು: <strong>[[:$2]]</strong>\nಈರ್ ಬಹುಶಃ ಒಂಜಿ ಹೆಚ್ಚ ಸ್ಪುಟವಾಯಿನ ಪುದರುನು ಬಳಸರೆ ಬಯಸುವರಾ?",
+       "fileexists-thumbnail-yes": "ಕಡತ ಒಂಜಿ ಕುಗ್ಗಾಯಿನ ಗಾತ್ರದ ಆಕೃತಿದ ಲೆಕ್ಕ ತೋಜುಂಡು  <em>(thumbnail)</em>.\n[[$1|thumb]]\nದಯಮಲ್ತ್ ಕಡತೊನು ಸಮಾತೂಲೆ <strong>[[:$1]]</strong>.\nಸಮಾತೂಯಿನ ಕಡತ ಮೂಲಗಾತ್ರದ ಅವೇ ಆಕೃತಿ ಆಂಡ, ನನ ಒಂಜಿ  (ಕೊಂಬಿರೆಲ್ ಚಿತ್ರ)  ಕಿರ್ಚಿತ್ರ ಮಿತೇರಾವುನ ಅಗತ್ಯ ಇಜ್ಜಿ.",
+       "file-thumbnail-no": "ಕಡತದ ಪುದ <strong>$1</strong>.ರು  ಸುರುವಾಪುಂಡು\nಕಡತ ಒಂಜಿ ಕುಗ್ಗಾಯಿನ ಗಾತ್ರದ ಆಕೃತಿದ ಲೆಕ್ಕ ತೋಜುಂಡು  <em>(thumbnail)</em>.\nಇರೆಡ ಈ ಆಕೃತಿದ ಪೂರ್ಣ ಸಂಕಲ್ಪದ ಪ್ರತಿ ಇತ್ತಿನಾಂಡ ಅವೆನ್ ಮಿತೇರಾಲೆ, ಇಜ್ಜಾಂಡ ದಯಮಲ್ತ್ ಕಡತಪುದರು ಬದಲಾಲೆ.",
+       "fileexists-forbidden": "ಈ ಪುದರುದ ಒಂಜಿ ಕಡತ ಅದಗನೆ ಉಂಡು, ಬೊಕ ಅಯಿತ ಮೇಲ್'ಬರೆವರೆ ಆಪುಜಿ.\nಈರ್ ನನಲಾ ಇರೆನ ಕಡತೊನು ಮಿತೇರಾವರೆ ಬಯಕುವರ್ಡ, ದಯಮಲ್ತ್ ಪಿರ ಪೋಲೆ ಬೊಕ ಒಂಜಿ ಪೊಸ ಪುದರು ಬಳಸಿಲೆ.\n[[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "ಈ ಪುದರುದ ಒಂಜಿ ಕಡತ ಅದಗನೆ ಉಂಡು, ಪಟೊಂದಿನ ಕಡತ ಸಂಚಯನೊಡು.\nಈರ್ ನನಲಾ ಇರೆನ ಕಡತೊನು ಮಿತೇರಾವರೆ ಬಯಕುವರ್ಡ, ದಯಮಲ್ತ್ ಪಿರ ಪೋಲೆ ಬೊಕ ಒಂಜಿ ಪೊಸ ಪುದರು ಬಳಸಿಲೆ.\n[[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "ಮಿತೇರಿಕೆ ಆಯಿನವು <strong>[[:$1]]</strong> ಇತ್ತೆದ ಆವೃತ್ತಿದ ಒಂಜಿ ಯಥಾರ್ಥ ಇರ್ಪಡಿ ಆದುಂಡು.",
+       "fileexists-duplicate-version": "ಮಿತೇರಿಕೆ ಆಯಿನವು <strong>[[:$1]]</strong> {{PLURAL:$2|ಒಂಜಿ ಪರ ಆವೃತ್ತಿ|ಪರ ಆವೃತ್ತಿಲೆನ}}  ಒಂಜಿ ಯಥಾರ್ಥ ಇರ್ಪಡಿ ಆದುಂಡು.",
+       "file-exists-duplicate": "ಈ ಕಡತ  ಬೆರಿಟೆಬರ್ಪಿನ {{PLURAL:$1|ಕಡತ|ಕಡತೊಲು}} ದ ಒಂಜಿ ಇರ್ಪಡಿ ಆದುಂಡು:",
+       "file-deleted-duplicate": " ಈ ಕಡತದ ಒಂಜಿ ಸರ್ವಸಮ ಕಡತೊನು ([[:$1]]) ನೆಡ್ದ್ ದುಂಬು ಮಾಜಾದುಂಡು.\nಪಿರ ಮಿತೇರಾವರೆ ಪೋಪಿನೆರ್ದ್ ಸುರುಟು ಈರ್, ಆ ಕಡತದ ಮಾಜಿಕೆ ಚರಿತ್ರೆನ್ ಸಮಾತೂವೊಡು.",
+       "file-deleted-duplicate-notitle": "ಈ ಕಡತದ ಒಂಜಿ ಸರ್ವಸಮ ಕಡತೊನು  ನೆಡ್ದ್ ದುಂಬು ಮಾಜಾದುಂಡು ಬೊಕ ತರೆಬರವುನು ದಮನಿಸಾದುಂಡು.\nಕಡತೊನು ಪಿರ-ಮಿತೇರಾವರೆ ಪೋಪಿನೆರ್ದ್ ಸುರುಟು ಈರ್, ಸನ್ನಿವೇಶೊನು ಪರಿಶೀಲಿಸಾವರೆ,ದಮನಿತ ಕಡತ ದತ್ತಾಂಶ ತೂವರೆ ಶಕ್ತವಾಯಿನ ಏರೆನಾಂಡಲಾ ಈರ್ ಕೇಣೊಡು",
+       "uploadwarning": "ಮಿತೇರಿಕೆ ಎಚ್ಚರಿಗೆ",
+       "uploadwarning-text": "ದಯಮಲ್ತ್  ತಿರ್ತ್'ದ  ಕಡತ ವಿವರಣೆನ್  ತಿದ್ದುಪಾಟ  ಮಲ್ತ್'ದ್ ಬೊಕ ಕುಡಾ ಯತ್ನ ಮಲ್ಪುಲೆ.",
+       "uploadwarning-text-nostash": "ದಯಮಲ್ತ್  ಕಡತೊನು ಪಿರ ಮಿತೇರಾಲೆ, ತಿರ್ತ್'ದ  ಕಡತ ವಿವರಣೆನ್  ತಿದ್ದುಪಾಟ  ಮಲ್ತ್'ದ್  ಬೊಕ ಕುಡಾ ಯತ್ನ ಮಲ್ಪುಲೆ.",
        "savefile": "ಕಡತನ್ ಒರಿಪಾಲೆ",
+       "uploaddisabled": "ಮಿತೇರಿಕೆಲೆನ್ ನಿಷ್ಕ್ರಿಯ ಮಲ್ದ್ಂಡ್.",
+       "copyuploaddisabled": "ಯುಆರ್'ಎಲ್ ಮಿತೇರಿಕೆ ನಿಷ್ಕ್ರಿಯ ಮಲ್ದ್ಂಡ್.",
+       "uploaddisabledtext": "ಕಡತ ಮಿತೇರಿಕೆಲೆನ್  ನಿಷ್ಕ್ರಿಯ ಮಲ್ದ್ಂಡ್",
+       "php-uploaddisabledtext": "ಪಿಎಚ್'ಪಿ. ಡ್  ಕಡತ  ಮಿತೇರಿಕೆಲೆನ್  ನಿಷ್ಕ್ರಿಯ  ಮಲ್ದ್ಂಡ್.\nದಯಮಲ್ತ್  ಕಡತ_ಮಿತೇರಿಕೆ  ಅಟ್ಟಣೆಲೆನ್  ಸಮಾತೂಲೆ.",
+       "uploadscripted": "ಕಡತೊಡು ಎಚ್'ಟಿಎಂಎಲ್ ಇಜಿಂಡ ಸ್ಕ್ರಿಪ್ಟ್ ಅಂಕೇತ ಉಂಡು, ಅವೆನ್ ಜಾಲದರ್ಶಿಲು ದೋಷಪೂರ್ಣವಾದ್ ವ್ಯಾಖ್ಯಾನ ಮಲ್ಪರೆ ಯಾವು.",
+       "upload-scripted-pi-callback": "ಎಕ್ಸ್'ಎಂಎಲ್ - ಶೈಲಿಪತ್ರ  ಪ್ರಕ್ರಿಯೆಕಾರಕ ಸೂಚನೆ ಉಪ್ಪುನ ಕಡತೊನು ಮಿತೇರಿಸಾವರೆ ಆಪುಜಿ.",
+       "upload-scripted-dtd": "ಅ-ಮಾನಕ ಡಿಟಿಡಿ ಘೋಷಣೆ ಉಪ್ಪುನ ಎಸ್ವಿಜಿ ಕಡತೊಲೆನ್ ಮಿತೇರಾವರೆ ಆಪುಜಿ.",
+       "uploaded-script-svg": "ಮಿತೇರಾಯಿನ ಎಸ್ವಿಜಿ ಕಡತೊಡು $1 ಲಿಪಿಕಾರಕ ಘಟಕ ಪತ್ತೆ ಆಂಡ್.",
+       "uploaded-hostile-svg": "ಮಿತೇರಾಯಿನ ಎಸ್ವಿಜಿ ಕಡತದ  ಶೈಲಿ ಘಟಕೊಡು  ಅಸುರಕ್ಷಿತ ಸಿಎಸ್ಎಸ್ ಪತ್ತೆ ಆಂಡ್.",
+       "uploaded-event-handler-on-svg": "ಎಸ್ವಿಜಿ ಕಡತೊಲೆಡ್ ಘಟನೆ-ನಿರ್ವಹಣ ಗುಣೊ <code>$1=\"$2\"</code>  ಅಟ್ಟಣೆಗ್ ಒಪ್ಪಿಗೆ ಇಜ್ಜಿ.",
+       "uploaded-href-attribute-svg": "<a> ಫಟಕೊಲು ದತ್ತಾಂಶೊಗು ಮಾತ್ರಾ ಕೊಂಡಿ (href) ಆಪಾ: (ಅಂತರ್ಗತ ಕಡತ), http:// or https://, ಇಜಿಂಡ ತುಂಡು  (#, ಅವೇ-ದಾಖಲೆ) ಗುರಿಲು.  ಇತರೆ ಘಟಕೊಲೆಗ್,ಉದರ್ಮೆಗ್ <image>, ದತ್ತಾಂಶ ಮಾತ್ರಾ: ಬೊಕ ತುಂಡುಲು ಒಪ್ಪುಂಡು.  ಎಸ್ವಿಜಿ-ನ್ ರಪ್ತು ಮಲ್ಪುನಗ ಆಕೃತಿಲೆನ್ ಅಂತರ್ಗತಿಸಾರೆ ಯತ್ನಿಸಾಲೆ.   ಪತ್ತೆ ಆಂಡ್ <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "ಅಸುರಕ್ಷಿತ ದತ್ತಾಂಶ href ಪತ್ತೆ ಆಂಡ್: ಮಿತೇರಾಯಿನ ಎಸ್ವಿಜಿ ಕಡತೊಡು ಯೂಆರ್'ಐ URI ಗುರಿ <code>&lt;$1 $2=\"$3\"&gt;</code> .",
+       "uploaded-animate-svg": "ಮಿತೇರಾಯಿನ ಎಸ್ವಿಜಿ ಕಡತೊಡು \"ಇಂದ\" ಗುಣ ಬಳಕೆ ಆಯಿನ <code>&lt;$1 $2=\"$3\"&gt;</code>, href ನು ಬದಲ್'ಮಲ್ಪುನ \"ಜೀವಂತಿಸಾಲೆ\" ಕುಚ್ಚಿ ಪತ್ತೆ ಆಂಡ್.",
+       "uploaded-setting-event-handler-svg": "ಘಟನೆ-ನಿರ್ವಹಣ ಗುಣೊಲೆನ ಅಟ್ಟಣೆ ತಡೆಯಾತುಂಡು. ಮಿತೇರಾಯಿನ  ಎಸ್ವಿಜಿ  ಕಡತೊಡು <code>&lt;$1 $2=\"$3\"&gt;</code>  ಪತ್ತೆಯಾಂಡ್.",
+       "uploaded-setting-href-svg": "ಪಿತೃ ಘಟಕೊಗು \"href\" ಸೇರಾರೆ, \"ಅಟ್ಟಣೆ\" ಕುಚ್ಚಿ ಬಳಕೆನ್ ತಡೆತ್'ದುಂಡು,",
+       "uploaded-wrong-setting-svg": "ಒವ್ವೆ ಗುಣೊಕು ಒಂಜಿ ದೂರಸಂವೇದಿ/ದತ್ತಾಂಶ/ಲಿಪಿಕಾರ ಗುರಿ ಸೇರಾರೆ, \"ಅಟ್ಟಣೆ\" ಕುಚ್ಚಿದ ಬಳಕೆನ್ ತಡೆತ್'ದುಂಡು,  ಮಿತೇರಾಯಿನ ಎಸ್ವಿಜಿ ಕಡತೊಡು  <code>&lt;set to=\"$1\"&gt;</code> ಪತ್ತೆ ಆಂಡ್.",
+       "uploaded-setting-handler-svg": "ದೂರಸಂವೇದಿ/ದತ್ತಾಂಶ/ಲಿಪಿಕರ ಒಟ್ಟುಗು ನಿಯಂತ್ರಕ ಗುಣೊನು ಪತ್ತುನ ಎಸ್ವಿಜಿ-ನ್ ತಡೆತ್'ದುಂಡು.\nಮಿತೇರಾಯಿನ  ಎಸ್ವಿಜಿ  ಕಡತೊಡು <code>$1=\"$2\"</code> ಪತ್ತೆ ಯಾಂಡ್ .",
+       "uploaded-remote-url-svg": "ದೂರಸಂವೇದಿ ಯೂಅರ್'ಎಲ್'ದ  ಒಟ್ಟುಗು ಒವ್ವೆ ಶೈಲಿದ ಗುಣೊನು ಪತ್ತುನ ಎಸ್ವಿಜಿ-ನ್ ತಡೆತ್'ದುಂಡು.\nಮಿತೇರಾಯಿನ  ಎಸ್ವಿಜಿ  ಕಡತೊಡು <code>$1=\"$2\"</code> ಪತ್ತೆ ಯಾಂಡ್.",
+       "uploaded-image-filter-svg": "ಮಿತೇರಾಯಿನ ಎಸ್ವಿಜಿ ಕಡತೊಡು <code>&lt;$1 $2=\"$3\"&gt;</code> ಯೂಆರ್'ಎಲ್'ದ  ಆಕೃತಿ  ಅರಿಪೆ ಪತ್ತೆ ಆಂಡ್.",
+       "uploadscriptednamespace": "ಈ ಎಸ್ವಿಜಿ ಕಡತೊಡು <nowiki>$1</nowiki> ಇನ್ಪಿನ ಒಂಜಿ ಕಾನೂನುಬಾಹಿರ ಪುದರತಾನ ಉಂಡು.",
+       "uploadinvalidxml": "ಮಿತೇರಾಯಿನ ಕಡತೊಡು ಇತ್ತಿನ  ಎಕ್ಸ್'ಎಂಎಲ್- ನ್ ವಿಂಗಡರೆ ಆಪುಜಿ.",
+       "uploadvirus": "ಕಡತೊಡು ಒಂಜಿ ವೈರಾಣು ಉಂಡು!\nವಿವರೊಲು:$1",
+       "uploadjava": "ಕಡತ  ಒಂಜಿ  ಜಾವಾ.class ಕಡತ ಉಪ್ಪುನ ಜಿಪ್ (ZIP) ಕಡತ ಆದುಂಡು.\nಜಾವಾ ಕಡತೊಲೆನ್ ಮಿತೇರಾವರೆ ಒಪ್ಪಿಗೆ ಇಜ್ಜಿ ಕಾರಣ ಅವು ರಕ್ಷಕ ನಿರ್ಬಂದೊಲೆನ್ ಅತಿಕ್ರಮ ಮಲ್ಪಾವರೆ ಯಾವು.",
        "upload-source": "ಮೂಲ ಕಡತ",
+       "sourcefilename": "ಮೂಲ ಕಡತಪುದರ್:",
+       "sourceurl": "ಮೂಲ ಯೂಆರ್'ಎಲ್:",
+       "destfilename": "ಗಮ್ಯತಾನ ಕಡತಪುದರ್:",
+       "upload-maxfilesize": "ಗರಿಷ್ಟ ಕಡತ ಗಾತ್ರ:$1",
+       "upload-description": "ಕಡತ ವಿವರಣೆ",
        "upload-options": "ಅಪ್ಲೋಡ್ ಆಯ್ಕೆಲು",
        "watchthisupload": "ಈ ಪುಟೊನು ತೂಲೆ",
+       "filewasdeleted": "ಈ ಪುದರುದ ಒಂಜಿ ಕಡತ ನೆತ ದುಂಬೆ ಮಿತೇರಾದ್ ಅಯಿಡ್ದ್  ಬೊಕ ಮಾಜಾದುಂಡು.\nಈರ್ ಅವೆನ್ ಕುಡೊರ ಮಿತೇರಾವರೆ ಪೋಪಿನ ದುಂಬು $1 ನ್ ಸಮಾತೂವೊಡು.",
+       "filename-thumb-name": "ಉಂದು ಕೊಂಬಿರೆಲ್'ಚಿತ್ರದ ತರೆಬರವುದ ಲೆಕ್ಕ ತೋಜುಂಡು. ದಯಮಲ್ತ್  ಅವೆ ವಿಕಿಕ್ ಕೊಂಬಿರೆಲ್'ಚಿತ್ರೊಲೆನ್ ಪಿರ ಮಿತೇರಾವೊರ್ಚಿ. ಇಜಿಂಡ ದಯಮಲ್ತ್ ಕಡತಪುದರುನು,  ಅವು ಹೆಚ್ಚ ಅರ್ಥಪೂರ್ಣವಾದಿತ್ತ್'ದ್,   ಕೊಂಬಿರೆಲ್'ಚಿತ್ರದ  ಆದಿಪ್ರತ್ಯಯ ಉಪ್ಪಂದಿಲೆಕ್ಕ ಸರಿಮಲ್ಪುಲೆ.",
+       "filename-bad-prefix": "ಈರ್ ಮಿತೇರಾವುನ ಕಡತದ ಪುದರ್ <strong>\"$1\"</strong>,  ಸುರುವಾಪುಂಡು; ಅವು ಒಂಜಿ ವಿವರಣಹೀನ ಪುದರ್  ಲಕ್ಷಣೊಡು  ಸ್ವಯಂಕೃತವಾದ್ ಅಂಕಿಕ ಕ್ಯಾಮರೊಲು ಕೊರ್ಪಿನವು ಆದುಂಡು.\nದಯಮಲ್ತ್ ಇರೆನ ಕಡತೊಗು  ಒಂಜಿ ಹೆಚ್ಚಿನ ವಿವರಣೆದ ಪುದರುನು ಪೆಜಿಲೆ.",
+       "upload-proto-error": "ಅಸಮಪರ್ಕ ಶಿಷ್ಟಾಚಾರ",
+       "upload-proto-error-text": "ದೂರಸಂವೇದಿ ಮಿತೇರಿಕೆಗ್    <code>http://</code> or <code>ftp://</code>  ಸುರುವಾಪಿನ  ಯೂಆರ್'ಎಲ್'-ಲು ಬೋಡು.",
        "upload-file-error": "ಆ೦ತರಿಕ ದೋಷ",
+       "upload-file-error-text": "ಜಾಲಸೇವಕೊಡು ಒಂಜಿ ಹಂಗಾಮಿ ಕಡತೊನು ರಚಿಸಾವರೆ ಯತ್ನ ಮಲ್ಪುನಗ  ಒಂಜಿ ಆಂತರಿಕ ದೋಷ ಆಂಡ್ .\nದಯಮಲ್ತ್ ಒರಿ  [[Special:ListUsers/sysop|administrator]]. ನ್ ಸಂಪರ್ಕಿಸಾಲೆ",
+       "upload-misc-error": "ಗೊತ್ತಾಂತಿನ ಮಿತೇರಿಕೆ ದೋಷ",
+       "upload-misc-error-text": "ಮಿತೇರಿಕೆಡ್  ಒಂಜಿ  ಗೊತ್ತಾಂತಿನ ದೋಷ  ಆಂಡ್.\nದಯಮಲ್ತ್  ಯೂಆರ್'ಎಲ್ ಮಾನ್ಯವಾದುಂಡು ಬೊಕ ಗಮ್ಯವಾದುಂಡು ಇಂದ್ ಪರಿಶೀಲಿಸಾದ್ ಬೊಕ ಕುಡಾ ಯತ್ನ ಮಲ್ಪುಲೆ.\nಸಮಸ್ಯೆ ಒರೀಂಡ, ಒರಿ  [[Special:ListUsers/sysop|administrator]]ನು  ಸಂಪರ್ಕಿಸಾಲೆ.",
+       "upload-too-many-redirects": "ಯೂಆರ್'ಎಲ್- ಡು  ದಿಂಜ ಪಿರರವಾನೆಲು ಉಂಡು.",
+       "upload-http-error": "ಒಂಜಿ HTTP ದೋಷ ಆಂಡ್: $1",
+       "upload-copy-upload-invalid-domain": "ಈ ಪರಿವಲಯೊಡು ನಕಲು ಮಿತೇರಿಕೆಲು ಲಭ್ಯ ಇಜ್ಜಿ.",
+       "upload-foreign-cant-upload": "ಕೇಣಿನ ವಿದೇಶಿ ಕಡತ ಸಂಚಯೊಗು ಕಡತೊಲೆನ್ ಮಿತೇರಾವರೆ ಈ ವಿಕಿ ಸಂರಚನೆ ಆತಿಜಿ.",
+       "upload-foreign-cant-load-config": "ವಿದೇಶಿ ಕಡತ ಸಂಚಯೊಗು ಕಡತೊಲೆನ ಮಿತೇರಿಕೆಗ್  ಸಂರಚನೆ ದಿಂಜಾವುನ  ವಿಫಲವಾಂಡ್.",
+       "upload-dialog-disabled": "ಈ ಸಂವಾದಿನ್  ಬಳಸಿನ  ಕಡತ ಮಿತೇರಿಕೆಲೆನ್  ಈ ವಿಕಿಟ್ ನಿಷ್ಕ್ರಿಯ ಮಲ್ದ್ಂಡ್.",
        "upload-dialog-title": "ಫೈಲ್ ಅಪ್ಲೋಡ್",
        "upload-dialog-button-cancel": "ವಜಾ ಮಲ್ಪುಲೆ",
        "upload-dialog-button-back": "ಪಿರ",
        "upload-dialog-button-upload": "ಅಪ್ಲೊಡ್",
        "upload-form-label-infoform-title": "ವಿವರೊ",
        "upload-form-label-infoform-name": "ಪುದರ್",
+       "upload-form-label-infoform-name-tooltip": "ಕಡತೊಗು ಒಂಜಿ ಅನನ್ಯ ವಿವರಣೆದ ತೆರಬರವು, ಅವು ಕಡತಪುದರಾದ್ ಒದಗೋಡು. ಈರ್ ಸರಳ ಭಾಷೆನ್ ಅವಕಾಶ ಸಹಿತವಾದ್  ಬಳಸೊಲಿ. ಕಡತ ವಿಸ್ತರಣ ಸೇರಾವೊರ್ಚಿ.",
        "upload-form-label-infoform-description": "ವಿವರಣೆ",
+       "upload-form-label-infoform-description-tooltip": "ಕಾಯಕದ ಮಾತಾ ಗಮನಾರ್ಹ ವಿಷಯೊಲೆನ್ ಸಂಕ್ಷಿಪ್ತವಾದ್ ವಿವರಿಸಾಲೆ.\nಒಂಜಿ ಚಿತ್ರದ ಮಿತ್ತ್ : ಚಿತ್ರ ತೋಜಾವುನ ಮುಖ್ಯವಿಷಯೊಲು, ಸಂದರ್ಭ ಇಜಿಂಡ ಜಾಗ ತೆರಿಪಾಲೆ",
+       "upload-form-label-usage-title": "ಬಳಕೆ",
        "upload-form-label-usage-filename": "ಕಡತದ ಪುದರ್",
+       "upload-form-label-own-work": "ಉಂದು ಎನ್ನ ಸ್ವಂತದ ಕೆಲಸ",
        "upload-form-label-infoform-categories": "ವರ್ಗೊಲು",
        "upload-form-label-infoform-date": "ದಿನೊ",
+       "upload-form-label-own-work-message-generic-local": "ಯಾನ್ ಈ ಕಡತೊನು {{SITENAME}} ಸೇವೆದ  ಷರತ್ತುಲು ಬೊಕ ಪರವಾನಿ  ಕಾರ್ಯನೀತಿದ ಅನುಸಾರ ಮಿತೇರಾವೊಂದುಲ್ಲೆ  ಇಂದ್  ದೃಡ ಮಲ್ಪುವೆ",
        "license": "ಪರವಾನಗಿ:",
        "license-header": "ಪರವಾನಿಗೆ",
+       "nolicense": "ವೊವ್ವುಲ ಅತುಜಿ",
        "listfiles-delete": "ಮಾಜಾಲೆ",
        "imgfile": "ಫೈಲ್",
        "listfiles": "ಕಡತೊಲೆನ ಪಟ್ಟಿ",
        "filepage-nofile": "ಈ ಪುದರ್‌ಡ್ ಒವ್ಲಾ ಕಡತ ಇಜ್ಜಿ.",
        "shared-repo-from": "$1 ನೆತ್ತ್",
        "upload-disallowed-here": "ಈರ್ ಈ ಫೈಲ್‍ನ್ ಕುಡೊರೊ ಬರೆಯೆರೆ ಸಾದ್ಯೊ ಇಜ್ಜಿ.",
+       "filerevert": "ಪಿರಕೊನರುನಾ $1",
        "filerevert-comment": "ಕಾರಣ:",
        "filerevert-submit": "ದುಂಬುದ ಲೆಕ ಮಲ್ಪುಲೆ",
        "filedelete": "$1 ನ್ ಮಾಜಾಲೆ",
        "filedelete-comment": "ಕಾರಣ",
        "filedelete-submit": "ಮಾಜಾಲೆ",
        "filedelete-reason-otherlist": "ಬೇತೆ ಕಾರಣ",
+       "filedelete-edit-reasonlist": "ಮಾಜಾಯಿನ ಕಾರಣೊಲೆನ್ ಸಂಪಾದನೆ ಮಲ್ಪುಲೆ",
        "mimesearch": "MIME ನಾಡುನಿ",
+       "mimetype": "MIME type:",
        "download": "ಡೌನ್‍ಲೋಡ್",
+       "unwatchedpages": "ತೂವಂತಿನ ಪುಟೊಲು",
        "listredirects": "ರೀಡೈರೆಕ್ಟ್ ಪಟ್ಟಿ",
        "listduplicatedfiles": "ಡುಪ್ಲಿಕೇಟ್ ಕಡತೊಲೆನ ಪಟ್ಟಿ",
        "unusedtemplates": "ಗಲಸಂದಿನ ಟೆಂಪ್ಲೇಟ್ಲು",
        "randomredirect": "ಗೊತ್ತುದಾಂತಿ ರೀಡೈರೆಕ್ಟ್",
        "statistics": "ಅಂಕಿ ಅಂಶೊಲು",
        "statistics-header-pages": "ಪುಟೊತ ಅಂಕಿ ಅಂಶಲು",
+       "statistics-articles": "ವಿಸಯ ಪುಟೊಕುಲು",
        "statistics-pages": "ಪುಟಕುಲು",
+       "statistics-files": "ಅಪ್ಲೋಡ್ ಆತಿಪ್ಪುನ ಫೈಲುಲು",
        "statistics-users-active": "ಸಕ್ರಿಯ ಬಳಕೆದಾರೆರ್",
        "pageswithprop-submit": "ಪೋಲೆ",
        "doubleredirects": "ರಡ್ಡ್ ರಿಡೈರೆಕ್ಟ್‌ಲು",
index f588e25..5709713 100644 (file)
        "returnto": "తిరిగి $1కి.",
        "tagline": "{{SITENAME}} నుండి",
        "help": "సహాయం",
+       "help-mediawiki": "మీడియావికీ సహాయం",
        "search": "వెతుకు",
        "search-ignored-headings": " #<!-- ఈ లైనును ఉన్నది ఉన్నట్లుగా వదిలేయండి --> <pre>\n# వెతుకులాటలో పరిగణింపబడని శీర్షికలు.\n# శీర్షికతో సహా పేజీ ఇండెక్స్ కాగానే మార్పులు వర్తిస్తాయి.\n# ఉత్తుత్తి సవరణ చేయడం ద్వారా బలవంతంగా రీయిండెక్సింగ్ చేయించవచ్చు.\n# వ్యాకరణం ఇలా ఉంటుంది:\n#   * \"#\" కారెక్టరు నుండి లైను చివరి వరకూ ఉన్నదంతా వ్యాఖ్య అవుతుంది\n#   * ఖాళీగా లేని ప్రతీ లైను వెతుకులాటలో పట్టించుకోనక్కర్లేని శీర్షికగా పరిగణింపబడుతుంది.\nమూలాలు\nబయటి లింకులు\nఇవి కూడా చూడండి\n #</pre> <!-- ఈ లైనును ఉన్నది ఉన్నట్లుగా వదిలేయండి -->",
        "searchbutton": "వెతుకు",
        "databaseerror-query": "క్వెరీ: $1",
        "databaseerror-function": "ఫంక్షన్: $1",
        "databaseerror-error": "లోపం: $1",
+       "transaction-duration-limit-exceeded": "రైట్ సమయం ($1) దాని పరిమితి అయిన $2 ను మించిపోయింది. అక్కువ రెప్లికేషన్ లాగ్ సృష్టించకుండా నివారించేందుకు గాను, ఈ ట్రాన్సాక్షనును ఆపేసాం.\nమీరు అనేక అంశాలను ఏకకాలంలో మారుస్తున్నట్లైతే, చిన్న చిన్న ఆపరేషన్లుగా విభజించి ప్రయత్నించండి.",
        "laggedslavemode": "<strong>హెచ్చరిక:</strong> పేజీలో ఇటీవల జరిగిన మార్పులు ఉండకపోవచ్చు.",
        "readonly": "డేటాబేసు లాక్‌చెయ్యబడింది",
        "enterlockreason": "డేటాబేసుకు వేయబోతున్న లాకుకు కారణం తెలుపండి, దానితోపాటే ఎంతసమయం తరువాత ఆ లాకు తీసేస్తారో కూడా తెలుపండి",
        "missingarticle-rev": "(కూర్పు#: $1)",
        "missingarticle-diff": "(తేడా: $1, $2)",
        "readonly_lag": "అనుచర (స్లేవ్) డేటాబేసు సర్వర్లు, ప్రధాన (మాస్టరు) సర్వరును అందుకునేందుకుగాను, డేటాబేసు ఆటోమాటిక్‌గా లాకు అయింది.",
+       "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' అనే HTTP హెడరును పంపించారు, కానీ దాన్ని API రైట్ మాడ్యూలుకు పంపించారు.",
        "internalerror": "అంతర్గత లోపం",
        "internalerror_info": "అంతర్గత లోపం: $1",
        "internalerror-fatal-exception": "\"$1\" రకం వినాశకర ఎక్సెప్షను",
        "badarticleerror": "ఈ పేజీపై ఈ పని చేయడం కుదరదు.",
        "cannotdelete": "\"$1\" అనే పేజీ లేదా ఫైలుని తొలగించలేకపోయాం.\nదాన్ని ఇప్పటికే ఎవరైనా తొలగించి ఉండవచ్చు.",
        "cannotdelete-title": "పేజీ \"$1\" ని తొలగించలేరు",
+       "delete-scheduled": "\"$1\" పేజీ తొలగింపు షెడ్యూలులో ఉంది.\nకాస్త ఓర్పుతో ఉండండి.",
        "delete-hook-aborted": "తొలగింపును హుక్ ఆపేసింది.\nవివరణ ఏమీ ఇవ్వలేదు.",
        "no-null-revision": "\"$1\" పేజీకి కొత్త శూన్య కూర్పు (నల్ రివిజన్) ను సృష్టించలేకపోయాం",
        "badtitle": "తప్పు శీర్షిక",
        "cascadeprotected": "కింది {{PLURAL:$1|పేజీని|పేజీలను}} కాస్కేడింగు ఆప్షనుతో సంరక్షించబడింది. ప్రస్తుత పేజీ, ఈ పేజీల్లో ట్రాన్స్‌క్లూడు అయి ఉంది కాబట్టి, దిద్దుబాటు చేసే వీలు లేకుండా ఇది కూడా రక్షణలో ఉంది:\n$2",
        "namespaceprotected": "'''$1''' నేంస్పేసులో మార్పులు చేయటానికి మీకు అనుమతి లేదు.",
        "customcssprotected": "ఈ CSS పేజీని మార్చేందుకు మీకు అనుమతి లేదు. ఎందుకంటే వేరే వాడుకరి యొక్క వ్యక్తిగత సెట్టింగులు అందులో ఉన్నాయి.",
+       "customjsonprotected": "ఈ JSON పేజీలో వేరే వాడుకరి వ్యక్తిగత సెట్టింగులున్నాయి కాబట్టి, అందులో దిద్దుబాటు చేసే అనుమతులు మీకు లేవు.",
        "customjsprotected": "ఈ JavaScript పేజీని మార్చేందుకు మీకు అనుమతి లేదు. ఎందుకంటే వేరే వాడుకరి యొక్క వ్యక్తిగత సెట్టింగులు అందులో ఉన్నాయి.",
-       "sitecssprotected": "à°\88 CSS à°²à±\8b à°®à±\80à°°à±\81 à°\9aà±\87à°¸à±\87 à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\8aà°¤à±\8dà°¤à°\82 à°¸à°\82దరà±\8dà°¶à°\95à±\81à°²à°\82దరినà±\80 à°ªà±\8dరభావితà°\82 à°\9aà±\87à°¸à±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది à°\95ాబà°\9fà±\8dà°\9fà°¿ ఆ అనుమతి మీకు లేదు.",
-       "sitejsonprotected": "à°\88 JSON à°²à±\8b à°®à±\80à°°à±\81 à°\9aà±\87à°¸à±\87 à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\8aà°¤à±\8dà°¤à°\82 à°¸à°\82దరà±\8dà°¶à°\95à±\81à°²à°\82దరినà±\80 à°ªà±\8dరభావితà°\82 à°\9aà±\87à°¸à±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది à°\95ాబà°\9fà±\8dà°\9fà°¿ ఆ అనుమతి మీకు లేదు.",
-       "sitejsprotected": "à°\88 JavaScript à°²à±\8b à°®à±\80à°°à±\81 à°\9aà±\87à°¸à±\87 à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\8aà°¤à±\8dà°¤à°\82 à°¸à°\82దరà±\8dà°¶à°\95à±\81à°²à°\82దరినà±\80 à°ªà±\8dరభావితà°\82 à°\9aà±\87à°¸à±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది à°\95ాబà°\9fà±\8dà°\9fà°¿ ఆ అనుమతి మీకు లేదు.",
+       "sitecssprotected": "à°\88 CSS à°ªà±\87à°\9cà±\80à°²à±\8b à°²à±\8b à°®à±\80à°°à±\81 à°\9aà±\87à°¸à±\87 à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\8aà°¤à±\8dà°¤à°\82 à°¸à°\82దరà±\8dà°¶à°\95à±\81à°²à°\82దరినà±\80 à°ªà±\8dరభావితà°\82 à°\9aà±\87à°¸à±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది à°\95ాబà°\9fà±\8dà°\9fà°¿, ఆ అనుమతి మీకు లేదు.",
+       "sitejsonprotected": "à°\88 JSON à°ªà±\87à°\9cà±\80à°²à±\8b à°²à±\8b à°®à±\80à°°à±\81 à°\9aà±\87à°¸à±\87 à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\8aà°¤à±\8dà°¤à°\82 à°¸à°\82దరà±\8dà°¶à°\95à±\81à°²à°\82దరినà±\80 à°ªà±\8dరభావితà°\82 à°\9aà±\87à°¸à±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది à°\95ాబà°\9fà±\8dà°\9fà°¿, ఆ అనుమతి మీకు లేదు.",
+       "sitejsprotected": "à°\88 JavaScript à°ªà±\87à°\9cà±\80à°²à±\8b à°®à±\80à°°à±\81 à°\9aà±\87à°¸à±\87 à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\8aà°¤à±\8dà°¤à°\82 à°¸à°\82దరà±\8dà°¶à°\95à±\81à°²à°\82దరినà±\80 à°ªà±\8dరభావితà°\82 à°\9aà±\87à°¸à±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది à°\95ాబà°\9fà±\8dà°\9fà°¿, ఆ అనుమతి మీకు లేదు.",
        "mycustomcssprotected": "ఈ CSS పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
        "mycustomjsonprotected": "ఈ JSON పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
        "mycustomjsprotected": "ఈ జావాస్క్రిప్టు పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
        "ns-specialprotected": "ప్రత్యేక పేజీలపై దిద్దుబాట్లు చేయలేరు.",
        "titleprotected": "ఈ శీర్షికను [[User:$1|$1]] సృష్టించకుండా సంరక్షించబడింది.\nఅందుకు ఇచ్చిన కారణం: <em>$2</em>.",
        "filereadonlyerror": "ఫైలు ఖజానా \"$2\" రీడ్-ఓన్లీ స్థితిలో ఉండటం చేత \"$1\" ఫైలులో మార్పులు చెయ్యలేకపోయాం.\n\nదానికి తాళం వేసిన సిస్టము నిర్వాహకుడు ఇచ్చిన వివరణ ఇది: \"$3\".",
+       "invalidtitle": "తప్పుడు శీర్షిక",
        "invalidtitle-knownnamespace": "పేరుబరి \"$2\", పాఠ్యము \"$3\" తో కూడిన ఈ శీర్షిక చెల్లనిది",
        "invalidtitle-unknownnamespace": "అపరిచితమైన పేరుబరి సంఖ్య \"$1\", పాఠ్యము \"$2\" తో కూడిన ఈ శీర్షిక చెల్లనిది",
        "exception-nologin": "లాగినై లేరు",
        "badretype": "మీరు ఇచ్చిన రెండు సంకేతపదాలు ఒకదానితో మరొకటి సరిపోలడం లేదు.",
        "usernameinprogress": "ఈ వాడుకరి పేరుతో ఖాతా సృష్టించుకోవడం పురోగతిలో ఉంది. కాస్త ఆగండి.",
        "userexists": "ఇచ్చిన వాడుకరిపేరు ఇప్పటికే వాడుకలో ఉంది.\nవేరే పేరును ఎంచుకోండి.",
+       "createacct-normalization": "సాంకేతిక కారణాల వలన మీ వాడుకరి పేరును \"$2\" కు సర్దుతాం.",
        "loginerror": "లాగిన్ లోపం",
        "createacct-error": "ఖాతా సృష్టించడంలో లోపం",
        "createaccounterror": "ఖాతాను సృష్టించలేకపోయాం: $1",
        "passwordtooshort": "సంకేతపదం కనీసం {{PLURAL:$1|1 అక్షరం|$1 అక్షరాల}} నిడివి ఉండాలి.",
        "passwordtoolong": "సంకేతపదం పొడవు {{PLURAL:$1|1 అక్షరం|$1 అక్షరాల}} కన్నా ఎక్కువ ఉండకూడదు.",
        "passwordtoopopular": "సాధారణంగా వాడే సంకేతపదాలను వాడే వీల్లేదు. ఊహించడానికి కష్టమైన సంకేతపదాన్ని ఎంచుకోండి.",
+       "passwordinlargeblacklist": "మీరిచ్చిన సంకేతపదం సర్వసామాన్యంగా వాడే సంకేతపదాల జాబితాలో ఉంది. మరింత అరుదైన సంకేతపదాన్ని ఎంచుకోండి.",
        "password-name-match": "మీ సంకేతపదం మీ వాడుకరిపేరుకి భిన్నంగా ఉండాలి.",
        "password-login-forbidden": "ఈ వాడుకరిపేరు, సంకేతపదాలను ఉపయోగించడం నిషిద్ధం.",
        "mailmypassword": "సంకేతపదాన్ని మార్చు",
        "accmailtext": "[[User talk:$1|$1]] కొరకు ఒక యాదృచ్ఛిక సంకేతపదాన్ని $2కి పంపించాం. లాగినయ్యాక, ''[[Special:ChangePassword|సంకేతపదాన్ని మార్చుకోండి]]'' అనే పేజీలో ఈ సంకేతపదాన్ని మార్చుకోవచ్చు.",
        "newarticle": "(కొత్తది)",
        "newarticletext": "ఈ లింకుకు సంబంధించిన పేజీ లేనే లేదు.\nకింది పెట్టెలో మీ రచనను టైపు చేసి ఆ పేజీని సృష్టించండి (దీనిపై సమాచారం కొరకు [$1 సహాయం పేజీ] చూడండి). మీరిక్కడికి పొరపాటున వచ్చి ఉంటే, మీ బ్రౌజరు <strong>back</strong> మీట నొక్కండి.",
-       "anontalkpagetext": "----\n<em>à°\87ది à°\92à°\95 à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\9aà°°à±\8dà°\9aà°¾ à°ªà±\87à°\9cà±\80. à°\86 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\87à°\82à°\95à°¾ à°¤à°¨à°\95à±\88 à°\96ాతానà±\81 à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà±\81à°\95à±\8bà°²à±\87à°¦à±\81, à°²à±\87దా à°\96ాతా à°\89à°¨à±\8dనా à°¦à°¾à°¨à°¿à°¨à°¿ à°\89పయà±\8bà°\97à°¿à°\82à°\9aà°¡à°\82 à°²à±\87à°¦à±\81.</em>\nà°\85à°\82à°\9aà±\87à°¤, à°\85తణà±\8dణి/à°\86à°®à±\86à°¨à±\81 à°\97à±\81à°°à±\8dతిà°\82à°\9aడానిà°\95à°¿ à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామానà±\81 à°µà°¾à°¡à°¾à°²à±\8dసి à°µà°\9aà±\8dà°\9aà°¿à°\82ది. \nà°\86 à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామానà±\81 à°\9aాలా à°®à°\82ది à°µà°¾à°¡à±\81à°\95à°°à±\81à°²à±\81 à°\89పయà±\8bà°\97à°¿à°\82à°\9aà±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది. \nà°®à±\80à°°à±\82 à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\85యితà±\87, à°®à±\80à°\95à±\81 à°¸à°\82à°¬à°\82à°§à°\82à°²à±\87ని à°µà±\8dయాà°\96à±\8dయలà±\81 à°®à°¿à°®à±\8dమలà±\8dని à°\89à°¦à±\8dà°¦à±\87శిà°\82à°\9aà°¿à°¨à°\9fà±\8dà°\9fà±\81à°\97à°¾ à°\85నిపిసà±\8dà°¤à±\87, à°­à°µà°¿à°·à±\8dయతà±\8dà°¤à±\81à°²à±\8b à°\87తర à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à±\81లతà±\8b à°\85à°¯à±\8bమయà°\82 à°²à±\87à°\95à±\81à°\82à°¡à°¾ à°\89à°\82à°¡à°\9fానిà°\95à°¿, [[Special:CreateAccount|à°\96ాతానà±\81 à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà±\81à°\95à±\8bà°\82à°¡à°¿]] à°²à±\87దా [[Special:UserLogin|లాà°\97ినవà°\82à°¡à°¿]].''",
+       "anontalkpagetext": "----\n<em>à°\87ది à°\92à°\95 à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\9aà°°à±\8dà°\9aà°¾ à°ªà±\87à°\9cà±\80. à°\86 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\87à°\82à°\95à°¾ à°¤à°¨à°\95à±\88 à°\96ాతానà±\81 à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà±\81à°\95à±\8bà°²à±\87à°¦à±\81, à°²à±\87దా à°\96ాతా à°\89à°¨à±\8dనా à°¦à°¾à°¨à°¿à°¨à°¿ à°\89పయà±\8bà°\97à°¿à°\82à°\9aà°¡à°\82 à°²à±\87à°¦à±\81.</em>\nà°\85à°\82à°\9aà±\87à°¤, à°µà°¾à°°à°¿à°¨à°¿ à°\97à±\81à°°à±\8dతిà°\82à°\9aడానిà°\95à°¿ à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామానà±\81 à°µà°¾à°¡à°¾à°²à±\8dసి à°µà°\9aà±\8dà°\9aà°¿à°\82ది. \nà°\86 à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామానà±\81 à°\9aాలా à°®à°\82ది à°µà°¾à°¡à±\81à°\95à°°à±\81à°²à±\81 à°\89పయà±\8bà°\97à°¿à°\82à°\9aà±\87 à°\85à°µà°\95ాశà°\82 à°\89à°\82ది. \nà°®à±\80à°°à±\82 à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\85యితà±\87, à°®à±\80à°\95à±\81 à°¸à°\82à°¬à°\82à°§à°\82à°²à±\87ని à°µà±\8dయాà°\96à±\8dయలà±\81 à°®à°¿à°®à±\8dమలà±\8dని à°\89à°¦à±\8dà°¦à±\87శిà°\82à°\9aà°¿à°¨à°\9fà±\8dà°\9fà±\81à°\97à°¾ à°\85నిపిసà±\8dà°¤à±\87, à°­à°µà°¿à°·à±\8dయతà±\8dà°¤à±\81à°²à±\8b à°\87తర à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à±\81లతà±\8b à°¸à°\82దిà°\97à±\8dధత à°²à±\87à°\95à±\81à°\82à°¡à°¾ à°\89à°\82à°¡à°\9fానిà°\95à°¿, [[Special:CreateAccount|à°\96ాతానà±\81 à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà±\81à°\95à±\8bà°\82à°¡à°¿]] à°²à±\87దా [[Special:UserLogin|లాà°\97ినవà°\82à°¡à°¿]].",
        "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": "\"{{FULLPAGENAME}}\" అనే పేజీ యొక్క కూర్పు #$1 ఉనికిలో లేదు. సాధారణంగా ఏదైనా తొలగించబడిన పేజీ యొక్క కాలం చెల్లిన చరితం లింకును నొక్కినపుడు ఇది జరుగుతుంది. వివరాలు [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} తొలగింపు లాగ్] లో దొరుకుతాయి.",
        "blocked-notice-logextract": "ప్రస్తుతం ఈ వాడుకరిని నిరోధించారు.\nనిరోధపు చిట్టాలోని చివరి పద్దుని మీ సమాచారం కోసం ఈ క్రింద ఇస్తున్నాం:",
        "clearyourcache": "<strong>గమనిక:</strong> భద్రపరచిన తర్వాత, మార్పులను చూడాలంటే మీ విహారిణి యొక్క కోశాన్ని తీసేయాల్సిరావచ్చు.\n*<strong>ఫైర్‌ఫాక్స్‌ / సఫారి:</strong> <em>Shift</em> మీటని నొక్కిపట్టి <em>Reload</em>ని నొక్కండి లేదా <em>Ctrl-F5</em> గానీ <em>Ctrl-R</em> (మాకింటోషులో <em>⌘-Shift-R</em>) గానీ నొక్కండి\n* <strong>గూగుల్ క్రోమ్:</strong> <em>Ctrl-Shift-R</em> (మాక్ లో <em>⌘-Shift-R</em>) నొక్కండి\n*<strong>ఇంటర్నెట్ ఎక్ప్లోరర్:</strong> <em>Ctrl</em> ను నొక్కిపట్టి <em>Refresh</em> నొక్కండి లేదా <em>Ctrl-F5</em> నొక్కండి.\n* <strong>ఓపెరా:</strong> <em>Menu → Settings</em> వెళ్ళి (మ్యాక్‌లో <em>Opera → Preferences</em>కు వెళ్ళాలి) తర్వాత <em>Privacy & security → Clear browsing data → Cached images and files</em>కు వెళ్ళండి.",
        "usercssyoucanpreview": "<strong>చిట్కా:</strong> భద్రపరిచేముందు మీ కొత్త CSSని పరీక్షించడానికి \"{{int:showpreview}}\" బొత్తాన్ని వాడండి.",
+       "userjsonyoucanpreview": "<strong>చిట్కా:</strong> కొత్త JSON ను భద్రపరచే ముందు, \"{{int:showpreview}}\" మీటను నొక్కి దాన్ని పరీక్షించండి.",
        "userjsyoucanpreview": "<strong>చిట్కా:</strong> భద్రపరిచేముందు మీ కొత్త జావాస్క్రిప్టుని పరీక్షించడానికి \"{{int:showpreview}}\" బొత్తాన్ని వాడండి.",
        "usercsspreview": "<strong>మీరు వాడుకరి CSSను కేవలం సరిచూస్తున్నారని గుర్తుంచుకోండి.\nదాన్నింకా భద్రపరచలేదు!</strong>",
        "userjspreview": "<strong>గుర్తుంచుకోండి, మీరింకా మీ వాడుకరి జావాస్క్రిప్ట్&zwnj;ను భద్రపరచలేదు, కేవలం పరీక్షిస్తున్నారు/సరిచూస్తున్నారు!</strong>",
        "copyrightwarning2": "{{SITENAME}}లో ప్రచురించే రచనలన్నిటినీ ఇతర రచయితలు సరిదిద్దడం, మార్చడం, తొలగించడం జరగవచ్చు. మీ రచనలను అలా నిర్దాక్షిణ్యంగా దిద్దుబాట్లు చెయ్యడం మీకిష్టం లేకపోతే, వాటిని ఇక్కడ ప్రచురించకండి. <br />\nఅలాగే, ఈ రచనను మీరే చేసారని, లేదా ఏదైనా సార్వజనిక వనరు నుండి గానీ, అలాంటి ఉచిత, స్వేచ్ఛా వనరు నుండి గానీ కాపీ చేసి తెచ్చారని మాకు వాగ్దానం చేస్తున్నారు. (వివరాలకు $1 చూడండి).\n<strong>తగు అనుమతులు లేకుండా కాపీ హక్కులు గల రచనలను సమర్పించకండి!</strong>",
        "editpage-cannot-use-custom-model": "ఈ పేజీ కంటెంట్ మోడల్ మార్చడం వీలుకాదు.",
        "longpageerror": "<strong>లోపం: మీరు సమర్పించిన పాఠ్యం {{PLURAL:$1|ఒక కిలోబైటు|$1 కిలోబైట్ల}} నిడివి కలిగి ఉంది. ఇది గరిష్ఠ పరిమితి అయిన {{PLURAL:$2|ఒక కిలోబైటుని|$2 కిలోబైట్లను}} మించింది.</strong>\n దీన్ని భద్రపరచలేము.",
-       "readonlywarning": "<strong>à°¹à±\86à°\9aà±\8dà°\9aà°°à°¿à°\95: à°¨à°¿à°°à±\8dవహణ à°\95à±\8aà°°à°\95à±\81 à°¡à±\87à°\9fాబà±\87à°¸à±\81à°\95à°¿ à°¤à°¾à°³à°\82 à°µà±\87సారà±\81. à°\95ాబà°\9fà±\8dà°\9fà°¿ à°®à±\80 à°®à°¾à°°à±\8dà°ªà±\81à°\9aà±\87à°°à±\8dà°ªà±\81లనà±\81 à°\87à°ªà±\8dà°ªà±\81à°¡à±\81 à°­à°¦à±\8dరపరà°\9aà°²à±\87à°°à±\81.</strong> \nà°®à±\80 à°®à°¾à°°à±\8dà°ªà±\81లనà±\81 à°\92à°\95 à°«à°¾à° à±\8dà°¯ à°«à±\88à°²à±\81à°²à±\8bà°\95à°¿ à°\95ాపà±\80 à°\9aà±\87సి à°­à°¦à±\8dరపరà°\9aà±\81à°\95à±\8aని, à°¤à°°à±\81వాత à°¸à°®à°°à±\8dపిà°\82à°\9aà°\82à°¡à°¿.\n\nతాళà°\82 à°µà±\87సిన à°¨à°¿à°°à±\8dవాహà°\95à±\81à°¡à°¿ à°µà°¿à°µà°°à°£ à°\87à°¦à±\80: $1",
+       "readonlywarning": "<strong>à°¹à±\86à°\9aà±\8dà°\9aà°°à°¿à°\95: à°¨à°¿à°°à±\8dవహణ à°\95à±\8aà°°à°\95à±\81 à°¡à±\87à°\9fాబà±\87à°¸à±\81à°\95à°¿ à°¤à°¾à°³à°\82 à°µà±\87సారà±\81. à°\95ాబà°\9fà±\8dà°\9fà°¿ à°®à±\80 à°®à°¾à°°à±\8dà°ªà±\81à°\9aà±\87à°°à±\8dà°ªà±\81లనà±\81 à°\87à°ªà±\8dà°ªà±\81à°¡à±\81 à°­à°¦à±\8dరపరà°\9aà°²à±\87à°°à±\81.</strong> \nà°®à±\80 à°®à°¾à°°à±\8dà°ªà±\81లనà±\81 à°\92à°\95 à°«à°¾à° à±\8dà°¯ à°«à±\88à°²à±\81à°²à±\8bà°\95à°¿ à°\95ాపà±\80 à°\9aà±\87సి à°­à°¦à±\8dరపరà°\9aà±\81à°\95à±\8aని, à°¤à°°à±\81వాత à°¸à°®à°°à±\8dపిà°\82à°\9aà°\82à°¡à°¿.\n\nతాళà°\82 à°µà±\87సిన à°¸à°¿à°¸à±\8dà°\9fà°®à±\81 à°¨à°¿à°°à±\8dవాహà°\95à±\81à°¡à°¿ à°µà°¿à°µà°°à°£ à°\87ది: $1",
        "protectedpagewarning": "<strong>హెచ్చరిక: ఈ పేజీ సంరక్షించబడింది. కాబట్టి నిర్వాహక అనుమతులు ఉన్న వాడుకరులు మాత్రమే మార్చగలరు.</strong>\nచివరి లాగ్ పద్దును మీ సమాచారం కోసం ఇక్కడ ఇస్తున్నాం:",
-       "semiprotectedpagewarning": "<strong>à°\97మనిà°\95:</strong> à°¨à°®à±\8bదయిన à°µà°¾à°¡à±\81à°\95à°°à±\81à°²à±\81 à°®à°¾à°¤à±\8dà°°à°®à±\87 à°®à°¾à°°à±\8dà°ªà±\81à°²à±\81 à°\9aà±\86à°¯à±\8dà°¯à°\97లిà°\97à±\87లా à°\88 à°ªà±\87à°\9cà±\80à°\95ి సంరక్షించారు.\nమీ సమాచారం కోసం చివరి లాగ్ పద్దుని ఇక్కడ ఇస్తున్నాం:",
-       "cascadeprotectedwarning": "'''హెచ్చరిక:''' ఈ పేజీ, కాస్కేడింగు రక్షణలో ఉన్న కింది {{PLURAL:$1|పేజీ|పేజీల్లో}} ఇంక్లూడు అయి ఉంది కాబట్టి, నిర్వాహకులు తప్ప ఇతరులు దిద్దుబాటు చేసే వీలు లేకుండా {{PLURAL:$1|పేజీని|పేజీలను}} లాకు చేసాం:",
+       "semiprotectedpagewarning": "<strong>à°\97మనిà°\95:</strong> à°\86à°\9fà±\8b-à°\95à°¨à±\8dà°«à°°à±\8dà°®à±\8dâ\80\8cà°¡à±\8d à°µà°¾à°¡à±\81à°\95à°°à±\81à°²à±\81 à°®à°¾à°¤à±\8dà°°à°®à±\87 à°®à°¾à°°à±\8dà°ªà±\81à°²à±\81 à°\9aà±\86à°¯à±\8dà°¯à°\97లిà°\97à±\87లా à°\88 à°ªà±\87à°\9cà±\80à°¨ి సంరక్షించారు.\nమీ సమాచారం కోసం చివరి లాగ్ పద్దుని ఇక్కడ ఇస్తున్నాం:",
+       "cascadeprotectedwarning": "<strong>హెచ్చరిక:</strong> ఈ పేజీ కాస్కేడింగు రక్షణలో ఉన్న కింది {{PLURAL:$1|పేజీ|పేజీల్లో}} ట్రాన్స్‌క్లూడు అయి ఉంది కాబట్టి రక్షణలో ఉంది. [[Special:ListGroupRights|ప్రత్యేకించిన అనుమతులు]] ఉన్న వాడుకరులు మాత్రమే దీనిలో దిద్దుబాటు చెయ్యగలరు:",
        "titleprotectedwarning": "<strong>హెచ్చరిక: ఈ పేజీని సంరక్షించారు కాబట్టి దీన్ని సృష్టించడానికి [[Special:ListGroupRights|ప్రత్యేక హక్కులు]] ఉండాలి.</strong>\nమీ సమాచారం కోసం చివరి చిట్టా పద్దుని ఇక్కడ ఇస్తున్నాం:",
        "templatesused": "ఈ పేజీలో వాడిన {{PLURAL:$1|మూస|మూసలు}}:",
        "templatesusedpreview": "ఈ మునుజూపులో వాడిన {{PLURAL:$1|మూస|మూసలు}}:",
        "unwatch": "వీక్షించవద్దు",
        "unwatchthispage": "వీక్షణను ఆపు",
        "notanarticle": "వ్యాసం పేజీ కాదు",
-       "notvisiblerev": "à°\88 కూర్పును తొలగించాం",
+       "notvisiblerev": "à°µà±\87à°°à±\87 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\9aà±\87సిన à°\9aివరి కూర్పును తొలగించాం",
        "watchlist-details": "మీ వీక్షణ జాబితాలో {{PLURAL:$1|ఒక పేజీ ఉంది|$1 పేజీలున్నాయి}} (చర్చా పేజీలు అదనం).",
        "wlheader-enotif": "ఈ-మెయిలు గమనికలు పంపబడతాయి.",
        "wlheader-showupdated": "మీ గత సందర్శన తరువాత మారిన పేజీలు <strong>బొద్దు</strong>గా చూపించబడ్డాయి.",
        "editcomment": "దిద్దుబాటు సారాశం: <em>$1</em>.",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|చర్చ]]) చేసిన మార్పులను [[User:$1|$1]] చివరి కూర్పు వరకు తిప్పికొట్టారు.",
        "revertpage-nouser": "దాగి ఉన్న వాడుకరి చేసిన మార్పులను [[User:$1|$1]] చివరి కూర్పు వరకు తిప్పికొట్టారు",
-       "rollback-success": "{{GENDER:$3|$1}} చేసిన దిద్దుబాట్లను వెనక్కు తీసుకెళ్ళాం; తిరిగి {{GENDER:$4|$2}} చేసిన చివరి కూర్పుకు మార్చాం.",
-       "rollback-success-notify": "$1 చేసిన దిద్దుబాట్లను వెనక్కు తీసుకెళ్ళాం;\nతిరిగి $2 చేసిన చివరి కూర్పుకు మార్చాం. [$3 మార్పులు చూపించు]",
+       "rollback-success": "{{GENDER:$3|$1}} చేసిన దిద్దుబాట్లను వెనక్కు తీసుకెళ్ళారు; తిరిగి {{GENDER:$4|$2}} చేసిన చివరి కూర్పుకు మార్చారు.",
        "sessionfailure-title": "సెషను వైఫల్యం",
        "sessionfailure": "మీ లాగిన్ సెషనుతో ఏదో సమస్య ఉన్నట్లుంది;\nసెషను హైజాకు కాకుండా ఈ చర్యను రద్దు చేసాం.\nఫారమును తిరిగి సమర్పించండి.",
        "changecontentmodel": "పేజీ కంటెంటు మోడలును మార్చు",
        "protectlogpage": "సంరక్షణల చిట్టా",
        "protectlogtext": "ఈ క్రింద ఉన్నది పేజీల సంరక్షణలకు జరిగిన మార్పుల జాబితా.\nప్రస్తుతం అమలులో ఉన్న సంరక్షణలకై [[Special:ProtectedPages|సంరక్షిత పేజీల జాబితా]]ను చూడండి.",
        "protectedarticle": "\"[[$1]]\" సంరక్షించబడింది.",
-       "modifiedarticleprotection": "\"[[$1]]\" à°¸à°\82à°°à°\95à±\8dà°·à°£ à°¸à±\8dథాయిని à°®à°¾à°°à±\8dà°\9aà°¾à°\82",
-       "unprotectedarticle": "\"[[$1]]\" à°¯à±\8aà°\95à±\8dà°\95 à°¸à°\82à°°à°\95à±\8dషణనà±\81 à°¤à±\8aà°²à°\97à°¿à°\82à°\9aà°¾à°\82",
+       "modifiedarticleprotection": "\"[[$1]]\" à°¸à°\82à°°à°\95à±\8dà°·à°£ à°¸à±\8dథాయిని à°®à°¾à°°à±\8dà°\9aారà±\81",
+       "unprotectedarticle": "\"[[$1]]\" à°¯à±\8aà°\95à±\8dà°\95 à°¸à°\82à°°à°\95à±\8dషణనà±\81 à°¤à±\8aà°²à°\97à°¿à°\82à°\9aారà±\81",
        "movedarticleprotection": "సంరక్షణా అమరికని \"[[$2]]\" నుండి \"[[$1]]\"కి మార్చారు",
        "protectedarticle-comment": "\"[[$1]]\" ను {{GENDER:$2|సంరక్షించారు}}",
        "modifiedarticleprotection-comment": "\"[[$1]]\" యొక్క {{GENDER:$2|సంరక్షణ స్థాయిని మార్చారు}}",
        "ipusubmit": "ఈ నిరోధాన్ని తొలగించు",
        "unblocked": "[[User:$1|$1]]పై నిరోధం తొలగించబడింది",
        "unblocked-range": "$1 పై నిరోధాన్ని తీసేసాం",
-       "unblocked-id": "$1 అనే నిరోధాన్ని తొలగించాం",
+       "unblocked-id": "$1 అనే నిరోధాన్ని తొలగించాం.",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] పైనున్న నిరోధాన్ని ఎత్తివేసాం.",
        "blocklist": "నిరోధిత వాడుకరులు",
        "autoblocklist": "ఆటోబ్లాకులు",
        "createaccountblock": "ఖాతా తెరవడాన్ని నిరోధించాము",
        "emailblock": "ఈ-మెయిలుని నిరోధించాం",
        "blocklist-nousertalk": "తమ చర్చాపేజీని మార్చలేరు",
+       "blocklist-editing": "దిద్దుబాటు",
+       "blocklist-editing-sitewide": "దిద్దుబాటు (సైటు పర్యంతం)",
+       "blocklist-editing-page": "పేజీలు",
+       "blocklist-editing-ns": "పేరుబరులు",
        "ipblocklist-empty": "నిరోధపు జాబితా ఖాళీగా ఉంది.",
        "ipblocklist-no-results": "మీరడిగిన ఐపీ అడ్రసు లేదా వాడుకరిపేరును నిరోధించలేదు.",
        "blocklink": "నిరోధించు",
        "blocklogtext": "వాడుకరుల నిరోధాలు, పునస్థాపనల చిట్టా ఇది. \nఆటోమాటిక్‌గా నిరోధానికి గురైన ఐ.పి. చిరునామాలు ఈ జాబితాలో ఉండవు. \nప్రస్తుతం అమల్లో ఉన్న నిరోధాలు, నిషేధాల కొరకు [[Special:BlockList|నిరోధాల జాబితా]]ను చూడండి.",
        "unblocklogentry": "$1పై నిరోధం తొలగించబడింది",
        "block-log-flags-anononly": "అజ్ఞాత వాడుకరులు మాత్రమే",
-       "block-log-flags-nocreate": "à°\96ాతా à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aడానà±\8dని à°\85à°¶à°\95à±\8dà°¤à°\82 à°\9aà±\87సాà°\82",
-       "block-log-flags-noautoblock": "à°\86à°\9fà±\8bమాà°\9fà°¿à°\95à±\8d à°¨à°¿à°°à±\8bధానà±\8dని à°\85à°¶à°\95à±\8dà°¤à°\82 à°\9aà±\87సాà°\82",
+       "block-log-flags-nocreate": "à°\96ాతా à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aడానà±\8dని à°\85à°¶à°\95à±\8dà°¤à°\82 à°\9aà±\87సారà±\81",
+       "block-log-flags-noautoblock": "à°\86à°\9fà±\8bమాà°\9fà°¿à°\95à±\8d à°¨à°¿à°°à±\8bధానà±\8dని à°\85à°¶à°\95à±\8dà°¤à°\82 à°\9aà±\87సారà±\81",
        "block-log-flags-noemail": "ఈ-మెయిలుని నిరోధించాం",
        "block-log-flags-nousertalk": "తమ చర్చాపేజీని మార్చలేరు",
        "block-log-flags-angry-autoblock": "మరింత ధృడమైన స్వయంనిరోధకం సచేతనం చేయబడింది",
        "block-log-flags-hiddenname": "వాడుకరిపేరుని దాచాం",
-       "range_block_disabled": "à°¶à±\8dà°°à±\87ణి(à°°à±\87à°\82à°\9cà°¿) à°¨à°¿à°°à±\8bà°§à°\82 à°\9aà±\86à°¯à±\8dà°¯à°\97à°² à°¨à°¿à°°à±\8dవాహà°\95 à°\85à°¨à±\81మతిని à°\85à°¶à°\95à±\8dà°¤à°\82 à°\9aà±\87సాà°\82.",
+       "range_block_disabled": "à°¶à±\8dà°°à±\87ణి(à°°à±\87à°\82à°\9cà°¿) à°¨à°¿à°°à±\8bà°§à°\82 à°\9aà±\86à°¯à±\8dà°¯à°\97à°² à°¨à°¿à°°à±\8dవాహà°\95 à°\85à°¨à±\81మతిని à°\85à°¶à°\95à±\8dà°¤à°\82 à°\9aà±\87సారà±\81.",
        "ipb_expiry_invalid": "అంతమయ్యే గడువు సరైనది కాదు.",
+       "ipb_expiry_old": "ముగిసే సమయం గతించిన కాలంలో ఉంది.",
        "ipb_expiry_temp": "దాచిన వాడుకరిపేరు నిరోధాలు శాశ్వతంగా ఉండాలి.",
        "ipb_hide_invalid": "ఈ ఖాతాను అణచలేకపోతున్నాం. దాని ఖాతాలో {{PLURAL:$1|ఒకటి కంటే|$1 కంటే}} ఎక్కువ దిద్దుబాట్లు ఉన్నాయి.",
+       "ipb_hide_partial": "వాడుకరిపేరును దాచి ఉంచిన నిరోధాలు, తప్పనిసరిగా సైటు పర్యంతం ఉండాలి.",
        "ipb_already_blocked": "\"$1\" ను ఇప్పటికే నిరోధించాం",
        "ipb-needreblock": "$1ని ఇప్పటికే నిరోధించారు. ఆ అమరికలని మీరు మార్చాలనుకుంటున్నారా?",
        "ipb-otherblocks-header": "ఇతర {{PLURAL:$1|నిరోధం|నిరోధాలు}}",
        "ipb_blocked_as_range": "లోపం: ఐపీ $1 ను నేరుగా నిరోధించలేదు, అంచేత నిరోధాన్ని రద్దుపరచలేము.  అయితే, అది $2 శ్రేణిలో భాగంగా నిరోధానికి గురైంది, ఈ శ్రేణిపై ఉన్న నిరోధాన్ని రద్దుపరచవచ్చు.",
        "ip_range_invalid": "సరైన ఐపీ శ్రేణి కాదు.",
        "ip_range_toolarge": "/$1  కంటే పెద్దవైన సామూహిక నిరోధాలు అనుమతించబడవు.",
+       "ip_range_exceeded": "ఐపీ శ్రేణి గరిష్ఠ శ్రేణిని దాటిపోయింది. అనుమతించిన శ్రేణి: /$1.",
        "proxyblocker": "ప్రాక్సీ నిరోధకం",
        "proxyblockreason": "మీ ఐపీ అడ్రసు ఒక ఓపెన్ ప్రాక్సీ కాబట్టి దాన్ని నిరోధించాం. మీ ఇంటర్నెట్ సేవాదారుని గానీ, సాంకేతిక సహాయకుని గానీ సంప్రదించి తీవ్రమైన ఈ భద్రతా వైఫల్యాన్ని గురించి తెలపండి.",
        "sorbsreason": "{{SITENAME}} వాడే DNSBLలో మీ ఐపీ అడ్రసు ఒక ఓపెన్ ప్రాక్సీగా నమోదై ఉంది.",
        "move-watch": "ఈ పేజీని గమనించు",
        "movepagebtn": "పేజీని తరలించు",
        "pagemovedsub": "తరలింపు విజయవంతమైనది",
+       "cannotmove": "ఈ పేజీని కింది {{PLURAL:$1|కారణం|కారణాల}} వలన తరలించలేక పోయాం:",
        "movepage-moved": "'''\"$1\"ని \"$2\"కి తరలించాం'''",
        "movepage-moved-redirect": "ఒక దారిమార్పుని సృష్టించాం.",
        "movepage-moved-noredirect": "దారిమార్పుని సృష్టించలేదు.",
+       "movepage-delete-first": "లక్ష్యిత పేజీకి చాలాకూర్పులు ఉన్నందున, తరలింపులో భాగంగా దాన్ని తొలగించలేం. ముందు ఆ పేజీని మానవికంగా తొలగించి, అప్పుడు ప్రయత్నించండి.",
        "articleexists": "ఆ పేరుతో ఇప్పటికే ఒక పేజీ ఉంది, లేదా మీరు ఎంచుకున్న పేరు సరైనది కాదు. వేరే పేరు ఎంచుకోండి.",
        "cantmove-titleprotected": "ఈ పేరుతోఉన్న పేజీని సృష్టించనివ్వకుండా సంరక్షిస్తున్నారు, అందుకని ఈ ప్రదేశంలోకి పేజీని తరలించలేను",
        "movetalk": "కూడా వున్న చర్చ పేజీని తరలించు",
        "tooltip-undo": "\"రద్దుచేయి\" ఈ మార్పుని రద్దుచేసి, దిద్దుబాటు ఫారాన్ని మునుజూపులో తెరుస్తుంది.\nసారాంశానికి కారణాన్ని చేర్చే వీలుకల్పిస్తుంది.",
        "tooltip-preferences-save": "అభిరుచులను భద్రపరచు",
        "tooltip-summary": "చిన్న సారాంశాన్ని ఇవ్వండి",
+       "common.json": "/* ఇక్కడున్న JSON, ప్రతి పేజీలోడుకు అందరి వాడుకరులకూ లోడవుతుంది. */",
        "anonymous": "{{SITENAME}} యొక్క అజ్ఞాత {{PLURAL:$1|వాడుకరి|వాడుకరులు}}",
        "siteuser": "{{SITENAME}} వాడుకరి $1",
        "anonuser": "{{SITENAME}} అజ్ఞాత వాడుకరి $1",
        "pageinfo-display-title": "చూపించే శీర్షిక",
        "pageinfo-default-sort": "అప్రమేయంగా విడదీసే కీ",
        "pageinfo-length": "పేజీ నిడివి (బైట్లలో)",
+       "pageinfo-namespace": "పేరుబరి",
        "pageinfo-article-id": "పేజీ ఐడీ",
        "pageinfo-language": "పేజీ విషయపు భాష",
        "pageinfo-language-change": "మార్చు",
        "pageinfo-category-files": "దస్త్రాల సంఖ్య",
        "pageinfo-user-id": "వాడుకరి ID",
        "pageinfo-file-hash": "హ్యాష్ వ్యాల్యూ",
+       "pageinfo-view-protect-log": "ఈ పేజీకి సంబంధించిన సంరక్షణ లాగ్‌ను చూడండి.",
        "markaspatrolleddiff": "పరీక్షించినట్లుగా గుర్తు పెట్టు",
        "markaspatrolledtext": "ఈ వ్యాసాన్ని పరీక్షించినట్లుగా గుర్తు పెట్టు",
        "markaspatrolledtext-file": "దస్త్రపు ఈ కూర్పు నిఘాలో ఉందని గుర్తు పెట్టు",
        "previousdiff": "← మునుపటి మార్పు",
        "nextdiff": "తరువాతి మార్పు →",
        "mediawarning": "'''హెచ్చరిక''': ఈ రకపు ఫైలులో హానికరమైన కోడ్‌ ఉండవచ్చు.\nదాన్ని నడపడం వల్ల, మీ సిస్టమ్ లొంగిపోవచ్చు.",
-       "imagemaxsize": "à°¬à±\8aà°®à±\8dà°® à°ªà°°à°¿à°®à°¾à°£à°\82à°ªà±\88 à°ªà°°à°¿à°®à°¿à°¤à°¿:<br />''(దసà±\8dà°¤à±\8dà°°à°ªà±\81 à°µà°¿à°µà°°à°£ à°ªà±\81à°\9fà°² à°\95à±\8aà°°à°\95à±\81)''",
+       "imagemaxsize": "వివరణ à°ªà±\87à°\9cà±\80à°²à±\8dà°²à±\8b à°¬à±\8aà°®à±\8dà°® à°ªà°°à°¿à°®à°¾à°£ à°ªà°°à°¿à°®à°¿à°¤à°¿:",
        "thumbsize": "నఖచిత్రం వైశాల్యం:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|పేజీ|పేజీలు}}",
        "file-info": "ఫైలు పరిమాణం: $1, MIME రకం: $2",
        "confirmemail_subject": "{{SITENAME}} ఈ-మెయిలు చిరునామా ధృవీకరణ",
        "confirmemail_body": "$1 ఐపీ చిరునామా నుండి ఎవరో, బహుశా మీరే,\n{{SITENAME}}లో \"$2\" అనే ఖాతాని ఈ ఈమెయిలు చిరునామాతో నమోదుచేసుకున్నారు.\n\nఆ ఖాతా నిజంగా మీదే అని నిర్ధారించేందుకు మరియు {{SITENAME}}లో ఈమెయిలు సౌలభ్యాలని చేతనం చేసుకునేందుకు, ఈ లంకెని మీ విహారిణిలో తెరవండి:\n\n$3\n\nఒకవేళ ఆ ఖాతా మీది *కాకపోతే*, ఈమెయిలు చిరునామా నిర్ధారణని రద్దుచేసేందుకు ఈ లంకెని అనుసరించండి:\n\n$5\n\nఈ నిర్ధారణా సంకేతం $4కి కాలంచెల్లుతుంది.",
        "confirmemail_body_changed": "$1 ఐపీ చిరునామా నుండి ఎవరో, బహుశా మీరే,\n{{SITENAME}}లో \"$2\" అనే ఖాతా యొక్క ఈ-మెయిలు చిరునామాని ఈ చిరునామాకి మార్చారు.\n\nఆ ఖాతా నిజంగా మీదే అని నిర్ధారించేందుకు మరియు {{SITENAME}}లో\nఈ-మెయిలు సౌలభ్యాలని పునఃచేతనం చేసుకునేందుకు, ఈ లంకెని మీ విహారిణిలో తెరవండి:\n\n$3\n\nఒకవేళ ఆ ఖాతా మీది *కాకపోతే*, ఈ-మెయిలు చిరునామా నిర్ధారణని రద్దుచేసేందుకు\nఈ లంకెని అనుసరించండి:\n\n$5\n\nఈ నిర్ధారణా సంకేతం $4కి కాలంచెల్లుతుంది.",
+       "confirmemail_body_set": "$1 ఐపీ చిరునామా నుండి ఎవరో, బహుశా మీరే, ఈ ఈ-మెయిలు చిరునామాను\n{{SITENAME}}లో \"$2\" అనే ఖాతా యొక్క ఈ-మెయిలు చిరునామాగా సెట్ చేసారు.\n\nఆ ఖాతా నిజంగా మీదే అని నిర్ధారించేందుకు, {{SITENAME}}లో\nఈ-మెయిలు సౌలభ్యాలని చేతనం చేసుకునేందుకూ ఈ లంకెని మీ విహారిణిలో తెరవండి:\n\n$3\n\nఒకవేళ ఆ ఖాతా మీది *కాకపోతే*, ఈ-మెయిలు చిరునామా నిర్ధారణను రద్దుచేసేందుకు\nఈ లంకెని నొక్కండి:\n\n$5\n\nఈ నిర్ధారణ లింకుకు $4 కు కాలం చెల్లుతుంది.",
        "confirmemail_invalidated": "ఈ-మెయిలు చిరునామా నిర్ధారణని రద్దుచేసాం",
        "invalidateemail": "ఈ-మెయిలు నిర్ధారణని రద్దుచేయండి",
-       "notificationemail_subject_changed": "{{SITENAME}} à°¨à°®à±\8bà°¦à±\88à°¨ à°\88à°®à±\86యిలà±\81 à°\85à°¡à±\8dà°°à°¸à±\81à°¨à±\81 à°®à°¾à°°à±\8dà°\9aà°¾à°\82",
+       "notificationemail_subject_changed": "{{SITENAME}} à°¨à°®à±\8bà°¦à±\88à°¨ à°\88à°®à±\86యిలà±\81 à°\85à°¡à±\8dà°°à°¸à±\81à°¨à±\81 à°®à°¾à°°à±\8dà°\9aారà±\81",
        "notificationemail_subject_removed": "{{SITENAME}} నమోదైన ఈమెయిలు అడ్రసును తీసివేసాం",
        "notificationemail_body_changed": "ఐపీ అడ్రసు $1 నుండి ఎవరో - బహుశా మీరే కావచ్చు -\n{{SITENAME}} లోని ఖాతా ఈమెయిలు అడ్రసు, \"$2\" ను \"$3\" కు మార్చారు.\n\nఅది మీరు కాకపోతే, వెంటనే ఓ సైటు నిర్వాహకుణ్ణి సంప్రదించండి.",
        "notificationemail_body_removed": "ఐపీ అడ్రసు $1 నుండి ఎవరో - బహుశా మీరే కావచ్చు -\n{{SITENAME}} లోని ఖాతా ఈమెయిలు అడ్రసు, \"$2\" ను తొలగించారు.\n\nఅది మీరు కాకపోతే, వెంటనే ఓ సైటు నిర్వాహకుణ్ణి సంప్రదించండి.",
        "confirm-unwatch-top": "ఈ పుటను మీ వీక్షణ జాబితా నుండి తొలగించాలా?",
        "confirm-rollback-button": "సరే",
        "confirm-rollback-top": "ఈ పేజీలో జరిగిన దిద్దుబాట్లను వెనక్కి తిప్పాలా?",
+       "confirm-mcrrestore-title": "ఓ కూర్పును పునస్స్థాపించండి",
+       "confirm-mcrundo-title": "మార్పును రద్దుచెయ్యండి",
+       "mcrundofailed": "రద్దు విఫలమైంది",
+       "mcrundo-changed": "ఈ పేజీ తేడాను చూసిన తరువాత, పేజీలో దిద్దుబాటు జరిగింది. కొత్త మార్పును పరిశీలించండి.",
        "quotation-marks": "“$1”",
        "imgmultipageprev": "← మునుపటి పేజీ",
        "imgmultipagenext": "తరువాతి పేజీ →",
        "autosumm-replace": "పేజీని '$1' తో మారుస్తున్నాం",
        "autoredircomment": "పేజీని [[$1]] కు దారి మళ్ళించారు",
        "autosumm-removed-redirect": "[[$1]] కు ఉన్న దారిమార్పును తీసేసాం",
-       "autosumm-changed-redirect-target": "దారిమారà±\8dà°ªà±\81à°¨à±\81 [[$1]] à°¨à±\81à°\82à°¡à°¿ [[$2]] à°\95à±\81 à°®à°¾à°°à±\8dà°\9aà°¾à°\82",
+       "autosumm-changed-redirect-target": "దారిమారà±\8dà°ªà±\81à°¨à±\81 [[$1]] à°¨à±\81à°\82à°¡à°¿ [[$2]] à°\95à±\81 à°®à°¾à°°à±\8dà°\9aారà±\81",
        "autosumm-new": "'$1' తో కొత్త పేజీని సృష్టించారు",
        "autosumm-newblank": "ఖాళీ పేజీని సృష్టించారు",
        "lag-warn-normal": "$1 {{PLURAL:$1|క్షణం|క్షణాల}} లోపు జరిగిన మార్పులు ఈ జాబితాలో కనిపించకపోవచ్చు.",
        "specialpages-group-developer": "వికాసకుల పనిముట్లు",
        "blankpage": "ఖాళీ పేజీ",
        "intentionallyblankpage": "బెంచిమార్కింగు, మొదలగు వాటికై ఈ పేజీని కావాలనే ఖాళీగా వదిలాము.",
+       "disabledspecialpage-disabled": "ఈ పేజీని సిస్టం నిర్వాహకుడు అచేతనం చేసారు.",
        "external_image_whitelist": " #ఈ లైనును ఎలా ఉన్నదో అలాగే వదిలెయ్యండి<pre>\n#regular expression తునకలను (// ల మధ్య ఉండే భాగం)కింద పెట్టండి\n#వీటిని బయటి బొమ్మల URLలతో సరిపోల్చుతాము\n#సరిపోలిన బొమ్మలను చూపిస్తాము, మిగిలినవాటి లింకులను మాత్రమే చూపిస్తాము\n##తో మొదలయ్యే లైనులు వ్యాఖ్యానాలుగా భావించబడతాయి\n#ఇది కేస్-సెన్సిటివ్\n\n#అన్ని తునకలను ఈ లైనుకు పైన ఉంచండి.  ఈ లైనును ఎలా ఉన్నదో అలాగే వదిలెయ్యండి</pre>",
        "tags": "సరైన మార్పు ట్యాగులు",
        "tag-filter": "[[Special:Tags|ట్యాగుల]] వడపోత:",
        "tag-mw-replace-description": "పేజీలోని పాఠ్యంలో 90% కి పైగా తీసివేసే దిద్దుబాట్లు",
        "tag-mw-rollback": "రోల్‌బ్యాక్",
        "tag-mw-rollback-description": "వెనక్కితిప్పు లింకు ద్వారా మునుపటి దిద్దుబాట్లను రద్దు చేసే దిద్దుబాట్లు",
+       "tag-mw-undo": "రద్దుచెయ్యి",
        "tags-title": "ట్యాగులు",
        "tags-intro": "మార్పుచేర్పులకు సాఫ్టువేరు ఇచ్చే ట్యాగులను, వాటి అర్ధాలనూ ఈ పేజీ చూపిస్తుంది.",
        "tags-tag": "ట్యాగు పేరు",
        "tags-actions-header": "చర్యలు",
        "tags-active-yes": "అవును",
        "tags-active-no": "కాదు",
+       "tags-source-extension": "సాఫ్టువేరు సృష్టించినవి",
+       "tags-source-manual": "వాడుకరులు, బాట్‌లు అమలు చేసేవి",
        "tags-source-none": "వాడుకలో లేదు",
        "tags-edit": "మార్చు",
        "tags-delete": "తొలగించు",
        "tags-activate": "చేతనంచేయి",
+       "tags-deactivate": "అచేతనం చేయి",
        "tags-hitcount": "$1 {{PLURAL:$1|మార్పు|మార్పులు}}",
        "tags-manage-no-permission": "ట్యాగులను నిర్వహించడానికి మీకు అనుమతి లేదు.",
+       "tags-manage-blocked": "{{GENDER:$1|మీరు}} నిరోధంలో ఉండగా, ట్యాగుల మార్పులను నిర్వహించలేరు.",
        "tags-create-heading": "కొత్త ట్యాగును సృష్టించు",
        "tags-create-explanation": "డిఫాల్టుగా, కొత్తగా సృష్టించిన ట్యాగులు, వాడుకరులు బాట్‌లూ వాడుకునేందుకు వెంటనే అందుబాటులోకి వస్తాయి.",
        "tags-create-tag-name": "ట్యాగు పేరు:",
        "tags-edit-logentry-submit": "{{PLURAL:$1|ఈ చిట్టా పద్దుకు|$1 చిట్టా పద్దులకు}} మార్పులను వర్తింపజేయి",
        "tags-edit-success": "మార్పులు ఆపాదించబడ్డాయి.",
        "tags-edit-failure": "మార్పులను వర్తింపజేయలేక పోయాం:\n$1",
+       "tags-edit-nooldid-title": "తప్పుడు లక్ష్యపు-కూర్పు",
+       "tags-edit-nooldid-text": "ఈ పని చేసేందుకు, మీరు లక్ష్యం కూర్పును ఇవ్వలేదు. లేదా ఇచ్చిన కూర్పు ఉనికిలో లేదు.",
        "tags-edit-none-selected": "చేర్చడానికి/తీసెయ్యడానికి కనీసం ఒక్క ట్యాగునైనా ఎంచుకోండి",
        "comparepages": "పుటల పోలిక",
        "compare-page1": "పుట 1",
        "compare-revision-not-exists": "మీరు పేర్కొన్న కూర్పు లేనే లేదు.",
        "diff-form": "తేడాలు",
        "diff-form-oldid": "పాత కూర్పు ID (ఐచ్ఛికం)",
+       "diff-form-revid": "తేడా యొక్క కూర్పు ఐడి",
        "diff-form-submit": "తేడాలను చూపించు",
        "permanentlink": "స్థిర లంకె",
        "permanentlink-revid": "కూర్పు ID",
        "logentry-block-block": "$1, {{GENDER:$4|$3}}ను {{GENDER:$2|నిరోధించారు}}. నిరోధ కాలం: $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$4|$3}} పై ఉన్న {{GENDER:$2|నిరోధాన్ని ఎత్తివేసారు}}",
        "logentry-block-reblock": "$1 {{GENDER:$4|$3}} యొక్క నిరోధపు కాలం తీరిపోయే వ్యవధిని $5 $6 గా సెట్టింగులను {{GENDER:$2|మార్చారు}}",
-       "logentry-partialblock-block": "{{GENDER:$4|$3}} {{PLURAL:$8}} పేజీల్లో ($7) మార్పులు చేయకుండా $1 {{GENDER:$2|నిరోధించారు}}. నిరోధించిన కాలం : $5 $6",
-       "logentry-partialblock-reblock": "{{GENDER:$4|$3}} {{PLURAL:$8}} పేజీల్లో ($7) మార్పులు చేయకుండా $1 {{GENDER:$2|నిరోధించారు}}. నిరోధించిన కాలం : $5 $6",
+       "logentry-partialblock-block-page": "{{PLURAL:$1|పేజీ|పేజీలు}} $2",
+       "logentry-partialblock-block-ns": "{{PLURAL:$1|పేరుబరి|పేరుబరులు}} $2",
+       "logentry-partialblock-block": "$7 లో దిద్దుబాట్లు చెయ్యకుండా {{GENDER:$4|$3}} ను $1 {{GENDER:$2|నిరోధించారు}}. గడువు $5 $6",
+       "logentry-partialblock-reblock": "$7 లో దిద్దుబాట్లు చెయ్యకుండా {{GENDER:$4|$3}} పై విధించిన నిరోధాన్ని, $1 {{GENDER:$2|సవరించారు}}. గడువు $5 $6",
        "logentry-non-editing-block-block": "$5 $6 సమయానికి నిరోధం ముగిసే వరకు {{GENDER:$4|$3}}ని $1 దిద్దుబాట్లు కాకుండా ఇతర చర్యల నుంచి {{GENDER:$2|నిరోధించారు}}",
        "logentry-non-editing-block-reblock": "{{GENDER:$4|$3}} నిరోధాల సెట్టింగులను $1 {{GENDER:$2|మార్చారు}}. ప్రస్తుతం నిరోధ కాలపు గడువు: $5 $6.",
        "logentry-suppress-block": "$1, {{GENDER:$4|$3}}ను {{GENDER:$2|నిరోధించారు}}. నిరోధ కాలం: $5 $6",
        "api-error-publishfailed": "అంతర్గత లోపం: తాత్కాలిక ఫైలును ప్రచురించడంలో సర్వరు విఫలమైంది.",
        "api-error-stashfailed": "అంతర్గత లోపం: తాత్కాలిక దస్త్రాన్ని భద్రపరచడంలో సేవకి విఫలమైంది.",
        "api-error-unknown-warning": "తెలియని హెచ్చరిక: \"$1\".",
-       "api-error-unknownerror": "à°¤à±\86లియని à°ªà±\8aరపాà°\9fà±\81: \"$1\".",
+       "api-error-unknownerror": "à°¤à±\86లియని à°²à±\8bà°ªà°\82: \"$1\".",
        "duration-seconds": "$1 {{PLURAL:$1|క్షణం|క్షణాలు}}",
        "duration-minutes": "$1 {{PLURAL:$1|నిమిషం|నిమిషాలు}}",
        "duration-hours": "$1 {{PLURAL:$1|గంట|గంటలు}}",
        "authmanager-create-no-primary": "మీరిచ్చిన విశేషాలతో ఖాతాను సృష్టించలేకపోయాం.",
        "authmanager-link-no-primary": "మీరిచ్చిన విశేషాలతో ఖాతాలను లింకు చెయ్యలేకపోయాం.",
        "authmanager-link-not-in-progress": "ఖాతాలను లింకు చేసే పని జరగడం లేదు. లేదా సెషను డేటా పోయింది. మళ్ళీ మొదటినుండి మొదలుపెట్టండి.",
-       "authmanager-authplugin-setpass-failed-title": "సంకేతపదం మార్పు విఫలమైంది.",
-       "authmanager-authplugin-setpass-failed-message": "సంకేతపదం మార్పును ఆథెంటికేషన్ ప్లగిన్ తిరస్కరించింది.",
-       "authmanager-authplugin-create-fail": "ఖాతా సృష్టిని ఆథెంటికేషన్ ప్లగిన్ తిరస్కరించింది.",
-       "authmanager-authplugin-setpass-denied": "ఆథెంటికేషన్ ప్లగిన్ సంకేతపదం మార్పులను అనుమతించదు.",
-       "authmanager-authplugin-setpass-bad-domain": "తప్పు డొమెయిన్",
        "authmanager-autocreate-noperm": "ఆటోమాటిక్ ఖాతా సృష్టికి అనుమతి లేదు.",
        "authmanager-userdoesnotexist": "వాడుకరి ఖాతా \"$1\" నమోదయి లేదు.",
        "authmanager-userlogin-remembermypassword-help": "సెషను ముగిసిన తరువాత కూడా సంకేతపదాన్ని గుర్తుంచుకోమంటారా",
index d58e1e0..0442149 100644 (file)
        "editcomment": "Хулосаи вироиш ин буд: <em>$1</em>.",
        "revertpage": "Вироиши [[Special:Contributions/$2|$2]] ([[User talk:$2|Баҳс]]) вогардонида шуд ба охирин тағйире, ки [[User:$1|$1]] анҷом дода буд",
        "rollback-success": "Вироишҳои $1 вогардонӣ шуд; саҳифа ба вироиши $2 баргардонида шуд.",
-       "rollback-success-notify": "Вироишоти $1 вогардонида шуд ба охирин вироише, ки  $2 анҷом дода буд. [$3 Намоиши тавофут]",
        "sessionfailure": "Ба назар мерасад, мушкилие дар мавриди нишасти корбарии шумо вуҷуд дорад; амали дархостшуда ба унвони иқдоми пешгирона дар баробари рабуда шудани иттилооти нишасти корбарӣ, лағв шуд. Лутфан тугмаи \"бозгашт\"-ро дар мурургари худ пахш кунед ва саҳифае, ки аз он инҷо расидаед муҷаддадан фарохонӣ кунед, сипас муҷаддадан боз саъй кунед.",
        "protectlogpage": "Гузориши муҳофизат",
        "protectlogtext": "Дар зер феҳристи қуфл карданҳо ва аз қуфл озод шуданҳо омада аст. Барои иттилооти бештар ба [[Special:ProtectedPages|феҳристи саҳифаҳои муҳофизатшуда]] нигаред.",
index a3ce556..64ec265 100644 (file)
        "index-category": "หน้าที่มีดัชนี",
        "noindex-category": "หน้าที่ไม่มีดัชนี",
        "broken-file-category": "หน้าที่มีลิงก์ไฟล์เสีย",
+       "categoryviewer-pagedlinks": "($1) ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "เกี่ยวกับ",
        "article": "หน้าเนื้อหา",
        "newwindow": "(เปิดหน้าต่างใหม่)",
        "moredotdotdot": "ดูเพิ่ม...",
        "morenotlisted": "รายการนี้อาจไม่สมบูรณ์",
        "mypage": "หน้า",
-       "mytalk": "à¸\9eูà¸\94à¸\84ุย",
-       "anontalk": "à¸\9eูà¸\94à¸\84ุย",
+       "mytalk": "คุย",
+       "anontalk": "คุย",
        "navigation": "การนำทาง",
        "and": "&#32;และ",
        "faq": "คำถามที่พบบ่อย",
        "versionrequired": "ต้องการมีเดียวิกิรุ่น $1",
        "versionrequiredtext": "การใช้หน้านี้ต้องการมีเดียวิกิรุ่น $1  ดู[[Special:Version|หน้ารุ่น]]",
        "ok": "ตกลง",
+       "pagetitle": "$1 - {{SITENAME}}",
+       "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "← $1",
        "retrievedfrom": "ดึงข้อมูลจาก \"$1\"",
        "youhavenewmessages": "คุณมี$1 ($2)",
        "youhavenewmessagesfromusers": "คุณมี $1จาก{{PLURAL:$3|ผู้ใช้คนอื่น|ผู้ใช้ $3 คน}} ($2)",
        "site-atom-feed": "ฟีดอะตอม $1",
        "page-rss-feed": "ฟีดอาร์เอสเอส \"$1\"",
        "page-atom-feed": "ฟีดอะตอม \"$1\"",
+       "feed-atom": "อะตอม",
+       "feed-rss": "RSS",
        "red-link-title": "$1 (ไม่มีหน้า)",
        "sort-descending": "เรียงจากมากไปน้อย",
        "sort-ascending": "เรียงจากน้อยไปมาก",
        "perfcachedts": "ข้อมูลต่อไปนี้ถูกเก็บในแคชและถูกปรับล่าสุดเมื่อ $1 มีผลลัพธ์สูงสุด $4 รายการในแคชได้",
        "querypage-no-updates": "ขณะนี้ปิดใช้งานการปรับหน้านี้ \nข้อมูลในที่นี้จะไม่รีเฟรชเป็นปัจจุบัน",
        "viewsource": "ดูต้นฉบับ",
-       "viewsource-title": "à¸\94ูà¹\82à¸\84à¹\89à¸\94สำหรับ $1",
+       "viewsource-title": "à¸\94ูà¸\95à¹\89à¸\99à¸\89à¸\9aัà¸\9aสำหรับ $1",
        "actionthrottled": "ปฏิบัติการถูกจำกัด",
        "actionthrottledtext": "เพื่อเป็นมาตรการป้องกันการละเมิด คุณจึงถูกจำกัดมิให้กระทำสิ่งนี้ติดต่อกันหลายครั้งเกินไปในช่วงระยะเวลาสั้น ๆ ซึ่งขณะนี้คุณเลยขีดจำกัดนี้แล้ว \nกรุณารอสักครู่แล้วลองอีกครั้ง",
        "protectedpagetext": "หน้านี้ถูกล็อกเพื่อป้องกันการแก้ไขหรือปฏิบัติการอื่น",
        "badretype": "รหัสผ่านที่คุณกรอกไม่ตรง",
        "usernameinprogress": "การสร้างบัญชีสำหรับชื่อผู้ใช้นี้อยู่ระหว่างดำเนินการแล้ว\nโปรดรอสักครู่",
        "userexists": "ชื่อผู้ใช้ที่กรอกมีผู้ใช้แล้ว \nกรุณาเลือกชื่ออื่น",
+       "createacct-normalization": "ชื่อผู้ใช้ของคุณจะถูกปรับเป็น\"$2\"เนื่องจากข้อจำกัดทางเทคนิค",
        "loginerror": "ข้อผิดพลาดในการเข้าสู่ระบบ",
        "createacct-error": "การสร้างบัญชีผิดพลาด",
        "createaccounterror": "ไม่สามารถสร้างบัญชี: $1",
        "nocookiesnew": "สร้างบัญชีผู้ใช้แล้ว แต่ยังไม่ได้เข้าสู่ระบบ \n{{SITENAME}} ใช้คุกกี้เพื่อนำผู้ใช้เข้าสู่ระบบ\nคุณปิดใช้งานคุกกี้\nโปรดเปิดใช้งาน แล้วเข้าสู่ระบบพร้อมชื่อผู้ใช้และรหัสผ่านใหม่ของคุณ",
        "nocookieslogin": "{{SITENAME}} ใช้คุกกี้เพื่อล็อกอินผู้ใช้\nคุณปิดใช้งานคุกกี้\nกรุณาเปิดใช้งานและลองอีกครั้ง",
        "nocookiesfornew": "บัญชีผู้ใช้ไม่ถูกสร้าง เนื่องจากเราไม่สามารถยืนยันต้นทาง\nกรุณาทำให้แน่ใจว่าคุณได้เปิดใช้งานคุกกี้ โหลดหน้านี้ใหม่และลองอีกครั้ง",
+       "nocookiesforlogin": "{{int:nocookieslogin}}",
        "createacct-loginerror": "บัญชีผู้ใช้ถูกสร้างสำเร็จแล้ว แต่คุณไม่สามารถเข้าสู่ระบบได้โดยอัตโนมัติ โปรด[[Special:UserLogin|เข้าสู่ระบบด้วยตนเอง]]",
        "noname": "คุณไม่ได้ใส่ชื่อผู้ใช้ที่ถูกต้อง",
        "loginsuccesstitle": "เข้าสู่ระบบแล้ว",
        "cannotchangeemail": "ไม่สามารถเปลี่ยนที่อยู่อีเมลบนวิกินี้",
        "emaildisabled": "เว็บไซต์นี้ไม่สามารถส่งอีเมล",
        "accountcreated": "สร้างบัญชีแล้ว",
-       "accountcreatedtext": "สรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89สำหรัà¸\9a [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|à¸\9eูà¸\94à¸\84ุย]]) à¹\81ลà¹\89ว",
+       "accountcreatedtext": "สร้างบัญชีผู้ใช้สำหรับ [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|คุย]]) แล้ว",
        "createaccount-title": "การสร้างบัญชีสำหรับ {{SITENAME}}",
        "createaccount-text": "มีบางคนสร้างบัญชีโดยใช้ที่อยู่อีเมลของคุณบน {{SITENAME}} ($4) โดยใช้ชื่อ \"$2\" และรหัสผ่าน \"$3\" \nคุณควรเข้าสู่ระบบและเปลี่ยนรหัสผ่านทันที\n\nคุณอาจเพิกเฉยข้อความนี้ หากการสร้างบัญชีนี้เป็นความผิดพลาด",
        "login-throttled": "ที่ผ่านมาคุณพยายามล็อกอินมากครั้งเกินไป\nกรุณารอ $1 ก่อนลองอีกครั้ง",
        "template-semiprotected": "(ถูกกึ่งป้องกัน)",
        "hiddencategories": "หน้านี้มี {{PLURAL:$1|1 หมวดหมู่ซ่อน|$1 หมวดหมู่ซ่อน}}:",
        "edittools": "<!-- ข้อความนี้จะแสดงผลใต้ฟอร์มสำหรับการแก้ไขและอัปโหลด -->",
+       "edittools-upload": "-",
        "nocreatetext": "{{SITENAME}} ได้จำกัดการสร้างหน้าใหม่\nคุณสามารถย้อนกลับไปแก้ไขหน้าที่มีอยู่เดิม หรือ[[Special:UserLogin|เข้าสู่ระบบหรือสร้างบัญชีผู้ใช้]]",
        "nocreate-loggedin": "คุณไม่มีสิทธิสร้างหน้าใหม่",
        "sectioneditnotsupported-title": "ไม่สนับสนุนการแก้ไขหัวข้อย่อย",
        "content-model-text": "ข้อความธรรมดา",
        "content-model-javascript": "จาวาสคริปต์",
        "content-model-css": "CSS",
+       "content-model-json": "JSON",
        "content-json-empty-object": "วัตถุเปล่า",
        "content-json-empty-array": "แถวเปล่า",
        "deprecated-self-close-category": "หน้าที่ใช้ป้าย HTML ที่ปิดเองที่ไม่ถูกต้อง",
        "mergehistory-comment": "ผสาน [[:$1]] เข้ากับ [[:$2]] แล้ว: $3",
        "mergehistory-same-destination": "หน้าต้นทางและปลายทางเป็นหน้าเดียวกันไม่ได้",
        "mergehistory-reason": "เหตุผล:",
+       "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "ปูมการผสาน",
        "revertmerge": "เลิกผสาน",
        "mergelogpagetext": "ด้านล่างนี้เป็นรายการการผสานประวัติหน้าหนึ่งกับของอีกหน้าหนึ่งล่าสุด",
        "prefs-namespaces": "เนมสเปซ",
        "default": "ค่าเริ่มต้น",
        "prefs-files": "ไฟล์",
-       "prefs-custom-css": "สไตล์ชีตปรับแต่งเอง",
+       "prefs-custom-css": "CSS กำหนดเอง",
        "prefs-custom-json": "JSON กำหนดเอง",
-       "prefs-custom-js": "à¸\88าวาสà¸\84ริà¸\9bà¸\95à¹\8cà¸\9bรัà¸\9aà¹\81à¸\95à¹\88à¸\87เอง",
+       "prefs-custom-js": "à¸\88าวาสà¸\84ริà¸\9bà¸\95à¹\8cà¸\81ำหà¸\99à¸\94เอง",
        "prefs-common-config": "CSS/JSON/จาวาสคริปต์รวมสำหรับทุกหน้าตา:",
        "prefs-reset-intro": "คุณสามารถใช้หน้านี้ตั้งการตั้งค่าของคุณเป็นค่าปริยายของเว็บใหม่\nไม่สามารถทำกลับได้",
        "prefs-emailconfirm-label": "การยืนยันอีเมล:",
        "youremail": "อีเมล:",
        "username": "{{GENDER:$1|ชื่อผู้ใช้}}:",
        "prefs-memberingroups": "เป็น{{GENDER:$2|สมาชิก}}ใน{{PLURAL:$1|กลุ่ม|กลุ่ม}}:",
+       "prefs-memberingroups-type": "$1",
        "group-membership-link-with-expiry": "$1 (จนกระทั่ง $2)",
        "prefs-registration": "เวลาลงทะเบียน:",
+       "prefs-registration-date-time": "$1",
        "yourrealname": "ชื่อจริง:",
        "yourlanguage": "ภาษา:",
        "yourvariant": "อักษรต่างรูปของเนื้อหา:",
        "saveusergroups": "บันทึกกลุ่ม{{GENDER:$1|ผู้ใช้}}",
        "userrights-groupsmember": "สมาชิกของ:",
        "userrights-groupsmember-auto": "สมาชิกโดยปริยายของ:",
+       "userrights-groupsmember-type": "$1",
        "userrights-groups-help": "คุณสามารถเปลี่ยนแปลงกลุ่มที่ผู้ใช้รายนี้อยู่:\n* กล่องที่มีเครื่องหมายถูก หมายความว่า ผู้ใช้อยู่ในกลุ่มนั้น\n* กล่องที่ไม่มีเครื่องหมายถูก หมายความว่า ผู้ใช้ไม่ได้อยู่ในกลุ่มนั้น\n* เครื่องหมาย * ชี้ว่าคุณไม่สามารถนำกลุ่มนั้นออกได้เมื่อคุณเพิ่มกลุ่มนั้นไปแล้ว หรือกลับกัน\n* เครื่องหมาย # บี้ว่าคุณสามารถแก้คืนเวลาหมดอายุของสมาชิกภาพกลุ่มนี้เท่านั้น คุณไม่สามารถร่นเวลาหมดอายุได้",
        "userrights-reason": "เหตุผล:",
        "userrights-no-interwiki": "คุณไม่มีสิทธิแก้ไขสิทธิผู้ใช้บนวิกิอื่น",
        "userrights-nodatabase": "ไม่มีฐานข้อมูล $1 หรือฐานข้อมูลอยู่บนเครื่องอื่น",
        "userrights-changeable-col": "กลุ่มที่คุณสามารถเปลี่ยนได้",
        "userrights-unchangeable-col": "กลุ่มที่คุณไม่สามารถเปลี่ยนได้",
+       "userrights-irreversible-marker": "$1*",
        "userrights-expiry-current": "หมดอายุ $1",
        "userrights-expiry-none": "ไม่มีวันหมดอายุ",
        "userrights-expiry": "หมดอายุ:",
        "group-bot": "บอต",
        "group-sysop": "ผู้ดูแลระบบ",
        "group-interface-admin": "ผู้ดูแลระบบอินเตอร์เฟซ",
-       "group-bureaucrat": "à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9aสิà¸\97à¸\98ิà¹\8cà¹\81à¸\95à¹\88à¸\87à¸\95ัà¹\89à¸\87",
+       "group-bureaucrat": "ผู้ดูแลระบบสิทธิแต่งตั้ง",
        "group-suppress": "ผู้ดูแลประวัติ",
        "group-all": "(ทั้งหมด)",
        "group-user-member": "{{GENDER:$1|ผู้ใช้}}",
        "group-bot-member": "{{GENDER:$1|บอต}}",
        "group-sysop-member": "{{GENDER:$1|ผู้ดูแลระบบ}}",
        "group-interface-admin-member": "{{GENDER:$1|ผู้ดูแลระบบอินเตอร์เฟซ}}",
-       "group-bureaucrat-member": "{{GENDER:$1|à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9aสิà¸\97à¸\98ิà¹\8cà¹\81à¸\95à¹\88à¸\87à¸\95ัà¹\89à¸\87}}",
+       "group-bureaucrat-member": "{{GENDER:$1|ผู้ดูแลระบบสิทธิแต่งตั้ง}}",
        "group-suppress-member": "{{GENDER:$1|ผู้ดูแลประวัติ}}",
        "grouppage-user": "{{ns:project}}:ผู้ใช้",
        "grouppage-autoconfirmed": "{{ns:project}}:ผู้ใช้ยืนยันอัตโนมัติ",
        "grouppage-bot": "{{ns:project}}:บอต",
        "grouppage-sysop": "{{ns:project}}:ผู้ดูแลระบบ",
        "grouppage-interface-admin": "{{ns:project}}:ผู้ดูแลระบบอินเตอร์เฟซ",
-       "grouppage-bureaucrat": "{{ns:project}}:à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9aสิà¸\97à¸\98ิà¹\8cà¹\81à¸\95à¹\88à¸\87à¸\95ัà¹\89à¸\87",
+       "grouppage-bureaucrat": "{{ns:project}}:ผู้ดูแลระบบสิทธิแต่งตั้ง",
        "grouppage-suppress": "{{ns:project}}:ผู้ดูแลประวัติ",
        "right-read": "อ่านหน้า",
        "right-edit": "แก้ไขหน้า",
        "recentchanges-label-plusminus": "ขนาดของหน้าเปลี่ยนไปจำนวนไบต์เท่านี้",
        "recentchanges-legend-heading": "<strong>คำอธิบายสัญลักษณ์:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ดูเพิ่มที่ [[Special:NewPages|รายชื่อหน้าใหม่]])",
+       "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "แสดง",
        "rcfilters-tag-remove": "ลบ '$1'",
        "rcfilters-legend-heading": "<strong>รายการอักษรย่อ:</strong>",
        "boteditletter": "บ",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 ผู้ใช้เฝ้าดู]",
+       "rc-change-size": "$1",
        "rc-change-size-new": "$1 ไบต์หลังเปลี่ยนแปลง",
        "newsectionsummary": "/* $1 */ ส่วนใหม่",
        "rc-enhanced-expand": "แสดงรายละเอียด",
        "upload-scripted-pi-callback": "ไม่สามารถอัปโหลดไฟล์ที่มีคำสั่งการประมวลผลสไตล์ชีต XML",
        "upload-scripted-dtd": "ไม่สามารถอัปโหลดไฟล์ SVG ที่มีการประกาศ DTD ที่ไม่ได้มาตรฐาน",
        "uploaded-script-svg": "พบองค์ประกอบที่สามารถใช้สคริปต์ \"$1\" ในไฟล์ SVG ที่อัปโหลด",
+       "uploaded-hostile-svg": "พบ CSS ที่ไม่ปลอดภัยในองค์ประกอบสไตล์ของไฟล์ SVG ที่คุณอัปโหลด",
+       "uploaded-event-handler-on-svg": "ไม่อนุญาตให้ตั้งค่าแอตทริบิวต์ตัวจัดการเหตุการณ์ <code>$1=\"$2\"</code> ในไฟล์ SVG",
+       "uploaded-href-unsafe-target-svg": "พบว่า href เป็นข้อมูลที่ไม่ปลอดภัย:URI เป้าหมาย <code>&lt;$1 $2=\"$3\"&gt;</code> ใน SVG ไฟล์ที่อัพโหลด",
        "uploadscriptednamespace": "ไฟล์ SVG นี้มีเนมสเปซไม่ถูกต้อง \"<nowiki>$1</nowiki>\"",
        "uploadinvalidxml": "ไม่สามารถตีความ XML ในไฟลืที่อัปโหลด",
        "uploadvirus": "ไฟล์นี้มีไวรัส! \nรายละเอียด: $1",
        "categoriesfrom": "แสดงหมวดหมู่เริ่มจาก:",
        "deletedcontributions": "การเข้ามีส่วนร่วมของผู้ใช้ที่ถูกลบ",
        "deletedcontributions-title": "การเข้ามีส่วนร่วมของผู้ใช้ที่ถูกลบ",
-       "sp-deletedcontributions-contribs": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88มีส่วนร่วม",
+       "sp-deletedcontributions-contribs": "à¸\81ารà¹\80à¸\82à¹\89ามีส่วนร่วม",
        "linksearch": "ค้นหาลิงก์ภายนอก",
        "linksearch-pat": "รูปแบบการค้นหา:",
        "linksearch-ns": "เนมสเปซ:",
        "listgrouprights-summary": "ด้านล่างเป็นรายการกลุ่มผู้ใช้ที่นิยามบนวิกินี้ และสิทธิการเข้าถึงที่เกี่ยวข้อง\nอาจมี[[{{MediaWiki:Listgrouprights-helppage}}|ข้อมูลเพิ่มเติม]]เกี่ยวกับสิทธิหนึ่ง ๆ",
        "listgrouprights-key": "คำอธิบาย:\n* <span class=\"listgrouprights-granted\">สิทธิที่ได้รับแต่งตั้ง</span>\n* <span class=\"listgrouprights-revoked\">สิทธิที่ถูกเพิกถอน</span>",
        "listgrouprights-group": "กลุ่ม",
-       "listgrouprights-rights": "สิทธิ",
+       "listgrouprights-rights": "สิทธิ",
        "listgrouprights-helppage": "Help:สิทธิกลุ่ม",
        "listgrouprights-members": "(รายการสมาชิก)",
        "listgrouprights-addgroup": "เพิ่ม{{PLURAL:$2|กลุ่มนี้|กลุ่มเหล่านี้}}: $1",
        "listgrouprights-namespaceprotection-restrictedto": "สิทธิอนุญาตให้ผู้ใช้แก้ไข",
        "listgrants": "การให้สิทธิ",
        "listgrants-grant": "การให้สิทธิ",
-       "listgrants-rights": "สิทธิ",
+       "listgrants-rights": "สิทธิ",
        "trackingcategories": "หมวดหมู่ค้นหาและติดตาม",
        "trackingcategories-summary": "หน้านี้แสดงรายการหมวดหมู่ค้นหาและติดตามซึ่งซอฟต์แวร์มีเดียวิกิจัดการอัตโนมัติ สามารถเปลี่ยนชื่อเหล่านี้ได้โดยการเปลี่ยนข้อความระบบที่เกี่ยวข้องในเนมสเปซ {{ns:8}}",
        "trackingcategories-msg": "หมวดหมู่ค้นหาและติดตาม",
        "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-notify": "ย้อนการแก้ไขโดย $1;\nเปลี่ยนกลับไปรุ่นล่าสุดโดย $2 [$3 แสดงการเปลี่ยนแปลง]",
+       "rollback-success": "ย้อนการแก้ไขโดย {{GENDER:$3|$1}};\nเปลี่ยนกลับไปรุ่นล่าสุดโดย {{GENDER:$4|$2}}",
        "sessionfailure-title": "เซสชันล้มเหลว",
        "sessionfailure": "ดูเหมือนมีปัญหากับเซสชันการเข้าสู่ระบบของคุณ\nการกระทำนี้ถูกยกเลิกเพื่อเป็นการป้องกันการลักลอบเซสชันไว้ก่อน \nกรุณากรอกแบบฟอร์มใหม่อีกครั้ง",
        "changecontentmodel-title-label": "ชื่อหน้า:",
        "movedarticleprotection": "ย้ายการตั้งค่าการล็อกจาก \"[[$2]]\" ไป \"[[$1]]\"",
        "protectedarticle-comment": "ป้องกัน \"[[$1]]\"",
        "modifiedarticleprotection-comment": "{{GENDER:$2|}}เปลี่ยนระดับการล็อกสำหรับ \"[[$1]]\"",
-       "unprotectedarticle-comment": "{{GENDER:$2|}}ปลดล็อก \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|ยกเลิกการป้องกัน}}จาก \"[[$1]]\"",
        "protect-title": "เปลี่ยนระดับการล็อกสำหรับ \"$1\"",
        "protect-title-notallowed": "ดูระดับการล็อกของ \"$1\"",
        "prot_1movedto2": "ย้าย [[$1]] เป็น [[$2]]",
        "log-action-filter-newusers-byemail": "การสร้างโดยรหัสผ่านที่ส่งทางอีเมล",
        "log-action-filter-patrol-patrol": "การตรวจสอบหน้าด้วยมือ",
        "log-action-filter-patrol-autopatrol": "การตรวจสอบหน้าอัตโนมัติ",
-       "log-action-filter-protect-protect": "à¸\81ารลà¹\87อà¸\81",
-       "log-action-filter-protect-modify": "à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\81ารลà¹\87อà¸\81",
-       "log-action-filter-protect-unprotect": "à¸\9bลà¸\94ลà¹\87อà¸\81",
-       "log-action-filter-protect-move_prot": "à¸\81ารลà¹\87อà¸\81ที่ถูกย้าย",
+       "log-action-filter-protect-protect": "à¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99",
+       "log-action-filter-protect-modify": "à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99",
+       "log-action-filter-protect-unprotect": "à¹\80ลิà¸\81à¸\9bà¹\89อà¸\87à¸\81ัà¸\99",
+       "log-action-filter-protect-move_prot": "à¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99ที่ถูกย้าย",
        "log-action-filter-rights-rights": "การเปลี่ยนด้วยมือ",
        "log-action-filter-rights-autopromote": "การเปลี่ยนอัตโนมัติ",
        "log-action-filter-suppress-event": "การระงับปูม",
        "authmanager-create-no-primary": "เอกสารทางการที่ให้ไม่สามารถใช้สำหรับการสร้างบัญชีได้",
        "authmanager-link-no-primary": "เอกสารทางการที่ให้ไม่สามารถใช้สำหรับการเชื่อมโยงบัญชี",
        "authmanager-link-not-in-progress": "ไม่อยู่ระหว่างการโยงบัญชีหรือข้อมูลเซสชันสูญหาย กรุณาเริ่มใหม่ตั้งแต่ต้น",
-       "authmanager-authplugin-setpass-failed-title": "การเปลี่ยนรหัสผ่านล้มเหลว",
-       "authmanager-authplugin-setpass-failed-message": "ปลั๊กอินการพิสูจน์ตัวจริงปฏิเสธการเปลี่ยนรหัสผ่าน",
-       "authmanager-authplugin-create-fail": "ปลั๊กอินการพิสูจน์ตัวจริงปฏิเสธการสร้างบัญชี",
-       "authmanager-authplugin-setpass-denied": "ปลั๊กอินการพิสูจน์ตัวจริงไม่อนุญาตการเปลี่ยนรหัสผ่าน",
-       "authmanager-authplugin-setpass-bad-domain": "โดเมนไม่สมเหตุสมผล",
        "authmanager-autocreate-noperm": "ไม่อนุญาตการสร้างบัญชีอัตโนมัติ",
        "authmanager-autocreate-exception": "ปิดใช้งานการสร้างบัญชีอัตโนมัติชั่วคราวเนื่องจากข้อผิดพลาดก่อนหน้านี้",
        "authmanager-userdoesnotexist": "บัญชีผู้ใช้ \"$1\"ยังไม่ลงทะเบียน",
index da0033c..7373150 100644 (file)
        "tog-norollbackdiff": "Eski hâline getirdikten sonra farkı gösterme",
        "tog-useeditwarning": "Bir düzenleme sayfasından değişiklikleri kaydetmeden ayrılırken beni uyar",
        "tog-prefershttps": "Oturum açıkken her zaman güvenli bir bağlantı kullan",
+       "tog-showrollbackconfirmation": "Geri alma bağlantısına tıkladığınızda bir onay istemi gösterin",
        "underline-always": "Her zaman",
        "underline-never": "Hiçbir zaman",
        "underline-default": "Görünüm ya da tarayıcı varsayılanı",
        "watchlistanontext": "Lütfen izleme listenizdeki maddeleri görmek ya da değiştirmek için oturum açın.",
        "watchnologin": "Oturum açık değil.",
        "addwatch": "İzleme listesine ekle",
-       "addedwatchtext": "\"[[:$1]]\" sayfası [[Special:Watchlist|izleme listenize]] eklenmiştir.\nBundan sonra, bu sayfaya ve ilgili tartışma sayfasına yapılacak değişiklikler burada listelenecek.",
+       "addedwatchtext": "\"[[:$1]]\" ve ona ait tartışma sayfası [[Special:Watchlist|izleme listenize]] eklenmiştir.",
        "addedwatchtext-short": "\"$1\" sayfası izleme listenize eklendi.",
        "removewatch": "İzleme listesinden kaldır",
-       "removedwatchtext": "\"[[:$1]]\" sayfası, tartışma sayfası ile birlikte [[Special:Watchlist|izleme listenizden]] silinmiştir.",
+       "removedwatchtext": "\"[[:$1]]\" ve ona ait tartışma sayfası ile birlikte [[Special:Watchlist|izleme listenizden]] silinmiştir.",
        "removedwatchtext-short": "\"$1\" sayfası izleme listenizden çıkarıldı.",
        "watch": "izle",
        "watchthispage": "Sayfayı izle",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}} için katkılar",
        "ipb-blocklist-duration-left": "$1 ayrıldı",
        "block-expiry": "Bitiş süresi",
+       "block-target": "Kullanıcı adı veya IP adresi:",
        "unblockip": "Kullanıcının engellemesini kaldır",
        "unblockiptext": "Daha önceden engellenmiş bir IP adresine ya da kullanıcı adına yazma erişimini geri vermek için aşağıdaki formu kullanın.",
        "ipusubmit": "Bu engellemeyi kaldır",
        "emailblock": "e-posta engellendi",
        "blocklist-nousertalk": "kendi mesaj sayfasını değiştiremez",
        "blocklist-editing-sitewide": "düzenleme (site geneli)",
+       "blocklist-editing-page": "sayfalar",
+       "blocklist-editing-ns": "ad alanı",
        "ipblocklist-empty": "Engelleme listesi boş.",
        "ipblocklist-no-results": "İstenen IP adresi ya da kullanıcı adı engellenmedi.",
        "blocklink": "engelle",
        "expand_templates_generate_xml": "XML derleyici ağacını göster",
        "expand_templates_generate_rawhtml": "Ham HTML göster",
        "expand_templates_preview": "Önizleme",
-       "expand_templates_preview_fail_html": "<em>{{SITENAME}} işlenmemiş HTML koduna izin verdiği ve oturum verilerinde kayıp yaşandığı için, ön izleme, JavaScript saldırılarına karşı önlem olarak gizlendi.</em>\n\n<strong>Eğer meşru bir ön izleme girişimi idiyse, tekrar deneyiniz.</strong>\nYine de çalışmıyorsa, [[Special:UserLogout|oturum kapamayı]] ve tekrar açmayı deneyin.",
+       "expand_templates_preview_fail_html": "<em>{{SITENAME}} işlenmemiş HTML koduna izin verdiği ve oturum verilerinde kayıp yaşandığı için, ön izleme, JavaScript saldırılarına karşı önlem olarak gizlendi.</em>\n\n<strong>Eğer bu meşru bir ön izleme girişimi idiyse, tekrar deneyiniz.</strong>\nYine de çalışmıyorsa, [[Special:UserLogout|oturum kapatıp]] tekrar açmayı deneyin ve tarayıcınızın bu siteden çerezlere izin verip vermediğini kontrol edin.",
        "expand_templates_preview_fail_html_anon": "<em>{{SITENAME}} işlenmemiş HTML koduna izin verdiği ve oturum verilerinde kayıp yaşandığı için, ön izleme, JavaScript saldırılarına karşı önlem olarak gizlendi.</em>\n\n<strong>Eğer meşru bir ön izleme girişimi idiyse, lütfen  [[Special:UserLogin|oturum açarak]] tekrar deneyin.</strong>",
        "expand_templates_input_missing": "En azından bazı giriş viki metni sağlamak zorundasınız.",
        "pagelanguage": "Sayfanın dilini değiştir",
        "log-action-filter-protect-move_prot": "Taşıma koruması",
        "log-action-filter-upload-upload": "Yeni yükleme",
        "log-action-filter-upload-overwrite": "Yeniden yükle",
-       "authmanager-authplugin-setpass-bad-domain": "Geçersiz alanadı.",
        "authmanager-autocreate-noperm": "Otomatik kullanıcı oluşturma izni yok.",
        "authmanager-userdoesnotexist": "\"$1\" kullanıcı hesabı kayıtlı değil.",
        "authmanager-email-label": "E-posta",
index f69d3e4..9c5db0f 100644 (file)
@@ -77,7 +77,9 @@
                        "Fitoschido",
                        "Movses",
                        "Esk78",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "Олександр М.",
+                       "Gzhegozh"
                ]
        },
        "tog-underline": "Підкреслювання посилань:",
        "tog-norollbackdiff": "Не показувати різницю версій після виконання відкоту",
        "tog-useeditwarning": "Попереджати мене, якщо я залишаю сторінку редагування з незбереженими змінами",
        "tog-prefershttps": "Завжди використовувати безпечне з'єднання при вході в систему",
+       "tog-showrollbackconfirmation": "Показати підтверджувальне вікно при натисканні на посилання відкоту",
        "underline-always": "Завжди",
        "underline-never": "Ніколи",
        "underline-default": "Використовувати налаштування браузера",
        "help-mediawiki": "Допомога про MediaWiki",
        "search": "Пошук",
        "search-ignored-headings": " #<!-- залиште цей рядок точно таким, яким він є --> <pre>\n# Заголовки, які будуть ігноруватися при пошуці.\n# Зміни, які набирають сили при індексуванні сторінки з заголовком.\n# Ви можете примусити переіндексувати сторінку з нульовим редагуванням.\n# Синтаксис наступний:\n#   * Усе, що починається з символу \"#\" до кінця рядка, є коментарем\n#   * Кожний непорожній рядок є точним заголовком для ігнорування\nПримітки\nПосилання\nДив. також\n #</pre> <!-- залиште цей рядок точно таким, яким він є -->",
-       "searchbutton": "Ð\9fоÑ\88Ñ\83к",
+       "searchbutton": "Ð\97найÑ\82и",
        "go": "Перейти",
        "searcharticle": "Перейти",
        "history": "Історія сторінки",
        "badretype": "Введені паролі не збігаються.",
        "usernameinprogress": "Створення облікового запису для цього імені користувача уже виконується.\nБудь ласка, зачекайте.",
        "userexists": "Введене ім'я користувача вже існує.\nБудь ласка оберіть інше ім'я.",
+       "createacct-normalization": "Ваше ім'я користувача буде скориговано на «$2» через технічні обмеження.",
        "loginerror": "Помилка при вході до системи",
        "createacct-error": "Помилка створення облікового запису",
        "createaccounterror": "Не в змозі створити обліковий запис: $1",
        "right-reupload-own": "перезаписування існуючих файлів, завантажених тим самим користувачем",
        "right-reupload-shared": "підміна файлів зі спільного сховища локальними",
        "right-upload_by_url": "завантаження файлів за URL-адресами",
-       "right-purge": "очищення кешу сторінки без необхідності підтвердження",
+       "right-purge": "очищення кешу сторінки",
        "right-autoconfirmed": "без обмежень швидкості за IP",
        "right-bot": "автоматична обробка",
        "right-nominornewtalk": "незначні редагування на сторінках обговорень користувачів не викликають попередження про нові повідомлення",
        "upload-scripted-pi-callback": "Неможливо завантажити файл, що містить інструкції опрацювання таблиці стилів XML.",
        "upload-scripted-dtd": "Неможливо завантажувати SVG-файли, які містять нестандартну декларацію DTD.",
        "uploaded-script-svg": " \t\t\nЗнайдений небезпечний елемент з підтримкою сценаріїв «$1» в завантаженому файлі SVG.",
-       "uploaded-hostile-svg": " \t\nЗнайдений небезпечний CSS-код в елементі стилю завантаженого файлу SVG.",
+       "uploaded-hostile-svg": "Знайдений небезпечний CSS-код в елементі стилю завантаженого файлу SVG.",
        "uploaded-event-handler-on-svg": " \t\nУстановка атрибутів обробника подій <code>$1=\"$2\"</code> не дозволено для SVG-файлів.",
        "uploaded-href-attribute-svg": "<a> елементи можуть лише посилатися (href) на цілі типу data: (вбудований файл), http:// або https://, або ж fragment (#, same-document). Для інших елементів, таких як <image>, дозволені лише data: і fragment. Спробуйте вбудовувати зображення при експортуванні Вашого файлу SVG. Знайдено <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-href-unsafe-target-svg": "У завантаженому SVG-файлі знайдено href на небезпечні дані: ціль URI <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "logeventslist-tag-log": "Журнал міток",
        "all-logs-page": "Усі публічні журнали",
        "alllogstext": "Комбінований показ журналів {{grammar:genitive|{{SITENAME}}}}.\nВи можете відфільтрувати результати за типом журналу, іменем користувача (враховується регістр) або зазначеною сторінкою (також враховується регістр).",
-       "logempty": "У Ð¶Ñ\83Ñ\80налÑ\96 Ð½ÐµÐ¼Ð°Ñ\94 Ð¿Ð¾Ð´Ñ\96бних записів.",
+       "logempty": "У Ð¶Ñ\83Ñ\80налÑ\96 Ð½ÐµÐ¼Ð°Ñ\94 Ð²Ñ\96дповÑ\96дних записів.",
        "log-title-wildcard": "Знайти заголовки, що починаються з цих символів",
        "showhideselectedlogentries": "Показати/приховати виділені записи журналу",
        "log-edit-tags": "Змінити мітки для вибраних записів журналів",
        "unwatchthispage": "Скасувати спостереження",
        "notanarticle": "Не стаття",
        "notvisiblerev": "Версія була вилучена",
-       "watchlist-details": "У Ð\92аÑ\88омÑ\83 Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f $1 {{PLURAL:$1|Ñ\81Ñ\82оÑ\80Ñ\96нка|Ñ\81Ñ\82оÑ\80Ñ\96нки|Ñ\81Ñ\82оÑ\80Ñ\96нок}} (плÑ\8eÑ\81 сторінки обговорення).",
+       "watchlist-details": "У Ð\92аÑ\88омÑ\83 Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f $1 {{PLURAL:$1|Ñ\81Ñ\82оÑ\80Ñ\96нка|Ñ\81Ñ\82оÑ\80Ñ\96нки|Ñ\81Ñ\82оÑ\80Ñ\96нок}} (а Ñ\89е сторінки обговорення).",
        "wlheader-enotif": "Сповіщення електронною поштою ввімкнено.",
        "wlheader-showupdated": "Сторінки, що змінилися після Вашого останнього їх відвідування, виділені '''жирним''' шрифтом.",
        "wlnote": "Нижче наведено {{PLURAL:$1|останнє $1 редагування|останні $1 редагування|останні $1 редагувань}} за {{PLURAL:$2|останню|останні|останні}} <strong>$2</strong> {{PLURAL:$2|годину|години|годин}}, на час $3 $4.",
        "deleting-backlinks-warning": "<strong>Попередження:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|інші сторінки]] посилаються або містять сторінку, яку Ви маєте намір видалити.",
        "deleting-subpages-warning": "<strong>Попередження:</strong> Сторінка, яку Ви маєте намір вилучити, має [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1 підсторінку|$1 підсторінки|$1 підсторінок|51=понад 50 підсторінок}}]].",
        "rollback": "Відкинуто редагування",
+       "rollback-confirmation-confirm": "Будь ласка, підтвердіть:",
+       "rollback-confirmation-yes": "Відкинути",
+       "rollback-confirmation-no": "Скасувати",
        "rollbacklink": "відкинути",
        "rollbacklinkcount": "відкинути $1 {{PLURAL:$1|редагування|редагування|редагувань}}",
        "rollbacklinkcount-morethan": "відкинути понад $1 {{PLURAL:$1|редагування|редагування|редагувань}}",
        "revertpage": "Відкинуто редагування [[Special:Contributions/$2|$2]] ([[User talk:$2|обговорення]]) до зробленого [[User:$1|$1]]",
        "revertpage-nouser": "Відкинуто редагування прихованого користувача до останньої версії, зробленої {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Відкинуті редагування {{GENDER:$3|користувача|користувачки}} $1; повернення до версії {{GENDER:$4|користувача|користувачки}} $2.",
-       "rollback-success-notify": "Відкинуті редагування користувача $1; \nповернено до останньої версії користувача $2. [$3 Показати зміни]",
        "sessionfailure-title": "Помилка сеансу",
        "sessionfailure": "Здається, виникли проблеми з поточним сеансом роботи;\nцю дію скасовано, щоб запобігти «захопленню сеансу».\nБудь ласка, надішліть форму ще раз.",
        "changecontentmodel": "Змінити модель вмісту сторінки",
        "mycontris": "Внесок",
        "anoncontribs": "Внесок",
        "contribsub2": "Для {{GENDER:$3|$1}} ($2)",
+       "contributions-subtitle": "Для {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "Обліковий запис користувача  «$1» не зареєстровано.",
        "negative-namespace-not-supported": "Не підтримуються простори назв із від'ємними значеннями.",
        "nocontribs": "Редагувань, що відповідають заданим умовам, не знайдено.",
        "ipb-confirm": "Підтвердити блокування",
        "ipb-sitewide": "У всій вікі",
        "ipb-partial": "Частково",
+       "ipb-sitewide-help": "Кожна сторінка у вікі та всі інші дії щодо внеску.",
+       "ipb-partial-help": "Окремі сторінки чи простори назв.",
        "ipb-pages-label": "Сторінки",
        "ipb-namespaces-label": "Простори назв",
        "badipaddress": "IP-адреса записана в невірному форматі, або користувача з таким іменем не існує.",
        "confirm-unwatch-top": "Вилучити цю сторінку з вашого списку спостереження?",
        "confirm-rollback-button": "Гаразд",
        "confirm-rollback-top": "Відкотити редагування цієї сторінки?",
+       "confirm-rollback-bottom": "Ця дія миттєво відкотить обрані зміни на цій сторінці.",
        "confirm-mcrrestore-title": "Відновити версію",
        "confirm-mcrundo-title": "Скасувати зміну",
        "mcrundofailed": "Помилка скасування",
        "logentry-rights-autopromote": "$1 було автоматично переведено із $4 в $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|завантажив|завантажила}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|завантажив|завантажила}} нову версію $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|заванÑ\82ажив|заванÑ\82ажила}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|повеÑ\80нÑ\83в|повеÑ\80нÑ\83ла}} $3 Ð´Ð¾ Ñ\81Ñ\82аÑ\80оÑ\97 Ð²ÐµÑ\80Ñ\81Ñ\96Ñ\97",
        "log-name-managetags": "Журнал управління мітками",
        "log-description-managetags": "На цій сторінці перераховані завдання управління, пов'язані з [[Special:Tags|мітками]]. Журнал містить тільки дії, виконані вручну адміністратором; мітки можуть бути створені або видалені програмним забезпеченням вікі без запису в цей журнал.",
        "logentry-managetags-create": "$1 {{GENDER:$2|створив|створила}} мітку «$4»",
        "log-action-filter-suppress-reblock": "Приховування користувача через повторне блокування",
        "log-action-filter-upload-upload": "Нове завантаження",
        "log-action-filter-upload-overwrite": "Повторне завантаження",
+       "log-action-filter-upload-revert": "Відкотити",
        "authmanager-authn-not-in-progress": "Автентифікація не виконується або втрачено дані сесії. Будь ласка, почніть знову з самого початку.",
        "authmanager-authn-no-primary": "Надані облікові дані не можуть бути завірені.",
        "authmanager-authn-no-local-user": "Надані облікові дані не пов'язані з жодним користувачем у цій вікі.",
        "authmanager-create-no-primary": "Надані облікові дані не можуть бути використані для створення облікового запису.",
        "authmanager-link-no-primary": "Надані облікові дані не можуть бути використані для прив'язки облікового запису.",
        "authmanager-link-not-in-progress": "Пов'язання облікового запису не виконується або втрачено дані сесії. Будь ласка, почніть знову з самого початку.",
-       "authmanager-authplugin-setpass-failed-title": "Не вдалося змінити пароль",
-       "authmanager-authplugin-setpass-failed-message": "Плагін автентифікації відмовив у зміні пароля.",
-       "authmanager-authplugin-create-fail": "Плагін автентифікації відмовив у створенні облікового запису.",
-       "authmanager-authplugin-setpass-denied": "Плагін автентифікації не дозволяє змінювати паролі.",
-       "authmanager-authplugin-setpass-bad-domain": "Неприпустимий домен.",
        "authmanager-autocreate-noperm": "Автоматичне створення облікових записів не допускається.",
        "authmanager-autocreate-exception": "Автоматичне створення облікових записів тимчасово відключене через попередні помилки.",
        "authmanager-userdoesnotexist": "Обліковий запис користувача «$1» не зареєстровано.",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль повинен бути коротшим $1 {{PLURAL:$1|символа|символів}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Пароль не може бути {{PLURAL:$1|часто вживаним|будь-яким з $1 часто вживаних паролів}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль не може перебувати у списку 100 000 найчастіше вживаних паролів.",
+       "passwordpolicies-policyflag-forcechange": "має бути змінено при вході",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "запропонувати зміну при вході",
        "easydeflate-invaliddeflate": "Наданий вміст не стиснений належним чином",
        "unprotected-js": "З міркувань безпеки JavaScript не можна запускати з незахищених сторінок. Будь ласка, створюйте javascript лише в просторі MediaWiki, або як особисту підсторінку користувача."
 }
index a1a109a..6fcb108 100644 (file)
@@ -40,7 +40,8 @@
                        "Fitoschido",
                        "Dcljr",
                        "Bukhari",
-                       "Sajidkhan"
+                       "Sajidkhan",
+                       "Hmfs.ind"
                ]
        },
        "tog-underline": "ربط کی خط کشیدگی:",
        "nstab-category": "زمرہ",
        "mainpage-nstab": "صفحۂ اول",
        "nosuchaction": "مطلوبہ اقدام موجود نہیں",
-       "nosuchactiontext": "URL کی جانب سے مختص کیا گیا عمل درست نہیں.\nآپ نے شاید URL غلط لکھا، یا کسی غیر صحیح ربط کی پیروی کی ہے.\n{{اِس سے SITENAME کے زیرِ استعمال مصنع لطیف میں کھٹمل کی نشاندہی کا بھی اندیشہ ہے}}.",
+       "nosuchactiontext": "URL کی جانب سے مختص کیا گیا عمل درست نہیں۔\nآپ نے شاید URL غلط لکھا ہے یا کسی نادرست ربط پر کلک کیا ہے۔\nاِس سے {{SITENAME}} کے زیرِ استعمال سافٹ ویئر میں کسی خامی کی موجودگی کا بھی اندیشہ ہے۔",
        "nosuchspecialpage": "کوئی ایسا خاص صفحہ نہیں",
        "nospecialpagetext": "<strong>آپ نے ایک غیر موجود خصوصی صفحہ کی درخواست کی ہے۔</strong>\n\nدرست خاص صفحات کی ایک فہرست [[Special:SpecialPages|{{int:specialpages}}]] پر دیکھی جاسکتی ہے۔",
        "error": "نقص",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|تبادلۂ خیال]]) کی ترامیم [[User:$1|$1]] کی گذشتہ ترمیم کی جانب واپس پھیر دی گئیں۔",
        "revertpage-nouser": "(حذف شدہ صارف نام) کی ترامیم {{GENDER:$1|[[User:$1|$1]]}} کی گذشتہ ترمیم کی جانب واپس پھیر دی گئیں",
        "rollback-success": "{{GENDER:$3|$1}} کی ترامیم واپس پھیر دی گئیں؛\nصفحہ واپس {{GENDER:$4|$2}} کی آخری ترمیم کی جانب منتقل کر دیا گیا۔",
-       "rollback-success-notify": "$1 کی ترامیم واپس پھیر دی گئیں؛\nصفحہ واپس $2 کی آخری ترمیم کی جانب منتقل کر دیا گیا۔ [$3 تبدیلیاں دکھائیں]",
        "sessionfailure-title": "نشست میں خامی",
        "sessionfailure": "معلوم ہوتا ہے کہ آپ کی لاگ ان نشست میں کوئی مسئلہ درپیش ہے؛\nاس صورت میں نشست کے اغوا کا خدشہ ہوتا ہے، چنانچہ پیش بندی کے طور پر آپ کے اقدام کو مسترد کر دیا گیا ہے۔\nبراہ کرم دوبارہ کوشش کریں۔",
        "changecontentmodel": "صفحہ کے مواد کے ماڈل میں تبدیلی کریں",
        "authmanager-create-no-primary": "فراہم کردہ وثیقوں کو کھاتہ سازی کے لیے استعمال نہیں کیا جا سکا۔",
        "authmanager-link-no-primary": "فراہم کردہ وثیقوں کو کھاتوں سے مربوط کرنے کے لیے استعمال نہیں کیا جا سکا۔",
        "authmanager-link-not-in-progress": "کھاتوں کو مربوط کرنے کا عمل جاری نہ رہ سکا یا نشست کا ڈیٹا گم ہو چکا ہے۔ براہ کرم آغاز سے دوبارہ کوشش کریں۔",
-       "authmanager-authplugin-setpass-failed-title": "پاس ورڈ کی تبدیلی ناکام رہی",
-       "authmanager-authplugin-setpass-failed-message": "تصدیقی ہلگ ان نے پاس ورڈ کی تبدیلی کو رد کر دیا۔",
-       "authmanager-authplugin-create-fail": "تصدیقی ہلگ ان نے کھاتہ سازی کو رد کر دیا۔",
-       "authmanager-authplugin-setpass-denied": "تصدیقی ہلگ ان میں پاس ورڈ کی تبدیلی کی اجازت نہیں ہے۔",
-       "authmanager-authplugin-setpass-bad-domain": "نادرست ڈومین۔",
        "authmanager-autocreate-noperm": "خودکار کھاتہ سازی کی اجازت نہیں ہے۔",
        "authmanager-autocreate-exception": "سابقہ نقص کی وجہ سے عارضی طور پر خودکار کھاتہ سازی غیر فعال ہے۔",
        "authmanager-userdoesnotexist": "«$1» کے نام سے صارف کھاتہ مندرج نہیں ہے۔",
index 122ecf0..8192034 100644 (file)
        "badretype": "Hai mật khẩu không khớp.",
        "usernameinprogress": "Đã tiến hành tạo tài khoản với tên người dùng này.\nXin vui lòng chờ đợi.",
        "userexists": "Tên người dùng được nhập đã có người lấy.\nHãy chọn một tên khác.",
+       "createacct-normalization": "Tên người dùng của bạn sẽ bị chỉnh lại thành “$2” do hạn chế kỹ thuật.",
        "loginerror": "Lỗi đăng nhập",
        "createacct-error": "Lỗi mở tài khoản",
        "createaccounterror": "Không thể mở tài khoản: $1",
        "revertpage": "Đã lùi lại sửa đổi của [[Special:Contributions/$2|$2]] ([[User talk:$2|Thảo luận]]) quay về phiên bản cuối của [[User:$1|$1]]",
        "revertpage-nouser": "Đã lùi lại sửa đổi của người dùng ẩn quay về phiên bản cuối của {{GENDER:$1}}[[User:$1|$1]]",
        "rollback-success": "Đã hủy sửa đổi của {{GENDER:$3}}$1;\nquay về phiên bản cuối của {{GENDER:$4}}$2.",
-       "rollback-success-notify": "Đã hủy sửa đổi của $1;\nquay về phiên bản cuối của $2. [$3 Xem thay đổi]",
        "sessionfailure-title": "Phiên thất bại",
        "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy gửi lại biểu mẫu.",
        "changecontentmodel": "Thay đổi kiểu nội dung của một trang",
        "log-action-filter-suppress-reblock": "Ẩn giấu người dùng bằng cách cấm lại",
        "log-action-filter-upload-upload": "Tải lên mới",
        "log-action-filter-upload-overwrite": "Tải lên lại",
+       "log-action-filter-upload-revert": "Lùi lại",
        "authmanager-authn-not-in-progress": "Không phải đang xác thực, hoặc dữ liệu phiên làm việc bị mất. Xin hãy thử lại từ đầu.",
        "authmanager-authn-no-primary": "Không thể xác thực định danh được cung cấp.",
        "authmanager-authn-no-local-user": "Định danh được cung cấp không ứng với người dùng nào trên wiki này.",
        "authmanager-create-no-primary": "Không thể sử dụng định danh được cung cấp để tạo tài khoản.",
        "authmanager-link-no-primary": "Không thể sử dụng định danh được cung cấp để liên kết tài khoản.",
        "authmanager-link-not-in-progress": "Không phải đang liên kết tài khoản, hoặc dữ liệu phiên làm việc bị mất. Xin hãy thử lại từ đầu.",
-       "authmanager-authplugin-setpass-failed-title": "Thay đổi mật khẩu bị thất bại",
-       "authmanager-authplugin-setpass-failed-message": "Phần bổ trợ xác thực đã từ chối việc đổi mật khẩu.",
-       "authmanager-authplugin-create-fail": "Phần bổ trợ xác thực đã từ chối việc tạo tài khoản.",
-       "authmanager-authplugin-setpass-denied": "Phần bổ trợ xác thực không cho phép đổi mật khẩu.",
-       "authmanager-authplugin-setpass-bad-domain": "Tên miền không hợp lệ.",
        "authmanager-autocreate-noperm": "Không cho phép tự động tạo tài khoản.",
        "authmanager-autocreate-exception": "Tạm thời không cho phép tự động tạo tài khoản vì các lỗi trước đây.",
        "authmanager-userdoesnotexist": "Chưa có tài khoản với tên “$1”.",
index 114a1c2..cc87a70 100644 (file)
        "accmailtext": "Uska hinimo nga random nga tigaman-panakob para kan [[User talk:$1|$1]] in ginpadangat ha $2. Puydi ini mabal-iwan ha ''[[Special:ChangePassword|liwani an tigaman-panakob]]'' nga pakli han paglog-in.",
        "newarticle": "(Bag-o)",
        "newarticletext": "Ginsunod mo an pakli nga waray pa kahihimo.  Para ighimo an pakli, tikanga pagmakinilya ha kahon nga aada ha ubos (kitaa an [$1 nabulig nga pakli] para han kadugangan nga pananabutan).  Kun sayop an imo pagkanhi, igpidlit an imo kanan panngaykay (''browser'') '''balik''' (''back'') nga piridlitan.",
-       "anontalkpagetext": "----\n<em>Ini in hiruhimangraw-nga-pakli para han waray magpakilala nga gumaramit, nga waray pa hinmimo hin akawnt.</em>\nMagamit la kami hin IP address para makilal-an hiya.\nSugad hini nga IP address, in puydi sinmaro hiton pipira nga mga gumaramit.\nKun ikaw in waray magpakilala nga gumaramit, ngan pag-abat mo in may mga diri naangay nga komento an ginpapadangat ha imo, alayon nala [[Special:CreateAccount|paghimo hin akawnt]] o [[Special:UserLogin|pag-log in]] para malikyan an sumurunod nga mga pagkalipat nga dapat para ha iba nga waray magpakilala nga mga gumaramit.",
+       "anontalkpagetext": "----\n<em>Ini in hiruhimangraw-nga-pakli para han waray magpakilala nga gumaramit, nga waray pa hinmimo hin akawnt.</em>\nMagamit la kami hin IP address para makilal-an hira.\nSugad hini nga IP address, in puydi sinmaro hiton pipira nga mga gumaramit.\nKun ikaw in waray magpakilala nga gumaramit, ngan pag-abat mo in may mga diri naangay nga komento an ginpapadangat ha imo, alayon nala [[Special:CreateAccount|paghimo hin akawnt]] o [[Special:UserLogin|pag-log in]] para malikyan an sumurunod nga mga pagkalipat nga dapat para ha iba nga waray magpakilala nga mga gumaramit.",
        "noarticletext": "Waray yana teksto ha sulod hinin nga pakli.\nPuyde ka [[Special:Search/{{PAGENAME}}|mamiling hin titulo hinin nga pakli]] ha iba pa nga mga pakli,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pamilnga an may mga pagkahisumpay nga mga talaan],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} igliwat ini nga pakli]</span>.",
        "noarticletext-nopermission": "Waray yana nahasurat hini nga pakli\nPuyde hi ikaw [[Special:Search/{{PAGENAME}}|magbiling han ngaran hini nga pakli]] ha iba nga mga pakli,\no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mamiling han mga nanginginlabot nga mga talaan]</span>, kundi diri ka gintutugotan hin paghímò hini nga pakli.",
        "missing-revision": "Waray na an rebisyon #$1 han pakli nga ginngaranan nga  \"{{FULLPAGENAME}}\".\n\nIni in agsob tungod han pagsunod hin daan nga sumpay hin kaagi ha pakli nga ginpara.\nAn mga detalye in mabibilngan ha [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
        "post-expand-template-inclusion-category": "Mga pakli kun diin an mga nahilalakip nga kadako han batakan in nalabaw.",
        "post-expand-template-argument-warning": "'''Pahimatngaon:''' Ini nga pakli in nagsusulod hin pinakaguti usa nga argumento hin batakan nga may-ada sobra nga dako it padako nga kadako.\nIni nga mga argumento in ginlaktawan.",
        "post-expand-template-argument-category": "Mga pakli nga nagsusulod hin ginlaktawan nga mga argumento hin batakan",
+       "undo-failure": "Ini nga pagliwat diri maakos matanggal an binuhat tungod han diri nagkakauyon nga intermediate edits.",
        "undo-norev": "An pagliwat in diri mapapawaray-buhat tungod waray ito dida o napara na.",
        "undo-summary": "Ginpawara-buhat an rebisyon nga $1 ni [[Special:Contributions/$2|$2]] ([[User talk:$2|himangrawi]])",
        "undo-summary-username-hidden": "Igpawara-an-ginbuhat nga rebisyon $1 han uska tago nga gumaramit",
        "notanarticle": "Diri uska unod nga pakli",
        "notvisiblerev": "An urhi nga pagliwat han iba nga gumaramit in ginpara",
        "watchlist-details": "{{PLURAL:$1|$1 nga pakli|$1 nga mga pakli}} aada ha imo talaan nga binabantayan (upod an mga hiruhimangraw-nga-pakli).",
+       "wlheader-showupdated": "An mga pakli nga nagbag-o tikang ha imo urhi nga pagbisita in ginpapakita hin <strong>madakmol nga kasurat</strong>.",
+       "wlnote": "Ha ilarom {{PLURAL:$1|amo an urhi nga pagbag-o|amo an mga urhi nga <strong>$1</strong> nga pagbag-o}} ha urhi nga {{PLURAL:$2|oras|<strong>$2</strong> mga oras}}, han $3, $4.",
        "wlshowlast": "Igpakita an katapusan nga $1 ka mga oras $2 ka mga adlaw",
        "watchlist-hide": "Tago-a",
        "watchlist-submit": "Pakit-a",
        "mycontris": "Mga ámot nakon",
        "anoncontribs": "Mga amot",
        "contribsub2": "Para {{HENERO:$3|$1}} ($2)",
+       "nocontribs": "Waray pagliwat an nabilngan han nauyon hini nga criteria.",
        "uctop": "pagkayana",
        "month": "Tikang ha bulan (ngan uruunhan):",
        "year": "Tikang ha tuig (ngan uruunhan):",
        "emaillink": "Padara hin e-mail",
        "blocklogpage": "Talaan han pagpugong",
        "blocklogentry": "ginpugngan hi [[$1]] nga natatapos ha takna hin $2 $3",
+       "reblock-logentry": "ginbalyo an block settings para kan [[$1]] nga may expiration time nga $2 $3",
        "unblocklogentry": "gintanggal an pagpugong $1",
        "block-log-flags-nocreate": "diri gintutugutan an paghimo hin akawnt",
        "block-log-flags-noemail": "Diri ginpapagana an e-mail",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|pakli|mga pakli}}",
        "file-info": "Kadako han paypay: $1, klase han MIME: $2",
        "file-info-size": "$1 × $2 nga pixel, kadako han fayl: $3, MIME nga tipo: $4",
+       "file-info-size-pages": "$1 × $2 mga pixel, kadako han file: $3, klase han MIME: $4, $5 {{PLURAL:$5|pakli|mga pakli}}",
        "file-nohires": "Waray mas hiruhitaas nga resolusyon.",
        "svg-long-desc": "SVG nga fayl, ginbabanabanahan nga $1 × $2 nga mga pixel, kadako han fayl: $3",
        "show-big-image": "Orihinal nga paypay",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 nga titulo|$1 nga mga titulo}} in gintanggal:",
        "watchlistedit-clear-titles": "Mga titulo:",
        "watchlistedit-clear-submit": "Hawana an barantayon nga listahan (Permamente ini!)",
+       "watchlisttools-clear": "Igpara an barantayan",
        "watchlisttools-view": "Kitaa an mga nanginginlabot nga mga pagbabag-o",
        "watchlisttools-edit": "Kitaa ngan igliwat an talaan han binabantayan",
        "watchlisttools-raw": "Igliwat an hilaw nga talaan han binabantayan",
index 76a8cf1..8ef8fb3 100644 (file)
        "special-characters-group-khmer": "ქჰმერული",
        "special-characters-title-endash": "საშუალო ტირე",
        "special-characters-title-emdash": "გრძელი ტირე",
-       "special-characters-title-minus": "მინუსის ნიშანი"
+       "special-characters-title-minus": "მინუსის ნიშანი",
+       "passwordpolicies-policyflag-forcechange": "მიშულაშ ბორჯის ითირას ოკო"
 }
index f1ca0fa..fd4f1bd 100644 (file)
@@ -80,6 +80,7 @@
        "tog-norollbackdiff": "進行反轉之後唔睇差異",
        "tog-useeditwarning": "當我離開未保存好嘅修改嗰陣警告我",
        "tog-prefershttps": "簽到後繼續用加密連線",
+       "tog-showrollbackconfirmation": "撳「反轉」掣嘅時候要撳確認",
        "underline-always": "全部",
        "underline-never": "永不",
        "underline-default": "瀏覽器或瀏覽器膚色預設",
        "newwindow": "(響新視窗度打開)",
        "cancel": "取消",
        "moredotdotdot": "更多...",
-       "morenotlisted": "爾張清單可能重未完成。",
+       "morenotlisted": "爾張清單可能唔完整。",
        "mypage": "版",
        "mytalk": "傾偈",
        "anontalk": "傾偈",
        "botpasswords-editexisting": "改已經有嘅機械人密碼",
        "botpasswords-label-needsreset": "(密碼要重新設定)",
        "botpasswords-label-appid": "機械人名:",
-       "botpasswords-label-create": "å\89µé\80 ",
-       "botpasswords-label-update": "上載",
+       "botpasswords-label-create": "建ç«\8b",
+       "botpasswords-label-update": "更新",
        "botpasswords-label-cancel": "取消",
        "botpasswords-label-delete": "刪除",
-       "botpasswords-label-resetpassword": "改過個密碼",
+       "botpasswords-label-resetpassword": "改過個密碼",
        "botpasswords-label-grants": "啱用嘅授權:",
        "botpasswords-label-grants-column": "授咗權",
        "botpasswords-bad-appid": "機械人名 \"$1\" 無效。",
        "sectioneditnotsupported-text": "呢版唔支援逐改段。",
        "permissionserrors": "權限出錯",
        "permissionserrorstext": "根據下面嘅{{PLURAL:$1|原因|原因}},你並無權限去做呢樣嘢:",
-       "permissionserrorstext-withaction": "根據下面嘅{{PLURAL:$1|原因|原因}},你並無權限去做$2:",
+       "permissionserrorstext-withaction": "根據下面嘅{{PLURAL:$1|原因}},你無權去$2:",
        "contentmodelediterror": "你唔改得呢版修訂,因為呢個修訂嘅內容模型係 <code>$1</code> ,同而家嘅內容模型 <code>$2</code> 有分別。",
        "recreate-moveddeleted-warn": "'''警告: 你而家重開一版係先前曾經刪除過嘅。'''\n\n你應該要考慮吓繼續編輯呢一版係唔係適合嘅。\n為咗方便起見,呢一版嘅刪除同搬版記錄已經響下面提供:",
        "moveddeleted-notice": "呢一版已經刪咗。\n呢版嘅刪除同搬版日誌響下面提供咗以便參考。",
        "searchprofile-advanced-tooltip": "響自定空間名度搵",
        "search-result-size": "$1 ($2個字)",
        "search-result-category-size": "$1位成員 ($2個細類,$3個檔案)",
-       "search-redirect": "(由$1過嚟)",
+       "search-redirect": "(由$1跳轉過來)",
        "search-section": "(小節 $1)",
        "search-category": "(類 $1)",
        "search-file-match": "(夾啱樓案内容)",
        "timezoneregion-europe": "歐洲",
        "timezoneregion-indian": "印度洋",
        "timezoneregion-pacific": "太平洋",
-       "allowemail": "允許其它用戶發電子郵件俾我",
+       "allowemail": "畀其它用戶發電郵俾我",
        "email-allow-new-users-label": "接收新簇簇用戶發嘅電郵",
        "email-blacklist-label": "禁止呢啲用戶發電郵畀我:",
        "prefs-searchoptions": "搵嘢",
        "prefs-help-prefershttps": "呢項喜好設定會喺你下次簽到先至開始生效。",
        "prefswarning-warning": "你改嘅喜好設定改動重未記低。\n如果你未撳「$1」就走咗,你嘅喜好設定唔會有更新。",
        "prefs-tabs-navigation-hint": "貼士:可以用鍵盤嘅←或→掣睇一覽內嘅分頁",
-       "userrights": "用戶權限",
-       "userrights-lookup-user": "揀個用戶",
+       "userrights": "用戶權限",
+       "userrights-lookup-user": "揀個用戶",
        "userrights-user-editname": "輸入一個用戶名:",
        "editusergroup": "載入用戶組",
        "editinguser": "改緊<strong>[[User:$1|$1]]</strong>嘅用戶權限 $2",
        "userrights-expiry-existing": "現時到期嘅時間: $2 $3",
        "userrights-expiry-othertime": "其它時間:",
        "userrights-expiry-options": "1日:1 day,1個禮拜:1 week,1個月:1 month,3個月:3 months,6個月:6 months,1年:1 year",
-       "userrights-invalid-expiry": "çµ\84\"$1\"å\98\85é\81\8eæ\9c\9fæ\99\82é\96\93å\86\87æ\95\88",
+       "userrights-invalid-expiry": "ç\94¨æ\88¶çµ\84ã\80\8c$1ã\80\8då\98\85é\81\8eæ\9c\9fæ\99\82é\96\93ç\84¡æ\95\88ã\80\82",
        "userrights-expiry-in-past": "組\"$1\"嘅過期時間係過咗嘅時間。",
        "userrights-conflict": "用戶權限更改有衝突!請再睇過同確認你嘅改動。",
        "group": "組:",
        "grant-editprotected": "改保護咗嘅版",
        "grant-highvolume": "大量編輯",
        "grant-oversight": "收埋用戶同禁止顯示修訂",
+       "grant-rollback": "反轉一啲版面嘅修改",
        "grant-sendemail": "寄電郵畀其他用戶",
        "grant-uploadeditmovefile": "上載、𠖫同搬檔",
        "grant-uploadfile": "上載新檔案",
        "rcfilters-filter-user-experience-level-unregistered-label": "未註冊",
        "rcfilters-filter-user-experience-level-unregistered-description": "無簽到嘅編者。",
        "rcfilters-filter-user-experience-level-newcomer-label": "新手",
-       "rcfilters-filter-user-experience-level-newcomer-description": "少過4日、10次編輯嘅用戶",
+       "rcfilters-filter-user-experience-level-newcomer-description": "活躍少過4日同少過10次編輯嘅用戶",
        "rcfilters-filter-user-experience-level-learner-label": "學徒",
        "rcfilters-filter-user-experience-level-learner-description": "編輯數同經驗多過「新手」但少過「老手」。",
        "rcfilters-filter-user-experience-level-experienced-label": "老手",
-       "rcfilters-filter-user-experience-level-experienced-description": "超過30日同埋500次編輯嘅用戶",
+       "rcfilters-filter-user-experience-level-experienced-description": "活躍超過30日同埋超過500次編輯嘅用戶。",
        "rcfilters-filtergroup-automated": "自動貢獻",
        "rcfilters-filter-bots-label": "機械人",
        "rcfilters-filter-bots-description": "用自動工具做嘅貢獻",
        "deleteprotected": "你唔可以刪呢版,因為佢畀人保護咗。",
        "deleting-backlinks-warning": "<strong>警告:</strong>有[[Special:WhatLinksHere/{{FULLPAGENAME}}|其他版]]連過來或嵌咗你準備刪嘅呢版。",
        "rollback": "反轉修改",
+       "rollback-confirmation-yes": "反轉",
        "rollbacklink": "反轉",
        "rollbacklinkcount": "反轉 $1 次修改",
        "rollbacklinkcount-morethan": "反轉超過$1次嘅{{PLURAL:$1|edit|修改}}",
        "confirm-unwatch-button": "好",
        "confirm-unwatch-top": "喺你嘅監視清單度刪走呢一版?",
        "confirm-rollback-button": "好",
+       "confirm-rollback-bottom": "呢個動作會立即反轉晒揀咗嘅修改。",
+       "confirm-mcrundo-title": "還原一個改動",
        "comma-separator": "、",
        "word-separator": "",
        "parentheses": "($1)",
        "tag-mw-blank": "清空",
        "tag-mw-replace": "換咗",
        "tag-mw-rollback": "反轉",
+       "tag-mw-rollback-description": "用「反轉」掣將之前修改打回頭嘅修改",
+       "tag-mw-undo": "還原",
+       "tag-mw-undo-description": "用「還原」掣還原之前修改嘅修改",
        "tags-title": "標籤",
        "tags-intro": "呢一版列示咗個軟件標示嘅編輯,同埋佢哋嘅解釋。",
        "tags-tag": "標籤名",
        "tags-hitcount": "$1次更改",
        "tags-create-reason": "原因:",
        "tags-create-submit": "開",
+       "tags-delete-explanation-warning": "呢個動作<strong>冇得返轉頭</strong>,係<strong>還原唔到</strong>嘅,就算資料庫管理員都還原唔到。唔該諗清楚你係咪想刪走呢個標籤。",
        "tags-delete-reason": "原因:",
        "tags-activate-title": "啟用標籤",
        "tags-activate-reason": "原因:",
        "log-action-filter-protect-protect": "保護",
        "log-action-filter-protect-unprotect": "取消保護",
        "log-action-filter-upload-overwrite": "再上載",
-       "authmanager-authplugin-setpass-failed-title": "改唔到密碼",
        "authmanager-email-label": "電郵",
        "authmanager-email-help": "電郵地址",
        "authmanager-realname-label": "真名",
index 56016d4..38adf73 100644 (file)
        "mediastatistics-header-total": "ⵎⴰⵕⵕⴰ ⵉⴼⵓⵍⵢⴰ",
        "randomrootpage": "ⵜⴰⵙⵏⴰ ⴰⵥⵓⵔ ⵜⴰⵡⴳⴰⵛⵓⵔⵜ",
        "log-action-filter-all": "ⵎⴰⵕⵕⴰ",
-       "authmanager-authplugin-setpass-denied": "ⵎⴰⵕⵕⴰ",
        "authmanager-email-label": "ⵉⵎⴰⵢⵍ",
        "authmanager-realname-label": "ⵉⵙⵎ ⴰⵎⴷⴷⴰⵜ",
        "authmanager-realname-help": "ⵉⵙⵎ ⴰⵎⴷⴷⴰⵜ ⵏ ⵓⵏⵙⵙⵔⵎⵙ",
index 224bf2d..232aef2 100644 (file)
                        "Angrydog001",
                        "GoForceX",
                        "Ff98sha",
-                       "VulpesVulpes825"
+                       "VulpesVulpes825",
+                       "佛壁灯"
                ]
        },
        "tog-underline": "链接下划线:",
        "tog-norollbackdiff": "执行回退后不显示差异",
        "tog-useeditwarning": "当我离开编辑页面时,如果有尚未保存的更改,请提醒我",
        "tog-prefershttps": "在登录后总是使用安全连接",
+       "tog-showrollbackconfirmation": "当点击回退链接时显示确认提示",
        "underline-always": "始终",
        "underline-never": "从不",
        "underline-default": "皮肤或浏览器默认设置",
        "badretype": "您所输入的密码并不相同。",
        "usernameinprogress": "此用户名的账户创建已在进行中。请等待。",
        "userexists": "用户名已存在。请使用其他名称。",
+       "createacct-normalization": "由于技术限制,您的用户名将被调整为“$2”。",
        "loginerror": "登录错误",
        "createacct-error": "账户创建出错",
        "createaccounterror": "无法建立账户:$1",
        "deleting-backlinks-warning": "<strong>警告:</strong>有[[Special:WhatLinksHere/{{FULLPAGENAME}}|其他页面]]链接至或包含您要删除的页面。",
        "deleting-subpages-warning": "<strong>警告:</strong>您要删除的页面有[[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1个子页面|51=超过50个子页面}}]]。",
        "rollback": "回退编辑",
+       "rollback-confirmation-confirm": "请确认:",
+       "rollback-confirmation-yes": "回退",
+       "rollback-confirmation-no": "取消",
        "rollbacklink": "回退",
        "rollbacklinkcount": "回退$1次编辑",
        "rollbacklinkcount-morethan": "回退超过$1次的编辑",
        "revertpage": "恢复[[Special:Contributions/$2|$2]]([[User talk:$2|讨论]])的编辑至[[User:$1|$1]]的最后版本",
        "revertpage-nouser": "恢复隐藏用户的编辑至{{GENDER:$1|[[User:$1|$1]]}}的最后版本",
        "rollback-success": "已恢复{{GENDER:$3|$1}}的编辑;更改回{{GENDER:$4|$2}}的最后版本。",
-       "rollback-success-notify": "已回退$1的编辑,更改回$2的最后版本。[$3 显示更改]",
        "sessionfailure-title": "会话无效",
        "sessionfailure": "似乎您的登录会话有问题;为了防止会话劫持,这个操作已经被取消。请重新提交表单。",
        "changecontentmodel": "更改一个页面的内容模型",
        "mycontris": "贡献",
        "anoncontribs": "贡献",
        "contribsub2": "{{GENDER:$3|$1}}的贡献($2)",
+       "contributions-subtitle": "对于{{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "用户“$1”尚未注册。",
        "negative-namespace-not-supported": "不支持带有负值的命名空间",
        "nocontribs": "没有找到匹配这些规则的更改。",
        "ipb-confirm": "确认封禁",
        "ipb-sitewide": "全站范围",
        "ipb-partial": "部分的",
+       "ipb-sitewide-help": "在 wiki 上的各个页面以及其它贡献行为。",
+       "ipb-partial-help": "特殊页面或名字空间。",
        "ipb-pages-label": "页面",
        "ipb-namespaces-label": "名字空间",
        "badipaddress": "无效IP地址",
        "confirm-unwatch-top": "从监视列表中删除此页吗?",
        "confirm-rollback-button": "确定",
        "confirm-rollback-top": "回退此页面的编辑么?",
+       "confirm-rollback-bottom": "此操作会立即回退对于此页面的所选更改。",
        "confirm-mcrrestore-title": "还原版本",
        "confirm-mcrundo-title": "撤销一次更改",
        "mcrundofailed": "撤销失败",
        "logentry-rights-autopromote": "$1被自动地{{GENDER:$2|提升}}自$4至$5",
        "logentry-upload-upload": "$1{{GENDER:$2|上传}}$3",
        "logentry-upload-overwrite": "$1{{GENDER:$2|上传}}$3的新版本",
-       "logentry-upload-revert": "$1{{GENDER:$2|上传}}$3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|已恢复}} $3 至旧版本",
        "log-name-managetags": "标签管理日志",
        "log-description-managetags": "此页面列出有关[[Special:Tags|标签]]的管理任务。该日志仅包含管理员手工进行的操作;wiki软件可能创建或删除标签而未在此日志中留下记录。",
        "logentry-managetags-create": "$1{{GENDER:$2|创建了}}标签“$4”",
        "log-action-filter-suppress-reblock": "通过再封禁的用户屏蔽",
        "log-action-filter-upload-upload": "新上传",
        "log-action-filter-upload-overwrite": "重新上传",
+       "log-action-filter-upload-revert": "恢复",
        "authmanager-authn-not-in-progress": "身份验证尚未进行,或会话数据丢失。请从头重新开始。",
        "authmanager-authn-no-primary": "提供的凭据不能被认证。",
        "authmanager-authn-no-local-user": "提供的证书没有与该wiki上的任何用户相关联。",
        "authmanager-create-no-primary": "提供的凭据不能用于账户创建。",
        "authmanager-link-no-primary": "提供的证书不能用于账户链接。",
        "authmanager-link-not-in-progress": "账户链接尚未进行,或会话数据丢失。请从头重新开始。",
-       "authmanager-authplugin-setpass-failed-title": "密码更改失败",
-       "authmanager-authplugin-setpass-failed-message": "身份验证插件拒绝了密码更改。",
-       "authmanager-authplugin-create-fail": "身份验证插件拒绝了账户创建。",
-       "authmanager-authplugin-setpass-denied": "身份验证插件不允许更改密码。",
-       "authmanager-authplugin-setpass-bad-domain": "无效域。",
        "authmanager-autocreate-noperm": "不允许自动账户创建。",
        "authmanager-autocreate-exception": "由于之前的错误,自动账户创建已临时停用。",
        "authmanager-userdoesnotexist": "用户帐户“$1”尚未注册。",
        "passwordpolicies-policy-maximalpasswordlength": "密码长度必须少于$1个{{PLURAL:$1|字符}}",
        "passwordpolicies-policy-passwordcannotbepopular": "密码不能{{PLURAL:$1|是最常见的密码|在$1个最常见密码的列表中}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "密码不能在100000个最常用的密码列表中。",
+       "passwordpolicies-policyflag-forcechange": "必须在登录时更改",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "建议在登录时更改",
        "easydeflate-invaliddeflate": "提供的内容未被适当缩小",
        "unprotected-js": "基于安全原因,JavaScript不能在未保护页面中载入。请在 MediaWiki : 命名空间或者用户子页面中添加JavaScript。"
 }
index e3a7300..33ce701 100644 (file)
                        "Kanashimi",
                        "Hello903hello",
                        "Luuva",
-                       "Davidzdh"
+                       "Davidzdh",
+                       "WQL"
                ]
        },
        "tog-underline": "底線標示連結:",
        "tog-watchmoves": "將我移動的頁面和檔案加入監視清單",
        "tog-watchdeletion": "將我刪除的頁面和檔案加入監視清單",
        "tog-watchuploads": "加入我上傳的新檔案至我的監視清單",
-       "tog-watchrollback": "將我曾經還原的頁面新增至監視清單",
+       "tog-watchrollback": "將我曾經回退的頁面新增至監視清單",
        "tog-minordefault": "預設標記所有的編輯為次要修訂",
        "tog-previewontop": "顯示預覽於編輯框上方",
        "tog-previewonfirst": "第一次編輯時顯示預覽",
        "tog-ccmeonemails": "我寄出郵件給其他使用者時,也寄給我一份副本",
        "tog-diffonly": "比對差異時下方不顯示頁面內容",
        "tog-showhiddencats": "顯示隱藏分類",
-       "tog-norollbackdiff": "執行還原後略過差異比對",
+       "tog-norollbackdiff": "執行回退後略過差異比對",
        "tog-useeditwarning": "未儲存離開編輯頁面時警告我",
        "tog-prefershttps": "永遠使用安全連線來登入",
+       "tog-showrollbackconfirmation": "當點擊回退連結時顯示確認提示",
        "underline-always": "永遠使用",
        "underline-never": "永不使用",
        "underline-default": "外觀或瀏覽器預設",
        "december-date": "12月$1日",
        "period-am": "AM",
        "period-pm": "PM",
-       "pagecategories": "{{PLURAL:$1|分類|$1 個分類}}",
+       "pagecategories": "{{PLURAL:$1|分類}}",
        "category_header": "「$1」分類的頁面",
        "subcategories": "子分類",
        "category-media-header": "「$1」分類的媒體",
        "navigation-heading": "導覽選單",
        "errorpagetitle": "錯誤",
        "returnto": "返回「$1」頁面",
-       "tagline": "出自 {{SITENAME}}",
+       "tagline": "出自{{SITENAME}}",
        "help": "說明",
        "help-mediawiki": "有關 MediaWiki 的說明",
        "search": "搜尋",
        "badretype": "兩次輸入的密碼並不相同。",
        "usernameinprogress": "已正在進行此使用者名稱的帳號建立作業。\n請稍候。",
        "userexists": "您所輸入的使用者名稱已存在,請另選一個名稱。",
+       "createacct-normalization": "基於技術限制,您的用戶名將調整為「$2」。",
        "loginerror": "登入錯誤",
        "createacct-error": "帳號建立錯誤",
        "createaccounterror": "無法建立帳號:$1",
        "histfirst": "最舊",
        "histlast": "最新",
        "historysize": "($1 位元組)",
-       "historyempty": "(空)",
+       "historyempty": "",
        "history-feed-title": "修訂歷史",
        "history-feed-description": "本 Wiki 上此頁面的修訂歷史",
        "history-feed-item-nocomment": "$1 於 $2",
        "right-reupload-own": "覆蓋自己上傳的檔案",
        "right-reupload-shared": "覆蓋共用媒體檔案庫於本地的檔案",
        "right-upload_by_url": "使用 URL 上傳檔案",
-       "right-purge": "不須確認即清除網站的頁面快取",
+       "right-purge": "清除頁面的站台快取",
        "right-autoconfirmed": "不受基於IP的使用頻率限制",
        "right-bot": "將其視為自動程序",
        "right-nominornewtalk": "不顯示討論頁面中次要編輯的新訊息提示",
        "right-viewmyprivateinfo": "檢視自己的私隱資料(如:電子郵件地址及真實姓名)",
        "right-editmyprivateinfo": "編輯自己的隱私資料 (如:電子郵件地址及真實姓名)",
        "right-editmyoptions": "編輯自己的偏好設定",
-       "right-rollback": "快速還原最後一位使用者對某一頁面的編輯",
+       "right-rollback": "快速回退最後一位使用者對某一頁面的編輯",
        "right-markbotedits": "標示還原編輯為機械人編輯",
        "right-noratelimit": "不受使用頻率限制",
        "right-import": "由其他 Wiki 匯入頁面",
        "grant-patrol": "巡邏頁面的變更",
        "grant-privateinfo": "存取隱私資訊",
        "grant-protect": "保護與取消保護頁面",
-       "grant-rollback": "還原頁面的變更",
+       "grant-rollback": "回退對於頁面的變更",
        "grant-sendemail": "傳送電子郵件聯絡其他使用者",
        "grant-uploadeditmovefile": "上傳、取代與移動檔案",
        "grant-uploadfile": "上傳新檔案",
        "action-suppressionlog": "檢視此非公開日誌",
        "action-block": "封鎖此使用者的編輯權限",
        "action-protect": "變更此頁面的保護層級",
-       "action-rollback": "快速還原最後一位使用者對某一頁面的編輯",
+       "action-rollback": "快速回退最後一位使用者對某一頁面的編輯",
        "action-import": "由其他 Wiki 匯入頁面",
        "action-importupload": "由檔案上傳匯入頁面",
        "action-patrol": "標示其它人的編輯為已巡查",
        "protectedpages": "受保護頁面",
        "protectedpages-filters": "篩選:",
        "protectedpages-indef": "只顯示無限期的保護頁面",
-       "protectedpages-summary": "此頁面列出目前受保護的頁面。 欲查詢受保護標題清單,請參考 [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]]。",
+       "protectedpages-summary": "此頁面列出目前受保護的頁面。 欲查詢受保護標題清單,請參考[[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]]。",
        "protectedpages-cascade": "只顯示連鎖的保護頁面",
        "protectedpages-noredirect": "隱藏重新導向頁面",
        "protectedpagesempty": "目前沒有使用這些參數的受保護頁面。",
        "protectedpages-unknown-timestamp": "不明",
        "protectedpages-unknown-performer": "不明的使用者",
        "protectedtitles": "受保護標題",
-       "protectedtitles-summary": "此頁面列出目前受保護的標題。 欲查詢受保護頁面清單,請參考 [[{{#special:ProtectedPages}}|{{int:protectedpages}}]]。",
+       "protectedtitles-summary": "此頁面列出目前受保護的標題。 欲查詢受保護頁面清單,請參考[[{{#special:ProtectedPages}}|{{int:protectedpages}}]]。",
        "protectedtitlesempty": "目前沒有使用這些參數的受保護標題。",
        "protectedtitles-submit": "顯示標題",
        "listusers": "使用者清單",
        "activeusers-noresult": "查無使用者。",
        "activeusers-submit": "顯示活動中的使用者",
        "listgrouprights": "使用者群組權限",
-       "listgrouprights-summary": "以下為此 Wiki 的使用者群組清單,以及相關的存取權限。\n您可以在 [[{{MediaWiki:Listgrouprights-helppage}}|詳細資訊]] 找到有關個別權限的資訊。",
+       "listgrouprights-summary": "以下為此 Wiki 的使用者群組清單,以及相關的存取權限。您可以在[[{{MediaWiki:Listgrouprights-helppage}}|詳細資訊]]找到有關個別權限的資訊。",
        "listgrouprights-key": "說明:\n* <span class=\"listgrouprights-granted\">已授予的權限</span>\n* <span class=\"listgrouprights-revoked\">已撤銷的權限</span>",
        "listgrouprights-group": "群組",
        "listgrouprights-rights": "權限",
        "post-expand-template-inclusion-category-desc": "展開模板後大小超過 <code>$wgMaxArticleSize</code> 導致部份模板未正常展開的頁面。",
        "post-expand-template-argument-category-desc": "展開模板參數後大小超過 <code>$wgMaxArticleSize</code> 的頁面 (有些於三括號中,如 <code>{{{Foo}}}</code>)。",
        "expensive-parserfunction-category-desc": "頁面使用太多消耗系統資源的解析器函數 (如 <code>#ifexist</code>)。\n請參考 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit]。",
-       "broken-file-category-desc": "含有損壞檔案連結的頁面 (內嵌檔案連結的檔案不存在)。",
+       "broken-file-category-desc": "含有損壞檔案連結的頁面(內嵌檔案連結的檔案不存在)。",
        "hidden-category-category-desc": "內容中使用 <code><nowiki>__HIDDENCAT__</nowiki></code> 的分類,可隱藏預設在頁面上顯示的分類連結方塊。",
        "trackingcategories-nodesc": "沒有可用的描述。",
        "trackingcategories-disabled": "已停用分類",
        "deleting-backlinks-warning": "<strong>警告:</strong>您正要刪除的頁面有[[Special:WhatLinksHere/{{FULLPAGENAME}}|其他頁面]]連結或引用。",
        "deleting-subpages-warning": "<strong>警告:</strong>您要刪除的頁面有[[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|$1個子頁面|51=超過50個子頁面}}]]。",
        "rollback": "復原編輯",
-       "rollbacklink": "還原",
+       "rollback-confirmation-confirm": "請確認:",
+       "rollback-confirmation-yes": "回退",
+       "rollback-confirmation-no": "取消",
+       "rollbacklink": "回退",
        "rollbacklinkcount": "還原 $1 次編輯",
-       "rollbacklinkcount-morethan": "還原超過 $1 次{{PLURAL:$1|編輯}}",
+       "rollbacklinkcount-morethan": "回退超過 $1 次{{PLURAL:$1|編輯}}",
        "rollbackfailed": "還原失敗",
        "rollback-missingparam": "請求缺少必要參數。",
        "rollback-missingrevision": "無法載入修訂資料。",
        "cantrollback": "無法還原編輯;\n此頁面的最後貢獻者是唯一的作者。",
-       "alreadyrolled": "無法還原由[[User:$2|$2]]([[User talk:$2|對話]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])所作的最後一次編輯[[:$1]],已有其他人編輯或還原了該頁面。\n\n最後一次編輯該頁面的使用者是[[User:$3|$3]]([[User talk:$3|對話]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])。",
+       "alreadyrolled": "無法回退由[[User:$2|$2]]([[User talk:$2|對話]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])所作的最後一次編輯[[:$1]],已有其他人編輯或回退了該頁面。\n\n最後一次編輯該頁面的使用者是[[User:$3|$3]]([[User talk:$3|對話]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])。",
        "editcomment": "編輯摘要為:<em>$1</em>。",
        "revertpage": "已還原[[Special:Contributions/$2|$2]]([[User talk:$2|對話]])的編輯為最後由[[User:$1|$1]]所修訂的版本",
        "revertpage-nouser": "已還原隱藏使用者的編輯為最後 {{GENDER:$1|[[User:$1|$1]]}} 修訂的版本",
        "rollback-success": "已還原 {{GENDER:$3|$1}} 所做的編輯;\n變更回由 {{GENDER:$4|$2}} 修訂的最後一個版本。",
-       "rollback-success-notify": "已還原 $1 所做的編輯;\n變更回由 $2 修訂的最後一個版本。[$3 顯示變更]",
        "sessionfailure-title": "連線階段失敗",
        "sessionfailure": "您的登入連線階段似乎有問題,為了預防連線階段受到劫持攻擊,此動作已經被取消。請重新提交表單。",
        "changecontentmodel": "變更頁面的內容模型",
        "mycontris": "貢獻",
        "anoncontribs": "貢獻",
        "contribsub2": "{{GENDER:$3|$1}}的貢獻($2)",
+       "contributions-subtitle": "對於{{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "使用者帳號 \"$1\" 尚未註冊。",
        "negative-namespace-not-supported": "不支援帶有負值的命名空間。",
        "nocontribs": "沒有找到符合條件的變更。",
        "ipb-confirm": "確認封鎖",
        "ipb-sitewide": "全站範圍",
        "ipb-partial": "部分",
+       "ipb-sitewide-help": "在 wiki 上的各個頁面以及其它貢獻行為。",
+       "ipb-partial-help": "特殊頁面或命名空間。",
        "ipb-pages-label": "頁面",
        "ipb-namespaces-label": "命名空間",
        "badipaddress": "無效的 IP 位址",
        "tooltip-watchlistedit-raw-submit": "更新監視清單",
        "tooltip-recreate": "無論是否被刪除,重新建立該頁面。",
        "tooltip-upload": "開始上傳",
-       "tooltip-rollback": "點選「還原」連結便可還原至上一位貢獻者對此頁面的編輯",
+       "tooltip-rollback": "點選「回退」連結便可還原至上一位貢獻者對此頁面的編輯",
        "tooltip-undo": "「復原」可還原此編輯並以預覽模式開啟編輯表單,讓您可在摘要中加入原因。",
        "tooltip-preferences-save": "儲存偏好設定",
        "tooltip-summary": "請輸入簡短摘要",
        "print.css": "/* 此處的 CSS 會影響列印輸出 */",
        "noscript.css": "/* 此 CSS 會影響沒有啟用 JavaScript 的使用者 */",
        "group-autoconfirmed.css": "/* 此 CSS 會影響自動確認的使用者 */",
+       "group-user.css": "/* 置於此處的CSS只會影響已註冊使用者 */",
        "group-bot.css": "/* 此 CSS 會影響機器人 */",
        "group-sysop.css": "/* 這裡的 CSS 會影響管理員 */",
        "group-bureaucrat.css": "/* 此 CSS 會影響行政員 */",
        "common.json": "/* 在此的任一 JavaScript 會為全部使用者在所有頁面裡載入。 */",
        "common.js": "/* 此 JavaScript 會用於使用者載入的每一個頁面。 */",
+       "group-autoconfirmed.js": "/* 這裡的任何JavaScript只會為自動確認的使用者載入 */",
+       "group-user.js": "/* 這裡的任何JavaScript只會為已註冊使用者載入 */",
+       "group-bot.js": "/* 這裡的任何JavaScript只會為機器人載入 */",
        "group-sysop.js": "/* 這裡的 JavaScript 會影響管理員 */",
+       "group-bureaucrat.js": "/* 這裡的任何JavaScript只會為行政員載入 */",
        "anonymous": "{{SITENAME}} 的匿名{{PLURAL:$1|使用者}}",
        "siteuser": "{{SITENAME}}使用者 $1",
        "anonuser": "{{SITENAME}} 匿名使用者 $1",
        "spam_blanking": "所有修訂均包含 $1 連結,清空中",
        "spam_deleting": "所有修訂均包含 $1 連結,刪除中",
        "simpleantispam-label": "防垃圾訊息檢查用。\n請 <strong>勿</strong> 填寫此欄位!",
-       "pageinfo-title": "\"$1\" 的資訊",
+       "pageinfo-title": "「$1」的資訊",
        "pageinfo-not-current": "抱歉,無法提供先前修訂的資訊。",
        "pageinfo-header-basic": "基本資訊",
        "pageinfo-header-edits": "編輯歷史",
        "confirm-unwatch-top": "從您的監視清單中移除此頁面?",
        "confirm-rollback-button": "確定",
        "confirm-rollback-top": "還原編輯到此頁面?",
+       "confirm-rollback-bottom": "此操作會立即回退對於此頁面的所選更改。",
        "confirm-mcrrestore-title": "還原修訂",
        "confirm-mcrundo-title": "還原變更",
        "mcrundofailed": "還原失敗",
        "logentry-newusers-autocreate": "已自動{{GENDER:$2|建立}}使用者帳號 $1",
        "logentry-protect-move_prot": "$1 {{GENDER:$2|已移動}}保護設定從 $4 至 $3",
        "logentry-protect-unprotect": "$1 {{GENDER:$2|已移除}} $3 的保護",
-       "logentry-protect-protect": "$1 {{GENDER:$2|已保護}} $3 $4",
+       "logentry-protect-protect": "$1 {{GENDER:$2|pó-hō͘ liáu}} $3 $4",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|已保護}} $3 $4 [連鎖]",
        "logentry-protect-modify": "$1 {{GENDER:$2|已變更}} $3 的保護層級 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|已變更}} $3 的保護層級 $4 [連鎖]",
        "logentry-rights-autopromote": "$1 已自動{{GENDER:$2|提升}}從 $4 成為 $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|已上傳}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|上傳了}}新版本的 $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|已上傳}} $3",
+       "logentry-upload-revert": "$1{{GENDER:$2|已還原}}$3至舊版本",
        "log-name-managetags": "標籤管理日誌",
        "log-description-managetags": "此頁面列出與[[Special:Tags|標籤]]相關的管理工作項目。 在日誌中僅包含由管理員手動所做的操作;被 Wiki 軟體所建立或刪除的標籤項目,不會記錄在此日誌中",
        "logentry-managetags-create": "$1 {{GENDER:$2|已建立}}標籤 \"$4\"",
        "log-action-filter-managetags-delete": "標籤刪除",
        "log-action-filter-managetags-activate": "標籤啟動",
        "log-action-filter-managetags-deactivate": "標籤取消啟動",
-       "log-action-filter-move-move": "移動不覆寫重新導向",
+       "log-action-filter-move-move": "移動不覆寫重新導向",
        "log-action-filter-move-move_redir": "移動覆寫重新導向",
        "log-action-filter-newusers-create": "由匿名使用者建立",
        "log-action-filter-newusers-create2": "由註冊使用者建立",
        "log-action-filter-suppress-reblock": "由重新封鎖禁止顯示使用者",
        "log-action-filter-upload-upload": "新上傳",
        "log-action-filter-upload-overwrite": "重新上傳",
+       "log-action-filter-upload-revert": "還原",
        "authmanager-authn-not-in-progress": "認證尚未進行或連線階段資料已遺失,請重頭再開始。",
        "authmanager-authn-no-primary": "提供的憑證無法用來認証。",
        "authmanager-authn-no-local-user": "提供的憑證沒有與任何在此 wiki 上的使用者相關聯。",
        "authmanager-create-no-primary": "提供的憑證不能用於帳號建立。",
        "authmanager-link-no-primary": "提供的憑證無使用在帳號連結。",
        "authmanager-link-not-in-progress": "帳號連結尚未進行或連線階段資料已遺失,請重頭再開始。",
-       "authmanager-authplugin-setpass-failed-title": "密碼變更失敗",
-       "authmanager-authplugin-setpass-failed-message": "認証外掛已拒絕密碼變更。",
-       "authmanager-authplugin-create-fail": "認証外掛已拒絕帳號建立。",
-       "authmanager-authplugin-setpass-denied": "驗證外掛程式不允許變更密碼。",
-       "authmanager-authplugin-setpass-bad-domain": "無效網域。",
        "authmanager-autocreate-noperm": "不允許自動帳號建立。",
        "authmanager-autocreate-exception": "自動帳號建立因發生錯誤臨時關閉。",
        "authmanager-userdoesnotexist": "使用者帳號 \"$1\" 尚未註冊。",
        "passwordpolicies-policy-maximalpasswordlength": "密碼必須小於 $1 個{{PLURAL:$1|字元|字元}}長度",
        "passwordpolicies-policy-passwordcannotbepopular": "密碼不可以是{{PLURAL:$1|常用密碼內容|在清單中的編號 $1 常用密碼}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "不能採用列在 100000 個最常用到密碼清單當中的密碼。",
+       "passwordpolicies-policyflag-forcechange": "必須在登入時更改",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "建議在登入時更改",
        "easydeflate-invaliddeflate": "提供的內容未被正常的壓縮",
        "unprotected-js": "基於安全因素,JavaScript 不能從未保護的頁面來載入。建立 JavaScript 請僅在 MediaWiki 的:命名空間或使用者子頁面"
 }
index cc1a3ae..4cdf3ae 100644 (file)
@@ -17,7 +17,8 @@
                        "Quest for Truth",
                        "Wxyveronica",
                        "和平至上",
-                       "A2093064"
+                       "A2093064",
+                       "WQL"
                ]
        },
        "tog-watchlisthidebots": "隱藏監視清單中機械人的編輯",
@@ -50,7 +51,7 @@
        "namespaces": "命名空間",
        "variants": "變體",
        "navigation-heading": "導覽菜單",
-       "tagline": "å¾\9e {{SITENAME}}",
+       "tagline": "å\87ºè\87ª{{SITENAME}}",
        "help": "說明",
        "search": "搜尋",
        "searchbutton": "搜尋",
index 6646122..25bab21 100644 (file)
@@ -54,6 +54,7 @@ $specialPageAliases = [
        'Ancientpages'              => [ 'Nejstarší_stránky', 'Staré_stránky', 'Stare_stranky' ],
        'ApiHelp'                   => [ 'Nápověda_k_API' ],
        'ApiSandbox'                => [ 'API_pískoviště' ],
+       'AutoblockList'             => [ 'Seznam_automatických_blokování' ],
        'Badtitle'                  => [ 'Neplatný_název' ],
        'Blankpage'                 => [ 'Prázdná_stránka' ],
        'Block'                     => [ 'Blokování', 'Blokovani', 'Blokovat_uživatele', 'Blokovat_IP', 'Blokovat_uzivatele' ],
@@ -62,6 +63,7 @@ $specialPageAliases = [
        'BrokenRedirects'           => [ 'Přerušená_přesměrování', 'Prerusena_presmerovani' ],
        'Categories'                => [ 'Kategorie' ],
        'ChangeContentModel'        => [ 'Změnit_model_obsahu_stránky' ],
+       'ChangeCredentials'         => [ 'Změna_přihlašovacích_údajů' ],
        'ChangeEmail'               => [ 'Změna_emailu', 'Zmena_emailu' ],
        'ChangePassword'            => [ 'Změna_hesla', 'Zmena_hesla' ],
        'ComparePages'              => [ 'Porovnání_stránek', 'PorovnáníStránek', 'Porovnani_stranek', 'PorovnaniStranek' ],
@@ -111,7 +113,7 @@ $specialPageAliases = [
        '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' ],
+       'Newimages'                 => [ 'Nové_soubory', 'Nové_obrázky', 'Galerie_nových_obrázků', 'Nove_obrazky' ],
        'Newpages'                  => [ 'Nové_stránky', 'Nove_stranky', 'Nejnovější_stránky', 'Nejnovejsi_stranky' ],
        'PagesWithProp'             => [ 'Stránky_s_vlastností', 'Stránky_s_vlastnostmi' ],
        'PasswordReset'             => [ 'Reset_hesla', 'Resetovat_heslo', 'Obnova_hesla', 'Obnovit_heslo' ],
@@ -127,6 +129,8 @@ $specialPageAliases = [
        'Recentchanges'             => [ 'Poslední_změny', 'Posledni_zmeny' ],
        'Recentchangeslinked'       => [ 'Související_změny', 'Souvisejici_zmeny' ],
        'Redirect'                  => [ 'Přesměrování', 'Přesměrovat' ],
+       'RemoveCredentials'         => [ 'Odstranění_přihlašovacích_údajů' ],
+       'ResetTokens'               => [ 'Reinicializace_klíčů' ],
        'Revisiondelete'            => [ 'Smazat_revizi' ],
        'Search'                    => [ 'Hledání', 'Hledani' ],
        'Shortpages'                => [ 'Nejkratší_stránky', 'Nejkratsi_stranky' ],
index f325641..86ac01a 100644 (file)
@@ -438,7 +438,7 @@ $specialPageAliases = [
        'Listgrants'                => [ 'ListGrants' ],
        'Listredirects'             => [ 'ListRedirects' ],
        'ListDuplicatedFiles'       => [ 'ListDuplicatedFiles', 'ListFileDuplicates' ],
-       'Listusers'                 => [ 'ListUsers', 'UserList' ],
+       'Listusers'                 => [ 'ListUsers', 'UserList', 'Users' ],
        'Lockdb'                    => [ 'LockDB' ],
        'Log'                       => [ 'Log', 'Logs' ],
        'Lonelypages'               => [ 'LonelyPages', 'OrphanedPages' ],
diff --git a/languages/messages/MessagesNqo.php b/languages/messages/MessagesNqo.php
new file mode 100644 (file)
index 0000000..4de60f3
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/** N'Ko (ߒߞߏ)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
+
+$rtl = true;
+
+$namespaceNames = [
+       NS_MEDIA            => 'ߟߊߛߋߢߊߥߙߍ',
+       NS_SPECIAL          => 'ߞߙߍߞߙߍߣߍ߲',
+       NS_TALK             => 'ߢߊߝߐߞߣߍ',
+       NS_USER             => 'ߟߊߓߊ߯ߙߟߊ',
+       NS_USER_TALK        => 'ߟߊߓߊ߯ߙߟߊ ߟߊ߫ ߢߊߝߐߞߣߍ',
+       NS_PROJECT_TALK     => '$1 ߢߊߝߐߞߣߍ',
+       NS_FILE             => 'ߞߐߕߐ߮',
+       NS_FILE_TALK        => 'ߞߐߕߐ߮ ߢߊߝߐߞߣߍ',
+       NS_MEDIAWIKI        => 'ߡߘߌߦߊߥߞߌ',
+       NS_MEDIAWIKI_TALK   => 'ߡߘߌߦߊߥߞߌ ߢߊߝߐߞߣߍ',
+       NS_TEMPLATE         => 'ߞߙߊߞߏ',
+       NS_TEMPLATE_TALK    => 'ߞߙߊߞߏ ߢߊߝߐߞߣߍ',
+       NS_HELP             => 'ߡߊ߬ߘߍ߬ߡߍ߲߬ߠߌ߲',
+       NS_HELP_TALK        => 'ߡߊ߬ߘߍ߬ߡߍ߲߬ߠߌ߲ ߢߊߝߐߞߣߍ',
+       NS_CATEGORY         => 'ߦߌߟߡߊ',
+       NS_CATEGORY_TALK    => 'ߦߌߟߡߊ ߢߊߝߐߞߣߍ',
+];
+
+$digitTransformTable = [
+       '0' => '߀', # U+07C0
+       '1' => '߁', # U+07C1
+       '2' => '߂', # U+07C2
+       '3' => '߃', # U+07C3
+       '4' => '߄', # U+07C4
+       '5' => '߅', # U+07C5
+       '6' => '߆', # U+07C6
+       '7' => '߇', # U+07C7
+       '8' => '߈', # U+07C8
+       '9' => '߉', # U+07C9
+];
index 9c1093b..6a763f2 100644 (file)
@@ -24,6 +24,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\Shell\Shell;
+
 /**
  * Stream wrapper around 7za filter program.
  * Required since we can't pass an open file resource to XMLReader->open()
@@ -48,7 +50,7 @@ class SevenZipStream {
                } else {
                        return false;
                }
-               $arg = wfEscapeShellArg( $this->stripPath( $path ) );
+               $arg = Shell::escape( $this->stripPath( $path ) );
                $command = "7za $options $arg";
                if ( !wfIsWindows() ) {
                        // Suppress the stupid messages on stderr
index f3c2e12..c88a1a0 100644 (file)
@@ -42,6 +42,13 @@ define( 'DO_MAINTENANCE', RUN_MAINTENANCE_IF_MAIN ); // original name, harmless
 
 $maintClass = false;
 
+// Some extensions rely on MW_INSTALL_PATH to find core files to include. Setting it here helps them
+// if they're included by a core script (like DatabaseUpdater) after Maintenance.php has already
+// been run.
+if ( strval( getenv( 'MW_INSTALL_PATH' ) ) === '' ) {
+       putenv( 'MW_INSTALL_PATH=' . realpath( __DIR__ . '/..' ) );
+}
+
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
@@ -54,6 +61,18 @@ use Wikimedia\Rdbms\IMaintainableDatabase;
  * is the execute() method. See docs/maintenance.txt for more info
  * and a quick demo of how to use it.
  *
+ * Terminology:
+ *   params: registry of named values that may be passed to the script
+ *   arg list: registry of positional values that may be passed to the script
+ *   options: passed param values
+ *   args: passed positional values
+ *
+ * In the command:
+ *   mwscript somescript.php --foo=bar baz
+ * foo is a param
+ * bar is the option value of the option for param foo
+ * baz is the arg value at index 0 in the arg list
+ *
  * @since 1.16
  * @ingroup Maintenance
  */
@@ -69,13 +88,13 @@ abstract class Maintenance {
        // Const for getStdin()
        const STDIN_ALL = 'all';
 
-       // This is the desired params
+       // Array of desired/allowed params
        protected $mParams = [];
 
        // Array of mapping short parameters to long ones
        protected $mShortParamsMap = [];
 
-       // Array of desired args
+       // Array of desired/allowed args
        protected $mArgList = [];
 
        // This is the list of options that were actually passed
@@ -159,11 +178,8 @@ abstract class Maintenance {
         * their own constructors
         */
        public function __construct() {
-               // Setup $IP, using MW_INSTALL_PATH if it exists
                global $IP;
-               $IP = strval( getenv( 'MW_INSTALL_PATH' ) ) !== ''
-                       ? getenv( 'MW_INSTALL_PATH' )
-                       : realpath( __DIR__ . '/..' );
+               $IP = getenv( 'MW_INSTALL_PATH' );
 
                $this->addDefaultParams();
                register_shutdown_function( [ $this, 'outputChanneled' ], false );
@@ -324,6 +340,10 @@ abstract class Maintenance {
         * @return bool
         */
        protected function hasArg( $argId = 0 ) {
+               if ( func_num_args() === 0 ) {
+                       wfDeprecated( __METHOD__ . ' without an $argId', '1.33' );
+               }
+
                return isset( $this->mArgs[$argId] );
        }
 
@@ -334,6 +354,10 @@ abstract class Maintenance {
         * @return mixed
         */
        protected function getArg( $argId = 0, $default = null ) {
+               if ( func_num_args() === 0 ) {
+                       wfDeprecated( __METHOD__ . ' without an $argId', '1.33' );
+               }
+
                return $this->hasArg( $argId ) ? $this->mArgs[$argId] : $default;
        }
 
@@ -697,7 +721,7 @@ abstract class Maintenance {
                }
 
                /**
-                * @var $child Maintenance
+                * @var Maintenance $child
                 */
                $child = new $maintClass();
                $child->loadParamsAndArgs( $this->mSelf, $this->mOptions, $this->mArgs );
@@ -738,7 +762,6 @@ abstract class Maintenance {
                }
 
                $this->loadParamsAndArgs();
-               $this->maybeHelp();
 
                # Set the memory limit
                # Note we need to set it again later in cache LocalSettings changed it
@@ -758,8 +781,6 @@ abstract class Maintenance {
                while ( ob_get_level() > 0 ) {
                        ob_end_flush();
                }
-
-               $this->validateParamsAndArgs();
        }
 
        /**
@@ -862,14 +883,7 @@ abstract class Maintenance {
                                        $this->setParam( $options, $option, $param );
                                } else {
                                        $bits = explode( '=', $option, 2 );
-                                       if ( count( $bits ) > 1 ) {
-                                               $option = $bits[0];
-                                               $param = $bits[1];
-                                       } else {
-                                               $param = 1;
-                                       }
-
-                                       $this->setParam( $options, $option, $param );
+                                       $this->setParam( $options, $bits[0], $bits[1] ?? 1 );
                                }
                        } elseif ( $arg == '-' ) {
                                # Lonely "-", often used to indicate stdin or stdout.
@@ -979,7 +993,7 @@ abstract class Maintenance {
        /**
         * Run some validation checks on the params, etc
         */
-       protected function validateParamsAndArgs() {
+       public function validateParamsAndArgs() {
                $die = false;
                # Check to make sure we've got all the required options
                foreach ( $this->mParams as $opt => $info ) {
@@ -1005,9 +1019,7 @@ abstract class Maintenance {
                        }
                }
 
-               if ( $die ) {
-                       $this->maybeHelp( true );
-               }
+               $this->maybeHelp( $die );
        }
 
        /**
@@ -1183,7 +1195,7 @@ abstract class Maintenance {
 
                        if ( $wgDBservers ) {
                                /**
-                                * @var $wgDBservers array
+                                * @var array $wgDBservers
                                 */
                                foreach ( $wgDBservers as $i => $server ) {
                                        $wgDBservers[$i]['user'] = $wgDBuser;
@@ -1251,12 +1263,9 @@ abstract class Maintenance {
                        $settingsFile = "$IP/LocalSettings.php";
                }
                if ( isset( $this->mOptions['wiki'] ) ) {
-                       $bits = explode( '-', $this->mOptions['wiki'] );
-                       if ( count( $bits ) == 1 ) {
-                               $bits[] = '';
-                       }
+                       $bits = explode( '-', $this->mOptions['wiki'], 2 );
                        define( 'MW_DB', $bits[0] );
-                       define( 'MW_PREFIX', $bits[1] );
+                       define( 'MW_PREFIX', $bits[1] ?? '' );
                } elseif ( isset( $this->mOptions['server'] ) ) {
                        // Provide the option for site admins to detect and configure
                        // multiple wikis based on server names. This offers --server
@@ -1281,27 +1290,45 @@ abstract class Maintenance {
         * @author Rob Church <robchur@gmail.com>
         */
        public function purgeRedundantText( $delete = true ) {
+               global $wgMultiContentRevisionSchemaMigrationStage;
+
                # Data should come off the master, wrapped in a transaction
                $dbw = $this->getDB( DB_MASTER );
                $this->beginTransaction( $dbw, __METHOD__ );
 
-               # Get "active" text records from the revisions table
-               $cur = [];
-               $this->output( 'Searching for active text records in revisions table...' );
-               $res = $dbw->select( 'revision', 'rev_text_id', [], __METHOD__, [ 'DISTINCT' ] );
-               foreach ( $res as $row ) {
-                       $cur[] = $row->rev_text_id;
-               }
-               $this->output( "done.\n" );
+               if ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_OLD ) {
+                       # Get "active" text records from the revisions table
+                       $cur = [];
+                       $this->output( 'Searching for active text records in revisions table...' );
+                       $res = $dbw->select( 'revision', 'rev_text_id', [], __METHOD__, [ 'DISTINCT' ] );
+                       foreach ( $res as $row ) {
+                               $cur[] = $row->rev_text_id;
+                       }
+                       $this->output( "done.\n" );
 
-               # Get "active" text records from the archive table
-               $this->output( 'Searching for active text records in archive table...' );
-               $res = $dbw->select( 'archive', 'ar_text_id', [], __METHOD__, [ 'DISTINCT' ] );
-               foreach ( $res as $row ) {
-                       # old pre-MW 1.5 records can have null ar_text_id's.
-                       if ( $row->ar_text_id !== null ) {
-                               $cur[] = $row->ar_text_id;
+                       # Get "active" text records from the archive table
+                       $this->output( 'Searching for active text records in archive table...' );
+                       $res = $dbw->select( 'archive', 'ar_text_id', [], __METHOD__, [ 'DISTINCT' ] );
+                       foreach ( $res as $row ) {
+                               # old pre-MW 1.5 records can have null ar_text_id's.
+                               if ( $row->ar_text_id !== null ) {
+                                       $cur[] = $row->ar_text_id;
+                               }
                        }
+                       $this->output( "done.\n" );
+               } else {
+                       # Get "active" text records via the content table
+                       $cur = [];
+                       $this->output( 'Searching for active text records via contents table...' );
+                       $res = $dbw->select( 'content', 'content_address', [], __METHOD__, [ 'DISTINCT' ] );
+                       $blobStore = MediaWikiServices::getInstance()->getBlobStore();
+                       foreach ( $res as $row ) {
+                               $textId = $blobStore->getTextIdFromAddress( $row->content_address );
+                               if ( $textId ) {
+                                       $cur[] = $textId;
+                               }
+                       }
+                       $this->output( "done.\n" );
                }
                $this->output( "done.\n" );
 
@@ -1427,7 +1454,7 @@ abstract class Maintenance {
                        'user',
                        'page_restrictions'
                ];
-               $db->lockTables( $read, $write, __CLASS__ . '::' . __METHOD__ );
+               $db->lockTables( $read, $write, __CLASS__ . '-searchIndexLock' );
        }
 
        /**
@@ -1435,7 +1462,7 @@ abstract class Maintenance {
         * @param IMaintainableDatabase &$db
         */
        private function unlockSearchindex( $db ) {
-               $db->unlockTables( __CLASS__ . '::' . __METHOD__ );
+               $db->unlockTables( __CLASS__ . '-searchIndexLock' );
        }
 
        /**
@@ -1592,10 +1619,10 @@ abstract class Maintenance {
                $bash = ExecutableFinder::findInDefaultPaths( 'bash' );
                if ( !wfIsWindows() && $bash ) {
                        $retval = false;
-                       $encPrompt = wfEscapeShellArg( $prompt );
+                       $encPrompt = Shell::escape( $prompt );
                        $command = "read -er -p $encPrompt && echo \"\$REPLY\"";
-                       $encCommand = wfEscapeShellArg( $command );
-                       $line = wfShellExec( "$bash -c $encCommand", $retval, [], [ 'walltime' => 0 ] );
+                       $encCommand = Shell::escape( $command );
+                       $line = Shell::escape( "$bash -c $encCommand", $retval, [], [ 'walltime' => 0 ] );
 
                        if ( $retval == 0 ) {
                                return $line;
diff --git a/maintenance/archives/patch-job-params-mediumblob.sql b/maintenance/archives/patch-job-params-mediumblob.sql
new file mode 100644 (file)
index 0000000..19fe0b6
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE /*$wgDBprefix*/job
+MODIFY COLUMN job_params mediumblob NOT NULL;
index 3a79ad3..a3a4974 100644 (file)
@@ -75,7 +75,7 @@ class BenchmarkParse extends Maintenance {
                // Set as a member variable to avoid function calls when we're timing the parse
                $this->linkCache = MediaWikiServices::getInstance()->getLinkCache();
 
-               $title = Title::newFromText( $this->getArg() );
+               $title = Title::newFromText( $this->getArg( 0 ) );
                if ( !$title ) {
                        $this->error( "Invalid title" );
                        exit( 1 );
@@ -145,7 +145,7 @@ class BenchmarkParse extends Maintenance {
                        ],
                        __METHOD__,
                        [ 'ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 1 ],
-                       [ 'revision' => [ 'INNER JOIN', 'rev_page=page_id' ] ]
+                       [ 'revision' => [ 'JOIN', 'rev_page=page_id' ] ]
                );
 
                return $id;
index 564f7ce..1d85dcc 100644 (file)
@@ -307,7 +307,7 @@ SPARQL;
                        'rc_type' => RC_LOG,
                ] );
                $it->addJoinConditions( [
-                       'page' => [ 'INNER JOIN', 'rc_cur_id = page_id' ],
+                       'page' => [ 'JOIN', 'rc_cur_id = page_id' ],
                ] );
                $this->addIndex( $it );
                return $it;
@@ -402,7 +402,7 @@ SPARQL;
        /**
         * Get iterator for links for categories.
         * @param IDatabase $dbr
-        * @param array $ids List of page IDs
+        * @param int[] $ids List of page IDs
         * @return Traversable
         */
        protected function getCategoryLinksIterator( IDatabase $dbr, array $ids ) {
index a1820b8..eb45cfc 100644 (file)
@@ -30,7 +30,7 @@ require_once __DIR__ . '/Maintenance.php';
  * @ingroup Maintenance
  */
 class CleanupInvalidDbKeys extends Maintenance {
-       /** @var array List of tables to clean up, and the field prefix for that table */
+       /** @var array[] List of tables to clean up, and the field prefix for that table */
        protected static $tables = [
                // Data tables
                [ 'page', 'page' ],
@@ -121,8 +121,7 @@ TEXT
         * @param array $tableParams A child array of self::$tables
         */
        protected function cleanupTable( $tableParams ) {
-               $table = $tableParams[0];
-               $prefix = $tableParams[1];
+               list( $table, $prefix ) = $tableParams;
                $idField = $tableParams['idField'] ?? "{$prefix}_id";
                $nsField = $tableParams['nsField'] ?? "{$prefix}_namespace";
                $titleField = $tableParams['titleField'] ?? "{$prefix}_title";
index a52ce17..66fc6d3 100644 (file)
@@ -60,7 +60,6 @@ class CleanupPreferences extends Maintenance {
                global $wgHiddenPrefs, $wgDefaultUserOptions;
 
                $dbw = $this->getDB( DB_MASTER );
-               $didWork = false;
                $hidden = $this->hasOption( 'hidden' );
                $unknown = $this->hasOption( 'unknown' );
                $bogus = $this->hasOption( 'bogus' );
@@ -100,9 +99,6 @@ class CleanupPreferences extends Maintenance {
                }
        }
 
-       /**
-        *
-        */
        private function deleteByWhere( $dbw, $startMessage, $where ) {
                $this->output( $startMessage . "...\n" );
                $total = 0;
index 17d2e18..e1ea247 100644 (file)
@@ -52,7 +52,7 @@ class CleanupSpam extends Maintenance {
                // Hack: Grant bot rights so we don't flood RecentChanges
                $wgUser->addGroup( 'bot' );
 
-               $spec = $this->getArg();
+               $spec = $this->getArg( 0 );
 
                $protConds = [];
                foreach ( [ 'http://', 'https://' ] as $prot ) {
@@ -68,7 +68,7 @@ class CleanupSpam extends Maintenance {
                        $this->output( "Finding spam on " . count( $wgLocalDatabases ) . " wikis\n" );
                        $found = false;
                        foreach ( $wgLocalDatabases as $wikiID ) {
-                               /** @var $dbr Database */
+                               /** @var Database $dbr */
                                $dbr = $this->getDB( DB_REPLICA, [], $wikiID );
 
                                foreach ( $protConds as $conds ) {
@@ -97,7 +97,7 @@ class CleanupSpam extends Maintenance {
                        // Clean up spam on this wiki
 
                        $count = 0;
-                       /** @var $dbr Database */
+                       /** @var Database $dbr */
                        $dbr = $this->getDB( DB_REPLICA );
                        foreach ( $protConds as $prot => $conds ) {
                                $res = $dbr->select(
index 3ace09c..b78e691 100644 (file)
@@ -165,7 +165,7 @@ class TableCleanup extends Maintenance {
        }
 
        /**
-        * @param array $matches
+        * @param string[] $matches
         * @return string
         */
        protected function hexChar( $matches ) {
index b2fdf2f..61d1e5d 100644 (file)
@@ -95,7 +95,7 @@ class CleanupUsersWithNoId extends LoggedUpdateMaintenance {
         * @param IDatabase $dbw
         * @param string[] $indexFields Fields in the index being ordered by
         * @param object $row Database row
-        * @return array [ string $next, string $display ]
+        * @return string[] [ string $next, string $display ]
         */
        private function makeNextCond( $dbw, $indexFields, $row ) {
                $next = '';
index 6c1edc2..a09ca5c 100644 (file)
@@ -19,7 +19,7 @@ class ConvertExtensionToRegistration extends Maintenance {
        /**
         * Things that were formerly globals and should still be converted
         *
-        * @var array
+        * @var string[]
         */
        protected $formerGlobals = [
                'TrackingCategories',
@@ -28,7 +28,7 @@ class ConvertExtensionToRegistration extends Maintenance {
        /**
         * No longer supported globals (with reason) should not be converted and emit a warning
         *
-        * @var array
+        * @var string[]
         */
        protected $noLongerSupportedGlobals = [
                'SpecialPageGroups' => 'deprecated', // Deprecated 1.21, removed in 1.26
@@ -37,7 +37,7 @@ class ConvertExtensionToRegistration extends Maintenance {
        /**
         * Keys that should be put at the top of the generated JSON file (T86608)
         *
-        * @var array
+        * @var string[]
         */
        protected $promote = [
                'name',
index af60eaa..59820a5 100644 (file)
@@ -126,7 +126,6 @@ class ConvertLinks extends Maintenance {
                $res = $dbw->query( "SELECT COUNT(*) AS count FROM $links" );
                $row = $dbw->fetchObject( $res );
                $numRows = $row->count;
-               $dbw->freeResult( $res );
 
                if ( $numRows == 0 ) {
                        $this->output( "Updating schema (no rows to convert)...\n" );
@@ -168,7 +167,6 @@ class ConvertLinks extends Maintenance {
                                        }
                                }
                        }
-                       $dbw->freeResult( $res );
                        $dbw->bufferResults( true );
                        $this->output( "Finished loading IDs.\n\n" );
                        $this->performanceLog(
@@ -214,7 +212,6 @@ class ConvertLinks extends Maintenance {
                                                $numBadLinks++;
                                        }
                                }
-                               $dbw->freeResult( $res );
                                # $this->output( "rowOffset: $rowOffset\ttuplesAdded: "
                                #       . "$tuplesAdded\tnumBadLinks: $numBadLinks\n" );
                                if ( $tuplesAdded != 0 ) {
index 3374893..9ba5bf5 100644 (file)
@@ -168,7 +168,7 @@ class CopyFileBackend extends Maintenance {
         * @param FileBackend $src
         * @param FileBackend $dst
         * @param string $backendRel
-        * @return array (rel paths in $src minus those in $dst)
+        * @return string[] (rel paths in $src minus those in $dst)
         */
        protected function getListingDiffRel( FileBackend $src, FileBackend $dst, $backendRel ) {
                $srcPathsRel = $src->getFileList( [
@@ -200,7 +200,7 @@ class CopyFileBackend extends Maintenance {
        }
 
        /**
-        * @param array $srcPathsRel
+        * @param string[] $srcPathsRel
         * @param string $backendRel
         * @param FileBackend $src
         * @param FileBackend $dst
@@ -288,7 +288,7 @@ class CopyFileBackend extends Maintenance {
        }
 
        /**
-        * @param array $dstPathsRel
+        * @param string[] $dstPathsRel
         * @param string $backendRel
         * @param FileBackend $dst
         * @return void
index 09e8211..4f9e488 100644 (file)
@@ -69,8 +69,8 @@ class DeleteBatch extends Maintenance {
                }
                $wgUser = $user;
 
-               if ( $this->hasArg() ) {
-                       $file = fopen( $this->getArg(), 'r' );
+               if ( $this->hasArg( 0 ) ) {
+                       $file = fopen( $this->getArg( 0 ), 'r' );
                } else {
                        $file = $this->getStdin();
                }
@@ -80,8 +80,6 @@ class DeleteBatch extends Maintenance {
                        $this->fatalError( "Unable to read file, exiting" );
                }
 
-               $dbw = $this->getDB( DB_MASTER );
-
                # Handle each entry
                for ( $linenum = 1; !feof( $file ); $linenum++ ) {
                        $line = trim( fgets( $file ) );
index 8d3f6b3..6f3ea4c 100644 (file)
@@ -84,13 +84,10 @@ class DeleteOrphanedRevisions extends Maintenance {
         * Delete one or more revisions from the database
         * Do this inside a transaction
         *
-        * @param array $id Array of revision id values
+        * @param int[] $id Array of revision id values
         * @param IDatabase $dbw Master DB handle
         */
-       private function deleteRevs( $id, &$dbw ) {
-               if ( !is_array( $id ) ) {
-                       $id = [ $id ];
-               }
+       private function deleteRevs( array $id, &$dbw ) {
                $dbw->delete( 'revision', [ 'rev_id' => $id ], __METHOD__ );
 
                // Delete from ip_changes should a record exist.
index 9917a4f..d767df0 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /**
  * Router for the php cli-server built-in webserver.
- * https://secure.php.net/manual/en/features.commandline.webserver.php
+ * https://www.php.net/manual/en/features.commandline.webserver.php
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,73 +25,59 @@ if ( PHP_SAPI != 'cli-server' ) {
        die( "This script can only be run by php's cli-server sapi." );
 }
 
-ini_set( 'display_errors', 1 );
-error_reporting( E_ALL );
-
-if ( isset( $_SERVER["SCRIPT_FILENAME"] ) ) {
-       # Known resource, sometimes a script sometimes a file
-       $file = $_SERVER["SCRIPT_FILENAME"];
-} elseif ( isset( $_SERVER["SCRIPT_NAME"] ) ) {
-       # Usually unknown, document root relative rather than absolute
-       # Happens with some cases like /wiki/File:Image.png
-       if ( is_readable( $_SERVER['DOCUMENT_ROOT'] . $_SERVER["SCRIPT_NAME"] ) ) {
-               # Just in case this actually IS a file, set it here
-               $file = $_SERVER['DOCUMENT_ROOT'] . $_SERVER["SCRIPT_NAME"];
-       } else {
-               # Otherwise let's pretend that this is supposed to go to index.php
-               $file = $_SERVER['DOCUMENT_ROOT'] . '/index.php';
-       }
-} else {
-       # Meh, we'll just give up
+if ( !isset( $_SERVER['SCRIPT_FILENAME'] ) ) {
+       // Let built-in server handle error.
        return false;
 }
 
-# And now do handling for that $file
-
+// The SCRIPT_FILENAME can be one of three things:
+// 1. Absolute path to a file in the docroot associated with the
+//    path of the current request URL. PHP does this for any file path
+//    where it finds a matching file on disk. For both PHP files, and for
+//    static files.
+// 2. Relative path to router.php (this file), for any unknown URL path
+//    that ends in ".php" or another extension that PHP would execute.
+// 3. Absolute path to {docroot}/index.php, for any other unknown path.
+//    Effectively treating it as a 404 handler.
+$file = $_SERVER['SCRIPT_FILENAME'];
 if ( !is_readable( $file ) ) {
-       # Let the server throw the error if it doesn't exist
+       // Let built-in server handle error.
        return false;
 }
+
 $ext = pathinfo( $file, PATHINFO_EXTENSION );
-if ( $ext == 'php' || $ext == 'php5' ) {
+if ( $ext == 'php' ) {
+       // Let built-in server handle script inclusion.
        return false;
-}
-$mime = false;
-// Borrow mime type file from MimeAnalyzer
-$lines = explode( "\n", file_get_contents( "includes/libs/mime/mime.types" ) );
-foreach ( $lines as $line ) {
-       $exts = explode( " ", $line );
-       $mime = array_shift( $exts );
-       if ( in_array( $ext, $exts ) ) {
-               break; # this is the right value for $mime
-       }
-       $mime = false;
-}
-if ( !$mime ) {
-       $basename = basename( $file );
-       if ( $basename == strtoupper( $basename ) ) {
-               # IF it's something like README serve it as text
-               $mime = "text/plain";
+} else {
+       // Serve static file with appropiate Content-Type headers.
+       // The built-in server for PHP 7.0+ supports most files already
+       // (contrary to PHP 5.2, which was supported when router.php was created).
+       // But it still doesn't support as many MIME types as MediaWiki (e.g. ".json")
+
+       // Fallback
+       $mime = 'text/plain';
+       // Borrow from MimeAnalyzer
+       $lines = explode( "\n", file_get_contents( "includes/libs/mime/mime.types" ) );
+       foreach ( $lines as $line ) {
+               $exts = explode( ' ', $line );
+               $type = array_shift( $exts );
+               if ( in_array( $ext, $exts ) ) {
+                       $mime = $type;
+                       break;
+               }
        }
-}
-if ( $mime ) {
-       # Use custom handling to serve files with a known MIME type
-       # This way we can serve things like .svg files that the built-in
-       # PHP webserver doesn't understand.
-       # ;) Nicely enough we just happen to bundle a mime.types file
-       $f = fopen( $file, 'rb' );
+
        if ( preg_match( '#^text/#', $mime ) ) {
-               # Text should have a charset=UTF-8 (php's webserver does this too)
+               // Text should have a charset=UTF-8 (PHP's webserver does this too)
                header( "Content-Type: $mime; charset=UTF-8" );
        } else {
                header( "Content-Type: $mime" );
        }
        header( "Content-Length: " . filesize( $file ) );
        // Stream that out to the browser
+       $f = fopen( $file, 'rb' );
        fpassthru( $f );
 
        return true;
 }
-
-# Let the php server handle things on its own otherwise
-return false;
index 1e3d410..cc5e6e5 100755 (executable)
@@ -14,7 +14,7 @@ fi
 
 VER=5.6.32
 TAR="php-$VER.tar.gz"
-PHPURL="https://secure.php.net/get/$TAR/from/this/mirror"
+PHPURL="https://www.php.net/get/$TAR/from/this/mirror"
 
 cd "$DEV"
 
index eca58cd..45457f5 100644 (file)
@@ -1792,7 +1792,6 @@ hidepatrolled
 hideredirects
 hiderevision
 hideuser
-hidpi
 highlimit
 highmax
 highuse
@@ -2426,7 +2425,6 @@ mkdir
 mms
 mobile
 mobileformat
-mobilelanding
 mobileview
 modified
 modifiedarticleprotection
index 1f1a4c7..1c53fe8 100644 (file)
@@ -90,6 +90,8 @@ $maintenance->checkRequiredExtensions();
 // This avoids having long running scripts just OOM and lose all the updates.
 $maintenance->setAgentAndTriggers();
 
+$maintenance->validateParamsAndArgs();
+
 // Do the work
 $success = $maintenance->execute();
 
index e4bd756..873d628 100644 (file)
@@ -90,7 +90,7 @@ class DumpCategoriesAsRdf extends Maintenance {
        /**
         * Get iterator for links for categories.
         * @param IDatabase $dbr
-        * @param array $ids List of page IDs
+        * @param int[] $ids List of page IDs
         * @return Traversable
         */
        public function getCategoryLinksIterator( IDatabase $dbr, array $ids ) {
index 512910c..7566fe0 100644 (file)
@@ -29,6 +29,9 @@ require_once __DIR__ . '/7zip.inc';
 require_once __DIR__ . '/../includes/export/WikiExporter.php';
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Shell\Shell;
+use MediaWiki\Storage\BlobAccessException;
+use MediaWiki\Storage\SqlBlobStore;
 use Wikimedia\Rdbms\IMaintainableDatabase;
 
 /**
@@ -139,6 +142,13 @@ TEXT
                }
        }
 
+       /**
+        * @return SqlBlobStore
+        */
+       private function getBlobStore() {
+               return MediaWikiServices::getInstance()->getBlobStore();
+       }
+
        function execute() {
                $this->processOptions();
                $this->dump( true );
@@ -520,17 +530,17 @@ TEXT
        }
 
        /**
-        * Tries to get the revision text for a revision id.
-        * Export transformations are applied if the content model can is given or can be
+        * Tries to load revision text.
+        * Export transformations are applied if the content model is given or can be
         * determined from the database.
         *
         * Upon errors, retries (Up to $this->maxFailures tries each call).
-        * If still no good revision get could be found even after this retrying, "" is returned.
+        * If still no good revision could be found even after this retrying, "" is returned.
         * If no good revision text could be returned for
         * $this->maxConsecutiveFailedTextRetrievals consecutive calls to getText, MWException
         * is thrown.
         *
-        * @param string $id The revision id to get the text for
+        * @param int|string $id Content address, or text row ID.
         * @param string|bool|null $model The content model used to determine
         *  applicable export transformations.
         *  If $model is null, it will be determined from the database.
@@ -558,6 +568,7 @@ TEXT
                $consecutiveFailedTextRetrievals = 0;
 
                if ( $model === null && $wgContentHandlerUseDB ) {
+                       // TODO: MCR: use content table
                        $row = $this->db->selectRow(
                                'revision',
                                [ 'rev_content_model', 'rev_content_format' ],
@@ -700,37 +711,42 @@ TEXT
        }
 
        /**
-        * May throw a database error if, say, the server dies during query.
-        * @param int $id
+        * Loads the serialized content from storage.
+        *
+        * @param int|string $id Content address, or text row ID.
         * @return bool|string
-        * @throws MWException
         */
        private function getTextDb( $id ) {
-               if ( !isset( $this->db ) ) {
-                       throw new MWException( __METHOD__ . "No database available" );
-               }
-               $row = $this->db->selectRow( 'text',
-                       [ 'old_text', 'old_flags' ],
-                       [ 'old_id' => $id ],
-                       __METHOD__ );
-               $text = Revision::getRevisionText( $row );
-               if ( $text === false ) {
+               $store = $this->getBlobStore();
+               $address = ( is_int( $id ) || strpos( $id, ':' ) === false )
+                       ? SqlBlobStore::makeAddressFromTextId( (int)$id )
+                       : $id;
+
+               try {
+                       $text = $store->getBlob( $address );
+
+                       $stripped = str_replace( "\r", "", $text );
+                       $normalized = MediaWikiServices::getInstance()->getContentLanguage()
+                               ->normalize( $stripped );
+
+                       return $normalized;
+               } catch ( BlobAccessException $ex ) {
+                       // XXX: log a warning?
                        return false;
                }
-               $stripped = str_replace( "\r", "", $text );
-               $normalized = MediaWikiServices::getInstance()->getContentLanguage()->
-                       normalize( $stripped );
-
-               return $normalized;
        }
 
-       private function getTextSpawned( $id ) {
+       /**
+        * @param int|string $address Content address, or text row ID.
+        * @return bool|string
+        */
+       private function getTextSpawned( $address ) {
                Wikimedia\suppressWarnings();
                if ( !$this->spawnProc ) {
                        // First time?
                        $this->openSpawn();
                }
-               $text = $this->getTextSpawnedOnce( $id );
+               $text = $this->getTextSpawnedOnce( $address );
                Wikimedia\restoreWarnings();
 
                return $text;
@@ -741,7 +757,7 @@ TEXT
 
                if ( file_exists( "$IP/../multiversion/MWScript.php" ) ) {
                        $cmd = implode( " ",
-                               array_map( 'wfEscapeShellArg',
+                               array_map( [ Shell::class, 'escape' ],
                                        [
                                                $this->php,
                                                "$IP/../multiversion/MWScript.php",
@@ -749,7 +765,7 @@ TEXT
                                                '--wiki', wfWikiID() ] ) );
                } else {
                        $cmd = implode( " ",
-                               array_map( 'wfEscapeShellArg',
+                               array_map( [ Shell::class, 'escape' ],
                                        [
                                                $this->php,
                                                "$IP/maintenance/fetchText.php",
@@ -797,8 +813,16 @@ TEXT
                Wikimedia\restoreWarnings();
        }
 
-       private function getTextSpawnedOnce( $id ) {
-               $ok = fwrite( $this->spawnWrite, "$id\n" );
+       /**
+        * @param int|string $address Content address, or text row ID.
+        * @return bool|string
+        */
+       private function getTextSpawnedOnce( $address ) {
+               if ( is_int( $address ) || intval( $address ) ) {
+                       $address = SqlBlobStore::makeAddressFromTextId( (int)$address );
+               }
+
+               $ok = fwrite( $this->spawnWrite, "$address\n" );
                // $this->progress( ">> $id" );
                if ( !$ok ) {
                        return false;
@@ -810,13 +834,18 @@ TEXT
                        return false;
                }
 
-               // check that the text id they are sending is the one we asked for
+               // check that the text address they are sending is the one we asked for
                // this avoids out of sync revision text errors we have encountered in the past
-               $newId = fgets( $this->spawnRead );
-               if ( $newId === false ) {
+               $newAddress = fgets( $this->spawnRead );
+               if ( $newAddress === false ) {
                        return false;
                }
-               if ( $id != intval( $newId ) ) {
+               $newAddress = trim( $newAddress );
+               if ( strpos( $newAddress, ':' ) === false ) {
+                       $newAddress = SqlBlobStore::makeAddressFromTextId( intval( $newAddress ) );
+               }
+
+               if ( $newAddress !== $address ) {
                        return false;
                }
 
index b4df20f..a5bc6cc 100644 (file)
@@ -82,7 +82,7 @@ By default, outputs relative paths against the parent directory of $wgUploadDire
 
                $sql = "SELECT DISTINCT il_to, img_name
                        FROM $imagelinks
-                       LEFT OUTER JOIN $image
+                       LEFT JOIN $image
                        ON il_to=img_name";
                $result = $dbr->query( $sql );
 
index d4a7bef..3609cf2 100644 (file)
@@ -71,7 +71,7 @@ class EditCLI extends Maintenance {
                        $wgUser->addToDatabase();
                }
 
-               $title = Title::newFromText( $this->getArg() );
+               $title = Title::newFromText( $this->getArg( 0 ) );
                if ( !$title ) {
                        $this->fatalError( "Invalid title" );
                }
index bc4fa31..8d04adc 100644 (file)
@@ -24,7 +24,9 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
-use Wikimedia\Rdbms\IDatabase;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\BlobAccessException;
+use MediaWiki\Storage\SqlBlobStore;
 
 /**
  * Maintenance script used to fetch page text in a subprocess.
@@ -32,14 +34,24 @@ use Wikimedia\Rdbms\IDatabase;
  * @ingroup Maintenance
  */
 class FetchText extends Maintenance {
+
        public function __construct() {
                parent::__construct();
-               $this->addDescription( "Fetch the raw revision blob from an old_id.\n" .
+
+               $this->addDescription( "Fetch the raw revision blob from a blob address.\n" .
+                       "Integer IDs are interpreted as referring to text.old_id for backwards compatibility.\n" .
                        "NOTE: Export transformations are NOT applied. " .
-                       "This is left to backupTextPass.php"
+                       "This is left to dumpTextPass.php"
                );
        }
 
+       /**
+        * @return SqlBlobStore
+        */
+       private function getBlobStore() {
+               return MediaWikiServices::getInstance()->getBlobStore();
+       }
+
        /**
         * returns a string containing the following in order:
         *   textid
@@ -51,7 +63,6 @@ class FetchText extends Maintenance {
         * note that the text string itself is *not* followed by newline
         */
        public function execute() {
-               $db = $this->getDB( DB_REPLICA );
                $stdin = $this->getStdin();
                while ( !feof( $stdin ) ) {
                        $line = fgets( $stdin );
@@ -59,37 +70,30 @@ class FetchText extends Maintenance {
                                // We appear to have lost contact...
                                break;
                        }
-                       $textId = intval( $line );
-                       $text = $this->doGetText( $db, $textId );
-                       if ( $text === false ) {
-                               # actual error, not zero-length text
-                               $textLen = "-1";
-                       } else {
+                       $blobAddress = trim( $line );
+
+                       // Plain integers are supported for backwards compatibility with pre-MCR dumps.
+                       if ( strpos( $blobAddress, ':' ) === false && is_numeric( $blobAddress ) ) {
+                               $blobAddress = SqlBlobStore::makeAddressFromTextId( intval( $blobAddress ) );
+                       }
+
+                       try {
+                               $text = $this->getBlobStore()->getBlob( $blobAddress );
                                $textLen = strlen( $text );
+                       } catch ( BlobAccessException $ex ) {
+                               // XXX: log $ex to stderr?
+                               $textLen = '-1';
+                               $text = '';
+                       } catch ( InvalidArgumentException $ex ) {
+                               // XXX: log $ex to stderr?
+                               $textLen = '-1';
+                               $text = '';
                        }
-                       $this->output( $textId . "\n" . $textLen . "\n" . $text );
-               }
-       }
 
-       /**
-        * May throw a database error if, say, the server dies during query.
-        * @param IDatabase $db
-        * @param int $id The old_id
-        * @return string
-        */
-       private function doGetText( $db, $id ) {
-               $id = intval( $id );
-               $row = $db->selectRow( 'text',
-                       [ 'old_text', 'old_flags' ],
-                       [ 'old_id' => $id ],
-                       __METHOD__ );
-               $text = Revision::getRevisionText( $row );
-               if ( $text === false ) {
-                       return false;
+                       $this->output( $blobAddress . "\n" . $textLen . "\n" . $text );
                }
-
-               return $text;
        }
+
 }
 
 $maintClass = FetchText::class;
index ed7a762..900752f 100644 (file)
@@ -320,6 +320,7 @@ class FindHooks extends Maintenance {
                        $iterator = new DirectoryIterator( $dir );
                }
 
+               /** @var SplFileInfo $info */
                foreach ( $iterator as $info ) {
                        // Ignore directories, work only on php files,
                        if ( $info->isFile() && in_array( $info->getExtension(), [ 'php', 'inc' ] )
index 4997cab..5c1d49e 100644 (file)
@@ -46,7 +46,7 @@ class FindMissingFiles extends Maintenance {
                $joinConds = [];
                if ( $mtime1 || $mtime2 ) {
                        $joinTables[] = 'page';
-                       $joinConds['page'] = [ 'INNER JOIN',
+                       $joinConds['page'] = [ 'JOIN',
                                [ 'page_title = img_name', 'page_namespace' => NS_FILE ] ];
                        $joinTables[] = 'logging';
                        $on = [ 'log_page = page_id', 'log_type' => [ 'upload', 'move', 'delete' ] ];
@@ -56,7 +56,7 @@ class FindMissingFiles extends Maintenance {
                        if ( $mtime2 ) {
                                $on[] = "log_timestamp < {$dbr->addQuotes($mtime2)}";
                        }
-                       $joinConds['logging'] = [ 'INNER JOIN', $on ];
+                       $joinConds['logging'] = [ 'JOIN', $on ];
                }
 
                do {
index 57e04e0..e81e197 100644 (file)
@@ -117,7 +117,7 @@ class FindOrphanedFiles extends Maintenance {
                                                $oiWheres ? $dbr->makeList( $oiWheres, LIST_OR ) : '1=0'
                                        )
                                ],
-                               true // UNION ALL (performance)
+                               $dbr::UNION_ALL
                        ),
                        __METHOD__
                );
index 3d34be1..160a20d 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\MediaWikiServices;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -61,10 +63,10 @@ class FormatInstallDoc extends Maintenance {
                $outText = InstallDocFormatter::format( $inText );
 
                if ( $this->hasOption( 'html' ) ) {
-                       global $wgParser;
+                       $parser = MediaWikiServices::getInstance()->getParser();
                        $opt = new ParserOptions;
                        $title = Title::newFromText( 'Text file' );
-                       $out = $wgParser->parse( $outText, $title, $opt );
+                       $out = $parser->parse( $outText, $title, $opt );
                        $outText = "<html><body>\n" . $out->getText() . "\n</body></html>\n";
                }
 
index efddfb3..e9f4eca 100644 (file)
@@ -79,6 +79,7 @@ class GenerateJsonI18n extends Maintenance {
                        $dir_iterator = new RecursiveDirectoryIterator( dirname( $phpfile ) );
                        $iterator = new RecursiveIteratorIterator(
                                $dir_iterator, RecursiveIteratorIterator::LEAVES_ONLY );
+                       /** @var SplFileInfo $fileObject */
                        foreach ( $iterator as $path => $fileObject ) {
                                if ( fnmatch( "*.i18n.php", $fileObject->getFilename() ) ) {
                                        $this->output( "Converting $path.\n" );
@@ -182,7 +183,7 @@ class GenerateJsonI18n extends Maintenance {
        /**
         * Get an array of author names from a documentation comment containing @author declarations.
         * @param string $comment Documentation comment
-        * @return array Array of author names (strings)
+        * @return string[] Array of author names
         */
        protected function getAuthorsFromComment( $comment ) {
                $matches = null;
index dc1de4f..af5373c 100644 (file)
@@ -230,7 +230,7 @@ class GenerateSitemap extends Maintenance {
                // Custom priorities
                if ( $wgSitemapNamespacesPriorities !== false ) {
                        /**
-                        * @var $wgSitemapNamespacesPriorities array
+                        * @var array $wgSitemapNamespacesPriorities
                         */
                        foreach ( $wgSitemapNamespacesPriorities as $namespace => $priority ) {
                                $float = floatval( $priority );
index de6e87a..f56729c 100644 (file)
@@ -56,7 +56,7 @@ class GetConfiguration extends Maintenance {
                $this->addOption( 'format', implode( ', ', self::$outFormats ), false, true );
        }
 
-       protected function validateParamsAndArgs() {
+       public function validateParamsAndArgs() {
                $error_out = false;
 
                # Get the format and make sure it is set to a valid default value
index cef0dad..9502cdc 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\Shell\Shell;
+
 require __DIR__ . '/../Maintenance.php';
 
 class HHVMMakeRepo extends Maintenance {
@@ -103,7 +105,7 @@ class HHVMMakeRepo extends Maintenance {
 
                $hhvm = $this->getOption( 'hhvm', 'hhvm' );
                $verbose = $this->getOption( 'verbose', 3 );
-               $cmd = wfEscapeShellArg(
+               $cmd = Shell::escape(
                        $hhvm,
                        '--hphp',
                        '--target', 'hhbc',
@@ -149,6 +151,7 @@ class HHVMMakeRepo extends Maintenance {
                        ),
                        RecursiveIteratorIterator::LEAVES_ONLY
                );
+               /** @var SplFileInfo $fileInfo */
                foreach ( $iter as $file => $fileInfo ) {
                        if ( $fileInfo->isFile() ) {
                                $files[] = $file;
index d84e02f..e1deb4c 100755 (executable)
@@ -1,6 +1,8 @@
 #!/usr/bin/hhvm -f
 <?php
 
+use MediaWiki\Shell\Shell;
+
 require __DIR__ . '/../Maintenance.php';
 
 class RunHipHopServer extends Maintenance {
@@ -12,8 +14,8 @@ class RunHipHopServer extends Maintenance {
                global $IP;
 
                passthru(
-                       'cd ' . wfEscapeShellArg( $IP ) . " && " .
-                       wfEscapeShellArg(
+                       'cd ' . Shell::escape( $IP ) . " && " .
+                       Shell::escape(
                                'hhvm',
                                '-c', __DIR__."/server.conf",
                                '--mode=server',
index 7c20748..c2c5ccf 100644 (file)
@@ -112,8 +112,8 @@ TEXT
                        $this->setNsfilter( explode( '|', $this->getOption( 'namespaces' ) ) );
                }
 
-               if ( $this->hasArg() ) {
-                       $this->importFromFile( $this->getArg() );
+               if ( $this->hasArg( 0 ) ) {
+                       $this->importFromFile( $this->getArg( 0 ) );
                } else {
                        $this->importFromStdin();
                }
index 7a2e0f4..1728695 100644 (file)
@@ -418,7 +418,7 @@ class ImportImages extends Maintenance {
                                $files = [];
                                while ( ( $file = readdir( $dhl ) ) !== false ) {
                                        if ( is_file( $dir . '/' . $file ) ) {
-                                               list( /* $name */, $ext ) = $this->splitFilename( $dir . '/' . $file );
+                                               $ext = pathinfo( $file, PATHINFO_EXTENSION );
                                                if ( array_search( strtolower( $ext ), $exts ) !== false ) {
                                                        $files[] = $dir . '/' . $file;
                                                }
@@ -436,21 +436,6 @@ class ImportImages extends Maintenance {
                }
        }
 
-       /**
-        * Split a filename into filename and extension
-        *
-        * @param string $filename
-        * @return array
-        */
-       private function splitFilename( $filename ) {
-               $parts = explode( '.', $filename );
-               $ext = $parts[count( $parts ) - 1];
-               unset( $parts[count( $parts ) - 1] );
-               $fname = implode( '.', $parts );
-
-               return [ $fname, $ext ];
-       }
-
        /**
         * Find an auxilliary file with the given extension, matching
         * the give base file path. $maxStrip determines how many extensions
index 31fe33f..0b450a6 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 require_once __DIR__ . '/../Maintenance.php';
+require_once __DIR__ . '/../../includes/export/WikiExporter.php';
 
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\LoadBalancer;
@@ -51,6 +52,7 @@ abstract class BackupDumper extends Maintenance {
        protected $reportingInterval = 100;
        protected $pageCount = 0;
        protected $revCount = 0;
+       protected $schemaVersion = null; // use default
        protected $server = null; // use default
        protected $sink = null; // Output filters
        protected $lastTime = 0;
@@ -74,9 +76,6 @@ abstract class BackupDumper extends Maintenance {
        /** @var LoadBalancer */
        protected $lb;
 
-       // @todo Unused?
-       private $stubText = false; // include rev_text_id instead of text; for 2-pass dump
-
        /**
         * @param array|null $args For backward compatibility
         */
@@ -89,6 +88,7 @@ abstract class BackupDumper extends Maintenance {
                $this->registerOutput( 'gzip', DumpGZipOutput::class );
                $this->registerOutput( 'bzip2', DumpBZip2Output::class );
                $this->registerOutput( 'dbzip2', DumpDBZip2Output::class );
+               $this->registerOutput( 'lbzip2', DumpLBZip2Output::class );
                $this->registerOutput( '7zip', Dump7ZipOutput::class );
 
                $this->registerFilter( 'latest', DumpLatestFilter::class );
@@ -99,11 +99,13 @@ abstract class BackupDumper extends Maintenance {
                $this->addOption( 'plugin', 'Load a dump plugin class. Specify as <class>[:<file>].',
                        false, true, false, true );
                $this->addOption( 'output', 'Begin a filtered output stream; Specify as <type>:<file>. ' .
-                       '<type>s: file, gzip, bzip2, 7zip, dbzip2', false, true, false, true );
+                       '<type>s: file, gzip, bzip2, 7zip, dbzip2, lbzip2', false, true, false, true );
                $this->addOption( 'filter', 'Add a filter on an output branch. Specify as ' .
                        '<type>[:<options>]. <types>s: latest, notalk, namespace', false, true, false, true );
                $this->addOption( 'report', 'Report position and speed after every n pages processed. ' .
                        'Default: 100.', false, true );
+               $this->addOption( 'schema-version', 'Schema version to use for output. ' .
+                       'Default: ' . WikiExporter::schemaVersion(), false, true );
                $this->addOption( 'server', 'Force reading from MySQL server', false, true );
                $this->addOption( '7ziplevel', '7zip compression level for all 7zip outputs. Used for ' .
                        '-mx option to 7za command.', false, true );
@@ -158,22 +160,20 @@ abstract class BackupDumper extends Maintenance {
                $sink = null;
                $sinks = [];
 
+               $this->schemaVersion = WikiExporter::schemaVersion();
+
                $options = $this->orderedOptions;
                foreach ( $options as $arg ) {
-                       $opt = $arg[0];
-                       $param = $arg[1];
+                       list( $opt, $param ) = $arg;
 
                        switch ( $opt ) {
                                case 'plugin':
-                                       $val = explode( ':', $param );
+                                       $val = explode( ':', $param, 2 );
 
                                        if ( count( $val ) === 1 ) {
                                                $this->loadPlugin( $val[0], '' );
                                        } elseif ( count( $val ) === 2 ) {
                                                $this->loadPlugin( $val[0], $val[1] );
-                                       } else {
-                                               $this->fatalError( 'Invalid plugin parameter' );
-                                               return;
                                        }
 
                                        break;
@@ -202,7 +202,7 @@ abstract class BackupDumper extends Maintenance {
                                                $sink = new DumpOutput();
                                        }
 
-                                       $split = explode( ':', $param );
+                                       $split = explode( ':', $param, 2 );
                                        $key = $split[0];
 
                                        if ( !isset( $this->filterTypes[$key] ) ) {
@@ -215,14 +215,21 @@ abstract class BackupDumper extends Maintenance {
                                                $filter = new $type( $sink );
                                        } elseif ( count( $split ) === 2 ) {
                                                $filter = new $type( $sink, $split[1] );
-                                       } else {
-                                               $this->fatalError( 'Invalid filter parameter' );
                                        }
 
                                        // references are lame in php...
                                        unset( $sink );
                                        $sink = $filter;
 
+                                       break;
+                               case 'schema-version':
+                                       if ( !in_array( $param, XmlDumpWriter::$supportedSchemas ) ) {
+                                               $this->fatalError(
+                                                       "Unsupported schema version $param. Supported versions: " .
+                                                       implode( ', ', XmlDumpWriter::$supportedSchemas )
+                                               );
+                                       }
+                                       $this->schemaVersion = $param;
                                        break;
                        }
                }
@@ -258,6 +265,7 @@ abstract class BackupDumper extends Maintenance {
 
                $db = $this->backupDb();
                $exporter = new WikiExporter( $db, $history, $text );
+               $exporter->setSchemaVersion( $this->schemaVersion );
                $exporter->dumpUploads = $this->dumpUploads;
                $exporter->dumpUploadFileContents = $this->dumpUploadFileContents;
 
index 813f88e..aff6758 100644 (file)
@@ -32,9 +32,13 @@ require_once __DIR__ . '/../Maintenance.php';
  * @ingroup Maintenance
  */
 class MigrateActors extends LoggedUpdateMaintenance {
+
+       protected $tables = null;
+
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Migrates actors from pre-1.31 columns to the \'actor\' table' );
+               $this->addOption( 'tables', 'List of tables to process, comma-separated', false, true );
                $this->setBatchSize( 100 );
        }
 
@@ -42,6 +46,10 @@ class MigrateActors extends LoggedUpdateMaintenance {
                return __CLASS__;
        }
 
+       protected function doTable( $table ) {
+               return $this->tables === null || in_array( $table, $this->tables, true );
+       }
+
        protected function doDBUpdates() {
                global $wgActorTableSchemaMigrationStage;
 
@@ -52,28 +60,51 @@ class MigrateActors extends LoggedUpdateMaintenance {
                        return false;
                }
 
-               $this->output( "Creating actor entries for all registered users\n" );
-               $end = 0;
-               $dbw = $this->getDB( DB_MASTER );
-               $max = $dbw->selectField( 'user', 'MAX(user_id)', '', __METHOD__ );
-               $count = 0;
-               while ( $end < $max ) {
-                       $start = $end + 1;
-                       $end = min( $start + $this->mBatchSize, $max );
-                       $this->output( "... $start - $end\n" );
-                       $dbw->insertSelect(
-                               'actor',
-                               'user',
-                               [ 'actor_user' => 'user_id', 'actor_name' => 'user_name' ],
-                               [ "user_id >= $start", "user_id <= $end" ],
+               $tables = $this->getOption( 'tables' );
+               if ( $tables !== null ) {
+                       $this->tables = explode( ',', $tables );
+               }
+
+               if ( $this->doTable( 'user' ) ) {
+                       $this->output( "Creating actor entries for all registered users\n" );
+                       $end = 0;
+                       $dbw = $this->getDB( DB_MASTER );
+                       $max = $dbw->selectField( 'user', 'MAX(user_id)', '', __METHOD__ );
+                       $count = 0;
+                       while ( $end < $max ) {
+                               $start = $end + 1;
+                               $end = min( $start + $this->mBatchSize, $max );
+                               $this->output( "... $start - $end\n" );
+                               $dbw->insertSelect(
+                                       'actor',
+                                       'user',
+                                       [ 'actor_user' => 'user_id', 'actor_name' => 'user_name' ],
+                                       [ "user_id >= $start", "user_id <= $end" ],
+                                       __METHOD__,
+                                       [ 'IGNORE' ],
+                                       [ 'ORDER BY' => [ 'user_id' ] ]
+                               );
+                               $count += $dbw->affectedRows();
+                               wfWaitForSlaves();
+                       }
+                       $this->output( "Completed actor creation, added $count new actor(s)\n" );
+               } else {
+                       $this->output( "Checking that actors exist for all registered users\n" );
+                       $dbr = $this->getDB( DB_REPLICA, [ 'vslow' ] );
+                       $anyMissing = $dbr->selectField(
+                               [ 'user', 'actor' ],
+                               '1',
+                               [ 'actor_id' => null ],
                                __METHOD__,
-                               [ 'IGNORE' ],
-                               [ 'ORDER BY' => [ 'user_id' ] ]
+                               [ 'LIMIT 1' ],
+                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
                        );
-                       $count += $dbw->affectedRows();
-                       wfWaitForSlaves();
+                       if ( $anyMissing ) {
+                               $this->error( 'Some users lack actors; run without --tables or include `user` in --tables.' );
+                               return false;
+                       }
+                       $this->output( "Ok, continuing.\n" );
                }
-               $this->output( "Completed actor creation, added $count new actor(s)\n" );
 
                $errors = 0;
                $errors += $this->migrateToTemp(
@@ -144,6 +175,8 @@ class MigrateActors extends LoggedUpdateMaintenance {
 
        /**
         * Add actors for anons in a set of rows
+        *
+        * @suppress SecurityCheck-SQLInjection The array_keys/array_map is too much for static analysis
         * @param IDatabase $dbw
         * @param string $nameField
         * @param object[] &$rows
@@ -227,6 +260,11 @@ class MigrateActors extends LoggedUpdateMaintenance {
         * @return int Number of errors
         */
        protected function migrate( $table, $primaryKey, $userField, $nameField, $actorField ) {
+               if ( !$this->doTable( $table ) ) {
+                       $this->output( "Skipping $table, not included in --tables\n" );
+                       return 0;
+               }
+
                $complainedAboutUsers = [];
 
                $primaryKey = (array)$primaryKey;
@@ -323,6 +361,11 @@ class MigrateActors extends LoggedUpdateMaintenance {
        protected function migrateToTemp(
                $table, $primaryKey, $extra, $userField, $nameField, $newPrimaryKey, $actorField
        ) {
+               if ( !$this->doTable( $table ) ) {
+                       $this->output( "Skipping $table, not included in --tables\n" );
+                       return 0;
+               }
+
                $complainedAboutUsers = [];
 
                $newTable = $table . '_actor_temp';
@@ -411,10 +454,14 @@ class MigrateActors extends LoggedUpdateMaintenance {
         * @return int Number of errors
         */
        protected function migrateLogSearch() {
+               if ( !$this->doTable( 'log_search' ) ) {
+                       $this->output( "Skipping log_search, not included in --tables\n" );
+                       return 0;
+               }
+
                $complainedAboutUsers = [];
 
                $primaryKey = [ 'ls_value', 'ls_log_id' ];
-               $pkFilter = array_flip( $primaryKey );
                $this->output( "Beginning migration of log_search\n" );
                wfWaitForSlaves();
 
@@ -423,6 +470,25 @@ class MigrateActors extends LoggedUpdateMaintenance {
                $countActors = 0;
                $countErrors = 0;
 
+               $anyBad = $dbw->selectField(
+                       'log_search',
+                       1,
+                       [ 'ls_field' => 'target_author_actor', 'ls_value' => '' ],
+                       __METHOD__,
+                       [ 'LIMIT' => 1 ]
+               );
+               if ( $anyBad ) {
+                       $this->output( "... Deleting bogus rows due to T215525\n" );
+                       $dbw->delete(
+                               'log_search',
+                               [ 'ls_field' => 'target_author_actor', 'ls_value' => '' ],
+                               __METHOD__
+                       );
+                       $ct = $dbw->affectedRows();
+                       $this->output( "... Deleted $ct bogus row(s) from T215525\n" );
+                       wfWaitForSlaves();
+               }
+
                $next = '1=1';
                while ( true ) {
                        // Fetch the rows needing update
@@ -438,7 +504,7 @@ class MigrateActors extends LoggedUpdateMaintenance {
                                        'ORDER BY' => $primaryKey,
                                        'LIMIT' => $this->mBatchSize,
                                ],
-                               [ 'actor' => [ 'LEFT JOIN', 'ls_value = ' . $dbw->buildStringCast( 'actor_user' ) ] ]
+                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = ' . $dbw->buildIntegerCast( 'ls_value' ) ] ]
                        );
                        if ( !$res->numRows() ) {
                                break;
index 3395458..1dd1909 100644 (file)
@@ -129,6 +129,11 @@ class CommandLineInstaller extends Maintenance {
                        $installer->execute();
                        $installer->writeConfigurationFile( $this->getOption( 'confpath', $IP ) );
                }
+               $installer->showMessage(
+                       'config-install-success',
+                       $installer->getVar( 'wgServer' ),
+                       $installer->getVar( 'wgScriptPath' )
+               );
        }
 
        private function setDbPassOption() {
index 3b83ea6..c1354e3 100644 (file)
                };
        </script>
        <script>
-               // Mock startup.js
+               // Mock ResourceLoaderStartUpModule substitutions
                window.$VARS = {
-                       baseModules: []
+                       baseModules: [],
+                       maxQueryLength: 2000
                };
+               // Mock startup.js
                window.RLQ = [];
        </script>
        <script src="modules/src/startup/mediawiki.js"></script>
index 661ec98..aa5077d 100644 (file)
@@ -38,7 +38,7 @@ class JSParseHelper extends Maintenance {
        }
 
        public function execute() {
-               if ( $this->hasArg() ) {
+               if ( $this->hasArg( 0 ) ) {
                        $files = $this->mArgs;
                } else {
                        $this->maybeHelp( true ); // @todo fixme this is a lame API :)
index f43d75f..5843f67 100644 (file)
@@ -23,6 +23,8 @@
 
 require_once __DIR__ . '/../Maintenance.php';
 
+use Wikimedia\StaticArrayWriter;
+
 /**
  * Generate first letter data files for Collation.php
  *
index 336495a..e689f7c 100644 (file)
@@ -23,6 +23,8 @@
 
 require_once __DIR__ . '/../Maintenance.php';
 
+use Wikimedia\StaticArrayWriter;
+
 /**
  * Generates the normalizer data file for Arabic.
  *
index 1b8ea09..5f865ce 100644 (file)
@@ -23,6 +23,8 @@
 
 require_once __DIR__ . '/../Maintenance.php';
 
+use Wikimedia\StaticArrayWriter;
+
 /**
  * Generates the normalizer data file for Malayalam.
  *
diff --git a/maintenance/manageForeignResources.php b/maintenance/manageForeignResources.php
new file mode 100644 (file)
index 0000000..54554b8
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Manage foreign resources registered with ResourceLoader.
+ *
+ * @ingroup Maintenance
+ * @since 1.32
+ */
+class ManageForeignResources extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( <<<TEXT
+Manage foreign resources registered with ResourceLoader.
+
+This helps developers with downloading, verifying, and updating local copies of upstream
+libraries registered as ResourceLoader modules. See resources/lib/foreign-resources.yaml.
+
+Use the "update" action to download urls specified in foreign-resources.yaml, and unpack
+them to the resources directory. This will also verify them against the integrity hashes.
+
+Use the "verify" action to verify the files currently in the resources directory match
+what "update" would replace them with. This is effectively a dry-run and will not change
+any module resources on disk.
+
+Use the "make-sri" action to compute an integrity hash for upstreams that do not publish
+one themselves. Add or update the urls foreign-resources.yaml as needed, but omit (or
+leave empty) the "integrity" key. Then, run the "make-sri" action for the module and
+copy the integrity into the file. Then, you can use "verify" or "update" normally.
+TEXT
+               );
+               $this->addArg( 'action', 'One of "update", "verify" or "make-sri"', true );
+               $this->addArg( 'module', 'Name of a single module (Default: all)', false );
+               $this->addOption( 'verbose', 'Be verbose', false, false, 'v' );
+       }
+
+       /**
+        * @return bool
+        * @throws Exception
+        */
+       public function execute() {
+               global $IP;
+               $frm = new ForeignResourceManager(
+                        "{$IP}/resources/lib/foreign-resources.yaml",
+                        "{$IP}/resources/lib",
+                       function ( $text ) {
+                               $this->output( $text );
+                       },
+                       function ( $text ) {
+                               $this->error( $text );
+                       },
+                       function ( $text ) {
+                               if ( $this->hasOption( 'verbose' ) ) {
+                                       $this->output( $text );
+                               }
+                       }
+               );
+
+               $action = $this->getArg( 0 );
+               $module = $this->getArg( 1, 'all' );
+               return $frm->run( $action, $module );
+       }
+}
+
+$maintClass = ManageForeignResources::class;
+require_once RUN_MAINTENANCE_IF_MAIN;
index c976bd7..98f0eb9 100644 (file)
@@ -50,8 +50,8 @@ class McTest extends Maintenance {
                                $this->fatalError( "MediaWiki isn't configured with a cache named '$cache'" );
                        }
                        $servers = $wgObjectCaches[$cache]['servers'];
-               } elseif ( $this->hasArg() ) {
-                       $servers = [ $this->getArg() ];
+               } elseif ( $this->hasArg( 0 ) ) {
+                       $servers = [ $this->getArg( 0 ) ];
                } elseif ( $wgMainCacheType === CACHE_MEMCACHED ) {
                        global $wgMemCachedServers;
                        $servers = $wgMemCachedServers;
diff --git a/maintenance/mediawiki.Title/generateJsToUpperCaseList.js b/maintenance/mediawiki.Title/generateJsToUpperCaseList.js
new file mode 100644 (file)
index 0000000..fd742f6
--- /dev/null
@@ -0,0 +1,8 @@
+/* eslint-env node, es6 */
+var i, chars = [];
+
+for ( i = 0; i < 65536; i++ ) {
+       chars.push( String.fromCharCode( i ).toUpperCase() );
+}
+// eslint-disable-next-line no-console
+console.log( JSON.stringify( chars ) );
diff --git a/maintenance/mediawiki.Title/generatePhpCharToUpperMappings.php b/maintenance/mediawiki.Title/generatePhpCharToUpperMappings.php
new file mode 100755 (executable)
index 0000000..a04958c
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+<?php
+/**
+ * Utility to generate mapping file used in mw.Title (phpCharToUpper.json)
+ *
+ * Compares output of String.toUpperCase in JavaScript with
+ * mb_strtoupper in PHP, and outputs a list of lower:upper
+ * mappings where they differ. This is then used by Title.js
+ * to provide the same normalization in the client as on
+ * the server.
+ */
+
+$data = [];
+
+// phpcs:disable MediaWiki.Usage.ForbiddenFunctions.exec
+$jsUpperChars = json_decode( exec( 'node generateJsToUpperCaseList.js' ) );
+// phpcs:enable MediaWiki.Usage.ForbiddenFunctions.exec
+
+for ( $i = 0; $i < 65536; $i++ ) {
+       if ( $i >= 0xd800 && $i <= 0xdfff ) {
+               // Skip surrogate pairs
+               continue;
+       }
+       $char = mb_convert_encoding( '&#' . $i . ';', 'UTF-8', 'HTML-ENTITIES' );
+       $phpUpper = mb_strtoupper( $char );
+       $jsUpper = $jsUpperChars[$i];
+       if ( $jsUpper !== $phpUpper ) {
+               $data[$char] = $phpUpper;
+       }
+}
+
+echo str_replace( '    ', "\t",
+       json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE )
+) . "\n";
index 51c41db..80e72fb 100644 (file)
@@ -77,7 +77,6 @@ class MergeMessageFileList extends Maintenance {
                        $extdir = $this->getOption( 'extensions-dir' );
                        # Allow multiple directories to be passed with ":" as delimiter
                        $extdirs = explode( ':', $extdir );
-                       $entries = [];
                        foreach ( $extdirs as $extdir ) {
                                $entries = scandir( $extdir );
                                foreach ( $entries as $extname ) {
@@ -185,7 +184,7 @@ if ( $queue ) {
 
 fwrite( STDERR, "\n" );
 $s =
-       "<" . "?php\n" .
+       "<?php\n" .
        "## This file is generated by mergeMessageFileList.php. Do not edit it directly.\n\n" .
        "if ( defined( 'MW_NO_EXTENSION_MESSAGES' ) ) return;\n\n" .
        '$wgExtensionMessagesFiles = ' . var_export( $wgExtensionMessagesFiles, true ) . ";\n\n" .
index 9c20c67..47828e6 100644 (file)
@@ -65,8 +65,8 @@ class MoveBatch extends Maintenance {
                $reason = $this->getOption( 'r', '' );
                $interval = $this->getOption( 'i', 0 );
                $noredirects = $this->hasOption( 'noredirects' );
-               if ( $this->hasArg() ) {
-                       $file = fopen( $this->getArg(), 'r' );
+               if ( $this->hasArg( 0 ) ) {
+                       $file = fopen( $this->getArg( 0 ), 'r' );
                } else {
                        $file = $this->getStdin();
                }
index 2d6a0be..791b360 100644 (file)
@@ -33,6 +33,8 @@
  * @version first release
  */
 
+use MediaWiki\Shell\Shell;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -88,7 +90,7 @@ class MWDocGen extends Maintenance {
 
                // Do not use wfShellWikiCmd, because mwdoc-filter.php is not
                // a Maintenance script.
-               $this->inputFilter = wfEscapeShellArg( [
+               $this->inputFilter = Shell::escape( [
                        $wgPhpCli,
                        $IP . '/maintenance/mwdoc-filter.php'
                ] );
index 9424402..c1e403c 100644 (file)
@@ -72,8 +72,6 @@ class MysqlMaintenance extends Maintenance {
                        $host = $this->getOption( 'host' );
                        $serverCount = $lb->getServerCount();
                        for ( $index = 0; $index < $serverCount; ++$index ) {
-                               $serverInfo = $lb->getServerInfo( $index );
-
                                if ( $lb->getServerName( $index ) === $host ) {
                                        break;
                                }
@@ -139,9 +137,7 @@ class MysqlMaintenance extends Maintenance {
                } elseif ( substr_count( $realServer, ':' ) == 1 ) {
                        // If we have a colon and something that's not a port number
                        // inside the hostname, assume it's the socket location
-                       $hostAndSocket = explode( ':', $realServer, 2 );
-                       $realServer = $hostAndSocket[0];
-                       $socket = $hostAndSocket[1];
+                       list( $realServer, $socket ) = explode( ':', $realServer, 2 );
                }
 
                if ( $dbName === false ) {
index baead94..ba0fe5d 100644 (file)
@@ -39,7 +39,7 @@ class NukePage extends Maintenance {
        }
 
        public function execute() {
-               $name = $this->getArg();
+               $name = $this->getArg( 0 );
                $delete = $this->hasOption( 'delete' );
 
                $dbw = $this->getDB( DB_MASTER );
index d47ca43..e13468e 100644 (file)
@@ -53,8 +53,6 @@ class Orphans extends Maintenance {
        public function execute() {
                $this->checkOrphans( $this->hasOption( 'fix' ) );
                $this->checkSeparation( $this->hasOption( 'fix' ) );
-               # Does not work yet, do not use
-               # $this->checkWidows( $this->hasOption( 'fix' ) );
        }
 
        /**
@@ -67,7 +65,7 @@ class Orphans extends Maintenance {
                if ( $extraTable ) {
                        $tbls = array_merge( $tbls, $extraTable );
                }
-               $db->lockTables( [], $tbls, __METHOD__, false );
+               $db->lockTables( [], $tbls, __METHOD__ );
        }
 
        /**
@@ -139,54 +137,6 @@ class Orphans extends Maintenance {
                }
        }
 
-       /**
-        * @param bool $fix
-        * @todo DON'T USE THIS YET! It will remove entries which have children,
-        *       but which aren't properly attached (eg if page_latest is bogus
-        *       but valid revisions do exist)
-        */
-       private function checkWidows( $fix ) {
-               $dbw = $this->getDB( DB_MASTER );
-               $page = $dbw->tableName( 'page' );
-               $revision = $dbw->tableName( 'revision' );
-
-               if ( $fix ) {
-                       $this->lockTables( $dbw );
-               }
-
-               $this->output( "\nChecking for childless page table entries... "
-                       . "(this may take a while on a large wiki)\n" );
-               $result = $dbw->query( "
-                       SELECT *
-                       FROM $page LEFT OUTER JOIN $revision ON page_latest=rev_id
-                       WHERE rev_id IS NULL
-               " );
-               $widows = $result->numRows();
-               if ( $widows > 0 ) {
-                       $this->output( "$widows childless pages...\n" );
-                       $this->output( sprintf( "%10s %11s %2s %s\n", 'page_id', 'page_latest', 'ns', 'page_title' ) );
-                       foreach ( $result as $row ) {
-                               printf( "%10d %11d %2d %s\n",
-                                       $row->page_id,
-                                       $row->page_latest,
-                                       $row->page_namespace,
-                                       $row->page_title );
-                               if ( $fix ) {
-                                       $dbw->delete( 'page', [ 'page_id' => $row->page_id ] );
-                               }
-                       }
-                       if ( !$fix ) {
-                               $this->output( "Run again with --fix to remove these entries automatically.\n" );
-                       }
-               } else {
-                       $this->output( "No childless pages! Yay!\n" );
-               }
-
-               if ( $fix ) {
-                       $dbw->unlockTables( __METHOD__ );
-               }
-       }
-
        /**
         * Check for pages where page_latest is wrong
         * @param bool $fix Whether to fix broken entries
@@ -204,7 +154,7 @@ class Orphans extends Maintenance {
                        . "(this may take a while on a large wiki)\n" );
                $result = $dbw->query( "
                        SELECT *
-                       FROM $page LEFT OUTER JOIN $revision ON page_latest=rev_id
+                       FROM $page LEFT JOIN $revision ON page_latest=rev_id
                " );
                $found = 0;
                foreach ( $result as $row ) {
index dc9bbda..6a5654f 100644 (file)
@@ -32,11 +32,10 @@ class PageExists extends Maintenance {
        }
 
        public function execute() {
-               $titleArg = $this->getArg();
+               $titleArg = $this->getArg( 0 );
                $title = Title::newFromText( $titleArg );
                $pageExists = $title && $title->exists();
 
-               $text = '';
                $code = 0;
                if ( $pageExists ) {
                        $text = "{$title} exists.";
index e2fd8b5..ac52721 100644 (file)
@@ -44,8 +44,6 @@ class PopulateBacklinkNamespace extends LoggedUpdateMaintenance {
        }
 
        public function doDBUpdates() {
-               $force = $this->getOption( 'force' );
-
                $db = $this->getDB( DB_MASTER );
 
                $this->output( "Updating *_from_namespace fields in links tables.\n" );
index f07bc55..ce1506c 100644 (file)
@@ -93,9 +93,9 @@ TEXT
 
                $throttle = intval( $throttle );
                if ( $begin !== '' ) {
-                       $where = 'cl_to > ' . $dbw->addQuotes( $begin );
+                       $where = [ 'cl_to > ' . $dbw->addQuotes( $begin ) ];
                } else {
-                       $where = null;
+                       $where = [ '1 = 1' ];
                }
                $i = 0;
 
index 8d64dae..e6f47d1 100644 (file)
@@ -160,7 +160,7 @@ class PopulateContentModel extends Maintenance {
                } else { // revision
                        $selectTables = [ 'revision', 'page' ];
                        $fields = [ 'page_title', 'page_namespace' ];
-                       $join_conds = [ 'page' => [ 'INNER JOIN', 'rev_page=page_id' ] ];
+                       $join_conds = [ 'page' => [ 'JOIN', 'rev_page=page_id' ] ];
                        $where = $ns === 'all' ? [] : [ 'page_namespace' => $ns ];
                        $page_id_column = 'rev_page';
                        $rev_id_column = 'rev_id';
index 644ff87..a264545 100644 (file)
@@ -188,6 +188,11 @@ class PopulateContentTables extends Maintenance {
                        $startOption = 'start-archive';
                }
 
+               if ( !$this->dbw->fieldExists( $table, $fields['text_id'], __METHOD__ ) ) {
+                       $this->writeln( "No need to populate, $table.{$fields['text_id']} field does not exist" );
+                       return;
+               }
+
                $minmax = $this->dbw->selectRow(
                        $table,
                        [ 'min' => "MIN( $idField )", 'max' => "MAX( $idField )" ],
index 212a20d..a71abb6 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\Shell\Shell;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -107,9 +109,9 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
                        // in the pipe buffer. This can improve performance by up to a
                        // factor of 2.
                        global $wgDBuser, $wgDBserver, $wgDBpassword, $wgDBname;
-                       $cmd = 'mysql -u' . wfEscapeShellArg( $wgDBuser ) .
-                               ' -h' . wfEscapeShellArg( $wgDBserver ) .
-                               ' -p' . wfEscapeShellArg( $wgDBpassword, $wgDBname );
+                       $cmd = 'mysql -u' . Shell::escape( $wgDBuser ) .
+                               ' -h' . Shell::escape( $wgDBserver ) .
+                               ' -p' . Shell::escape( $wgDBpassword, $wgDBname );
                        $this->output( "Using pipe method\n" );
                        $pipe = popen( $cmd, 'w' );
                }
index 1ba7054..591fbd4 100644 (file)
@@ -93,6 +93,7 @@ class PopulatePPSortKey extends LoggedUpdateMaintenance {
                }
 
                $this->output( "Populating page_props.pp_sortkey complete.\n" );
+               return true;
        }
 
        protected function getUpdateKey() {
index f8526d0..75904d0 100644 (file)
@@ -25,6 +25,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\MediaWikiServices;
+
 require_once __DIR__ . '/dumpIterator.php';
 
 /**
@@ -40,9 +42,9 @@ class PreprocessDump extends DumpIterator {
        public $mPPNodeCount = 0;
 
        public function getStripList() {
-               global $wgParser;
+               $parser = MediaWikiServices::getInstance()->getParser();
 
-               return $wgParser->getStripList();
+               return $parser->getStripList();
        }
 
        public function __construct() {
index d5d27ad..8df01e6 100644 (file)
@@ -239,7 +239,7 @@ class PPFuzzTest {
 class PPFuzzUser extends User {
        public $ppfz_test, $mDataLoaded;
 
-       function load() {
+       function load( $flags = null ) {
                if ( $this->mDataLoaded ) {
                        return;
                }
index b47476a..1603ab0 100644 (file)
@@ -62,10 +62,7 @@ class Protect extends Maintenance {
                        $this->fatalError( "Invalid username" );
                }
 
-               // @todo FIXME: This is reset 7 lines down.
-               $restrictions = [ 'edit' => $protection, 'move' => $protection ];
-
-               $t = Title::newFromText( $this->getArg() );
+               $t = Title::newFromText( $this->getArg( 0 ) );
                if ( !$t ) {
                        $this->fatalError( "Invalid title" );
                }
index 7d5d40b..29a36d5 100644 (file)
@@ -77,7 +77,7 @@ class PurgeChangedFiles extends Maintenance {
                global $wgHTCPRouting;
 
                if ( $this->hasOption( 'htcp-dest' ) ) {
-                       $parts = explode( ':', $this->getOption( 'htcp-dest' ) );
+                       $parts = explode( ':', $this->getOption( 'htcp-dest' ), 2 );
                        if ( count( $parts ) < 2 ) {
                                // Add default htcp port
                                $parts[] = '4827';
index 22020e7..81fb5e3 100644 (file)
@@ -52,7 +52,7 @@ class PurgeChangedPages extends Maintenance {
                global $wgHTCPRouting;
 
                if ( $this->hasOption( 'htcp-dest' ) ) {
-                       $parts = explode( ':', $this->getOption( 'htcp-dest' ) );
+                       $parts = explode( ':', $this->getOption( 'htcp-dest' ), 2 );
                        if ( count( $parts ) < 2 ) {
                                // Add default htcp port
                                $parts[] = '4827';
@@ -99,7 +99,7 @@ class PurgeChangedPages extends Maintenance {
                                __METHOD__,
                                [ 'ORDER BY' => 'rev_timestamp', 'LIMIT' => $bSize ],
                                [
-                                       'page' => [ 'INNER JOIN', 'rev_page=page_id' ],
+                                       'page' => [ 'JOIN', 'rev_page=page_id' ],
                                ]
                        );
 
@@ -170,23 +170,31 @@ class PurgeChangedPages extends Maintenance {
         */
        protected function pageableSortedRows( ResultWrapper $res, $column, $limit ) {
                $rows = iterator_to_array( $res, false );
-               $count = count( $rows );
-               if ( !$count ) {
-                       return [ [], null ]; // nothing to do
-               } elseif ( $count < $limit ) {
-                       return [ $rows, $rows[$count - 1]->$column ]; // no more rows left
+
+               // Nothing to do
+               if ( !$rows ) {
+                       return [ [], null ];
+               }
+
+               $lastValue = end( $rows )->$column;
+               if ( count( $rows ) < $limit ) {
+                       return [ $rows, $lastValue ];
                }
-               $lastValue = $rows[$count - 1]->$column; // should be the highest
-               for ( $i = $count - 1; $i >= 0; --$i ) {
-                       if ( $rows[$i]->$column === $lastValue ) {
-                               unset( $rows[$i] );
-                       } else {
+
+               for ( $i = count( $rows ) - 1; $i >= 0; --$i ) {
+                       if ( $rows[$i]->$column !== $lastValue ) {
                                break;
                        }
+
+                       unset( $rows[$i] );
+               }
+
+               // No more rows left
+               if ( !$rows ) {
+                       return [ [], null ];
                }
-               $lastValueLeft = count( $rows ) ? $rows[count( $rows ) - 1]->$column : null;
 
-               return [ $rows, $lastValueLeft ];
+               return [ $rows, end( $rows )->$column ];
        }
 }
 
diff --git a/maintenance/rebuildSitesCache.php b/maintenance/rebuildSitesCache.php
deleted file mode 100644 (file)
index 41fd863..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once __DIR__ . '/Maintenance.php';
-
-/**
- * Maintenance script to dump a SiteStore as a static json file.
- *
- * @ingroup Maintenance
- */
-class RebuildSitesCache extends Maintenance {
-
-       public function __construct() {
-               parent::__construct();
-
-               $this->addDescription( 'Cache sites as json for file-based lookup.' );
-               $this->addOption( 'file', 'File to output the json to', false, true );
-       }
-
-       public function execute() {
-               $sitesCacheFileBuilder = new SitesCacheFileBuilder(
-                       \MediaWiki\MediaWikiServices::getInstance()->getSiteLookup(),
-                       $this->getCacheFile()
-               );
-
-               $sitesCacheFileBuilder->build();
-       }
-
-       /**
-        * @return string
-        */
-       private function getCacheFile() {
-               if ( $this->hasOption( 'file' ) ) {
-                       $jsonFile = $this->getOption( 'file' );
-               } else {
-                       $jsonFile = $this->getConfig()->get( 'SitesCacheFile' );
-
-                       if ( $jsonFile === false ) {
-                               $this->fatalError( 'Error: No file set in configuration for SitesCacheFile.' );
-                       }
-               }
-
-               return $jsonFile;
-       }
-
-}
-
-$maintClass = RebuildSitesCache::class;
-require_once RUN_MAINTENANCE_IF_MAIN;
index 45bb6de..4e92653 100644 (file)
@@ -372,7 +372,7 @@ class RebuildRecentchanges extends Maintenance {
                                [ 'ug_group' => $botgroups ],
                                __METHOD__,
                                [ 'DISTINCT' ],
-                               [ 'user_group' => [ 'JOIN', 'user_id = ug_user' ] ] + $userQuery['joins']
+                               [ 'user_groups' => [ 'JOIN', 'user_id = ug_user' ] ] + $userQuery['joins']
                        );
 
                        $botusers = [];
@@ -425,7 +425,7 @@ class RebuildRecentchanges extends Maintenance {
                                [ 'ug_group' => $autopatrolgroups ],
                                __METHOD__,
                                [ 'DISTINCT' ],
-                               [ 'user_group' => [ 'JOIN', 'user_id = ug_user' ] ] + $userQuery['joins']
+                               [ 'user_groups' => [ 'JOIN', 'user_id = ug_user' ] ] + $userQuery['joins']
                        );
 
                        foreach ( $res as $obj ) {
index 900a52a..2e4cc88 100644 (file)
@@ -93,7 +93,7 @@ class RebuildTextIndex extends Maintenance {
                $this->output( "Rebuilding index fields for {$count} pages...\n" );
                $n = 0;
 
-               $revQuery = Revision::getQueryInfo( [ 'page', 'text' ] );
+               $revQuery = Revision::getQueryInfo( [ 'page' ] );
 
                while ( $n < $count ) {
                        if ( $n ) {
@@ -104,7 +104,7 @@ class RebuildTextIndex extends Maintenance {
                        $res = $this->db->select(
                                $revQuery['tables'],
                                $revQuery['fields'],
-                               [ "page_id BETWEEN $n AND $end", 'page_latest = rev_id', 'rev_text_id = old_id' ],
+                               [ "page_id BETWEEN $n AND $end", 'page_latest = rev_id' ],
                                __METHOD__,
                                [],
                                $revQuery['joins']
index 73bc4d9..e5aa23e 100644 (file)
@@ -82,7 +82,9 @@ class RenameDbPrefix extends Maintenance {
                                // $old should be regexp safe ([a-zA-Z_])
                                $newTable = preg_replace( '/^' . $old . '/', $new, $table );
                                $this->output( "Renaming table $table to $newTable\n" );
-                               $dbw->query( "RENAME TABLE $table TO $newTable" );
+                               $oldTableEnc = $dbw->addIdentifierQuotes( $table );
+                               $newTableEnc = $dbw->addIdentifierQuotes( $newTable );
+                               $dbw->query( "RENAME TABLE $oldTableEnc TO $newTableEnc" );
                        }
                        $count++;
                }
index 771d19b..3ba5c6b 100644 (file)
@@ -32,10 +32,10 @@ require_once __DIR__ . '/Maintenance.php';
 class ResetUserEmail extends Maintenance {
        public function __construct() {
                $this->addDescription( "Resets a user's email" );
-               $this->addArg( 'user', 'Username or user ID, if starts with #', true );
+               $this->addArg( 'user', 'Username or user ID, if starts with #' );
                $this->addArg( 'email', 'Email to assign' );
 
-               $this->addOption( 'no-reset-password', 'Don\'t reset the user\'s password', false, false );
+               $this->addOption( 'no-reset-password', 'Don\'t reset the user\'s password' );
 
                parent::__construct();
        }
diff --git a/maintenance/resources/foreign-resources.yaml b/maintenance/resources/foreign-resources.yaml
deleted file mode 100644 (file)
index af0744a..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-### Format of this file
-#
-# The top-level keys are directory names (under resources/lib/).
-# They should match module names (as registered in Resources.php), but there are exceptions.
-# Each top-level key holds a resource descriptor that must have one of
-# the following `type` values:
-#
-# - `tar`: For tarball archive (may be gzip-compressed).
-# - `file: For a plain file.
-# - `multi-file`: For multiple plain files.
-#
-### Type tar
-#
-# The `src` and `integrity` keys are required.
-#
-# * `src`: Full URL to the remote resource.
-# * `integrity`: Cryptographic hash (integrity metadata format per <https://www.w3.org/TR/SRI/>).
-# * `dest`: An object mapping paths to files or directory from the remote resource to a destination
-#    in the module directory. The value of key in dest may be omitted, which will extract the key
-#    directly to the module directory.
-#
-### Type file
-#
-# The `src` and `integrity` keys are required.
-#
-# * `src`: Full URL to the remote resource.
-# * `integrity`: Cryptographic hash (integrity metadata format per <https://www.w3.org/TR/SRI/>).
-# * `dest`: The name of the file in the module directory. Default: Basename of URL.
-#
-### Type multi-file
-#
-# The `files` key is required.
-#
-# * `files`: An object mapping destination paths to an object containing `src` and `integrity`
-#    keys.
-
-CLDRPluralRuleParser:
-  type: file
-  src: https://raw.githubusercontent.com/santhoshtr/CLDRPluralRuleParser/0dda851/src/CLDRPluralRuleParser.js
-  integrity: sha384-M4taeYYG2+9Ob1/La16iO+zlRRmBV5lBR3xUKkQT6kfkJ0aLbCi6yc0RYI1BDzdh
-
-easy-deflate:
-  type: multi-file
-  files:
-    deflate.js:
-      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/deflate.js
-      integrity: sha384-sHnZLDSWMUhA2w9ygkzCK8YFvoh/fQKY6lXMbvmrYzjuNURiLB0DZFCDNMpGyZ77
-    easydeflate.js:
-      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/easydeflate.js
-      integrity: sha384-EwPfP2RMkDPa1HkzQsXgzTsy1KEjcIzQPA1HDS/JPHjvEMvVUsCxWwm1oXql/jk2
-    inflate.js:
-      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/inflate.js
-      integrity: sha384-hMg44Hw424mUYvmzKl0JT4J8UU/1YYhTiGRtR0YX/MXNLK9qWTK0d62FBCDGxmxw
-    README.md:
-      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/README.md
-      integrity: sha384-6kwcfCLivvqXBZy2ATyya+mTVWLk3eaQyBdC6tbpBtkygnBrM2SNkq3jz/l7IkvP
-
-html5shiv:
-  type: file
-  src: https://raw.githubusercontent.com/aFarkas/html5shiv/3.7.3/src/html5shiv.js
-  integrity: sha384-RPXhaTf22QktT8KTwZ6bUz/C+7CnccaIw5W/y/t0FW5WSDGj3wc3YtRIJC0w47in
-
-jquery:
-  type: file
-  src: https://code.jquery.com/jquery-3.3.1.js
-  # Integrity from link modals https://code.jquery.com/jquery/
-  integrity: sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=
-  dest: jquery.js
-
-jquery.client:
-  type: tar
-  src: https://registry.npmjs.org/jquery-client/-/jquery-client-2.0.2.tgz
-  integrity: sha256-8c8nBbBykHEMc4I7ksdKJvvw/P7WkaC2X46RTPdz/pw=
-  dest:
-    package/AUTHORS.txt:
-    package/jquery.client.js:
-    package/LICENSE-MIT:
-    package/README.md:
-
-jquery.cookie:
-  type: multi-file
-  files:
-    jquery.cookie.js:
-      src: https://raw.githubusercontent.com/carhartl/jquery-cookie/v1.3.1/jquery.cookie.js
-      integrity: sha384-Xxq63E9KDgzUJ6WPNPqVeOtRIwZyx6y9DzEwY2u6LYKSnWrjSoGtWSKmTindYBf2
-    MIT-LICENSE.txt:
-      src: https://raw.githubusercontent.com/carhartl/jquery-cookie/v1.3.1/MIT-LICENSE.txt
-      integrity: sha384-zYsGf3KJ7S0AhOICjcoh0kkn7aGZlzYUXXX5xz8dwR9KjLMM+/JPR2g/jVOGGeId
-    CHANGELOG.md:
-      src: https://raw.githubusercontent.com/carhartl/jquery-cookie/v1.3.1/CHANGELOG.md
-      integrity: sha384-SQOHhLc7PHxHDQpGE/zv9XfXKL0A7OBu8kuyVDnHVp+zSoWyRw4xUJ+LSm5ql4kS
-
-moment:
-  type: tar
-  src: https://codeload.github.com/moment/moment/tar.gz/2.24.0
-  integrity: sha384-2/I9rfqkN8AAgh5wOXXphuo827uV7lMmOodrCfIvqC6W6JKKiDGOwd+lE3e8R0yz
-  dest:
-    moment-2.24.0/moment.js:
-    moment-2.24.0/CHANGELOG.md:
-    moment-2.24.0/README.md:
-    moment-2.24.0/LICENSE:
-    moment-2.24.0/locale/*.js: locale
-
-mustache:
-  type: multi-file
-  files:
-    mustache.js:
-      src: https://raw.githubusercontent.com/janl/mustache.js/v1.0.0/mustache.js
-      integrity: sha384-k2UYqmzoiq/qgIzZvcYBxbXQW4YdPAsXDOTkHTGb9TCZ9sjCkyT4TlaUN0wQRkql
-    LICENSE:
-      src: https://raw.githubusercontent.com/janl/mustache.js/v1.0.0/LICENSE
-      integrity: sha384-MYVwXwula9+YkyXexOJVZ0v0DaVvG22uX57mNq5Di+7u8OH9EG9q3yuXkp1Iehiq
-
-oojs:
-  type: tar
-  src: https://registry.npmjs.org/oojs/-/oojs-2.2.2.tgz
-  integrity: sha256-ebgQW2EGrSkBCnDJBGqDpsBDjA3PMN/M8U5DyLHt9mw=
-  dest:
-    package/dist/oojs.jquery.js:
-    package/AUTHORS.txt:
-    package/LICENSE-MIT:
-    package/README.md:
-
-oojs-router:
-  type: tar
-  src: https://registry.npmjs.org/oojs-router/-/oojs-router-0.2.0.tgz
-  integrity: sha384-VngYqdQ3vTDMXbm4e4FUZCCGos7fB0Jkr9V+kBL5MElprK1h0yQZOzBNnMHtSJS/
-  dest:
-    package/dist/oojs-router.js:
-    package/LICENSE:
-    package/AUTHORS.txt:
-    package/History.md:
-
-ooui:
-  type: tar
-  src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.30.3.tgz
-  integrity: sha384-lKv5WHjcSDfly2Vd2u9JJErkfo+1yFi/+pfFL0bmOu3hKpcZQmaLvu6gmhkzH5WN
-  dest:
-    # Main stuff
-    package/dist/oojs-ui-core.js{,.map.json}:
-    package/dist/oojs-ui-core-{wikimediaui,apex}.css:
-    package/dist/oojs-ui-widgets.js{,.map.json}:
-    package/dist/oojs-ui-widgets-{wikimediaui,apex}.css:
-    package/dist/oojs-ui-toolbars.js{,.map.json}:
-    package/dist/oojs-ui-toolbars-{wikimediaui,apex}.css:
-    package/dist/oojs-ui-windows.js{,.map.json}:
-    package/dist/oojs-ui-windows-{wikimediaui,apex}.css:
-    package/dist/oojs-ui-{wikimediaui,apex}.js{,.map.json}:
-    package/dist/i18n:
-    package/dist/images:
-    # WikimediaUI theme
-    package/dist/themes/wikimediaui/images/icons/*.{svg,png}: themes/wikimediaui/images/icons
-    package/dist/themes/wikimediaui/images/indicators/*.{svg,png}: themes/wikimediaui/images/indicators
-    package/dist/themes/wikimediaui/images/textures/*.{gif,svg}: themes/wikimediaui/images/textures
-    package/src/themes/wikimediaui/*.json: themes/wikimediaui
-    package/dist/wikimedia-ui-base.less:
-    # Apex theme (icons, indicators, and textures)
-    package/src/themes/apex/*.json: themes/apex
-    # Misc stuff
-    package/dist/AUTHORS.txt:
-    package/dist/History.md:
-    package/dist/LICENSE-MIT:
-    package/dist/README.md:
-
-qunitjs:
-  type: multi-file
-  # Integrity from link modals at https://code.jquery.com/qunit/
-  files:
-    qunit.js:
-      src: http://code.jquery.com/qunit/qunit-2.9.1.js
-      integrity: sha256-eNccBdxd8zReziWcVjEsPeyJDi3LKMYnzMXyDv8bzsU=
-    qunit.css:
-      src: https://code.jquery.com/qunit/qunit-2.9.1.css
-      integrity: sha256-SSS7o92V7wzcIFg3qnJL9mc4msePaT4klbxtuSGvVVo=
-
-sinonjs:
-  type: file
-  src: https://sinonjs.org/releases/sinon-1.17.7.js
-  integrity: sha384-wR63Jwy75KqwBfzCmXd6gYws6uj3qV/XMAybzXrkEYGYG3AQ58ZWwr1fVpkHa5e8
-  dest: sinon.js
diff --git a/maintenance/resources/manageForeignResources.php b/maintenance/resources/manageForeignResources.php
deleted file mode 100644 (file)
index 6de82c0..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once __DIR__ . '/../Maintenance.php';
-
-/**
- * Manage foreign resources registered with ResourceLoader.
- *
- * @ingroup Maintenance
- * @since 1.32
- */
-class ManageForeignResources extends Maintenance {
-       public function __construct() {
-               parent::__construct();
-               $this->addDescription( <<<TEXT
-Manage foreign resources registered with ResourceLoader.
-
-This helps developers to download, verify and update local copies of upstream
-libraries registered as ResourceLoader modules. See also foreign-resources.yaml.
-
-For sources that don't publish an integrity hash, omit "integrity" (or leave empty)
-and run the "make-sri" action to compute the missing hashes.
-
-This script runs in dry-run mode by default. Use --update to actually change,
-remove, or add files to resources/lib/.
-TEXT
-               );
-               $this->addArg( 'action', 'One of "update", "verify" or "make-sri"', true );
-               $this->addArg( 'module', 'Name of a single module (Default: all)', false );
-               $this->addOption( 'verbose', 'Be verbose', false, false, 'v' );
-       }
-
-       /**
-        * @return bool
-        * @throws Exception
-        */
-       public function execute() {
-               global $IP;
-               $frm = new ForeignResourceManager(
-                        __DIR__ . '/foreign-resources.yaml',
-                        "{$IP}/resources/lib",
-                       function ( $text ) {
-                               $this->output( $text );
-                       },
-                       function ( $text ) {
-                               $this->error( $text );
-                       },
-                       function ( $text ) {
-                               if ( $this->hasOption( 'verbose' ) ) {
-                                       $this->output( $text );
-                               }
-                       }
-               );
-
-               $action = $this->getArg( 0 );
-               $module = $this->getArg( 1, 'all' );
-               return $frm->run( $action, $module );
-       }
-}
-
-$maintClass = ManageForeignResources::class;
-require_once RUN_MAINTENANCE_IF_MAIN;
index 51c52be..802a114 100644 (file)
@@ -99,6 +99,10 @@ class RunJobs extends Maintenance {
                                $response['reached'] === 'job-limit' ||
                                $response['reached'] === 'memory-limit'
                        ) {
+                               // If job queue is empty, output it
+                               if ( !$outputJSON && $response['jobs'] === [] ) {
+                                       $this->output( "Job queue is empty.\n" );
+                               }
                                break;
                        }
 
index a95789d..eed8019 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Shell\Shell;
 
 if ( !defined( 'MEDIAWIKI' ) ) {
        $optionsWithoutArgs = [ 'fix' ];
@@ -86,7 +87,6 @@ class CheckStorage {
                        foreach ( $res as $row ) {
                                $this->oldIdMap[$row->rev_id] = $row->rev_text_id;
                        }
-                       $dbr->freeResult( $res );
 
                        if ( !count( $this->oldIdMap ) ) {
                                continue;
@@ -104,7 +104,7 @@ class CheckStorage {
                        );
                        foreach ( $res as $row ) {
                                /**
-                                * @var $flags int
+                                * @var int $flags
                                 */
                                $flags = $row->old_flags;
                                $id = $row->old_id;
@@ -147,7 +147,6 @@ class CheckStorage {
                                        $this->addError( 'unfixable', "Error: invalid flags field \"$flags\"", $id );
                                }
                        }
-                       $dbr->freeResult( $res );
 
                        // Output errors for any missing text rows
                        foreach ( $missingTextRows as $oldId => $revId ) {
@@ -187,7 +186,6 @@ class CheckStorage {
                                                $externalNormalBlobs[$cluster][$id][] = $row->old_id;
                                        }
                                }
-                               $dbr->freeResult( $res );
                        }
 
                        // Check external concat blobs for the right header
@@ -210,7 +208,6 @@ class CheckStorage {
                                        foreach ( $res as $row ) {
                                                unset( $xBlobIds[$row->blob_id] );
                                        }
-                                       $extDb->freeResult( $res );
                                        // Print errors for missing blobs rows
                                        foreach ( $xBlobIds as $blobId => $oldId ) {
                                                $this->addError(
@@ -279,7 +276,6 @@ class CheckStorage {
                                                        $this->addError( 'unfixable', "Error: unrecognised object class \"$className\"", $oldId );
                                        }
                                }
-                               $dbr->freeResult( $res );
                        }
 
                        // Check local concat blob validity
@@ -333,7 +329,6 @@ class CheckStorage {
 
                                        unset( $concatBlobs[$row->old_id] );
                                }
-                               $dbr->freeResult( $res );
                        }
 
                        // Check targets of unresolved stubs
@@ -421,7 +416,6 @@ class CheckStorage {
                                }
                                unset( $oldIds[$row->blob_id] );
                        }
-                       $extDb->freeResult( $res );
 
                        // Print errors for missing blobs rows
                        foreach ( $oldIds as $blobId => $oldIds2 ) {
@@ -458,7 +452,7 @@ class CheckStorage {
                echo "Filtering XML dump...\n";
                $exitStatus = 0;
                passthru( 'mwdumper ' .
-                       wfEscapeShellArg(
+                       Shell::escape(
                                "--output=file:$filteredXmlFileName",
                                "--filter=revlist:$revFileName",
                                $xml
index 8a1069e..ac4e120 100644 (file)
@@ -104,7 +104,7 @@ class CompressOld extends Maintenance {
                global $wgDBname;
                if ( !function_exists( "gzdeflate" ) ) {
                        $this->fatalError( "You must enable zlib support in PHP to compress old revisions!\n" .
-                               "Please see https://secure.php.net/manual/en/ref.zlib.php\n" );
+                               "Please see https://www.php.net/manual/en/ref.zlib.php\n" );
                }
 
                $type = $this->getOption( 'type', 'concat' );
index b00db20..7d9883e 100644 (file)
@@ -39,7 +39,7 @@ class DumpRev extends Maintenance {
        }
 
        public function execute() {
-               $id = (int)$this->getArg();
+               $id = (int)$this->getArg( 0 );
 
                $lookup = MediaWikiServices::getInstance()->getRevisionLookup();
                $rev = $lookup->getRevisionById( $id );
index 7f36442..f17b00c 100644 (file)
@@ -24,6 +24,7 @@
 
 use MediaWiki\Logger\LegacyLogger;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Shell\Shell;
 use Wikimedia\Rdbms\IDatabase;
 
 $optionsWithArgs = RecompressTracked::getOptionsWithArgs();
@@ -215,19 +216,19 @@ class RecompressTracked {
         * writing are all slow.
         */
        function startReplicaProcs() {
-               $cmd = 'php ' . wfEscapeShellArg( __FILE__ );
+               $cmd = 'php ' . Shell::escape( __FILE__ );
                foreach ( self::$cmdLineOptionMap as $cmdOption => $classOption ) {
                        if ( $cmdOption == 'replica-id' ) {
                                continue;
                        } elseif ( in_array( $cmdOption, self::$optionsWithArgs ) && isset( $this->$classOption ) ) {
-                               $cmd .= " --$cmdOption " . wfEscapeShellArg( $this->$classOption );
+                               $cmd .= " --$cmdOption " . Shell::escape( $this->$classOption );
                        } elseif ( $this->$classOption ) {
                                $cmd .= " --$cmdOption";
                        }
                }
                $cmd .= ' --child' .
-                       ' --wiki ' . wfEscapeShellArg( wfWikiID() ) .
-                       ' ' . wfEscapeShellArg( ...$this->destClusters );
+                       ' --wiki ' . Shell::escape( wfWikiID() ) .
+                       ' ' . Shell::escape( ...$this->destClusters );
 
                $this->replicaPipes = $this->replicaProcs = [];
                for ( $i = 0; $i < $this->numProcs; $i++ ) {
@@ -271,10 +272,11 @@ class RecompressTracked {
         * Dispatch a command to the next available replica DB.
         * This may block until a replica DB finishes its work and becomes available.
         */
-       function dispatch( /*...*/ ) {
-               $args = func_get_args();
+       function dispatch( ...$args ) {
                $pipes = $this->replicaPipes;
-               $numPipes = stream_select( $x = [], $pipes, $y = [], 3600 );
+               $x = [];
+               $y = [];
+               $numPipes = stream_select( $x, $pipes, $y, 3600 );
                if ( !$numPipes ) {
                        $this->critical( "Error waiting to write to replica DBs. Aborting" );
                        exit( 1 );
index 49627c3..76a5721 100644 (file)
@@ -254,7 +254,7 @@ class SyncFileBackend extends Maintenance {
                                        'src' => $fsFile->getPath(), 'dst' => $dPath, 'overwrite' => 1 ];
                        } elseif ( $sExists === false ) { // does not exist in source
                                $ops[] = [ 'op' => 'delete', 'src' => $dPath, 'ignoreMissingSource' => 1 ];
-                       } else { // error
+                       } else {
                                $this->error( "Unable to sync '$dPath': could not stat file." );
                                $status->fatal( 'backend-fail-internal', $src->getName() );
 
index dac222f..0739666 100644 (file)
@@ -1683,7 +1683,7 @@ CREATE TABLE /*_*/job (
 
   -- Any other parameters to the command
   -- Stored as a PHP serialized array, or an empty string if there are no parameters
-  job_params blob NOT NULL,
+  job_params mediumblob NOT NULL,
 
   -- Random, non-unique, number used for job acquisition (for lock concurrency)
   job_random integer unsigned NOT NULL default 0,
index e9b2abd..144518e 100644 (file)
@@ -37,7 +37,7 @@ class Undelete extends Maintenance {
 
                $user = $this->getOption( 'user', false );
                $reason = $this->getOption( 'reason', '' );
-               $pageName = $this->getArg();
+               $pageName = $this->getArg( 0 );
 
                $title = Title::newFromText( $pageName );
                if ( !$title ) {
index 2a1feb4..50fb6dc 100755 (executable)
@@ -242,6 +242,24 @@ class UpdateMediaWiki extends Maintenance {
                        'manualRecache' => false,
                ];
        }
+
+       public function validateParamsAndArgs() {
+               // Allow extensions to add additional params.
+               $params = [];
+               Hooks::run( 'MaintenanceUpdateAddParams', [ &$params ] );
+               foreach ( $params as $name => $param ) {
+                       $this->addOption(
+                               $name,
+                               $param['desc'],
+                               $param['require'] ?? false,
+                               $param['withArg'] ?? false,
+                               $param['shortName'] ?? false,
+                               $param['multiOccurrence'] ?? false
+                       );
+               }
+
+               parent::validateParamsAndArgs();
+       }
 }
 
 $maintClass = UpdateMediaWiki::class;
index 12b33b4..ebace75 100644 (file)
@@ -26,6 +26,7 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
@@ -142,7 +143,6 @@ TEXT
                        wfWaitForSlaves();
                }
                $count = 0;
-               $batchCount = 0;
                $batchConds = [];
                do {
                        $this->output( "Selecting next " . self::BATCH_SIZE . " rows..." );
@@ -187,7 +187,8 @@ TEXT
                                }
                                # cl_type will be wrong for lots of pages if cl_collation is 0,
                                # so let's update it while we're here.
-                               $type = MWNamespace::getCategoryLinkType( $title->getNamespace() );
+                               $type = MediaWikiServices::getInstance()->getNamespaceInfo()->
+                                       getCategoryLinkType( $title->getNamespace() );
                                $newSortKey = $collation->getSortKey(
                                        $title->getCategorySortkey( $prefix ) );
                                if ( $verboseStats ) {
index 668ba79..dec0bb6 100644 (file)
@@ -71,7 +71,7 @@ class UpdateRestrictions extends Maintenance {
                        foreach ( $res as $row ) {
                                $oldRestrictions = [];
                                foreach ( explode( ':', trim( $row->page_restrictions ) ) as $restrict ) {
-                                       $temp = explode( '=', trim( $restrict ) );
+                                       $temp = explode( '=', trim( $restrict ), 2 );
                                        // Make sure we are not settings restrictions to ""
                                        if ( count( $temp ) == 1 && $temp[0] ) {
                                                // old old format should be treated as edit/move restriction
index 3b28b65..5d756e8 100644 (file)
@@ -49,7 +49,7 @@ class UpdateSpecialPages extends Maintenance {
                $this->doSpecialPageCacheUpdates( $dbw );
 
                foreach ( QueryPage::getPages() as $page ) {
-                       list( $class, $special ) = $page;
+                       list( , $special ) = $page;
                        $limit = $page[2] ?? null;
 
                        # --list : just show the name of pages
index 4b07796..0d6cfa2 100644 (file)
@@ -5,19 +5,25 @@ require_once __DIR__ . '/Maintenance.php';
 class ValidateRegistrationFile extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->addArg( 'path', 'Path to extension.json/skin.json file.', true );
+               $this->addArg(
+                       'path',
+                       'Path or glob pattern to extension.json/skin.json file.',
+                       true
+               );
        }
        public function execute() {
                $validator = new ExtensionJsonValidator( function ( $msg ) {
                        $this->fatalError( $msg );
                } );
                $validator->checkDependencies();
-               $path = $this->getArg( 0 );
-               try {
-                       $validator->validate( $path );
-                       $this->output( "$path validates against the schema!\n" );
-               } catch ( ExtensionJsonValidationError $e ) {
-                       $this->fatalError( $e->getMessage() );
+               $paths = glob( $this->getArg( 0 ) );
+               foreach ( $paths as $path ) {
+                       try {
+                               $validator->validate( $path );
+                               $this->output( "$path validates against the schema!\n" );
+                       } catch ( ExtensionJsonValidationError $e ) {
+                               $this->fatalError( $e->getMessage() );
+                       }
                }
        }
 }
index 24b5007..671369a 100644 (file)
@@ -36,7 +36,7 @@ class ViewCLI extends Maintenance {
        }
 
        public function execute() {
-               $title = Title::newFromText( $this->getArg() );
+               $title = Title::newFromText( $this->getArg( 0 ) );
                if ( !$title ) {
                        $this->fatalError( "Invalid title" );
                }
index ef9e46e..00046d3 100644 (file)
@@ -114,7 +114,7 @@ class WrapOldPasswords extends Maintenance {
 
                        // Clear memcached so old passwords are wiped out
                        foreach ( $updateUsers as $user ) {
-                               $user->clearSharedCache();
+                               $user->clearSharedCache( 'refresh' );
                        }
                } while ( $res->numRows() );
        }
index 804d0a1..b625c96 100644 (file)
@@ -38,12 +38,13 @@ require dirname( __DIR__ ) . '/includes/WebStart.php';
 wfInstallerMain();
 
 function wfInstallerMain() {
-       global $wgRequest, $wgLang, $wgMetaNamespace, $wgCanonicalNamespaceNames;
+       global $wgLang, $wgMetaNamespace, $wgCanonicalNamespaceNames;
+       $request = RequestContext::getMain()->getRequest();
 
-       $installer = InstallerOverrides::getWebInstaller( $wgRequest );
+       $installer = InstallerOverrides::getWebInstaller( $request );
 
        if ( !$installer->startSession() ) {
-               if ( $installer->request->getVal( "css" ) ) {
+               if ( $installer->request->getVal( 'css' ) ) {
                        // Do not display errors on css pages
                        $installer->outputCss();
                        exit;
@@ -62,8 +63,8 @@ function wfInstallerMain() {
                $session = array();
        }
 
-       if ( !is_null( $wgRequest->getVal( 'uselang' ) ) ) {
-               $langCode = $wgRequest->getVal( 'uselang' );
+       if ( $request->getCheck( 'uselang' ) ) {
+               $langCode = $request->getVal( 'uselang' );
        } elseif ( isset( $session['settings']['_UserLang'] ) ) {
                $langCode = $session['settings']['_UserLang'];
        } else {
index d000972..dccdd38 100644 (file)
@@ -412,6 +412,7 @@ $filter = $_REQUEST['filter'] ?? '';
        $queries = [];
        $sqltotal = 0.0;
 
+       /** @var profile_point|false $last */
        $last = false;
        foreach ( $res as $o ) {
                $next = new profile_point( $o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory );
@@ -435,7 +436,7 @@ $filter = $_REQUEST['filter'] ?? '';
                }
        }
 
-       $s = new profile_point( 'SQL Queries', 0, $sqltotal, 0, 0 );
+       $s = new profile_point( 'SQL Queries', 0, $sqltotal, 0 );
        foreach ( $queries as $q ) {
                $s->add_child( $q );
        }
index 1edfdd3..174c7d9 100644 (file)
@@ -27,12 +27,6 @@ if ( !defined( 'MEDIAWIKI' ) ) {
 global $wgResourceBasePath;
 
 return [
-
-       /**
-        * Special modules who have their own classes
-        */
-       'startup' => [ 'class' => ResourceLoaderStartUpModule::class ],
-
        // Scripts managed by the local wiki (stored in the MediaWiki namespace)
        'site' => [ 'class' => ResourceLoaderSiteModule::class ],
        'site.styles' => [ 'class' => ResourceLoaderSiteStylesModule::class ],
@@ -223,20 +217,15 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'jquery.form' => [
-               'scripts' => 'resources/lib/jquery.form.js',
+               'scripts' => 'resources/lib/jquery.form/jquery.form.js',
        ],
        'jquery.fullscreen' => [
-               'scripts' => 'resources/lib/jquery.fullscreen.js',
+               'scripts' => 'resources/lib/jquery.fullscreen/jquery.fullscreen.js',
        ],
        'jquery.getAttrs' => [
                'scripts' => 'resources/src/jquery/jquery.getAttrs.js',
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'jquery.hidpi' => [
-               'deprecated' => 'Use of the srcset polyfill is deprecated since MediaWiki 1.32.0',
-               'scripts' => 'resources/src/jquery/jquery.hidpi.js',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
        'jquery.highlightText' => [
                'scripts' => 'resources/src/jquery/jquery.highlightText.js',
                'dependencies' => [
@@ -245,7 +234,7 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'jquery.hoverIntent' => [
-               'scripts' => 'resources/lib/jquery.hoverIntent.js',
+               'scripts' => 'resources/lib/jquery.hoverIntent/jquery.hoverIntent.js',
        ],
        'jquery.i18n' => [
                'scripts' => [
@@ -288,9 +277,6 @@ return [
                'messages' => [ 'collapsible-expand', 'collapsible-collapse' ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'jquery.mockjax' => [
-               'scripts' => 'resources/lib/jquery.mockjax.js',
-       ],
        'jquery.mw-jump' => [
                'scripts' => 'resources/src/jquery/jquery.mw-jump.js',
                'targets' => [ 'desktop', 'mobile' ],
@@ -302,12 +288,12 @@ return [
        ],
        'jquery.spinner' => [
                'scripts' => 'resources/src/jquery.spinner/spinner.js',
-               'styles' => 'resources/src/jquery.spinner/spinner.css',
+               'styles' => 'resources/src/jquery.spinner/spinner.less',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'jquery.jStorage' => [
                'deprecated' => 'Please use "mediawiki.storage" instead.',
-               'scripts' => 'resources/lib/jquery.jStorage.js',
+               'scripts' => 'resources/lib/jquery.jStorage/jstorage.js',
        ],
        'jquery.suggestions' => [
                'targets' => [ 'desktop', 'mobile' ],
@@ -340,12 +326,9 @@ return [
        'jquery.throttle-debounce' => [
                'deprecated' => 'Please use OO.ui.throttle/debounce instead. See '
                        . 'https://phabricator.wikimedia.org/T213426',
-               'scripts' => 'resources/lib/jquery.ba-throttle-debounce.js',
+               'scripts' => 'resources/lib/jquery.throttle-debounce/jquery.ba-throttle-debounce.js',
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'jquery.xmldom' => [
-               'scripts' => 'resources/lib/jquery.xmldom.js',
-       ],
 
        /* jQuery Tipsy */
 
@@ -602,18 +585,6 @@ return [
                ],
                'group' => 'jquery.ui',
        ],
-       'jquery.ui.spinner' => [
-               'scripts' => 'resources/lib/jquery.ui/jquery.ui.spinner.js',
-               'dependencies' => [
-                       'jquery.ui.core',
-                       'jquery.ui.widget',
-                       'jquery.ui.button',
-               ],
-               'skinStyles' => [
-                       'default' => 'resources/lib/jquery.ui/themes/smoothness/jquery.ui.spinner.css',
-               ],
-               'group' => 'jquery.ui',
-       ],
        'jquery.ui.tabs' => [
                'scripts' => 'resources/lib/jquery.ui/jquery.ui.tabs.js',
                'dependencies' => [
@@ -643,7 +614,7 @@ return [
                'group' => 'jquery.ui',
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       // Effects
+
        'jquery.effects.core' => [
                'deprecated' => true,
                'scripts' => 'resources/lib/jquery.ui/jquery.ui.effect.js',
@@ -763,6 +734,7 @@ return [
                        'fy' => 'resources/lib/moment/locale/fy.js',
                        'gd' => 'resources/lib/moment/locale/gd.js',
                        'gl' => 'resources/lib/moment/locale/gl.js',
+                       'gom' => 'resources/lib/moment/locale/gom-latn.js',
                        'gom-latn' => 'resources/lib/moment/locale/gom-latn.js',
                        'gu' => 'resources/lib/moment/locale/gu.js',
                        'he' => 'resources/lib/moment/locale/he.js',
@@ -840,6 +812,7 @@ return [
                ],
                'dependencies' => [
                        'mediawiki.language',
+                       'mediawiki.RegExp',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
@@ -914,25 +887,12 @@ return [
                ],
        ],
        'mediawiki.diff.styles' => [
-               // FIXME: Remove class and lessMessages
-               // when I6aad563e48f41c783df8b176a4f437e60a1255cc has
-               // been in production for 1 week.
-               'class' => ResourceLoaderLessVarFileModule::class,
                'styles' => [
-                       // Remove resources/src/mediawiki.interface.helpers.styles.less
-                       // when I6aad563e48f41c783df8b176a4f437e60a1255cc has
-                       // been in production for 1 week.
-                       'resources/src/mediawiki.interface.helpers.styles.less',
                        'resources/src/mediawiki.diff.styles/diff.css',
                        'resources/src/mediawiki.diff.styles/print.css' => [
                                'media' => 'print'
                        ],
                ],
-               'lessMessages' => [
-                       'parentheses-start',
-                       'parentheses-end',
-                       'pipe-separator'
-               ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.feedback' => [
@@ -1157,9 +1117,11 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.Title' => [
-               'scripts' => [
-                       'resources/src/mediawiki.Title/Title.js',
-                       'resources/src/mediawiki.Title/phpCharToUpper.js',
+               'localBasePath' => "$IP/resources/src/mediawiki.Title",
+               'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.Title",
+               'packageFiles' => [
+                       'Title.js',
+                       'phpCharToUpper.json'
                ],
                'dependencies' => [
                        'mediawiki.String',
@@ -1357,13 +1319,25 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.checkboxtoggle' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'scripts' => 'resources/src/mediawiki.checkboxtoggle.js',
        ],
        'mediawiki.checkboxtoggle.styles' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'styles' => 'resources/src/mediawiki.checkboxtoggle.styles.css',
        ],
        'mediawiki.cookie' => [
-               'scripts' => 'resources/src/mediawiki.cookie.js',
+               'localBasePath' => "$IP/resources/src/mediawiki.cookie",
+               'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.cookie",
+               'packageFiles' => [
+                       'index.js',
+                       [ 'name' => 'config.json', 'config' => [
+                               'prefix' => 'CookiePrefix',
+                               'domain' => 'CookieDomain',
+                               'path' => 'CookiePath',
+                               'expires' => 'CookieExpiration'
+                       ] ],
+               ],
                'dependencies' => 'jquery.cookie',
                'targets' => [ 'desktop', 'mobile' ],
        ],
@@ -1461,11 +1435,15 @@ return [
                ],
        ],
        'mediawiki.action.history' => [
+               'dependencies' => [ 'jquery.makeCollapsible' ],
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.history.js',
                'styles' => 'resources/src/mediawiki.action/mediawiki.action.history.css',
        ],
        'mediawiki.action.history.styles' => [
-               'styles' => 'resources/src/mediawiki.action/mediawiki.action.history.styles.css',
+               'skinStyles' => [
+                       'default' => 'resources/src/mediawiki.action/mediawiki.action.history.styles.less',
+               ],
+               'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.action.view.dblClickEdit' => [
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.view.dblClickEdit.js',
@@ -1517,6 +1495,7 @@ return [
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.view.rightClickEdit.js',
        ],
        'mediawiki.action.edit.editWarning' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.edit.editWarning.js',
                'dependencies' => [
                        'jquery.textSelection',
@@ -1571,7 +1550,7 @@ return [
        ],
 
        'mediawiki.cldr' => [
-               'scripts' => 'resources/src/mediawiki.language/mediawiki.cldr.js',
+               'scripts' => 'resources/src/mediawiki.cldr/index.js',
                'dependencies' => [
                        'mediawiki.libs.pluralruleparser',
                ],
@@ -1775,17 +1754,15 @@ return [
                        'removedwatchtext-talk',
                ],
        ],
-       'mediawiki.page.rollback' => [
-               'scripts' => 'resources/src/mediawiki.page.rollback.js',
+       'mediawiki.page.rollback.confirmation' => [
+               'scripts' => 'resources/src/mediawiki.rollback.confirmation.js',
                'dependencies' => [
-                       'mediawiki.api',
-                       'mediawiki.notify',
-                       'mediawiki.util',
-                       'jquery.spinner',
+                       'jquery.confirmable'
                ],
                'messages' => [
-                       'rollbackfailed',
-                       'actioncomplete',
+                       'rollback-confirmation-confirm',
+                       'rollback-confirmation-yes',
+                       'rollback-confirmation-no',
                ],
        ],
        'mediawiki.page.image.pagination' => [
@@ -1799,14 +1776,16 @@ return [
        /* MediaWiki Special pages */
 
        'mediawiki.rcfilters.filters.base.styles' => [
-               'styles' => [
-                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
+               'skinStyles' => [
+                       'default' => 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
                ],
        ],
        'mediawiki.rcfilters.highlightCircles.seenunseen.styles' => [
-               'styles' => [
-                       'resources/src/mediawiki.rcfilters/' .
-                       'styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less',
+               'skinStyles' => [
+                       'default' => [
+                               'resources/src/mediawiki.rcfilters/' .
+                               'styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less',
+                       ],
                ],
        ],
        'mediawiki.rcfilters.filters.dm' => [
@@ -2024,8 +2003,8 @@ return [
                        'parentheses-end',
                        'pipe-separator'
                ],
-               'styles' => [
-                       'resources/src/mediawiki.interface.helpers.styles.less',
+               'skinStyles' => [
+                       'default' => 'resources/src/mediawiki.interface.helpers.styles.less',
                ],
                'targets' => [
                        'desktop', 'mobile'
@@ -2121,7 +2100,15 @@ return [
                ],
        ],
        'mediawiki.special.block' => [
-               'scripts' => 'resources/src/mediawiki.special.block.js',
+               'localBasePath' => "$IP/resources/src",
+               'remoteBasePath' => "$wgResourceBasePath/resources/src",
+               'packageFiles' => [
+                       'mediawiki.special.block.js',
+                       [ 'name' => 'config.json', 'config' => [
+                               'EnablePartialBlocks',
+                               'BlockAllowsUTEdit',
+                       ] ],
+               ],
                'dependencies' => [
                        'oojs-ui-core',
                        'oojs-ui.styles.icons-editing-core',
@@ -2146,20 +2133,11 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.changeslist' => [
-               // FIXME: Remove class and lessMessages
-               // when I6aad563e48f41c783df8b176a4f437e60a1255cc has
-               // been in production for 1 week.
-               'class' => ResourceLoaderLessVarFileModule::class,
-               'lessMessages' => [
-                       'parentheses-start',
-                       'parentheses-end',
-                       'pipe-separator'
-               ],
                'styles' => [
-                       // FIXME: Remove this line when I6aad563e48f41c783df8b176a4f437e60a1255cc has
-                       // been in production for 1 week.
-                       'resources/src/mediawiki.interface.helpers.styles.less',
-                       'resources/src/mediawiki.special.changeslist.less',
+                       'resources/src/mediawiki.special.changeslist/changeslist.less'
+               ],
+               'skinStyles' => [
+                       'default' => 'resources/src/mediawiki.special.changeslist/default.less',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
@@ -2353,6 +2331,7 @@ return [
                        'createacct-emailrequired',
                        'noname',
                        'userexists',
+                       'createacct-normalization',
                ],
                'dependencies' => [
                        'mediawiki.api',
@@ -2672,6 +2651,7 @@ return [
                        'period-pm',
                ],
                'dependencies' => [
+                       'mediawiki.RegExp',
                        'oojs-ui-core',
                        'oojs-ui.styles.icons-moderation',
                        'oojs-ui.styles.icons-movement',
@@ -2798,6 +2778,7 @@ return [
        'mediawiki.widgets.NamespacesMultiselectWidget' => [
                'scripts' => [
                        'resources/src/mediawiki.widgets/mw.widgets.NamespacesMultiselectWidget.js',
+                       'resources/src/mediawiki.widgets/mw.widgets.NamespacesMenuOptionWidget.js',
                ],
                'dependencies' => [
                        'oojs-ui-widgets',
diff --git a/resources/lib/foreign-resources.yaml b/resources/lib/foreign-resources.yaml
new file mode 100644 (file)
index 0000000..dc7379a
--- /dev/null
@@ -0,0 +1,267 @@
+# ## Format of this file
+#
+# The top-level keys in this file correspond with directories under resources/lib/.
+# These in turn are registered as module bundles in Resources.php.
+#
+# ## How to install an foreign resource
+#
+# 1. Add or update the url(s) for the upstream module to this YAML file.
+#
+#    Look at other modules for examples. To install a module from npm,
+#    we use the tarball distribution from npmjs.org. This is the same as what
+#    the npm CLI uses. For example, to install jquery-client@9.2.0, use:
+#    <https://registry.npmjs.org/jquery-client/-/jquery-client-9.2.0.tgz>.
+#
+# 2. If the upstream maintainers publish an integrity hash, set that as well.
+#    Otherwise, use manageForeignResources.php to compute the integrity hash.
+#
+#    Run `php manageForeignResources.php make-sri "my module name"`
+#
+#    This will download the specified file(s) and print their integrity hashes,
+#    already formatted in YAML, ready for copying to this file.
+#
+# 3. Last but not least, decide where files go.
+#
+#    If you specified a direct url to JavaScript or CSS file, this step is
+#    optional. See the corresponding documentation section below for more
+#    information and examples for "dest" keys. Once you've set any "dest" keys,
+#    run `php manageForeignResources.php update "my module name"`.
+#
+# ## Package formats
+#
+# Each top-level key must use one of these types:
+#
+# - `file`: For a plain file.
+# - `multi-file`: For multiple plain files.
+# - `tar`: For a tarball archive (may be compressed).
+#
+# ### The "file" type
+#
+# * `src`: Full URL to the remote resource.
+# * `integrity`: Cryptographic hash (integrity metadata format per <https://www.w3.org/TR/SRI/>).
+# * `dest`: [optional] The file name to use in the module directory. Default: Basename of URL.
+#
+# For example, the following would produce resources/lib/mymodule/x.js:
+#
+#     mymodule:
+#       type: file
+#       src: https://mymodule.example/1.2.3/x.js
+#       integrity: sha384-Je+NE+saisQuoi
+#
+# ### The "multi-file" type
+#
+# * `files`: An object mapping destination paths to `src` and `integrity` keys.
+#
+# For example:
+#
+#     mymodule:
+#       type: multi-file
+#       files:
+#         x.js:
+#           src: https://mymodule.example/1.2.3/x.js
+#           integrity: sha384-Je+NE+saisQuoi
+#         x.css:
+#           src: https://mymodule.example/1.2.3/x.css
+#           integrity: sha384-Je+NE+saisQuoi
+#
+# ### The "tar" type
+#
+# * `src`: Full URL to the remote resource.
+# * `integrity`: Cryptographic hash (integrity metadata format per <https://www.w3.org/TR/SRI/>).
+# * `dest`: [optional] The default is to extract all files from the package.
+#    To only extract some of the files or directories, use "dest" to specify
+#    files, directories, and/or glob patterns. You can use a site like https://unpkg.com/
+#    to easily inspect an npm package, like <https://unpkg.com/jquery-client@2.0.2/>.
+#
+# For example:
+#
+#     mymodule:
+#       type: tar
+#       src: https://registry.npmjs.org/jquery-client/-/jquery-client-9.2.0.tgz
+#       integrity: sha384-Je+NE+saisQuoi
+#       dest:
+#         package/dist/x.js:
+#         package/dist/i18n:
+#         package/dist/style/*.css:
+#
+# The would extract the "x.js" file, the "i18n" directory (recursive),
+# and any "*.css" files from the "style" directory.
+#
+
+CLDRPluralRuleParser:
+  type: file
+  src: https://raw.githubusercontent.com/santhoshtr/CLDRPluralRuleParser/0dda851/src/CLDRPluralRuleParser.js
+  integrity: sha384-M4taeYYG2+9Ob1/La16iO+zlRRmBV5lBR3xUKkQT6kfkJ0aLbCi6yc0RYI1BDzdh
+
+easy-deflate:
+  type: multi-file
+  files:
+    deflate.js:
+      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/deflate.js
+      integrity: sha384-sHnZLDSWMUhA2w9ygkzCK8YFvoh/fQKY6lXMbvmrYzjuNURiLB0DZFCDNMpGyZ77
+    easydeflate.js:
+      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/easydeflate.js
+      integrity: sha384-EwPfP2RMkDPa1HkzQsXgzTsy1KEjcIzQPA1HDS/JPHjvEMvVUsCxWwm1oXql/jk2
+    inflate.js:
+      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/inflate.js
+      integrity: sha384-hMg44Hw424mUYvmzKl0JT4J8UU/1YYhTiGRtR0YX/MXNLK9qWTK0d62FBCDGxmxw
+    README.md:
+      src: https://raw.githubusercontent.com/edg2s/Easy-Deflate/7a6056e5302f6f385ff2efa60afda45b4ad81e51/README.md
+      integrity: sha384-6kwcfCLivvqXBZy2ATyya+mTVWLk3eaQyBdC6tbpBtkygnBrM2SNkq3jz/l7IkvP
+
+html5shiv:
+  type: file
+  src: https://raw.githubusercontent.com/aFarkas/html5shiv/3.7.3/src/html5shiv.js
+  integrity: sha384-RPXhaTf22QktT8KTwZ6bUz/C+7CnccaIw5W/y/t0FW5WSDGj3wc3YtRIJC0w47in
+
+jquery:
+  type: file
+  src: https://code.jquery.com/jquery-3.3.1.js
+  # Integrity from link modals https://code.jquery.com/jquery/
+  integrity: sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=
+  dest: jquery.js
+
+# TODO: jquery.async.js
+
+# TODO: jquery.chosen
+
+jquery.client:
+  type: tar
+  src: https://registry.npmjs.org/jquery-client/-/jquery-client-2.0.2.tgz
+  integrity: sha256-8c8nBbBykHEMc4I7ksdKJvvw/P7WkaC2X46RTPdz/pw=
+  dest:
+    package/AUTHORS.txt:
+    package/jquery.client.js:
+    package/LICENSE-MIT:
+    package/README.md:
+
+jquery.cookie:
+  type: multi-file
+  files:
+    jquery.cookie.js:
+      src: https://raw.githubusercontent.com/carhartl/jquery-cookie/v1.3.1/jquery.cookie.js
+      integrity: sha384-Xxq63E9KDgzUJ6WPNPqVeOtRIwZyx6y9DzEwY2u6LYKSnWrjSoGtWSKmTindYBf2
+    MIT-LICENSE.txt:
+      src: https://raw.githubusercontent.com/carhartl/jquery-cookie/v1.3.1/MIT-LICENSE.txt
+      integrity: sha384-zYsGf3KJ7S0AhOICjcoh0kkn7aGZlzYUXXX5xz8dwR9KjLMM+/JPR2g/jVOGGeId
+    CHANGELOG.md:
+      src: https://raw.githubusercontent.com/carhartl/jquery-cookie/v1.3.1/CHANGELOG.md
+      integrity: sha384-SQOHhLc7PHxHDQpGE/zv9XfXKL0A7OBu8kuyVDnHVp+zSoWyRw4xUJ+LSm5ql4kS
+
+jquery.form:
+  type: file
+  src: https://raw.githubusercontent.com/jquery-form/form/ff80d9ddf4/jquery.form.js
+  integrity: sha384-h4G2CrcSbixzMvrrK259cNBYaL/vS1D4+KdUN9NJDzQnTU1bQ6Avluget+Id13M7
+
+jquery.fullscreen:
+  type: file
+  src: https://raw.githubusercontent.com/theopolisme/jquery-fullscreen/v2.1.0/jquery.fullscreen.js
+  integrity: sha384-G4KPs2d99tgcsyUnJ3eeZ1r2hEKDwZfc4+/xowL/LIemq2VVwEE8HpVAWt4WYNLR
+
+jquery.hoverIntent:
+  type: file
+  src: https://raw.githubusercontent.com/briancherne/jquery-hoverIntent/823603fdac/jquery.hoverIntent.js
+  integrity: sha384-lca0haN0hqFGGh2aYUhtAgX9dhVHfQnTADH4svDeM6gcXnL7aFGeAi1NYwipDMyS
+
+# TODO: jquery.i18n
+
+jquery.jStorage:
+  type: file
+  src: https://raw.githubusercontent.com/andris9/jStorage/v0.4.12/jstorage.js
+  integrity: sha384-geMeN8k803kPp6cqRL4VNfuSM1L8DcbKRk0St/KHJzxgpX9S0y9FA6HxA/JgucrJ
+
+jquery.throttle-debounce:
+  type: file
+  src: https://raw.githubusercontent.com/cowboy/jquery-throttle-debounce/v1.1/jquery.ba-throttle-debounce.js
+  integrity: sha384-ULOy4DbAghrCqRcrTJLXOY9e4gDpWh0BeEf6xMSL0VtNudXWggcb6AmrVrl4KDAP
+
+# TODO: jquery.ui (!)
+
+moment:
+  type: tar
+  src: https://codeload.github.com/moment/moment/tar.gz/2.24.0
+  integrity: sha384-2/I9rfqkN8AAgh5wOXXphuo827uV7lMmOodrCfIvqC6W6JKKiDGOwd+lE3e8R0yz
+  dest:
+    moment-2.24.0/moment.js:
+    moment-2.24.0/CHANGELOG.md:
+    moment-2.24.0/README.md:
+    moment-2.24.0/LICENSE:
+    moment-2.24.0/locale/*.js: locale
+
+mustache:
+  type: multi-file
+  files:
+    mustache.js:
+      src: https://raw.githubusercontent.com/janl/mustache.js/v3.0.1/mustache.js
+      integrity: sha384-YjAj6Nll7fkEWzxTlE9o3NWC9qdZt1Upat6Afjib9eLs8lTODpSKEBHeXq8o/VUH
+    LICENSE:
+      src: https://raw.githubusercontent.com/janl/mustache.js/v3.0.1/LICENSE
+      integrity: sha384-j2EDj6YtCRgFvYDtzo6pXzbskIj/K1Yg65BL0j3/L6UIHxbMtRMJwC/W+XoYx0FZ
+
+oojs:
+  type: tar
+  src: https://registry.npmjs.org/oojs/-/oojs-2.2.2.tgz
+  integrity: sha256-ebgQW2EGrSkBCnDJBGqDpsBDjA3PMN/M8U5DyLHt9mw=
+  dest:
+    package/dist/oojs.jquery.js:
+    package/AUTHORS.txt:
+    package/LICENSE-MIT:
+    package/README.md:
+
+oojs-router:
+  type: tar
+  src: https://registry.npmjs.org/oojs-router/-/oojs-router-0.2.0.tgz
+  integrity: sha384-VngYqdQ3vTDMXbm4e4FUZCCGos7fB0Jkr9V+kBL5MElprK1h0yQZOzBNnMHtSJS/
+  dest:
+    package/dist/oojs-router.js:
+    package/LICENSE:
+    package/AUTHORS.txt:
+    package/History.md:
+
+ooui:
+  type: tar
+  src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.31.3.tgz
+  integrity: sha384-4Z7gxGPS5BlbUecWzyy/Pr7cZDfl1BRb3UMkE1xxYTm+FIo+0zJjTD3yrLSSDd1j
+  dest:
+    # Main stuff
+    package/dist/oojs-ui-core.js{,.map.json}:
+    package/dist/oojs-ui-core-{wikimediaui,apex}.css:
+    package/dist/oojs-ui-widgets.js{,.map.json}:
+    package/dist/oojs-ui-widgets-{wikimediaui,apex}.css:
+    package/dist/oojs-ui-toolbars.js{,.map.json}:
+    package/dist/oojs-ui-toolbars-{wikimediaui,apex}.css:
+    package/dist/oojs-ui-windows.js{,.map.json}:
+    package/dist/oojs-ui-windows-{wikimediaui,apex}.css:
+    package/dist/oojs-ui-{wikimediaui,apex}.js{,.map.json}:
+    package/dist/i18n:
+    package/dist/images:
+    # WikimediaUI theme
+    package/dist/themes/wikimediaui/images/icons/*.{svg,png}: themes/wikimediaui/images/icons
+    package/dist/themes/wikimediaui/images/indicators/*.{svg,png}: themes/wikimediaui/images/indicators
+    package/dist/themes/wikimediaui/images/textures/*.{gif,svg}: themes/wikimediaui/images/textures
+    package/dist/themes/wikimediaui/*.json: themes/wikimediaui
+    package/dist/wikimedia-ui-base.less:
+    # Apex theme (icons, indicators, and textures)
+    package/dist/themes/apex/*.json: themes/apex
+    # Misc stuff
+    package/dist/AUTHORS.txt:
+    package/dist/History.md:
+    package/dist/LICENSE-MIT:
+    package/dist/README.md:
+
+qunitjs:
+  type: multi-file
+  # Integrity from link modals at https://code.jquery.com/qunit/
+  files:
+    qunit.js:
+      src: http://code.jquery.com/qunit/qunit-2.9.1.js
+      integrity: sha256-eNccBdxd8zReziWcVjEsPeyJDi3LKMYnzMXyDv8bzsU=
+    qunit.css:
+      src: https://code.jquery.com/qunit/qunit-2.9.1.css
+      integrity: sha256-SSS7o92V7wzcIFg3qnJL9mc4msePaT4klbxtuSGvVVo=
+
+sinonjs:
+  type: file
+  src: https://sinonjs.org/releases/sinon-1.17.7.js
+  integrity: sha384-wR63Jwy75KqwBfzCmXd6gYws6uj3qV/XMAybzXrkEYGYG3AQ58ZWwr1fVpkHa5e8
+  dest: sinon.js
diff --git a/resources/lib/jquery.ba-throttle-debounce.js b/resources/lib/jquery.ba-throttle-debounce.js
deleted file mode 100644 (file)
index fa30bdf..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-/*!
- * jQuery throttle / debounce - v1.1 - 3/7/2010
- * http://benalman.com/projects/jquery-throttle-debounce-plugin/
- * 
- * Copyright (c) 2010 "Cowboy" Ben Alman
- * Dual licensed under the MIT and GPL licenses.
- * http://benalman.com/about/license/
- */
-
-// Script: jQuery throttle / debounce: Sometimes, less is more!
-//
-// *Version: 1.1, Last updated: 3/7/2010*
-// 
-// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/
-// GitHub       - http://github.com/cowboy/jquery-throttle-debounce/
-// Source       - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js
-// (Minified)   - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb)
-// 
-// About: License
-// 
-// Copyright (c) 2010 "Cowboy" Ben Alman,
-// Dual licensed under the MIT and GPL licenses.
-// http://benalman.com/about/license/
-// 
-// About: Examples
-// 
-// These working examples, complete with fully commented code, illustrate a few
-// ways in which this plugin can be used.
-// 
-// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
-// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
-// 
-// About: Support and Testing
-// 
-// Information about what version or versions of jQuery this plugin has been
-// tested with, what browsers it has been tested in, and where the unit tests
-// reside (so you can test it yourself).
-// 
-// jQuery Versions - none, 1.3.2, 1.4.2
-// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
-// Unit Tests      - http://benalman.com/code/projects/jquery-throttle-debounce/unit/
-// 
-// About: Release History
-// 
-// 1.1 - (3/7/2010) Fixed a bug in <jQuery.throttle> where trailing callbacks
-//       executed later than they should. Reworked a fair amount of internal
-//       logic as well.
-// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over
-//       from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the
-//       no_trailing throttle parameter and debounce functionality.
-// 
-// Topic: Note for non-jQuery users
-// 
-// jQuery isn't actually required for this plugin, because nothing internal
-// uses any jQuery methods or properties. jQuery is just used as a namespace
-// under which these methods can exist.
-// 
-// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist
-// when this plugin is loaded, the method described below will be created in
-// the `Cowboy` namespace. Usage will be exactly the same, but instead of
-// $.method() or jQuery.method(), you'll need to use Cowboy.method().
-
-(function(window,undefined){
-  '$:nomunge'; // Used by YUI compressor.
-  
-  // Since jQuery really isn't required for this plugin, use `jQuery` as the
-  // namespace only if it already exists, otherwise use the `Cowboy` namespace,
-  // creating it if necessary.
-  var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ),
-    
-    // Internal method reference.
-    jq_throttle;
-  
-  // Method: jQuery.throttle
-  // 
-  // Throttle execution of a function. Especially useful for rate limiting
-  // execution of handlers on events like resize and scroll. If you want to
-  // rate-limit execution of a function to a single time, see the
-  // <jQuery.debounce> method.
-  // 
-  // In this visualization, | is a throttled-function call and X is the actual
-  // callback execution:
-  // 
-  // > Throttled with `no_trailing` specified as false or unspecified:
-  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
-  // > X    X    X    X    X    X        X    X    X    X    X    X
-  // > 
-  // > Throttled with `no_trailing` specified as true:
-  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
-  // > X    X    X    X    X             X    X    X    X    X
-  // 
-  // Usage:
-  // 
-  // > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback );
-  // > 
-  // > jQuery('selector').bind( 'someevent', throttled );
-  // > jQuery('selector').unbind( 'someevent', throttled );
-  // 
-  // This also works in jQuery 1.4+:
-  // 
-  // > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) );
-  // > jQuery('selector').unbind( 'someevent', callback );
-  // 
-  // Arguments:
-  // 
-  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
-  //    callbacks, values around 100 or 250 (or even higher) are most useful.
-  //  no_trailing - (Boolean) Optional, defaults to false. If no_trailing is
-  //    true, callback will only execute every `delay` milliseconds while the
-  //    throttled-function is being called. If no_trailing is false or
-  //    unspecified, callback will be executed one final time after the last
-  //    throttled-function call. (After the throttled-function has not been
-  //    called for `delay` milliseconds, the internal counter is reset)
-  //  callback - (Function) A function to be executed after delay milliseconds.
-  //    The `this` context and all arguments are passed through, as-is, to
-  //    `callback` when the throttled-function is executed.
-  // 
-  // Returns:
-  // 
-  //  (Function) A new, throttled, function.
-  
-  $.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) {
-    // After wrapper has stopped being called, this timeout ensures that
-    // `callback` is executed at the proper times in `throttle` and `end`
-    // debounce modes.
-    var timeout_id,
-      
-      // Keep track of the last time `callback` was executed.
-      last_exec = 0;
-    
-    // `no_trailing` defaults to falsy.
-    if ( typeof no_trailing !== 'boolean' ) {
-      debounce_mode = callback;
-      callback = no_trailing;
-      no_trailing = undefined;
-    }
-    
-    // The `wrapper` function encapsulates all of the throttling / debouncing
-    // functionality and when executed will limit the rate at which `callback`
-    // is executed.
-    function wrapper() {
-      var that = this,
-        elapsed = +new Date() - last_exec,
-        args = arguments;
-      
-      // Execute `callback` and update the `last_exec` timestamp.
-      function exec() {
-        last_exec = +new Date();
-        callback.apply( that, args );
-      };
-      
-      // If `debounce_mode` is true (at_begin) this is used to clear the flag
-      // to allow future `callback` executions.
-      function clear() {
-        timeout_id = undefined;
-      };
-      
-      if ( debounce_mode && !timeout_id ) {
-        // Since `wrapper` is being called for the first time and
-        // `debounce_mode` is true (at_begin), execute `callback`.
-        exec();
-      }
-      
-      // Clear any existing timeout.
-      timeout_id && clearTimeout( timeout_id );
-      
-      if ( debounce_mode === undefined && elapsed > delay ) {
-        // In throttle mode, if `delay` time has been exceeded, execute
-        // `callback`.
-        exec();
-        
-      } else if ( no_trailing !== true ) {
-        // In trailing throttle mode, since `delay` time has not been
-        // exceeded, schedule `callback` to execute `delay` ms after most
-        // recent execution.
-        // 
-        // If `debounce_mode` is true (at_begin), schedule `clear` to execute
-        // after `delay` ms.
-        // 
-        // If `debounce_mode` is false (at end), schedule `callback` to
-        // execute after `delay` ms.
-        timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
-      }
-    };
-    
-    // Set the guid of `wrapper` function to the same of original callback, so
-    // it can be removed in jQuery 1.4+ .unbind or .die by using the original
-    // callback as a reference.
-    if ( $.guid ) {
-      wrapper.guid = callback.guid = callback.guid || $.guid++;
-    }
-    
-    // Return the wrapper function.
-    return wrapper;
-  };
-  
-  // Method: jQuery.debounce
-  // 
-  // Debounce execution of a function. Debouncing, unlike throttling,
-  // guarantees that a function is only executed a single time, either at the
-  // very beginning of a series of calls, or at the very end. If you want to
-  // simply rate-limit execution of a function, see the <jQuery.throttle>
-  // method.
-  // 
-  // In this visualization, | is a debounced-function call and X is the actual
-  // callback execution:
-  // 
-  // > Debounced with `at_begin` specified as false or unspecified:
-  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
-  // >                          X                                 X
-  // > 
-  // > Debounced with `at_begin` specified as true:
-  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
-  // > X                                 X
-  // 
-  // Usage:
-  // 
-  // > var debounced = jQuery.debounce( delay, [ at_begin, ] callback );
-  // > 
-  // > jQuery('selector').bind( 'someevent', debounced );
-  // > jQuery('selector').unbind( 'someevent', debounced );
-  // 
-  // This also works in jQuery 1.4+:
-  // 
-  // > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) );
-  // > jQuery('selector').unbind( 'someevent', callback );
-  // 
-  // Arguments:
-  // 
-  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
-  //    callbacks, values around 100 or 250 (or even higher) are most useful.
-  //  at_begin - (Boolean) Optional, defaults to false. If at_begin is false or
-  //    unspecified, callback will only be executed `delay` milliseconds after
-  //    the last debounced-function call. If at_begin is true, callback will be
-  //    executed only at the first debounced-function call. (After the
-  //    throttled-function has not been called for `delay` milliseconds, the
-  //    internal counter is reset)
-  //  callback - (Function) A function to be executed after delay milliseconds.
-  //    The `this` context and all arguments are passed through, as-is, to
-  //    `callback` when the debounced-function is executed.
-  // 
-  // Returns:
-  // 
-  //  (Function) A new, debounced, function.
-  
-  $.debounce = function( delay, at_begin, callback ) {
-    return callback === undefined
-      ? jq_throttle( delay, at_begin, false )
-      : jq_throttle( delay, callback, at_begin !== false );
-  };
-  
-})(this);
diff --git a/resources/lib/jquery.form.js b/resources/lib/jquery.form.js
deleted file mode 100644 (file)
index 13e9a55..0000000
+++ /dev/null
@@ -1,1089 +0,0 @@
-/*!
- * jQuery Form Plugin
- * version: 3.14 (30-JUL-2012)
- * @requires jQuery v1.3.2 or later
- *
- * Examples and documentation at: http://malsup.com/jquery/form/
- * Project repository: https://github.com/malsup/form
- * Dual licensed under the MIT and GPL licenses:
- *    http://malsup.github.com/mit-license.txt
- *    http://malsup.github.com/gpl-license-v2.txt
- */
-/*global ActiveXObject alert */
-;(function($) {
-"use strict";
-
-/*
-    Usage Note:
-    -----------
-    Do not use both ajaxSubmit and ajaxForm on the same form.  These
-    functions are mutually exclusive.  Use ajaxSubmit if you want
-    to bind your own submit handler to the form.  For example,
-
-    $(document).ready(function() {
-        $('#myForm').on('submit', function(e) {
-            e.preventDefault(); // <-- important
-            $(this).ajaxSubmit({
-                target: '#output'
-            });
-        });
-    });
-
-    Use ajaxForm when you want the plugin to manage all the event binding
-    for you.  For example,
-
-    $(document).ready(function() {
-        $('#myForm').ajaxForm({
-            target: '#output'
-        });
-    });
-    
-    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
-    form does not have to exist when you invoke ajaxForm:
-
-    $('#myForm').ajaxForm({
-        delegation: true,
-        target: '#output'
-    });
-    
-    When using ajaxForm, the ajaxSubmit function will be invoked for you
-    at the appropriate time.
-*/
-
-/**
- * Feature detection
- */
-var feature = {};
-feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
-feature.formdata = window.FormData !== undefined;
-
-/**
- * ajaxSubmit() provides a mechanism for immediately submitting
- * an HTML form using AJAX.
- */
-$.fn.ajaxSubmit = function(options) {
-    /*jshint scripturl:true */
-
-    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
-    if (!this.length) {
-        log('ajaxSubmit: skipping submit process - no element selected');
-        return this;
-    }
-    
-    var method, action, url, $form = this;
-
-    if (typeof options == 'function') {
-        options = { success: options };
-    }
-
-    method = this.attr('method');
-    action = this.attr('action');
-    url = (typeof action === 'string') ? $.trim(action) : '';
-    url = url || window.location.href || '';
-    if (url) {
-        // clean url (don't include hash vaue)
-        url = (url.match(/^([^#]+)/)||[])[1];
-    }
-
-    options = $.extend(true, {
-        url:  url,
-        success: $.ajaxSettings.success,
-        type: method || 'GET',
-        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
-    }, options);
-
-    // hook for manipulating the form data before it is extracted;
-    // convenient for use with rich editors like tinyMCE or FCKEditor
-    var veto = {};
-    this.trigger('form-pre-serialize', [this, options, veto]);
-    if (veto.veto) {
-        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
-        return this;
-    }
-
-    // provide opportunity to alter form data before it is serialized
-    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
-        log('ajaxSubmit: submit aborted via beforeSerialize callback');
-        return this;
-    }
-
-    var traditional = options.traditional;
-    if ( traditional === undefined ) {
-        traditional = $.ajaxSettings.traditional;
-    }
-    
-    var elements = [];
-    var qx, a = this.formToArray(options.semantic, elements);
-    if (options.data) {
-        options.extraData = options.data;
-        qx = $.param(options.data, traditional);
-    }
-
-    // give pre-submit callback an opportunity to abort the submit
-    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
-        log('ajaxSubmit: submit aborted via beforeSubmit callback');
-        return this;
-    }
-
-    // fire vetoable 'validate' event
-    this.trigger('form-submit-validate', [a, this, options, veto]);
-    if (veto.veto) {
-        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
-        return this;
-    }
-
-    var q = $.param(a, traditional);
-    if (qx) {
-        q = ( q ? (q + '&' + qx) : qx );
-    }    
-    if (options.type.toUpperCase() == 'GET') {
-        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
-        options.data = null;  // data is null for 'get'
-    }
-    else {
-        options.data = q; // data is the query string for 'post'
-    }
-
-    var callbacks = [];
-    if (options.resetForm) {
-        callbacks.push(function() { $form.resetForm(); });
-    }
-    if (options.clearForm) {
-        callbacks.push(function() { $form.clearForm(options.includeHidden); });
-    }
-
-    // perform a load on the target only if dataType is not provided
-    if (!options.dataType && options.target) {
-        var oldSuccess = options.success || function(){};
-        callbacks.push(function(data) {
-            var fn = options.replaceTarget ? 'replaceWith' : 'html';
-            $(options.target)[fn](data).each(oldSuccess, arguments);
-        });
-    }
-    else if (options.success) {
-        callbacks.push(options.success);
-    }
-
-    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
-        var context = options.context || this ;    // jQuery 1.4+ supports scope context 
-        for (var i=0, max=callbacks.length; i < max; i++) {
-            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
-        }
-    };
-
-    // are there files to upload?
-    var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
-    var hasFileInputs = fileInputs.length > 0;
-    var mp = 'multipart/form-data';
-    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
-
-    var fileAPI = feature.fileapi && feature.formdata;
-    log("fileAPI :" + fileAPI);
-    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
-
-    // options.iframe allows user to force iframe mode
-    // 06-NOV-09: now defaulting to iframe mode if file input is detected
-    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
-        // hack to fix Safari hang (thanks to Tim Molendijk for this)
-        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
-        if (options.closeKeepAlive) {
-            $.get(options.closeKeepAlive, function() {
-                fileUploadIframe(a);
-            });
-        }
-          else {
-            fileUploadIframe(a);
-          }
-    }
-    else if ((hasFileInputs || multipart) && fileAPI) {
-        fileUploadXhr(a);
-    }
-    else {
-        $.ajax(options);
-    }
-
-    // clear element array
-    for (var k=0; k < elements.length; k++)
-        elements[k] = null;
-
-    // fire 'notify' event
-    this.trigger('form-submit-notify', [this, options]);
-    return this;
-
-     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
-    function fileUploadXhr(a) {
-        var formdata = new FormData();
-
-        for (var i=0; i < a.length; i++) {
-            formdata.append(a[i].name, a[i].value);
-        }
-
-        if (options.extraData) {
-            for (var p in options.extraData)
-                if (options.extraData.hasOwnProperty(p))
-                    formdata.append(p, options.extraData[p]);
-        }
-
-        options.data = null;
-
-        var s = $.extend(true, {}, $.ajaxSettings, options, {
-            contentType: false,
-            processData: false,
-            cache: false,
-            type: 'POST'
-        });
-        
-        if (options.uploadProgress) {
-            // workaround because jqXHR does not expose upload property
-            s.xhr = function() {
-                var xhr = jQuery.ajaxSettings.xhr();
-                if (xhr.upload) {
-                    xhr.upload.onprogress = function(event) {
-                        var percent = 0;
-                        var position = event.loaded || event.position; /*event.position is deprecated*/
-                        var total = event.total;
-                        if (event.lengthComputable) {
-                            percent = Math.ceil(position / total * 100);
-                        }
-                        options.uploadProgress(event, position, total, percent);
-                    };
-                }
-                return xhr;
-            };
-        }
-
-        s.data = null;
-            var beforeSend = s.beforeSend;
-            s.beforeSend = function(xhr, o) {
-                o.data = formdata;
-                if(beforeSend)
-                    beforeSend.call(this, xhr, o);
-        };
-        $.ajax(s);
-    }
-
-    // private function for handling file uploads (hat tip to YAHOO!)
-    function fileUploadIframe(a) {
-        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
-        var useProp = !!$.fn.prop;
-
-        if ($(':input[name=submit],:input[id=submit]', form).length) {
-            // if there is an input with a name or id of 'submit' then we won't be
-            // able to invoke the submit fn on the form (at least not x-browser)
-            alert('Error: Form elements must not have name or id of "submit".');
-            return;
-        }
-        
-        if (a) {
-            // ensure that every serialized input is still enabled
-            for (i=0; i < elements.length; i++) {
-                el = $(elements[i]);
-                if ( useProp )
-                    el.prop('disabled', false);
-                else
-                    el.removeAttr('disabled');
-            }
-        }
-
-        s = $.extend(true, {}, $.ajaxSettings, options);
-        s.context = s.context || s;
-        id = 'jqFormIO' + (new Date().getTime());
-        if (s.iframeTarget) {
-            $io = $(s.iframeTarget);
-            n = $io.attr('name');
-            if (!n)
-                 $io.attr('name', id);
-            else
-                id = n;
-        }
-        else {
-            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
-            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
-        }
-        io = $io[0];
-
-
-        xhr = { // mock object
-            aborted: 0,
-            responseText: null,
-            responseXML: null,
-            status: 0,
-            statusText: 'n/a',
-            getAllResponseHeaders: function() {},
-            getResponseHeader: function() {},
-            setRequestHeader: function() {},
-            abort: function(status) {
-                var e = (status === 'timeout' ? 'timeout' : 'aborted');
-                log('aborting upload... ' + e);
-                this.aborted = 1;
-                // #214
-                if (io.contentWindow.document.execCommand) {
-                    try { // #214
-                        io.contentWindow.document.execCommand('Stop');
-                    } catch(ignore) {}
-                }
-                $io.attr('src', s.iframeSrc); // abort op in progress
-                xhr.error = e;
-                if (s.error)
-                    s.error.call(s.context, xhr, e, status);
-                if (g)
-                    $.event.trigger("ajaxError", [xhr, s, e]);
-                if (s.complete)
-                    s.complete.call(s.context, xhr, e);
-            }
-        };
-
-        g = s.global;
-        // trigger ajax global events so that activity/block indicators work like normal
-        if (g && 0 === $.active++) {
-            $.event.trigger("ajaxStart");
-        }
-        if (g) {
-            $.event.trigger("ajaxSend", [xhr, s]);
-        }
-
-        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
-            if (s.global) {
-                $.active--;
-            }
-            return;
-        }
-        if (xhr.aborted) {
-            return;
-        }
-
-        // add submitting element to data if we know it
-        sub = form.clk;
-        if (sub) {
-            n = sub.name;
-            if (n && !sub.disabled) {
-                s.extraData = s.extraData || {};
-                s.extraData[n] = sub.value;
-                if (sub.type == "image") {
-                    s.extraData[n+'.x'] = form.clk_x;
-                    s.extraData[n+'.y'] = form.clk_y;
-                }
-            }
-        }
-        
-        var CLIENT_TIMEOUT_ABORT = 1;
-        var SERVER_ABORT = 2;
-
-        function getDoc(frame) {
-            var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
-            return doc;
-        }
-        
-        // Rails CSRF hack (thanks to Yvan Barthelemy)
-        var csrf_token = $('meta[name=csrf-token]').attr('content');
-        var csrf_param = $('meta[name=csrf-param]').attr('content');
-        if (csrf_param && csrf_token) {
-            s.extraData = s.extraData || {};
-            s.extraData[csrf_param] = csrf_token;
-        }
-
-        // take a breath so that pending repaints get some cpu time before the upload starts
-        function doSubmit() {
-            // make sure form attrs are set
-            var t = $form.attr('target'), a = $form.attr('action');
-
-            // update form attrs in IE friendly way
-            form.setAttribute('target',id);
-            if (!method) {
-                form.setAttribute('method', 'POST');
-            }
-            if (a != s.url) {
-                form.setAttribute('action', s.url);
-            }
-
-            // ie borks in some cases when setting encoding
-            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
-                $form.attr({
-                    encoding: 'multipart/form-data',
-                    enctype:  'multipart/form-data'
-                });
-            }
-
-            // support timout
-            if (s.timeout) {
-                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
-            }
-            
-            // look for server aborts
-            function checkState() {
-                try {
-                    var state = getDoc(io).readyState;
-                    log('state = ' + state);
-                    if (state && state.toLowerCase() == 'uninitialized')
-                        setTimeout(checkState,50);
-                }
-                catch(e) {
-                    log('Server abort: ' , e, ' (', e.name, ')');
-                    cb(SERVER_ABORT);
-                    if (timeoutHandle)
-                        clearTimeout(timeoutHandle);
-                    timeoutHandle = undefined;
-                }
-            }
-
-            // add "extra" data to form if provided in options
-            var extraInputs = [];
-            try {
-                if (s.extraData) {
-                    for (var n in s.extraData) {
-                        if (s.extraData.hasOwnProperty(n)) {
-                           // if using the $.param format that allows for multiple values with the same name
-                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
-                               extraInputs.push(
-                               $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
-                                   .appendTo(form)[0]);
-                           } else {
-                               extraInputs.push(
-                               $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
-                                   .appendTo(form)[0]);
-                           }
-                        }
-                    }
-                }
-
-                if (!s.iframeTarget) {
-                    // add iframe to doc and submit the form
-                    $io.appendTo('body');
-                    if (io.attachEvent)
-                        io.attachEvent('onload', cb);
-                    else
-                        io.addEventListener('load', cb, false);
-                }
-                setTimeout(checkState,15);
-                form.submit();
-            }
-            finally {
-                // reset attrs and remove "extra" input elements
-                form.setAttribute('action',a);
-                if(t) {
-                    form.setAttribute('target', t);
-                } else {
-                    $form.removeAttr('target');
-                }
-                $(extraInputs).remove();
-            }
-        }
-
-        if (s.forceSync) {
-            doSubmit();
-        }
-        else {
-            setTimeout(doSubmit, 10); // this lets dom updates render
-        }
-
-        var data, doc, domCheckCount = 50, callbackProcessed;
-
-        function cb(e) {
-            if (xhr.aborted || callbackProcessed) {
-                return;
-            }
-            try {
-                doc = getDoc(io);
-            }
-            catch(ex) {
-                log('cannot access response document: ', ex);
-                e = SERVER_ABORT;
-            }
-            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
-                xhr.abort('timeout');
-                return;
-            }
-            else if (e == SERVER_ABORT && xhr) {
-                xhr.abort('server abort');
-                return;
-            }
-
-            if (!doc || doc.location.href == s.iframeSrc) {
-                // response not received yet
-                if (!timedOut)
-                    return;
-            }
-            if (io.detachEvent)
-                io.detachEvent('onload', cb);
-            else    
-                io.removeEventListener('load', cb, false);
-
-            var status = 'success', errMsg;
-            try {
-                if (timedOut) {
-                    throw 'timeout';
-                }
-
-                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
-                log('isXml='+isXml);
-                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
-                    if (--domCheckCount) {
-                        // in some browsers (Opera) the iframe DOM is not always traversable when
-                        // the onload callback fires, so we loop a bit to accommodate
-                        log('requeing onLoad callback, DOM not available');
-                        setTimeout(cb, 250);
-                        return;
-                    }
-                    // let this fall through because server response could be an empty document
-                    //log('Could not access iframe DOM after mutiple tries.');
-                    //throw 'DOMException: not available';
-                }
-
-                //log('response detected');
-                var docRoot = doc.body ? doc.body : doc.documentElement;
-                xhr.responseText = docRoot ? docRoot.innerHTML : null;
-                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
-                if (isXml)
-                    s.dataType = 'xml';
-                xhr.getResponseHeader = function(header){
-                    var headers = {'content-type': s.dataType};
-                    return headers[header];
-                };
-                // support for XHR 'status' & 'statusText' emulation :
-                if (docRoot) {
-                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
-                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
-                }
-
-                var dt = (s.dataType || '').toLowerCase();
-                var scr = /(json|script|text)/.test(dt);
-                if (scr || s.textarea) {
-                    // see if user embedded response in textarea
-                    var ta = doc.getElementsByTagName('textarea')[0];
-                    if (ta) {
-                        xhr.responseText = ta.value;
-                        // support for XHR 'status' & 'statusText' emulation :
-                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
-                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
-                    }
-                    else if (scr) {
-                        // account for browsers injecting pre around json response
-                        var pre = doc.getElementsByTagName('pre')[0];
-                        var b = doc.getElementsByTagName('body')[0];
-                        if (pre) {
-                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
-                        }
-                        else if (b) {
-                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
-                        }
-                    }
-                }
-                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
-                    xhr.responseXML = toXml(xhr.responseText);
-                }
-
-                try {
-                    data = httpData(xhr, dt, s);
-                }
-                catch (e) {
-                    status = 'parsererror';
-                    xhr.error = errMsg = (e || status);
-                }
-            }
-            catch (e) {
-                log('error caught: ',e);
-                status = 'error';
-                xhr.error = errMsg = (e || status);
-            }
-
-            if (xhr.aborted) {
-                log('upload aborted');
-                status = null;
-            }
-
-            if (xhr.status) { // we've set xhr.status
-                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
-            }
-
-            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
-            if (status === 'success') {
-                if (s.success)
-                    s.success.call(s.context, data, 'success', xhr);
-                if (g)
-                    $.event.trigger("ajaxSuccess", [xhr, s]);
-            }
-            else if (status) {
-                if (errMsg === undefined)
-                    errMsg = xhr.statusText;
-                if (s.error)
-                    s.error.call(s.context, xhr, status, errMsg);
-                if (g)
-                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
-            }
-
-            if (g)
-                $.event.trigger("ajaxComplete", [xhr, s]);
-
-            if (g && ! --$.active) {
-                $.event.trigger("ajaxStop");
-            }
-
-            if (s.complete)
-                s.complete.call(s.context, xhr, status);
-
-            callbackProcessed = true;
-            if (s.timeout)
-                clearTimeout(timeoutHandle);
-
-            // clean up
-            setTimeout(function() {
-                if (!s.iframeTarget)
-                    $io.remove();
-                xhr.responseXML = null;
-            }, 100);
-        }
-
-        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
-            if (window.ActiveXObject) {
-                doc = new ActiveXObject('Microsoft.XMLDOM');
-                doc.async = 'false';
-                doc.loadXML(s);
-            }
-            else {
-                doc = (new DOMParser()).parseFromString(s, 'text/xml');
-            }
-            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
-        };
-        var parseJSON = $.parseJSON || function(s) {
-            /*jslint evil:true */
-            return window['eval']('(' + s + ')');
-        };
-
-        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
-
-            var ct = xhr.getResponseHeader('content-type') || '',
-                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
-                data = xml ? xhr.responseXML : xhr.responseText;
-
-            if (xml && data.documentElement.nodeName === 'parsererror') {
-                if ($.error)
-                    $.error('parsererror');
-            }
-            if (s && s.dataFilter) {
-                data = s.dataFilter(data, type);
-            }
-            if (typeof data === 'string') {
-                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
-                    data = parseJSON(data);
-                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
-                    $.globalEval(data);
-                }
-            }
-            return data;
-        };
-    }
-};
-
-/**
- * ajaxForm() provides a mechanism for fully automating form submission.
- *
- * The advantages of using this method instead of ajaxSubmit() are:
- *
- * 1: This method will include coordinates for <input type="image" /> elements (if the element
- *    is used to submit the form).
- * 2. This method will include the submit element's name/value data (for the element that was
- *    used to submit the form).
- * 3. This method binds the submit() method to the form for you.
- *
- * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
- * passes the options argument along after properly binding events for submit elements and
- * the form itself.
- */
-$.fn.ajaxForm = function(options) {
-    options = options || {};
-    options.delegation = options.delegation && $.isFunction($.fn.on);
-    
-    // in jQuery 1.3+ we can fix mistakes with the ready state
-    if (!options.delegation && this.length === 0) {
-        var o = { s: this.selector, c: this.context };
-        if (!$.isReady && o.s) {
-            log('DOM not ready, queuing ajaxForm');
-            $(function() {
-                $(o.s,o.c).ajaxForm(options);
-            });
-            return this;
-        }
-        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
-        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
-        return this;
-    }
-
-    if ( options.delegation ) {
-        $(document)
-            .off('submit.form-plugin', this.selector, doAjaxSubmit)
-            .off('click.form-plugin', this.selector, captureSubmittingElement)
-            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
-            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
-        return this;
-    }
-
-    return this.ajaxFormUnbind()
-        .bind('submit.form-plugin', options, doAjaxSubmit)
-        .bind('click.form-plugin', options, captureSubmittingElement);
-};
-
-// private event handlers    
-function doAjaxSubmit(e) {
-    /*jshint validthis:true */
-    var options = e.data;
-    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
-        e.preventDefault();
-        $(this).ajaxSubmit(options);
-    }
-}
-    
-function captureSubmittingElement(e) {
-    /*jshint validthis:true */
-    var target = e.target;
-    var $el = $(target);
-    if (!($el.is(":submit,input:image"))) {
-        // is this a child element of the submit el?  (ex: a span within a button)
-        var t = $el.closest(':submit');
-        if (t.length === 0) {
-            return;
-        }
-        target = t[0];
-    }
-    var form = this;
-    form.clk = target;
-    if (target.type == 'image') {
-        if (e.offsetX !== undefined) {
-            form.clk_x = e.offsetX;
-            form.clk_y = e.offsetY;
-        } else if (typeof $.fn.offset == 'function') {
-            var offset = $el.offset();
-            form.clk_x = e.pageX - offset.left;
-            form.clk_y = e.pageY - offset.top;
-        } else {
-            form.clk_x = e.pageX - target.offsetLeft;
-            form.clk_y = e.pageY - target.offsetTop;
-        }
-    }
-    // clear form vars
-    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
-}
-
-
-// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
-$.fn.ajaxFormUnbind = function() {
-    return this.unbind('submit.form-plugin click.form-plugin');
-};
-
-/**
- * formToArray() gathers form element data into an array of objects that can
- * be passed to any of the following ajax functions: $.get, $.post, or load.
- * Each object in the array has both a 'name' and 'value' property.  An example of
- * an array for a simple login form might be:
- *
- * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
- *
- * It is this array that is passed to pre-submit callback functions provided to the
- * ajaxSubmit() and ajaxForm() methods.
- */
-$.fn.formToArray = function(semantic, elements) {
-    var a = [];
-    if (this.length === 0) {
-        return a;
-    }
-
-    var form = this[0];
-    var els = semantic ? form.getElementsByTagName('*') : form.elements;
-    if (!els) {
-        return a;
-    }
-
-    var i,j,n,v,el,max,jmax;
-    for(i=0, max=els.length; i < max; i++) {
-        el = els[i];
-        n = el.name;
-        if (!n) {
-            continue;
-        }
-
-        if (semantic && form.clk && el.type == "image") {
-            // handle image inputs on the fly when semantic == true
-            if(!el.disabled && form.clk == el) {
-                a.push({name: n, value: $(el).val(), type: el.type });
-                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-            }
-            continue;
-        }
-
-        v = $.fieldValue(el, true);
-        if (v && v.constructor == Array) {
-            if (elements) 
-                elements.push(el);
-            for(j=0, jmax=v.length; j < jmax; j++) {
-                a.push({name: n, value: v[j]});
-            }
-        }
-        else if (feature.fileapi && el.type == 'file' && !el.disabled) {
-            if (elements) 
-                elements.push(el);
-            var files = el.files;
-            if (files.length) {
-                for (j=0; j < files.length; j++) {
-                    a.push({name: n, value: files[j], type: el.type});
-                }
-            }
-            else {
-                // #180
-                a.push({ name: n, value: '', type: el.type });
-            }
-        }
-        else if (v !== null && typeof v != 'undefined') {
-            if (elements) 
-                elements.push(el);
-            a.push({name: n, value: v, type: el.type, required: el.required});
-        }
-    }
-
-    if (!semantic && form.clk) {
-        // input type=='image' are not found in elements array! handle it here
-        var $input = $(form.clk), input = $input[0];
-        n = input.name;
-        if (n && !input.disabled && input.type == 'image') {
-            a.push({name: n, value: $input.val()});
-            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-        }
-    }
-    return a;
-};
-
-/**
- * Serializes form data into a 'submittable' string. This method will return a string
- * in the format: name1=value1&amp;name2=value2
- */
-$.fn.formSerialize = function(semantic) {
-    //hand off to jQuery.param for proper encoding
-    return $.param(this.formToArray(semantic));
-};
-
-/**
- * Serializes all field elements in the jQuery object into a query string.
- * This method will return a string in the format: name1=value1&amp;name2=value2
- */
-$.fn.fieldSerialize = function(successful) {
-    var a = [];
-    this.each(function() {
-        var n = this.name;
-        if (!n) {
-            return;
-        }
-        var v = $.fieldValue(this, successful);
-        if (v && v.constructor == Array) {
-            for (var i=0,max=v.length; i < max; i++) {
-                a.push({name: n, value: v[i]});
-            }
-        }
-        else if (v !== null && typeof v != 'undefined') {
-            a.push({name: this.name, value: v});
-        }
-    });
-    //hand off to jQuery.param for proper encoding
-    return $.param(a);
-};
-
-/**
- * Returns the value(s) of the element in the matched set.  For example, consider the following form:
- *
- *  <form><fieldset>
- *      <input name="A" type="text" />
- *      <input name="A" type="text" />
- *      <input name="B" type="checkbox" value="B1" />
- *      <input name="B" type="checkbox" value="B2"/>
- *      <input name="C" type="radio" value="C1" />
- *      <input name="C" type="radio" value="C2" />
- *  </fieldset></form>
- *
- *  var v = $(':text').fieldValue();
- *  // if no values are entered into the text inputs
- *  v == ['','']
- *  // if values entered into the text inputs are 'foo' and 'bar'
- *  v == ['foo','bar']
- *
- *  var v = $(':checkbox').fieldValue();
- *  // if neither checkbox is checked
- *  v === undefined
- *  // if both checkboxes are checked
- *  v == ['B1', 'B2']
- *
- *  var v = $(':radio').fieldValue();
- *  // if neither radio is checked
- *  v === undefined
- *  // if first radio is checked
- *  v == ['C1']
- *
- * The successful argument controls whether or not the field element must be 'successful'
- * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
- * The default value of the successful argument is true.  If this value is false the value(s)
- * for each element is returned.
- *
- * Note: This method *always* returns an array.  If no valid value can be determined the
- *    array will be empty, otherwise it will contain one or more values.
- */
-$.fn.fieldValue = function(successful) {
-    for (var val=[], i=0, max=this.length; i < max; i++) {
-        var el = this[i];
-        var v = $.fieldValue(el, successful);
-        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
-            continue;
-        }
-        if (v.constructor == Array)
-            $.merge(val, v);
-        else
-            val.push(v);
-    }
-    return val;
-};
-
-/**
- * Returns the value of the field element.
- */
-$.fieldValue = function(el, successful) {
-    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
-    if (successful === undefined) {
-        successful = true;
-    }
-
-    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
-        (t == 'checkbox' || t == 'radio') && !el.checked ||
-        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
-        tag == 'select' && el.selectedIndex == -1)) {
-            return null;
-    }
-
-    if (tag == 'select') {
-        var index = el.selectedIndex;
-        if (index < 0) {
-            return null;
-        }
-        var a = [], ops = el.options;
-        var one = (t == 'select-one');
-        var max = (one ? index+1 : ops.length);
-        for(var i=(one ? index : 0); i < max; i++) {
-            var op = ops[i];
-            if (op.selected) {
-                var v = op.value;
-                if (!v) { // extra pain for IE...
-                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
-                }
-                if (one) {
-                    return v;
-                }
-                a.push(v);
-            }
-        }
-        return a;
-    }
-    return $(el).val();
-};
-
-/**
- * Clears the form data.  Takes the following actions on the form's input fields:
- *  - input text fields will have their 'value' property set to the empty string
- *  - select elements will have their 'selectedIndex' property set to -1
- *  - checkbox and radio inputs will have their 'checked' property set to false
- *  - inputs of type submit, button, reset, and hidden will *not* be effected
- *  - button elements will *not* be effected
- */
-$.fn.clearForm = function(includeHidden) {
-    return this.each(function() {
-        $('input,select,textarea', this).clearFields(includeHidden);
-    });
-};
-
-/**
- * Clears the selected form elements.
- */
-$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
-    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
-    return this.each(function() {
-        var t = this.type, tag = this.tagName.toLowerCase();
-        if (re.test(t) || tag == 'textarea') {
-            this.value = '';
-        }
-        else if (t == 'checkbox' || t == 'radio') {
-            this.checked = false;
-        }
-        else if (tag == 'select') {
-            this.selectedIndex = -1;
-        }
-        else if (includeHidden) {
-            // includeHidden can be the value true, or it can be a selector string
-            // indicating a special test; for example:
-            //  $('#myForm').clearForm('.special:hidden')
-            // the above would clean hidden inputs that have the class of 'special'
-            if ( (includeHidden === true && /hidden/.test(t)) ||
-                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
-                this.value = '';
-        }
-    });
-};
-
-/**
- * Resets the form data.  Causes all form elements to be reset to their original value.
- */
-$.fn.resetForm = function() {
-    return this.each(function() {
-        // guard against an input with the name of 'reset'
-        // note that IE reports the reset function as an 'object'
-        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
-            this.reset();
-        }
-    });
-};
-
-/**
- * Enables or disables any matching elements.
- */
-$.fn.enable = function(b) {
-    if (b === undefined) {
-        b = true;
-    }
-    return this.each(function() {
-        this.disabled = !b;
-    });
-};
-
-/**
- * Checks/unchecks any matching checkboxes or radio buttons and
- * selects/deselects and matching option elements.
- */
-$.fn.selected = function(select) {
-    if (select === undefined) {
-        select = true;
-    }
-    return this.each(function() {
-        var t = this.type;
-        if (t == 'checkbox' || t == 'radio') {
-            this.checked = select;
-        }
-        else if (this.tagName.toLowerCase() == 'option') {
-            var $sel = $(this).parent('select');
-            if (select && $sel[0] && $sel[0].type == 'select-one') {
-                // deselect all other options
-                $sel.find('option').selected(false);
-            }
-            this.selected = select;
-        }
-    });
-};
-
-// expose debug var
-$.fn.ajaxSubmit.debug = false;
-
-// helper fn for console logging
-function log() {
-    if (!$.fn.ajaxSubmit.debug) 
-        return;
-    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
-    if (window.console && window.console.log) {
-        window.console.log(msg);
-    }
-    else if (window.opera && window.opera.postError) {
-        window.opera.postError(msg);
-    }
-}
-
-})(jQuery);
diff --git a/resources/lib/jquery.form/jquery.form.js b/resources/lib/jquery.form/jquery.form.js
new file mode 100644 (file)
index 0000000..13e9a55
--- /dev/null
@@ -0,0 +1,1089 @@
+/*!
+ * jQuery Form Plugin
+ * version: 3.14 (30-JUL-2012)
+ * @requires jQuery v1.3.2 or later
+ *
+ * Examples and documentation at: http://malsup.com/jquery/form/
+ * Project repository: https://github.com/malsup/form
+ * Dual licensed under the MIT and GPL licenses:
+ *    http://malsup.github.com/mit-license.txt
+ *    http://malsup.github.com/gpl-license-v2.txt
+ */
+/*global ActiveXObject alert */
+;(function($) {
+"use strict";
+
+/*
+    Usage Note:
+    -----------
+    Do not use both ajaxSubmit and ajaxForm on the same form.  These
+    functions are mutually exclusive.  Use ajaxSubmit if you want
+    to bind your own submit handler to the form.  For example,
+
+    $(document).ready(function() {
+        $('#myForm').on('submit', function(e) {
+            e.preventDefault(); // <-- important
+            $(this).ajaxSubmit({
+                target: '#output'
+            });
+        });
+    });
+
+    Use ajaxForm when you want the plugin to manage all the event binding
+    for you.  For example,
+
+    $(document).ready(function() {
+        $('#myForm').ajaxForm({
+            target: '#output'
+        });
+    });
+    
+    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
+    form does not have to exist when you invoke ajaxForm:
+
+    $('#myForm').ajaxForm({
+        delegation: true,
+        target: '#output'
+    });
+    
+    When using ajaxForm, the ajaxSubmit function will be invoked for you
+    at the appropriate time.
+*/
+
+/**
+ * Feature detection
+ */
+var feature = {};
+feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
+feature.formdata = window.FormData !== undefined;
+
+/**
+ * ajaxSubmit() provides a mechanism for immediately submitting
+ * an HTML form using AJAX.
+ */
+$.fn.ajaxSubmit = function(options) {
+    /*jshint scripturl:true */
+
+    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
+    if (!this.length) {
+        log('ajaxSubmit: skipping submit process - no element selected');
+        return this;
+    }
+    
+    var method, action, url, $form = this;
+
+    if (typeof options == 'function') {
+        options = { success: options };
+    }
+
+    method = this.attr('method');
+    action = this.attr('action');
+    url = (typeof action === 'string') ? $.trim(action) : '';
+    url = url || window.location.href || '';
+    if (url) {
+        // clean url (don't include hash vaue)
+        url = (url.match(/^([^#]+)/)||[])[1];
+    }
+
+    options = $.extend(true, {
+        url:  url,
+        success: $.ajaxSettings.success,
+        type: method || 'GET',
+        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
+    }, options);
+
+    // hook for manipulating the form data before it is extracted;
+    // convenient for use with rich editors like tinyMCE or FCKEditor
+    var veto = {};
+    this.trigger('form-pre-serialize', [this, options, veto]);
+    if (veto.veto) {
+        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
+        return this;
+    }
+
+    // provide opportunity to alter form data before it is serialized
+    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
+        log('ajaxSubmit: submit aborted via beforeSerialize callback');
+        return this;
+    }
+
+    var traditional = options.traditional;
+    if ( traditional === undefined ) {
+        traditional = $.ajaxSettings.traditional;
+    }
+    
+    var elements = [];
+    var qx, a = this.formToArray(options.semantic, elements);
+    if (options.data) {
+        options.extraData = options.data;
+        qx = $.param(options.data, traditional);
+    }
+
+    // give pre-submit callback an opportunity to abort the submit
+    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
+        log('ajaxSubmit: submit aborted via beforeSubmit callback');
+        return this;
+    }
+
+    // fire vetoable 'validate' event
+    this.trigger('form-submit-validate', [a, this, options, veto]);
+    if (veto.veto) {
+        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
+        return this;
+    }
+
+    var q = $.param(a, traditional);
+    if (qx) {
+        q = ( q ? (q + '&' + qx) : qx );
+    }    
+    if (options.type.toUpperCase() == 'GET') {
+        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
+        options.data = null;  // data is null for 'get'
+    }
+    else {
+        options.data = q; // data is the query string for 'post'
+    }
+
+    var callbacks = [];
+    if (options.resetForm) {
+        callbacks.push(function() { $form.resetForm(); });
+    }
+    if (options.clearForm) {
+        callbacks.push(function() { $form.clearForm(options.includeHidden); });
+    }
+
+    // perform a load on the target only if dataType is not provided
+    if (!options.dataType && options.target) {
+        var oldSuccess = options.success || function(){};
+        callbacks.push(function(data) {
+            var fn = options.replaceTarget ? 'replaceWith' : 'html';
+            $(options.target)[fn](data).each(oldSuccess, arguments);
+        });
+    }
+    else if (options.success) {
+        callbacks.push(options.success);
+    }
+
+    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
+        var context = options.context || this ;    // jQuery 1.4+ supports scope context 
+        for (var i=0, max=callbacks.length; i < max; i++) {
+            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
+        }
+    };
+
+    // are there files to upload?
+    var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
+    var hasFileInputs = fileInputs.length > 0;
+    var mp = 'multipart/form-data';
+    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
+
+    var fileAPI = feature.fileapi && feature.formdata;
+    log("fileAPI :" + fileAPI);
+    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
+
+    // options.iframe allows user to force iframe mode
+    // 06-NOV-09: now defaulting to iframe mode if file input is detected
+    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
+        // hack to fix Safari hang (thanks to Tim Molendijk for this)
+        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
+        if (options.closeKeepAlive) {
+            $.get(options.closeKeepAlive, function() {
+                fileUploadIframe(a);
+            });
+        }
+          else {
+            fileUploadIframe(a);
+          }
+    }
+    else if ((hasFileInputs || multipart) && fileAPI) {
+        fileUploadXhr(a);
+    }
+    else {
+        $.ajax(options);
+    }
+
+    // clear element array
+    for (var k=0; k < elements.length; k++)
+        elements[k] = null;
+
+    // fire 'notify' event
+    this.trigger('form-submit-notify', [this, options]);
+    return this;
+
+     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
+    function fileUploadXhr(a) {
+        var formdata = new FormData();
+
+        for (var i=0; i < a.length; i++) {
+            formdata.append(a[i].name, a[i].value);
+        }
+
+        if (options.extraData) {
+            for (var p in options.extraData)
+                if (options.extraData.hasOwnProperty(p))
+                    formdata.append(p, options.extraData[p]);
+        }
+
+        options.data = null;
+
+        var s = $.extend(true, {}, $.ajaxSettings, options, {
+            contentType: false,
+            processData: false,
+            cache: false,
+            type: 'POST'
+        });
+        
+        if (options.uploadProgress) {
+            // workaround because jqXHR does not expose upload property
+            s.xhr = function() {
+                var xhr = jQuery.ajaxSettings.xhr();
+                if (xhr.upload) {
+                    xhr.upload.onprogress = function(event) {
+                        var percent = 0;
+                        var position = event.loaded || event.position; /*event.position is deprecated*/
+                        var total = event.total;
+                        if (event.lengthComputable) {
+                            percent = Math.ceil(position / total * 100);
+                        }
+                        options.uploadProgress(event, position, total, percent);
+                    };
+                }
+                return xhr;
+            };
+        }
+
+        s.data = null;
+            var beforeSend = s.beforeSend;
+            s.beforeSend = function(xhr, o) {
+                o.data = formdata;
+                if(beforeSend)
+                    beforeSend.call(this, xhr, o);
+        };
+        $.ajax(s);
+    }
+
+    // private function for handling file uploads (hat tip to YAHOO!)
+    function fileUploadIframe(a) {
+        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
+        var useProp = !!$.fn.prop;
+
+        if ($(':input[name=submit],:input[id=submit]', form).length) {
+            // if there is an input with a name or id of 'submit' then we won't be
+            // able to invoke the submit fn on the form (at least not x-browser)
+            alert('Error: Form elements must not have name or id of "submit".');
+            return;
+        }
+        
+        if (a) {
+            // ensure that every serialized input is still enabled
+            for (i=0; i < elements.length; i++) {
+                el = $(elements[i]);
+                if ( useProp )
+                    el.prop('disabled', false);
+                else
+                    el.removeAttr('disabled');
+            }
+        }
+
+        s = $.extend(true, {}, $.ajaxSettings, options);
+        s.context = s.context || s;
+        id = 'jqFormIO' + (new Date().getTime());
+        if (s.iframeTarget) {
+            $io = $(s.iframeTarget);
+            n = $io.attr('name');
+            if (!n)
+                 $io.attr('name', id);
+            else
+                id = n;
+        }
+        else {
+            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
+            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
+        }
+        io = $io[0];
+
+
+        xhr = { // mock object
+            aborted: 0,
+            responseText: null,
+            responseXML: null,
+            status: 0,
+            statusText: 'n/a',
+            getAllResponseHeaders: function() {},
+            getResponseHeader: function() {},
+            setRequestHeader: function() {},
+            abort: function(status) {
+                var e = (status === 'timeout' ? 'timeout' : 'aborted');
+                log('aborting upload... ' + e);
+                this.aborted = 1;
+                // #214
+                if (io.contentWindow.document.execCommand) {
+                    try { // #214
+                        io.contentWindow.document.execCommand('Stop');
+                    } catch(ignore) {}
+                }
+                $io.attr('src', s.iframeSrc); // abort op in progress
+                xhr.error = e;
+                if (s.error)
+                    s.error.call(s.context, xhr, e, status);
+                if (g)
+                    $.event.trigger("ajaxError", [xhr, s, e]);
+                if (s.complete)
+                    s.complete.call(s.context, xhr, e);
+            }
+        };
+
+        g = s.global;
+        // trigger ajax global events so that activity/block indicators work like normal
+        if (g && 0 === $.active++) {
+            $.event.trigger("ajaxStart");
+        }
+        if (g) {
+            $.event.trigger("ajaxSend", [xhr, s]);
+        }
+
+        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
+            if (s.global) {
+                $.active--;
+            }
+            return;
+        }
+        if (xhr.aborted) {
+            return;
+        }
+
+        // add submitting element to data if we know it
+        sub = form.clk;
+        if (sub) {
+            n = sub.name;
+            if (n && !sub.disabled) {
+                s.extraData = s.extraData || {};
+                s.extraData[n] = sub.value;
+                if (sub.type == "image") {
+                    s.extraData[n+'.x'] = form.clk_x;
+                    s.extraData[n+'.y'] = form.clk_y;
+                }
+            }
+        }
+        
+        var CLIENT_TIMEOUT_ABORT = 1;
+        var SERVER_ABORT = 2;
+
+        function getDoc(frame) {
+            var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
+            return doc;
+        }
+        
+        // Rails CSRF hack (thanks to Yvan Barthelemy)
+        var csrf_token = $('meta[name=csrf-token]').attr('content');
+        var csrf_param = $('meta[name=csrf-param]').attr('content');
+        if (csrf_param && csrf_token) {
+            s.extraData = s.extraData || {};
+            s.extraData[csrf_param] = csrf_token;
+        }
+
+        // take a breath so that pending repaints get some cpu time before the upload starts
+        function doSubmit() {
+            // make sure form attrs are set
+            var t = $form.attr('target'), a = $form.attr('action');
+
+            // update form attrs in IE friendly way
+            form.setAttribute('target',id);
+            if (!method) {
+                form.setAttribute('method', 'POST');
+            }
+            if (a != s.url) {
+                form.setAttribute('action', s.url);
+            }
+
+            // ie borks in some cases when setting encoding
+            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
+                $form.attr({
+                    encoding: 'multipart/form-data',
+                    enctype:  'multipart/form-data'
+                });
+            }
+
+            // support timout
+            if (s.timeout) {
+                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
+            }
+            
+            // look for server aborts
+            function checkState() {
+                try {
+                    var state = getDoc(io).readyState;
+                    log('state = ' + state);
+                    if (state && state.toLowerCase() == 'uninitialized')
+                        setTimeout(checkState,50);
+                }
+                catch(e) {
+                    log('Server abort: ' , e, ' (', e.name, ')');
+                    cb(SERVER_ABORT);
+                    if (timeoutHandle)
+                        clearTimeout(timeoutHandle);
+                    timeoutHandle = undefined;
+                }
+            }
+
+            // add "extra" data to form if provided in options
+            var extraInputs = [];
+            try {
+                if (s.extraData) {
+                    for (var n in s.extraData) {
+                        if (s.extraData.hasOwnProperty(n)) {
+                           // if using the $.param format that allows for multiple values with the same name
+                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
+                               extraInputs.push(
+                               $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
+                                   .appendTo(form)[0]);
+                           } else {
+                               extraInputs.push(
+                               $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
+                                   .appendTo(form)[0]);
+                           }
+                        }
+                    }
+                }
+
+                if (!s.iframeTarget) {
+                    // add iframe to doc and submit the form
+                    $io.appendTo('body');
+                    if (io.attachEvent)
+                        io.attachEvent('onload', cb);
+                    else
+                        io.addEventListener('load', cb, false);
+                }
+                setTimeout(checkState,15);
+                form.submit();
+            }
+            finally {
+                // reset attrs and remove "extra" input elements
+                form.setAttribute('action',a);
+                if(t) {
+                    form.setAttribute('target', t);
+                } else {
+                    $form.removeAttr('target');
+                }
+                $(extraInputs).remove();
+            }
+        }
+
+        if (s.forceSync) {
+            doSubmit();
+        }
+        else {
+            setTimeout(doSubmit, 10); // this lets dom updates render
+        }
+
+        var data, doc, domCheckCount = 50, callbackProcessed;
+
+        function cb(e) {
+            if (xhr.aborted || callbackProcessed) {
+                return;
+            }
+            try {
+                doc = getDoc(io);
+            }
+            catch(ex) {
+                log('cannot access response document: ', ex);
+                e = SERVER_ABORT;
+            }
+            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
+                xhr.abort('timeout');
+                return;
+            }
+            else if (e == SERVER_ABORT && xhr) {
+                xhr.abort('server abort');
+                return;
+            }
+
+            if (!doc || doc.location.href == s.iframeSrc) {
+                // response not received yet
+                if (!timedOut)
+                    return;
+            }
+            if (io.detachEvent)
+                io.detachEvent('onload', cb);
+            else    
+                io.removeEventListener('load', cb, false);
+
+            var status = 'success', errMsg;
+            try {
+                if (timedOut) {
+                    throw 'timeout';
+                }
+
+                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
+                log('isXml='+isXml);
+                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
+                    if (--domCheckCount) {
+                        // in some browsers (Opera) the iframe DOM is not always traversable when
+                        // the onload callback fires, so we loop a bit to accommodate
+                        log('requeing onLoad callback, DOM not available');
+                        setTimeout(cb, 250);
+                        return;
+                    }
+                    // let this fall through because server response could be an empty document
+                    //log('Could not access iframe DOM after mutiple tries.');
+                    //throw 'DOMException: not available';
+                }
+
+                //log('response detected');
+                var docRoot = doc.body ? doc.body : doc.documentElement;
+                xhr.responseText = docRoot ? docRoot.innerHTML : null;
+                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
+                if (isXml)
+                    s.dataType = 'xml';
+                xhr.getResponseHeader = function(header){
+                    var headers = {'content-type': s.dataType};
+                    return headers[header];
+                };
+                // support for XHR 'status' & 'statusText' emulation :
+                if (docRoot) {
+                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
+                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
+                }
+
+                var dt = (s.dataType || '').toLowerCase();
+                var scr = /(json|script|text)/.test(dt);
+                if (scr || s.textarea) {
+                    // see if user embedded response in textarea
+                    var ta = doc.getElementsByTagName('textarea')[0];
+                    if (ta) {
+                        xhr.responseText = ta.value;
+                        // support for XHR 'status' & 'statusText' emulation :
+                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
+                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
+                    }
+                    else if (scr) {
+                        // account for browsers injecting pre around json response
+                        var pre = doc.getElementsByTagName('pre')[0];
+                        var b = doc.getElementsByTagName('body')[0];
+                        if (pre) {
+                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
+                        }
+                        else if (b) {
+                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
+                        }
+                    }
+                }
+                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
+                    xhr.responseXML = toXml(xhr.responseText);
+                }
+
+                try {
+                    data = httpData(xhr, dt, s);
+                }
+                catch (e) {
+                    status = 'parsererror';
+                    xhr.error = errMsg = (e || status);
+                }
+            }
+            catch (e) {
+                log('error caught: ',e);
+                status = 'error';
+                xhr.error = errMsg = (e || status);
+            }
+
+            if (xhr.aborted) {
+                log('upload aborted');
+                status = null;
+            }
+
+            if (xhr.status) { // we've set xhr.status
+                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
+            }
+
+            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
+            if (status === 'success') {
+                if (s.success)
+                    s.success.call(s.context, data, 'success', xhr);
+                if (g)
+                    $.event.trigger("ajaxSuccess", [xhr, s]);
+            }
+            else if (status) {
+                if (errMsg === undefined)
+                    errMsg = xhr.statusText;
+                if (s.error)
+                    s.error.call(s.context, xhr, status, errMsg);
+                if (g)
+                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
+            }
+
+            if (g)
+                $.event.trigger("ajaxComplete", [xhr, s]);
+
+            if (g && ! --$.active) {
+                $.event.trigger("ajaxStop");
+            }
+
+            if (s.complete)
+                s.complete.call(s.context, xhr, status);
+
+            callbackProcessed = true;
+            if (s.timeout)
+                clearTimeout(timeoutHandle);
+
+            // clean up
+            setTimeout(function() {
+                if (!s.iframeTarget)
+                    $io.remove();
+                xhr.responseXML = null;
+            }, 100);
+        }
+
+        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
+            if (window.ActiveXObject) {
+                doc = new ActiveXObject('Microsoft.XMLDOM');
+                doc.async = 'false';
+                doc.loadXML(s);
+            }
+            else {
+                doc = (new DOMParser()).parseFromString(s, 'text/xml');
+            }
+            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
+        };
+        var parseJSON = $.parseJSON || function(s) {
+            /*jslint evil:true */
+            return window['eval']('(' + s + ')');
+        };
+
+        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
+
+            var ct = xhr.getResponseHeader('content-type') || '',
+                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
+                data = xml ? xhr.responseXML : xhr.responseText;
+
+            if (xml && data.documentElement.nodeName === 'parsererror') {
+                if ($.error)
+                    $.error('parsererror');
+            }
+            if (s && s.dataFilter) {
+                data = s.dataFilter(data, type);
+            }
+            if (typeof data === 'string') {
+                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
+                    data = parseJSON(data);
+                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
+                    $.globalEval(data);
+                }
+            }
+            return data;
+        };
+    }
+};
+
+/**
+ * ajaxForm() provides a mechanism for fully automating form submission.
+ *
+ * The advantages of using this method instead of ajaxSubmit() are:
+ *
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
+ *    is used to submit the form).
+ * 2. This method will include the submit element's name/value data (for the element that was
+ *    used to submit the form).
+ * 3. This method binds the submit() method to the form for you.
+ *
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
+ * passes the options argument along after properly binding events for submit elements and
+ * the form itself.
+ */
+$.fn.ajaxForm = function(options) {
+    options = options || {};
+    options.delegation = options.delegation && $.isFunction($.fn.on);
+    
+    // in jQuery 1.3+ we can fix mistakes with the ready state
+    if (!options.delegation && this.length === 0) {
+        var o = { s: this.selector, c: this.context };
+        if (!$.isReady && o.s) {
+            log('DOM not ready, queuing ajaxForm');
+            $(function() {
+                $(o.s,o.c).ajaxForm(options);
+            });
+            return this;
+        }
+        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
+        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
+        return this;
+    }
+
+    if ( options.delegation ) {
+        $(document)
+            .off('submit.form-plugin', this.selector, doAjaxSubmit)
+            .off('click.form-plugin', this.selector, captureSubmittingElement)
+            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
+            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
+        return this;
+    }
+
+    return this.ajaxFormUnbind()
+        .bind('submit.form-plugin', options, doAjaxSubmit)
+        .bind('click.form-plugin', options, captureSubmittingElement);
+};
+
+// private event handlers    
+function doAjaxSubmit(e) {
+    /*jshint validthis:true */
+    var options = e.data;
+    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
+        e.preventDefault();
+        $(this).ajaxSubmit(options);
+    }
+}
+    
+function captureSubmittingElement(e) {
+    /*jshint validthis:true */
+    var target = e.target;
+    var $el = $(target);
+    if (!($el.is(":submit,input:image"))) {
+        // is this a child element of the submit el?  (ex: a span within a button)
+        var t = $el.closest(':submit');
+        if (t.length === 0) {
+            return;
+        }
+        target = t[0];
+    }
+    var form = this;
+    form.clk = target;
+    if (target.type == 'image') {
+        if (e.offsetX !== undefined) {
+            form.clk_x = e.offsetX;
+            form.clk_y = e.offsetY;
+        } else if (typeof $.fn.offset == 'function') {
+            var offset = $el.offset();
+            form.clk_x = e.pageX - offset.left;
+            form.clk_y = e.pageY - offset.top;
+        } else {
+            form.clk_x = e.pageX - target.offsetLeft;
+            form.clk_y = e.pageY - target.offsetTop;
+        }
+    }
+    // clear form vars
+    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
+}
+
+
+// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
+$.fn.ajaxFormUnbind = function() {
+    return this.unbind('submit.form-plugin click.form-plugin');
+};
+
+/**
+ * formToArray() gathers form element data into an array of objects that can
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
+ * Each object in the array has both a 'name' and 'value' property.  An example of
+ * an array for a simple login form might be:
+ *
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+ *
+ * It is this array that is passed to pre-submit callback functions provided to the
+ * ajaxSubmit() and ajaxForm() methods.
+ */
+$.fn.formToArray = function(semantic, elements) {
+    var a = [];
+    if (this.length === 0) {
+        return a;
+    }
+
+    var form = this[0];
+    var els = semantic ? form.getElementsByTagName('*') : form.elements;
+    if (!els) {
+        return a;
+    }
+
+    var i,j,n,v,el,max,jmax;
+    for(i=0, max=els.length; i < max; i++) {
+        el = els[i];
+        n = el.name;
+        if (!n) {
+            continue;
+        }
+
+        if (semantic && form.clk && el.type == "image") {
+            // handle image inputs on the fly when semantic == true
+            if(!el.disabled && form.clk == el) {
+                a.push({name: n, value: $(el).val(), type: el.type });
+                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+            }
+            continue;
+        }
+
+        v = $.fieldValue(el, true);
+        if (v && v.constructor == Array) {
+            if (elements) 
+                elements.push(el);
+            for(j=0, jmax=v.length; j < jmax; j++) {
+                a.push({name: n, value: v[j]});
+            }
+        }
+        else if (feature.fileapi && el.type == 'file' && !el.disabled) {
+            if (elements) 
+                elements.push(el);
+            var files = el.files;
+            if (files.length) {
+                for (j=0; j < files.length; j++) {
+                    a.push({name: n, value: files[j], type: el.type});
+                }
+            }
+            else {
+                // #180
+                a.push({ name: n, value: '', type: el.type });
+            }
+        }
+        else if (v !== null && typeof v != 'undefined') {
+            if (elements) 
+                elements.push(el);
+            a.push({name: n, value: v, type: el.type, required: el.required});
+        }
+    }
+
+    if (!semantic && form.clk) {
+        // input type=='image' are not found in elements array! handle it here
+        var $input = $(form.clk), input = $input[0];
+        n = input.name;
+        if (n && !input.disabled && input.type == 'image') {
+            a.push({name: n, value: $input.val()});
+            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+        }
+    }
+    return a;
+};
+
+/**
+ * Serializes form data into a 'submittable' string. This method will return a string
+ * in the format: name1=value1&amp;name2=value2
+ */
+$.fn.formSerialize = function(semantic) {
+    //hand off to jQuery.param for proper encoding
+    return $.param(this.formToArray(semantic));
+};
+
+/**
+ * Serializes all field elements in the jQuery object into a query string.
+ * This method will return a string in the format: name1=value1&amp;name2=value2
+ */
+$.fn.fieldSerialize = function(successful) {
+    var a = [];
+    this.each(function() {
+        var n = this.name;
+        if (!n) {
+            return;
+        }
+        var v = $.fieldValue(this, successful);
+        if (v && v.constructor == Array) {
+            for (var i=0,max=v.length; i < max; i++) {
+                a.push({name: n, value: v[i]});
+            }
+        }
+        else if (v !== null && typeof v != 'undefined') {
+            a.push({name: this.name, value: v});
+        }
+    });
+    //hand off to jQuery.param for proper encoding
+    return $.param(a);
+};
+
+/**
+ * Returns the value(s) of the element in the matched set.  For example, consider the following form:
+ *
+ *  <form><fieldset>
+ *      <input name="A" type="text" />
+ *      <input name="A" type="text" />
+ *      <input name="B" type="checkbox" value="B1" />
+ *      <input name="B" type="checkbox" value="B2"/>
+ *      <input name="C" type="radio" value="C1" />
+ *      <input name="C" type="radio" value="C2" />
+ *  </fieldset></form>
+ *
+ *  var v = $(':text').fieldValue();
+ *  // if no values are entered into the text inputs
+ *  v == ['','']
+ *  // if values entered into the text inputs are 'foo' and 'bar'
+ *  v == ['foo','bar']
+ *
+ *  var v = $(':checkbox').fieldValue();
+ *  // if neither checkbox is checked
+ *  v === undefined
+ *  // if both checkboxes are checked
+ *  v == ['B1', 'B2']
+ *
+ *  var v = $(':radio').fieldValue();
+ *  // if neither radio is checked
+ *  v === undefined
+ *  // if first radio is checked
+ *  v == ['C1']
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If this value is false the value(s)
+ * for each element is returned.
+ *
+ * Note: This method *always* returns an array.  If no valid value can be determined the
+ *    array will be empty, otherwise it will contain one or more values.
+ */
+$.fn.fieldValue = function(successful) {
+    for (var val=[], i=0, max=this.length; i < max; i++) {
+        var el = this[i];
+        var v = $.fieldValue(el, successful);
+        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
+            continue;
+        }
+        if (v.constructor == Array)
+            $.merge(val, v);
+        else
+            val.push(v);
+    }
+    return val;
+};
+
+/**
+ * Returns the value of the field element.
+ */
+$.fieldValue = function(el, successful) {
+    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
+    if (successful === undefined) {
+        successful = true;
+    }
+
+    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
+        (t == 'checkbox' || t == 'radio') && !el.checked ||
+        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
+        tag == 'select' && el.selectedIndex == -1)) {
+            return null;
+    }
+
+    if (tag == 'select') {
+        var index = el.selectedIndex;
+        if (index < 0) {
+            return null;
+        }
+        var a = [], ops = el.options;
+        var one = (t == 'select-one');
+        var max = (one ? index+1 : ops.length);
+        for(var i=(one ? index : 0); i < max; i++) {
+            var op = ops[i];
+            if (op.selected) {
+                var v = op.value;
+                if (!v) { // extra pain for IE...
+                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
+                }
+                if (one) {
+                    return v;
+                }
+                a.push(v);
+            }
+        }
+        return a;
+    }
+    return $(el).val();
+};
+
+/**
+ * Clears the form data.  Takes the following actions on the form's input fields:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ */
+$.fn.clearForm = function(includeHidden) {
+    return this.each(function() {
+        $('input,select,textarea', this).clearFields(includeHidden);
+    });
+};
+
+/**
+ * Clears the selected form elements.
+ */
+$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
+    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
+    return this.each(function() {
+        var t = this.type, tag = this.tagName.toLowerCase();
+        if (re.test(t) || tag == 'textarea') {
+            this.value = '';
+        }
+        else if (t == 'checkbox' || t == 'radio') {
+            this.checked = false;
+        }
+        else if (tag == 'select') {
+            this.selectedIndex = -1;
+        }
+        else if (includeHidden) {
+            // includeHidden can be the value true, or it can be a selector string
+            // indicating a special test; for example:
+            //  $('#myForm').clearForm('.special:hidden')
+            // the above would clean hidden inputs that have the class of 'special'
+            if ( (includeHidden === true && /hidden/.test(t)) ||
+                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
+                this.value = '';
+        }
+    });
+};
+
+/**
+ * Resets the form data.  Causes all form elements to be reset to their original value.
+ */
+$.fn.resetForm = function() {
+    return this.each(function() {
+        // guard against an input with the name of 'reset'
+        // note that IE reports the reset function as an 'object'
+        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
+            this.reset();
+        }
+    });
+};
+
+/**
+ * Enables or disables any matching elements.
+ */
+$.fn.enable = function(b) {
+    if (b === undefined) {
+        b = true;
+    }
+    return this.each(function() {
+        this.disabled = !b;
+    });
+};
+
+/**
+ * Checks/unchecks any matching checkboxes or radio buttons and
+ * selects/deselects and matching option elements.
+ */
+$.fn.selected = function(select) {
+    if (select === undefined) {
+        select = true;
+    }
+    return this.each(function() {
+        var t = this.type;
+        if (t == 'checkbox' || t == 'radio') {
+            this.checked = select;
+        }
+        else if (this.tagName.toLowerCase() == 'option') {
+            var $sel = $(this).parent('select');
+            if (select && $sel[0] && $sel[0].type == 'select-one') {
+                // deselect all other options
+                $sel.find('option').selected(false);
+            }
+            this.selected = select;
+        }
+    });
+};
+
+// expose debug var
+$.fn.ajaxSubmit.debug = false;
+
+// helper fn for console logging
+function log() {
+    if (!$.fn.ajaxSubmit.debug) 
+        return;
+    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
+    if (window.console && window.console.log) {
+        window.console.log(msg);
+    }
+    else if (window.opera && window.opera.postError) {
+        window.opera.postError(msg);
+    }
+}
+
+})(jQuery);
diff --git a/resources/lib/jquery.fullscreen.js b/resources/lib/jquery.fullscreen.js
deleted file mode 100644 (file)
index 30e4484..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * jQuery fullscreen plugin v2.0.0-git (9f8f97d127)
- * https://github.com/theopolisme/jquery-fullscreen
- *
- * Copyright (c) 2013 Theopolisme <theopolismewiki@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-( function ( $ ) {
-       var setupFullscreen,
-               fsClass = 'jq-fullscreened';
-
-       /**
-        * On fullscreenchange, trigger a jq-fullscreen-change event
-        * The event is given an object, which contains the fullscreened DOM element (element), if any
-        * and a boolean value (fullscreen) indicating if we've entered or exited fullscreen mode
-        * Also remove the 'fullscreened' class from elements that are no longer fullscreen
-        */
-       function handleFullscreenChange () {
-               var fullscreenElement = document.fullscreenElement ||
-                       document.mozFullScreenElement ||
-                       document.webkitFullscreenElement ||
-                       document.msFullscreenElement;
-
-               if ( !fullscreenElement ) {
-                       $( '.' + fsClass ).data( 'isFullscreened', false ).removeClass( fsClass );
-               }
-
-               $( document ).trigger( $.Event( 'jq-fullscreen-change', { element: fullscreenElement, fullscreen: !!fullscreenElement } ) );
-       }
-
-       /**
-        * Enters full screen with the "this" element in focus.
-        * Check the .data( 'isFullscreened' ) of the return value to check
-        * success or failure, if you're into that sort of thing.
-        * @chainable
-        * @return {jQuery}
-        */
-       function enterFullscreen () {
-               var element = this.get(0),
-                       $element = this.first();
-               if ( element ) {
-                       if ( element.requestFullscreen ) {
-                               element.requestFullscreen();
-                       } else if ( element.mozRequestFullScreen ) {
-                               element.mozRequestFullScreen();
-                       } else if ( element.webkitRequestFullscreen ) {
-                               element.webkitRequestFullscreen();
-                       } else if ( element.msRequestFullscreen ) {
-                               element.msRequestFullscreen();
-                       } else {
-                               // Unable to make fullscreen
-                               $element.data( 'isFullscreened', false );
-                               return this;
-                       }
-                       // Add the fullscreen class and data attribute to `element`
-                       $element.addClass( fsClass ).data( 'isFullscreened', true );
-                       return this;
-               } else {
-                       $element.data( 'isFullscreened', false );
-                       return this;
-               }
-       }
-
-       /**
-        * Brings the "this" element out of fullscreen.
-        * Check the .data( 'isFullscreened' ) of the return value to check
-        * success or failure, if you're into that sort of thing.
-        * @chainable
-        * @return {jQuery}
-        */
-       function exitFullscreen () {
-               var fullscreenElement = ( document.fullscreenElement ||
-                               document.mozFullScreenElement ||
-                               document.webkitFullscreenElement ||
-                               document.msFullscreenElement );
-
-               // Ensure that we only exit fullscreen if exitFullscreen() is being called on the same element that is currently fullscreen
-               if ( fullscreenElement && this.get(0) === fullscreenElement ) {
-                       if ( document.exitFullscreen ) {
-                               document.exitFullscreen();
-                       } else if ( document.mozCancelFullScreen ) {
-                               document.mozCancelFullScreen();
-                       } else if ( document.webkitCancelFullScreen ) {
-                               document.webkitCancelFullScreen();
-                       } else if ( document.msExitFullscreen ) {
-                               document.msExitFullscreen();
-                       } else {
-                               // Unable to cancel fullscreen mode
-                               return this;
-                       }
-                       // We don't need to remove the fullscreen class here,
-                       // because it will be removed in handleFullscreenChange.
-                       // But we should change the data on the element so the
-                       // caller can check for success.
-                       this.first().data( 'isFullscreened', false );
-               }
-
-               return this;
-       }
-
-       /**
-        * Set up fullscreen handling and install necessary event handlers.
-        * Return false if fullscreen is not supported.
-        */
-       setupFullscreen = function () {
-               if ( $.support.fullscreen ) {
-                       // When the fullscreen mode is changed, trigger the
-                       // fullscreen events (and when exiting,
-                       // also remove the fullscreen class)
-                       $( document ).on( 'fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange', handleFullscreenChange);
-                       // Convenience wrapper so that one only needs to listen for
-                       // 'fullscreenerror', not all of the prefixed versions
-                       $( document ).on( 'webkitfullscreenerror mozfullscreenerror MSFullscreenError', function () {
-                               $( document ).trigger( $.Event( 'fullscreenerror' ) );
-                       } );
-                       // Fullscreen has been set up, so always return true
-                       setupFullscreen = function () { return true; };
-                       return true;
-               } else {
-                       // Always return false from now on, since fullscreen is not supported
-                       setupFullscreen = function () { return false; };
-                       return false;
-               }
-       };
-
-       /**
-        * Set up fullscreen handling if necessary, then make the first element
-        * matching the given selector fullscreen
-        * @chainable
-        * @return {jQuery}
-        */
-       $.fn.enterFullscreen = function () {
-               if ( setupFullscreen() ) {
-                       $.fn.enterFullscreen = enterFullscreen;
-                       return this.enterFullscreen();
-               } else {
-                       $.fn.enterFullscreen = function () { return this; };
-                       return this;
-               }
-       };
-
-       /**
-        * Set up fullscreen handling if necessary, then cancel fullscreen mode
-        * for the first element matching the given selector.
-        * @chainable
-        * @return {jQuery}
-        */
-       $.fn.exitFullscreen = function () {
-               if ( setupFullscreen() ) {
-                       $.fn.exitFullscreen = exitFullscreen;
-                       return this.exitFullscreen();
-               } else {
-                       $.fn.exitFullscreen = function () { return this; };
-                       return this;
-               }
-       };
-
-       $.support.fullscreen = document.fullscreenEnabled ||
-               document.webkitFullscreenEnabled ||
-               document.mozFullScreenEnabled ||
-               document.msFullscreenEnabled;
-}( jQuery ) );
diff --git a/resources/lib/jquery.fullscreen/jquery.fullscreen.js b/resources/lib/jquery.fullscreen/jquery.fullscreen.js
new file mode 100644 (file)
index 0000000..2702cee
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * jQuery fullscreen plugin
+ * https://github.com/theopolisme/jquery-fullscreen
+ *
+ * Copyright (c) 2013 Theopolisme <theopolismewiki@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+( function ( $ ) {
+       var setupFullscreen,
+               fsClass = 'jq-fullscreened';
+
+       /**
+        * On fullscreenchange, trigger a jq-fullscreen-change event
+        * The event is given an object, which contains the fullscreened DOM element (element), if any
+        * and a boolean value (fullscreen) indicating if we've entered or exited fullscreen mode
+        * Also remove the 'fullscreened' class from elements that are no longer fullscreen
+        */
+       function handleFullscreenChange () {
+               var fullscreenElement = document.fullscreenElement ||
+                       document.mozFullScreenElement ||
+                       document.webkitFullscreenElement ||
+                       document.msFullscreenElement;
+
+               if ( !fullscreenElement ) {
+                       $( '.' + fsClass ).data( 'isFullscreened', false ).removeClass( fsClass );
+               }
+
+               $( document ).trigger( $.Event( 'jq-fullscreen-change', { element: fullscreenElement, fullscreen: !!fullscreenElement } ) );
+       }
+
+       /**
+        * Enters full screen with the "this" element in focus.
+        * Check the .data( 'isFullscreened' ) of the return value to check
+        * success or failure, if you're into that sort of thing.
+        * @chainable
+        * @return {jQuery}
+        */
+       function enterFullscreen () {
+               var element = this.get(0),
+                       $element = this.first();
+               if ( element ) {
+                       if ( element.requestFullscreen ) {
+                               element.requestFullscreen();
+                       } else if ( element.mozRequestFullScreen ) {
+                               element.mozRequestFullScreen();
+                       } else if ( element.webkitRequestFullscreen ) {
+                               element.webkitRequestFullscreen();
+                       } else if ( element.msRequestFullscreen ) {
+                               element.msRequestFullscreen();
+                       } else {
+                               // Unable to make fullscreen
+                               $element.data( 'isFullscreened', false );
+                               return this;
+                       }
+                       // Add the fullscreen class and data attribute to `element`
+                       $element.addClass( fsClass ).data( 'isFullscreened', true );
+                       return this;
+               } else {
+                       $element.data( 'isFullscreened', false );
+                       return this;
+               }
+       }
+
+       /**
+        * Brings the "this" element out of fullscreen.
+        * Check the .data( 'isFullscreened' ) of the return value to check
+        * success or failure, if you're into that sort of thing.
+        * @chainable
+        * @return {jQuery}
+        */
+       function exitFullscreen () {
+               var fullscreenElement = ( document.fullscreenElement ||
+                               document.mozFullScreenElement ||
+                               document.webkitFullscreenElement ||
+                               document.msFullscreenElement );
+
+               // Ensure that we only exit fullscreen if exitFullscreen() is being called on the same element that is currently fullscreen
+               if ( fullscreenElement && this.get(0) === fullscreenElement ) {
+                       if ( document.exitFullscreen ) {
+                               document.exitFullscreen();
+                       } else if ( document.mozCancelFullScreen ) {
+                               document.mozCancelFullScreen();
+                       } else if ( document.webkitCancelFullScreen ) {
+                               document.webkitCancelFullScreen();
+                       } else if ( document.msExitFullscreen ) {
+                               document.msExitFullscreen();
+                       } else {
+                               // Unable to cancel fullscreen mode
+                               return this;
+                       }
+                       // We don't need to remove the fullscreen class here,
+                       // because it will be removed in handleFullscreenChange.
+                       // But we should change the data on the element so the
+                       // caller can check for success.
+                       this.first().data( 'isFullscreened', false );
+               }
+
+               return this;
+       }
+
+       /**
+        * Set up fullscreen handling and install necessary event handlers.
+        * Return false if fullscreen is not supported.
+        */
+       setupFullscreen = function () {
+               if ( $.support.fullscreen ) {
+                       // When the fullscreen mode is changed, trigger the
+                       // fullscreen events (and when exiting,
+                       // also remove the fullscreen class)
+                       $( document ).on( 'fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange', handleFullscreenChange);
+                       // Convenience wrapper so that one only needs to listen for
+                       // 'fullscreenerror', not all of the prefixed versions
+                       $( document ).on( 'webkitfullscreenerror mozfullscreenerror MSFullscreenError', function () {
+                               $( document ).trigger( $.Event( 'fullscreenerror' ) );
+                       } );
+                       // Fullscreen has been set up, so always return true
+                       setupFullscreen = function () { return true; };
+                       return true;
+               } else {
+                       // Always return false from now on, since fullscreen is not supported
+                       setupFullscreen = function () { return false; };
+                       return false;
+               }
+       };
+
+       /**
+        * Set up fullscreen handling if necessary, then make the first element
+        * matching the given selector fullscreen
+        * @chainable
+        * @return {jQuery}
+        */
+       $.fn.enterFullscreen = function () {
+               if ( setupFullscreen() ) {
+                       $.fn.enterFullscreen = enterFullscreen;
+                       return this.enterFullscreen();
+               } else {
+                       $.fn.enterFullscreen = function () { return this; };
+                       return this;
+               }
+       };
+
+       /**
+        * Set up fullscreen handling if necessary, then cancel fullscreen mode
+        * for the first element matching the given selector.
+        * @chainable
+        * @return {jQuery}
+        */
+       $.fn.exitFullscreen = function () {
+               if ( setupFullscreen() ) {
+                       $.fn.exitFullscreen = exitFullscreen;
+                       return this.exitFullscreen();
+               } else {
+                       $.fn.exitFullscreen = function () { return this; };
+                       return this;
+               }
+       };
+
+       $.support.fullscreen = document.fullscreenEnabled ||
+               document.webkitFullscreenEnabled ||
+               document.mozFullScreenEnabled ||
+               document.msFullscreenEnabled;
+}( jQuery ) );
diff --git a/resources/lib/jquery.hoverIntent.js b/resources/lib/jquery.hoverIntent.js
deleted file mode 100644 (file)
index adf948d..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
-* hoverIntent is similar to jQuery's built-in "hover" function except that
-* instead of firing the onMouseOver event immediately, hoverIntent checks
-* to see if the user's mouse has slowed down (beneath the sensitivity
-* threshold) before firing the onMouseOver event.
-* 
-* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
-* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
-* 
-* hoverIntent is currently available for use in all personal or commercial 
-* projects under both MIT and GPL licenses. This means that you can choose 
-* the license that best suits your project, and use it accordingly.
-* 
-* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
-* $("ul li").hoverIntent( showNav , hideNav );
-* 
-* // advanced usage receives configuration object only
-* $("ul li").hoverIntent({
-*      sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
-*      interval: 100,   // number = milliseconds of polling interval
-*      over: showNav,  // function = onMouseOver callback (required)
-*      timeout: 0,   // number = milliseconds delay before onMouseOut function call
-*      out: hideNav    // function = onMouseOut callback (required)
-* });
-* 
-* @param  f  onMouseOver function || An object with configuration options
-* @param  g  onMouseOut function  || Nothing (use configuration options object)
-* @author    Brian Cherne <brian@cherne.net>
-*/
-(function($) {
-       $.fn.hoverIntent = function(f,g) {
-               // default configuration options
-               var cfg = {
-                       sensitivity: 7,
-                       interval: 100,
-                       timeout: 0
-               };
-               // override configuration options with user supplied object
-               cfg = $.extend(cfg, g ? { over: f, out: g } : f );
-
-               // instantiate variables
-               // cX, cY = current X and Y position of mouse, updated by mousemove event
-               // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
-               var cX, cY, pX, pY;
-
-               // A private function for getting mouse position
-               var track = function(ev) {
-                       cX = ev.pageX;
-                       cY = ev.pageY;
-               };
-
-               // A private function for comparing current and previous mouse position
-               var compare = function(ev,ob) {
-                       ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
-                       // compare mouse positions to see if they've crossed the threshold
-                       if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
-                               $(ob).unbind("mousemove",track);
-                               // set hoverIntent state to true (so mouseOut can be called)
-                               ob.hoverIntent_s = 1;
-                               return cfg.over.apply(ob,[ev]);
-                       } else {
-                               // set previous coordinates for next time
-                               pX = cX; pY = cY;
-                               // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
-                               ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
-                       }
-               };
-
-               // A private function for delaying the mouseOut function
-               var delay = function(ev,ob) {
-                       ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
-                       ob.hoverIntent_s = 0;
-                       return cfg.out.apply(ob,[ev]);
-               };
-
-               // A private function for handling mouse 'hovering'
-               var handleHover = function(e) {
-                       // next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
-                       var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
-                       while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
-                       if ( p == this ) { return false; }
-
-                       // copy objects to be passed into t (required for event object to be passed in IE)
-                       var ev = $.extend({},e);
-                       var ob = this;
-
-                       // cancel hoverIntent timer if it exists
-                       if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
-
-                       // else e.type == "onmouseover"
-                       if (e.type == "mouseover") {
-                               // set "previous" X and Y position based on initial entry point
-                               pX = ev.pageX; pY = ev.pageY;
-                               // update "current" X and Y position based on mousemove
-                               $(ob).bind("mousemove",track);
-                               // start polling interval (self-calling timeout) to compare mouse coordinates over time
-                               if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
-
-                       // else e.type == "onmouseout"
-                       } else {
-                               // unbind expensive mousemove event
-                               $(ob).unbind("mousemove",track);
-                               // if hoverIntent state is true, then call the mouseOut function after the specified delay
-                               if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
-                       }
-               };
-
-               // bind the function to the two event listeners
-               return this.mouseover(handleHover).mouseout(handleHover);
-       };
-})(jQuery);
\ No newline at end of file
diff --git a/resources/lib/jquery.hoverIntent/jquery.hoverIntent.js b/resources/lib/jquery.hoverIntent/jquery.hoverIntent.js
new file mode 100644 (file)
index 0000000..bd11442
--- /dev/null
@@ -0,0 +1,111 @@
+/**
+* hoverIntent is similar to jQuery's built-in "hover" function except that
+* instead of firing the onMouseOver event immediately, hoverIntent checks
+* to see if the user's mouse has slowed down (beneath the sensitivity
+* threshold) before firing the onMouseOver event.
+* 
+* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
+* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
+* 
+* hoverIntent is currently available for use in all personal or commercial 
+* projects under both MIT and GPL licenses. This means that you can choose 
+* the license that best suits your project, and use it accordingly.
+* 
+* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
+* $("ul li").hoverIntent( showNav , hideNav );
+* 
+* // advanced usage receives configuration object only
+* $("ul li").hoverIntent({
+*      sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
+*      interval: 100,   // number = milliseconds of polling interval
+*      over: showNav,  // function = onMouseOver callback (required)
+*      timeout: 0,   // number = milliseconds delay before onMouseOut function call
+*      out: hideNav    // function = onMouseOut callback (required)
+* });
+* 
+* @param  f  onMouseOver function || An object with configuration options
+* @param  g  onMouseOut function  || Nothing (use configuration options object)
+* @author    Brian Cherne <brian@cherne.net>
+*/
+(function($) {
+       $.fn.hoverIntent = function(f,g) {
+               // default configuration options
+               var cfg = {
+                       sensitivity: 7,
+                       interval: 100,
+                       timeout: 0
+               };
+               // override configuration options with user supplied object
+               cfg = $.extend(cfg, g ? { over: f, out: g } : f );
+
+               // instantiate variables
+               // cX, cY = current X and Y position of mouse, updated by mousemove event
+               // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
+               var cX, cY, pX, pY;
+
+               // A private function for getting mouse position
+               var track = function(ev) {
+                       cX = ev.pageX;
+                       cY = ev.pageY;
+               };
+
+               // A private function for comparing current and previous mouse position
+               var compare = function(ev,ob) {
+                       ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+                       // compare mouse positions to see if they've crossed the threshold
+                       if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
+                               $(ob).unbind("mousemove",track);
+                               // set hoverIntent state to true (so mouseOut can be called)
+                               ob.hoverIntent_s = 1;
+                               return cfg.over.apply(ob,[ev]);
+                       } else {
+                               // set previous coordinates for next time
+                               pX = cX; pY = cY;
+                               // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
+                               ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
+                       }
+               };
+
+               // A private function for delaying the mouseOut function
+               var delay = function(ev,ob) {
+                       ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+                       ob.hoverIntent_s = 0;
+                       return cfg.out.apply(ob,[ev]);
+               };
+
+               // A private function for handling mouse 'hovering'
+               var handleHover = function(e) {
+                       // next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
+                       var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
+                       while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
+                       if ( p == this ) { return false; }
+
+                       // copy objects to be passed into t (required for event object to be passed in IE)
+                       var ev = jQuery.extend({},e);
+                       var ob = this;
+
+                       // cancel hoverIntent timer if it exists
+                       if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
+
+                       // else e.type == "onmouseover"
+                       if (e.type == "mouseover") {
+                               // set "previous" X and Y position based on initial entry point
+                               pX = ev.pageX; pY = ev.pageY;
+                               // update "current" X and Y position based on mousemove
+                               $(ob).bind("mousemove",track);
+                               // start polling interval (self-calling timeout) to compare mouse coordinates over time
+                               if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
+
+                       // else e.type == "onmouseout"
+                       } else {
+                               // unbind expensive mousemove event
+                               $(ob).unbind("mousemove",track);
+                               // if hoverIntent state is true, then call the mouseOut function after the specified delay
+                               if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
+                       }
+               };
+
+               // bind the function to the two event listeners
+               return this.mouseover(handleHover).mouseout(handleHover);
+       };
+})(jQuery);
\ No newline at end of file
diff --git a/resources/lib/jquery.jStorage.js b/resources/lib/jquery.jStorage.js
deleted file mode 100644 (file)
index 45e19ac..0000000
+++ /dev/null
@@ -1,996 +0,0 @@
-/*
- * ----------------------------- JSTORAGE -------------------------------------
- * Simple local storage wrapper to save data on the browser side, supporting
- * all major browsers - IE6+, Firefox2+, Safari4+, Chrome4+ and Opera 10.5+
- *
- * Author: Andris Reinman, andris.reinman@gmail.com
- * Project homepage: www.jstorage.info
- *
- * Licensed under Unlicense:
- *
- * This is free and unencumbered software released into the public domain.
- *
- * Anyone is free to copy, modify, publish, use, compile, sell, or
- * distribute this software, either in source code form or as a compiled
- * binary, for any purpose, commercial or non-commercial, and by any
- * means.
- *
- * In jurisdictions that recognize copyright laws, the author or authors
- * of this software dedicate any and all copyright interest in the
- * software to the public domain. We make this dedication for the benefit
- * of the public at large and to the detriment of our heirs and
- * successors. We intend this dedication to be an overt act of
- * relinquishment in perpetuity of all present and future rights to this
- * software under copyright law.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * For more information, please refer to <http://unlicense.org/>
- */
-
-/* global ActiveXObject: false */
-/* jshint browser: true */
-
-(function() {
-    'use strict';
-
-    var
-    /* jStorage version */
-        JSTORAGE_VERSION = '0.4.12',
-
-        /* detect a dollar object or create one if not found */
-        $ = window.jQuery || window.$ || (window.$ = {}),
-
-        /* check for a JSON handling support */
-        JSON = {
-            parse: window.JSON && (window.JSON.parse || window.JSON.decode) ||
-                String.prototype.evalJSON && function(str) {
-                    return String(str).evalJSON();
-            } ||
-                $.parseJSON ||
-                $.evalJSON,
-            stringify: Object.toJSON ||
-                window.JSON && (window.JSON.stringify || window.JSON.encode) ||
-                $.toJSON
-        };
-
-    // Break if no JSON support was found
-    if (typeof JSON.parse !== 'function' || typeof JSON.stringify !== 'function') {
-        throw new Error('No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page');
-    }
-
-    var
-    /* This is the object, that holds the cached values */
-        _storage = {
-            __jstorage_meta: {
-                CRC32: {}
-            }
-        },
-
-        /* Actual browser storage (localStorage or globalStorage['domain']) */
-        _storage_service = {
-            jStorage: '{}'
-        },
-
-        /* DOM element for older IE versions, holds userData behavior */
-        _storage_elm = null,
-
-        /* How much space does the storage take */
-        _storage_size = 0,
-
-        /* which backend is currently used */
-        _backend = false,
-
-        /* onchange observers */
-        _observers = {},
-
-        /* timeout to wait after onchange event */
-        _observer_timeout = false,
-
-        /* last update time */
-        _observer_update = 0,
-
-        /* pubsub observers */
-        _pubsub_observers = {},
-
-        /* skip published items older than current timestamp */
-        _pubsub_last = +new Date(),
-
-        /* Next check for TTL */
-        _ttl_timeout,
-
-        /**
-         * XML encoding and decoding as XML nodes can't be JSON'ized
-         * XML nodes are encoded and decoded if the node is the value to be saved
-         * but not if it's as a property of another object
-         * Eg. -
-         *   $.jStorage.set('key', xmlNode);        // IS OK
-         *   $.jStorage.set('key', {xml: xmlNode}); // NOT OK
-         */
-        _XMLService = {
-
-            /**
-             * Validates a XML node to be XML
-             * based on jQuery.isXML function
-             */
-            isXML: function(elm) {
-                var documentElement = (elm ? elm.ownerDocument || elm : 0).documentElement;
-                return documentElement ? documentElement.nodeName !== 'HTML' : false;
-            },
-
-            /**
-             * Encodes a XML node to string
-             * based on http://www.mercurytide.co.uk/news/article/issues-when-working-ajax/
-             */
-            encode: function(xmlNode) {
-                if (!this.isXML(xmlNode)) {
-                    return false;
-                }
-                try { // Mozilla, Webkit, Opera
-                    return new XMLSerializer().serializeToString(xmlNode);
-                } catch (E1) {
-                    try { // IE
-                        return xmlNode.xml;
-                    } catch (E2) {}
-                }
-                return false;
-            },
-
-            /**
-             * Decodes a XML node from string
-             * loosely based on http://outwestmedia.com/jquery-plugins/xmldom/
-             */
-            decode: function(xmlString) {
-                var dom_parser = ('DOMParser' in window && (new DOMParser()).parseFromString) ||
-                    (window.ActiveXObject && function(_xmlString) {
-                        var xml_doc = new ActiveXObject('Microsoft.XMLDOM');
-                        xml_doc.async = 'false';
-                        xml_doc.loadXML(_xmlString);
-                        return xml_doc;
-                    }),
-                    resultXML;
-                if (!dom_parser) {
-                    return false;
-                }
-                resultXML = dom_parser.call('DOMParser' in window && (new DOMParser()) || window, xmlString, 'text/xml');
-                return this.isXML(resultXML) ? resultXML : false;
-            }
-        };
-
-
-    ////////////////////////// PRIVATE METHODS ////////////////////////
-
-    /**
-     * Initialization function. Detects if the browser supports DOM Storage
-     * or userData behavior and behaves accordingly.
-     */
-    function _init() {
-        /* Check if browser supports localStorage */
-        var localStorageReallyWorks = false;
-        if ('localStorage' in window) {
-            try {
-                window.localStorage.setItem('_tmptest', 'tmpval');
-                localStorageReallyWorks = true;
-                window.localStorage.removeItem('_tmptest');
-            } catch (BogusQuotaExceededErrorOnIos5) {
-                // Thanks be to iOS5 Private Browsing mode which throws
-                // QUOTA_EXCEEDED_ERRROR DOM Exception 22.
-            }
-        }
-
-        if (localStorageReallyWorks) {
-            try {
-                if (window.localStorage) {
-                    _storage_service = window.localStorage;
-                    _backend = 'localStorage';
-                    _observer_update = _storage_service.jStorage_update;
-                }
-            } catch (E3) { /* Firefox fails when touching localStorage and cookies are disabled */ }
-        }
-        /* Check if browser supports globalStorage */
-        else if ('globalStorage' in window) {
-            try {
-                if (window.globalStorage) {
-                    if (window.location.hostname == 'localhost') {
-                        _storage_service = window.globalStorage['localhost.localdomain'];
-                    } else {
-                        _storage_service = window.globalStorage[window.location.hostname];
-                    }
-                    _backend = 'globalStorage';
-                    _observer_update = _storage_service.jStorage_update;
-                }
-            } catch (E4) { /* Firefox fails when touching localStorage and cookies are disabled */ }
-        }
-        /* Check if browser supports userData behavior */
-        else {
-            _storage_elm = document.createElement('link');
-            if (_storage_elm.addBehavior) {
-
-                /* Use a DOM element to act as userData storage */
-                _storage_elm.style.behavior = 'url(#default#userData)';
-
-                /* userData element needs to be inserted into the DOM! */
-                document.getElementsByTagName('head')[0].appendChild(_storage_elm);
-
-                try {
-                    _storage_elm.load('jStorage');
-                } catch (E) {
-                    // try to reset cache
-                    _storage_elm.setAttribute('jStorage', '{}');
-                    _storage_elm.save('jStorage');
-                    _storage_elm.load('jStorage');
-                }
-
-                var data = '{}';
-                try {
-                    data = _storage_elm.getAttribute('jStorage');
-                } catch (E5) {}
-
-                try {
-                    _observer_update = _storage_elm.getAttribute('jStorage_update');
-                } catch (E6) {}
-
-                _storage_service.jStorage = data;
-                _backend = 'userDataBehavior';
-            } else {
-                _storage_elm = null;
-                return;
-            }
-        }
-
-        // Load data from storage
-        _load_storage();
-
-        // remove dead keys
-        _handleTTL();
-
-        // start listening for changes
-        _setupObserver();
-
-        // initialize publish-subscribe service
-        _handlePubSub();
-
-        // handle cached navigation
-        if ('addEventListener' in window) {
-            window.addEventListener('pageshow', function(event) {
-                if (event.persisted) {
-                    _storageObserver();
-                }
-            }, false);
-        }
-    }
-
-    /**
-     * Reload data from storage when needed
-     */
-    function _reloadData() {
-        var data = '{}';
-
-        if (_backend == 'userDataBehavior') {
-            _storage_elm.load('jStorage');
-
-            try {
-                data = _storage_elm.getAttribute('jStorage');
-            } catch (E5) {}
-
-            try {
-                _observer_update = _storage_elm.getAttribute('jStorage_update');
-            } catch (E6) {}
-
-            _storage_service.jStorage = data;
-        }
-
-        _load_storage();
-
-        // remove dead keys
-        _handleTTL();
-
-        _handlePubSub();
-    }
-
-    /**
-     * Sets up a storage change observer
-     */
-    function _setupObserver() {
-        if (_backend == 'localStorage' || _backend == 'globalStorage') {
-            if ('addEventListener' in window) {
-                window.addEventListener('storage', _storageObserver, false);
-            } else {
-                document.attachEvent('onstorage', _storageObserver);
-            }
-        } else if (_backend == 'userDataBehavior') {
-            setInterval(_storageObserver, 1000);
-        }
-    }
-
-    /**
-     * Fired on any kind of data change, needs to check if anything has
-     * really been changed
-     */
-    function _storageObserver() {
-        var updateTime;
-        // cumulate change notifications with timeout
-        clearTimeout(_observer_timeout);
-        _observer_timeout = setTimeout(function() {
-
-            if (_backend == 'localStorage' || _backend == 'globalStorage') {
-                updateTime = _storage_service.jStorage_update;
-            } else if (_backend == 'userDataBehavior') {
-                _storage_elm.load('jStorage');
-                try {
-                    updateTime = _storage_elm.getAttribute('jStorage_update');
-                } catch (E5) {}
-            }
-
-            if (updateTime && updateTime != _observer_update) {
-                _observer_update = updateTime;
-                _checkUpdatedKeys();
-            }
-
-        }, 25);
-    }
-
-    /**
-     * Reloads the data and checks if any keys are changed
-     */
-    function _checkUpdatedKeys() {
-        var oldCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32)),
-            newCrc32List;
-
-        _reloadData();
-        newCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32));
-
-        var key,
-            updated = [],
-            removed = [];
-
-        for (key in oldCrc32List) {
-            if (oldCrc32List.hasOwnProperty(key)) {
-                if (!newCrc32List[key]) {
-                    removed.push(key);
-                    continue;
-                }
-                if (oldCrc32List[key] != newCrc32List[key] && String(oldCrc32List[key]).substr(0, 2) == '2.') {
-                    updated.push(key);
-                }
-            }
-        }
-
-        for (key in newCrc32List) {
-            if (newCrc32List.hasOwnProperty(key)) {
-                if (!oldCrc32List[key]) {
-                    updated.push(key);
-                }
-            }
-        }
-
-        _fireObservers(updated, 'updated');
-        _fireObservers(removed, 'deleted');
-    }
-
-    /**
-     * Fires observers for updated keys
-     *
-     * @param {Array|String} keys Array of key names or a key
-     * @param {String} action What happened with the value (updated, deleted, flushed)
-     */
-    function _fireObservers(keys, action) {
-        keys = [].concat(keys || []);
-
-        var i, j, len, jlen;
-
-        if (action == 'flushed') {
-            keys = [];
-            for (var key in _observers) {
-                if (_observers.hasOwnProperty(key)) {
-                    keys.push(key);
-                }
-            }
-            action = 'deleted';
-        }
-        for (i = 0, len = keys.length; i < len; i++) {
-            if (_observers[keys[i]]) {
-                for (j = 0, jlen = _observers[keys[i]].length; j < jlen; j++) {
-                    _observers[keys[i]][j](keys[i], action);
-                }
-            }
-            if (_observers['*']) {
-                for (j = 0, jlen = _observers['*'].length; j < jlen; j++) {
-                    _observers['*'][j](keys[i], action);
-                }
-            }
-        }
-    }
-
-    /**
-     * Publishes key change to listeners
-     */
-    function _publishChange() {
-        var updateTime = (+new Date()).toString();
-
-        if (_backend == 'localStorage' || _backend == 'globalStorage') {
-            try {
-                _storage_service.jStorage_update = updateTime;
-            } catch (E8) {
-                // safari private mode has been enabled after the jStorage initialization
-                _backend = false;
-            }
-        } else if (_backend == 'userDataBehavior') {
-            _storage_elm.setAttribute('jStorage_update', updateTime);
-            _storage_elm.save('jStorage');
-        }
-
-        _storageObserver();
-    }
-
-    /**
-     * Loads the data from the storage based on the supported mechanism
-     */
-    function _load_storage() {
-        /* if jStorage string is retrieved, then decode it */
-        if (_storage_service.jStorage) {
-            try {
-                _storage = JSON.parse(String(_storage_service.jStorage));
-            } catch (E6) {
-                _storage_service.jStorage = '{}';
-            }
-        } else {
-            _storage_service.jStorage = '{}';
-        }
-        _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
-
-        if (!_storage.__jstorage_meta) {
-            _storage.__jstorage_meta = {};
-        }
-        if (!_storage.__jstorage_meta.CRC32) {
-            _storage.__jstorage_meta.CRC32 = {};
-        }
-    }
-
-    /**
-     * This functions provides the 'save' mechanism to store the jStorage object
-     */
-    function _save() {
-        _dropOldEvents(); // remove expired events
-        try {
-            _storage_service.jStorage = JSON.stringify(_storage);
-            // If userData is used as the storage engine, additional
-            if (_storage_elm) {
-                _storage_elm.setAttribute('jStorage', _storage_service.jStorage);
-                _storage_elm.save('jStorage');
-            }
-            _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
-        } catch (E7) { /* probably cache is full, nothing is saved this way*/ }
-    }
-
-    /**
-     * Function checks if a key is set and is string or numberic
-     *
-     * @param {String} key Key name
-     */
-    function _checkKey(key) {
-        if (typeof key != 'string' && typeof key != 'number') {
-            throw new TypeError('Key name must be string or numeric');
-        }
-        if (key == '__jstorage_meta') {
-            throw new TypeError('Reserved key name');
-        }
-        return true;
-    }
-
-    /**
-     * Removes expired keys
-     */
-    function _handleTTL() {
-        var curtime, i, TTL, CRC32, nextExpire = Infinity,
-            changed = false,
-            deleted = [];
-
-        clearTimeout(_ttl_timeout);
-
-        if (!_storage.__jstorage_meta || typeof _storage.__jstorage_meta.TTL != 'object') {
-            // nothing to do here
-            return;
-        }
-
-        curtime = +new Date();
-        TTL = _storage.__jstorage_meta.TTL;
-
-        CRC32 = _storage.__jstorage_meta.CRC32;
-        for (i in TTL) {
-            if (TTL.hasOwnProperty(i)) {
-                if (TTL[i] <= curtime) {
-                    delete TTL[i];
-                    delete CRC32[i];
-                    delete _storage[i];
-                    changed = true;
-                    deleted.push(i);
-                } else if (TTL[i] < nextExpire) {
-                    nextExpire = TTL[i];
-                }
-            }
-        }
-
-        // set next check
-        if (nextExpire != Infinity) {
-            _ttl_timeout = setTimeout(_handleTTL, Math.min(nextExpire - curtime, 0x7FFFFFFF));
-        }
-
-        // save changes
-        if (changed) {
-            _save();
-            _publishChange();
-            _fireObservers(deleted, 'deleted');
-        }
-    }
-
-    /**
-     * Checks if there's any events on hold to be fired to listeners
-     */
-    function _handlePubSub() {
-        var i, len;
-        if (!_storage.__jstorage_meta.PubSub) {
-            return;
-        }
-        var pubelm,
-            _pubsubCurrent = _pubsub_last,
-            needFired = [];
-
-        for (i = len = _storage.__jstorage_meta.PubSub.length - 1; i >= 0; i--) {
-            pubelm = _storage.__jstorage_meta.PubSub[i];
-            if (pubelm[0] > _pubsub_last) {
-                _pubsubCurrent = pubelm[0];
-                needFired.unshift(pubelm);
-            }
-        }
-
-        for (i = needFired.length - 1; i >= 0; i--) {
-            _fireSubscribers(needFired[i][1], needFired[i][2]);
-        }
-
-        _pubsub_last = _pubsubCurrent;
-    }
-
-    /**
-     * Fires all subscriber listeners for a pubsub channel
-     *
-     * @param {String} channel Channel name
-     * @param {Mixed} payload Payload data to deliver
-     */
-    function _fireSubscribers(channel, payload) {
-        if (_pubsub_observers[channel]) {
-            for (var i = 0, len = _pubsub_observers[channel].length; i < len; i++) {
-                // send immutable data that can't be modified by listeners
-                try {
-                    _pubsub_observers[channel][i](channel, JSON.parse(JSON.stringify(payload)));
-                } catch (E) {}
-            }
-        }
-    }
-
-    /**
-     * Remove old events from the publish stream (at least 2sec old)
-     */
-    function _dropOldEvents() {
-        if (!_storage.__jstorage_meta.PubSub) {
-            return;
-        }
-
-        var retire = +new Date() - 2000;
-
-        for (var i = 0, len = _storage.__jstorage_meta.PubSub.length; i < len; i++) {
-            if (_storage.__jstorage_meta.PubSub[i][0] <= retire) {
-                // deleteCount is needed for IE6
-                _storage.__jstorage_meta.PubSub.splice(i, _storage.__jstorage_meta.PubSub.length - i);
-                break;
-            }
-        }
-
-        if (!_storage.__jstorage_meta.PubSub.length) {
-            delete _storage.__jstorage_meta.PubSub;
-        }
-
-    }
-
-    /**
-     * Publish payload to a channel
-     *
-     * @param {String} channel Channel name
-     * @param {Mixed} payload Payload to send to the subscribers
-     */
-    function _publish(channel, payload) {
-        if (!_storage.__jstorage_meta) {
-            _storage.__jstorage_meta = {};
-        }
-        if (!_storage.__jstorage_meta.PubSub) {
-            _storage.__jstorage_meta.PubSub = [];
-        }
-
-        _storage.__jstorage_meta.PubSub.unshift([+new Date(), channel, payload]);
-
-        _save();
-        _publishChange();
-    }
-
-
-    /**
-     * JS Implementation of MurmurHash2
-     *
-     *  SOURCE: https://github.com/garycourt/murmurhash-js (MIT licensed)
-     *
-     * @author <a href='mailto:gary.court@gmail.com'>Gary Court</a>
-     * @see http://github.com/garycourt/murmurhash-js
-     * @author <a href='mailto:aappleby@gmail.com'>Austin Appleby</a>
-     * @see http://sites.google.com/site/murmurhash/
-     *
-     * @param {string} str ASCII only
-     * @param {number} seed Positive integer only
-     * @return {number} 32-bit positive integer hash
-     */
-
-    function murmurhash2_32_gc(str, seed) {
-        var
-            l = str.length,
-            h = seed ^ l,
-            i = 0,
-            k;
-
-        while (l >= 4) {
-            k =
-                ((str.charCodeAt(i) & 0xff)) |
-                ((str.charCodeAt(++i) & 0xff) << 8) |
-                ((str.charCodeAt(++i) & 0xff) << 16) |
-                ((str.charCodeAt(++i) & 0xff) << 24);
-
-            k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
-            k ^= k >>> 24;
-            k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
-
-            h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;
-
-            l -= 4;
-            ++i;
-        }
-
-        switch (l) {
-            case 3:
-                h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
-                /* falls through */
-            case 2:
-                h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
-                /* falls through */
-            case 1:
-                h ^= (str.charCodeAt(i) & 0xff);
-                h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
-        }
-
-        h ^= h >>> 13;
-        h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
-        h ^= h >>> 15;
-
-        return h >>> 0;
-    }
-
-    ////////////////////////// PUBLIC INTERFACE /////////////////////////
-
-    $.jStorage = {
-        /* Version number */
-        version: JSTORAGE_VERSION,
-
-        /**
-         * Sets a key's value.
-         *
-         * @param {String} key Key to set. If this value is not set or not
-         *              a string an exception is raised.
-         * @param {Mixed} value Value to set. This can be any value that is JSON
-         *              compatible (Numbers, Strings, Objects etc.).
-         * @param {Object} [options] - possible options to use
-         * @param {Number} [options.TTL] - optional TTL value, in milliseconds
-         * @return {Mixed} the used value
-         */
-        set: function(key, value, options) {
-            _checkKey(key);
-
-            options = options || {};
-
-            // undefined values are deleted automatically
-            if (typeof value == 'undefined') {
-                this.deleteKey(key);
-                return value;
-            }
-
-            if (_XMLService.isXML(value)) {
-                value = {
-                    _is_xml: true,
-                    xml: _XMLService.encode(value)
-                };
-            } else if (typeof value == 'function') {
-                return undefined; // functions can't be saved!
-            } else if (value && typeof value == 'object') {
-                // clone the object before saving to _storage tree
-                value = JSON.parse(JSON.stringify(value));
-            }
-
-            _storage[key] = value;
-
-            _storage.__jstorage_meta.CRC32[key] = '2.' + murmurhash2_32_gc(JSON.stringify(value), 0x9747b28c);
-
-            this.setTTL(key, options.TTL || 0); // also handles saving and _publishChange
-
-            _fireObservers(key, 'updated');
-            return value;
-        },
-
-        /**
-         * Looks up a key in cache
-         *
-         * @param {String} key - Key to look up.
-         * @param {mixed} def - Default value to return, if key didn't exist.
-         * @return {Mixed} the key value, default value or null
-         */
-        get: function(key, def) {
-            _checkKey(key);
-            if (key in _storage) {
-                if (_storage[key] && typeof _storage[key] == 'object' && _storage[key]._is_xml) {
-                    return _XMLService.decode(_storage[key].xml);
-                } else {
-                    return _storage[key];
-                }
-            }
-            return typeof(def) == 'undefined' ? null : def;
-        },
-
-        /**
-         * Deletes a key from cache.
-         *
-         * @param {String} key - Key to delete.
-         * @return {Boolean} true if key existed or false if it didn't
-         */
-        deleteKey: function(key) {
-            _checkKey(key);
-            if (key in _storage) {
-                delete _storage[key];
-                // remove from TTL list
-                if (typeof _storage.__jstorage_meta.TTL == 'object' &&
-                    key in _storage.__jstorage_meta.TTL) {
-                    delete _storage.__jstorage_meta.TTL[key];
-                }
-
-                delete _storage.__jstorage_meta.CRC32[key];
-
-                _save();
-                _publishChange();
-                _fireObservers(key, 'deleted');
-                return true;
-            }
-            return false;
-        },
-
-        /**
-         * Sets a TTL for a key, or remove it if ttl value is 0 or below
-         *
-         * @param {String} key - key to set the TTL for
-         * @param {Number} ttl - TTL timeout in milliseconds
-         * @return {Boolean} true if key existed or false if it didn't
-         */
-        setTTL: function(key, ttl) {
-            var curtime = +new Date();
-            _checkKey(key);
-            ttl = Number(ttl) || 0;
-            if (key in _storage) {
-
-                if (!_storage.__jstorage_meta.TTL) {
-                    _storage.__jstorage_meta.TTL = {};
-                }
-
-                // Set TTL value for the key
-                if (ttl > 0) {
-                    _storage.__jstorage_meta.TTL[key] = curtime + ttl;
-                } else {
-                    delete _storage.__jstorage_meta.TTL[key];
-                }
-
-                _save();
-
-                _handleTTL();
-
-                _publishChange();
-                return true;
-            }
-            return false;
-        },
-
-        /**
-         * Gets remaining TTL (in milliseconds) for a key or 0 when no TTL has been set
-         *
-         * @param {String} key Key to check
-         * @return {Number} Remaining TTL in milliseconds
-         */
-        getTTL: function(key) {
-            var curtime = +new Date(),
-                ttl;
-            _checkKey(key);
-            if (key in _storage && _storage.__jstorage_meta.TTL && _storage.__jstorage_meta.TTL[key]) {
-                ttl = _storage.__jstorage_meta.TTL[key] - curtime;
-                return ttl || 0;
-            }
-            return 0;
-        },
-
-        /**
-         * Deletes everything in cache.
-         *
-         * @return {Boolean} Always true
-         */
-        flush: function() {
-            _storage = {
-                __jstorage_meta: {
-                    CRC32: {}
-                }
-            };
-            _save();
-            _publishChange();
-            _fireObservers(null, 'flushed');
-            return true;
-        },
-
-        /**
-         * Returns a read-only copy of _storage
-         *
-         * @return {Object} Read-only copy of _storage
-         */
-        storageObj: function() {
-            function F() {}
-            F.prototype = _storage;
-            return new F();
-        },
-
-        /**
-         * Returns an index of all used keys as an array
-         * ['key1', 'key2',..'keyN']
-         *
-         * @return {Array} Used keys
-         */
-        index: function() {
-            var index = [],
-                i;
-            for (i in _storage) {
-                if (_storage.hasOwnProperty(i) && i != '__jstorage_meta') {
-                    index.push(i);
-                }
-            }
-            return index;
-        },
-
-        /**
-         * How much space in bytes does the storage take?
-         *
-         * @return {Number} Storage size in chars (not the same as in bytes,
-         *                  since some chars may take several bytes)
-         */
-        storageSize: function() {
-            return _storage_size;
-        },
-
-        /**
-         * Which backend is currently in use?
-         *
-         * @return {String} Backend name
-         */
-        currentBackend: function() {
-            return _backend;
-        },
-
-        /**
-         * Test if storage is available
-         *
-         * @return {Boolean} True if storage can be used
-         */
-        storageAvailable: function() {
-            return !!_backend;
-        },
-
-        /**
-         * Register change listeners
-         *
-         * @param {String} key Key name
-         * @param {Function} callback Function to run when the key changes
-         */
-        listenKeyChange: function(key, callback) {
-            _checkKey(key);
-            if (!_observers[key]) {
-                _observers[key] = [];
-            }
-            _observers[key].push(callback);
-        },
-
-        /**
-         * Remove change listeners
-         *
-         * @param {String} key Key name to unregister listeners against
-         * @param {Function} [callback] If set, unregister the callback, if not - unregister all
-         */
-        stopListening: function(key, callback) {
-            _checkKey(key);
-
-            if (!_observers[key]) {
-                return;
-            }
-
-            if (!callback) {
-                delete _observers[key];
-                return;
-            }
-
-            for (var i = _observers[key].length - 1; i >= 0; i--) {
-                if (_observers[key][i] == callback) {
-                    _observers[key].splice(i, 1);
-                }
-            }
-        },
-
-        /**
-         * Subscribe to a Publish/Subscribe event stream
-         *
-         * @param {String} channel Channel name
-         * @param {Function} callback Function to run when the something is published to the channel
-         */
-        subscribe: function(channel, callback) {
-            channel = (channel || '').toString();
-            if (!channel) {
-                throw new TypeError('Channel not defined');
-            }
-            if (!_pubsub_observers[channel]) {
-                _pubsub_observers[channel] = [];
-            }
-            _pubsub_observers[channel].push(callback);
-        },
-
-        /**
-         * Publish data to an event stream
-         *
-         * @param {String} channel Channel name
-         * @param {Mixed} payload Payload to deliver
-         */
-        publish: function(channel, payload) {
-            channel = (channel || '').toString();
-            if (!channel) {
-                throw new TypeError('Channel not defined');
-            }
-
-            _publish(channel, payload);
-        },
-
-        /**
-         * Reloads the data from browser storage
-         */
-        reInit: function() {
-            _reloadData();
-        },
-
-        /**
-         * Removes reference from global objects and saves it as jStorage
-         *
-         * @param {Boolean} option if needed to save object as simple 'jStorage' in windows context
-         */
-        noConflict: function(saveInGlobal) {
-            delete window.$.jStorage;
-
-            if (saveInGlobal) {
-                window.jStorage = this;
-            }
-
-            return this;
-        }
-    };
-
-    // Initialize jStorage
-    _init();
-
-})();
diff --git a/resources/lib/jquery.jStorage/jstorage.js b/resources/lib/jquery.jStorage/jstorage.js
new file mode 100644 (file)
index 0000000..1ac8fcc
--- /dev/null
@@ -0,0 +1,996 @@
+/*
+ * ----------------------------- JSTORAGE -------------------------------------
+ * Simple local storage wrapper to save data on the browser side, supporting
+ * all major browsers - IE6+, Firefox2+, Safari4+, Chrome4+ and Opera 10.5+
+ *
+ * Author: Andris Reinman, andris.reinman@gmail.com
+ * Project homepage: www.jstorage.info
+ *
+ * Licensed under Unlicense:
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * For more information, please refer to <http://unlicense.org/>
+ */
+
+/* global ActiveXObject: false */
+/* jshint browser: true */
+
+(function() {
+    'use strict';
+
+    var
+    /* jStorage version */
+        JSTORAGE_VERSION = '0.4.12',
+
+        /* detect a dollar object or create one if not found */
+        $ = window.jQuery || window.$ || (window.$ = {}),
+
+        /* check for a JSON handling support */
+        JSON = {
+            parse: window.JSON && (window.JSON.parse || window.JSON.decode) ||
+                String.prototype.evalJSON && function(str) {
+                    return String(str).evalJSON();
+            } ||
+                $.parseJSON ||
+                $.evalJSON,
+            stringify: Object.toJSON ||
+                window.JSON && (window.JSON.stringify || window.JSON.encode) ||
+                $.toJSON
+        };
+
+    // Break if no JSON support was found
+    if (typeof JSON.parse !== 'function' || typeof JSON.stringify !== 'function') {
+        throw new Error('No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page');
+    }
+
+    var
+    /* This is the object, that holds the cached values */
+        _storage = {
+            __jstorage_meta: {
+                CRC32: {}
+            }
+        },
+
+        /* Actual browser storage (localStorage or globalStorage['domain']) */
+        _storage_service = {
+            jStorage: '{}'
+        },
+
+        /* DOM element for older IE versions, holds userData behavior */
+        _storage_elm = null,
+
+        /* How much space does the storage take */
+        _storage_size = 0,
+
+        /* which backend is currently used */
+        _backend = false,
+
+        /* onchange observers */
+        _observers = {},
+
+        /* timeout to wait after onchange event */
+        _observer_timeout = false,
+
+        /* last update time */
+        _observer_update = 0,
+
+        /* pubsub observers */
+        _pubsub_observers = {},
+
+        /* skip published items older than current timestamp */
+        _pubsub_last = +new Date(),
+
+        /* Next check for TTL */
+        _ttl_timeout,
+
+        /**
+         * XML encoding and decoding as XML nodes can't be JSON'ized
+         * XML nodes are encoded and decoded if the node is the value to be saved
+         * but not if it's as a property of another object
+         * Eg. -
+         *   $.jStorage.set('key', xmlNode);        // IS OK
+         *   $.jStorage.set('key', {xml: xmlNode}); // NOT OK
+         */
+        _XMLService = {
+
+            /**
+             * Validates a XML node to be XML
+             * based on jQuery.isXML function
+             */
+            isXML: function(elm) {
+                var documentElement = (elm ? elm.ownerDocument || elm : 0).documentElement;
+                return documentElement ? documentElement.nodeName !== 'HTML' : false;
+            },
+
+            /**
+             * Encodes a XML node to string
+             * based on http://www.mercurytide.co.uk/news/article/issues-when-working-ajax/
+             */
+            encode: function(xmlNode) {
+                if (!this.isXML(xmlNode)) {
+                    return false;
+                }
+                try { // Mozilla, Webkit, Opera
+                    return new XMLSerializer().serializeToString(xmlNode);
+                } catch (E1) {
+                    try { // IE
+                        return xmlNode.xml;
+                    } catch (E2) {}
+                }
+                return false;
+            },
+
+            /**
+             * Decodes a XML node from string
+             * loosely based on http://outwestmedia.com/jquery-plugins/xmldom/
+             */
+            decode: function(xmlString) {
+                var dom_parser = ('DOMParser' in window && (new DOMParser()).parseFromString) ||
+                    (window.ActiveXObject && function(_xmlString) {
+                        var xml_doc = new ActiveXObject('Microsoft.XMLDOM');
+                        xml_doc.async = 'false';
+                        xml_doc.loadXML(_xmlString);
+                        return xml_doc;
+                    }),
+                    resultXML;
+                if (!dom_parser) {
+                    return false;
+                }
+                resultXML = dom_parser.call('DOMParser' in window && (new DOMParser()) || window, xmlString, 'text/xml');
+                return this.isXML(resultXML) ? resultXML : false;
+            }
+        };
+
+
+    ////////////////////////// PRIVATE METHODS ////////////////////////
+
+    /**
+     * Initialization function. Detects if the browser supports DOM Storage
+     * or userData behavior and behaves accordingly.
+     */
+    function _init() {
+        /* Check if browser supports localStorage */
+        var localStorageReallyWorks = false;
+        if ('localStorage' in window) {
+            try {
+                window.localStorage.setItem('_tmptest', 'tmpval');
+                localStorageReallyWorks = true;
+                window.localStorage.removeItem('_tmptest');
+            } catch (BogusQuotaExceededErrorOnIos5) {
+                // Thanks be to iOS5 Private Browsing mode which throws
+                // QUOTA_EXCEEDED_ERRROR DOM Exception 22.
+            }
+        }
+
+        if (localStorageReallyWorks) {
+            try {
+                if (window.localStorage) {
+                    _storage_service = window.localStorage;
+                    _backend = 'localStorage';
+                    _observer_update = _storage_service.jStorage_update;
+                }
+            } catch (E3) { /* Firefox fails when touching localStorage and cookies are disabled */ }
+        }
+        /* Check if browser supports globalStorage */
+        else if ('globalStorage' in window) {
+            try {
+                if (window.globalStorage) {
+                    if (window.location.hostname == 'localhost') {
+                        _storage_service = window.globalStorage['localhost.localdomain'];
+                    } else {
+                        _storage_service = window.globalStorage[window.location.hostname];
+                    }
+                    _backend = 'globalStorage';
+                    _observer_update = _storage_service.jStorage_update;
+                }
+            } catch (E4) { /* Firefox fails when touching localStorage and cookies are disabled */ }
+        }
+        /* Check if browser supports userData behavior */
+        else {
+            _storage_elm = document.createElement('link');
+            if (_storage_elm.addBehavior) {
+
+                /* Use a DOM element to act as userData storage */
+                _storage_elm.style.behavior = 'url(#default#userData)';
+
+                /* userData element needs to be inserted into the DOM! */
+                document.getElementsByTagName('head')[0].appendChild(_storage_elm);
+
+                try {
+                    _storage_elm.load('jStorage');
+                } catch (E) {
+                    // try to reset cache
+                    _storage_elm.setAttribute('jStorage', '{}');
+                    _storage_elm.save('jStorage');
+                    _storage_elm.load('jStorage');
+                }
+
+                var data = '{}';
+                try {
+                    data = _storage_elm.getAttribute('jStorage');
+                } catch (E5) {}
+
+                try {
+                    _observer_update = _storage_elm.getAttribute('jStorage_update');
+                } catch (E6) {}
+
+                _storage_service.jStorage = data;
+                _backend = 'userDataBehavior';
+            } else {
+                _storage_elm = null;
+                return;
+            }
+        }
+
+        // Load data from storage
+        _load_storage();
+
+        // remove dead keys
+        _handleTTL();
+
+        // start listening for changes
+        _setupObserver();
+
+        // initialize publish-subscribe service
+        _handlePubSub();
+
+        // handle cached navigation
+        if ('addEventListener' in window) {
+            window.addEventListener('pageshow', function(event) {
+                if (event.persisted) {
+                    _storageObserver();
+                }
+            }, false);
+        }
+    }
+
+    /**
+     * Reload data from storage when needed
+     */
+    function _reloadData() {
+        var data = '{}';
+
+        if (_backend == 'userDataBehavior') {
+            _storage_elm.load('jStorage');
+
+            try {
+                data = _storage_elm.getAttribute('jStorage');
+            } catch (E5) {}
+
+            try {
+                _observer_update = _storage_elm.getAttribute('jStorage_update');
+            } catch (E6) {}
+
+            _storage_service.jStorage = data;
+        }
+
+        _load_storage();
+
+        // remove dead keys
+        _handleTTL();
+
+        _handlePubSub();
+    }
+
+    /**
+     * Sets up a storage change observer
+     */
+    function _setupObserver() {
+        if (_backend == 'localStorage' || _backend == 'globalStorage') {
+            if ('addEventListener' in window) {
+                window.addEventListener('storage', _storageObserver, false);
+            } else {
+                document.attachEvent('onstorage', _storageObserver);
+            }
+        } else if (_backend == 'userDataBehavior') {
+            setInterval(_storageObserver, 1000);
+        }
+    }
+
+    /**
+     * Fired on any kind of data change, needs to check if anything has
+     * really been changed
+     */
+    function _storageObserver() {
+        var updateTime;
+        // cumulate change notifications with timeout
+        clearTimeout(_observer_timeout);
+        _observer_timeout = setTimeout(function() {
+
+            if (_backend == 'localStorage' || _backend == 'globalStorage') {
+                updateTime = _storage_service.jStorage_update;
+            } else if (_backend == 'userDataBehavior') {
+                _storage_elm.load('jStorage');
+                try {
+                    updateTime = _storage_elm.getAttribute('jStorage_update');
+                } catch (E5) {}
+            }
+
+            if (updateTime && updateTime != _observer_update) {
+                _observer_update = updateTime;
+                _checkUpdatedKeys();
+            }
+
+        }, 25);
+    }
+
+    /**
+     * Reloads the data and checks if any keys are changed
+     */
+    function _checkUpdatedKeys() {
+        var oldCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32)),
+            newCrc32List;
+
+        _reloadData();
+        newCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32));
+
+        var key,
+            updated = [],
+            removed = [];
+
+        for (key in oldCrc32List) {
+            if (oldCrc32List.hasOwnProperty(key)) {
+                if (!newCrc32List[key]) {
+                    removed.push(key);
+                    continue;
+                }
+                if (oldCrc32List[key] != newCrc32List[key] && String(oldCrc32List[key]).substr(0, 2) == '2.') {
+                    updated.push(key);
+                }
+            }
+        }
+
+        for (key in newCrc32List) {
+            if (newCrc32List.hasOwnProperty(key)) {
+                if (!oldCrc32List[key]) {
+                    updated.push(key);
+                }
+            }
+        }
+
+        _fireObservers(updated, 'updated');
+        _fireObservers(removed, 'deleted');
+    }
+
+    /**
+     * Fires observers for updated keys
+     *
+     * @param {Array|String} keys Array of key names or a key
+     * @param {String} action What happened with the value (updated, deleted, flushed)
+     */
+    function _fireObservers(keys, action) {
+        keys = [].concat(keys || []);
+
+        var i, j, len, jlen;
+
+        if (action == 'flushed') {
+            keys = [];
+            for (var key in _observers) {
+                if (_observers.hasOwnProperty(key)) {
+                    keys.push(key);
+                }
+            }
+            action = 'deleted';
+        }
+        for (i = 0, len = keys.length; i < len; i++) {
+            if (_observers[keys[i]]) {
+                for (j = 0, jlen = _observers[keys[i]].length; j < jlen; j++) {
+                    _observers[keys[i]][j](keys[i], action);
+                }
+            }
+            if (_observers['*']) {
+                for (j = 0, jlen = _observers['*'].length; j < jlen; j++) {
+                    _observers['*'][j](keys[i], action);
+                }
+            }
+        }
+    }
+
+    /**
+     * Publishes key change to listeners
+     */
+    function _publishChange() {
+        var updateTime = (+new Date()).toString();
+
+        if (_backend == 'localStorage' || _backend == 'globalStorage') {
+            try {
+                _storage_service.jStorage_update = updateTime;
+            } catch (E8) {
+                // safari private mode has been enabled after the jStorage initialization
+                _backend = false;
+            }
+        } else if (_backend == 'userDataBehavior') {
+            _storage_elm.setAttribute('jStorage_update', updateTime);
+            _storage_elm.save('jStorage');
+        }
+
+        _storageObserver();
+    }
+
+    /**
+     * Loads the data from the storage based on the supported mechanism
+     */
+    function _load_storage() {
+        /* if jStorage string is retrieved, then decode it */
+        if (_storage_service.jStorage) {
+            try {
+                _storage = JSON.parse(String(_storage_service.jStorage));
+            } catch (E6) {
+                _storage_service.jStorage = '{}';
+            }
+        } else {
+            _storage_service.jStorage = '{}';
+        }
+        _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
+
+        if (!_storage.__jstorage_meta) {
+            _storage.__jstorage_meta = {};
+        }
+        if (!_storage.__jstorage_meta.CRC32) {
+            _storage.__jstorage_meta.CRC32 = {};
+        }
+    }
+
+    /**
+     * This functions provides the 'save' mechanism to store the jStorage object
+     */
+    function _save() {
+        _dropOldEvents(); // remove expired events
+        try {
+            _storage_service.jStorage = JSON.stringify(_storage);
+            // If userData is used as the storage engine, additional
+            if (_storage_elm) {
+                _storage_elm.setAttribute('jStorage', _storage_service.jStorage);
+                _storage_elm.save('jStorage');
+            }
+            _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
+        } catch (E7) { /* probably cache is full, nothing is saved this way*/ }
+    }
+
+    /**
+     * Function checks if a key is set and is string or numberic
+     *
+     * @param {String} key Key name
+     */
+    function _checkKey(key) {
+        if (typeof key != 'string' && typeof key != 'number') {
+            throw new TypeError('Key name must be string or numeric');
+        }
+        if (key == '__jstorage_meta') {
+            throw new TypeError('Reserved key name');
+        }
+        return true;
+    }
+
+    /**
+     * Removes expired keys
+     */
+    function _handleTTL() {
+        var curtime, i, TTL, CRC32, nextExpire = Infinity,
+            changed = false,
+            deleted = [];
+
+        clearTimeout(_ttl_timeout);
+
+        if (!_storage.__jstorage_meta || typeof _storage.__jstorage_meta.TTL != 'object') {
+            // nothing to do here
+            return;
+        }
+
+        curtime = +new Date();
+        TTL = _storage.__jstorage_meta.TTL;
+
+        CRC32 = _storage.__jstorage_meta.CRC32;
+        for (i in TTL) {
+            if (TTL.hasOwnProperty(i)) {
+                if (TTL[i] <= curtime) {
+                    delete TTL[i];
+                    delete CRC32[i];
+                    delete _storage[i];
+                    changed = true;
+                    deleted.push(i);
+                } else if (TTL[i] < nextExpire) {
+                    nextExpire = TTL[i];
+                }
+            }
+        }
+
+        // set next check
+        if (nextExpire != Infinity) {
+            _ttl_timeout = setTimeout(_handleTTL, Math.min(nextExpire - curtime, 0x7FFFFFFF));
+        }
+
+        // save changes
+        if (changed) {
+            _save();
+            _publishChange();
+            _fireObservers(deleted, 'deleted');
+        }
+    }
+
+    /**
+     * Checks if there's any events on hold to be fired to listeners
+     */
+    function _handlePubSub() {
+        var i, len;
+        if (!_storage.__jstorage_meta.PubSub) {
+            return;
+        }
+        var pubelm,
+            _pubsubCurrent = _pubsub_last,
+            needFired = [];
+
+        for (i = len = _storage.__jstorage_meta.PubSub.length - 1; i >= 0; i--) {
+            pubelm = _storage.__jstorage_meta.PubSub[i];
+            if (pubelm[0] > _pubsub_last) {
+                _pubsubCurrent = pubelm[0];
+                needFired.unshift(pubelm);
+            }
+        }
+
+        for (i = needFired.length - 1; i >= 0; i--) {
+            _fireSubscribers(needFired[i][1], needFired[i][2]);
+        }
+
+        _pubsub_last = _pubsubCurrent;
+    }
+
+    /**
+     * Fires all subscriber listeners for a pubsub channel
+     *
+     * @param {String} channel Channel name
+     * @param {Mixed} payload Payload data to deliver
+     */
+    function _fireSubscribers(channel, payload) {
+        if (_pubsub_observers[channel]) {
+            for (var i = 0, len = _pubsub_observers[channel].length; i < len; i++) {
+                // send immutable data that can't be modified by listeners
+                try {
+                    _pubsub_observers[channel][i](channel, JSON.parse(JSON.stringify(payload)));
+                } catch (E) {}
+            }
+        }
+    }
+
+    /**
+     * Remove old events from the publish stream (at least 2sec old)
+     */
+    function _dropOldEvents() {
+        if (!_storage.__jstorage_meta.PubSub) {
+            return;
+        }
+
+        var retire = +new Date() - 2000;
+
+        for (var i = 0, len = _storage.__jstorage_meta.PubSub.length; i < len; i++) {
+            if (_storage.__jstorage_meta.PubSub[i][0] <= retire) {
+                // deleteCount is needed for IE6
+                _storage.__jstorage_meta.PubSub.splice(i, _storage.__jstorage_meta.PubSub.length - i);
+                break;
+            }
+        }
+
+        if (!_storage.__jstorage_meta.PubSub.length) {
+            delete _storage.__jstorage_meta.PubSub;
+        }
+
+    }
+
+    /**
+     * Publish payload to a channel
+     *
+     * @param {String} channel Channel name
+     * @param {Mixed} payload Payload to send to the subscribers
+     */
+    function _publish(channel, payload) {
+        if (!_storage.__jstorage_meta) {
+            _storage.__jstorage_meta = {};
+        }
+        if (!_storage.__jstorage_meta.PubSub) {
+            _storage.__jstorage_meta.PubSub = [];
+        }
+
+        _storage.__jstorage_meta.PubSub.unshift([+new Date(), channel, payload]);
+
+        _save();
+        _publishChange();
+    }
+
+
+    /**
+     * JS Implementation of MurmurHash2
+     *
+     *  SOURCE: https://github.com/garycourt/murmurhash-js (MIT licensed)
+     *
+     * @author <a href='mailto:gary.court@gmail.com'>Gary Court</a>
+     * @see http://github.com/garycourt/murmurhash-js
+     * @author <a href='mailto:aappleby@gmail.com'>Austin Appleby</a>
+     * @see http://sites.google.com/site/murmurhash/
+     *
+     * @param {string} str ASCII only
+     * @param {number} seed Positive integer only
+     * @return {number} 32-bit positive integer hash
+     */
+
+    function murmurhash2_32_gc(str, seed) {
+        var
+            l = str.length,
+            h = seed ^ l,
+            i = 0,
+            k;
+
+        while (l >= 4) {
+            k =
+                ((str.charCodeAt(i) & 0xff)) |
+                ((str.charCodeAt(++i) & 0xff) << 8) |
+                ((str.charCodeAt(++i) & 0xff) << 16) |
+                ((str.charCodeAt(++i) & 0xff) << 24);
+
+            k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
+            k ^= k >>> 24;
+            k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
+
+            h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;
+
+            l -= 4;
+            ++i;
+        }
+
+        switch (l) {
+            case 3:
+                h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
+                /* falls through */
+            case 2:
+                h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
+                /* falls through */
+            case 1:
+                h ^= (str.charCodeAt(i) & 0xff);
+                h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
+        }
+
+        h ^= h >>> 13;
+        h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
+        h ^= h >>> 15;
+
+        return h >>> 0;
+    }
+
+    ////////////////////////// PUBLIC INTERFACE /////////////////////////
+
+    $.jStorage = {
+        /* Version number */
+        version: JSTORAGE_VERSION,
+
+        /**
+         * Sets a key's value.
+         *
+         * @param {String} key Key to set. If this value is not set or not
+         *              a string an exception is raised.
+         * @param {Mixed} value Value to set. This can be any value that is JSON
+         *              compatible (Numbers, Strings, Objects etc.).
+         * @param {Object} [options] - possible options to use
+         * @param {Number} [options.TTL] - optional TTL value, in milliseconds
+         * @return {Mixed} the used value
+         */
+        set: function(key, value, options) {
+            _checkKey(key);
+
+            options = options || {};
+
+            // undefined values are deleted automatically
+            if (typeof value == 'undefined') {
+                this.deleteKey(key);
+                return value;
+            }
+
+            if (_XMLService.isXML(value)) {
+                value = {
+                    _is_xml: true,
+                    xml: _XMLService.encode(value)
+                };
+            } else if (typeof value == 'function') {
+                return undefined; // functions can't be saved!
+            } else if (value && typeof value == 'object') {
+                // clone the object before saving to _storage tree
+                value = JSON.parse(JSON.stringify(value));
+            }
+
+            _storage[key] = value;
+
+            _storage.__jstorage_meta.CRC32[key] = '2.' + murmurhash2_32_gc(JSON.stringify(value), 0x9747b28c);
+
+            this.setTTL(key, options.TTL || 0); // also handles saving and _publishChange
+
+            _fireObservers(key, 'updated');
+            return value;
+        },
+
+        /**
+         * Looks up a key in cache
+         *
+         * @param {String} key - Key to look up.
+         * @param {mixed} def - Default value to return, if key didn't exist.
+         * @return {Mixed} the key value, default value or null
+         */
+        get: function(key, def) {
+            _checkKey(key);
+            if (key in _storage) {
+                if (_storage[key] && typeof _storage[key] == 'object' && _storage[key]._is_xml) {
+                    return _XMLService.decode(_storage[key].xml);
+                } else {
+                    return _storage[key];
+                }
+            }
+            return typeof(def) == 'undefined' ? null : def;
+        },
+
+        /**
+         * Deletes a key from cache.
+         *
+         * @param {String} key - Key to delete.
+         * @return {Boolean} true if key existed or false if it didn't
+         */
+        deleteKey: function(key) {
+            _checkKey(key);
+            if (key in _storage) {
+                delete _storage[key];
+                // remove from TTL list
+                if (typeof _storage.__jstorage_meta.TTL == 'object' &&
+                    key in _storage.__jstorage_meta.TTL) {
+                    delete _storage.__jstorage_meta.TTL[key];
+                }
+
+                delete _storage.__jstorage_meta.CRC32[key];
+
+                _save();
+                _publishChange();
+                _fireObservers(key, 'deleted');
+                return true;
+            }
+            return false;
+        },
+
+        /**
+         * Sets a TTL for a key, or remove it if ttl value is 0 or below
+         *
+         * @param {String} key - key to set the TTL for
+         * @param {Number} ttl - TTL timeout in milliseconds
+         * @return {Boolean} true if key existed or false if it didn't
+         */
+        setTTL: function(key, ttl) {
+            var curtime = +new Date();
+            _checkKey(key);
+            ttl = Number(ttl) || 0;
+            if (key in _storage) {
+
+                if (!_storage.__jstorage_meta.TTL) {
+                    _storage.__jstorage_meta.TTL = {};
+                }
+
+                // Set TTL value for the key
+                if (ttl > 0) {
+                    _storage.__jstorage_meta.TTL[key] = curtime + ttl;
+                } else {
+                    delete _storage.__jstorage_meta.TTL[key];
+                }
+
+                _save();
+
+                _handleTTL();
+
+                _publishChange();
+                return true;
+            }
+            return false;
+        },
+
+        /**
+         * Gets remaining TTL (in milliseconds) for a key or 0 when no TTL has been set
+         *
+         * @param {String} key Key to check
+         * @return {Number} Remaining TTL in milliseconds
+         */
+        getTTL: function(key) {
+            var curtime = +new Date(),
+                ttl;
+            _checkKey(key);
+            if (key in _storage && _storage.__jstorage_meta.TTL && _storage.__jstorage_meta.TTL[key]) {
+                ttl = _storage.__jstorage_meta.TTL[key] - curtime;
+                return ttl || 0;
+            }
+            return 0;
+        },
+
+        /**
+         * Deletes everything in cache.
+         *
+         * @return {Boolean} Always true
+         */
+        flush: function() {
+            _storage = {
+                __jstorage_meta: {
+                    CRC32: {}
+                }
+            };
+            _save();
+            _publishChange();
+            _fireObservers(null, 'flushed');
+            return true;
+        },
+
+        /**
+         * Returns a read-only copy of _storage
+         *
+         * @return {Object} Read-only copy of _storage
+         */
+        storageObj: function() {
+            function F() {}
+            F.prototype = _storage;
+            return new F();
+        },
+
+        /**
+         * Returns an index of all used keys as an array
+         * ['key1', 'key2',..'keyN']
+         *
+         * @return {Array} Used keys
+         */
+        index: function() {
+            var index = [],
+                i;
+            for (i in _storage) {
+                if (_storage.hasOwnProperty(i) && i != '__jstorage_meta') {
+                    index.push(i);
+                }
+            }
+            return index;
+        },
+
+        /**
+         * How much space in bytes does the storage take?
+         *
+         * @return {Number} Storage size in chars (not the same as in bytes,
+         *                  since some chars may take several bytes)
+         */
+        storageSize: function() {
+            return _storage_size;
+        },
+
+        /**
+         * Which backend is currently in use?
+         *
+         * @return {String} Backend name
+         */
+        currentBackend: function() {
+            return _backend;
+        },
+
+        /**
+         * Test if storage is available
+         *
+         * @return {Boolean} True if storage can be used
+         */
+        storageAvailable: function() {
+            return !!_backend;
+        },
+
+        /**
+         * Register change listeners
+         *
+         * @param {String} key Key name
+         * @param {Function} callback Function to run when the key changes
+         */
+        listenKeyChange: function(key, callback) {
+            _checkKey(key);
+            if (!_observers[key]) {
+                _observers[key] = [];
+            }
+            _observers[key].push(callback);
+        },
+
+        /**
+         * Remove change listeners
+         *
+         * @param {String} key Key name to unregister listeners against
+         * @param {Function} [callback] If set, unregister the callback, if not - unregister all
+         */
+        stopListening: function(key, callback) {
+            _checkKey(key);
+
+            if (!_observers[key]) {
+                return;
+            }
+
+            if (!callback) {
+                delete _observers[key];
+                return;
+            }
+
+            for (var i = _observers[key].length - 1; i >= 0; i--) {
+                if (_observers[key][i] == callback) {
+                    _observers[key].splice(i, 1);
+                }
+            }
+        },
+
+        /**
+         * Subscribe to a Publish/Subscribe event stream
+         *
+         * @param {String} channel Channel name
+         * @param {Function} callback Function to run when the something is published to the channel
+         */
+        subscribe: function(channel, callback) {
+            channel = (channel || '').toString();
+            if (!channel) {
+                throw new TypeError('Channel not defined');
+            }
+            if (!_pubsub_observers[channel]) {
+                _pubsub_observers[channel] = [];
+            }
+            _pubsub_observers[channel].push(callback);
+        },
+
+        /**
+         * Publish data to an event stream
+         *
+         * @param {String} channel Channel name
+         * @param {Mixed} payload Payload to deliver
+         */
+        publish: function(channel, payload) {
+            channel = (channel || '').toString();
+            if (!channel) {
+                throw new TypeError('Channel not defined');
+            }
+
+            _publish(channel, payload);
+        },
+
+        /**
+         * Reloads the data from browser storage
+         */
+        reInit: function() {
+            _reloadData();
+        },
+
+        /**
+         * Removes reference from global objects and saves it as jStorage
+         *
+         * @param {Boolean} option if needed to save object as simple 'jStorage' in windows context
+         */
+        noConflict: function(saveInGlobal) {
+            delete window.$.jStorage;
+
+            if (saveInGlobal) {
+                window.jStorage = this;
+            }
+
+            return this;
+        }
+    };
+
+    // Initialize jStorage
+    _init();
+
+})();
\ No newline at end of file
diff --git a/resources/lib/jquery.mockjax.js b/resources/lib/jquery.mockjax.js
deleted file mode 100644 (file)
index 5f6e130..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/*!
- * MockJax - jQuery Plugin to Mock Ajax requests
- *
- * Version:  1.4.0
- * Released: 2011-02-04
- * Source:   http://github.com/appendto/jquery-mockjax
- * Docs:     http://enterprisejquery.com/2010/07/mock-your-ajax-requests-with-mockjax-for-rapid-development
- * Plugin:   mockjax
- * Author:   Jonathan Sharp (http://jdsharp.com)
- * License:  MIT,GPL
- * 
- * Copyright (c) 2010 appendTo LLC.
- * Dual licensed under the MIT or GPL licenses.
- * http://appendto.com/open-source-licenses
- */
-(function($) {
-       var _ajax = $.ajax,
-               mockHandlers = [];
-       
-       function parseXML(xml) {
-               if ( window['DOMParser'] == undefined && window.ActiveXObject ) {
-                       DOMParser = function() { };
-                       DOMParser.prototype.parseFromString = function( xmlString ) {
-                               var doc = new ActiveXObject('Microsoft.XMLDOM');
-                       doc.async = 'false';
-                       doc.loadXML( xmlString );
-                               return doc;
-                       };
-               }
-               
-               try {
-                       var xmlDoc      = ( new DOMParser() ).parseFromString( xml, 'text/xml' );
-                       if ( $.isXMLDoc( xmlDoc ) ) {
-                               var err = $('parsererror', xmlDoc);
-                               if ( err.length == 1 ) {
-                                       throw('Error: ' + $(xmlDoc).text() );
-                               }
-                       } else {
-                               throw('Unable to parse XML');
-                       }
-               } catch( e ) {
-                       var msg = ( e.name == undefined ? e : e.name + ': ' + e.message );
-                       $(document).trigger('xmlParseError', [ msg ]);
-                       return undefined;
-               }
-               return xmlDoc;
-       }
-       
-       $.extend({
-               ajax: function(origSettings) {
-                       var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
-                           mock = false;
-                       // Iterate over our mock handlers (in registration order) until we find
-                       // one that is willing to intercept the request
-                       $.each(mockHandlers, function(k, v) {
-                               if ( !mockHandlers[k] ) {
-                                       return;
-                               }
-                               var m = null;
-                               // If the mock was registered with a function, let the function decide if we 
-                               // want to mock this request
-                               if ( $.isFunction(mockHandlers[k]) ) {
-                                       m = mockHandlers[k](s);
-                               } else {
-                                       m = mockHandlers[k];
-                                       // Inspect the URL of the request and check if the mock handler's url 
-                                       // matches the url for this ajax request
-                                       if ( $.isFunction(m.url.test) ) {
-                                               // The user provided a regex for the url, test it
-                                               if ( !m.url.test( s.url ) ) {
-                                                       m = null;
-                                               }
-                                       } else {
-                                               // Look for a simple wildcard '*' or a direct URL match
-                                               var star = m.url.indexOf('*');
-                                               if ( ( m.url != '*' && m.url != s.url && star == -1 ) ||
-                                                       ( star > -1 && m.url.substr(0, star) != s.url.substr(0, star) ) ) {
-                                                        // The url we tested did not match the wildcard *
-                                                        m = null;
-                                               }
-                                       }
-                                       if ( m ) {
-                                               // Inspect the data submitted in the request (either POST body or GET query string)
-                                               if ( m.data && s.data ) {
-                                                       var identical = false;
-                                                       // Deep inspect the identity of the objects
-                                                       (function ident(mock, live) {
-                                                               // Test for situations where the data is a querystring (not an object)
-                                                               if (typeof live === 'string') {
-                                                                       // Querystring may be a regex
-                                                                       identical = $.isFunction( mock.test ) ? mock.test(live) : mock == live;
-                                                                       return identical;
-                                                               }
-                                                               $.each(mock, function(k, v) {
-                                                                       if ( live[k] === undefined ) {
-                                                                               identical = false;
-                                                                               return false;
-                                                                       } else {
-                                                                               identical = true;
-                                                                               if ( typeof live[k] == 'object' ) {
-                                                                                       return ident(mock[k], live[k]);
-                                                                               } else {
-                                                                                       if ( $.isFunction( mock[k].test ) ) {
-                                                                                               identical = mock[k].test(live[k]);
-                                                                                       } else {
-                                                                                               identical = ( mock[k] == live[k] );
-                                                                                       }
-                                                                                       return identical;
-                                                                               }
-                                                                       }
-                                                               });
-                                                       })(m.data, s.data);
-                                                       // They're not identical, do not mock this request
-                                                       if ( identical == false ) {
-                                                               m = null;
-                                                       }
-                                               }
-                                               // Inspect the request type
-                                               if ( m && m.type && m.type != s.type ) {
-                                                       // The request type doesn't match (GET vs. POST)
-                                                       m = null;
-                                               }
-                                       }
-                               }
-                               if ( m ) {
-                                       mock = true;
-
-                                       // Handle console logging
-                                       var c = $.extend({}, $.mockjaxSettings, m);
-                                       if ( c.log && $.isFunction(c.log) ) {
-                                               c.log('MOCK ' + s.type.toUpperCase() + ': ' + s.url, $.extend({}, s));
-                                       }
-                                       
-                                       var jsre = /=\?(&|$)/, jsc = (new Date()).getTime();
-
-                                       // Handle JSONP Parameter Callbacks, we need to replicate some of the jQuery core here
-                                       // because there isn't an easy hook for the cross domain script tag of jsonp
-                                       if ( s.dataType === "jsonp" ) {
-                                               if ( s.type.toUpperCase() === "GET" ) {
-                                                       if ( !jsre.test( s.url ) ) {
-                                                               s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
-                                                       }
-                                               } else if ( !s.data || !jsre.test(s.data) ) {
-                                                       s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
-                                               }
-                                               s.dataType = "json";
-                                       }
-                       
-                                       // Build temporary JSONP function
-                                       if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
-                                               jsonp = s.jsonpCallback || ("jsonp" + jsc++);
-                       
-                                               // Replace the =? sequence both in the query string and the data
-                                               if ( s.data ) {
-                                                       s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
-                                               }
-                       
-                                               s.url = s.url.replace(jsre, "=" + jsonp + "$1");
-                       
-                                               // We need to make sure
-                                               // that a JSONP style response is executed properly
-                                               s.dataType = "script";
-                       
-                                               // Handle JSONP-style loading
-                                               window[ jsonp ] = window[ jsonp ] || function( tmp ) {
-                                                       data = tmp;
-                                                       success();
-                                                       complete();
-                                                       // Garbage collect
-                                                       window[ jsonp ] = undefined;
-                       
-                                                       try {
-                                                               delete window[ jsonp ];
-                                                       } catch(e) {}
-                       
-                                                       if ( head ) {
-                                                               head.removeChild( script );
-                                                       }
-                                               };
-                                       }
-                                       
-                                       var rurl = /^(\w+:)?\/\/([^\/?#]+)/,
-                                               parts = rurl.exec( s.url ),
-                                               remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
-                                       
-                                       // Test if we are going to create a script tag (if so, intercept & mock)
-                                       if ( s.dataType === "script" && s.type.toUpperCase() === "GET" && remote ) {
-                                               // Synthesize the mock request for adding a script tag
-                                               var callbackContext = origSettings && origSettings.context || s;
-                                               
-                                               function success() {
-                                                       // If a local callback was specified, fire it and pass it the data
-                                                       if ( s.success ) {
-                                                               s.success.call( callbackContext, ( m.response ? m.response.toString() : m.responseText || ''), status, {} );
-                                                       }
-                               
-                                                       // Fire the global callback
-                                                       if ( s.global ) {
-                                                               trigger( "ajaxSuccess", [{}, s] );
-                                                       }
-                                               }
-                               
-                                               function complete() {
-                                                       // Process result
-                                                       if ( s.complete ) {
-                                                               s.complete.call( callbackContext, {} , status );
-                                                       }
-                               
-                                                       // The request was completed
-                                                       if ( s.global ) {
-                                                               trigger( "ajaxComplete", [{}, s] );
-                                                       }
-                               
-                                                       // Handle the global AJAX counter
-                                                       if ( s.global && ! --jQuery.active ) {
-                                                               jQuery.event.trigger( "ajaxStop" );
-                                                       }
-                                               }
-                                               
-                                               function trigger(type, args) {
-                                                       (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
-                                               }
-                                               
-                                               if ( m.response && $.isFunction(m.response) ) {
-                                                       m.response(origSettings);
-                                               } else {
-                                                       $.globalEval(m.responseText);
-                                               }
-                                               success();
-                                               complete();
-                                               return false;
-                                       }
-                                       mock = _ajax.call($, $.extend(true, {}, origSettings, {
-                                               // Mock the XHR object
-                                               xhr: function() {
-                                                       // Extend with our default mockjax settings
-                                                       m = $.extend({}, $.mockjaxSettings, m);
-
-                                                       if ( m.contentType ) {
-                                                               m.headers['content-type'] = m.contentType;
-                                                       }
-
-                                                       // Return our mock xhr object
-                                                       return {
-                                                               status: m.status,
-                                                               readyState: 1,
-                                                               open: function() { },
-                                                               send: function() {
-                                                                       // This is a substitute for < 1.4 which lacks $.proxy
-                                                                       var process = (function(that) {
-                                                                               return function() {
-                                                                                       return (function() {
-                                                                                               // The request has returned
-                                                                                               this.status             = m.status;
-                                                                                               this.readyState         = 4;
-                                                                               
-                                                                                               // We have an executable function, call it to give 
-                                                                                               // the mock handler a chance to update it's data
-                                                                                               if ( $.isFunction(m.response) ) {
-                                                                                                       m.response(origSettings);
-                                                                                               }
-                                                                                               // Copy over our mock to our xhr object before passing control back to 
-                                                                                               // jQuery's onreadystatechange callback
-                                                                                               if ( s.dataType == 'json' && ( typeof m.responseText == 'object' ) ) {
-                                                                                                       this.responseText = JSON.stringify(m.responseText);
-                                                                                               } else if ( s.dataType == 'xml' ) {
-                                                                                                       if ( typeof m.responseXML == 'string' ) {
-                                                                                                               this.responseXML = parseXML(m.responseXML);
-                                                                                                       } else {
-                                                                                                               this.responseXML = m.responseXML;
-                                                                                                       }
-                                                                                               } else {
-                                                                                                       this.responseText = m.responseText;
-                                                                                               }
-                                                                                               // jQuery < 1.4 doesn't have onreadystate change for xhr
-                                                                                               if ( $.isFunction(this.onreadystatechange) ) {
-                                                                                                       this.onreadystatechange( m.isTimeout ? 'timeout' : undefined );
-                                                                                               }
-                                                                                       }).apply(that);
-                                                                               };
-                                                                       })(this);
-
-                                                                       if ( m.proxy ) {
-                                                                               // We're proxying this request and loading in an external file instead
-                                                                               _ajax({
-                                                                                       global: false,
-                                                                                       url: m.proxy,
-                                                                                       type: m.proxyType,
-                                                                                       data: m.data,
-                                                                                       dataType: s.dataType,
-                                                                                       complete: function(xhr, txt) {
-                                                                                               m.responseXML = xhr.responseXML;
-                                                                                               m.responseText = xhr.responseText;
-                                                                                               this.responseTimer = setTimeout(process, m.responseTime || 0);
-                                                                                       }
-                                                                               });
-                                                                       } else {
-                                                                               // type == 'POST' || 'GET' || 'DELETE'
-                                                                               if ( s.async === false ) {
-                                                                                       // TODO: Blocking delay
-                                                                                       process();
-                                                                               } else {
-                                                                                       this.responseTimer = setTimeout(process, m.responseTime || 50);
-                                                                               }
-                                                                       }
-                                                               },
-                                                               abort: function() {
-                                                                       clearTimeout(this.responseTimer);
-                                                               },
-                                                               setRequestHeader: function() { },
-                                                               getResponseHeader: function(header) {
-                                                                       // 'Last-modified', 'Etag', 'content-type' are all checked by jQuery
-                                                                       if ( m.headers && m.headers[header] ) {
-                                                                               // Return arbitrary headers
-                                                                               return m.headers[header];
-                                                                       } else if ( header.toLowerCase() == 'last-modified' ) {
-                                                                               return m.lastModified || (new Date()).toString();
-                                                                       } else if ( header.toLowerCase() == 'etag' ) {
-                                                                               return m.etag || '';
-                                                                       } else if ( header.toLowerCase() == 'content-type' ) {
-                                                                               return m.contentType || 'text/plain';
-                                                                       }
-                                                               },
-                                                               getAllResponseHeaders: function() {
-                                                                       var headers = '';
-                                                                       $.each(m.headers, function(k, v) {
-                                                                               headers += k + ': ' + v + "\n";
-                                                                       });
-                                                                       return headers;
-                                                               }
-                                                       };
-                                               }
-                                       }));
-                                       return false;
-                               }
-                       });
-                       // We don't have a mock request, trigger a normal request
-                       if ( !mock ) {
-                               return _ajax.apply($, arguments);
-                       } else {
-                               return mock;
-                       }
-               }
-       });
-
-       $.mockjaxSettings = {
-               //url:        null,
-               //type:       'GET',
-               log:          function(msg) {
-                               window['console'] && window.console.log && window.console.log(msg);
-                             },
-               status:       200,
-               responseTime: 500,
-               isTimeout:    false,
-               contentType:  'text/plain',
-               response:     '', 
-               responseText: '',
-               responseXML:  '',
-               proxy:        '',
-               proxyType:    'GET',
-               
-               lastModified: null,
-               etag:         '',
-               headers: {
-                       etag: 'IJF@H#@923uf8023hFO@I#H#',
-                       'content-type' : 'text/plain'
-               }
-       };
-
-       $.mockjax = function(settings) {
-               var i = mockHandlers.length;
-               mockHandlers[i] = settings;
-               return i;
-       };
-       $.mockjaxClear = function(i) {
-               if ( arguments.length == 1 ) {
-                       mockHandlers[i] = null;
-               } else {
-                       mockHandlers = [];
-               }
-       };
-})(jQuery);
diff --git a/resources/lib/jquery.throttle-debounce/jquery.ba-throttle-debounce.js b/resources/lib/jquery.throttle-debounce/jquery.ba-throttle-debounce.js
new file mode 100644 (file)
index 0000000..fa30bdf
--- /dev/null
@@ -0,0 +1,252 @@
+/*!
+ * jQuery throttle / debounce - v1.1 - 3/7/2010
+ * http://benalman.com/projects/jquery-throttle-debounce-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+
+// Script: jQuery throttle / debounce: Sometimes, less is more!
+//
+// *Version: 1.1, Last updated: 3/7/2010*
+// 
+// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/
+// GitHub       - http://github.com/cowboy/jquery-throttle-debounce/
+// Source       - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js
+// (Minified)   - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb)
+// 
+// About: License
+// 
+// Copyright (c) 2010 "Cowboy" Ben Alman,
+// Dual licensed under the MIT and GPL licenses.
+// http://benalman.com/about/license/
+// 
+// About: Examples
+// 
+// These working examples, complete with fully commented code, illustrate a few
+// ways in which this plugin can be used.
+// 
+// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
+// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
+// 
+// About: Support and Testing
+// 
+// Information about what version or versions of jQuery this plugin has been
+// tested with, what browsers it has been tested in, and where the unit tests
+// reside (so you can test it yourself).
+// 
+// jQuery Versions - none, 1.3.2, 1.4.2
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
+// Unit Tests      - http://benalman.com/code/projects/jquery-throttle-debounce/unit/
+// 
+// About: Release History
+// 
+// 1.1 - (3/7/2010) Fixed a bug in <jQuery.throttle> where trailing callbacks
+//       executed later than they should. Reworked a fair amount of internal
+//       logic as well.
+// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over
+//       from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the
+//       no_trailing throttle parameter and debounce functionality.
+// 
+// Topic: Note for non-jQuery users
+// 
+// jQuery isn't actually required for this plugin, because nothing internal
+// uses any jQuery methods or properties. jQuery is just used as a namespace
+// under which these methods can exist.
+// 
+// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist
+// when this plugin is loaded, the method described below will be created in
+// the `Cowboy` namespace. Usage will be exactly the same, but instead of
+// $.method() or jQuery.method(), you'll need to use Cowboy.method().
+
+(function(window,undefined){
+  '$:nomunge'; // Used by YUI compressor.
+  
+  // Since jQuery really isn't required for this plugin, use `jQuery` as the
+  // namespace only if it already exists, otherwise use the `Cowboy` namespace,
+  // creating it if necessary.
+  var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ),
+    
+    // Internal method reference.
+    jq_throttle;
+  
+  // Method: jQuery.throttle
+  // 
+  // Throttle execution of a function. Especially useful for rate limiting
+  // execution of handlers on events like resize and scroll. If you want to
+  // rate-limit execution of a function to a single time, see the
+  // <jQuery.debounce> method.
+  // 
+  // In this visualization, | is a throttled-function call and X is the actual
+  // callback execution:
+  // 
+  // > Throttled with `no_trailing` specified as false or unspecified:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // > X    X    X    X    X    X        X    X    X    X    X    X
+  // > 
+  // > Throttled with `no_trailing` specified as true:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // > X    X    X    X    X             X    X    X    X    X
+  // 
+  // Usage:
+  // 
+  // > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback );
+  // > 
+  // > jQuery('selector').bind( 'someevent', throttled );
+  // > jQuery('selector').unbind( 'someevent', throttled );
+  // 
+  // This also works in jQuery 1.4+:
+  // 
+  // > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) );
+  // > jQuery('selector').unbind( 'someevent', callback );
+  // 
+  // Arguments:
+  // 
+  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
+  //    callbacks, values around 100 or 250 (or even higher) are most useful.
+  //  no_trailing - (Boolean) Optional, defaults to false. If no_trailing is
+  //    true, callback will only execute every `delay` milliseconds while the
+  //    throttled-function is being called. If no_trailing is false or
+  //    unspecified, callback will be executed one final time after the last
+  //    throttled-function call. (After the throttled-function has not been
+  //    called for `delay` milliseconds, the internal counter is reset)
+  //  callback - (Function) A function to be executed after delay milliseconds.
+  //    The `this` context and all arguments are passed through, as-is, to
+  //    `callback` when the throttled-function is executed.
+  // 
+  // Returns:
+  // 
+  //  (Function) A new, throttled, function.
+  
+  $.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) {
+    // After wrapper has stopped being called, this timeout ensures that
+    // `callback` is executed at the proper times in `throttle` and `end`
+    // debounce modes.
+    var timeout_id,
+      
+      // Keep track of the last time `callback` was executed.
+      last_exec = 0;
+    
+    // `no_trailing` defaults to falsy.
+    if ( typeof no_trailing !== 'boolean' ) {
+      debounce_mode = callback;
+      callback = no_trailing;
+      no_trailing = undefined;
+    }
+    
+    // The `wrapper` function encapsulates all of the throttling / debouncing
+    // functionality and when executed will limit the rate at which `callback`
+    // is executed.
+    function wrapper() {
+      var that = this,
+        elapsed = +new Date() - last_exec,
+        args = arguments;
+      
+      // Execute `callback` and update the `last_exec` timestamp.
+      function exec() {
+        last_exec = +new Date();
+        callback.apply( that, args );
+      };
+      
+      // If `debounce_mode` is true (at_begin) this is used to clear the flag
+      // to allow future `callback` executions.
+      function clear() {
+        timeout_id = undefined;
+      };
+      
+      if ( debounce_mode && !timeout_id ) {
+        // Since `wrapper` is being called for the first time and
+        // `debounce_mode` is true (at_begin), execute `callback`.
+        exec();
+      }
+      
+      // Clear any existing timeout.
+      timeout_id && clearTimeout( timeout_id );
+      
+      if ( debounce_mode === undefined && elapsed > delay ) {
+        // In throttle mode, if `delay` time has been exceeded, execute
+        // `callback`.
+        exec();
+        
+      } else if ( no_trailing !== true ) {
+        // In trailing throttle mode, since `delay` time has not been
+        // exceeded, schedule `callback` to execute `delay` ms after most
+        // recent execution.
+        // 
+        // If `debounce_mode` is true (at_begin), schedule `clear` to execute
+        // after `delay` ms.
+        // 
+        // If `debounce_mode` is false (at end), schedule `callback` to
+        // execute after `delay` ms.
+        timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
+      }
+    };
+    
+    // Set the guid of `wrapper` function to the same of original callback, so
+    // it can be removed in jQuery 1.4+ .unbind or .die by using the original
+    // callback as a reference.
+    if ( $.guid ) {
+      wrapper.guid = callback.guid = callback.guid || $.guid++;
+    }
+    
+    // Return the wrapper function.
+    return wrapper;
+  };
+  
+  // Method: jQuery.debounce
+  // 
+  // Debounce execution of a function. Debouncing, unlike throttling,
+  // guarantees that a function is only executed a single time, either at the
+  // very beginning of a series of calls, or at the very end. If you want to
+  // simply rate-limit execution of a function, see the <jQuery.throttle>
+  // method.
+  // 
+  // In this visualization, | is a debounced-function call and X is the actual
+  // callback execution:
+  // 
+  // > Debounced with `at_begin` specified as false or unspecified:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // >                          X                                 X
+  // > 
+  // > Debounced with `at_begin` specified as true:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // > X                                 X
+  // 
+  // Usage:
+  // 
+  // > var debounced = jQuery.debounce( delay, [ at_begin, ] callback );
+  // > 
+  // > jQuery('selector').bind( 'someevent', debounced );
+  // > jQuery('selector').unbind( 'someevent', debounced );
+  // 
+  // This also works in jQuery 1.4+:
+  // 
+  // > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) );
+  // > jQuery('selector').unbind( 'someevent', callback );
+  // 
+  // Arguments:
+  // 
+  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
+  //    callbacks, values around 100 or 250 (or even higher) are most useful.
+  //  at_begin - (Boolean) Optional, defaults to false. If at_begin is false or
+  //    unspecified, callback will only be executed `delay` milliseconds after
+  //    the last debounced-function call. If at_begin is true, callback will be
+  //    executed only at the first debounced-function call. (After the
+  //    throttled-function has not been called for `delay` milliseconds, the
+  //    internal counter is reset)
+  //  callback - (Function) A function to be executed after delay milliseconds.
+  //    The `this` context and all arguments are passed through, as-is, to
+  //    `callback` when the debounced-function is executed.
+  // 
+  // Returns:
+  // 
+  //  (Function) A new, debounced, function.
+  
+  $.debounce = function( delay, at_begin, callback ) {
+    return callback === undefined
+      ? jq_throttle( delay, at_begin, false )
+      : jq_throttle( delay, callback, at_begin !== false );
+  };
+  
+})(this);
diff --git a/resources/lib/jquery.ui/jquery.ui.spinner.js b/resources/lib/jquery.ui/jquery.ui.spinner.js
deleted file mode 100644 (file)
index 98dc9df..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/*!
- * jQuery UI Spinner 1.9.2
- * http://jqueryui.com
- *
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * http://api.jqueryui.com/spinner/
- *
- * Depends:
- *  jquery.ui.core.js
- *  jquery.ui.widget.js
- *  jquery.ui.button.js
- */
-(function( $ ) {
-
-function modifier( fn ) {
-       return function() {
-               var previous = this.element.val();
-               fn.apply( this, arguments );
-               this._refresh();
-               if ( previous !== this.element.val() ) {
-                       this._trigger( "change" );
-               }
-       };
-}
-
-$.widget( "ui.spinner", {
-       version: "1.9.2",
-       defaultElement: "<input>",
-       widgetEventPrefix: "spin",
-       options: {
-               culture: null,
-               icons: {
-                       down: "ui-icon-triangle-1-s",
-                       up: "ui-icon-triangle-1-n"
-               },
-               incremental: true,
-               max: null,
-               min: null,
-               numberFormat: null,
-               page: 10,
-               step: 1,
-
-               change: null,
-               spin: null,
-               start: null,
-               stop: null
-       },
-
-       _create: function() {
-               // handle string values that need to be parsed
-               this._setOption( "max", this.options.max );
-               this._setOption( "min", this.options.min );
-               this._setOption( "step", this.options.step );
-
-               // format the value, but don't constrain
-               this._value( this.element.val(), true );
-
-               this._draw();
-               this._on( this._events );
-               this._refresh();
-
-               // turning off autocomplete prevents the browser from remembering the
-               // value when navigating through history, so we re-enable autocomplete
-               // if the page is unloaded before the widget is destroyed. #7790
-               this._on( this.window, {
-                       beforeunload: function() {
-                               this.element.removeAttr( "autocomplete" );
-                       }
-               });
-       },
-
-       _getCreateOptions: function() {
-               var options = {},
-                       element = this.element;
-
-               $.each( [ "min", "max", "step" ], function( i, option ) {
-                       var value = element.attr( option );
-                       if ( value !== undefined && value.length ) {
-                               options[ option ] = value;
-                       }
-               });
-
-               return options;
-       },
-
-       _events: {
-               keydown: function( event ) {
-                       if ( this._start( event ) && this._keydown( event ) ) {
-                               event.preventDefault();
-                       }
-               },
-               keyup: "_stop",
-               focus: function() {
-                       this.previous = this.element.val();
-               },
-               blur: function( event ) {
-                       if ( this.cancelBlur ) {
-                               delete this.cancelBlur;
-                               return;
-                       }
-
-                       this._refresh();
-                       if ( this.previous !== this.element.val() ) {
-                               this._trigger( "change", event );
-                       }
-               },
-               mousewheel: function( event, delta ) {
-                       if ( !delta ) {
-                               return;
-                       }
-                       if ( !this.spinning && !this._start( event ) ) {
-                               return false;
-                       }
-
-                       this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
-                       clearTimeout( this.mousewheelTimer );
-                       this.mousewheelTimer = this._delay(function() {
-                               if ( this.spinning ) {
-                                       this._stop( event );
-                               }
-                       }, 100 );
-                       event.preventDefault();
-               },
-               "mousedown .ui-spinner-button": function( event ) {
-                       var previous;
-
-                       // We never want the buttons to have focus; whenever the user is
-                       // interacting with the spinner, the focus should be on the input.
-                       // If the input is focused then this.previous is properly set from
-                       // when the input first received focus. If the input is not focused
-                       // then we need to set this.previous based on the value before spinning.
-                       previous = this.element[0] === this.document[0].activeElement ?
-                               this.previous : this.element.val();
-                       function checkFocus() {
-                               var isActive = this.element[0] === this.document[0].activeElement;
-                               if ( !isActive ) {
-                                       this.element.focus();
-                                       this.previous = previous;
-                                       // support: IE
-                                       // IE sets focus asynchronously, so we need to check if focus
-                                       // moved off of the input because the user clicked on the button.
-                                       this._delay(function() {
-                                               this.previous = previous;
-                                       });
-                               }
-                       }
-
-                       // ensure focus is on (or stays on) the text field
-                       event.preventDefault();
-                       checkFocus.call( this );
-
-                       // support: IE
-                       // IE doesn't prevent moving focus even with event.preventDefault()
-                       // so we set a flag to know when we should ignore the blur event
-                       // and check (again) if focus moved off of the input.
-                       this.cancelBlur = true;
-                       this._delay(function() {
-                               delete this.cancelBlur;
-                               checkFocus.call( this );
-                       });
-
-                       if ( this._start( event ) === false ) {
-                               return;
-                       }
-
-                       this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
-               },
-               "mouseup .ui-spinner-button": "_stop",
-               "mouseenter .ui-spinner-button": function( event ) {
-                       // button will add ui-state-active if mouse was down while mouseleave and kept down
-                       if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
-                               return;
-                       }
-
-                       if ( this._start( event ) === false ) {
-                               return false;
-                       }
-                       this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
-               },
-               // TODO: do we really want to consider this a stop?
-               // shouldn't we just stop the repeater and wait until mouseup before
-               // we trigger the stop event?
-               "mouseleave .ui-spinner-button": "_stop"
-       },
-
-       _draw: function() {
-               var uiSpinner = this.uiSpinner = this.element
-                       .addClass( "ui-spinner-input" )
-                       .attr( "autocomplete", "off" )
-                       .wrap( this._uiSpinnerHtml() )
-                       .parent()
-                               // add buttons
-                               .append( this._buttonHtml() );
-
-               this.element.attr( "role", "spinbutton" );
-
-               // button bindings
-               this.buttons = uiSpinner.find( ".ui-spinner-button" )
-                       .attr( "tabIndex", -1 )
-                       .button()
-                       .removeClass( "ui-corner-all" );
-
-               // IE 6 doesn't understand height: 50% for the buttons
-               // unless the wrapper has an explicit height
-               if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
-                               uiSpinner.height() > 0 ) {
-                       uiSpinner.height( uiSpinner.height() );
-               }
-
-               // disable spinner if element was already disabled
-               if ( this.options.disabled ) {
-                       this.disable();
-               }
-       },
-
-       _keydown: function( event ) {
-               var options = this.options,
-                       keyCode = $.ui.keyCode;
-
-               switch ( event.keyCode ) {
-               case keyCode.UP:
-                       this._repeat( null, 1, event );
-                       return true;
-               case keyCode.DOWN:
-                       this._repeat( null, -1, event );
-                       return true;
-               case keyCode.PAGE_UP:
-                       this._repeat( null, options.page, event );
-                       return true;
-               case keyCode.PAGE_DOWN:
-                       this._repeat( null, -options.page, event );
-                       return true;
-               }
-
-               return false;
-       },
-
-       _uiSpinnerHtml: function() {
-               return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
-       },
-
-       _buttonHtml: function() {
-               return "" +
-                       "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
-                               "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
-                       "</a>" +
-                       "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
-                               "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
-                       "</a>";
-       },
-
-       _start: function( event ) {
-               if ( !this.spinning && this._trigger( "start", event ) === false ) {
-                       return false;
-               }
-
-               if ( !this.counter ) {
-                       this.counter = 1;
-               }
-               this.spinning = true;
-               return true;
-       },
-
-       _repeat: function( i, steps, event ) {
-               i = i || 500;
-
-               clearTimeout( this.timer );
-               this.timer = this._delay(function() {
-                       this._repeat( 40, steps, event );
-               }, i );
-
-               this._spin( steps * this.options.step, event );
-       },
-
-       _spin: function( step, event ) {
-               var value = this.value() || 0;
-
-               if ( !this.counter ) {
-                       this.counter = 1;
-               }
-
-               value = this._adjustValue( value + step * this._increment( this.counter ) );
-
-               if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
-                       this._value( value );
-                       this.counter++;
-               }
-       },
-
-       _increment: function( i ) {
-               var incremental = this.options.incremental;
-
-               if ( incremental ) {
-                       return $.isFunction( incremental ) ?
-                               incremental( i ) :
-                               Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
-               }
-
-               return 1;
-       },
-
-       _precision: function() {
-               var precision = this._precisionOf( this.options.step );
-               if ( this.options.min !== null ) {
-                       precision = Math.max( precision, this._precisionOf( this.options.min ) );
-               }
-               return precision;
-       },
-
-       _precisionOf: function( num ) {
-               var str = num.toString(),
-                       decimal = str.indexOf( "." );
-               return decimal === -1 ? 0 : str.length - decimal - 1;
-       },
-
-       _adjustValue: function( value ) {
-               var base, aboveMin,
-                       options = this.options;
-
-               // make sure we're at a valid step
-               // - find out where we are relative to the base (min or 0)
-               base = options.min !== null ? options.min : 0;
-               aboveMin = value - base;
-               // - round to the nearest step
-               aboveMin = Math.round(aboveMin / options.step) * options.step;
-               // - rounding is based on 0, so adjust back to our base
-               value = base + aboveMin;
-
-               // fix precision from bad JS floating point math
-               value = parseFloat( value.toFixed( this._precision() ) );
-
-               // clamp the value
-               if ( options.max !== null && value > options.max) {
-                       return options.max;
-               }
-               if ( options.min !== null && value < options.min ) {
-                       return options.min;
-               }
-
-               return value;
-       },
-
-       _stop: function( event ) {
-               if ( !this.spinning ) {
-                       return;
-               }
-
-               clearTimeout( this.timer );
-               clearTimeout( this.mousewheelTimer );
-               this.counter = 0;
-               this.spinning = false;
-               this._trigger( "stop", event );
-       },
-
-       _setOption: function( key, value ) {
-               if ( key === "culture" || key === "numberFormat" ) {
-                       var prevValue = this._parse( this.element.val() );
-                       this.options[ key ] = value;
-                       this.element.val( this._format( prevValue ) );
-                       return;
-               }
-
-               if ( key === "max" || key === "min" || key === "step" ) {
-                       if ( typeof value === "string" ) {
-                               value = this._parse( value );
-                       }
-               }
-
-               this._super( key, value );
-
-               if ( key === "disabled" ) {
-                       if ( value ) {
-                               this.element.prop( "disabled", true );
-                               this.buttons.button( "disable" );
-                       } else {
-                               this.element.prop( "disabled", false );
-                               this.buttons.button( "enable" );
-                       }
-               }
-       },
-
-       _setOptions: modifier(function( options ) {
-               this._super( options );
-               this._value( this.element.val() );
-       }),
-
-       _parse: function( val ) {
-               if ( typeof val === "string" && val !== "" ) {
-                       val = window.Globalize && this.options.numberFormat ?
-                               Globalize.parseFloat( val, 10, this.options.culture ) : +val;
-               }
-               return val === "" || isNaN( val ) ? null : val;
-       },
-
-       _format: function( value ) {
-               if ( value === "" ) {
-                       return "";
-               }
-               return window.Globalize && this.options.numberFormat ?
-                       Globalize.format( value, this.options.numberFormat, this.options.culture ) :
-                       value;
-       },
-
-       _refresh: function() {
-               this.element.attr({
-                       "aria-valuemin": this.options.min,
-                       "aria-valuemax": this.options.max,
-                       // TODO: what should we do with values that can't be parsed?
-                       "aria-valuenow": this._parse( this.element.val() )
-               });
-       },
-
-       // update the value without triggering change
-       _value: function( value, allowAny ) {
-               var parsed;
-               if ( value !== "" ) {
-                       parsed = this._parse( value );
-                       if ( parsed !== null ) {
-                               if ( !allowAny ) {
-                                       parsed = this._adjustValue( parsed );
-                               }
-                               value = this._format( parsed );
-                       }
-               }
-               this.element.val( value );
-               this._refresh();
-       },
-
-       _destroy: function() {
-               this.element
-                       .removeClass( "ui-spinner-input" )
-                       .prop( "disabled", false )
-                       .removeAttr( "autocomplete" )
-                       .removeAttr( "role" )
-                       .removeAttr( "aria-valuemin" )
-                       .removeAttr( "aria-valuemax" )
-                       .removeAttr( "aria-valuenow" );
-               this.uiSpinner.replaceWith( this.element );
-       },
-
-       stepUp: modifier(function( steps ) {
-               this._stepUp( steps );
-       }),
-       _stepUp: function( steps ) {
-               this._spin( (steps || 1) * this.options.step );
-       },
-
-       stepDown: modifier(function( steps ) {
-               this._stepDown( steps );
-       }),
-       _stepDown: function( steps ) {
-               this._spin( (steps || 1) * -this.options.step );
-       },
-
-       pageUp: modifier(function( pages ) {
-               this._stepUp( (pages || 1) * this.options.page );
-       }),
-
-       pageDown: modifier(function( pages ) {
-               this._stepDown( (pages || 1) * this.options.page );
-       }),
-
-       value: function( newVal ) {
-               if ( !arguments.length ) {
-                       return this._parse( this.element.val() );
-               }
-               modifier( this._value ).call( this, newVal );
-       },
-
-       widget: function() {
-               return this.uiSpinner;
-       }
-});
-
-}( jQuery ) );
diff --git a/resources/lib/jquery.ui/themes/smoothness/jquery.ui.spinner.css b/resources/lib/jquery.ui/themes/smoothness/jquery.ui.spinner.css
deleted file mode 100644 (file)
index e89b720..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*!
- * jQuery UI Spinner 1.9.2
- * http://jqueryui.com
- *
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Spinner#theming
- */
-.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
-.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
-.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
-.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
-.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
-.ui-spinner-up { top: 0; }
-.ui-spinner-down { bottom: 0; }
-
-/* TR overrides */
-.ui-spinner .ui-icon-triangle-1-s {
-       /* need to fix icons sprite */
-       background-position:-65px -16px;
-}
diff --git a/resources/lib/jquery.xmldom.js b/resources/lib/jquery.xmldom.js
deleted file mode 100644 (file)
index 85d0083..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*!
- * jQuery xmlDOM Plugin v1.0
- * http://outwestmedia.com/jquery-plugins/xmldom/
- *
- * Released: 2009-04-06
- * Version: 1.0
- *
- * Copyright (c) 2009 Jonathan Sharp, Out West Media LLC.
- * Dual licensed under the MIT and GPL licenses.
- * http://docs.jquery.com/License
- */
-(function($) {
-       // IE DOMParser wrapper
-       if ( window['DOMParser'] == undefined && window.ActiveXObject ) {
-               DOMParser = function() { };
-               DOMParser.prototype.parseFromString = function( xmlString ) {
-                       var doc = new ActiveXObject('Microsoft.XMLDOM');
-               doc.async = 'false';
-               doc.loadXML( xmlString );
-                       return doc;
-               };
-       }
-       
-       $.xmlDOM = function(xml, onErrorFn) {
-               try {
-                       var xmlDoc      = ( new DOMParser() ).parseFromString( xml, 'text/xml' );
-                       if ( $.isXMLDoc( xmlDoc ) ) {
-                               var err = $('parsererror', xmlDoc);
-                               if ( err.length == 1 ) {
-                                       throw('Error: ' + $(xmlDoc).text() );
-                               }
-                       } else {
-                               throw('Unable to parse XML');
-                       }
-               } catch( e ) {
-                       var msg = ( e.name == undefined ? e : e.name + ': ' + e.message );
-                       if ( $.isFunction( onErrorFn ) ) {
-                               onErrorFn( msg );
-                       } else {
-                               $(document).trigger('xmlParseError', [ msg ]);
-                       }
-                       return $([]);
-               }
-               return $( xmlDoc );
-       };
-})(jQuery);
\ No newline at end of file
index aa1b831..4df7d1a 100644 (file)
@@ -2,6 +2,7 @@ The MIT License
 
 Copyright (c) 2009 Chris Wanstrath (Ruby)
 Copyright (c) 2010-2014 Jan Lehnardt (JavaScript)
+Copyright (c) 2010-2015 The mustache.js community
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 
index c7ffbef..8ec1b44 100644 (file)
@@ -3,54 +3,86 @@
  * http://github.com/janl/mustache.js
  */
 
-/*global define: false*/
+/*global define: false Mustache: true*/
 
-(function (global, factory) {
-  if (typeof exports === "object" && exports) {
+(function defineMustache (global, factory) {
+  if (typeof exports === 'object' && exports && typeof exports.nodeName !== 'string') {
     factory(exports); // CommonJS
-  } else if (typeof define === "function" && define.amd) {
+  } else if (typeof define === 'function' && define.amd) {
     define(['exports'], factory); // AMD
   } else {
-    factory(global.Mustache = {}); // <script>
+    global.Mustache = {};
+    factory(global.Mustache); // script, wsh, asp
   }
-}(this, function (mustache) {
+}(this, function mustacheFactory (mustache) {
 
-  var Object_toString = Object.prototype.toString;
-  var isArray = Array.isArray || function (object) {
-    return Object_toString.call(object) === '[object Array]';
+  var objectToString = Object.prototype.toString;
+  var isArray = Array.isArray || function isArrayPolyfill (object) {
+    return objectToString.call(object) === '[object Array]';
   };
 
-  function isFunction(object) {
+  function isFunction (object) {
     return typeof object === 'function';
   }
 
-  function escapeRegExp(string) {
-    return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
+  /**
+   * More correct typeof string handling array
+   * which normally returns typeof 'object'
+   */
+  function typeStr (obj) {
+    return isArray(obj) ? 'array' : typeof obj;
+  }
+
+  function escapeRegExp (string) {
+    return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
+  }
+
+  /**
+   * Null safe way of checking whether or not an object,
+   * including its prototype, has a given property
+   */
+  function hasProperty (obj, propName) {
+    return obj != null && typeof obj === 'object' && (propName in obj);
+  }
+
+  /**
+   * Safe way of detecting whether or not the given thing is a primitive and
+   * whether it has the given property
+   */
+  function primitiveHasOwnProperty (primitive, propName) {  
+    return (
+      primitive != null
+      && typeof primitive !== 'object'
+      && primitive.hasOwnProperty
+      && primitive.hasOwnProperty(propName)
+    );
   }
 
   // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
   // See https://github.com/janl/mustache.js/issues/189
-  var RegExp_test = RegExp.prototype.test;
-  function testRegExp(re, string) {
-    return RegExp_test.call(re, string);
+  var regExpTest = RegExp.prototype.test;
+  function testRegExp (re, string) {
+    return regExpTest.call(re, string);
   }
 
   var nonSpaceRe = /\S/;
-  function isWhitespace(string) {
+  function isWhitespace (string) {
     return !testRegExp(nonSpaceRe, string);
   }
 
   var entityMap = {
-    "&": "&amp;",
-    "<": "&lt;",
-    ">": "&gt;",
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
     '"': '&quot;',
     "'": '&#39;',
-    "/": '&#x2F;'
+    '/': '&#x2F;',
+    '`': '&#x60;',
+    '=': '&#x3D;'
   };
 
-  function escapeHtml(string) {
-    return String(string).replace(/[&<>"'\/]/g, function (s) {
+  function escapeHtml (string) {
+    return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) {
       return entityMap[s];
     });
   }
    * array of tokens in the subtree and 2) the index in the original template at
    * which the closing tag for that section begins.
    */
-  function parseTemplate(template, tags) {
+  function parseTemplate (template, tags) {
     if (!template)
       return [];
 
 
     // Strips all whitespace tokens array for the current line
     // if there was a {{#tag}} on it and otherwise only space.
-    function stripSpace() {
+    function stripSpace () {
       if (hasTag && !nonSpace) {
         while (spaces.length)
           delete tokens[spaces.pop()];
     }
 
     var openingTagRe, closingTagRe, closingCurlyRe;
-    function compileTags(tags) {
-      if (typeof tags === 'string')
-        tags = tags.split(spaceRe, 2);
+    function compileTags (tagsToCompile) {
+      if (typeof tagsToCompile === 'string')
+        tagsToCompile = tagsToCompile.split(spaceRe, 2);
 
-      if (!isArray(tags) || tags.length !== 2)
-        throw new Error('Invalid tags: ' + tags);
+      if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
+        throw new Error('Invalid tags: ' + tagsToCompile);
 
-      openingTagRe = new RegExp(escapeRegExp(tags[0]) + '\\s*');
-      closingTagRe = new RegExp('\\s*' + escapeRegExp(tags[1]));
-      closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tags[1]));
+      openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
+      closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
+      closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
     }
 
     compileTags(tags || mustache.tags);
    * Combines the values of consecutive text tokens in the given `tokens` array
    * to a single token.
    */
-  function squashTokens(tokens) {
+  function squashTokens (tokens) {
     var squashedTokens = [];
 
     var token, lastToken;
    * all tokens that appear in that section and 2) the index in the original
    * template that represents the end of that section.
    */
-  function nestTokens(tokens) {
+  function nestTokens (tokens) {
     var nestedTokens = [];
     var collector = nestedTokens;
     var sections = [];
       token = tokens[i];
 
       switch (token[0]) {
-      case '#':
-      case '^':
-        collector.push(token);
-        sections.push(token);
-        collector = token[4] = [];
-        break;
-      case '/':
-        section = sections.pop();
-        section[5] = token[2];
-        collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
-        break;
-      default:
-        collector.push(token);
+        case '#':
+        case '^':
+          collector.push(token);
+          sections.push(token);
+          collector = token[4] = [];
+          break;
+        case '/':
+          section = sections.pop();
+          section[5] = token[2];
+          collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
+          break;
+        default:
+          collector.push(token);
       }
     }
 
    * A simple string scanner that is used by the template parser to find
    * tokens in template strings.
    */
-  function Scanner(string) {
+  function Scanner (string) {
     this.string = string;
     this.tail = string;
     this.pos = 0;
   /**
    * Returns `true` if the tail is empty (end of string).
    */
-  Scanner.prototype.eos = function () {
-    return this.tail === "";
+  Scanner.prototype.eos = function eos () {
+    return this.tail === '';
   };
 
   /**
    * Tries to match the given regular expression at the current position.
    * Returns the matched text if it can match, the empty string otherwise.
    */
-  Scanner.prototype.scan = function (re) {
+  Scanner.prototype.scan = function scan (re) {
     var match = this.tail.match(re);
 
     if (!match || match.index !== 0)
    * Skips all text until the given regular expression can be matched. Returns
    * the skipped string, which is the entire tail if no match can be made.
    */
-  Scanner.prototype.scanUntil = function (re) {
+  Scanner.prototype.scanUntil = function scanUntil (re) {
     var index = this.tail.search(re), match;
 
     switch (index) {
-    case -1:
-      match = this.tail;
-      this.tail = "";
-      break;
-    case 0:
-      match = "";
-      break;
-    default:
-      match = this.tail.substring(0, index);
-      this.tail = this.tail.substring(index);
+      case -1:
+        match = this.tail;
+        this.tail = '';
+        break;
+      case 0:
+        match = '';
+        break;
+      default:
+        match = this.tail.substring(0, index);
+        this.tail = this.tail.substring(index);
     }
 
     this.pos += match.length;
    * Represents a rendering context by wrapping a view object and
    * maintaining a reference to the parent context.
    */
-  function Context(view, parentContext) {
-    this.view = view == null ? {} : view;
+  function Context (view, parentContext) {
+    this.view = view;
     this.cache = { '.': this.view };
     this.parent = parentContext;
   }
    * Creates a new context using the given view with this context
    * as the parent.
    */
-  Context.prototype.push = function (view) {
+  Context.prototype.push = function push (view) {
     return new Context(view, this);
   };
 
    * Returns the value of the given name in this context, traversing
    * up the context hierarchy if the value is absent in this context's view.
    */
-  Context.prototype.lookup = function (name) {
+  Context.prototype.lookup = function lookup (name) {
     var cache = this.cache;
 
     var value;
-    if (name in cache) {
+    if (cache.hasOwnProperty(name)) {
       value = cache[name];
     } else {
-      var context = this, names, index;
+      var context = this, intermediateValue, names, index, lookupHit = false;
 
       while (context) {
         if (name.indexOf('.') > 0) {
-          value = context.view;
+          intermediateValue = context.view;
           names = name.split('.');
           index = 0;
 
-          while (value != null && index < names.length)
-            value = value[names[index++]];
-        } else if (typeof context.view == 'object') {
-          value = context.view[name];
+          /**
+           * Using the dot notion path in `name`, we descend through the
+           * nested objects.
+           *
+           * To be certain that the lookup has been successful, we have to
+           * check if the last object in the path actually has the property
+           * we are looking for. We store the result in `lookupHit`.
+           *
+           * This is specially necessary for when the value has been set to
+           * `undefined` and we want to avoid looking up parent contexts.
+           *
+           * In the case where dot notation is used, we consider the lookup
+           * to be successful even if the last "object" in the path is
+           * not actually an object but a primitive (e.g., a string, or an
+           * integer), because it is sometimes useful to access a property
+           * of an autoboxed primitive, such as the length of a string.
+           **/
+          while (intermediateValue != null && index < names.length) {
+            if (index === names.length - 1)
+              lookupHit = (
+                hasProperty(intermediateValue, names[index]) 
+                || primitiveHasOwnProperty(intermediateValue, names[index])
+              );
+
+            intermediateValue = intermediateValue[names[index++]];
+          }
+        } else {
+          intermediateValue = context.view[name];
+
+          /**
+           * Only checking against `hasProperty`, which always returns `false` if
+           * `context.view` is not an object. Deliberately omitting the check
+           * against `primitiveHasOwnProperty` if dot notation is not used.
+           *
+           * Consider this example:
+           * ```
+           * Mustache.render("The length of a football field is {{#length}}{{length}}{{/length}}.", {length: "100 yards"})
+           * ```
+           *
+           * If we were to check also against `primitiveHasOwnProperty`, as we do
+           * in the dot notation case, then render call would return:
+           *
+           * "The length of a football field is 9."
+           *
+           * rather than the expected:
+           *
+           * "The length of a football field is 100 yards."
+           **/
+          lookupHit = hasProperty(context.view, name);
         }
 
-        if (value != null)
+        if (lookupHit) {
+          value = intermediateValue;
           break;
+        }
 
         context = context.parent;
       }
    * string, given a context. It also maintains a cache of templates to
    * avoid the need to parse the same template twice.
    */
-  function Writer() {
+  function Writer () {
     this.cache = {};
   }
 
   /**
    * Clears all cached templates in this writer.
    */
-  Writer.prototype.clearCache = function () {
+  Writer.prototype.clearCache = function clearCache () {
     this.cache = {};
   };
 
   /**
-   * Parses and caches the given `template` and returns the array of tokens
+   * Parses and caches the given `template` according to the given `tags` or
+   * `mustache.tags` if `tags` is omitted,  and returns the array of tokens
    * that is generated from the parse.
    */
-  Writer.prototype.parse = function (template, tags) {
+  Writer.prototype.parse = function parse (template, tags) {
     var cache = this.cache;
-    var tokens = cache[template];
+    var cacheKey = template + ':' + (tags || mustache.tags).join(':');
+    var tokens = cache[cacheKey];
 
     if (tokens == null)
-      tokens = cache[template] = parseTemplate(template, tags);
+      tokens = cache[cacheKey] = parseTemplate(template, tags);
 
     return tokens;
   };
    * names and templates of partials that are used in the template. It may
    * also be a function that is used to load partial templates on the fly
    * that takes a single argument: the name of the partial.
+   *
+   * If the optional `tags` argument is given here it must be an array with two
+   * string values: the opening and closing tags used in the template (e.g.
+   * [ "<%", "%>" ]). The default is to mustache.tags.
    */
-  Writer.prototype.render = function (template, view, partials) {
-    var tokens = this.parse(template);
+  Writer.prototype.render = function render (template, view, partials, tags) {
+    var tokens = this.parse(template, tags);
     var context = (view instanceof Context) ? view : new Context(view);
-    return this.renderTokens(tokens, context, partials, template);
+    return this.renderTokens(tokens, context, partials, template, tags);
   };
 
   /**
    * If the template doesn't use higher-order sections, this argument may
    * be omitted.
    */
-  Writer.prototype.renderTokens = function (tokens, context, partials, originalTemplate) {
+  Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, tags) {
     var buffer = '';
 
-    // This function is used to render an arbitrary template
-    // in the current context by higher-order sections.
-    var self = this;
-    function subRender(template) {
-      return self.render(template, context, partials);
-    }
-
-    var token, value;
+    var token, symbol, value;
     for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
+      value = undefined;
       token = tokens[i];
+      symbol = token[0];
 
-      switch (token[0]) {
-      case '#':
-        value = context.lookup(token[1]);
+      if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate);
+      else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate);
+      else if (symbol === '>') value = this.renderPartial(token, context, partials, tags);
+      else if (symbol === '&') value = this.unescapedValue(token, context);
+      else if (symbol === 'name') value = this.escapedValue(token, context);
+      else if (symbol === 'text') value = this.rawValue(token);
 
-        if (!value)
-          continue;
+      if (value !== undefined)
+        buffer += value;
+    }
 
-        if (isArray(value)) {
-          for (var j = 0, valueLength = value.length; j < valueLength; ++j) {
-            buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate);
-          }
-        } else if (typeof value === 'object' || typeof value === 'string') {
-          buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate);
-        } else if (isFunction(value)) {
-          if (typeof originalTemplate !== 'string')
-            throw new Error('Cannot use higher-order sections without the original template');
+    return buffer;
+  };
 
-          // Extract the portion of the original template that the section contains.
-          value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
+  Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate) {
+    var self = this;
+    var buffer = '';
+    var value = context.lookup(token[1]);
 
-          if (value != null)
-            buffer += value;
-        } else {
-          buffer += this.renderTokens(token[4], context, partials, originalTemplate);
-        }
+    // This function is used to render an arbitrary template
+    // in the current context by higher-order sections.
+    function subRender (template) {
+      return self.render(template, context, partials);
+    }
 
-        break;
-      case '^':
-        value = context.lookup(token[1]);
+    if (!value) return;
 
-        // Use JavaScript's definition of falsy. Include empty arrays.
-        // See https://github.com/janl/mustache.js/issues/186
-        if (!value || (isArray(value) && value.length === 0))
-          buffer += this.renderTokens(token[4], context, partials, originalTemplate);
+    if (isArray(value)) {
+      for (var j = 0, valueLength = value.length; j < valueLength; ++j) {
+        buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate);
+      }
+    } else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {
+      buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate);
+    } else if (isFunction(value)) {
+      if (typeof originalTemplate !== 'string')
+        throw new Error('Cannot use higher-order sections without the original template');
 
-        break;
-      case '>':
-        if (!partials)
-          continue;
+      // Extract the portion of the original template that the section contains.
+      value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
 
-        value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
+      if (value != null)
+        buffer += value;
+    } else {
+      buffer += this.renderTokens(token[4], context, partials, originalTemplate);
+    }
+    return buffer;
+  };
 
-        if (value != null)
-          buffer += this.renderTokens(this.parse(value), context, partials, value);
+  Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate) {
+    var value = context.lookup(token[1]);
 
-        break;
-      case '&':
-        value = context.lookup(token[1]);
+    // Use JavaScript's definition of falsy. Include empty arrays.
+    // See https://github.com/janl/mustache.js/issues/186
+    if (!value || (isArray(value) && value.length === 0))
+      return this.renderTokens(token[4], context, partials, originalTemplate);
+  };
 
-        if (value != null)
-          buffer += value;
+  Writer.prototype.renderPartial = function renderPartial (token, context, partials, tags) {
+    if (!partials) return;
 
-        break;
-      case 'name':
-        value = context.lookup(token[1]);
+    var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
+    if (value != null)
+      return this.renderTokens(this.parse(value, tags), context, partials, value);
+  };
 
-        if (value != null)
-          buffer += mustache.escape(value);
+  Writer.prototype.unescapedValue = function unescapedValue (token, context) {
+    var value = context.lookup(token[1]);
+    if (value != null)
+      return value;
+  };
 
-        break;
-      case 'text':
-        buffer += token[1];
-        break;
-      }
-    }
+  Writer.prototype.escapedValue = function escapedValue (token, context) {
+    var value = context.lookup(token[1]);
+    if (value != null)
+      return mustache.escape(value);
+  };
 
-    return buffer;
+  Writer.prototype.rawValue = function rawValue (token) {
+    return token[1];
   };
 
-  mustache.name = "mustache.js";
-  mustache.version = "1.0.0";
-  mustache.tags = [ "{{", "}}" ];
+  mustache.name = 'mustache.js';
+  mustache.version = '3.0.1';
+  mustache.tags = [ '{{', '}}' ];
 
   // All high-level mustache.* functions use this writer.
   var defaultWriter = new Writer();
   /**
    * Clears all cached templates in the default writer.
    */
-  mustache.clearCache = function () {
+  mustache.clearCache = function clearCache () {
     return defaultWriter.clearCache();
   };
 
    * array of tokens it contains. Doing this ahead of time avoids the need to
    * parse templates on the fly as they are rendered.
    */
-  mustache.parse = function (template, tags) {
+  mustache.parse = function parse (template, tags) {
     return defaultWriter.parse(template, tags);
   };
 
   /**
    * Renders the `template` with the given `view` and `partials` using the
-   * default writer.
+   * default writer. If the optional `tags` argument is given here it must be an
+   * array with two string values: the opening and closing tags used in the
+   * template (e.g. [ "<%", "%>" ]). The default is to mustache.tags.
    */
-  mustache.render = function (template, view, partials) {
-    return defaultWriter.render(template, view, partials);
+  mustache.render = function render (template, view, partials, tags) {
+    if (typeof template !== 'string') {
+      throw new TypeError('Invalid template! Template should be a "string" ' +
+                          'but "' + typeStr(template) + '" was given as the first ' +
+                          'argument for mustache#render(template, view, partials)');
+    }
+
+    return defaultWriter.render(template, view, partials, tags);
   };
 
-  // This is here for backwards compatibility with 0.4.x.
-  mustache.to_html = function (template, view, partials, send) {
+  // This is here for backwards compatibility with 0.4.x.,
+  /*eslint-disable */ // eslint wants camel cased function name
+  mustache.to_html = function to_html (template, view, partials, send) {
+    /*eslint-enable*/
+
     var result = mustache.render(template, view, partials);
 
     if (isFunction(send)) {
   mustache.Context = Context;
   mustache.Writer = Writer;
 
+  return mustache;
 }));
index 405130f..dd8c3bf 100644 (file)
@@ -1,4 +1,170 @@
 # OOUI Release History
+## v0.31.3 / 2019-04-03
+### Features
+* SelectFileInputWidget: Support multiple files (Ed Sanders)
+* WikimediaUI theme: Allow inverted icons to appear anywhere (Roan Kattouw)
+
+### Styles
+* CheckboxMultiselect- & RadioselectInputWidget: Fix infusion reflow (Volker E.)
+* DropdownInputWidget: Make WikimediaUI version useable for non-JS users (Volker E.)
+* WikimediaUI theme: Increase and unify widget `line-height` (Volker E.)
+* WikimediaUI theme: Reduce accessory icon's opacity in non-focussed state (Volker E.)
+* WikimediaUI theme: Unify inlined FieldLayout padding (Volker E.)
+* icons: Add 'error' icon to 'alerts' pack (Volker E.)
+* icons: Amend 'helpNotice' filename (Volker E.)
+* icons: Make 'error' octagon regular (Ed Sanders)
+
+### Code
+* SelectFile(Input)Widget: Remove addInput and inline setupInput (Ed Sanders)
+* SelectFileInputWidget: Make 'title' behaviour consistent (Ed Sanders)
+* build: Bump non-qunit devDependencies to latest where possible (Volker E.)
+* build: Do not duplicate localisation messages and their docs in JS code (Bartosz Dziewoński)
+* build: Have 'quick-build' use 'build-code' to include messages (Ed Sanders)
+* build: Remove unnecessary 'enable-source-maps' task (Bartosz Dziewoński)
+* build: We distribute icon/indicator/texture manifests, too (James D. Forrester)
+* demos: Add Vietnamese labels (Volker E.)
+* demos: Add `title` to LTR/RTL ButtonWidgets (Volker E.)
+* demos: Re-order PHP TextInput demo to align with the JS demo (Volker E.)
+* docs: Fix syntax errors in MenuLayout (Huji Lee)
+
+
+## v0.31.2 / 2019-03-26
+### Features
+* CheckboxInputWidget: Add support for indeterminate state (Ed Sanders & Bartosz Dziewoński)
+
+### Code
+* DropdownInputWidget: Fix typo in Apex border styles (Ed Sanders)
+* SelectFileInputWidget: Apply IE11 scrolling fix (Ed Sanders)
+* TextInputWidget: Remove proprietary vendor UI extensions (Volker E.)
+* PHP: Tag: Use strict comparison for `array_search` (Ed Sanders)
+* icons: Identical optimization to both newspaper-ltr… and …rtl.svg icons (Thiemo Kreuz)
+* icons: Make use of the auto-closing feature in SVG `<path>`s (Thiemo Kreuz)
+* icons: Remove non-standard offset from web.svg icon (Thiemo Kreuz)
+* demo: Match PHP toolbar to JS (Ed Sanders)
+* build: Update package-lock.json (Ed Sanders)
+* build: Upgrade js-yaml sub-dependency from 3.12.1 to 3.13.0 for DoS fix (James D. Forrester)
+* packages: Massively trim down which files are in npm and composer packages (James D. Forrester)
+
+
+## v0.31.1 / 2019-03-21
+### Deprecations
+* [DEPRECATING CHANGE] core: Remove unused Date.now fallback (Timo Tijhof)
+* [DEPRECATING CHANGE] textures: Deprecate 'pending.gif' (Volker E.)
+* [DEPRECATING CHANGE] textures: Deprecate unused 'transparency' (Volker E.)
+
+### Features
+* MenuTagMultiselectWidget: `hideOnChoose` should be set to false (Moriel Schottlender)
+* MenuTagMultiselectWidget: `highlightOnFilter` only if not `allowArbitrary` (Moriel Schottlender)
+* MenuTagMultiselectWidget: Fix highlight and scrolling to item behavior (Moriel Schottlender)
+* SearchInputWidget: Use click handler for indicator (Ed Sanders)
+* SelectWidget: Allow multiselect mode, add to MenuTagMultiselectWidget (Moriel Schottlender)
+* SelectFileWidget: Support a button-only mode (Ed Sanders)
+* SelectFileWidget: Suppress misleading browser default tooltips (Bartosz Dziewoński)
+* SelectFileInputWidget: Create as a super-class of SelectFileWidget (Ed Sanders)
+* SelectFileInputWidget: Allow button config to be passed (Ed Sanders)
+* TagMultiselectWidget: Edit by item label, not data (Moriel Schottlender)
+
+### Styles
+* Separate SelectFileWidget and SelectFileInputWidget styles (Ed Sanders)
+* themes: Provide `background` needed for PendingElement on inputs (Volker E.)
+* themes: Replace 'pending.gif' with CSS animation (Volker E.)
+* icons: Manually rewrite paths of tableMove….svg icons (Thiemo Kreuz)
+* icons: Recreate settings.svg icon with shorter syntax (Thiemo Kreuz)
+* icons: Remove invisible parts from web.svg icon (Thiemo Kreuz)
+* icons: Remove unused dotted borders from imageLayout….svg icons (Thiemo Kreuz)
+* icons: Use rounded <rect> elements to optimize some SVG icons (Thiemo Kreuz)
+
+### Code
+* MenuSectionOptionWidget: Avoid select events (Gabriel Birke)
+* SelectFileInputWidget: Rewrite as an ActionFieldLayout (Ed Sanders)
+* testsuitegenerator: Reduce PHP test count by 40% (Ed Sanders)
+* testsuitegenerator: Reduce some code duplication (Bartosz Dziewoński)
+* testsuitegenerator: Use normal methods more instead of lambdas (Bartosz Dziewoński)
+* docs: Clarify some types in documentation (Bartosz Dziewoński)
+* docs: Fix missing `;` and typos in documentation examples (Volker E.)
+* demos: Make demo toolbar narrower (Ed Sanders)
+* build: Specify library entry (Stephen Niedzielski)
+* Grunt: Add a quick-build-code task for JS-only quick builds (Ed Sanders)
+
+
+## v0.31.0 / 2019-03-13
+### Breaking changes
+* [BREAKING CHANGE] Remove FlaggedElement from InputWidget (Ed Sanders)
+* [BREAKING CHANGE] Remove method names deprecated in 0.28.3 (Ed Sanders)
+* [BREAKING CHANGE] indicators: Drop 'search', deprecated in v0.30.0 (James D. Forrester)
+* [BREAKING CHANGE]: Drop `iconTitle` and `indicatorTitle`, deprecated in v0.30.0 (James D. Forrester)
+
+### Features
+* Add 'success' message type (Volker E.)
+* Make mixin configs extendable (Ed Sanders)
+* PanelLayout: Create preserveContent config (Ed Sanders)
+* SelectFileWidget: Be consistent with showDropTarget requiring droppable (Ed Sanders)
+* SelectFileWidget: Mixin TabIndexedElement (Ed Sanders)
+* PHP: Added server-side version of IndexLayout (Cormac Parle)
+* PHP: Implement MenuLayout (Ed Sanders)
+* PHP: Implement StackLayout (Ed Sanders)
+* PHP: Implement TabPanelLayout (Ed Sanders)
+* PHP: Implement TabSelectWidget/TabOptionWidget (Ed Sanders)
+* PHP: Preserve content inside PanelLayout and test (Ed Sanders)
+
+### Styles
+* WikimediaUI theme: Fix ComboBoxInputWidget rounded corners (Bartosz Dziewoński)
+* WikimediaUI theme: Fix toolbar tools' `padding` (Volker E.)
+
+### Code
+* MenuLayout.php: Fix visiblity of properties and default config values (Ed Sanders)
+* Tag.php: Fix (ap/pre)pendContent to behave like JS DOM (Ed Sanders)
+* PHP tests: Only test ltr/rtl for 'dir', remove value='b' tests (Ed Sanders)
+* PHP tests: Only test one string for inputId (Ed Sanders)
+* demo: Unify demo navigation toolbars (Ed Sanders)
+* docs: Change docblock style for array elements in $config (Daimona Eaytoy)
+* build: Upgrade grunt-svg2png to 0.2.7-wmf.2 for audit fixes (James D. Forrester)
+* build: Upgrade imagemin-zopfli to 6.0.0 for audit fix (James D. Forrester)
+* build: Upgrade javascript-stringify to 2.0.0 for audit fix (James D. Forrester)
+* eslint: Enable cache (Ed Sanders)
+
+
+## v0.30.4 / 2019-03-06
+### Deprecations
+* [DEPRECATING CHANGE] SelectWidget: Rename '-depressed' to '-unpressed' (Ed Sanders)
+* [DEPRECATING CHANGE] icons: Deprecate 'web' from 'editing-citation' (Volker E.)
+
+### Features
+* Implement 'error' flag and 'warning' type messages (Volker E.)
+* MenuSelectWidget: Add 'filterMode' (Moriel Schottlender)
+
+### Styles
+* Apex theme: Bring icons and layout styles from WikimediaUI theme (Volker E.)
+* ButtonElement: Add styling for disabled active framed buttons (Bartosz Dziewoński)
+* icons: Snap 'camera' icon's frame to pixel grid (Ed Sanders)
+* icons: Add 'articleAdd' to 'content' pack (Volker E.)
+* icons: Add 'imageLayout…' icons to 'editing-advanced' pack (Volker E.)
+* WikimediaUI theme: De-emphasize `opacity` on TextInputWidget icons (Volker E.)
+* WikimediaUI theme: Give user messages more whitespace (Volker E.)
+* WikimediaUI theme: Place icons at top of message (Volker E.)
+* themes: Fix TagItemWidget's vertical alignment in Safari (Volker E.)
+* themes: Fix `padding` of label in DropdownWidget (Volker E.)
+* themes: Provide 'emphasized' color for messages (Volker E.)
+
+### Code
+* Consistently spell "access key" (Bartosz Dziewoński)
+* Follow-up I5991001e257: Add missing function call to normalize query (Ed Sanders)
+* Follow-up I5991001e: Do not filter item if query is empty (Moriel Schottlender)
+* MenuTagMultiselectWidget: Use 'highlightOnFilter' flag in MenuSelectWidget (Ed Sanders)
+* SelectWidget: Rewrite getItemMatcher without regular expressions (Ed Sanders)
+* Tag.php: Prevent duplicates in class list (Ed Sanders)
+* TextInputWidget: Reduce selector where applicable (Volker E.)
+* themes: Unify TextInput selector code (Volker E.)
+* build: Consistently indent .eslintrc.json files with tabs (Bartosz Dziewoński)
+* build: Enable eslint 'max-len' in code and fix (James D. Forrester)
+* build: Remove obsolete stylelint overrides (Volker E.)
+* build: Update eslint-config-wikimedia to 0.11.0 (Ed Sanders)
+* docs: Unify key names in documentation (Volker E.)
+* icons: Manually optimize the SVG code of some icons (Thiemo Kreuz)
+* icons: Re-crush with 'svgmin' build task (Volker E.)
+* icons: Remove redundant `ry="…"` SVG attribute when identical to `rx="…"` (Thiemo Kreuz)
+
+
 ## v0.30.3 / 2019-02-20
 ### Styles
 * WikimediaUI theme: Align TagItemWidget's close icon correctly (Volker E.)
 * ComboBoxInputWidget: Disable controls when widget is set to read-only (Ed Sanders)
 * MenuSelectWidget: Documentation fix (Ed Sanders)
 * ProgressBarWidget: Fix irregularities in indeterminate styling (Bartosz Dziewoński)
-* TagMultiselectWidget: Populate input with item label on backspace (Thalia Chan)
+* TagMultiselectWidget: Populate input with item label on Backspace key press (Thalia Chan)
 * Update getScrollLeft from upstream (Ed Sanders)
 * themes: Replace element by class attribute selector (Volker E.)
 * WikimediaUI theme: Remove variables with duplicated values (Volker E.)
 ## v0.22.4 / 2017-08-01
 ### Features
 * CheckboxMultiselectInputWidget: setValue when CheckboxMultiselect changes (Prateek Saxena)
-* FieldLayout: Show widget's accesskey in our title (Bartosz Dziewoński)
+* FieldLayout: Show widget's access key in our title (Bartosz Dziewoński)
 * TextInputWidget: When positioning label, don't clear padding if we will set it again (Bartosz Dziewoński)
 * TitledElement: When an AccessKeyedElement, show access key in the title (Bartosz Dziewoński)
 
 * Allow more widgets to be focussed programatically (Bartosz Dziewoński)
 * Generalize `.getInputId()` for all widgets (Bartosz Dziewoński)
 * Use `.focus()` method when possible instead of looking inside widgets (Bartosz Dziewoński)
-* TagMultiselectWidget: Fix `Ctrl`+`Backspace` to delete last item (Bartosz Dziewoński)
+* TagMultiselectWidget: Fix Control+Backspace keys to delete last item (Bartosz Dziewoński)
 * TagMultiselectWidget: Fix order of checks for `allowArbitrary`/`allowDuplicates` (Bartosz Dziewoński)
 
 ### Styles
 
 ## v0.19.1 / 2017-02-07
 ### Features
-* Dialog: Support meta as well as ctrl for modifier on enter key (David Lynch)
+* Dialog: Support Meta as well as Control for modifier on Enter key (David Lynch)
 
 ### Styles
 * FieldLayout: Fix styling for disabled widgets in PHP (Bartosz Dziewoński)
 * [DEPRECATING CHANGE] CapsuleMultiSelectWidget: Rename to CapsuleMultiselectWidget (Bartosz Dziewoński)
 
 ### Features
-* SelectWidget/OptionWidget: Implement selecting by accesskey (Bartosz Dziewoński)
+* SelectWidget/OptionWidget: Implement selecting by access key (Bartosz Dziewoński)
 * TextInputWidget: Stop returning 'multiline' from 'getSaneType' (Prateek Saxena)
 
 ### Styles
 * [DEPRECATING CHANGE] Move some editing icons from core to editing-* (James D. Forrester)
 
 ### Features
-* Dialog: trigger the primary action with ctrl-enter (David Lynch)
+* Dialog: trigger the primary action with Control+Enter (David Lynch)
 * TextInputWidget: Allow type="date" (Geoffrey Mon)
 
 ### Styles
 ## v0.15.3 / 2016-02-09
 ### Features
 * CapsuleItemWidget: Let user tab through items, edit and delete them (Prateek Saxena)
-* CapsuleMultiSelectWidget: Edit instead of remove on backspace (Prateek Saxena)
+* CapsuleMultiSelectWidget: Edit instead of remove on Backspace (Prateek Saxena)
 * CapsuleWidgets: Edit on click and remove on Ctrl+Backspace (Prateek Saxena)
 * CapsuleWidgets: Toggle through capsules and the input with arrow keys (Prateek Saxena)
 * DropdownWidget: Open menu on up and down arrow keys (Prateek Saxena)
 * [DEPRECATING CHANGE] core: Deprecate add/removeCaptureEventListener (Bartosz Dziewoński)
 
 ### Features
-* Send escape key cancel events through action handler (Alex Monk)
+* Send Escape key cancel events through action handler (Alex Monk)
 
 ### Styles
 * MediaWiki theme: Align variable values & properties to CSS/Less guidelines (Volker E)
 * FieldLayout: Use `<label>` for this.$body, not this.$element (Bartosz Dziewoński)
 * Fix primary button description text (Niklas Laxström)
 * GridLayout: Don't round to 1% (Bartosz Dziewoński)
-* Kill the escape keydown event after handling a window close (Ed Sanders)
+* Kill the Escape keydown event after handling a window close (Ed Sanders)
 * RadioInputWidget: Remove documentation lies (Bartosz Dziewoński)
 * Temporarily remove position:absolute on body when resizing (Ed Sanders)
 * build: Use String#slice instead of discouraged String#substr (Timo Tijhof)
index 2e06748..fa7db35 100644 (file)
@@ -21,7 +21,7 @@
        "ooui-dialog-message-accept": "TEMAM",
        "ooui-dialog-message-reject": "Bıtexelne",
        "ooui-dialog-process-error": "Tayê çi ğelet şi...",
-       "ooui-dialog-process-dismiss": "Racın",
+       "ooui-dialog-process-dismiss": "Red ke",
        "ooui-dialog-process-retry": "Fına bıcerbın",
        "ooui-dialog-process-continue": "Dewam ke",
        "ooui-combobox-button-label": "Seba qutiya abiyaye menu",
index e6e4463..ae6171d 100644 (file)
@@ -31,6 +31,7 @@
        "ooui-dialog-process-dismiss": "رد",
        "ooui-dialog-process-retry": "دوباره امتحان کنید",
        "ooui-dialog-process-continue": "ادامه",
+       "ooui-combobox-button-label": "پایین‌رونده برای جعبهٔ پایین‌رونده",
        "ooui-selectfile-button-select": "یک فایل انتخاب کنید",
        "ooui-selectfile-not-supported": "انتخاب پرونده پشتیبانی نمی‌شود",
        "ooui-selectfile-placeholder": "هیچ پرونده‌ای انتخاب نشده است",
index 22174f7..291ecd3 100644 (file)
@@ -22,6 +22,7 @@
        "ooui-dialog-process-dismiss": "Agochar",
        "ooui-dialog-process-retry": "Inténteo de novo",
        "ooui-dialog-process-continue": "Continuar",
+       "ooui-combobox-button-label": "Lista despregable para caixa combinada",
        "ooui-selectfile-button-select": "Seleccionar un ficheiro",
        "ooui-selectfile-not-supported": "Non está soportada a selección de ficheiros",
        "ooui-selectfile-placeholder": "Non se seleccionou ningún ficheiro",
index e8de4b2..40c77b2 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:07Z
+ * Date: 2019-04-04T19:10:48Z
  */
 ( function ( OO ) {
 
index dc56169..3a8b2b1 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
 .oo-ui-element-hidden {
   display: none !important;
   border-color: #ccc;
   box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus {
+  background-color: #ebebeb;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fafafa));
+  background-image: -webkit-linear-gradient(top, #ddd 0, #fafafa 100%);
+  background-image: -moz-linear-gradient(top, #ddd 0, #fafafa 100%);
+  background-image: linear-gradient(to bottom, #ddd 0, #fafafa 100%);
+  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+}
 
 .oo-ui-clippableElement-clippable {
   -webkit-box-sizing: border-box;
 }
 
 .oo-ui-pendingElement-pending {
-  background-image: /* @embed */ url(themes/wikimediaui/images/textures/pending.gif);
+  background-color: #ddd;
+  background-image: -webkit-linear-gradient(135deg, #fff 25%, transparent 25%, transparent 50%, #fff 50%, #fff 75%, transparent 75%, transparent);
+  background-image: -moz-linear-gradient(135deg, #fff 25%, transparent 25%, transparent 50%, #fff 50%, #fff 75%, transparent 75%, transparent);
+  background-image: linear-gradient(135deg, #fff 25%, transparent 25%, transparent 50%, #fff 50%, #fff 75%, transparent 75%, transparent);
+  background-size: 1.5625em 1.5625em;
+  -webkit-animation: oo-ui-pendingElement-stripes 650ms linear infinite;
+  -moz-animation: oo-ui-pendingElement-stripes 650ms linear infinite;
+  animation: oo-ui-pendingElement-stripes 650ms linear infinite;
+}
+@-webkit-keyframes oo-ui-pendingElement-stripes {
+  0% {
+    background-position: -1.5625em 0;
+  }
+  100% {
+    background-position: 0 0;
+  }
+}
+@-moz-keyframes oo-ui-pendingElement-stripes {
+  0% {
+    background-position: -1.5625em 0;
+  }
+  100% {
+    background-position: 0 0;
+  }
+}
+@keyframes oo-ui-pendingElement-stripes {
+  0% {
+    background-position: -1.5625em 0;
+  }
+  100% {
+    background-position: 0 0;
+  }
 }
 
 
 }
 .oo-ui-fieldLayout-messages {
   list-style: none none;
-  margin: 0;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  max-width: 50em;
+  margin: 0.25em 0 0 0.25em;
   padding: 0;
-  margin-top: 0.25em;
-  margin-left: 0.25em;
 }
 .oo-ui-fieldLayout-messages > [class|='oo-ui-fieldLayout-messages'] {
-  margin: 0;
+  color: #000;
+  display: table;
+  margin: 0.625em 0 0;
   padding: 0;
 }
-.oo-ui-fieldLayout-messages .oo-ui-iconWidget {
-  display: none;
+.oo-ui-fieldLayout-messages > [class|='oo-ui-fieldLayout-messages']:first-child {
+  margin-top: 0.3125em;
 }
 .oo-ui-fieldLayout-messages .oo-ui-fieldLayout-messages-error {
   color: #d45353;
 }
+.oo-ui-fieldLayout-messages .oo-ui-iconWidget.oo-ui-iconElement-icon {
+  background-position: 0 0;
+  display: table-cell;
+}
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
-  padding: 0.1em 0;
-  line-height: 1.5em;
+  display: table-cell;
+  padding-left: 0.5em;
+  line-height: 1.5;
   vertical-align: middle;
 }
 
@@ -641,7 +691,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-optionWidget .oo-ui-labelElement-label {
   line-height: 1.5em;
 }
-.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected {
+.oo-ui-selectWidget-unpressed .oo-ui-optionWidget-selected {
   background-color: #a7dcff;
 }
 .oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
@@ -1022,6 +1072,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body {
   padding: 0.3125em 0;
 }
+.oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-labelElement-label {
+  line-height: 1.5;
+}
 
 .oo-ui-dropdownInputWidget {
   position: relative;
@@ -1054,7 +1107,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   padding: 0.5em;
   font-size: inherit;
   font-family: inherit;
-  border: #ccc;
+  border: 1px solid #ccc;
   border-radius: 3px;
 }
 .oo-ui-dropdownInputWidget option {
@@ -1087,6 +1140,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body {
   padding: 0.3125em 0;
 }
+.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-labelElement-label {
+  line-height: 1.5;
+}
 
 .oo-ui-textInputWidget {
   position: relative;
@@ -1097,55 +1153,35 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   width: 100%;
   max-width: 50em;
 }
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
+.oo-ui-textInputWidget .oo-ui-inputWidget-input {
+  -webkit-appearance: none;
   display: block;
   width: 100%;
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
+.oo-ui-textInputWidget input {
+  -moz-appearance: textfield;
+}
+.oo-ui-textInputWidget input::-ms-clear {
+  display: none;
+}
 .oo-ui-textInputWidget textarea {
   overflow: auto;
 }
 .oo-ui-textInputWidget textarea.oo-ui-textInputWidget-autosized {
   resize: none;
 }
-.oo-ui-textInputWidget [type='number'] {
-  -moz-appearance: textfield;
-}
 .oo-ui-textInputWidget [type='number']::-webkit-outer-spin-button,
 .oo-ui-textInputWidget [type='number']::-webkit-inner-spin-button {
   -webkit-appearance: none;
   margin: 0;
 }
-.oo-ui-textInputWidget [type='search'] {
-  -webkit-appearance: none;
-}
-.oo-ui-textInputWidget [type='search']::-ms-clear {
-  display: none;
-}
 .oo-ui-textInputWidget [type='search']::-webkit-search-decoration,
 .oo-ui-textInputWidget [type='search']::-webkit-search-cancel-button {
   display: none;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-  cursor: text;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
-  cursor: pointer;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled > * {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-}
-.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
-  display: block;
-}
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
   left: 0;
@@ -1154,20 +1190,36 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
   right: 0;
 }
-.oo-ui-textInputWidget-labelPosition-after.oo-ui-labelElement ::-ms-clear {
-  display: none;
-}
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
   position: absolute;
   top: 0;
 }
+.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
+  display: block;
+}
+.oo-ui-textInputWidget-labelPosition-after.oo-ui-labelElement ::-ms-clear {
+  display: none;
+}
 .oo-ui-textInputWidget-php > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget-php > .oo-ui-indicatorElement-indicator,
 .oo-ui-textInputWidget-php > .oo-ui-labelElement-label {
   pointer-events: none;
 }
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
+  cursor: text;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
+  cursor: pointer;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled > * {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-textInputWidget .oo-ui-inputWidget-input {
   background-color: #fff;
   color: #000;
   border: 1px solid #ccc;
@@ -1180,69 +1232,14 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   -moz-transition: border-color 250ms, box-shadow 250ms;
   transition: border-color 250ms, box-shadow 250ms;
 }
-.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: #767676;
-  opacity: 1;
-}
-.oo-ui-textInputWidget input:-ms-input-placeholder,
-.oo-ui-textInputWidget textarea:-ms-input-placeholder {
-  color: #767676;
-  opacity: 1;
-}
-.oo-ui-textInputWidget input::-moz-placeholder,
-.oo-ui-textInputWidget textarea::-moz-placeholder {
-  color: #767676;
-  opacity: 1;
-}
-.oo-ui-textInputWidget input:-moz-placeholder,
-.oo-ui-textInputWidget textarea:-moz-placeholder {
-  color: #767676;
-  opacity: 1;
-}
-.oo-ui-textInputWidget input::placeholder,
-.oo-ui-textInputWidget textarea::placeholder {
-  color: #767676;
-  opacity: 1;
-}
 .oo-ui-textInputWidget input {
   line-height: 1.172em;
 }
 .oo-ui-textInputWidget textarea {
   line-height: 1.275;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-  outline: 0;
-  border-color: #ace;
-  box-shadow: 0 0 2px 2px #ace;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
-  background-color: #f3f3f3;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
-  background-color: #fdd;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled input,
-.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-  color: #ccc;
-  border-color: #ddd;
-  background-color: #f3f3f3;
-  text-shadow: 0 1px 1px #fff;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator {
-  opacity: 0.2;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled > .oo-ui-labelElement-label {
-  color: #ddd;
-  text-shadow: 0 1px 1px #fff;
+.oo-ui-textInputWidget .oo-ui-pendingElement-pending {
+  background-color: #ddd;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
@@ -1251,16 +1248,14 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   height: 100%;
   margin: 0 0.15625em;
 }
-.oo-ui-textInputWidget.oo-ui-iconElement input,
-.oo-ui-textInputWidget.oo-ui-iconElement textarea {
+.oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-inputWidget-input {
   padding-left: 2.475em;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon {
   max-height: 2.5em;
   margin-left: 0.5em;
 }
-.oo-ui-textInputWidget.oo-ui-indicatorElement input,
-.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
+.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-inputWidget-input {
   padding-right: 2.4875em;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
@@ -1268,11 +1263,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-right: 0.775em;
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
-  display: none;
+  color: #767676;
   top: 1px;
   padding: 0.546875em 0.4em 0.625em 0.4em;
   line-height: 1.172em;
-  color: #767676;
 }
 .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
   margin-right: 2.0875em;
@@ -1280,6 +1274,51 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
   margin-left: 2.075em;
 }
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input::-webkit-input-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:-ms-input-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input::-moz-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:-moz-placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input::placeholder {
+  color: #767676;
+  opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:focus {
+  outline: 0;
+  border-color: #ace;
+  box-shadow: 0 0 2px 2px #ace;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input[readonly] {
+  background-color: #f3f3f3;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid .oo-ui-inputWidget-input {
+  background-color: #fdd;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-inputWidget-input {
+  background-color: #f3f3f3;
+  color: #ccc;
+  border-color: #ddd;
+  text-shadow: 0 1px 1px #fff;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator {
+  opacity: 0.2;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled > .oo-ui-labelElement-label {
+  color: #ddd;
+  text-shadow: 0 1px 1px #fff;
+}
 
 .oo-ui-menuSelectWidget {
   position: absolute;
@@ -1395,6 +1434,12 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   right: 0;
   margin: 0 0.775em;
 }
+.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
+  margin-left: 3em;
+}
+.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle {
+  padding-right: 2.5em;
+}
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
   background-color: #fff;
 }
@@ -1414,12 +1459,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
   opacity: 0.2;
 }
-.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-  margin-left: 3em;
-}
-.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-  margin-right: 2em;
-}
 
 .oo-ui-comboBoxInputWidget {
   display: inline-block;
@@ -1655,6 +1694,68 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-left-width: 0;
 }
 
+.oo-ui-selectFileInputWidget {
+  width: 100%;
+  max-width: 50em;
+  margin-right: 0.5em;
+}
+.oo-ui-selectFileInputWidget-selectButton > .oo-ui-buttonElement-button {
+  position: relative;
+  overflow: hidden;
+}
+.oo-ui-selectFileInputWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  z-index: 1;
+  cursor: pointer;
+  padding-top: 100px;
+}
+.oo-ui-selectFileInputWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
+  display: none;
+}
+.oo-ui-selectFileInputWidget-info > .oo-ui-inputWidget-input {
+  pointer-events: none;
+}
+.oo-ui-selectFileInputWidget-label {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  text-overflow: ellipsis;
+}
+.oo-ui-selectFileInputWidget-clearButton {
+  position: absolute;
+  z-index: 2;
+}
+.oo-ui-selectFileInputWidget-empty .oo-ui-selectFileInputWidget-clearButton {
+  display: none;
+}
+.oo-ui-selectFileInputWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileInputWidget-label {
+  cursor: default;
+}
+.oo-ui-selectFileInputWidget:last-child {
+  margin-right: 0;
+}
+.oo-ui-selectFileInputWidget-label {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  left: 0.5em;
+  right: 2.175em;
+  line-height: 2.3em;
+  margin: 0;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+
 .oo-ui-defaultOverlay {
   position: absolute;
   top: 0;
index 8569532..c6cf8fa 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
 .oo-ui-element-hidden {
   display: none !important;
@@ -65,7 +65,7 @@
 }
 .oo-ui-buttonElement.oo-ui-labelElement > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  line-height: 1;
+  line-height: 1.28571429em;
 }
 .oo-ui-buttonElement.oo-ui-labelElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
   padding-right: 2.28571429em;
   border-color: transparent;
   border-style: solid;
   border-width: 1px;
-  padding: 0.57142857em 0.14285714em;
+  padding: 0.42857143em 0.14285714em;
 }
 .oo-ui-buttonElement-frameless.oo-ui-labelElement.oo-ui-iconElement > .oo-ui-buttonElement-button {
   padding-left: 2.14285714em;
 }
 .oo-ui-buttonElement-frameless.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
   padding-left: 0.14285714em;
-  padding-top: 0.57142857em;
+  padding-top: 0.42857143em;
 }
 .oo-ui-buttonElement-frameless.oo-ui-indicatorElement.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
   padding-left: 2.14285714em;
   padding-right: 2.28571429em;
 }
 .oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button {
-  padding-top: 0.57142857em;
-  padding-bottom: 0.57142857em;
+  padding-top: 0.42857143em;
+  padding-bottom: 0.42857143em;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
   background-color: #c8ccd1;
   color: #fff;
   border-color: #c8ccd1;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  background-color: #919fb9;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
   background-color: #f8f9fa;
   color: #222;
 }
 
 .oo-ui-pendingElement-pending {
-  background-image: /* @embed */ url(themes/wikimediaui/images/textures/pending.gif);
+  background-color: #eaecf0;
+  background-image: -webkit-linear-gradient(135deg, #fff 25%, transparent 25%, transparent 50%, #fff 50%, #fff 75%, transparent 75%, transparent);
+  background-image: -moz-linear-gradient(135deg, #fff 25%, transparent 25%, transparent 50%, #fff 50%, #fff 75%, transparent 75%, transparent);
+  background-image: linear-gradient(135deg, #fff 25%, transparent 25%, transparent 50%, #fff 50%, #fff 75%, transparent 75%, transparent);
+  background-size: 1.42857143em 1.42857143em;
+  -webkit-animation: oo-ui-pendingElement-stripes 650ms linear infinite;
+  -moz-animation: oo-ui-pendingElement-stripes 650ms linear infinite;
+  animation: oo-ui-pendingElement-stripes 650ms linear infinite;
+}
+@-webkit-keyframes oo-ui-pendingElement-stripes {
+  0% {
+    background-position: -1.42857143em 0;
+  }
+  100% {
+    background-position: 0 0;
+  }
+}
+@-moz-keyframes oo-ui-pendingElement-stripes {
+  0% {
+    background-position: -1.42857143em 0;
+  }
+  100% {
+    background-position: 0 0;
+  }
+}
+@keyframes oo-ui-pendingElement-stripes {
+  0% {
+    background-position: -1.42857143em 0;
+  }
+  100% {
+    background-position: 0 0;
+  }
 }
 
 
   padding: 0.28571429em 0.85714286em;
 }
 .oo-ui-fieldLayout-messages > [class|='oo-ui-fieldLayout-messages'] {
+  color: #000;
   display: table;
-  margin: 0.28571429em 0 0;
+  margin: 0.57142857em 0 0;
   padding: 0;
 }
-.oo-ui-fieldLayout-messages .oo-ui-iconElement.oo-ui-iconElement-icon {
+.oo-ui-fieldLayout-messages > [class|='oo-ui-fieldLayout-messages']:first-child {
+  margin-top: 0.28571429em;
+}
+.oo-ui-fieldLayout-messages .oo-ui-fieldLayout-messages-error {
+  color: #d33;
+}
+.oo-ui-fieldLayout-messages .oo-ui-fieldLayout-messages-success {
+  color: #14866d;
+}
+.oo-ui-fieldLayout-messages .oo-ui-iconWidget.oo-ui-iconElement-icon {
+  background-position: 0 0;
   display: table-cell;
-  position: static;
-  top: auto;
-  height: 1.42857143em;
 }
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
   display: table-cell;
-  padding-left: 0.42857143em;
+  padding-left: 0.57142857em;
   vertical-align: middle;
 }
 .oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label {
@@ -794,7 +836,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 
 .oo-ui-decoratedOptionWidget {
-  padding: 0.57142857em 0.85714286em;
+  padding: 0.42857143em 0.85714286em;
   line-height: 1;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-iconElement {
@@ -851,6 +893,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-radioOptionWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
   white-space: normal;
 }
+.oo-ui-radioOptionWidget:first-child {
+  margin-top: -0.28571429em;
+}
 .oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
   padding-left: 0.42857143em;
 }
@@ -1129,8 +1174,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   transition: width 100ms, height 100ms, left 100ms;
 }
 .oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-  margin: 0.64285714em 2.64285714em 0.57142857em 0.85714286em;
-  line-height: 1;
+  margin: 0.64285714em 2.64285714em 0.42857143em 0.85714286em;
+  line-height: 1.28571429em;
 }
 .oo-ui-popupWidget-head > .oo-ui-buttonWidget {
   right: 0;
@@ -1142,13 +1187,13 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   line-height: 1.42857143em;
 }
 .oo-ui-popupWidget-body-padded {
-  margin: 0.64285714em 0.85714286em 0.57142857em;
+  margin: 0.64285714em 0.85714286em 0.42857143em;
 }
 .oo-ui-popupWidget-body-padded > :first-child {
   margin-top: 0;
 }
 .oo-ui-popupWidget-footer {
-  margin: 0.64285714em 0.85714286em 0.57142857em;
+  margin: 0.64285714em 0.85714286em 0.42857143em;
 }
 
 .oo-ui-popupButtonWidget {
@@ -1209,6 +1254,20 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-checkboxInputWidget [type='checkbox']:checked + span {
   background-size: 1em 1em;
 }
+.oo-ui-checkboxInputWidget [type='checkbox']:indeterminate + span {
+  background-image: none;
+  background-color: #36c;
+  border-color: #36c;
+}
+.oo-ui-checkboxInputWidget [type='checkbox']:indeterminate + span:before {
+  content: ' ';
+  position: absolute;
+  top: 0.57142857em;
+  bottom: 0.57142857em;
+  left: 0.21428571em;
+  right: 0.21428571em;
+  background-color: #fff;
+}
 .oo-ui-checkboxInputWidget [type='checkbox']:disabled + span {
   background-color: #c8ccd1;
   border-color: #c8ccd1;
@@ -1254,7 +1313,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout {
-  margin-top: 0.28571429em;
+  margin-top: 0;
+  padding: 0.28571429em 0;
+}
+.oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout:first-child {
+  margin-top: -0.28571429em;
 }
 
 .oo-ui-dropdownInputWidget {
@@ -1282,20 +1345,18 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select {
   cursor: pointer;
 }
-.oo-ui-dropdownInputWidget-php {
-  border-right: 1px solid #a2a9b1;
-  border-radius: 2px;
-  overflow-x: hidden;
-}
 .oo-ui-dropdownInputWidget select {
   -webkit-appearance: none;
   -moz-appearance: none;
+  background-color: transparent;
+  background-position: right 0.85714286em center;
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
+  height: 2.28571429em;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding: 0.57142857em 0.85714286em;
+  padding: 0.42857143em 0.85714286em;
   font-size: inherit;
   font-family: inherit;
   vertical-align: middle;
@@ -1303,27 +1364,35 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-dropdownInputWidget select::-ms-expand {
   display: none;
 }
-.oo-ui-dropdownInputWidget select:not( [no-ie] ) {
-  background-position: right 1.75em center;
-  width: calc( 100% + 1em );
-  height: 2.28571429em;
-  padding: 0 0 0 0.85714286em;
+@media screen and (min-width: 0 \0 ) {
+  .oo-ui-dropdownInputWidget select select {
+    background-image: none\9;
+    padding: 5px\9;
+  }
 }
 .oo-ui-dropdownInputWidget option {
+  background-color: transparent;
   font-size: inherit;
   font-family: inherit;
   height: 1.5em;
-  padding: 0.57142857em 0.85714286em;
+  padding: 0.42857143em 0.85714286em;
 }
-.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select {
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled {
   background-color: #f8f9fa;
+  -webkit-transition: background-color 100ms;
+  -moz-transition: background-color 100ms;
+  transition: background-color 100ms;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled:hover {
+  background-color: #fff;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select {
   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;
+  -webkit-transition: border-color 100ms, box-shadow 100ms;
+  -moz-transition: border-color 100ms, box-shadow 100ms;
+  transition: border-color 100ms, box-shadow 100ms;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover {
-  background-color: #fff;
   color: #444;
   border-color: #a2a9b1;
 }
@@ -1336,8 +1405,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   outline: 0;
   box-shadow: inset 0 0 0 1px #36c;
 }
-.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
+.oo-ui-dropdownInputWidget.oo-ui-widget-disabled {
   background-color: #eaecf0;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
   color: #72777d;
   border-color: #c8ccd1;
 }
@@ -1430,7 +1501,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
-  margin-top: 0.28571429em;
+  margin-top: 0;
+  padding: 0.28571429em 0;
+}
+.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout:first-child {
+  margin-top: -0.28571429em;
 }
 
 .oo-ui-textInputWidget {
@@ -1442,55 +1517,35 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   width: 100%;
   max-width: 50em;
 }
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
+.oo-ui-textInputWidget .oo-ui-inputWidget-input {
+  -webkit-appearance: none;
   display: block;
   width: 100%;
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
+.oo-ui-textInputWidget input {
+  -moz-appearance: textfield;
+}
+.oo-ui-textInputWidget input::-ms-clear {
+  display: none;
+}
 .oo-ui-textInputWidget textarea {
   overflow: auto;
 }
 .oo-ui-textInputWidget textarea.oo-ui-textInputWidget-autosized {
   resize: none;
 }
-.oo-ui-textInputWidget [type='number'] {
-  -moz-appearance: textfield;
-}
 .oo-ui-textInputWidget [type='number']::-webkit-outer-spin-button,
 .oo-ui-textInputWidget [type='number']::-webkit-inner-spin-button {
   -webkit-appearance: none;
   margin: 0;
 }
-.oo-ui-textInputWidget [type='search'] {
-  -webkit-appearance: none;
-}
-.oo-ui-textInputWidget [type='search']::-ms-clear {
-  display: none;
-}
 .oo-ui-textInputWidget [type='search']::-webkit-search-decoration,
 .oo-ui-textInputWidget [type='search']::-webkit-search-cancel-button {
   display: none;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-  cursor: text;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
-  cursor: pointer;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled > * {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-}
-.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
-  display: block;
-}
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
   left: 0;
@@ -1499,114 +1554,153 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
   right: 0;
 }
-.oo-ui-textInputWidget-labelPosition-after.oo-ui-labelElement ::-ms-clear {
-  display: none;
-}
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
   position: absolute;
   top: 0;
 }
+.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
+  display: block;
+}
+.oo-ui-textInputWidget-labelPosition-after.oo-ui-labelElement ::-ms-clear {
+  display: none;
+}
 .oo-ui-textInputWidget-php > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget-php > .oo-ui-indicatorElement-indicator,
 .oo-ui-textInputWidget-php > .oo-ui-labelElement-label {
   pointer-events: none;
 }
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
-  -webkit-appearance: none;
-  margin: 0;
-  font-size: inherit;
-  font-family: inherit;
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
+  cursor: text;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
+  cursor: pointer;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled > * {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-textInputWidget .oo-ui-inputWidget-input {
   background-color: #fff;
   color: #000;
+  margin: 0;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding: 0.57142857em 0.57142857em;
+  padding: 0.42857143em 0.57142857em;
+  font-size: inherit;
+  font-family: inherit;
+  line-height: 1.28571429em;
 }
 .oo-ui-textInputWidget input {
   height: 2.28571429em;
-  line-height: 1;
-}
-.oo-ui-textInputWidget textarea {
-  line-height: 1.286;
 }
 .oo-ui-textInputWidget .oo-ui-pendingElement-pending {
-  background-color: transparent;
+  background-color: #eaecf0;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-inputWidget-input {
+  padding-left: 2.64285714em;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon {
+  left: 0.57142857em;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement textarea + .oo-ui-iconElement-icon {
+  max-height: 2.28571429em;
+}
+.oo-ui-textInputWidget > .oo-ui-labelElement-label {
+  color: #72777d;
+  margin-top: 1px;
+  padding: 0.42857143em 0.85714286em 0.42857143em 0.57142857em;
+  line-height: 1.28571429em;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-inputWidget-input {
+  padding-right: 2em;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
+  padding-right: 0;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
+  max-height: 2.28571429em;
+  margin-right: 0.85714286em;
+}
+.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
+  margin-right: 2.28571429em;
+}
+.oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
+  padding-left: 2.64285714em;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input {
   box-shadow: inset 0 0 0 1px transparent;
   -webkit-transition: border-color 250ms, box-shadow 250ms;
   -moz-transition: border-color 250ms, box-shadow 250ms;
   transition: border-color 250ms, box-shadow 250ms;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input::-webkit-input-placeholder,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea::-webkit-input-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input::-webkit-input-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input:-ms-input-placeholder,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:-ms-input-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:-ms-input-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input::-moz-placeholder,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea::-moz-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input::-moz-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input:-moz-placeholder,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:-moz-placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:-moz-placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input::placeholder,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea::placeholder {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input::placeholder {
   color: #72777d;
   opacity: 1;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:focus {
   outline: 0;
   border-color: #36c;
   box-shadow: inset 0 0 0 1px #36c;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:focus ~ .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input:focus ~ .oo-ui-indicatorElement-indicator {
+  opacity: 1;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled .oo-ui-inputWidget-input[readonly] {
   background-color: #f8f9fa;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled:hover input,
-.oo-ui-textInputWidget.oo-ui-widget-enabled:hover textarea {
+.oo-ui-textInputWidget.oo-ui-widget-enabled:hover .oo-ui-inputWidget-input {
   border-color: #72777d;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled:hover input:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled:hover textarea:focus {
+.oo-ui-textInputWidget.oo-ui-widget-enabled:hover .oo-ui-inputWidget-input:focus {
   border-color: #36c;
 }
 @media screen and (min-width: 0) {
-  .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
+  .oo-ui-textInputWidget.oo-ui-widget-enabled textarea.oo-ui-inputWidget-input:focus {
     outline: 1px solid #36c;
     outline-offset: -2px;
   }
-  .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:focus {
+  .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea.oo-ui-inputWidget-input:focus {
     outline-color: #d33;
   }
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon {
+  opacity: 0.67;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
+  opacity: 0.87;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid .oo-ui-inputWidget-input {
   border-color: #d33;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:hover,
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:hover {
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid .oo-ui-inputWidget-input:hover {
   border-color: #d33;
 }
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:focus {
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid .oo-ui-inputWidget-input:focus {
   border-color: #d33;
   box-shadow: inset 0 0 0 1px #d33;
 }
-.oo-ui-textInputWidget.oo-ui-widget-disabled input,
-.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-inputWidget-input {
   background-color: #eaecf0;
   -webkit-text-fill-color: #72777d;
   color: #72777d;
@@ -1621,39 +1715,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   color: #72777d;
   text-shadow: 0 1px 1px #fff;
 }
-.oo-ui-textInputWidget.oo-ui-iconElement input,
-.oo-ui-textInputWidget.oo-ui-iconElement textarea {
-  padding-left: 2.64285714em;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon {
-  left: 0.57142857em;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement textarea + .oo-ui-iconElement-icon {
-  max-height: 2.28571429em;
-}
-.oo-ui-textInputWidget > .oo-ui-labelElement-label {
-  color: #72777d;
-  margin-top: 1px;
-  padding: 0.57142857em 0.85714286em 0.57142857em 0.57142857em;
-  line-height: 1;
-}
-.oo-ui-textInputWidget.oo-ui-indicatorElement input,
-.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
-  padding-right: 2em;
-}
-.oo-ui-textInputWidget.oo-ui-indicatorElement.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
-  padding-right: 0;
-}
-.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
-  max-height: 2.28571429em;
-  margin-right: 0.85714286em;
-}
-.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-  margin-right: 2.28571429em;
-}
-.oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
-  padding-left: 2.64285714em;
-}
 
 .oo-ui-menuSelectWidget {
   position: absolute;
@@ -1700,7 +1761,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 
 .oo-ui-menuSectionOptionWidget {
   color: #72777d;
-  padding: 0.57142857em 0.85714286em 0.28571429em;
+  padding: 0.42857143em 0.85714286em 0.28571429em;
   font-weight: bold;
 }
 .oo-ui-menuSectionOptionWidget.oo-ui-widget-enabled {
@@ -1759,7 +1820,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   min-height: 2.28571429em;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding: 0.57142857em 0.85714286em;
+  padding: 0.42857143em 0.85714286em;
   line-height: 1;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
@@ -1769,13 +1830,13 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   right: 0.78571429em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-  line-height: 1;
+  line-height: 1.28571429em;
 }
 .oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle {
   padding-left: 2.64285714em;
 }
 .oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle {
-  padding-right: 1.71428571em;
+  padding-right: 2.57142857em;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
   background-color: #f8f9fa;
@@ -1870,14 +1931,14 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   height: 100%;
   pointer-events: none;
 }
-.oo-ui-comboBoxInputWidget input {
+.oo-ui-comboBoxInputWidget .oo-ui-inputWidget-input {
   height: 2.28571429em;
   border-top-right-radius: 0;
   border-bottom-right-radius: 0;
   border-right-width: 0;
 }
-.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty input,
-.oo-ui-comboBoxInputWidget-php input {
+.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty .oo-ui-inputWidget-input,
+.oo-ui-comboBoxInputWidget-php .oo-ui-inputWidget-input {
   border-top-right-radius: 2px;
   border-bottom-right-radius: 2px;
   border-right-width: 1px;
@@ -1950,6 +2011,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
   white-space: normal;
 }
+.oo-ui-checkboxMultioptionWidget:first-child {
+  margin-top: -0.28571429em;
+}
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
   padding-left: 0.42857143em;
 }
@@ -2082,6 +2146,70 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   opacity: 1;
 }
 
+.oo-ui-selectFileInputWidget {
+  width: 100%;
+  max-width: 50em;
+  margin-right: 0.5em;
+}
+.oo-ui-selectFileInputWidget-selectButton > .oo-ui-buttonElement-button {
+  position: relative;
+  overflow: hidden;
+}
+.oo-ui-selectFileInputWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  z-index: 1;
+  cursor: pointer;
+  padding-top: 100px;
+}
+.oo-ui-selectFileInputWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
+  display: none;
+}
+.oo-ui-selectFileInputWidget-info > .oo-ui-inputWidget-input {
+  pointer-events: none;
+}
+.oo-ui-selectFileInputWidget-label {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  text-overflow: ellipsis;
+}
+.oo-ui-selectFileInputWidget-clearButton {
+  position: absolute;
+  z-index: 2;
+}
+.oo-ui-selectFileInputWidget-empty .oo-ui-selectFileInputWidget-clearButton {
+  display: none;
+}
+.oo-ui-selectFileInputWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileInputWidget-label {
+  cursor: default;
+}
+.oo-ui-selectFileInputWidget:last-child {
+  margin-right: 0;
+}
+.oo-ui-selectFileInputWidget-label {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  display: block;
+  right: 2.85714286em;
+  padding-top: 0.42857143em;
+  padding-left: 0.57142857em;
+  padding-bottom: 0.42857143em;
+  white-space: nowrap;
+}
+.oo-ui-selectFileInputWidget.oo-ui-labelElement .oo-ui-selectFileInputWidget-label {
+  line-height: 1.28571429em;
+}
+
 .oo-ui-defaultOverlay {
   position: absolute;
   top: 0;
index 72b1e05..2bb08e0 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:07Z
+ * Date: 2019-04-04T19:10:48Z
  */
 ( function ( OO ) {
 
@@ -127,7 +127,7 @@ OO.ui.isFocusableElement = function ( $element ) {
 };
 
 /**
- * Find a focusable child
+ * Find a focusable child.
  *
  * @param {jQuery} $container Container to search in
  * @param {boolean} [backwards] Search backwards
@@ -204,14 +204,15 @@ OO.ui.getLocalValue = function ( obj, lang, fallback ) {
 };
 
 /**
- * Check if a node is contained within another node
+ * Check if a node is contained within another node.
  *
  * Similar to jQuery#contains except a list of containers can be supplied
  * and a boolean argument allows you to include the container in the match list
  *
  * @param {HTMLElement|HTMLElement[]} containers Container node(s) to search in
  * @param {HTMLElement} contained Node to find
- * @param {boolean} [matchContainers] Include the container(s) in the list of nodes to match, otherwise only match descendants
+ * @param {boolean} [matchContainers] Include the container(s) in the list of nodes to match,
+ *  otherwise only match descendants
  * @return {boolean} The node is in the list of target nodes
  */
 OO.ui.contains = function ( containers, contained, matchContainers ) {
@@ -220,7 +221,10 @@ OO.ui.contains = function ( containers, contained, matchContainers ) {
                containers = [ containers ];
        }
        for ( i = containers.length - 1; i >= 0; i-- ) {
-               if ( ( matchContainers && contained === containers[ i ] ) || $.contains( containers[ i ], contained ) ) {
+               if (
+                       ( matchContainers && contained === containers[ i ] ) ||
+                       $.contains( containers[ i ], contained )
+               ) {
                        return true;
                }
        }
@@ -291,7 +295,7 @@ OO.ui.throttle = function ( func, wait ) {
                previous = 0,
                run = function () {
                        timeout = null;
-                       previous = OO.ui.now();
+                       previous = Date.now();
                        func.apply( context, args );
                };
        return function () {
@@ -300,7 +304,7 @@ OO.ui.throttle = function ( func, wait ) {
                // period. If it's less, run the function immediately. If it's more,
                // set a timeout for the remaining time -- but don't replace an
                // existing timeout, since that'd indefinitely prolong the wait.
-               var remaining = wait - ( OO.ui.now() - previous );
+               var remaining = wait - ( Date.now() - previous );
                context = this;
                args = arguments;
                if ( remaining <= 0 ) {
@@ -317,12 +321,14 @@ OO.ui.throttle = function ( func, wait ) {
 };
 
 /**
- * A (possibly faster) way to get the current timestamp as an integer
+ * A (possibly faster) way to get the current timestamp as an integer.
  *
+ * @deprecated Since 0.31.1; use `Date.now()` instead.
  * @return {number} Current timestamp, in milliseconds since the Unix epoch
  */
-OO.ui.now = Date.now || function () {
-       return new Date().getTime();
+OO.ui.now = function () {
+       OO.ui.warnDeprecation( 'OO.ui.now() is deprecated, use Date.now() instead' );
+       return Date.now();
 };
 
 /**
@@ -341,122 +347,74 @@ OO.ui.infuse = function ( idOrNode, config ) {
        return OO.ui.Element.static.infuse( idOrNode, config );
 };
 
-( function () {
-       /**
-        * Message store for the default implementation of OO.ui.msg
-        *
-        * Environments that provide a localization system should not use this, but should override
-        * OO.ui.msg altogether.
-        *
-        * @private
-        */
-       var messages = {
-               // Tool tip for a button that moves items in a list down one place
-               'ooui-outline-control-move-down': 'Move item down',
-               // Tool tip for a button that moves items in a list up one place
-               'ooui-outline-control-move-up': 'Move item up',
-               // Tool tip for a button that removes items from a list
-               'ooui-outline-control-remove': 'Remove item',
-               // Label for the toolbar group that contains a list of all other available tools
-               'ooui-toolbar-more': 'More',
-               // Label for the fake tool that expands the full list of tools in a toolbar group
-               'ooui-toolgroup-expand': 'More',
-               // Label for the fake tool that collapses the full list of tools in a toolbar group
-               'ooui-toolgroup-collapse': 'Fewer',
-               // Default label for the tooltip for the button that removes a tag item
-               'ooui-item-remove': 'Remove',
-               // Default label for the accept button of a confirmation dialog
-               'ooui-dialog-message-accept': 'OK',
-               // Default label for the reject button of a confirmation dialog
-               'ooui-dialog-message-reject': 'Cancel',
-               // Title for process dialog error description
-               'ooui-dialog-process-error': 'Something went wrong',
-               // Label for process dialog dismiss error button, visible when describing errors
-               'ooui-dialog-process-dismiss': 'Dismiss',
-               // Label for process dialog retry action button, visible when describing only recoverable errors
-               'ooui-dialog-process-retry': 'Try again',
-               // Label for process dialog retry action button, visible when describing only warnings
-               'ooui-dialog-process-continue': 'Continue',
-               // Label for button in combobox input that triggers its dropdown
-               'ooui-combobox-button-label': 'Dropdown for combobox',
-               // Label for the file selection widget's select file button
-               'ooui-selectfile-button-select': 'Select a file',
-               // Label for the file selection widget if file selection is not supported
-               'ooui-selectfile-not-supported': 'File selection is not supported',
-               // Label for the file selection widget when no file is currently selected
-               'ooui-selectfile-placeholder': 'No file is selected',
-               // Label for the file selection widget's drop target
-               'ooui-selectfile-dragdrop-placeholder': 'Drop file here',
-               // Label for the help icon attached to a form field
-               'ooui-field-help': 'Help'
-       };
-
-       /**
-        * Get a localized message.
-        *
-        * After the message key, message parameters may optionally be passed. In the default implementation,
-        * any occurrences of $1 are replaced with the first parameter, $2 with the second parameter, etc.
-        * Alternative implementations of OO.ui.msg may use any substitution system they like, as long as
-        * they support unnamed, ordered message parameters.
-        *
-        * In environments that provide a localization system, this function should be overridden to
-        * return the message translated in the user's language. The default implementation always returns
-        * English messages. An example of doing this with [jQuery.i18n](https://github.com/wikimedia/jquery.i18n)
-        * follows.
-        *
-        *     @example
-        *     var i, iLen, button,
-        *         messagePath = 'oojs-ui/dist/i18n/',
-        *         languages = [ $.i18n().locale, 'ur', 'en' ],
-        *         languageMap = {};
-        *
-        *     for ( i = 0, iLen = languages.length; i < iLen; i++ ) {
-        *         languageMap[ languages[ i ] ] = messagePath + languages[ i ].toLowerCase() + '.json';
-        *     }
-        *
-        *     $.i18n().load( languageMap ).done( function() {
-        *         // Replace the built-in `msg` only once we've loaded the internationalization.
-        *         // OOUI uses `OO.ui.deferMsg` for all initially-loaded messages. So long as
-        *         // you put off creating any widgets until this promise is complete, no English
-        *         // will be displayed.
-        *         OO.ui.msg = $.i18n;
-        *
-        *         // A button displaying "OK" in the default locale
-        *         button = new OO.ui.ButtonWidget( {
-        *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),
-        *             icon: 'check'
-        *         } );
-        *         $( document.body ).append( button.$element );
-        *
-        *         // A button displaying "OK" in Urdu
-        *         $.i18n().locale = 'ur';
-        *         button = new OO.ui.ButtonWidget( {
-        *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),
-        *             icon: 'check'
-        *         } );
-        *         $( document.body ).append( button.$element );
-        *     } );
-        *
-        * @param {string} key Message key
-        * @param {...Mixed} [params] Message parameters
-        * @return {string} Translated message with parameters substituted
-        */
-       OO.ui.msg = function ( key ) {
-               var message = messages[ key ],
-                       params = Array.prototype.slice.call( arguments, 1 );
-               if ( typeof message === 'string' ) {
-                       // Perform $1 substitution
-                       message = message.replace( /\$(\d+)/g, function ( unused, n ) {
-                               var i = parseInt( n, 10 );
-                               return params[ i - 1 ] !== undefined ? params[ i - 1 ] : '$' + n;
-                       } );
-               } else {
-                       // Return placeholder if message not found
-                       message = '[' + key + ']';
-               }
-               return message;
-       };
-}() );
+/**
+ * Get a localized message.
+ *
+ * After the message key, message parameters may optionally be passed. In the default
+ * implementation, any occurrences of $1 are replaced with the first parameter, $2 with the
+ * second parameter, etc.
+ * Alternative implementations of OO.ui.msg may use any substitution system they like, as long
+ * as they support unnamed, ordered message parameters.
+ *
+ * In environments that provide a localization system, this function should be overridden to
+ * return the message translated in the user's language. The default implementation always
+ * returns English messages. An example of doing this with
+ * [jQuery.i18n](https://github.com/wikimedia/jquery.i18n) follows.
+ *
+ *     @example
+ *     var i, iLen, button,
+ *         messagePath = 'oojs-ui/dist/i18n/',
+ *         languages = [ $.i18n().locale, 'ur', 'en' ],
+ *         languageMap = {};
+ *
+ *     for ( i = 0, iLen = languages.length; i < iLen; i++ ) {
+ *         languageMap[ languages[ i ] ] = messagePath + languages[ i ].toLowerCase() + '.json';
+ *     }
+ *
+ *     $.i18n().load( languageMap ).done( function() {
+ *         // Replace the built-in `msg` only once we've loaded the internationalization.
+ *         // OOUI uses `OO.ui.deferMsg` for all initially-loaded messages. So long as
+ *         // you put off creating any widgets until this promise is complete, no English
+ *         // will be displayed.
+ *         OO.ui.msg = $.i18n;
+ *
+ *         // A button displaying "OK" in the default locale
+ *         button = new OO.ui.ButtonWidget( {
+ *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),
+ *             icon: 'check'
+ *         } );
+ *         $( document.body ).append( button.$element );
+ *
+ *         // A button displaying "OK" in Urdu
+ *         $.i18n().locale = 'ur';
+ *         button = new OO.ui.ButtonWidget( {
+ *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),
+ *             icon: 'check'
+ *         } );
+ *         $( document.body ).append( button.$element );
+ *     } );
+ *
+ * @param {string} key Message key
+ * @param {...Mixed} [params] Message parameters
+ * @return {string} Translated message with parameters substituted
+ */
+OO.ui.msg = function ( key ) {
+       // `OO.ui.msg.messages` is defined in code generated during the build process
+       var messages = OO.ui.msg.messages,
+               message = messages[ key ],
+               params = Array.prototype.slice.call( arguments, 1 );
+       if ( typeof message === 'string' ) {
+               // Perform $1 substitution
+               message = message.replace( /\$(\d+)/g, function ( unused, n ) {
+                       var i = parseInt( n, 10 );
+                       return params[ i - 1 ] !== undefined ? params[ i - 1 ] : '$' + n;
+               } );
+       } else {
+               // Return placeholder if message not found
+               message = '[' + key + ']';
+       }
+       return message;
+};
 
 /**
  * Package a message and arguments for deferred resolution.
@@ -550,7 +508,7 @@ OO.ui.isMobile = function () {
  * such menus overlapping any fixed headers/toolbars/navigation used by the site.
  *
  * @return {Object} Object with the properties 'top', 'right', 'bottom', 'left', each representing
- *     the extra spacing from that edge of viewport (in pixels)
+ *  the extra spacing from that edge of viewport (in pixels)
  */
 OO.ui.getViewportSpacing = function () {
        return {
@@ -575,6 +533,36 @@ OO.ui.getDefaultOverlay = function () {
        return OO.ui.$defaultOverlay;
 };
 
+/**
+ * Message store for the default implementation of OO.ui.msg.
+ *
+ * Environments that provide a localization system should not use this, but should override
+ * OO.ui.msg altogether.
+ *
+ * @private
+ */
+OO.ui.msg.messages = {
+       "ooui-outline-control-move-down": "Move item down",
+       "ooui-outline-control-move-up": "Move item up",
+       "ooui-outline-control-remove": "Remove item",
+       "ooui-toolbar-more": "More",
+       "ooui-toolgroup-expand": "More",
+       "ooui-toolgroup-collapse": "Fewer",
+       "ooui-item-remove": "Remove",
+       "ooui-dialog-message-accept": "OK",
+       "ooui-dialog-message-reject": "Cancel",
+       "ooui-dialog-process-error": "Something went wrong",
+       "ooui-dialog-process-dismiss": "Dismiss",
+       "ooui-dialog-process-retry": "Try again",
+       "ooui-dialog-process-continue": "Continue",
+       "ooui-combobox-button-label": "Dropdown for combobox",
+       "ooui-selectfile-button-select": "Select a file",
+       "ooui-selectfile-not-supported": "File selection is not supported",
+       "ooui-selectfile-placeholder": "No file is selected",
+       "ooui-selectfile-dragdrop-placeholder": "Drop file here",
+       "ooui-field-help": "Help"
+};
+
 /*!
  * Mixin namespace.
  */
@@ -594,17 +582,17 @@ OO.ui.mixin = {};
 
 /**
  * Each Element represents a rendering in the DOM—a button or an icon, for example, or anything
- * that is visible to a user. Unlike {@link OO.ui.Widget widgets}, plain elements usually do not have events
- * connected to them and can't be interacted with.
+ * that is visible to a user. Unlike {@link OO.ui.Widget widgets}, plain elements usually do not
+ * have events connected to them and can't be interacted with.
  *
  * @abstract
  * @class
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {string[]} [classes] The names of the CSS classes to apply to the element. CSS styles are added
- *  to the top level (e.g., the outermost div) of the element. See the [OOUI documentation on MediaWiki][2]
- *  for an example.
+ * @cfg {string[]} [classes] The names of the CSS classes to apply to the element. CSS styles are
+ *  added to the top level (e.g., the outermost div) of the element. See the
+ *  [OOUI documentation on MediaWiki][2] for an example.
  *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches#cssExample
  * @cfg {string} [id] The HTML id attribute used in the rendered tag.
  * @cfg {string} [text] Text to insert
@@ -613,7 +601,8 @@ OO.ui.mixin = {};
  *  Instances of OO.ui.Element will have their $element appended.
  * @cfg {jQuery} [$content] Content elements to append (after #text).
  * @cfg {jQuery} [$element] Wrapper element. Defaults to a new element with #getTagName.
- * @cfg {Mixed} [data] Custom data of any type or combination of types (e.g., string, number, array, object).
+ * @cfg {Mixed} [data] Custom data of any type or combination of types (e.g., string, number,
+ *  array, object).
  *  Data can also be specified with the #setData method.
  */
 OO.ui.Element = function OoUiElement( config ) {
@@ -652,7 +641,8 @@ OO.ui.Element = function OoUiElement( config ) {
                this.$element.append( config.content.map( function ( v ) {
                        if ( typeof v === 'string' ) {
                                // Escape string so it is properly represented in HTML.
-                               return document.createTextNode( v );
+                               // Don't create empty text nodes for empty strings.
+                               return v ? document.createTextNode( v ) : undefined;
                        } else if ( v instanceof OO.ui.HtmlSnippet ) {
                                // Bypass escaping.
                                return v.toString();
@@ -761,9 +751,10 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, config, domPromise ) {
                        throw new Error( 'Circular dependency! ' + id );
                }
                if ( domPromise ) {
-                       // pick up dynamic state, like focus, value of form inputs, scroll position, etc.
+                       // Pick up dynamic state, like focus, value of form inputs, scroll position, etc.
                        state = data.constructor.static.gatherPreInfuseState( $elem, data );
-                       // restore dynamic state after the new element is re-inserted into DOM under infused parent
+                       // Restore dynamic state after the new element is re-inserted into DOM under
+                       // infused parent.
                        domPromise.done( data.restorePreInfuseState.bind( data, state ) );
                        infusedChildren = $elem.data( 'ooui-infused-children' );
                        if ( infusedChildren && infusedChildren.length ) {
@@ -827,7 +818,10 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, config, domPromise ) {
                                infused = OO.ui.Element.static.unsafeInfuse( value.tag, config, domPromise );
                                infusedChildren.push( infused );
                                // Flatten the structure
-                               infusedChildren.push.apply( infusedChildren, infused.$element.data( 'ooui-infused-children' ) || [] );
+                               infusedChildren.push.apply(
+                                       infusedChildren,
+                                       infused.$element.data( 'ooui-infused-children' ) || []
+                               );
                                infused.$element.removeData( 'ooui-infused-children' );
                                return infused;
                        }
@@ -849,8 +843,8 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, config, domPromise ) {
        $elem[ 0 ].oouiInfused = obj.$element;
        // now replace old DOM with this new DOM.
        if ( top ) {
-               // An efficient constructor might be able to reuse the entire DOM tree of the original element,
-               // so only mutate the DOM if we need to.
+               // An efficient constructor might be able to reuse the entire DOM tree of the original
+               // element, so only mutate the DOM if we need to.
                if ( $elem[ 0 ] !== obj.$element[ 0 ] ) {
                        $elem.replaceWith( obj.$element );
                }
@@ -882,8 +876,8 @@ OO.ui.Element.static.reusePreInfuseDOM = function ( node, config ) {
 };
 
 /**
- * Gather the dynamic state (focus, value of form inputs, scroll position, etc.) of an HTML DOM node
- * (and its children) that represent an Element of the same class and the given configuration,
+ * Gather the dynamic state (focus, value of form inputs, scroll position, etc.) of an HTML DOM
+ * node (and its children) that represent an Element of the same class and the given configuration,
  * generated by the PHP implementation.
  *
  * This method is called just before `node` is detached from the DOM. The return value of this
@@ -1142,10 +1136,10 @@ OO.ui.Element.static.getDimensions = function ( el ) {
  * @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).
+ *  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;
@@ -1255,8 +1249,9 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension )
                props = [ 'overflow-' + dimension ];
        }
 
-       // Special case for the document root (which doesn't really have any scrollable container, since
-       // it is the ultimate scrollable container, but this is probably saner than null or exception)
+       // Special case for the document root (which doesn't really have any scrollable container,
+       // since it is the ultimate scrollable container, but this is probably saner than null or
+       // exception).
        if ( $( el ).is( 'html, body' ) ) {
                return this.getRootScrollableElement( el );
        }
@@ -1268,10 +1263,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.
+                       // 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 ];
@@ -1295,7 +1291,8 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension )
  * @return {jQuery.Promise} Promise which resolves when the scroll is complete
  */
 OO.ui.Element.static.scrollIntoView = function ( el, config ) {
-       var position, animations, container, $container, elementDimensions, containerDimensions, $window,
+       var position, animations, container, $container, elementDimensions, containerDimensions,
+               $window,
                deferred = $.Deferred();
 
        // Configuration initialization
@@ -1320,10 +1317,14 @@ OO.ui.Element.static.scrollIntoView = function ( el, config ) {
        } else {
                // Otherwise, we have to subtract el's coordinates from container's coordinates
                position = {
-                       top: elementDimensions.rect.top - ( containerDimensions.rect.top + containerDimensions.borders.top ),
-                       bottom: containerDimensions.rect.bottom - containerDimensions.borders.bottom - containerDimensions.scrollbar.bottom - elementDimensions.rect.bottom,
-                       left: elementDimensions.rect.left - ( containerDimensions.rect.left + containerDimensions.borders.left ),
-                       right: containerDimensions.rect.right - containerDimensions.borders.right - containerDimensions.scrollbar.right - elementDimensions.rect.right
+                       top: elementDimensions.rect.top -
+                               ( containerDimensions.rect.top + containerDimensions.borders.top ),
+                       bottom: containerDimensions.rect.bottom - containerDimensions.borders.bottom -
+                               containerDimensions.scrollbar.bottom - elementDimensions.rect.bottom,
+                       left: elementDimensions.rect.left -
+                               ( containerDimensions.rect.left + containerDimensions.borders.left ),
+                       right: containerDimensions.rect.right - containerDimensions.borders.right -
+                               containerDimensions.scrollbar.right - elementDimensions.rect.right
                };
        }
 
@@ -1331,19 +1332,22 @@ OO.ui.Element.static.scrollIntoView = function ( el, config ) {
                if ( position.top < 0 ) {
                        animations.scrollTop = containerDimensions.scroll.top + position.top;
                } else if ( position.top > 0 && position.bottom < 0 ) {
-                       animations.scrollTop = containerDimensions.scroll.top + Math.min( position.top, -position.bottom );
+                       animations.scrollTop = containerDimensions.scroll.top +
+                               Math.min( position.top, -position.bottom );
                }
        }
        if ( !config.direction || config.direction === 'x' ) {
                if ( position.left < 0 ) {
                        animations.scrollLeft = containerDimensions.scroll.left + position.left;
                } else if ( position.left > 0 && position.right < 0 ) {
-                       animations.scrollLeft = containerDimensions.scroll.left + Math.min( position.left, -position.right );
+                       animations.scrollLeft = containerDimensions.scroll.left +
+                               Math.min( position.left, -position.right );
                }
        }
        if ( !$.isEmptyObject( animations ) ) {
-               // eslint-disable-next-line jquery/no-animate
-               $container.stop( true ).animate( animations, config.duration === undefined ? 'fast' : config.duration );
+               // eslint-disable-next-line no-jquery/no-animate
+               $container.stop( true ).animate( animations, config.duration === undefined ?
+                       'fast' : config.duration );
                $container.queue( function ( next ) {
                        deferred.resolve();
                        next();
@@ -1360,8 +1364,8 @@ OO.ui.Element.static.scrollIntoView = function ( el, config ) {
  *
  * Workaround primarily for <https://code.google.com/p/chromium/issues/detail?id=387290>, but also
  * similar bugs in other browsers. "Just" forcing a reflow is not sufficient in all cases, we need
- * to first actually detach (or hide, but detaching is simpler) all children, *then* force a reflow,
- * and then reattach (or show) them back.
+ * to first actually detach (or hide, but detaching is simpler) all children, *then* force a
+ * reflow, and then reattach (or show) them back.
  *
  * @static
  * @param {HTMLElement} el Element to reconsider the scrollbars on
@@ -1626,11 +1630,14 @@ OO.ui.HtmlSnippet.prototype.toString = function () {
 };
 
 /**
- * Layouts are containers for elements and are used to arrange other widgets of arbitrary type in a way
- * that is centrally controlled and can be updated dynamically. Layouts can be, and usually are, combined.
- * See {@link OO.ui.FieldsetLayout FieldsetLayout}, {@link OO.ui.FieldLayout FieldLayout}, {@link OO.ui.FormLayout FormLayout},
- * {@link OO.ui.PanelLayout PanelLayout}, {@link OO.ui.StackLayout StackLayout}, {@link OO.ui.PageLayout PageLayout},
- * {@link OO.ui.HorizontalLayout HorizontalLayout}, and {@link OO.ui.BookletLayout BookletLayout} for more information and examples.
+ * Layouts are containers for elements and are used to arrange other widgets of arbitrary type in
+ * a way that is centrally controlled and can be updated dynamically. Layouts can be, and usually
+ * are, combined.
+ * See {@link OO.ui.FieldsetLayout FieldsetLayout}, {@link OO.ui.FieldLayout FieldLayout},
+ * {@link OO.ui.FormLayout FormLayout}, {@link OO.ui.PanelLayout PanelLayout},
+ * {@link OO.ui.StackLayout StackLayout}, {@link OO.ui.PageLayout PageLayout},
+ * {@link OO.ui.HorizontalLayout HorizontalLayout}, and {@link OO.ui.BookletLayout BookletLayout}
+ * for more information and examples.
  *
  * @abstract
  * @class
@@ -1907,7 +1914,7 @@ OO.ui.Theme.prototype.getDialogTransitionDuration = function () {
 /**
  * The TabIndexedElement class is an attribute mixin used to add additional functionality to an
  * element created by another class. The mixin provides a ‘tabIndex’ property, which specifies the
- * order in which users will navigate through the focusable elements via the “tab” key.
+ * order in which users will navigate through the focusable elements via the Tab key.
  *
  *     @example
  *     // TabIndexedElement is mixed into the ButtonWidget class
@@ -1928,7 +1935,12 @@ OO.ui.Theme.prototype.getDialogTransitionDuration = function () {
  *             label: 'first',
  *             tabIndex: 1
  *         } );
- *     $( document.body ).append( button1.$element, button2.$element, button3.$element, button4.$element );
+ *     $( document.body ).append(
+ *         button1.$element,
+ *         button2.$element,
+ *         button3.$element,
+ *         button4.$element
+ *      );
  *
  * @abstract
  * @class
@@ -1936,11 +1948,11 @@ OO.ui.Theme.prototype.getDialogTransitionDuration = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {jQuery} [$tabIndexed] The element that should use the tabindex functionality. By default,
- *  the functionality is applied to the element created by the class ($element). If a different element is specified, the tabindex
- *  functionality will be applied to it instead.
- * @cfg {string|number|null} [tabIndex=0] Number that specifies the element’s position in the tab-navigation
- *  order (e.g., 1 for the first focusable element). Use 0 to use the default navigation order; use -1
- *  to remove the element from the tab-navigation flow.
+ *  the functionality is applied to the element created by the class ($element). If a different
+ *  element is specified, the tabindex functionality will be applied to it instead.
+ * @cfg {string|number|null} [tabIndex=0] Number that specifies the element’s position in the
+ *  tab-navigation order (e.g., 1 for the first focusable element). Use 0 to use the default
+ *  navigation order; use -1 to remove the element from the tab-navigation flow.
  */
 OO.ui.mixin.TabIndexedElement = function OoUiMixinTabIndexedElement( config ) {
        // Configuration initialization
@@ -1951,7 +1963,9 @@ OO.ui.mixin.TabIndexedElement = function OoUiMixinTabIndexedElement( config ) {
        this.tabIndex = null;
 
        // Events
-       this.connect( this, { disable: 'onTabIndexedElementDisable' } );
+       this.connect( this, {
+               disable: 'onTabIndexedElementDisable'
+       } );
 
        // Initialization
        this.setTabIndex( config.tabIndex );
@@ -2086,7 +2100,7 @@ OO.ui.mixin.TabIndexedElement.prototype.getInputId = function () {
 OO.ui.mixin.TabIndexedElement.prototype.isLabelableNode = function ( $node ) {
        var
                labelableTags = [ 'button', 'meter', 'output', 'progress', 'select', 'textarea' ],
-               tagName = $node.prop( 'tagName' ).toLowerCase();
+               tagName = ( $node.prop( 'tagName' ) || '' ).toLowerCase();
 
        if ( tagName === 'input' && $node.attr( 'type' ) !== 'hidden' ) {
                return true;
@@ -2174,10 +2188,11 @@ OO.initClass( OO.ui.mixin.ButtonElement );
 /**
  * Cancel mouse down events.
  *
- * This property is usually set to `true` to prevent the focus from changing when the button is clicked.
- * Classes such as {@link OO.ui.mixin.DraggableElement DraggableElement} and {@link OO.ui.ButtonOptionWidget ButtonOptionWidget}
- * use a value of `false` so that dragging behavior is possible and mousedown events can be handled by a
- * parent widget.
+ * This property is usually set to `true` to prevent the focus from changing when the button is
+ * clicked.
+ * Classes such as {@link OO.ui.mixin.DraggableElement DraggableElement} and
+ * {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} use a value of `false` so that dragging
+ * behavior is possible and mousedown events can be handled by a parent widget.
  *
  * @static
  * @inheritable
@@ -2269,12 +2284,6 @@ OO.ui.mixin.ButtonElement.prototype.onDocumentMouseUp = function ( e ) {
        this.getElementDocument().removeEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.mixin.ButtonElement.prototype.onMouseUp = function () {
-       OO.ui.warnDeprecation( 'onMouseUp is deprecated, use onDocumentMouseUp instead' );
-       this.onDocumentMouseUp.apply( this, arguments );
-};
-
 /**
  * Handles mouse click events.
  *
@@ -2322,12 +2331,6 @@ OO.ui.mixin.ButtonElement.prototype.onDocumentKeyUp = function ( e ) {
        this.getElementDocument().removeEventListener( 'keyup', this.onDocumentKeyUpHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.mixin.ButtonElement.prototype.onKeyUp = function () {
-       OO.ui.warnDeprecation( 'onKeyUp is deprecated, use onDocumentKeyUp instead' );
-       this.onDocumentKeyUp.apply( this, arguments );
-};
-
 /**
  * Handles key press events.
  *
@@ -2354,7 +2357,8 @@ OO.ui.mixin.ButtonElement.prototype.isFramed = function () {
 };
 
 /**
- * Render the button with or without a frame. Omit the `framed` parameter to toggle the button frame on and off.
+ * Render the button with or without a frame. Omit the `framed` parameter to toggle the button frame
+ * on and off.
  *
  * @param {boolean} [framed] Make button framed, omit to toggle
  * @chainable
@@ -2493,7 +2497,8 @@ OO.ui.mixin.GroupElement.prototype.findItemFromData = function ( data ) {
 /**
  * Find items by their data.
  *
- * All items with matching data will be returned. To return only the first match, use the #findItemFromData method instead.
+ * All items with matching data will be returned. To return only the first match, use the
+ * #findItemFromData method instead.
  *
  * @param {Object} data Item data to search for
  * @return {OO.ui.Element[]} Items with equivalent data
@@ -2516,8 +2521,9 @@ OO.ui.mixin.GroupElement.prototype.findItemsFromData = function ( data ) {
 /**
  * Add items to the group.
  *
- * Items will be added to the end of the group array unless the optional `index` parameter specifies
- * a different insertion point. Adding an existing item will move it to the end of the array or the point specified by the `index`.
+ * Items will be added to the end of the group array unless the optional `index` parameter
+ * specifies a different insertion point. Adding an existing item will move it to the end of the
+ * array or the point specified by the `index`.
  *
  * @param {OO.ui.Element[]} items An array of items to add to the group
  * @param {number} [index] Index of the insertion point
@@ -2653,12 +2659,12 @@ OO.ui.mixin.GroupElement.prototype.clearItems = function () {
  * @param {Object} [config] Configuration options
  * @cfg {jQuery} [$label] The label element created by the class. If this
  *  configuration is omitted, the label element will use a generated `<span>`.
- * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be specified
- *  as a plaintext string, a jQuery selection of elements, or a function that will produce a string
- *  in the future. See the [OOUI documentation on MediaWiki] [2] for examples.
+ * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be
+ *  specified as a plaintext string, a jQuery selection of elements, or a function that will
+ *  produce a string in the future. See the [OOUI documentation on MediaWiki] [2] for examples.
  *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Labels
- * @cfg {boolean} [invisibleLabel] Whether the label should be visually hidden (but still accessible
- *  to screen-readers).
+ * @cfg {boolean} [invisibleLabel] Whether the label should be visually hidden (but still
+ *  accessible to screen-readers).
  */
 OO.ui.mixin.LabelElement = function OoUiMixinLabelElement( config ) {
        // Configuration initialization
@@ -2765,8 +2771,8 @@ OO.ui.mixin.LabelElement.prototype.setLabelElement = function ( $label ) {
  * An empty string will result in the label being hidden. A string containing only whitespace will
  * be converted to a single `&nbsp;`.
  *
- * @param {jQuery|string|OO.ui.HtmlSnippet|Function|null} label Label nodes; text; a function that returns nodes or
- *  text; or null for no label
+ * @param {jQuery|string|OO.ui.HtmlSnippet|Function|null} label Label nodes; text; a function that
+ *  returns nodes or text; or null for no label
  * @chainable
  * @return {OO.ui.Element} The element, for chaining
  */
@@ -2883,18 +2889,16 @@ OO.ui.mixin.LabelElement.prototype.setLabelContent = function ( label ) {
  *     $icon: this.$element
  *     // Use an icon element from a child widget
  *     $icon: this.childwidget.$element
- * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of
- *  symbolic names.  A map is used for i18n purposes and contains a `default` icon
- *  name and additional names keyed by language code. The `default` name is used when no icon is keyed
- *  by the user's language.
+ * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a
+ *  map of symbolic names. A map is used for i18n purposes and contains a `default` icon
+ *  name and additional names keyed by language code. The `default` name is used when no icon is
+ *  keyed by the user's language.
  *
  *  Example of an i18n map:
  *
  *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
  *  See the [OOUI documentation on MediaWiki] [2] for a list of icons included in the library.
  * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Icons
- * @cfg {string|Function} [iconTitle] A text string used as the icon title, or a function that returns title
- *  text. The icon title is displayed when users move the mouse over the icon.
  */
 OO.ui.mixin.IconElement = function OoUiMixinIconElement( config ) {
        // Configuration initialization
@@ -2903,16 +2907,9 @@ OO.ui.mixin.IconElement = function OoUiMixinIconElement( config ) {
        // Properties
        this.$icon = null;
        this.icon = null;
-       this.iconTitle = null;
-
-       // `iconTitle`s are deprecated since 0.30.0
-       if ( config.iconTitle !== undefined ) {
-               OO.ui.warnDeprecation( 'IconElement: Widgets with iconTitle set are deprecated, use title instead. See T76638 for details.' );
-       }
 
        // Initialization
        this.setIcon( config.icon || this.constructor.static.icon );
-       this.setIconTitle( config.iconTitle || this.constructor.static.iconTitle );
        this.setIconElement( config.$icon || $( '<span>' ) );
 };
 
@@ -2923,8 +2920,8 @@ OO.initClass( OO.ui.mixin.IconElement );
 /* Static Properties */
 
 /**
- * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map is used
- * for i18n purposes and contains a `default` icon name and additional names keyed by
+ * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map
+ * is used for i18n purposes and contains a `default` icon name and additional names keyed by
  * language code. The `default` name is used when no icon is keyed by the user's language.
  *
  * Example of an i18n map:
@@ -3014,40 +3011,6 @@ OO.ui.mixin.IconElement.prototype.setIcon = function ( icon ) {
        return this;
 };
 
-/**
- * Set the icon title. Use `null` to remove the title.
- *
- * @param {string|Function|null} iconTitle A text string used as the icon title,
- *  a function that returns title text, or `null` for no title.
- * @chainable
- * @return {OO.ui.Element} The element, for chaining
- * @deprecated
- */
-OO.ui.mixin.IconElement.prototype.setIconTitle = function ( iconTitle ) {
-       iconTitle =
-               ( typeof iconTitle === 'function' || ( typeof iconTitle === 'string' && iconTitle.length ) ) ?
-                       OO.ui.resolveMsg( iconTitle ) : null;
-
-       if ( this.iconTitle !== iconTitle ) {
-               this.iconTitle = iconTitle;
-               if ( this.$icon ) {
-                       if ( this.iconTitle !== null ) {
-                               this.$icon.attr( 'title', iconTitle );
-                       } else {
-                               this.$icon.removeAttr( 'title' );
-                       }
-               }
-       }
-
-       // `setIconTitle is deprecated since 0.30.0
-       if ( iconTitle !== null ) {
-               // Avoid a warning when this is called from the constructor with no iconTitle set
-               OO.ui.warnDeprecation( 'IconElement: setIconTitle is deprecated, use setTitle of TitledElement instead. See T76638 for details.' );
-       }
-
-       return this;
-};
-
 /**
  * Get the symbolic name of the icon.
  *
@@ -3061,6 +3024,7 @@ OO.ui.mixin.IconElement.prototype.getIcon = function () {
  * Get the icon title. The title text is displayed when a user moves the mouse over the icon.
  *
  * @return {string} Icon title text
+ * @deprecated
  */
 OO.ui.mixin.IconElement.prototype.getIconTitle = function () {
        return this.iconTitle;
@@ -3091,9 +3055,6 @@ OO.ui.mixin.IconElement.prototype.getIconTitle = function () {
  *  See the [OOUI documentation on MediaWiki][2] for a list of indicators included
  *  in the library.
  * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators
- * @cfg {string|Function} [indicatorTitle] A text string used as the indicator title,
- *  or a function that returns title text. The indicator title is displayed when users move
- *  the mouse over the indicator.
  */
 OO.ui.mixin.IndicatorElement = function OoUiMixinIndicatorElement( config ) {
        // Configuration initialization
@@ -3102,16 +3063,9 @@ OO.ui.mixin.IndicatorElement = function OoUiMixinIndicatorElement( config ) {
        // Properties
        this.$indicator = null;
        this.indicator = null;
-       this.indicatorTitle = null;
-
-       // `indicatorTitle`s are deprecated since 0.30.0
-       if ( config.indicatorTitle !== undefined ) {
-               OO.ui.warnDeprecation( 'IndicatorElement: Widgets with indicatorTitle set are deprecated, use title instead. See T76638 for details.' );
-       }
 
        // Initialization
        this.setIndicator( config.indicator || this.constructor.static.indicator );
-       this.setIndicatorTitle( config.indicatorTitle || this.constructor.static.indicatorTitle );
        this.setIndicatorElement( config.$indicator || $( '<span>' ) );
 };
 
@@ -3133,7 +3087,8 @@ OO.ui.mixin.IndicatorElement.static.indicator = null;
 
 /**
  * A text string used as the indicator title, a function that returns title text, or `null`
- * for no title. The static property will be overridden if the #indicatorTitle configuration is used.
+ * for no title. The static property will be overridden if the #indicatorTitle configuration is
+ * used.
  *
  * @static
  * @inheritable
@@ -3169,7 +3124,8 @@ OO.ui.mixin.IndicatorElement.prototype.setIndicatorElement = function ( $indicat
 };
 
 /**
- * Set the indicator by its symbolic name: ‘clear’, ‘down’, ‘required’, ‘search’, ‘up’. Use `null` to remove the indicator.
+ * Set the indicator by its symbolic name: ‘clear’, ‘down’, ‘required’, ‘search’, ‘up’. Use `null`
+ * to remove the indicator.
  *
  * @param {string|null} indicator Symbolic name of indicator, or `null` for no indicator
  * @chainable
@@ -3199,42 +3155,6 @@ OO.ui.mixin.IndicatorElement.prototype.setIndicator = function ( indicator ) {
        return this;
 };
 
-/**
- * Set the indicator title.
- *
- * The title is displayed when a user moves the mouse over the indicator.
- *
- * @param {string|Function|null} indicatorTitle Indicator title text, a function that returns text, or
- *   `null` for no indicator title
- * @chainable
- * @return {OO.ui.Element} The element, for chaining
- * @deprecated
- */
-OO.ui.mixin.IndicatorElement.prototype.setIndicatorTitle = function ( indicatorTitle ) {
-       indicatorTitle =
-               ( typeof indicatorTitle === 'function' || ( typeof indicatorTitle === 'string' && indicatorTitle.length ) ) ?
-                       OO.ui.resolveMsg( indicatorTitle ) : null;
-
-       if ( this.indicatorTitle !== indicatorTitle ) {
-               this.indicatorTitle = indicatorTitle;
-               if ( this.$indicator ) {
-                       if ( this.indicatorTitle !== null ) {
-                               this.$indicator.attr( 'title', indicatorTitle );
-                       } else {
-                               this.$indicator.removeAttr( 'title' );
-                       }
-               }
-       }
-
-       // `setIndicatorTitle is deprecated since 0.30.0
-       if ( indicatorTitle !== null ) {
-               // Avoid a warning when this is called from the constructor with no indicatorTitle set
-               OO.ui.warnDeprecation( 'IndicatorElement: setIndicatorTitle is deprecated, use setTitle of TitledElement instead. See T76638 for details.' );
-       }
-
-       return this;
-};
-
 /**
  * Get the symbolic name of the indicator (e.g., ‘clear’ or  ‘down’).
  *
@@ -3250,6 +3170,7 @@ OO.ui.mixin.IndicatorElement.prototype.getIndicator = function () {
  * The title is displayed when a user moves the mouse over the indicator.
  *
  * @return {string} Indicator title text
+ * @deprecated
  */
 OO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {
        return this.indicatorTitle;
@@ -3264,8 +3185,10 @@ OO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {
  *
  * The library currently contains the following styling flags for general use:
  *
- * - **progressive**: Progressive styling is applied to convey that the widget will move the user forward in a process.
- * - **destructive**: Destructive styling is applied to convey that the widget will remove something.
+ * - **progressive**: Progressive styling is applied to convey that the widget will move the user
+ *   forward in a process.
+ * - **destructive**: Destructive styling is applied to convey that the widget will remove
+ *   something.
  *
  * The flags affect the appearance of the buttons:
  *
@@ -3281,7 +3204,8 @@ OO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {
  *         } );
  *     $( document.body ).append( button1.$element, button2.$element );
  *
- * {@link OO.ui.ActionWidget ActionWidgets}, which are a special kind of button that execute an action, use these flags: **primary** and **safe**.
+ * {@link OO.ui.ActionWidget ActionWidgets}, which are a special kind of button that execute an
+ * action, use these flags: **primary** and **safe**.
  * Please see the [OOUI documentation on MediaWiki] [1] for more information.
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged
@@ -3291,7 +3215,8 @@ OO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {string|string[]} [flags] The name or names of the flags (e.g., 'progressive' or 'primary') to apply.
+ * @cfg {string|string[]} [flags] The name or names of the flags (e.g., 'progressive' or 'primary')
+ *  to apply.
  *  Please see the [OOUI documentation on MediaWiki] [2] for more information about available flags.
  *  [2]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged
  * @cfg {jQuery} [$flagged] The flagged element. By default,
@@ -3328,7 +3253,8 @@ OO.ui.mixin.FlaggedElement = function OoUiMixinFlaggedElement( config ) {
 /**
  * Set the flagged element.
  *
- * This method is used to retarget a flagged mixin so that its functionality applies to the specified element.
+ * This method is used to retarget a flagged mixin so that its functionality applies to the
+ * specified element.
  * If an element is already set, the method will remove the mixin’s effect on that element.
  *
  * @param {jQuery} $flagged Element that should be flagged
@@ -3509,8 +3435,11 @@ OO.initClass( OO.ui.mixin.TitledElement );
 /* Static Properties */
 
 /**
- * The title text, a function that returns text, or `null` for no title. The value of the static property
- * is overridden if the #title config option is used.
+ * The title text, a function that returns text, or `null` for no title. The value of the static
+ * property is overridden if the #title config option is used.
+ *
+ * If the element has a default title (e.g. `<input type=file>`), `null` will allow that title to be
+ * shown. Use empty string to suppress it.
  *
  * @static
  * @inheritable
@@ -3523,8 +3452,10 @@ OO.ui.mixin.TitledElement.static.title = null;
 /**
  * Set the titled element.
  *
- * This method is used to retarget a TitledElement mixin so that its functionality applies to the specified element.
- * If an element is already set, the mixin’s effect on that element is removed before the new element is set up.
+ * This method is used to retarget a TitledElement mixin so that its functionality applies to the
+ * specified element.
+ * If an element is already set, the mixin’s effect on that element is removed before the new
+ * element is set up.
  *
  * @param {jQuery} $titled Element that should use the 'titled' functionality
  */
@@ -3534,21 +3465,20 @@ OO.ui.mixin.TitledElement.prototype.setTitledElement = function ( $titled ) {
        }
 
        this.$titled = $titled;
-       if ( this.title ) {
-               this.updateTitle();
-       }
+       this.updateTitle();
 };
 
 /**
  * Set title.
  *
- * @param {string|Function|null} title Title text, a function that returns text, or `null` for no title
+ * @param {string|Function|null} title Title text, a function that returns text, or `null`
+ *  for no title
  * @chainable
  * @return {OO.ui.Element} The element, for chaining
  */
 OO.ui.mixin.TitledElement.prototype.setTitle = function ( title ) {
        title = typeof title === 'function' ? OO.ui.resolveMsg( title ) : title;
-       title = ( typeof title === 'string' && title.length ) ? title : null;
+       title = typeof title === 'string' ? title : null;
 
        if ( this.title !== title ) {
                this.title = title;
@@ -3592,7 +3522,7 @@ OO.ui.mixin.TitledElement.prototype.getTitle = function () {
 
 /**
  * AccessKeyedElement is mixed into other classes to provide an `accesskey` HTML attribute.
- * Accesskeys allow an user to go to a specific element by using
+ * Access keys allow an user to go to a specific element by using
  * a shortcut combination of a browser specific keys + the key
  * set to the field.
  *
@@ -3600,7 +3530,7 @@ OO.ui.mixin.TitledElement.prototype.getTitle = function () {
  *     // AccessKeyedElement provides an `accesskey` attribute to the
  *     // ButtonWidget class.
  *     var button = new OO.ui.ButtonWidget( {
- *         label: 'Button with Accesskey',
+ *         label: 'Button with access key',
  *         accessKey: 'k'
  *     } );
  *     $( document.body ).append( button.$element );
@@ -3611,10 +3541,10 @@ OO.ui.mixin.TitledElement.prototype.getTitle = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {jQuery} [$accessKeyed] The element to which the `accesskey` attribute is applied.
- *  If this config is omitted, the accesskey functionality is applied to $element, the
+ *  If this config is omitted, the access key functionality is applied to $element, the
  *  element created by the class.
  * @cfg {string|Function} [accessKey] The key or a function that returns the key. If
- *  this config is omitted, no accesskey will be added.
+ *  this config is omitted, no access key will be added.
  */
 OO.ui.mixin.AccessKeyedElement = function OoUiMixinAccessKeyedElement( config ) {
        // Configuration initialization
@@ -3642,7 +3572,7 @@ OO.initClass( OO.ui.mixin.AccessKeyedElement );
 /* Static Properties */
 
 /**
- * The access key, a function that returns a key, or `null` for no accesskey.
+ * The access key, a function that returns a key, or `null` for no access key.
  *
  * @static
  * @inheritable
@@ -3653,12 +3583,14 @@ OO.ui.mixin.AccessKeyedElement.static.accessKey = null;
 /* Methods */
 
 /**
- * Set the accesskeyed element.
+ * Set the access keyed element.
  *
- * This method is used to retarget a AccessKeyedElement mixin so that its functionality applies to the specified element.
- * If an element is already set, the mixin's effect on that element is removed before the new element is set up.
+ * This method is used to retarget a AccessKeyedElement mixin so that its functionality applies to
+ * the specified element.
+ * If an element is already set, the mixin's effect on that element is removed before the new
+ * element is set up.
  *
- * @param {jQuery} $accessKeyed Element that should use the 'accesskeyed' functionality
+ * @param {jQuery} $accessKeyed Element that should use the 'access keyed' functionality
  */
 OO.ui.mixin.AccessKeyedElement.prototype.setAccessKeyedElement = function ( $accessKeyed ) {
        if ( this.$accessKeyed ) {
@@ -3672,9 +3604,10 @@ OO.ui.mixin.AccessKeyedElement.prototype.setAccessKeyedElement = function ( $acc
 };
 
 /**
- * Set accesskey.
+ * Set access key.
  *
- * @param {string|Function|null} accessKey Key, a function that returns a key, or `null` for no accesskey
+ * @param {string|Function|null} accessKey Key, a function that returns a key, or `null` for no
+ *  access key
  * @chainable
  * @return {OO.ui.Element} The element, for chaining
  */
@@ -3701,7 +3634,7 @@ OO.ui.mixin.AccessKeyedElement.prototype.setAccessKey = function ( accessKey ) {
 };
 
 /**
- * Get accesskey.
+ * Get access key.
  *
  * @return {string} accessKey string
  */
@@ -3720,10 +3653,12 @@ OO.ui.mixin.AccessKeyedElement.prototype.formatTitleWithAccessKey = function ( t
        var accessKey;
 
        if ( !this.$accessKeyed ) {
-               // Not initialized yet; the constructor will call updateTitle() which will rerun this function
+               // Not initialized yet; the constructor will call updateTitle() which will rerun this
+               // function.
                return title;
        }
-       // Use jquery.accessKeyLabel if available to show modifiers, otherwise just display the single key
+       // Use jquery.accessKeyLabel if available to show modifiers, otherwise just display the
+       // single key.
        if ( $.fn.updateTooltipAccessKeys && $.fn.updateTooltipAccessKeys.getAccessKeyLabel ) {
                accessKey = $.fn.updateTooltipAccessKeys.getAccessKeyLabel( this.$accessKeyed[ 0 ] );
        } else {
@@ -3784,10 +3719,16 @@ OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
        OO.ui.mixin.IconElement.call( this, config );
        OO.ui.mixin.IndicatorElement.call( this, config );
        OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {
+               $titled: this.$button
+       }, config ) );
        OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );
-       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$button } ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {
+               $tabIndexed: this.$button
+       }, config ) );
+       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {
+               $accessKeyed: this.$button
+       }, config ) );
 
        // Properties
        this.href = null;
@@ -3795,7 +3736,9 @@ OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
        this.noFollow = false;
 
        // Events
-       this.connect( this, { disable: 'onDisable' } );
+       this.connect( this, {
+               disable: 'onDisable'
+       } );
 
        // Initialization
        this.$button.append( this.$icon, this.$label, this.$indicator );
@@ -4005,7 +3948,9 @@ OO.ui.ButtonGroupWidget = function OoUiButtonGroupWidget( config ) {
        OO.ui.ButtonGroupWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+       OO.ui.mixin.GroupElement.call( this, $.extend( {
+               $group: this.$element
+       }, config ) );
        OO.ui.mixin.TitledElement.call( this, config );
 
        // Initialization
@@ -4054,8 +3999,9 @@ OO.ui.ButtonGroupWidget.prototype.simulateLabelClick = function () {
 };
 
 /**
- * IconWidget is a generic widget for {@link OO.ui.mixin.IconElement icons}. In general, IconWidgets should be used with OO.ui.LabelWidget,
- * which creates a label that identifies the icon’s function. See the [OOUI documentation on MediaWiki] [1]
+ * IconWidget is a generic widget for {@link OO.ui.mixin.IconElement icons}.
+ * In general, IconWidgets should be used with OO.ui.LabelWidget, which creates a label that
+ * identifies the icon’s function. See the [OOUI documentation on MediaWiki] [1]
  * for a list of icons included in the library.
  *
  *     @example
@@ -4090,10 +4036,19 @@ OO.ui.IconWidget = function OoUiIconWidget( config ) {
        OO.ui.IconWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, $.extend( {}, config, { $icon: this.$element } ) );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );
-       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element, invisibleLabel: true } ) );
-       OO.ui.mixin.FlaggedElement.call( this, $.extend( {}, config, { $flagged: this.$element } ) );
+       OO.ui.mixin.IconElement.call( this, $.extend( {
+               $icon: this.$element
+       }, config ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {
+               $titled: this.$element
+       }, config ) );
+       OO.ui.mixin.LabelElement.call( this, $.extend( {
+               $label: this.$element,
+               invisibleLabel: true
+       }, config ) );
+       OO.ui.mixin.FlaggedElement.call( this, $.extend( {
+               $flagged: this.$element
+       }, config ) );
 
        // Initialization
        this.$element.addClass( 'oo-ui-iconWidget' );
@@ -4156,9 +4111,16 @@ OO.ui.IndicatorWidget = function OoUiIndicatorWidget( config ) {
        OO.ui.IndicatorWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.IndicatorElement.call( this, $.extend( {}, config, { $indicator: this.$element } ) );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );
-       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element, invisibleLabel: true } ) );
+       OO.ui.mixin.IndicatorElement.call( this, $.extend( {
+               $indicator: this.$element
+       }, config ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {
+               $titled: this.$element
+       }, config ) );
+       OO.ui.mixin.LabelElement.call( this, $.extend( {
+               $label: this.$element,
+               invisibleLabel: true
+       }, config ) );
 
        // Initialization
        this.$element.addClass( 'oo-ui-indicatorWidget' );
@@ -4188,12 +4150,13 @@ OO.ui.IndicatorWidget.static.tagName = 'span';
  *
  * - String: a plaintext string
  * - jQuery selection: a jQuery selection, used for anything other than a plaintext label, e.g., a
- *   label that includes a link or special styling, such as a gray color or additional graphical elements.
+ *   label that includes a link or special styling, such as a gray color or additional
+ *   graphical elements.
  * - Function: a function that will produce a string in the future. Functions are used
  *   in cases where the value of the label is not currently defined.
  *
- * In addition, the LabelWidget can be associated with an {@link OO.ui.InputWidget input widget}, which
- * will come into focus when the label is clicked.
+ * In addition, the LabelWidget can be associated with an {@link OO.ui.InputWidget input widget},
+ * which will come into focus when the label is clicked.
  *
  *     @example
  *     // Two LabelWidgets.
@@ -4229,7 +4192,9 @@ OO.ui.LabelWidget = function OoUiLabelWidget( config ) {
        OO.ui.LabelWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element } ) );
+       OO.ui.mixin.LabelElement.call( this, $.extend( {
+               $label: this.$element
+       }, config ) );
        OO.ui.mixin.TitledElement.call( this, config );
 
        // Properties
@@ -4263,14 +4228,15 @@ OO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.TitledElement );
 OO.ui.LabelWidget.static.tagName = 'label';
 
 /**
- * PendingElement is a mixin that is used to create elements that notify users that something is happening
- * and that they should wait before proceeding. The pending state is visually represented with a pending
- * texture that appears in the head of a pending {@link OO.ui.ProcessDialog process dialog} or in the input
- * field of a {@link OO.ui.TextInputWidget text input widget}.
+ * PendingElement is a mixin that is used to create elements that notify users that something is
+ * happening and that they should wait before proceeding. The pending state is visually represented
+ * with a pending texture that appears in the head of a pending
+ * {@link OO.ui.ProcessDialog process dialog} or in the input field of a
+ * {@link OO.ui.TextInputWidget text input widget}.
  *
- * Currently, {@link OO.ui.ActionWidget Action widgets}, which mix in this class, can also be marked as pending, but only when
- * used in {@link OO.ui.MessageDialog message dialogs}. The behavior is not currently supported for action widgets used
- * in process dialogs.
+ * Currently, {@link OO.ui.ActionWidget Action widgets}, which mix in this class, can also be marked
+ * as pending, but only when used in {@link OO.ui.MessageDialog message dialogs}. The behavior is
+ * not currently supported for action widgets used in process dialogs.
  *
  *     @example
  *     function MessageDialog( config ) {
@@ -4287,7 +4253,9 @@ OO.ui.LabelWidget.static.tagName = 'label';
  *     MessageDialog.prototype.initialize = function () {
  *         MessageDialog.parent.prototype.initialize.apply( this, arguments );
  *         this.content = new OO.ui.PanelLayout( { padded: true } );
- *         this.content.$element.append( '<p>Click the \'Done\' action widget to see its pending state. Note that action widgets can be marked pending in message dialogs but not process dialogs.</p>' );
+ *         this.content.$element.append( '<p>Click the \'Done\' action widget to see its pending ' +
+ *             'state. Note that action widgets can be marked pending in message dialogs but not ' +
+ *             'process dialogs.</p>' );
  *         this.$body.append( this.content.$element );
  *     };
  *     MessageDialog.prototype.getBodyHeight = function () {
@@ -4449,7 +4417,8 @@ OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) {
        this.setFloatableElement( config.$floatable || this.$element );
        this.setVerticalPosition( config.verticalPosition || 'below' );
        this.setHorizontalPosition( config.horizontalPosition || 'start' );
-       this.hideWhenOutOfView = config.hideWhenOutOfView === undefined ? true : !!config.hideWhenOutOfView;
+       this.hideWhenOutOfView = config.hideWhenOutOfView === undefined ?
+               true : !!config.hideWhenOutOfView;
 };
 
 /* Methods */
@@ -4545,11 +4514,15 @@ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positionin
        if ( this.positioning !== positioning ) {
                this.positioning = positioning;
 
-               closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] );
+               closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer(
+                       this.$floatableContainer[ 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' ) ) {
-                       closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer );
+                       closestScrollableOfContainer = OO.ui.Element.static.getWindow(
+                               closestScrollableOfContainer
+                       );
                }
 
                if ( positioning ) {
@@ -4580,7 +4553,8 @@ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positionin
 };
 
 /**
- * Check whether the bottom edge of the given element is within the viewport of the given container.
+ * Check whether the bottom edge of the given element is within the viewport of the given
+ * container.
  *
  * @private
  * @param {jQuery} $element
@@ -4588,8 +4562,8 @@ OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positionin
  * @return {boolean}
  */
 OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) {
-       var elemRect, contRect, topEdgeInBounds, bottomEdgeInBounds, leftEdgeInBounds, rightEdgeInBounds,
-               startEdgeInBounds, endEdgeInBounds, viewportSpacing,
+       var elemRect, contRect, topEdgeInBounds, bottomEdgeInBounds, leftEdgeInBounds,
+               rightEdgeInBounds, startEdgeInBounds, endEdgeInBounds, viewportSpacing,
                direction = $element.css( 'direction' );
 
        elemRect = $element[ 0 ].getBoundingClientRect();
@@ -4676,7 +4650,8 @@ OO.ui.mixin.FloatableElement.prototype.position = function () {
                return this;
        }
 
-       this.floatableOutOfView = this.hideWhenOutOfView && !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable );
+       this.floatableOutOfView = this.hideWhenOutOfView &&
+               !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable );
        if ( this.floatableOutOfView ) {
                this.$floatable.addClass( 'oo-ui-element-hidden' );
                return this;
@@ -4689,8 +4664,8 @@ OO.ui.mixin.FloatableElement.prototype.position = function () {
        // We updated the position, so re-evaluate the clipping state.
        // (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so
        // will not notice the need to update itself.)
-       // TODO: This is terrible, we shouldn't need to know about ClippableElement at all here. Why does
-       // it not listen to the right events in the right places?
+       // TODO: This is terrible, we shouldn't need to know about ClippableElement at all here.
+       // Why does it not listen to the right events in the right places?
        if ( this.clip ) {
                this.clip();
        }
@@ -4718,15 +4693,19 @@ OO.ui.mixin.FloatableElement.prototype.computePosition = function () {
                $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';
+       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;
+       // 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
@@ -4766,7 +4745,8 @@ OO.ui.mixin.FloatableElement.prototype.computePosition = function () {
 
        if ( newPos.start !== undefined ) {
                if ( direction === 'rtl' ) {
-                       newPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) : $offsetParent ).outerWidth() - newPos.start;
+                       newPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) :
+                               $offsetParent ).outerWidth() - newPos.start;
                } else {
                        newPos.left = newPos.start;
                }
@@ -4776,7 +4756,8 @@ OO.ui.mixin.FloatableElement.prototype.computePosition = function () {
                if ( direction === 'rtl' ) {
                        newPos.left = newPos.end;
                } else {
-                       newPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) : $offsetParent ).outerWidth() - newPos.end;
+                       newPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) :
+                               $offsetParent ).outerWidth() - newPos.end;
                }
                delete newPos.end;
        }
@@ -5073,7 +5054,8 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
                buffer = 7;
 
        if ( !this.clipping ) {
-               // this.$clippableScrollableContainer and this.$clippableWindow are null, so the below will fail
+               // this.$clippableScrollableContainer and this.$clippableWindow are null, so the below
+               // will fail
                return this;
        }
 
@@ -5164,8 +5146,10 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
        clipHeight = allotedHeight < naturalHeight;
 
        if ( clipWidth ) {
-               // The order matters here. If overflow is not set first, Chrome displays bogus scrollbars. See T157672.
-               // Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for this case.
+               // The order matters here. If overflow is not set first, Chrome displays bogus scrollbars.
+               // See T157672.
+               // Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for
+               // this case.
                this.$clippable.css( 'overflowX', 'scroll' );
                // eslint-disable-next-line no-void
                void this.$clippable[ 0 ].offsetHeight; // Force reflow
@@ -5181,8 +5165,10 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
                } );
        }
        if ( clipHeight ) {
-               // The order matters here. If overflow is not set first, Chrome displays bogus scrollbars. See T157672.
-               // Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for this case.
+               // The order matters here. If overflow is not set first, Chrome displays bogus scrollbars.
+               // See T157672.
+               // Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for
+               // this case.
                this.$clippable.css( 'overflowY', 'scroll' );
                // eslint-disable-next-line no-void
                void this.$clippable[ 0 ].offsetHeight; // Force reflow
@@ -5243,22 +5229,22 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
  * @cfg {boolean} [anchor=true] Show anchor pointing to origin of popup
  * @cfg {string} [position='below'] Where to position the popup relative to $floatableContainer
  *  'above': Put popup above $floatableContainer; anchor points down to the horizontal center
- *           of $floatableContainer
+ *    of $floatableContainer
  *  'below': Put popup below $floatableContainer; anchor points up to the horizontal center
- *           of $floatableContainer
+ *    of $floatableContainer
  *  'before': Put popup to the left (LTR) / right (RTL) of $floatableContainer; anchor points
- *            endwards (right/left) to the vertical center of $floatableContainer
+ *    endwards (right/left) to the vertical center of $floatableContainer
  *  'after': Put popup to the right (LTR) / left (RTL) of $floatableContainer; anchor points
- *            startwards (left/right) to the vertical center of $floatableContainer
+ *    startwards (left/right) to the vertical center of $floatableContainer
  * @cfg {string} [align='center'] How to align the popup to $floatableContainer
- *  'forwards': If position is above/below, move the popup as far endwards (right in LTR, left in RTL)
- *              as possible while still keeping the anchor within the popup;
- *              if position is before/after, move the popup as far downwards as possible.
- *  'backwards': If position is above/below, move the popup as far startwards (left in LTR, right in RTL)
- *               as possible while still keeping the anchor within the popup;
- *               if position in before/after, move the popup as far upwards as possible.
- *  'center': Horizontally (if position is above/below) or vertically (before/after) align the center
- *            of the popup with the center of $floatableContainer.
+ *  'forwards': If position is above/below, move the popup as far endwards (right in LTR, left in
+ *    RTL) as possible while still keeping the anchor within the popup; if position is before/after,
+ *    move the popup as far downwards as possible.
+ *  'backwards': If position is above/below, move the popup as far startwards (left in LTR, right in
+ *    RTL) as possible while still keeping the anchor within the popup; if position is before/after,
+ *     move the popup as far upwards as possible.
+ *  'center': Horizontally (if position is above/below) or vertically (before/after) align the
+ *     center of the popup with the center of $floatableContainer.
  * 'force-left': Alias for 'forwards' in LTR and 'backwards' in RTL
  * 'force-right': Alias for 'backwards' in RTL and 'forwards' in LTR
  * @cfg {boolean} [autoFlip=true] Whether to automatically switch the popup's position between
@@ -5267,13 +5253,14 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
  * @cfg {jQuery} [$container] Constrain the popup to the boundaries of the specified container.
  *  See the [OOUI docs on MediaWiki][3] for an example.
  *  [3]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups#containerExample
- * @cfg {number} [containerPadding=10] Padding between the popup and its container, specified as a number of pixels.
+ * @cfg {number} [containerPadding=10] Padding between the popup and its container, specified as a
+ *  number of pixels.
  * @cfg {jQuery} [$content] Content to append to the popup's body
  * @cfg {jQuery} [$footer] Content to append to the popup's footer
  * @cfg {boolean} [autoClose=false] Automatically close the popup when it loses focus.
  * @cfg {jQuery} [$autoCloseIgnore] Elements that will not close the popup when clicked.
- *  This config option is only relevant if #autoClose is set to `true`. See the [OOUI documentation on MediaWiki][2]
- *  for an example.
+ *  This config option is only relevant if #autoClose is set to `true`. See the
+ *  [OOUI documentation on MediaWiki][2] for an example.
  *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups#autocloseExample
  * @cfg {boolean} [head=false] Show a popup header that contains a #label (if specified) and close
  *  button.
@@ -5292,10 +5279,10 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
 
        // Mixin constructors
        OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, {
+       OO.ui.mixin.ClippableElement.call( this, $.extend( {
                $clippable: this.$body,
                $clippableContainer: this.$popup
-       } ) );
+       }, config ) );
        OO.ui.mixin.FloatableElement.call( this, config );
 
        // Properties
@@ -5335,8 +5322,13 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
        }
 
        if ( config.head ) {
-               this.closeButton = new OO.ui.ButtonWidget( { framed: false, icon: 'close' } );
-               this.closeButton.connect( this, { click: 'onCloseButtonClick' } );
+               this.closeButton = new OO.ui.ButtonWidget( {
+                       framed: false,
+                       icon: 'close'
+               } );
+               this.closeButton.connect( this, {
+                       click: 'onCloseButtonClick'
+               } );
                this.$head = $( '<div>' )
                        .addClass( 'oo-ui-popupWidget-head' )
                        .append( this.$label, this.closeButton.$element );
@@ -5389,12 +5381,6 @@ OO.ui.PopupWidget.prototype.onDocumentMouseDown = function ( e ) {
        }
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.PopupWidget.prototype.onMouseDown = function () {
-       OO.ui.warnDeprecation( 'onMouseDown is deprecated, use onDocumentMouseDown instead' );
-       this.onDocumentMouseDown.apply( this, arguments );
-};
-
 /**
  * Bind document mouse down listener.
  *
@@ -5412,12 +5398,6 @@ OO.ui.PopupWidget.prototype.bindDocumentMouseDownListener = function () {
        this.getElementDocument().addEventListener( 'click', this.onDocumentMouseDownHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.PopupWidget.prototype.bindMouseDownListener = function () {
-       OO.ui.warnDeprecation( 'bindMouseDownListener is deprecated, use bindDocumentMouseDownListener instead' );
-       this.bindDocumentMouseDownListener.apply( this, arguments );
-};
-
 /**
  * Handles close button click events.
  *
@@ -5439,12 +5419,6 @@ OO.ui.PopupWidget.prototype.unbindDocumentMouseDownListener = function () {
        this.getElementDocument().removeEventListener( 'click', this.onDocumentMouseDownHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {
-       OO.ui.warnDeprecation( 'unbindMouseDownListener is deprecated, use unbindDocumentMouseDownListener instead' );
-       this.unbindDocumentMouseDownListener.apply( this, arguments );
-};
-
 /**
  * Handles document key down events.
  *
@@ -5471,12 +5445,6 @@ OO.ui.PopupWidget.prototype.bindDocumentKeyDownListener = function () {
        this.getElementDocument().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.PopupWidget.prototype.bindKeyDownListener = function () {
-       OO.ui.warnDeprecation( 'bindKeyDownListener is deprecated, use bindDocumentKeyDownListener instead' );
-       this.bindDocumentKeyDownListener.apply( this, arguments );
-};
-
 /**
  * Unbind document key down listener.
  *
@@ -5486,12 +5454,6 @@ OO.ui.PopupWidget.prototype.unbindDocumentKeyDownListener = function () {
        this.getElementDocument().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.PopupWidget.prototype.unbindKeyDownListener = function () {
-       OO.ui.warnDeprecation( 'unbindKeyDownListener is deprecated, use unbindDocumentKeyDownListener instead' );
-       this.unbindDocumentKeyDownListener.apply( this, arguments );
-};
-
 /**
  * Show, hide, or toggle the visibility of the anchor.
  *
@@ -5567,8 +5529,8 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) {
        }
 
        if ( change && show && this.autoFlip ) {
-               // Reset auto-flipping before showing the popup again. It's possible we no longer need to flip
-               // (e.g. if the user scrolled).
+               // Reset auto-flipping before showing the popup again. It's possible we no longer need to
+               // flip (e.g. if the user scrolled).
                this.isAutoFlipped = false;
        }
 
@@ -5589,8 +5551,8 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) {
                        if ( this.autoFlip ) {
                                if ( this.popupPosition === 'above' || this.popupPosition === 'below' ) {
                                        if ( this.isClippedVertically() || this.isFloatableOutOfView() ) {
-                                               // If opening the popup in the normal direction causes it to be clipped, open
-                                               // in the opposite one instead
+                                               // If opening the popup in the normal direction causes it to be clipped,
+                                               // open in the opposite one instead
                                                normalHeight = this.$element.height();
                                                this.isAutoFlipped = !this.isAutoFlipped;
                                                this.position();
@@ -5607,12 +5569,13 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) {
                                }
                                if ( this.popupPosition === 'before' || this.popupPosition === 'after' ) {
                                        if ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {
-                                               // If opening the popup in the normal direction causes it to be clipped, open
-                                               // in the opposite one instead
+                                               // If opening the popup in the normal direction causes it to be clipped,
+                                               // open in the opposite one instead
                                                normalWidth = this.$element.width();
                                                this.isAutoFlipped = !this.isAutoFlipped;
-                                               // Due to T180173 horizontally clipped PopupWidgets have messed up dimensions,
-                                               // which causes positioning to be off. Toggle clipping back and fort to work around.
+                                               // Due to T180173 horizontally clipped PopupWidgets have messed up
+                                               // dimensions, which causes positioning to be off. Toggle clipping back and
+                                               // forth to work around.
                                                this.toggleClipping( false );
                                                this.position();
                                                this.toggleClipping( true );
@@ -5622,8 +5585,9 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) {
                                                        oppositeWidth = this.$element.width();
                                                        if ( oppositeWidth < normalWidth ) {
                                                                this.isAutoFlipped = !this.isAutoFlipped;
-                                                               // Due to T180173 horizontally clipped PopupWidgets have messed up dimensions,
-                                                               // which causes positioning to be off. Toggle clipping back and fort to work around.
+                                                               // Due to T180173, horizontally clipped PopupWidgets have messed up
+                                                               // dimensions, which causes positioning to be off. Toggle clipping
+                                                               // back and forth to work around.
                                                                this.toggleClipping( false );
                                                                this.position();
                                                                this.toggleClipping( true );
@@ -5700,9 +5664,9 @@ OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {
  * @inheritdoc
  */
 OO.ui.PopupWidget.prototype.computePosition = function () {
-       var direction, align, vertical, start, end, near, far, sizeProp, popupSize, anchorSize, anchorPos,
-               anchorOffset, anchorMargin, parentPosition, positionProp, positionAdjustment, floatablePos,
-               offsetParentPos, containerPos, popupPosition, viewportSpacing,
+       var direction, align, vertical, start, end, near, far, sizeProp, popupSize, anchorSize,
+               anchorPos, anchorOffset, anchorMargin, parentPosition, positionProp, positionAdjustment,
+               floatablePos, offsetParentPos, containerPos, popupPosition, viewportSpacing,
                popupPos = {},
                anchorCss = { left: '', right: '', top: '', bottom: '' },
                popupPositionOppositeMap = {
@@ -5757,14 +5721,17 @@ OO.ui.PopupWidget.prototype.computePosition = function () {
                popupPosition = popupPositionOppositeMap[ popupPosition ];
        }
 
-       // If the popup is positioned before or after, then the anchor positioning is vertical, otherwise horizontal
+       // If the popup is positioned before or after, then the anchor positioning is vertical,
+       // otherwise horizontal
        vertical = popupPosition === 'before' || popupPosition === 'after';
        start = vertical ? 'top' : ( direction === 'rtl' ? 'right' : 'left' );
        end = vertical ? 'bottom' : ( direction === 'rtl' ? 'left' : 'right' );
        near = vertical ? 'top' : 'left';
        far = vertical ? 'bottom' : 'right';
        sizeProp = vertical ? 'Height' : 'Width';
-       popupSize = vertical ? ( this.height || this.$popup.height() ) : ( this.width || this.$popup.width() );
+       popupSize = vertical ?
+               ( this.height || this.$popup.height() ) :
+               ( this.width || this.$popup.width() );
 
        this.setAnchorEdge( anchorEdgeMap[ popupPosition ] );
        this.horizontalPosition = vertical ? popupPosition : hPosMap[ align ];
@@ -5795,12 +5762,14 @@ OO.ui.PopupWidget.prototype.computePosition = function () {
        }
 
        if ( this.anchored ) {
-               // Position the anchor (which is positioned relative to the popup) to point to $floatableContainer
+               // Position the anchor (which is positioned relative to the popup) to point to
+               // $floatableContainer
                anchorPos = ( floatablePos[ start ] + floatablePos[ end ] ) / 2;
                anchorOffset = ( start === far ? -1 : 1 ) * ( anchorPos - popupPos[ start ] );
 
-               // If the anchor is less than 2*anchorSize from either edge, move the popup to make more space
-               // this.$anchor.width()/height() returns 0 because of the CSS trickery we use, so use scrollWidth/Height
+               // If the anchor is less than 2*anchorSize from either edge, move the popup to make more
+               // space this.$anchor.width()/height() returns 0 because of the CSS trickery we use, so use
+               // scrollWidth/Height
                anchorSize = this.$anchor[ 0 ][ 'scroll' + sizeProp ];
                anchorMargin = parseFloat( this.$anchor.css( 'margin-' + start ) );
                if ( anchorOffset + anchorMargin < 2 * anchorSize ) {
@@ -6011,9 +5980,10 @@ OO.ui.mixin.PopupElement.prototype.getPopup = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$overlay] Render the popup into a separate layer. This configuration is useful in cases where
- *  the expanded popup is larger than its containing `<div>`. The specified overlay layer is usually on top of the
- *  containing `<div>` and has a larger area. By default, the popup uses relative positioning.
+ * @cfg {jQuery} [$overlay] Render the popup into a separate layer. This configuration is useful
+ *  in cases where the expanded popup is larger than its containing `<div>`. The specified overlay
+ *  layer is usually on top of the containing `<div>` and has a larger area. By default, the popup
+ *  uses relative positioning.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
  */
 OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {
@@ -6027,14 +5997,16 @@ OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {
        OO.ui.mixin.PopupElement.call( this, config );
 
        // Properties
-       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
+       this.$overlay = ( config.$overlay === true ?
+               OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
 
        // Events
-       this.connect( this, { click: 'onAction' } );
+       this.connect( this, {
+               click: 'onAction'
+       } );
 
        // Initialization
-       this.$element
-               .addClass( 'oo-ui-popupButtonWidget' );
+       this.$element.addClass( 'oo-ui-popupButtonWidget' );
        this.popup.$element
                .addClass( 'oo-ui-popupButtonWidget-popup' )
                .toggleClass( 'oo-ui-popupButtonWidget-framed-popup', this.isFramed() )
@@ -6111,8 +6083,8 @@ OO.ui.mixin.GroupWidget.prototype.setDisabled = function ( disabled ) {
 /**
  * Mixin for widgets used as items in widgets that mix in OO.ui.mixin.GroupWidget.
  *
- * Item widgets have a reference to a OO.ui.mixin.GroupWidget while they are attached to the group. This
- * allows bidirectional communication.
+ * Item widgets have a reference to a OO.ui.mixin.GroupWidget while they are attached to the group.
+ * This allows bidirectional communication.
  *
  * Use together with OO.ui.mixin.GroupWidget to make disabled state inheritable.
  *
@@ -6192,17 +6164,16 @@ OO.ui.OptionWidget = function OoUiOptionWidget( config ) {
        OO.ui.mixin.TitledElement.call( this, config );
 
        // Properties
-       this.selected = false;
        this.highlighted = false;
        this.pressed = false;
+       this.setSelected( !!config.selected );
 
        // Initialization
        this.$element
                .data( 'oo-ui-optionWidget', this )
-               // Allow programmatic focussing (and by accesskey), but not tabbing
+               // Allow programmatic focussing (and by access key), but not tabbing
                .attr( 'tabindex', '-1' )
                .attr( 'role', 'option' )
-               .attr( 'aria-selected', 'false' )
                .addClass( 'oo-ui-optionWidget' )
                .append( this.$label );
 };
@@ -6267,7 +6238,7 @@ OO.ui.OptionWidget.prototype.isSelectable = function () {
 
 /**
  * Check if the option can be highlighted. A highlight indicates that the option
- * may be selected when a user presses enter or clicks. Disabled items cannot
+ * may be selected when a user presses Enter key or clicks. Disabled items cannot
  * be highlighted.
  *
  * @return {boolean} Item is highlightable
@@ -6297,7 +6268,7 @@ OO.ui.OptionWidget.prototype.isSelected = function () {
 
 /**
  * Check if the option is highlighted. A highlight indicates that the
- * item may be selected when a user presses enter or clicks.
+ * item may be selected when a user presses Enter key or clicks.
  *
  * @return {boolean} Item is highlighted
  */
@@ -6318,8 +6289,8 @@ OO.ui.OptionWidget.prototype.isPressed = function () {
 
 /**
  * Set the option’s selected state. In general, all modifications to the selection
- * should be handled by the SelectWidget’s {@link OO.ui.SelectWidget#selectItem selectItem( [item] )}
- * method instead of this method.
+ * should be handled by the SelectWidget’s
+ * {@link OO.ui.SelectWidget#selectItem selectItem( [item] )} method instead of this method.
  *
  * @param {boolean} [state=false] Select option
  * @chainable
@@ -6396,8 +6367,8 @@ OO.ui.OptionWidget.prototype.getMatchText = function () {
  * {@link OO.ui.RadioSelectWidget radio selects}, and {@link OO.ui.MenuSelectWidget
  * menu selects}.
  *
- * This class should be used together with OO.ui.OptionWidget or OO.ui.DecoratedOptionWidget. For more
- * information, please see the [OOUI documentation on MediaWiki][1].
+ * This class should be used together with OO.ui.OptionWidget or OO.ui.DecoratedOptionWidget. For
+ * more information, please see the [OOUI documentation on MediaWiki][1].
  *
  *     @example
  *     // A select widget with three options.
@@ -6432,6 +6403,7 @@ OO.ui.OptionWidget.prototype.getMatchText = function () {
  *  Options are created with {@link OO.ui.OptionWidget OptionWidget} classes. See
  *  the [OOUI documentation on MediaWiki] [2] for examples.
  *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options
+ * @cfg {boolean} [multiselect] Allow for multiple selections
  */
 OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
        // Configuration initialization
@@ -6441,11 +6413,14 @@ OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
        OO.ui.SelectWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.GroupWidget.call( this, $.extend( {}, config, { $group: this.$element } ) );
+       OO.ui.mixin.GroupWidget.call( this, $.extend( {
+               $group: this.$element
+       }, config ) );
 
        // Properties
        this.pressed = false;
        this.selecting = null;
+       this.multiselect = !!config.multiselect;
        this.onDocumentMouseUpHandler = this.onDocumentMouseUp.bind( this );
        this.onDocumentMouseMoveHandler = this.onDocumentMouseMove.bind( this );
        this.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );
@@ -6467,7 +6442,8 @@ OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
 
        // Initialization
        this.$element
-               .addClass( 'oo-ui-selectWidget oo-ui-selectWidget-depressed' )
+               // -depressed is a deprecated alias of -unpressed
+               .addClass( 'oo-ui-selectWidget oo-ui-selectWidget-unpressed oo-ui-selectWidget-depressed' )
                .attr( 'role', 'listbox' );
        this.setFocusOwner( this.$element );
        if ( Array.isArray( config.items ) ) {
@@ -6502,15 +6478,19 @@ OO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupWidget );
 /**
  * @event select
  *
- * A `select` event is emitted when the selection is modified programmatically with the #selectItem method.
+ * A `select` event is emitted when the selection is modified programmatically with the #selectItem
+ * method.
  *
- * @param {OO.ui.OptionWidget|null} item Selected item
+ * @param {OO.ui.OptionWidget[]|OO.ui.OptionWidget|null} items Currently selected items
  */
 
 /**
  * @event choose
+ *
  * A `choose` event is emitted when an item is chosen with the #chooseItem method.
+ *
  * @param {OO.ui.OptionWidget} item Chosen item
+ * @param {boolean} selected Item is selected
  */
 
 /**
@@ -6531,6 +6511,27 @@ OO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupWidget );
  * @param {OO.ui.OptionWidget[]} items Removed items
  */
 
+/* Static methods */
+
+/**
+ * Normalize text for filter matching
+ *
+ * @param {string} text Text
+ * @return {string} Normalized text
+ */
+OO.ui.SelectWidget.static.normalizeForMatching = function ( text ) {
+       // Replace trailing whitespace, normalize multiple spaces and make case insensitive
+       var normalized = text.trim().replace( /\s+/, ' ' ).toLowerCase();
+
+       // Normalize Unicode
+       // eslint-disable-next-line no-restricted-properties
+       if ( normalized.normalize ) {
+               // eslint-disable-next-line no-restricted-properties
+               normalized = normalized.normalize();
+       }
+       return normalized;
+};
+
 /* Methods */
 
 /**
@@ -6550,12 +6551,13 @@ OO.ui.SelectWidget.prototype.onFocus = function ( event ) {
        } else {
                if ( event.target.tabIndex === -1 ) {
                        // One of the options got focussed (and the event bubbled up here).
-                       // They can't be tabbed to, but they can be activated using accesskeys.
+                       // They can't be tabbed to, but they can be activated using access keys.
                        // OptionWidgets and focusable UI elements inside them have tabindex="-1" set.
                        item = this.findTargetItem( event );
                } else {
-                       // There is something actually user-focusable in one of the labels of the options, and the
-                       // user focussed it (e.g. by tabbing to it). Do nothing (especially, don't change the focus).
+                       // There is something actually user-focusable in one of the labels of the options, and
+                       // the user focussed it (e.g. by tabbing to it). Do nothing (especially, don't change
+                       // the focus).
                        return;
                }
        }
@@ -6625,12 +6627,6 @@ OO.ui.SelectWidget.prototype.onDocumentMouseUp = function ( e ) {
        return false;
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.onMouseUp = function () {
-       OO.ui.warnDeprecation( 'onMouseUp is deprecated, use onDocumentMouseUp instead' );
-       this.onDocumentMouseUp.apply( this, arguments );
-};
-
 /**
  * Handle document mouse move events.
  *
@@ -6649,12 +6645,6 @@ OO.ui.SelectWidget.prototype.onDocumentMouseMove = function ( e ) {
        }
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.onMouseMove = function () {
-       OO.ui.warnDeprecation( 'onMouseMove is deprecated, use onDocumentMouseMove instead' );
-       this.onDocumentMouseMove.apply( this, arguments );
-};
-
 /**
  * Handle mouse over events.
  *
@@ -6697,12 +6687,13 @@ OO.ui.SelectWidget.prototype.onMouseLeave = function () {
 OO.ui.SelectWidget.prototype.onDocumentKeyDown = function ( e ) {
        var nextItem,
                handled = false,
-               currentItem = this.findHighlightedItem() || this.findSelectedItem();
+               currentItem = this.findHighlightedItem(),
+               firstItem = this.getItems()[ 0 ];
 
        if ( !this.isDisabled() && this.isVisible() ) {
                switch ( e.keyCode ) {
                        case OO.ui.Keys.ENTER:
-                               if ( currentItem && currentItem.constructor.static.highlightable ) {
+                               if ( currentItem ) {
                                        // Was only highlighted, now let's select it. No-op if already selected.
                                        this.chooseItem( currentItem );
                                        handled = true;
@@ -6711,18 +6702,18 @@ OO.ui.SelectWidget.prototype.onDocumentKeyDown = function ( e ) {
                        case OO.ui.Keys.UP:
                        case OO.ui.Keys.LEFT:
                                this.clearKeyPressBuffer();
-                               nextItem = this.findRelativeSelectableItem( currentItem, -1 );
+                               nextItem = currentItem ? this.findRelativeSelectableItem( currentItem, -1 ) : firstItem;
                                handled = true;
                                break;
                        case OO.ui.Keys.DOWN:
                        case OO.ui.Keys.RIGHT:
                                this.clearKeyPressBuffer();
-                               nextItem = this.findRelativeSelectableItem( currentItem, 1 );
+                               nextItem = currentItem ? this.findRelativeSelectableItem( currentItem, 1 ) : firstItem;
                                handled = true;
                                break;
                        case OO.ui.Keys.ESCAPE:
                        case OO.ui.Keys.TAB:
-                               if ( currentItem && currentItem.constructor.static.highlightable ) {
+                               if ( currentItem ) {
                                        currentItem.setHighlighted( false );
                                }
                                this.unbindDocumentKeyDownListener();
@@ -6748,12 +6739,6 @@ OO.ui.SelectWidget.prototype.onDocumentKeyDown = function ( e ) {
        }
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.onKeyDown = function () {
-       OO.ui.warnDeprecation( 'onKeyDown is deprecated, use onDocumentKeyDown instead' );
-       this.onDocumentKeyDown.apply( this, arguments );
-};
-
 /**
  * Bind document key down listener.
  *
@@ -6763,12 +6748,6 @@ OO.ui.SelectWidget.prototype.bindDocumentKeyDownListener = function () {
        this.getElementDocument().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.bindKeyDownListener = function () {
-       OO.ui.warnDeprecation( 'bindKeyDownListener is deprecated, use bindDocumentKeyDownListener instead' );
-       this.bindDocumentKeyDownListener.apply( this, arguments );
-};
-
 /**
  * Unbind document key down listener.
  *
@@ -6778,12 +6757,6 @@ OO.ui.SelectWidget.prototype.unbindDocumentKeyDownListener = function () {
        this.getElementDocument().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {
-       OO.ui.warnDeprecation( 'unbindKeyDownListener is deprecated, use unbindDocumentKeyDownListener instead' );
-       this.unbindDocumentKeyDownListener.apply( this, arguments );
-};
-
 /**
  * Scroll item into view, preventing spurious mouse highlight actions from happening.
  *
@@ -6791,8 +6764,8 @@ OO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {
  */
 OO.ui.SelectWidget.prototype.scrollItemIntoView = function ( item ) {
        var widget = this;
-       // Chromium's Blink engine will generate spurious 'mouseover' events during programmatic scrolling
-       // and around 100-150 ms after it is finished.
+       // Chromium's Blink engine will generate spurious 'mouseover' events during programmatic
+       // scrolling and around 100-150 ms after it is finished.
        this.blockMouseOverEvents++;
        item.scrollElementIntoView().done( function () {
                setTimeout( function () {
@@ -6873,42 +6846,41 @@ OO.ui.SelectWidget.prototype.onDocumentKeyPress = function ( e ) {
        e.stopPropagation();
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.onKeyPress = function () {
-       OO.ui.warnDeprecation( 'onKeyPress is deprecated, use onDocumentKeyPress instead' );
-       this.onDocumentKeyPress.apply( this, arguments );
-};
-
 /**
  * Get a matcher for the specific string
  *
  * @protected
- * @param {string} s String to match against items
- * @param {boolean} [exact=false] Only accept exact matches
+ * @param {string} query String to match against items
+ * @param {string} [mode='prefix'] Matching mode: 'substring', 'prefix', or 'exact'
  * @return {Function} function ( OO.ui.OptionWidget ) => boolean
  */
-OO.ui.SelectWidget.prototype.getItemMatcher = function ( s, exact ) {
-       var re;
+OO.ui.SelectWidget.prototype.getItemMatcher = function ( query, mode ) {
+       var normalizeForMatching = this.constructor.static.normalizeForMatching,
+               normalizedQuery = normalizeForMatching( query );
 
-       // eslint-disable-next-line no-restricted-properties
-       if ( s.normalize ) {
-               // eslint-disable-next-line no-restricted-properties
-               s = s.normalize();
-       }
-       s = exact ? s.trim() : s.replace( /^\s+/, '' );
-       re = '^\\s*' + s.replace( /([\\{}()|.?*+\-^$[\]])/g, '\\$1' ).replace( /\s+/g, '\\s+' );
-       if ( exact ) {
-               re += '\\s*$';
+       // Support deprecated exact=true argument
+       if ( mode === true ) {
+               mode = 'exact';
        }
-       re = new RegExp( re, 'i' );
+
        return function ( item ) {
-               var matchText = item.getMatchText();
-               // eslint-disable-next-line no-restricted-properties
-               if ( matchText.normalize ) {
-                       // eslint-disable-next-line no-restricted-properties
-                       matchText = matchText.normalize();
+               var matchText = normalizeForMatching( item.getMatchText() );
+
+               if ( normalizedQuery === '' ) {
+                       // Empty string matches all, except if we are in 'exact'
+                       // mode, where it doesn't match at all
+                       return mode !== 'exact';
+               }
+
+               switch ( mode ) {
+                       case 'exact':
+                               return matchText === normalizedQuery;
+                       case 'substring':
+                               return matchText.indexOf( normalizedQuery ) !== -1;
+                       // 'prefix'
+                       default:
+                               return matchText.indexOf( normalizedQuery ) === 0;
                }
-               return re.test( matchText );
        };
 };
 
@@ -6921,12 +6893,6 @@ OO.ui.SelectWidget.prototype.bindDocumentKeyPressListener = function () {
        this.getElementDocument().addEventListener( 'keypress', this.onDocumentKeyPressHandler, true );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.bindKeyPressListener = function () {
-       OO.ui.warnDeprecation( 'bindKeyPressListener is deprecated, use bindDocumentKeyPressListener instead' );
-       this.bindDocumentKeyPressListener.apply( this, arguments );
-};
-
 /**
  * Unbind document key down listener.
  *
@@ -6940,12 +6906,6 @@ OO.ui.SelectWidget.prototype.unbindDocumentKeyPressListener = function () {
        this.clearKeyPressBuffer();
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.SelectWidget.prototype.unbindKeyPressListener = function () {
-       OO.ui.warnDeprecation( 'unbindKeyPressListener is deprecated, use unbindDocumentKeyPressListener instead' );
-       this.unbindDocumentKeyPressListener.apply( this, arguments );
-};
-
 /**
  * Visibility change handler
  *
@@ -6973,20 +6933,36 @@ OO.ui.SelectWidget.prototype.findTargetItem = function ( e ) {
        return $option.data( 'oo-ui-optionWidget' ) || null;
 };
 
+/**
+ * Find all selected items, if there are any. If the widget allows for multiselect
+ * it will return an array of selected options. If the widget doesn't allow for
+ * multiselect, it will return the selected option or null if no item is selected.
+ *
+ * @return {OO.ui.OptionWidget[]|OO.ui.OptionWidget|null} If the widget is multiselect
+ *  then return an array of selected items (or empty array),
+ *  if the widget is not multiselect, return a single selected item, or `null`
+ *  if no item is selected
+ */
+OO.ui.SelectWidget.prototype.findSelectedItems = function () {
+       var selected = this.items.filter( function ( item ) {
+               return item.isSelected();
+       } );
+
+       return this.multiselect ?
+               selected :
+               selected[ 0 ] || null;
+};
+
 /**
  * Find selected item.
  *
- * @return {OO.ui.OptionWidget|null} Selected item, `null` if no item is selected
+ * @return {OO.ui.OptionWidget[]|OO.ui.OptionWidget|null} If the widget is multiselect
+ *  then return an array of selected items (or empty array),
+ *  if the widget is not multiselect, return a single selected item, or `null`
+ *  if no item is selected
  */
 OO.ui.SelectWidget.prototype.findSelectedItem = function () {
-       var i, len;
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               if ( this.items[ i ].isSelected() ) {
-                       return this.items[ i ];
-               }
-       }
-       return null;
+       return this.findSelectedItems();
 };
 
 /**
@@ -7021,7 +6997,8 @@ OO.ui.SelectWidget.prototype.togglePressed = function ( pressed ) {
        if ( pressed !== this.pressed ) {
                this.$element
                        .toggleClass( 'oo-ui-selectWidget-pressed', pressed )
-                       .toggleClass( 'oo-ui-selectWidget-depressed', !pressed );
+                       // -depressed is a deprecated alias of -unpressed
+                       .toggleClass( 'oo-ui-selectWidget-unpressed oo-ui-selectWidget-depressed', !pressed );
                this.pressed = pressed;
        }
 };
@@ -7068,7 +7045,7 @@ OO.ui.SelectWidget.prototype.highlightItem = function ( item ) {
 OO.ui.SelectWidget.prototype.getItemFromLabel = function ( label, prefix ) {
        var i, item, found,
                len = this.items.length,
-               filter = this.getItemMatcher( label, true );
+               filter = this.getItemMatcher( label, 'exact' );
 
        for ( i = 0; i < len; i++ ) {
                item = this.items[ i ];
@@ -7079,7 +7056,7 @@ OO.ui.SelectWidget.prototype.getItemFromLabel = function ( label, prefix ) {
 
        if ( prefix ) {
                found = null;
-               filter = this.getItemMatcher( label, false );
+               filter = this.getItemMatcher( label, 'prefix' );
                for ( i = 0; i < len; i++ ) {
                        item = this.items[ i ];
                        if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {
@@ -7132,6 +7109,30 @@ OO.ui.SelectWidget.prototype.selectItemByData = function ( data ) {
        return this.selectItem( itemFromData );
 };
 
+/**
+ * Programmatically unselect an option by its reference. If the widget
+ * allows for multiple selections, there may be other items still selected;
+ * otherwise, no items will be selected.
+ * If no item is given, all selected items will be unselected.
+ *
+ * @param {OO.ui.OptionWidget} [item] Item to unselect
+ * @fires select
+ * @chainable
+ * @return {OO.ui.Widget} The widget, for chaining
+ */
+OO.ui.SelectWidget.prototype.unselectItem = function ( item ) {
+       if ( item ) {
+               item.setSelected( false );
+       } else {
+               this.items.forEach( function ( item ) {
+                       item.setSelected( false );
+               } );
+       }
+
+       this.emit( 'select', this.findSelectedItems() );
+       return this;
+};
+
 /**
  * Programmatically select an option by its reference. If the `item` parameter is omitted,
  * all options will be deselected.
@@ -7145,14 +7146,20 @@ OO.ui.SelectWidget.prototype.selectItem = function ( item ) {
        var i, len, selected,
                changed = false;
 
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               selected = this.items[ i ] === item;
-               if ( this.items[ i ].isSelected() !== selected ) {
-                       this.items[ i ].setSelected( selected );
-                       changed = true;
+       if ( this.multiselect && item ) {
+               // Select the item directly
+               item.setSelected( true );
+       } else {
+               for ( i = 0, len = this.items.length; i < len; i++ ) {
+                       selected = this.items[ i ] === item;
+                       if ( this.items[ i ].isSelected() !== selected ) {
+                               this.items[ i ].setSelected( selected );
+                               changed = true;
+                       }
                }
        }
        if ( changed ) {
+               // TODO: When should a non-highlightable element be selected?
                if ( item && !item.constructor.static.highlightable ) {
                        if ( item ) {
                                this.$focusOwner.attr( 'aria-activedescendant', item.getElementId() );
@@ -7160,7 +7167,7 @@ OO.ui.SelectWidget.prototype.selectItem = function ( item ) {
                                this.$focusOwner.removeAttr( 'aria-activedescendant' );
                        }
                }
-               this.emit( 'select', item );
+               this.emit( 'select', this.findSelectedItems() );
        }
 
        return this;
@@ -7213,20 +7220,26 @@ OO.ui.SelectWidget.prototype.pressItem = function ( item ) {
  */
 OO.ui.SelectWidget.prototype.chooseItem = function ( item ) {
        if ( item ) {
-               this.selectItem( item );
-               this.emit( 'choose', item );
+               if ( this.multiselect && item.isSelected() ) {
+                       this.unselectItem( item );
+               } else {
+                       this.selectItem( item );
+               }
+
+               this.emit( 'choose', item, item.isSelected() );
        }
 
        return this;
 };
 
 /**
- * Find an option by its position relative to the specified item (or to the start of the option array,
- * if item is `null`). The direction in which to search through the option array is specified with a
- * number: -1 for reverse (the default) or 1 for forward. The method will return an option, or
- * `null` if there are no options in the array.
+ * Find an option by its position relative to the specified item (or to the start of the option
+ * array, if item is `null`). The direction in which to search through the option array is specified
+ * with a number: -1 for reverse (the default) or 1 for forward. The method will return an option,
+ * or `null` if there are no options in the array.
  *
- * @param {OO.ui.OptionWidget|null} item Item to describe the start position, or `null` to start at the beginning of the array.
+ * @param {OO.ui.OptionWidget|null} item Item to describe the start position, or `null` to start at
+ *  the beginning of the array.
  * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward
  * @param {Function} [filter] Only consider items for which this function returns
  *  true. Function takes an OO.ui.OptionWidget and returns a boolean.
@@ -7355,7 +7368,8 @@ OO.ui.SelectWidget.prototype.setFocusOwner = function ( $focusOwner ) {
 
 /**
  * DecoratedOptionWidgets are {@link OO.ui.OptionWidget options} that can be configured
- * with an {@link OO.ui.mixin.IconElement icon} and/or {@link OO.ui.mixin.IndicatorElement indicator}.
+ * with an {@link OO.ui.mixin.IconElement icon} and/or
+ * {@link OO.ui.mixin.IndicatorElement indicator}.
  * This class is used with OO.ui.SelectWidget to create a selection of mutually exclusive
  * options. For more information about options and selects, please see the
  * [OOUI documentation on MediaWiki][1].
@@ -7451,8 +7465,9 @@ OO.inheritClass( OO.ui.MenuOptionWidget, OO.ui.DecoratedOptionWidget );
 OO.ui.MenuOptionWidget.static.scrollIntoViewOnSelect = true;
 
 /**
- * MenuSectionOptionWidgets are used inside {@link OO.ui.MenuSelectWidget menu select widgets} to group one or more related
- * {@link OO.ui.MenuOptionWidget menu options}. MenuSectionOptionWidgets cannot be highlighted or selected.
+ * MenuSectionOptionWidgets are used inside {@link OO.ui.MenuSelectWidget menu select widgets} to
+ * group one or more related {@link OO.ui.MenuOptionWidget menu options}. MenuSectionOptionWidgets
+ * cannot be highlighted or selected.
  *
  *     @example
  *     var dropdown = new OO.ui.DropdownWidget( {
@@ -7492,8 +7507,10 @@ OO.ui.MenuSectionOptionWidget = function OoUiMenuSectionOptionWidget( config ) {
        OO.ui.MenuSectionOptionWidget.parent.call( this, config );
 
        // Initialization
-       this.$element.addClass( 'oo-ui-menuSectionOptionWidget' )
+       this.$element
+               .addClass( 'oo-ui-menuSectionOptionWidget' )
                .removeAttr( 'role aria-selected' );
+       this.selected = false;
 };
 
 /* Setup */
@@ -7517,8 +7534,9 @@ OO.ui.MenuSectionOptionWidget.static.highlightable = false;
 /**
  * MenuSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains options and
  * is used together with OO.ui.MenuOptionWidget. It is designed be used as part of another widget.
- * See {@link OO.ui.DropdownWidget DropdownWidget}, {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget},
- * and {@link OO.ui.mixin.LookupElement LookupElement} for examples of widgets that contain menus.
+ * See {@link OO.ui.DropdownWidget DropdownWidget},
+ * {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget}, and
+ * {@link OO.ui.mixin.LookupElement LookupElement} for examples of widgets that contain menus.
  * MenuSelectWidgets themselves are not instantiated directly, rather subclassed
  * and customized to be opened, closed, and displayed as needed.
  *
@@ -7530,7 +7548,7 @@ OO.ui.MenuSectionOptionWidget.static.highlightable = false;
  * - Enter/Return key: choose and select a menu option
  * - Up-arrow key: highlight the previous menu option
  * - Down-arrow key: highlight the next menu option
- * - Esc key: hide the menu
+ * - Escape key: hide the menu
  *
  * Unlike most widgets, MenuSelectWidget is initially hidden and must be shown by calling #toggle.
  *
@@ -7544,22 +7562,27 @@ OO.ui.MenuSectionOptionWidget.static.highlightable = false;
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {OO.ui.TextInputWidget} [input] Text input used to implement option highlighting for menu items that match
- *  the text the user types. This config is used by {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget}
- *  and {@link OO.ui.mixin.LookupElement LookupElement}
+ * @cfg {OO.ui.TextInputWidget} [input] Text input used to implement option highlighting for menu
+ *  items that match the text the user types. This config is used by
+ *  {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget} and
+ *  {@link OO.ui.mixin.LookupElement LookupElement}
  * @cfg {jQuery} [$input] Text input used to implement option highlighting for menu items that match
- *  the text the user types. This config is used by {@link OO.ui.TagMultiselectWidget TagMultiselectWidget}
- * @cfg {OO.ui.Widget} [widget] Widget associated with the menu's active state. If the user clicks the mouse
- *  anywhere on the page outside of this widget, the menu is hidden. For example, if there is a button
- *  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.
+ *  the text the user types. This config is used by
+ *  {@link OO.ui.TagMultiselectWidget TagMultiselectWidget}
+ * @cfg {OO.ui.Widget} [widget] Widget associated with the menu's active state. If the user clicks
+ *  the mouse anywhere on the page outside of this widget, the menu is hidden. For example, if
+ *  there is a button 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 {jQuery} [$autoCloseIgnore] If these elements are clicked, don't auto-hide 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
  * @cfg {boolean} [highlightOnFilter] Highlight the first result when filtering
- * @param {number|string} [width] Width of the menu as a number of pixels or CSS string with unit suffix,
- *  used by {@link OO.ui.mixin.ClippableElement ClippableElement}
+ * @cfg {string} [filterMode='prefix'] The mode by which the menu filters the results.
+ *  Options are 'exact', 'prefix' or 'substring'. See `OO.ui.SelectWidget#getItemMatcher`
+ * @param {number|string} [width] Width of the menu as a number of pixels or CSS string with unit
+ *  suffix, used by {@link OO.ui.mixin.ClippableElement ClippableElement}
  */
 OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
        // Configuration initialization
@@ -7569,7 +7592,7 @@ OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
        OO.ui.MenuSelectWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
+       OO.ui.mixin.ClippableElement.call( this, $.extend( { $clippable: this.$group }, config ) );
        OO.ui.mixin.FloatableElement.call( this, config );
 
        // Initial vertical positions other than 'center' will result in
@@ -7587,7 +7610,9 @@ OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
        this.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );
        this.onInputEditHandler = OO.ui.debounce( this.updateItemVisibility.bind( this ), 100 );
        this.highlightOnFilter = !!config.highlightOnFilter;
+       this.lastHighlightedItem = null;
        this.width = config.width;
+       this.filterMode = config.filterMode;
 
        // Initialization
        this.$element.addClass( 'oo-ui-menuSelectWidget' );
@@ -7670,7 +7695,7 @@ OO.ui.MenuSelectWidget.prototype.onDocumentKeyDown = function ( e ) {
                                break;
                        case OO.ui.Keys.ESCAPE:
                        case OO.ui.Keys.TAB:
-                               if ( currentItem ) {
+                               if ( currentItem && !this.multiselect ) {
                                        currentItem.setHighlighted( false );
                                }
                                this.toggle( false );
@@ -7701,8 +7726,8 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
                exactMatch = false;
 
        if ( this.$input && this.filterFromInput ) {
-               filter = showAll ? null : this.getItemMatcher( this.$input.val() );
-               exactFilter = this.getItemMatcher( this.$input.val(), true );
+               filter = showAll ? null : this.getItemMatcher( this.$input.val(), this.filterMode );
+               exactFilter = this.getItemMatcher( this.$input.val(), 'exact' );
                // Hide non-matching options, and also hide section headers if all options
                // in their section are hidden.
                for ( i = 0; i < len; i++ ) {
@@ -7727,17 +7752,16 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
                        section.toggle( showAll || !sectionEmpty );
                }
 
-               if ( anyVisible && this.items.length && !exactMatch ) {
-                       this.scrollItemIntoView( this.items[ 0 ] );
-               }
-
                if ( !anyVisible ) {
                        this.highlightItem( null );
                }
 
                this.$element.toggleClass( 'oo-ui-menuSelectWidget-invisible', !anyVisible );
 
-               if ( this.highlightOnFilter ) {
+               if (
+                       this.highlightOnFilter &&
+                       !( this.lastHighlightedItem && this.lastHighlightedItem.isVisible() )
+               ) {
                        // Highlight the first item on the list
                        item = null;
                        items = this.getItems();
@@ -7748,6 +7772,7 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
                                }
                        }
                        this.highlightItem( item );
+                       this.lastHighlightedItem = item;
                }
 
        }
@@ -7784,7 +7809,10 @@ OO.ui.MenuSelectWidget.prototype.unbindDocumentKeyDownListener = function () {
 OO.ui.MenuSelectWidget.prototype.bindDocumentKeyPressListener = function () {
        if ( this.$input ) {
                if ( this.filterFromInput ) {
-                       this.$input.on( 'keydown mouseup cut paste change input select', this.onInputEditHandler );
+                       this.$input.on(
+                               'keydown mouseup cut paste change input select',
+                               this.onInputEditHandler
+                       );
                        this.updateItemVisibility();
                }
        } else {
@@ -7798,7 +7826,10 @@ OO.ui.MenuSelectWidget.prototype.bindDocumentKeyPressListener = function () {
 OO.ui.MenuSelectWidget.prototype.unbindDocumentKeyPressListener = function () {
        if ( this.$input ) {
                if ( this.filterFromInput ) {
-                       this.$input.off( 'keydown mouseup cut paste change input select', this.onInputEditHandler );
+                       this.$input.off(
+                               'keydown mouseup cut paste change input select',
+                               this.onInputEditHandler
+                       );
                        this.updateItemVisibility();
                }
        } else {
@@ -7809,10 +7840,12 @@ OO.ui.MenuSelectWidget.prototype.unbindDocumentKeyPressListener = function () {
 /**
  * Choose an item.
  *
- * When a user chooses an item, the menu is closed, unless the hideOnChoose config option is set to false.
+ * 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.
+ * 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.
  *
  * @param {OO.ui.OptionWidget} item Item to choose
  * @chainable
@@ -7875,7 +7908,7 @@ OO.ui.MenuSelectWidget.prototype.clearItems = function () {
  * @inheritdoc
  */
 OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
-       var change, originalHeight, flippedHeight;
+       var change, originalHeight, flippedHeight, selectedItem;
 
        visible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;
        change = visible !== this.isVisible();
@@ -7940,9 +7973,13 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
 
                        this.$focusOwner.attr( 'aria-expanded', 'true' );
 
-                       if ( this.findSelectedItem() ) {
-                               this.$focusOwner.attr( 'aria-activedescendant', this.findSelectedItem().getElementId() );
-                               this.findSelectedItem().scrollElementIntoView( { duration: 0 } );
+                       selectedItem = this.findSelectedItem();
+                       if ( !this.multiselect && selectedItem ) {
+                               // TODO: Verify if this is even needed; This is already done on highlight changes
+                               // in SelectWidget#highlightItem, so we should just need to highlight the item we need to
+                               // highlight here and not bother with attr or checking selections.
+                               this.$focusOwner.attr( 'aria-activedescendant', selectedItem.getElementId() );
+                               selectedItem.scrollElementIntoView( { duration: 0 } );
                        }
 
                        // Auto-hide
@@ -7965,6 +8002,13 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
        return this;
 };
 
+/**
+ * Scroll to the top of the menu
+ */
+OO.ui.MenuSelectWidget.prototype.scrollToTop = function () {
+       this.$element.scrollTop( 0 );
+};
+
 /**
  * DropdownWidgets are not menus themselves, rather they contain a menu of options created with
  * OO.ui.MenuOptionWidget. The DropdownWidget takes care of opening and displaying the menu so that
@@ -8015,10 +8059,12 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.MenuSelectWidget menu select widget}
- * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
- *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
- *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.
+ * @cfg {Object} [menu] Configuration options to pass to
+ *  {@link OO.ui.MenuSelectWidget menu select widget}.
+ * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful
+ *  in cases where the expanded menu is larger than its containing `<div>`. The specified overlay
+ *  layer is usually on top of the containing `<div>` and has a larger area. By default, the menu
+ *  uses relative positioning.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
  */
 OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {
@@ -8030,14 +8076,19 @@ OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {
 
        // Properties (must be set before TabIndexedElement constructor call)
        this.$handle = $( '<button>' );
-       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
+       this.$overlay = ( config.$overlay === true ?
+               OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
 
        // Mixin constructors
        OO.ui.mixin.IconElement.call( this, config );
        OO.ui.mixin.IndicatorElement.call( this, config );
        OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {
+               $titled: this.$label
+       }, config ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {
+               $tabIndexed: this.$handle
+       }, config ) );
 
        // Properties
        this.menu = new OO.ui.MenuSelectWidget( $.extend( {
@@ -8049,7 +8100,7 @@ OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {
        this.$handle.on( {
                click: this.onClick.bind( this ),
                keydown: this.onKeyDown.bind( this ),
-               // Hack? Handle type-to-search when menu is not expanded and not handling its own events
+               // Hack? Handle type-to-search when menu is not expanded and not handling its own events.
                keypress: this.menu.onDocumentKeyPressHandler,
                blur: this.menu.clearKeyPressBuffer.bind( this.menu )
        } );
@@ -8396,8 +8447,8 @@ OO.ui.MultioptionWidget.prototype.isSelected = function () {
 
 /**
  * Set the option’s selected state. In general, all modifications to the selection
- * should be handled by the SelectWidget’s {@link OO.ui.SelectWidget#selectItem selectItem( [item] )}
- * method instead of this method.
+ * should be handled by the SelectWidget’s
+ * {@link OO.ui.SelectWidget#selectItem selectItem( [item] )} method instead of this method.
  *
  * @param {boolean} [state=false] Select option
  * @chainable
@@ -8416,7 +8467,8 @@ OO.ui.MultioptionWidget.prototype.setSelected = function ( state ) {
 /**
  * MultiselectWidget allows selecting multiple options from a list.
  *
- * For more information about menus and options, please see the [OOUI documentation on MediaWiki][1].
+ * For more information about menus and options, please see the [OOUI documentation
+ * on MediaWiki][1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options
  *
@@ -8442,10 +8494,14 @@ OO.ui.MultiselectWidget = function OoUiMultiselectWidget( config ) {
        OO.ui.mixin.TitledElement.call( this, config );
 
        // Events
-       this.aggregate( { change: 'select' } );
+       this.aggregate( {
+               change: 'select'
+       } );
        // This is mostly for compatibility with TagMultiselectWidget... normally, 'change' is emitted
        // by GroupElement only when items are added/removed
-       this.connect( this, { select: [ 'emit', 'change' ] } );
+       this.connect( this, {
+               select: [ 'emit', 'change' ]
+       } );
 
        // Initialization
        if ( config.items ) {
@@ -8680,8 +8736,7 @@ OO.ui.CheckboxMultiselectWidget = function OoUiCheckboxMultiselectWidget( config
        this.$group.on( 'click', this.onClick.bind( this ) );
 
        // Initialization
-       this.$element
-               .addClass( 'oo-ui-checkboxMultiselectWidget' );
+       this.$element.addClass( 'oo-ui-checkboxMultiselectWidget' );
 };
 
 /* Setup */
@@ -8691,14 +8746,16 @@ OO.inheritClass( OO.ui.CheckboxMultiselectWidget, OO.ui.MultiselectWidget );
 /* Methods */
 
 /**
- * Get an option by its position relative to the specified item (or to the start of the option array,
- * if item is `null`). The direction in which to search through the option array is specified with a
- * number: -1 for reverse (the default) or 1 for forward. The method will return an option, or
- * `null` if there are no options in the array.
+ * Get an option by its position relative to the specified item (or to the start of the
+ * option array, if item is `null`). The direction in which to search through the option array
+ * is specified with a number: -1 for reverse (the default) or 1 for forward. The method will
+ * return an option, or `null` if there are no options in the array.
  *
- * @param {OO.ui.CheckboxMultioptionWidget|null} item Item to describe the start position, or `null` to start at the beginning of the array.
+ * @param {OO.ui.CheckboxMultioptionWidget|null} item Item to describe the start position, or
+ *  `null` to start at the beginning of the array.
  * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward
- * @return {OO.ui.CheckboxMultioptionWidget|null} Item at position, `null` if there are no items in the select
+ * @return {OO.ui.CheckboxMultioptionWidget|null} Item at position, `null` if there are no items
+ *  in the select.
  */
 OO.ui.CheckboxMultiselectWidget.prototype.getRelativeFocusableItem = function ( item, direction ) {
        var currentIndex, nextIndex, i,
@@ -8740,14 +8797,15 @@ OO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) {
                $options = this.$group.find( '.oo-ui-checkboxMultioptionWidget' );
                lastClickedIndex = $options.index( $lastClicked );
                nowClickedIndex = $options.index( $nowClicked );
-               // If it's the same item, either the user is being silly, or it's a fake event generated by the
-               // browser. In either case we don't need custom handling.
+               // If it's the same item, either the user is being silly, or it's a fake event generated
+               // by the browser. In either case we don't need custom handling.
                if ( nowClickedIndex !== lastClickedIndex ) {
                        items = this.items;
                        wasSelected = items[ nowClickedIndex ].isSelected();
                        direction = nowClickedIndex > lastClickedIndex ? 1 : -1;
 
-                       // This depends on the DOM order of the items and the order of the .items array being the same.
+                       // This depends on the DOM order of the items and the order of the .items array being
+                       // the same.
                        for ( i = lastClickedIndex; i !== nowClickedIndex; i += direction ) {
                                if ( !items[ i ].isDisabled() ) {
                                        items[ i ].setSelected( !wasSelected );
@@ -8755,8 +8813,8 @@ OO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) {
                        }
                        // For the now-clicked element, use immediate timeout to allow the browser to do its own
                        // handling first, then set our value. The order in which events happen is different for
-                       // clicks on the <input> and on the <label> and there are additional fake clicks fired for
-                       // non-click actions that change the checkboxes.
+                       // clicks on the <input> and on the <label> and there are additional fake clicks fired
+                       // for non-click actions that change the checkboxes.
                        e.preventDefault();
                        setTimeout( function () {
                                if ( !items[ nowClickedIndex ].isDisabled() ) {
@@ -8805,7 +8863,8 @@ OO.ui.CheckboxMultiselectWidget.prototype.simulateLabelClick = function () {
  *   is taking place. Because the extent of an indeterminate operation is unknown, the bar does
  *   not use percentages.
  *
- * The value of the `progress` configuration determines whether the bar is determinate or indeterminate.
+ * The value of the `progress` configuration determines whether the bar is determinate
+ * or indeterminate.
  *
  *     @example
  *     // Examples of determinate and indeterminate progress bars.
@@ -8834,7 +8893,8 @@ OO.ui.CheckboxMultiselectWidget.prototype.simulateLabelClick = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {number|boolean} [progress=false] The type of progress bar (determinate or indeterminate).
- *  To create a determinate progress bar, specify a number that reflects the initial percent complete.
+ *  To create a determinate progress bar, specify a number that reflects the initial
+ *  percent complete.
  *  By default, the progress bar is indeterminate.
  */
 OO.ui.ProgressBarWidget = function OoUiProgressBarWidget( config ) {
@@ -8876,7 +8936,8 @@ OO.ui.ProgressBarWidget.static.tagName = 'div';
 /* Methods */
 
 /**
- * Get the percent of the progress that has been completed. Indeterminate progresses will return `false`.
+ * Get the percent of the progress that has been completed. Indeterminate progresses will
+ * return `false`.
  *
  * @return {number|boolean} Progress percent
  */
@@ -8904,8 +8965,9 @@ OO.ui.ProgressBarWidget.prototype.setProgress = function ( progress ) {
 
 /**
  * InputWidget is the base class for all input widgets, which
- * include {@link OO.ui.TextInputWidget text inputs}, {@link OO.ui.CheckboxInputWidget checkbox inputs},
- * {@link OO.ui.RadioInputWidget radio inputs}, and {@link OO.ui.ButtonInputWidget button inputs}.
+ * include {@link OO.ui.TextInputWidget text inputs}, {@link OO.ui.CheckboxInputWidget checkbox
+ * inputs}, {@link OO.ui.RadioInputWidget radio inputs}, and
+ * {@link OO.ui.ButtonInputWidget button inputs}.
  * See the [OOUI documentation on MediaWiki] [1] for more information and examples.
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs
@@ -8913,7 +8975,6 @@ OO.ui.ProgressBarWidget.prototype.setProgress = function ( progress ) {
  * @abstract
  * @class
  * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.FlaggedElement
  * @mixins OO.ui.mixin.TabIndexedElement
  * @mixins OO.ui.mixin.TitledElement
  * @mixins OO.ui.mixin.AccessKeyedElement
@@ -8924,8 +8985,8 @@ OO.ui.ProgressBarWidget.prototype.setProgress = function ( progress ) {
  * @cfg {string} [value=''] The value of the input.
  * @cfg {string} [dir] The directionality of the input (ltr/rtl).
  * @cfg {string} [inputId] The value of the input’s HTML `id` attribute.
- * @cfg {Function} [inputFilter] The name of an input filter function. Input filters modify the value of an input
- *  before it is accepted.
+ * @cfg {Function} [inputFilter] The name of an input filter function. Input filters modify the
+ *  value of an input before it is accepted.
  */
 OO.ui.InputWidget = function OoUiInputWidget( config ) {
        // Configuration initialization
@@ -8941,10 +9002,15 @@ OO.ui.InputWidget = function OoUiInputWidget( config ) {
        this.inputFilter = config.inputFilter;
 
        // Mixin constructors
-       OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );
-       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$input } ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {
+               $tabIndexed: this.$input
+       }, config ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {
+               $titled: this.$input
+       }, config ) );
+       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {
+               $accessKeyed: this.$input
+       }, config ) );
 
        // Events
        this.$input.on( 'keydown mouseup cut paste change input select', this.onEdit.bind( this ) );
@@ -8969,7 +9035,6 @@ OO.ui.InputWidget = function OoUiInputWidget( config ) {
 /* Setup */
 
 OO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.FlaggedElement );
 OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TabIndexedElement );
 OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TitledElement );
 OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.AccessKeyedElement );
@@ -8993,7 +9058,8 @@ OO.ui.InputWidget.static.gatherPreInfuseState = function ( node, config ) {
        var state = OO.ui.InputWidget.parent.static.gatherPreInfuseState( node, config );
        if ( config.$input && config.$input.length ) {
                state.value = config.$input.val();
-               // Might be better in TabIndexedElement, but it's awkward to do there because mixins are awkward
+               // Might be better in TabIndexedElement, but it's awkward to do there because
+               // mixins are awkward
                state.focus = config.$input.is( ':focus' );
        }
        return state;
@@ -9215,14 +9281,17 @@ OO.ui.HiddenInputWidget.static.tagName = 'input';
  * @mixins OO.ui.mixin.IconElement
  * @mixins OO.ui.mixin.IndicatorElement
  * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.FlaggedElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {string} [type='button'] The value of the HTML `'type'` attribute: 'button', 'submit' or 'reset'.
+ * @cfg {string} [type='button'] The value of the HTML `'type'` attribute:
+ *  'button', 'submit' or 'reset'.
  * @cfg {boolean} [useInputTag=false] Use an `<input>` tag instead of a `<button>` tag, the default.
- *  Widgets configured to be an `<input>` do not support {@link #icon icons} and {@link #indicator indicators},
- *  non-plaintext {@link #label labels}, or {@link #value values}. In general, useInputTag should only
- *  be set to `true` when there’s need to support IE 6 in a form with multiple buttons.
+ *  Widgets configured to be an `<input>` do not support {@link #icon icons} and
+ *  {@link #indicator indicators},
+ *  non-plaintext {@link #label labels}, or {@link #value values}. In general, useInputTag should
+ *  only be set to `true` when there’s need to support IE 6 in a form with multiple buttons.
  */
 OO.ui.ButtonInputWidget = function OoUiButtonInputWidget( config ) {
        // Configuration initialization
@@ -9240,10 +9309,13 @@ OO.ui.ButtonInputWidget = function OoUiButtonInputWidget( config ) {
        OO.ui.ButtonInputWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.ButtonElement.call( this, $.extend( {}, config, { $button: this.$input } ) );
+       OO.ui.mixin.ButtonElement.call( this, $.extend( {
+               $button: this.$input
+       }, config ) );
        OO.ui.mixin.IconElement.call( this, config );
        OO.ui.mixin.IndicatorElement.call( this, config );
        OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.FlaggedElement.call( this, config );
 
        // Initialization
        if ( !config.useInputTag ) {
@@ -9259,6 +9331,7 @@ OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.ButtonElement );
 OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IconElement );
 OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IndicatorElement );
 OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.FlaggedElement );
 
 /* Static Properties */
 
@@ -9328,8 +9401,9 @@ OO.ui.ButtonInputWidget.prototype.setValue = function ( value ) {
  * @inheritdoc
  */
 OO.ui.ButtonInputWidget.prototype.getInputId = function () {
-       // Disable generating `<label>` elements for buttons. One would very rarely need additional label
-       // for a button, and it's already a big clickable target, and it causes unexpected rendering.
+       // Disable generating `<label>` elements for buttons. One would very rarely need additional
+       // label for a button, and it's already a big clickable target, and it causes
+       // unexpected rendering.
        return null;
 };
 
@@ -9372,7 +9446,9 @@ OO.ui.ButtonInputWidget.prototype.getInputId = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {boolean} [selected=false] Select the checkbox initially. By default, the checkbox is not selected.
+ * @cfg {boolean} [selected=false] Select the checkbox initially. By default, the checkbox is
+ *  not selected.
+ * @cfg {boolean} [indeterminate=false] Whether the checkbox is in the indeterminate state.
  */
 OO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {
        // Configuration initialization
@@ -9393,12 +9469,24 @@ OO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {
                // Required for pretty styling in WikimediaUI theme
                .append( this.checkIcon.$element );
        this.setSelected( config.selected !== undefined ? config.selected : false );
+       this.setIndeterminate( config.indeterminate !== undefined ? config.indeterminate : false );
 };
 
 /* Setup */
 
 OO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );
 
+/* Events */
+
+/**
+ * @event change
+ *
+ * A change event is emitted when the state of the input changes.
+ *
+ * @param {boolean} selected
+ * @param {boolean} indeterminate
+ */
+
 /* Static Properties */
 
 /**
@@ -9437,6 +9525,7 @@ OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
                // Allow the stack to clear so the value will be updated
                setTimeout( function () {
                        widget.setSelected( widget.$input.prop( 'checked' ) );
+                       widget.setIndeterminate( widget.$input.prop( 'indeterminate' ) );
                } );
        }
 };
@@ -9444,16 +9533,20 @@ OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
 /**
  * Set selection state of this checkbox.
  *
- * @param {boolean} state `true` for selected
+ * @param {boolean} state Selected state
+ * @param {boolean} internal Used for internal calls to suppress events
  * @chainable
- * @return {OO.ui.Widget} The widget, for chaining
+ * @return {OO.ui.CheckboxInputWidget} The widget, for chaining
  */
-OO.ui.CheckboxInputWidget.prototype.setSelected = function ( state ) {
+OO.ui.CheckboxInputWidget.prototype.setSelected = function ( state, internal ) {
        state = !!state;
        if ( this.selected !== state ) {
                this.selected = state;
                this.$input.prop( 'checked', this.selected );
-               this.emit( 'change', this.selected );
+               if ( !internal ) {
+                       this.setIndeterminate( false, true );
+                       this.emit( 'change', this.selected, this.indeterminate );
+               }
        }
        // The first time that the selection state is set (probably while constructing the widget),
        // remember it in defaultSelected. This property can be later used to check whether
@@ -9480,6 +9573,42 @@ OO.ui.CheckboxInputWidget.prototype.isSelected = function () {
        return this.selected;
 };
 
+/**
+ * Set indeterminate state of this checkbox.
+ *
+ * @param {boolean} state Indeterminate state
+ * @param {boolean} internal Used for internal calls to suppress events
+ * @chainable
+ * @return {OO.ui.CheckboxInputWidget} The widget, for chaining
+ */
+OO.ui.CheckboxInputWidget.prototype.setIndeterminate = function ( state, internal ) {
+       state = !!state;
+       if ( this.indeterminate !== state ) {
+               this.indeterminate = state;
+               this.$input.prop( 'indeterminate', this.indeterminate );
+               if ( !internal ) {
+                       this.setSelected( false, true );
+                       this.emit( 'change', this.selected, this.indeterminate );
+               }
+       }
+       return this;
+};
+
+/**
+ * Check if this checkbox is selected.
+ *
+ * @return {boolean} Checkbox is selected
+ */
+OO.ui.CheckboxInputWidget.prototype.isIndeterminate = function () {
+       // Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
+       // it, and we won't know unless they're kind enough to trigger a 'change' event.
+       var indeterminate = this.$input.prop( 'indeterminate' );
+       if ( this.indeterminate !== indeterminate ) {
+               this.setIndeterminate( indeterminate );
+       }
+       return this.indeterminate;
+};
+
 /**
  * @inheritdoc
  */
@@ -9502,8 +9631,8 @@ OO.ui.CheckboxInputWidget.prototype.restorePreInfuseState = function ( state ) {
 
 /**
  * DropdownInputWidget is a {@link OO.ui.DropdownWidget DropdownWidget} intended to be used
- * within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value
- * of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for
+ * within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the
+ * value of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for
  * more information about input widgets.
  *
  * A DropdownInputWidget always has a value (one of the options is always selected), unless there
@@ -9533,9 +9662,10 @@ OO.ui.CheckboxInputWidget.prototype.restorePreInfuseState = function ( state ) {
  * @param {Object} [config] Configuration options
  * @cfg {Object[]} [options=[]] Array of menu options in the format described above.
  * @cfg {Object} [dropdown] Configuration options for {@link OO.ui.DropdownWidget DropdownWidget}
- * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
- *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
- *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.
+ * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful
+ *  in cases where the expanded menu is larger than its containing `<div>`. The specified overlay
+ *  layer is usually on top of the containing `<div>` and has a larger area. By default, the menu
+ *  uses relative positioning.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
  */
 OO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) {
@@ -9557,7 +9687,9 @@ OO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) {
        OO.ui.DropdownInputWidget.parent.call( this, config );
 
        // Events
-       this.dropdownWidget.getMenu().connect( this, { select: 'onMenuSelect' } );
+       this.dropdownWidget.getMenu().connect( this, {
+               select: 'onMenuSelect'
+       } );
 
        // Initialization
        this.$element
@@ -9675,8 +9807,11 @@ OO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) {
                }
 
                // Disable the menu option if it is itself disabled or if its parent optgroup is disabled.
-               if ( opt.disabled !== undefined ||
-                       previousOptgroup instanceof OO.ui.MenuSectionOptionWidget && previousOptgroup.isDisabled() ) {
+               if (
+                       opt.disabled !== undefined ||
+                       previousOptgroup instanceof OO.ui.MenuSectionOptionWidget &&
+                       previousOptgroup.isDisabled()
+               ) {
                        optionWidget.setDisabled( true );
                }
 
@@ -9813,7 +9948,8 @@ OO.ui.DropdownInputWidget.prototype.blur = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {boolean} [selected=false] Select the radio button initially. By default, the radio button is not selected.
+ * @cfg {boolean} [selected=false] Select the radio button initially. By default, the radio button
+ *  is not selected.
  */
 OO.ui.RadioInputWidget = function OoUiRadioInputWidget( config ) {
        // Configuration initialization
@@ -9920,9 +10056,9 @@ OO.ui.RadioInputWidget.prototype.restorePreInfuseState = function ( state ) {
 };
 
 /**
- * RadioSelectInputWidget is a {@link OO.ui.RadioSelectWidget RadioSelectWidget} intended to be used
- * within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value
- * of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for
+ * RadioSelectInputWidget is a {@link OO.ui.RadioSelectWidget RadioSelectWidget} intended to be
+ * used within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with
+ * the value of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for
  * more information about input widgets.
  *
  * This and OO.ui.DropdownInputWidget support similar configuration options.
@@ -9961,7 +10097,9 @@ OO.ui.RadioSelectInputWidget = function OoUiRadioSelectInputWidget( config ) {
        OO.ui.RadioSelectInputWidget.parent.call( this, config );
 
        // Events
-       this.radioSelectWidget.connect( this, { select: 'onMenuSelect' } );
+       this.radioSelectWidget.connect( this, {
+               select: 'onMenuSelect'
+       } );
 
        // Initialization
        this.$element
@@ -10124,7 +10262,8 @@ OO.ui.RadioSelectInputWidget.prototype.blur = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: …, disabled: … }`
+ * @cfg {Object[]} [options=[]] Array of menu options in the format
+ *  `{ data: …, label: …, disabled: … }`
  */
 OO.ui.CheckboxMultiselectInputWidget = function OoUiCheckboxMultiselectInputWidget( config ) {
        // Configuration initialization
@@ -10142,7 +10281,9 @@ OO.ui.CheckboxMultiselectInputWidget = function OoUiCheckboxMultiselectInputWidg
        OO.ui.CheckboxMultiselectInputWidget.parent.call( this, config );
 
        // Events
-       this.checkboxMultiselectWidget.connect( this, { select: 'onCheckboxesSelect' } );
+       this.checkboxMultiselectWidget.connect( this, {
+               select: 'onCheckboxesSelect'
+       } );
 
        // Initialization
        this.$element
@@ -10162,7 +10303,9 @@ OO.inheritClass( OO.ui.CheckboxMultiselectInputWidget, OO.ui.InputWidget );
  * @inheritdoc
  */
 OO.ui.CheckboxMultiselectInputWidget.static.gatherPreInfuseState = function ( node, config ) {
-       var state = OO.ui.CheckboxMultiselectInputWidget.parent.static.gatherPreInfuseState( node, config );
+       var state = OO.ui.CheckboxMultiselectInputWidget.parent.static.gatherPreInfuseState(
+               node, config
+       );
        state.value = $( node ).find( '.oo-ui-checkboxInputWidget .oo-ui-inputWidget-input:checked' )
                .toArray().map( function ( el ) { return el.value; } );
        return state;
@@ -10238,8 +10381,8 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.cleanUpValue = function ( value )
                return cleanValue;
        }
        for ( i = 0; i < value.length; i++ ) {
-               singleValue =
-                       OO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue.call( this, value[ i ] );
+               singleValue = OO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue
+                       .call( this, value[ i ] );
                // Remove options that we don't have here
                if ( !this.checkboxMultiselectWidget.findItemFromData( singleValue ) ) {
                        continue;
@@ -10261,7 +10404,8 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.setDisabled = function ( state )
 /**
  * Set the options available for this input.
  *
- * @param {Object[]} options Array of menu options in the format `{ data: …, label: …, disabled: … }`
+ * @param {Object[]} options Array of menu options in the format
+ *  `{ data: …, label: …, disabled: … }`
  * @chainable
  * @return {OO.ui.Widget} The widget, for chaining
  */
@@ -10283,7 +10427,8 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.setOptions = function ( options )
  * This method may be called before the parent constructor, so various properties may not be
  * intialized yet.
  *
- * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`
+ * @param {Object[]} options Array of menu options in the format
+ *  `{ data: …, label: … }`
  * @private
  */
 OO.ui.CheckboxMultiselectInputWidget.prototype.setOptionsData = function ( options ) {
@@ -10295,8 +10440,8 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.setOptionsData = function ( optio
                .clearItems()
                .addItems( options.map( function ( opt ) {
                        var optValue, item, optDisabled;
-                       optValue =
-                               OO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue.call( widget, opt.data );
+                       optValue = OO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue
+                               .call( widget, opt.data );
                        optDisabled = opt.disabled !== undefined ? opt.disabled : false;
                        item = new OO.ui.CheckboxMultioptionWidget( {
                                data: optValue,
@@ -10342,9 +10487,9 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.focus = function () {
 /**
  * TextInputWidgets, like HTML text inputs, can be configured with options that customize the
  * size of the field as well as its presentation. In addition, these widgets can be configured
- * with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators}, an optional
- * validation-pattern (used to determine if an input value is valid or not) and an input filter,
- * which modifies incoming values rather than validating them.
+ * with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators}, an
+ * optional validation-pattern (used to determine if an input value is valid or not) and an input
+ * filter, which modifies incoming values rather than validating them.
  * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.
  *
  * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.
@@ -10353,7 +10498,7 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.focus = function () {
  *     // A TextInputWidget.
  *     var textInput = new OO.ui.TextInputWidget( {
  *         value: 'Text input'
- *     } )
+ *     } );
  *     $( document.body ).append( textInput.$element );
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs
@@ -10364,6 +10509,7 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.focus = function () {
  * @mixins OO.ui.mixin.IndicatorElement
  * @mixins OO.ui.mixin.PendingElement
  * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.FlaggedElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -10380,11 +10526,12 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.focus = function () {
  *  many emojis) count as 2 characters each.
  * @cfg {string} [labelPosition='after'] The position of the inline label relative to that of
  *  the value or placeholder text: `'before'` or `'after'`
- * @cfg {boolean} [required=false] Mark the field as required with `true`. Implies `indicator: 'required'`.
- *  Note that `false` & setting `indicator: 'required' will result in no indicator shown.
+ * @cfg {boolean} [required=false] Mark the field as required with `true`. Implies `indicator:
+ *  'required'`. Note that `false` & setting `indicator: 'required' will result in no indicator
+ *  shown.
  * @cfg {boolean} [autocomplete=true] Should the browser support autocomplete for this field
- * @cfg {boolean} [spellcheck] Should the browser support spellcheck for this field (`undefined` means
- *  leaving it up to the browser).
+ * @cfg {boolean} [spellcheck] Should the browser support spellcheck for this field (`undefined`
+ *  means leaving it up to the browser).
  * @cfg {RegExp|Function|string} [validate] Validation pattern: when string, a symbolic name of a
  *  pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer'
  *  (the value must contain only numbers); when RegExp, a regular expression that must match the
@@ -10404,8 +10551,9 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        // Mixin constructors
        OO.ui.mixin.IconElement.call( this, config );
        OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$input } ) );
+       OO.ui.mixin.PendingElement.call( this, $.extend( { $pending: this.$input }, config ) );
        OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.FlaggedElement.call( this, config );
 
        // Properties
        this.type = this.getSaneType( config );
@@ -10446,14 +10594,15 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        if ( config.autocomplete === false ) {
                this.$input.attr( 'autocomplete', 'off' );
                // Turning off autocompletion also disables "form caching" when the user navigates to a
-               // different page and then clicks "Back". Re-enable it when leaving. Borrowed from jQuery UI.
+               // different page and then clicks "Back". Re-enable it when leaving.
+               // Borrowed from jQuery UI.
                $( window ).on( {
                        beforeunload: function () {
                                this.$input.removeAttr( 'autocomplete' );
                        }.bind( this ),
                        pageshow: function () {
-                               // Browsers don't seem to actually fire this event on "Back", they instead just reload the
-                               // whole page... it shouldn't hurt, though.
+                               // Browsers don't seem to actually fire this event on "Back", they instead just
+                               // reload the whole page... it shouldn't hurt, though.
                                this.$input.attr( 'autocomplete', 'off' );
                        }.bind( this )
                } );
@@ -10474,6 +10623,7 @@ OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IconElement );
 OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IndicatorElement );
 OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.PendingElement );
 OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.FlaggedElement );
 
 /* Static Properties */
 
@@ -10485,7 +10635,7 @@ OO.ui.TextInputWidget.static.validationPatterns = {
 /* Events */
 
 /**
- * An `enter` event is emitted when the user presses 'enter' inside the text box.
+ * An `enter` event is emitted when the user presses Enter key inside the text box.
  *
  * @event enter
  */
@@ -10525,7 +10675,7 @@ OO.ui.TextInputWidget.prototype.onIndicatorMouseDown = function ( e ) {
  *
  * @private
  * @param {jQuery.Event} e Key press event
- * @fires enter If enter key is pressed
+ * @fires enter If Enter key is pressed
  */
 OO.ui.TextInputWidget.prototype.onKeyPress = function ( e ) {
        if ( e.which === OO.ui.Keys.ENTER ) {
@@ -10650,17 +10800,19 @@ OO.ui.TextInputWidget.prototype.setRequired = function ( state ) {
  */
 OO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {
        var mutationObserver, onRemove, topmostNode, fakeParentNode,
-               MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
+               MutationObserver = window.MutationObserver ||
+                       window.WebKitMutationObserver ||
+                       window.MozMutationObserver,
                widget = this;
 
        if ( MutationObserver ) {
                // The new way. If only it wasn't so ugly.
 
                if ( this.isElementAttached() ) {
-                       // Widget is attached already, do nothing. This breaks the functionality of this function when
-                       // the widget is detached and reattached. Alas, doing this correctly with MutationObserver
-                       // would require observation of the whole document, which would hurt performance of other,
-                       // more important code.
+                       // Widget is attached already, do nothing. This breaks the functionality of this
+                       // function when the widget is detached and reattached. Alas, doing this correctly with
+                       // MutationObserver would require observation of the whole document, which would hurt
+                       // performance of other, more important code.
                        return;
                }
 
@@ -10670,12 +10822,11 @@ OO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {
                        topmostNode = topmostNode.parentNode;
                }
 
-               // We have no way to detect the $element being attached somewhere without observing the entire
-               // DOM with subtree modifications, which would hurt performance. So we cheat: we hook to the
-               // parent node of $element, and instead detect when $element is removed from it (and thus
-               // probably attached somewhere else). If there is no parent, we create a "fake" one. If it
-               // doesn't get attached, we end up back here and create the parent.
-
+               // We have no way to detect the $element being attached somewhere without observing the
+               // entire DOM with subtree modifications, which would hurt performance. So we cheat: we hook
+               // to the parent node of $element, and instead detect when $element is removed from it (and
+               // thus probably attached somewhere else). If there is no parent, we create a "fake" one. If
+               // it doesn't get attached, we end up back here and create the parent.
                mutationObserver = new MutationObserver( function ( mutations ) {
                        var i, j, removedNodes;
                        for ( i = 0; i < mutations.length; i++ ) {
@@ -11067,6 +11218,7 @@ OO.ui.SearchInputWidget = function OoUiSearchInputWidget( config ) {
        this.connect( this, {
                change: 'onChange'
        } );
+       this.$indicator.on( 'click', this.onIndicatorClick.bind( this ) );
 
        // Initialization
        this.updateSearchIndicator();
@@ -11090,9 +11242,12 @@ OO.ui.SearchInputWidget.prototype.getSaneType = function () {
 };
 
 /**
- * @inheritdoc
+ * Handle click events on the indicator
+ *
+ * @param {jQuery.Event} e Click event
+ * @return {boolean}
  */
-OO.ui.SearchInputWidget.prototype.onIndicatorMouseDown = function ( e ) {
+OO.ui.SearchInputWidget.prototype.onIndicatorClick = function ( e ) {
        if ( e.which === OO.ui.MouseButtons.LEFT ) {
                // Clear the text field
                this.setValue( '' );
@@ -11155,8 +11310,8 @@ OO.ui.SearchInputWidget.prototype.setReadOnly = function ( state ) {
  *     // A MultilineTextInputWidget.
  *     var multilineTextInput = new OO.ui.MultilineTextInputWidget( {
  *         value: 'Text input on multiple lines'
- *     } )
- *     $( 'body' ).append( multilineTextInput.$element );
+ *     } );
+ *     $( document.body ).append( multilineTextInput.$element );
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs#MultilineTextInputWidget
  *
@@ -11262,7 +11417,7 @@ OO.ui.MultilineTextInputWidget.prototype.updatePosition = function () {
 OO.ui.MultilineTextInputWidget.prototype.onKeyPress = function ( e ) {
        if (
                ( e.which === OO.ui.Keys.ENTER && ( e.ctrlKey || e.metaKey ) ) ||
-               // Some platforms emit keycode 10 for ctrl+enter in a textarea
+               // Some platforms emit keycode 10 for Control+Enter keypress in a textarea
                e.which === 10
        ) {
                this.emit( 'enter', e );
@@ -11388,7 +11543,8 @@ OO.ui.MultilineTextInputWidget.prototype.restorePreInfuseState = function ( stat
  *
  * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.
  *
- * For more information about menus and options, please see the [OOUI documentation on MediaWiki][1].
+ * For more information about menus and options, please see the
+ * [OOUI documentation on MediaWiki][1].
  *
  *     @example
  *     // A ComboBoxInputWidget.
@@ -11431,10 +11587,12 @@ OO.ui.MultilineTextInputWidget.prototype.restorePreInfuseState = function ( stat
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
- * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.MenuSelectWidget menu select widget}.
- * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
- *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
- *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.
+ * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.MenuSelectWidget menu
+ *  select widget}.
+ * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful
+ *  in cases where the expanded menu is larger than its containing `<div>`. The specified overlay
+ *  layer is usually on top of the containing `<div>` and has a larger area. By default, the menu
+ *  uses relative positioning.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
  */
 OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
@@ -11455,7 +11613,8 @@ OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
        OO.ui.ComboBoxInputWidget.parent.call( this, config );
 
        // Properties
-       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
+       this.$overlay = ( config.$overlay === true ?
+               OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
        this.dropdownButton = new OO.ui.ButtonWidget( {
                classes: [ 'oo-ui-comboBoxInputWidget-dropdownButton' ],
                label: OO.ui.msg( 'ooui-combobox-button-label' ),
@@ -11671,7 +11830,8 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
  * FieldLayouts are used with OO.ui.FieldsetLayout. Each FieldLayout requires a field-widget,
  * which is a widget that is specified by reference before any optional configuration settings.
  *
- * Field layouts can be configured with help text and/or labels. Labels are aligned in one of four ways:
+ * Field layouts can be configured with help text and/or labels. Labels are aligned in one of
+ * four ways:
  *
  * - **left**: The label is placed before the field-widget and aligned with the left margin.
  *   A left-alignment is used for forms with many fields.
@@ -11685,11 +11845,12 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
  *
  * Help text can either be:
  *
- * - accessed via a help icon that appears in the upper right corner of the rendered field layout, or
+ * - accessed via a help icon that appears in the upper right corner of the rendered field layout,
+ *   or
  * - shown as a subtle explanation below the label.
  *
- * If the help text is brief, or is essential to always expose it, set `helpInline` to `true`. If it
- * is long or not essential, leave `helpInline` to its default, `false`.
+ * If the help text is brief, or is essential to always expose it, set `helpInline` to `true`.
+ * If it is long or not essential, leave `helpInline` to its default, `false`.
  *
  * Please see the [OOUI documentation on MediaWiki] [1] for examples and more information.
  *
@@ -11707,6 +11868,10 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
  *  or 'inline'
  * @cfg {Array} [errors] Error messages about the widget, which will be
  *  displayed below the widget.
+ * @cfg {Array} [warnings] Warning messages about the widget, which will be
+ *  displayed below the widget.
+ * @cfg {Array} [successMessages] Success messages on user interactions with the widget,
+ *  which will be displayed below the widget.
  *  The array may contain strings or OO.ui.HtmlSnippet instances.
  * @cfg {Array} [notices] Notices about the widget, which will be displayed
  *  below the widget.
@@ -11745,14 +11910,16 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
        OO.ui.FieldLayout.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {
+       OO.ui.mixin.LabelElement.call( this, $.extend( {
                $label: $( '<label>' )
-       } ) );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );
+       }, config ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( { $titled: this.$label }, config ) );
 
        // Properties
        this.fieldWidget = fieldWidget;
        this.errors = [];
+       this.warnings = [];
+       this.successMessages = [];
        this.notices = [];
        this.$field = this.isFieldInline() ? $( '<span>' ) : $( '<div>' );
        this.$messages = $( '<ul>' );
@@ -11762,7 +11929,9 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
        this.helpInline = config.helpInline;
 
        // Events
-       this.fieldWidget.connect( this, { disable: 'onFieldDisable' } );
+       this.fieldWidget.connect( this, {
+               disable: 'onFieldDisable'
+       } );
 
        // Initialization
        this.$help = config.help ?
@@ -11795,6 +11964,8 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
                .append( this.fieldWidget.$element );
 
        this.setErrors( config.errors || [] );
+       this.setWarnings( config.warnings || [] );
+       this.setSuccess( config.successMessages || [] );
        this.setNotices( config.notices || [] );
        this.setAlignment( config.align );
        // Call this again to take into account the widget's accessKey
@@ -11849,8 +12020,13 @@ OO.ui.FieldLayout.prototype.makeMessage = function ( kind, text ) {
        var $listItem, $icon, message;
        $listItem = $( '<li>' );
        if ( kind === 'error' ) {
+               $icon = new OO.ui.IconWidget( { icon: 'alert', flags: [ 'error' ] } ).$element;
+               $listItem.attr( 'role', 'alert' );
+       } else if ( kind === 'warning' ) {
                $icon = new OO.ui.IconWidget( { icon: 'alert', flags: [ 'warning' ] } ).$element;
                $listItem.attr( 'role', 'alert' );
+       } else if ( kind === 'success' ) {
+               $icon = new OO.ui.IconWidget( { icon: 'check', flags: [ 'success' ] } ).$element;
        } else if ( kind === 'notice' ) {
                $icon = new OO.ui.IconWidget( { icon: 'notice' } ).$element;
        } else {
@@ -11935,6 +12111,36 @@ OO.ui.FieldLayout.prototype.setErrors = function ( errors ) {
        return this;
 };
 
+/**
+ * Set the list of warning messages.
+ *
+ * @param {Array} warnings Warning messages about the widget, which will be displayed below
+ *  the widget.
+ *  The array may contain strings or OO.ui.HtmlSnippet instances.
+ * @chainable
+ * @return {OO.ui.BookletLayout} The layout, for chaining
+ */
+OO.ui.FieldLayout.prototype.setWarnings = function ( warnings ) {
+       this.warnings = warnings.slice();
+       this.updateMessages();
+       return this;
+};
+
+/**
+ * Set the list of success messages.
+ *
+ * @param {Array} successMessages Success messages about the widget, which will be displayed below
+ *  the widget.
+ *  The array may contain strings or OO.ui.HtmlSnippet instances.
+ * @chainable
+ * @return {OO.ui.BookletLayout} The layout, for chaining
+ */
+OO.ui.FieldLayout.prototype.setSuccess = function ( successMessages ) {
+       this.successMessages = successMessages.slice();
+       this.updateMessages();
+       return this;
+};
+
 /**
  * Set the list of notice messages.
  *
@@ -11950,7 +12156,7 @@ OO.ui.FieldLayout.prototype.setNotices = function ( notices ) {
 };
 
 /**
- * Update the rendering of error and notice messages.
+ * Update the rendering of error, warning, success and notice messages.
  *
  * @private
  */
@@ -11958,19 +12164,30 @@ OO.ui.FieldLayout.prototype.updateMessages = function () {
        var i;
        this.$messages.empty();
 
-       if ( this.errors.length || this.notices.length ) {
+       if (
+               this.errors.length ||
+               this.warnings.length ||
+               this.successMessages.length ||
+               this.notices.length
+       ) {
                this.$body.after( this.$messages );
        } else {
                this.$messages.remove();
                return;
        }
 
-       for ( i = 0; i < this.notices.length; i++ ) {
-               this.$messages.append( this.makeMessage( 'notice', this.notices[ i ] ) );
-       }
        for ( i = 0; i < this.errors.length; i++ ) {
                this.$messages.append( this.makeMessage( 'error', this.errors[ i ] ) );
        }
+       for ( i = 0; i < this.warnings.length; i++ ) {
+               this.$messages.append( this.makeMessage( 'warning', this.warnings[ i ] ) );
+       }
+       for ( i = 0; i < this.successMessages.length; i++ ) {
+               this.$messages.append( this.makeMessage( 'success', this.successMessages[ i ] ) );
+       }
+       for ( i = 0; i < this.notices.length; i++ ) {
+               this.$messages.append( this.makeMessage( 'notice', this.notices[ i ] ) );
+       }
 };
 
 /**
@@ -12040,9 +12257,10 @@ OO.ui.FieldLayout.prototype.createHelpElement = function ( help, $overlay ) {
 };
 
 /**
- * ActionFieldLayouts are used with OO.ui.FieldsetLayout. The layout consists of a field-widget, a button,
- * and an optional label and/or help text. The field-widget (e.g., a {@link OO.ui.TextInputWidget TextInputWidget}),
- * is required and is specified before any optional configuration settings.
+ * ActionFieldLayouts are used with OO.ui.FieldsetLayout. The layout consists of a field-widget,
+ * a button, and an optional label and/or help text. The field-widget (e.g., a
+ * {@link OO.ui.TextInputWidget TextInputWidget}), is required and is specified before any optional
+ * configuration settings.
  *
  * Labels can be aligned in one of four ways:
  *
@@ -12056,8 +12274,8 @@ OO.ui.FieldLayout.prototype.createHelpElement = function ( help, $overlay ) {
  * - **inline**: The label is placed after the field-widget and aligned to the left.
  *   An inline-alignment is best used with checkboxes or radio buttons.
  *
- * Help text is accessed via a help icon that appears in the upper right corner of the rendered field layout when help
- * text is specified.
+ * Help text is accessed via a help icon that appears in the upper right corner of the rendered
+ * field layout when help text is specified.
  *
  *     @example
  *     // Example of an ActionFieldLayout
@@ -12102,16 +12320,14 @@ OO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWid
        this.$input = this.isFieldInline() ? $( '<span>' ) : $( '<div>' );
 
        // Initialization
-       this.$element
-               .addClass( 'oo-ui-actionFieldLayout' );
+       this.$element.addClass( 'oo-ui-actionFieldLayout' );
        this.$button
                .addClass( 'oo-ui-actionFieldLayout-button' )
                .append( this.buttonWidget.$element );
        this.$input
                .addClass( 'oo-ui-actionFieldLayout-input' )
                .append( this.fieldWidget.$element );
-       this.$field
-               .append( this.$input, this.$button );
+       this.$field.append( this.$input, this.$button );
 };
 
 /* Setup */
@@ -12158,10 +12374,11 @@ OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {OO.ui.FieldLayout[]} [items] An array of fields to add to the fieldset. See OO.ui.FieldLayout for more information about fields.
- * @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 {OO.ui.FieldLayout[]} [items] An array of fields to add to the fieldset.
+ *  See OO.ui.FieldLayout for more information about fields.
+ * @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.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
  */
@@ -12230,9 +12447,10 @@ OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.GroupElement );
 OO.ui.FieldsetLayout.static.tagName = 'fieldset';
 
 /**
- * FormLayouts are used to wrap {@link OO.ui.FieldsetLayout FieldsetLayouts} when you intend to use browser-based
- * form submission for the fields instead of handling them in JavaScript. Form layouts can be configured with an
- * HTML form action, an encoding type, and a method using the #action, #enctype, and #method configs, respectively.
+ * FormLayouts are used to wrap {@link OO.ui.FieldsetLayout FieldsetLayouts} when you intend to use
+ * browser-based form submission for the fields instead of handling them in JavaScript. Form layouts
+ * can be configured with an HTML form action, an encoding type, and a method using the #action,
+ * #enctype, and #method configs, respectively.
  * See the [OOUI documentation on MediaWiki] [1] for more information and examples.
  *
  * Only widgets from the {@link OO.ui.InputWidget InputWidget} family support form submission. It
@@ -12247,21 +12465,21 @@ OO.ui.FieldsetLayout.static.tagName = 'fieldset';
  * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs
  *
  *     @example
- *     // Example of a form layout that wraps a fieldset layout
+ *     // Example of a form layout that wraps a fieldset layout.
  *     var input1 = new OO.ui.TextInputWidget( {
- *         placeholder: 'Username'
- *     } );
- *     var input2 = new OO.ui.TextInputWidget( {
- *         placeholder: 'Password',
- *         type: 'password'
- *     } );
- *     var submit = new OO.ui.ButtonInputWidget( {
- *         label: 'Submit'
- *     } );
+ *             placeholder: 'Username'
+ *         } ),
+ *         input2 = new OO.ui.TextInputWidget( {
+ *             placeholder: 'Password',
+ *             type: 'password'
+ *         } ),
+ *         submit = new OO.ui.ButtonInputWidget( {
+ *             label: 'Submit'
+ *         } ),
+ *         fieldset = new OO.ui.FieldsetLayout( {
+ *             label: 'A form layout'
+ *         } );
  *
- *     var fieldset = new OO.ui.FieldsetLayout( {
- *         label: 'A form layout'
- *     } );
  *     fieldset.addItems( [
  *         new OO.ui.FieldLayout( input1, {
  *             label: 'Username',
@@ -12301,7 +12519,7 @@ OO.ui.FormLayout = function OoUiFormLayout( config ) {
        OO.ui.FormLayout.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+       OO.ui.mixin.GroupElement.call( this, $.extend( { $group: this.$element }, config ) );
 
        // Events
        this.$element.on( 'submit', this.onFormSubmit.bind( this ) );
@@ -12363,8 +12581,9 @@ OO.ui.FormLayout.prototype.onFormSubmit = function () {
 };
 
 /**
- * PanelLayouts expand to cover the entire area of their parent. They can be configured with scrolling, padding,
- * and a frame, and are often used together with {@link OO.ui.StackLayout StackLayouts}.
+ * PanelLayouts expand to cover the entire area of their parent. They can be configured with
+ * scrolling, padding, and a frame, and are often used together with
+ * {@link OO.ui.StackLayout StackLayouts}.
  *
  *     @example
  *     // Example of a panel layout
@@ -12384,7 +12603,8 @@ OO.ui.FormLayout.prototype.onFormSubmit = function () {
  * @cfg {boolean} [scrollable=false] Allow vertical scrolling
  * @cfg {boolean} [padded=false] Add padding between the content and the edges of the panel.
  * @cfg {boolean} [expanded=true] Expand the panel to fill the entire parent element.
- * @cfg {boolean} [framed=false] Render the panel with a frame to visually separate it from outside content.
+ * @cfg {boolean} [framed=false] Render the panel with a frame to visually separate it from outside
+ *  content.
  */
 OO.ui.PanelLayout = function OoUiPanelLayout( config ) {
        // Configuration initialization
@@ -12418,6 +12638,19 @@ OO.ui.PanelLayout = function OoUiPanelLayout( config ) {
 
 OO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout );
 
+/* Static Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.PanelLayout.static.reusePreInfuseDOM = function ( node, config ) {
+       config = OO.ui.PanelLayout.parent.static.reusePreInfuseDOM( node, config );
+       if ( config.preserveContent !== false ) {
+               config.$content = $( node ).contents();
+       }
+       return config;
+};
+
 /* Methods */
 
 /**
@@ -12437,7 +12670,7 @@ OO.ui.PanelLayout.prototype.focus = function () {
  * Note that inline elements, such as OO.ui.ButtonWidgets, do not need this wrapper.
  *
  *     @example
- *     // HorizontalLayout with a text input and a label
+ *     // HorizontalLayout with a text input and a label.
  *     var layout = new OO.ui.HorizontalLayout( {
  *       items: [
  *         new OO.ui.LabelWidget( { label: 'Label' } ),
@@ -12462,7 +12695,7 @@ OO.ui.HorizontalLayout = function OoUiHorizontalLayout( config ) {
        OO.ui.HorizontalLayout.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+       OO.ui.mixin.GroupElement.call( this, $.extend( { $group: this.$element }, config ) );
 
        // Initialization
        this.$element.addClass( 'oo-ui-horizontalLayout' );
@@ -12503,15 +12736,14 @@ OO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement );
  * @cfg {number} [min=-Infinity] Minimum allowed value
  * @cfg {number} [max=Infinity] Maximum allowed value
  * @cfg {number|null} [step] If specified, the field only accepts values that are multiples of this.
- * @cfg {number} [buttonStep=step||1] Delta when using the buttons or up/down arrow keys.
+ * @cfg {number} [buttonStep=step||1] Delta when using the buttons or Up/Down arrow keys.
  *  Defaults to `step` if specified, otherwise `1`.
- * @cfg {number} [pageStep=10*buttonStep] Delta when using the page-up/page-down keys.
+ * @cfg {number} [pageStep=10*buttonStep] Delta when using the Page-up/Page-down keys.
  *  Defaults to 10 times `buttonStep`.
  * @cfg {boolean} [showButtons=true] Whether to show the plus and minus buttons.
  */
 OO.ui.NumberInputWidget = function OoUiNumberInputWidget( config ) {
-       var $field = $( '<div>' )
-               .addClass( 'oo-ui-numberInputWidget-field' );
+       var $field = $( '<div>' ).addClass( 'oo-ui-numberInputWidget-field' );
 
        // Configuration initialization
        config = $.extend( {
@@ -12644,7 +12876,8 @@ OO.ui.NumberInputWidget.prototype.getRange = function () {
  *  Defaults to `step` if specified, otherwise `1`.
  * @param {number} [pageStep=10*buttonStep] Delta when using the page-up/page-down keys.
  *  Defaults to 10 times `buttonStep`.
- * @param {number|null} [step] If specified, the field only accepts values that are multiples of this.
+ * @param {number|null} [step] If specified, the field only accepts values that are multiples
+ *  of this.
  */
 OO.ui.NumberInputWidget.prototype.setStep = function ( buttonStep, pageStep, step ) {
        if ( buttonStep === undefined ) {
@@ -12850,6 +13083,269 @@ OO.ui.NumberInputWidget.prototype.setDisabled = function ( disabled ) {
        return this;
 };
 
+/**
+ * SelectFileInputWidgets allow for selecting files, using <input type="file">. These
+ * widgets can be configured with {@link OO.ui.mixin.IconElement icons}, {@link
+ * OO.ui.mixin.IndicatorElement indicators} and {@link OO.ui.mixin.TitledElement titles}.
+ * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.
+ *
+ * SelectFileInputWidgets must be used in HTML forms, as getValue only returns the filename.
+ *
+ *     @example
+ *     // A file select input widget.
+ *     var selectFile = new OO.ui.SelectFileInputWidget();
+ *     $( document.body ).append( selectFile.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets
+ *
+ * @class
+ * @extends OO.ui.InputWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string[]|null} [accept=null] MIME types to accept. null accepts all types.
+ * @cfg {boolean} [multiple=false] Allow multiple files to be selected.
+ * @cfg {string} [placeholder] Text to display when no file is selected.
+ * @cfg {Object} [button] Config to pass to select file button.
+ * @cfg {string} [icon] Icon to show next to file info
+ */
+OO.ui.SelectFileInputWidget = function OoUiSelectFileInputWidget( config ) {
+       var widget = this;
+
+       config = config || {};
+
+       // Construct buttons before parent method is called (calling setDisabled)
+       this.selectButton = new OO.ui.ButtonWidget( $.extend( {
+               $element: $( '<label>' ),
+               classes: [ 'oo-ui-selectFileInputWidget-selectButton' ],
+               label: OO.ui.msg( 'ooui-selectfile-button-select' )
+       }, config.button ) );
+
+       // Configuration initialization
+       config = $.extend( {
+               accept: null,
+               placeholder: OO.ui.msg( 'ooui-selectfile-placeholder' ),
+               $tabIndexed: this.selectButton.$tabIndexed
+       }, config );
+
+       this.info = new OO.ui.SearchInputWidget( {
+               classes: [ 'oo-ui-selectFileInputWidget-info' ],
+               placeholder: config.placeholder,
+               // Pass an empty collection so that .focus() always does nothing
+               $tabIndexed: $( [] )
+       } ).setIcon( config.icon );
+       // Set tabindex manually on $input as $tabIndexed has been overridden
+       this.info.$input.attr( 'tabindex', -1 );
+
+       // Parent constructor
+       OO.ui.SelectFileInputWidget.parent.call( this, config );
+
+       // Properties
+       this.currentFiles = this.filterFiles( this.$input[ 0 ].files || [] );
+       if ( Array.isArray( config.accept ) ) {
+               this.accept = config.accept;
+       } else {
+               this.accept = null;
+       }
+       this.multiple = !!config.multiple;
+
+       // Events
+       this.info.connect( this, { change: 'onInfoChange' } );
+       this.selectButton.$button.on( {
+               keypress: this.onKeyPress.bind( this )
+       } );
+       this.$input.on( {
+               change: this.onFileSelected.bind( this ),
+               // Support: IE11
+               // In IE 11, focussing a file input (by clicking on it) displays a text cursor and scrolls
+               // the cursor into view (in this case, it scrolls the button, which has 'overflow: hidden').
+               // Since this messes with our custom styling (the file input has large dimensions and this
+               // causes the label to scroll out of view), scroll the button back to top. (T192131)
+               focus: function () {
+                       widget.$input.parent().prop( 'scrollTop', 0 );
+               }
+       } );
+       this.connect( this, { change: 'updateUI' } );
+
+       this.fieldLayout = new OO.ui.ActionFieldLayout( this.info, this.selectButton, { align: 'top' } );
+
+       this.$input
+               .attr( {
+                       type: 'file',
+                       // this.selectButton is tabindexed
+                       tabindex: -1,
+                       // Infused input may have previously by
+                       // TabIndexed, so remove aria-disabled attr.
+                       'aria-disabled': null
+               } );
+
+       if ( this.accept ) {
+               this.$input.attr( 'accept', this.accept.join( ', ' ) );
+       }
+       if ( this.multiple ) {
+               this.$input.attr( 'multiple', '' );
+       }
+       this.selectButton.$button.append( this.$input );
+
+       this.$element
+               .addClass( 'oo-ui-selectFileInputWidget' )
+               .append( this.fieldLayout.$element );
+
+       this.updateUI();
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.SelectFileInputWidget, OO.ui.InputWidget );
+
+/* Static properties */
+
+// Set empty title so that browser default tooltips like "No file chosen" don't appear.
+// On SelectFileWidget this tooltip will often be incorrect, so create a consistent
+// experience on SelectFileInputWidget.
+OO.ui.SelectFileInputWidget.static.title = '';
+
+/* Methods */
+
+/**
+ * Get the filename of the currently selected file.
+ *
+ * @return {string} Filename
+ */
+OO.ui.SelectFileInputWidget.prototype.getFilename = function () {
+       if ( this.currentFiles.length ) {
+               return this.currentFiles.map( function ( file ) {
+                       return file.name;
+               } ).join( ', ' );
+       } else {
+               // Try to strip leading fakepath.
+               return this.getValue().split( '\\' ).pop();
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.SelectFileInputWidget.prototype.setValue = function ( value ) {
+       if ( value === undefined ) {
+               // Called during init, don't replace value if just infusing.
+               return;
+       }
+       if ( value ) {
+               // We need to update this.value, but without trying to modify
+               // the DOM value, which would throw an exception.
+               if ( this.value !== value ) {
+                       this.value = value;
+                       this.emit( 'change', this.value );
+               }
+       } else {
+               this.currentFiles = [];
+               // Parent method
+               OO.ui.SelectFileInputWidget.super.prototype.setValue.call( this, '' );
+       }
+};
+
+/**
+ * Handle file selection from the input.
+ *
+ * @protected
+ * @param {jQuery.Event} e
+ */
+OO.ui.SelectFileInputWidget.prototype.onFileSelected = function ( e ) {
+       this.currentFiles = this.filterFiles( e.target.files || [] );
+};
+
+/**
+ * Update the user interface when a file is selected or unselected.
+ *
+ * @protected
+ */
+OO.ui.SelectFileInputWidget.prototype.updateUI = function () {
+       this.info.setValue( this.getFilename() );
+};
+
+/**
+ * Determine if we should accept this file.
+ *
+ * @private
+ * @param {FileList|File[]} files Files to filter
+ * @return {File[]} Filter files
+ */
+OO.ui.SelectFileInputWidget.prototype.filterFiles = function ( files ) {
+       var accept = this.accept;
+
+       function mimeAllowed( file ) {
+               var i, mimeTest,
+                       mimeType = file.type;
+
+               if ( !accept || !mimeType ) {
+                       return true;
+               }
+
+               for ( i = 0; i < accept.length; i++ ) {
+                       mimeTest = accept[ i ];
+                       if ( mimeTest === mimeType ) {
+                               return true;
+                       } else if ( mimeTest.substr( -2 ) === '/*' ) {
+                               mimeTest = mimeTest.substr( 0, mimeTest.length - 1 );
+                               if ( mimeType.substr( 0, mimeTest.length ) === mimeTest ) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       return Array.prototype.filter.call( files, mimeAllowed );
+};
+
+/**
+ * Handle info input change events
+ *
+ * The info widget can only be changed by the user
+ * with the clear button.
+ *
+ * @private
+ * @param {string} value
+ */
+OO.ui.SelectFileInputWidget.prototype.onInfoChange = function ( value ) {
+       if ( value === '' ) {
+               this.setValue( null );
+       }
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ * @return {undefined/boolean} False to prevent default if event is handled
+ */
+OO.ui.SelectFileInputWidget.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() && this.$input &&
+               ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               // Emit a click to open the file selector.
+               this.$input.trigger( 'click' );
+               // Taking focus from the selectButton means keyUp isn't fired, so fire it manually.
+               this.selectButton.onDocumentKeyUp( e );
+               return false;
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.SelectFileInputWidget.prototype.setDisabled = function ( disabled ) {
+       // Parent method
+       OO.ui.SelectFileInputWidget.parent.prototype.setDisabled.call( this, disabled );
+
+       this.selectButton.setDisabled( disabled );
+       this.info.setDisabled( disabled );
+
+       return this;
+};
+
 }( OO ) );
 
 //# sourceMappingURL=oojs-ui-core.js.map.json
\ No newline at end of file
index 71fba1c..46a8693 100644 (file)
@@ -1 +1 @@
-{"version":3,"sources":["../src/intro.js.txt","../src/core.js","../src/mixin.js","../src/Element.js","../src/HtmlSnippet.js","../src/Layout.js","../src/Widget.js","../src/Theme.js","../src/mixins/TabIndexedElement.js","../src/mixins/ButtonElement.js","../src/mixins/GroupElement.js","../src/mixins/LabelElement.js","../src/mixins/IconElement.js","../src/mixins/IndicatorElement.js","../src/mixins/FlaggedElement.js","../src/mixins/TitledElement.js","../src/mixins/AccessKeyedElement.js","../src/widgets/ButtonWidget.js","../src/widgets/ButtonGroupWidget.js","../src/widgets/IconWidget.js","../src/widgets/IndicatorWidget.js","../src/widgets/LabelWidget.js","../src/mixins/PendingElement.js","../src/mixins/FloatableElement.js","../src/mixins/ClippableElement.js","../src/widgets/PopupWidget.js","../src/mixins/PopupElement.js","../src/widgets/PopupButtonWidget.js","../src/mixins/GroupWidget.js","../src/mixins/ItemWidget.js","../src/widgets/OptionWidget.js","../src/widgets/SelectWidget.js","../src/widgets/DecoratedOptionWidget.js","../src/widgets/MenuOptionWidget.js","../src/widgets/MenuSectionOptionWidget.js","../src/widgets/MenuSelectWidget.js","../src/widgets/DropdownWidget.js","../src/widgets/RadioOptionWidget.js","../src/widgets/RadioSelectWidget.js","../src/widgets/MultioptionWidget.js","../src/widgets/MultiselectWidget.js","../src/widgets/CheckboxMultioptionWidget.js","../src/widgets/CheckboxMultiselectWidget.js","../src/widgets/ProgressBarWidget.js","../src/widgets/InputWidget.js","../src/widgets/HiddenInputWidget.js","../src/widgets/ButtonInputWidget.js","../src/widgets/CheckboxInputWidget.js","../src/widgets/DropdownInputWidget.js","../src/widgets/RadioInputWidget.js","../src/widgets/RadioSelectInputWidget.js","../src/widgets/CheckboxMultiselectInputWidget.js","../src/widgets/TextInputWidget.js","../src/widgets/SearchInputWidget.js","../src/widgets/MultilineTextInputWidget.js","../src/widgets/ComboBoxInputWidget.js","../src/layouts/FieldLayout.js","../src/layouts/ActionFieldLayout.js","../src/layouts/FieldsetLayout.js","../src/layouts/FormLayout.js","../src/layouts/PanelLayout.js","../src/layouts/HorizontalLayout.js","../src/widgets/NumberInputWidget.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-core.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * Namespace for all classes, static methods and static properties.\n *\n * @class\n * @singleton\n */\nOO.ui = {};\n\nOO.ui.bind = $.proxy;\n\n/**\n * @property {Object}\n */\nOO.ui.Keys = {\n\tUNDEFINED: 0,\n\tBACKSPACE: 8,\n\tDELETE: 46,\n\tLEFT: 37,\n\tRIGHT: 39,\n\tUP: 38,\n\tDOWN: 40,\n\tENTER: 13,\n\tEND: 35,\n\tHOME: 36,\n\tTAB: 9,\n\tPAGEUP: 33,\n\tPAGEDOWN: 34,\n\tESCAPE: 27,\n\tSHIFT: 16,\n\tSPACE: 32\n};\n\n/**\n * Constants for MouseEvent.which\n *\n * @property {Object}\n */\nOO.ui.MouseButtons = {\n\tLEFT: 1,\n\tMIDDLE: 2,\n\tRIGHT: 3\n};\n\n/**\n * @property {number}\n * @private\n */\nOO.ui.elementId = 0;\n\n/**\n * Generate a unique ID for element\n *\n * @return {string} ID\n */\nOO.ui.generateElementId = function () {\n\tOO.ui.elementId++;\n\treturn 'ooui-' + OO.ui.elementId;\n};\n\n/**\n * Check if an element is focusable.\n * Inspired by :focusable in jQueryUI v1.11.4 - 2015-04-14\n *\n * @param {jQuery} $element Element to test\n * @return {boolean} Element is focusable\n */\nOO.ui.isFocusableElement = function ( $element ) {\n\tvar nodeName,\n\t\telement = $element[ 0 ];\n\n\t// Anything disabled is not focusable\n\tif ( element.disabled ) {\n\t\treturn false;\n\t}\n\n\t// Check if the element is visible\n\tif ( !(\n\t\t// This is quicker than calling $element.is( ':visible' )\n\t\t$.expr.pseudos.visible( element ) &&\n\t\t// Check that all parents are visible\n\t\t!$element.parents().addBack().filter( function () {\n\t\t\treturn $.css( this, 'visibility' ) === 'hidden';\n\t\t} ).length\n\t) ) {\n\t\treturn false;\n\t}\n\n\t// Check if the element is ContentEditable, which is the string 'true'\n\tif ( element.contentEditable === 'true' ) {\n\t\treturn true;\n\t}\n\n\t// Anything with a non-negative numeric tabIndex is focusable.\n\t// Use .prop to avoid browser bugs\n\tif ( $element.prop( 'tabIndex' ) >= 0 ) {\n\t\treturn true;\n\t}\n\n\t// Some element types are naturally focusable\n\t// (indexOf is much faster than regex in Chrome and about the\n\t// same in FF: https://jsperf.com/regex-vs-indexof-array2)\n\tnodeName = element.nodeName.toLowerCase();\n\tif ( [ 'input', 'select', 'textarea', 'button', 'object' ].indexOf( nodeName ) !== -1 ) {\n\t\treturn true;\n\t}\n\n\t// Links and areas are focusable if they have an href\n\tif ( ( nodeName === 'a' || nodeName === 'area' ) && $element.attr( 'href' ) !== undefined ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Find a focusable child\n *\n * @param {jQuery} $container Container to search in\n * @param {boolean} [backwards] Search backwards\n * @return {jQuery} Focusable child, or an empty jQuery object if none found\n */\nOO.ui.findFocusable = function ( $container, backwards ) {\n\tvar $focusable = $( [] ),\n\t\t// $focusableCandidates is a superset of things that\n\t\t// could get matched by isFocusableElement\n\t\t$focusableCandidates = $container\n\t\t\t.find( 'input, select, textarea, button, object, a, area, [contenteditable], [tabindex]' );\n\n\tif ( backwards ) {\n\t\t$focusableCandidates = Array.prototype.reverse.call( $focusableCandidates );\n\t}\n\n\t$focusableCandidates.each( function () {\n\t\tvar $this = $( this );\n\t\tif ( OO.ui.isFocusableElement( $this ) ) {\n\t\t\t$focusable = $this;\n\t\t\treturn false;\n\t\t}\n\t} );\n\treturn $focusable;\n};\n\n/**\n * Get the user's language and any fallback languages.\n *\n * These language codes are used to localize user interface elements in the user's language.\n *\n * In environments that provide a localization system, this function should be overridden to\n * return the user's language(s). The default implementation returns English (en) only.\n *\n * @return {string[]} Language codes, in descending order of priority\n */\nOO.ui.getUserLanguages = function () {\n\treturn [ 'en' ];\n};\n\n/**\n * Get a value in an object keyed by language code.\n *\n * @param {Object.<string,Mixed>} obj Object keyed by language code\n * @param {string|null} [lang] Language code, if omitted or null defaults to any user language\n * @param {string} [fallback] Fallback code, used if no matching language can be found\n * @return {Mixed} Local value\n */\nOO.ui.getLocalValue = function ( obj, lang, fallback ) {\n\tvar i, len, langs;\n\n\t// Requested language\n\tif ( obj[ lang ] ) {\n\t\treturn obj[ lang ];\n\t}\n\t// Known user language\n\tlangs = OO.ui.getUserLanguages();\n\tfor ( i = 0, len = langs.length; i < len; i++ ) {\n\t\tlang = langs[ i ];\n\t\tif ( obj[ lang ] ) {\n\t\t\treturn obj[ lang ];\n\t\t}\n\t}\n\t// Fallback language\n\tif ( obj[ fallback ] ) {\n\t\treturn obj[ fallback ];\n\t}\n\t// First existing language\n\tfor ( lang in obj ) {\n\t\treturn obj[ lang ];\n\t}\n\n\treturn undefined;\n};\n\n/**\n * Check if a node is contained within another node\n *\n * Similar to jQuery#contains except a list of containers can be supplied\n * and a boolean argument allows you to include the container in the match list\n *\n * @param {HTMLElement|HTMLElement[]} containers Container node(s) to search in\n * @param {HTMLElement} contained Node to find\n * @param {boolean} [matchContainers] Include the container(s) in the list of nodes to match, otherwise only match descendants\n * @return {boolean} The node is in the list of target nodes\n */\nOO.ui.contains = function ( containers, contained, matchContainers ) {\n\tvar i;\n\tif ( !Array.isArray( containers ) ) {\n\t\tcontainers = [ containers ];\n\t}\n\tfor ( i = containers.length - 1; i >= 0; i-- ) {\n\t\tif ( ( matchContainers && contained === containers[ i ] ) || $.contains( containers[ i ], contained ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/**\n * Return a function, that, as long as it continues to be invoked, will not\n * be triggered. The function will be called after it stops being called for\n * N milliseconds. If `immediate` is passed, trigger the function on the\n * leading edge, instead of the trailing.\n *\n * Ported from: http://underscorejs.org/underscore.js\n *\n * @param {Function} func Function to debounce\n * @param {number} [wait=0] Wait period in milliseconds\n * @param {boolean} [immediate] Trigger on leading edge\n * @return {Function} Debounced function\n */\nOO.ui.debounce = function ( func, wait, immediate ) {\n\tvar timeout;\n\treturn function () {\n\t\tvar context = this,\n\t\t\targs = arguments,\n\t\t\tlater = function () {\n\t\t\t\ttimeout = null;\n\t\t\t\tif ( !immediate ) {\n\t\t\t\t\tfunc.apply( context, args );\n\t\t\t\t}\n\t\t\t};\n\t\tif ( immediate && !timeout ) {\n\t\t\tfunc.apply( context, args );\n\t\t}\n\t\tif ( !timeout || wait ) {\n\t\t\tclearTimeout( timeout );\n\t\t\ttimeout = setTimeout( later, wait );\n\t\t}\n\t};\n};\n\n/**\n * Puts a console warning with provided message.\n *\n * @param {string} message Message\n */\nOO.ui.warnDeprecation = function ( message ) {\n\tif ( OO.getProp( window, 'console', 'warn' ) !== undefined ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn( message );\n\t}\n};\n\n/**\n * Returns a function, that, when invoked, will only be triggered at most once\n * during a given window of time. If called again during that window, it will\n * wait until the window ends and then trigger itself again.\n *\n * As it's not knowable to the caller whether the function will actually run\n * when the wrapper is called, return values from the function are entirely\n * discarded.\n *\n * @param {Function} func Function to throttle\n * @param {number} wait Throttle window length, in milliseconds\n * @return {Function} Throttled function\n */\nOO.ui.throttle = function ( func, wait ) {\n\tvar context, args, timeout,\n\t\tprevious = 0,\n\t\trun = function () {\n\t\t\ttimeout = null;\n\t\t\tprevious = OO.ui.now();\n\t\t\tfunc.apply( context, args );\n\t\t};\n\treturn function () {\n\t\t// Check how long it's been since the last time the function was\n\t\t// called, and whether it's more or less than the requested throttle\n\t\t// period. If it's less, run the function immediately. If it's more,\n\t\t// set a timeout for the remaining time -- but don't replace an\n\t\t// existing timeout, since that'd indefinitely prolong the wait.\n\t\tvar remaining = wait - ( OO.ui.now() - previous );\n\t\tcontext = this;\n\t\targs = arguments;\n\t\tif ( remaining <= 0 ) {\n\t\t\t// Note: unless wait was ridiculously large, this means we'll\n\t\t\t// automatically run the first time the function was called in a\n\t\t\t// given period. (If you provide a wait period larger than the\n\t\t\t// current Unix timestamp, you *deserve* unexpected behavior.)\n\t\t\tclearTimeout( timeout );\n\t\t\trun();\n\t\t} else if ( !timeout ) {\n\t\t\ttimeout = setTimeout( run, remaining );\n\t\t}\n\t};\n};\n\n/**\n * A (possibly faster) way to get the current timestamp as an integer\n *\n * @return {number} Current timestamp, in milliseconds since the Unix epoch\n */\nOO.ui.now = Date.now || function () {\n\treturn new Date().getTime();\n};\n\n/**\n * Reconstitute a JavaScript object corresponding to a widget created by\n * the PHP implementation.\n *\n * This is an alias for `OO.ui.Element.static.infuse()`.\n *\n * @param {string|HTMLElement|jQuery} idOrNode\n *   A DOM id (if a string) or node for the widget to infuse.\n * @param {Object} [config] Configuration options\n * @return {OO.ui.Element}\n *   The `OO.ui.Element` corresponding to this (infusable) document node.\n */\nOO.ui.infuse = function ( idOrNode, config ) {\n\treturn OO.ui.Element.static.infuse( idOrNode, config );\n};\n\n( function () {\n\t/**\n\t * Message store for the default implementation of OO.ui.msg\n\t *\n\t * Environments that provide a localization system should not use this, but should override\n\t * OO.ui.msg altogether.\n\t *\n\t * @private\n\t */\n\tvar messages = {\n\t\t// Tool tip for a button that moves items in a list down one place\n\t\t'ooui-outline-control-move-down': 'Move item down',\n\t\t// Tool tip for a button that moves items in a list up one place\n\t\t'ooui-outline-control-move-up': 'Move item up',\n\t\t// Tool tip for a button that removes items from a list\n\t\t'ooui-outline-control-remove': 'Remove item',\n\t\t// Label for the toolbar group that contains a list of all other available tools\n\t\t'ooui-toolbar-more': 'More',\n\t\t// Label for the fake tool that expands the full list of tools in a toolbar group\n\t\t'ooui-toolgroup-expand': 'More',\n\t\t// Label for the fake tool that collapses the full list of tools in a toolbar group\n\t\t'ooui-toolgroup-collapse': 'Fewer',\n\t\t// Default label for the tooltip for the button that removes a tag item\n\t\t'ooui-item-remove': 'Remove',\n\t\t// Default label for the accept button of a confirmation dialog\n\t\t'ooui-dialog-message-accept': 'OK',\n\t\t// Default label for the reject button of a confirmation dialog\n\t\t'ooui-dialog-message-reject': 'Cancel',\n\t\t// Title for process dialog error description\n\t\t'ooui-dialog-process-error': 'Something went wrong',\n\t\t// Label for process dialog dismiss error button, visible when describing errors\n\t\t'ooui-dialog-process-dismiss': 'Dismiss',\n\t\t// Label for process dialog retry action button, visible when describing only recoverable errors\n\t\t'ooui-dialog-process-retry': 'Try again',\n\t\t// Label for process dialog retry action button, visible when describing only warnings\n\t\t'ooui-dialog-process-continue': 'Continue',\n\t\t// Label for button in combobox input that triggers its dropdown\n\t\t'ooui-combobox-button-label': 'Dropdown for combobox',\n\t\t// Label for the file selection widget's select file button\n\t\t'ooui-selectfile-button-select': 'Select a file',\n\t\t// Label for the file selection widget if file selection is not supported\n\t\t'ooui-selectfile-not-supported': 'File selection is not supported',\n\t\t// Label for the file selection widget when no file is currently selected\n\t\t'ooui-selectfile-placeholder': 'No file is selected',\n\t\t// Label for the file selection widget's drop target\n\t\t'ooui-selectfile-dragdrop-placeholder': 'Drop file here',\n\t\t// Label for the help icon attached to a form field\n\t\t'ooui-field-help': 'Help'\n\t};\n\n\t/**\n\t * Get a localized message.\n\t *\n\t * After the message key, message parameters may optionally be passed. In the default implementation,\n\t * any occurrences of $1 are replaced with the first parameter, $2 with the second parameter, etc.\n\t * Alternative implementations of OO.ui.msg may use any substitution system they like, as long as\n\t * they support unnamed, ordered message parameters.\n\t *\n\t * In environments that provide a localization system, this function should be overridden to\n\t * return the message translated in the user's language. The default implementation always returns\n\t * English messages. An example of doing this with [jQuery.i18n](https://github.com/wikimedia/jquery.i18n)\n\t * follows.\n\t *\n\t *     @example\n\t *     var i, iLen, button,\n\t *         messagePath = 'oojs-ui/dist/i18n/',\n\t *         languages = [ $.i18n().locale, 'ur', 'en' ],\n\t *         languageMap = {};\n\t *\n\t *     for ( i = 0, iLen = languages.length; i < iLen; i++ ) {\n\t *         languageMap[ languages[ i ] ] = messagePath + languages[ i ].toLowerCase() + '.json';\n\t *     }\n\t *\n\t *     $.i18n().load( languageMap ).done( function() {\n\t *         // Replace the built-in `msg` only once we've loaded the internationalization.\n\t *         // OOUI uses `OO.ui.deferMsg` for all initially-loaded messages. So long as\n\t *         // you put off creating any widgets until this promise is complete, no English\n\t *         // will be displayed.\n\t *         OO.ui.msg = $.i18n;\n\t *\n\t *         // A button displaying \"OK\" in the default locale\n\t *         button = new OO.ui.ButtonWidget( {\n\t *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),\n\t *             icon: 'check'\n\t *         } );\n\t *         $( document.body ).append( button.$element );\n\t *\n\t *         // A button displaying \"OK\" in Urdu\n\t *         $.i18n().locale = 'ur';\n\t *         button = new OO.ui.ButtonWidget( {\n\t *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),\n\t *             icon: 'check'\n\t *         } );\n\t *         $( document.body ).append( button.$element );\n\t *     } );\n\t *\n\t * @param {string} key Message key\n\t * @param {...Mixed} [params] Message parameters\n\t * @return {string} Translated message with parameters substituted\n\t */\n\tOO.ui.msg = function ( key ) {\n\t\tvar message = messages[ key ],\n\t\t\tparams = Array.prototype.slice.call( arguments, 1 );\n\t\tif ( typeof message === 'string' ) {\n\t\t\t// Perform $1 substitution\n\t\t\tmessage = message.replace( /\\$(\\d+)/g, function ( unused, n ) {\n\t\t\t\tvar i = parseInt( n, 10 );\n\t\t\t\treturn params[ i - 1 ] !== undefined ? params[ i - 1 ] : '$' + n;\n\t\t\t} );\n\t\t} else {\n\t\t\t// Return placeholder if message not found\n\t\t\tmessage = '[' + key + ']';\n\t\t}\n\t\treturn message;\n\t};\n}() );\n\n/**\n * Package a message and arguments for deferred resolution.\n *\n * Use this when you are statically specifying a message and the message may not yet be present.\n *\n * @param {string} key Message key\n * @param {...Mixed} [params] Message parameters\n * @return {Function} Function that returns the resolved message when executed\n */\nOO.ui.deferMsg = function () {\n\tvar args = arguments;\n\treturn function () {\n\t\treturn OO.ui.msg.apply( OO.ui, args );\n\t};\n};\n\n/**\n * Resolve a message.\n *\n * If the message is a function it will be executed, otherwise it will pass through directly.\n *\n * @param {Function|string} msg Deferred message, or message text\n * @return {string} Resolved message\n */\nOO.ui.resolveMsg = function ( msg ) {\n\tif ( typeof msg === 'function' ) {\n\t\treturn msg();\n\t}\n\treturn msg;\n};\n\n/**\n * @param {string} url\n * @return {boolean}\n */\nOO.ui.isSafeUrl = function ( url ) {\n\t// Keep this function in sync with php/Tag.php\n\tvar i, protocolWhitelist;\n\n\tfunction stringStartsWith( haystack, needle ) {\n\t\treturn haystack.substr( 0, needle.length ) === needle;\n\t}\n\n\tprotocolWhitelist = [\n\t\t'bitcoin', 'ftp', 'ftps', 'geo', 'git', 'gopher', 'http', 'https', 'irc', 'ircs',\n\t\t'magnet', 'mailto', 'mms', 'news', 'nntp', 'redis', 'sftp', 'sip', 'sips', 'sms', 'ssh',\n\t\t'svn', 'tel', 'telnet', 'urn', 'worldwind', 'xmpp'\n\t];\n\n\tif ( url === '' ) {\n\t\treturn true;\n\t}\n\n\tfor ( i = 0; i < protocolWhitelist.length; i++ ) {\n\t\tif ( stringStartsWith( url, protocolWhitelist[ i ] + ':' ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// This matches '//' too\n\tif ( stringStartsWith( url, '/' ) || stringStartsWith( url, './' ) ) {\n\t\treturn true;\n\t}\n\tif ( stringStartsWith( url, '?' ) || stringStartsWith( url, '#' ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Check if the user has a 'mobile' device.\n *\n * For our purposes this means the user is primarily using an\n * on-screen keyboard, touch input instead of a mouse and may\n * have a physically small display.\n *\n * It is left up to implementors to decide how to compute this\n * so the default implementation always returns false.\n *\n * @return {boolean} User is on a mobile device\n */\nOO.ui.isMobile = function () {\n\treturn false;\n};\n\n/**\n * Get the additional spacing that should be taken into account when displaying elements that are\n * clipped to the viewport, e.g. dropdown menus and popups. This is meant to be overridden to avoid\n * such menus overlapping any fixed headers/toolbars/navigation used by the site.\n *\n * @return {Object} Object with the properties 'top', 'right', 'bottom', 'left', each representing\n *     the extra spacing from that edge of viewport (in pixels)\n */\nOO.ui.getViewportSpacing = function () {\n\treturn {\n\t\ttop: 0,\n\t\tright: 0,\n\t\tbottom: 0,\n\t\tleft: 0\n\t};\n};\n\n/**\n * Get the default overlay, which is used by various widgets when they are passed `$overlay: true`.\n * See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n *\n * @return {jQuery} Default overlay node\n */\nOO.ui.getDefaultOverlay = function () {\n\tif ( !OO.ui.$defaultOverlay ) {\n\t\tOO.ui.$defaultOverlay = $( '<div>' ).addClass( 'oo-ui-defaultOverlay' );\n\t\t$( document.body ).append( OO.ui.$defaultOverlay );\n\t}\n\treturn OO.ui.$defaultOverlay;\n};\n","/*!\n * Mixin namespace.\n */\n\n/**\n * Namespace for OOUI mixins.\n *\n * Mixins are named according to the type of object they are intended to\n * be mixed in to.  For example, OO.ui.mixin.GroupElement is intended to be\n * mixed in to an instance of OO.ui.Element, and OO.ui.mixin.GroupWidget\n * is intended to be mixed in to an instance of OO.ui.Widget.\n *\n * @class\n * @singleton\n */\nOO.ui.mixin = {};\n","/**\n * Each Element represents a rendering in the DOM—a button or an icon, for example, or anything\n * that is visible to a user. Unlike {@link OO.ui.Widget widgets}, plain elements usually do not have events\n * connected to them and can't be interacted with.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string[]} [classes] The names of the CSS classes to apply to the element. CSS styles are added\n *  to the top level (e.g., the outermost div) of the element. See the [OOUI documentation on MediaWiki][2]\n *  for an example.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches#cssExample\n * @cfg {string} [id] The HTML id attribute used in the rendered tag.\n * @cfg {string} [text] Text to insert\n * @cfg {Array} [content] An array of content elements to append (after #text).\n *  Strings will be html-escaped; use an OO.ui.HtmlSnippet to append raw HTML.\n *  Instances of OO.ui.Element will have their $element appended.\n * @cfg {jQuery} [$content] Content elements to append (after #text).\n * @cfg {jQuery} [$element] Wrapper element. Defaults to a new element with #getTagName.\n * @cfg {Mixed} [data] Custom data of any type or combination of types (e.g., string, number, array, object).\n *  Data can also be specified with the #setData method.\n */\nOO.ui.Element = function OoUiElement( config ) {\n\tif ( OO.ui.isDemo ) {\n\t\tthis.initialConfig = config;\n\t}\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$ = function () {\n\t\tOO.ui.warnDeprecation( 'this.$ is deprecated, use global $ instead' );\n\t\treturn $.apply( this, arguments );\n\t};\n\tthis.elementId = null;\n\tthis.visible = true;\n\tthis.data = config.data;\n\tthis.$element = config.$element ||\n\t\t$( document.createElement( this.getTagName() ) );\n\tthis.elementGroup = null;\n\n\t// Initialization\n\tif ( Array.isArray( config.classes ) ) {\n\t\tthis.$element.addClass( config.classes );\n\t}\n\tif ( config.id ) {\n\t\tthis.setElementId( config.id );\n\t}\n\tif ( config.text ) {\n\t\tthis.$element.text( config.text );\n\t}\n\tif ( config.content ) {\n\t\t// The `content` property treats plain strings as text; use an\n\t\t// HtmlSnippet to append HTML content.  `OO.ui.Element`s get their\n\t\t// appropriate $element appended.\n\t\tthis.$element.append( config.content.map( function ( v ) {\n\t\t\tif ( typeof v === 'string' ) {\n\t\t\t\t// Escape string so it is properly represented in HTML.\n\t\t\t\treturn document.createTextNode( v );\n\t\t\t} else if ( v instanceof OO.ui.HtmlSnippet ) {\n\t\t\t\t// Bypass escaping.\n\t\t\t\treturn v.toString();\n\t\t\t} else if ( v instanceof OO.ui.Element ) {\n\t\t\t\treturn v.$element;\n\t\t\t}\n\t\t\treturn v;\n\t\t} ) );\n\t}\n\tif ( config.$content ) {\n\t\t// The `$content` property treats plain strings as HTML.\n\t\tthis.$element.append( config.$content );\n\t}\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Element );\n\n/* Static Properties */\n\n/**\n * The name of the HTML tag used by the element.\n *\n * The static value may be ignored if the #getTagName method is overridden.\n *\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Element.static.tagName = 'div';\n\n/* Static Methods */\n\n/**\n * Reconstitute a JavaScript object corresponding to a widget created\n * by the PHP implementation.\n *\n * @param {string|HTMLElement|jQuery} idOrNode\n *   A DOM id (if a string) or node for the widget to infuse.\n * @param {Object} [config] Configuration options\n * @return {OO.ui.Element}\n *   The `OO.ui.Element` corresponding to this (infusable) document node.\n *   For `Tag` objects emitted on the HTML side (used occasionally for content)\n *   the value returned is a newly-created Element wrapping around the existing\n *   DOM node.\n */\nOO.ui.Element.static.infuse = function ( idOrNode, config ) {\n\tvar obj = OO.ui.Element.static.unsafeInfuse( idOrNode, config, false );\n\n\tif ( typeof idOrNode === 'string' ) {\n\t\t// IDs deprecated since 0.29.7\n\t\tOO.ui.warnDeprecation(\n\t\t\t'Passing a string ID to infuse is deprecated. Use an HTMLElement or jQuery collection instead.'\n\t\t);\n\t}\n\t// Verify that the type matches up.\n\t// FIXME: uncomment after T89721 is fixed, see T90929.\n\t/*\n\tif ( !( obj instanceof this['class'] ) ) {\n\t\tthrow new Error( 'Infusion type mismatch!' );\n\t}\n\t*/\n\treturn obj;\n};\n\n/**\n * Implementation helper for `infuse`; skips the type check and has an\n * extra property so that only the top-level invocation touches the DOM.\n *\n * @private\n * @param {string|HTMLElement|jQuery} idOrNode\n * @param {Object} [config] Configuration options\n * @param {jQuery.Promise} [domPromise] A promise that will be resolved\n *     when the top-level widget of this infusion is inserted into DOM,\n *     replacing the original node; only used internally.\n * @return {OO.ui.Element}\n */\nOO.ui.Element.static.unsafeInfuse = function ( idOrNode, config, domPromise ) {\n\t// look for a cached result of a previous infusion.\n\tvar id, $elem, error, data, cls, parts, parent, obj, top, state, infusedChildren;\n\tif ( typeof idOrNode === 'string' ) {\n\t\tid = idOrNode;\n\t\t$elem = $( document.getElementById( id ) );\n\t} else {\n\t\t$elem = $( idOrNode );\n\t\tid = $elem.attr( 'id' );\n\t}\n\tif ( !$elem.length ) {\n\t\tif ( typeof idOrNode === 'string' ) {\n\t\t\terror = 'Widget not found: ' + idOrNode;\n\t\t} else if ( idOrNode && idOrNode.selector ) {\n\t\t\terror = 'Widget not found: ' + idOrNode.selector;\n\t\t} else {\n\t\t\terror = 'Widget not found';\n\t\t}\n\t\tthrow new Error( error );\n\t}\n\tif ( $elem[ 0 ].oouiInfused ) {\n\t\t$elem = $elem[ 0 ].oouiInfused;\n\t}\n\tdata = $elem.data( 'ooui-infused' );\n\tif ( data ) {\n\t\t// cached!\n\t\tif ( data === true ) {\n\t\t\tthrow new Error( 'Circular dependency! ' + id );\n\t\t}\n\t\tif ( domPromise ) {\n\t\t\t// pick up dynamic state, like focus, value of form inputs, scroll position, etc.\n\t\t\tstate = data.constructor.static.gatherPreInfuseState( $elem, data );\n\t\t\t// restore dynamic state after the new element is re-inserted into DOM under infused parent\n\t\t\tdomPromise.done( data.restorePreInfuseState.bind( data, state ) );\n\t\t\tinfusedChildren = $elem.data( 'ooui-infused-children' );\n\t\t\tif ( infusedChildren && infusedChildren.length ) {\n\t\t\t\tinfusedChildren.forEach( function ( data ) {\n\t\t\t\t\tvar state = data.constructor.static.gatherPreInfuseState( $elem, data );\n\t\t\t\t\tdomPromise.done( data.restorePreInfuseState.bind( data, state ) );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\treturn data;\n\t}\n\tdata = $elem.attr( 'data-ooui' );\n\tif ( !data ) {\n\t\tthrow new Error( 'No infusion data found: ' + id );\n\t}\n\ttry {\n\t\tdata = JSON.parse( data );\n\t} catch ( _ ) {\n\t\tdata = null;\n\t}\n\tif ( !( data && data._ ) ) {\n\t\tthrow new Error( 'No valid infusion data found: ' + id );\n\t}\n\tif ( data._ === 'Tag' ) {\n\t\t// Special case: this is a raw Tag; wrap existing node, don't rebuild.\n\t\treturn new OO.ui.Element( $.extend( {}, config, { $element: $elem } ) );\n\t}\n\tparts = data._.split( '.' );\n\tcls = OO.getProp.apply( OO, [ window ].concat( parts ) );\n\tif ( cls === undefined ) {\n\t\tthrow new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );\n\t}\n\n\t// Verify that we're creating an OO.ui.Element instance\n\tparent = cls.parent;\n\n\twhile ( parent !== undefined ) {\n\t\tif ( parent === OO.ui.Element ) {\n\t\t\t// Safe\n\t\t\tbreak;\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\tif ( parent !== OO.ui.Element ) {\n\t\tthrow new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );\n\t}\n\n\tif ( !domPromise ) {\n\t\ttop = $.Deferred();\n\t\tdomPromise = top.promise();\n\t}\n\t$elem.data( 'ooui-infused', true ); // prevent loops\n\tdata.id = id; // implicit\n\tinfusedChildren = [];\n\tdata = OO.copy( data, null, function deserialize( value ) {\n\t\tvar infused;\n\t\tif ( OO.isPlainObject( value ) ) {\n\t\t\tif ( value.tag ) {\n\t\t\t\tinfused = OO.ui.Element.static.unsafeInfuse( value.tag, config, domPromise );\n\t\t\t\tinfusedChildren.push( infused );\n\t\t\t\t// Flatten the structure\n\t\t\t\tinfusedChildren.push.apply( infusedChildren, infused.$element.data( 'ooui-infused-children' ) || [] );\n\t\t\t\tinfused.$element.removeData( 'ooui-infused-children' );\n\t\t\t\treturn infused;\n\t\t\t}\n\t\t\tif ( value.html !== undefined ) {\n\t\t\t\treturn new OO.ui.HtmlSnippet( value.html );\n\t\t\t}\n\t\t}\n\t} );\n\t// allow widgets to reuse parts of the DOM\n\tdata = cls.static.reusePreInfuseDOM( $elem[ 0 ], data );\n\t// pick up dynamic state, like focus, value of form inputs, scroll position, etc.\n\tstate = cls.static.gatherPreInfuseState( $elem[ 0 ], data );\n\t// rebuild widget\n\t// eslint-disable-next-line new-cap\n\tobj = new cls( $.extend( {}, config, data ) );\n\t// If anyone is holding a reference to the old DOM element,\n\t// let's allow them to OO.ui.infuse() it and do what they expect, see T105828.\n\t// Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design.\n\t$elem[ 0 ].oouiInfused = obj.$element;\n\t// now replace old DOM with this new DOM.\n\tif ( top ) {\n\t\t// An efficient constructor might be able to reuse the entire DOM tree of the original element,\n\t\t// so only mutate the DOM if we need to.\n\t\tif ( $elem[ 0 ] !== obj.$element[ 0 ] ) {\n\t\t\t$elem.replaceWith( obj.$element );\n\t\t}\n\t\ttop.resolve();\n\t}\n\tobj.$element.data( 'ooui-infused', obj );\n\tobj.$element.data( 'ooui-infused-children', infusedChildren );\n\t// set the 'data-ooui' attribute so we can identify infused widgets\n\tobj.$element.attr( 'data-ooui', '' );\n\t// restore dynamic state after the new element is inserted into DOM\n\tdomPromise.done( obj.restorePreInfuseState.bind( obj, state ) );\n\treturn obj;\n};\n\n/**\n * Pick out parts of `node`'s DOM to be reused when infusing a widget.\n *\n * This method **must not** make any changes to the DOM, only find interesting pieces and add them\n * to `config` (which should then be returned). Actual DOM juggling should then be done by the\n * constructor, which will be given the enhanced config.\n *\n * @protected\n * @param {HTMLElement} node\n * @param {Object} config\n * @return {Object}\n */\nOO.ui.Element.static.reusePreInfuseDOM = function ( node, config ) {\n\treturn config;\n};\n\n/**\n * Gather the dynamic state (focus, value of form inputs, scroll position, etc.) of an HTML DOM node\n * (and its children) that represent an Element of the same class and the given configuration,\n * generated by the PHP implementation.\n *\n * This method is called just before `node` is detached from the DOM. The return value of this\n * function will be passed to #restorePreInfuseState after the newly created widget's #$element\n * is inserted into DOM to replace `node`.\n *\n * @protected\n * @param {HTMLElement} node\n * @param {Object} config\n * @return {Object}\n */\nOO.ui.Element.static.gatherPreInfuseState = function () {\n\treturn {};\n};\n\n/**\n * Get a jQuery function within a specific document.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} context Context to bind the function to\n * @param {jQuery} [$iframe] HTML iframe element that contains the document, omit if document is\n *   not in an iframe\n * @return {Function} Bound jQuery function\n */\nOO.ui.Element.static.getJQuery = function ( context, $iframe ) {\n\tfunction wrapper( selector ) {\n\t\treturn $( selector, wrapper.context );\n\t}\n\n\twrapper.context = this.getDocument( context );\n\n\tif ( $iframe ) {\n\t\twrapper.$iframe = $iframe;\n\t}\n\n\treturn wrapper;\n};\n\n/**\n * Get the document of an element.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Object to get the document for\n * @return {HTMLDocument|null} Document object\n */\nOO.ui.Element.static.getDocument = function ( obj ) {\n\t// jQuery - selections created \"offscreen\" won't have a context, so .context isn't reliable\n\treturn ( obj[ 0 ] && obj[ 0 ].ownerDocument ) ||\n\t\t// Empty jQuery selections might have a context\n\t\tobj.context ||\n\t\t// HTMLElement\n\t\tobj.ownerDocument ||\n\t\t// Window\n\t\tobj.document ||\n\t\t// HTMLDocument\n\t\t( obj.nodeType === Node.DOCUMENT_NODE && obj ) ||\n\t\tnull;\n};\n\n/**\n * Get the window of an element or document.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the window for\n * @return {Window} Window object\n */\nOO.ui.Element.static.getWindow = function ( obj ) {\n\tvar doc = this.getDocument( obj );\n\treturn doc.defaultView;\n};\n\n/**\n * Get the direction of an element or document.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the direction for\n * @return {string} Text direction, either 'ltr' or 'rtl'\n */\nOO.ui.Element.static.getDir = function ( obj ) {\n\tvar isDoc, isWin;\n\n\tif ( obj instanceof $ ) {\n\t\tobj = obj[ 0 ];\n\t}\n\tisDoc = obj.nodeType === Node.DOCUMENT_NODE;\n\tisWin = obj.document !== undefined;\n\tif ( isDoc || isWin ) {\n\t\tif ( isWin ) {\n\t\t\tobj = obj.document;\n\t\t}\n\t\tobj = obj.body;\n\t}\n\treturn $( obj ).css( 'direction' );\n};\n\n/**\n * Get the offset between two frames.\n *\n * TODO: Make this function not use recursion.\n *\n * @static\n * @param {Window} from Window of the child frame\n * @param {Window} [to=window] Window of the parent frame\n * @param {Object} [offset] Offset to start with, used internally\n * @return {Object} Offset object, containing left and top properties\n */\nOO.ui.Element.static.getFrameOffset = function ( from, to, offset ) {\n\tvar i, len, frames, frame, rect;\n\n\tif ( !to ) {\n\t\tto = window;\n\t}\n\tif ( !offset ) {\n\t\toffset = { top: 0, left: 0 };\n\t}\n\tif ( from.parent === from ) {\n\t\treturn offset;\n\t}\n\n\t// Get iframe element\n\tframes = from.parent.document.getElementsByTagName( 'iframe' );\n\tfor ( i = 0, len = frames.length; i < len; i++ ) {\n\t\tif ( frames[ i ].contentWindow === from ) {\n\t\t\tframe = frames[ i ];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Recursively accumulate offset values\n\tif ( frame ) {\n\t\trect = frame.getBoundingClientRect();\n\t\toffset.left += rect.left;\n\t\toffset.top += rect.top;\n\t\tif ( from !== to ) {\n\t\t\tthis.getFrameOffset( from.parent, offset );\n\t\t}\n\t}\n\treturn offset;\n};\n\n/**\n * Get the offset between two elements.\n *\n * The two elements may be in a different frame, but in that case the frame $element is in must\n * be contained in the frame $anchor is in.\n *\n * @static\n * @param {jQuery} $element Element whose position to get\n * @param {jQuery} $anchor Element to get $element's position relative to\n * @return {Object} Translated position coordinates, containing top and left properties\n */\nOO.ui.Element.static.getRelativePosition = function ( $element, $anchor ) {\n\tvar iframe, iframePos,\n\t\tpos = $element.offset(),\n\t\tanchorPos = $anchor.offset(),\n\t\telementDocument = this.getDocument( $element ),\n\t\tanchorDocument = this.getDocument( $anchor );\n\n\t// If $element isn't in the same document as $anchor, traverse up\n\twhile ( elementDocument !== anchorDocument ) {\n\t\tiframe = elementDocument.defaultView.frameElement;\n\t\tif ( !iframe ) {\n\t\t\tthrow new Error( '$element frame is not contained in $anchor frame' );\n\t\t}\n\t\tiframePos = $( iframe ).offset();\n\t\tpos.left += iframePos.left;\n\t\tpos.top += iframePos.top;\n\t\telementDocument = iframe.ownerDocument;\n\t}\n\tpos.left -= anchorPos.left;\n\tpos.top -= anchorPos.top;\n\treturn pos;\n};\n\n/**\n * Get element border sizes.\n *\n * @static\n * @param {HTMLElement} el Element to measure\n * @return {Object} Dimensions object with `top`, `left`, `bottom` and `right` properties\n */\nOO.ui.Element.static.getBorders = function ( el ) {\n\tvar doc = el.ownerDocument,\n\t\twin = doc.defaultView,\n\t\tstyle = win.getComputedStyle( el, null ),\n\t\t$el = $( el ),\n\t\ttop = parseFloat( style ? style.borderTopWidth : $el.css( 'borderTopWidth' ) ) || 0,\n\t\tleft = parseFloat( style ? style.borderLeftWidth : $el.css( 'borderLeftWidth' ) ) || 0,\n\t\tbottom = parseFloat( style ? style.borderBottomWidth : $el.css( 'borderBottomWidth' ) ) || 0,\n\t\tright = parseFloat( style ? style.borderRightWidth : $el.css( 'borderRightWidth' ) ) || 0;\n\n\treturn {\n\t\ttop: top,\n\t\tleft: left,\n\t\tbottom: bottom,\n\t\tright: right\n\t};\n};\n\n/**\n * Get dimensions of an element or window.\n *\n * @static\n * @param {HTMLElement|Window} el Element to measure\n * @return {Object} Dimensions object with `borders`, `scroll`, `scrollbar` and `rect` properties\n */\nOO.ui.Element.static.getDimensions = function ( el ) {\n\tvar $el, $win,\n\t\tdoc = el.ownerDocument || el.document,\n\t\twin = doc.defaultView;\n\n\tif ( win === el || el === doc.documentElement ) {\n\t\t$win = $( win );\n\t\treturn {\n\t\t\tborders: { top: 0, left: 0, bottom: 0, right: 0 },\n\t\t\tscroll: {\n\t\t\t\ttop: $win.scrollTop(),\n\t\t\t\tleft: $win.scrollLeft()\n\t\t\t},\n\t\t\tscrollbar: { right: 0, bottom: 0 },\n\t\t\trect: {\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tbottom: $win.innerHeight(),\n\t\t\t\tright: $win.innerWidth()\n\t\t\t}\n\t\t};\n\t} else {\n\t\t$el = $( el );\n\t\treturn {\n\t\t\tborders: this.getBorders( el ),\n\t\t\tscroll: {\n\t\t\t\ttop: $el.scrollTop(),\n\t\t\t\tleft: $el.scrollLeft()\n\t\t\t},\n\t\t\tscrollbar: {\n\t\t\t\tright: $el.innerWidth() - el.clientWidth,\n\t\t\t\tbottom: $el.innerHeight() - el.clientHeight\n\t\t\t},\n\t\t\trect: el.getBoundingClientRect()\n\t\t};\n\t}\n};\n\n/**\n * Get the number of pixels that an element's content is scrolled to the left.\n *\n * Adapted from <https://github.com/othree/jquery.rtl-scroll-type>.\n * Original code copyright 2012 Wei-Ko Kao, licensed under the MIT License.\n *\n * This function smooths out browser inconsistencies (nicely described in the README at\n * <https://github.com/othree/jquery.rtl-scroll-type>) and produces a result consistent\n * with Firefox's 'scrollLeft', which seems the sanest.\n *\n * @static\n * @method\n * @param {HTMLElement|Window} el Element to measure\n * @return {number} Scroll position from the left.\n *  If the element's direction is LTR, this is a positive number between `0` (initial scroll position)\n *  and `el.scrollWidth - el.clientWidth` (furthest possible scroll position).\n *  If the element's direction is RTL, this is a negative number between `0` (initial scroll position)\n *  and `-el.scrollWidth + el.clientWidth` (furthest possible scroll position).\n */\nOO.ui.Element.static.getScrollLeft = ( function () {\n\tvar rtlScrollType = null;\n\n\tfunction test() {\n\t\tvar $definer = $( '<div>' ).attr( {\n\t\t\t\tdir: 'rtl',\n\t\t\t\tstyle: 'font-size: 14px; width: 4px; height: 1px; position: absolute; top: -1000px; overflow: scroll;'\n\t\t\t} ).text( 'ABCD' ),\n\t\t\tdefiner = $definer[ 0 ];\n\n\t\t$definer.appendTo( 'body' );\n\t\tif ( definer.scrollLeft > 0 ) {\n\t\t\t// Safari, Chrome\n\t\t\trtlScrollType = 'default';\n\t\t} else {\n\t\t\tdefiner.scrollLeft = 1;\n\t\t\tif ( definer.scrollLeft === 0 ) {\n\t\t\t\t// Firefox, old Opera\n\t\t\t\trtlScrollType = 'negative';\n\t\t\t} else {\n\t\t\t\t// Internet Explorer, Edge\n\t\t\t\trtlScrollType = 'reverse';\n\t\t\t}\n\t\t}\n\t\t$definer.remove();\n\t}\n\n\treturn function getScrollLeft( el ) {\n\t\tvar isRoot = el.window === el ||\n\t\t\t\tel === el.ownerDocument.body ||\n\t\t\t\tel === el.ownerDocument.documentElement,\n\t\t\tscrollLeft = isRoot ? $( window ).scrollLeft() : el.scrollLeft,\n\t\t\t// All browsers use the correct scroll type ('negative') on the root, so don't\n\t\t\t// do any fixups when looking at the root element\n\t\t\tdirection = isRoot ? 'ltr' : $( el ).css( 'direction' );\n\n\t\tif ( direction === 'rtl' ) {\n\t\t\tif ( rtlScrollType === null ) {\n\t\t\t\ttest();\n\t\t\t}\n\t\t\tif ( rtlScrollType === 'reverse' ) {\n\t\t\t\tscrollLeft = -scrollLeft;\n\t\t\t} else if ( rtlScrollType === 'default' ) {\n\t\t\t\tscrollLeft = scrollLeft - el.scrollWidth + el.clientWidth;\n\t\t\t}\n\t\t}\n\n\t\treturn scrollLeft;\n\t};\n}() );\n\n/**\n * Get the root scrollable element of given element's document.\n *\n * On Blink-based browsers (Chrome etc.), `document.documentElement` can't be used to get or set\n * the scrollTop property; instead we have to use `document.body`. Changing and testing the value\n * lets us use 'body' or 'documentElement' based on what is working.\n *\n * https://code.google.com/p/chromium/issues/detail?id=303131\n *\n * @static\n * @param {HTMLElement} el Element to find root scrollable parent for\n * @return {HTMLElement} Scrollable parent, `document.body` or `document.documentElement`\n *     depending on browser\n */\nOO.ui.Element.static.getRootScrollableElement = function ( el ) {\n\tvar scrollTop, body;\n\n\tif ( OO.ui.scrollableElement === undefined ) {\n\t\tbody = el.ownerDocument.body;\n\t\tscrollTop = body.scrollTop;\n\t\tbody.scrollTop = 1;\n\n\t\t// In some browsers (observed in Chrome 56 on Linux Mint 18.1),\n\t\t// body.scrollTop doesn't become exactly 1, but a fractional value like 0.76\n\t\tif ( Math.round( body.scrollTop ) === 1 ) {\n\t\t\tbody.scrollTop = scrollTop;\n\t\t\tOO.ui.scrollableElement = 'body';\n\t\t} else {\n\t\t\tOO.ui.scrollableElement = 'documentElement';\n\t\t}\n\t}\n\n\treturn el.ownerDocument[ OO.ui.scrollableElement ];\n};\n\n/**\n * Get closest scrollable container.\n *\n * Traverses up until either a scrollable element or the root is reached, in which case the root\n * scrollable element will be returned (see #getRootScrollableElement).\n *\n * @static\n * @param {HTMLElement} el Element to find scrollable container for\n * @param {string} [dimension] Dimension of scrolling to look for; `x`, `y` or omit for either\n * @return {HTMLElement} Closest scrollable container\n */\nOO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) {\n\tvar i, val,\n\t\t// Browsers do not correctly return the computed value of 'overflow' when 'overflow-x' and\n\t\t// 'overflow-y' have different values, so we need to check the separate properties.\n\t\tprops = [ 'overflow-x', 'overflow-y' ],\n\t\t$parent = $( el ).parent();\n\n\tif ( dimension === 'x' || dimension === 'y' ) {\n\t\tprops = [ 'overflow-' + dimension ];\n\t}\n\n\t// Special case for the document root (which doesn't really have any scrollable container, since\n\t// it is the ultimate scrollable container, but this is probably saner than null or exception)\n\tif ( $( el ).is( 'html, body' ) ) {\n\t\treturn this.getRootScrollableElement( el );\n\t}\n\n\twhile ( $parent.length ) {\n\t\tif ( $parent[ 0 ] === this.getRootScrollableElement( el ) ) {\n\t\t\treturn $parent[ 0 ];\n\t\t}\n\t\ti = props.length;\n\t\twhile ( i-- ) {\n\t\t\tval = $parent.css( props[ i ] );\n\t\t\t// We assume that elements with 'overflow' (in any direction) set to 'hidden' will never be\n\t\t\t// scrolled in that direction, but they can actually be scrolled programatically. The user can\n\t\t\t// unintentionally perform a scroll in such case even if the application doesn't scroll\n\t\t\t// programatically, e.g. when jumping to an anchor, or when using built-in find functionality.\n\t\t\t// This could cause funny issues...\n\t\t\tif ( val === 'auto' || val === 'scroll' ) {\n\t\t\t\treturn $parent[ 0 ];\n\t\t\t}\n\t\t}\n\t\t$parent = $parent.parent();\n\t}\n\t// The element is unattached... return something mostly sane\n\treturn this.getRootScrollableElement( el );\n};\n\n/**\n * Scroll element into view.\n *\n * @static\n * @param {HTMLElement} el Element to scroll into view\n * @param {Object} [config] Configuration options\n * @param {string} [config.duration='fast'] jQuery animation duration value\n * @param {string} [config.direction] Scroll in only one direction, e.g. 'x' or 'y', omit\n *  to scroll in both directions\n * @return {jQuery.Promise} Promise which resolves when the scroll is complete\n */\nOO.ui.Element.static.scrollIntoView = function ( el, config ) {\n\tvar position, animations, container, $container, elementDimensions, containerDimensions, $window,\n\t\tdeferred = $.Deferred();\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\tanimations = {};\n\tcontainer = this.getClosestScrollableContainer( el, config.direction );\n\t$container = $( container );\n\telementDimensions = this.getDimensions( el );\n\tcontainerDimensions = this.getDimensions( container );\n\t$window = $( this.getWindow( el ) );\n\n\t// Compute the element's position relative to the container\n\tif ( $container.is( 'html, body' ) ) {\n\t\t// If the scrollable container is the root, this is easy\n\t\tposition = {\n\t\t\ttop: elementDimensions.rect.top,\n\t\t\tbottom: $window.innerHeight() - elementDimensions.rect.bottom,\n\t\t\tleft: elementDimensions.rect.left,\n\t\t\tright: $window.innerWidth() - elementDimensions.rect.right\n\t\t};\n\t} else {\n\t\t// Otherwise, we have to subtract el's coordinates from container's coordinates\n\t\tposition = {\n\t\t\ttop: elementDimensions.rect.top - ( containerDimensions.rect.top + containerDimensions.borders.top ),\n\t\t\tbottom: containerDimensions.rect.bottom - containerDimensions.borders.bottom - containerDimensions.scrollbar.bottom - elementDimensions.rect.bottom,\n\t\t\tleft: elementDimensions.rect.left - ( containerDimensions.rect.left + containerDimensions.borders.left ),\n\t\t\tright: containerDimensions.rect.right - containerDimensions.borders.right - containerDimensions.scrollbar.right - elementDimensions.rect.right\n\t\t};\n\t}\n\n\tif ( !config.direction || config.direction === 'y' ) {\n\t\tif ( position.top < 0 ) {\n\t\t\tanimations.scrollTop = containerDimensions.scroll.top + position.top;\n\t\t} else if ( position.top > 0 && position.bottom < 0 ) {\n\t\t\tanimations.scrollTop = containerDimensions.scroll.top + Math.min( position.top, -position.bottom );\n\t\t}\n\t}\n\tif ( !config.direction || config.direction === 'x' ) {\n\t\tif ( position.left < 0 ) {\n\t\t\tanimations.scrollLeft = containerDimensions.scroll.left + position.left;\n\t\t} else if ( position.left > 0 && position.right < 0 ) {\n\t\t\tanimations.scrollLeft = containerDimensions.scroll.left + Math.min( position.left, -position.right );\n\t\t}\n\t}\n\tif ( !$.isEmptyObject( animations ) ) {\n\t\t// eslint-disable-next-line jquery/no-animate\n\t\t$container.stop( true ).animate( animations, config.duration === undefined ? 'fast' : config.duration );\n\t\t$container.queue( function ( next ) {\n\t\t\tdeferred.resolve();\n\t\t\tnext();\n\t\t} );\n\t} else {\n\t\tdeferred.resolve();\n\t}\n\treturn deferred.promise();\n};\n\n/**\n * Force the browser to reconsider whether it really needs to render scrollbars inside the element\n * and reserve space for them, because it probably doesn't.\n *\n * Workaround primarily for <https://code.google.com/p/chromium/issues/detail?id=387290>, but also\n * similar bugs in other browsers. \"Just\" forcing a reflow is not sufficient in all cases, we need\n * to first actually detach (or hide, but detaching is simpler) all children, *then* force a reflow,\n * and then reattach (or show) them back.\n *\n * @static\n * @param {HTMLElement} el Element to reconsider the scrollbars on\n */\nOO.ui.Element.static.reconsiderScrollbars = function ( el ) {\n\tvar i, len, scrollLeft, scrollTop, nodes = [];\n\t// Save scroll position\n\tscrollLeft = el.scrollLeft;\n\tscrollTop = el.scrollTop;\n\t// Detach all children\n\twhile ( el.firstChild ) {\n\t\tnodes.push( el.firstChild );\n\t\tel.removeChild( el.firstChild );\n\t}\n\t// Force reflow\n\t// eslint-disable-next-line no-void\n\tvoid el.offsetHeight;\n\t// Reattach all children\n\tfor ( i = 0, len = nodes.length; i < len; i++ ) {\n\t\tel.appendChild( nodes[ i ] );\n\t}\n\t// Restore scroll position (no-op if scrollbars disappeared)\n\tel.scrollLeft = scrollLeft;\n\tel.scrollTop = scrollTop;\n};\n\n/* Methods */\n\n/**\n * Toggle visibility of an element.\n *\n * @param {boolean} [show] Make element visible, omit to toggle visibility\n * @fires visible\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.toggle = function ( show ) {\n\tshow = show === undefined ? !this.visible : !!show;\n\n\tif ( show !== this.isVisible() ) {\n\t\tthis.visible = show;\n\t\tthis.$element.toggleClass( 'oo-ui-element-hidden', !this.visible );\n\t\tthis.emit( 'toggle', show );\n\t}\n\n\treturn this;\n};\n\n/**\n * Check if element is visible.\n *\n * @return {boolean} element is visible\n */\nOO.ui.Element.prototype.isVisible = function () {\n\treturn this.visible;\n};\n\n/**\n * Get element data.\n *\n * @return {Mixed} Element data\n */\nOO.ui.Element.prototype.getData = function () {\n\treturn this.data;\n};\n\n/**\n * Set element data.\n *\n * @param {Mixed} data Element data\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.setData = function ( data ) {\n\tthis.data = data;\n\treturn this;\n};\n\n/**\n * Set the element has an 'id' attribute.\n *\n * @param {string} id\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.setElementId = function ( id ) {\n\tthis.elementId = id;\n\tthis.$element.attr( 'id', id );\n\treturn this;\n};\n\n/**\n * Ensure that the element has an 'id' attribute, setting it to an unique value if it's missing,\n * and return its value.\n *\n * @return {string}\n */\nOO.ui.Element.prototype.getElementId = function () {\n\tif ( this.elementId === null ) {\n\t\tthis.setElementId( OO.ui.generateElementId() );\n\t}\n\treturn this.elementId;\n};\n\n/**\n * Check if element supports one or more methods.\n *\n * @param {string|string[]} methods Method or list of methods to check\n * @return {boolean} All methods are supported\n */\nOO.ui.Element.prototype.supports = function ( methods ) {\n\tvar i, len,\n\t\tsupport = 0;\n\n\tmethods = Array.isArray( methods ) ? methods : [ methods ];\n\tfor ( i = 0, len = methods.length; i < len; i++ ) {\n\t\tif ( typeof this[ methods[ i ] ] === 'function' ) {\n\t\t\tsupport++;\n\t\t}\n\t}\n\n\treturn methods.length === support;\n};\n\n/**\n * Update the theme-provided classes.\n *\n * @localdoc This is called in element mixins and widget classes any time state changes.\n *   Updating is debounced, minimizing overhead of changing multiple attributes and\n *   guaranteeing that theme updates do not occur within an element's constructor\n */\nOO.ui.Element.prototype.updateThemeClasses = function () {\n\tOO.ui.theme.queueUpdateElementClasses( this );\n};\n\n/**\n * Get the HTML tag name.\n *\n * Override this method to base the result on instance information.\n *\n * @return {string} HTML tag name\n */\nOO.ui.Element.prototype.getTagName = function () {\n\treturn this.constructor.static.tagName;\n};\n\n/**\n * Check if the element is attached to the DOM\n *\n * @return {boolean} The element is attached to the DOM\n */\nOO.ui.Element.prototype.isElementAttached = function () {\n\treturn $.contains( this.getElementDocument(), this.$element[ 0 ] );\n};\n\n/**\n * Get the DOM document.\n *\n * @return {HTMLDocument} Document object\n */\nOO.ui.Element.prototype.getElementDocument = function () {\n\t// Don't cache this in other ways either because subclasses could can change this.$element\n\treturn OO.ui.Element.static.getDocument( this.$element );\n};\n\n/**\n * Get the DOM window.\n *\n * @return {Window} Window object\n */\nOO.ui.Element.prototype.getElementWindow = function () {\n\treturn OO.ui.Element.static.getWindow( this.$element );\n};\n\n/**\n * Get closest scrollable container.\n *\n * @return {HTMLElement} Closest scrollable container\n */\nOO.ui.Element.prototype.getClosestScrollableElementContainer = function () {\n\treturn OO.ui.Element.static.getClosestScrollableContainer( this.$element[ 0 ] );\n};\n\n/**\n * Get group element is in.\n *\n * @return {OO.ui.mixin.GroupElement|null} Group element, null if none\n */\nOO.ui.Element.prototype.getElementGroup = function () {\n\treturn this.elementGroup;\n};\n\n/**\n * Set group element is in.\n *\n * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.setElementGroup = function ( group ) {\n\tthis.elementGroup = group;\n\treturn this;\n};\n\n/**\n * Scroll element into view.\n *\n * @param {Object} [config] Configuration options\n * @return {jQuery.Promise} Promise which resolves when the scroll is complete\n */\nOO.ui.Element.prototype.scrollElementIntoView = function ( config ) {\n\tif (\n\t\t!this.isElementAttached() ||\n\t\t!this.isVisible() ||\n\t\t( this.getElementGroup() && !this.getElementGroup().isVisible() )\n\t) {\n\t\treturn $.Deferred().resolve();\n\t}\n\treturn OO.ui.Element.static.scrollIntoView( this.$element[ 0 ], config );\n};\n\n/**\n * Restore the pre-infusion dynamic state for this widget.\n *\n * This method is called after #$element has been inserted into DOM. The parameter is the return\n * value of #gatherPreInfuseState.\n *\n * @protected\n * @param {Object} state\n */\nOO.ui.Element.prototype.restorePreInfuseState = function () {\n};\n","/**\n * Wraps an HTML snippet for use with configuration values which default\n * to strings.  This bypasses the default html-escaping done to string\n * values.\n *\n * @class\n *\n * @constructor\n * @param {string} [content] HTML content\n */\nOO.ui.HtmlSnippet = function OoUiHtmlSnippet( content ) {\n\t// Properties\n\tthis.content = content;\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.HtmlSnippet );\n\n/* Methods */\n\n/**\n * Render into HTML.\n *\n * @return {string} Unchanged HTML snippet.\n */\nOO.ui.HtmlSnippet.prototype.toString = function () {\n\treturn this.content;\n};\n","/**\n * Layouts are containers for elements and are used to arrange other widgets of arbitrary type in a way\n * that is centrally controlled and can be updated dynamically. Layouts can be, and usually are, combined.\n * See {@link OO.ui.FieldsetLayout FieldsetLayout}, {@link OO.ui.FieldLayout FieldLayout}, {@link OO.ui.FormLayout FormLayout},\n * {@link OO.ui.PanelLayout PanelLayout}, {@link OO.ui.StackLayout StackLayout}, {@link OO.ui.PageLayout PageLayout},\n * {@link OO.ui.HorizontalLayout HorizontalLayout}, and {@link OO.ui.BookletLayout BookletLayout} for more information and examples.\n *\n * @abstract\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.Layout = function OoUiLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Layout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-layout' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Layout, OO.ui.Element );\nOO.mixinClass( OO.ui.Layout, OO.EventEmitter );\n\n/* Methods */\n\n/**\n * Reset scroll offsets\n *\n * @chainable\n * @return {OO.ui.Layout} The layout, for chaining\n */\nOO.ui.Layout.prototype.resetScroll = function () {\n\tthis.$element[ 0 ].scrollTop = 0;\n\t// TODO: Reset scrollLeft in an RTL-aware manner, see OO.ui.Element.static.getScrollLeft.\n\n\treturn this;\n};\n","/**\n * Widgets are compositions of one or more OOUI elements that users can both view\n * and interact with. All widgets can be configured and modified via a standard API,\n * and their state can change dynamically according to a model.\n *\n * @abstract\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [disabled=false] Disable the widget. Disabled widgets cannot be used and their\n *  appearance reflects this state.\n */\nOO.ui.Widget = function OoUiWidget( config ) {\n\t// Initialize config\n\tconfig = $.extend( { disabled: false }, config );\n\n\t// Parent constructor\n\tOO.ui.Widget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.disabled = null;\n\tthis.wasDisabled = null;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-widget' );\n\tthis.setDisabled( !!config.disabled );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Widget, OO.ui.Element );\nOO.mixinClass( OO.ui.Widget, OO.EventEmitter );\n\n/* Events */\n\n/**\n * @event disable\n *\n * A 'disable' event is emitted when the disabled state of the widget changes\n * (i.e. on disable **and** enable).\n *\n * @param {boolean} disabled Widget is disabled\n */\n\n/**\n * @event toggle\n *\n * A 'toggle' event is emitted when the visibility of the widget changes.\n *\n * @param {boolean} visible Widget is visible\n */\n\n/* Methods */\n\n/**\n * Check if the widget is disabled.\n *\n * @return {boolean} Widget is disabled\n */\nOO.ui.Widget.prototype.isDisabled = function () {\n\treturn this.disabled;\n};\n\n/**\n * Set the 'disabled' state of the widget.\n *\n * When a widget is disabled, it cannot be used and its appearance is updated to reflect this state.\n *\n * @param {boolean} disabled Disable widget\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.Widget.prototype.setDisabled = function ( disabled ) {\n\tvar isDisabled;\n\n\tthis.disabled = !!disabled;\n\tisDisabled = this.isDisabled();\n\tif ( isDisabled !== this.wasDisabled ) {\n\t\tthis.$element.toggleClass( 'oo-ui-widget-disabled', isDisabled );\n\t\tthis.$element.toggleClass( 'oo-ui-widget-enabled', !isDisabled );\n\t\tthis.$element.attr( 'aria-disabled', isDisabled.toString() );\n\t\tthis.emit( 'disable', isDisabled );\n\t\tthis.updateThemeClasses();\n\t}\n\tthis.wasDisabled = isDisabled;\n\n\treturn this;\n};\n\n/**\n * Update the disabled state, in case of changes in parent widget.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.Widget.prototype.updateDisabled = function () {\n\tthis.setDisabled( this.disabled );\n\treturn this;\n};\n\n/**\n * Get an ID of a labelable node which is part of this widget, if any, to be used for `<label for>`\n * value.\n *\n * If this function returns null, the widget should have a meaningful #simulateLabelClick method\n * instead.\n *\n * @return {string|null} The ID of the labelable element\n */\nOO.ui.Widget.prototype.getInputId = function () {\n\treturn null;\n};\n\n/**\n * Simulate the behavior of clicking on a label (a HTML `<label>` element) bound to this input.\n * HTML only allows `<label>` to act on specific \"labelable\" elements; complex widgets might need to\n * override this method to provide intuitive, accessible behavior.\n *\n * By default, this does nothing. OO.ui.mixin.TabIndexedElement overrides it for focusable widgets.\n * Individual widgets may override it too.\n *\n * This method is called by OO.ui.LabelWidget and OO.ui.FieldLayout. It should not be called\n * directly.\n */\nOO.ui.Widget.prototype.simulateLabelClick = function () {\n};\n","/**\n * Theme logic.\n *\n * @abstract\n * @class\n *\n * @constructor\n */\nOO.ui.Theme = function OoUiTheme() {\n\tthis.elementClassesQueue = [];\n\tthis.debouncedUpdateQueuedElementClasses = OO.ui.debounce( this.updateQueuedElementClasses );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Theme );\n\n/* Methods */\n\n/**\n * Get a list of classes to be applied to a widget.\n *\n * The 'on' and 'off' lists combined MUST contain keys for all classes the theme adds or removes,\n * otherwise state transitions will not work properly.\n *\n * @param {OO.ui.Element} element Element for which to get classes\n * @return {Object.<string,string[]>} Categorized class names with `on` and `off` lists\n */\nOO.ui.Theme.prototype.getElementClasses = function () {\n\treturn { on: [], off: [] };\n};\n\n/**\n * Update CSS classes provided by the theme.\n *\n * For elements with theme logic hooks, this should be called any time there's a state change.\n *\n * @param {OO.ui.Element} element Element for which to update classes\n */\nOO.ui.Theme.prototype.updateElementClasses = function ( element ) {\n\tvar $elements = $( [] ),\n\t\tclasses = this.getElementClasses( element );\n\n\tif ( element.$icon ) {\n\t\t$elements = $elements.add( element.$icon );\n\t}\n\tif ( element.$indicator ) {\n\t\t$elements = $elements.add( element.$indicator );\n\t}\n\n\t$elements\n\t\t.removeClass( classes.off )\n\t\t.addClass( classes.on );\n};\n\n/**\n * @private\n */\nOO.ui.Theme.prototype.updateQueuedElementClasses = function () {\n\tvar i;\n\tfor ( i = 0; i < this.elementClassesQueue.length; i++ ) {\n\t\tthis.updateElementClasses( this.elementClassesQueue[ i ] );\n\t}\n\t// Clear the queue\n\tthis.elementClassesQueue = [];\n};\n\n/**\n * Queue #updateElementClasses to be called for this element.\n *\n * @localdoc QUnit tests override this method to directly call #queueUpdateElementClasses,\n *   to make them synchronous.\n *\n * @param {OO.ui.Element} element Element for which to update classes\n */\nOO.ui.Theme.prototype.queueUpdateElementClasses = function ( element ) {\n\t// Keep items in the queue unique. Use lastIndexOf to start checking from the end because that's\n\t// the most common case (this method is often called repeatedly for the same element).\n\tif ( this.elementClassesQueue.lastIndexOf( element ) !== -1 ) {\n\t\treturn;\n\t}\n\tthis.elementClassesQueue.push( element );\n\tthis.debouncedUpdateQueuedElementClasses();\n};\n\n/**\n * Get the transition duration in milliseconds for dialogs opening/closing\n *\n * The dialog should be fully rendered this many milliseconds after the\n * ready process has executed.\n *\n * @return {number} Transition duration in milliseconds\n */\nOO.ui.Theme.prototype.getDialogTransitionDuration = function () {\n\treturn 0;\n};\n","/**\n * The TabIndexedElement class is an attribute mixin used to add additional functionality to an\n * element created by another class. The mixin provides a ‘tabIndex’ property, which specifies the\n * order in which users will navigate through the focusable elements via the “tab” key.\n *\n *     @example\n *     // TabIndexedElement is mixed into the ButtonWidget class\n *     // to provide a tabIndex property.\n *     var button1 = new OO.ui.ButtonWidget( {\n *             label: 'fourth',\n *             tabIndex: 4\n *         } ),\n *         button2 = new OO.ui.ButtonWidget( {\n *             label: 'second',\n *             tabIndex: 2\n *         } ),\n *         button3 = new OO.ui.ButtonWidget( {\n *             label: 'third',\n *             tabIndex: 3\n *         } ),\n *         button4 = new OO.ui.ButtonWidget( {\n *             label: 'first',\n *             tabIndex: 1\n *         } );\n *     $( document.body ).append( button1.$element, button2.$element, button3.$element, button4.$element );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$tabIndexed] The element that should use the tabindex functionality. By default,\n *  the functionality is applied to the element created by the class ($element). If a different element is specified, the tabindex\n *  functionality will be applied to it instead.\n * @cfg {string|number|null} [tabIndex=0] Number that specifies the element’s position in the tab-navigation\n *  order (e.g., 1 for the first focusable element). Use 0 to use the default navigation order; use -1\n *  to remove the element from the tab-navigation flow.\n */\nOO.ui.mixin.TabIndexedElement = function OoUiMixinTabIndexedElement( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { tabIndex: 0 }, config );\n\n\t// Properties\n\tthis.$tabIndexed = null;\n\tthis.tabIndex = null;\n\n\t// Events\n\tthis.connect( this, { disable: 'onTabIndexedElementDisable' } );\n\n\t// Initialization\n\tthis.setTabIndex( config.tabIndex );\n\tthis.setTabIndexedElement( config.$tabIndexed || this.$element );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Set the element that should use the tabindex functionality.\n *\n * This method is used to retarget a tabindex mixin so that its functionality applies\n * to the specified element. If an element is currently using the functionality, the mixin’s\n * effect on that element is removed before the new element is set up.\n *\n * @param {jQuery} $tabIndexed Element that should use the tabindex functionality\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.setTabIndexedElement = function ( $tabIndexed ) {\n\tvar tabIndex = this.tabIndex;\n\t// Remove attributes from old $tabIndexed\n\tthis.setTabIndex( null );\n\t// Force update of new $tabIndexed\n\tthis.$tabIndexed = $tabIndexed;\n\tthis.tabIndex = tabIndex;\n\treturn this.updateTabIndex();\n};\n\n/**\n * Set the value of the tabindex.\n *\n * @param {string|number|null} tabIndex Tabindex value, or `null` for no tabindex\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.setTabIndex = function ( tabIndex ) {\n\ttabIndex = /^-?\\d+$/.test( tabIndex ) ? Number( tabIndex ) : null;\n\n\tif ( this.tabIndex !== tabIndex ) {\n\t\tthis.tabIndex = tabIndex;\n\t\tthis.updateTabIndex();\n\t}\n\n\treturn this;\n};\n\n/**\n * Update the `tabindex` attribute, in case of changes to tab index or\n * disabled state.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.updateTabIndex = function () {\n\tif ( this.$tabIndexed ) {\n\t\tif ( this.tabIndex !== null ) {\n\t\t\t// Do not index over disabled elements\n\t\t\tthis.$tabIndexed.attr( {\n\t\t\t\ttabindex: this.isDisabled() ? -1 : this.tabIndex,\n\t\t\t\t// Support: ChromeVox and NVDA\n\t\t\t\t// These do not seem to inherit aria-disabled from parent elements\n\t\t\t\t'aria-disabled': this.isDisabled().toString()\n\t\t\t} );\n\t\t} else {\n\t\t\tthis.$tabIndexed.removeAttr( 'tabindex aria-disabled' );\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Handle disable events.\n *\n * @private\n * @param {boolean} disabled Element is disabled\n */\nOO.ui.mixin.TabIndexedElement.prototype.onTabIndexedElementDisable = function () {\n\tthis.updateTabIndex();\n};\n\n/**\n * Get the value of the tabindex.\n *\n * @return {number|null} Tabindex value\n */\nOO.ui.mixin.TabIndexedElement.prototype.getTabIndex = function () {\n\treturn this.tabIndex;\n};\n\n/**\n * Get an ID of a focusable element of this widget, if any, to be used for `<label for>` value.\n *\n * If the element already has an ID then that is returned, otherwise unique ID is\n * generated, set on the element, and returned.\n *\n * @return {string|null} The ID of the focusable element\n */\nOO.ui.mixin.TabIndexedElement.prototype.getInputId = function () {\n\tvar id;\n\n\tif ( !this.$tabIndexed ) {\n\t\treturn null;\n\t}\n\tif ( !this.isLabelableNode( this.$tabIndexed ) ) {\n\t\treturn null;\n\t}\n\n\tid = this.$tabIndexed.attr( 'id' );\n\tif ( id === undefined ) {\n\t\tid = OO.ui.generateElementId();\n\t\tthis.$tabIndexed.attr( 'id', id );\n\t}\n\n\treturn id;\n};\n\n/**\n * Whether the node is 'labelable' according to the HTML spec\n * (i.e., whether it can be interacted with through a `<label for=\"…\">`).\n * See: <https://html.spec.whatwg.org/multipage/forms.html#category-label>.\n *\n * @private\n * @param {jQuery} $node\n * @return {boolean}\n */\nOO.ui.mixin.TabIndexedElement.prototype.isLabelableNode = function ( $node ) {\n\tvar\n\t\tlabelableTags = [ 'button', 'meter', 'output', 'progress', 'select', 'textarea' ],\n\t\ttagName = $node.prop( 'tagName' ).toLowerCase();\n\n\tif ( tagName === 'input' && $node.attr( 'type' ) !== 'hidden' ) {\n\t\treturn true;\n\t}\n\tif ( labelableTags.indexOf( tagName ) !== -1 ) {\n\t\treturn true;\n\t}\n\treturn false;\n};\n\n/**\n * Focus this element.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$tabIndexed.trigger( 'focus' );\n\t}\n\treturn this;\n};\n\n/**\n * Blur this element.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.blur = function () {\n\tthis.$tabIndexed.trigger( 'blur' );\n\treturn this;\n};\n\n/**\n * @inheritdoc OO.ui.Widget\n */\nOO.ui.mixin.TabIndexedElement.prototype.simulateLabelClick = function () {\n\tthis.focus();\n};\n","/**\n * ButtonElement is often mixed into other classes to generate a button, which is a clickable\n * interface element that can be configured with access keys for keyboard interaction.\n * See the [OOUI documentation on MediaWiki] [1] for examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches#Buttons\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$button] The button element created by the class.\n *  If this configuration is omitted, the button element will use a generated `<a>`.\n * @cfg {boolean} [framed=true] Render the button with a frame\n */\nOO.ui.mixin.ButtonElement = function OoUiMixinButtonElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$button = null;\n\tthis.framed = null;\n\tthis.active = config.active !== undefined && config.active;\n\tthis.onDocumentMouseUpHandler = this.onDocumentMouseUp.bind( this );\n\tthis.onMouseDownHandler = this.onMouseDown.bind( this );\n\tthis.onDocumentKeyUpHandler = this.onDocumentKeyUp.bind( this );\n\tthis.onKeyDownHandler = this.onKeyDown.bind( this );\n\tthis.onClickHandler = this.onClick.bind( this );\n\tthis.onKeyPressHandler = this.onKeyPress.bind( this );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonElement' );\n\tthis.toggleFramed( config.framed === undefined || config.framed );\n\tthis.setButtonElement( config.$button || $( '<a>' ) );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.ButtonElement );\n\n/* Static Properties */\n\n/**\n * Cancel mouse down events.\n *\n * This property is usually set to `true` to prevent the focus from changing when the button is clicked.\n * Classes such as {@link OO.ui.mixin.DraggableElement DraggableElement} and {@link OO.ui.ButtonOptionWidget ButtonOptionWidget}\n * use a value of `false` so that dragging behavior is possible and mousedown events can be handled by a\n * parent widget.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.mixin.ButtonElement.static.cancelButtonMouseDownEvents = true;\n\n/* Events */\n\n/**\n * A 'click' event is emitted when the button element is clicked.\n *\n * @event click\n */\n\n/* Methods */\n\n/**\n * Set the button element.\n *\n * This method is used to retarget a button mixin so that its functionality applies to\n * the specified button element instead of the one created by the class. If a button element\n * is already set, the method will remove the mixin’s effect on that element.\n *\n * @param {jQuery} $button Element to use as button\n */\nOO.ui.mixin.ButtonElement.prototype.setButtonElement = function ( $button ) {\n\tif ( this.$button ) {\n\t\tthis.$button\n\t\t\t.removeClass( 'oo-ui-buttonElement-button' )\n\t\t\t.removeAttr( 'role accesskey' )\n\t\t\t.off( {\n\t\t\t\tmousedown: this.onMouseDownHandler,\n\t\t\t\tkeydown: this.onKeyDownHandler,\n\t\t\t\tclick: this.onClickHandler,\n\t\t\t\tkeypress: this.onKeyPressHandler\n\t\t\t} );\n\t}\n\n\tthis.$button = $button\n\t\t.addClass( 'oo-ui-buttonElement-button' )\n\t\t.on( {\n\t\t\tmousedown: this.onMouseDownHandler,\n\t\t\tkeydown: this.onKeyDownHandler,\n\t\t\tclick: this.onClickHandler,\n\t\t\tkeypress: this.onKeyPressHandler\n\t\t} );\n\n\t// Add `role=\"button\"` on `<a>` elements, where it's needed\n\t// `toUpperCase()` is added for XHTML documents\n\tif ( this.$button.prop( 'tagName' ).toUpperCase() === 'A' ) {\n\t\tthis.$button.attr( 'role', 'button' );\n\t}\n};\n\n/**\n * Handles mouse down events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.mixin.ButtonElement.prototype.onMouseDown = function ( e ) {\n\tif ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {\n\t\treturn;\n\t}\n\tthis.$element.addClass( 'oo-ui-buttonElement-pressed' );\n\t// Run the mouseup handler no matter where the mouse is when the button is let go, so we can\n\t// reliably remove the pressed class\n\tthis.getElementDocument().addEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n\t// Prevent change of focus unless specifically configured otherwise\n\tif ( this.constructor.static.cancelButtonMouseDownEvents ) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Handles document mouse up events.\n *\n * @protected\n * @param {MouseEvent} e Mouse up event\n */\nOO.ui.mixin.ButtonElement.prototype.onDocumentMouseUp = function ( e ) {\n\tif ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {\n\t\treturn;\n\t}\n\tthis.$element.removeClass( 'oo-ui-buttonElement-pressed' );\n\t// Stop listening for mouseup, since we only needed this once\n\tthis.getElementDocument().removeEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.mixin.ButtonElement.prototype.onMouseUp = function () {\n\tOO.ui.warnDeprecation( 'onMouseUp is deprecated, use onDocumentMouseUp instead' );\n\tthis.onDocumentMouseUp.apply( this, arguments );\n};\n\n/**\n * Handles mouse click events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse click event\n * @fires click\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.mixin.ButtonElement.prototype.onClick = function ( e ) {\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tif ( this.emit( 'click' ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Handles key down events.\n *\n * @protected\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.mixin.ButtonElement.prototype.onKeyDown = function ( e ) {\n\tif ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {\n\t\treturn;\n\t}\n\tthis.$element.addClass( 'oo-ui-buttonElement-pressed' );\n\t// Run the keyup handler no matter where the key is when the button is let go, so we can\n\t// reliably remove the pressed class\n\tthis.getElementDocument().addEventListener( 'keyup', this.onDocumentKeyUpHandler, true );\n};\n\n/**\n * Handles document key up events.\n *\n * @protected\n * @param {KeyboardEvent} e Key up event\n */\nOO.ui.mixin.ButtonElement.prototype.onDocumentKeyUp = function ( e ) {\n\tif ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {\n\t\treturn;\n\t}\n\tthis.$element.removeClass( 'oo-ui-buttonElement-pressed' );\n\t// Stop listening for keyup, since we only needed this once\n\tthis.getElementDocument().removeEventListener( 'keyup', this.onDocumentKeyUpHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.mixin.ButtonElement.prototype.onKeyUp = function () {\n\tOO.ui.warnDeprecation( 'onKeyUp is deprecated, use onDocumentKeyUp instead' );\n\tthis.onDocumentKeyUp.apply( this, arguments );\n};\n\n/**\n * Handles key press events.\n *\n * @protected\n * @param {jQuery.Event} e Key press event\n * @fires click\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.mixin.ButtonElement.prototype.onKeyPress = function ( e ) {\n\tif ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {\n\t\tif ( this.emit( 'click' ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Check if button has a frame.\n *\n * @return {boolean} Button is framed\n */\nOO.ui.mixin.ButtonElement.prototype.isFramed = function () {\n\treturn this.framed;\n};\n\n/**\n * Render the button with or without a frame. Omit the `framed` parameter to toggle the button frame on and off.\n *\n * @param {boolean} [framed] Make button framed, omit to toggle\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ButtonElement.prototype.toggleFramed = function ( framed ) {\n\tframed = framed === undefined ? !this.framed : !!framed;\n\tif ( framed !== this.framed ) {\n\t\tthis.framed = framed;\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-buttonElement-frameless', !framed )\n\t\t\t.toggleClass( 'oo-ui-buttonElement-framed', framed );\n\t\tthis.updateThemeClasses();\n\t}\n\n\treturn this;\n};\n\n/**\n * Set the button's active state.\n *\n * The active state can be set on:\n *\n *  - {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} when it is selected\n *  - {@link OO.ui.ToggleButtonWidget ToggleButtonWidget} when it is toggle on\n *  - {@link OO.ui.ButtonWidget ButtonWidget} when clicking the button would only refresh the page\n *\n * @protected\n * @param {boolean} value Make button active\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ButtonElement.prototype.setActive = function ( value ) {\n\tthis.active = !!value;\n\tthis.$element.toggleClass( 'oo-ui-buttonElement-active', this.active );\n\tthis.updateThemeClasses();\n\treturn this;\n};\n\n/**\n * Check if the button is active\n *\n * @protected\n * @return {boolean} The button is active\n */\nOO.ui.mixin.ButtonElement.prototype.isActive = function () {\n\treturn this.active;\n};\n","/**\n * Any OOUI widget that contains other widgets (such as {@link OO.ui.ButtonWidget buttons} or\n * {@link OO.ui.OptionWidget options}) mixes in GroupElement. Adding, removing, and clearing\n * items from the group is done through the interface the class provides.\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Elements/Groups\n *\n * @abstract\n * @mixins OO.EmitterList\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$group] The container element created by the class. If this configuration\n *  is omitted, the group element will use a generated `<div>`.\n */\nOO.ui.mixin.GroupElement = function OoUiMixinGroupElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Mixin constructors\n\tOO.EmitterList.call( this, config );\n\n\t// Properties\n\tthis.$group = null;\n\n\t// Initialization\n\tthis.setGroupElement( config.$group || $( '<div>' ) );\n};\n\n/* Setup */\n\nOO.mixinClass( OO.ui.mixin.GroupElement, OO.EmitterList );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the set of selected items changes.\n *\n * @param {OO.ui.Element[]} items Items currently in the group\n */\n\n/* Methods */\n\n/**\n * Set the group element.\n *\n * If an element is already set, items will be moved to the new element.\n *\n * @param {jQuery} $group Element to use as group\n */\nOO.ui.mixin.GroupElement.prototype.setGroupElement = function ( $group ) {\n\tvar i, len;\n\n\tthis.$group = $group;\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tthis.$group.append( this.items[ i ].$element );\n\t}\n};\n\n/**\n * Find an item by its data.\n *\n * Only the first item with matching data will be returned. To return all matching items,\n * use the #findItemsFromData method.\n *\n * @param {Object} data Item data to search for\n * @return {OO.ui.Element|null} Item with equivalent data, `null` if none exists\n */\nOO.ui.mixin.GroupElement.prototype.findItemFromData = function ( data ) {\n\tvar i, len, item,\n\t\thash = OO.getHash( data );\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\titem = this.items[ i ];\n\t\tif ( hash === OO.getHash( item.getData() ) ) {\n\t\t\treturn item;\n\t\t}\n\t}\n\n\treturn null;\n};\n\n/**\n * Find items by their data.\n *\n * All items with matching data will be returned. To return only the first match, use the #findItemFromData method instead.\n *\n * @param {Object} data Item data to search for\n * @return {OO.ui.Element[]} Items with equivalent data\n */\nOO.ui.mixin.GroupElement.prototype.findItemsFromData = function ( data ) {\n\tvar i, len, item,\n\t\thash = OO.getHash( data ),\n\t\titems = [];\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\titem = this.items[ i ];\n\t\tif ( hash === OO.getHash( item.getData() ) ) {\n\t\t\titems.push( item );\n\t\t}\n\t}\n\n\treturn items;\n};\n\n/**\n * Add items to the group.\n *\n * Items will be added to the end of the group array unless the optional `index` parameter specifies\n * a different insertion point. Adding an existing item will move it to the end of the array or the point specified by the `index`.\n *\n * @param {OO.ui.Element[]} items An array of items to add to the group\n * @param {number} [index] Index of the insertion point\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {\n\n\tif ( items.length === 0 ) {\n\t\treturn this;\n\t}\n\n\t// Mixin method\n\tOO.EmitterList.prototype.addItems.call( this, items, index );\n\n\tthis.emit( 'change', this.getItems() );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.mixin.GroupElement.prototype.moveItem = function ( items, newIndex ) {\n\t// insertItemElements expects this.items to not have been modified yet, so call before the mixin\n\tthis.insertItemElements( items, newIndex );\n\n\t// Mixin method\n\tnewIndex = OO.EmitterList.prototype.moveItem.call( this, items, newIndex );\n\n\treturn newIndex;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.mixin.GroupElement.prototype.insertItem = function ( item, index ) {\n\titem.setElementGroup( this );\n\tthis.insertItemElements( item, index );\n\n\t// Mixin method\n\tindex = OO.EmitterList.prototype.insertItem.call( this, item, index );\n\n\treturn index;\n};\n\n/**\n * Insert elements into the group\n *\n * @private\n * @param {OO.ui.Element} itemWidget Item to insert\n * @param {number} index Insertion index\n */\nOO.ui.mixin.GroupElement.prototype.insertItemElements = function ( itemWidget, index ) {\n\tif ( index === undefined || index < 0 || index >= this.items.length ) {\n\t\tthis.$group.append( itemWidget.$element );\n\t} else if ( index === 0 ) {\n\t\tthis.$group.prepend( itemWidget.$element );\n\t} else {\n\t\tthis.items[ index ].$element.before( itemWidget.$element );\n\t}\n};\n\n/**\n * Remove the specified items from a group.\n *\n * Removed items are detached (not removed) from the DOM so that they may be reused.\n * To remove all items from a group, you may wish to use the #clearItems method instead.\n *\n * @param {OO.ui.Element[]} items An array of items to remove\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {\n\tvar i, len, item, index;\n\n\tif ( items.length === 0 ) {\n\t\treturn this;\n\t}\n\n\t// Remove specific items elements\n\tfor ( i = 0, len = items.length; i < len; i++ ) {\n\t\titem = items[ i ];\n\t\tindex = this.items.indexOf( item );\n\t\tif ( index !== -1 ) {\n\t\t\titem.setElementGroup( null );\n\t\t\titem.$element.detach();\n\t\t}\n\t}\n\n\t// Mixin method\n\tOO.EmitterList.prototype.removeItems.call( this, items );\n\n\tthis.emit( 'change', this.getItems() );\n\treturn this;\n};\n\n/**\n * Clear all items from the group.\n *\n * Cleared items are detached from the DOM, not removed, so that they may be reused.\n * To remove only a subset of items from a group, use the #removeItems method.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.GroupElement.prototype.clearItems = function () {\n\tvar i, len;\n\n\t// Remove all item elements\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tthis.items[ i ].setElementGroup( null );\n\t\tthis.items[ i ].$element.detach();\n\t}\n\n\t// Mixin method\n\tOO.EmitterList.prototype.clearItems.call( this );\n\n\tthis.emit( 'change', this.getItems() );\n\treturn this;\n};\n","/**\n * LabelElement is often mixed into other classes to generate a label, which\n * helps identify the function of an interface element.\n * See the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Labels\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$label] The label element created by the class. If this\n *  configuration is omitted, the label element will use a generated `<span>`.\n * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be specified\n *  as a plaintext string, a jQuery selection of elements, or a function that will produce a string\n *  in the future. See the [OOUI documentation on MediaWiki] [2] for examples.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Labels\n * @cfg {boolean} [invisibleLabel] Whether the label should be visually hidden (but still accessible\n *  to screen-readers).\n */\nOO.ui.mixin.LabelElement = function OoUiMixinLabelElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$label = null;\n\tthis.label = null;\n\tthis.invisibleLabel = null;\n\n\t// Initialization\n\tthis.setLabel( config.label || this.constructor.static.label );\n\tthis.setLabelElement( config.$label || $( '<span>' ) );\n\tthis.setInvisibleLabel( config.invisibleLabel );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.LabelElement );\n\n/* Events */\n\n/**\n * @event labelChange\n * @param {string} value\n */\n\n/* Static Properties */\n\n/**\n * The label text. The label can be specified as a plaintext string, a function that will\n * produce a string in the future, or `null` for no label. The static value will\n * be overridden if a label is specified with the #label config option.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.LabelElement.static.label = null;\n\n/* Static methods */\n\n/**\n * Highlight the first occurrence of the query in the given text\n *\n * @param {string} text Text\n * @param {string} query Query to find\n * @param {Function} [compare] Optional string comparator, e.g. Intl.Collator().compare\n * @return {jQuery} Text with the first match of the query\n *  sub-string wrapped in highlighted span\n */\nOO.ui.mixin.LabelElement.static.highlightQuery = function ( text, query, compare ) {\n\tvar i, tLen, qLen,\n\t\toffset = -1,\n\t\t$result = $( '<span>' );\n\n\tif ( compare ) {\n\t\ttLen = text.length;\n\t\tqLen = query.length;\n\t\tfor ( i = 0; offset === -1 && i <= tLen - qLen; i++ ) {\n\t\t\tif ( compare( query, text.slice( i, i + qLen ) ) === 0 ) {\n\t\t\t\toffset = i;\n\t\t\t}\n\t\t}\n\t} else {\n\t\toffset = text.toLowerCase().indexOf( query.toLowerCase() );\n\t}\n\n\tif ( !query.length || offset === -1 ) {\n\t\t$result.text( text );\n\t} else {\n\t\t$result.append(\n\t\t\tdocument.createTextNode( text.slice( 0, offset ) ),\n\t\t\t$( '<span>' )\n\t\t\t\t.addClass( 'oo-ui-labelElement-label-highlight' )\n\t\t\t\t.text( text.slice( offset, offset + query.length ) ),\n\t\t\tdocument.createTextNode( text.slice( offset + query.length ) )\n\t\t);\n\t}\n\treturn $result.contents();\n};\n\n/* Methods */\n\n/**\n * Set the label element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $label Element to use as label\n */\nOO.ui.mixin.LabelElement.prototype.setLabelElement = function ( $label ) {\n\tif ( this.$label ) {\n\t\tthis.$label.removeClass( 'oo-ui-labelElement-label' ).empty();\n\t}\n\n\tthis.$label = $label.addClass( 'oo-ui-labelElement-label' );\n\tthis.setLabelContent( this.label );\n};\n\n/**\n * Set the label.\n *\n * An empty string will result in the label being hidden. A string containing only whitespace will\n * be converted to a single `&nbsp;`.\n *\n * @param {jQuery|string|OO.ui.HtmlSnippet|Function|null} label Label nodes; text; a function that returns nodes or\n *  text; or null for no label\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LabelElement.prototype.setLabel = function ( label ) {\n\tlabel = typeof label === 'function' ? OO.ui.resolveMsg( label ) : label;\n\tlabel = ( ( typeof label === 'string' || label instanceof $ ) && label.length ) || ( label instanceof OO.ui.HtmlSnippet && label.toString().length ) ? label : null;\n\n\tif ( this.label !== label ) {\n\t\tif ( this.$label ) {\n\t\t\tthis.setLabelContent( label );\n\t\t}\n\t\tthis.label = label;\n\t\tthis.emit( 'labelChange' );\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-labelElement', !!this.label && !this.invisibleLabel );\n\n\treturn this;\n};\n\n/**\n * Set whether the label should be visually hidden (but still accessible to screen-readers).\n *\n * @param {boolean} invisibleLabel\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LabelElement.prototype.setInvisibleLabel = function ( invisibleLabel ) {\n\tinvisibleLabel = !!invisibleLabel;\n\n\tif ( this.invisibleLabel !== invisibleLabel ) {\n\t\tthis.invisibleLabel = invisibleLabel;\n\t\tthis.emit( 'labelChange' );\n\t}\n\n\tthis.$label.toggleClass( 'oo-ui-labelElement-invisible', this.invisibleLabel );\n\t// Pretend that there is no label, a lot of CSS has been written with this assumption\n\tthis.$element.toggleClass( 'oo-ui-labelElement', !!this.label && !this.invisibleLabel );\n\n\treturn this;\n};\n\n/**\n * Set the label as plain text with a highlighted query\n *\n * @param {string} text Text label to set\n * @param {string} query Substring of text to highlight\n * @param {Function} [compare] Optional string comparator, e.g. Intl.Collator().compare\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LabelElement.prototype.setHighlightedQuery = function ( text, query, compare ) {\n\treturn this.setLabel( this.constructor.static.highlightQuery( text, query, compare ) );\n};\n\n/**\n * Get the label.\n *\n * @return {jQuery|string|Function|null} Label nodes; text; a function that returns nodes or\n *  text; or null for no label\n */\nOO.ui.mixin.LabelElement.prototype.getLabel = function () {\n\treturn this.label;\n};\n\n/**\n * Set the content of the label.\n *\n * Do not call this method until after the label element has been set by #setLabelElement.\n *\n * @private\n * @param {jQuery|string|Function|null} label Label nodes; text; a function that returns nodes or\n *  text; or null for no label\n */\nOO.ui.mixin.LabelElement.prototype.setLabelContent = function ( label ) {\n\tif ( typeof label === 'string' ) {\n\t\tif ( label.match( /^\\s*$/ ) ) {\n\t\t\t// Convert whitespace only string to a single non-breaking space\n\t\t\tthis.$label.html( '&nbsp;' );\n\t\t} else {\n\t\t\tthis.$label.text( label );\n\t\t}\n\t} else if ( label instanceof OO.ui.HtmlSnippet ) {\n\t\tthis.$label.html( label.toString() );\n\t} else if ( label instanceof $ ) {\n\t\tthis.$label.empty().append( label );\n\t} else {\n\t\tthis.$label.empty();\n\t}\n};\n","/**\n * IconElement is often mixed into other classes to generate an icon.\n * Icons are graphics, about the size of normal text. They are used to aid the user\n * in locating a control or to convey information in a space-efficient way. See the\n * [OOUI documentation on MediaWiki] [1] for a list of icons\n * included in the library.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Icons\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$icon] The icon element created by the class. If this configuration is omitted,\n *  the icon element will use a generated `<span>`. To use a different HTML tag, or to specify that\n *  the icon element be set to an existing icon instead of the one generated by this class, set a\n *  value using a jQuery selection. For example:\n *\n *      // Use a <div> tag instead of a <span>\n *     $icon: $( '<div>' )\n *     // Use an existing icon element instead of the one generated by the class\n *     $icon: this.$element\n *     // Use an icon element from a child widget\n *     $icon: this.childwidget.$element\n * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of\n *  symbolic names.  A map is used for i18n purposes and contains a `default` icon\n *  name and additional names keyed by language code. The `default` name is used when no icon is keyed\n *  by the user's language.\n *\n *  Example of an i18n map:\n *\n *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }\n *  See the [OOUI documentation on MediaWiki] [2] for a list of icons included in the library.\n * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Icons\n * @cfg {string|Function} [iconTitle] A text string used as the icon title, or a function that returns title\n *  text. The icon title is displayed when users move the mouse over the icon.\n */\nOO.ui.mixin.IconElement = function OoUiMixinIconElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$icon = null;\n\tthis.icon = null;\n\tthis.iconTitle = null;\n\n\t// `iconTitle`s are deprecated since 0.30.0\n\tif ( config.iconTitle !== undefined ) {\n\t\tOO.ui.warnDeprecation( 'IconElement: Widgets with iconTitle set are deprecated, use title instead. See T76638 for details.' );\n\t}\n\n\t// Initialization\n\tthis.setIcon( config.icon || this.constructor.static.icon );\n\tthis.setIconTitle( config.iconTitle || this.constructor.static.iconTitle );\n\tthis.setIconElement( config.$icon || $( '<span>' ) );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.IconElement );\n\n/* Static Properties */\n\n/**\n * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map is used\n * for i18n purposes and contains a `default` icon name and additional names keyed by\n * language code. The `default` name is used when no icon is keyed by the user's language.\n *\n * Example of an i18n map:\n *\n *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }\n *\n * Note: the static property will be overridden if the #icon configuration is used.\n *\n * @static\n * @inheritable\n * @property {Object|string}\n */\nOO.ui.mixin.IconElement.static.icon = null;\n\n/**\n * The icon title, displayed when users move the mouse over the icon. The value can be text, a\n * function that returns title text, or `null` for no title.\n *\n * The static property will be overridden if the #iconTitle configuration is used.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.IconElement.static.iconTitle = null;\n\n/* Methods */\n\n/**\n * Set the icon element. This method is used to retarget an icon mixin so that its functionality\n * applies to the specified icon element instead of the one created by the class. If an icon\n * element is already set, the mixin’s effect on that element is removed. Generated CSS classes\n * and mixin methods will no longer affect the element.\n *\n * @param {jQuery} $icon Element to use as icon\n */\nOO.ui.mixin.IconElement.prototype.setIconElement = function ( $icon ) {\n\tif ( this.$icon ) {\n\t\tthis.$icon\n\t\t\t.removeClass( 'oo-ui-iconElement-icon oo-ui-icon-' + this.icon )\n\t\t\t.removeAttr( 'title' );\n\t}\n\n\tthis.$icon = $icon\n\t\t.addClass( 'oo-ui-iconElement-icon' )\n\t\t.toggleClass( 'oo-ui-iconElement-noIcon', !this.icon )\n\t\t.toggleClass( 'oo-ui-icon-' + this.icon, !!this.icon );\n\tif ( this.iconTitle !== null ) {\n\t\tthis.$icon.attr( 'title', this.iconTitle );\n\t}\n\n\tthis.updateThemeClasses();\n};\n\n/**\n * Set icon by symbolic name (e.g., ‘remove’ or ‘menu’). Use `null` to remove an icon.\n * The icon parameter can also be set to a map of icon names. See the #icon config setting\n * for an example.\n *\n * @param {Object|string|null} icon A symbolic icon name, a {@link #icon map of icon names} keyed\n *  by language code, or `null` to remove the icon.\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.IconElement.prototype.setIcon = function ( icon ) {\n\ticon = OO.isPlainObject( icon ) ? OO.ui.getLocalValue( icon, null, 'default' ) : icon;\n\ticon = typeof icon === 'string' && icon.trim().length ? icon.trim() : null;\n\n\tif ( this.icon !== icon ) {\n\t\tif ( this.$icon ) {\n\t\t\tif ( this.icon !== null ) {\n\t\t\t\tthis.$icon.removeClass( 'oo-ui-icon-' + this.icon );\n\t\t\t}\n\t\t\tif ( icon !== null ) {\n\t\t\t\tthis.$icon.addClass( 'oo-ui-icon-' + icon );\n\t\t\t}\n\t\t}\n\t\tthis.icon = icon;\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-iconElement', !!this.icon );\n\tif ( this.$icon ) {\n\t\tthis.$icon.toggleClass( 'oo-ui-iconElement-noIcon', !this.icon );\n\t}\n\tthis.updateThemeClasses();\n\n\treturn this;\n};\n\n/**\n * Set the icon title. Use `null` to remove the title.\n *\n * @param {string|Function|null} iconTitle A text string used as the icon title,\n *  a function that returns title text, or `null` for no title.\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n * @deprecated\n */\nOO.ui.mixin.IconElement.prototype.setIconTitle = function ( iconTitle ) {\n\ticonTitle =\n\t\t( typeof iconTitle === 'function' || ( typeof iconTitle === 'string' && iconTitle.length ) ) ?\n\t\t\tOO.ui.resolveMsg( iconTitle ) : null;\n\n\tif ( this.iconTitle !== iconTitle ) {\n\t\tthis.iconTitle = iconTitle;\n\t\tif ( this.$icon ) {\n\t\t\tif ( this.iconTitle !== null ) {\n\t\t\t\tthis.$icon.attr( 'title', iconTitle );\n\t\t\t} else {\n\t\t\t\tthis.$icon.removeAttr( 'title' );\n\t\t\t}\n\t\t}\n\t}\n\n\t// `setIconTitle is deprecated since 0.30.0\n\tif ( iconTitle !== null ) {\n\t\t// Avoid a warning when this is called from the constructor with no iconTitle set\n\t\tOO.ui.warnDeprecation( 'IconElement: setIconTitle is deprecated, use setTitle of TitledElement instead. See T76638 for details.' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Get the symbolic name of the icon.\n *\n * @return {string} Icon name\n */\nOO.ui.mixin.IconElement.prototype.getIcon = function () {\n\treturn this.icon;\n};\n\n/**\n * Get the icon title. The title text is displayed when a user moves the mouse over the icon.\n *\n * @return {string} Icon title text\n */\nOO.ui.mixin.IconElement.prototype.getIconTitle = function () {\n\treturn this.iconTitle;\n};\n","/**\n * IndicatorElement is often mixed into other classes to generate an indicator.\n * Indicators are small graphics that are generally used in two ways:\n *\n * - To draw attention to the status of an item. For example, an indicator might be\n *   used to show that an item in a list has errors that need to be resolved.\n * - To clarify the function of a control that acts in an exceptional way (a button\n *   that opens a menu instead of performing an action directly, for example).\n *\n * For a list of indicators included in the library, please see the\n * [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$indicator] The indicator element created by the class. If this\n *  configuration is omitted, the indicator element will use a generated `<span>`.\n * @cfg {string} [indicator] Symbolic name of the indicator (e.g., ‘clear’ or ‘down’).\n *  See the [OOUI documentation on MediaWiki][2] for a list of indicators included\n *  in the library.\n * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators\n * @cfg {string|Function} [indicatorTitle] A text string used as the indicator title,\n *  or a function that returns title text. The indicator title is displayed when users move\n *  the mouse over the indicator.\n */\nOO.ui.mixin.IndicatorElement = function OoUiMixinIndicatorElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$indicator = null;\n\tthis.indicator = null;\n\tthis.indicatorTitle = null;\n\n\t// `indicatorTitle`s are deprecated since 0.30.0\n\tif ( config.indicatorTitle !== undefined ) {\n\t\tOO.ui.warnDeprecation( 'IndicatorElement: Widgets with indicatorTitle set are deprecated, use title instead. See T76638 for details.' );\n\t}\n\n\t// Initialization\n\tthis.setIndicator( config.indicator || this.constructor.static.indicator );\n\tthis.setIndicatorTitle( config.indicatorTitle || this.constructor.static.indicatorTitle );\n\tthis.setIndicatorElement( config.$indicator || $( '<span>' ) );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.IndicatorElement );\n\n/* Static Properties */\n\n/**\n * Symbolic name of the indicator (e.g., ‘clear’ or  ‘down’).\n * The static property will be overridden if the #indicator configuration is used.\n *\n * @static\n * @inheritable\n * @property {string|null}\n */\nOO.ui.mixin.IndicatorElement.static.indicator = null;\n\n/**\n * A text string used as the indicator title, a function that returns title text, or `null`\n * for no title. The static property will be overridden if the #indicatorTitle configuration is used.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.IndicatorElement.static.indicatorTitle = null;\n\n/* Methods */\n\n/**\n * Set the indicator element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $indicator Element to use as indicator\n */\nOO.ui.mixin.IndicatorElement.prototype.setIndicatorElement = function ( $indicator ) {\n\tif ( this.$indicator ) {\n\t\tthis.$indicator\n\t\t\t.removeClass( 'oo-ui-indicatorElement-indicator oo-ui-indicator-' + this.indicator )\n\t\t\t.removeAttr( 'title' );\n\t}\n\n\tthis.$indicator = $indicator\n\t\t.addClass( 'oo-ui-indicatorElement-indicator' )\n\t\t.toggleClass( 'oo-ui-indicatorElement-noIndicator', !this.indicator )\n\t\t.toggleClass( 'oo-ui-indicator-' + this.indicator, !!this.indicator );\n\tif ( this.indicatorTitle !== null ) {\n\t\tthis.$indicator.attr( 'title', this.indicatorTitle );\n\t}\n\n\tthis.updateThemeClasses();\n};\n\n/**\n * Set the indicator by its symbolic name: ‘clear’, ‘down’, ‘required’, ‘search’, ‘up’. Use `null` to remove the indicator.\n *\n * @param {string|null} indicator Symbolic name of indicator, or `null` for no indicator\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.IndicatorElement.prototype.setIndicator = function ( indicator ) {\n\tindicator = typeof indicator === 'string' && indicator.length ? indicator.trim() : null;\n\n\tif ( this.indicator !== indicator ) {\n\t\tif ( this.$indicator ) {\n\t\t\tif ( this.indicator !== null ) {\n\t\t\t\tthis.$indicator.removeClass( 'oo-ui-indicator-' + this.indicator );\n\t\t\t}\n\t\t\tif ( indicator !== null ) {\n\t\t\t\tthis.$indicator.addClass( 'oo-ui-indicator-' + indicator );\n\t\t\t}\n\t\t}\n\t\tthis.indicator = indicator;\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-indicatorElement', !!this.indicator );\n\tif ( this.$indicator ) {\n\t\tthis.$indicator.toggleClass( 'oo-ui-indicatorElement-noIndicator', !this.indicator );\n\t}\n\tthis.updateThemeClasses();\n\n\treturn this;\n};\n\n/**\n * Set the indicator title.\n *\n * The title is displayed when a user moves the mouse over the indicator.\n *\n * @param {string|Function|null} indicatorTitle Indicator title text, a function that returns text, or\n *   `null` for no indicator title\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n * @deprecated\n */\nOO.ui.mixin.IndicatorElement.prototype.setIndicatorTitle = function ( indicatorTitle ) {\n\tindicatorTitle =\n\t\t( typeof indicatorTitle === 'function' || ( typeof indicatorTitle === 'string' && indicatorTitle.length ) ) ?\n\t\t\tOO.ui.resolveMsg( indicatorTitle ) : null;\n\n\tif ( this.indicatorTitle !== indicatorTitle ) {\n\t\tthis.indicatorTitle = indicatorTitle;\n\t\tif ( this.$indicator ) {\n\t\t\tif ( this.indicatorTitle !== null ) {\n\t\t\t\tthis.$indicator.attr( 'title', indicatorTitle );\n\t\t\t} else {\n\t\t\t\tthis.$indicator.removeAttr( 'title' );\n\t\t\t}\n\t\t}\n\t}\n\n\t// `setIndicatorTitle is deprecated since 0.30.0\n\tif ( indicatorTitle !== null ) {\n\t\t// Avoid a warning when this is called from the constructor with no indicatorTitle set\n\t\tOO.ui.warnDeprecation( 'IndicatorElement: setIndicatorTitle is deprecated, use setTitle of TitledElement instead. See T76638 for details.' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Get the symbolic name of the indicator (e.g., ‘clear’ or  ‘down’).\n *\n * @return {string} Symbolic name of indicator\n */\nOO.ui.mixin.IndicatorElement.prototype.getIndicator = function () {\n\treturn this.indicator;\n};\n\n/**\n * Get the indicator title.\n *\n * The title is displayed when a user moves the mouse over the indicator.\n *\n * @return {string} Indicator title text\n */\nOO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {\n\treturn this.indicatorTitle;\n};\n","/**\n * The FlaggedElement class is an attribute mixin, meaning that it is used to add\n * additional functionality to an element created by another class. The class provides\n * a ‘flags’ property assigned the name (or an array of names) of styling flags,\n * which are used to customize the look and feel of a widget to better describe its\n * importance and functionality.\n *\n * The library currently contains the following styling flags for general use:\n *\n * - **progressive**: Progressive styling is applied to convey that the widget will move the user forward in a process.\n * - **destructive**: Destructive styling is applied to convey that the widget will remove something.\n *\n * The flags affect the appearance of the buttons:\n *\n *     @example\n *     // FlaggedElement is mixed into ButtonWidget to provide styling flags\n *     var button1 = new OO.ui.ButtonWidget( {\n *             label: 'Progressive',\n *             flags: 'progressive'\n *         } ),\n *         button2 = new OO.ui.ButtonWidget( {\n *             label: 'Destructive',\n *             flags: 'destructive'\n *         } );\n *     $( document.body ).append( button1.$element, button2.$element );\n *\n * {@link OO.ui.ActionWidget ActionWidgets}, which are a special kind of button that execute an action, use these flags: **primary** and **safe**.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string|string[]} [flags] The name or names of the flags (e.g., 'progressive' or 'primary') to apply.\n *  Please see the [OOUI documentation on MediaWiki] [2] for more information about available flags.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged\n * @cfg {jQuery} [$flagged] The flagged element. By default,\n *  the flagged functionality is applied to the element created by the class ($element).\n *  If a different element is specified, the flagged functionality will be applied to it instead.\n */\nOO.ui.mixin.FlaggedElement = function OoUiMixinFlaggedElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.flags = {};\n\tthis.$flagged = null;\n\n\t// Initialization\n\tthis.setFlags( config.flags );\n\tthis.setFlaggedElement( config.$flagged || this.$element );\n};\n\n/* Events */\n\n/**\n * @event flag\n * A flag event is emitted when the #clearFlags or #setFlags methods are used. The `changes`\n * parameter contains the name of each modified flag and indicates whether it was\n * added or removed.\n *\n * @param {Object.<string,boolean>} changes Object keyed by flag name. A Boolean `true` indicates\n * that the flag was added, `false` that the flag was removed.\n */\n\n/* Methods */\n\n/**\n * Set the flagged element.\n *\n * This method is used to retarget a flagged mixin so that its functionality applies to the specified element.\n * If an element is already set, the method will remove the mixin’s effect on that element.\n *\n * @param {jQuery} $flagged Element that should be flagged\n */\nOO.ui.mixin.FlaggedElement.prototype.setFlaggedElement = function ( $flagged ) {\n\tvar classNames = Object.keys( this.flags ).map( function ( flag ) {\n\t\treturn 'oo-ui-flaggedElement-' + flag;\n\t} );\n\n\tif ( this.$flagged ) {\n\t\tthis.$flagged.removeClass( classNames );\n\t}\n\n\tthis.$flagged = $flagged.addClass( classNames );\n};\n\n/**\n * Check if the specified flag is set.\n *\n * @param {string} flag Name of flag\n * @return {boolean} The flag is set\n */\nOO.ui.mixin.FlaggedElement.prototype.hasFlag = function ( flag ) {\n\t// This may be called before the constructor, thus before this.flags is set\n\treturn this.flags && ( flag in this.flags );\n};\n\n/**\n * Get the names of all flags set.\n *\n * @return {string[]} Flag names\n */\nOO.ui.mixin.FlaggedElement.prototype.getFlags = function () {\n\t// This may be called before the constructor, thus before this.flags is set\n\treturn Object.keys( this.flags || {} );\n};\n\n/**\n * Clear all flags.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n * @fires flag\n */\nOO.ui.mixin.FlaggedElement.prototype.clearFlags = function () {\n\tvar flag, className,\n\t\tchanges = {},\n\t\tremove = [],\n\t\tclassPrefix = 'oo-ui-flaggedElement-';\n\n\tfor ( flag in this.flags ) {\n\t\tclassName = classPrefix + flag;\n\t\tchanges[ flag ] = false;\n\t\tdelete this.flags[ flag ];\n\t\tremove.push( className );\n\t}\n\n\tif ( this.$flagged ) {\n\t\tthis.$flagged.removeClass( remove );\n\t}\n\n\tthis.updateThemeClasses();\n\tthis.emit( 'flag', changes );\n\n\treturn this;\n};\n\n/**\n * Add one or more flags.\n *\n * @param {string|string[]|Object.<string, boolean>} flags A flag name, an array of flag names,\n *  or an object keyed by flag name with a boolean value that indicates whether the flag should\n *  be added (`true`) or removed (`false`).\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n * @fires flag\n */\nOO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) {\n\tvar i, len, flag, className,\n\t\tchanges = {},\n\t\tadd = [],\n\t\tremove = [],\n\t\tclassPrefix = 'oo-ui-flaggedElement-';\n\n\tif ( typeof flags === 'string' ) {\n\t\tclassName = classPrefix + flags;\n\t\t// Set\n\t\tif ( !this.flags[ flags ] ) {\n\t\t\tthis.flags[ flags ] = true;\n\t\t\tadd.push( className );\n\t\t}\n\t} else if ( Array.isArray( flags ) ) {\n\t\tfor ( i = 0, len = flags.length; i < len; i++ ) {\n\t\t\tflag = flags[ i ];\n\t\t\tclassName = classPrefix + flag;\n\t\t\t// Set\n\t\t\tif ( !this.flags[ flag ] ) {\n\t\t\t\tchanges[ flag ] = true;\n\t\t\t\tthis.flags[ flag ] = true;\n\t\t\t\tadd.push( className );\n\t\t\t}\n\t\t}\n\t} else if ( OO.isPlainObject( flags ) ) {\n\t\tfor ( flag in flags ) {\n\t\t\tclassName = classPrefix + flag;\n\t\t\tif ( flags[ flag ] ) {\n\t\t\t\t// Set\n\t\t\t\tif ( !this.flags[ flag ] ) {\n\t\t\t\t\tchanges[ flag ] = true;\n\t\t\t\t\tthis.flags[ flag ] = true;\n\t\t\t\t\tadd.push( className );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Remove\n\t\t\t\tif ( this.flags[ flag ] ) {\n\t\t\t\t\tchanges[ flag ] = false;\n\t\t\t\t\tdelete this.flags[ flag ];\n\t\t\t\t\tremove.push( className );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( this.$flagged ) {\n\t\tthis.$flagged\n\t\t\t.addClass( add )\n\t\t\t.removeClass( remove );\n\t}\n\n\tthis.updateThemeClasses();\n\tthis.emit( 'flag', changes );\n\n\treturn this;\n};\n","/**\n * TitledElement is mixed into other classes to provide a `title` attribute.\n * Titles are rendered by the browser and are made visible when the user moves\n * the mouse over the element. Titles are not visible on touch devices.\n *\n *     @example\n *     // TitledElement provides a `title` attribute to the\n *     // ButtonWidget class.\n *     var button = new OO.ui.ButtonWidget( {\n *         label: 'Button with Title',\n *         title: 'I am a button'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$titled] The element to which the `title` attribute is applied.\n *  If this config is omitted, the title functionality is applied to $element, the\n *  element created by the class.\n * @cfg {string|Function} [title] The title text or a function that returns text. If\n *  this config is omitted, the value of the {@link #static-title static title} property is used.\n */\nOO.ui.mixin.TitledElement = function OoUiMixinTitledElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$titled = null;\n\tthis.title = null;\n\n\t// Initialization\n\tthis.setTitle( config.title !== undefined ? config.title : this.constructor.static.title );\n\tthis.setTitledElement( config.$titled || this.$element );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * The title text, a function that returns text, or `null` for no title. The value of the static property\n * is overridden if the #title config option is used.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.TitledElement.static.title = null;\n\n/* Methods */\n\n/**\n * Set the titled element.\n *\n * This method is used to retarget a TitledElement mixin so that its functionality applies to the specified element.\n * If an element is already set, the mixin’s effect on that element is removed before the new element is set up.\n *\n * @param {jQuery} $titled Element that should use the 'titled' functionality\n */\nOO.ui.mixin.TitledElement.prototype.setTitledElement = function ( $titled ) {\n\tif ( this.$titled ) {\n\t\tthis.$titled.removeAttr( 'title' );\n\t}\n\n\tthis.$titled = $titled;\n\tif ( this.title ) {\n\t\tthis.updateTitle();\n\t}\n};\n\n/**\n * Set title.\n *\n * @param {string|Function|null} title Title text, a function that returns text, or `null` for no title\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TitledElement.prototype.setTitle = function ( title ) {\n\ttitle = typeof title === 'function' ? OO.ui.resolveMsg( title ) : title;\n\ttitle = ( typeof title === 'string' && title.length ) ? title : null;\n\n\tif ( this.title !== title ) {\n\t\tthis.title = title;\n\t\tthis.updateTitle();\n\t}\n\n\treturn this;\n};\n\n/**\n * Update the title attribute, in case of changes to title or accessKey.\n *\n * @protected\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TitledElement.prototype.updateTitle = function () {\n\tvar title = this.getTitle();\n\tif ( this.$titled ) {\n\t\tif ( title !== null ) {\n\t\t\t// Only if this is an AccessKeyedElement\n\t\t\tif ( this.formatTitleWithAccessKey ) {\n\t\t\t\ttitle = this.formatTitleWithAccessKey( title );\n\t\t\t}\n\t\t\tthis.$titled.attr( 'title', title );\n\t\t} else {\n\t\t\tthis.$titled.removeAttr( 'title' );\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Get title.\n *\n * @return {string} Title string\n */\nOO.ui.mixin.TitledElement.prototype.getTitle = function () {\n\treturn this.title;\n};\n","/**\n * AccessKeyedElement is mixed into other classes to provide an `accesskey` HTML attribute.\n * Accesskeys allow an user to go to a specific element by using\n * a shortcut combination of a browser specific keys + the key\n * set to the field.\n *\n *     @example\n *     // AccessKeyedElement provides an `accesskey` attribute to the\n *     // ButtonWidget class.\n *     var button = new OO.ui.ButtonWidget( {\n *         label: 'Button with Accesskey',\n *         accessKey: 'k'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$accessKeyed] The element to which the `accesskey` attribute is applied.\n *  If this config is omitted, the accesskey functionality is applied to $element, the\n *  element created by the class.\n * @cfg {string|Function} [accessKey] The key or a function that returns the key. If\n *  this config is omitted, no accesskey will be added.\n */\nOO.ui.mixin.AccessKeyedElement = function OoUiMixinAccessKeyedElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$accessKeyed = null;\n\tthis.accessKey = null;\n\n\t// Initialization\n\tthis.setAccessKey( config.accessKey || null );\n\tthis.setAccessKeyedElement( config.$accessKeyed || this.$element );\n\n\t// If this is also a TitledElement and it initialized before we did, we may have\n\t// to update the title with the access key\n\tif ( this.updateTitle ) {\n\t\tthis.updateTitle();\n\t}\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.AccessKeyedElement );\n\n/* Static Properties */\n\n/**\n * The access key, a function that returns a key, or `null` for no accesskey.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.AccessKeyedElement.static.accessKey = null;\n\n/* Methods */\n\n/**\n * Set the accesskeyed element.\n *\n * This method is used to retarget a AccessKeyedElement mixin so that its functionality applies to the specified element.\n * If an element is already set, the mixin's effect on that element is removed before the new element is set up.\n *\n * @param {jQuery} $accessKeyed Element that should use the 'accesskeyed' functionality\n */\nOO.ui.mixin.AccessKeyedElement.prototype.setAccessKeyedElement = function ( $accessKeyed ) {\n\tif ( this.$accessKeyed ) {\n\t\tthis.$accessKeyed.removeAttr( 'accesskey' );\n\t}\n\n\tthis.$accessKeyed = $accessKeyed;\n\tif ( this.accessKey ) {\n\t\tthis.$accessKeyed.attr( 'accesskey', this.accessKey );\n\t}\n};\n\n/**\n * Set accesskey.\n *\n * @param {string|Function|null} accessKey Key, a function that returns a key, or `null` for no accesskey\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.AccessKeyedElement.prototype.setAccessKey = function ( accessKey ) {\n\taccessKey = typeof accessKey === 'string' ? OO.ui.resolveMsg( accessKey ) : null;\n\n\tif ( this.accessKey !== accessKey ) {\n\t\tif ( this.$accessKeyed ) {\n\t\t\tif ( accessKey !== null ) {\n\t\t\t\tthis.$accessKeyed.attr( 'accesskey', accessKey );\n\t\t\t} else {\n\t\t\t\tthis.$accessKeyed.removeAttr( 'accesskey' );\n\t\t\t}\n\t\t}\n\t\tthis.accessKey = accessKey;\n\n\t\t// Only if this is a TitledElement\n\t\tif ( this.updateTitle ) {\n\t\t\tthis.updateTitle();\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Get accesskey.\n *\n * @return {string} accessKey string\n */\nOO.ui.mixin.AccessKeyedElement.prototype.getAccessKey = function () {\n\treturn this.accessKey;\n};\n\n/**\n * Add information about the access key to the element's tooltip label.\n * (This is only public for hacky usage in FieldLayout.)\n *\n * @param {string} title Tooltip label for `title` attribute\n * @return {string}\n */\nOO.ui.mixin.AccessKeyedElement.prototype.formatTitleWithAccessKey = function ( title ) {\n\tvar accessKey;\n\n\tif ( !this.$accessKeyed ) {\n\t\t// Not initialized yet; the constructor will call updateTitle() which will rerun this function\n\t\treturn title;\n\t}\n\t// Use jquery.accessKeyLabel if available to show modifiers, otherwise just display the single key\n\tif ( $.fn.updateTooltipAccessKeys && $.fn.updateTooltipAccessKeys.getAccessKeyLabel ) {\n\t\taccessKey = $.fn.updateTooltipAccessKeys.getAccessKeyLabel( this.$accessKeyed[ 0 ] );\n\t} else {\n\t\taccessKey = this.getAccessKey();\n\t}\n\tif ( accessKey ) {\n\t\ttitle += ' [' + accessKey + ']';\n\t}\n\treturn title;\n};\n","/**\n * ButtonWidget is a generic widget for buttons. A wide variety of looks,\n * feels, and functionality can be customized via the class’s configuration options\n * and methods. Please see the [OOUI documentation on MediaWiki] [1] for more information\n * and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches\n *\n *     @example\n *     // A button widget.\n *     var button = new OO.ui.ButtonWidget( {\n *         label: 'Button with Icon',\n *         icon: 'trash',\n *         title: 'Remove'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * NOTE: HTML form buttons should use the OO.ui.ButtonInputWidget class.\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.AccessKeyedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [active=false] Whether button should be shown as active\n * @cfg {string} [href] Hyperlink to visit when the button is clicked.\n * @cfg {string} [target] The frame or window in which to open the hyperlink.\n * @cfg {boolean} [noFollow] Search engine traversal hint (default: true)\n */\nOO.ui.ButtonWidget = function OoUiButtonWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ButtonWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );\n\tOO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$button } ) );\n\n\t// Properties\n\tthis.href = null;\n\tthis.target = null;\n\tthis.noFollow = false;\n\n\t// Events\n\tthis.connect( this, { disable: 'onDisable' } );\n\n\t// Initialization\n\tthis.$button.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element\n\t\t.addClass( 'oo-ui-buttonWidget' )\n\t\t.append( this.$button );\n\tthis.setActive( config.active );\n\tthis.setHref( config.href );\n\tthis.setTarget( config.target );\n\tthis.setNoFollow( config.noFollow );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.AccessKeyedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonWidget.static.cancelButtonMouseDownEvents = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * Get hyperlink location.\n *\n * @return {string} Hyperlink location\n */\nOO.ui.ButtonWidget.prototype.getHref = function () {\n\treturn this.href;\n};\n\n/**\n * Get hyperlink target.\n *\n * @return {string} Hyperlink target\n */\nOO.ui.ButtonWidget.prototype.getTarget = function () {\n\treturn this.target;\n};\n\n/**\n * Get search engine traversal hint.\n *\n * @return {boolean} Whether search engines should avoid traversing this hyperlink\n */\nOO.ui.ButtonWidget.prototype.getNoFollow = function () {\n\treturn this.noFollow;\n};\n\n/**\n * Set hyperlink location.\n *\n * @param {string|null} href Hyperlink location, null to remove\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.setHref = function ( href ) {\n\thref = typeof href === 'string' ? href : null;\n\tif ( href !== null && !OO.ui.isSafeUrl( href ) ) {\n\t\thref = './' + href;\n\t}\n\n\tif ( href !== this.href ) {\n\t\tthis.href = href;\n\t\tthis.updateHref();\n\t}\n\n\treturn this;\n};\n\n/**\n * Update the `href` attribute, in case of changes to href or\n * disabled state.\n *\n * @private\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.updateHref = function () {\n\tif ( this.href !== null && !this.isDisabled() ) {\n\t\tthis.$button.attr( 'href', this.href );\n\t} else {\n\t\tthis.$button.removeAttr( 'href' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Handle disable events.\n *\n * @private\n * @param {boolean} disabled Element is disabled\n */\nOO.ui.ButtonWidget.prototype.onDisable = function () {\n\tthis.updateHref();\n};\n\n/**\n * Set hyperlink target.\n *\n * @param {string|null} target Hyperlink target, null to remove\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.setTarget = function ( target ) {\n\ttarget = typeof target === 'string' ? target : null;\n\n\tif ( target !== this.target ) {\n\t\tthis.target = target;\n\t\tif ( target !== null ) {\n\t\t\tthis.$button.attr( 'target', target );\n\t\t} else {\n\t\t\tthis.$button.removeAttr( 'target' );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Set search engine traversal hint.\n *\n * @param {boolean} noFollow True if search engines should avoid traversing this hyperlink\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.setNoFollow = function ( noFollow ) {\n\tnoFollow = typeof noFollow === 'boolean' ? noFollow : true;\n\n\tif ( noFollow !== this.noFollow ) {\n\t\tthis.noFollow = noFollow;\n\t\tif ( noFollow ) {\n\t\t\tthis.$button.attr( 'rel', 'nofollow' );\n\t\t} else {\n\t\t\tthis.$button.removeAttr( 'rel' );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n// Override method visibility hints from ButtonElement\n/**\n * @method setActive\n * @inheritdoc\n */\n/**\n * @method isActive\n * @inheritdoc\n */\n","/**\n * A ButtonGroupWidget groups related buttons and is used together with OO.ui.ButtonWidget and\n * its subclasses. Each button in a group is addressed by a unique reference. Buttons can be added,\n * removed, and cleared from the group.\n *\n *     @example\n *     // A ButtonGroupWidget with two buttons.\n *     var button1 = new OO.ui.PopupButtonWidget( {\n *             label: 'Select a category',\n *             icon: 'menu',\n *             popup: {\n *                 $content: $( '<p>List of categories…</p>' ),\n *                 padded: true,\n *                 align: 'left'\n *             }\n *         } ),\n *         button2 = new OO.ui.ButtonWidget( {\n *             label: 'Add item'\n *         } ),\n *         buttonGroup = new OO.ui.ButtonGroupWidget( {\n *             items: [ button1, button2 ]\n *         } );\n *     $( document.body ).append( buttonGroup.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.ButtonWidget[]} [items] Buttons to add\n */\nOO.ui.ButtonGroupWidget = function OoUiButtonGroupWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ButtonGroupWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonGroupWidget' );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonGroupWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.mixin.GroupElement );\nOO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonGroupWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * Focus the widget\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonGroupWidget.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tif ( this.items[ 0 ] ) {\n\t\t\tthis.items[ 0 ].focus();\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ButtonGroupWidget.prototype.simulateLabelClick = function () {\n\tthis.focus();\n};\n","/**\n * IconWidget is a generic widget for {@link OO.ui.mixin.IconElement icons}. In general, IconWidgets should be used with OO.ui.LabelWidget,\n * which creates a label that identifies the icon’s function. See the [OOUI documentation on MediaWiki] [1]\n * for a list of icons included in the library.\n *\n *     @example\n *     // An IconWidget with a label via LabelWidget.\n *     var myIcon = new OO.ui.IconWidget( {\n *             icon: 'help',\n *             title: 'Help'\n *          } ),\n *          // Create a label.\n *          iconLabel = new OO.ui.LabelWidget( {\n *              label: 'Help'\n *          } );\n *      $( document.body ).append( myIcon.$element, iconLabel.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Icons\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.IconWidget = function OoUiIconWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.IconWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, $.extend( {}, config, { $icon: this.$element } ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element, invisibleLabel: true } ) );\n\tOO.ui.mixin.FlaggedElement.call( this, $.extend( {}, config, { $flagged: this.$element } ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-iconWidget' );\n\t// Remove class added by LabelElement initialization. It causes unexpected CSS to apply when\n\t// nested in other widgets, because this widget used to not mix in LabelElement.\n\tthis.$element.removeClass( 'oo-ui-labelElement-label' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.IconWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.FlaggedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.IconWidget.static.tagName = 'span';\n","/**\n * IndicatorWidgets create indicators, which are small graphics that are generally used to draw\n * attention to the status of an item or to clarify the function within a control. For a list of\n * indicators included in the library, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // An indicator widget.\n *     var indicator1 = new OO.ui.IndicatorWidget( {\n *             indicator: 'required'\n *         } ),\n *         // Create a fieldset layout to add a label.\n *         fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( indicator1, {\n *             label: 'A required indicator:'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.LabelElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.IndicatorWidget = function OoUiIndicatorWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.IndicatorWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IndicatorElement.call( this, $.extend( {}, config, { $indicator: this.$element } ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element, invisibleLabel: true } ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-indicatorWidget' );\n\t// Remove class added by LabelElement initialization. It causes unexpected CSS to apply when\n\t// nested in other widgets, because this widget used to not mix in LabelElement.\n\tthis.$element.removeClass( 'oo-ui-labelElement-label' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.IndicatorWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.LabelElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.IndicatorWidget.static.tagName = 'span';\n","/**\n * LabelWidgets help identify the function of interface elements. Each LabelWidget can\n * be configured with a `label` option that is set to a string, a label node, or a function:\n *\n * - String: a plaintext string\n * - jQuery selection: a jQuery selection, used for anything other than a plaintext label, e.g., a\n *   label that includes a link or special styling, such as a gray color or additional graphical elements.\n * - Function: a function that will produce a string in the future. Functions are used\n *   in cases where the value of the label is not currently defined.\n *\n * In addition, the LabelWidget can be associated with an {@link OO.ui.InputWidget input widget}, which\n * will come into focus when the label is clicked.\n *\n *     @example\n *     // Two LabelWidgets.\n *     var label1 = new OO.ui.LabelWidget( {\n *             label: 'plaintext label'\n *         } ),\n *         label2 = new OO.ui.LabelWidget( {\n *             label: $( '<a>' ).attr( 'href', 'default.html' ).text( 'jQuery label' )\n *         } ),\n *         // Create a fieldset layout with fields for each example.\n *         fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( label1 ),\n *         new OO.ui.FieldLayout( label2 )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.InputWidget} [input] {@link OO.ui.InputWidget Input widget} that uses the label.\n *  Clicking the label will focus the specified input field.\n */\nOO.ui.LabelWidget = function OoUiLabelWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.LabelWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element } ) );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.input = config.input;\n\n\t// Initialization\n\tif ( this.input ) {\n\t\tif ( this.input.getInputId() ) {\n\t\t\tthis.$element.attr( 'for', this.input.getInputId() );\n\t\t} else {\n\t\t\tthis.$label.on( 'click', function () {\n\t\t\t\tthis.input.simulateLabelClick();\n\t\t\t}.bind( this ) );\n\t\t}\n\t}\n\tthis.$element.addClass( 'oo-ui-labelWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.LabelWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.LabelWidget.static.tagName = 'label';\n","/**\n * PendingElement is a mixin that is used to create elements that notify users that something is happening\n * and that they should wait before proceeding. The pending state is visually represented with a pending\n * texture that appears in the head of a pending {@link OO.ui.ProcessDialog process dialog} or in the input\n * field of a {@link OO.ui.TextInputWidget text input widget}.\n *\n * Currently, {@link OO.ui.ActionWidget Action widgets}, which mix in this class, can also be marked as pending, but only when\n * used in {@link OO.ui.MessageDialog message dialogs}. The behavior is not currently supported for action widgets used\n * in process dialogs.\n *\n *     @example\n *     function MessageDialog( config ) {\n *         MessageDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MessageDialog, OO.ui.MessageDialog );\n *\n *     MessageDialog.static.name = 'myMessageDialog';\n *     MessageDialog.static.actions = [\n *         { action: 'save', label: 'Done', flags: 'primary' },\n *         { label: 'Cancel', flags: 'safe' }\n *     ];\n *\n *     MessageDialog.prototype.initialize = function () {\n *         MessageDialog.parent.prototype.initialize.apply( this, arguments );\n *         this.content = new OO.ui.PanelLayout( { padded: true } );\n *         this.content.$element.append( '<p>Click the \\'Done\\' action widget to see its pending state. Note that action widgets can be marked pending in message dialogs but not process dialogs.</p>' );\n *         this.$body.append( this.content.$element );\n *     };\n *     MessageDialog.prototype.getBodyHeight = function () {\n *         return 100;\n *     }\n *     MessageDialog.prototype.getActionProcess = function ( action ) {\n *         var dialog = this;\n *         if ( action === 'save' ) {\n *             dialog.getActions().get({actions: 'save'})[0].pushPending();\n *             return new OO.ui.Process()\n *             .next( 1000 )\n *             .next( function () {\n *                 dialog.getActions().get({actions: 'save'})[0].popPending();\n *             } );\n *         }\n *         return MessageDialog.parent.prototype.getActionProcess.call( this, action );\n *     };\n *\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *\n *     var dialog = new MessageDialog();\n *     windowManager.addWindows( [ dialog ] );\n *     windowManager.openWindow( dialog );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$pending] Element to mark as pending, defaults to this.$element\n */\nOO.ui.mixin.PendingElement = function OoUiMixinPendingElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.pending = 0;\n\tthis.$pending = null;\n\n\t// Initialisation\n\tthis.setPendingElement( config.$pending || this.$element );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.PendingElement );\n\n/* Methods */\n\n/**\n * Set the pending element (and clean up any existing one).\n *\n * @param {jQuery} $pending The element to set to pending.\n */\nOO.ui.mixin.PendingElement.prototype.setPendingElement = function ( $pending ) {\n\tif ( this.$pending ) {\n\t\tthis.$pending.removeClass( 'oo-ui-pendingElement-pending' );\n\t}\n\n\tthis.$pending = $pending;\n\tif ( this.pending > 0 ) {\n\t\tthis.$pending.addClass( 'oo-ui-pendingElement-pending' );\n\t}\n};\n\n/**\n * Check if an element is pending.\n *\n * @return {boolean} Element is pending\n */\nOO.ui.mixin.PendingElement.prototype.isPending = function () {\n\treturn !!this.pending;\n};\n\n/**\n * Increase the pending counter. The pending state will remain active until the counter is zero\n * (i.e., the number of calls to #pushPending and #popPending is the same).\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.PendingElement.prototype.pushPending = function () {\n\tif ( this.pending === 0 ) {\n\t\tthis.$pending.addClass( 'oo-ui-pendingElement-pending' );\n\t\tthis.updateThemeClasses();\n\t}\n\tthis.pending++;\n\n\treturn this;\n};\n\n/**\n * Decrease the pending counter. The pending state will remain active until the counter is zero\n * (i.e., the number of calls to #pushPending and #popPending is the same).\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.PendingElement.prototype.popPending = function () {\n\tif ( this.pending === 1 ) {\n\t\tthis.$pending.removeClass( 'oo-ui-pendingElement-pending' );\n\t\tthis.updateThemeClasses();\n\t}\n\tthis.pending = Math.max( 0, this.pending - 1 );\n\n\treturn this;\n};\n","/**\n * Element that will stick adjacent to a specified container, even when it is inserted elsewhere\n * in the document (for example, in an OO.ui.Window's $overlay).\n *\n * The elements's position is automatically calculated and maintained when window is resized or the\n * page is scrolled. If you reposition the container manually, you have to call #position to make\n * sure the element is still placed correctly.\n *\n * As positioning is only possible when both the element and the container are attached to the DOM\n * and visible, it's only done after you call #togglePositioning. You might want to do this inside\n * the #toggle method to display a floating popup, for example.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element\n * @cfg {jQuery} [$floatableContainer] Node to position adjacent to\n * @cfg {string} [verticalPosition='below'] Where to position $floatable vertically:\n *  'below': Directly below $floatableContainer, aligning f's top edge with fC's bottom edge\n *  'above': Directly above $floatableContainer, aligning f's bottom edge with fC's top edge\n *  'top': Align the top edge with $floatableContainer's top edge\n *  'bottom': Align the bottom edge with $floatableContainer's bottom edge\n *  'center': Vertically align the center with $floatableContainer's center\n * @cfg {string} [horizontalPosition='start'] Where to position $floatable horizontally:\n *  'before': Directly before $floatableContainer, aligning f's end edge with fC's start edge\n *  'after': Directly after $floatableContainer, aligning f's start edge with fC's end edge\n *  'start': Align the start (left in LTR, right in RTL) edge with $floatableContainer's start edge\n *  'end': Align the end (right in LTR, left in RTL) edge with $floatableContainer's end edge\n *  'center': Horizontally align the center with $floatableContainer's center\n * @cfg {boolean} [hideWhenOutOfView=true] Whether to hide the floatable element if the container\n *  is out of view\n */\nOO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$floatable = null;\n\tthis.$floatableContainer = null;\n\tthis.$floatableWindow = null;\n\tthis.$floatableClosestScrollable = null;\n\tthis.floatableOutOfView = false;\n\tthis.onFloatableScrollHandler = this.position.bind( this );\n\tthis.onFloatableWindowResizeHandler = this.position.bind( this );\n\n\t// Initialization\n\tthis.setFloatableContainer( config.$floatableContainer );\n\tthis.setFloatableElement( config.$floatable || this.$element );\n\tthis.setVerticalPosition( config.verticalPosition || 'below' );\n\tthis.setHorizontalPosition( config.horizontalPosition || 'start' );\n\tthis.hideWhenOutOfView = config.hideWhenOutOfView === undefined ? true : !!config.hideWhenOutOfView;\n};\n\n/* Methods */\n\n/**\n * Set floatable element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $floatable Element to make floatable\n */\nOO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatable ) {\n\tif ( this.$floatable ) {\n\t\tthis.$floatable.removeClass( 'oo-ui-floatableElement-floatable' );\n\t\tthis.$floatable.css( { left: '', top: '' } );\n\t}\n\n\tthis.$floatable = $floatable.addClass( 'oo-ui-floatableElement-floatable' );\n\tthis.position();\n};\n\n/**\n * Set floatable container.\n *\n * The element will be positioned relative to the specified container.\n *\n * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset\n */\nOO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $floatableContainer ) {\n\tthis.$floatableContainer = $floatableContainer;\n\tif ( this.$floatable ) {\n\t\tthis.position();\n\t}\n};\n\n/**\n * Change how the element is positioned vertically.\n *\n * @param {string} position 'below', 'above', 'top', 'bottom' or 'center'\n */\nOO.ui.mixin.FloatableElement.prototype.setVerticalPosition = function ( position ) {\n\tif ( [ 'below', 'above', 'top', 'bottom', 'center' ].indexOf( position ) === -1 ) {\n\t\tthrow new Error( 'Invalid value for vertical position: ' + position );\n\t}\n\tif ( this.verticalPosition !== position ) {\n\t\tthis.verticalPosition = position;\n\t\tif ( this.$floatable ) {\n\t\t\tthis.position();\n\t\t}\n\t}\n};\n\n/**\n * Change how the element is positioned horizontally.\n *\n * @param {string} position 'before', 'after', 'start', 'end' or 'center'\n */\nOO.ui.mixin.FloatableElement.prototype.setHorizontalPosition = function ( position ) {\n\tif ( [ 'before', 'after', 'start', 'end', 'center' ].indexOf( position ) === -1 ) {\n\t\tthrow new Error( 'Invalid value for horizontal position: ' + position );\n\t}\n\tif ( this.horizontalPosition !== position ) {\n\t\tthis.horizontalPosition = position;\n\t\tif ( this.$floatable ) {\n\t\t\tthis.position();\n\t\t}\n\t}\n};\n\n/**\n * Toggle positioning.\n *\n * Do not turn positioning on until after the element is attached to the DOM and visible.\n *\n * @param {boolean} [positioning] Enable positioning, omit to toggle\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) {\n\tvar closestScrollableOfContainer;\n\n\tif ( !this.$floatable || !this.$floatableContainer ) {\n\t\treturn this;\n\t}\n\n\tpositioning = positioning === undefined ? !this.positioning : !!positioning;\n\n\tif ( positioning && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'FloatableElement#togglePositioning: Before calling this method, the element must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\n\tif ( this.positioning !== positioning ) {\n\t\tthis.positioning = positioning;\n\n\t\tclosestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] );\n\t\t// If the scrollable is the root, we have to listen to scroll events\n\t\t// on the window because of browser inconsistencies.\n\t\tif ( $( closestScrollableOfContainer ).is( 'html, body' ) ) {\n\t\t\tclosestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer );\n\t\t}\n\n\t\tif ( positioning ) {\n\t\t\tthis.$floatableWindow = $( this.getElementWindow() );\n\t\t\tthis.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler );\n\n\t\t\tthis.$floatableClosestScrollable = $( closestScrollableOfContainer );\n\t\t\tthis.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler );\n\n\t\t\t// Initial position after visible\n\t\t\tthis.position();\n\t\t} else {\n\t\t\tif ( this.$floatableWindow ) {\n\t\t\t\tthis.$floatableWindow.off( 'resize', this.onFloatableWindowResizeHandler );\n\t\t\t\tthis.$floatableWindow = null;\n\t\t\t}\n\n\t\t\tif ( this.$floatableClosestScrollable ) {\n\t\t\t\tthis.$floatableClosestScrollable.off( 'scroll', this.onFloatableScrollHandler );\n\t\t\t\tthis.$floatableClosestScrollable = null;\n\t\t\t}\n\n\t\t\tthis.$floatable.css( { left: '', right: '', top: '' } );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Check whether the bottom edge of the given element is within the viewport of the given container.\n *\n * @private\n * @param {jQuery} $element\n * @param {jQuery} $container\n * @return {boolean}\n */\nOO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) {\n\tvar elemRect, contRect, topEdgeInBounds, bottomEdgeInBounds, leftEdgeInBounds, rightEdgeInBounds,\n\t\tstartEdgeInBounds, endEdgeInBounds, viewportSpacing,\n\t\tdirection = $element.css( 'direction' );\n\n\telemRect = $element[ 0 ].getBoundingClientRect();\n\tif ( $container[ 0 ] === window ) {\n\t\tviewportSpacing = OO.ui.getViewportSpacing();\n\t\tcontRect = {\n\t\t\ttop: 0,\n\t\t\tleft: 0,\n\t\t\tright: document.documentElement.clientWidth,\n\t\t\tbottom: document.documentElement.clientHeight\n\t\t};\n\t\tcontRect.top += viewportSpacing.top;\n\t\tcontRect.left += viewportSpacing.left;\n\t\tcontRect.right -= viewportSpacing.right;\n\t\tcontRect.bottom -= viewportSpacing.bottom;\n\t} else {\n\t\tcontRect = $container[ 0 ].getBoundingClientRect();\n\t}\n\n\ttopEdgeInBounds = elemRect.top >= contRect.top && elemRect.top <= contRect.bottom;\n\tbottomEdgeInBounds = elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom;\n\tleftEdgeInBounds = elemRect.left >= contRect.left && elemRect.left <= contRect.right;\n\trightEdgeInBounds = elemRect.right >= contRect.left && elemRect.right <= contRect.right;\n\tif ( direction === 'rtl' ) {\n\t\tstartEdgeInBounds = rightEdgeInBounds;\n\t\tendEdgeInBounds = leftEdgeInBounds;\n\t} else {\n\t\tstartEdgeInBounds = leftEdgeInBounds;\n\t\tendEdgeInBounds = rightEdgeInBounds;\n\t}\n\n\tif ( this.verticalPosition === 'below' && !bottomEdgeInBounds ) {\n\t\treturn false;\n\t}\n\tif ( this.verticalPosition === 'above' && !topEdgeInBounds ) {\n\t\treturn false;\n\t}\n\tif ( this.horizontalPosition === 'before' && !startEdgeInBounds ) {\n\t\treturn false;\n\t}\n\tif ( this.horizontalPosition === 'after' && !endEdgeInBounds ) {\n\t\treturn false;\n\t}\n\n\t// The other positioning values are all about being inside the container,\n\t// so in those cases all we care about is that any part of the container is visible.\n\treturn elemRect.top <= contRect.bottom && elemRect.bottom >= contRect.top &&\n\t\telemRect.left <= contRect.right && elemRect.right >= contRect.left;\n};\n\n/**\n * Check if the floatable is hidden to the user because it was offscreen.\n *\n * @return {boolean} Floatable is out of view\n */\nOO.ui.mixin.FloatableElement.prototype.isFloatableOutOfView = function () {\n\treturn this.floatableOutOfView;\n};\n\n/**\n * Position the floatable below its container.\n *\n * This should only be done when both of them are attached to the DOM and visible.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.FloatableElement.prototype.position = function () {\n\tif ( !this.positioning ) {\n\t\treturn this;\n\t}\n\n\tif ( !(\n\t\t// To continue, some things need to be true:\n\t\t// The element must actually be in the DOM\n\t\tthis.isElementAttached() && (\n\t\t\t// The closest scrollable is the current window\n\t\t\tthis.$floatableClosestScrollable[ 0 ] === this.getElementWindow() ||\n\t\t\t// OR is an element in the element's DOM\n\t\t\t$.contains( this.getElementDocument(), this.$floatableClosestScrollable[ 0 ] )\n\t\t)\n\t) ) {\n\t\t// Abort early if important parts of the widget are no longer attached to the DOM\n\t\treturn this;\n\t}\n\n\tthis.floatableOutOfView = this.hideWhenOutOfView && !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable );\n\tif ( this.floatableOutOfView ) {\n\t\tthis.$floatable.addClass( 'oo-ui-element-hidden' );\n\t\treturn this;\n\t} else {\n\t\tthis.$floatable.removeClass( 'oo-ui-element-hidden' );\n\t}\n\n\tthis.$floatable.css( this.computePosition() );\n\n\t// We updated the position, so re-evaluate the clipping state.\n\t// (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so\n\t// will not notice the need to update itself.)\n\t// TODO: This is terrible, we shouldn't need to know about ClippableElement at all here. Why does\n\t// it not listen to the right events in the right places?\n\tif ( this.clip ) {\n\t\tthis.clip();\n\t}\n\n\treturn this;\n};\n\n/**\n * Compute how #$floatable should be positioned based on the position of #$floatableContainer\n * and the positioning settings. This is a helper for #position that shouldn't be called directly,\n * but may be overridden by subclasses if they want to change or add to the positioning logic.\n *\n * @return {Object} New position to apply with .css(). Keys are 'top', 'left', 'bottom' and 'right'.\n */\nOO.ui.mixin.FloatableElement.prototype.computePosition = function () {\n\tvar isBody, scrollableX, scrollableY, containerPos,\n\t\thorizScrollbarHeight, vertScrollbarWidth, scrollTop, scrollLeft,\n\t\tnewPos = { top: '', left: '', bottom: '', right: '' },\n\t\tdirection = this.$floatableContainer.css( 'direction' ),\n\t\t$offsetParent = this.$floatable.offsetParent();\n\n\tif ( $offsetParent.is( 'html' ) ) {\n\t\t// The innerHeight/Width and clientHeight/Width calculations don't work well on the\n\t\t// <html> element, but they do work on the <body>\n\t\t$offsetParent = $( $offsetParent[ 0 ].ownerDocument.body );\n\t}\n\tisBody = $offsetParent.is( 'body' );\n\tscrollableX = $offsetParent.css( 'overflow-x' ) === 'scroll' || $offsetParent.css( 'overflow-x' ) === 'auto';\n\tscrollableY = $offsetParent.css( 'overflow-y' ) === 'scroll' || $offsetParent.css( 'overflow-y' ) === 'auto';\n\n\tvertScrollbarWidth = $offsetParent.innerWidth() - $offsetParent.prop( 'clientWidth' );\n\thorizScrollbarHeight = $offsetParent.innerHeight() - $offsetParent.prop( 'clientHeight' );\n\t// We don't need to compute and add scrollTop and scrollLeft if the scrollable container is the body,\n\t// or if it isn't scrollable\n\tscrollTop = scrollableY && !isBody ? $offsetParent.scrollTop() : 0;\n\tscrollLeft = scrollableX && !isBody ? OO.ui.Element.static.getScrollLeft( $offsetParent[ 0 ] ) : 0;\n\n\t// Avoid passing the <body> to getRelativePosition(), because it won't return what we expect\n\t// if the <body> has a margin\n\tcontainerPos = isBody ?\n\t\tthis.$floatableContainer.offset() :\n\t\tOO.ui.Element.static.getRelativePosition( this.$floatableContainer, $offsetParent );\n\tcontainerPos.bottom = containerPos.top + this.$floatableContainer.outerHeight();\n\tcontainerPos.right = containerPos.left + this.$floatableContainer.outerWidth();\n\tcontainerPos.start = direction === 'rtl' ? containerPos.right : containerPos.left;\n\tcontainerPos.end = direction === 'rtl' ? containerPos.left : containerPos.right;\n\n\tif ( this.verticalPosition === 'below' ) {\n\t\tnewPos.top = containerPos.bottom;\n\t} else if ( this.verticalPosition === 'above' ) {\n\t\tnewPos.bottom = $offsetParent.outerHeight() - containerPos.top;\n\t} else if ( this.verticalPosition === 'top' ) {\n\t\tnewPos.top = containerPos.top;\n\t} else if ( this.verticalPosition === 'bottom' ) {\n\t\tnewPos.bottom = $offsetParent.outerHeight() - containerPos.bottom;\n\t} else if ( this.verticalPosition === 'center' ) {\n\t\tnewPos.top = containerPos.top +\n\t\t\t( this.$floatableContainer.height() - this.$floatable.height() ) / 2;\n\t}\n\n\tif ( this.horizontalPosition === 'before' ) {\n\t\tnewPos.end = containerPos.start;\n\t} else if ( this.horizontalPosition === 'after' ) {\n\t\tnewPos.start = containerPos.end;\n\t} else if ( this.horizontalPosition === 'start' ) {\n\t\tnewPos.start = containerPos.start;\n\t} else if ( this.horizontalPosition === 'end' ) {\n\t\tnewPos.end = containerPos.end;\n\t} else if ( this.horizontalPosition === 'center' ) {\n\t\tnewPos.left = containerPos.left +\n\t\t\t( this.$floatableContainer.width() - this.$floatable.width() ) / 2;\n\t}\n\n\tif ( newPos.start !== undefined ) {\n\t\tif ( direction === 'rtl' ) {\n\t\t\tnewPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) : $offsetParent ).outerWidth() - newPos.start;\n\t\t} else {\n\t\t\tnewPos.left = newPos.start;\n\t\t}\n\t\tdelete newPos.start;\n\t}\n\tif ( newPos.end !== undefined ) {\n\t\tif ( direction === 'rtl' ) {\n\t\t\tnewPos.left = newPos.end;\n\t\t} else {\n\t\t\tnewPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) : $offsetParent ).outerWidth() - newPos.end;\n\t\t}\n\t\tdelete newPos.end;\n\t}\n\n\t// Account for scroll position\n\tif ( newPos.top !== '' ) {\n\t\tnewPos.top += scrollTop;\n\t}\n\tif ( newPos.bottom !== '' ) {\n\t\tnewPos.bottom -= scrollTop;\n\t}\n\tif ( newPos.left !== '' ) {\n\t\tnewPos.left += scrollLeft;\n\t}\n\tif ( newPos.right !== '' ) {\n\t\tnewPos.right -= scrollLeft;\n\t}\n\n\t// Account for scrollbar gutter\n\tif ( newPos.bottom !== '' ) {\n\t\tnewPos.bottom -= horizScrollbarHeight;\n\t}\n\tif ( direction === 'rtl' ) {\n\t\tif ( newPos.left !== '' ) {\n\t\t\tnewPos.left -= vertScrollbarWidth;\n\t\t}\n\t} else {\n\t\tif ( newPos.right !== '' ) {\n\t\t\tnewPos.right -= vertScrollbarWidth;\n\t\t}\n\t}\n\n\treturn newPos;\n};\n","/**\n * Element that can be automatically clipped to visible boundaries.\n *\n * Whenever the element's natural height changes, you have to call\n * {@link OO.ui.mixin.ClippableElement#clip} to make sure it's still\n * clipping correctly.\n *\n * The dimensions of #$clippableContainer will be compared to the boundaries of the\n * nearest scrollable container. If #$clippableContainer is too tall and/or too wide,\n * then #$clippable will be given a fixed reduced height and/or width and will be made\n * scrollable. By default, #$clippable and #$clippableContainer are the same element,\n * but you can build a static footer by setting #$clippableContainer to an element that contains\n * #$clippable and the footer.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$clippable] Node to clip, assigned to #$clippable, omit to use #$element\n * @cfg {jQuery} [$clippableContainer] Node to keep visible, assigned to #$clippableContainer,\n *   omit to use #$clippable\n */\nOO.ui.mixin.ClippableElement = function OoUiMixinClippableElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$clippable = null;\n\tthis.$clippableContainer = null;\n\tthis.clipping = false;\n\tthis.clippedHorizontally = false;\n\tthis.clippedVertically = false;\n\tthis.$clippableScrollableContainer = null;\n\tthis.$clippableScroller = null;\n\tthis.$clippableWindow = null;\n\tthis.idealWidth = null;\n\tthis.idealHeight = null;\n\tthis.onClippableScrollHandler = this.clip.bind( this );\n\tthis.onClippableWindowResizeHandler = this.clip.bind( this );\n\n\t// Initialization\n\tif ( config.$clippableContainer ) {\n\t\tthis.setClippableContainer( config.$clippableContainer );\n\t}\n\tthis.setClippableElement( config.$clippable || this.$element );\n};\n\n/* Methods */\n\n/**\n * Set clippable element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $clippable Element to make clippable\n */\nOO.ui.mixin.ClippableElement.prototype.setClippableElement = function ( $clippable ) {\n\tif ( this.$clippable ) {\n\t\tthis.$clippable.removeClass( 'oo-ui-clippableElement-clippable' );\n\t\tthis.$clippable.css( { width: '', height: '', overflowX: '', overflowY: '' } );\n\t\tOO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );\n\t}\n\n\tthis.$clippable = $clippable.addClass( 'oo-ui-clippableElement-clippable' );\n\tthis.clip();\n};\n\n/**\n * Set clippable container.\n *\n * This is the container that will be measured when deciding whether to clip. When clipping,\n * #$clippable will be resized in order to keep the clippable container fully visible.\n *\n * If the clippable container is unset, #$clippable will be used.\n *\n * @param {jQuery|null} $clippableContainer Container to keep visible, or null to unset\n */\nOO.ui.mixin.ClippableElement.prototype.setClippableContainer = function ( $clippableContainer ) {\n\tthis.$clippableContainer = $clippableContainer;\n\tif ( this.$clippable ) {\n\t\tthis.clip();\n\t}\n};\n\n/**\n * Toggle clipping.\n *\n * Do not turn clipping on until after the element is attached to the DOM and visible.\n *\n * @param {boolean} [clipping] Enable clipping, omit to toggle\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ClippableElement.prototype.toggleClipping = function ( clipping ) {\n\tclipping = clipping === undefined ? !this.clipping : !!clipping;\n\n\tif ( clipping && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'ClippableElement#toggleClipping: Before calling this method, the element must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\n\tif ( this.clipping !== clipping ) {\n\t\tthis.clipping = clipping;\n\t\tif ( clipping ) {\n\t\t\tthis.$clippableScrollableContainer = $( this.getClosestScrollableElementContainer() );\n\t\t\t// If the clippable container is the root, we have to listen to scroll events and check\n\t\t\t// jQuery.scrollTop on the window because of browser inconsistencies\n\t\t\tthis.$clippableScroller = this.$clippableScrollableContainer.is( 'html, body' ) ?\n\t\t\t\t$( OO.ui.Element.static.getWindow( this.$clippableScrollableContainer ) ) :\n\t\t\t\tthis.$clippableScrollableContainer;\n\t\t\tthis.$clippableScroller.on( 'scroll', this.onClippableScrollHandler );\n\t\t\tthis.$clippableWindow = $( this.getElementWindow() )\n\t\t\t\t.on( 'resize', this.onClippableWindowResizeHandler );\n\t\t\t// Initial clip after visible\n\t\t\tthis.clip();\n\t\t} else {\n\t\t\tthis.$clippable.css( {\n\t\t\t\twidth: '',\n\t\t\t\theight: '',\n\t\t\t\tmaxWidth: '',\n\t\t\t\tmaxHeight: '',\n\t\t\t\toverflowX: '',\n\t\t\t\toverflowY: ''\n\t\t\t} );\n\t\t\tOO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );\n\n\t\t\tthis.$clippableScrollableContainer = null;\n\t\t\tthis.$clippableScroller.off( 'scroll', this.onClippableScrollHandler );\n\t\t\tthis.$clippableScroller = null;\n\t\t\tthis.$clippableWindow.off( 'resize', this.onClippableWindowResizeHandler );\n\t\t\tthis.$clippableWindow = null;\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Check if the element will be clipped to fit the visible area of the nearest scrollable container.\n *\n * @return {boolean} Element will be clipped to the visible area\n */\nOO.ui.mixin.ClippableElement.prototype.isClipping = function () {\n\treturn this.clipping;\n};\n\n/**\n * Check if the bottom or right of the element is being clipped by the nearest scrollable container.\n *\n * @return {boolean} Part of the element is being clipped\n */\nOO.ui.mixin.ClippableElement.prototype.isClipped = function () {\n\treturn this.clippedHorizontally || this.clippedVertically;\n};\n\n/**\n * Check if the right of the element is being clipped by the nearest scrollable container.\n *\n * @return {boolean} Part of the element is being clipped\n */\nOO.ui.mixin.ClippableElement.prototype.isClippedHorizontally = function () {\n\treturn this.clippedHorizontally;\n};\n\n/**\n * Check if the bottom of the element is being clipped by the nearest scrollable container.\n *\n * @return {boolean} Part of the element is being clipped\n */\nOO.ui.mixin.ClippableElement.prototype.isClippedVertically = function () {\n\treturn this.clippedVertically;\n};\n\n/**\n * Set the ideal size. These are the dimensions #$clippable will have when it's not being clipped.\n *\n * @param {number|string} [width] Width as a number of pixels or CSS string with unit suffix\n * @param {number|string} [height] Height as a number of pixels or CSS string with unit suffix\n */\nOO.ui.mixin.ClippableElement.prototype.setIdealSize = function ( width, height ) {\n\tthis.idealWidth = width;\n\tthis.idealHeight = height;\n\n\tif ( !this.clipping ) {\n\t\t// Update dimensions\n\t\tthis.$clippable.css( { width: width, height: height } );\n\t}\n\t// While clipping, idealWidth and idealHeight are not considered\n};\n\n/**\n * Return the side of the clippable on which it is \"anchored\" (aligned to something else).\n * ClippableElement will clip the opposite side when reducing element's width.\n *\n * Classes that mix in ClippableElement should override this to return 'right' if their\n * clippable is absolutely positioned and using 'right: Npx' (and not using 'left').\n * If your class also mixes in FloatableElement, this is handled automatically.\n *\n * (This can't be guessed from the actual CSS because the computed values for 'left'/'right' are\n * always in pixels, even if they were unset or set to 'auto'.)\n *\n * When in doubt, 'left' (or 'right' in RTL) is a sane fallback.\n *\n * @return {string} 'left' or 'right'\n */\nOO.ui.mixin.ClippableElement.prototype.getHorizontalAnchorEdge = function () {\n\tif ( this.computePosition && this.positioning && this.computePosition().right !== '' ) {\n\t\treturn 'right';\n\t}\n\treturn 'left';\n};\n\n/**\n * Return the side of the clippable on which it is \"anchored\" (aligned to something else).\n * ClippableElement will clip the opposite side when reducing element's width.\n *\n * Classes that mix in ClippableElement should override this to return 'bottom' if their\n * clippable is absolutely positioned and using 'bottom: Npx' (and not using 'top').\n * If your class also mixes in FloatableElement, this is handled automatically.\n *\n * (This can't be guessed from the actual CSS because the computed values for 'left'/'right' are\n * always in pixels, even if they were unset or set to 'auto'.)\n *\n * When in doubt, 'top' is a sane fallback.\n *\n * @return {string} 'top' or 'bottom'\n */\nOO.ui.mixin.ClippableElement.prototype.getVerticalAnchorEdge = function () {\n\tif ( this.computePosition && this.positioning && this.computePosition().bottom !== '' ) {\n\t\treturn 'bottom';\n\t}\n\treturn 'top';\n};\n\n/**\n * Clip element to visible boundaries and allow scrolling when needed. You should call this method\n * when the element's natural height changes.\n *\n * Element will be clipped the bottom or right of the element is within 10px of the edge of, or\n * overlapped by, the visible area of the nearest scrollable container.\n *\n * Because calling clip() when the natural height changes isn't always possible, we also set\n * max-height when the element isn't being clipped. This means that if the element tries to grow\n * beyond the edge, something reasonable will happen before clip() is called.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ClippableElement.prototype.clip = function () {\n\tvar extraHeight, extraWidth, viewportSpacing,\n\t\tdesiredWidth, desiredHeight, allotedWidth, allotedHeight,\n\t\tnaturalWidth, naturalHeight, clipWidth, clipHeight,\n\t\t$item, itemRect, $viewport, viewportRect, availableRect,\n\t\tdirection, vertScrollbarWidth, horizScrollbarHeight,\n\t\t// Extra tolerance so that the sloppy code below doesn't result in results that are off\n\t\t// by one or two pixels. (And also so that we have space to display drop shadows.)\n\t\t// Chosen by fair dice roll.\n\t\tbuffer = 7;\n\n\tif ( !this.clipping ) {\n\t\t// this.$clippableScrollableContainer and this.$clippableWindow are null, so the below will fail\n\t\treturn this;\n\t}\n\n\tfunction rectIntersection( a, b ) {\n\t\tvar out = {};\n\t\tout.top = Math.max( a.top, b.top );\n\t\tout.left = Math.max( a.left, b.left );\n\t\tout.bottom = Math.min( a.bottom, b.bottom );\n\t\tout.right = Math.min( a.right, b.right );\n\t\treturn out;\n\t}\n\n\tviewportSpacing = OO.ui.getViewportSpacing();\n\n\tif ( this.$clippableScrollableContainer.is( 'html, body' ) ) {\n\t\t$viewport = $( this.$clippableScrollableContainer[ 0 ].ownerDocument.body );\n\t\t// Dimensions of the browser window, rather than the element!\n\t\tviewportRect = {\n\t\t\ttop: 0,\n\t\t\tleft: 0,\n\t\t\tright: document.documentElement.clientWidth,\n\t\t\tbottom: document.documentElement.clientHeight\n\t\t};\n\t\tviewportRect.top += viewportSpacing.top;\n\t\tviewportRect.left += viewportSpacing.left;\n\t\tviewportRect.right -= viewportSpacing.right;\n\t\tviewportRect.bottom -= viewportSpacing.bottom;\n\t} else {\n\t\t$viewport = this.$clippableScrollableContainer;\n\t\tviewportRect = $viewport[ 0 ].getBoundingClientRect();\n\t\t// Convert into a plain object\n\t\tviewportRect = $.extend( {}, viewportRect );\n\t}\n\n\t// Account for scrollbar gutter\n\tdirection = $viewport.css( 'direction' );\n\tvertScrollbarWidth = $viewport.innerWidth() - $viewport.prop( 'clientWidth' );\n\thorizScrollbarHeight = $viewport.innerHeight() - $viewport.prop( 'clientHeight' );\n\tviewportRect.bottom -= horizScrollbarHeight;\n\tif ( direction === 'rtl' ) {\n\t\tviewportRect.left += vertScrollbarWidth;\n\t} else {\n\t\tviewportRect.right -= vertScrollbarWidth;\n\t}\n\n\t// Add arbitrary tolerance\n\tviewportRect.top += buffer;\n\tviewportRect.left += buffer;\n\tviewportRect.right -= buffer;\n\tviewportRect.bottom -= buffer;\n\n\t$item = this.$clippableContainer || this.$clippable;\n\n\textraHeight = $item.outerHeight() - this.$clippable.outerHeight();\n\textraWidth = $item.outerWidth() - this.$clippable.outerWidth();\n\n\titemRect = $item[ 0 ].getBoundingClientRect();\n\t// Convert into a plain object\n\titemRect = $.extend( {}, itemRect );\n\n\t// Item might already be clipped, so we can't just use its dimensions (in case we might need to\n\t// make it larger than before). Extend the rectangle to the maximum size we are allowed to take.\n\tif ( this.getHorizontalAnchorEdge() === 'right' ) {\n\t\titemRect.left = viewportRect.left;\n\t} else {\n\t\titemRect.right = viewportRect.right;\n\t}\n\tif ( this.getVerticalAnchorEdge() === 'bottom' ) {\n\t\titemRect.top = viewportRect.top;\n\t} else {\n\t\titemRect.bottom = viewportRect.bottom;\n\t}\n\n\tavailableRect = rectIntersection( viewportRect, itemRect );\n\n\tdesiredWidth = Math.max( 0, availableRect.right - availableRect.left );\n\tdesiredHeight = Math.max( 0, availableRect.bottom - availableRect.top );\n\t// It should never be desirable to exceed the dimensions of the browser viewport... right?\n\tdesiredWidth = Math.min( desiredWidth,\n\t\tdocument.documentElement.clientWidth - viewportSpacing.left - viewportSpacing.right );\n\tdesiredHeight = Math.min( desiredHeight,\n\t\tdocument.documentElement.clientHeight - viewportSpacing.top - viewportSpacing.right );\n\tallotedWidth = Math.ceil( desiredWidth - extraWidth );\n\tallotedHeight = Math.ceil( desiredHeight - extraHeight );\n\tnaturalWidth = this.$clippable.prop( 'scrollWidth' );\n\tnaturalHeight = this.$clippable.prop( 'scrollHeight' );\n\tclipWidth = allotedWidth < naturalWidth;\n\tclipHeight = allotedHeight < naturalHeight;\n\n\tif ( clipWidth ) {\n\t\t// The order matters here. If overflow is not set first, Chrome displays bogus scrollbars. See T157672.\n\t\t// Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for this case.\n\t\tthis.$clippable.css( 'overflowX', 'scroll' );\n\t\t// eslint-disable-next-line no-void\n\t\tvoid this.$clippable[ 0 ].offsetHeight; // Force reflow\n\t\tthis.$clippable.css( {\n\t\t\twidth: Math.max( 0, allotedWidth ),\n\t\t\tmaxWidth: ''\n\t\t} );\n\t} else {\n\t\tthis.$clippable.css( {\n\t\t\toverflowX: '',\n\t\t\twidth: this.idealWidth || '',\n\t\t\tmaxWidth: Math.max( 0, allotedWidth )\n\t\t} );\n\t}\n\tif ( clipHeight ) {\n\t\t// The order matters here. If overflow is not set first, Chrome displays bogus scrollbars. See T157672.\n\t\t// Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for this case.\n\t\tthis.$clippable.css( 'overflowY', 'scroll' );\n\t\t// eslint-disable-next-line no-void\n\t\tvoid this.$clippable[ 0 ].offsetHeight; // Force reflow\n\t\tthis.$clippable.css( {\n\t\t\theight: Math.max( 0, allotedHeight ),\n\t\t\tmaxHeight: ''\n\t\t} );\n\t} else {\n\t\tthis.$clippable.css( {\n\t\t\toverflowY: '',\n\t\t\theight: this.idealHeight || '',\n\t\t\tmaxHeight: Math.max( 0, allotedHeight )\n\t\t} );\n\t}\n\n\t// If we stopped clipping in at least one of the dimensions\n\tif ( ( this.clippedHorizontally && !clipWidth ) || ( this.clippedVertically && !clipHeight ) ) {\n\t\tOO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );\n\t}\n\n\tthis.clippedHorizontally = clipWidth;\n\tthis.clippedVertically = clipHeight;\n\n\treturn this;\n};\n","/**\n * PopupWidget is a container for content. The popup is overlaid and positioned absolutely.\n * By default, each popup has an anchor that points toward its origin.\n * Please see the [OOUI documentation on MediaWiki.org] [1] for more information and examples.\n *\n * Unlike most widgets, PopupWidget is initially hidden and must be shown by calling #toggle.\n *\n *     @example\n *     // A PopupWidget.\n *     var popup = new OO.ui.PopupWidget( {\n *         $content: $( '<p>Hi there!</p>' ),\n *         padded: true,\n *         width: 300\n *     } );\n *\n *     $( document.body ).append( popup.$element );\n *     // To display the popup, toggle the visibility to 'true'.\n *     popup.toggle( true );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.ClippableElement\n * @mixins OO.ui.mixin.FloatableElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number|null} [width=320] Width of popup in pixels. Pass `null` to use automatic width.\n * @cfg {number|null} [height=null] Height of popup in pixels. Pass `null` to use automatic height.\n * @cfg {boolean} [anchor=true] Show anchor pointing to origin of popup\n * @cfg {string} [position='below'] Where to position the popup relative to $floatableContainer\n *  'above': Put popup above $floatableContainer; anchor points down to the horizontal center\n *           of $floatableContainer\n *  'below': Put popup below $floatableContainer; anchor points up to the horizontal center\n *           of $floatableContainer\n *  'before': Put popup to the left (LTR) / right (RTL) of $floatableContainer; anchor points\n *            endwards (right/left) to the vertical center of $floatableContainer\n *  'after': Put popup to the right (LTR) / left (RTL) of $floatableContainer; anchor points\n *            startwards (left/right) to the vertical center of $floatableContainer\n * @cfg {string} [align='center'] How to align the popup to $floatableContainer\n *  'forwards': If position is above/below, move the popup as far endwards (right in LTR, left in RTL)\n *              as possible while still keeping the anchor within the popup;\n *              if position is before/after, move the popup as far downwards as possible.\n *  'backwards': If position is above/below, move the popup as far startwards (left in LTR, right in RTL)\n *               as possible while still keeping the anchor within the popup;\n *               if position in before/after, move the popup as far upwards as possible.\n *  'center': Horizontally (if position is above/below) or vertically (before/after) align the center\n *            of the popup with the center of $floatableContainer.\n * 'force-left': Alias for 'forwards' in LTR and 'backwards' in RTL\n * 'force-right': Alias for 'backwards' in RTL and 'forwards' in LTR\n * @cfg {boolean} [autoFlip=true] Whether to automatically switch the popup's position between\n *  'above' and 'below', or between 'before' and 'after', if there is not enough space in the\n *  desired direction to display the popup without clipping\n * @cfg {jQuery} [$container] Constrain the popup to the boundaries of the specified container.\n *  See the [OOUI docs on MediaWiki][3] for an example.\n *  [3]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups#containerExample\n * @cfg {number} [containerPadding=10] Padding between the popup and its container, specified as a number of pixels.\n * @cfg {jQuery} [$content] Content to append to the popup's body\n * @cfg {jQuery} [$footer] Content to append to the popup's footer\n * @cfg {boolean} [autoClose=false] Automatically close the popup when it loses focus.\n * @cfg {jQuery} [$autoCloseIgnore] Elements that will not close the popup when clicked.\n *  This config option is only relevant if #autoClose is set to `true`. See the [OOUI documentation on MediaWiki][2]\n *  for an example.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups#autocloseExample\n * @cfg {boolean} [head=false] Show a popup header that contains a #label (if specified) and close\n *  button.\n * @cfg {boolean} [padded=false] Add padding to the popup's body\n */\nOO.ui.PopupWidget = function OoUiPopupWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.PopupWidget.parent.call( this, config );\n\n\t// Properties (must be set before ClippableElement constructor call)\n\tthis.$body = $( '<div>' );\n\tthis.$popup = $( '<div>' );\n\n\t// Mixin constructors\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, {\n\t\t$clippable: this.$body,\n\t\t$clippableContainer: this.$popup\n\t} ) );\n\tOO.ui.mixin.FloatableElement.call( this, config );\n\n\t// Properties\n\tthis.$anchor = $( '<div>' );\n\t// If undefined, will be computed lazily in computePosition()\n\tthis.$container = config.$container;\n\tthis.containerPadding = config.containerPadding !== undefined ? config.containerPadding : 10;\n\tthis.autoClose = !!config.autoClose;\n\tthis.transitionTimeout = null;\n\tthis.anchored = false;\n\tthis.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );\n\tthis.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );\n\n\t// Initialization\n\tthis.setSize( config.width, config.height );\n\tthis.toggleAnchor( config.anchor === undefined || config.anchor );\n\tthis.setAlignment( config.align || 'center' );\n\tthis.setPosition( config.position || 'below' );\n\tthis.setAutoFlip( config.autoFlip === undefined || config.autoFlip );\n\tthis.setAutoCloseIgnore( config.$autoCloseIgnore );\n\tthis.$body.addClass( 'oo-ui-popupWidget-body' );\n\tthis.$anchor.addClass( 'oo-ui-popupWidget-anchor' );\n\tthis.$popup\n\t\t.addClass( 'oo-ui-popupWidget-popup' )\n\t\t.append( this.$body );\n\tthis.$element\n\t\t.addClass( 'oo-ui-popupWidget' )\n\t\t.append( this.$popup, this.$anchor );\n\t// Move content, which was added to #$element by OO.ui.Widget, to the body\n\t// FIXME This is gross, we should use '$body' or something for the config\n\tif ( config.$content instanceof $ ) {\n\t\tthis.$body.append( config.$content );\n\t}\n\n\tif ( config.padded ) {\n\t\tthis.$body.addClass( 'oo-ui-popupWidget-body-padded' );\n\t}\n\n\tif ( config.head ) {\n\t\tthis.closeButton = new OO.ui.ButtonWidget( { framed: false, icon: 'close' } );\n\t\tthis.closeButton.connect( this, { click: 'onCloseButtonClick' } );\n\t\tthis.$head = $( '<div>' )\n\t\t\t.addClass( 'oo-ui-popupWidget-head' )\n\t\t\t.append( this.$label, this.closeButton.$element );\n\t\tthis.$popup.prepend( this.$head );\n\t}\n\n\tif ( config.$footer ) {\n\t\tthis.$footer = $( '<div>' )\n\t\t\t.addClass( 'oo-ui-popupWidget-footer' )\n\t\t\t.append( config.$footer );\n\t\tthis.$popup.append( this.$footer );\n\t}\n\n\t// Initially hidden - using #toggle may cause errors if subclasses override toggle with methods\n\t// that reference properties not initialized at that time of parent class construction\n\t// TODO: Find a better way to handle post-constructor setup\n\tthis.visible = false;\n\tthis.$element.addClass( 'oo-ui-element-hidden' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement );\nOO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.FloatableElement );\n\n/* Events */\n\n/**\n * @event ready\n *\n * The popup is ready: it is visible and has been positioned and clipped.\n */\n\n/* Methods */\n\n/**\n * Handles document mouse down events.\n *\n * @private\n * @param {MouseEvent} e Mouse down event\n */\nOO.ui.PopupWidget.prototype.onDocumentMouseDown = function ( e ) {\n\tif (\n\t\tthis.isVisible() &&\n\t\t!OO.ui.contains( this.$element.add( this.$autoCloseIgnore ).get(), e.target, true )\n\t) {\n\t\tthis.toggle( false );\n\t}\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.PopupWidget.prototype.onMouseDown = function () {\n\tOO.ui.warnDeprecation( 'onMouseDown is deprecated, use onDocumentMouseDown instead' );\n\tthis.onDocumentMouseDown.apply( this, arguments );\n};\n\n/**\n * Bind document mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindDocumentMouseDownListener = function () {\n\t// Capture clicks outside popup\n\tthis.getElementDocument().addEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\t// We add 'click' event because iOS safari needs to respond to this event.\n\t// We can't use 'touchstart' (as is usually the equivalent to 'mousedown') because\n\t// then it will trigger when scrolling. While iOS Safari has some reported behavior\n\t// of occasionally not emitting 'click' properly, that event seems to be the standard\n\t// that it should be emitting, so we add it to this and will operate the event handler\n\t// on whichever of these events was triggered first\n\tthis.getElementDocument().addEventListener( 'click', this.onDocumentMouseDownHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.PopupWidget.prototype.bindMouseDownListener = function () {\n\tOO.ui.warnDeprecation( 'bindMouseDownListener is deprecated, use bindDocumentMouseDownListener instead' );\n\tthis.bindDocumentMouseDownListener.apply( this, arguments );\n};\n\n/**\n * Handles close button click events.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.onCloseButtonClick = function () {\n\tif ( this.isVisible() ) {\n\t\tthis.toggle( false );\n\t}\n};\n\n/**\n * Unbind document mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindDocumentMouseDownListener = function () {\n\tthis.getElementDocument().removeEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\tthis.getElementDocument().removeEventListener( 'click', this.onDocumentMouseDownHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {\n\tOO.ui.warnDeprecation( 'unbindMouseDownListener is deprecated, use unbindDocumentMouseDownListener instead' );\n\tthis.unbindDocumentMouseDownListener.apply( this, arguments );\n};\n\n/**\n * Handles document key down events.\n *\n * @private\n * @param {KeyboardEvent} e Key down event\n */\nOO.ui.PopupWidget.prototype.onDocumentKeyDown = function ( e ) {\n\tif (\n\t\te.which === OO.ui.Keys.ESCAPE &&\n\t\tthis.isVisible()\n\t) {\n\t\tthis.toggle( false );\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t}\n};\n\n/**\n * Bind document key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.PopupWidget.prototype.bindKeyDownListener = function () {\n\tOO.ui.warnDeprecation( 'bindKeyDownListener is deprecated, use bindDocumentKeyDownListener instead' );\n\tthis.bindDocumentKeyDownListener.apply( this, arguments );\n};\n\n/**\n * Unbind document key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.PopupWidget.prototype.unbindKeyDownListener = function () {\n\tOO.ui.warnDeprecation( 'unbindKeyDownListener is deprecated, use unbindDocumentKeyDownListener instead' );\n\tthis.unbindDocumentKeyDownListener.apply( this, arguments );\n};\n\n/**\n * Show, hide, or toggle the visibility of the anchor.\n *\n * @param {boolean} [show] Show anchor, omit to toggle\n */\nOO.ui.PopupWidget.prototype.toggleAnchor = function ( show ) {\n\tshow = show === undefined ? !this.anchored : !!show;\n\n\tif ( this.anchored !== show ) {\n\t\tif ( show ) {\n\t\t\tthis.$element.addClass( 'oo-ui-popupWidget-anchored' );\n\t\t\tthis.$element.addClass( 'oo-ui-popupWidget-anchored-' + this.anchorEdge );\n\t\t} else {\n\t\t\tthis.$element.removeClass( 'oo-ui-popupWidget-anchored' );\n\t\t\tthis.$element.removeClass( 'oo-ui-popupWidget-anchored-' + this.anchorEdge );\n\t\t}\n\t\tthis.anchored = show;\n\t}\n};\n\n/**\n * Change which edge the anchor appears on.\n *\n * @param {string} edge 'top', 'bottom', 'start' or 'end'\n */\nOO.ui.PopupWidget.prototype.setAnchorEdge = function ( edge ) {\n\tif ( [ 'top', 'bottom', 'start', 'end' ].indexOf( edge ) === -1 ) {\n\t\tthrow new Error( 'Invalid value for edge: ' + edge );\n\t}\n\tif ( this.anchorEdge !== null ) {\n\t\tthis.$element.removeClass( 'oo-ui-popupWidget-anchored-' + this.anchorEdge );\n\t}\n\tthis.anchorEdge = edge;\n\tif ( this.anchored ) {\n\t\tthis.$element.addClass( 'oo-ui-popupWidget-anchored-' + edge );\n\t}\n};\n\n/**\n * Check if the anchor is visible.\n *\n * @return {boolean} Anchor is visible\n */\nOO.ui.PopupWidget.prototype.hasAnchor = function () {\n\treturn this.anchored;\n};\n\n/**\n * Toggle visibility of the popup. The popup is initially hidden and must be shown by calling\n * `.toggle( true )` after its #$element is attached to the DOM.\n *\n * Do not show the popup while it is not attached to the DOM. The calculations required to display\n * it in the right place and with the right dimensions only work correctly while it is attached.\n * Side-effects may include broken interface and exceptions being thrown. This wasn't always\n * strictly enforced, so currently it only generates a warning in the browser console.\n *\n * @fires ready\n * @inheritdoc\n */\nOO.ui.PopupWidget.prototype.toggle = function ( show ) {\n\tvar change, normalHeight, oppositeHeight, normalWidth, oppositeWidth;\n\tshow = show === undefined ? !this.isVisible() : !!show;\n\n\tchange = show !== this.isVisible();\n\n\tif ( show && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'PopupWidget#toggle: Before calling this method, the popup must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\tif ( show && !this.$floatableContainer && this.isElementAttached() ) {\n\t\t// Fall back to the parent node if the floatableContainer is not set\n\t\tthis.setFloatableContainer( this.$element.parent() );\n\t}\n\n\tif ( change && show && this.autoFlip ) {\n\t\t// Reset auto-flipping before showing the popup again. It's possible we no longer need to flip\n\t\t// (e.g. if the user scrolled).\n\t\tthis.isAutoFlipped = false;\n\t}\n\n\t// Parent method\n\tOO.ui.PopupWidget.parent.prototype.toggle.call( this, show );\n\n\tif ( change ) {\n\t\tthis.togglePositioning( show && !!this.$floatableContainer );\n\n\t\tif ( show ) {\n\t\t\tif ( this.autoClose ) {\n\t\t\t\tthis.bindDocumentMouseDownListener();\n\t\t\t\tthis.bindDocumentKeyDownListener();\n\t\t\t}\n\t\t\tthis.updateDimensions();\n\t\t\tthis.toggleClipping( true );\n\n\t\t\tif ( this.autoFlip ) {\n\t\t\t\tif ( this.popupPosition === 'above' || this.popupPosition === 'below' ) {\n\t\t\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t// If opening the popup in the normal direction causes it to be clipped, open\n\t\t\t\t\t\t// in the opposite one instead\n\t\t\t\t\t\tnormalHeight = this.$element.height();\n\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t\t// If that also causes it to be clipped, open in whichever direction\n\t\t\t\t\t\t\t// we have more space\n\t\t\t\t\t\t\toppositeHeight = this.$element.height();\n\t\t\t\t\t\t\tif ( oppositeHeight < normalHeight ) {\n\t\t\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( this.popupPosition === 'before' || this.popupPosition === 'after' ) {\n\t\t\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t// If opening the popup in the normal direction causes it to be clipped, open\n\t\t\t\t\t\t// in the opposite one instead\n\t\t\t\t\t\tnormalWidth = this.$element.width();\n\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\t// Due to T180173 horizontally clipped PopupWidgets have messed up dimensions,\n\t\t\t\t\t\t// which causes positioning to be off. Toggle clipping back and fort to work around.\n\t\t\t\t\t\tthis.toggleClipping( false );\n\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\tthis.toggleClipping( true );\n\t\t\t\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t\t// If that also causes it to be clipped, open in whichever direction\n\t\t\t\t\t\t\t// we have more space\n\t\t\t\t\t\t\toppositeWidth = this.$element.width();\n\t\t\t\t\t\t\tif ( oppositeWidth < normalWidth ) {\n\t\t\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\t\t\t// Due to T180173 horizontally clipped PopupWidgets have messed up dimensions,\n\t\t\t\t\t\t\t\t// which causes positioning to be off. Toggle clipping back and fort to work around.\n\t\t\t\t\t\t\t\tthis.toggleClipping( false );\n\t\t\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\t\t\tthis.toggleClipping( true );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.emit( 'ready' );\n\t\t} else {\n\t\t\tthis.toggleClipping( false );\n\t\t\tif ( this.autoClose ) {\n\t\t\t\tthis.unbindDocumentMouseDownListener();\n\t\t\t\tthis.unbindDocumentKeyDownListener();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Set the size of the popup.\n *\n * Changing the size may also change the popup's position depending on the alignment.\n *\n * @param {number|null} [width=320] Width in pixels. Pass `null` to use automatic width.\n * @param {number|null} [height=null] Height in pixels. Pass `null` to use automatic height.\n * @param {boolean} [transition=false] Use a smooth transition\n * @chainable\n */\nOO.ui.PopupWidget.prototype.setSize = function ( width, height, transition ) {\n\tthis.width = width !== undefined ? width : 320;\n\tthis.height = height !== undefined ? height : null;\n\tif ( this.isVisible() ) {\n\t\tthis.updateDimensions( transition );\n\t}\n};\n\n/**\n * Update the size and position.\n *\n * Only use this to keep the popup properly anchored. Use #setSize to change the size, and this will\n * be called automatically.\n *\n * @param {boolean} [transition=false] Use a smooth transition\n * @chainable\n */\nOO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {\n\tvar widget = this;\n\n\t// Prevent transition from being interrupted\n\tclearTimeout( this.transitionTimeout );\n\tif ( transition ) {\n\t\t// Enable transition\n\t\tthis.$element.addClass( 'oo-ui-popupWidget-transitioning' );\n\t}\n\n\tthis.position();\n\n\tif ( transition ) {\n\t\t// Prevent transitioning after transition is complete\n\t\tthis.transitionTimeout = setTimeout( function () {\n\t\t\twidget.$element.removeClass( 'oo-ui-popupWidget-transitioning' );\n\t\t}, 200 );\n\t} else {\n\t\t// Prevent transitioning immediately\n\t\tthis.$element.removeClass( 'oo-ui-popupWidget-transitioning' );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupWidget.prototype.computePosition = function () {\n\tvar direction, align, vertical, start, end, near, far, sizeProp, popupSize, anchorSize, anchorPos,\n\t\tanchorOffset, anchorMargin, parentPosition, positionProp, positionAdjustment, floatablePos,\n\t\toffsetParentPos, containerPos, popupPosition, viewportSpacing,\n\t\tpopupPos = {},\n\t\tanchorCss = { left: '', right: '', top: '', bottom: '' },\n\t\tpopupPositionOppositeMap = {\n\t\t\tabove: 'below',\n\t\t\tbelow: 'above',\n\t\t\tbefore: 'after',\n\t\t\tafter: 'before'\n\t\t},\n\t\talignMap = {\n\t\t\tltr: {\n\t\t\t\t'force-left': 'backwards',\n\t\t\t\t'force-right': 'forwards'\n\t\t\t},\n\t\t\trtl: {\n\t\t\t\t'force-left': 'forwards',\n\t\t\t\t'force-right': 'backwards'\n\t\t\t}\n\t\t},\n\t\tanchorEdgeMap = {\n\t\t\tabove: 'bottom',\n\t\t\tbelow: 'top',\n\t\t\tbefore: 'end',\n\t\t\tafter: 'start'\n\t\t},\n\t\thPosMap = {\n\t\t\tforwards: 'start',\n\t\t\tcenter: 'center',\n\t\t\tbackwards: this.anchored ? 'before' : 'end'\n\t\t},\n\t\tvPosMap = {\n\t\t\tforwards: 'top',\n\t\t\tcenter: 'center',\n\t\t\tbackwards: 'bottom'\n\t\t};\n\n\tif ( !this.$container ) {\n\t\t// Lazy-initialize $container if not specified in constructor\n\t\tthis.$container = $( this.getClosestScrollableElementContainer() );\n\t}\n\tdirection = this.$container.css( 'direction' );\n\n\t// Set height and width before we do anything else, since it might cause our measurements\n\t// to change (e.g. due to scrollbars appearing or disappearing), and it also affects centering\n\tthis.$popup.css( {\n\t\twidth: this.width !== null ? this.width : 'auto',\n\t\theight: this.height !== null ? this.height : 'auto'\n\t} );\n\n\talign = alignMap[ direction ][ this.align ] || this.align;\n\tpopupPosition = this.popupPosition;\n\tif ( this.isAutoFlipped ) {\n\t\tpopupPosition = popupPositionOppositeMap[ popupPosition ];\n\t}\n\n\t// If the popup is positioned before or after, then the anchor positioning is vertical, otherwise horizontal\n\tvertical = popupPosition === 'before' || popupPosition === 'after';\n\tstart = vertical ? 'top' : ( direction === 'rtl' ? 'right' : 'left' );\n\tend = vertical ? 'bottom' : ( direction === 'rtl' ? 'left' : 'right' );\n\tnear = vertical ? 'top' : 'left';\n\tfar = vertical ? 'bottom' : 'right';\n\tsizeProp = vertical ? 'Height' : 'Width';\n\tpopupSize = vertical ? ( this.height || this.$popup.height() ) : ( this.width || this.$popup.width() );\n\n\tthis.setAnchorEdge( anchorEdgeMap[ popupPosition ] );\n\tthis.horizontalPosition = vertical ? popupPosition : hPosMap[ align ];\n\tthis.verticalPosition = vertical ? vPosMap[ align ] : popupPosition;\n\n\t// Parent method\n\tparentPosition = OO.ui.mixin.FloatableElement.prototype.computePosition.call( this );\n\t// Find out which property FloatableElement used for positioning, and adjust that value\n\tpositionProp = vertical ?\n\t\t( parentPosition.top !== '' ? 'top' : 'bottom' ) :\n\t\t( parentPosition.left !== '' ? 'left' : 'right' );\n\n\t// Figure out where the near and far edges of the popup and $floatableContainer are\n\tfloatablePos = this.$floatableContainer.offset();\n\tfloatablePos[ far ] = floatablePos[ near ] + this.$floatableContainer[ 'outer' + sizeProp ]();\n\t// Measure where the offsetParent is and compute our position based on that and parentPosition\n\toffsetParentPos = this.$element.offsetParent()[ 0 ] === document.documentElement ?\n\t\t{ top: 0, left: 0 } :\n\t\tthis.$element.offsetParent().offset();\n\n\tif ( positionProp === near ) {\n\t\tpopupPos[ near ] = offsetParentPos[ near ] + parentPosition[ near ];\n\t\tpopupPos[ far ] = popupPos[ near ] + popupSize;\n\t} else {\n\t\tpopupPos[ far ] = offsetParentPos[ near ] +\n\t\t\tthis.$element.offsetParent()[ 'inner' + sizeProp ]() - parentPosition[ far ];\n\t\tpopupPos[ near ] = popupPos[ far ] - popupSize;\n\t}\n\n\tif ( this.anchored ) {\n\t\t// Position the anchor (which is positioned relative to the popup) to point to $floatableContainer\n\t\tanchorPos = ( floatablePos[ start ] + floatablePos[ end ] ) / 2;\n\t\tanchorOffset = ( start === far ? -1 : 1 ) * ( anchorPos - popupPos[ start ] );\n\n\t\t// If the anchor is less than 2*anchorSize from either edge, move the popup to make more space\n\t\t// this.$anchor.width()/height() returns 0 because of the CSS trickery we use, so use scrollWidth/Height\n\t\tanchorSize = this.$anchor[ 0 ][ 'scroll' + sizeProp ];\n\t\tanchorMargin = parseFloat( this.$anchor.css( 'margin-' + start ) );\n\t\tif ( anchorOffset + anchorMargin < 2 * anchorSize ) {\n\t\t\t// Not enough space for the anchor on the start side; pull the popup startwards\n\t\t\tpositionAdjustment = ( positionProp === start ? -1 : 1 ) *\n\t\t\t\t( 2 * anchorSize - ( anchorOffset + anchorMargin ) );\n\t\t} else if ( anchorOffset + anchorMargin > popupSize - 2 * anchorSize ) {\n\t\t\t// Not enough space for the anchor on the end side; pull the popup endwards\n\t\t\tpositionAdjustment = ( positionProp === end ? -1 : 1 ) *\n\t\t\t\t( anchorOffset + anchorMargin - ( popupSize - 2 * anchorSize ) );\n\t\t} else {\n\t\t\tpositionAdjustment = 0;\n\t\t}\n\t} else {\n\t\tpositionAdjustment = 0;\n\t}\n\n\t// Check if the popup will go beyond the edge of this.$container\n\tcontainerPos = this.$container[ 0 ] === document.documentElement ?\n\t\t{ top: 0, left: 0 } :\n\t\tthis.$container.offset();\n\tcontainerPos[ far ] = containerPos[ near ] + this.$container[ 'inner' + sizeProp ]();\n\tif ( this.$container[ 0 ] === document.documentElement ) {\n\t\tviewportSpacing = OO.ui.getViewportSpacing();\n\t\tcontainerPos[ near ] += viewportSpacing[ near ];\n\t\tcontainerPos[ far ] -= viewportSpacing[ far ];\n\t}\n\t// Take into account how much the popup will move because of the adjustments we're going to make\n\tpopupPos[ near ] += ( positionProp === near ? 1 : -1 ) * positionAdjustment;\n\tpopupPos[ far ] += ( positionProp === near ? 1 : -1 ) * positionAdjustment;\n\tif ( containerPos[ near ] + this.containerPadding > popupPos[ near ] ) {\n\t\t// Popup goes beyond the near (left/top) edge, move it to the right/bottom\n\t\tpositionAdjustment += ( positionProp === near ? 1 : -1 ) *\n\t\t\t( containerPos[ near ] + this.containerPadding - popupPos[ near ] );\n\t} else if ( containerPos[ far ] - this.containerPadding < popupPos[ far ] ) {\n\t\t// Popup goes beyond the far (right/bottom) edge, move it to the left/top\n\t\tpositionAdjustment += ( positionProp === far ? 1 : -1 ) *\n\t\t\t( popupPos[ far ] - ( containerPos[ far ] - this.containerPadding ) );\n\t}\n\n\tif ( this.anchored ) {\n\t\t// Adjust anchorOffset for positionAdjustment\n\t\tanchorOffset += ( positionProp === start ? -1 : 1 ) * positionAdjustment;\n\n\t\t// Position the anchor\n\t\tanchorCss[ start ] = anchorOffset;\n\t\tthis.$anchor.css( anchorCss );\n\t}\n\n\t// Move the popup if needed\n\tparentPosition[ positionProp ] += positionAdjustment;\n\n\treturn parentPosition;\n};\n\n/**\n * Set popup alignment\n *\n * @param {string} [align=center] Alignment of the popup, `center`, `force-left`, `force-right`,\n *  `backwards` or `forwards`.\n */\nOO.ui.PopupWidget.prototype.setAlignment = function ( align ) {\n\t// Validate alignment\n\tif ( [ 'force-left', 'force-right', 'backwards', 'forwards', 'center' ].indexOf( align ) > -1 ) {\n\t\tthis.align = align;\n\t} else {\n\t\tthis.align = 'center';\n\t}\n\tthis.position();\n};\n\n/**\n * Get popup alignment\n *\n * @return {string} Alignment of the popup, `center`, `force-left`, `force-right`,\n *  `backwards` or `forwards`.\n */\nOO.ui.PopupWidget.prototype.getAlignment = function () {\n\treturn this.align;\n};\n\n/**\n * Change the positioning of the popup.\n *\n * @param {string} position 'above', 'below', 'before' or 'after'\n */\nOO.ui.PopupWidget.prototype.setPosition = function ( position ) {\n\tif ( [ 'above', 'below', 'before', 'after' ].indexOf( position ) === -1 ) {\n\t\tposition = 'below';\n\t}\n\tthis.popupPosition = position;\n\tthis.position();\n};\n\n/**\n * Get popup positioning.\n *\n * @return {string} 'above', 'below', 'before' or 'after'\n */\nOO.ui.PopupWidget.prototype.getPosition = function () {\n\treturn this.popupPosition;\n};\n\n/**\n * Set popup auto-flipping.\n *\n * @param {boolean} autoFlip Whether to automatically switch the popup's position between\n *  'above' and 'below', or between 'before' and 'after', if there is not enough space in the\n *  desired direction to display the popup without clipping\n */\nOO.ui.PopupWidget.prototype.setAutoFlip = function ( autoFlip ) {\n\tautoFlip = !!autoFlip;\n\n\tif ( this.autoFlip !== autoFlip ) {\n\t\tthis.autoFlip = autoFlip;\n\t}\n};\n\n/**\n * Set which elements will not close the popup when clicked.\n *\n * For auto-closing popups, clicks on these elements will not cause the popup to auto-close.\n *\n * @param {jQuery} $autoCloseIgnore Elements to ignore for auto-closing\n */\nOO.ui.PopupWidget.prototype.setAutoCloseIgnore = function ( $autoCloseIgnore ) {\n\tthis.$autoCloseIgnore = $autoCloseIgnore;\n};\n\n/**\n * Get an ID of the body element, this can be used as the\n * `aria-describedby` attribute for an input field.\n *\n * @return {string} The ID of the body element\n */\nOO.ui.PopupWidget.prototype.getBodyId = function () {\n\tvar id = this.$body.attr( 'id' );\n\tif ( id === undefined ) {\n\t\tid = OO.ui.generateElementId();\n\t\tthis.$body.attr( 'id', id );\n\t}\n\treturn id;\n};\n","/**\n * PopupElement is mixed into other classes to generate a {@link OO.ui.PopupWidget popup widget}.\n * A popup is a container for content. It is overlaid and positioned absolutely. By default, each\n * popup has an anchor, which is an arrow-like protrusion that points toward the popup’s origin.\n * See {@link OO.ui.PopupWidget PopupWidget} for an example.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object} [popup] Configuration to pass to popup\n * @cfg {boolean} [popup.autoClose=true] Popup auto-closes when it loses focus\n */\nOO.ui.mixin.PopupElement = function OoUiMixinPopupElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.popup = new OO.ui.PopupWidget( $.extend(\n\t\t{\n\t\t\tautoClose: true,\n\t\t\t$floatableContainer: this.$element\n\t\t},\n\t\tconfig.popup,\n\t\t{\n\t\t\t$autoCloseIgnore: this.$element.add( config.popup && config.popup.$autoCloseIgnore )\n\t\t}\n\t) );\n};\n\n/* Methods */\n\n/**\n * Get popup.\n *\n * @return {OO.ui.PopupWidget} Popup widget\n */\nOO.ui.mixin.PopupElement.prototype.getPopup = function () {\n\treturn this.popup;\n};\n","/**\n * PopupButtonWidgets toggle the visibility of a contained {@link OO.ui.PopupWidget PopupWidget},\n * which is used to display additional information or options.\n *\n *     @example\n *     // A PopupButtonWidget.\n *     var popupButton = new OO.ui.PopupButtonWidget( {\n *         label: 'Popup button with options',\n *         icon: 'menu',\n *         popup: {\n *             $content: $( '<p>Additional options here.</p>' ),\n *             padded: true,\n *             align: 'force-left'\n *         }\n *     } );\n *     // Append the button to the DOM.\n *     $( document.body ).append( popupButton.$element );\n *\n * @class\n * @extends OO.ui.ButtonWidget\n * @mixins OO.ui.mixin.PopupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$overlay] Render the popup into a separate layer. This configuration is useful in cases where\n *  the expanded popup is larger than its containing `<div>`. The specified overlay layer is usually on top of the\n *  containing `<div>` and has a larger area. By default, the popup uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.PopupButtonWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PopupElement.call( this, config );\n\n\t// Properties\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\n\t// Events\n\tthis.connect( this, { click: 'onAction' } );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-popupButtonWidget' );\n\tthis.popup.$element\n\t\t.addClass( 'oo-ui-popupButtonWidget-popup' )\n\t\t.toggleClass( 'oo-ui-popupButtonWidget-framed-popup', this.isFramed() )\n\t\t.toggleClass( 'oo-ui-popupButtonWidget-frameless-popup', !this.isFramed() );\n\tthis.$overlay.append( this.popup.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupButtonWidget, OO.ui.ButtonWidget );\nOO.mixinClass( OO.ui.PopupButtonWidget, OO.ui.mixin.PopupElement );\n\n/* Methods */\n\n/**\n * Handle the button action being triggered.\n *\n * @private\n */\nOO.ui.PopupButtonWidget.prototype.onAction = function () {\n\tthis.popup.toggle();\n};\n","/**\n * Mixin for OO.ui.Widget subclasses to provide OO.ui.mixin.GroupElement.\n *\n * Use together with OO.ui.mixin.ItemWidget to make disabled state inheritable.\n *\n * @private\n * @abstract\n * @class\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.mixin.GroupWidget = function OoUiMixinGroupWidget( config ) {\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n};\n\n/* Setup */\n\nOO.mixinClass( OO.ui.mixin.GroupWidget, OO.ui.mixin.GroupElement );\n\n/* Methods */\n\n/**\n * Set the disabled state of the widget.\n *\n * This will also update the disabled state of child widgets.\n *\n * @param {boolean} disabled Disable widget\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.mixin.GroupWidget.prototype.setDisabled = function ( disabled ) {\n\tvar i, len;\n\n\t// Parent method\n\t// Note: Calling #setDisabled this way assumes this is mixed into an OO.ui.Widget\n\tOO.ui.Widget.prototype.setDisabled.call( this, disabled );\n\n\t// During construction, #setDisabled is called before the OO.ui.mixin.GroupElement constructor\n\tif ( this.items ) {\n\t\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\t\tthis.items[ i ].updateDisabled();\n\t\t}\n\t}\n\n\treturn this;\n};\n","/**\n * Mixin for widgets used as items in widgets that mix in OO.ui.mixin.GroupWidget.\n *\n * Item widgets have a reference to a OO.ui.mixin.GroupWidget while they are attached to the group. This\n * allows bidirectional communication.\n *\n * Use together with OO.ui.mixin.GroupWidget to make disabled state inheritable.\n *\n * @private\n * @abstract\n * @class\n *\n * @constructor\n */\nOO.ui.mixin.ItemWidget = function OoUiMixinItemWidget() {\n\t//\n};\n\n/* Methods */\n\n/**\n * Check if widget is disabled.\n *\n * Checks parent if present, making disabled state inheritable.\n *\n * @return {boolean} Widget is disabled\n */\nOO.ui.mixin.ItemWidget.prototype.isDisabled = function () {\n\treturn this.disabled ||\n\t\t( this.elementGroup instanceof OO.ui.Widget && this.elementGroup.isDisabled() );\n};\n\n/**\n * Set group element is in.\n *\n * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.mixin.ItemWidget.prototype.setElementGroup = function ( group ) {\n\t// Parent method\n\t// Note: Calling #setElementGroup this way assumes this is mixed into an OO.ui.Element\n\tOO.ui.Element.prototype.setElementGroup.call( this, group );\n\n\t// Initialize item disabled states\n\tthis.updateDisabled();\n\n\treturn this;\n};\n","/**\n * OptionWidgets are special elements that can be selected and configured with data. The\n * data is often unique for each option, but it does not have to be. OptionWidgets are used\n * with OO.ui.SelectWidget to create a selection of mutually exclusive options. For more information\n * and examples, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.AccessKeyedElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.OptionWidget = function OoUiOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.OptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ItemWidget.call( this );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.AccessKeyedElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.selected = false;\n\tthis.highlighted = false;\n\tthis.pressed = false;\n\n\t// Initialization\n\tthis.$element\n\t\t.data( 'oo-ui-optionWidget', this )\n\t\t// Allow programmatic focussing (and by accesskey), but not tabbing\n\t\t.attr( 'tabindex', '-1' )\n\t\t.attr( 'role', 'option' )\n\t\t.attr( 'aria-selected', 'false' )\n\t\t.addClass( 'oo-ui-optionWidget' )\n\t\t.append( this.$label );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OptionWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.AccessKeyedElement );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * Whether this option can be selected. See #setSelected.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.selectable = true;\n\n/**\n * Whether this option can be highlighted. See #setHighlighted.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.highlightable = true;\n\n/**\n * Whether this option can be pressed. See #setPressed.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.pressable = true;\n\n/**\n * Whether this option will be scrolled into view when it is selected.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.scrollIntoViewOnSelect = false;\n\n/* Methods */\n\n/**\n * Check if the option can be selected.\n *\n * @return {boolean} Item is selectable\n */\nOO.ui.OptionWidget.prototype.isSelectable = function () {\n\treturn this.constructor.static.selectable && !this.disabled && this.isVisible();\n};\n\n/**\n * Check if the option can be highlighted. A highlight indicates that the option\n * may be selected when a user presses enter or clicks. Disabled items cannot\n * be highlighted.\n *\n * @return {boolean} Item is highlightable\n */\nOO.ui.OptionWidget.prototype.isHighlightable = function () {\n\treturn this.constructor.static.highlightable && !this.disabled && this.isVisible();\n};\n\n/**\n * Check if the option can be pressed. The pressed state occurs when a user mouses\n * down on an item, but has not yet let go of the mouse.\n *\n * @return {boolean} Item is pressable\n */\nOO.ui.OptionWidget.prototype.isPressable = function () {\n\treturn this.constructor.static.pressable && !this.disabled && this.isVisible();\n};\n\n/**\n * Check if the option is selected.\n *\n * @return {boolean} Item is selected\n */\nOO.ui.OptionWidget.prototype.isSelected = function () {\n\treturn this.selected;\n};\n\n/**\n * Check if the option is highlighted. A highlight indicates that the\n * item may be selected when a user presses enter or clicks.\n *\n * @return {boolean} Item is highlighted\n */\nOO.ui.OptionWidget.prototype.isHighlighted = function () {\n\treturn this.highlighted;\n};\n\n/**\n * Check if the option is pressed. The pressed state occurs when a user mouses\n * down on an item, but has not yet let go of the mouse. The item may appear\n * selected, but it will not be selected until the user releases the mouse.\n *\n * @return {boolean} Item is pressed\n */\nOO.ui.OptionWidget.prototype.isPressed = function () {\n\treturn this.pressed;\n};\n\n/**\n * Set the option’s selected state. In general, all modifications to the selection\n * should be handled by the SelectWidget’s {@link OO.ui.SelectWidget#selectItem selectItem( [item] )}\n * method instead of this method.\n *\n * @param {boolean} [state=false] Select option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OptionWidget.prototype.setSelected = function ( state ) {\n\tif ( this.constructor.static.selectable ) {\n\t\tthis.selected = !!state;\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-optionWidget-selected', state )\n\t\t\t.attr( 'aria-selected', state.toString() );\n\t\tif ( state && this.constructor.static.scrollIntoViewOnSelect ) {\n\t\t\tthis.scrollElementIntoView();\n\t\t}\n\t\tthis.updateThemeClasses();\n\t}\n\treturn this;\n};\n\n/**\n * Set the option’s highlighted state. In general, all programmatic\n * modifications to the highlight should be handled by the\n * SelectWidget’s {@link OO.ui.SelectWidget#highlightItem highlightItem( [item] )}\n * method instead of this method.\n *\n * @param {boolean} [state=false] Highlight option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OptionWidget.prototype.setHighlighted = function ( state ) {\n\tif ( this.constructor.static.highlightable ) {\n\t\tthis.highlighted = !!state;\n\t\tthis.$element.toggleClass( 'oo-ui-optionWidget-highlighted', state );\n\t\tthis.updateThemeClasses();\n\t}\n\treturn this;\n};\n\n/**\n * Set the option’s pressed state. In general, all\n * programmatic modifications to the pressed state should be handled by the\n * SelectWidget’s {@link OO.ui.SelectWidget#pressItem pressItem( [item] )}\n * method instead of this method.\n *\n * @param {boolean} [state=false] Press option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OptionWidget.prototype.setPressed = function ( state ) {\n\tif ( this.constructor.static.pressable ) {\n\t\tthis.pressed = !!state;\n\t\tthis.$element.toggleClass( 'oo-ui-optionWidget-pressed', state );\n\t\tthis.updateThemeClasses();\n\t}\n\treturn this;\n};\n\n/**\n * Get text to match search strings against.\n *\n * The default implementation returns the label text, but subclasses\n * can override this to provide more complex behavior.\n *\n * @return {string|boolean} String to match search string against\n */\nOO.ui.OptionWidget.prototype.getMatchText = function () {\n\tvar label = this.getLabel();\n\treturn typeof label === 'string' ? label : this.$label.text();\n};\n","/**\n * A SelectWidget is of a generic selection of options. The OOUI library contains several types of\n * select widgets, including {@link OO.ui.ButtonSelectWidget button selects},\n * {@link OO.ui.RadioSelectWidget radio selects}, and {@link OO.ui.MenuSelectWidget\n * menu selects}.\n *\n * This class should be used together with OO.ui.OptionWidget or OO.ui.DecoratedOptionWidget. For more\n * information, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // A select widget with three options.\n *     var select = new OO.ui.SelectWidget( {\n *         items: [\n *             new OO.ui.OptionWidget( {\n *                 data: 'a',\n *                 label: 'Option One',\n *             } ),\n *             new OO.ui.OptionWidget( {\n *                 data: 'b',\n *                 label: 'Option Two',\n *             } ),\n *             new OO.ui.OptionWidget( {\n *                 data: 'c',\n *                 label: 'Option Three',\n *             } )\n *         ]\n *     } );\n *     $( document.body ).append( select.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.OptionWidget[]} [items] An array of options to add to the select.\n *  Options are created with {@link OO.ui.OptionWidget OptionWidget} classes. See\n *  the [OOUI documentation on MediaWiki] [2] for examples.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n */\nOO.ui.SelectWidget = function OoUiSelectWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.SelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupWidget.call( this, $.extend( {}, config, { $group: this.$element } ) );\n\n\t// Properties\n\tthis.pressed = false;\n\tthis.selecting = null;\n\tthis.onDocumentMouseUpHandler = this.onDocumentMouseUp.bind( this );\n\tthis.onDocumentMouseMoveHandler = this.onDocumentMouseMove.bind( this );\n\tthis.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );\n\tthis.onDocumentKeyPressHandler = this.onDocumentKeyPress.bind( this );\n\tthis.keyPressBuffer = '';\n\tthis.keyPressBufferTimer = null;\n\tthis.blockMouseOverEvents = 0;\n\n\t// Events\n\tthis.connect( this, {\n\t\ttoggle: 'onToggle'\n\t} );\n\tthis.$element.on( {\n\t\tfocusin: this.onFocus.bind( this ),\n\t\tmousedown: this.onMouseDown.bind( this ),\n\t\tmouseover: this.onMouseOver.bind( this ),\n\t\tmouseleave: this.onMouseLeave.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-selectWidget oo-ui-selectWidget-depressed' )\n\t\t.attr( 'role', 'listbox' );\n\tthis.setFocusOwner( this.$element );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SelectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupWidget );\n\n/* Events */\n\n/**\n * @event highlight\n *\n * A `highlight` event is emitted when the highlight is changed with the #highlightItem method.\n *\n * @param {OO.ui.OptionWidget|null} item Highlighted item\n */\n\n/**\n * @event press\n *\n * A `press` event is emitted when the #pressItem method is used to programmatically modify the\n * pressed state of an option.\n *\n * @param {OO.ui.OptionWidget|null} item Pressed item\n */\n\n/**\n * @event select\n *\n * A `select` event is emitted when the selection is modified programmatically with the #selectItem method.\n *\n * @param {OO.ui.OptionWidget|null} item Selected item\n */\n\n/**\n * @event choose\n * A `choose` event is emitted when an item is chosen with the #chooseItem method.\n * @param {OO.ui.OptionWidget} item Chosen item\n */\n\n/**\n * @event add\n *\n * An `add` event is emitted when options are added to the select with the #addItems method.\n *\n * @param {OO.ui.OptionWidget[]} items Added items\n * @param {number} index Index of insertion point\n */\n\n/**\n * @event remove\n *\n * A `remove` event is emitted when options are removed from the select with the #clearItems\n * or #removeItems methods.\n *\n * @param {OO.ui.OptionWidget[]} items Removed items\n */\n\n/* Methods */\n\n/**\n * Handle focus events\n *\n * @private\n * @param {jQuery.Event} event\n */\nOO.ui.SelectWidget.prototype.onFocus = function ( event ) {\n\tvar item;\n\tif ( event.target === this.$element[ 0 ] ) {\n\t\t// This widget was focussed, e.g. by the user tabbing to it.\n\t\t// The styles for focus state depend on one of the items being selected.\n\t\tif ( !this.findSelectedItem() ) {\n\t\t\titem = this.findFirstSelectableItem();\n\t\t}\n\t} else {\n\t\tif ( event.target.tabIndex === -1 ) {\n\t\t\t// One of the options got focussed (and the event bubbled up here).\n\t\t\t// They can't be tabbed to, but they can be activated using accesskeys.\n\t\t\t// OptionWidgets and focusable UI elements inside them have tabindex=\"-1\" set.\n\t\t\titem = this.findTargetItem( event );\n\t\t} else {\n\t\t\t// There is something actually user-focusable in one of the labels of the options, and the\n\t\t\t// user focussed it (e.g. by tabbing to it). Do nothing (especially, don't change the focus).\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif ( item ) {\n\t\tif ( item.constructor.static.highlightable ) {\n\t\t\tthis.highlightItem( item );\n\t\t} else {\n\t\t\tthis.selectItem( item );\n\t\t}\n\t}\n\n\tif ( event.target !== this.$element[ 0 ] ) {\n\t\tthis.$focusOwner.trigger( 'focus' );\n\t}\n};\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onMouseDown = function ( e ) {\n\tvar item;\n\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.togglePressed( true );\n\t\titem = this.findTargetItem( e );\n\t\tif ( item && item.isSelectable() ) {\n\t\t\tthis.pressItem( item );\n\t\t\tthis.selecting = item;\n\t\t\tthis.getElementDocument().addEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'mousemove', this.onDocumentMouseMoveHandler, true );\n\t\t}\n\t}\n\treturn false;\n};\n\n/**\n * Handle document mouse up events.\n *\n * @private\n * @param {MouseEvent} e Mouse up event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onDocumentMouseUp = function ( e ) {\n\tvar item;\n\n\tthis.togglePressed( false );\n\tif ( !this.selecting ) {\n\t\titem = this.findTargetItem( e );\n\t\tif ( item && item.isSelectable() ) {\n\t\t\tthis.selecting = item;\n\t\t}\n\t}\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT && this.selecting ) {\n\t\tthis.pressItem( null );\n\t\tthis.chooseItem( this.selecting );\n\t\tthis.selecting = null;\n\t}\n\n\tthis.getElementDocument().removeEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n\tthis.getElementDocument().removeEventListener( 'mousemove', this.onDocumentMouseMoveHandler, true );\n\n\treturn false;\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.onMouseUp = function () {\n\tOO.ui.warnDeprecation( 'onMouseUp is deprecated, use onDocumentMouseUp instead' );\n\tthis.onDocumentMouseUp.apply( this, arguments );\n};\n\n/**\n * Handle document mouse move events.\n *\n * @private\n * @param {MouseEvent} e Mouse move event\n */\nOO.ui.SelectWidget.prototype.onDocumentMouseMove = function ( e ) {\n\tvar item;\n\n\tif ( !this.isDisabled() && this.pressed ) {\n\t\titem = this.findTargetItem( e );\n\t\tif ( item && item !== this.selecting && item.isSelectable() ) {\n\t\t\tthis.pressItem( item );\n\t\t\tthis.selecting = item;\n\t\t}\n\t}\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.onMouseMove = function () {\n\tOO.ui.warnDeprecation( 'onMouseMove is deprecated, use onDocumentMouseMove instead' );\n\tthis.onDocumentMouseMove.apply( this, arguments );\n};\n\n/**\n * Handle mouse over events.\n *\n * @private\n * @param {jQuery.Event} e Mouse over event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onMouseOver = function ( e ) {\n\tvar item;\n\tif ( this.blockMouseOverEvents ) {\n\t\treturn;\n\t}\n\tif ( !this.isDisabled() ) {\n\t\titem = this.findTargetItem( e );\n\t\tthis.highlightItem( item && item.isHighlightable() ? item : null );\n\t}\n\treturn false;\n};\n\n/**\n * Handle mouse leave events.\n *\n * @private\n * @param {jQuery.Event} e Mouse over event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onMouseLeave = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.highlightItem( null );\n\t}\n\treturn false;\n};\n\n/**\n * Handle document key down events.\n *\n * @protected\n * @param {KeyboardEvent} e Key down event\n */\nOO.ui.SelectWidget.prototype.onDocumentKeyDown = function ( e ) {\n\tvar nextItem,\n\t\thandled = false,\n\t\tcurrentItem = this.findHighlightedItem() || this.findSelectedItem();\n\n\tif ( !this.isDisabled() && this.isVisible() ) {\n\t\tswitch ( e.keyCode ) {\n\t\t\tcase OO.ui.Keys.ENTER:\n\t\t\t\tif ( currentItem && currentItem.constructor.static.highlightable ) {\n\t\t\t\t\t// Was only highlighted, now let's select it. No-op if already selected.\n\t\t\t\t\tthis.chooseItem( currentItem );\n\t\t\t\t\thandled = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.UP:\n\t\t\tcase OO.ui.Keys.LEFT:\n\t\t\t\tthis.clearKeyPressBuffer();\n\t\t\t\tnextItem = this.findRelativeSelectableItem( currentItem, -1 );\n\t\t\t\thandled = true;\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.DOWN:\n\t\t\tcase OO.ui.Keys.RIGHT:\n\t\t\t\tthis.clearKeyPressBuffer();\n\t\t\t\tnextItem = this.findRelativeSelectableItem( currentItem, 1 );\n\t\t\t\thandled = true;\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.ESCAPE:\n\t\t\tcase OO.ui.Keys.TAB:\n\t\t\t\tif ( currentItem && currentItem.constructor.static.highlightable ) {\n\t\t\t\t\tcurrentItem.setHighlighted( false );\n\t\t\t\t}\n\t\t\t\tthis.unbindDocumentKeyDownListener();\n\t\t\t\tthis.unbindDocumentKeyPressListener();\n\t\t\t\t// Don't prevent tabbing away / defocusing\n\t\t\t\thandled = false;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( nextItem ) {\n\t\t\tif ( nextItem.constructor.static.highlightable ) {\n\t\t\t\tthis.highlightItem( nextItem );\n\t\t\t} else {\n\t\t\t\tthis.chooseItem( nextItem );\n\t\t\t}\n\t\t\tthis.scrollItemIntoView( nextItem );\n\t\t}\n\n\t\tif ( handled ) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t}\n\t}\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.onKeyDown = function () {\n\tOO.ui.warnDeprecation( 'onKeyDown is deprecated, use onDocumentKeyDown instead' );\n\tthis.onDocumentKeyDown.apply( this, arguments );\n};\n\n/**\n * Bind document key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.bindKeyDownListener = function () {\n\tOO.ui.warnDeprecation( 'bindKeyDownListener is deprecated, use bindDocumentKeyDownListener instead' );\n\tthis.bindDocumentKeyDownListener.apply( this, arguments );\n};\n\n/**\n * Unbind document key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.unbindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {\n\tOO.ui.warnDeprecation( 'unbindKeyDownListener is deprecated, use unbindDocumentKeyDownListener instead' );\n\tthis.unbindDocumentKeyDownListener.apply( this, arguments );\n};\n\n/**\n * Scroll item into view, preventing spurious mouse highlight actions from happening.\n *\n * @param {OO.ui.OptionWidget} item Item to scroll into view\n */\nOO.ui.SelectWidget.prototype.scrollItemIntoView = function ( item ) {\n\tvar widget = this;\n\t// Chromium's Blink engine will generate spurious 'mouseover' events during programmatic scrolling\n\t// and around 100-150 ms after it is finished.\n\tthis.blockMouseOverEvents++;\n\titem.scrollElementIntoView().done( function () {\n\t\tsetTimeout( function () {\n\t\t\twidget.blockMouseOverEvents--;\n\t\t}, 200 );\n\t} );\n};\n\n/**\n * Clear the key-press buffer\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.clearKeyPressBuffer = function () {\n\tif ( this.keyPressBufferTimer ) {\n\t\tclearTimeout( this.keyPressBufferTimer );\n\t\tthis.keyPressBufferTimer = null;\n\t}\n\tthis.keyPressBuffer = '';\n};\n\n/**\n * Handle key press events.\n *\n * @protected\n * @param {KeyboardEvent} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onDocumentKeyPress = function ( e ) {\n\tvar c, filter, item;\n\n\tif ( !e.charCode ) {\n\t\tif ( e.keyCode === OO.ui.Keys.BACKSPACE && this.keyPressBuffer !== '' ) {\n\t\t\tthis.keyPressBuffer = this.keyPressBuffer.substr( 0, this.keyPressBuffer.length - 1 );\n\t\t\treturn false;\n\t\t}\n\t\treturn;\n\t}\n\t// eslint-disable-next-line no-restricted-properties\n\tif ( String.fromCodePoint ) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tc = String.fromCodePoint( e.charCode );\n\t} else {\n\t\tc = String.fromCharCode( e.charCode );\n\t}\n\n\tif ( this.keyPressBufferTimer ) {\n\t\tclearTimeout( this.keyPressBufferTimer );\n\t}\n\tthis.keyPressBufferTimer = setTimeout( this.clearKeyPressBuffer.bind( this ), 1500 );\n\n\titem = this.findHighlightedItem() || this.findSelectedItem();\n\n\tif ( this.keyPressBuffer === c ) {\n\t\t// Common (if weird) special case: typing \"xxxx\" will cycle through all\n\t\t// the items beginning with \"x\".\n\t\tif ( item ) {\n\t\t\titem = this.findRelativeSelectableItem( item, 1 );\n\t\t}\n\t} else {\n\t\tthis.keyPressBuffer += c;\n\t}\n\n\tfilter = this.getItemMatcher( this.keyPressBuffer, false );\n\tif ( !item || !filter( item ) ) {\n\t\titem = this.findRelativeSelectableItem( item, 1, filter );\n\t}\n\tif ( item ) {\n\t\tif ( this.isVisible() && item.constructor.static.highlightable ) {\n\t\t\tthis.highlightItem( item );\n\t\t} else {\n\t\t\tthis.chooseItem( item );\n\t\t}\n\t\tthis.scrollItemIntoView( item );\n\t}\n\n\te.preventDefault();\n\te.stopPropagation();\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.onKeyPress = function () {\n\tOO.ui.warnDeprecation( 'onKeyPress is deprecated, use onDocumentKeyPress instead' );\n\tthis.onDocumentKeyPress.apply( this, arguments );\n};\n\n/**\n * Get a matcher for the specific string\n *\n * @protected\n * @param {string} s String to match against items\n * @param {boolean} [exact=false] Only accept exact matches\n * @return {Function} function ( OO.ui.OptionWidget ) => boolean\n */\nOO.ui.SelectWidget.prototype.getItemMatcher = function ( s, exact ) {\n\tvar re;\n\n\t// eslint-disable-next-line no-restricted-properties\n\tif ( s.normalize ) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\ts = s.normalize();\n\t}\n\ts = exact ? s.trim() : s.replace( /^\\s+/, '' );\n\tre = '^\\\\s*' + s.replace( /([\\\\{}()|.?*+\\-^$[\\]])/g, '\\\\$1' ).replace( /\\s+/g, '\\\\s+' );\n\tif ( exact ) {\n\t\tre += '\\\\s*$';\n\t}\n\tre = new RegExp( re, 'i' );\n\treturn function ( item ) {\n\t\tvar matchText = item.getMatchText();\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tif ( matchText.normalize ) {\n\t\t\t// eslint-disable-next-line no-restricted-properties\n\t\t\tmatchText = matchText.normalize();\n\t\t}\n\t\treturn re.test( matchText );\n\t};\n};\n\n/**\n * Bind document key press listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindDocumentKeyPressListener = function () {\n\tthis.getElementDocument().addEventListener( 'keypress', this.onDocumentKeyPressHandler, true );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.bindKeyPressListener = function () {\n\tOO.ui.warnDeprecation( 'bindKeyPressListener is deprecated, use bindDocumentKeyPressListener instead' );\n\tthis.bindDocumentKeyPressListener.apply( this, arguments );\n};\n\n/**\n * Unbind document key down listener.\n *\n * If you override this, be sure to call this.clearKeyPressBuffer() from your\n * implementation.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.unbindDocumentKeyPressListener = function () {\n\tthis.getElementDocument().removeEventListener( 'keypress', this.onDocumentKeyPressHandler, true );\n\tthis.clearKeyPressBuffer();\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.SelectWidget.prototype.unbindKeyPressListener = function () {\n\tOO.ui.warnDeprecation( 'unbindKeyPressListener is deprecated, use unbindDocumentKeyPressListener instead' );\n\tthis.unbindDocumentKeyPressListener.apply( this, arguments );\n};\n\n/**\n * Visibility change handler\n *\n * @protected\n * @param {boolean} visible\n */\nOO.ui.SelectWidget.prototype.onToggle = function ( visible ) {\n\tif ( !visible ) {\n\t\tthis.clearKeyPressBuffer();\n\t}\n};\n\n/**\n * Get the closest item to a jQuery.Event.\n *\n * @private\n * @param {jQuery.Event} e\n * @return {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found\n */\nOO.ui.SelectWidget.prototype.findTargetItem = function ( e ) {\n\tvar $option = $( e.target ).closest( '.oo-ui-optionWidget' );\n\tif ( !$option.closest( '.oo-ui-selectWidget' ).is( this.$element ) ) {\n\t\treturn null;\n\t}\n\treturn $option.data( 'oo-ui-optionWidget' ) || null;\n};\n\n/**\n * Find selected item.\n *\n * @return {OO.ui.OptionWidget|null} Selected item, `null` if no item is selected\n */\nOO.ui.SelectWidget.prototype.findSelectedItem = function () {\n\tvar i, len;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tif ( this.items[ i ].isSelected() ) {\n\t\t\treturn this.items[ i ];\n\t\t}\n\t}\n\treturn null;\n};\n\n/**\n * Find highlighted item.\n *\n * @return {OO.ui.OptionWidget|null} Highlighted item, `null` if no item is highlighted\n */\nOO.ui.SelectWidget.prototype.findHighlightedItem = function () {\n\tvar i, len;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tif ( this.items[ i ].isHighlighted() ) {\n\t\t\treturn this.items[ i ];\n\t\t}\n\t}\n\treturn null;\n};\n\n/**\n * Toggle pressed state.\n *\n * Press is a state that occurs when a user mouses down on an item, but\n * has not yet let go of the mouse. The item may appear selected, but it will not be selected\n * until the user releases the mouse.\n *\n * @param {boolean} pressed An option is being pressed\n */\nOO.ui.SelectWidget.prototype.togglePressed = function ( pressed ) {\n\tif ( pressed === undefined ) {\n\t\tpressed = !this.pressed;\n\t}\n\tif ( pressed !== this.pressed ) {\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-selectWidget-pressed', pressed )\n\t\t\t.toggleClass( 'oo-ui-selectWidget-depressed', !pressed );\n\t\tthis.pressed = pressed;\n\t}\n};\n\n/**\n * Highlight an option. If the `item` param is omitted, no options will be highlighted\n * and any existing highlight will be removed. The highlight is mutually exclusive.\n *\n * @param {OO.ui.OptionWidget} [item] Item to highlight, omit for no highlight\n * @fires highlight\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.highlightItem = function ( item ) {\n\tvar i, len, highlighted,\n\t\tchanged = false;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\thighlighted = this.items[ i ] === item;\n\t\tif ( this.items[ i ].isHighlighted() !== highlighted ) {\n\t\t\tthis.items[ i ].setHighlighted( highlighted );\n\t\t\tchanged = true;\n\t\t}\n\t}\n\tif ( changed ) {\n\t\tif ( item ) {\n\t\t\tthis.$focusOwner.attr( 'aria-activedescendant', item.getElementId() );\n\t\t} else {\n\t\t\tthis.$focusOwner.removeAttr( 'aria-activedescendant' );\n\t\t}\n\t\tthis.emit( 'highlight', item );\n\t}\n\n\treturn this;\n};\n\n/**\n * Fetch an item by its label.\n *\n * @param {string} label Label of the item to select.\n * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches\n * @return {OO.ui.Element|null} Item with equivalent label, `null` if none exists\n */\nOO.ui.SelectWidget.prototype.getItemFromLabel = function ( label, prefix ) {\n\tvar i, item, found,\n\t\tlen = this.items.length,\n\t\tfilter = this.getItemMatcher( label, true );\n\n\tfor ( i = 0; i < len; i++ ) {\n\t\titem = this.items[ i ];\n\t\tif ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {\n\t\t\treturn item;\n\t\t}\n\t}\n\n\tif ( prefix ) {\n\t\tfound = null;\n\t\tfilter = this.getItemMatcher( label, false );\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\titem = this.items[ i ];\n\t\t\tif ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {\n\t\t\t\tif ( found ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tfound = item;\n\t\t\t}\n\t\t}\n\t\tif ( found ) {\n\t\t\treturn found;\n\t\t}\n\t}\n\n\treturn null;\n};\n\n/**\n * Programmatically select an option by its label. If the item does not exist,\n * all options will be deselected.\n *\n * @param {string} [label] Label of the item to select.\n * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches\n * @fires select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.selectItemByLabel = function ( label, prefix ) {\n\tvar itemFromLabel = this.getItemFromLabel( label, !!prefix );\n\tif ( label === undefined || !itemFromLabel ) {\n\t\treturn this.selectItem();\n\t}\n\treturn this.selectItem( itemFromLabel );\n};\n\n/**\n * Programmatically select an option by its data. If the `data` parameter is omitted,\n * or if the item does not exist, all options will be deselected.\n *\n * @param {Object|string} [data] Value of the item to select, omit to deselect all\n * @fires select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.selectItemByData = function ( data ) {\n\tvar itemFromData = this.findItemFromData( data );\n\tif ( data === undefined || !itemFromData ) {\n\t\treturn this.selectItem();\n\t}\n\treturn this.selectItem( itemFromData );\n};\n\n/**\n * Programmatically select an option by its reference. If the `item` parameter is omitted,\n * all options will be deselected.\n *\n * @param {OO.ui.OptionWidget} [item] Item to select, omit to deselect all\n * @fires select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n*/\nOO.ui.SelectWidget.prototype.selectItem = function ( item ) {\n\tvar i, len, selected,\n\t\tchanged = false;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tselected = this.items[ i ] === item;\n\t\tif ( this.items[ i ].isSelected() !== selected ) {\n\t\t\tthis.items[ i ].setSelected( selected );\n\t\t\tchanged = true;\n\t\t}\n\t}\n\tif ( changed ) {\n\t\tif ( item && !item.constructor.static.highlightable ) {\n\t\t\tif ( item ) {\n\t\t\t\tthis.$focusOwner.attr( 'aria-activedescendant', item.getElementId() );\n\t\t\t} else {\n\t\t\t\tthis.$focusOwner.removeAttr( 'aria-activedescendant' );\n\t\t\t}\n\t\t}\n\t\tthis.emit( 'select', item );\n\t}\n\n\treturn this;\n};\n\n/**\n * Press an item.\n *\n * Press is a state that occurs when a user mouses down on an item, but has not\n * yet let go of the mouse. The item may appear selected, but it will not be selected until the user\n * releases the mouse.\n *\n * @param {OO.ui.OptionWidget} [item] Item to press, omit to depress all\n * @fires press\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.pressItem = function ( item ) {\n\tvar i, len, pressed,\n\t\tchanged = false;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tpressed = this.items[ i ] === item;\n\t\tif ( this.items[ i ].isPressed() !== pressed ) {\n\t\t\tthis.items[ i ].setPressed( pressed );\n\t\t\tchanged = true;\n\t\t}\n\t}\n\tif ( changed ) {\n\t\tthis.emit( 'press', item );\n\t}\n\n\treturn this;\n};\n\n/**\n * Choose an item.\n *\n * Note that ‘choose’ should never be modified programmatically. A user can choose\n * an option with the keyboard or mouse and it becomes selected. To select an item programmatically,\n * use the #selectItem method.\n *\n * This method is identical to #selectItem, but may vary in subclasses that take additional action\n * when users choose an item with the keyboard or mouse.\n *\n * @param {OO.ui.OptionWidget} item Item to choose\n * @fires choose\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.chooseItem = function ( item ) {\n\tif ( item ) {\n\t\tthis.selectItem( item );\n\t\tthis.emit( 'choose', item );\n\t}\n\n\treturn this;\n};\n\n/**\n * Find an option by its position relative to the specified item (or to the start of the option array,\n * if item is `null`). The direction in which to search through the option array is specified with a\n * number: -1 for reverse (the default) or 1 for forward. The method will return an option, or\n * `null` if there are no options in the array.\n *\n * @param {OO.ui.OptionWidget|null} item Item to describe the start position, or `null` to start at the beginning of the array.\n * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward\n * @param {Function} [filter] Only consider items for which this function returns\n *  true. Function takes an OO.ui.OptionWidget and returns a boolean.\n * @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the select\n */\nOO.ui.SelectWidget.prototype.findRelativeSelectableItem = function ( item, direction, filter ) {\n\tvar currentIndex, nextIndex, i,\n\t\tincrease = direction > 0 ? 1 : -1,\n\t\tlen = this.items.length;\n\n\tif ( item instanceof OO.ui.OptionWidget ) {\n\t\tcurrentIndex = this.items.indexOf( item );\n\t\tnextIndex = ( currentIndex + increase + len ) % len;\n\t} else {\n\t\t// If no item is selected and moving forward, start at the beginning.\n\t\t// If moving backward, start at the end.\n\t\tnextIndex = direction > 0 ? 0 : len - 1;\n\t}\n\n\tfor ( i = 0; i < len; i++ ) {\n\t\titem = this.items[ nextIndex ];\n\t\tif (\n\t\t\titem instanceof OO.ui.OptionWidget && item.isSelectable() &&\n\t\t\t( !filter || filter( item ) )\n\t\t) {\n\t\t\treturn item;\n\t\t}\n\t\tnextIndex = ( nextIndex + increase + len ) % len;\n\t}\n\treturn null;\n};\n\n/**\n * Find the next selectable item or `null` if there are no selectable items.\n * Disabled options and menu-section markers and breaks are not selectable.\n *\n * @return {OO.ui.OptionWidget|null} Item, `null` if there aren't any selectable items\n */\nOO.ui.SelectWidget.prototype.findFirstSelectableItem = function () {\n\treturn this.findRelativeSelectableItem( null, 1 );\n};\n\n/**\n * Add an array of options to the select. Optionally, an index number can be used to\n * specify an insertion point.\n *\n * @param {OO.ui.OptionWidget[]} items Items to add\n * @param {number} [index] Index to insert items after\n * @fires add\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.addItems = function ( items, index ) {\n\t// Mixin method\n\tOO.ui.mixin.GroupWidget.prototype.addItems.call( this, items, index );\n\n\t// Always provide an index, even if it was omitted\n\tthis.emit( 'add', items, index === undefined ? this.items.length - items.length - 1 : index );\n\n\treturn this;\n};\n\n/**\n * Remove the specified array of options from the select. Options will be detached\n * from the DOM, not removed, so they can be reused later. To remove all options from\n * the select, you may wish to use the #clearItems method instead.\n *\n * @param {OO.ui.OptionWidget[]} items Items to remove\n * @fires remove\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.removeItems = function ( items ) {\n\tvar i, len, item;\n\n\t// Deselect items being removed\n\tfor ( i = 0, len = items.length; i < len; i++ ) {\n\t\titem = items[ i ];\n\t\tif ( item.isSelected() ) {\n\t\t\tthis.selectItem( null );\n\t\t}\n\t}\n\n\t// Mixin method\n\tOO.ui.mixin.GroupWidget.prototype.removeItems.call( this, items );\n\n\tthis.emit( 'remove', items );\n\n\treturn this;\n};\n\n/**\n * Clear all options from the select. Options will be detached from the DOM, not removed,\n * so that they can be reused later. To remove a subset of options from the select, use\n * the #removeItems method.\n *\n * @fires remove\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.clearItems = function () {\n\tvar items = this.items.slice();\n\n\t// Mixin method\n\tOO.ui.mixin.GroupWidget.prototype.clearItems.call( this );\n\n\t// Clear selection\n\tthis.selectItem( null );\n\n\tthis.emit( 'remove', items );\n\n\treturn this;\n};\n\n/**\n * Set the DOM element which has focus while the user is interacting with this SelectWidget.\n *\n * This is used to set `aria-activedescendant` and `aria-expanded` on it.\n *\n * @protected\n * @param {jQuery} $focusOwner\n */\nOO.ui.SelectWidget.prototype.setFocusOwner = function ( $focusOwner ) {\n\tthis.$focusOwner = $focusOwner;\n};\n","/**\n * DecoratedOptionWidgets are {@link OO.ui.OptionWidget options} that can be configured\n * with an {@link OO.ui.mixin.IconElement icon} and/or {@link OO.ui.mixin.IndicatorElement indicator}.\n * This class is used with OO.ui.SelectWidget to create a selection of mutually exclusive\n * options. For more information about options and selects, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Decorated options in a select widget.\n *     var select = new OO.ui.SelectWidget( {\n *         items: [\n *             new OO.ui.DecoratedOptionWidget( {\n *                 data: 'a',\n *                 label: 'Option with icon',\n *                 icon: 'help'\n *             } ),\n *             new OO.ui.DecoratedOptionWidget( {\n *                 data: 'b',\n *                 label: 'Option with indicator',\n *                 indicator: 'next'\n *             } )\n *         ]\n *     } );\n *     $( document.body ).append( select.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.OptionWidget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.DecoratedOptionWidget = function OoUiDecoratedOptionWidget( config ) {\n\t// Parent constructor\n\tOO.ui.DecoratedOptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-decoratedOptionWidget' )\n\t\t.prepend( this.$icon )\n\t\t.append( this.$indicator );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.DecoratedOptionWidget, OO.ui.OptionWidget );\nOO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IndicatorElement );\n","/**\n * MenuOptionWidget is an option widget that looks like a menu item. The class is used with\n * OO.ui.MenuSelectWidget to create a menu of mutually exclusive options. Please see\n * the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @extends OO.ui.DecoratedOptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.MenuOptionWidget = function OoUiMenuOptionWidget( config ) {\n\t// Parent constructor\n\tOO.ui.MenuOptionWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.checkIcon = new OO.ui.IconWidget( {\n\t\ticon: 'check',\n\t\tclasses: [ 'oo-ui-menuOptionWidget-checkIcon' ]\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.prepend( this.checkIcon.$element )\n\t\t.addClass( 'oo-ui-menuOptionWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuOptionWidget, OO.ui.DecoratedOptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuOptionWidget.static.scrollIntoViewOnSelect = true;\n","/**\n * MenuSectionOptionWidgets are used inside {@link OO.ui.MenuSelectWidget menu select widgets} to group one or more related\n * {@link OO.ui.MenuOptionWidget menu options}. MenuSectionOptionWidgets cannot be highlighted or selected.\n *\n *     @example\n *     var dropdown = new OO.ui.DropdownWidget( {\n *         menu: {\n *             items: [\n *                 new OO.ui.MenuSectionOptionWidget( {\n *                     label: 'Dogs'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'corgi',\n *                     label: 'Welsh Corgi'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'poodle',\n *                     label: 'Standard Poodle'\n *                 } ),\n *                 new OO.ui.MenuSectionOptionWidget( {\n *                     label: 'Cats'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'lion',\n *                     label: 'Lion'\n *                 } )\n *             ]\n *         }\n *     } );\n *     $( document.body ).append( dropdown.$element );\n *\n * @class\n * @extends OO.ui.DecoratedOptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.MenuSectionOptionWidget = function OoUiMenuSectionOptionWidget( config ) {\n\t// Parent constructor\n\tOO.ui.MenuSectionOptionWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-menuSectionOptionWidget' )\n\t\t.removeAttr( 'role aria-selected' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuSectionOptionWidget, OO.ui.DecoratedOptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuSectionOptionWidget.static.selectable = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuSectionOptionWidget.static.highlightable = false;\n","/**\n * MenuSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains options and\n * is used together with OO.ui.MenuOptionWidget. It is designed be used as part of another widget.\n * See {@link OO.ui.DropdownWidget DropdownWidget}, {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget},\n * and {@link OO.ui.mixin.LookupElement LookupElement} for examples of widgets that contain menus.\n * MenuSelectWidgets themselves are not instantiated directly, rather subclassed\n * and customized to be opened, closed, and displayed as needed.\n *\n * By default, menus are clipped to the visible viewport and are not visible when a user presses the\n * mouse outside the menu.\n *\n * Menus also have support for keyboard interaction:\n *\n * - Enter/Return key: choose and select a menu option\n * - Up-arrow key: highlight the previous menu option\n * - Down-arrow key: highlight the next menu option\n * - Esc key: hide the menu\n *\n * Unlike most widgets, MenuSelectWidget is initially hidden and must be shown by calling #toggle.\n *\n * Please see the [OOUI documentation on MediaWiki][1] for more information.\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.ClippableElement\n * @mixins OO.ui.mixin.FloatableElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.TextInputWidget} [input] Text input used to implement option highlighting for menu items that match\n *  the text the user types. This config is used by {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget}\n *  and {@link OO.ui.mixin.LookupElement LookupElement}\n * @cfg {jQuery} [$input] Text input used to implement option highlighting for menu items that match\n *  the text the user types. This config is used by {@link OO.ui.TagMultiselectWidget TagMultiselectWidget}\n * @cfg {OO.ui.Widget} [widget] Widget associated with the menu's active state. If the user clicks the mouse\n *  anywhere on the page outside of this widget, the menu is hidden. For example, if there is a button\n *  that toggles the menu's visibility on click, the menu will be hidden then re-shown when the user clicks\n *  that button, unless the button (or its parent widget) is passed in here.\n * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu.\n * @cfg {jQuery} [$autoCloseIgnore] If these elements are clicked, don't auto-hide the menu.\n * @cfg {boolean} [hideOnChoose=true] Hide the menu when the user chooses an option.\n * @cfg {boolean} [filterFromInput=false] Filter the displayed options from the input\n * @cfg {boolean} [highlightOnFilter] Highlight the first result when filtering\n * @param {number|string} [width] Width of the menu as a number of pixels or CSS string with unit suffix,\n *  used by {@link OO.ui.mixin.ClippableElement ClippableElement}\n */\nOO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MenuSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );\n\tOO.ui.mixin.FloatableElement.call( this, config );\n\n\t// Initial vertical positions other than 'center' will result in\n\t// the menu being flipped if there is not enough space in the container.\n\t// Store the original position so we know what to reset to.\n\tthis.originalVerticalPosition = this.verticalPosition;\n\n\t// Properties\n\tthis.autoHide = config.autoHide === undefined || !!config.autoHide;\n\tthis.hideOnChoose = config.hideOnChoose === undefined || !!config.hideOnChoose;\n\tthis.filterFromInput = !!config.filterFromInput;\n\tthis.$input = config.$input ? config.$input : config.input ? config.input.$input : null;\n\tthis.$widget = config.widget ? config.widget.$element : null;\n\tthis.$autoCloseIgnore = config.$autoCloseIgnore || $( [] );\n\tthis.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );\n\tthis.onInputEditHandler = OO.ui.debounce( this.updateItemVisibility.bind( this ), 100 );\n\tthis.highlightOnFilter = !!config.highlightOnFilter;\n\tthis.width = config.width;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-menuSelectWidget' );\n\tif ( config.widget ) {\n\t\tthis.setFocusOwner( config.widget.$tabIndexed );\n\t}\n\n\t// Initially hidden - using #toggle may cause errors if subclasses override toggle with methods\n\t// that reference properties not initialized at that time of parent class construction\n\t// TODO: Find a better way to handle post-constructor setup\n\tthis.visible = false;\n\tthis.$element.addClass( 'oo-ui-element-hidden' );\n\tthis.$focusOwner.attr( 'aria-expanded', 'false' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.ClippableElement );\nOO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.FloatableElement );\n\n/* Events */\n\n/**\n * @event ready\n *\n * The menu is ready: it is visible and has been positioned and clipped.\n */\n\n/* Static properties */\n\n/**\n * Positions to flip to if there isn't room in the container for the\n * menu in a specific direction.\n *\n * @property {Object.<string,string>}\n */\nOO.ui.MenuSelectWidget.static.flippedPositions = {\n\tbelow: 'above',\n\tabove: 'below',\n\ttop: 'bottom',\n\tbottom: 'top'\n};\n\n/* Methods */\n\n/**\n * Handles document mouse down events.\n *\n * @protected\n * @param {MouseEvent} e Mouse down event\n */\nOO.ui.MenuSelectWidget.prototype.onDocumentMouseDown = function ( e ) {\n\tif (\n\t\tthis.isVisible() &&\n\t\t!OO.ui.contains(\n\t\t\tthis.$element.add( this.$widget ).add( this.$autoCloseIgnore ).get(),\n\t\t\te.target,\n\t\t\ttrue\n\t\t)\n\t) {\n\t\tthis.toggle( false );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.onDocumentKeyDown = function ( e ) {\n\tvar currentItem = this.findHighlightedItem() || this.findSelectedItem();\n\n\tif ( !this.isDisabled() && this.isVisible() ) {\n\t\tswitch ( e.keyCode ) {\n\t\t\tcase OO.ui.Keys.LEFT:\n\t\t\tcase OO.ui.Keys.RIGHT:\n\t\t\t\t// Do nothing if a text field is associated, arrow keys will be handled natively\n\t\t\t\tif ( !this.$input ) {\n\t\t\t\t\tOO.ui.MenuSelectWidget.parent.prototype.onDocumentKeyDown.call( this, e );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.ESCAPE:\n\t\t\tcase OO.ui.Keys.TAB:\n\t\t\t\tif ( currentItem ) {\n\t\t\t\t\tcurrentItem.setHighlighted( false );\n\t\t\t\t}\n\t\t\t\tthis.toggle( false );\n\t\t\t\t// Don't prevent tabbing away, prevent defocusing\n\t\t\t\tif ( e.keyCode === OO.ui.Keys.ESCAPE ) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tOO.ui.MenuSelectWidget.parent.prototype.onDocumentKeyDown.call( this, e );\n\t\t\t\treturn;\n\t\t}\n\t}\n};\n\n/**\n * Update menu item visibility and clipping after input changes (if filterFromInput is enabled)\n * or after items were added/removed (always).\n *\n * @protected\n */\nOO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {\n\tvar i, item, items, visible, section, sectionEmpty, filter, exactFilter,\n\t\tanyVisible = false,\n\t\tlen = this.items.length,\n\t\tshowAll = !this.isVisible(),\n\t\texactMatch = false;\n\n\tif ( this.$input && this.filterFromInput ) {\n\t\tfilter = showAll ? null : this.getItemMatcher( this.$input.val() );\n\t\texactFilter = this.getItemMatcher( this.$input.val(), true );\n\t\t// Hide non-matching options, and also hide section headers if all options\n\t\t// in their section are hidden.\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\titem = this.items[ i ];\n\t\t\tif ( item instanceof OO.ui.MenuSectionOptionWidget ) {\n\t\t\t\tif ( section ) {\n\t\t\t\t\t// If the previous section was empty, hide its header\n\t\t\t\t\tsection.toggle( showAll || !sectionEmpty );\n\t\t\t\t}\n\t\t\t\tsection = item;\n\t\t\t\tsectionEmpty = true;\n\t\t\t} else if ( item instanceof OO.ui.OptionWidget ) {\n\t\t\t\tvisible = showAll || filter( item );\n\t\t\t\texactMatch = exactMatch || exactFilter( item );\n\t\t\t\tanyVisible = anyVisible || visible;\n\t\t\t\tsectionEmpty = sectionEmpty && !visible;\n\t\t\t\titem.toggle( visible );\n\t\t\t}\n\t\t}\n\t\t// Process the final section\n\t\tif ( section ) {\n\t\t\tsection.toggle( showAll || !sectionEmpty );\n\t\t}\n\n\t\tif ( anyVisible && this.items.length && !exactMatch ) {\n\t\t\tthis.scrollItemIntoView( this.items[ 0 ] );\n\t\t}\n\n\t\tif ( !anyVisible ) {\n\t\t\tthis.highlightItem( null );\n\t\t}\n\n\t\tthis.$element.toggleClass( 'oo-ui-menuSelectWidget-invisible', !anyVisible );\n\n\t\tif ( this.highlightOnFilter ) {\n\t\t\t// Highlight the first item on the list\n\t\t\titem = null;\n\t\t\titems = this.getItems();\n\t\t\tfor ( i = 0; i < items.length; i++ ) {\n\t\t\t\tif ( items[ i ].isVisible() ) {\n\t\t\t\t\titem = items[ i ];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.highlightItem( item );\n\t\t}\n\n\t}\n\n\t// Reevaluate clipping\n\tthis.clip();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.bindDocumentKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.on( 'keydown', this.onDocumentKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.bindDocumentKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindDocumentKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.off( 'keydown', this.onDocumentKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.unbindDocumentKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.bindDocumentKeyPressListener = function () {\n\tif ( this.$input ) {\n\t\tif ( this.filterFromInput ) {\n\t\t\tthis.$input.on( 'keydown mouseup cut paste change input select', this.onInputEditHandler );\n\t\t\tthis.updateItemVisibility();\n\t\t}\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.bindDocumentKeyPressListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindDocumentKeyPressListener = function () {\n\tif ( this.$input ) {\n\t\tif ( this.filterFromInput ) {\n\t\t\tthis.$input.off( 'keydown mouseup cut paste change input select', this.onInputEditHandler );\n\t\t\tthis.updateItemVisibility();\n\t\t}\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.unbindDocumentKeyPressListener.call( this );\n\t}\n};\n\n/**\n * Choose an item.\n *\n * When a user chooses an item, the menu is closed, unless the hideOnChoose config option is set to false.\n *\n * Note that ‘choose’ should never be modified programmatically. A user can choose an option with the keyboard\n * or mouse and it becomes selected. To select an item programmatically, use the #selectItem method.\n *\n * @param {OO.ui.OptionWidget} item Item to choose\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MenuSelectWidget.prototype.chooseItem = function ( item ) {\n\tOO.ui.MenuSelectWidget.parent.prototype.chooseItem.call( this, item );\n\tif ( this.hideOnChoose ) {\n\t\tthis.toggle( false );\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.addItems = function ( items, index ) {\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.addItems.call( this, items, index );\n\n\tthis.updateItemVisibility();\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.removeItems = function ( items ) {\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.removeItems.call( this, items );\n\n\tthis.updateItemVisibility();\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.clearItems = function () {\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.clearItems.call( this );\n\n\tthis.updateItemVisibility();\n\n\treturn this;\n};\n\n/**\n * Toggle visibility of the menu. The menu is initially hidden and must be shown by calling\n * `.toggle( true )` after its #$element is attached to the DOM.\n *\n * Do not show the menu while it is not attached to the DOM. The calculations required to display\n * it in the right place and with the right dimensions only work correctly while it is attached.\n * Side-effects may include broken interface and exceptions being thrown. This wasn't always\n * strictly enforced, so currently it only generates a warning in the browser console.\n *\n * @fires ready\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {\n\tvar change, originalHeight, flippedHeight;\n\n\tvisible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;\n\tchange = visible !== this.isVisible();\n\n\tif ( visible && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'MenuSelectWidget#toggle: Before calling this method, the menu must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\n\tif ( change && visible ) {\n\t\t// Reset position before showing the popup again. It's possible we no longer need to flip\n\t\t// (e.g. if the user scrolled).\n\t\tthis.setVerticalPosition( this.originalVerticalPosition );\n\t}\n\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.toggle.call( this, visible );\n\n\tif ( change ) {\n\t\tif ( visible ) {\n\n\t\t\tif ( this.width ) {\n\t\t\t\tthis.setIdealSize( this.width );\n\t\t\t} else if ( this.$floatableContainer ) {\n\t\t\t\tthis.$clippable.css( 'width', 'auto' );\n\t\t\t\tthis.setIdealSize(\n\t\t\t\t\tthis.$floatableContainer[ 0 ].offsetWidth > this.$clippable[ 0 ].offsetWidth ?\n\t\t\t\t\t\t// Dropdown is smaller than handle so expand to width\n\t\t\t\t\t\tthis.$floatableContainer[ 0 ].offsetWidth :\n\t\t\t\t\t\t// Dropdown is larger than handle so auto size\n\t\t\t\t\t\t'auto'\n\t\t\t\t);\n\t\t\t\tthis.$clippable.css( 'width', '' );\n\t\t\t}\n\n\t\t\tthis.togglePositioning( !!this.$floatableContainer );\n\t\t\tthis.toggleClipping( true );\n\n\t\t\tthis.bindDocumentKeyDownListener();\n\t\t\tthis.bindDocumentKeyPressListener();\n\n\t\t\tif (\n\t\t\t\t( this.isClippedVertically() || this.isFloatableOutOfView() ) &&\n\t\t\t\tthis.originalVerticalPosition !== 'center'\n\t\t\t) {\n\t\t\t\t// If opening the menu in one direction causes it to be clipped, flip it\n\t\t\t\toriginalHeight = this.$element.height();\n\t\t\t\tthis.setVerticalPosition(\n\t\t\t\t\tthis.constructor.static.flippedPositions[ this.originalVerticalPosition ]\n\t\t\t\t);\n\t\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t// If flipping also causes it to be clipped, open in whichever direction\n\t\t\t\t\t// we have more space\n\t\t\t\t\tflippedHeight = this.$element.height();\n\t\t\t\t\tif ( originalHeight > flippedHeight ) {\n\t\t\t\t\t\tthis.setVerticalPosition( this.originalVerticalPosition );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Note that we do not flip the menu's opening direction if the clipping changes\n\t\t\t// later (e.g. after the user scrolls), that seems like it would be annoying\n\n\t\t\tthis.$focusOwner.attr( 'aria-expanded', 'true' );\n\n\t\t\tif ( this.findSelectedItem() ) {\n\t\t\t\tthis.$focusOwner.attr( 'aria-activedescendant', this.findSelectedItem().getElementId() );\n\t\t\t\tthis.findSelectedItem().scrollElementIntoView( { duration: 0 } );\n\t\t\t}\n\n\t\t\t// Auto-hide\n\t\t\tif ( this.autoHide ) {\n\t\t\t\tthis.getElementDocument().addEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\t\t\t}\n\n\t\t\tthis.emit( 'ready' );\n\t\t} else {\n\t\t\tthis.$focusOwner.removeAttr( 'aria-activedescendant' );\n\t\t\tthis.unbindDocumentKeyDownListener();\n\t\t\tthis.unbindDocumentKeyPressListener();\n\t\t\tthis.$focusOwner.attr( 'aria-expanded', 'false' );\n\t\t\tthis.getElementDocument().removeEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\t\t\tthis.togglePositioning( false );\n\t\t\tthis.toggleClipping( false );\n\t\t}\n\t}\n\n\treturn this;\n};\n","/**\n * DropdownWidgets are not menus themselves, rather they contain a menu of options created with\n * OO.ui.MenuOptionWidget. The DropdownWidget takes care of opening and displaying the menu so that\n * users can interact with it.\n *\n * If you want to use this within an HTML form, such as a OO.ui.FormLayout, use\n * OO.ui.DropdownInputWidget instead.\n *\n *     @example\n *     // A DropdownWidget with a menu that contains three options.\n *     var dropDown = new OO.ui.DropdownWidget( {\n *         label: 'Dropdown menu: Select a menu option',\n *         menu: {\n *             items: [\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'a',\n *                     label: 'First'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'b',\n *                     label: 'Second'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'c',\n *                     label: 'Third'\n *                 } )\n *             ]\n *         }\n *     } );\n *\n *     $( document.body ).append( dropDown.$element );\n *\n *     dropDown.getMenu().selectItemByData( 'b' );\n *\n *     dropDown.getMenu().findSelectedItem().getData(); // Returns 'b'.\n *\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.MenuSelectWidget menu select widget}\n * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where\n *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the\n *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { indicator: 'down' }, config );\n\n\t// Parent constructor\n\tOO.ui.DropdownWidget.parent.call( this, config );\n\n\t// Properties (must be set before TabIndexedElement constructor call)\n\tthis.$handle = $( '<button>' );\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );\n\n\t// Properties\n\tthis.menu = new OO.ui.MenuSelectWidget( $.extend( {\n\t\twidget: this,\n\t\t$floatableContainer: this.$element\n\t}, config.menu ) );\n\n\t// Events\n\tthis.$handle.on( {\n\t\tclick: this.onClick.bind( this ),\n\t\tkeydown: this.onKeyDown.bind( this ),\n\t\t// Hack? Handle type-to-search when menu is not expanded and not handling its own events\n\t\tkeypress: this.menu.onDocumentKeyPressHandler,\n\t\tblur: this.menu.clearKeyPressBuffer.bind( this.menu )\n\t} );\n\tthis.menu.connect( this, {\n\t\tselect: 'onMenuSelect',\n\t\ttoggle: 'onMenuToggle'\n\t} );\n\n\t// Initialization\n\tthis.$handle\n\t\t.addClass( 'oo-ui-dropdownWidget-handle' )\n\t\t.attr( {\n\t\t\ttype: 'button',\n\t\t\t'aria-owns': this.menu.getElementId(),\n\t\t\t'aria-haspopup': 'listbox'\n\t\t} )\n\t\t.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element\n\t\t.addClass( 'oo-ui-dropdownWidget' )\n\t\t.append( this.$handle );\n\tthis.$overlay.append( this.menu.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.DropdownWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Get the menu.\n *\n * @return {OO.ui.MenuSelectWidget} Menu of widget\n */\nOO.ui.DropdownWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Handles menu select events.\n *\n * @private\n * @param {OO.ui.MenuOptionWidget} item Selected menu item\n */\nOO.ui.DropdownWidget.prototype.onMenuSelect = function ( item ) {\n\tvar selectedLabel;\n\n\tif ( !item ) {\n\t\tthis.setLabel( null );\n\t\treturn;\n\t}\n\n\tselectedLabel = item.getLabel();\n\n\t// If the label is a DOM element, clone it, because setLabel will append() it\n\tif ( selectedLabel instanceof $ ) {\n\t\tselectedLabel = selectedLabel.clone();\n\t}\n\n\tthis.setLabel( selectedLabel );\n};\n\n/**\n * Handle menu toggle events.\n *\n * @private\n * @param {boolean} isVisible Open state of the menu\n */\nOO.ui.DropdownWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tthis.$element.toggleClass( 'oo-ui-dropdownWidget-open', isVisible );\n};\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {jQuery.Event} e Mouse click event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.DropdownWidget.prototype.onClick = function ( e ) {\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.menu.toggle();\n\t}\n\treturn false;\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.DropdownWidget.prototype.onKeyDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\t(\n\t\t\te.which === OO.ui.Keys.ENTER ||\n\t\t\t(\n\t\t\t\te.which === OO.ui.Keys.SPACE &&\n\t\t\t\t// Avoid conflicts with type-to-search, see SelectWidget#onKeyPress.\n\t\t\t\t// Space only closes the menu is the user is not typing to search.\n\t\t\t\tthis.menu.keyPressBuffer === ''\n\t\t\t) ||\n\t\t\t(\n\t\t\t\t!this.menu.isVisible() &&\n\t\t\t\t(\n\t\t\t\t\te.which === OO.ui.Keys.UP ||\n\t\t\t\t\te.which === OO.ui.Keys.DOWN\n\t\t\t\t)\n\t\t\t)\n\t\t)\n\t) {\n\t\tthis.menu.toggle();\n\t\treturn false;\n\t}\n};\n","/**\n * RadioOptionWidget is an option widget that looks like a radio button.\n * The class is used with OO.ui.RadioSelectWidget to create a selection of radio options.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Button_selects_and_option\n *\n * @class\n * @extends OO.ui.OptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.RadioOptionWidget = function OoUiRadioOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.radio = new OO.ui.RadioInputWidget( { value: config.data, tabIndex: -1 } );\n\n\t// Parent constructor\n\tOO.ui.RadioOptionWidget.parent.call( this, config );\n\n\t// Initialization\n\t// Remove implicit role, we're handling it ourselves\n\tthis.radio.$input.attr( 'role', 'presentation' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioOptionWidget' )\n\t\t.attr( 'role', 'radio' )\n\t\t.attr( 'aria-checked', 'false' )\n\t\t.removeAttr( 'aria-selected' )\n\t\t.prepend( this.radio.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioOptionWidget, OO.ui.OptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.highlightable = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.scrollIntoViewOnSelect = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.pressable = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.tagName = 'label';\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.RadioOptionWidget.parent.prototype.setSelected.call( this, state );\n\n\tthis.radio.setSelected( state );\n\tthis.$element\n\t\t.attr( 'aria-checked', state.toString() )\n\t\t.removeAttr( 'aria-selected' );\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.prototype.setDisabled = function ( disabled ) {\n\tOO.ui.RadioOptionWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tthis.radio.setDisabled( this.isDisabled() );\n\n\treturn this;\n};\n","/**\n * RadioSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains radio\n * options and is used together with OO.ui.RadioOptionWidget. The RadioSelectWidget provides\n * an interface for adding, removing and selecting options.\n * Please see the [OOUI documentation on MediaWiki][1] for more information.\n *\n * If you want to use this within an HTML form, such as a OO.ui.FormLayout, use\n * OO.ui.RadioSelectInputWidget instead.\n *\n *     @example\n *     // A RadioSelectWidget with RadioOptions.\n *     var option1 = new OO.ui.RadioOptionWidget( {\n *             data: 'a',\n *             label: 'Selected radio option'\n *         } ),\n *         option2 = new OO.ui.RadioOptionWidget( {\n *             data: 'b',\n *             label: 'Unselected radio option'\n *         } );\n *         radioSelect = new OO.ui.RadioSelectWidget( {\n *             items: [ option1, option2 ]\n *         } );\n *\n *     // Select 'option 1' using the RadioSelectWidget's selectItem() method.\n *     radioSelect.selectItem( option1 );\n *\n *     $( document.body ).append( radioSelect.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.RadioSelectWidget = function OoUiRadioSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.RadioSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioSelectWidget' )\n\t\t.attr( 'role', 'radiogroup' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.RadioSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * MultioptionWidgets are special elements that can be selected and configured with data. The\n * data is often unique for each option, but it does not have to be. MultioptionWidgets are used\n * with OO.ui.SelectWidget to create a selection of mutually exclusive options. For more information\n * and examples, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [selected=false] Whether the option is initially selected\n */\nOO.ui.MultioptionWidget = function OoUiMultioptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MultioptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ItemWidget.call( this );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.selected = null;\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-multioptionWidget' )\n\t\t.append( this.$label );\n\tthis.setSelected( config.selected );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MultioptionWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.MultioptionWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.MultioptionWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.MultioptionWidget, OO.ui.mixin.TitledElement );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the selected state of the option changes.\n *\n * @param {boolean} selected Whether the option is now selected\n */\n\n/* Methods */\n\n/**\n * Check if the option is selected.\n *\n * @return {boolean} Item is selected\n */\nOO.ui.MultioptionWidget.prototype.isSelected = function () {\n\treturn this.selected;\n};\n\n/**\n * Set the option’s selected state. In general, all modifications to the selection\n * should be handled by the SelectWidget’s {@link OO.ui.SelectWidget#selectItem selectItem( [item] )}\n * method instead of this method.\n *\n * @param {boolean} [state=false] Select option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MultioptionWidget.prototype.setSelected = function ( state ) {\n\tstate = !!state;\n\tif ( this.selected !== state ) {\n\t\tthis.selected = state;\n\t\tthis.emit( 'change', state );\n\t\tthis.$element.toggleClass( 'oo-ui-multioptionWidget-selected', state );\n\t}\n\treturn this;\n};\n","/**\n * MultiselectWidget allows selecting multiple options from a list.\n *\n * For more information about menus and options, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @abstract\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupWidget\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.MultioptionWidget[]} [items] An array of options to add to the multiselect.\n */\nOO.ui.MultiselectWidget = function OoUiMultiselectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.MultiselectWidget.parent.call( this, config );\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupWidget.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Events\n\tthis.aggregate( { change: 'select' } );\n\t// This is mostly for compatibility with TagMultiselectWidget... normally, 'change' is emitted\n\t// by GroupElement only when items are added/removed\n\tthis.connect( this, { select: [ 'emit', 'change' ] } );\n\n\t// Initialization\n\tif ( config.items ) {\n\t\tthis.addItems( config.items );\n\t}\n\tthis.$group.addClass( 'oo-ui-multiselectWidget-group' );\n\tthis.$element.addClass( 'oo-ui-multiselectWidget' )\n\t\t.append( this.$group );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MultiselectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.MultiselectWidget, OO.ui.mixin.GroupWidget );\nOO.mixinClass( OO.ui.MultiselectWidget, OO.ui.mixin.TitledElement );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the set of items changes, or an item is selected or deselected.\n */\n\n/**\n * @event select\n *\n * A select event is emitted when an item is selected or deselected.\n */\n\n/* Methods */\n\n/**\n * Find options that are selected.\n *\n * @return {OO.ui.MultioptionWidget[]} Selected options\n */\nOO.ui.MultiselectWidget.prototype.findSelectedItems = function () {\n\treturn this.items.filter( function ( item ) {\n\t\treturn item.isSelected();\n\t} );\n};\n\n/**\n * Find the data of options that are selected.\n *\n * @return {Object[]|string[]} Values of selected options\n */\nOO.ui.MultiselectWidget.prototype.findSelectedItemsData = function () {\n\treturn this.findSelectedItems().map( function ( item ) {\n\t\treturn item.data;\n\t} );\n};\n\n/**\n * Select options by reference. Options not mentioned in the `items` array will be deselected.\n *\n * @param {OO.ui.MultioptionWidget[]} items Items to select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MultiselectWidget.prototype.selectItems = function ( items ) {\n\tthis.items.forEach( function ( item ) {\n\t\tvar selected = items.indexOf( item ) !== -1;\n\t\titem.setSelected( selected );\n\t} );\n\treturn this;\n};\n\n/**\n * Select items by their data. Options not mentioned in the `datas` array will be deselected.\n *\n * @param {Object[]|string[]} datas Values of items to select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MultiselectWidget.prototype.selectItemsByData = function ( datas ) {\n\tvar items,\n\t\twidget = this;\n\titems = datas.map( function ( data ) {\n\t\treturn widget.findItemFromData( data );\n\t} );\n\tthis.selectItems( items );\n\treturn this;\n};\n","/**\n * CheckboxMultioptionWidget is an option widget that looks like a checkbox.\n * The class is used with OO.ui.CheckboxMultiselectWidget to create a selection of checkbox options.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Button_selects_and_option\n *\n * @class\n * @extends OO.ui.MultioptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.CheckboxMultioptionWidget = function OoUiCheckboxMultioptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.checkbox = new OO.ui.CheckboxInputWidget();\n\n\t// Parent constructor\n\tOO.ui.CheckboxMultioptionWidget.parent.call( this, config );\n\n\t// Events\n\tthis.checkbox.on( 'change', this.onCheckboxChange.bind( this ) );\n\tthis.$element.on( 'keydown', this.onKeyDown.bind( this ) );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-checkboxMultioptionWidget' )\n\t\t.prepend( this.checkbox.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxMultioptionWidget, OO.ui.MultioptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.CheckboxMultioptionWidget.static.tagName = 'label';\n\n/* Methods */\n\n/**\n * Handle checkbox selected state change.\n *\n * @private\n */\nOO.ui.CheckboxMultioptionWidget.prototype.onCheckboxChange = function () {\n\tthis.setSelected( this.checkbox.isSelected() );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultioptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.CheckboxMultioptionWidget.parent.prototype.setSelected.call( this, state );\n\tthis.checkbox.setSelected( state );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultioptionWidget.prototype.setDisabled = function ( disabled ) {\n\tOO.ui.CheckboxMultioptionWidget.parent.prototype.setDisabled.call( this, disabled );\n\tthis.checkbox.setDisabled( this.isDisabled() );\n\treturn this;\n};\n\n/**\n * Focus the widget.\n */\nOO.ui.CheckboxMultioptionWidget.prototype.focus = function () {\n\tthis.checkbox.focus();\n};\n\n/**\n * Handle key down events.\n *\n * @protected\n * @param {jQuery.Event} e\n */\nOO.ui.CheckboxMultioptionWidget.prototype.onKeyDown = function ( e ) {\n\tvar\n\t\telement = this.getElementGroup(),\n\t\tnextItem;\n\n\tif ( e.keyCode === OO.ui.Keys.LEFT || e.keyCode === OO.ui.Keys.UP ) {\n\t\tnextItem = element.getRelativeFocusableItem( this, -1 );\n\t} else if ( e.keyCode === OO.ui.Keys.RIGHT || e.keyCode === OO.ui.Keys.DOWN ) {\n\t\tnextItem = element.getRelativeFocusableItem( this, 1 );\n\t}\n\n\tif ( nextItem ) {\n\t\te.preventDefault();\n\t\tnextItem.focus();\n\t}\n};\n","/**\n * CheckboxMultiselectWidget is a {@link OO.ui.MultiselectWidget multiselect widget} that contains\n * checkboxes and is used together with OO.ui.CheckboxMultioptionWidget. The\n * CheckboxMultiselectWidget provides an interface for adding, removing and selecting options.\n * Please see the [OOUI documentation on MediaWiki][1] for more information.\n *\n * If you want to use this within an HTML form, such as a OO.ui.FormLayout, use\n * OO.ui.CheckboxMultiselectInputWidget instead.\n *\n *     @example\n *     // A CheckboxMultiselectWidget with CheckboxMultioptions.\n *     var option1 = new OO.ui.CheckboxMultioptionWidget( {\n *             data: 'a',\n *             selected: true,\n *             label: 'Selected checkbox'\n *         } ),\n *         option2 = new OO.ui.CheckboxMultioptionWidget( {\n *             data: 'b',\n *             label: 'Unselected checkbox'\n *         } ),\n *         multiselect = new OO.ui.CheckboxMultiselectWidget( {\n *             items: [ option1, option2 ]\n *         } );\n *     $( document.body ).append( multiselect.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.MultiselectWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.CheckboxMultiselectWidget = function OoUiCheckboxMultiselectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.CheckboxMultiselectWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.$lastClicked = null;\n\n\t// Events\n\tthis.$group.on( 'click', this.onClick.bind( this ) );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-checkboxMultiselectWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxMultiselectWidget, OO.ui.MultiselectWidget );\n\n/* Methods */\n\n/**\n * Get an option by its position relative to the specified item (or to the start of the option array,\n * if item is `null`). The direction in which to search through the option array is specified with a\n * number: -1 for reverse (the default) or 1 for forward. The method will return an option, or\n * `null` if there are no options in the array.\n *\n * @param {OO.ui.CheckboxMultioptionWidget|null} item Item to describe the start position, or `null` to start at the beginning of the array.\n * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward\n * @return {OO.ui.CheckboxMultioptionWidget|null} Item at position, `null` if there are no items in the select\n */\nOO.ui.CheckboxMultiselectWidget.prototype.getRelativeFocusableItem = function ( item, direction ) {\n\tvar currentIndex, nextIndex, i,\n\t\tincrease = direction > 0 ? 1 : -1,\n\t\tlen = this.items.length;\n\n\tif ( item ) {\n\t\tcurrentIndex = this.items.indexOf( item );\n\t\tnextIndex = ( currentIndex + increase + len ) % len;\n\t} else {\n\t\t// If no item is selected and moving forward, start at the beginning.\n\t\t// If moving backward, start at the end.\n\t\tnextIndex = direction > 0 ? 0 : len - 1;\n\t}\n\n\tfor ( i = 0; i < len; i++ ) {\n\t\titem = this.items[ nextIndex ];\n\t\tif ( item && !item.isDisabled() ) {\n\t\t\treturn item;\n\t\t}\n\t\tnextIndex = ( nextIndex + increase + len ) % len;\n\t}\n\treturn null;\n};\n\n/**\n * Handle click events on checkboxes.\n *\n * @param {jQuery.Event} e\n */\nOO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) {\n\tvar $options, lastClickedIndex, nowClickedIndex, i, direction, wasSelected, items,\n\t\t$lastClicked = this.$lastClicked,\n\t\t$nowClicked = $( e.target ).closest( '.oo-ui-checkboxMultioptionWidget' )\n\t\t\t.not( '.oo-ui-widget-disabled' );\n\n\t// Allow selecting multiple options at once by Shift-clicking them\n\tif ( $lastClicked && $nowClicked.length && e.shiftKey ) {\n\t\t$options = this.$group.find( '.oo-ui-checkboxMultioptionWidget' );\n\t\tlastClickedIndex = $options.index( $lastClicked );\n\t\tnowClickedIndex = $options.index( $nowClicked );\n\t\t// If it's the same item, either the user is being silly, or it's a fake event generated by the\n\t\t// browser. In either case we don't need custom handling.\n\t\tif ( nowClickedIndex !== lastClickedIndex ) {\n\t\t\titems = this.items;\n\t\t\twasSelected = items[ nowClickedIndex ].isSelected();\n\t\t\tdirection = nowClickedIndex > lastClickedIndex ? 1 : -1;\n\n\t\t\t// This depends on the DOM order of the items and the order of the .items array being the same.\n\t\t\tfor ( i = lastClickedIndex; i !== nowClickedIndex; i += direction ) {\n\t\t\t\tif ( !items[ i ].isDisabled() ) {\n\t\t\t\t\titems[ i ].setSelected( !wasSelected );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// For the now-clicked element, use immediate timeout to allow the browser to do its own\n\t\t\t// handling first, then set our value. The order in which events happen is different for\n\t\t\t// clicks on the <input> and on the <label> and there are additional fake clicks fired for\n\t\t\t// non-click actions that change the checkboxes.\n\t\t\te.preventDefault();\n\t\t\tsetTimeout( function () {\n\t\t\t\tif ( !items[ nowClickedIndex ].isDisabled() ) {\n\t\t\t\t\titems[ nowClickedIndex ].setSelected( !wasSelected );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\tif ( $nowClicked.length ) {\n\t\tthis.$lastClicked = $nowClicked;\n\t}\n};\n\n/**\n * Focus the widget\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.CheckboxMultiselectWidget.prototype.focus = function () {\n\tvar item;\n\tif ( !this.isDisabled() ) {\n\t\titem = this.getRelativeFocusableItem( null, 1 );\n\t\tif ( item ) {\n\t\t\titem.focus();\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectWidget.prototype.simulateLabelClick = function () {\n\tthis.focus();\n};\n","/**\n * Progress bars visually display the status of an operation, such as a download,\n * and can be either determinate or indeterminate:\n *\n * - **determinate** process bars show the percent of an operation that is complete.\n *\n * - **indeterminate** process bars use a visual display of motion to indicate that an operation\n *   is taking place. Because the extent of an indeterminate operation is unknown, the bar does\n *   not use percentages.\n *\n * The value of the `progress` configuration determines whether the bar is determinate or indeterminate.\n *\n *     @example\n *     // Examples of determinate and indeterminate progress bars.\n *     var progressBar1 = new OO.ui.ProgressBarWidget( {\n *         progress: 33\n *     } );\n *     var progressBar2 = new OO.ui.ProgressBarWidget();\n *\n *     // Create a FieldsetLayout to layout progress bars.\n *     var fieldset = new OO.ui.FieldsetLayout;\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( progressBar1, {\n *             label: 'Determinate',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( progressBar2, {\n *             label: 'Indeterminate',\n *             align: 'top'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * @class\n * @extends OO.ui.Widget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number|boolean} [progress=false] The type of progress bar (determinate or indeterminate).\n *  To create a determinate progress bar, specify a number that reflects the initial percent complete.\n *  By default, the progress bar is indeterminate.\n */\nOO.ui.ProgressBarWidget = function OoUiProgressBarWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ProgressBarWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.$bar = $( '<div>' );\n\tthis.progress = null;\n\n\t// Initialization\n\tthis.setProgress( config.progress !== undefined ? config.progress : false );\n\tthis.$bar.addClass( 'oo-ui-progressBarWidget-bar' );\n\tthis.$element\n\t\t.attr( {\n\t\t\trole: 'progressbar',\n\t\t\t'aria-valuemin': 0,\n\t\t\t'aria-valuemax': 100\n\t\t} )\n\t\t.addClass( 'oo-ui-progressBarWidget' )\n\t\t.append( this.$bar );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ProgressBarWidget, OO.ui.Widget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ProgressBarWidget.static.tagName = 'div';\n\n/* Methods */\n\n/**\n * Get the percent of the progress that has been completed. Indeterminate progresses will return `false`.\n *\n * @return {number|boolean} Progress percent\n */\nOO.ui.ProgressBarWidget.prototype.getProgress = function () {\n\treturn this.progress;\n};\n\n/**\n * Set the percent of the process completed or `false` for an indeterminate process.\n *\n * @param {number|boolean} progress Progress percent or `false` for indeterminate\n */\nOO.ui.ProgressBarWidget.prototype.setProgress = function ( progress ) {\n\tthis.progress = progress;\n\n\tif ( progress !== false ) {\n\t\tthis.$bar.css( 'width', this.progress + '%' );\n\t\tthis.$element.attr( 'aria-valuenow', this.progress );\n\t} else {\n\t\tthis.$bar.css( 'width', '' );\n\t\tthis.$element.removeAttr( 'aria-valuenow' );\n\t}\n\tthis.$element.toggleClass( 'oo-ui-progressBarWidget-indeterminate', progress === false );\n};\n","/**\n * InputWidget is the base class for all input widgets, which\n * include {@link OO.ui.TextInputWidget text inputs}, {@link OO.ui.CheckboxInputWidget checkbox inputs},\n * {@link OO.ui.RadioInputWidget radio inputs}, and {@link OO.ui.ButtonInputWidget button inputs}.\n * See the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.AccessKeyedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [name=''] The value of the input’s HTML `name` attribute.\n * @cfg {string} [value=''] The value of the input.\n * @cfg {string} [dir] The directionality of the input (ltr/rtl).\n * @cfg {string} [inputId] The value of the input’s HTML `id` attribute.\n * @cfg {Function} [inputFilter] The name of an input filter function. Input filters modify the value of an input\n *  before it is accepted.\n */\nOO.ui.InputWidget = function OoUiInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.InputWidget.parent.call( this, config );\n\n\t// Properties\n\t// See #reusePreInfuseDOM about config.$input\n\tthis.$input = config.$input || this.getInputElement( config );\n\tthis.value = '';\n\tthis.inputFilter = config.inputFilter;\n\n\t// Mixin constructors\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );\n\tOO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$input } ) );\n\n\t// Events\n\tthis.$input.on( 'keydown mouseup cut paste change input select', this.onEdit.bind( this ) );\n\n\t// Initialization\n\tthis.$input\n\t\t.addClass( 'oo-ui-inputWidget-input' )\n\t\t.attr( 'name', config.name )\n\t\t.prop( 'disabled', this.isDisabled() );\n\tthis.$element\n\t\t.addClass( 'oo-ui-inputWidget' )\n\t\t.append( this.$input );\n\tthis.setValue( config.value );\n\tif ( config.dir ) {\n\t\tthis.setDir( config.dir );\n\t}\n\tif ( config.inputId !== undefined ) {\n\t\tthis.setInputId( config.inputId );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.AccessKeyedElement );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.static.reusePreInfuseDOM = function ( node, config ) {\n\tconfig = OO.ui.InputWidget.parent.static.reusePreInfuseDOM( node, config );\n\t// Reusing `$input` lets browsers preserve inputted values across page reloads, see T114134.\n\tconfig.$input = $( node ).find( '.oo-ui-inputWidget-input' );\n\treturn config;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.InputWidget.parent.static.gatherPreInfuseState( node, config );\n\tif ( config.$input && config.$input.length ) {\n\t\tstate.value = config.$input.val();\n\t\t// Might be better in TabIndexedElement, but it's awkward to do there because mixins are awkward\n\t\tstate.focus = config.$input.is( ':focus' );\n\t}\n\treturn state;\n};\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the value of the input changes.\n *\n * @param {string} value\n */\n\n/* Methods */\n\n/**\n * Get input element.\n *\n * Subclasses of OO.ui.InputWidget use the `config` parameter to produce different elements in\n * different circumstances. The element must have a `value` property (like form elements).\n *\n * @protected\n * @param {Object} config Configuration options\n * @return {jQuery} Input element\n */\nOO.ui.InputWidget.prototype.getInputElement = function () {\n\treturn $( '<input>' );\n};\n\n/**\n * Handle potentially value-changing events.\n *\n * @private\n * @param {jQuery.Event} e Key down, mouse up, cut, paste, change, input, or select event\n */\nOO.ui.InputWidget.prototype.onEdit = function () {\n\tvar widget = this;\n\tif ( !this.isDisabled() ) {\n\t\t// Allow the stack to clear so the value will be updated\n\t\tsetTimeout( function () {\n\t\t\twidget.setValue( widget.$input.val() );\n\t\t} );\n\t}\n};\n\n/**\n * Get the value of the input.\n *\n * @return {string} Input value\n */\nOO.ui.InputWidget.prototype.getValue = function () {\n\t// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify\n\t// it, and we won't know unless they're kind enough to trigger a 'change' event.\n\tvar value = this.$input.val();\n\tif ( this.value !== value ) {\n\t\tthis.setValue( value );\n\t}\n\treturn this.value;\n};\n\n/**\n * Set the directionality of the input.\n *\n * @param {string} dir Text directionality: 'ltr', 'rtl' or 'auto'\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.InputWidget.prototype.setDir = function ( dir ) {\n\tthis.$input.prop( 'dir', dir );\n\treturn this;\n};\n\n/**\n * Set the value of the input.\n *\n * @param {string} value New value\n * @fires change\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.InputWidget.prototype.setValue = function ( value ) {\n\tvalue = this.cleanUpValue( value );\n\t// Update the DOM if it has changed. Note that with cleanUpValue, it\n\t// is possible for the DOM value to change without this.value changing.\n\tif ( this.$input.val() !== value ) {\n\t\tthis.$input.val( value );\n\t}\n\tif ( this.value !== value ) {\n\t\tthis.value = value;\n\t\tthis.emit( 'change', this.value );\n\t}\n\t// The first time that the value is set (probably while constructing the widget),\n\t// remember it in defaultValue. This property can be later used to check whether\n\t// the value of the input has been changed since it was created.\n\tif ( this.defaultValue === undefined ) {\n\t\tthis.defaultValue = this.value;\n\t\tthis.$input[ 0 ].defaultValue = this.defaultValue;\n\t}\n\treturn this;\n};\n\n/**\n * Clean up incoming value.\n *\n * Ensures value is a string, and converts undefined and null to empty string.\n *\n * @private\n * @param {string} value Original value\n * @return {string} Cleaned up value\n */\nOO.ui.InputWidget.prototype.cleanUpValue = function ( value ) {\n\tif ( value === undefined || value === null ) {\n\t\treturn '';\n\t} else if ( this.inputFilter ) {\n\t\treturn this.inputFilter( String( value ) );\n\t} else {\n\t\treturn String( value );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.prototype.setDisabled = function ( state ) {\n\tOO.ui.InputWidget.parent.prototype.setDisabled.call( this, state );\n\tif ( this.$input ) {\n\t\tthis.$input.prop( 'disabled', this.isDisabled() );\n\t}\n\treturn this;\n};\n\n/**\n * Set the 'id' attribute of the `<input>` element.\n *\n * @param {string} id\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.InputWidget.prototype.setInputId = function ( id ) {\n\tthis.$input.attr( 'id', id );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.InputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.value !== undefined && state.value !== this.getValue() ) {\n\t\tthis.setValue( state.value );\n\t}\n\tif ( state.focus ) {\n\t\tthis.focus();\n\t}\n};\n","/**\n * Data widget intended for creating `<input type=\"hidden\">` inputs.\n *\n * @class\n * @extends OO.ui.Widget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [value=''] The value of the input.\n * @cfg {string} [name=''] The value of the input’s HTML `name` attribute.\n */\nOO.ui.HiddenInputWidget = function OoUiHiddenInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { value: '', name: '' }, config );\n\n\t// Parent constructor\n\tOO.ui.HiddenInputWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element.attr( {\n\t\ttype: 'hidden',\n\t\tvalue: config.value,\n\t\tname: config.name\n\t} );\n\tthis.$element.removeAttr( 'aria-disabled' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.HiddenInputWidget, OO.ui.Widget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.HiddenInputWidget.static.tagName = 'input';\n","/**\n * ButtonInputWidget is used to submit HTML forms and is intended to be used within\n * a OO.ui.FormLayout. If you do not need the button to work with HTML forms, you probably\n * want to use OO.ui.ButtonWidget instead. Button input widgets can be rendered as either an\n * HTML `<button>` (the default) or an HTML `<input>` tags. See the\n * [OOUI documentation on MediaWiki] [1] for more information.\n *\n *     @example\n *     // A ButtonInputWidget rendered as an HTML button, the default.\n *     var button = new OO.ui.ButtonInputWidget( {\n *         label: 'Input button',\n *         icon: 'check',\n *         value: 'check'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs#Button_inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [type='button'] The value of the HTML `'type'` attribute: 'button', 'submit' or 'reset'.\n * @cfg {boolean} [useInputTag=false] Use an `<input>` tag instead of a `<button>` tag, the default.\n *  Widgets configured to be an `<input>` do not support {@link #icon icons} and {@link #indicator indicators},\n *  non-plaintext {@link #label labels}, or {@link #value values}. In general, useInputTag should only\n *  be set to `true` when there’s need to support IE 6 in a form with multiple buttons.\n */\nOO.ui.ButtonInputWidget = function OoUiButtonInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { type: 'button', useInputTag: false }, config );\n\n\t// See InputWidget#reusePreInfuseDOM about config.$input\n\tif ( config.$input ) {\n\t\tconfig.$input.empty();\n\t}\n\n\t// Properties (must be set before parent constructor, which calls #setValue)\n\tthis.useInputTag = config.useInputTag;\n\n\t// Parent constructor\n\tOO.ui.ButtonInputWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, $.extend( {}, config, { $button: this.$input } ) );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\n\t// Initialization\n\tif ( !config.useInputTag ) {\n\t\tthis.$input.append( this.$icon, this.$label, this.$indicator );\n\t}\n\tthis.$element.addClass( 'oo-ui-buttonInputWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonInputWidget, OO.ui.InputWidget );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.LabelElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonInputWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.ButtonInputWidget.prototype.getInputElement = function ( config ) {\n\tvar type;\n\ttype = [ 'button', 'submit', 'reset' ].indexOf( config.type ) !== -1 ? config.type : 'button';\n\treturn $( '<' + ( config.useInputTag ? 'input' : 'button' ) + ' type=\"' + type + '\">' );\n};\n\n/**\n * Set label value.\n *\n * If #useInputTag is `true`, the label is set as the `value` of the `<input>` tag.\n *\n * @param {jQuery|string|Function|null} label Label nodes, text, a function that returns nodes or\n *  text, or `null` for no label\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonInputWidget.prototype.setLabel = function ( label ) {\n\tif ( typeof label === 'function' ) {\n\t\tlabel = OO.ui.resolveMsg( label );\n\t}\n\n\tif ( this.useInputTag ) {\n\t\t// Discard non-plaintext labels\n\t\tif ( typeof label !== 'string' ) {\n\t\t\tlabel = '';\n\t\t}\n\n\t\tthis.$input.val( label );\n\t}\n\n\treturn OO.ui.mixin.LabelElement.prototype.setLabel.call( this, label );\n};\n\n/**\n * Set the value of the input.\n *\n * This method is disabled for button inputs configured as {@link #useInputTag <input> tags}, as\n * they do not support {@link #value values}.\n *\n * @param {string} value New value\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonInputWidget.prototype.setValue = function ( value ) {\n\tif ( !this.useInputTag ) {\n\t\tOO.ui.ButtonInputWidget.parent.prototype.setValue.call( this, value );\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ButtonInputWidget.prototype.getInputId = function () {\n\t// Disable generating `<label>` elements for buttons. One would very rarely need additional label\n\t// for a button, and it's already a big clickable target, and it causes unexpected rendering.\n\treturn null;\n};\n","/**\n * CheckboxInputWidgets, like HTML checkboxes, can be selected and/or configured with a value.\n * Note that these {@link OO.ui.InputWidget input widgets} are best laid out\n * in {@link OO.ui.FieldLayout field layouts} that use the {@link OO.ui.FieldLayout#align inline}\n * alignment. For more information, please see the [OOUI documentation on MediaWiki][1].\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // An example of selected, unselected, and disabled checkbox inputs.\n *     var checkbox1 = new OO.ui.CheckboxInputWidget( {\n *             value: 'a',\n *              selected: true\n *         } ),\n *         checkbox2 = new OO.ui.CheckboxInputWidget( {\n *             value: 'b'\n *         } ),\n *         checkbox3 = new OO.ui.CheckboxInputWidget( {\n *             value:'c',\n *             disabled: true\n *         } ),\n *         // Create a fieldset layout with fields for each checkbox.\n *         fieldset = new OO.ui.FieldsetLayout( {\n *             label: 'Checkboxes'\n *         } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( checkbox1, { label: 'Selected checkbox', align: 'inline' } ),\n *         new OO.ui.FieldLayout( checkbox2, { label: 'Unselected checkbox', align: 'inline' } ),\n *         new OO.ui.FieldLayout( checkbox3, { label: 'Disabled checkbox', align: 'inline' } ),\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [selected=false] Select the checkbox initially. By default, the checkbox is not selected.\n */\nOO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.CheckboxInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.checkIcon = new OO.ui.IconWidget( {\n\t\ticon: 'check',\n\t\tclasses: [ 'oo-ui-checkboxInputWidget-checkIcon' ]\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-checkboxInputWidget' )\n\t\t// Required for pretty styling in WikimediaUI theme\n\t\t.append( this.checkIcon.$element );\n\tthis.setSelected( config.selected !== undefined ? config.selected : false );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.static.tagName = 'span';\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.CheckboxInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.checked = config.$input.prop( 'checked' );\n\treturn state;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.CheckboxInputWidget.prototype.getInputElement = function () {\n\treturn $( '<input>' ).attr( 'type', 'checkbox' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.prototype.onEdit = function () {\n\tvar widget = this;\n\tif ( !this.isDisabled() ) {\n\t\t// Allow the stack to clear so the value will be updated\n\t\tsetTimeout( function () {\n\t\t\twidget.setSelected( widget.$input.prop( 'checked' ) );\n\t\t} );\n\t}\n};\n\n/**\n * Set selection state of this checkbox.\n *\n * @param {boolean} state `true` for selected\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.CheckboxInputWidget.prototype.setSelected = function ( state ) {\n\tstate = !!state;\n\tif ( this.selected !== state ) {\n\t\tthis.selected = state;\n\t\tthis.$input.prop( 'checked', this.selected );\n\t\tthis.emit( 'change', this.selected );\n\t}\n\t// The first time that the selection state is set (probably while constructing the widget),\n\t// remember it in defaultSelected. This property can be later used to check whether\n\t// the selection state of the input has been changed since it was created.\n\tif ( this.defaultSelected === undefined ) {\n\t\tthis.defaultSelected = this.selected;\n\t\tthis.$input[ 0 ].defaultChecked = this.defaultSelected;\n\t}\n\treturn this;\n};\n\n/**\n * Check if this checkbox is selected.\n *\n * @return {boolean} Checkbox is selected\n */\nOO.ui.CheckboxInputWidget.prototype.isSelected = function () {\n\t// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify\n\t// it, and we won't know unless they're kind enough to trigger a 'change' event.\n\tvar selected = this.$input.prop( 'checked' );\n\tif ( this.selected !== selected ) {\n\t\tthis.setSelected( selected );\n\t}\n\treturn this.selected;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.prototype.simulateLabelClick = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$handle.trigger( 'click' );\n\t}\n\tthis.focus();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.CheckboxInputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.checked !== undefined && state.checked !== this.isSelected() ) {\n\t\tthis.setSelected( state.checked );\n\t}\n};\n","/**\n * DropdownInputWidget is a {@link OO.ui.DropdownWidget DropdownWidget} intended to be used\n * within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value\n * of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for\n * more information about input widgets.\n *\n * A DropdownInputWidget always has a value (one of the options is always selected), unless there\n * are no options. If no `value` configuration option is provided, the first option is selected.\n * If you need a state representing no value (no option being selected), use a DropdownWidget.\n *\n * This and OO.ui.RadioSelectInputWidget support similar configuration options.\n *\n *     @example\n *     // A DropdownInputWidget with three options.\n *     var dropdownInput = new OO.ui.DropdownInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second', disabled: true },\n *             { optgroup: 'Group label' },\n *             { data: 'c', label: 'First sub-item)' }\n *         ]\n *     } );\n *     $( document.body ).append( dropdownInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format described above.\n * @cfg {Object} [dropdown] Configuration options for {@link OO.ui.DropdownWidget DropdownWidget}\n * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where\n *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the\n *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.dropdownWidget = new OO.ui.DropdownWidget( $.extend(\n\t\t{\n\t\t\t$overlay: config.$overlay\n\t\t},\n\t\tconfig.dropdown\n\t) );\n\t// Set up the options before parent constructor, which uses them to validate config.value.\n\t// Use this instead of setOptions() because this.$input is not set up yet.\n\tthis.setOptionsData( config.options || [] );\n\n\t// Parent constructor\n\tOO.ui.DropdownInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.dropdownWidget.getMenu().connect( this, { select: 'onMenuSelect' } );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-dropdownInputWidget' )\n\t\t.append( this.dropdownWidget.$element );\n\tthis.setTabIndexedElement( this.dropdownWidget.$tabIndexed );\n\tthis.setTitledElement( this.dropdownWidget.$handle );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.DropdownInputWidget, OO.ui.InputWidget );\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.DropdownInputWidget.prototype.getInputElement = function () {\n\treturn $( '<select>' );\n};\n\n/**\n * Handles menu select events.\n *\n * @private\n * @param {OO.ui.MenuOptionWidget|null} item Selected menu item\n */\nOO.ui.DropdownInputWidget.prototype.onMenuSelect = function ( item ) {\n\tthis.setValue( item ? item.getData() : '' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.setValue = function ( value ) {\n\tvar selected;\n\tvalue = this.cleanUpValue( value );\n\t// Only allow setting values that are actually present in the dropdown\n\tselected = this.dropdownWidget.getMenu().findItemFromData( value ) ||\n\t\tthis.dropdownWidget.getMenu().findFirstSelectableItem();\n\tthis.dropdownWidget.getMenu().selectItem( selected );\n\tvalue = selected ? selected.getData() : '';\n\tOO.ui.DropdownInputWidget.parent.prototype.setValue.call( this, value );\n\tif ( this.optionsDirty ) {\n\t\t// We reached this from the constructor or from #setOptions.\n\t\t// We have to update the <select> element.\n\t\tthis.updateOptionsInterface();\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.setDisabled = function ( state ) {\n\tthis.dropdownWidget.setDisabled( state );\n\tOO.ui.DropdownInputWidget.parent.prototype.setDisabled.call( this, state );\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.DropdownInputWidget.prototype.setOptions = function ( options ) {\n\tvar value = this.getValue();\n\n\tthis.setOptionsData( options );\n\n\t// Re-set the value to update the visible interface (DropdownWidget and <select>).\n\t// In case the previous value is no longer an available option, select the first valid one.\n\tthis.setValue( value );\n\n\treturn this;\n};\n\n/**\n * Set the internal list of options, used e.g. by setValue() to see which options are allowed.\n *\n * This method may be called before the parent constructor, so various properties may not be\n * initialized yet.\n *\n * @param {Object[]} options Array of menu options (see #constructor for details).\n * @private\n */\nOO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar optionWidgets, optIndex, opt, previousOptgroup, optionWidget, optValue,\n\t\twidget = this;\n\n\tthis.optionsDirty = true;\n\n\t// Go through all the supplied option configs and create either\n\t// MenuSectionOption or MenuOption widgets from each.\n\toptionWidgets = [];\n\tfor ( optIndex = 0; optIndex < options.length; optIndex++ ) {\n\t\topt = options[ optIndex ];\n\n\t\tif ( opt.optgroup !== undefined ) {\n\t\t\t// Create a <optgroup> menu item.\n\t\t\toptionWidget = widget.createMenuSectionOptionWidget( opt.optgroup );\n\t\t\tpreviousOptgroup = optionWidget;\n\n\t\t} else {\n\t\t\t// Create a normal <option> menu item.\n\t\t\toptValue = widget.cleanUpValue( opt.data );\n\t\t\toptionWidget = widget.createMenuOptionWidget(\n\t\t\t\toptValue,\n\t\t\t\topt.label !== undefined ? opt.label : optValue\n\t\t\t);\n\t\t}\n\n\t\t// Disable the menu option if it is itself disabled or if its parent optgroup is disabled.\n\t\tif ( opt.disabled !== undefined ||\n\t\t\tpreviousOptgroup instanceof OO.ui.MenuSectionOptionWidget && previousOptgroup.isDisabled() ) {\n\t\t\toptionWidget.setDisabled( true );\n\t\t}\n\n\t\toptionWidgets.push( optionWidget );\n\t}\n\n\tthis.dropdownWidget.getMenu().clearItems().addItems( optionWidgets );\n};\n\n/**\n * Create a menu option widget.\n *\n * @protected\n * @param {string} data Item data\n * @param {string} label Item label\n * @return {OO.ui.MenuOptionWidget} Option widget\n */\nOO.ui.DropdownInputWidget.prototype.createMenuOptionWidget = function ( data, label ) {\n\treturn new OO.ui.MenuOptionWidget( {\n\t\tdata: data,\n\t\tlabel: label\n\t} );\n};\n\n/**\n * Create a menu section option widget.\n *\n * @protected\n * @param {string} label Section item label\n * @return {OO.ui.MenuSectionOptionWidget} Menu section option widget\n */\nOO.ui.DropdownInputWidget.prototype.createMenuSectionOptionWidget = function ( label ) {\n\treturn new OO.ui.MenuSectionOptionWidget( {\n\t\tlabel: label\n\t} );\n};\n\n/**\n * Update the user-visible interface to match the internal list of options and value.\n *\n * This method must only be called after the parent constructor.\n *\n * @private\n */\nOO.ui.DropdownInputWidget.prototype.updateOptionsInterface = function () {\n\tvar\n\t\t$optionsContainer = this.$input,\n\t\tdefaultValue = this.defaultValue,\n\t\twidget = this;\n\n\tthis.$input.empty();\n\n\tthis.dropdownWidget.getMenu().getItems().forEach( function ( optionWidget ) {\n\t\tvar $optionNode;\n\n\t\tif ( !( optionWidget instanceof OO.ui.MenuSectionOptionWidget ) ) {\n\t\t\t$optionNode = $( '<option>' )\n\t\t\t\t.attr( 'value', optionWidget.getData() )\n\t\t\t\t.text( optionWidget.getLabel() );\n\n\t\t\t// Remember original selection state. This property can be later used to check whether\n\t\t\t// the selection state of the input has been changed since it was created.\n\t\t\t$optionNode[ 0 ].defaultSelected = ( optionWidget.getData() === defaultValue );\n\n\t\t\t$optionsContainer.append( $optionNode );\n\t\t} else {\n\t\t\t$optionNode = $( '<optgroup>' )\n\t\t\t\t.attr( 'label', optionWidget.getLabel() );\n\t\t\twidget.$input.append( $optionNode );\n\t\t\t$optionsContainer = $optionNode;\n\t\t}\n\n\t\t// Disable the option or optgroup if required.\n\t\tif ( optionWidget.isDisabled() ) {\n\t\t\t$optionNode.prop( 'disabled', true );\n\t\t}\n\t} );\n\n\tthis.optionsDirty = false;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.focus = function () {\n\tthis.dropdownWidget.focus();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.blur = function () {\n\tthis.dropdownWidget.blur();\n\treturn this;\n};\n","/**\n * RadioInputWidget creates a single radio button. Because radio buttons are usually used as a set,\n * in most cases you will want to use a {@link OO.ui.RadioSelectWidget radio select}\n * with {@link OO.ui.RadioOptionWidget radio options} instead of this class. For more information,\n * please see the [OOUI documentation on MediaWiki][1].\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // An example of selected, unselected, and disabled radio inputs\n *     var radio1 = new OO.ui.RadioInputWidget( {\n *         value: 'a',\n *         selected: true\n *     } );\n *     var radio2 = new OO.ui.RadioInputWidget( {\n *         value: 'b'\n *     } );\n *     var radio3 = new OO.ui.RadioInputWidget( {\n *         value: 'c',\n *         disabled: true\n *     } );\n *     // Create a fieldset layout with fields for each radio button.\n *     var fieldset = new OO.ui.FieldsetLayout( {\n *         label: 'Radio inputs'\n *     } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( radio1, { label: 'Selected', align: 'inline' } ),\n *         new OO.ui.FieldLayout( radio2, { label: 'Unselected', align: 'inline' } ),\n *         new OO.ui.FieldLayout( radio3, { label: 'Disabled', align: 'inline' } ),\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [selected=false] Select the radio button initially. By default, the radio button is not selected.\n */\nOO.ui.RadioInputWidget = function OoUiRadioInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.RadioInputWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioInputWidget' )\n\t\t// Required for pretty styling in WikimediaUI theme\n\t\t.append( $( '<span>' ) );\n\tthis.setSelected( config.selected !== undefined ? config.selected : false );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioInputWidget, OO.ui.InputWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.static.tagName = 'span';\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.RadioInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.checked = config.$input.prop( 'checked' );\n\treturn state;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.RadioInputWidget.prototype.getInputElement = function () {\n\treturn $( '<input>' ).attr( 'type', 'radio' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.prototype.onEdit = function () {\n\t// RadioInputWidget doesn't track its state.\n};\n\n/**\n * Set selection state of this radio button.\n *\n * @param {boolean} state `true` for selected\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.RadioInputWidget.prototype.setSelected = function ( state ) {\n\t// RadioInputWidget doesn't track its state.\n\tthis.$input.prop( 'checked', state );\n\t// The first time that the selection state is set (probably while constructing the widget),\n\t// remember it in defaultSelected. This property can be later used to check whether\n\t// the selection state of the input has been changed since it was created.\n\tif ( this.defaultSelected === undefined ) {\n\t\tthis.defaultSelected = state;\n\t\tthis.$input[ 0 ].defaultChecked = this.defaultSelected;\n\t}\n\treturn this;\n};\n\n/**\n * Check if this radio button is selected.\n *\n * @return {boolean} Radio is selected\n */\nOO.ui.RadioInputWidget.prototype.isSelected = function () {\n\treturn this.$input.prop( 'checked' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.prototype.simulateLabelClick = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$input.trigger( 'click' );\n\t}\n\tthis.focus();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.RadioInputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.checked !== undefined && state.checked !== this.isSelected() ) {\n\t\tthis.setSelected( state.checked );\n\t}\n};\n","/**\n * RadioSelectInputWidget is a {@link OO.ui.RadioSelectWidget RadioSelectWidget} intended to be used\n * within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value\n * of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for\n * more information about input widgets.\n *\n * This and OO.ui.DropdownInputWidget support similar configuration options.\n *\n *     @example\n *     // A RadioSelectInputWidget with three options\n *     var radioSelectInput = new OO.ui.RadioSelectInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second'},\n *             { data: 'c', label: 'Third' }\n *         ]\n *     } );\n *     $( document.body ).append( radioSelectInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`\n */\nOO.ui.RadioSelectInputWidget = function OoUiRadioSelectInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.radioSelectWidget = new OO.ui.RadioSelectWidget();\n\t// Set up the options before parent constructor, which uses them to validate config.value.\n\t// Use this instead of setOptions() because this.$input is not set up yet\n\tthis.setOptionsData( config.options || [] );\n\n\t// Parent constructor\n\tOO.ui.RadioSelectInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.radioSelectWidget.connect( this, { select: 'onMenuSelect' } );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioSelectInputWidget' )\n\t\t.append( this.radioSelectWidget.$element );\n\tthis.setTabIndexedElement( this.radioSelectWidget.$tabIndexed );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioSelectInputWidget, OO.ui.InputWidget );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.RadioSelectInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.value = $( node ).find( '.oo-ui-radioInputWidget .oo-ui-inputWidget-input:checked' ).val();\n\treturn state;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.static.reusePreInfuseDOM = function ( node, config ) {\n\tconfig = OO.ui.RadioSelectInputWidget.parent.static.reusePreInfuseDOM( node, config );\n\t// Cannot reuse the `<input type=radio>` set\n\tdelete config.$input;\n\treturn config;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.RadioSelectInputWidget.prototype.getInputElement = function () {\n\t// Use this instead of <input type=\"hidden\">, because hidden inputs do not have separate\n\t// 'value' and 'defaultValue' properties, and InputWidget wants to handle 'defaultValue'.\n\treturn $( '<input>' ).addClass( 'oo-ui-element-hidden' );\n};\n\n/**\n * Handles menu select events.\n *\n * @private\n * @param {OO.ui.RadioOptionWidget} item Selected menu item\n */\nOO.ui.RadioSelectInputWidget.prototype.onMenuSelect = function ( item ) {\n\tthis.setValue( item.getData() );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.setValue = function ( value ) {\n\tvar selected;\n\tvalue = this.cleanUpValue( value );\n\t// Only allow setting values that are actually present in the dropdown\n\tselected = this.radioSelectWidget.findItemFromData( value ) ||\n\t\tthis.radioSelectWidget.findFirstSelectableItem();\n\tthis.radioSelectWidget.selectItem( selected );\n\tvalue = selected ? selected.getData() : '';\n\tOO.ui.RadioSelectInputWidget.parent.prototype.setValue.call( this, value );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.setDisabled = function ( state ) {\n\tthis.radioSelectWidget.setDisabled( state );\n\tOO.ui.RadioSelectInputWidget.parent.prototype.setDisabled.call( this, state );\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.RadioSelectInputWidget.prototype.setOptions = function ( options ) {\n\tvar value = this.getValue();\n\n\tthis.setOptionsData( options );\n\n\t// Re-set the value to update the visible interface (RadioSelectWidget).\n\t// In case the previous value is no longer an available option, select the first valid one.\n\tthis.setValue( value );\n\n\treturn this;\n};\n\n/**\n * Set the internal list of options, used e.g. by setValue() to see which options are allowed.\n *\n * This method may be called before the parent constructor, so various properties may not be\n * intialized yet.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @private\n */\nOO.ui.RadioSelectInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar widget = this;\n\n\tthis.radioSelectWidget\n\t\t.clearItems()\n\t\t.addItems( options.map( function ( opt ) {\n\t\t\tvar optValue = widget.cleanUpValue( opt.data );\n\t\t\treturn new OO.ui.RadioOptionWidget( {\n\t\t\t\tdata: optValue,\n\t\t\t\tlabel: opt.label !== undefined ? opt.label : optValue\n\t\t\t} );\n\t\t} ) );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.focus = function () {\n\tthis.radioSelectWidget.focus();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.blur = function () {\n\tthis.radioSelectWidget.blur();\n\treturn this;\n};\n","/**\n * CheckboxMultiselectInputWidget is a\n * {@link OO.ui.CheckboxMultiselectWidget CheckboxMultiselectWidget} intended to be used within a\n * HTML form, such as a OO.ui.FormLayout. The selected values are synchronized with the value of\n * HTML `<input type=checkbox>` tags. Please see the [OOUI documentation on MediaWiki][1] for\n * more information about input widgets.\n *\n *     @example\n *     // A CheckboxMultiselectInputWidget with three options.\n *     var multiselectInput = new OO.ui.CheckboxMultiselectInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second' },\n *             { data: 'c', label: 'Third' }\n *         ]\n *     } );\n *     $( document.body ).append( multiselectInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: …, disabled: … }`\n */\nOO.ui.CheckboxMultiselectInputWidget = function OoUiCheckboxMultiselectInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.checkboxMultiselectWidget = new OO.ui.CheckboxMultiselectWidget();\n\t// Must be set before the #setOptionsData call below\n\tthis.inputName = config.name;\n\t// Set up the options before parent constructor, which uses them to validate config.value.\n\t// Use this instead of setOptions() because this.$input is not set up yet\n\tthis.setOptionsData( config.options || [] );\n\n\t// Parent constructor\n\tOO.ui.CheckboxMultiselectInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.checkboxMultiselectWidget.connect( this, { select: 'onCheckboxesSelect' } );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-checkboxMultiselectInputWidget' )\n\t\t.append( this.checkboxMultiselectWidget.$element );\n\t// We don't use this.$input, but rather the CheckboxInputWidgets inside each option\n\tthis.$input.detach();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxMultiselectInputWidget, OO.ui.InputWidget );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.CheckboxMultiselectInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.value = $( node ).find( '.oo-ui-checkboxInputWidget .oo-ui-inputWidget-input:checked' )\n\t\t.toArray().map( function ( el ) { return el.value; } );\n\treturn state;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.static.reusePreInfuseDOM = function ( node, config ) {\n\tconfig = OO.ui.CheckboxMultiselectInputWidget.parent.static.reusePreInfuseDOM( node, config );\n\t// Cannot reuse the `<input type=checkbox>` set\n\tdelete config.$input;\n\treturn config;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.getInputElement = function () {\n\t// Actually unused\n\treturn $( '<unused>' );\n};\n\n/**\n * Handles CheckboxMultiselectWidget select events.\n *\n * @private\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.onCheckboxesSelect = function () {\n\tthis.setValue( this.checkboxMultiselectWidget.findSelectedItemsData() );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.getValue = function () {\n\tvar value = this.$element.find( '.oo-ui-checkboxInputWidget .oo-ui-inputWidget-input:checked' )\n\t\t.toArray().map( function ( el ) { return el.value; } );\n\tif ( this.value !== value ) {\n\t\tthis.setValue( value );\n\t}\n\treturn this.value;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setValue = function ( value ) {\n\tvalue = this.cleanUpValue( value );\n\tthis.checkboxMultiselectWidget.selectItemsByData( value );\n\tOO.ui.CheckboxMultiselectInputWidget.parent.prototype.setValue.call( this, value );\n\tif ( this.optionsDirty ) {\n\t\t// We reached this from the constructor or from #setOptions.\n\t\t// We have to update the <select> element.\n\t\tthis.updateOptionsInterface();\n\t}\n\treturn this;\n};\n\n/**\n * Clean up incoming value.\n *\n * @param {string[]} value Original value\n * @return {string[]} Cleaned up value\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.cleanUpValue = function ( value ) {\n\tvar i, singleValue,\n\t\tcleanValue = [];\n\tif ( !Array.isArray( value ) ) {\n\t\treturn cleanValue;\n\t}\n\tfor ( i = 0; i < value.length; i++ ) {\n\t\tsingleValue =\n\t\t\tOO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue.call( this, value[ i ] );\n\t\t// Remove options that we don't have here\n\t\tif ( !this.checkboxMultiselectWidget.findItemFromData( singleValue ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tcleanValue.push( singleValue );\n\t}\n\treturn cleanValue;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setDisabled = function ( state ) {\n\tthis.checkboxMultiselectWidget.setDisabled( state );\n\tOO.ui.CheckboxMultiselectInputWidget.parent.prototype.setDisabled.call( this, state );\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: …, disabled: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setOptions = function ( options ) {\n\tvar value = this.getValue();\n\n\tthis.setOptionsData( options );\n\n\t// Re-set the value to update the visible interface (CheckboxMultiselectWidget).\n\t// This will also get rid of any stale options that we just removed.\n\tthis.setValue( value );\n\n\treturn this;\n};\n\n/**\n * Set the internal list of options, used e.g. by setValue() to see which options are allowed.\n *\n * This method may be called before the parent constructor, so various properties may not be\n * intialized yet.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @private\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar widget = this;\n\n\tthis.optionsDirty = true;\n\n\tthis.checkboxMultiselectWidget\n\t\t.clearItems()\n\t\t.addItems( options.map( function ( opt ) {\n\t\t\tvar optValue, item, optDisabled;\n\t\t\toptValue =\n\t\t\t\tOO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue.call( widget, opt.data );\n\t\t\toptDisabled = opt.disabled !== undefined ? opt.disabled : false;\n\t\t\titem = new OO.ui.CheckboxMultioptionWidget( {\n\t\t\t\tdata: optValue,\n\t\t\t\tlabel: opt.label !== undefined ? opt.label : optValue,\n\t\t\t\tdisabled: optDisabled\n\t\t\t} );\n\t\t\t// Set the 'name' and 'value' for form submission\n\t\t\titem.checkbox.$input.attr( 'name', widget.inputName );\n\t\t\titem.checkbox.setValue( optValue );\n\t\t\treturn item;\n\t\t} ) );\n};\n\n/**\n * Update the user-visible interface to match the internal list of options and value.\n *\n * This method must only be called after the parent constructor.\n *\n * @private\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.updateOptionsInterface = function () {\n\tvar defaultValue = this.defaultValue;\n\n\tthis.checkboxMultiselectWidget.getItems().forEach( function ( item ) {\n\t\t// Remember original selection state. This property can be later used to check whether\n\t\t// the selection state of the input has been changed since it was created.\n\t\tvar isDefault = defaultValue.indexOf( item.getData() ) !== -1;\n\t\titem.checkbox.defaultSelected = isDefault;\n\t\titem.checkbox.$input[ 0 ].defaultChecked = isDefault;\n\t} );\n\n\tthis.optionsDirty = false;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.focus = function () {\n\tthis.checkboxMultiselectWidget.focus();\n\treturn this;\n};\n","/**\n * TextInputWidgets, like HTML text inputs, can be configured with options that customize the\n * size of the field as well as its presentation. In addition, these widgets can be configured\n * with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators}, an optional\n * validation-pattern (used to determine if an input value is valid or not) and an input filter,\n * which modifies incoming values rather than validating them.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // A TextInputWidget.\n *     var textInput = new OO.ui.TextInputWidget( {\n *         value: 'Text input'\n *     } )\n *     $( document.body ).append( textInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.PendingElement\n * @mixins OO.ui.mixin.LabelElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [type='text'] The value of the HTML `type` attribute: 'text', 'password'\n *  'email', 'url' or 'number'.\n * @cfg {string} [placeholder] Placeholder text\n * @cfg {boolean} [autofocus=false] Use an HTML `autofocus` attribute to\n *  instruct the browser to focus this widget.\n * @cfg {boolean} [readOnly=false] Prevent changes to the value of the text input.\n * @cfg {number} [maxLength] Maximum number of characters allowed in the input.\n *\n *  For unfortunate historical reasons, this counts the number of UTF-16 code units rather than\n *  Unicode codepoints, which means that codepoints outside the Basic Multilingual Plane (e.g.\n *  many emojis) count as 2 characters each.\n * @cfg {string} [labelPosition='after'] The position of the inline label relative to that of\n *  the value or placeholder text: `'before'` or `'after'`\n * @cfg {boolean} [required=false] Mark the field as required with `true`. Implies `indicator: 'required'`.\n *  Note that `false` & setting `indicator: 'required' will result in no indicator shown.\n * @cfg {boolean} [autocomplete=true] Should the browser support autocomplete for this field\n * @cfg {boolean} [spellcheck] Should the browser support spellcheck for this field (`undefined` means\n *  leaving it up to the browser).\n * @cfg {RegExp|Function|string} [validate] Validation pattern: when string, a symbolic name of a\n *  pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer'\n *  (the value must contain only numbers); when RegExp, a regular expression that must match the\n *  value for it to be considered valid; when Function, a function receiving the value as parameter\n *  that must return true, or promise resolving to true, for it to be considered valid.\n */\nOO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\ttype: 'text',\n\t\tlabelPosition: 'after'\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.TextInputWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$input } ) );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\n\t// Properties\n\tthis.type = this.getSaneType( config );\n\tthis.readOnly = false;\n\tthis.required = false;\n\tthis.validate = null;\n\tthis.scrollWidth = null;\n\n\tthis.setValidation( config.validate );\n\tthis.setLabelPosition( config.labelPosition );\n\n\t// Events\n\tthis.$input.on( {\n\t\tkeypress: this.onKeyPress.bind( this ),\n\t\tblur: this.onBlur.bind( this ),\n\t\tfocus: this.onFocus.bind( this )\n\t} );\n\tthis.$icon.on( 'mousedown', this.onIconMouseDown.bind( this ) );\n\tthis.$indicator.on( 'mousedown', this.onIndicatorMouseDown.bind( this ) );\n\tthis.on( 'labelChange', this.updatePosition.bind( this ) );\n\tthis.on( 'change', OO.ui.debounce( this.onDebouncedChange.bind( this ), 250 ) );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-textInputWidget oo-ui-textInputWidget-type-' + this.type )\n\t\t.append( this.$icon, this.$indicator );\n\tthis.setReadOnly( !!config.readOnly );\n\tthis.setRequired( !!config.required );\n\tif ( config.placeholder !== undefined ) {\n\t\tthis.$input.attr( 'placeholder', config.placeholder );\n\t}\n\tif ( config.maxLength !== undefined ) {\n\t\tthis.$input.attr( 'maxlength', config.maxLength );\n\t}\n\tif ( config.autofocus ) {\n\t\tthis.$input.attr( 'autofocus', 'autofocus' );\n\t}\n\tif ( config.autocomplete === false ) {\n\t\tthis.$input.attr( 'autocomplete', 'off' );\n\t\t// Turning off autocompletion also disables \"form caching\" when the user navigates to a\n\t\t// different page and then clicks \"Back\". Re-enable it when leaving. Borrowed from jQuery UI.\n\t\t$( window ).on( {\n\t\t\tbeforeunload: function () {\n\t\t\t\tthis.$input.removeAttr( 'autocomplete' );\n\t\t\t}.bind( this ),\n\t\t\tpageshow: function () {\n\t\t\t\t// Browsers don't seem to actually fire this event on \"Back\", they instead just reload the\n\t\t\t\t// whole page... it shouldn't hurt, though.\n\t\t\t\tthis.$input.attr( 'autocomplete', 'off' );\n\t\t\t}.bind( this )\n\t\t} );\n\t}\n\tif ( config.spellcheck !== undefined ) {\n\t\tthis.$input.attr( 'spellcheck', config.spellcheck ? 'true' : 'false' );\n\t}\n\tif ( this.label ) {\n\t\tthis.isWaitingToBeAttached = true;\n\t\tthis.installParentChangeDetector();\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TextInputWidget, OO.ui.InputWidget );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.PendingElement );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.LabelElement );\n\n/* Static Properties */\n\nOO.ui.TextInputWidget.static.validationPatterns = {\n\t'non-empty': /.+/,\n\tinteger: /^\\d+$/\n};\n\n/* Events */\n\n/**\n * An `enter` event is emitted when the user presses 'enter' inside the text box.\n *\n * @event enter\n */\n\n/* Methods */\n\n/**\n * Handle icon mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.TextInputWidget.prototype.onIconMouseDown = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle indicator mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.TextInputWidget.prototype.onIndicatorMouseDown = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @fires enter If enter key is pressed\n */\nOO.ui.TextInputWidget.prototype.onKeyPress = function ( e ) {\n\tif ( e.which === OO.ui.Keys.ENTER ) {\n\t\tthis.emit( 'enter', e );\n\t}\n};\n\n/**\n * Handle blur events.\n *\n * @private\n * @param {jQuery.Event} e Blur event\n */\nOO.ui.TextInputWidget.prototype.onBlur = function () {\n\tthis.setValidityFlag();\n};\n\n/**\n * Handle focus events.\n *\n * @private\n * @param {jQuery.Event} e Focus event\n */\nOO.ui.TextInputWidget.prototype.onFocus = function () {\n\tif ( this.isWaitingToBeAttached ) {\n\t\t// If we've received focus, then we must be attached to the document, and if\n\t\t// isWaitingToBeAttached is still true, that means the handler never fired. Fire it now.\n\t\tthis.onElementAttach();\n\t}\n\tthis.setValidityFlag( true );\n};\n\n/**\n * Handle element attach events.\n *\n * @private\n * @param {jQuery.Event} e Element attach event\n */\nOO.ui.TextInputWidget.prototype.onElementAttach = function () {\n\tthis.isWaitingToBeAttached = false;\n\t// Any previously calculated size is now probably invalid if we reattached elsewhere\n\tthis.valCache = null;\n\tthis.positionLabel();\n};\n\n/**\n * Handle debounced change events.\n *\n * @param {string} value\n * @private\n */\nOO.ui.TextInputWidget.prototype.onDebouncedChange = function () {\n\tthis.setValidityFlag();\n};\n\n/**\n * Check if the input is {@link #readOnly read-only}.\n *\n * @return {boolean}\n */\nOO.ui.TextInputWidget.prototype.isReadOnly = function () {\n\treturn this.readOnly;\n};\n\n/**\n * Set the {@link #readOnly read-only} state of the input.\n *\n * @param {boolean} state Make input read-only\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.setReadOnly = function ( state ) {\n\tthis.readOnly = !!state;\n\tthis.$input.prop( 'readOnly', this.readOnly );\n\treturn this;\n};\n\n/**\n * Check if the input is {@link #required required}.\n *\n * @return {boolean}\n */\nOO.ui.TextInputWidget.prototype.isRequired = function () {\n\treturn this.required;\n};\n\n/**\n * Set the {@link #required required} state of the input.\n *\n * @param {boolean} state Make input required\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.setRequired = function ( state ) {\n\tthis.required = !!state;\n\tif ( this.required ) {\n\t\tthis.$input\n\t\t\t.prop( 'required', true )\n\t\t\t.attr( 'aria-required', 'true' );\n\t\tif ( this.getIndicator() === null ) {\n\t\t\tthis.setIndicator( 'required' );\n\t\t}\n\t} else {\n\t\tthis.$input\n\t\t\t.prop( 'required', false )\n\t\t\t.removeAttr( 'aria-required' );\n\t\tif ( this.getIndicator() === 'required' ) {\n\t\t\tthis.setIndicator( null );\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Support function for making #onElementAttach work across browsers.\n *\n * This whole function could be replaced with one line of code using the DOMNodeInsertedIntoDocument\n * event, but it's not supported by Firefox and allegedly deprecated, so we only use it as fallback.\n *\n * Due to MutationObserver performance woes, #onElementAttach is only somewhat reliably called the\n * first time that the element gets attached to the documented.\n */\nOO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {\n\tvar mutationObserver, onRemove, topmostNode, fakeParentNode,\n\t\tMutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,\n\t\twidget = this;\n\n\tif ( MutationObserver ) {\n\t\t// The new way. If only it wasn't so ugly.\n\n\t\tif ( this.isElementAttached() ) {\n\t\t\t// Widget is attached already, do nothing. This breaks the functionality of this function when\n\t\t\t// the widget is detached and reattached. Alas, doing this correctly with MutationObserver\n\t\t\t// would require observation of the whole document, which would hurt performance of other,\n\t\t\t// more important code.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find topmost node in the tree\n\t\ttopmostNode = this.$element[ 0 ];\n\t\twhile ( topmostNode.parentNode ) {\n\t\t\ttopmostNode = topmostNode.parentNode;\n\t\t}\n\n\t\t// We have no way to detect the $element being attached somewhere without observing the entire\n\t\t// DOM with subtree modifications, which would hurt performance. So we cheat: we hook to the\n\t\t// parent node of $element, and instead detect when $element is removed from it (and thus\n\t\t// probably attached somewhere else). If there is no parent, we create a \"fake\" one. If it\n\t\t// doesn't get attached, we end up back here and create the parent.\n\n\t\tmutationObserver = new MutationObserver( function ( mutations ) {\n\t\t\tvar i, j, removedNodes;\n\t\t\tfor ( i = 0; i < mutations.length; i++ ) {\n\t\t\t\tremovedNodes = mutations[ i ].removedNodes;\n\t\t\t\tfor ( j = 0; j < removedNodes.length; j++ ) {\n\t\t\t\t\tif ( removedNodes[ j ] === topmostNode ) {\n\t\t\t\t\t\tsetTimeout( onRemove, 0 );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tonRemove = function () {\n\t\t\t// If the node was attached somewhere else, report it\n\t\t\tif ( widget.isElementAttached() ) {\n\t\t\t\twidget.onElementAttach();\n\t\t\t}\n\t\t\tmutationObserver.disconnect();\n\t\t\twidget.installParentChangeDetector();\n\t\t};\n\n\t\t// Create a fake parent and observe it\n\t\tfakeParentNode = $( '<div>' ).append( topmostNode )[ 0 ];\n\t\tmutationObserver.observe( fakeParentNode, { childList: true } );\n\t} else {\n\t\t// Using the DOMNodeInsertedIntoDocument event is much nicer and less magical, and works for\n\t\t// detachment and reattachment, but it's not supported by Firefox and allegedly deprecated.\n\t\tthis.$element.on( 'DOMNodeInsertedIntoDocument', this.onElementAttach.bind( this ) );\n\t}\n};\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.TextInputWidget.prototype.getInputElement = function ( config ) {\n\tif ( this.getSaneType( config ) === 'number' ) {\n\t\treturn $( '<input>' )\n\t\t\t.attr( 'step', 'any' )\n\t\t\t.attr( 'type', 'number' );\n\t} else {\n\t\treturn $( '<input>' ).attr( 'type', this.getSaneType( config ) );\n\t}\n};\n\n/**\n * Get sanitized value for 'type' for given config.\n *\n * @param {Object} config Configuration options\n * @return {string|null}\n * @protected\n */\nOO.ui.TextInputWidget.prototype.getSaneType = function ( config ) {\n\tvar allowedTypes = [\n\t\t'text',\n\t\t'password',\n\t\t'email',\n\t\t'url',\n\t\t'number'\n\t];\n\treturn allowedTypes.indexOf( config.type ) !== -1 ? config.type : 'text';\n};\n\n/**\n * Focus the input and select a specified range within the text.\n *\n * @param {number} from Select from offset\n * @param {number} [to] Select to offset, defaults to from\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.selectRange = function ( from, to ) {\n\tvar isBackwards, start, end,\n\t\tinput = this.$input[ 0 ];\n\n\tto = to || from;\n\n\tisBackwards = to < from;\n\tstart = isBackwards ? to : from;\n\tend = isBackwards ? from : to;\n\n\tthis.focus();\n\n\ttry {\n\t\tinput.setSelectionRange( start, end, isBackwards ? 'backward' : 'forward' );\n\t} catch ( e ) {\n\t\t// IE throws an exception if you call setSelectionRange on a unattached DOM node.\n\t\t// Rather than expensively check if the input is attached every time, just check\n\t\t// if it was the cause of an error being thrown. If not, rethrow the error.\n\t\tif ( this.getElementDocument().body.contains( input ) ) {\n\t\t\tthrow e;\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Get an object describing the current selection range in a directional manner\n *\n * @return {Object} Object containing 'from' and 'to' offsets\n */\nOO.ui.TextInputWidget.prototype.getRange = function () {\n\tvar input = this.$input[ 0 ],\n\t\tstart = input.selectionStart,\n\t\tend = input.selectionEnd,\n\t\tisBackwards = input.selectionDirection === 'backward';\n\n\treturn {\n\t\tfrom: isBackwards ? end : start,\n\t\tto: isBackwards ? start : end\n\t};\n};\n\n/**\n * Get the length of the text input value.\n *\n * This could differ from the length of #getValue if the\n * value gets filtered\n *\n * @return {number} Input length\n */\nOO.ui.TextInputWidget.prototype.getInputLength = function () {\n\treturn this.$input[ 0 ].value.length;\n};\n\n/**\n * Focus the input and select the entire text.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.select = function () {\n\treturn this.selectRange( 0, this.getInputLength() );\n};\n\n/**\n * Focus the input and move the cursor to the start.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.moveCursorToStart = function () {\n\treturn this.selectRange( 0 );\n};\n\n/**\n * Focus the input and move the cursor to the end.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.moveCursorToEnd = function () {\n\treturn this.selectRange( this.getInputLength() );\n};\n\n/**\n * Insert new content into the input.\n *\n * @param {string} content Content to be inserted\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.insertContent = function ( content ) {\n\tvar start, end,\n\t\trange = this.getRange(),\n\t\tvalue = this.getValue();\n\n\tstart = Math.min( range.from, range.to );\n\tend = Math.max( range.from, range.to );\n\n\tthis.setValue( value.slice( 0, start ) + content + value.slice( end ) );\n\tthis.selectRange( start + content.length );\n\treturn this;\n};\n\n/**\n * Insert new content either side of a selection.\n *\n * @param {string} pre Content to be inserted before the selection\n * @param {string} post Content to be inserted after the selection\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.encapsulateContent = function ( pre, post ) {\n\tvar start, end,\n\t\trange = this.getRange(),\n\t\toffset = pre.length;\n\n\tstart = Math.min( range.from, range.to );\n\tend = Math.max( range.from, range.to );\n\n\tthis.selectRange( start ).insertContent( pre );\n\tthis.selectRange( offset + end ).insertContent( post );\n\n\tthis.selectRange( offset + start, offset + end );\n\treturn this;\n};\n\n/**\n * Set the validation pattern.\n *\n * The validation pattern is either a regular expression, a function, or the symbolic name of a\n * pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer' (the\n * value must contain only numbers).\n *\n * @param {RegExp|Function|string|null} validate Regular expression, function, or the symbolic name\n *  of a pattern (either ‘integer’ or ‘non-empty’) defined by the class.\n */\nOO.ui.TextInputWidget.prototype.setValidation = function ( validate ) {\n\tif ( validate instanceof RegExp || validate instanceof Function ) {\n\t\tthis.validate = validate;\n\t} else {\n\t\tthis.validate = this.constructor.static.validationPatterns[ validate ] || /.*/;\n\t}\n};\n\n/**\n * Sets the 'invalid' flag appropriately.\n *\n * @param {boolean} [isValid] Optionally override validation result\n */\nOO.ui.TextInputWidget.prototype.setValidityFlag = function ( isValid ) {\n\tvar widget = this,\n\t\tsetFlag = function ( valid ) {\n\t\t\tif ( !valid ) {\n\t\t\t\twidget.$input.attr( 'aria-invalid', 'true' );\n\t\t\t} else {\n\t\t\t\twidget.$input.removeAttr( 'aria-invalid' );\n\t\t\t}\n\t\t\twidget.setFlags( { invalid: !valid } );\n\t\t};\n\n\tif ( isValid !== undefined ) {\n\t\tsetFlag( isValid );\n\t} else {\n\t\tthis.getValidity().then( function () {\n\t\t\tsetFlag( true );\n\t\t}, function () {\n\t\t\tsetFlag( false );\n\t\t} );\n\t}\n};\n\n/**\n * Get the validity of current value.\n *\n * This method returns a promise that resolves if the value is valid and rejects if\n * it isn't. Uses the {@link #validate validation pattern}  to check for validity.\n *\n * @return {jQuery.Promise} A promise that resolves if the value is valid, rejects if not.\n */\nOO.ui.TextInputWidget.prototype.getValidity = function () {\n\tvar result;\n\n\tfunction rejectOrResolve( valid ) {\n\t\tif ( valid ) {\n\t\t\treturn $.Deferred().resolve().promise();\n\t\t} else {\n\t\t\treturn $.Deferred().reject().promise();\n\t\t}\n\t}\n\n\t// Check browser validity and reject if it is invalid\n\tif (\n\t\tthis.$input[ 0 ].checkValidity !== undefined &&\n\t\tthis.$input[ 0 ].checkValidity() === false\n\t) {\n\t\treturn rejectOrResolve( false );\n\t}\n\n\t// Run our checks if the browser thinks the field is valid\n\tif ( this.validate instanceof Function ) {\n\t\tresult = this.validate( this.getValue() );\n\t\tif ( result && typeof result.promise === 'function' ) {\n\t\t\treturn result.promise().then( function ( valid ) {\n\t\t\t\treturn rejectOrResolve( valid );\n\t\t\t} );\n\t\t} else {\n\t\t\treturn rejectOrResolve( result );\n\t\t}\n\t} else {\n\t\treturn rejectOrResolve( this.getValue().match( this.validate ) );\n\t}\n};\n\n/**\n * Set the position of the inline label relative to that of the value: `‘before’` or `‘after’`.\n *\n * @param {string} labelPosition Label position, 'before' or 'after'\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.setLabelPosition = function ( labelPosition ) {\n\tthis.labelPosition = labelPosition;\n\tif ( this.label ) {\n\t\t// If there is no label and we only change the position, #updatePosition is a no-op,\n\t\t// but it takes really a lot of work to do nothing.\n\t\tthis.updatePosition();\n\t}\n\treturn this;\n};\n\n/**\n * Update the position of the inline label.\n *\n * This method is called by #setLabelPosition, and can also be called on its own if\n * something causes the label to be mispositioned.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.updatePosition = function () {\n\tvar after = this.labelPosition === 'after';\n\n\tthis.$element\n\t\t.toggleClass( 'oo-ui-textInputWidget-labelPosition-after', !!this.label && after )\n\t\t.toggleClass( 'oo-ui-textInputWidget-labelPosition-before', !!this.label && !after );\n\n\tthis.valCache = null;\n\tthis.scrollWidth = null;\n\tthis.positionLabel();\n\n\treturn this;\n};\n\n/**\n * Position the label by setting the correct padding on the input.\n *\n * @private\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.positionLabel = function () {\n\tvar after, rtl, property, newCss;\n\n\tif ( this.isWaitingToBeAttached ) {\n\t\t// #onElementAttach will be called soon, which calls this method\n\t\treturn this;\n\t}\n\n\tnewCss = {\n\t\t'padding-right': '',\n\t\t'padding-left': ''\n\t};\n\n\tif ( this.label ) {\n\t\tthis.$element.append( this.$label );\n\t} else {\n\t\tthis.$label.detach();\n\t\t// Clear old values if present\n\t\tthis.$input.css( newCss );\n\t\treturn;\n\t}\n\n\tafter = this.labelPosition === 'after';\n\trtl = this.$element.css( 'direction' ) === 'rtl';\n\tproperty = after === rtl ? 'padding-left' : 'padding-right';\n\n\tnewCss[ property ] = this.$label.outerWidth( true ) + ( after ? this.scrollWidth : 0 );\n\t// We have to clear the padding on the other side, in case the element direction changed\n\tthis.$input.css( newCss );\n\n\treturn this;\n};\n","/**\n * SearchInputWidgets are TextInputWidgets with `type=\"search\"` assigned and feature a\n * {@link OO.ui.mixin.IconElement search icon} by default.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs#SearchInputWidget\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.SearchInputWidget = function OoUiSearchInputWidget( config ) {\n\tconfig = $.extend( {\n\t\ticon: 'search'\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.SearchInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.connect( this, {\n\t\tchange: 'onChange'\n\t} );\n\n\t// Initialization\n\tthis.updateSearchIndicator();\n\tthis.connect( this, {\n\t\tdisable: 'onDisable'\n\t} );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SearchInputWidget, OO.ui.TextInputWidget );\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.SearchInputWidget.prototype.getSaneType = function () {\n\treturn 'search';\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SearchInputWidget.prototype.onIndicatorMouseDown = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\t// Clear the text field\n\t\tthis.setValue( '' );\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Update the 'clear' indicator displayed on type: 'search' text\n * fields, hiding it when the field is already empty or when it's not\n * editable.\n */\nOO.ui.SearchInputWidget.prototype.updateSearchIndicator = function () {\n\tif ( this.getValue() === '' || this.isDisabled() || this.isReadOnly() ) {\n\t\tthis.setIndicator( null );\n\t} else {\n\t\tthis.setIndicator( 'clear' );\n\t}\n};\n\n/**\n * Handle change events.\n *\n * @private\n */\nOO.ui.SearchInputWidget.prototype.onChange = function () {\n\tthis.updateSearchIndicator();\n};\n\n/**\n * Handle disable events.\n *\n * @param {boolean} disabled Element is disabled\n * @private\n */\nOO.ui.SearchInputWidget.prototype.onDisable = function () {\n\tthis.updateSearchIndicator();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SearchInputWidget.prototype.setReadOnly = function ( state ) {\n\tOO.ui.SearchInputWidget.parent.prototype.setReadOnly.call( this, state );\n\tthis.updateSearchIndicator();\n\treturn this;\n};\n","/**\n * MultilineTextInputWidgets, like HTML textareas, are featuring customization options to\n * configure number of rows visible. In addition, these widgets can be autosized to fit user\n * inputs and can show {@link OO.ui.mixin.IconElement icons} and\n * {@link OO.ui.mixin.IndicatorElement indicators}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // A MultilineTextInputWidget.\n *     var multilineTextInput = new OO.ui.MultilineTextInputWidget( {\n *         value: 'Text input on multiple lines'\n *     } )\n *     $( 'body' ).append( multilineTextInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs#MultilineTextInputWidget\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number} [rows] Number of visible lines in textarea. If used with `autosize`,\n *  specifies minimum number of rows to display.\n * @cfg {boolean} [autosize=false] Automatically resize the text input to fit its content.\n *  Use the #maxRows config to specify a maximum number of displayed rows.\n * @cfg {number} [maxRows] Maximum number of rows to display when #autosize is set to true.\n *  Defaults to the maximum of `10` and `2 * rows`, or `10` if `rows` isn't provided.\n */\nOO.ui.MultilineTextInputWidget = function OoUiMultilineTextInputWidget( config ) {\n\tconfig = $.extend( {\n\t\ttype: 'text'\n\t}, config );\n\t// Parent constructor\n\tOO.ui.MultilineTextInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.autosize = !!config.autosize;\n\tthis.styleHeight = null;\n\tthis.minRows = config.rows !== undefined ? config.rows : '';\n\tthis.maxRows = config.maxRows || Math.max( 2 * ( this.minRows || 0 ), 10 );\n\n\t// Clone for resizing\n\tif ( this.autosize ) {\n\t\tthis.$clone = this.$input\n\t\t\t.clone()\n\t\t\t.removeAttr( 'id' )\n\t\t\t.removeAttr( 'name' )\n\t\t\t.insertAfter( this.$input )\n\t\t\t.attr( 'aria-hidden', 'true' )\n\t\t\t.addClass( 'oo-ui-element-hidden' );\n\t}\n\n\t// Events\n\tthis.connect( this, {\n\t\tchange: 'onChange'\n\t} );\n\n\t// Initialization\n\tif ( config.rows ) {\n\t\tthis.$input.attr( 'rows', config.rows );\n\t}\n\tif ( this.autosize ) {\n\t\tthis.$input.addClass( 'oo-ui-textInputWidget-autosized' );\n\t\tthis.isWaitingToBeAttached = true;\n\t\tthis.installParentChangeDetector();\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MultilineTextInputWidget, OO.ui.TextInputWidget );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.MultilineTextInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.scrollTop = config.$input.scrollTop();\n\treturn state;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.prototype.onElementAttach = function () {\n\tOO.ui.MultilineTextInputWidget.parent.prototype.onElementAttach.call( this );\n\tthis.adjustSize();\n};\n\n/**\n * Handle change events.\n *\n * @private\n */\nOO.ui.MultilineTextInputWidget.prototype.onChange = function () {\n\tthis.adjustSize();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.prototype.updatePosition = function () {\n\tOO.ui.MultilineTextInputWidget.parent.prototype.updatePosition.call( this );\n\tthis.adjustSize();\n};\n\n/**\n * @inheritdoc\n *\n * Modify to emit 'enter' on Ctrl/Meta+Enter, instead of plain Enter\n */\nOO.ui.MultilineTextInputWidget.prototype.onKeyPress = function ( e ) {\n\tif (\n\t\t( e.which === OO.ui.Keys.ENTER && ( e.ctrlKey || e.metaKey ) ) ||\n\t\t// Some platforms emit keycode 10 for ctrl+enter in a textarea\n\t\te.which === 10\n\t) {\n\t\tthis.emit( 'enter', e );\n\t}\n};\n\n/**\n * Automatically adjust the size of the text input.\n *\n * This only affects multiline inputs that are {@link #autosize autosized}.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n * @fires resize\n */\nOO.ui.MultilineTextInputWidget.prototype.adjustSize = function () {\n\tvar scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError,\n\t\tidealHeight, newHeight, scrollWidth, property;\n\n\tif ( this.$input.val() !== this.valCache ) {\n\t\tif ( this.autosize ) {\n\t\t\tthis.$clone\n\t\t\t\t.val( this.$input.val() )\n\t\t\t\t.attr( 'rows', this.minRows )\n\t\t\t\t// Set inline height property to 0 to measure scroll height\n\t\t\t\t.css( 'height', 0 );\n\n\t\t\tthis.$clone.removeClass( 'oo-ui-element-hidden' );\n\n\t\t\tthis.valCache = this.$input.val();\n\n\t\t\tscrollHeight = this.$clone[ 0 ].scrollHeight;\n\n\t\t\t// Remove inline height property to measure natural heights\n\t\t\tthis.$clone.css( 'height', '' );\n\t\t\tinnerHeight = this.$clone.innerHeight();\n\t\t\touterHeight = this.$clone.outerHeight();\n\n\t\t\t// Measure max rows height\n\t\t\tthis.$clone\n\t\t\t\t.attr( 'rows', this.maxRows )\n\t\t\t\t.css( 'height', 'auto' )\n\t\t\t\t.val( '' );\n\t\t\tmaxInnerHeight = this.$clone.innerHeight();\n\n\t\t\t// Difference between reported innerHeight and scrollHeight with no scrollbars present.\n\t\t\t// This is sometimes non-zero on Blink-based browsers, depending on zoom level.\n\t\t\tmeasurementError = maxInnerHeight - this.$clone[ 0 ].scrollHeight;\n\t\t\tidealHeight = Math.min( maxInnerHeight, scrollHeight + measurementError );\n\n\t\t\tthis.$clone.addClass( 'oo-ui-element-hidden' );\n\n\t\t\t// Only apply inline height when expansion beyond natural height is needed\n\t\t\t// Use the difference between the inner and outer height as a buffer\n\t\t\tnewHeight = idealHeight > innerHeight ? idealHeight + ( outerHeight - innerHeight ) : '';\n\t\t\tif ( newHeight !== this.styleHeight ) {\n\t\t\t\tthis.$input.css( 'height', newHeight );\n\t\t\t\tthis.styleHeight = newHeight;\n\t\t\t\tthis.emit( 'resize' );\n\t\t\t}\n\t\t}\n\t\tscrollWidth = this.$input[ 0 ].offsetWidth - this.$input[ 0 ].clientWidth;\n\t\tif ( scrollWidth !== this.scrollWidth ) {\n\t\t\tproperty = this.$element.css( 'direction' ) === 'rtl' ? 'left' : 'right';\n\t\t\t// Reset\n\t\t\tthis.$label.css( { right: '', left: '' } );\n\t\t\tthis.$indicator.css( { right: '', left: '' } );\n\n\t\t\tif ( scrollWidth ) {\n\t\t\t\tthis.$indicator.css( property, scrollWidth );\n\t\t\t\tif ( this.labelPosition === 'after' ) {\n\t\t\t\t\tthis.$label.css( property, scrollWidth );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.scrollWidth = scrollWidth;\n\t\t\tthis.positionLabel();\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.MultilineTextInputWidget.prototype.getInputElement = function () {\n\treturn $( '<textarea>' );\n};\n\n/**\n * Check if the input automatically adjusts its size.\n *\n * @return {boolean}\n */\nOO.ui.MultilineTextInputWidget.prototype.isAutosizing = function () {\n\treturn !!this.autosize;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.MultilineTextInputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.scrollTop !== undefined ) {\n\t\tthis.$input.scrollTop( state.scrollTop );\n\t}\n};\n","/**\n * ComboBoxInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value\n * can be entered manually) and a {@link OO.ui.MenuSelectWidget menu of options} (from which\n * a value can be chosen instead). Users can choose options from the combo box in one of two ways:\n *\n * - by typing a value in the text input field. If the value exactly matches the value of a menu\n *   option, that option will appear to be selected.\n * - by choosing a value from the menu. The value of the chosen option will then appear in the text\n *   input field.\n *\n * After the user chooses an option, its `data` will be used as a new value for the widget.\n * A `label` also can be specified for each option: if given, it will be shown instead of the\n * `data` in the dropdown menu.\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n * For more information about menus and options, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // A ComboBoxInputWidget.\n *     var comboBox = new OO.ui.ComboBoxInputWidget( {\n *         value: 'Option 1',\n *         options: [\n *             { data: 'Option 1' },\n *             { data: 'Option 2' },\n *             { data: 'Option 3' }\n *         ]\n *     } );\n *     $( document.body ).append( comboBox.$element );\n *\n *     @example\n *     // Example: A ComboBoxInputWidget with additional option labels.\n *     var comboBox = new OO.ui.ComboBoxInputWidget( {\n *         value: 'Option 1',\n *         options: [\n *             {\n *                 data: 'Option 1',\n *                 label: 'Option One'\n *             },\n *             {\n *                 data: 'Option 2',\n *                 label: 'Option Two'\n *             },\n *             {\n *                 data: 'Option 3',\n *                 label: 'Option Three'\n *             }\n *         ]\n *     } );\n *     $( document.body ).append( comboBox.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`\n * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.MenuSelectWidget menu select widget}.\n * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where\n *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the\n *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tautocomplete: false\n\t}, config );\n\n\t// ComboBoxInputWidget shouldn't support `multiline`\n\tconfig.multiline = false;\n\n\t// See InputWidget#reusePreInfuseDOM about `config.$input`\n\tif ( config.$input ) {\n\t\tconfig.$input.removeAttr( 'list' );\n\t}\n\n\t// Parent constructor\n\tOO.ui.ComboBoxInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.dropdownButton = new OO.ui.ButtonWidget( {\n\t\tclasses: [ 'oo-ui-comboBoxInputWidget-dropdownButton' ],\n\t\tlabel: OO.ui.msg( 'ooui-combobox-button-label' ),\n\t\tindicator: 'down',\n\t\tinvisibleLabel: true,\n\t\tdisabled: this.disabled\n\t} );\n\tthis.menu = new OO.ui.MenuSelectWidget( $.extend(\n\t\t{\n\t\t\twidget: this,\n\t\t\tinput: this,\n\t\t\t$floatableContainer: this.$element,\n\t\t\tdisabled: this.isDisabled()\n\t\t},\n\t\tconfig.menu\n\t) );\n\n\t// Events\n\tthis.connect( this, {\n\t\tchange: 'onInputChange',\n\t\tenter: 'onInputEnter'\n\t} );\n\tthis.dropdownButton.connect( this, {\n\t\tclick: 'onDropdownButtonClick'\n\t} );\n\tthis.menu.connect( this, {\n\t\tchoose: 'onMenuChoose',\n\t\tadd: 'onMenuItemsChange',\n\t\tremove: 'onMenuItemsChange',\n\t\ttoggle: 'onMenuToggle'\n\t} );\n\n\t// Initialization\n\tthis.$input.attr( {\n\t\trole: 'combobox',\n\t\t'aria-owns': this.menu.getElementId(),\n\t\t'aria-autocomplete': 'list'\n\t} );\n\tthis.dropdownButton.$button.attr( {\n\t\t'aria-controls': this.menu.getElementId()\n\t} );\n\t// Do not override options set via config.menu.items\n\tif ( config.options !== undefined ) {\n\t\tthis.setOptions( config.options );\n\t}\n\tthis.$field = $( '<div>' )\n\t\t.addClass( 'oo-ui-comboBoxInputWidget-field' )\n\t\t.append( this.$input, this.dropdownButton.$element );\n\tthis.$element\n\t\t.addClass( 'oo-ui-comboBoxInputWidget' )\n\t\t.append( this.$field );\n\tthis.$overlay.append( this.menu.$element );\n\tthis.onMenuItemsChange();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ComboBoxInputWidget, OO.ui.TextInputWidget );\n\n/* Methods */\n\n/**\n * Get the combobox's menu.\n *\n * @return {OO.ui.MenuSelectWidget} Menu widget\n */\nOO.ui.ComboBoxInputWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Get the combobox's text input widget.\n *\n * @return {OO.ui.TextInputWidget} Text input widget\n */\nOO.ui.ComboBoxInputWidget.prototype.getInput = function () {\n\treturn this;\n};\n\n/**\n * Handle input change events.\n *\n * @private\n * @param {string} value New value\n */\nOO.ui.ComboBoxInputWidget.prototype.onInputChange = function ( value ) {\n\tvar match = this.menu.findItemFromData( value );\n\n\tthis.menu.selectItem( match );\n\tif ( this.menu.findHighlightedItem() ) {\n\t\tthis.menu.highlightItem( match );\n\t}\n\n\tif ( !this.isDisabled() ) {\n\t\tthis.menu.toggle( true );\n\t}\n};\n\n/**\n * Handle input enter events.\n *\n * @private\n */\nOO.ui.ComboBoxInputWidget.prototype.onInputEnter = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.menu.toggle( false );\n\t}\n};\n\n/**\n * Handle button click events.\n *\n * @private\n */\nOO.ui.ComboBoxInputWidget.prototype.onDropdownButtonClick = function () {\n\tthis.menu.toggle();\n\tthis.focus();\n};\n\n/**\n * Handle menu choose events.\n *\n * @private\n * @param {OO.ui.OptionWidget} item Chosen item\n */\nOO.ui.ComboBoxInputWidget.prototype.onMenuChoose = function ( item ) {\n\tthis.setValue( item.getData() );\n};\n\n/**\n * Handle menu item change events.\n *\n * @private\n */\nOO.ui.ComboBoxInputWidget.prototype.onMenuItemsChange = function () {\n\tvar match = this.menu.findItemFromData( this.getValue() );\n\tthis.menu.selectItem( match );\n\tif ( this.menu.findHighlightedItem() ) {\n\t\tthis.menu.highlightItem( match );\n\t}\n\tthis.$element.toggleClass( 'oo-ui-comboBoxInputWidget-empty', this.menu.isEmpty() );\n};\n\n/**\n * Handle menu toggle events.\n *\n * @private\n * @param {boolean} isVisible Open state of the menu\n */\nOO.ui.ComboBoxInputWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tthis.$element.toggleClass( 'oo-ui-comboBoxInputWidget-open', isVisible );\n};\n\n/**\n * Update the disabled state of the controls\n *\n * @chainable\n * @protected\n * @return {OO.ui.ComboBoxInputWidget} The widget, for chaining\n */\nOO.ui.ComboBoxInputWidget.prototype.updateControlsDisabled = function () {\n\tvar disabled = this.isDisabled() || this.isReadOnly();\n\tif ( this.dropdownButton ) {\n\t\tthis.dropdownButton.setDisabled( disabled );\n\t}\n\tif ( this.menu ) {\n\t\tthis.menu.setDisabled( disabled );\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ComboBoxInputWidget.prototype.setDisabled = function () {\n\t// Parent method\n\tOO.ui.ComboBoxInputWidget.parent.prototype.setDisabled.apply( this, arguments );\n\tthis.updateControlsDisabled();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ComboBoxInputWidget.prototype.setReadOnly = function () {\n\t// Parent method\n\tOO.ui.ComboBoxInputWidget.parent.prototype.setReadOnly.apply( this, arguments );\n\tthis.updateControlsDisabled();\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {\n\tthis.getMenu()\n\t\t.clearItems()\n\t\t.addItems( options.map( function ( opt ) {\n\t\t\treturn new OO.ui.MenuOptionWidget( {\n\t\t\t\tdata: opt.data,\n\t\t\t\tlabel: opt.label !== undefined ? opt.label : opt.data\n\t\t\t} );\n\t\t} ) );\n\n\treturn this;\n};\n","/**\n * FieldLayouts are used with OO.ui.FieldsetLayout. Each FieldLayout requires a field-widget,\n * which is a widget that is specified by reference before any optional configuration settings.\n *\n * Field layouts can be configured with help text and/or labels. Labels are aligned in one of four ways:\n *\n * - **left**: The label is placed before the field-widget and aligned with the left margin.\n *   A left-alignment is used for forms with many fields.\n * - **right**: The label is placed before the field-widget and aligned to the right margin.\n *   A right-alignment is used for long but familiar forms which users tab through,\n *   verifying the current field with a quick glance at the label.\n * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms\n *   that users fill out from top to bottom.\n * - **inline**: The label is placed after the field-widget and aligned to the left.\n *   An inline-alignment is best used with checkboxes or radio buttons.\n *\n * Help text can either be:\n *\n * - accessed via a help icon that appears in the upper right corner of the rendered field layout, or\n * - shown as a subtle explanation below the label.\n *\n * If the help text is brief, or is essential to always expose it, set `helpInline` to `true`. If it\n * is long or not essential, leave `helpInline` to its default, `false`.\n *\n * Please see the [OOUI documentation on MediaWiki] [1] for examples and more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Layouts/Fields_and_Fieldsets\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {OO.ui.Widget} fieldWidget Field widget\n * @param {Object} [config] Configuration options\n * @cfg {string} [align='left'] Alignment of the label: 'left', 'right', 'top'\n *  or 'inline'\n * @cfg {Array} [errors] Error messages about the widget, which will be\n *  displayed below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @cfg {Array} [notices] Notices about the widget, which will be displayed\n *  below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n *  These are more visible than `help` messages when `helpInline` is set, and so\n *  might be good for transient messages.\n * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified\n *  and `helpInline` is `false`, a \"help\" icon will appear in the upper-right\n *  corner of the rendered field; clicking it will display the text in a popup.\n *  If `helpInline` is `true`, then a subtle description will be shown after the\n *  label.\n * @cfg {boolean} [helpInline=false] Whether or not the help should be inline,\n *  or shown when the \"help\" icon is clicked.\n * @cfg {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup, if\n * `help` is given.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n *\n * @throws {Error} An error is thrown if no widget is specified\n */\nOO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( fieldWidget ) && config === undefined ) {\n\t\tconfig = fieldWidget;\n\t\tfieldWidget = config.fieldWidget;\n\t}\n\n\t// Make sure we have required constructor arguments\n\tif ( fieldWidget === undefined ) {\n\t\tthrow new Error( 'Widget not found' );\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( { align: 'left', helpInline: false }, config );\n\n\t// Parent constructor\n\tOO.ui.FieldLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {\n\t\t$label: $( '<label>' )\n\t} ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );\n\n\t// Properties\n\tthis.fieldWidget = fieldWidget;\n\tthis.errors = [];\n\tthis.notices = [];\n\tthis.$field = this.isFieldInline() ? $( '<span>' ) : $( '<div>' );\n\tthis.$messages = $( '<ul>' );\n\tthis.$header = $( '<span>' );\n\tthis.$body = $( '<div>' );\n\tthis.align = null;\n\tthis.helpInline = config.helpInline;\n\n\t// Events\n\tthis.fieldWidget.connect( this, { disable: 'onFieldDisable' } );\n\n\t// Initialization\n\tthis.$help = config.help ?\n\t\tthis.createHelpElement( config.help, config.$overlay ) :\n\t\t$( [] );\n\tif ( this.fieldWidget.getInputId() ) {\n\t\tthis.$label.attr( 'for', this.fieldWidget.getInputId() );\n\t\tif ( this.helpInline ) {\n\t\t\tthis.$help.attr( 'for', this.fieldWidget.getInputId() );\n\t\t}\n\t} else {\n\t\tthis.$label.on( 'click', function () {\n\t\t\tthis.fieldWidget.simulateLabelClick();\n\t\t}.bind( this ) );\n\t\tif ( this.helpInline ) {\n\t\t\tthis.$help.on( 'click', function () {\n\t\t\t\tthis.fieldWidget.simulateLabelClick();\n\t\t\t}.bind( this ) );\n\t\t}\n\t}\n\tthis.$element\n\t\t.addClass( 'oo-ui-fieldLayout' )\n\t\t.toggleClass( 'oo-ui-fieldLayout-disabled', this.fieldWidget.isDisabled() )\n\t\t.append( this.$body );\n\tthis.$body.addClass( 'oo-ui-fieldLayout-body' );\n\tthis.$header.addClass( 'oo-ui-fieldLayout-header' );\n\tthis.$messages.addClass( 'oo-ui-fieldLayout-messages' );\n\tthis.$field\n\t\t.addClass( 'oo-ui-fieldLayout-field' )\n\t\t.append( this.fieldWidget.$element );\n\n\tthis.setErrors( config.errors || [] );\n\tthis.setNotices( config.notices || [] );\n\tthis.setAlignment( config.align );\n\t// Call this again to take into account the widget's accessKey\n\tthis.updateTitle();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.FieldLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.TitledElement );\n\n/* Methods */\n\n/**\n * Handle field disable events.\n *\n * @private\n * @param {boolean} value Field is disabled\n */\nOO.ui.FieldLayout.prototype.onFieldDisable = function ( value ) {\n\tthis.$element.toggleClass( 'oo-ui-fieldLayout-disabled', value );\n};\n\n/**\n * Get the widget contained by the field.\n *\n * @return {OO.ui.Widget} Field widget\n */\nOO.ui.FieldLayout.prototype.getField = function () {\n\treturn this.fieldWidget;\n};\n\n/**\n * Return `true` if the given field widget can be used with `'inline'` alignment (see\n * #setAlignment). Return `false` if it can't or if this can't be determined.\n *\n * @return {boolean}\n */\nOO.ui.FieldLayout.prototype.isFieldInline = function () {\n\t// This is very simplistic, but should be good enough.\n\treturn this.getField().$element.prop( 'tagName' ).toLowerCase() === 'span';\n};\n\n/**\n * @protected\n * @param {string} kind 'error' or 'notice'\n * @param {string|OO.ui.HtmlSnippet} text\n * @return {jQuery}\n */\nOO.ui.FieldLayout.prototype.makeMessage = function ( kind, text ) {\n\tvar $listItem, $icon, message;\n\t$listItem = $( '<li>' );\n\tif ( kind === 'error' ) {\n\t\t$icon = new OO.ui.IconWidget( { icon: 'alert', flags: [ 'warning' ] } ).$element;\n\t\t$listItem.attr( 'role', 'alert' );\n\t} else if ( kind === 'notice' ) {\n\t\t$icon = new OO.ui.IconWidget( { icon: 'notice' } ).$element;\n\t} else {\n\t\t$icon = '';\n\t}\n\tmessage = new OO.ui.LabelWidget( { label: text } );\n\t$listItem\n\t\t.append( $icon, message.$element )\n\t\t.addClass( 'oo-ui-fieldLayout-messages-' + kind );\n\treturn $listItem;\n};\n\n/**\n * Set the field alignment mode.\n *\n * @private\n * @param {string} value Alignment mode, either 'left', 'right', 'top' or 'inline'\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setAlignment = function ( value ) {\n\tif ( value !== this.align ) {\n\t\t// Default to 'left'\n\t\tif ( [ 'left', 'right', 'top', 'inline' ].indexOf( value ) === -1 ) {\n\t\t\tvalue = 'left';\n\t\t}\n\t\t// Validate\n\t\tif ( value === 'inline' && !this.isFieldInline() ) {\n\t\t\tvalue = 'top';\n\t\t}\n\t\t// Reorder elements\n\n\t\tif ( this.helpInline ) {\n\t\t\tif ( value === 'top' ) {\n\t\t\t\tthis.$header.append( this.$label );\n\t\t\t\tthis.$body.append( this.$header, this.$field, this.$help );\n\t\t\t} else if ( value === 'inline' ) {\n\t\t\t\tthis.$header.append( this.$label, this.$help );\n\t\t\t\tthis.$body.append( this.$field, this.$header );\n\t\t\t} else {\n\t\t\t\tthis.$header.append( this.$label, this.$help );\n\t\t\t\tthis.$body.append( this.$header, this.$field );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( value === 'top' ) {\n\t\t\t\tthis.$header.append( this.$help, this.$label );\n\t\t\t\tthis.$body.append( this.$header, this.$field );\n\t\t\t} else if ( value === 'inline' ) {\n\t\t\t\tthis.$header.append( this.$help, this.$label );\n\t\t\t\tthis.$body.append( this.$field, this.$header );\n\t\t\t} else {\n\t\t\t\tthis.$header.append( this.$label );\n\t\t\t\tthis.$body.append( this.$header, this.$help, this.$field );\n\t\t\t}\n\t\t}\n\t\t// Set classes. The following classes can be used here:\n\t\t// * oo-ui-fieldLayout-align-left\n\t\t// * oo-ui-fieldLayout-align-right\n\t\t// * oo-ui-fieldLayout-align-top\n\t\t// * oo-ui-fieldLayout-align-inline\n\t\tif ( this.align ) {\n\t\t\tthis.$element.removeClass( 'oo-ui-fieldLayout-align-' + this.align );\n\t\t}\n\t\tthis.$element.addClass( 'oo-ui-fieldLayout-align-' + value );\n\t\tthis.align = value;\n\t}\n\n\treturn this;\n};\n\n/**\n * Set the list of error messages.\n *\n * @param {Array} errors Error messages about the widget, which will be displayed below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setErrors = function ( errors ) {\n\tthis.errors = errors.slice();\n\tthis.updateMessages();\n\treturn this;\n};\n\n/**\n * Set the list of notice messages.\n *\n * @param {Array} notices Notices about the widget, which will be displayed below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setNotices = function ( notices ) {\n\tthis.notices = notices.slice();\n\tthis.updateMessages();\n\treturn this;\n};\n\n/**\n * Update the rendering of error and notice messages.\n *\n * @private\n */\nOO.ui.FieldLayout.prototype.updateMessages = function () {\n\tvar i;\n\tthis.$messages.empty();\n\n\tif ( this.errors.length || this.notices.length ) {\n\t\tthis.$body.after( this.$messages );\n\t} else {\n\t\tthis.$messages.remove();\n\t\treturn;\n\t}\n\n\tfor ( i = 0; i < this.notices.length; i++ ) {\n\t\tthis.$messages.append( this.makeMessage( 'notice', this.notices[ i ] ) );\n\t}\n\tfor ( i = 0; i < this.errors.length; i++ ) {\n\t\tthis.$messages.append( this.makeMessage( 'error', this.errors[ i ] ) );\n\t}\n};\n\n/**\n * Include information about the widget's accessKey in our title. TitledElement calls this method.\n * (This is a bit of a hack.)\n *\n * @protected\n * @param {string} title Tooltip label for 'title' attribute\n * @return {string}\n */\nOO.ui.FieldLayout.prototype.formatTitleWithAccessKey = function ( title ) {\n\tif ( this.fieldWidget && this.fieldWidget.formatTitleWithAccessKey ) {\n\t\treturn this.fieldWidget.formatTitleWithAccessKey( title );\n\t}\n\treturn title;\n};\n\n/**\n * Creates and returns the help element. Also sets the `aria-describedby`\n * attribute on the main element of the `fieldWidget`.\n *\n * @private\n * @param {string|OO.ui.HtmlSnippet} [help] Help text.\n * @param {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup.\n * @return {jQuery} The element that should become `this.$help`.\n */\nOO.ui.FieldLayout.prototype.createHelpElement = function ( help, $overlay ) {\n\tvar helpId, helpWidget;\n\n\tif ( this.helpInline ) {\n\t\thelpWidget = new OO.ui.LabelWidget( {\n\t\t\tlabel: help,\n\t\t\tclasses: [ 'oo-ui-inline-help' ]\n\t\t} );\n\n\t\thelpId = helpWidget.getElementId();\n\t} else {\n\t\thelpWidget = new OO.ui.PopupButtonWidget( {\n\t\t\t$overlay: $overlay,\n\t\t\tpopup: {\n\t\t\t\tpadded: true\n\t\t\t},\n\t\t\tclasses: [ 'oo-ui-fieldLayout-help' ],\n\t\t\tframed: false,\n\t\t\ticon: 'info',\n\t\t\tlabel: OO.ui.msg( 'ooui-field-help' ),\n\t\t\tinvisibleLabel: true\n\t\t} );\n\t\tif ( help instanceof OO.ui.HtmlSnippet ) {\n\t\t\thelpWidget.getPopup().$body.html( help.toString() );\n\t\t} else {\n\t\t\thelpWidget.getPopup().$body.text( help );\n\t\t}\n\n\t\thelpId = helpWidget.getPopup().getBodyId();\n\t}\n\n\t// Set the 'aria-describedby' attribute on the fieldWidget\n\t// Preference given to an input or a button\n\t(\n\t\tthis.fieldWidget.$input ||\n\t\tthis.fieldWidget.$button ||\n\t\tthis.fieldWidget.$element\n\t).attr( 'aria-describedby', helpId );\n\n\treturn helpWidget.$element;\n};\n","/**\n * ActionFieldLayouts are used with OO.ui.FieldsetLayout. The layout consists of a field-widget, a button,\n * and an optional label and/or help text. The field-widget (e.g., a {@link OO.ui.TextInputWidget TextInputWidget}),\n * is required and is specified before any optional configuration settings.\n *\n * Labels can be aligned in one of four ways:\n *\n * - **left**: The label is placed before the field-widget and aligned with the left margin.\n *   A left-alignment is used for forms with many fields.\n * - **right**: The label is placed before the field-widget and aligned to the right margin.\n *   A right-alignment is used for long but familiar forms which users tab through,\n *   verifying the current field with a quick glance at the label.\n * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms\n *   that users fill out from top to bottom.\n * - **inline**: The label is placed after the field-widget and aligned to the left.\n *   An inline-alignment is best used with checkboxes or radio buttons.\n *\n * Help text is accessed via a help icon that appears in the upper right corner of the rendered field layout when help\n * text is specified.\n *\n *     @example\n *     // Example of an ActionFieldLayout\n *     var actionFieldLayout = new OO.ui.ActionFieldLayout(\n *         new OO.ui.TextInputWidget( {\n *             placeholder: 'Field widget'\n *         } ),\n *         new OO.ui.ButtonWidget( {\n *             label: 'Button'\n *         } ),\n *         {\n *             label: 'An ActionFieldLayout. This label is aligned top',\n *             align: 'top',\n *             help: 'This is help text'\n *         }\n *     );\n *\n *     $( document.body ).append( actionFieldLayout.$element );\n *\n * @class\n * @extends OO.ui.FieldLayout\n *\n * @constructor\n * @param {OO.ui.Widget} fieldWidget Field widget\n * @param {OO.ui.ButtonWidget} buttonWidget Button widget\n * @param {Object} config\n */\nOO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWidget, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( fieldWidget ) && config === undefined ) {\n\t\tconfig = fieldWidget;\n\t\tfieldWidget = config.fieldWidget;\n\t\tbuttonWidget = config.buttonWidget;\n\t}\n\n\t// Parent constructor\n\tOO.ui.ActionFieldLayout.parent.call( this, fieldWidget, config );\n\n\t// Properties\n\tthis.buttonWidget = buttonWidget;\n\tthis.$button = $( '<span>' );\n\tthis.$input = this.isFieldInline() ? $( '<span>' ) : $( '<div>' );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-actionFieldLayout' );\n\tthis.$button\n\t\t.addClass( 'oo-ui-actionFieldLayout-button' )\n\t\t.append( this.buttonWidget.$element );\n\tthis.$input\n\t\t.addClass( 'oo-ui-actionFieldLayout-input' )\n\t\t.append( this.fieldWidget.$element );\n\tthis.$field\n\t\t.append( this.$input, this.$button );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );\n","/**\n * FieldsetLayouts are composed of one or more {@link OO.ui.FieldLayout FieldLayouts},\n * which each contain an individual widget and, optionally, a label. Each Fieldset can be\n * configured with a label as well. For more information and examples,\n * please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Example of a fieldset layout\n *     var input1 = new OO.ui.TextInputWidget( {\n *         placeholder: 'A text input field'\n *     } );\n *\n *     var input2 = new OO.ui.TextInputWidget( {\n *         placeholder: 'A text input field'\n *     } );\n *\n *     var fieldset = new OO.ui.FieldsetLayout( {\n *         label: 'Example of a fieldset layout'\n *     } );\n *\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( input1, {\n *             label: 'Field One'\n *         } ),\n *         new OO.ui.FieldLayout( input2, {\n *             label: 'Field Two'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Layouts/Fields_and_Fieldsets\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.FieldLayout[]} [items] An array of fields to add to the fieldset. See OO.ui.FieldLayout for more information about fields.\n * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a \"help\" icon will appear\n *  in the upper-right corner of the rendered field; clicking it will display the text in a popup.\n *  For important messages, you are advised to use `notices`, as they are always shown.\n * @cfg {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup, if `help` is given.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.FieldsetLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.$header = $( '<legend>' );\n\tif ( config.help ) {\n\t\tthis.popupButtonWidget = new OO.ui.PopupButtonWidget( {\n\t\t\t$overlay: config.$overlay,\n\t\t\tpopup: {\n\t\t\t\tpadded: true\n\t\t\t},\n\t\t\tclasses: [ 'oo-ui-fieldsetLayout-help' ],\n\t\t\tframed: false,\n\t\t\ticon: 'info',\n\t\t\tlabel: OO.ui.msg( 'ooui-field-help' ),\n\t\t\tinvisibleLabel: true\n\t\t} );\n\t\tif ( config.help instanceof OO.ui.HtmlSnippet ) {\n\t\t\tthis.popupButtonWidget.getPopup().$body.html( config.help.toString() );\n\t\t} else {\n\t\t\tthis.popupButtonWidget.getPopup().$body.text( config.help );\n\t\t}\n\t\tthis.$help = this.popupButtonWidget.$element;\n\t} else {\n\t\tthis.$help = $( [] );\n\t}\n\n\t// Initialization\n\tthis.$header\n\t\t.addClass( 'oo-ui-fieldsetLayout-header' )\n\t\t.append( this.$icon, this.$label, this.$help );\n\tthis.$group.addClass( 'oo-ui-fieldsetLayout-group' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-fieldsetLayout' )\n\t\t.prepend( this.$header, this.$group );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.FieldsetLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.GroupElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.FieldsetLayout.static.tagName = 'fieldset';\n","/**\n * FormLayouts are used to wrap {@link OO.ui.FieldsetLayout FieldsetLayouts} when you intend to use browser-based\n * form submission for the fields instead of handling them in JavaScript. Form layouts can be configured with an\n * HTML form action, an encoding type, and a method using the #action, #enctype, and #method configs, respectively.\n * See the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * Only widgets from the {@link OO.ui.InputWidget InputWidget} family support form submission. It\n * includes standard form elements like {@link OO.ui.CheckboxInputWidget checkboxes}, {@link\n * OO.ui.RadioInputWidget radio buttons} and {@link OO.ui.TextInputWidget text fields}, as well as\n * some fancier controls. Some controls have both regular and InputWidget variants, for example\n * OO.ui.DropdownWidget and OO.ui.DropdownInputWidget – only the latter support form submission and\n * often have simplified APIs to match the capabilities of HTML forms.\n * See the [OOUI documentation on MediaWiki] [2] for more information about InputWidgets.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Layouts/Forms\n * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n *     @example\n *     // Example of a form layout that wraps a fieldset layout\n *     var input1 = new OO.ui.TextInputWidget( {\n *         placeholder: 'Username'\n *     } );\n *     var input2 = new OO.ui.TextInputWidget( {\n *         placeholder: 'Password',\n *         type: 'password'\n *     } );\n *     var submit = new OO.ui.ButtonInputWidget( {\n *         label: 'Submit'\n *     } );\n *\n *     var fieldset = new OO.ui.FieldsetLayout( {\n *         label: 'A form layout'\n *     } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( input1, {\n *             label: 'Username',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( input2, {\n *             label: 'Password',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( submit )\n *     ] );\n *     var form = new OO.ui.FormLayout( {\n *         items: [ fieldset ],\n *         action: '/api/formhandler',\n *         method: 'get'\n *     } )\n *     $( document.body ).append( form.$element );\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [method] HTML form `method` attribute\n * @cfg {string} [action] HTML form `action` attribute\n * @cfg {string} [enctype] HTML form `enctype` attribute\n * @cfg {OO.ui.FieldsetLayout[]} [items] Fieldset layouts to add to the form layout.\n */\nOO.ui.FormLayout = function OoUiFormLayout( config ) {\n\tvar action;\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.FormLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );\n\n\t// Events\n\tthis.$element.on( 'submit', this.onFormSubmit.bind( this ) );\n\n\t// Make sure the action is safe\n\taction = config.action;\n\tif ( action !== undefined && !OO.ui.isSafeUrl( action ) ) {\n\t\taction = './' + action;\n\t}\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-formLayout' )\n\t\t.attr( {\n\t\t\tmethod: config.method,\n\t\t\taction: action,\n\t\t\tenctype: config.enctype\n\t\t} );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.FormLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.FormLayout, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * A 'submit' event is emitted when the form is submitted.\n *\n * @event submit\n */\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.FormLayout.static.tagName = 'form';\n\n/* Methods */\n\n/**\n * Handle form submit events.\n *\n * @private\n * @param {jQuery.Event} e Submit event\n * @fires submit\n * @return {OO.ui.FormLayout} The layout, for chaining\n */\nOO.ui.FormLayout.prototype.onFormSubmit = function () {\n\tif ( this.emit( 'submit' ) ) {\n\t\treturn false;\n\t}\n};\n","/**\n * PanelLayouts expand to cover the entire area of their parent. They can be configured with scrolling, padding,\n * and a frame, and are often used together with {@link OO.ui.StackLayout StackLayouts}.\n *\n *     @example\n *     // Example of a panel layout\n *     var panel = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true,\n *         padded: true,\n *         $content: $( '<p>A panel layout with padding and a frame.</p>' )\n *     } );\n *     $( document.body ).append( panel.$element );\n *\n * @class\n * @extends OO.ui.Layout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [scrollable=false] Allow vertical scrolling\n * @cfg {boolean} [padded=false] Add padding between the content and the edges of the panel.\n * @cfg {boolean} [expanded=true] Expand the panel to fill the entire parent element.\n * @cfg {boolean} [framed=false] Render the panel with a frame to visually separate it from outside content.\n */\nOO.ui.PanelLayout = function OoUiPanelLayout( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tscrollable: false,\n\t\tpadded: false,\n\t\texpanded: true,\n\t\tframed: false\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.PanelLayout.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-panelLayout' );\n\tif ( config.scrollable ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-scrollable' );\n\t}\n\tif ( config.padded ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-padded' );\n\t}\n\tif ( config.expanded ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-expanded' );\n\t}\n\tif ( config.framed ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-framed' );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout );\n\n/* Methods */\n\n/**\n * Focus the panel layout\n *\n * The default implementation just focuses the first focusable element in the panel\n */\nOO.ui.PanelLayout.prototype.focus = function () {\n\tOO.ui.findFocusable( this.$element ).focus();\n};\n","/**\n * HorizontalLayout arranges its contents in a single line (using `display: inline-block` for its\n * items), with small margins between them. Convenient when you need to put a number of block-level\n * widgets on a single line next to each other.\n *\n * Note that inline elements, such as OO.ui.ButtonWidgets, do not need this wrapper.\n *\n *     @example\n *     // HorizontalLayout with a text input and a label\n *     var layout = new OO.ui.HorizontalLayout( {\n *       items: [\n *         new OO.ui.LabelWidget( { label: 'Label' } ),\n *         new OO.ui.TextInputWidget( { value: 'Text' } )\n *       ]\n *     } );\n *     $( document.body ).append( layout.$element );\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.Widget[]|OO.ui.Layout[]} [items] Widgets or other layouts to add to the layout.\n */\nOO.ui.HorizontalLayout = function OoUiHorizontalLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.HorizontalLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-horizontalLayout' );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.HorizontalLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement );\n","/**\n * NumberInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value\n * can be entered manually) and two {@link OO.ui.ButtonWidget button widgets}\n * (to adjust the value in increments) to allow the user to enter a number.\n *\n *     @example\n *     // A NumberInputWidget.\n *     var numberInput = new OO.ui.NumberInputWidget( {\n *         label: 'NumberInputWidget',\n *         input: { value: 5 },\n *         min: 1,\n *         max: 10\n *     } );\n *     $( document.body ).append( numberInput.$element );\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object} [minusButton] Configuration options to pass to the\n *  {@link OO.ui.ButtonWidget decrementing button widget}.\n * @cfg {Object} [plusButton] Configuration options to pass to the\n *  {@link OO.ui.ButtonWidget incrementing button widget}.\n * @cfg {number} [min=-Infinity] Minimum allowed value\n * @cfg {number} [max=Infinity] Maximum allowed value\n * @cfg {number|null} [step] If specified, the field only accepts values that are multiples of this.\n * @cfg {number} [buttonStep=step||1] Delta when using the buttons or up/down arrow keys.\n *  Defaults to `step` if specified, otherwise `1`.\n * @cfg {number} [pageStep=10*buttonStep] Delta when using the page-up/page-down keys.\n *  Defaults to 10 times `buttonStep`.\n * @cfg {boolean} [showButtons=true] Whether to show the plus and minus buttons.\n */\nOO.ui.NumberInputWidget = function OoUiNumberInputWidget( config ) {\n\tvar $field = $( '<div>' )\n\t\t.addClass( 'oo-ui-numberInputWidget-field' );\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tmin: -Infinity,\n\t\tmax: Infinity,\n\t\tshowButtons: true\n\t}, config );\n\n\t// For backward compatibility\n\t$.extend( config, config.input );\n\tthis.input = this;\n\n\t// Parent constructor\n\tOO.ui.NumberInputWidget.parent.call( this, $.extend( config, {\n\t\ttype: 'number'\n\t} ) );\n\n\tif ( config.showButtons ) {\n\t\tthis.minusButton = new OO.ui.ButtonWidget( $.extend(\n\t\t\t{\n\t\t\t\tdisabled: this.isDisabled(),\n\t\t\t\ttabIndex: -1,\n\t\t\t\tclasses: [ 'oo-ui-numberInputWidget-minusButton' ],\n\t\t\t\ticon: 'subtract'\n\t\t\t},\n\t\t\tconfig.minusButton\n\t\t) );\n\t\tthis.minusButton.$element.attr( 'aria-hidden', 'true' );\n\t\tthis.plusButton = new OO.ui.ButtonWidget( $.extend(\n\t\t\t{\n\t\t\t\tdisabled: this.isDisabled(),\n\t\t\t\ttabIndex: -1,\n\t\t\t\tclasses: [ 'oo-ui-numberInputWidget-plusButton' ],\n\t\t\t\ticon: 'add'\n\t\t\t},\n\t\t\tconfig.plusButton\n\t\t) );\n\t\tthis.plusButton.$element.attr( 'aria-hidden', 'true' );\n\t}\n\n\t// Events\n\tthis.$input.on( {\n\t\tkeydown: this.onKeyDown.bind( this ),\n\t\t'wheel mousewheel DOMMouseScroll': this.onWheel.bind( this )\n\t} );\n\tif ( config.showButtons ) {\n\t\tthis.plusButton.connect( this, {\n\t\t\tclick: [ 'onButtonClick', +1 ]\n\t\t} );\n\t\tthis.minusButton.connect( this, {\n\t\t\tclick: [ 'onButtonClick', -1 ]\n\t\t} );\n\t}\n\n\t// Build the field\n\t$field.append( this.$input );\n\tif ( config.showButtons ) {\n\t\t$field\n\t\t\t.prepend( this.minusButton.$element )\n\t\t\t.append( this.plusButton.$element );\n\t}\n\n\t// Initialization\n\tif ( config.allowInteger || config.isInteger ) {\n\t\t// Backward compatibility\n\t\tconfig.step = 1;\n\t}\n\tthis.setRange( config.min, config.max );\n\tthis.setStep( config.buttonStep, config.pageStep, config.step );\n\t// Set the validation method after we set step and range\n\t// so that it doesn't immediately call setValidityFlag\n\tthis.setValidation( this.validateNumber.bind( this ) );\n\n\tthis.$element\n\t\t.addClass( 'oo-ui-numberInputWidget' )\n\t\t.toggleClass( 'oo-ui-numberInputWidget-buttoned', config.showButtons )\n\t\t.append( $field );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.NumberInputWidget, OO.ui.TextInputWidget );\n\n/* Methods */\n\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.setAllowInteger = function ( flag ) {\n\tthis.setStep( flag ? 1 : null );\n};\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.setIsInteger = OO.ui.NumberInputWidget.prototype.setAllowInteger;\n\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.getAllowInteger = function () {\n\treturn this.step === 1;\n};\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.getIsInteger = OO.ui.NumberInputWidget.prototype.getAllowInteger;\n\n/**\n * Set the range of allowed values\n *\n * @param {number} min Minimum allowed value\n * @param {number} max Maximum allowed value\n */\nOO.ui.NumberInputWidget.prototype.setRange = function ( min, max ) {\n\tif ( min > max ) {\n\t\tthrow new Error( 'Minimum (' + min + ') must not be greater than maximum (' + max + ')' );\n\t}\n\tthis.min = min;\n\tthis.max = max;\n\tthis.$input.attr( 'min', this.min );\n\tthis.$input.attr( 'max', this.max );\n\tthis.setValidityFlag();\n};\n\n/**\n * Get the current range\n *\n * @return {number[]} Minimum and maximum values\n */\nOO.ui.NumberInputWidget.prototype.getRange = function () {\n\treturn [ this.min, this.max ];\n};\n\n/**\n * Set the stepping deltas\n *\n * @param {number} [buttonStep=step||1] Delta when using the buttons or up/down arrow keys.\n *  Defaults to `step` if specified, otherwise `1`.\n * @param {number} [pageStep=10*buttonStep] Delta when using the page-up/page-down keys.\n *  Defaults to 10 times `buttonStep`.\n * @param {number|null} [step] If specified, the field only accepts values that are multiples of this.\n */\nOO.ui.NumberInputWidget.prototype.setStep = function ( buttonStep, pageStep, step ) {\n\tif ( buttonStep === undefined ) {\n\t\tbuttonStep = step || 1;\n\t}\n\tif ( pageStep === undefined ) {\n\t\tpageStep = 10 * buttonStep;\n\t}\n\tif ( step !== null && step <= 0 ) {\n\t\tthrow new Error( 'Step value, if given, must be positive' );\n\t}\n\tif ( buttonStep <= 0 ) {\n\t\tthrow new Error( 'Button step value must be positive' );\n\t}\n\tif ( pageStep <= 0 ) {\n\t\tthrow new Error( 'Page step value must be positive' );\n\t}\n\tthis.step = step;\n\tthis.buttonStep = buttonStep;\n\tthis.pageStep = pageStep;\n\tthis.$input.attr( 'step', this.step || 'any' );\n\tthis.setValidityFlag();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.NumberInputWidget.prototype.setValue = function ( value ) {\n\tif ( value === '' ) {\n\t\t// Some browsers allow a value in the input even if there isn't one reported by $input.val()\n\t\t// so here we make sure an 'empty' value is actually displayed as such.\n\t\tthis.$input.val( '' );\n\t}\n\treturn OO.ui.NumberInputWidget.parent.prototype.setValue.call( this, value );\n};\n\n/**\n * Get the current stepping values\n *\n * @return {number[]} Button step, page step, and validity step\n */\nOO.ui.NumberInputWidget.prototype.getStep = function () {\n\treturn [ this.buttonStep, this.pageStep, this.step ];\n};\n\n/**\n * Get the current value of the widget as a number\n *\n * @return {number} May be NaN, or an invalid number\n */\nOO.ui.NumberInputWidget.prototype.getNumericValue = function () {\n\treturn +this.getValue();\n};\n\n/**\n * Adjust the value of the widget\n *\n * @param {number} delta Adjustment amount\n */\nOO.ui.NumberInputWidget.prototype.adjustValue = function ( delta ) {\n\tvar n, v = this.getNumericValue();\n\n\tdelta = +delta;\n\tif ( isNaN( delta ) || !isFinite( delta ) ) {\n\t\tthrow new Error( 'Delta must be a finite number' );\n\t}\n\n\tif ( isNaN( v ) ) {\n\t\tn = 0;\n\t} else {\n\t\tn = v + delta;\n\t\tn = Math.max( Math.min( n, this.max ), this.min );\n\t\tif ( this.step ) {\n\t\t\tn = Math.round( n / this.step ) * this.step;\n\t\t}\n\t}\n\n\tif ( n !== v ) {\n\t\tthis.setValue( n );\n\t}\n};\n/**\n * Validate input\n *\n * @private\n * @param {string} value Field value\n * @return {boolean}\n */\nOO.ui.NumberInputWidget.prototype.validateNumber = function ( value ) {\n\tvar n = +value;\n\tif ( value === '' ) {\n\t\treturn !this.isRequired();\n\t}\n\n\tif ( isNaN( n ) || !isFinite( n ) ) {\n\t\treturn false;\n\t}\n\n\tif ( this.step && Math.floor( n / this.step ) !== n / this.step ) {\n\t\treturn false;\n\t}\n\n\tif ( n < this.min || n > this.max ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {number} dir +1 or -1\n */\nOO.ui.NumberInputWidget.prototype.onButtonClick = function ( dir ) {\n\tthis.adjustValue( dir * this.buttonStep );\n};\n\n/**\n * Handle mouse wheel events.\n *\n * @private\n * @param {jQuery.Event} event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.NumberInputWidget.prototype.onWheel = function ( event ) {\n\tvar delta = 0;\n\n\tif ( !this.isDisabled() && this.$input.is( ':focus' ) ) {\n\t\t// Standard 'wheel' event\n\t\tif ( event.originalEvent.deltaMode !== undefined ) {\n\t\t\tthis.sawWheelEvent = true;\n\t\t}\n\t\tif ( event.originalEvent.deltaY ) {\n\t\t\tdelta = -event.originalEvent.deltaY;\n\t\t} else if ( event.originalEvent.deltaX ) {\n\t\t\tdelta = event.originalEvent.deltaX;\n\t\t}\n\n\t\t// Non-standard events\n\t\tif ( !this.sawWheelEvent ) {\n\t\t\tif ( event.originalEvent.wheelDeltaX ) {\n\t\t\t\tdelta = -event.originalEvent.wheelDeltaX;\n\t\t\t} else if ( event.originalEvent.wheelDeltaY ) {\n\t\t\t\tdelta = event.originalEvent.wheelDeltaY;\n\t\t\t} else if ( event.originalEvent.wheelDelta ) {\n\t\t\t\tdelta = event.originalEvent.wheelDelta;\n\t\t\t} else if ( event.originalEvent.detail ) {\n\t\t\t\tdelta = -event.originalEvent.detail;\n\t\t\t}\n\t\t}\n\n\t\tif ( delta ) {\n\t\t\tdelta = delta < 0 ? -1 : 1;\n\t\t\tthis.adjustValue( delta * this.buttonStep );\n\t\t}\n\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.NumberInputWidget.prototype.onKeyDown = function ( e ) {\n\tif ( !this.isDisabled() ) {\n\t\tswitch ( e.which ) {\n\t\t\tcase OO.ui.Keys.UP:\n\t\t\t\tthis.adjustValue( this.buttonStep );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.DOWN:\n\t\t\t\tthis.adjustValue( -this.buttonStep );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.PAGEUP:\n\t\t\t\tthis.adjustValue( this.pageStep );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.PAGEDOWN:\n\t\t\t\tthis.adjustValue( -this.pageStep );\n\t\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.NumberInputWidget.prototype.setDisabled = function ( disabled ) {\n\t// Parent method\n\tOO.ui.NumberInputWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tif ( this.minusButton ) {\n\t\tthis.minusButton.setDisabled( this.isDisabled() );\n\t}\n\tif ( this.plusButton ) {\n\t\tthis.plusButton.setDisabled( this.isDisabled() );\n\t}\n\n\treturn this;\n};\n","}( OO ) );\n"]}
\ No newline at end of file
+{"version":3,"sources":["../src/intro.js.txt","../src/core.js","tmp/src/core-messages.js","../src/mixin.js","../src/Element.js","../src/HtmlSnippet.js","../src/Layout.js","../src/Widget.js","../src/Theme.js","../src/mixins/TabIndexedElement.js","../src/mixins/ButtonElement.js","../src/mixins/GroupElement.js","../src/mixins/LabelElement.js","../src/mixins/IconElement.js","../src/mixins/IndicatorElement.js","../src/mixins/FlaggedElement.js","../src/mixins/TitledElement.js","../src/mixins/AccessKeyedElement.js","../src/widgets/ButtonWidget.js","../src/widgets/ButtonGroupWidget.js","../src/widgets/IconWidget.js","../src/widgets/IndicatorWidget.js","../src/widgets/LabelWidget.js","../src/mixins/PendingElement.js","../src/mixins/FloatableElement.js","../src/mixins/ClippableElement.js","../src/widgets/PopupWidget.js","../src/mixins/PopupElement.js","../src/widgets/PopupButtonWidget.js","../src/mixins/GroupWidget.js","../src/mixins/ItemWidget.js","../src/widgets/OptionWidget.js","../src/widgets/SelectWidget.js","../src/widgets/DecoratedOptionWidget.js","../src/widgets/MenuOptionWidget.js","../src/widgets/MenuSectionOptionWidget.js","../src/widgets/MenuSelectWidget.js","../src/widgets/DropdownWidget.js","../src/widgets/RadioOptionWidget.js","../src/widgets/RadioSelectWidget.js","../src/widgets/MultioptionWidget.js","../src/widgets/MultiselectWidget.js","../src/widgets/CheckboxMultioptionWidget.js","../src/widgets/CheckboxMultiselectWidget.js","../src/widgets/ProgressBarWidget.js","../src/widgets/InputWidget.js","../src/widgets/HiddenInputWidget.js","../src/widgets/ButtonInputWidget.js","../src/widgets/CheckboxInputWidget.js","../src/widgets/DropdownInputWidget.js","../src/widgets/RadioInputWidget.js","../src/widgets/RadioSelectInputWidget.js","../src/widgets/CheckboxMultiselectInputWidget.js","../src/widgets/TextInputWidget.js","../src/widgets/SearchInputWidget.js","../src/widgets/MultilineTextInputWidget.js","../src/widgets/ComboBoxInputWidget.js","../src/layouts/FieldLayout.js","../src/layouts/ActionFieldLayout.js","../src/layouts/FieldsetLayout.js","../src/layouts/FormLayout.js","../src/layouts/PanelLayout.js","../src/layouts/HorizontalLayout.js","../src/widgets/NumberInputWidget.js","../src/widgets/SelectFileInputWidget.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-core.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * Namespace for all classes, static methods and static properties.\n *\n * @class\n * @singleton\n */\nOO.ui = {};\n\nOO.ui.bind = $.proxy;\n\n/**\n * @property {Object}\n */\nOO.ui.Keys = {\n\tUNDEFINED: 0,\n\tBACKSPACE: 8,\n\tDELETE: 46,\n\tLEFT: 37,\n\tRIGHT: 39,\n\tUP: 38,\n\tDOWN: 40,\n\tENTER: 13,\n\tEND: 35,\n\tHOME: 36,\n\tTAB: 9,\n\tPAGEUP: 33,\n\tPAGEDOWN: 34,\n\tESCAPE: 27,\n\tSHIFT: 16,\n\tSPACE: 32\n};\n\n/**\n * Constants for MouseEvent.which\n *\n * @property {Object}\n */\nOO.ui.MouseButtons = {\n\tLEFT: 1,\n\tMIDDLE: 2,\n\tRIGHT: 3\n};\n\n/**\n * @property {number}\n * @private\n */\nOO.ui.elementId = 0;\n\n/**\n * Generate a unique ID for element\n *\n * @return {string} ID\n */\nOO.ui.generateElementId = function () {\n\tOO.ui.elementId++;\n\treturn 'ooui-' + OO.ui.elementId;\n};\n\n/**\n * Check if an element is focusable.\n * Inspired by :focusable in jQueryUI v1.11.4 - 2015-04-14\n *\n * @param {jQuery} $element Element to test\n * @return {boolean} Element is focusable\n */\nOO.ui.isFocusableElement = function ( $element ) {\n\tvar nodeName,\n\t\telement = $element[ 0 ];\n\n\t// Anything disabled is not focusable\n\tif ( element.disabled ) {\n\t\treturn false;\n\t}\n\n\t// Check if the element is visible\n\tif ( !(\n\t\t// This is quicker than calling $element.is( ':visible' )\n\t\t$.expr.pseudos.visible( element ) &&\n\t\t// Check that all parents are visible\n\t\t!$element.parents().addBack().filter( function () {\n\t\t\treturn $.css( this, 'visibility' ) === 'hidden';\n\t\t} ).length\n\t) ) {\n\t\treturn false;\n\t}\n\n\t// Check if the element is ContentEditable, which is the string 'true'\n\tif ( element.contentEditable === 'true' ) {\n\t\treturn true;\n\t}\n\n\t// Anything with a non-negative numeric tabIndex is focusable.\n\t// Use .prop to avoid browser bugs\n\tif ( $element.prop( 'tabIndex' ) >= 0 ) {\n\t\treturn true;\n\t}\n\n\t// Some element types are naturally focusable\n\t// (indexOf is much faster than regex in Chrome and about the\n\t// same in FF: https://jsperf.com/regex-vs-indexof-array2)\n\tnodeName = element.nodeName.toLowerCase();\n\tif ( [ 'input', 'select', 'textarea', 'button', 'object' ].indexOf( nodeName ) !== -1 ) {\n\t\treturn true;\n\t}\n\n\t// Links and areas are focusable if they have an href\n\tif ( ( nodeName === 'a' || nodeName === 'area' ) && $element.attr( 'href' ) !== undefined ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Find a focusable child.\n *\n * @param {jQuery} $container Container to search in\n * @param {boolean} [backwards] Search backwards\n * @return {jQuery} Focusable child, or an empty jQuery object if none found\n */\nOO.ui.findFocusable = function ( $container, backwards ) {\n\tvar $focusable = $( [] ),\n\t\t// $focusableCandidates is a superset of things that\n\t\t// could get matched by isFocusableElement\n\t\t$focusableCandidates = $container\n\t\t\t.find( 'input, select, textarea, button, object, a, area, [contenteditable], [tabindex]' );\n\n\tif ( backwards ) {\n\t\t$focusableCandidates = Array.prototype.reverse.call( $focusableCandidates );\n\t}\n\n\t$focusableCandidates.each( function () {\n\t\tvar $this = $( this );\n\t\tif ( OO.ui.isFocusableElement( $this ) ) {\n\t\t\t$focusable = $this;\n\t\t\treturn false;\n\t\t}\n\t} );\n\treturn $focusable;\n};\n\n/**\n * Get the user's language and any fallback languages.\n *\n * These language codes are used to localize user interface elements in the user's language.\n *\n * In environments that provide a localization system, this function should be overridden to\n * return the user's language(s). The default implementation returns English (en) only.\n *\n * @return {string[]} Language codes, in descending order of priority\n */\nOO.ui.getUserLanguages = function () {\n\treturn [ 'en' ];\n};\n\n/**\n * Get a value in an object keyed by language code.\n *\n * @param {Object.<string,Mixed>} obj Object keyed by language code\n * @param {string|null} [lang] Language code, if omitted or null defaults to any user language\n * @param {string} [fallback] Fallback code, used if no matching language can be found\n * @return {Mixed} Local value\n */\nOO.ui.getLocalValue = function ( obj, lang, fallback ) {\n\tvar i, len, langs;\n\n\t// Requested language\n\tif ( obj[ lang ] ) {\n\t\treturn obj[ lang ];\n\t}\n\t// Known user language\n\tlangs = OO.ui.getUserLanguages();\n\tfor ( i = 0, len = langs.length; i < len; i++ ) {\n\t\tlang = langs[ i ];\n\t\tif ( obj[ lang ] ) {\n\t\t\treturn obj[ lang ];\n\t\t}\n\t}\n\t// Fallback language\n\tif ( obj[ fallback ] ) {\n\t\treturn obj[ fallback ];\n\t}\n\t// First existing language\n\tfor ( lang in obj ) {\n\t\treturn obj[ lang ];\n\t}\n\n\treturn undefined;\n};\n\n/**\n * Check if a node is contained within another node.\n *\n * Similar to jQuery#contains except a list of containers can be supplied\n * and a boolean argument allows you to include the container in the match list\n *\n * @param {HTMLElement|HTMLElement[]} containers Container node(s) to search in\n * @param {HTMLElement} contained Node to find\n * @param {boolean} [matchContainers] Include the container(s) in the list of nodes to match,\n *  otherwise only match descendants\n * @return {boolean} The node is in the list of target nodes\n */\nOO.ui.contains = function ( containers, contained, matchContainers ) {\n\tvar i;\n\tif ( !Array.isArray( containers ) ) {\n\t\tcontainers = [ containers ];\n\t}\n\tfor ( i = containers.length - 1; i >= 0; i-- ) {\n\t\tif (\n\t\t\t( matchContainers && contained === containers[ i ] ) ||\n\t\t\t$.contains( containers[ i ], contained )\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/**\n * Return a function, that, as long as it continues to be invoked, will not\n * be triggered. The function will be called after it stops being called for\n * N milliseconds. If `immediate` is passed, trigger the function on the\n * leading edge, instead of the trailing.\n *\n * Ported from: http://underscorejs.org/underscore.js\n *\n * @param {Function} func Function to debounce\n * @param {number} [wait=0] Wait period in milliseconds\n * @param {boolean} [immediate] Trigger on leading edge\n * @return {Function} Debounced function\n */\nOO.ui.debounce = function ( func, wait, immediate ) {\n\tvar timeout;\n\treturn function () {\n\t\tvar context = this,\n\t\t\targs = arguments,\n\t\t\tlater = function () {\n\t\t\t\ttimeout = null;\n\t\t\t\tif ( !immediate ) {\n\t\t\t\t\tfunc.apply( context, args );\n\t\t\t\t}\n\t\t\t};\n\t\tif ( immediate && !timeout ) {\n\t\t\tfunc.apply( context, args );\n\t\t}\n\t\tif ( !timeout || wait ) {\n\t\t\tclearTimeout( timeout );\n\t\t\ttimeout = setTimeout( later, wait );\n\t\t}\n\t};\n};\n\n/**\n * Puts a console warning with provided message.\n *\n * @param {string} message Message\n */\nOO.ui.warnDeprecation = function ( message ) {\n\tif ( OO.getProp( window, 'console', 'warn' ) !== undefined ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn( message );\n\t}\n};\n\n/**\n * Returns a function, that, when invoked, will only be triggered at most once\n * during a given window of time. If called again during that window, it will\n * wait until the window ends and then trigger itself again.\n *\n * As it's not knowable to the caller whether the function will actually run\n * when the wrapper is called, return values from the function are entirely\n * discarded.\n *\n * @param {Function} func Function to throttle\n * @param {number} wait Throttle window length, in milliseconds\n * @return {Function} Throttled function\n */\nOO.ui.throttle = function ( func, wait ) {\n\tvar context, args, timeout,\n\t\tprevious = 0,\n\t\trun = function () {\n\t\t\ttimeout = null;\n\t\t\tprevious = Date.now();\n\t\t\tfunc.apply( context, args );\n\t\t};\n\treturn function () {\n\t\t// Check how long it's been since the last time the function was\n\t\t// called, and whether it's more or less than the requested throttle\n\t\t// period. If it's less, run the function immediately. If it's more,\n\t\t// set a timeout for the remaining time -- but don't replace an\n\t\t// existing timeout, since that'd indefinitely prolong the wait.\n\t\tvar remaining = wait - ( Date.now() - previous );\n\t\tcontext = this;\n\t\targs = arguments;\n\t\tif ( remaining <= 0 ) {\n\t\t\t// Note: unless wait was ridiculously large, this means we'll\n\t\t\t// automatically run the first time the function was called in a\n\t\t\t// given period. (If you provide a wait period larger than the\n\t\t\t// current Unix timestamp, you *deserve* unexpected behavior.)\n\t\t\tclearTimeout( timeout );\n\t\t\trun();\n\t\t} else if ( !timeout ) {\n\t\t\ttimeout = setTimeout( run, remaining );\n\t\t}\n\t};\n};\n\n/**\n * A (possibly faster) way to get the current timestamp as an integer.\n *\n * @deprecated Since 0.31.1; use `Date.now()` instead.\n * @return {number} Current timestamp, in milliseconds since the Unix epoch\n */\nOO.ui.now = function () {\n\tOO.ui.warnDeprecation( 'OO.ui.now() is deprecated, use Date.now() instead' );\n\treturn Date.now();\n};\n\n/**\n * Reconstitute a JavaScript object corresponding to a widget created by\n * the PHP implementation.\n *\n * This is an alias for `OO.ui.Element.static.infuse()`.\n *\n * @param {string|HTMLElement|jQuery} idOrNode\n *   A DOM id (if a string) or node for the widget to infuse.\n * @param {Object} [config] Configuration options\n * @return {OO.ui.Element}\n *   The `OO.ui.Element` corresponding to this (infusable) document node.\n */\nOO.ui.infuse = function ( idOrNode, config ) {\n\treturn OO.ui.Element.static.infuse( idOrNode, config );\n};\n\n/**\n * Get a localized message.\n *\n * After the message key, message parameters may optionally be passed. In the default\n * implementation, any occurrences of $1 are replaced with the first parameter, $2 with the\n * second parameter, etc.\n * Alternative implementations of OO.ui.msg may use any substitution system they like, as long\n * as they support unnamed, ordered message parameters.\n *\n * In environments that provide a localization system, this function should be overridden to\n * return the message translated in the user's language. The default implementation always\n * returns English messages. An example of doing this with\n * [jQuery.i18n](https://github.com/wikimedia/jquery.i18n) follows.\n *\n *     @example\n *     var i, iLen, button,\n *         messagePath = 'oojs-ui/dist/i18n/',\n *         languages = [ $.i18n().locale, 'ur', 'en' ],\n *         languageMap = {};\n *\n *     for ( i = 0, iLen = languages.length; i < iLen; i++ ) {\n *         languageMap[ languages[ i ] ] = messagePath + languages[ i ].toLowerCase() + '.json';\n *     }\n *\n *     $.i18n().load( languageMap ).done( function() {\n *         // Replace the built-in `msg` only once we've loaded the internationalization.\n *         // OOUI uses `OO.ui.deferMsg` for all initially-loaded messages. So long as\n *         // you put off creating any widgets until this promise is complete, no English\n *         // will be displayed.\n *         OO.ui.msg = $.i18n;\n *\n *         // A button displaying \"OK\" in the default locale\n *         button = new OO.ui.ButtonWidget( {\n *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),\n *             icon: 'check'\n *         } );\n *         $( document.body ).append( button.$element );\n *\n *         // A button displaying \"OK\" in Urdu\n *         $.i18n().locale = 'ur';\n *         button = new OO.ui.ButtonWidget( {\n *             label: OO.ui.msg( 'ooui-dialog-message-accept' ),\n *             icon: 'check'\n *         } );\n *         $( document.body ).append( button.$element );\n *     } );\n *\n * @param {string} key Message key\n * @param {...Mixed} [params] Message parameters\n * @return {string} Translated message with parameters substituted\n */\nOO.ui.msg = function ( key ) {\n\t// `OO.ui.msg.messages` is defined in code generated during the build process\n\tvar messages = OO.ui.msg.messages,\n\t\tmessage = messages[ key ],\n\t\tparams = Array.prototype.slice.call( arguments, 1 );\n\tif ( typeof message === 'string' ) {\n\t\t// Perform $1 substitution\n\t\tmessage = message.replace( /\\$(\\d+)/g, function ( unused, n ) {\n\t\t\tvar i = parseInt( n, 10 );\n\t\t\treturn params[ i - 1 ] !== undefined ? params[ i - 1 ] : '$' + n;\n\t\t} );\n\t} else {\n\t\t// Return placeholder if message not found\n\t\tmessage = '[' + key + ']';\n\t}\n\treturn message;\n};\n\n/**\n * Package a message and arguments for deferred resolution.\n *\n * Use this when you are statically specifying a message and the message may not yet be present.\n *\n * @param {string} key Message key\n * @param {...Mixed} [params] Message parameters\n * @return {Function} Function that returns the resolved message when executed\n */\nOO.ui.deferMsg = function () {\n\tvar args = arguments;\n\treturn function () {\n\t\treturn OO.ui.msg.apply( OO.ui, args );\n\t};\n};\n\n/**\n * Resolve a message.\n *\n * If the message is a function it will be executed, otherwise it will pass through directly.\n *\n * @param {Function|string} msg Deferred message, or message text\n * @return {string} Resolved message\n */\nOO.ui.resolveMsg = function ( msg ) {\n\tif ( typeof msg === 'function' ) {\n\t\treturn msg();\n\t}\n\treturn msg;\n};\n\n/**\n * @param {string} url\n * @return {boolean}\n */\nOO.ui.isSafeUrl = function ( url ) {\n\t// Keep this function in sync with php/Tag.php\n\tvar i, protocolWhitelist;\n\n\tfunction stringStartsWith( haystack, needle ) {\n\t\treturn haystack.substr( 0, needle.length ) === needle;\n\t}\n\n\tprotocolWhitelist = [\n\t\t'bitcoin', 'ftp', 'ftps', 'geo', 'git', 'gopher', 'http', 'https', 'irc', 'ircs',\n\t\t'magnet', 'mailto', 'mms', 'news', 'nntp', 'redis', 'sftp', 'sip', 'sips', 'sms', 'ssh',\n\t\t'svn', 'tel', 'telnet', 'urn', 'worldwind', 'xmpp'\n\t];\n\n\tif ( url === '' ) {\n\t\treturn true;\n\t}\n\n\tfor ( i = 0; i < protocolWhitelist.length; i++ ) {\n\t\tif ( stringStartsWith( url, protocolWhitelist[ i ] + ':' ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// This matches '//' too\n\tif ( stringStartsWith( url, '/' ) || stringStartsWith( url, './' ) ) {\n\t\treturn true;\n\t}\n\tif ( stringStartsWith( url, '?' ) || stringStartsWith( url, '#' ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Check if the user has a 'mobile' device.\n *\n * For our purposes this means the user is primarily using an\n * on-screen keyboard, touch input instead of a mouse and may\n * have a physically small display.\n *\n * It is left up to implementors to decide how to compute this\n * so the default implementation always returns false.\n *\n * @return {boolean} User is on a mobile device\n */\nOO.ui.isMobile = function () {\n\treturn false;\n};\n\n/**\n * Get the additional spacing that should be taken into account when displaying elements that are\n * clipped to the viewport, e.g. dropdown menus and popups. This is meant to be overridden to avoid\n * such menus overlapping any fixed headers/toolbars/navigation used by the site.\n *\n * @return {Object} Object with the properties 'top', 'right', 'bottom', 'left', each representing\n *  the extra spacing from that edge of viewport (in pixels)\n */\nOO.ui.getViewportSpacing = function () {\n\treturn {\n\t\ttop: 0,\n\t\tright: 0,\n\t\tbottom: 0,\n\t\tleft: 0\n\t};\n};\n\n/**\n * Get the default overlay, which is used by various widgets when they are passed `$overlay: true`.\n * See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n *\n * @return {jQuery} Default overlay node\n */\nOO.ui.getDefaultOverlay = function () {\n\tif ( !OO.ui.$defaultOverlay ) {\n\t\tOO.ui.$defaultOverlay = $( '<div>' ).addClass( 'oo-ui-defaultOverlay' );\n\t\t$( document.body ).append( OO.ui.$defaultOverlay );\n\t}\n\treturn OO.ui.$defaultOverlay;\n};\n","/**\n * Message store for the default implementation of OO.ui.msg.\n *\n * Environments that provide a localization system should not use this, but should override\n * OO.ui.msg altogether.\n *\n * @private\n */\nOO.ui.msg.messages = {\n\t\"ooui-outline-control-move-down\": \"Move item down\",\n\t\"ooui-outline-control-move-up\": \"Move item up\",\n\t\"ooui-outline-control-remove\": \"Remove item\",\n\t\"ooui-toolbar-more\": \"More\",\n\t\"ooui-toolgroup-expand\": \"More\",\n\t\"ooui-toolgroup-collapse\": \"Fewer\",\n\t\"ooui-item-remove\": \"Remove\",\n\t\"ooui-dialog-message-accept\": \"OK\",\n\t\"ooui-dialog-message-reject\": \"Cancel\",\n\t\"ooui-dialog-process-error\": \"Something went wrong\",\n\t\"ooui-dialog-process-dismiss\": \"Dismiss\",\n\t\"ooui-dialog-process-retry\": \"Try again\",\n\t\"ooui-dialog-process-continue\": \"Continue\",\n\t\"ooui-combobox-button-label\": \"Dropdown for combobox\",\n\t\"ooui-selectfile-button-select\": \"Select a file\",\n\t\"ooui-selectfile-not-supported\": \"File selection is not supported\",\n\t\"ooui-selectfile-placeholder\": \"No file is selected\",\n\t\"ooui-selectfile-dragdrop-placeholder\": \"Drop file here\",\n\t\"ooui-field-help\": \"Help\"\n};\n","/*!\n * Mixin namespace.\n */\n\n/**\n * Namespace for OOUI mixins.\n *\n * Mixins are named according to the type of object they are intended to\n * be mixed in to.  For example, OO.ui.mixin.GroupElement is intended to be\n * mixed in to an instance of OO.ui.Element, and OO.ui.mixin.GroupWidget\n * is intended to be mixed in to an instance of OO.ui.Widget.\n *\n * @class\n * @singleton\n */\nOO.ui.mixin = {};\n","/**\n * Each Element represents a rendering in the DOM—a button or an icon, for example, or anything\n * that is visible to a user. Unlike {@link OO.ui.Widget widgets}, plain elements usually do not\n * have events connected to them and can't be interacted with.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string[]} [classes] The names of the CSS classes to apply to the element. CSS styles are\n *  added to the top level (e.g., the outermost div) of the element. See the\n *  [OOUI documentation on MediaWiki][2] for an example.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches#cssExample\n * @cfg {string} [id] The HTML id attribute used in the rendered tag.\n * @cfg {string} [text] Text to insert\n * @cfg {Array} [content] An array of content elements to append (after #text).\n *  Strings will be html-escaped; use an OO.ui.HtmlSnippet to append raw HTML.\n *  Instances of OO.ui.Element will have their $element appended.\n * @cfg {jQuery} [$content] Content elements to append (after #text).\n * @cfg {jQuery} [$element] Wrapper element. Defaults to a new element with #getTagName.\n * @cfg {Mixed} [data] Custom data of any type or combination of types (e.g., string, number,\n *  array, object).\n *  Data can also be specified with the #setData method.\n */\nOO.ui.Element = function OoUiElement( config ) {\n\tif ( OO.ui.isDemo ) {\n\t\tthis.initialConfig = config;\n\t}\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$ = function () {\n\t\tOO.ui.warnDeprecation( 'this.$ is deprecated, use global $ instead' );\n\t\treturn $.apply( this, arguments );\n\t};\n\tthis.elementId = null;\n\tthis.visible = true;\n\tthis.data = config.data;\n\tthis.$element = config.$element ||\n\t\t$( document.createElement( this.getTagName() ) );\n\tthis.elementGroup = null;\n\n\t// Initialization\n\tif ( Array.isArray( config.classes ) ) {\n\t\tthis.$element.addClass( config.classes );\n\t}\n\tif ( config.id ) {\n\t\tthis.setElementId( config.id );\n\t}\n\tif ( config.text ) {\n\t\tthis.$element.text( config.text );\n\t}\n\tif ( config.content ) {\n\t\t// The `content` property treats plain strings as text; use an\n\t\t// HtmlSnippet to append HTML content.  `OO.ui.Element`s get their\n\t\t// appropriate $element appended.\n\t\tthis.$element.append( config.content.map( function ( v ) {\n\t\t\tif ( typeof v === 'string' ) {\n\t\t\t\t// Escape string so it is properly represented in HTML.\n\t\t\t\t// Don't create empty text nodes for empty strings.\n\t\t\t\treturn v ? document.createTextNode( v ) : undefined;\n\t\t\t} else if ( v instanceof OO.ui.HtmlSnippet ) {\n\t\t\t\t// Bypass escaping.\n\t\t\t\treturn v.toString();\n\t\t\t} else if ( v instanceof OO.ui.Element ) {\n\t\t\t\treturn v.$element;\n\t\t\t}\n\t\t\treturn v;\n\t\t} ) );\n\t}\n\tif ( config.$content ) {\n\t\t// The `$content` property treats plain strings as HTML.\n\t\tthis.$element.append( config.$content );\n\t}\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Element );\n\n/* Static Properties */\n\n/**\n * The name of the HTML tag used by the element.\n *\n * The static value may be ignored if the #getTagName method is overridden.\n *\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Element.static.tagName = 'div';\n\n/* Static Methods */\n\n/**\n * Reconstitute a JavaScript object corresponding to a widget created\n * by the PHP implementation.\n *\n * @param {string|HTMLElement|jQuery} idOrNode\n *   A DOM id (if a string) or node for the widget to infuse.\n * @param {Object} [config] Configuration options\n * @return {OO.ui.Element}\n *   The `OO.ui.Element` corresponding to this (infusable) document node.\n *   For `Tag` objects emitted on the HTML side (used occasionally for content)\n *   the value returned is a newly-created Element wrapping around the existing\n *   DOM node.\n */\nOO.ui.Element.static.infuse = function ( idOrNode, config ) {\n\tvar obj = OO.ui.Element.static.unsafeInfuse( idOrNode, config, false );\n\n\tif ( typeof idOrNode === 'string' ) {\n\t\t// IDs deprecated since 0.29.7\n\t\tOO.ui.warnDeprecation(\n\t\t\t'Passing a string ID to infuse is deprecated. Use an HTMLElement or jQuery collection instead.'\n\t\t);\n\t}\n\t// Verify that the type matches up.\n\t// FIXME: uncomment after T89721 is fixed, see T90929.\n\t/*\n\tif ( !( obj instanceof this['class'] ) ) {\n\t\tthrow new Error( 'Infusion type mismatch!' );\n\t}\n\t*/\n\treturn obj;\n};\n\n/**\n * Implementation helper for `infuse`; skips the type check and has an\n * extra property so that only the top-level invocation touches the DOM.\n *\n * @private\n * @param {string|HTMLElement|jQuery} idOrNode\n * @param {Object} [config] Configuration options\n * @param {jQuery.Promise} [domPromise] A promise that will be resolved\n *     when the top-level widget of this infusion is inserted into DOM,\n *     replacing the original node; only used internally.\n * @return {OO.ui.Element}\n */\nOO.ui.Element.static.unsafeInfuse = function ( idOrNode, config, domPromise ) {\n\t// look for a cached result of a previous infusion.\n\tvar id, $elem, error, data, cls, parts, parent, obj, top, state, infusedChildren;\n\tif ( typeof idOrNode === 'string' ) {\n\t\tid = idOrNode;\n\t\t$elem = $( document.getElementById( id ) );\n\t} else {\n\t\t$elem = $( idOrNode );\n\t\tid = $elem.attr( 'id' );\n\t}\n\tif ( !$elem.length ) {\n\t\tif ( typeof idOrNode === 'string' ) {\n\t\t\terror = 'Widget not found: ' + idOrNode;\n\t\t} else if ( idOrNode && idOrNode.selector ) {\n\t\t\terror = 'Widget not found: ' + idOrNode.selector;\n\t\t} else {\n\t\t\terror = 'Widget not found';\n\t\t}\n\t\tthrow new Error( error );\n\t}\n\tif ( $elem[ 0 ].oouiInfused ) {\n\t\t$elem = $elem[ 0 ].oouiInfused;\n\t}\n\tdata = $elem.data( 'ooui-infused' );\n\tif ( data ) {\n\t\t// cached!\n\t\tif ( data === true ) {\n\t\t\tthrow new Error( 'Circular dependency! ' + id );\n\t\t}\n\t\tif ( domPromise ) {\n\t\t\t// Pick up dynamic state, like focus, value of form inputs, scroll position, etc.\n\t\t\tstate = data.constructor.static.gatherPreInfuseState( $elem, data );\n\t\t\t// Restore dynamic state after the new element is re-inserted into DOM under\n\t\t\t// infused parent.\n\t\t\tdomPromise.done( data.restorePreInfuseState.bind( data, state ) );\n\t\t\tinfusedChildren = $elem.data( 'ooui-infused-children' );\n\t\t\tif ( infusedChildren && infusedChildren.length ) {\n\t\t\t\tinfusedChildren.forEach( function ( data ) {\n\t\t\t\t\tvar state = data.constructor.static.gatherPreInfuseState( $elem, data );\n\t\t\t\t\tdomPromise.done( data.restorePreInfuseState.bind( data, state ) );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\treturn data;\n\t}\n\tdata = $elem.attr( 'data-ooui' );\n\tif ( !data ) {\n\t\tthrow new Error( 'No infusion data found: ' + id );\n\t}\n\ttry {\n\t\tdata = JSON.parse( data );\n\t} catch ( _ ) {\n\t\tdata = null;\n\t}\n\tif ( !( data && data._ ) ) {\n\t\tthrow new Error( 'No valid infusion data found: ' + id );\n\t}\n\tif ( data._ === 'Tag' ) {\n\t\t// Special case: this is a raw Tag; wrap existing node, don't rebuild.\n\t\treturn new OO.ui.Element( $.extend( {}, config, { $element: $elem } ) );\n\t}\n\tparts = data._.split( '.' );\n\tcls = OO.getProp.apply( OO, [ window ].concat( parts ) );\n\tif ( cls === undefined ) {\n\t\tthrow new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );\n\t}\n\n\t// Verify that we're creating an OO.ui.Element instance\n\tparent = cls.parent;\n\n\twhile ( parent !== undefined ) {\n\t\tif ( parent === OO.ui.Element ) {\n\t\t\t// Safe\n\t\t\tbreak;\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\tif ( parent !== OO.ui.Element ) {\n\t\tthrow new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );\n\t}\n\n\tif ( !domPromise ) {\n\t\ttop = $.Deferred();\n\t\tdomPromise = top.promise();\n\t}\n\t$elem.data( 'ooui-infused', true ); // prevent loops\n\tdata.id = id; // implicit\n\tinfusedChildren = [];\n\tdata = OO.copy( data, null, function deserialize( value ) {\n\t\tvar infused;\n\t\tif ( OO.isPlainObject( value ) ) {\n\t\t\tif ( value.tag ) {\n\t\t\t\tinfused = OO.ui.Element.static.unsafeInfuse( value.tag, config, domPromise );\n\t\t\t\tinfusedChildren.push( infused );\n\t\t\t\t// Flatten the structure\n\t\t\t\tinfusedChildren.push.apply(\n\t\t\t\t\tinfusedChildren,\n\t\t\t\t\tinfused.$element.data( 'ooui-infused-children' ) || []\n\t\t\t\t);\n\t\t\t\tinfused.$element.removeData( 'ooui-infused-children' );\n\t\t\t\treturn infused;\n\t\t\t}\n\t\t\tif ( value.html !== undefined ) {\n\t\t\t\treturn new OO.ui.HtmlSnippet( value.html );\n\t\t\t}\n\t\t}\n\t} );\n\t// allow widgets to reuse parts of the DOM\n\tdata = cls.static.reusePreInfuseDOM( $elem[ 0 ], data );\n\t// pick up dynamic state, like focus, value of form inputs, scroll position, etc.\n\tstate = cls.static.gatherPreInfuseState( $elem[ 0 ], data );\n\t// rebuild widget\n\t// eslint-disable-next-line new-cap\n\tobj = new cls( $.extend( {}, config, data ) );\n\t// If anyone is holding a reference to the old DOM element,\n\t// let's allow them to OO.ui.infuse() it and do what they expect, see T105828.\n\t// Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design.\n\t$elem[ 0 ].oouiInfused = obj.$element;\n\t// now replace old DOM with this new DOM.\n\tif ( top ) {\n\t\t// An efficient constructor might be able to reuse the entire DOM tree of the original\n\t\t// element, so only mutate the DOM if we need to.\n\t\tif ( $elem[ 0 ] !== obj.$element[ 0 ] ) {\n\t\t\t$elem.replaceWith( obj.$element );\n\t\t}\n\t\ttop.resolve();\n\t}\n\tobj.$element.data( 'ooui-infused', obj );\n\tobj.$element.data( 'ooui-infused-children', infusedChildren );\n\t// set the 'data-ooui' attribute so we can identify infused widgets\n\tobj.$element.attr( 'data-ooui', '' );\n\t// restore dynamic state after the new element is inserted into DOM\n\tdomPromise.done( obj.restorePreInfuseState.bind( obj, state ) );\n\treturn obj;\n};\n\n/**\n * Pick out parts of `node`'s DOM to be reused when infusing a widget.\n *\n * This method **must not** make any changes to the DOM, only find interesting pieces and add them\n * to `config` (which should then be returned). Actual DOM juggling should then be done by the\n * constructor, which will be given the enhanced config.\n *\n * @protected\n * @param {HTMLElement} node\n * @param {Object} config\n * @return {Object}\n */\nOO.ui.Element.static.reusePreInfuseDOM = function ( node, config ) {\n\treturn config;\n};\n\n/**\n * Gather the dynamic state (focus, value of form inputs, scroll position, etc.) of an HTML DOM\n * node (and its children) that represent an Element of the same class and the given configuration,\n * generated by the PHP implementation.\n *\n * This method is called just before `node` is detached from the DOM. The return value of this\n * function will be passed to #restorePreInfuseState after the newly created widget's #$element\n * is inserted into DOM to replace `node`.\n *\n * @protected\n * @param {HTMLElement} node\n * @param {Object} config\n * @return {Object}\n */\nOO.ui.Element.static.gatherPreInfuseState = function () {\n\treturn {};\n};\n\n/**\n * Get a jQuery function within a specific document.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} context Context to bind the function to\n * @param {jQuery} [$iframe] HTML iframe element that contains the document, omit if document is\n *   not in an iframe\n * @return {Function} Bound jQuery function\n */\nOO.ui.Element.static.getJQuery = function ( context, $iframe ) {\n\tfunction wrapper( selector ) {\n\t\treturn $( selector, wrapper.context );\n\t}\n\n\twrapper.context = this.getDocument( context );\n\n\tif ( $iframe ) {\n\t\twrapper.$iframe = $iframe;\n\t}\n\n\treturn wrapper;\n};\n\n/**\n * Get the document of an element.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Object to get the document for\n * @return {HTMLDocument|null} Document object\n */\nOO.ui.Element.static.getDocument = function ( obj ) {\n\t// jQuery - selections created \"offscreen\" won't have a context, so .context isn't reliable\n\treturn ( obj[ 0 ] && obj[ 0 ].ownerDocument ) ||\n\t\t// Empty jQuery selections might have a context\n\t\tobj.context ||\n\t\t// HTMLElement\n\t\tobj.ownerDocument ||\n\t\t// Window\n\t\tobj.document ||\n\t\t// HTMLDocument\n\t\t( obj.nodeType === Node.DOCUMENT_NODE && obj ) ||\n\t\tnull;\n};\n\n/**\n * Get the window of an element or document.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the window for\n * @return {Window} Window object\n */\nOO.ui.Element.static.getWindow = function ( obj ) {\n\tvar doc = this.getDocument( obj );\n\treturn doc.defaultView;\n};\n\n/**\n * Get the direction of an element or document.\n *\n * @static\n * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the direction for\n * @return {string} Text direction, either 'ltr' or 'rtl'\n */\nOO.ui.Element.static.getDir = function ( obj ) {\n\tvar isDoc, isWin;\n\n\tif ( obj instanceof $ ) {\n\t\tobj = obj[ 0 ];\n\t}\n\tisDoc = obj.nodeType === Node.DOCUMENT_NODE;\n\tisWin = obj.document !== undefined;\n\tif ( isDoc || isWin ) {\n\t\tif ( isWin ) {\n\t\t\tobj = obj.document;\n\t\t}\n\t\tobj = obj.body;\n\t}\n\treturn $( obj ).css( 'direction' );\n};\n\n/**\n * Get the offset between two frames.\n *\n * TODO: Make this function not use recursion.\n *\n * @static\n * @param {Window} from Window of the child frame\n * @param {Window} [to=window] Window of the parent frame\n * @param {Object} [offset] Offset to start with, used internally\n * @return {Object} Offset object, containing left and top properties\n */\nOO.ui.Element.static.getFrameOffset = function ( from, to, offset ) {\n\tvar i, len, frames, frame, rect;\n\n\tif ( !to ) {\n\t\tto = window;\n\t}\n\tif ( !offset ) {\n\t\toffset = { top: 0, left: 0 };\n\t}\n\tif ( from.parent === from ) {\n\t\treturn offset;\n\t}\n\n\t// Get iframe element\n\tframes = from.parent.document.getElementsByTagName( 'iframe' );\n\tfor ( i = 0, len = frames.length; i < len; i++ ) {\n\t\tif ( frames[ i ].contentWindow === from ) {\n\t\t\tframe = frames[ i ];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Recursively accumulate offset values\n\tif ( frame ) {\n\t\trect = frame.getBoundingClientRect();\n\t\toffset.left += rect.left;\n\t\toffset.top += rect.top;\n\t\tif ( from !== to ) {\n\t\t\tthis.getFrameOffset( from.parent, offset );\n\t\t}\n\t}\n\treturn offset;\n};\n\n/**\n * Get the offset between two elements.\n *\n * The two elements may be in a different frame, but in that case the frame $element is in must\n * be contained in the frame $anchor is in.\n *\n * @static\n * @param {jQuery} $element Element whose position to get\n * @param {jQuery} $anchor Element to get $element's position relative to\n * @return {Object} Translated position coordinates, containing top and left properties\n */\nOO.ui.Element.static.getRelativePosition = function ( $element, $anchor ) {\n\tvar iframe, iframePos,\n\t\tpos = $element.offset(),\n\t\tanchorPos = $anchor.offset(),\n\t\telementDocument = this.getDocument( $element ),\n\t\tanchorDocument = this.getDocument( $anchor );\n\n\t// If $element isn't in the same document as $anchor, traverse up\n\twhile ( elementDocument !== anchorDocument ) {\n\t\tiframe = elementDocument.defaultView.frameElement;\n\t\tif ( !iframe ) {\n\t\t\tthrow new Error( '$element frame is not contained in $anchor frame' );\n\t\t}\n\t\tiframePos = $( iframe ).offset();\n\t\tpos.left += iframePos.left;\n\t\tpos.top += iframePos.top;\n\t\telementDocument = iframe.ownerDocument;\n\t}\n\tpos.left -= anchorPos.left;\n\tpos.top -= anchorPos.top;\n\treturn pos;\n};\n\n/**\n * Get element border sizes.\n *\n * @static\n * @param {HTMLElement} el Element to measure\n * @return {Object} Dimensions object with `top`, `left`, `bottom` and `right` properties\n */\nOO.ui.Element.static.getBorders = function ( el ) {\n\tvar doc = el.ownerDocument,\n\t\twin = doc.defaultView,\n\t\tstyle = win.getComputedStyle( el, null ),\n\t\t$el = $( el ),\n\t\ttop = parseFloat( style ? style.borderTopWidth : $el.css( 'borderTopWidth' ) ) || 0,\n\t\tleft = parseFloat( style ? style.borderLeftWidth : $el.css( 'borderLeftWidth' ) ) || 0,\n\t\tbottom = parseFloat( style ? style.borderBottomWidth : $el.css( 'borderBottomWidth' ) ) || 0,\n\t\tright = parseFloat( style ? style.borderRightWidth : $el.css( 'borderRightWidth' ) ) || 0;\n\n\treturn {\n\t\ttop: top,\n\t\tleft: left,\n\t\tbottom: bottom,\n\t\tright: right\n\t};\n};\n\n/**\n * Get dimensions of an element or window.\n *\n * @static\n * @param {HTMLElement|Window} el Element to measure\n * @return {Object} Dimensions object with `borders`, `scroll`, `scrollbar` and `rect` properties\n */\nOO.ui.Element.static.getDimensions = function ( el ) {\n\tvar $el, $win,\n\t\tdoc = el.ownerDocument || el.document,\n\t\twin = doc.defaultView;\n\n\tif ( win === el || el === doc.documentElement ) {\n\t\t$win = $( win );\n\t\treturn {\n\t\t\tborders: { top: 0, left: 0, bottom: 0, right: 0 },\n\t\t\tscroll: {\n\t\t\t\ttop: $win.scrollTop(),\n\t\t\t\tleft: $win.scrollLeft()\n\t\t\t},\n\t\t\tscrollbar: { right: 0, bottom: 0 },\n\t\t\trect: {\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tbottom: $win.innerHeight(),\n\t\t\t\tright: $win.innerWidth()\n\t\t\t}\n\t\t};\n\t} else {\n\t\t$el = $( el );\n\t\treturn {\n\t\t\tborders: this.getBorders( el ),\n\t\t\tscroll: {\n\t\t\t\ttop: $el.scrollTop(),\n\t\t\t\tleft: $el.scrollLeft()\n\t\t\t},\n\t\t\tscrollbar: {\n\t\t\t\tright: $el.innerWidth() - el.clientWidth,\n\t\t\t\tbottom: $el.innerHeight() - el.clientHeight\n\t\t\t},\n\t\t\trect: el.getBoundingClientRect()\n\t\t};\n\t}\n};\n\n/**\n * Get the number of pixels that an element's content is scrolled to the left.\n *\n * Adapted from <https://github.com/othree/jquery.rtl-scroll-type>.\n * Original code copyright 2012 Wei-Ko Kao, licensed under the MIT License.\n *\n * This function smooths out browser inconsistencies (nicely described in the README at\n * <https://github.com/othree/jquery.rtl-scroll-type>) and produces a result consistent\n * with Firefox's 'scrollLeft', which seems the sanest.\n *\n * @static\n * @method\n * @param {HTMLElement|Window} el Element to measure\n * @return {number} Scroll position from the left.\n *  If the element's direction is LTR, this is a positive number between `0` (initial scroll\n *  position) and `el.scrollWidth - el.clientWidth` (furthest possible scroll position).\n *  If the element's direction is RTL, this is a negative number between `0` (initial scroll\n *  position) and `-el.scrollWidth + el.clientWidth` (furthest possible scroll position).\n */\nOO.ui.Element.static.getScrollLeft = ( function () {\n\tvar rtlScrollType = null;\n\n\tfunction test() {\n\t\tvar $definer = $( '<div>' ).attr( {\n\t\t\t\tdir: 'rtl',\n\t\t\t\tstyle: 'font-size: 14px; width: 4px; height: 1px; position: absolute; top: -1000px; overflow: scroll;'\n\t\t\t} ).text( 'ABCD' ),\n\t\t\tdefiner = $definer[ 0 ];\n\n\t\t$definer.appendTo( 'body' );\n\t\tif ( definer.scrollLeft > 0 ) {\n\t\t\t// Safari, Chrome\n\t\t\trtlScrollType = 'default';\n\t\t} else {\n\t\t\tdefiner.scrollLeft = 1;\n\t\t\tif ( definer.scrollLeft === 0 ) {\n\t\t\t\t// Firefox, old Opera\n\t\t\t\trtlScrollType = 'negative';\n\t\t\t} else {\n\t\t\t\t// Internet Explorer, Edge\n\t\t\t\trtlScrollType = 'reverse';\n\t\t\t}\n\t\t}\n\t\t$definer.remove();\n\t}\n\n\treturn function getScrollLeft( el ) {\n\t\tvar isRoot = el.window === el ||\n\t\t\t\tel === el.ownerDocument.body ||\n\t\t\t\tel === el.ownerDocument.documentElement,\n\t\t\tscrollLeft = isRoot ? $( window ).scrollLeft() : el.scrollLeft,\n\t\t\t// All browsers use the correct scroll type ('negative') on the root, so don't\n\t\t\t// do any fixups when looking at the root element\n\t\t\tdirection = isRoot ? 'ltr' : $( el ).css( 'direction' );\n\n\t\tif ( direction === 'rtl' ) {\n\t\t\tif ( rtlScrollType === null ) {\n\t\t\t\ttest();\n\t\t\t}\n\t\t\tif ( rtlScrollType === 'reverse' ) {\n\t\t\t\tscrollLeft = -scrollLeft;\n\t\t\t} else if ( rtlScrollType === 'default' ) {\n\t\t\t\tscrollLeft = scrollLeft - el.scrollWidth + el.clientWidth;\n\t\t\t}\n\t\t}\n\n\t\treturn scrollLeft;\n\t};\n}() );\n\n/**\n * Get the root scrollable element of given element's document.\n *\n * On Blink-based browsers (Chrome etc.), `document.documentElement` can't be used to get or set\n * the scrollTop property; instead we have to use `document.body`. Changing and testing the value\n * lets us use 'body' or 'documentElement' based on what is working.\n *\n * https://code.google.com/p/chromium/issues/detail?id=303131\n *\n * @static\n * @param {HTMLElement} el Element to find root scrollable parent for\n * @return {HTMLElement} Scrollable parent, `document.body` or `document.documentElement`\n *     depending on browser\n */\nOO.ui.Element.static.getRootScrollableElement = function ( el ) {\n\tvar scrollTop, body;\n\n\tif ( OO.ui.scrollableElement === undefined ) {\n\t\tbody = el.ownerDocument.body;\n\t\tscrollTop = body.scrollTop;\n\t\tbody.scrollTop = 1;\n\n\t\t// In some browsers (observed in Chrome 56 on Linux Mint 18.1),\n\t\t// body.scrollTop doesn't become exactly 1, but a fractional value like 0.76\n\t\tif ( Math.round( body.scrollTop ) === 1 ) {\n\t\t\tbody.scrollTop = scrollTop;\n\t\t\tOO.ui.scrollableElement = 'body';\n\t\t} else {\n\t\t\tOO.ui.scrollableElement = 'documentElement';\n\t\t}\n\t}\n\n\treturn el.ownerDocument[ OO.ui.scrollableElement ];\n};\n\n/**\n * Get closest scrollable container.\n *\n * Traverses up until either a scrollable element or the root is reached, in which case the root\n * scrollable element will be returned (see #getRootScrollableElement).\n *\n * @static\n * @param {HTMLElement} el Element to find scrollable container for\n * @param {string} [dimension] Dimension of scrolling to look for; `x`, `y` or omit for either\n * @return {HTMLElement} Closest scrollable container\n */\nOO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) {\n\tvar i, val,\n\t\t// Browsers do not correctly return the computed value of 'overflow' when 'overflow-x' and\n\t\t// 'overflow-y' have different values, so we need to check the separate properties.\n\t\tprops = [ 'overflow-x', 'overflow-y' ],\n\t\t$parent = $( el ).parent();\n\n\tif ( dimension === 'x' || dimension === 'y' ) {\n\t\tprops = [ 'overflow-' + dimension ];\n\t}\n\n\t// Special case for the document root (which doesn't really have any scrollable container,\n\t// since it is the ultimate scrollable container, but this is probably saner than null or\n\t// exception).\n\tif ( $( el ).is( 'html, body' ) ) {\n\t\treturn this.getRootScrollableElement( el );\n\t}\n\n\twhile ( $parent.length ) {\n\t\tif ( $parent[ 0 ] === this.getRootScrollableElement( el ) ) {\n\t\t\treturn $parent[ 0 ];\n\t\t}\n\t\ti = props.length;\n\t\twhile ( i-- ) {\n\t\t\tval = $parent.css( props[ i ] );\n\t\t\t// We assume that elements with 'overflow' (in any direction) set to 'hidden' will\n\t\t\t// never be scrolled in that direction, but they can actually be scrolled\n\t\t\t// programatically. The user can unintentionally perform a scroll in such case even if\n\t\t\t// the application doesn't scroll programatically, e.g. when jumping to an anchor, or\n\t\t\t// when using built-in find functionality.\n\t\t\t// This could cause funny issues...\n\t\t\tif ( val === 'auto' || val === 'scroll' ) {\n\t\t\t\treturn $parent[ 0 ];\n\t\t\t}\n\t\t}\n\t\t$parent = $parent.parent();\n\t}\n\t// The element is unattached... return something mostly sane\n\treturn this.getRootScrollableElement( el );\n};\n\n/**\n * Scroll element into view.\n *\n * @static\n * @param {HTMLElement} el Element to scroll into view\n * @param {Object} [config] Configuration options\n * @param {string} [config.duration='fast'] jQuery animation duration value\n * @param {string} [config.direction] Scroll in only one direction, e.g. 'x' or 'y', omit\n *  to scroll in both directions\n * @return {jQuery.Promise} Promise which resolves when the scroll is complete\n */\nOO.ui.Element.static.scrollIntoView = function ( el, config ) {\n\tvar position, animations, container, $container, elementDimensions, containerDimensions,\n\t\t$window,\n\t\tdeferred = $.Deferred();\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\tanimations = {};\n\tcontainer = this.getClosestScrollableContainer( el, config.direction );\n\t$container = $( container );\n\telementDimensions = this.getDimensions( el );\n\tcontainerDimensions = this.getDimensions( container );\n\t$window = $( this.getWindow( el ) );\n\n\t// Compute the element's position relative to the container\n\tif ( $container.is( 'html, body' ) ) {\n\t\t// If the scrollable container is the root, this is easy\n\t\tposition = {\n\t\t\ttop: elementDimensions.rect.top,\n\t\t\tbottom: $window.innerHeight() - elementDimensions.rect.bottom,\n\t\t\tleft: elementDimensions.rect.left,\n\t\t\tright: $window.innerWidth() - elementDimensions.rect.right\n\t\t};\n\t} else {\n\t\t// Otherwise, we have to subtract el's coordinates from container's coordinates\n\t\tposition = {\n\t\t\ttop: elementDimensions.rect.top -\n\t\t\t\t( containerDimensions.rect.top + containerDimensions.borders.top ),\n\t\t\tbottom: containerDimensions.rect.bottom - containerDimensions.borders.bottom -\n\t\t\t\tcontainerDimensions.scrollbar.bottom - elementDimensions.rect.bottom,\n\t\t\tleft: elementDimensions.rect.left -\n\t\t\t\t( containerDimensions.rect.left + containerDimensions.borders.left ),\n\t\t\tright: containerDimensions.rect.right - containerDimensions.borders.right -\n\t\t\t\tcontainerDimensions.scrollbar.right - elementDimensions.rect.right\n\t\t};\n\t}\n\n\tif ( !config.direction || config.direction === 'y' ) {\n\t\tif ( position.top < 0 ) {\n\t\t\tanimations.scrollTop = containerDimensions.scroll.top + position.top;\n\t\t} else if ( position.top > 0 && position.bottom < 0 ) {\n\t\t\tanimations.scrollTop = containerDimensions.scroll.top +\n\t\t\t\tMath.min( position.top, -position.bottom );\n\t\t}\n\t}\n\tif ( !config.direction || config.direction === 'x' ) {\n\t\tif ( position.left < 0 ) {\n\t\t\tanimations.scrollLeft = containerDimensions.scroll.left + position.left;\n\t\t} else if ( position.left > 0 && position.right < 0 ) {\n\t\t\tanimations.scrollLeft = containerDimensions.scroll.left +\n\t\t\t\tMath.min( position.left, -position.right );\n\t\t}\n\t}\n\tif ( !$.isEmptyObject( animations ) ) {\n\t\t// eslint-disable-next-line no-jquery/no-animate\n\t\t$container.stop( true ).animate( animations, config.duration === undefined ?\n\t\t\t'fast' : config.duration );\n\t\t$container.queue( function ( next ) {\n\t\t\tdeferred.resolve();\n\t\t\tnext();\n\t\t} );\n\t} else {\n\t\tdeferred.resolve();\n\t}\n\treturn deferred.promise();\n};\n\n/**\n * Force the browser to reconsider whether it really needs to render scrollbars inside the element\n * and reserve space for them, because it probably doesn't.\n *\n * Workaround primarily for <https://code.google.com/p/chromium/issues/detail?id=387290>, but also\n * similar bugs in other browsers. \"Just\" forcing a reflow is not sufficient in all cases, we need\n * to first actually detach (or hide, but detaching is simpler) all children, *then* force a\n * reflow, and then reattach (or show) them back.\n *\n * @static\n * @param {HTMLElement} el Element to reconsider the scrollbars on\n */\nOO.ui.Element.static.reconsiderScrollbars = function ( el ) {\n\tvar i, len, scrollLeft, scrollTop, nodes = [];\n\t// Save scroll position\n\tscrollLeft = el.scrollLeft;\n\tscrollTop = el.scrollTop;\n\t// Detach all children\n\twhile ( el.firstChild ) {\n\t\tnodes.push( el.firstChild );\n\t\tel.removeChild( el.firstChild );\n\t}\n\t// Force reflow\n\t// eslint-disable-next-line no-void\n\tvoid el.offsetHeight;\n\t// Reattach all children\n\tfor ( i = 0, len = nodes.length; i < len; i++ ) {\n\t\tel.appendChild( nodes[ i ] );\n\t}\n\t// Restore scroll position (no-op if scrollbars disappeared)\n\tel.scrollLeft = scrollLeft;\n\tel.scrollTop = scrollTop;\n};\n\n/* Methods */\n\n/**\n * Toggle visibility of an element.\n *\n * @param {boolean} [show] Make element visible, omit to toggle visibility\n * @fires visible\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.toggle = function ( show ) {\n\tshow = show === undefined ? !this.visible : !!show;\n\n\tif ( show !== this.isVisible() ) {\n\t\tthis.visible = show;\n\t\tthis.$element.toggleClass( 'oo-ui-element-hidden', !this.visible );\n\t\tthis.emit( 'toggle', show );\n\t}\n\n\treturn this;\n};\n\n/**\n * Check if element is visible.\n *\n * @return {boolean} element is visible\n */\nOO.ui.Element.prototype.isVisible = function () {\n\treturn this.visible;\n};\n\n/**\n * Get element data.\n *\n * @return {Mixed} Element data\n */\nOO.ui.Element.prototype.getData = function () {\n\treturn this.data;\n};\n\n/**\n * Set element data.\n *\n * @param {Mixed} data Element data\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.setData = function ( data ) {\n\tthis.data = data;\n\treturn this;\n};\n\n/**\n * Set the element has an 'id' attribute.\n *\n * @param {string} id\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.setElementId = function ( id ) {\n\tthis.elementId = id;\n\tthis.$element.attr( 'id', id );\n\treturn this;\n};\n\n/**\n * Ensure that the element has an 'id' attribute, setting it to an unique value if it's missing,\n * and return its value.\n *\n * @return {string}\n */\nOO.ui.Element.prototype.getElementId = function () {\n\tif ( this.elementId === null ) {\n\t\tthis.setElementId( OO.ui.generateElementId() );\n\t}\n\treturn this.elementId;\n};\n\n/**\n * Check if element supports one or more methods.\n *\n * @param {string|string[]} methods Method or list of methods to check\n * @return {boolean} All methods are supported\n */\nOO.ui.Element.prototype.supports = function ( methods ) {\n\tvar i, len,\n\t\tsupport = 0;\n\n\tmethods = Array.isArray( methods ) ? methods : [ methods ];\n\tfor ( i = 0, len = methods.length; i < len; i++ ) {\n\t\tif ( typeof this[ methods[ i ] ] === 'function' ) {\n\t\t\tsupport++;\n\t\t}\n\t}\n\n\treturn methods.length === support;\n};\n\n/**\n * Update the theme-provided classes.\n *\n * @localdoc This is called in element mixins and widget classes any time state changes.\n *   Updating is debounced, minimizing overhead of changing multiple attributes and\n *   guaranteeing that theme updates do not occur within an element's constructor\n */\nOO.ui.Element.prototype.updateThemeClasses = function () {\n\tOO.ui.theme.queueUpdateElementClasses( this );\n};\n\n/**\n * Get the HTML tag name.\n *\n * Override this method to base the result on instance information.\n *\n * @return {string} HTML tag name\n */\nOO.ui.Element.prototype.getTagName = function () {\n\treturn this.constructor.static.tagName;\n};\n\n/**\n * Check if the element is attached to the DOM\n *\n * @return {boolean} The element is attached to the DOM\n */\nOO.ui.Element.prototype.isElementAttached = function () {\n\treturn $.contains( this.getElementDocument(), this.$element[ 0 ] );\n};\n\n/**\n * Get the DOM document.\n *\n * @return {HTMLDocument} Document object\n */\nOO.ui.Element.prototype.getElementDocument = function () {\n\t// Don't cache this in other ways either because subclasses could can change this.$element\n\treturn OO.ui.Element.static.getDocument( this.$element );\n};\n\n/**\n * Get the DOM window.\n *\n * @return {Window} Window object\n */\nOO.ui.Element.prototype.getElementWindow = function () {\n\treturn OO.ui.Element.static.getWindow( this.$element );\n};\n\n/**\n * Get closest scrollable container.\n *\n * @return {HTMLElement} Closest scrollable container\n */\nOO.ui.Element.prototype.getClosestScrollableElementContainer = function () {\n\treturn OO.ui.Element.static.getClosestScrollableContainer( this.$element[ 0 ] );\n};\n\n/**\n * Get group element is in.\n *\n * @return {OO.ui.mixin.GroupElement|null} Group element, null if none\n */\nOO.ui.Element.prototype.getElementGroup = function () {\n\treturn this.elementGroup;\n};\n\n/**\n * Set group element is in.\n *\n * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.Element.prototype.setElementGroup = function ( group ) {\n\tthis.elementGroup = group;\n\treturn this;\n};\n\n/**\n * Scroll element into view.\n *\n * @param {Object} [config] Configuration options\n * @return {jQuery.Promise} Promise which resolves when the scroll is complete\n */\nOO.ui.Element.prototype.scrollElementIntoView = function ( config ) {\n\tif (\n\t\t!this.isElementAttached() ||\n\t\t!this.isVisible() ||\n\t\t( this.getElementGroup() && !this.getElementGroup().isVisible() )\n\t) {\n\t\treturn $.Deferred().resolve();\n\t}\n\treturn OO.ui.Element.static.scrollIntoView( this.$element[ 0 ], config );\n};\n\n/**\n * Restore the pre-infusion dynamic state for this widget.\n *\n * This method is called after #$element has been inserted into DOM. The parameter is the return\n * value of #gatherPreInfuseState.\n *\n * @protected\n * @param {Object} state\n */\nOO.ui.Element.prototype.restorePreInfuseState = function () {\n};\n","/**\n * Wraps an HTML snippet for use with configuration values which default\n * to strings.  This bypasses the default html-escaping done to string\n * values.\n *\n * @class\n *\n * @constructor\n * @param {string} [content] HTML content\n */\nOO.ui.HtmlSnippet = function OoUiHtmlSnippet( content ) {\n\t// Properties\n\tthis.content = content;\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.HtmlSnippet );\n\n/* Methods */\n\n/**\n * Render into HTML.\n *\n * @return {string} Unchanged HTML snippet.\n */\nOO.ui.HtmlSnippet.prototype.toString = function () {\n\treturn this.content;\n};\n","/**\n * Layouts are containers for elements and are used to arrange other widgets of arbitrary type in\n * a way that is centrally controlled and can be updated dynamically. Layouts can be, and usually\n * are, combined.\n * See {@link OO.ui.FieldsetLayout FieldsetLayout}, {@link OO.ui.FieldLayout FieldLayout},\n * {@link OO.ui.FormLayout FormLayout}, {@link OO.ui.PanelLayout PanelLayout},\n * {@link OO.ui.StackLayout StackLayout}, {@link OO.ui.PageLayout PageLayout},\n * {@link OO.ui.HorizontalLayout HorizontalLayout}, and {@link OO.ui.BookletLayout BookletLayout}\n * for more information and examples.\n *\n * @abstract\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.Layout = function OoUiLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Layout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-layout' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Layout, OO.ui.Element );\nOO.mixinClass( OO.ui.Layout, OO.EventEmitter );\n\n/* Methods */\n\n/**\n * Reset scroll offsets\n *\n * @chainable\n * @return {OO.ui.Layout} The layout, for chaining\n */\nOO.ui.Layout.prototype.resetScroll = function () {\n\tthis.$element[ 0 ].scrollTop = 0;\n\t// TODO: Reset scrollLeft in an RTL-aware manner, see OO.ui.Element.static.getScrollLeft.\n\n\treturn this;\n};\n","/**\n * Widgets are compositions of one or more OOUI elements that users can both view\n * and interact with. All widgets can be configured and modified via a standard API,\n * and their state can change dynamically according to a model.\n *\n * @abstract\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [disabled=false] Disable the widget. Disabled widgets cannot be used and their\n *  appearance reflects this state.\n */\nOO.ui.Widget = function OoUiWidget( config ) {\n\t// Initialize config\n\tconfig = $.extend( { disabled: false }, config );\n\n\t// Parent constructor\n\tOO.ui.Widget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.disabled = null;\n\tthis.wasDisabled = null;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-widget' );\n\tthis.setDisabled( !!config.disabled );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Widget, OO.ui.Element );\nOO.mixinClass( OO.ui.Widget, OO.EventEmitter );\n\n/* Events */\n\n/**\n * @event disable\n *\n * A 'disable' event is emitted when the disabled state of the widget changes\n * (i.e. on disable **and** enable).\n *\n * @param {boolean} disabled Widget is disabled\n */\n\n/**\n * @event toggle\n *\n * A 'toggle' event is emitted when the visibility of the widget changes.\n *\n * @param {boolean} visible Widget is visible\n */\n\n/* Methods */\n\n/**\n * Check if the widget is disabled.\n *\n * @return {boolean} Widget is disabled\n */\nOO.ui.Widget.prototype.isDisabled = function () {\n\treturn this.disabled;\n};\n\n/**\n * Set the 'disabled' state of the widget.\n *\n * When a widget is disabled, it cannot be used and its appearance is updated to reflect this state.\n *\n * @param {boolean} disabled Disable widget\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.Widget.prototype.setDisabled = function ( disabled ) {\n\tvar isDisabled;\n\n\tthis.disabled = !!disabled;\n\tisDisabled = this.isDisabled();\n\tif ( isDisabled !== this.wasDisabled ) {\n\t\tthis.$element.toggleClass( 'oo-ui-widget-disabled', isDisabled );\n\t\tthis.$element.toggleClass( 'oo-ui-widget-enabled', !isDisabled );\n\t\tthis.$element.attr( 'aria-disabled', isDisabled.toString() );\n\t\tthis.emit( 'disable', isDisabled );\n\t\tthis.updateThemeClasses();\n\t}\n\tthis.wasDisabled = isDisabled;\n\n\treturn this;\n};\n\n/**\n * Update the disabled state, in case of changes in parent widget.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.Widget.prototype.updateDisabled = function () {\n\tthis.setDisabled( this.disabled );\n\treturn this;\n};\n\n/**\n * Get an ID of a labelable node which is part of this widget, if any, to be used for `<label for>`\n * value.\n *\n * If this function returns null, the widget should have a meaningful #simulateLabelClick method\n * instead.\n *\n * @return {string|null} The ID of the labelable element\n */\nOO.ui.Widget.prototype.getInputId = function () {\n\treturn null;\n};\n\n/**\n * Simulate the behavior of clicking on a label (a HTML `<label>` element) bound to this input.\n * HTML only allows `<label>` to act on specific \"labelable\" elements; complex widgets might need to\n * override this method to provide intuitive, accessible behavior.\n *\n * By default, this does nothing. OO.ui.mixin.TabIndexedElement overrides it for focusable widgets.\n * Individual widgets may override it too.\n *\n * This method is called by OO.ui.LabelWidget and OO.ui.FieldLayout. It should not be called\n * directly.\n */\nOO.ui.Widget.prototype.simulateLabelClick = function () {\n};\n","/**\n * Theme logic.\n *\n * @abstract\n * @class\n *\n * @constructor\n */\nOO.ui.Theme = function OoUiTheme() {\n\tthis.elementClassesQueue = [];\n\tthis.debouncedUpdateQueuedElementClasses = OO.ui.debounce( this.updateQueuedElementClasses );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Theme );\n\n/* Methods */\n\n/**\n * Get a list of classes to be applied to a widget.\n *\n * The 'on' and 'off' lists combined MUST contain keys for all classes the theme adds or removes,\n * otherwise state transitions will not work properly.\n *\n * @param {OO.ui.Element} element Element for which to get classes\n * @return {Object.<string,string[]>} Categorized class names with `on` and `off` lists\n */\nOO.ui.Theme.prototype.getElementClasses = function () {\n\treturn { on: [], off: [] };\n};\n\n/**\n * Update CSS classes provided by the theme.\n *\n * For elements with theme logic hooks, this should be called any time there's a state change.\n *\n * @param {OO.ui.Element} element Element for which to update classes\n */\nOO.ui.Theme.prototype.updateElementClasses = function ( element ) {\n\tvar $elements = $( [] ),\n\t\tclasses = this.getElementClasses( element );\n\n\tif ( element.$icon ) {\n\t\t$elements = $elements.add( element.$icon );\n\t}\n\tif ( element.$indicator ) {\n\t\t$elements = $elements.add( element.$indicator );\n\t}\n\n\t$elements\n\t\t.removeClass( classes.off )\n\t\t.addClass( classes.on );\n};\n\n/**\n * @private\n */\nOO.ui.Theme.prototype.updateQueuedElementClasses = function () {\n\tvar i;\n\tfor ( i = 0; i < this.elementClassesQueue.length; i++ ) {\n\t\tthis.updateElementClasses( this.elementClassesQueue[ i ] );\n\t}\n\t// Clear the queue\n\tthis.elementClassesQueue = [];\n};\n\n/**\n * Queue #updateElementClasses to be called for this element.\n *\n * @localdoc QUnit tests override this method to directly call #queueUpdateElementClasses,\n *   to make them synchronous.\n *\n * @param {OO.ui.Element} element Element for which to update classes\n */\nOO.ui.Theme.prototype.queueUpdateElementClasses = function ( element ) {\n\t// Keep items in the queue unique. Use lastIndexOf to start checking from the end because that's\n\t// the most common case (this method is often called repeatedly for the same element).\n\tif ( this.elementClassesQueue.lastIndexOf( element ) !== -1 ) {\n\t\treturn;\n\t}\n\tthis.elementClassesQueue.push( element );\n\tthis.debouncedUpdateQueuedElementClasses();\n};\n\n/**\n * Get the transition duration in milliseconds for dialogs opening/closing\n *\n * The dialog should be fully rendered this many milliseconds after the\n * ready process has executed.\n *\n * @return {number} Transition duration in milliseconds\n */\nOO.ui.Theme.prototype.getDialogTransitionDuration = function () {\n\treturn 0;\n};\n","/**\n * The TabIndexedElement class is an attribute mixin used to add additional functionality to an\n * element created by another class. The mixin provides a ‘tabIndex’ property, which specifies the\n * order in which users will navigate through the focusable elements via the Tab key.\n *\n *     @example\n *     // TabIndexedElement is mixed into the ButtonWidget class\n *     // to provide a tabIndex property.\n *     var button1 = new OO.ui.ButtonWidget( {\n *             label: 'fourth',\n *             tabIndex: 4\n *         } ),\n *         button2 = new OO.ui.ButtonWidget( {\n *             label: 'second',\n *             tabIndex: 2\n *         } ),\n *         button3 = new OO.ui.ButtonWidget( {\n *             label: 'third',\n *             tabIndex: 3\n *         } ),\n *         button4 = new OO.ui.ButtonWidget( {\n *             label: 'first',\n *             tabIndex: 1\n *         } );\n *     $( document.body ).append(\n *         button1.$element,\n *         button2.$element,\n *         button3.$element,\n *         button4.$element\n *      );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$tabIndexed] The element that should use the tabindex functionality. By default,\n *  the functionality is applied to the element created by the class ($element). If a different\n *  element is specified, the tabindex functionality will be applied to it instead.\n * @cfg {string|number|null} [tabIndex=0] Number that specifies the element’s position in the\n *  tab-navigation order (e.g., 1 for the first focusable element). Use 0 to use the default\n *  navigation order; use -1 to remove the element from the tab-navigation flow.\n */\nOO.ui.mixin.TabIndexedElement = function OoUiMixinTabIndexedElement( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { tabIndex: 0 }, config );\n\n\t// Properties\n\tthis.$tabIndexed = null;\n\tthis.tabIndex = null;\n\n\t// Events\n\tthis.connect( this, {\n\t\tdisable: 'onTabIndexedElementDisable'\n\t} );\n\n\t// Initialization\n\tthis.setTabIndex( config.tabIndex );\n\tthis.setTabIndexedElement( config.$tabIndexed || this.$element );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Set the element that should use the tabindex functionality.\n *\n * This method is used to retarget a tabindex mixin so that its functionality applies\n * to the specified element. If an element is currently using the functionality, the mixin’s\n * effect on that element is removed before the new element is set up.\n *\n * @param {jQuery} $tabIndexed Element that should use the tabindex functionality\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.setTabIndexedElement = function ( $tabIndexed ) {\n\tvar tabIndex = this.tabIndex;\n\t// Remove attributes from old $tabIndexed\n\tthis.setTabIndex( null );\n\t// Force update of new $tabIndexed\n\tthis.$tabIndexed = $tabIndexed;\n\tthis.tabIndex = tabIndex;\n\treturn this.updateTabIndex();\n};\n\n/**\n * Set the value of the tabindex.\n *\n * @param {string|number|null} tabIndex Tabindex value, or `null` for no tabindex\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.setTabIndex = function ( tabIndex ) {\n\ttabIndex = /^-?\\d+$/.test( tabIndex ) ? Number( tabIndex ) : null;\n\n\tif ( this.tabIndex !== tabIndex ) {\n\t\tthis.tabIndex = tabIndex;\n\t\tthis.updateTabIndex();\n\t}\n\n\treturn this;\n};\n\n/**\n * Update the `tabindex` attribute, in case of changes to tab index or\n * disabled state.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.updateTabIndex = function () {\n\tif ( this.$tabIndexed ) {\n\t\tif ( this.tabIndex !== null ) {\n\t\t\t// Do not index over disabled elements\n\t\t\tthis.$tabIndexed.attr( {\n\t\t\t\ttabindex: this.isDisabled() ? -1 : this.tabIndex,\n\t\t\t\t// Support: ChromeVox and NVDA\n\t\t\t\t// These do not seem to inherit aria-disabled from parent elements\n\t\t\t\t'aria-disabled': this.isDisabled().toString()\n\t\t\t} );\n\t\t} else {\n\t\t\tthis.$tabIndexed.removeAttr( 'tabindex aria-disabled' );\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Handle disable events.\n *\n * @private\n * @param {boolean} disabled Element is disabled\n */\nOO.ui.mixin.TabIndexedElement.prototype.onTabIndexedElementDisable = function () {\n\tthis.updateTabIndex();\n};\n\n/**\n * Get the value of the tabindex.\n *\n * @return {number|null} Tabindex value\n */\nOO.ui.mixin.TabIndexedElement.prototype.getTabIndex = function () {\n\treturn this.tabIndex;\n};\n\n/**\n * Get an ID of a focusable element of this widget, if any, to be used for `<label for>` value.\n *\n * If the element already has an ID then that is returned, otherwise unique ID is\n * generated, set on the element, and returned.\n *\n * @return {string|null} The ID of the focusable element\n */\nOO.ui.mixin.TabIndexedElement.prototype.getInputId = function () {\n\tvar id;\n\n\tif ( !this.$tabIndexed ) {\n\t\treturn null;\n\t}\n\tif ( !this.isLabelableNode( this.$tabIndexed ) ) {\n\t\treturn null;\n\t}\n\n\tid = this.$tabIndexed.attr( 'id' );\n\tif ( id === undefined ) {\n\t\tid = OO.ui.generateElementId();\n\t\tthis.$tabIndexed.attr( 'id', id );\n\t}\n\n\treturn id;\n};\n\n/**\n * Whether the node is 'labelable' according to the HTML spec\n * (i.e., whether it can be interacted with through a `<label for=\"…\">`).\n * See: <https://html.spec.whatwg.org/multipage/forms.html#category-label>.\n *\n * @private\n * @param {jQuery} $node\n * @return {boolean}\n */\nOO.ui.mixin.TabIndexedElement.prototype.isLabelableNode = function ( $node ) {\n\tvar\n\t\tlabelableTags = [ 'button', 'meter', 'output', 'progress', 'select', 'textarea' ],\n\t\ttagName = ( $node.prop( 'tagName' ) || '' ).toLowerCase();\n\n\tif ( tagName === 'input' && $node.attr( 'type' ) !== 'hidden' ) {\n\t\treturn true;\n\t}\n\tif ( labelableTags.indexOf( tagName ) !== -1 ) {\n\t\treturn true;\n\t}\n\treturn false;\n};\n\n/**\n * Focus this element.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$tabIndexed.trigger( 'focus' );\n\t}\n\treturn this;\n};\n\n/**\n * Blur this element.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TabIndexedElement.prototype.blur = function () {\n\tthis.$tabIndexed.trigger( 'blur' );\n\treturn this;\n};\n\n/**\n * @inheritdoc OO.ui.Widget\n */\nOO.ui.mixin.TabIndexedElement.prototype.simulateLabelClick = function () {\n\tthis.focus();\n};\n","/**\n * ButtonElement is often mixed into other classes to generate a button, which is a clickable\n * interface element that can be configured with access keys for keyboard interaction.\n * See the [OOUI documentation on MediaWiki] [1] for examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches#Buttons\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$button] The button element created by the class.\n *  If this configuration is omitted, the button element will use a generated `<a>`.\n * @cfg {boolean} [framed=true] Render the button with a frame\n */\nOO.ui.mixin.ButtonElement = function OoUiMixinButtonElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$button = null;\n\tthis.framed = null;\n\tthis.active = config.active !== undefined && config.active;\n\tthis.onDocumentMouseUpHandler = this.onDocumentMouseUp.bind( this );\n\tthis.onMouseDownHandler = this.onMouseDown.bind( this );\n\tthis.onDocumentKeyUpHandler = this.onDocumentKeyUp.bind( this );\n\tthis.onKeyDownHandler = this.onKeyDown.bind( this );\n\tthis.onClickHandler = this.onClick.bind( this );\n\tthis.onKeyPressHandler = this.onKeyPress.bind( this );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonElement' );\n\tthis.toggleFramed( config.framed === undefined || config.framed );\n\tthis.setButtonElement( config.$button || $( '<a>' ) );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.ButtonElement );\n\n/* Static Properties */\n\n/**\n * Cancel mouse down events.\n *\n * This property is usually set to `true` to prevent the focus from changing when the button is\n * clicked.\n * Classes such as {@link OO.ui.mixin.DraggableElement DraggableElement} and\n * {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} use a value of `false` so that dragging\n * behavior is possible and mousedown events can be handled by a parent widget.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.mixin.ButtonElement.static.cancelButtonMouseDownEvents = true;\n\n/* Events */\n\n/**\n * A 'click' event is emitted when the button element is clicked.\n *\n * @event click\n */\n\n/* Methods */\n\n/**\n * Set the button element.\n *\n * This method is used to retarget a button mixin so that its functionality applies to\n * the specified button element instead of the one created by the class. If a button element\n * is already set, the method will remove the mixin’s effect on that element.\n *\n * @param {jQuery} $button Element to use as button\n */\nOO.ui.mixin.ButtonElement.prototype.setButtonElement = function ( $button ) {\n\tif ( this.$button ) {\n\t\tthis.$button\n\t\t\t.removeClass( 'oo-ui-buttonElement-button' )\n\t\t\t.removeAttr( 'role accesskey' )\n\t\t\t.off( {\n\t\t\t\tmousedown: this.onMouseDownHandler,\n\t\t\t\tkeydown: this.onKeyDownHandler,\n\t\t\t\tclick: this.onClickHandler,\n\t\t\t\tkeypress: this.onKeyPressHandler\n\t\t\t} );\n\t}\n\n\tthis.$button = $button\n\t\t.addClass( 'oo-ui-buttonElement-button' )\n\t\t.on( {\n\t\t\tmousedown: this.onMouseDownHandler,\n\t\t\tkeydown: this.onKeyDownHandler,\n\t\t\tclick: this.onClickHandler,\n\t\t\tkeypress: this.onKeyPressHandler\n\t\t} );\n\n\t// Add `role=\"button\"` on `<a>` elements, where it's needed\n\t// `toUpperCase()` is added for XHTML documents\n\tif ( this.$button.prop( 'tagName' ).toUpperCase() === 'A' ) {\n\t\tthis.$button.attr( 'role', 'button' );\n\t}\n};\n\n/**\n * Handles mouse down events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.mixin.ButtonElement.prototype.onMouseDown = function ( e ) {\n\tif ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {\n\t\treturn;\n\t}\n\tthis.$element.addClass( 'oo-ui-buttonElement-pressed' );\n\t// Run the mouseup handler no matter where the mouse is when the button is let go, so we can\n\t// reliably remove the pressed class\n\tthis.getElementDocument().addEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n\t// Prevent change of focus unless specifically configured otherwise\n\tif ( this.constructor.static.cancelButtonMouseDownEvents ) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Handles document mouse up events.\n *\n * @protected\n * @param {MouseEvent} e Mouse up event\n */\nOO.ui.mixin.ButtonElement.prototype.onDocumentMouseUp = function ( e ) {\n\tif ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {\n\t\treturn;\n\t}\n\tthis.$element.removeClass( 'oo-ui-buttonElement-pressed' );\n\t// Stop listening for mouseup, since we only needed this once\n\tthis.getElementDocument().removeEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n};\n\n/**\n * Handles mouse click events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse click event\n * @fires click\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.mixin.ButtonElement.prototype.onClick = function ( e ) {\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tif ( this.emit( 'click' ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Handles key down events.\n *\n * @protected\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.mixin.ButtonElement.prototype.onKeyDown = function ( e ) {\n\tif ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {\n\t\treturn;\n\t}\n\tthis.$element.addClass( 'oo-ui-buttonElement-pressed' );\n\t// Run the keyup handler no matter where the key is when the button is let go, so we can\n\t// reliably remove the pressed class\n\tthis.getElementDocument().addEventListener( 'keyup', this.onDocumentKeyUpHandler, true );\n};\n\n/**\n * Handles document key up events.\n *\n * @protected\n * @param {KeyboardEvent} e Key up event\n */\nOO.ui.mixin.ButtonElement.prototype.onDocumentKeyUp = function ( e ) {\n\tif ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {\n\t\treturn;\n\t}\n\tthis.$element.removeClass( 'oo-ui-buttonElement-pressed' );\n\t// Stop listening for keyup, since we only needed this once\n\tthis.getElementDocument().removeEventListener( 'keyup', this.onDocumentKeyUpHandler, true );\n};\n\n/**\n * Handles key press events.\n *\n * @protected\n * @param {jQuery.Event} e Key press event\n * @fires click\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.mixin.ButtonElement.prototype.onKeyPress = function ( e ) {\n\tif ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {\n\t\tif ( this.emit( 'click' ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Check if button has a frame.\n *\n * @return {boolean} Button is framed\n */\nOO.ui.mixin.ButtonElement.prototype.isFramed = function () {\n\treturn this.framed;\n};\n\n/**\n * Render the button with or without a frame. Omit the `framed` parameter to toggle the button frame\n * on and off.\n *\n * @param {boolean} [framed] Make button framed, omit to toggle\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ButtonElement.prototype.toggleFramed = function ( framed ) {\n\tframed = framed === undefined ? !this.framed : !!framed;\n\tif ( framed !== this.framed ) {\n\t\tthis.framed = framed;\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-buttonElement-frameless', !framed )\n\t\t\t.toggleClass( 'oo-ui-buttonElement-framed', framed );\n\t\tthis.updateThemeClasses();\n\t}\n\n\treturn this;\n};\n\n/**\n * Set the button's active state.\n *\n * The active state can be set on:\n *\n *  - {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} when it is selected\n *  - {@link OO.ui.ToggleButtonWidget ToggleButtonWidget} when it is toggle on\n *  - {@link OO.ui.ButtonWidget ButtonWidget} when clicking the button would only refresh the page\n *\n * @protected\n * @param {boolean} value Make button active\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ButtonElement.prototype.setActive = function ( value ) {\n\tthis.active = !!value;\n\tthis.$element.toggleClass( 'oo-ui-buttonElement-active', this.active );\n\tthis.updateThemeClasses();\n\treturn this;\n};\n\n/**\n * Check if the button is active\n *\n * @protected\n * @return {boolean} The button is active\n */\nOO.ui.mixin.ButtonElement.prototype.isActive = function () {\n\treturn this.active;\n};\n","/**\n * Any OOUI widget that contains other widgets (such as {@link OO.ui.ButtonWidget buttons} or\n * {@link OO.ui.OptionWidget options}) mixes in GroupElement. Adding, removing, and clearing\n * items from the group is done through the interface the class provides.\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Elements/Groups\n *\n * @abstract\n * @mixins OO.EmitterList\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$group] The container element created by the class. If this configuration\n *  is omitted, the group element will use a generated `<div>`.\n */\nOO.ui.mixin.GroupElement = function OoUiMixinGroupElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Mixin constructors\n\tOO.EmitterList.call( this, config );\n\n\t// Properties\n\tthis.$group = null;\n\n\t// Initialization\n\tthis.setGroupElement( config.$group || $( '<div>' ) );\n};\n\n/* Setup */\n\nOO.mixinClass( OO.ui.mixin.GroupElement, OO.EmitterList );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the set of selected items changes.\n *\n * @param {OO.ui.Element[]} items Items currently in the group\n */\n\n/* Methods */\n\n/**\n * Set the group element.\n *\n * If an element is already set, items will be moved to the new element.\n *\n * @param {jQuery} $group Element to use as group\n */\nOO.ui.mixin.GroupElement.prototype.setGroupElement = function ( $group ) {\n\tvar i, len;\n\n\tthis.$group = $group;\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tthis.$group.append( this.items[ i ].$element );\n\t}\n};\n\n/**\n * Find an item by its data.\n *\n * Only the first item with matching data will be returned. To return all matching items,\n * use the #findItemsFromData method.\n *\n * @param {Object} data Item data to search for\n * @return {OO.ui.Element|null} Item with equivalent data, `null` if none exists\n */\nOO.ui.mixin.GroupElement.prototype.findItemFromData = function ( data ) {\n\tvar i, len, item,\n\t\thash = OO.getHash( data );\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\titem = this.items[ i ];\n\t\tif ( hash === OO.getHash( item.getData() ) ) {\n\t\t\treturn item;\n\t\t}\n\t}\n\n\treturn null;\n};\n\n/**\n * Find items by their data.\n *\n * All items with matching data will be returned. To return only the first match, use the\n * #findItemFromData method instead.\n *\n * @param {Object} data Item data to search for\n * @return {OO.ui.Element[]} Items with equivalent data\n */\nOO.ui.mixin.GroupElement.prototype.findItemsFromData = function ( data ) {\n\tvar i, len, item,\n\t\thash = OO.getHash( data ),\n\t\titems = [];\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\titem = this.items[ i ];\n\t\tif ( hash === OO.getHash( item.getData() ) ) {\n\t\t\titems.push( item );\n\t\t}\n\t}\n\n\treturn items;\n};\n\n/**\n * Add items to the group.\n *\n * Items will be added to the end of the group array unless the optional `index` parameter\n * specifies a different insertion point. Adding an existing item will move it to the end of the\n * array or the point specified by the `index`.\n *\n * @param {OO.ui.Element[]} items An array of items to add to the group\n * @param {number} [index] Index of the insertion point\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {\n\n\tif ( items.length === 0 ) {\n\t\treturn this;\n\t}\n\n\t// Mixin method\n\tOO.EmitterList.prototype.addItems.call( this, items, index );\n\n\tthis.emit( 'change', this.getItems() );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.mixin.GroupElement.prototype.moveItem = function ( items, newIndex ) {\n\t// insertItemElements expects this.items to not have been modified yet, so call before the mixin\n\tthis.insertItemElements( items, newIndex );\n\n\t// Mixin method\n\tnewIndex = OO.EmitterList.prototype.moveItem.call( this, items, newIndex );\n\n\treturn newIndex;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.mixin.GroupElement.prototype.insertItem = function ( item, index ) {\n\titem.setElementGroup( this );\n\tthis.insertItemElements( item, index );\n\n\t// Mixin method\n\tindex = OO.EmitterList.prototype.insertItem.call( this, item, index );\n\n\treturn index;\n};\n\n/**\n * Insert elements into the group\n *\n * @private\n * @param {OO.ui.Element} itemWidget Item to insert\n * @param {number} index Insertion index\n */\nOO.ui.mixin.GroupElement.prototype.insertItemElements = function ( itemWidget, index ) {\n\tif ( index === undefined || index < 0 || index >= this.items.length ) {\n\t\tthis.$group.append( itemWidget.$element );\n\t} else if ( index === 0 ) {\n\t\tthis.$group.prepend( itemWidget.$element );\n\t} else {\n\t\tthis.items[ index ].$element.before( itemWidget.$element );\n\t}\n};\n\n/**\n * Remove the specified items from a group.\n *\n * Removed items are detached (not removed) from the DOM so that they may be reused.\n * To remove all items from a group, you may wish to use the #clearItems method instead.\n *\n * @param {OO.ui.Element[]} items An array of items to remove\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {\n\tvar i, len, item, index;\n\n\tif ( items.length === 0 ) {\n\t\treturn this;\n\t}\n\n\t// Remove specific items elements\n\tfor ( i = 0, len = items.length; i < len; i++ ) {\n\t\titem = items[ i ];\n\t\tindex = this.items.indexOf( item );\n\t\tif ( index !== -1 ) {\n\t\t\titem.setElementGroup( null );\n\t\t\titem.$element.detach();\n\t\t}\n\t}\n\n\t// Mixin method\n\tOO.EmitterList.prototype.removeItems.call( this, items );\n\n\tthis.emit( 'change', this.getItems() );\n\treturn this;\n};\n\n/**\n * Clear all items from the group.\n *\n * Cleared items are detached from the DOM, not removed, so that they may be reused.\n * To remove only a subset of items from a group, use the #removeItems method.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.GroupElement.prototype.clearItems = function () {\n\tvar i, len;\n\n\t// Remove all item elements\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tthis.items[ i ].setElementGroup( null );\n\t\tthis.items[ i ].$element.detach();\n\t}\n\n\t// Mixin method\n\tOO.EmitterList.prototype.clearItems.call( this );\n\n\tthis.emit( 'change', this.getItems() );\n\treturn this;\n};\n","/**\n * LabelElement is often mixed into other classes to generate a label, which\n * helps identify the function of an interface element.\n * See the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Labels\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$label] The label element created by the class. If this\n *  configuration is omitted, the label element will use a generated `<span>`.\n * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be\n *  specified as a plaintext string, a jQuery selection of elements, or a function that will\n *  produce a string in the future. See the [OOUI documentation on MediaWiki] [2] for examples.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Labels\n * @cfg {boolean} [invisibleLabel] Whether the label should be visually hidden (but still\n *  accessible to screen-readers).\n */\nOO.ui.mixin.LabelElement = function OoUiMixinLabelElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$label = null;\n\tthis.label = null;\n\tthis.invisibleLabel = null;\n\n\t// Initialization\n\tthis.setLabel( config.label || this.constructor.static.label );\n\tthis.setLabelElement( config.$label || $( '<span>' ) );\n\tthis.setInvisibleLabel( config.invisibleLabel );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.LabelElement );\n\n/* Events */\n\n/**\n * @event labelChange\n * @param {string} value\n */\n\n/* Static Properties */\n\n/**\n * The label text. The label can be specified as a plaintext string, a function that will\n * produce a string in the future, or `null` for no label. The static value will\n * be overridden if a label is specified with the #label config option.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.LabelElement.static.label = null;\n\n/* Static methods */\n\n/**\n * Highlight the first occurrence of the query in the given text\n *\n * @param {string} text Text\n * @param {string} query Query to find\n * @param {Function} [compare] Optional string comparator, e.g. Intl.Collator().compare\n * @return {jQuery} Text with the first match of the query\n *  sub-string wrapped in highlighted span\n */\nOO.ui.mixin.LabelElement.static.highlightQuery = function ( text, query, compare ) {\n\tvar i, tLen, qLen,\n\t\toffset = -1,\n\t\t$result = $( '<span>' );\n\n\tif ( compare ) {\n\t\ttLen = text.length;\n\t\tqLen = query.length;\n\t\tfor ( i = 0; offset === -1 && i <= tLen - qLen; i++ ) {\n\t\t\tif ( compare( query, text.slice( i, i + qLen ) ) === 0 ) {\n\t\t\t\toffset = i;\n\t\t\t}\n\t\t}\n\t} else {\n\t\toffset = text.toLowerCase().indexOf( query.toLowerCase() );\n\t}\n\n\tif ( !query.length || offset === -1 ) {\n\t\t$result.text( text );\n\t} else {\n\t\t$result.append(\n\t\t\tdocument.createTextNode( text.slice( 0, offset ) ),\n\t\t\t$( '<span>' )\n\t\t\t\t.addClass( 'oo-ui-labelElement-label-highlight' )\n\t\t\t\t.text( text.slice( offset, offset + query.length ) ),\n\t\t\tdocument.createTextNode( text.slice( offset + query.length ) )\n\t\t);\n\t}\n\treturn $result.contents();\n};\n\n/* Methods */\n\n/**\n * Set the label element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $label Element to use as label\n */\nOO.ui.mixin.LabelElement.prototype.setLabelElement = function ( $label ) {\n\tif ( this.$label ) {\n\t\tthis.$label.removeClass( 'oo-ui-labelElement-label' ).empty();\n\t}\n\n\tthis.$label = $label.addClass( 'oo-ui-labelElement-label' );\n\tthis.setLabelContent( this.label );\n};\n\n/**\n * Set the label.\n *\n * An empty string will result in the label being hidden. A string containing only whitespace will\n * be converted to a single `&nbsp;`.\n *\n * @param {jQuery|string|OO.ui.HtmlSnippet|Function|null} label Label nodes; text; a function that\n *  returns nodes or text; or null for no label\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LabelElement.prototype.setLabel = function ( label ) {\n\tlabel = typeof label === 'function' ? OO.ui.resolveMsg( label ) : label;\n\tlabel = ( ( typeof label === 'string' || label instanceof $ ) && label.length ) || ( label instanceof OO.ui.HtmlSnippet && label.toString().length ) ? label : null;\n\n\tif ( this.label !== label ) {\n\t\tif ( this.$label ) {\n\t\t\tthis.setLabelContent( label );\n\t\t}\n\t\tthis.label = label;\n\t\tthis.emit( 'labelChange' );\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-labelElement', !!this.label && !this.invisibleLabel );\n\n\treturn this;\n};\n\n/**\n * Set whether the label should be visually hidden (but still accessible to screen-readers).\n *\n * @param {boolean} invisibleLabel\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LabelElement.prototype.setInvisibleLabel = function ( invisibleLabel ) {\n\tinvisibleLabel = !!invisibleLabel;\n\n\tif ( this.invisibleLabel !== invisibleLabel ) {\n\t\tthis.invisibleLabel = invisibleLabel;\n\t\tthis.emit( 'labelChange' );\n\t}\n\n\tthis.$label.toggleClass( 'oo-ui-labelElement-invisible', this.invisibleLabel );\n\t// Pretend that there is no label, a lot of CSS has been written with this assumption\n\tthis.$element.toggleClass( 'oo-ui-labelElement', !!this.label && !this.invisibleLabel );\n\n\treturn this;\n};\n\n/**\n * Set the label as plain text with a highlighted query\n *\n * @param {string} text Text label to set\n * @param {string} query Substring of text to highlight\n * @param {Function} [compare] Optional string comparator, e.g. Intl.Collator().compare\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LabelElement.prototype.setHighlightedQuery = function ( text, query, compare ) {\n\treturn this.setLabel( this.constructor.static.highlightQuery( text, query, compare ) );\n};\n\n/**\n * Get the label.\n *\n * @return {jQuery|string|Function|null} Label nodes; text; a function that returns nodes or\n *  text; or null for no label\n */\nOO.ui.mixin.LabelElement.prototype.getLabel = function () {\n\treturn this.label;\n};\n\n/**\n * Set the content of the label.\n *\n * Do not call this method until after the label element has been set by #setLabelElement.\n *\n * @private\n * @param {jQuery|string|Function|null} label Label nodes; text; a function that returns nodes or\n *  text; or null for no label\n */\nOO.ui.mixin.LabelElement.prototype.setLabelContent = function ( label ) {\n\tif ( typeof label === 'string' ) {\n\t\tif ( label.match( /^\\s*$/ ) ) {\n\t\t\t// Convert whitespace only string to a single non-breaking space\n\t\t\tthis.$label.html( '&nbsp;' );\n\t\t} else {\n\t\t\tthis.$label.text( label );\n\t\t}\n\t} else if ( label instanceof OO.ui.HtmlSnippet ) {\n\t\tthis.$label.html( label.toString() );\n\t} else if ( label instanceof $ ) {\n\t\tthis.$label.empty().append( label );\n\t} else {\n\t\tthis.$label.empty();\n\t}\n};\n","/**\n * IconElement is often mixed into other classes to generate an icon.\n * Icons are graphics, about the size of normal text. They are used to aid the user\n * in locating a control or to convey information in a space-efficient way. See the\n * [OOUI documentation on MediaWiki] [1] for a list of icons\n * included in the library.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Icons\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$icon] The icon element created by the class. If this configuration is omitted,\n *  the icon element will use a generated `<span>`. To use a different HTML tag, or to specify that\n *  the icon element be set to an existing icon instead of the one generated by this class, set a\n *  value using a jQuery selection. For example:\n *\n *      // Use a <div> tag instead of a <span>\n *     $icon: $( '<div>' )\n *     // Use an existing icon element instead of the one generated by the class\n *     $icon: this.$element\n *     // Use an icon element from a child widget\n *     $icon: this.childwidget.$element\n * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a\n *  map of symbolic names. A map is used for i18n purposes and contains a `default` icon\n *  name and additional names keyed by language code. The `default` name is used when no icon is\n *  keyed by the user's language.\n *\n *  Example of an i18n map:\n *\n *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }\n *  See the [OOUI documentation on MediaWiki] [2] for a list of icons included in the library.\n * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Icons\n */\nOO.ui.mixin.IconElement = function OoUiMixinIconElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$icon = null;\n\tthis.icon = null;\n\n\t// Initialization\n\tthis.setIcon( config.icon || this.constructor.static.icon );\n\tthis.setIconElement( config.$icon || $( '<span>' ) );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.IconElement );\n\n/* Static Properties */\n\n/**\n * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map\n * is used for i18n purposes and contains a `default` icon name and additional names keyed by\n * language code. The `default` name is used when no icon is keyed by the user's language.\n *\n * Example of an i18n map:\n *\n *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }\n *\n * Note: the static property will be overridden if the #icon configuration is used.\n *\n * @static\n * @inheritable\n * @property {Object|string}\n */\nOO.ui.mixin.IconElement.static.icon = null;\n\n/**\n * The icon title, displayed when users move the mouse over the icon. The value can be text, a\n * function that returns title text, or `null` for no title.\n *\n * The static property will be overridden if the #iconTitle configuration is used.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.IconElement.static.iconTitle = null;\n\n/* Methods */\n\n/**\n * Set the icon element. This method is used to retarget an icon mixin so that its functionality\n * applies to the specified icon element instead of the one created by the class. If an icon\n * element is already set, the mixin’s effect on that element is removed. Generated CSS classes\n * and mixin methods will no longer affect the element.\n *\n * @param {jQuery} $icon Element to use as icon\n */\nOO.ui.mixin.IconElement.prototype.setIconElement = function ( $icon ) {\n\tif ( this.$icon ) {\n\t\tthis.$icon\n\t\t\t.removeClass( 'oo-ui-iconElement-icon oo-ui-icon-' + this.icon )\n\t\t\t.removeAttr( 'title' );\n\t}\n\n\tthis.$icon = $icon\n\t\t.addClass( 'oo-ui-iconElement-icon' )\n\t\t.toggleClass( 'oo-ui-iconElement-noIcon', !this.icon )\n\t\t.toggleClass( 'oo-ui-icon-' + this.icon, !!this.icon );\n\tif ( this.iconTitle !== null ) {\n\t\tthis.$icon.attr( 'title', this.iconTitle );\n\t}\n\n\tthis.updateThemeClasses();\n};\n\n/**\n * Set icon by symbolic name (e.g., ‘remove’ or ‘menu’). Use `null` to remove an icon.\n * The icon parameter can also be set to a map of icon names. See the #icon config setting\n * for an example.\n *\n * @param {Object|string|null} icon A symbolic icon name, a {@link #icon map of icon names} keyed\n *  by language code, or `null` to remove the icon.\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.IconElement.prototype.setIcon = function ( icon ) {\n\ticon = OO.isPlainObject( icon ) ? OO.ui.getLocalValue( icon, null, 'default' ) : icon;\n\ticon = typeof icon === 'string' && icon.trim().length ? icon.trim() : null;\n\n\tif ( this.icon !== icon ) {\n\t\tif ( this.$icon ) {\n\t\t\tif ( this.icon !== null ) {\n\t\t\t\tthis.$icon.removeClass( 'oo-ui-icon-' + this.icon );\n\t\t\t}\n\t\t\tif ( icon !== null ) {\n\t\t\t\tthis.$icon.addClass( 'oo-ui-icon-' + icon );\n\t\t\t}\n\t\t}\n\t\tthis.icon = icon;\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-iconElement', !!this.icon );\n\tif ( this.$icon ) {\n\t\tthis.$icon.toggleClass( 'oo-ui-iconElement-noIcon', !this.icon );\n\t}\n\tthis.updateThemeClasses();\n\n\treturn this;\n};\n\n/**\n * Get the symbolic name of the icon.\n *\n * @return {string} Icon name\n */\nOO.ui.mixin.IconElement.prototype.getIcon = function () {\n\treturn this.icon;\n};\n\n/**\n * Get the icon title. The title text is displayed when a user moves the mouse over the icon.\n *\n * @return {string} Icon title text\n * @deprecated\n */\nOO.ui.mixin.IconElement.prototype.getIconTitle = function () {\n\treturn this.iconTitle;\n};\n","/**\n * IndicatorElement is often mixed into other classes to generate an indicator.\n * Indicators are small graphics that are generally used in two ways:\n *\n * - To draw attention to the status of an item. For example, an indicator might be\n *   used to show that an item in a list has errors that need to be resolved.\n * - To clarify the function of a control that acts in an exceptional way (a button\n *   that opens a menu instead of performing an action directly, for example).\n *\n * For a list of indicators included in the library, please see the\n * [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$indicator] The indicator element created by the class. If this\n *  configuration is omitted, the indicator element will use a generated `<span>`.\n * @cfg {string} [indicator] Symbolic name of the indicator (e.g., ‘clear’ or ‘down’).\n *  See the [OOUI documentation on MediaWiki][2] for a list of indicators included\n *  in the library.\n * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators\n */\nOO.ui.mixin.IndicatorElement = function OoUiMixinIndicatorElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$indicator = null;\n\tthis.indicator = null;\n\n\t// Initialization\n\tthis.setIndicator( config.indicator || this.constructor.static.indicator );\n\tthis.setIndicatorElement( config.$indicator || $( '<span>' ) );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.IndicatorElement );\n\n/* Static Properties */\n\n/**\n * Symbolic name of the indicator (e.g., ‘clear’ or  ‘down’).\n * The static property will be overridden if the #indicator configuration is used.\n *\n * @static\n * @inheritable\n * @property {string|null}\n */\nOO.ui.mixin.IndicatorElement.static.indicator = null;\n\n/**\n * A text string used as the indicator title, a function that returns title text, or `null`\n * for no title. The static property will be overridden if the #indicatorTitle configuration is\n * used.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.IndicatorElement.static.indicatorTitle = null;\n\n/* Methods */\n\n/**\n * Set the indicator element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $indicator Element to use as indicator\n */\nOO.ui.mixin.IndicatorElement.prototype.setIndicatorElement = function ( $indicator ) {\n\tif ( this.$indicator ) {\n\t\tthis.$indicator\n\t\t\t.removeClass( 'oo-ui-indicatorElement-indicator oo-ui-indicator-' + this.indicator )\n\t\t\t.removeAttr( 'title' );\n\t}\n\n\tthis.$indicator = $indicator\n\t\t.addClass( 'oo-ui-indicatorElement-indicator' )\n\t\t.toggleClass( 'oo-ui-indicatorElement-noIndicator', !this.indicator )\n\t\t.toggleClass( 'oo-ui-indicator-' + this.indicator, !!this.indicator );\n\tif ( this.indicatorTitle !== null ) {\n\t\tthis.$indicator.attr( 'title', this.indicatorTitle );\n\t}\n\n\tthis.updateThemeClasses();\n};\n\n/**\n * Set the indicator by its symbolic name: ‘clear’, ‘down’, ‘required’, ‘search’, ‘up’. Use `null`\n * to remove the indicator.\n *\n * @param {string|null} indicator Symbolic name of indicator, or `null` for no indicator\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.IndicatorElement.prototype.setIndicator = function ( indicator ) {\n\tindicator = typeof indicator === 'string' && indicator.length ? indicator.trim() : null;\n\n\tif ( this.indicator !== indicator ) {\n\t\tif ( this.$indicator ) {\n\t\t\tif ( this.indicator !== null ) {\n\t\t\t\tthis.$indicator.removeClass( 'oo-ui-indicator-' + this.indicator );\n\t\t\t}\n\t\t\tif ( indicator !== null ) {\n\t\t\t\tthis.$indicator.addClass( 'oo-ui-indicator-' + indicator );\n\t\t\t}\n\t\t}\n\t\tthis.indicator = indicator;\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-indicatorElement', !!this.indicator );\n\tif ( this.$indicator ) {\n\t\tthis.$indicator.toggleClass( 'oo-ui-indicatorElement-noIndicator', !this.indicator );\n\t}\n\tthis.updateThemeClasses();\n\n\treturn this;\n};\n\n/**\n * Get the symbolic name of the indicator (e.g., ‘clear’ or  ‘down’).\n *\n * @return {string} Symbolic name of indicator\n */\nOO.ui.mixin.IndicatorElement.prototype.getIndicator = function () {\n\treturn this.indicator;\n};\n\n/**\n * Get the indicator title.\n *\n * The title is displayed when a user moves the mouse over the indicator.\n *\n * @return {string} Indicator title text\n * @deprecated\n */\nOO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {\n\treturn this.indicatorTitle;\n};\n","/**\n * The FlaggedElement class is an attribute mixin, meaning that it is used to add\n * additional functionality to an element created by another class. The class provides\n * a ‘flags’ property assigned the name (or an array of names) of styling flags,\n * which are used to customize the look and feel of a widget to better describe its\n * importance and functionality.\n *\n * The library currently contains the following styling flags for general use:\n *\n * - **progressive**: Progressive styling is applied to convey that the widget will move the user\n *   forward in a process.\n * - **destructive**: Destructive styling is applied to convey that the widget will remove\n *   something.\n *\n * The flags affect the appearance of the buttons:\n *\n *     @example\n *     // FlaggedElement is mixed into ButtonWidget to provide styling flags\n *     var button1 = new OO.ui.ButtonWidget( {\n *             label: 'Progressive',\n *             flags: 'progressive'\n *         } ),\n *         button2 = new OO.ui.ButtonWidget( {\n *             label: 'Destructive',\n *             flags: 'destructive'\n *         } );\n *     $( document.body ).append( button1.$element, button2.$element );\n *\n * {@link OO.ui.ActionWidget ActionWidgets}, which are a special kind of button that execute an\n * action, use these flags: **primary** and **safe**.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string|string[]} [flags] The name or names of the flags (e.g., 'progressive' or 'primary')\n *  to apply.\n *  Please see the [OOUI documentation on MediaWiki] [2] for more information about available flags.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged\n * @cfg {jQuery} [$flagged] The flagged element. By default,\n *  the flagged functionality is applied to the element created by the class ($element).\n *  If a different element is specified, the flagged functionality will be applied to it instead.\n */\nOO.ui.mixin.FlaggedElement = function OoUiMixinFlaggedElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.flags = {};\n\tthis.$flagged = null;\n\n\t// Initialization\n\tthis.setFlags( config.flags );\n\tthis.setFlaggedElement( config.$flagged || this.$element );\n};\n\n/* Events */\n\n/**\n * @event flag\n * A flag event is emitted when the #clearFlags or #setFlags methods are used. The `changes`\n * parameter contains the name of each modified flag and indicates whether it was\n * added or removed.\n *\n * @param {Object.<string,boolean>} changes Object keyed by flag name. A Boolean `true` indicates\n * that the flag was added, `false` that the flag was removed.\n */\n\n/* Methods */\n\n/**\n * Set the flagged element.\n *\n * This method is used to retarget a flagged mixin so that its functionality applies to the\n * specified element.\n * If an element is already set, the method will remove the mixin’s effect on that element.\n *\n * @param {jQuery} $flagged Element that should be flagged\n */\nOO.ui.mixin.FlaggedElement.prototype.setFlaggedElement = function ( $flagged ) {\n\tvar classNames = Object.keys( this.flags ).map( function ( flag ) {\n\t\treturn 'oo-ui-flaggedElement-' + flag;\n\t} );\n\n\tif ( this.$flagged ) {\n\t\tthis.$flagged.removeClass( classNames );\n\t}\n\n\tthis.$flagged = $flagged.addClass( classNames );\n};\n\n/**\n * Check if the specified flag is set.\n *\n * @param {string} flag Name of flag\n * @return {boolean} The flag is set\n */\nOO.ui.mixin.FlaggedElement.prototype.hasFlag = function ( flag ) {\n\t// This may be called before the constructor, thus before this.flags is set\n\treturn this.flags && ( flag in this.flags );\n};\n\n/**\n * Get the names of all flags set.\n *\n * @return {string[]} Flag names\n */\nOO.ui.mixin.FlaggedElement.prototype.getFlags = function () {\n\t// This may be called before the constructor, thus before this.flags is set\n\treturn Object.keys( this.flags || {} );\n};\n\n/**\n * Clear all flags.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n * @fires flag\n */\nOO.ui.mixin.FlaggedElement.prototype.clearFlags = function () {\n\tvar flag, className,\n\t\tchanges = {},\n\t\tremove = [],\n\t\tclassPrefix = 'oo-ui-flaggedElement-';\n\n\tfor ( flag in this.flags ) {\n\t\tclassName = classPrefix + flag;\n\t\tchanges[ flag ] = false;\n\t\tdelete this.flags[ flag ];\n\t\tremove.push( className );\n\t}\n\n\tif ( this.$flagged ) {\n\t\tthis.$flagged.removeClass( remove );\n\t}\n\n\tthis.updateThemeClasses();\n\tthis.emit( 'flag', changes );\n\n\treturn this;\n};\n\n/**\n * Add one or more flags.\n *\n * @param {string|string[]|Object.<string, boolean>} flags A flag name, an array of flag names,\n *  or an object keyed by flag name with a boolean value that indicates whether the flag should\n *  be added (`true`) or removed (`false`).\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n * @fires flag\n */\nOO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) {\n\tvar i, len, flag, className,\n\t\tchanges = {},\n\t\tadd = [],\n\t\tremove = [],\n\t\tclassPrefix = 'oo-ui-flaggedElement-';\n\n\tif ( typeof flags === 'string' ) {\n\t\tclassName = classPrefix + flags;\n\t\t// Set\n\t\tif ( !this.flags[ flags ] ) {\n\t\t\tthis.flags[ flags ] = true;\n\t\t\tadd.push( className );\n\t\t}\n\t} else if ( Array.isArray( flags ) ) {\n\t\tfor ( i = 0, len = flags.length; i < len; i++ ) {\n\t\t\tflag = flags[ i ];\n\t\t\tclassName = classPrefix + flag;\n\t\t\t// Set\n\t\t\tif ( !this.flags[ flag ] ) {\n\t\t\t\tchanges[ flag ] = true;\n\t\t\t\tthis.flags[ flag ] = true;\n\t\t\t\tadd.push( className );\n\t\t\t}\n\t\t}\n\t} else if ( OO.isPlainObject( flags ) ) {\n\t\tfor ( flag in flags ) {\n\t\t\tclassName = classPrefix + flag;\n\t\t\tif ( flags[ flag ] ) {\n\t\t\t\t// Set\n\t\t\t\tif ( !this.flags[ flag ] ) {\n\t\t\t\t\tchanges[ flag ] = true;\n\t\t\t\t\tthis.flags[ flag ] = true;\n\t\t\t\t\tadd.push( className );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Remove\n\t\t\t\tif ( this.flags[ flag ] ) {\n\t\t\t\t\tchanges[ flag ] = false;\n\t\t\t\t\tdelete this.flags[ flag ];\n\t\t\t\t\tremove.push( className );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( this.$flagged ) {\n\t\tthis.$flagged\n\t\t\t.addClass( add )\n\t\t\t.removeClass( remove );\n\t}\n\n\tthis.updateThemeClasses();\n\tthis.emit( 'flag', changes );\n\n\treturn this;\n};\n","/**\n * TitledElement is mixed into other classes to provide a `title` attribute.\n * Titles are rendered by the browser and are made visible when the user moves\n * the mouse over the element. Titles are not visible on touch devices.\n *\n *     @example\n *     // TitledElement provides a `title` attribute to the\n *     // ButtonWidget class.\n *     var button = new OO.ui.ButtonWidget( {\n *         label: 'Button with Title',\n *         title: 'I am a button'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$titled] The element to which the `title` attribute is applied.\n *  If this config is omitted, the title functionality is applied to $element, the\n *  element created by the class.\n * @cfg {string|Function} [title] The title text or a function that returns text. If\n *  this config is omitted, the value of the {@link #static-title static title} property is used.\n */\nOO.ui.mixin.TitledElement = function OoUiMixinTitledElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$titled = null;\n\tthis.title = null;\n\n\t// Initialization\n\tthis.setTitle( config.title !== undefined ? config.title : this.constructor.static.title );\n\tthis.setTitledElement( config.$titled || this.$element );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * The title text, a function that returns text, or `null` for no title. The value of the static\n * property is overridden if the #title config option is used.\n *\n * If the element has a default title (e.g. `<input type=file>`), `null` will allow that title to be\n * shown. Use empty string to suppress it.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.TitledElement.static.title = null;\n\n/* Methods */\n\n/**\n * Set the titled element.\n *\n * This method is used to retarget a TitledElement mixin so that its functionality applies to the\n * specified element.\n * If an element is already set, the mixin’s effect on that element is removed before the new\n * element is set up.\n *\n * @param {jQuery} $titled Element that should use the 'titled' functionality\n */\nOO.ui.mixin.TitledElement.prototype.setTitledElement = function ( $titled ) {\n\tif ( this.$titled ) {\n\t\tthis.$titled.removeAttr( 'title' );\n\t}\n\n\tthis.$titled = $titled;\n\tthis.updateTitle();\n};\n\n/**\n * Set title.\n *\n * @param {string|Function|null} title Title text, a function that returns text, or `null`\n *  for no title\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TitledElement.prototype.setTitle = function ( title ) {\n\ttitle = typeof title === 'function' ? OO.ui.resolveMsg( title ) : title;\n\ttitle = typeof title === 'string' ? title : null;\n\n\tif ( this.title !== title ) {\n\t\tthis.title = title;\n\t\tthis.updateTitle();\n\t}\n\n\treturn this;\n};\n\n/**\n * Update the title attribute, in case of changes to title or accessKey.\n *\n * @protected\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.TitledElement.prototype.updateTitle = function () {\n\tvar title = this.getTitle();\n\tif ( this.$titled ) {\n\t\tif ( title !== null ) {\n\t\t\t// Only if this is an AccessKeyedElement\n\t\t\tif ( this.formatTitleWithAccessKey ) {\n\t\t\t\ttitle = this.formatTitleWithAccessKey( title );\n\t\t\t}\n\t\t\tthis.$titled.attr( 'title', title );\n\t\t} else {\n\t\t\tthis.$titled.removeAttr( 'title' );\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Get title.\n *\n * @return {string} Title string\n */\nOO.ui.mixin.TitledElement.prototype.getTitle = function () {\n\treturn this.title;\n};\n","/**\n * AccessKeyedElement is mixed into other classes to provide an `accesskey` HTML attribute.\n * Access keys allow an user to go to a specific element by using\n * a shortcut combination of a browser specific keys + the key\n * set to the field.\n *\n *     @example\n *     // AccessKeyedElement provides an `accesskey` attribute to the\n *     // ButtonWidget class.\n *     var button = new OO.ui.ButtonWidget( {\n *         label: 'Button with access key',\n *         accessKey: 'k'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$accessKeyed] The element to which the `accesskey` attribute is applied.\n *  If this config is omitted, the access key functionality is applied to $element, the\n *  element created by the class.\n * @cfg {string|Function} [accessKey] The key or a function that returns the key. If\n *  this config is omitted, no access key will be added.\n */\nOO.ui.mixin.AccessKeyedElement = function OoUiMixinAccessKeyedElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$accessKeyed = null;\n\tthis.accessKey = null;\n\n\t// Initialization\n\tthis.setAccessKey( config.accessKey || null );\n\tthis.setAccessKeyedElement( config.$accessKeyed || this.$element );\n\n\t// If this is also a TitledElement and it initialized before we did, we may have\n\t// to update the title with the access key\n\tif ( this.updateTitle ) {\n\t\tthis.updateTitle();\n\t}\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.AccessKeyedElement );\n\n/* Static Properties */\n\n/**\n * The access key, a function that returns a key, or `null` for no access key.\n *\n * @static\n * @inheritable\n * @property {string|Function|null}\n */\nOO.ui.mixin.AccessKeyedElement.static.accessKey = null;\n\n/* Methods */\n\n/**\n * Set the access keyed element.\n *\n * This method is used to retarget a AccessKeyedElement mixin so that its functionality applies to\n * the specified element.\n * If an element is already set, the mixin's effect on that element is removed before the new\n * element is set up.\n *\n * @param {jQuery} $accessKeyed Element that should use the 'access keyed' functionality\n */\nOO.ui.mixin.AccessKeyedElement.prototype.setAccessKeyedElement = function ( $accessKeyed ) {\n\tif ( this.$accessKeyed ) {\n\t\tthis.$accessKeyed.removeAttr( 'accesskey' );\n\t}\n\n\tthis.$accessKeyed = $accessKeyed;\n\tif ( this.accessKey ) {\n\t\tthis.$accessKeyed.attr( 'accesskey', this.accessKey );\n\t}\n};\n\n/**\n * Set access key.\n *\n * @param {string|Function|null} accessKey Key, a function that returns a key, or `null` for no\n *  access key\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.AccessKeyedElement.prototype.setAccessKey = function ( accessKey ) {\n\taccessKey = typeof accessKey === 'string' ? OO.ui.resolveMsg( accessKey ) : null;\n\n\tif ( this.accessKey !== accessKey ) {\n\t\tif ( this.$accessKeyed ) {\n\t\t\tif ( accessKey !== null ) {\n\t\t\t\tthis.$accessKeyed.attr( 'accesskey', accessKey );\n\t\t\t} else {\n\t\t\t\tthis.$accessKeyed.removeAttr( 'accesskey' );\n\t\t\t}\n\t\t}\n\t\tthis.accessKey = accessKey;\n\n\t\t// Only if this is a TitledElement\n\t\tif ( this.updateTitle ) {\n\t\t\tthis.updateTitle();\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Get access key.\n *\n * @return {string} accessKey string\n */\nOO.ui.mixin.AccessKeyedElement.prototype.getAccessKey = function () {\n\treturn this.accessKey;\n};\n\n/**\n * Add information about the access key to the element's tooltip label.\n * (This is only public for hacky usage in FieldLayout.)\n *\n * @param {string} title Tooltip label for `title` attribute\n * @return {string}\n */\nOO.ui.mixin.AccessKeyedElement.prototype.formatTitleWithAccessKey = function ( title ) {\n\tvar accessKey;\n\n\tif ( !this.$accessKeyed ) {\n\t\t// Not initialized yet; the constructor will call updateTitle() which will rerun this\n\t\t// function.\n\t\treturn title;\n\t}\n\t// Use jquery.accessKeyLabel if available to show modifiers, otherwise just display the\n\t// single key.\n\tif ( $.fn.updateTooltipAccessKeys && $.fn.updateTooltipAccessKeys.getAccessKeyLabel ) {\n\t\taccessKey = $.fn.updateTooltipAccessKeys.getAccessKeyLabel( this.$accessKeyed[ 0 ] );\n\t} else {\n\t\taccessKey = this.getAccessKey();\n\t}\n\tif ( accessKey ) {\n\t\ttitle += ' [' + accessKey + ']';\n\t}\n\treturn title;\n};\n","/**\n * ButtonWidget is a generic widget for buttons. A wide variety of looks,\n * feels, and functionality can be customized via the class’s configuration options\n * and methods. Please see the [OOUI documentation on MediaWiki] [1] for more information\n * and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches\n *\n *     @example\n *     // A button widget.\n *     var button = new OO.ui.ButtonWidget( {\n *         label: 'Button with Icon',\n *         icon: 'trash',\n *         title: 'Remove'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * NOTE: HTML form buttons should use the OO.ui.ButtonInputWidget class.\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.AccessKeyedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [active=false] Whether button should be shown as active\n * @cfg {string} [href] Hyperlink to visit when the button is clicked.\n * @cfg {string} [target] The frame or window in which to open the hyperlink.\n * @cfg {boolean} [noFollow] Search engine traversal hint (default: true)\n */\nOO.ui.ButtonWidget = function OoUiButtonWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ButtonWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {\n\t\t$titled: this.$button\n\t}, config ) );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {\n\t\t$tabIndexed: this.$button\n\t}, config ) );\n\tOO.ui.mixin.AccessKeyedElement.call( this, $.extend( {\n\t\t$accessKeyed: this.$button\n\t}, config ) );\n\n\t// Properties\n\tthis.href = null;\n\tthis.target = null;\n\tthis.noFollow = false;\n\n\t// Events\n\tthis.connect( this, {\n\t\tdisable: 'onDisable'\n\t} );\n\n\t// Initialization\n\tthis.$button.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element\n\t\t.addClass( 'oo-ui-buttonWidget' )\n\t\t.append( this.$button );\n\tthis.setActive( config.active );\n\tthis.setHref( config.href );\n\tthis.setTarget( config.target );\n\tthis.setNoFollow( config.noFollow );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.AccessKeyedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonWidget.static.cancelButtonMouseDownEvents = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * Get hyperlink location.\n *\n * @return {string} Hyperlink location\n */\nOO.ui.ButtonWidget.prototype.getHref = function () {\n\treturn this.href;\n};\n\n/**\n * Get hyperlink target.\n *\n * @return {string} Hyperlink target\n */\nOO.ui.ButtonWidget.prototype.getTarget = function () {\n\treturn this.target;\n};\n\n/**\n * Get search engine traversal hint.\n *\n * @return {boolean} Whether search engines should avoid traversing this hyperlink\n */\nOO.ui.ButtonWidget.prototype.getNoFollow = function () {\n\treturn this.noFollow;\n};\n\n/**\n * Set hyperlink location.\n *\n * @param {string|null} href Hyperlink location, null to remove\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.setHref = function ( href ) {\n\thref = typeof href === 'string' ? href : null;\n\tif ( href !== null && !OO.ui.isSafeUrl( href ) ) {\n\t\thref = './' + href;\n\t}\n\n\tif ( href !== this.href ) {\n\t\tthis.href = href;\n\t\tthis.updateHref();\n\t}\n\n\treturn this;\n};\n\n/**\n * Update the `href` attribute, in case of changes to href or\n * disabled state.\n *\n * @private\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.updateHref = function () {\n\tif ( this.href !== null && !this.isDisabled() ) {\n\t\tthis.$button.attr( 'href', this.href );\n\t} else {\n\t\tthis.$button.removeAttr( 'href' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Handle disable events.\n *\n * @private\n * @param {boolean} disabled Element is disabled\n */\nOO.ui.ButtonWidget.prototype.onDisable = function () {\n\tthis.updateHref();\n};\n\n/**\n * Set hyperlink target.\n *\n * @param {string|null} target Hyperlink target, null to remove\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.setTarget = function ( target ) {\n\ttarget = typeof target === 'string' ? target : null;\n\n\tif ( target !== this.target ) {\n\t\tthis.target = target;\n\t\tif ( target !== null ) {\n\t\t\tthis.$button.attr( 'target', target );\n\t\t} else {\n\t\t\tthis.$button.removeAttr( 'target' );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Set search engine traversal hint.\n *\n * @param {boolean} noFollow True if search engines should avoid traversing this hyperlink\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonWidget.prototype.setNoFollow = function ( noFollow ) {\n\tnoFollow = typeof noFollow === 'boolean' ? noFollow : true;\n\n\tif ( noFollow !== this.noFollow ) {\n\t\tthis.noFollow = noFollow;\n\t\tif ( noFollow ) {\n\t\t\tthis.$button.attr( 'rel', 'nofollow' );\n\t\t} else {\n\t\t\tthis.$button.removeAttr( 'rel' );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n// Override method visibility hints from ButtonElement\n/**\n * @method setActive\n * @inheritdoc\n */\n/**\n * @method isActive\n * @inheritdoc\n */\n","/**\n * A ButtonGroupWidget groups related buttons and is used together with OO.ui.ButtonWidget and\n * its subclasses. Each button in a group is addressed by a unique reference. Buttons can be added,\n * removed, and cleared from the group.\n *\n *     @example\n *     // A ButtonGroupWidget with two buttons.\n *     var button1 = new OO.ui.PopupButtonWidget( {\n *             label: 'Select a category',\n *             icon: 'menu',\n *             popup: {\n *                 $content: $( '<p>List of categories…</p>' ),\n *                 padded: true,\n *                 align: 'left'\n *             }\n *         } ),\n *         button2 = new OO.ui.ButtonWidget( {\n *             label: 'Add item'\n *         } ),\n *         buttonGroup = new OO.ui.ButtonGroupWidget( {\n *             items: [ button1, button2 ]\n *         } );\n *     $( document.body ).append( buttonGroup.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.ButtonWidget[]} [items] Buttons to add\n */\nOO.ui.ButtonGroupWidget = function OoUiButtonGroupWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ButtonGroupWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( {\n\t\t$group: this.$element\n\t}, config ) );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonGroupWidget' );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonGroupWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.mixin.GroupElement );\nOO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonGroupWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * Focus the widget\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonGroupWidget.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tif ( this.items[ 0 ] ) {\n\t\t\tthis.items[ 0 ].focus();\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ButtonGroupWidget.prototype.simulateLabelClick = function () {\n\tthis.focus();\n};\n","/**\n * IconWidget is a generic widget for {@link OO.ui.mixin.IconElement icons}.\n * In general, IconWidgets should be used with OO.ui.LabelWidget, which creates a label that\n * identifies the icon’s function. See the [OOUI documentation on MediaWiki] [1]\n * for a list of icons included in the library.\n *\n *     @example\n *     // An IconWidget with a label via LabelWidget.\n *     var myIcon = new OO.ui.IconWidget( {\n *             icon: 'help',\n *             title: 'Help'\n *          } ),\n *          // Create a label.\n *          iconLabel = new OO.ui.LabelWidget( {\n *              label: 'Help'\n *          } );\n *      $( document.body ).append( myIcon.$element, iconLabel.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Icons\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.IconWidget = function OoUiIconWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.IconWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, $.extend( {\n\t\t$icon: this.$element\n\t}, config ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {\n\t\t$titled: this.$element\n\t}, config ) );\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {\n\t\t$label: this.$element,\n\t\tinvisibleLabel: true\n\t}, config ) );\n\tOO.ui.mixin.FlaggedElement.call( this, $.extend( {\n\t\t$flagged: this.$element\n\t}, config ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-iconWidget' );\n\t// Remove class added by LabelElement initialization. It causes unexpected CSS to apply when\n\t// nested in other widgets, because this widget used to not mix in LabelElement.\n\tthis.$element.removeClass( 'oo-ui-labelElement-label' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.IconWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.FlaggedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.IconWidget.static.tagName = 'span';\n","/**\n * IndicatorWidgets create indicators, which are small graphics that are generally used to draw\n * attention to the status of an item or to clarify the function within a control. For a list of\n * indicators included in the library, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // An indicator widget.\n *     var indicator1 = new OO.ui.IndicatorWidget( {\n *             indicator: 'required'\n *         } ),\n *         // Create a fieldset layout to add a label.\n *         fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( indicator1, {\n *             label: 'A required indicator:'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Icons,_Indicators,_and_Labels#Indicators\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.LabelElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.IndicatorWidget = function OoUiIndicatorWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.IndicatorWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IndicatorElement.call( this, $.extend( {\n\t\t$indicator: this.$element\n\t}, config ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {\n\t\t$titled: this.$element\n\t}, config ) );\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {\n\t\t$label: this.$element,\n\t\tinvisibleLabel: true\n\t}, config ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-indicatorWidget' );\n\t// Remove class added by LabelElement initialization. It causes unexpected CSS to apply when\n\t// nested in other widgets, because this widget used to not mix in LabelElement.\n\tthis.$element.removeClass( 'oo-ui-labelElement-label' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.IndicatorWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.LabelElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.IndicatorWidget.static.tagName = 'span';\n","/**\n * LabelWidgets help identify the function of interface elements. Each LabelWidget can\n * be configured with a `label` option that is set to a string, a label node, or a function:\n *\n * - String: a plaintext string\n * - jQuery selection: a jQuery selection, used for anything other than a plaintext label, e.g., a\n *   label that includes a link or special styling, such as a gray color or additional\n *   graphical elements.\n * - Function: a function that will produce a string in the future. Functions are used\n *   in cases where the value of the label is not currently defined.\n *\n * In addition, the LabelWidget can be associated with an {@link OO.ui.InputWidget input widget},\n * which will come into focus when the label is clicked.\n *\n *     @example\n *     // Two LabelWidgets.\n *     var label1 = new OO.ui.LabelWidget( {\n *             label: 'plaintext label'\n *         } ),\n *         label2 = new OO.ui.LabelWidget( {\n *             label: $( '<a>' ).attr( 'href', 'default.html' ).text( 'jQuery label' )\n *         } ),\n *         // Create a fieldset layout with fields for each example.\n *         fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( label1 ),\n *         new OO.ui.FieldLayout( label2 )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.InputWidget} [input] {@link OO.ui.InputWidget Input widget} that uses the label.\n *  Clicking the label will focus the specified input field.\n */\nOO.ui.LabelWidget = function OoUiLabelWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.LabelWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {\n\t\t$label: this.$element\n\t}, config ) );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.input = config.input;\n\n\t// Initialization\n\tif ( this.input ) {\n\t\tif ( this.input.getInputId() ) {\n\t\t\tthis.$element.attr( 'for', this.input.getInputId() );\n\t\t} else {\n\t\t\tthis.$label.on( 'click', function () {\n\t\t\t\tthis.input.simulateLabelClick();\n\t\t\t}.bind( this ) );\n\t\t}\n\t}\n\tthis.$element.addClass( 'oo-ui-labelWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.LabelWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.LabelWidget.static.tagName = 'label';\n","/**\n * PendingElement is a mixin that is used to create elements that notify users that something is\n * happening and that they should wait before proceeding. The pending state is visually represented\n * with a pending texture that appears in the head of a pending\n * {@link OO.ui.ProcessDialog process dialog} or in the input field of a\n * {@link OO.ui.TextInputWidget text input widget}.\n *\n * Currently, {@link OO.ui.ActionWidget Action widgets}, which mix in this class, can also be marked\n * as pending, but only when used in {@link OO.ui.MessageDialog message dialogs}. The behavior is\n * not currently supported for action widgets used in process dialogs.\n *\n *     @example\n *     function MessageDialog( config ) {\n *         MessageDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MessageDialog, OO.ui.MessageDialog );\n *\n *     MessageDialog.static.name = 'myMessageDialog';\n *     MessageDialog.static.actions = [\n *         { action: 'save', label: 'Done', flags: 'primary' },\n *         { label: 'Cancel', flags: 'safe' }\n *     ];\n *\n *     MessageDialog.prototype.initialize = function () {\n *         MessageDialog.parent.prototype.initialize.apply( this, arguments );\n *         this.content = new OO.ui.PanelLayout( { padded: true } );\n *         this.content.$element.append( '<p>Click the \\'Done\\' action widget to see its pending ' +\n *             'state. Note that action widgets can be marked pending in message dialogs but not ' +\n *             'process dialogs.</p>' );\n *         this.$body.append( this.content.$element );\n *     };\n *     MessageDialog.prototype.getBodyHeight = function () {\n *         return 100;\n *     }\n *     MessageDialog.prototype.getActionProcess = function ( action ) {\n *         var dialog = this;\n *         if ( action === 'save' ) {\n *             dialog.getActions().get({actions: 'save'})[0].pushPending();\n *             return new OO.ui.Process()\n *             .next( 1000 )\n *             .next( function () {\n *                 dialog.getActions().get({actions: 'save'})[0].popPending();\n *             } );\n *         }\n *         return MessageDialog.parent.prototype.getActionProcess.call( this, action );\n *     };\n *\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *\n *     var dialog = new MessageDialog();\n *     windowManager.addWindows( [ dialog ] );\n *     windowManager.openWindow( dialog );\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$pending] Element to mark as pending, defaults to this.$element\n */\nOO.ui.mixin.PendingElement = function OoUiMixinPendingElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.pending = 0;\n\tthis.$pending = null;\n\n\t// Initialisation\n\tthis.setPendingElement( config.$pending || this.$element );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.PendingElement );\n\n/* Methods */\n\n/**\n * Set the pending element (and clean up any existing one).\n *\n * @param {jQuery} $pending The element to set to pending.\n */\nOO.ui.mixin.PendingElement.prototype.setPendingElement = function ( $pending ) {\n\tif ( this.$pending ) {\n\t\tthis.$pending.removeClass( 'oo-ui-pendingElement-pending' );\n\t}\n\n\tthis.$pending = $pending;\n\tif ( this.pending > 0 ) {\n\t\tthis.$pending.addClass( 'oo-ui-pendingElement-pending' );\n\t}\n};\n\n/**\n * Check if an element is pending.\n *\n * @return {boolean} Element is pending\n */\nOO.ui.mixin.PendingElement.prototype.isPending = function () {\n\treturn !!this.pending;\n};\n\n/**\n * Increase the pending counter. The pending state will remain active until the counter is zero\n * (i.e., the number of calls to #pushPending and #popPending is the same).\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.PendingElement.prototype.pushPending = function () {\n\tif ( this.pending === 0 ) {\n\t\tthis.$pending.addClass( 'oo-ui-pendingElement-pending' );\n\t\tthis.updateThemeClasses();\n\t}\n\tthis.pending++;\n\n\treturn this;\n};\n\n/**\n * Decrease the pending counter. The pending state will remain active until the counter is zero\n * (i.e., the number of calls to #pushPending and #popPending is the same).\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.PendingElement.prototype.popPending = function () {\n\tif ( this.pending === 1 ) {\n\t\tthis.$pending.removeClass( 'oo-ui-pendingElement-pending' );\n\t\tthis.updateThemeClasses();\n\t}\n\tthis.pending = Math.max( 0, this.pending - 1 );\n\n\treturn this;\n};\n","/**\n * Element that will stick adjacent to a specified container, even when it is inserted elsewhere\n * in the document (for example, in an OO.ui.Window's $overlay).\n *\n * The elements's position is automatically calculated and maintained when window is resized or the\n * page is scrolled. If you reposition the container manually, you have to call #position to make\n * sure the element is still placed correctly.\n *\n * As positioning is only possible when both the element and the container are attached to the DOM\n * and visible, it's only done after you call #togglePositioning. You might want to do this inside\n * the #toggle method to display a floating popup, for example.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element\n * @cfg {jQuery} [$floatableContainer] Node to position adjacent to\n * @cfg {string} [verticalPosition='below'] Where to position $floatable vertically:\n *  'below': Directly below $floatableContainer, aligning f's top edge with fC's bottom edge\n *  'above': Directly above $floatableContainer, aligning f's bottom edge with fC's top edge\n *  'top': Align the top edge with $floatableContainer's top edge\n *  'bottom': Align the bottom edge with $floatableContainer's bottom edge\n *  'center': Vertically align the center with $floatableContainer's center\n * @cfg {string} [horizontalPosition='start'] Where to position $floatable horizontally:\n *  'before': Directly before $floatableContainer, aligning f's end edge with fC's start edge\n *  'after': Directly after $floatableContainer, aligning f's start edge with fC's end edge\n *  'start': Align the start (left in LTR, right in RTL) edge with $floatableContainer's start edge\n *  'end': Align the end (right in LTR, left in RTL) edge with $floatableContainer's end edge\n *  'center': Horizontally align the center with $floatableContainer's center\n * @cfg {boolean} [hideWhenOutOfView=true] Whether to hide the floatable element if the container\n *  is out of view\n */\nOO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$floatable = null;\n\tthis.$floatableContainer = null;\n\tthis.$floatableWindow = null;\n\tthis.$floatableClosestScrollable = null;\n\tthis.floatableOutOfView = false;\n\tthis.onFloatableScrollHandler = this.position.bind( this );\n\tthis.onFloatableWindowResizeHandler = this.position.bind( this );\n\n\t// Initialization\n\tthis.setFloatableContainer( config.$floatableContainer );\n\tthis.setFloatableElement( config.$floatable || this.$element );\n\tthis.setVerticalPosition( config.verticalPosition || 'below' );\n\tthis.setHorizontalPosition( config.horizontalPosition || 'start' );\n\tthis.hideWhenOutOfView = config.hideWhenOutOfView === undefined ?\n\t\ttrue : !!config.hideWhenOutOfView;\n};\n\n/* Methods */\n\n/**\n * Set floatable element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $floatable Element to make floatable\n */\nOO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatable ) {\n\tif ( this.$floatable ) {\n\t\tthis.$floatable.removeClass( 'oo-ui-floatableElement-floatable' );\n\t\tthis.$floatable.css( { left: '', top: '' } );\n\t}\n\n\tthis.$floatable = $floatable.addClass( 'oo-ui-floatableElement-floatable' );\n\tthis.position();\n};\n\n/**\n * Set floatable container.\n *\n * The element will be positioned relative to the specified container.\n *\n * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset\n */\nOO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $floatableContainer ) {\n\tthis.$floatableContainer = $floatableContainer;\n\tif ( this.$floatable ) {\n\t\tthis.position();\n\t}\n};\n\n/**\n * Change how the element is positioned vertically.\n *\n * @param {string} position 'below', 'above', 'top', 'bottom' or 'center'\n */\nOO.ui.mixin.FloatableElement.prototype.setVerticalPosition = function ( position ) {\n\tif ( [ 'below', 'above', 'top', 'bottom', 'center' ].indexOf( position ) === -1 ) {\n\t\tthrow new Error( 'Invalid value for vertical position: ' + position );\n\t}\n\tif ( this.verticalPosition !== position ) {\n\t\tthis.verticalPosition = position;\n\t\tif ( this.$floatable ) {\n\t\t\tthis.position();\n\t\t}\n\t}\n};\n\n/**\n * Change how the element is positioned horizontally.\n *\n * @param {string} position 'before', 'after', 'start', 'end' or 'center'\n */\nOO.ui.mixin.FloatableElement.prototype.setHorizontalPosition = function ( position ) {\n\tif ( [ 'before', 'after', 'start', 'end', 'center' ].indexOf( position ) === -1 ) {\n\t\tthrow new Error( 'Invalid value for horizontal position: ' + position );\n\t}\n\tif ( this.horizontalPosition !== position ) {\n\t\tthis.horizontalPosition = position;\n\t\tif ( this.$floatable ) {\n\t\t\tthis.position();\n\t\t}\n\t}\n};\n\n/**\n * Toggle positioning.\n *\n * Do not turn positioning on until after the element is attached to the DOM and visible.\n *\n * @param {boolean} [positioning] Enable positioning, omit to toggle\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) {\n\tvar closestScrollableOfContainer;\n\n\tif ( !this.$floatable || !this.$floatableContainer ) {\n\t\treturn this;\n\t}\n\n\tpositioning = positioning === undefined ? !this.positioning : !!positioning;\n\n\tif ( positioning && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'FloatableElement#togglePositioning: Before calling this method, the element must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\n\tif ( this.positioning !== positioning ) {\n\t\tthis.positioning = positioning;\n\n\t\tclosestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer(\n\t\t\tthis.$floatableContainer[ 0 ]\n\t\t);\n\t\t// If the scrollable is the root, we have to listen to scroll events\n\t\t// on the window because of browser inconsistencies.\n\t\tif ( $( closestScrollableOfContainer ).is( 'html, body' ) ) {\n\t\t\tclosestScrollableOfContainer = OO.ui.Element.static.getWindow(\n\t\t\t\tclosestScrollableOfContainer\n\t\t\t);\n\t\t}\n\n\t\tif ( positioning ) {\n\t\t\tthis.$floatableWindow = $( this.getElementWindow() );\n\t\t\tthis.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler );\n\n\t\t\tthis.$floatableClosestScrollable = $( closestScrollableOfContainer );\n\t\t\tthis.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler );\n\n\t\t\t// Initial position after visible\n\t\t\tthis.position();\n\t\t} else {\n\t\t\tif ( this.$floatableWindow ) {\n\t\t\t\tthis.$floatableWindow.off( 'resize', this.onFloatableWindowResizeHandler );\n\t\t\t\tthis.$floatableWindow = null;\n\t\t\t}\n\n\t\t\tif ( this.$floatableClosestScrollable ) {\n\t\t\t\tthis.$floatableClosestScrollable.off( 'scroll', this.onFloatableScrollHandler );\n\t\t\t\tthis.$floatableClosestScrollable = null;\n\t\t\t}\n\n\t\t\tthis.$floatable.css( { left: '', right: '', top: '' } );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Check whether the bottom edge of the given element is within the viewport of the given\n * container.\n *\n * @private\n * @param {jQuery} $element\n * @param {jQuery} $container\n * @return {boolean}\n */\nOO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) {\n\tvar elemRect, contRect, topEdgeInBounds, bottomEdgeInBounds, leftEdgeInBounds,\n\t\trightEdgeInBounds, startEdgeInBounds, endEdgeInBounds, viewportSpacing,\n\t\tdirection = $element.css( 'direction' );\n\n\telemRect = $element[ 0 ].getBoundingClientRect();\n\tif ( $container[ 0 ] === window ) {\n\t\tviewportSpacing = OO.ui.getViewportSpacing();\n\t\tcontRect = {\n\t\t\ttop: 0,\n\t\t\tleft: 0,\n\t\t\tright: document.documentElement.clientWidth,\n\t\t\tbottom: document.documentElement.clientHeight\n\t\t};\n\t\tcontRect.top += viewportSpacing.top;\n\t\tcontRect.left += viewportSpacing.left;\n\t\tcontRect.right -= viewportSpacing.right;\n\t\tcontRect.bottom -= viewportSpacing.bottom;\n\t} else {\n\t\tcontRect = $container[ 0 ].getBoundingClientRect();\n\t}\n\n\ttopEdgeInBounds = elemRect.top >= contRect.top && elemRect.top <= contRect.bottom;\n\tbottomEdgeInBounds = elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom;\n\tleftEdgeInBounds = elemRect.left >= contRect.left && elemRect.left <= contRect.right;\n\trightEdgeInBounds = elemRect.right >= contRect.left && elemRect.right <= contRect.right;\n\tif ( direction === 'rtl' ) {\n\t\tstartEdgeInBounds = rightEdgeInBounds;\n\t\tendEdgeInBounds = leftEdgeInBounds;\n\t} else {\n\t\tstartEdgeInBounds = leftEdgeInBounds;\n\t\tendEdgeInBounds = rightEdgeInBounds;\n\t}\n\n\tif ( this.verticalPosition === 'below' && !bottomEdgeInBounds ) {\n\t\treturn false;\n\t}\n\tif ( this.verticalPosition === 'above' && !topEdgeInBounds ) {\n\t\treturn false;\n\t}\n\tif ( this.horizontalPosition === 'before' && !startEdgeInBounds ) {\n\t\treturn false;\n\t}\n\tif ( this.horizontalPosition === 'after' && !endEdgeInBounds ) {\n\t\treturn false;\n\t}\n\n\t// The other positioning values are all about being inside the container,\n\t// so in those cases all we care about is that any part of the container is visible.\n\treturn elemRect.top <= contRect.bottom && elemRect.bottom >= contRect.top &&\n\t\telemRect.left <= contRect.right && elemRect.right >= contRect.left;\n};\n\n/**\n * Check if the floatable is hidden to the user because it was offscreen.\n *\n * @return {boolean} Floatable is out of view\n */\nOO.ui.mixin.FloatableElement.prototype.isFloatableOutOfView = function () {\n\treturn this.floatableOutOfView;\n};\n\n/**\n * Position the floatable below its container.\n *\n * This should only be done when both of them are attached to the DOM and visible.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.FloatableElement.prototype.position = function () {\n\tif ( !this.positioning ) {\n\t\treturn this;\n\t}\n\n\tif ( !(\n\t\t// To continue, some things need to be true:\n\t\t// The element must actually be in the DOM\n\t\tthis.isElementAttached() && (\n\t\t\t// The closest scrollable is the current window\n\t\t\tthis.$floatableClosestScrollable[ 0 ] === this.getElementWindow() ||\n\t\t\t// OR is an element in the element's DOM\n\t\t\t$.contains( this.getElementDocument(), this.$floatableClosestScrollable[ 0 ] )\n\t\t)\n\t) ) {\n\t\t// Abort early if important parts of the widget are no longer attached to the DOM\n\t\treturn this;\n\t}\n\n\tthis.floatableOutOfView = this.hideWhenOutOfView &&\n\t\t!this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable );\n\tif ( this.floatableOutOfView ) {\n\t\tthis.$floatable.addClass( 'oo-ui-element-hidden' );\n\t\treturn this;\n\t} else {\n\t\tthis.$floatable.removeClass( 'oo-ui-element-hidden' );\n\t}\n\n\tthis.$floatable.css( this.computePosition() );\n\n\t// We updated the position, so re-evaluate the clipping state.\n\t// (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so\n\t// will not notice the need to update itself.)\n\t// TODO: This is terrible, we shouldn't need to know about ClippableElement at all here.\n\t// Why does it not listen to the right events in the right places?\n\tif ( this.clip ) {\n\t\tthis.clip();\n\t}\n\n\treturn this;\n};\n\n/**\n * Compute how #$floatable should be positioned based on the position of #$floatableContainer\n * and the positioning settings. This is a helper for #position that shouldn't be called directly,\n * but may be overridden by subclasses if they want to change or add to the positioning logic.\n *\n * @return {Object} New position to apply with .css(). Keys are 'top', 'left', 'bottom' and 'right'.\n */\nOO.ui.mixin.FloatableElement.prototype.computePosition = function () {\n\tvar isBody, scrollableX, scrollableY, containerPos,\n\t\thorizScrollbarHeight, vertScrollbarWidth, scrollTop, scrollLeft,\n\t\tnewPos = { top: '', left: '', bottom: '', right: '' },\n\t\tdirection = this.$floatableContainer.css( 'direction' ),\n\t\t$offsetParent = this.$floatable.offsetParent();\n\n\tif ( $offsetParent.is( 'html' ) ) {\n\t\t// The innerHeight/Width and clientHeight/Width calculations don't work well on the\n\t\t// <html> element, but they do work on the <body>\n\t\t$offsetParent = $( $offsetParent[ 0 ].ownerDocument.body );\n\t}\n\tisBody = $offsetParent.is( 'body' );\n\tscrollableX = $offsetParent.css( 'overflow-x' ) === 'scroll' ||\n\t\t$offsetParent.css( 'overflow-x' ) === 'auto';\n\tscrollableY = $offsetParent.css( 'overflow-y' ) === 'scroll' ||\n\t\t$offsetParent.css( 'overflow-y' ) === 'auto';\n\n\tvertScrollbarWidth = $offsetParent.innerWidth() - $offsetParent.prop( 'clientWidth' );\n\thorizScrollbarHeight = $offsetParent.innerHeight() - $offsetParent.prop( 'clientHeight' );\n\t// We don't need to compute and add scrollTop and scrollLeft if the scrollable container\n\t// is the body, or if it isn't scrollable\n\tscrollTop = scrollableY && !isBody ?\n\t\t$offsetParent.scrollTop() : 0;\n\tscrollLeft = scrollableX && !isBody ?\n\t\tOO.ui.Element.static.getScrollLeft( $offsetParent[ 0 ] ) : 0;\n\n\t// Avoid passing the <body> to getRelativePosition(), because it won't return what we expect\n\t// if the <body> has a margin\n\tcontainerPos = isBody ?\n\t\tthis.$floatableContainer.offset() :\n\t\tOO.ui.Element.static.getRelativePosition( this.$floatableContainer, $offsetParent );\n\tcontainerPos.bottom = containerPos.top + this.$floatableContainer.outerHeight();\n\tcontainerPos.right = containerPos.left + this.$floatableContainer.outerWidth();\n\tcontainerPos.start = direction === 'rtl' ? containerPos.right : containerPos.left;\n\tcontainerPos.end = direction === 'rtl' ? containerPos.left : containerPos.right;\n\n\tif ( this.verticalPosition === 'below' ) {\n\t\tnewPos.top = containerPos.bottom;\n\t} else if ( this.verticalPosition === 'above' ) {\n\t\tnewPos.bottom = $offsetParent.outerHeight() - containerPos.top;\n\t} else if ( this.verticalPosition === 'top' ) {\n\t\tnewPos.top = containerPos.top;\n\t} else if ( this.verticalPosition === 'bottom' ) {\n\t\tnewPos.bottom = $offsetParent.outerHeight() - containerPos.bottom;\n\t} else if ( this.verticalPosition === 'center' ) {\n\t\tnewPos.top = containerPos.top +\n\t\t\t( this.$floatableContainer.height() - this.$floatable.height() ) / 2;\n\t}\n\n\tif ( this.horizontalPosition === 'before' ) {\n\t\tnewPos.end = containerPos.start;\n\t} else if ( this.horizontalPosition === 'after' ) {\n\t\tnewPos.start = containerPos.end;\n\t} else if ( this.horizontalPosition === 'start' ) {\n\t\tnewPos.start = containerPos.start;\n\t} else if ( this.horizontalPosition === 'end' ) {\n\t\tnewPos.end = containerPos.end;\n\t} else if ( this.horizontalPosition === 'center' ) {\n\t\tnewPos.left = containerPos.left +\n\t\t\t( this.$floatableContainer.width() - this.$floatable.width() ) / 2;\n\t}\n\n\tif ( newPos.start !== undefined ) {\n\t\tif ( direction === 'rtl' ) {\n\t\t\tnewPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) :\n\t\t\t\t$offsetParent ).outerWidth() - newPos.start;\n\t\t} else {\n\t\t\tnewPos.left = newPos.start;\n\t\t}\n\t\tdelete newPos.start;\n\t}\n\tif ( newPos.end !== undefined ) {\n\t\tif ( direction === 'rtl' ) {\n\t\t\tnewPos.left = newPos.end;\n\t\t} else {\n\t\t\tnewPos.right = ( isBody ? $( $offsetParent[ 0 ].ownerDocument.documentElement ) :\n\t\t\t\t$offsetParent ).outerWidth() - newPos.end;\n\t\t}\n\t\tdelete newPos.end;\n\t}\n\n\t// Account for scroll position\n\tif ( newPos.top !== '' ) {\n\t\tnewPos.top += scrollTop;\n\t}\n\tif ( newPos.bottom !== '' ) {\n\t\tnewPos.bottom -= scrollTop;\n\t}\n\tif ( newPos.left !== '' ) {\n\t\tnewPos.left += scrollLeft;\n\t}\n\tif ( newPos.right !== '' ) {\n\t\tnewPos.right -= scrollLeft;\n\t}\n\n\t// Account for scrollbar gutter\n\tif ( newPos.bottom !== '' ) {\n\t\tnewPos.bottom -= horizScrollbarHeight;\n\t}\n\tif ( direction === 'rtl' ) {\n\t\tif ( newPos.left !== '' ) {\n\t\t\tnewPos.left -= vertScrollbarWidth;\n\t\t}\n\t} else {\n\t\tif ( newPos.right !== '' ) {\n\t\t\tnewPos.right -= vertScrollbarWidth;\n\t\t}\n\t}\n\n\treturn newPos;\n};\n","/**\n * Element that can be automatically clipped to visible boundaries.\n *\n * Whenever the element's natural height changes, you have to call\n * {@link OO.ui.mixin.ClippableElement#clip} to make sure it's still\n * clipping correctly.\n *\n * The dimensions of #$clippableContainer will be compared to the boundaries of the\n * nearest scrollable container. If #$clippableContainer is too tall and/or too wide,\n * then #$clippable will be given a fixed reduced height and/or width and will be made\n * scrollable. By default, #$clippable and #$clippableContainer are the same element,\n * but you can build a static footer by setting #$clippableContainer to an element that contains\n * #$clippable and the footer.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$clippable] Node to clip, assigned to #$clippable, omit to use #$element\n * @cfg {jQuery} [$clippableContainer] Node to keep visible, assigned to #$clippableContainer,\n *   omit to use #$clippable\n */\nOO.ui.mixin.ClippableElement = function OoUiMixinClippableElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.$clippable = null;\n\tthis.$clippableContainer = null;\n\tthis.clipping = false;\n\tthis.clippedHorizontally = false;\n\tthis.clippedVertically = false;\n\tthis.$clippableScrollableContainer = null;\n\tthis.$clippableScroller = null;\n\tthis.$clippableWindow = null;\n\tthis.idealWidth = null;\n\tthis.idealHeight = null;\n\tthis.onClippableScrollHandler = this.clip.bind( this );\n\tthis.onClippableWindowResizeHandler = this.clip.bind( this );\n\n\t// Initialization\n\tif ( config.$clippableContainer ) {\n\t\tthis.setClippableContainer( config.$clippableContainer );\n\t}\n\tthis.setClippableElement( config.$clippable || this.$element );\n};\n\n/* Methods */\n\n/**\n * Set clippable element.\n *\n * If an element is already set, it will be cleaned up before setting up the new element.\n *\n * @param {jQuery} $clippable Element to make clippable\n */\nOO.ui.mixin.ClippableElement.prototype.setClippableElement = function ( $clippable ) {\n\tif ( this.$clippable ) {\n\t\tthis.$clippable.removeClass( 'oo-ui-clippableElement-clippable' );\n\t\tthis.$clippable.css( { width: '', height: '', overflowX: '', overflowY: '' } );\n\t\tOO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );\n\t}\n\n\tthis.$clippable = $clippable.addClass( 'oo-ui-clippableElement-clippable' );\n\tthis.clip();\n};\n\n/**\n * Set clippable container.\n *\n * This is the container that will be measured when deciding whether to clip. When clipping,\n * #$clippable will be resized in order to keep the clippable container fully visible.\n *\n * If the clippable container is unset, #$clippable will be used.\n *\n * @param {jQuery|null} $clippableContainer Container to keep visible, or null to unset\n */\nOO.ui.mixin.ClippableElement.prototype.setClippableContainer = function ( $clippableContainer ) {\n\tthis.$clippableContainer = $clippableContainer;\n\tif ( this.$clippable ) {\n\t\tthis.clip();\n\t}\n};\n\n/**\n * Toggle clipping.\n *\n * Do not turn clipping on until after the element is attached to the DOM and visible.\n *\n * @param {boolean} [clipping] Enable clipping, omit to toggle\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ClippableElement.prototype.toggleClipping = function ( clipping ) {\n\tclipping = clipping === undefined ? !this.clipping : !!clipping;\n\n\tif ( clipping && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'ClippableElement#toggleClipping: Before calling this method, the element must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\n\tif ( this.clipping !== clipping ) {\n\t\tthis.clipping = clipping;\n\t\tif ( clipping ) {\n\t\t\tthis.$clippableScrollableContainer = $( this.getClosestScrollableElementContainer() );\n\t\t\t// If the clippable container is the root, we have to listen to scroll events and check\n\t\t\t// jQuery.scrollTop on the window because of browser inconsistencies\n\t\t\tthis.$clippableScroller = this.$clippableScrollableContainer.is( 'html, body' ) ?\n\t\t\t\t$( OO.ui.Element.static.getWindow( this.$clippableScrollableContainer ) ) :\n\t\t\t\tthis.$clippableScrollableContainer;\n\t\t\tthis.$clippableScroller.on( 'scroll', this.onClippableScrollHandler );\n\t\t\tthis.$clippableWindow = $( this.getElementWindow() )\n\t\t\t\t.on( 'resize', this.onClippableWindowResizeHandler );\n\t\t\t// Initial clip after visible\n\t\t\tthis.clip();\n\t\t} else {\n\t\t\tthis.$clippable.css( {\n\t\t\t\twidth: '',\n\t\t\t\theight: '',\n\t\t\t\tmaxWidth: '',\n\t\t\t\tmaxHeight: '',\n\t\t\t\toverflowX: '',\n\t\t\t\toverflowY: ''\n\t\t\t} );\n\t\t\tOO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );\n\n\t\t\tthis.$clippableScrollableContainer = null;\n\t\t\tthis.$clippableScroller.off( 'scroll', this.onClippableScrollHandler );\n\t\t\tthis.$clippableScroller = null;\n\t\t\tthis.$clippableWindow.off( 'resize', this.onClippableWindowResizeHandler );\n\t\t\tthis.$clippableWindow = null;\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Check if the element will be clipped to fit the visible area of the nearest scrollable container.\n *\n * @return {boolean} Element will be clipped to the visible area\n */\nOO.ui.mixin.ClippableElement.prototype.isClipping = function () {\n\treturn this.clipping;\n};\n\n/**\n * Check if the bottom or right of the element is being clipped by the nearest scrollable container.\n *\n * @return {boolean} Part of the element is being clipped\n */\nOO.ui.mixin.ClippableElement.prototype.isClipped = function () {\n\treturn this.clippedHorizontally || this.clippedVertically;\n};\n\n/**\n * Check if the right of the element is being clipped by the nearest scrollable container.\n *\n * @return {boolean} Part of the element is being clipped\n */\nOO.ui.mixin.ClippableElement.prototype.isClippedHorizontally = function () {\n\treturn this.clippedHorizontally;\n};\n\n/**\n * Check if the bottom of the element is being clipped by the nearest scrollable container.\n *\n * @return {boolean} Part of the element is being clipped\n */\nOO.ui.mixin.ClippableElement.prototype.isClippedVertically = function () {\n\treturn this.clippedVertically;\n};\n\n/**\n * Set the ideal size. These are the dimensions #$clippable will have when it's not being clipped.\n *\n * @param {number|string} [width] Width as a number of pixels or CSS string with unit suffix\n * @param {number|string} [height] Height as a number of pixels or CSS string with unit suffix\n */\nOO.ui.mixin.ClippableElement.prototype.setIdealSize = function ( width, height ) {\n\tthis.idealWidth = width;\n\tthis.idealHeight = height;\n\n\tif ( !this.clipping ) {\n\t\t// Update dimensions\n\t\tthis.$clippable.css( { width: width, height: height } );\n\t}\n\t// While clipping, idealWidth and idealHeight are not considered\n};\n\n/**\n * Return the side of the clippable on which it is \"anchored\" (aligned to something else).\n * ClippableElement will clip the opposite side when reducing element's width.\n *\n * Classes that mix in ClippableElement should override this to return 'right' if their\n * clippable is absolutely positioned and using 'right: Npx' (and not using 'left').\n * If your class also mixes in FloatableElement, this is handled automatically.\n *\n * (This can't be guessed from the actual CSS because the computed values for 'left'/'right' are\n * always in pixels, even if they were unset or set to 'auto'.)\n *\n * When in doubt, 'left' (or 'right' in RTL) is a sane fallback.\n *\n * @return {string} 'left' or 'right'\n */\nOO.ui.mixin.ClippableElement.prototype.getHorizontalAnchorEdge = function () {\n\tif ( this.computePosition && this.positioning && this.computePosition().right !== '' ) {\n\t\treturn 'right';\n\t}\n\treturn 'left';\n};\n\n/**\n * Return the side of the clippable on which it is \"anchored\" (aligned to something else).\n * ClippableElement will clip the opposite side when reducing element's width.\n *\n * Classes that mix in ClippableElement should override this to return 'bottom' if their\n * clippable is absolutely positioned and using 'bottom: Npx' (and not using 'top').\n * If your class also mixes in FloatableElement, this is handled automatically.\n *\n * (This can't be guessed from the actual CSS because the computed values for 'left'/'right' are\n * always in pixels, even if they were unset or set to 'auto'.)\n *\n * When in doubt, 'top' is a sane fallback.\n *\n * @return {string} 'top' or 'bottom'\n */\nOO.ui.mixin.ClippableElement.prototype.getVerticalAnchorEdge = function () {\n\tif ( this.computePosition && this.positioning && this.computePosition().bottom !== '' ) {\n\t\treturn 'bottom';\n\t}\n\treturn 'top';\n};\n\n/**\n * Clip element to visible boundaries and allow scrolling when needed. You should call this method\n * when the element's natural height changes.\n *\n * Element will be clipped the bottom or right of the element is within 10px of the edge of, or\n * overlapped by, the visible area of the nearest scrollable container.\n *\n * Because calling clip() when the natural height changes isn't always possible, we also set\n * max-height when the element isn't being clipped. This means that if the element tries to grow\n * beyond the edge, something reasonable will happen before clip() is called.\n *\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.ClippableElement.prototype.clip = function () {\n\tvar extraHeight, extraWidth, viewportSpacing,\n\t\tdesiredWidth, desiredHeight, allotedWidth, allotedHeight,\n\t\tnaturalWidth, naturalHeight, clipWidth, clipHeight,\n\t\t$item, itemRect, $viewport, viewportRect, availableRect,\n\t\tdirection, vertScrollbarWidth, horizScrollbarHeight,\n\t\t// Extra tolerance so that the sloppy code below doesn't result in results that are off\n\t\t// by one or two pixels. (And also so that we have space to display drop shadows.)\n\t\t// Chosen by fair dice roll.\n\t\tbuffer = 7;\n\n\tif ( !this.clipping ) {\n\t\t// this.$clippableScrollableContainer and this.$clippableWindow are null, so the below\n\t\t// will fail\n\t\treturn this;\n\t}\n\n\tfunction rectIntersection( a, b ) {\n\t\tvar out = {};\n\t\tout.top = Math.max( a.top, b.top );\n\t\tout.left = Math.max( a.left, b.left );\n\t\tout.bottom = Math.min( a.bottom, b.bottom );\n\t\tout.right = Math.min( a.right, b.right );\n\t\treturn out;\n\t}\n\n\tviewportSpacing = OO.ui.getViewportSpacing();\n\n\tif ( this.$clippableScrollableContainer.is( 'html, body' ) ) {\n\t\t$viewport = $( this.$clippableScrollableContainer[ 0 ].ownerDocument.body );\n\t\t// Dimensions of the browser window, rather than the element!\n\t\tviewportRect = {\n\t\t\ttop: 0,\n\t\t\tleft: 0,\n\t\t\tright: document.documentElement.clientWidth,\n\t\t\tbottom: document.documentElement.clientHeight\n\t\t};\n\t\tviewportRect.top += viewportSpacing.top;\n\t\tviewportRect.left += viewportSpacing.left;\n\t\tviewportRect.right -= viewportSpacing.right;\n\t\tviewportRect.bottom -= viewportSpacing.bottom;\n\t} else {\n\t\t$viewport = this.$clippableScrollableContainer;\n\t\tviewportRect = $viewport[ 0 ].getBoundingClientRect();\n\t\t// Convert into a plain object\n\t\tviewportRect = $.extend( {}, viewportRect );\n\t}\n\n\t// Account for scrollbar gutter\n\tdirection = $viewport.css( 'direction' );\n\tvertScrollbarWidth = $viewport.innerWidth() - $viewport.prop( 'clientWidth' );\n\thorizScrollbarHeight = $viewport.innerHeight() - $viewport.prop( 'clientHeight' );\n\tviewportRect.bottom -= horizScrollbarHeight;\n\tif ( direction === 'rtl' ) {\n\t\tviewportRect.left += vertScrollbarWidth;\n\t} else {\n\t\tviewportRect.right -= vertScrollbarWidth;\n\t}\n\n\t// Add arbitrary tolerance\n\tviewportRect.top += buffer;\n\tviewportRect.left += buffer;\n\tviewportRect.right -= buffer;\n\tviewportRect.bottom -= buffer;\n\n\t$item = this.$clippableContainer || this.$clippable;\n\n\textraHeight = $item.outerHeight() - this.$clippable.outerHeight();\n\textraWidth = $item.outerWidth() - this.$clippable.outerWidth();\n\n\titemRect = $item[ 0 ].getBoundingClientRect();\n\t// Convert into a plain object\n\titemRect = $.extend( {}, itemRect );\n\n\t// Item might already be clipped, so we can't just use its dimensions (in case we might need to\n\t// make it larger than before). Extend the rectangle to the maximum size we are allowed to take.\n\tif ( this.getHorizontalAnchorEdge() === 'right' ) {\n\t\titemRect.left = viewportRect.left;\n\t} else {\n\t\titemRect.right = viewportRect.right;\n\t}\n\tif ( this.getVerticalAnchorEdge() === 'bottom' ) {\n\t\titemRect.top = viewportRect.top;\n\t} else {\n\t\titemRect.bottom = viewportRect.bottom;\n\t}\n\n\tavailableRect = rectIntersection( viewportRect, itemRect );\n\n\tdesiredWidth = Math.max( 0, availableRect.right - availableRect.left );\n\tdesiredHeight = Math.max( 0, availableRect.bottom - availableRect.top );\n\t// It should never be desirable to exceed the dimensions of the browser viewport... right?\n\tdesiredWidth = Math.min( desiredWidth,\n\t\tdocument.documentElement.clientWidth - viewportSpacing.left - viewportSpacing.right );\n\tdesiredHeight = Math.min( desiredHeight,\n\t\tdocument.documentElement.clientHeight - viewportSpacing.top - viewportSpacing.right );\n\tallotedWidth = Math.ceil( desiredWidth - extraWidth );\n\tallotedHeight = Math.ceil( desiredHeight - extraHeight );\n\tnaturalWidth = this.$clippable.prop( 'scrollWidth' );\n\tnaturalHeight = this.$clippable.prop( 'scrollHeight' );\n\tclipWidth = allotedWidth < naturalWidth;\n\tclipHeight = allotedHeight < naturalHeight;\n\n\tif ( clipWidth ) {\n\t\t// The order matters here. If overflow is not set first, Chrome displays bogus scrollbars.\n\t\t// See T157672.\n\t\t// Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for\n\t\t// this case.\n\t\tthis.$clippable.css( 'overflowX', 'scroll' );\n\t\t// eslint-disable-next-line no-void\n\t\tvoid this.$clippable[ 0 ].offsetHeight; // Force reflow\n\t\tthis.$clippable.css( {\n\t\t\twidth: Math.max( 0, allotedWidth ),\n\t\t\tmaxWidth: ''\n\t\t} );\n\t} else {\n\t\tthis.$clippable.css( {\n\t\t\toverflowX: '',\n\t\t\twidth: this.idealWidth || '',\n\t\t\tmaxWidth: Math.max( 0, allotedWidth )\n\t\t} );\n\t}\n\tif ( clipHeight ) {\n\t\t// The order matters here. If overflow is not set first, Chrome displays bogus scrollbars.\n\t\t// See T157672.\n\t\t// Forcing a reflow is a smaller workaround than calling reconsiderScrollbars() for\n\t\t// this case.\n\t\tthis.$clippable.css( 'overflowY', 'scroll' );\n\t\t// eslint-disable-next-line no-void\n\t\tvoid this.$clippable[ 0 ].offsetHeight; // Force reflow\n\t\tthis.$clippable.css( {\n\t\t\theight: Math.max( 0, allotedHeight ),\n\t\t\tmaxHeight: ''\n\t\t} );\n\t} else {\n\t\tthis.$clippable.css( {\n\t\t\toverflowY: '',\n\t\t\theight: this.idealHeight || '',\n\t\t\tmaxHeight: Math.max( 0, allotedHeight )\n\t\t} );\n\t}\n\n\t// If we stopped clipping in at least one of the dimensions\n\tif ( ( this.clippedHorizontally && !clipWidth ) || ( this.clippedVertically && !clipHeight ) ) {\n\t\tOO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );\n\t}\n\n\tthis.clippedHorizontally = clipWidth;\n\tthis.clippedVertically = clipHeight;\n\n\treturn this;\n};\n","/**\n * PopupWidget is a container for content. The popup is overlaid and positioned absolutely.\n * By default, each popup has an anchor that points toward its origin.\n * Please see the [OOUI documentation on MediaWiki.org] [1] for more information and examples.\n *\n * Unlike most widgets, PopupWidget is initially hidden and must be shown by calling #toggle.\n *\n *     @example\n *     // A PopupWidget.\n *     var popup = new OO.ui.PopupWidget( {\n *         $content: $( '<p>Hi there!</p>' ),\n *         padded: true,\n *         width: 300\n *     } );\n *\n *     $( document.body ).append( popup.$element );\n *     // To display the popup, toggle the visibility to 'true'.\n *     popup.toggle( true );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.ClippableElement\n * @mixins OO.ui.mixin.FloatableElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number|null} [width=320] Width of popup in pixels. Pass `null` to use automatic width.\n * @cfg {number|null} [height=null] Height of popup in pixels. Pass `null` to use automatic height.\n * @cfg {boolean} [anchor=true] Show anchor pointing to origin of popup\n * @cfg {string} [position='below'] Where to position the popup relative to $floatableContainer\n *  'above': Put popup above $floatableContainer; anchor points down to the horizontal center\n *    of $floatableContainer\n *  'below': Put popup below $floatableContainer; anchor points up to the horizontal center\n *    of $floatableContainer\n *  'before': Put popup to the left (LTR) / right (RTL) of $floatableContainer; anchor points\n *    endwards (right/left) to the vertical center of $floatableContainer\n *  'after': Put popup to the right (LTR) / left (RTL) of $floatableContainer; anchor points\n *    startwards (left/right) to the vertical center of $floatableContainer\n * @cfg {string} [align='center'] How to align the popup to $floatableContainer\n *  'forwards': If position is above/below, move the popup as far endwards (right in LTR, left in\n *    RTL) as possible while still keeping the anchor within the popup; if position is before/after,\n *    move the popup as far downwards as possible.\n *  'backwards': If position is above/below, move the popup as far startwards (left in LTR, right in\n *    RTL) as possible while still keeping the anchor within the popup; if position is before/after,\n *     move the popup as far upwards as possible.\n *  'center': Horizontally (if position is above/below) or vertically (before/after) align the\n *     center of the popup with the center of $floatableContainer.\n * 'force-left': Alias for 'forwards' in LTR and 'backwards' in RTL\n * 'force-right': Alias for 'backwards' in RTL and 'forwards' in LTR\n * @cfg {boolean} [autoFlip=true] Whether to automatically switch the popup's position between\n *  'above' and 'below', or between 'before' and 'after', if there is not enough space in the\n *  desired direction to display the popup without clipping\n * @cfg {jQuery} [$container] Constrain the popup to the boundaries of the specified container.\n *  See the [OOUI docs on MediaWiki][3] for an example.\n *  [3]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups#containerExample\n * @cfg {number} [containerPadding=10] Padding between the popup and its container, specified as a\n *  number of pixels.\n * @cfg {jQuery} [$content] Content to append to the popup's body\n * @cfg {jQuery} [$footer] Content to append to the popup's footer\n * @cfg {boolean} [autoClose=false] Automatically close the popup when it loses focus.\n * @cfg {jQuery} [$autoCloseIgnore] Elements that will not close the popup when clicked.\n *  This config option is only relevant if #autoClose is set to `true`. See the\n *  [OOUI documentation on MediaWiki][2] for an example.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Popups#autocloseExample\n * @cfg {boolean} [head=false] Show a popup header that contains a #label (if specified) and close\n *  button.\n * @cfg {boolean} [padded=false] Add padding to the popup's body\n */\nOO.ui.PopupWidget = function OoUiPopupWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.PopupWidget.parent.call( this, config );\n\n\t// Properties (must be set before ClippableElement constructor call)\n\tthis.$body = $( '<div>' );\n\tthis.$popup = $( '<div>' );\n\n\t// Mixin constructors\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.ClippableElement.call( this, $.extend( {\n\t\t$clippable: this.$body,\n\t\t$clippableContainer: this.$popup\n\t}, config ) );\n\tOO.ui.mixin.FloatableElement.call( this, config );\n\n\t// Properties\n\tthis.$anchor = $( '<div>' );\n\t// If undefined, will be computed lazily in computePosition()\n\tthis.$container = config.$container;\n\tthis.containerPadding = config.containerPadding !== undefined ? config.containerPadding : 10;\n\tthis.autoClose = !!config.autoClose;\n\tthis.transitionTimeout = null;\n\tthis.anchored = false;\n\tthis.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );\n\tthis.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );\n\n\t// Initialization\n\tthis.setSize( config.width, config.height );\n\tthis.toggleAnchor( config.anchor === undefined || config.anchor );\n\tthis.setAlignment( config.align || 'center' );\n\tthis.setPosition( config.position || 'below' );\n\tthis.setAutoFlip( config.autoFlip === undefined || config.autoFlip );\n\tthis.setAutoCloseIgnore( config.$autoCloseIgnore );\n\tthis.$body.addClass( 'oo-ui-popupWidget-body' );\n\tthis.$anchor.addClass( 'oo-ui-popupWidget-anchor' );\n\tthis.$popup\n\t\t.addClass( 'oo-ui-popupWidget-popup' )\n\t\t.append( this.$body );\n\tthis.$element\n\t\t.addClass( 'oo-ui-popupWidget' )\n\t\t.append( this.$popup, this.$anchor );\n\t// Move content, which was added to #$element by OO.ui.Widget, to the body\n\t// FIXME This is gross, we should use '$body' or something for the config\n\tif ( config.$content instanceof $ ) {\n\t\tthis.$body.append( config.$content );\n\t}\n\n\tif ( config.padded ) {\n\t\tthis.$body.addClass( 'oo-ui-popupWidget-body-padded' );\n\t}\n\n\tif ( config.head ) {\n\t\tthis.closeButton = new OO.ui.ButtonWidget( {\n\t\t\tframed: false,\n\t\t\ticon: 'close'\n\t\t} );\n\t\tthis.closeButton.connect( this, {\n\t\t\tclick: 'onCloseButtonClick'\n\t\t} );\n\t\tthis.$head = $( '<div>' )\n\t\t\t.addClass( 'oo-ui-popupWidget-head' )\n\t\t\t.append( this.$label, this.closeButton.$element );\n\t\tthis.$popup.prepend( this.$head );\n\t}\n\n\tif ( config.$footer ) {\n\t\tthis.$footer = $( '<div>' )\n\t\t\t.addClass( 'oo-ui-popupWidget-footer' )\n\t\t\t.append( config.$footer );\n\t\tthis.$popup.append( this.$footer );\n\t}\n\n\t// Initially hidden - using #toggle may cause errors if subclasses override toggle with methods\n\t// that reference properties not initialized at that time of parent class construction\n\t// TODO: Find a better way to handle post-constructor setup\n\tthis.visible = false;\n\tthis.$element.addClass( 'oo-ui-element-hidden' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement );\nOO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.FloatableElement );\n\n/* Events */\n\n/**\n * @event ready\n *\n * The popup is ready: it is visible and has been positioned and clipped.\n */\n\n/* Methods */\n\n/**\n * Handles document mouse down events.\n *\n * @private\n * @param {MouseEvent} e Mouse down event\n */\nOO.ui.PopupWidget.prototype.onDocumentMouseDown = function ( e ) {\n\tif (\n\t\tthis.isVisible() &&\n\t\t!OO.ui.contains( this.$element.add( this.$autoCloseIgnore ).get(), e.target, true )\n\t) {\n\t\tthis.toggle( false );\n\t}\n};\n\n/**\n * Bind document mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindDocumentMouseDownListener = function () {\n\t// Capture clicks outside popup\n\tthis.getElementDocument().addEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\t// We add 'click' event because iOS safari needs to respond to this event.\n\t// We can't use 'touchstart' (as is usually the equivalent to 'mousedown') because\n\t// then it will trigger when scrolling. While iOS Safari has some reported behavior\n\t// of occasionally not emitting 'click' properly, that event seems to be the standard\n\t// that it should be emitting, so we add it to this and will operate the event handler\n\t// on whichever of these events was triggered first\n\tthis.getElementDocument().addEventListener( 'click', this.onDocumentMouseDownHandler, true );\n};\n\n/**\n * Handles close button click events.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.onCloseButtonClick = function () {\n\tif ( this.isVisible() ) {\n\t\tthis.toggle( false );\n\t}\n};\n\n/**\n * Unbind document mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindDocumentMouseDownListener = function () {\n\tthis.getElementDocument().removeEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\tthis.getElementDocument().removeEventListener( 'click', this.onDocumentMouseDownHandler, true );\n};\n\n/**\n * Handles document key down events.\n *\n * @private\n * @param {KeyboardEvent} e Key down event\n */\nOO.ui.PopupWidget.prototype.onDocumentKeyDown = function ( e ) {\n\tif (\n\t\te.which === OO.ui.Keys.ESCAPE &&\n\t\tthis.isVisible()\n\t) {\n\t\tthis.toggle( false );\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t}\n};\n\n/**\n * Bind document key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n/**\n * Unbind document key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n/**\n * Show, hide, or toggle the visibility of the anchor.\n *\n * @param {boolean} [show] Show anchor, omit to toggle\n */\nOO.ui.PopupWidget.prototype.toggleAnchor = function ( show ) {\n\tshow = show === undefined ? !this.anchored : !!show;\n\n\tif ( this.anchored !== show ) {\n\t\tif ( show ) {\n\t\t\tthis.$element.addClass( 'oo-ui-popupWidget-anchored' );\n\t\t\tthis.$element.addClass( 'oo-ui-popupWidget-anchored-' + this.anchorEdge );\n\t\t} else {\n\t\t\tthis.$element.removeClass( 'oo-ui-popupWidget-anchored' );\n\t\t\tthis.$element.removeClass( 'oo-ui-popupWidget-anchored-' + this.anchorEdge );\n\t\t}\n\t\tthis.anchored = show;\n\t}\n};\n\n/**\n * Change which edge the anchor appears on.\n *\n * @param {string} edge 'top', 'bottom', 'start' or 'end'\n */\nOO.ui.PopupWidget.prototype.setAnchorEdge = function ( edge ) {\n\tif ( [ 'top', 'bottom', 'start', 'end' ].indexOf( edge ) === -1 ) {\n\t\tthrow new Error( 'Invalid value for edge: ' + edge );\n\t}\n\tif ( this.anchorEdge !== null ) {\n\t\tthis.$element.removeClass( 'oo-ui-popupWidget-anchored-' + this.anchorEdge );\n\t}\n\tthis.anchorEdge = edge;\n\tif ( this.anchored ) {\n\t\tthis.$element.addClass( 'oo-ui-popupWidget-anchored-' + edge );\n\t}\n};\n\n/**\n * Check if the anchor is visible.\n *\n * @return {boolean} Anchor is visible\n */\nOO.ui.PopupWidget.prototype.hasAnchor = function () {\n\treturn this.anchored;\n};\n\n/**\n * Toggle visibility of the popup. The popup is initially hidden and must be shown by calling\n * `.toggle( true )` after its #$element is attached to the DOM.\n *\n * Do not show the popup while it is not attached to the DOM. The calculations required to display\n * it in the right place and with the right dimensions only work correctly while it is attached.\n * Side-effects may include broken interface and exceptions being thrown. This wasn't always\n * strictly enforced, so currently it only generates a warning in the browser console.\n *\n * @fires ready\n * @inheritdoc\n */\nOO.ui.PopupWidget.prototype.toggle = function ( show ) {\n\tvar change, normalHeight, oppositeHeight, normalWidth, oppositeWidth;\n\tshow = show === undefined ? !this.isVisible() : !!show;\n\n\tchange = show !== this.isVisible();\n\n\tif ( show && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'PopupWidget#toggle: Before calling this method, the popup must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\tif ( show && !this.$floatableContainer && this.isElementAttached() ) {\n\t\t// Fall back to the parent node if the floatableContainer is not set\n\t\tthis.setFloatableContainer( this.$element.parent() );\n\t}\n\n\tif ( change && show && this.autoFlip ) {\n\t\t// Reset auto-flipping before showing the popup again. It's possible we no longer need to\n\t\t// flip (e.g. if the user scrolled).\n\t\tthis.isAutoFlipped = false;\n\t}\n\n\t// Parent method\n\tOO.ui.PopupWidget.parent.prototype.toggle.call( this, show );\n\n\tif ( change ) {\n\t\tthis.togglePositioning( show && !!this.$floatableContainer );\n\n\t\tif ( show ) {\n\t\t\tif ( this.autoClose ) {\n\t\t\t\tthis.bindDocumentMouseDownListener();\n\t\t\t\tthis.bindDocumentKeyDownListener();\n\t\t\t}\n\t\t\tthis.updateDimensions();\n\t\t\tthis.toggleClipping( true );\n\n\t\t\tif ( this.autoFlip ) {\n\t\t\t\tif ( this.popupPosition === 'above' || this.popupPosition === 'below' ) {\n\t\t\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t// If opening the popup in the normal direction causes it to be clipped,\n\t\t\t\t\t\t// open in the opposite one instead\n\t\t\t\t\t\tnormalHeight = this.$element.height();\n\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t\t// If that also causes it to be clipped, open in whichever direction\n\t\t\t\t\t\t\t// we have more space\n\t\t\t\t\t\t\toppositeHeight = this.$element.height();\n\t\t\t\t\t\t\tif ( oppositeHeight < normalHeight ) {\n\t\t\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( this.popupPosition === 'before' || this.popupPosition === 'after' ) {\n\t\t\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t// If opening the popup in the normal direction causes it to be clipped,\n\t\t\t\t\t\t// open in the opposite one instead\n\t\t\t\t\t\tnormalWidth = this.$element.width();\n\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\t// Due to T180173 horizontally clipped PopupWidgets have messed up\n\t\t\t\t\t\t// dimensions, which causes positioning to be off. Toggle clipping back and\n\t\t\t\t\t\t// forth to work around.\n\t\t\t\t\t\tthis.toggleClipping( false );\n\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\tthis.toggleClipping( true );\n\t\t\t\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t\t\t// If that also causes it to be clipped, open in whichever direction\n\t\t\t\t\t\t\t// we have more space\n\t\t\t\t\t\t\toppositeWidth = this.$element.width();\n\t\t\t\t\t\t\tif ( oppositeWidth < normalWidth ) {\n\t\t\t\t\t\t\t\tthis.isAutoFlipped = !this.isAutoFlipped;\n\t\t\t\t\t\t\t\t// Due to T180173, horizontally clipped PopupWidgets have messed up\n\t\t\t\t\t\t\t\t// dimensions, which causes positioning to be off. Toggle clipping\n\t\t\t\t\t\t\t\t// back and forth to work around.\n\t\t\t\t\t\t\t\tthis.toggleClipping( false );\n\t\t\t\t\t\t\t\tthis.position();\n\t\t\t\t\t\t\t\tthis.toggleClipping( true );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.emit( 'ready' );\n\t\t} else {\n\t\t\tthis.toggleClipping( false );\n\t\t\tif ( this.autoClose ) {\n\t\t\t\tthis.unbindDocumentMouseDownListener();\n\t\t\t\tthis.unbindDocumentKeyDownListener();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Set the size of the popup.\n *\n * Changing the size may also change the popup's position depending on the alignment.\n *\n * @param {number|null} [width=320] Width in pixels. Pass `null` to use automatic width.\n * @param {number|null} [height=null] Height in pixels. Pass `null` to use automatic height.\n * @param {boolean} [transition=false] Use a smooth transition\n * @chainable\n */\nOO.ui.PopupWidget.prototype.setSize = function ( width, height, transition ) {\n\tthis.width = width !== undefined ? width : 320;\n\tthis.height = height !== undefined ? height : null;\n\tif ( this.isVisible() ) {\n\t\tthis.updateDimensions( transition );\n\t}\n};\n\n/**\n * Update the size and position.\n *\n * Only use this to keep the popup properly anchored. Use #setSize to change the size, and this will\n * be called automatically.\n *\n * @param {boolean} [transition=false] Use a smooth transition\n * @chainable\n */\nOO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {\n\tvar widget = this;\n\n\t// Prevent transition from being interrupted\n\tclearTimeout( this.transitionTimeout );\n\tif ( transition ) {\n\t\t// Enable transition\n\t\tthis.$element.addClass( 'oo-ui-popupWidget-transitioning' );\n\t}\n\n\tthis.position();\n\n\tif ( transition ) {\n\t\t// Prevent transitioning after transition is complete\n\t\tthis.transitionTimeout = setTimeout( function () {\n\t\t\twidget.$element.removeClass( 'oo-ui-popupWidget-transitioning' );\n\t\t}, 200 );\n\t} else {\n\t\t// Prevent transitioning immediately\n\t\tthis.$element.removeClass( 'oo-ui-popupWidget-transitioning' );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupWidget.prototype.computePosition = function () {\n\tvar direction, align, vertical, start, end, near, far, sizeProp, popupSize, anchorSize,\n\t\tanchorPos, anchorOffset, anchorMargin, parentPosition, positionProp, positionAdjustment,\n\t\tfloatablePos, offsetParentPos, containerPos, popupPosition, viewportSpacing,\n\t\tpopupPos = {},\n\t\tanchorCss = { left: '', right: '', top: '', bottom: '' },\n\t\tpopupPositionOppositeMap = {\n\t\t\tabove: 'below',\n\t\t\tbelow: 'above',\n\t\t\tbefore: 'after',\n\t\t\tafter: 'before'\n\t\t},\n\t\talignMap = {\n\t\t\tltr: {\n\t\t\t\t'force-left': 'backwards',\n\t\t\t\t'force-right': 'forwards'\n\t\t\t},\n\t\t\trtl: {\n\t\t\t\t'force-left': 'forwards',\n\t\t\t\t'force-right': 'backwards'\n\t\t\t}\n\t\t},\n\t\tanchorEdgeMap = {\n\t\t\tabove: 'bottom',\n\t\t\tbelow: 'top',\n\t\t\tbefore: 'end',\n\t\t\tafter: 'start'\n\t\t},\n\t\thPosMap = {\n\t\t\tforwards: 'start',\n\t\t\tcenter: 'center',\n\t\t\tbackwards: this.anchored ? 'before' : 'end'\n\t\t},\n\t\tvPosMap = {\n\t\t\tforwards: 'top',\n\t\t\tcenter: 'center',\n\t\t\tbackwards: 'bottom'\n\t\t};\n\n\tif ( !this.$container ) {\n\t\t// Lazy-initialize $container if not specified in constructor\n\t\tthis.$container = $( this.getClosestScrollableElementContainer() );\n\t}\n\tdirection = this.$container.css( 'direction' );\n\n\t// Set height and width before we do anything else, since it might cause our measurements\n\t// to change (e.g. due to scrollbars appearing or disappearing), and it also affects centering\n\tthis.$popup.css( {\n\t\twidth: this.width !== null ? this.width : 'auto',\n\t\theight: this.height !== null ? this.height : 'auto'\n\t} );\n\n\talign = alignMap[ direction ][ this.align ] || this.align;\n\tpopupPosition = this.popupPosition;\n\tif ( this.isAutoFlipped ) {\n\t\tpopupPosition = popupPositionOppositeMap[ popupPosition ];\n\t}\n\n\t// If the popup is positioned before or after, then the anchor positioning is vertical,\n\t// otherwise horizontal\n\tvertical = popupPosition === 'before' || popupPosition === 'after';\n\tstart = vertical ? 'top' : ( direction === 'rtl' ? 'right' : 'left' );\n\tend = vertical ? 'bottom' : ( direction === 'rtl' ? 'left' : 'right' );\n\tnear = vertical ? 'top' : 'left';\n\tfar = vertical ? 'bottom' : 'right';\n\tsizeProp = vertical ? 'Height' : 'Width';\n\tpopupSize = vertical ?\n\t\t( this.height || this.$popup.height() ) :\n\t\t( this.width || this.$popup.width() );\n\n\tthis.setAnchorEdge( anchorEdgeMap[ popupPosition ] );\n\tthis.horizontalPosition = vertical ? popupPosition : hPosMap[ align ];\n\tthis.verticalPosition = vertical ? vPosMap[ align ] : popupPosition;\n\n\t// Parent method\n\tparentPosition = OO.ui.mixin.FloatableElement.prototype.computePosition.call( this );\n\t// Find out which property FloatableElement used for positioning, and adjust that value\n\tpositionProp = vertical ?\n\t\t( parentPosition.top !== '' ? 'top' : 'bottom' ) :\n\t\t( parentPosition.left !== '' ? 'left' : 'right' );\n\n\t// Figure out where the near and far edges of the popup and $floatableContainer are\n\tfloatablePos = this.$floatableContainer.offset();\n\tfloatablePos[ far ] = floatablePos[ near ] + this.$floatableContainer[ 'outer' + sizeProp ]();\n\t// Measure where the offsetParent is and compute our position based on that and parentPosition\n\toffsetParentPos = this.$element.offsetParent()[ 0 ] === document.documentElement ?\n\t\t{ top: 0, left: 0 } :\n\t\tthis.$element.offsetParent().offset();\n\n\tif ( positionProp === near ) {\n\t\tpopupPos[ near ] = offsetParentPos[ near ] + parentPosition[ near ];\n\t\tpopupPos[ far ] = popupPos[ near ] + popupSize;\n\t} else {\n\t\tpopupPos[ far ] = offsetParentPos[ near ] +\n\t\t\tthis.$element.offsetParent()[ 'inner' + sizeProp ]() - parentPosition[ far ];\n\t\tpopupPos[ near ] = popupPos[ far ] - popupSize;\n\t}\n\n\tif ( this.anchored ) {\n\t\t// Position the anchor (which is positioned relative to the popup) to point to\n\t\t// $floatableContainer\n\t\tanchorPos = ( floatablePos[ start ] + floatablePos[ end ] ) / 2;\n\t\tanchorOffset = ( start === far ? -1 : 1 ) * ( anchorPos - popupPos[ start ] );\n\n\t\t// If the anchor is less than 2*anchorSize from either edge, move the popup to make more\n\t\t// space this.$anchor.width()/height() returns 0 because of the CSS trickery we use, so use\n\t\t// scrollWidth/Height\n\t\tanchorSize = this.$anchor[ 0 ][ 'scroll' + sizeProp ];\n\t\tanchorMargin = parseFloat( this.$anchor.css( 'margin-' + start ) );\n\t\tif ( anchorOffset + anchorMargin < 2 * anchorSize ) {\n\t\t\t// Not enough space for the anchor on the start side; pull the popup startwards\n\t\t\tpositionAdjustment = ( positionProp === start ? -1 : 1 ) *\n\t\t\t\t( 2 * anchorSize - ( anchorOffset + anchorMargin ) );\n\t\t} else if ( anchorOffset + anchorMargin > popupSize - 2 * anchorSize ) {\n\t\t\t// Not enough space for the anchor on the end side; pull the popup endwards\n\t\t\tpositionAdjustment = ( positionProp === end ? -1 : 1 ) *\n\t\t\t\t( anchorOffset + anchorMargin - ( popupSize - 2 * anchorSize ) );\n\t\t} else {\n\t\t\tpositionAdjustment = 0;\n\t\t}\n\t} else {\n\t\tpositionAdjustment = 0;\n\t}\n\n\t// Check if the popup will go beyond the edge of this.$container\n\tcontainerPos = this.$container[ 0 ] === document.documentElement ?\n\t\t{ top: 0, left: 0 } :\n\t\tthis.$container.offset();\n\tcontainerPos[ far ] = containerPos[ near ] + this.$container[ 'inner' + sizeProp ]();\n\tif ( this.$container[ 0 ] === document.documentElement ) {\n\t\tviewportSpacing = OO.ui.getViewportSpacing();\n\t\tcontainerPos[ near ] += viewportSpacing[ near ];\n\t\tcontainerPos[ far ] -= viewportSpacing[ far ];\n\t}\n\t// Take into account how much the popup will move because of the adjustments we're going to make\n\tpopupPos[ near ] += ( positionProp === near ? 1 : -1 ) * positionAdjustment;\n\tpopupPos[ far ] += ( positionProp === near ? 1 : -1 ) * positionAdjustment;\n\tif ( containerPos[ near ] + this.containerPadding > popupPos[ near ] ) {\n\t\t// Popup goes beyond the near (left/top) edge, move it to the right/bottom\n\t\tpositionAdjustment += ( positionProp === near ? 1 : -1 ) *\n\t\t\t( containerPos[ near ] + this.containerPadding - popupPos[ near ] );\n\t} else if ( containerPos[ far ] - this.containerPadding < popupPos[ far ] ) {\n\t\t// Popup goes beyond the far (right/bottom) edge, move it to the left/top\n\t\tpositionAdjustment += ( positionProp === far ? 1 : -1 ) *\n\t\t\t( popupPos[ far ] - ( containerPos[ far ] - this.containerPadding ) );\n\t}\n\n\tif ( this.anchored ) {\n\t\t// Adjust anchorOffset for positionAdjustment\n\t\tanchorOffset += ( positionProp === start ? -1 : 1 ) * positionAdjustment;\n\n\t\t// Position the anchor\n\t\tanchorCss[ start ] = anchorOffset;\n\t\tthis.$anchor.css( anchorCss );\n\t}\n\n\t// Move the popup if needed\n\tparentPosition[ positionProp ] += positionAdjustment;\n\n\treturn parentPosition;\n};\n\n/**\n * Set popup alignment\n *\n * @param {string} [align=center] Alignment of the popup, `center`, `force-left`, `force-right`,\n *  `backwards` or `forwards`.\n */\nOO.ui.PopupWidget.prototype.setAlignment = function ( align ) {\n\t// Validate alignment\n\tif ( [ 'force-left', 'force-right', 'backwards', 'forwards', 'center' ].indexOf( align ) > -1 ) {\n\t\tthis.align = align;\n\t} else {\n\t\tthis.align = 'center';\n\t}\n\tthis.position();\n};\n\n/**\n * Get popup alignment\n *\n * @return {string} Alignment of the popup, `center`, `force-left`, `force-right`,\n *  `backwards` or `forwards`.\n */\nOO.ui.PopupWidget.prototype.getAlignment = function () {\n\treturn this.align;\n};\n\n/**\n * Change the positioning of the popup.\n *\n * @param {string} position 'above', 'below', 'before' or 'after'\n */\nOO.ui.PopupWidget.prototype.setPosition = function ( position ) {\n\tif ( [ 'above', 'below', 'before', 'after' ].indexOf( position ) === -1 ) {\n\t\tposition = 'below';\n\t}\n\tthis.popupPosition = position;\n\tthis.position();\n};\n\n/**\n * Get popup positioning.\n *\n * @return {string} 'above', 'below', 'before' or 'after'\n */\nOO.ui.PopupWidget.prototype.getPosition = function () {\n\treturn this.popupPosition;\n};\n\n/**\n * Set popup auto-flipping.\n *\n * @param {boolean} autoFlip Whether to automatically switch the popup's position between\n *  'above' and 'below', or between 'before' and 'after', if there is not enough space in the\n *  desired direction to display the popup without clipping\n */\nOO.ui.PopupWidget.prototype.setAutoFlip = function ( autoFlip ) {\n\tautoFlip = !!autoFlip;\n\n\tif ( this.autoFlip !== autoFlip ) {\n\t\tthis.autoFlip = autoFlip;\n\t}\n};\n\n/**\n * Set which elements will not close the popup when clicked.\n *\n * For auto-closing popups, clicks on these elements will not cause the popup to auto-close.\n *\n * @param {jQuery} $autoCloseIgnore Elements to ignore for auto-closing\n */\nOO.ui.PopupWidget.prototype.setAutoCloseIgnore = function ( $autoCloseIgnore ) {\n\tthis.$autoCloseIgnore = $autoCloseIgnore;\n};\n\n/**\n * Get an ID of the body element, this can be used as the\n * `aria-describedby` attribute for an input field.\n *\n * @return {string} The ID of the body element\n */\nOO.ui.PopupWidget.prototype.getBodyId = function () {\n\tvar id = this.$body.attr( 'id' );\n\tif ( id === undefined ) {\n\t\tid = OO.ui.generateElementId();\n\t\tthis.$body.attr( 'id', id );\n\t}\n\treturn id;\n};\n","/**\n * PopupElement is mixed into other classes to generate a {@link OO.ui.PopupWidget popup widget}.\n * A popup is a container for content. It is overlaid and positioned absolutely. By default, each\n * popup has an anchor, which is an arrow-like protrusion that points toward the popup’s origin.\n * See {@link OO.ui.PopupWidget PopupWidget} for an example.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object} [popup] Configuration to pass to popup\n * @cfg {boolean} [popup.autoClose=true] Popup auto-closes when it loses focus\n */\nOO.ui.mixin.PopupElement = function OoUiMixinPopupElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.popup = new OO.ui.PopupWidget( $.extend(\n\t\t{\n\t\t\tautoClose: true,\n\t\t\t$floatableContainer: this.$element\n\t\t},\n\t\tconfig.popup,\n\t\t{\n\t\t\t$autoCloseIgnore: this.$element.add( config.popup && config.popup.$autoCloseIgnore )\n\t\t}\n\t) );\n};\n\n/* Methods */\n\n/**\n * Get popup.\n *\n * @return {OO.ui.PopupWidget} Popup widget\n */\nOO.ui.mixin.PopupElement.prototype.getPopup = function () {\n\treturn this.popup;\n};\n","/**\n * PopupButtonWidgets toggle the visibility of a contained {@link OO.ui.PopupWidget PopupWidget},\n * which is used to display additional information or options.\n *\n *     @example\n *     // A PopupButtonWidget.\n *     var popupButton = new OO.ui.PopupButtonWidget( {\n *         label: 'Popup button with options',\n *         icon: 'menu',\n *         popup: {\n *             $content: $( '<p>Additional options here.</p>' ),\n *             padded: true,\n *             align: 'force-left'\n *         }\n *     } );\n *     // Append the button to the DOM.\n *     $( document.body ).append( popupButton.$element );\n *\n * @class\n * @extends OO.ui.ButtonWidget\n * @mixins OO.ui.mixin.PopupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$overlay] Render the popup into a separate layer. This configuration is useful\n *  in cases where the expanded popup is larger than its containing `<div>`. The specified overlay\n *  layer is usually on top of the containing `<div>` and has a larger area. By default, the popup\n *  uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.PopupButtonWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PopupElement.call( this, config );\n\n\t// Properties\n\tthis.$overlay = ( config.$overlay === true ?\n\t\tOO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\n\t// Events\n\tthis.connect( this, {\n\t\tclick: 'onAction'\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-popupButtonWidget' );\n\tthis.popup.$element\n\t\t.addClass( 'oo-ui-popupButtonWidget-popup' )\n\t\t.toggleClass( 'oo-ui-popupButtonWidget-framed-popup', this.isFramed() )\n\t\t.toggleClass( 'oo-ui-popupButtonWidget-frameless-popup', !this.isFramed() );\n\tthis.$overlay.append( this.popup.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupButtonWidget, OO.ui.ButtonWidget );\nOO.mixinClass( OO.ui.PopupButtonWidget, OO.ui.mixin.PopupElement );\n\n/* Methods */\n\n/**\n * Handle the button action being triggered.\n *\n * @private\n */\nOO.ui.PopupButtonWidget.prototype.onAction = function () {\n\tthis.popup.toggle();\n};\n","/**\n * Mixin for OO.ui.Widget subclasses to provide OO.ui.mixin.GroupElement.\n *\n * Use together with OO.ui.mixin.ItemWidget to make disabled state inheritable.\n *\n * @private\n * @abstract\n * @class\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.mixin.GroupWidget = function OoUiMixinGroupWidget( config ) {\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n};\n\n/* Setup */\n\nOO.mixinClass( OO.ui.mixin.GroupWidget, OO.ui.mixin.GroupElement );\n\n/* Methods */\n\n/**\n * Set the disabled state of the widget.\n *\n * This will also update the disabled state of child widgets.\n *\n * @param {boolean} disabled Disable widget\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.mixin.GroupWidget.prototype.setDisabled = function ( disabled ) {\n\tvar i, len;\n\n\t// Parent method\n\t// Note: Calling #setDisabled this way assumes this is mixed into an OO.ui.Widget\n\tOO.ui.Widget.prototype.setDisabled.call( this, disabled );\n\n\t// During construction, #setDisabled is called before the OO.ui.mixin.GroupElement constructor\n\tif ( this.items ) {\n\t\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\t\tthis.items[ i ].updateDisabled();\n\t\t}\n\t}\n\n\treturn this;\n};\n","/**\n * Mixin for widgets used as items in widgets that mix in OO.ui.mixin.GroupWidget.\n *\n * Item widgets have a reference to a OO.ui.mixin.GroupWidget while they are attached to the group.\n * This allows bidirectional communication.\n *\n * Use together with OO.ui.mixin.GroupWidget to make disabled state inheritable.\n *\n * @private\n * @abstract\n * @class\n *\n * @constructor\n */\nOO.ui.mixin.ItemWidget = function OoUiMixinItemWidget() {\n\t//\n};\n\n/* Methods */\n\n/**\n * Check if widget is disabled.\n *\n * Checks parent if present, making disabled state inheritable.\n *\n * @return {boolean} Widget is disabled\n */\nOO.ui.mixin.ItemWidget.prototype.isDisabled = function () {\n\treturn this.disabled ||\n\t\t( this.elementGroup instanceof OO.ui.Widget && this.elementGroup.isDisabled() );\n};\n\n/**\n * Set group element is in.\n *\n * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.mixin.ItemWidget.prototype.setElementGroup = function ( group ) {\n\t// Parent method\n\t// Note: Calling #setElementGroup this way assumes this is mixed into an OO.ui.Element\n\tOO.ui.Element.prototype.setElementGroup.call( this, group );\n\n\t// Initialize item disabled states\n\tthis.updateDisabled();\n\n\treturn this;\n};\n","/**\n * OptionWidgets are special elements that can be selected and configured with data. The\n * data is often unique for each option, but it does not have to be. OptionWidgets are used\n * with OO.ui.SelectWidget to create a selection of mutually exclusive options. For more information\n * and examples, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.AccessKeyedElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.OptionWidget = function OoUiOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.OptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ItemWidget.call( this );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.AccessKeyedElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.highlighted = false;\n\tthis.pressed = false;\n\tthis.setSelected( !!config.selected );\n\n\t// Initialization\n\tthis.$element\n\t\t.data( 'oo-ui-optionWidget', this )\n\t\t// Allow programmatic focussing (and by access key), but not tabbing\n\t\t.attr( 'tabindex', '-1' )\n\t\t.attr( 'role', 'option' )\n\t\t.addClass( 'oo-ui-optionWidget' )\n\t\t.append( this.$label );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OptionWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.AccessKeyedElement );\nOO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * Whether this option can be selected. See #setSelected.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.selectable = true;\n\n/**\n * Whether this option can be highlighted. See #setHighlighted.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.highlightable = true;\n\n/**\n * Whether this option can be pressed. See #setPressed.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.pressable = true;\n\n/**\n * Whether this option will be scrolled into view when it is selected.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.OptionWidget.static.scrollIntoViewOnSelect = false;\n\n/* Methods */\n\n/**\n * Check if the option can be selected.\n *\n * @return {boolean} Item is selectable\n */\nOO.ui.OptionWidget.prototype.isSelectable = function () {\n\treturn this.constructor.static.selectable && !this.disabled && this.isVisible();\n};\n\n/**\n * Check if the option can be highlighted. A highlight indicates that the option\n * may be selected when a user presses Enter key or clicks. Disabled items cannot\n * be highlighted.\n *\n * @return {boolean} Item is highlightable\n */\nOO.ui.OptionWidget.prototype.isHighlightable = function () {\n\treturn this.constructor.static.highlightable && !this.disabled && this.isVisible();\n};\n\n/**\n * Check if the option can be pressed. The pressed state occurs when a user mouses\n * down on an item, but has not yet let go of the mouse.\n *\n * @return {boolean} Item is pressable\n */\nOO.ui.OptionWidget.prototype.isPressable = function () {\n\treturn this.constructor.static.pressable && !this.disabled && this.isVisible();\n};\n\n/**\n * Check if the option is selected.\n *\n * @return {boolean} Item is selected\n */\nOO.ui.OptionWidget.prototype.isSelected = function () {\n\treturn this.selected;\n};\n\n/**\n * Check if the option is highlighted. A highlight indicates that the\n * item may be selected when a user presses Enter key or clicks.\n *\n * @return {boolean} Item is highlighted\n */\nOO.ui.OptionWidget.prototype.isHighlighted = function () {\n\treturn this.highlighted;\n};\n\n/**\n * Check if the option is pressed. The pressed state occurs when a user mouses\n * down on an item, but has not yet let go of the mouse. The item may appear\n * selected, but it will not be selected until the user releases the mouse.\n *\n * @return {boolean} Item is pressed\n */\nOO.ui.OptionWidget.prototype.isPressed = function () {\n\treturn this.pressed;\n};\n\n/**\n * Set the option’s selected state. In general, all modifications to the selection\n * should be handled by the SelectWidget’s\n * {@link OO.ui.SelectWidget#selectItem selectItem( [item] )} method instead of this method.\n *\n * @param {boolean} [state=false] Select option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OptionWidget.prototype.setSelected = function ( state ) {\n\tif ( this.constructor.static.selectable ) {\n\t\tthis.selected = !!state;\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-optionWidget-selected', state )\n\t\t\t.attr( 'aria-selected', state.toString() );\n\t\tif ( state && this.constructor.static.scrollIntoViewOnSelect ) {\n\t\t\tthis.scrollElementIntoView();\n\t\t}\n\t\tthis.updateThemeClasses();\n\t}\n\treturn this;\n};\n\n/**\n * Set the option’s highlighted state. In general, all programmatic\n * modifications to the highlight should be handled by the\n * SelectWidget’s {@link OO.ui.SelectWidget#highlightItem highlightItem( [item] )}\n * method instead of this method.\n *\n * @param {boolean} [state=false] Highlight option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OptionWidget.prototype.setHighlighted = function ( state ) {\n\tif ( this.constructor.static.highlightable ) {\n\t\tthis.highlighted = !!state;\n\t\tthis.$element.toggleClass( 'oo-ui-optionWidget-highlighted', state );\n\t\tthis.updateThemeClasses();\n\t}\n\treturn this;\n};\n\n/**\n * Set the option’s pressed state. In general, all\n * programmatic modifications to the pressed state should be handled by the\n * SelectWidget’s {@link OO.ui.SelectWidget#pressItem pressItem( [item] )}\n * method instead of this method.\n *\n * @param {boolean} [state=false] Press option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OptionWidget.prototype.setPressed = function ( state ) {\n\tif ( this.constructor.static.pressable ) {\n\t\tthis.pressed = !!state;\n\t\tthis.$element.toggleClass( 'oo-ui-optionWidget-pressed', state );\n\t\tthis.updateThemeClasses();\n\t}\n\treturn this;\n};\n\n/**\n * Get text to match search strings against.\n *\n * The default implementation returns the label text, but subclasses\n * can override this to provide more complex behavior.\n *\n * @return {string|boolean} String to match search string against\n */\nOO.ui.OptionWidget.prototype.getMatchText = function () {\n\tvar label = this.getLabel();\n\treturn typeof label === 'string' ? label : this.$label.text();\n};\n","/**\n * A SelectWidget is of a generic selection of options. The OOUI library contains several types of\n * select widgets, including {@link OO.ui.ButtonSelectWidget button selects},\n * {@link OO.ui.RadioSelectWidget radio selects}, and {@link OO.ui.MenuSelectWidget\n * menu selects}.\n *\n * This class should be used together with OO.ui.OptionWidget or OO.ui.DecoratedOptionWidget. For\n * more information, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // A select widget with three options.\n *     var select = new OO.ui.SelectWidget( {\n *         items: [\n *             new OO.ui.OptionWidget( {\n *                 data: 'a',\n *                 label: 'Option One',\n *             } ),\n *             new OO.ui.OptionWidget( {\n *                 data: 'b',\n *                 label: 'Option Two',\n *             } ),\n *             new OO.ui.OptionWidget( {\n *                 data: 'c',\n *                 label: 'Option Three',\n *             } )\n *         ]\n *     } );\n *     $( document.body ).append( select.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.OptionWidget[]} [items] An array of options to add to the select.\n *  Options are created with {@link OO.ui.OptionWidget OptionWidget} classes. See\n *  the [OOUI documentation on MediaWiki] [2] for examples.\n *  [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n * @cfg {boolean} [multiselect] Allow for multiple selections\n */\nOO.ui.SelectWidget = function OoUiSelectWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.SelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupWidget.call( this, $.extend( {\n\t\t$group: this.$element\n\t}, config ) );\n\n\t// Properties\n\tthis.pressed = false;\n\tthis.selecting = null;\n\tthis.multiselect = !!config.multiselect;\n\tthis.onDocumentMouseUpHandler = this.onDocumentMouseUp.bind( this );\n\tthis.onDocumentMouseMoveHandler = this.onDocumentMouseMove.bind( this );\n\tthis.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );\n\tthis.onDocumentKeyPressHandler = this.onDocumentKeyPress.bind( this );\n\tthis.keyPressBuffer = '';\n\tthis.keyPressBufferTimer = null;\n\tthis.blockMouseOverEvents = 0;\n\n\t// Events\n\tthis.connect( this, {\n\t\ttoggle: 'onToggle'\n\t} );\n\tthis.$element.on( {\n\t\tfocusin: this.onFocus.bind( this ),\n\t\tmousedown: this.onMouseDown.bind( this ),\n\t\tmouseover: this.onMouseOver.bind( this ),\n\t\tmouseleave: this.onMouseLeave.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t// -depressed is a deprecated alias of -unpressed\n\t\t.addClass( 'oo-ui-selectWidget oo-ui-selectWidget-unpressed oo-ui-selectWidget-depressed' )\n\t\t.attr( 'role', 'listbox' );\n\tthis.setFocusOwner( this.$element );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SelectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupWidget );\n\n/* Events */\n\n/**\n * @event highlight\n *\n * A `highlight` event is emitted when the highlight is changed with the #highlightItem method.\n *\n * @param {OO.ui.OptionWidget|null} item Highlighted item\n */\n\n/**\n * @event press\n *\n * A `press` event is emitted when the #pressItem method is used to programmatically modify the\n * pressed state of an option.\n *\n * @param {OO.ui.OptionWidget|null} item Pressed item\n */\n\n/**\n * @event select\n *\n * A `select` event is emitted when the selection is modified programmatically with the #selectItem\n * method.\n *\n * @param {OO.ui.OptionWidget[]|OO.ui.OptionWidget|null} items Currently selected items\n */\n\n/**\n * @event choose\n *\n * A `choose` event is emitted when an item is chosen with the #chooseItem method.\n *\n * @param {OO.ui.OptionWidget} item Chosen item\n * @param {boolean} selected Item is selected\n */\n\n/**\n * @event add\n *\n * An `add` event is emitted when options are added to the select with the #addItems method.\n *\n * @param {OO.ui.OptionWidget[]} items Added items\n * @param {number} index Index of insertion point\n */\n\n/**\n * @event remove\n *\n * A `remove` event is emitted when options are removed from the select with the #clearItems\n * or #removeItems methods.\n *\n * @param {OO.ui.OptionWidget[]} items Removed items\n */\n\n/* Static methods */\n\n/**\n * Normalize text for filter matching\n *\n * @param {string} text Text\n * @return {string} Normalized text\n */\nOO.ui.SelectWidget.static.normalizeForMatching = function ( text ) {\n\t// Replace trailing whitespace, normalize multiple spaces and make case insensitive\n\tvar normalized = text.trim().replace( /\\s+/, ' ' ).toLowerCase();\n\n\t// Normalize Unicode\n\t// eslint-disable-next-line no-restricted-properties\n\tif ( normalized.normalize ) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tnormalized = normalized.normalize();\n\t}\n\treturn normalized;\n};\n\n/* Methods */\n\n/**\n * Handle focus events\n *\n * @private\n * @param {jQuery.Event} event\n */\nOO.ui.SelectWidget.prototype.onFocus = function ( event ) {\n\tvar item;\n\tif ( event.target === this.$element[ 0 ] ) {\n\t\t// This widget was focussed, e.g. by the user tabbing to it.\n\t\t// The styles for focus state depend on one of the items being selected.\n\t\tif ( !this.findSelectedItem() ) {\n\t\t\titem = this.findFirstSelectableItem();\n\t\t}\n\t} else {\n\t\tif ( event.target.tabIndex === -1 ) {\n\t\t\t// One of the options got focussed (and the event bubbled up here).\n\t\t\t// They can't be tabbed to, but they can be activated using access keys.\n\t\t\t// OptionWidgets and focusable UI elements inside them have tabindex=\"-1\" set.\n\t\t\titem = this.findTargetItem( event );\n\t\t} else {\n\t\t\t// There is something actually user-focusable in one of the labels of the options, and\n\t\t\t// the user focussed it (e.g. by tabbing to it). Do nothing (especially, don't change\n\t\t\t// the focus).\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif ( item ) {\n\t\tif ( item.constructor.static.highlightable ) {\n\t\t\tthis.highlightItem( item );\n\t\t} else {\n\t\t\tthis.selectItem( item );\n\t\t}\n\t}\n\n\tif ( event.target !== this.$element[ 0 ] ) {\n\t\tthis.$focusOwner.trigger( 'focus' );\n\t}\n};\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onMouseDown = function ( e ) {\n\tvar item;\n\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.togglePressed( true );\n\t\titem = this.findTargetItem( e );\n\t\tif ( item && item.isSelectable() ) {\n\t\t\tthis.pressItem( item );\n\t\t\tthis.selecting = item;\n\t\t\tthis.getElementDocument().addEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'mousemove', this.onDocumentMouseMoveHandler, true );\n\t\t}\n\t}\n\treturn false;\n};\n\n/**\n * Handle document mouse up events.\n *\n * @private\n * @param {MouseEvent} e Mouse up event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onDocumentMouseUp = function ( e ) {\n\tvar item;\n\n\tthis.togglePressed( false );\n\tif ( !this.selecting ) {\n\t\titem = this.findTargetItem( e );\n\t\tif ( item && item.isSelectable() ) {\n\t\t\tthis.selecting = item;\n\t\t}\n\t}\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT && this.selecting ) {\n\t\tthis.pressItem( null );\n\t\tthis.chooseItem( this.selecting );\n\t\tthis.selecting = null;\n\t}\n\n\tthis.getElementDocument().removeEventListener( 'mouseup', this.onDocumentMouseUpHandler, true );\n\tthis.getElementDocument().removeEventListener( 'mousemove', this.onDocumentMouseMoveHandler, true );\n\n\treturn false;\n};\n\n/**\n * Handle document mouse move events.\n *\n * @private\n * @param {MouseEvent} e Mouse move event\n */\nOO.ui.SelectWidget.prototype.onDocumentMouseMove = function ( e ) {\n\tvar item;\n\n\tif ( !this.isDisabled() && this.pressed ) {\n\t\titem = this.findTargetItem( e );\n\t\tif ( item && item !== this.selecting && item.isSelectable() ) {\n\t\t\tthis.pressItem( item );\n\t\t\tthis.selecting = item;\n\t\t}\n\t}\n};\n\n/**\n * Handle mouse over events.\n *\n * @private\n * @param {jQuery.Event} e Mouse over event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onMouseOver = function ( e ) {\n\tvar item;\n\tif ( this.blockMouseOverEvents ) {\n\t\treturn;\n\t}\n\tif ( !this.isDisabled() ) {\n\t\titem = this.findTargetItem( e );\n\t\tthis.highlightItem( item && item.isHighlightable() ? item : null );\n\t}\n\treturn false;\n};\n\n/**\n * Handle mouse leave events.\n *\n * @private\n * @param {jQuery.Event} e Mouse over event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onMouseLeave = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.highlightItem( null );\n\t}\n\treturn false;\n};\n\n/**\n * Handle document key down events.\n *\n * @protected\n * @param {KeyboardEvent} e Key down event\n */\nOO.ui.SelectWidget.prototype.onDocumentKeyDown = function ( e ) {\n\tvar nextItem,\n\t\thandled = false,\n\t\tcurrentItem = this.findHighlightedItem(),\n\t\tfirstItem = this.getItems()[ 0 ];\n\n\tif ( !this.isDisabled() && this.isVisible() ) {\n\t\tswitch ( e.keyCode ) {\n\t\t\tcase OO.ui.Keys.ENTER:\n\t\t\t\tif ( currentItem ) {\n\t\t\t\t\t// Was only highlighted, now let's select it. No-op if already selected.\n\t\t\t\t\tthis.chooseItem( currentItem );\n\t\t\t\t\thandled = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.UP:\n\t\t\tcase OO.ui.Keys.LEFT:\n\t\t\t\tthis.clearKeyPressBuffer();\n\t\t\t\tnextItem = currentItem ? this.findRelativeSelectableItem( currentItem, -1 ) : firstItem;\n\t\t\t\thandled = true;\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.DOWN:\n\t\t\tcase OO.ui.Keys.RIGHT:\n\t\t\t\tthis.clearKeyPressBuffer();\n\t\t\t\tnextItem = currentItem ? this.findRelativeSelectableItem( currentItem, 1 ) : firstItem;\n\t\t\t\thandled = true;\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.ESCAPE:\n\t\t\tcase OO.ui.Keys.TAB:\n\t\t\t\tif ( currentItem ) {\n\t\t\t\t\tcurrentItem.setHighlighted( false );\n\t\t\t\t}\n\t\t\t\tthis.unbindDocumentKeyDownListener();\n\t\t\t\tthis.unbindDocumentKeyPressListener();\n\t\t\t\t// Don't prevent tabbing away / defocusing\n\t\t\t\thandled = false;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( nextItem ) {\n\t\t\tif ( nextItem.constructor.static.highlightable ) {\n\t\t\t\tthis.highlightItem( nextItem );\n\t\t\t} else {\n\t\t\t\tthis.chooseItem( nextItem );\n\t\t\t}\n\t\t\tthis.scrollItemIntoView( nextItem );\n\t\t}\n\n\t\tif ( handled ) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t}\n\t}\n};\n\n/**\n * Bind document key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n/**\n * Unbind document key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.unbindDocumentKeyDownListener = function () {\n\tthis.getElementDocument().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n/**\n * Scroll item into view, preventing spurious mouse highlight actions from happening.\n *\n * @param {OO.ui.OptionWidget} item Item to scroll into view\n */\nOO.ui.SelectWidget.prototype.scrollItemIntoView = function ( item ) {\n\tvar widget = this;\n\t// Chromium's Blink engine will generate spurious 'mouseover' events during programmatic\n\t// scrolling and around 100-150 ms after it is finished.\n\tthis.blockMouseOverEvents++;\n\titem.scrollElementIntoView().done( function () {\n\t\tsetTimeout( function () {\n\t\t\twidget.blockMouseOverEvents--;\n\t\t}, 200 );\n\t} );\n};\n\n/**\n * Clear the key-press buffer\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.clearKeyPressBuffer = function () {\n\tif ( this.keyPressBufferTimer ) {\n\t\tclearTimeout( this.keyPressBufferTimer );\n\t\tthis.keyPressBufferTimer = null;\n\t}\n\tthis.keyPressBuffer = '';\n};\n\n/**\n * Handle key press events.\n *\n * @protected\n * @param {KeyboardEvent} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectWidget.prototype.onDocumentKeyPress = function ( e ) {\n\tvar c, filter, item;\n\n\tif ( !e.charCode ) {\n\t\tif ( e.keyCode === OO.ui.Keys.BACKSPACE && this.keyPressBuffer !== '' ) {\n\t\t\tthis.keyPressBuffer = this.keyPressBuffer.substr( 0, this.keyPressBuffer.length - 1 );\n\t\t\treturn false;\n\t\t}\n\t\treturn;\n\t}\n\t// eslint-disable-next-line no-restricted-properties\n\tif ( String.fromCodePoint ) {\n\t\t// eslint-disable-next-line no-restricted-properties\n\t\tc = String.fromCodePoint( e.charCode );\n\t} else {\n\t\tc = String.fromCharCode( e.charCode );\n\t}\n\n\tif ( this.keyPressBufferTimer ) {\n\t\tclearTimeout( this.keyPressBufferTimer );\n\t}\n\tthis.keyPressBufferTimer = setTimeout( this.clearKeyPressBuffer.bind( this ), 1500 );\n\n\titem = this.findHighlightedItem() || this.findSelectedItem();\n\n\tif ( this.keyPressBuffer === c ) {\n\t\t// Common (if weird) special case: typing \"xxxx\" will cycle through all\n\t\t// the items beginning with \"x\".\n\t\tif ( item ) {\n\t\t\titem = this.findRelativeSelectableItem( item, 1 );\n\t\t}\n\t} else {\n\t\tthis.keyPressBuffer += c;\n\t}\n\n\tfilter = this.getItemMatcher( this.keyPressBuffer, false );\n\tif ( !item || !filter( item ) ) {\n\t\titem = this.findRelativeSelectableItem( item, 1, filter );\n\t}\n\tif ( item ) {\n\t\tif ( this.isVisible() && item.constructor.static.highlightable ) {\n\t\t\tthis.highlightItem( item );\n\t\t} else {\n\t\t\tthis.chooseItem( item );\n\t\t}\n\t\tthis.scrollItemIntoView( item );\n\t}\n\n\te.preventDefault();\n\te.stopPropagation();\n};\n\n/**\n * Get a matcher for the specific string\n *\n * @protected\n * @param {string} query String to match against items\n * @param {string} [mode='prefix'] Matching mode: 'substring', 'prefix', or 'exact'\n * @return {Function} function ( OO.ui.OptionWidget ) => boolean\n */\nOO.ui.SelectWidget.prototype.getItemMatcher = function ( query, mode ) {\n\tvar normalizeForMatching = this.constructor.static.normalizeForMatching,\n\t\tnormalizedQuery = normalizeForMatching( query );\n\n\t// Support deprecated exact=true argument\n\tif ( mode === true ) {\n\t\tmode = 'exact';\n\t}\n\n\treturn function ( item ) {\n\t\tvar matchText = normalizeForMatching( item.getMatchText() );\n\n\t\tif ( normalizedQuery === '' ) {\n\t\t\t// Empty string matches all, except if we are in 'exact'\n\t\t\t// mode, where it doesn't match at all\n\t\t\treturn mode !== 'exact';\n\t\t}\n\n\t\tswitch ( mode ) {\n\t\t\tcase 'exact':\n\t\t\t\treturn matchText === normalizedQuery;\n\t\t\tcase 'substring':\n\t\t\t\treturn matchText.indexOf( normalizedQuery ) !== -1;\n\t\t\t// 'prefix'\n\t\t\tdefault:\n\t\t\t\treturn matchText.indexOf( normalizedQuery ) === 0;\n\t\t}\n\t};\n};\n\n/**\n * Bind document key press listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindDocumentKeyPressListener = function () {\n\tthis.getElementDocument().addEventListener( 'keypress', this.onDocumentKeyPressHandler, true );\n};\n\n/**\n * Unbind document key down listener.\n *\n * If you override this, be sure to call this.clearKeyPressBuffer() from your\n * implementation.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.unbindDocumentKeyPressListener = function () {\n\tthis.getElementDocument().removeEventListener( 'keypress', this.onDocumentKeyPressHandler, true );\n\tthis.clearKeyPressBuffer();\n};\n\n/**\n * Visibility change handler\n *\n * @protected\n * @param {boolean} visible\n */\nOO.ui.SelectWidget.prototype.onToggle = function ( visible ) {\n\tif ( !visible ) {\n\t\tthis.clearKeyPressBuffer();\n\t}\n};\n\n/**\n * Get the closest item to a jQuery.Event.\n *\n * @private\n * @param {jQuery.Event} e\n * @return {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found\n */\nOO.ui.SelectWidget.prototype.findTargetItem = function ( e ) {\n\tvar $option = $( e.target ).closest( '.oo-ui-optionWidget' );\n\tif ( !$option.closest( '.oo-ui-selectWidget' ).is( this.$element ) ) {\n\t\treturn null;\n\t}\n\treturn $option.data( 'oo-ui-optionWidget' ) || null;\n};\n\n/**\n * Find all selected items, if there are any. If the widget allows for multiselect\n * it will return an array of selected options. If the widget doesn't allow for\n * multiselect, it will return the selected option or null if no item is selected.\n *\n * @return {OO.ui.OptionWidget[]|OO.ui.OptionWidget|null} If the widget is multiselect\n *  then return an array of selected items (or empty array),\n *  if the widget is not multiselect, return a single selected item, or `null`\n *  if no item is selected\n */\nOO.ui.SelectWidget.prototype.findSelectedItems = function () {\n\tvar selected = this.items.filter( function ( item ) {\n\t\treturn item.isSelected();\n\t} );\n\n\treturn this.multiselect ?\n\t\tselected :\n\t\tselected[ 0 ] || null;\n};\n\n/**\n * Find selected item.\n *\n * @return {OO.ui.OptionWidget[]|OO.ui.OptionWidget|null} If the widget is multiselect\n *  then return an array of selected items (or empty array),\n *  if the widget is not multiselect, return a single selected item, or `null`\n *  if no item is selected\n */\nOO.ui.SelectWidget.prototype.findSelectedItem = function () {\n\treturn this.findSelectedItems();\n};\n\n/**\n * Find highlighted item.\n *\n * @return {OO.ui.OptionWidget|null} Highlighted item, `null` if no item is highlighted\n */\nOO.ui.SelectWidget.prototype.findHighlightedItem = function () {\n\tvar i, len;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tif ( this.items[ i ].isHighlighted() ) {\n\t\t\treturn this.items[ i ];\n\t\t}\n\t}\n\treturn null;\n};\n\n/**\n * Toggle pressed state.\n *\n * Press is a state that occurs when a user mouses down on an item, but\n * has not yet let go of the mouse. The item may appear selected, but it will not be selected\n * until the user releases the mouse.\n *\n * @param {boolean} pressed An option is being pressed\n */\nOO.ui.SelectWidget.prototype.togglePressed = function ( pressed ) {\n\tif ( pressed === undefined ) {\n\t\tpressed = !this.pressed;\n\t}\n\tif ( pressed !== this.pressed ) {\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-selectWidget-pressed', pressed )\n\t\t\t// -depressed is a deprecated alias of -unpressed\n\t\t\t.toggleClass( 'oo-ui-selectWidget-unpressed oo-ui-selectWidget-depressed', !pressed );\n\t\tthis.pressed = pressed;\n\t}\n};\n\n/**\n * Highlight an option. If the `item` param is omitted, no options will be highlighted\n * and any existing highlight will be removed. The highlight is mutually exclusive.\n *\n * @param {OO.ui.OptionWidget} [item] Item to highlight, omit for no highlight\n * @fires highlight\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.highlightItem = function ( item ) {\n\tvar i, len, highlighted,\n\t\tchanged = false;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\thighlighted = this.items[ i ] === item;\n\t\tif ( this.items[ i ].isHighlighted() !== highlighted ) {\n\t\t\tthis.items[ i ].setHighlighted( highlighted );\n\t\t\tchanged = true;\n\t\t}\n\t}\n\tif ( changed ) {\n\t\tif ( item ) {\n\t\t\tthis.$focusOwner.attr( 'aria-activedescendant', item.getElementId() );\n\t\t} else {\n\t\t\tthis.$focusOwner.removeAttr( 'aria-activedescendant' );\n\t\t}\n\t\tthis.emit( 'highlight', item );\n\t}\n\n\treturn this;\n};\n\n/**\n * Fetch an item by its label.\n *\n * @param {string} label Label of the item to select.\n * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches\n * @return {OO.ui.Element|null} Item with equivalent label, `null` if none exists\n */\nOO.ui.SelectWidget.prototype.getItemFromLabel = function ( label, prefix ) {\n\tvar i, item, found,\n\t\tlen = this.items.length,\n\t\tfilter = this.getItemMatcher( label, 'exact' );\n\n\tfor ( i = 0; i < len; i++ ) {\n\t\titem = this.items[ i ];\n\t\tif ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {\n\t\t\treturn item;\n\t\t}\n\t}\n\n\tif ( prefix ) {\n\t\tfound = null;\n\t\tfilter = this.getItemMatcher( label, 'prefix' );\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\titem = this.items[ i ];\n\t\t\tif ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {\n\t\t\t\tif ( found ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tfound = item;\n\t\t\t}\n\t\t}\n\t\tif ( found ) {\n\t\t\treturn found;\n\t\t}\n\t}\n\n\treturn null;\n};\n\n/**\n * Programmatically select an option by its label. If the item does not exist,\n * all options will be deselected.\n *\n * @param {string} [label] Label of the item to select.\n * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches\n * @fires select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.selectItemByLabel = function ( label, prefix ) {\n\tvar itemFromLabel = this.getItemFromLabel( label, !!prefix );\n\tif ( label === undefined || !itemFromLabel ) {\n\t\treturn this.selectItem();\n\t}\n\treturn this.selectItem( itemFromLabel );\n};\n\n/**\n * Programmatically select an option by its data. If the `data` parameter is omitted,\n * or if the item does not exist, all options will be deselected.\n *\n * @param {Object|string} [data] Value of the item to select, omit to deselect all\n * @fires select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.selectItemByData = function ( data ) {\n\tvar itemFromData = this.findItemFromData( data );\n\tif ( data === undefined || !itemFromData ) {\n\t\treturn this.selectItem();\n\t}\n\treturn this.selectItem( itemFromData );\n};\n\n/**\n * Programmatically unselect an option by its reference. If the widget\n * allows for multiple selections, there may be other items still selected;\n * otherwise, no items will be selected.\n * If no item is given, all selected items will be unselected.\n *\n * @param {OO.ui.OptionWidget} [item] Item to unselect\n * @fires select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.unselectItem = function ( item ) {\n\tif ( item ) {\n\t\titem.setSelected( false );\n\t} else {\n\t\tthis.items.forEach( function ( item ) {\n\t\t\titem.setSelected( false );\n\t\t} );\n\t}\n\n\tthis.emit( 'select', this.findSelectedItems() );\n\treturn this;\n};\n\n/**\n * Programmatically select an option by its reference. If the `item` parameter is omitted,\n * all options will be deselected.\n *\n * @param {OO.ui.OptionWidget} [item] Item to select, omit to deselect all\n * @fires select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n*/\nOO.ui.SelectWidget.prototype.selectItem = function ( item ) {\n\tvar i, len, selected,\n\t\tchanged = false;\n\n\tif ( this.multiselect && item ) {\n\t\t// Select the item directly\n\t\titem.setSelected( true );\n\t} else {\n\t\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\t\tselected = this.items[ i ] === item;\n\t\t\tif ( this.items[ i ].isSelected() !== selected ) {\n\t\t\t\tthis.items[ i ].setSelected( selected );\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\t}\n\tif ( changed ) {\n\t\t// TODO: When should a non-highlightable element be selected?\n\t\tif ( item && !item.constructor.static.highlightable ) {\n\t\t\tif ( item ) {\n\t\t\t\tthis.$focusOwner.attr( 'aria-activedescendant', item.getElementId() );\n\t\t\t} else {\n\t\t\t\tthis.$focusOwner.removeAttr( 'aria-activedescendant' );\n\t\t\t}\n\t\t}\n\t\tthis.emit( 'select', this.findSelectedItems() );\n\t}\n\n\treturn this;\n};\n\n/**\n * Press an item.\n *\n * Press is a state that occurs when a user mouses down on an item, but has not\n * yet let go of the mouse. The item may appear selected, but it will not be selected until the user\n * releases the mouse.\n *\n * @param {OO.ui.OptionWidget} [item] Item to press, omit to depress all\n * @fires press\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.pressItem = function ( item ) {\n\tvar i, len, pressed,\n\t\tchanged = false;\n\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tpressed = this.items[ i ] === item;\n\t\tif ( this.items[ i ].isPressed() !== pressed ) {\n\t\t\tthis.items[ i ].setPressed( pressed );\n\t\t\tchanged = true;\n\t\t}\n\t}\n\tif ( changed ) {\n\t\tthis.emit( 'press', item );\n\t}\n\n\treturn this;\n};\n\n/**\n * Choose an item.\n *\n * Note that ‘choose’ should never be modified programmatically. A user can choose\n * an option with the keyboard or mouse and it becomes selected. To select an item programmatically,\n * use the #selectItem method.\n *\n * This method is identical to #selectItem, but may vary in subclasses that take additional action\n * when users choose an item with the keyboard or mouse.\n *\n * @param {OO.ui.OptionWidget} item Item to choose\n * @fires choose\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.chooseItem = function ( item ) {\n\tif ( item ) {\n\t\tif ( this.multiselect && item.isSelected() ) {\n\t\t\tthis.unselectItem( item );\n\t\t} else {\n\t\t\tthis.selectItem( item );\n\t\t}\n\n\t\tthis.emit( 'choose', item, item.isSelected() );\n\t}\n\n\treturn this;\n};\n\n/**\n * Find an option by its position relative to the specified item (or to the start of the option\n * array, if item is `null`). The direction in which to search through the option array is specified\n * with a number: -1 for reverse (the default) or 1 for forward. The method will return an option,\n * or `null` if there are no options in the array.\n *\n * @param {OO.ui.OptionWidget|null} item Item to describe the start position, or `null` to start at\n *  the beginning of the array.\n * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward\n * @param {Function} [filter] Only consider items for which this function returns\n *  true. Function takes an OO.ui.OptionWidget and returns a boolean.\n * @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the select\n */\nOO.ui.SelectWidget.prototype.findRelativeSelectableItem = function ( item, direction, filter ) {\n\tvar currentIndex, nextIndex, i,\n\t\tincrease = direction > 0 ? 1 : -1,\n\t\tlen = this.items.length;\n\n\tif ( item instanceof OO.ui.OptionWidget ) {\n\t\tcurrentIndex = this.items.indexOf( item );\n\t\tnextIndex = ( currentIndex + increase + len ) % len;\n\t} else {\n\t\t// If no item is selected and moving forward, start at the beginning.\n\t\t// If moving backward, start at the end.\n\t\tnextIndex = direction > 0 ? 0 : len - 1;\n\t}\n\n\tfor ( i = 0; i < len; i++ ) {\n\t\titem = this.items[ nextIndex ];\n\t\tif (\n\t\t\titem instanceof OO.ui.OptionWidget && item.isSelectable() &&\n\t\t\t( !filter || filter( item ) )\n\t\t) {\n\t\t\treturn item;\n\t\t}\n\t\tnextIndex = ( nextIndex + increase + len ) % len;\n\t}\n\treturn null;\n};\n\n/**\n * Find the next selectable item or `null` if there are no selectable items.\n * Disabled options and menu-section markers and breaks are not selectable.\n *\n * @return {OO.ui.OptionWidget|null} Item, `null` if there aren't any selectable items\n */\nOO.ui.SelectWidget.prototype.findFirstSelectableItem = function () {\n\treturn this.findRelativeSelectableItem( null, 1 );\n};\n\n/**\n * Add an array of options to the select. Optionally, an index number can be used to\n * specify an insertion point.\n *\n * @param {OO.ui.OptionWidget[]} items Items to add\n * @param {number} [index] Index to insert items after\n * @fires add\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.addItems = function ( items, index ) {\n\t// Mixin method\n\tOO.ui.mixin.GroupWidget.prototype.addItems.call( this, items, index );\n\n\t// Always provide an index, even if it was omitted\n\tthis.emit( 'add', items, index === undefined ? this.items.length - items.length - 1 : index );\n\n\treturn this;\n};\n\n/**\n * Remove the specified array of options from the select. Options will be detached\n * from the DOM, not removed, so they can be reused later. To remove all options from\n * the select, you may wish to use the #clearItems method instead.\n *\n * @param {OO.ui.OptionWidget[]} items Items to remove\n * @fires remove\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.removeItems = function ( items ) {\n\tvar i, len, item;\n\n\t// Deselect items being removed\n\tfor ( i = 0, len = items.length; i < len; i++ ) {\n\t\titem = items[ i ];\n\t\tif ( item.isSelected() ) {\n\t\t\tthis.selectItem( null );\n\t\t}\n\t}\n\n\t// Mixin method\n\tOO.ui.mixin.GroupWidget.prototype.removeItems.call( this, items );\n\n\tthis.emit( 'remove', items );\n\n\treturn this;\n};\n\n/**\n * Clear all options from the select. Options will be detached from the DOM, not removed,\n * so that they can be reused later. To remove a subset of options from the select, use\n * the #removeItems method.\n *\n * @fires remove\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectWidget.prototype.clearItems = function () {\n\tvar items = this.items.slice();\n\n\t// Mixin method\n\tOO.ui.mixin.GroupWidget.prototype.clearItems.call( this );\n\n\t// Clear selection\n\tthis.selectItem( null );\n\n\tthis.emit( 'remove', items );\n\n\treturn this;\n};\n\n/**\n * Set the DOM element which has focus while the user is interacting with this SelectWidget.\n *\n * This is used to set `aria-activedescendant` and `aria-expanded` on it.\n *\n * @protected\n * @param {jQuery} $focusOwner\n */\nOO.ui.SelectWidget.prototype.setFocusOwner = function ( $focusOwner ) {\n\tthis.$focusOwner = $focusOwner;\n};\n","/**\n * DecoratedOptionWidgets are {@link OO.ui.OptionWidget options} that can be configured\n * with an {@link OO.ui.mixin.IconElement icon} and/or\n * {@link OO.ui.mixin.IndicatorElement indicator}.\n * This class is used with OO.ui.SelectWidget to create a selection of mutually exclusive\n * options. For more information about options and selects, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Decorated options in a select widget.\n *     var select = new OO.ui.SelectWidget( {\n *         items: [\n *             new OO.ui.DecoratedOptionWidget( {\n *                 data: 'a',\n *                 label: 'Option with icon',\n *                 icon: 'help'\n *             } ),\n *             new OO.ui.DecoratedOptionWidget( {\n *                 data: 'b',\n *                 label: 'Option with indicator',\n *                 indicator: 'next'\n *             } )\n *         ]\n *     } );\n *     $( document.body ).append( select.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.OptionWidget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.DecoratedOptionWidget = function OoUiDecoratedOptionWidget( config ) {\n\t// Parent constructor\n\tOO.ui.DecoratedOptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-decoratedOptionWidget' )\n\t\t.prepend( this.$icon )\n\t\t.append( this.$indicator );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.DecoratedOptionWidget, OO.ui.OptionWidget );\nOO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IndicatorElement );\n","/**\n * MenuOptionWidget is an option widget that looks like a menu item. The class is used with\n * OO.ui.MenuSelectWidget to create a menu of mutually exclusive options. Please see\n * the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @extends OO.ui.DecoratedOptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.MenuOptionWidget = function OoUiMenuOptionWidget( config ) {\n\t// Parent constructor\n\tOO.ui.MenuOptionWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.checkIcon = new OO.ui.IconWidget( {\n\t\ticon: 'check',\n\t\tclasses: [ 'oo-ui-menuOptionWidget-checkIcon' ]\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.prepend( this.checkIcon.$element )\n\t\t.addClass( 'oo-ui-menuOptionWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuOptionWidget, OO.ui.DecoratedOptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuOptionWidget.static.scrollIntoViewOnSelect = true;\n","/**\n * MenuSectionOptionWidgets are used inside {@link OO.ui.MenuSelectWidget menu select widgets} to\n * group one or more related {@link OO.ui.MenuOptionWidget menu options}. MenuSectionOptionWidgets\n * cannot be highlighted or selected.\n *\n *     @example\n *     var dropdown = new OO.ui.DropdownWidget( {\n *         menu: {\n *             items: [\n *                 new OO.ui.MenuSectionOptionWidget( {\n *                     label: 'Dogs'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'corgi',\n *                     label: 'Welsh Corgi'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'poodle',\n *                     label: 'Standard Poodle'\n *                 } ),\n *                 new OO.ui.MenuSectionOptionWidget( {\n *                     label: 'Cats'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'lion',\n *                     label: 'Lion'\n *                 } )\n *             ]\n *         }\n *     } );\n *     $( document.body ).append( dropdown.$element );\n *\n * @class\n * @extends OO.ui.DecoratedOptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.MenuSectionOptionWidget = function OoUiMenuSectionOptionWidget( config ) {\n\t// Parent constructor\n\tOO.ui.MenuSectionOptionWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-menuSectionOptionWidget' )\n\t\t.removeAttr( 'role aria-selected' );\n\tthis.selected = false;\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuSectionOptionWidget, OO.ui.DecoratedOptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuSectionOptionWidget.static.selectable = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuSectionOptionWidget.static.highlightable = false;\n","/**\n * MenuSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains options and\n * is used together with OO.ui.MenuOptionWidget. It is designed be used as part of another widget.\n * See {@link OO.ui.DropdownWidget DropdownWidget},\n * {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget}, and\n * {@link OO.ui.mixin.LookupElement LookupElement} for examples of widgets that contain menus.\n * MenuSelectWidgets themselves are not instantiated directly, rather subclassed\n * and customized to be opened, closed, and displayed as needed.\n *\n * By default, menus are clipped to the visible viewport and are not visible when a user presses the\n * mouse outside the menu.\n *\n * Menus also have support for keyboard interaction:\n *\n * - Enter/Return key: choose and select a menu option\n * - Up-arrow key: highlight the previous menu option\n * - Down-arrow key: highlight the next menu option\n * - Escape key: hide the menu\n *\n * Unlike most widgets, MenuSelectWidget is initially hidden and must be shown by calling #toggle.\n *\n * Please see the [OOUI documentation on MediaWiki][1] for more information.\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.ClippableElement\n * @mixins OO.ui.mixin.FloatableElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.TextInputWidget} [input] Text input used to implement option highlighting for menu\n *  items that match the text the user types. This config is used by\n *  {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget} and\n *  {@link OO.ui.mixin.LookupElement LookupElement}\n * @cfg {jQuery} [$input] Text input used to implement option highlighting for menu items that match\n *  the text the user types. This config is used by\n *  {@link OO.ui.TagMultiselectWidget TagMultiselectWidget}\n * @cfg {OO.ui.Widget} [widget] Widget associated with the menu's active state. If the user clicks\n *  the mouse anywhere on the page outside of this widget, the menu is hidden. For example, if\n *  there is a button that toggles the menu's visibility on click, the menu will be hidden then\n *  re-shown when the user clicks that button, unless the button (or its parent widget) is passed\n *  in here.\n * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu.\n * @cfg {jQuery} [$autoCloseIgnore] If these elements are clicked, don't auto-hide the menu.\n * @cfg {boolean} [hideOnChoose=true] Hide the menu when the user chooses an option.\n * @cfg {boolean} [filterFromInput=false] Filter the displayed options from the input\n * @cfg {boolean} [highlightOnFilter] Highlight the first result when filtering\n * @cfg {string} [filterMode='prefix'] The mode by which the menu filters the results.\n *  Options are 'exact', 'prefix' or 'substring'. See `OO.ui.SelectWidget#getItemMatcher`\n * @param {number|string} [width] Width of the menu as a number of pixels or CSS string with unit\n *  suffix, used by {@link OO.ui.mixin.ClippableElement ClippableElement}\n */\nOO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MenuSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ClippableElement.call( this, $.extend( { $clippable: this.$group }, config ) );\n\tOO.ui.mixin.FloatableElement.call( this, config );\n\n\t// Initial vertical positions other than 'center' will result in\n\t// the menu being flipped if there is not enough space in the container.\n\t// Store the original position so we know what to reset to.\n\tthis.originalVerticalPosition = this.verticalPosition;\n\n\t// Properties\n\tthis.autoHide = config.autoHide === undefined || !!config.autoHide;\n\tthis.hideOnChoose = config.hideOnChoose === undefined || !!config.hideOnChoose;\n\tthis.filterFromInput = !!config.filterFromInput;\n\tthis.$input = config.$input ? config.$input : config.input ? config.input.$input : null;\n\tthis.$widget = config.widget ? config.widget.$element : null;\n\tthis.$autoCloseIgnore = config.$autoCloseIgnore || $( [] );\n\tthis.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );\n\tthis.onInputEditHandler = OO.ui.debounce( this.updateItemVisibility.bind( this ), 100 );\n\tthis.highlightOnFilter = !!config.highlightOnFilter;\n\tthis.lastHighlightedItem = null;\n\tthis.width = config.width;\n\tthis.filterMode = config.filterMode;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-menuSelectWidget' );\n\tif ( config.widget ) {\n\t\tthis.setFocusOwner( config.widget.$tabIndexed );\n\t}\n\n\t// Initially hidden - using #toggle may cause errors if subclasses override toggle with methods\n\t// that reference properties not initialized at that time of parent class construction\n\t// TODO: Find a better way to handle post-constructor setup\n\tthis.visible = false;\n\tthis.$element.addClass( 'oo-ui-element-hidden' );\n\tthis.$focusOwner.attr( 'aria-expanded', 'false' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.ClippableElement );\nOO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.FloatableElement );\n\n/* Events */\n\n/**\n * @event ready\n *\n * The menu is ready: it is visible and has been positioned and clipped.\n */\n\n/* Static properties */\n\n/**\n * Positions to flip to if there isn't room in the container for the\n * menu in a specific direction.\n *\n * @property {Object.<string,string>}\n */\nOO.ui.MenuSelectWidget.static.flippedPositions = {\n\tbelow: 'above',\n\tabove: 'below',\n\ttop: 'bottom',\n\tbottom: 'top'\n};\n\n/* Methods */\n\n/**\n * Handles document mouse down events.\n *\n * @protected\n * @param {MouseEvent} e Mouse down event\n */\nOO.ui.MenuSelectWidget.prototype.onDocumentMouseDown = function ( e ) {\n\tif (\n\t\tthis.isVisible() &&\n\t\t!OO.ui.contains(\n\t\t\tthis.$element.add( this.$widget ).add( this.$autoCloseIgnore ).get(),\n\t\t\te.target,\n\t\t\ttrue\n\t\t)\n\t) {\n\t\tthis.toggle( false );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.onDocumentKeyDown = function ( e ) {\n\tvar currentItem = this.findHighlightedItem() || this.findSelectedItem();\n\n\tif ( !this.isDisabled() && this.isVisible() ) {\n\t\tswitch ( e.keyCode ) {\n\t\t\tcase OO.ui.Keys.LEFT:\n\t\t\tcase OO.ui.Keys.RIGHT:\n\t\t\t\t// Do nothing if a text field is associated, arrow keys will be handled natively\n\t\t\t\tif ( !this.$input ) {\n\t\t\t\t\tOO.ui.MenuSelectWidget.parent.prototype.onDocumentKeyDown.call( this, e );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase OO.ui.Keys.ESCAPE:\n\t\t\tcase OO.ui.Keys.TAB:\n\t\t\t\tif ( currentItem && !this.multiselect ) {\n\t\t\t\t\tcurrentItem.setHighlighted( false );\n\t\t\t\t}\n\t\t\t\tthis.toggle( false );\n\t\t\t\t// Don't prevent tabbing away, prevent defocusing\n\t\t\t\tif ( e.keyCode === OO.ui.Keys.ESCAPE ) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tOO.ui.MenuSelectWidget.parent.prototype.onDocumentKeyDown.call( this, e );\n\t\t\t\treturn;\n\t\t}\n\t}\n};\n\n/**\n * Update menu item visibility and clipping after input changes (if filterFromInput is enabled)\n * or after items were added/removed (always).\n *\n * @protected\n */\nOO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {\n\tvar i, item, items, visible, section, sectionEmpty, filter, exactFilter,\n\t\tanyVisible = false,\n\t\tlen = this.items.length,\n\t\tshowAll = !this.isVisible(),\n\t\texactMatch = false;\n\n\tif ( this.$input && this.filterFromInput ) {\n\t\tfilter = showAll ? null : this.getItemMatcher( this.$input.val(), this.filterMode );\n\t\texactFilter = this.getItemMatcher( this.$input.val(), 'exact' );\n\t\t// Hide non-matching options, and also hide section headers if all options\n\t\t// in their section are hidden.\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\titem = this.items[ i ];\n\t\t\tif ( item instanceof OO.ui.MenuSectionOptionWidget ) {\n\t\t\t\tif ( section ) {\n\t\t\t\t\t// If the previous section was empty, hide its header\n\t\t\t\t\tsection.toggle( showAll || !sectionEmpty );\n\t\t\t\t}\n\t\t\t\tsection = item;\n\t\t\t\tsectionEmpty = true;\n\t\t\t} else if ( item instanceof OO.ui.OptionWidget ) {\n\t\t\t\tvisible = showAll || filter( item );\n\t\t\t\texactMatch = exactMatch || exactFilter( item );\n\t\t\t\tanyVisible = anyVisible || visible;\n\t\t\t\tsectionEmpty = sectionEmpty && !visible;\n\t\t\t\titem.toggle( visible );\n\t\t\t}\n\t\t}\n\t\t// Process the final section\n\t\tif ( section ) {\n\t\t\tsection.toggle( showAll || !sectionEmpty );\n\t\t}\n\n\t\tif ( !anyVisible ) {\n\t\t\tthis.highlightItem( null );\n\t\t}\n\n\t\tthis.$element.toggleClass( 'oo-ui-menuSelectWidget-invisible', !anyVisible );\n\n\t\tif (\n\t\t\tthis.highlightOnFilter &&\n\t\t\t!( this.lastHighlightedItem && this.lastHighlightedItem.isVisible() )\n\t\t) {\n\t\t\t// Highlight the first item on the list\n\t\t\titem = null;\n\t\t\titems = this.getItems();\n\t\t\tfor ( i = 0; i < items.length; i++ ) {\n\t\t\t\tif ( items[ i ].isVisible() ) {\n\t\t\t\t\titem = items[ i ];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.highlightItem( item );\n\t\t\tthis.lastHighlightedItem = item;\n\t\t}\n\n\t}\n\n\t// Reevaluate clipping\n\tthis.clip();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.bindDocumentKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.on( 'keydown', this.onDocumentKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.bindDocumentKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindDocumentKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.off( 'keydown', this.onDocumentKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.unbindDocumentKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.bindDocumentKeyPressListener = function () {\n\tif ( this.$input ) {\n\t\tif ( this.filterFromInput ) {\n\t\t\tthis.$input.on(\n\t\t\t\t'keydown mouseup cut paste change input select',\n\t\t\t\tthis.onInputEditHandler\n\t\t\t);\n\t\t\tthis.updateItemVisibility();\n\t\t}\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.bindDocumentKeyPressListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindDocumentKeyPressListener = function () {\n\tif ( this.$input ) {\n\t\tif ( this.filterFromInput ) {\n\t\t\tthis.$input.off(\n\t\t\t\t'keydown mouseup cut paste change input select',\n\t\t\t\tthis.onInputEditHandler\n\t\t\t);\n\t\t\tthis.updateItemVisibility();\n\t\t}\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.unbindDocumentKeyPressListener.call( this );\n\t}\n};\n\n/**\n * Choose an item.\n *\n * When a user chooses an item, the menu is closed, unless the hideOnChoose config option is\n * set to false.\n *\n * Note that ‘choose’ should never be modified programmatically. A user can choose an option with\n * the keyboard or mouse and it becomes selected. To select an item programmatically,\n * use the #selectItem method.\n *\n * @param {OO.ui.OptionWidget} item Item to choose\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MenuSelectWidget.prototype.chooseItem = function ( item ) {\n\tOO.ui.MenuSelectWidget.parent.prototype.chooseItem.call( this, item );\n\tif ( this.hideOnChoose ) {\n\t\tthis.toggle( false );\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.addItems = function ( items, index ) {\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.addItems.call( this, items, index );\n\n\tthis.updateItemVisibility();\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.removeItems = function ( items ) {\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.removeItems.call( this, items );\n\n\tthis.updateItemVisibility();\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.clearItems = function () {\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.clearItems.call( this );\n\n\tthis.updateItemVisibility();\n\n\treturn this;\n};\n\n/**\n * Toggle visibility of the menu. The menu is initially hidden and must be shown by calling\n * `.toggle( true )` after its #$element is attached to the DOM.\n *\n * Do not show the menu while it is not attached to the DOM. The calculations required to display\n * it in the right place and with the right dimensions only work correctly while it is attached.\n * Side-effects may include broken interface and exceptions being thrown. This wasn't always\n * strictly enforced, so currently it only generates a warning in the browser console.\n *\n * @fires ready\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {\n\tvar change, originalHeight, flippedHeight, selectedItem;\n\n\tvisible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;\n\tchange = visible !== this.isVisible();\n\n\tif ( visible && !this.warnedUnattached && !this.isElementAttached() ) {\n\t\tOO.ui.warnDeprecation( 'MenuSelectWidget#toggle: Before calling this method, the menu must be attached to the DOM.' );\n\t\tthis.warnedUnattached = true;\n\t}\n\n\tif ( change && visible ) {\n\t\t// Reset position before showing the popup again. It's possible we no longer need to flip\n\t\t// (e.g. if the user scrolled).\n\t\tthis.setVerticalPosition( this.originalVerticalPosition );\n\t}\n\n\t// Parent method\n\tOO.ui.MenuSelectWidget.parent.prototype.toggle.call( this, visible );\n\n\tif ( change ) {\n\t\tif ( visible ) {\n\n\t\t\tif ( this.width ) {\n\t\t\t\tthis.setIdealSize( this.width );\n\t\t\t} else if ( this.$floatableContainer ) {\n\t\t\t\tthis.$clippable.css( 'width', 'auto' );\n\t\t\t\tthis.setIdealSize(\n\t\t\t\t\tthis.$floatableContainer[ 0 ].offsetWidth > this.$clippable[ 0 ].offsetWidth ?\n\t\t\t\t\t\t// Dropdown is smaller than handle so expand to width\n\t\t\t\t\t\tthis.$floatableContainer[ 0 ].offsetWidth :\n\t\t\t\t\t\t// Dropdown is larger than handle so auto size\n\t\t\t\t\t\t'auto'\n\t\t\t\t);\n\t\t\t\tthis.$clippable.css( 'width', '' );\n\t\t\t}\n\n\t\t\tthis.togglePositioning( !!this.$floatableContainer );\n\t\t\tthis.toggleClipping( true );\n\n\t\t\tthis.bindDocumentKeyDownListener();\n\t\t\tthis.bindDocumentKeyPressListener();\n\n\t\t\tif (\n\t\t\t\t( this.isClippedVertically() || this.isFloatableOutOfView() ) &&\n\t\t\t\tthis.originalVerticalPosition !== 'center'\n\t\t\t) {\n\t\t\t\t// If opening the menu in one direction causes it to be clipped, flip it\n\t\t\t\toriginalHeight = this.$element.height();\n\t\t\t\tthis.setVerticalPosition(\n\t\t\t\t\tthis.constructor.static.flippedPositions[ this.originalVerticalPosition ]\n\t\t\t\t);\n\t\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t// If flipping also causes it to be clipped, open in whichever direction\n\t\t\t\t\t// we have more space\n\t\t\t\t\tflippedHeight = this.$element.height();\n\t\t\t\t\tif ( originalHeight > flippedHeight ) {\n\t\t\t\t\t\tthis.setVerticalPosition( this.originalVerticalPosition );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Note that we do not flip the menu's opening direction if the clipping changes\n\t\t\t// later (e.g. after the user scrolls), that seems like it would be annoying\n\n\t\t\tthis.$focusOwner.attr( 'aria-expanded', 'true' );\n\n\t\t\tselectedItem = this.findSelectedItem();\n\t\t\tif ( !this.multiselect && selectedItem ) {\n\t\t\t\t// TODO: Verify if this is even needed; This is already done on highlight changes\n\t\t\t\t// in SelectWidget#highlightItem, so we should just need to highlight the item we need to\n\t\t\t\t// highlight here and not bother with attr or checking selections.\n\t\t\t\tthis.$focusOwner.attr( 'aria-activedescendant', selectedItem.getElementId() );\n\t\t\t\tselectedItem.scrollElementIntoView( { duration: 0 } );\n\t\t\t}\n\n\t\t\t// Auto-hide\n\t\t\tif ( this.autoHide ) {\n\t\t\t\tthis.getElementDocument().addEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\t\t\t}\n\n\t\t\tthis.emit( 'ready' );\n\t\t} else {\n\t\t\tthis.$focusOwner.removeAttr( 'aria-activedescendant' );\n\t\t\tthis.unbindDocumentKeyDownListener();\n\t\t\tthis.unbindDocumentKeyPressListener();\n\t\t\tthis.$focusOwner.attr( 'aria-expanded', 'false' );\n\t\t\tthis.getElementDocument().removeEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );\n\t\t\tthis.togglePositioning( false );\n\t\t\tthis.toggleClipping( false );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Scroll to the top of the menu\n */\nOO.ui.MenuSelectWidget.prototype.scrollToTop = function () {\n\tthis.$element.scrollTop( 0 );\n};\n","/**\n * DropdownWidgets are not menus themselves, rather they contain a menu of options created with\n * OO.ui.MenuOptionWidget. The DropdownWidget takes care of opening and displaying the menu so that\n * users can interact with it.\n *\n * If you want to use this within an HTML form, such as a OO.ui.FormLayout, use\n * OO.ui.DropdownInputWidget instead.\n *\n *     @example\n *     // A DropdownWidget with a menu that contains three options.\n *     var dropDown = new OO.ui.DropdownWidget( {\n *         label: 'Dropdown menu: Select a menu option',\n *         menu: {\n *             items: [\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'a',\n *                     label: 'First'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'b',\n *                     label: 'Second'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'c',\n *                     label: 'Third'\n *                 } )\n *             ]\n *         }\n *     } );\n *\n *     $( document.body ).append( dropDown.$element );\n *\n *     dropDown.getMenu().selectItemByData( 'b' );\n *\n *     dropDown.getMenu().findSelectedItem().getData(); // Returns 'b'.\n *\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object} [menu] Configuration options to pass to\n *  {@link OO.ui.MenuSelectWidget menu select widget}.\n * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful\n *  in cases where the expanded menu is larger than its containing `<div>`. The specified overlay\n *  layer is usually on top of the containing `<div>` and has a larger area. By default, the menu\n *  uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { indicator: 'down' }, config );\n\n\t// Parent constructor\n\tOO.ui.DropdownWidget.parent.call( this, config );\n\n\t// Properties (must be set before TabIndexedElement constructor call)\n\tthis.$handle = $( '<button>' );\n\tthis.$overlay = ( config.$overlay === true ?\n\t\tOO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {\n\t\t$titled: this.$label\n\t}, config ) );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {\n\t\t$tabIndexed: this.$handle\n\t}, config ) );\n\n\t// Properties\n\tthis.menu = new OO.ui.MenuSelectWidget( $.extend( {\n\t\twidget: this,\n\t\t$floatableContainer: this.$element\n\t}, config.menu ) );\n\n\t// Events\n\tthis.$handle.on( {\n\t\tclick: this.onClick.bind( this ),\n\t\tkeydown: this.onKeyDown.bind( this ),\n\t\t// Hack? Handle type-to-search when menu is not expanded and not handling its own events.\n\t\tkeypress: this.menu.onDocumentKeyPressHandler,\n\t\tblur: this.menu.clearKeyPressBuffer.bind( this.menu )\n\t} );\n\tthis.menu.connect( this, {\n\t\tselect: 'onMenuSelect',\n\t\ttoggle: 'onMenuToggle'\n\t} );\n\n\t// Initialization\n\tthis.$handle\n\t\t.addClass( 'oo-ui-dropdownWidget-handle' )\n\t\t.attr( {\n\t\t\ttype: 'button',\n\t\t\t'aria-owns': this.menu.getElementId(),\n\t\t\t'aria-haspopup': 'listbox'\n\t\t} )\n\t\t.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element\n\t\t.addClass( 'oo-ui-dropdownWidget' )\n\t\t.append( this.$handle );\n\tthis.$overlay.append( this.menu.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.DropdownWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Get the menu.\n *\n * @return {OO.ui.MenuSelectWidget} Menu of widget\n */\nOO.ui.DropdownWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Handles menu select events.\n *\n * @private\n * @param {OO.ui.MenuOptionWidget} item Selected menu item\n */\nOO.ui.DropdownWidget.prototype.onMenuSelect = function ( item ) {\n\tvar selectedLabel;\n\n\tif ( !item ) {\n\t\tthis.setLabel( null );\n\t\treturn;\n\t}\n\n\tselectedLabel = item.getLabel();\n\n\t// If the label is a DOM element, clone it, because setLabel will append() it\n\tif ( selectedLabel instanceof $ ) {\n\t\tselectedLabel = selectedLabel.clone();\n\t}\n\n\tthis.setLabel( selectedLabel );\n};\n\n/**\n * Handle menu toggle events.\n *\n * @private\n * @param {boolean} isVisible Open state of the menu\n */\nOO.ui.DropdownWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tthis.$element.toggleClass( 'oo-ui-dropdownWidget-open', isVisible );\n};\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {jQuery.Event} e Mouse click event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.DropdownWidget.prototype.onClick = function ( e ) {\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.menu.toggle();\n\t}\n\treturn false;\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.DropdownWidget.prototype.onKeyDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\t(\n\t\t\te.which === OO.ui.Keys.ENTER ||\n\t\t\t(\n\t\t\t\te.which === OO.ui.Keys.SPACE &&\n\t\t\t\t// Avoid conflicts with type-to-search, see SelectWidget#onKeyPress.\n\t\t\t\t// Space only closes the menu is the user is not typing to search.\n\t\t\t\tthis.menu.keyPressBuffer === ''\n\t\t\t) ||\n\t\t\t(\n\t\t\t\t!this.menu.isVisible() &&\n\t\t\t\t(\n\t\t\t\t\te.which === OO.ui.Keys.UP ||\n\t\t\t\t\te.which === OO.ui.Keys.DOWN\n\t\t\t\t)\n\t\t\t)\n\t\t)\n\t) {\n\t\tthis.menu.toggle();\n\t\treturn false;\n\t}\n};\n","/**\n * RadioOptionWidget is an option widget that looks like a radio button.\n * The class is used with OO.ui.RadioSelectWidget to create a selection of radio options.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Button_selects_and_option\n *\n * @class\n * @extends OO.ui.OptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.RadioOptionWidget = function OoUiRadioOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.radio = new OO.ui.RadioInputWidget( { value: config.data, tabIndex: -1 } );\n\n\t// Parent constructor\n\tOO.ui.RadioOptionWidget.parent.call( this, config );\n\n\t// Initialization\n\t// Remove implicit role, we're handling it ourselves\n\tthis.radio.$input.attr( 'role', 'presentation' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioOptionWidget' )\n\t\t.attr( 'role', 'radio' )\n\t\t.attr( 'aria-checked', 'false' )\n\t\t.removeAttr( 'aria-selected' )\n\t\t.prepend( this.radio.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioOptionWidget, OO.ui.OptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.highlightable = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.scrollIntoViewOnSelect = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.pressable = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.static.tagName = 'label';\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.RadioOptionWidget.parent.prototype.setSelected.call( this, state );\n\n\tthis.radio.setSelected( state );\n\tthis.$element\n\t\t.attr( 'aria-checked', state.toString() )\n\t\t.removeAttr( 'aria-selected' );\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioOptionWidget.prototype.setDisabled = function ( disabled ) {\n\tOO.ui.RadioOptionWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tthis.radio.setDisabled( this.isDisabled() );\n\n\treturn this;\n};\n","/**\n * RadioSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains radio\n * options and is used together with OO.ui.RadioOptionWidget. The RadioSelectWidget provides\n * an interface for adding, removing and selecting options.\n * Please see the [OOUI documentation on MediaWiki][1] for more information.\n *\n * If you want to use this within an HTML form, such as a OO.ui.FormLayout, use\n * OO.ui.RadioSelectInputWidget instead.\n *\n *     @example\n *     // A RadioSelectWidget with RadioOptions.\n *     var option1 = new OO.ui.RadioOptionWidget( {\n *             data: 'a',\n *             label: 'Selected radio option'\n *         } ),\n *         option2 = new OO.ui.RadioOptionWidget( {\n *             data: 'b',\n *             label: 'Unselected radio option'\n *         } );\n *         radioSelect = new OO.ui.RadioSelectWidget( {\n *             items: [ option1, option2 ]\n *         } );\n *\n *     // Select 'option 1' using the RadioSelectWidget's selectItem() method.\n *     radioSelect.selectItem( option1 );\n *\n *     $( document.body ).append( radioSelect.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.RadioSelectWidget = function OoUiRadioSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.RadioSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioSelectWidget' )\n\t\t.attr( 'role', 'radiogroup' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.RadioSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * MultioptionWidgets are special elements that can be selected and configured with data. The\n * data is often unique for each option, but it does not have to be. MultioptionWidgets are used\n * with OO.ui.SelectWidget to create a selection of mutually exclusive options. For more information\n * and examples, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [selected=false] Whether the option is initially selected\n */\nOO.ui.MultioptionWidget = function OoUiMultioptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MultioptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ItemWidget.call( this );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.selected = null;\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-multioptionWidget' )\n\t\t.append( this.$label );\n\tthis.setSelected( config.selected );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MultioptionWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.MultioptionWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.MultioptionWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.MultioptionWidget, OO.ui.mixin.TitledElement );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the selected state of the option changes.\n *\n * @param {boolean} selected Whether the option is now selected\n */\n\n/* Methods */\n\n/**\n * Check if the option is selected.\n *\n * @return {boolean} Item is selected\n */\nOO.ui.MultioptionWidget.prototype.isSelected = function () {\n\treturn this.selected;\n};\n\n/**\n * Set the option’s selected state. In general, all modifications to the selection\n * should be handled by the SelectWidget’s\n * {@link OO.ui.SelectWidget#selectItem selectItem( [item] )} method instead of this method.\n *\n * @param {boolean} [state=false] Select option\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MultioptionWidget.prototype.setSelected = function ( state ) {\n\tstate = !!state;\n\tif ( this.selected !== state ) {\n\t\tthis.selected = state;\n\t\tthis.emit( 'change', state );\n\t\tthis.$element.toggleClass( 'oo-ui-multioptionWidget-selected', state );\n\t}\n\treturn this;\n};\n","/**\n * MultiselectWidget allows selecting multiple options from a list.\n *\n * For more information about menus and options, please see the [OOUI documentation\n * on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @abstract\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupWidget\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.MultioptionWidget[]} [items] An array of options to add to the multiselect.\n */\nOO.ui.MultiselectWidget = function OoUiMultiselectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.MultiselectWidget.parent.call( this, config );\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupWidget.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Events\n\tthis.aggregate( {\n\t\tchange: 'select'\n\t} );\n\t// This is mostly for compatibility with TagMultiselectWidget... normally, 'change' is emitted\n\t// by GroupElement only when items are added/removed\n\tthis.connect( this, {\n\t\tselect: [ 'emit', 'change' ]\n\t} );\n\n\t// Initialization\n\tif ( config.items ) {\n\t\tthis.addItems( config.items );\n\t}\n\tthis.$group.addClass( 'oo-ui-multiselectWidget-group' );\n\tthis.$element.addClass( 'oo-ui-multiselectWidget' )\n\t\t.append( this.$group );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MultiselectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.MultiselectWidget, OO.ui.mixin.GroupWidget );\nOO.mixinClass( OO.ui.MultiselectWidget, OO.ui.mixin.TitledElement );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the set of items changes, or an item is selected or deselected.\n */\n\n/**\n * @event select\n *\n * A select event is emitted when an item is selected or deselected.\n */\n\n/* Methods */\n\n/**\n * Find options that are selected.\n *\n * @return {OO.ui.MultioptionWidget[]} Selected options\n */\nOO.ui.MultiselectWidget.prototype.findSelectedItems = function () {\n\treturn this.items.filter( function ( item ) {\n\t\treturn item.isSelected();\n\t} );\n};\n\n/**\n * Find the data of options that are selected.\n *\n * @return {Object[]|string[]} Values of selected options\n */\nOO.ui.MultiselectWidget.prototype.findSelectedItemsData = function () {\n\treturn this.findSelectedItems().map( function ( item ) {\n\t\treturn item.data;\n\t} );\n};\n\n/**\n * Select options by reference. Options not mentioned in the `items` array will be deselected.\n *\n * @param {OO.ui.MultioptionWidget[]} items Items to select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MultiselectWidget.prototype.selectItems = function ( items ) {\n\tthis.items.forEach( function ( item ) {\n\t\tvar selected = items.indexOf( item ) !== -1;\n\t\titem.setSelected( selected );\n\t} );\n\treturn this;\n};\n\n/**\n * Select items by their data. Options not mentioned in the `datas` array will be deselected.\n *\n * @param {Object[]|string[]} datas Values of items to select\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.MultiselectWidget.prototype.selectItemsByData = function ( datas ) {\n\tvar items,\n\t\twidget = this;\n\titems = datas.map( function ( data ) {\n\t\treturn widget.findItemFromData( data );\n\t} );\n\tthis.selectItems( items );\n\treturn this;\n};\n","/**\n * CheckboxMultioptionWidget is an option widget that looks like a checkbox.\n * The class is used with OO.ui.CheckboxMultiselectWidget to create a selection of checkbox options.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Button_selects_and_option\n *\n * @class\n * @extends OO.ui.MultioptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.CheckboxMultioptionWidget = function OoUiCheckboxMultioptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.checkbox = new OO.ui.CheckboxInputWidget();\n\n\t// Parent constructor\n\tOO.ui.CheckboxMultioptionWidget.parent.call( this, config );\n\n\t// Events\n\tthis.checkbox.on( 'change', this.onCheckboxChange.bind( this ) );\n\tthis.$element.on( 'keydown', this.onKeyDown.bind( this ) );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-checkboxMultioptionWidget' )\n\t\t.prepend( this.checkbox.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxMultioptionWidget, OO.ui.MultioptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.CheckboxMultioptionWidget.static.tagName = 'label';\n\n/* Methods */\n\n/**\n * Handle checkbox selected state change.\n *\n * @private\n */\nOO.ui.CheckboxMultioptionWidget.prototype.onCheckboxChange = function () {\n\tthis.setSelected( this.checkbox.isSelected() );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultioptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.CheckboxMultioptionWidget.parent.prototype.setSelected.call( this, state );\n\tthis.checkbox.setSelected( state );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultioptionWidget.prototype.setDisabled = function ( disabled ) {\n\tOO.ui.CheckboxMultioptionWidget.parent.prototype.setDisabled.call( this, disabled );\n\tthis.checkbox.setDisabled( this.isDisabled() );\n\treturn this;\n};\n\n/**\n * Focus the widget.\n */\nOO.ui.CheckboxMultioptionWidget.prototype.focus = function () {\n\tthis.checkbox.focus();\n};\n\n/**\n * Handle key down events.\n *\n * @protected\n * @param {jQuery.Event} e\n */\nOO.ui.CheckboxMultioptionWidget.prototype.onKeyDown = function ( e ) {\n\tvar\n\t\telement = this.getElementGroup(),\n\t\tnextItem;\n\n\tif ( e.keyCode === OO.ui.Keys.LEFT || e.keyCode === OO.ui.Keys.UP ) {\n\t\tnextItem = element.getRelativeFocusableItem( this, -1 );\n\t} else if ( e.keyCode === OO.ui.Keys.RIGHT || e.keyCode === OO.ui.Keys.DOWN ) {\n\t\tnextItem = element.getRelativeFocusableItem( this, 1 );\n\t}\n\n\tif ( nextItem ) {\n\t\te.preventDefault();\n\t\tnextItem.focus();\n\t}\n};\n","/**\n * CheckboxMultiselectWidget is a {@link OO.ui.MultiselectWidget multiselect widget} that contains\n * checkboxes and is used together with OO.ui.CheckboxMultioptionWidget. The\n * CheckboxMultiselectWidget provides an interface for adding, removing and selecting options.\n * Please see the [OOUI documentation on MediaWiki][1] for more information.\n *\n * If you want to use this within an HTML form, such as a OO.ui.FormLayout, use\n * OO.ui.CheckboxMultiselectInputWidget instead.\n *\n *     @example\n *     // A CheckboxMultiselectWidget with CheckboxMultioptions.\n *     var option1 = new OO.ui.CheckboxMultioptionWidget( {\n *             data: 'a',\n *             selected: true,\n *             label: 'Selected checkbox'\n *         } ),\n *         option2 = new OO.ui.CheckboxMultioptionWidget( {\n *             data: 'b',\n *             label: 'Unselected checkbox'\n *         } ),\n *         multiselect = new OO.ui.CheckboxMultiselectWidget( {\n *             items: [ option1, option2 ]\n *         } );\n *     $( document.body ).append( multiselect.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.MultiselectWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.CheckboxMultiselectWidget = function OoUiCheckboxMultiselectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.CheckboxMultiselectWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.$lastClicked = null;\n\n\t// Events\n\tthis.$group.on( 'click', this.onClick.bind( this ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-checkboxMultiselectWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxMultiselectWidget, OO.ui.MultiselectWidget );\n\n/* Methods */\n\n/**\n * Get an option by its position relative to the specified item (or to the start of the\n * option array, if item is `null`). The direction in which to search through the option array\n * is specified with a number: -1 for reverse (the default) or 1 for forward. The method will\n * return an option, or `null` if there are no options in the array.\n *\n * @param {OO.ui.CheckboxMultioptionWidget|null} item Item to describe the start position, or\n *  `null` to start at the beginning of the array.\n * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward\n * @return {OO.ui.CheckboxMultioptionWidget|null} Item at position, `null` if there are no items\n *  in the select.\n */\nOO.ui.CheckboxMultiselectWidget.prototype.getRelativeFocusableItem = function ( item, direction ) {\n\tvar currentIndex, nextIndex, i,\n\t\tincrease = direction > 0 ? 1 : -1,\n\t\tlen = this.items.length;\n\n\tif ( item ) {\n\t\tcurrentIndex = this.items.indexOf( item );\n\t\tnextIndex = ( currentIndex + increase + len ) % len;\n\t} else {\n\t\t// If no item is selected and moving forward, start at the beginning.\n\t\t// If moving backward, start at the end.\n\t\tnextIndex = direction > 0 ? 0 : len - 1;\n\t}\n\n\tfor ( i = 0; i < len; i++ ) {\n\t\titem = this.items[ nextIndex ];\n\t\tif ( item && !item.isDisabled() ) {\n\t\t\treturn item;\n\t\t}\n\t\tnextIndex = ( nextIndex + increase + len ) % len;\n\t}\n\treturn null;\n};\n\n/**\n * Handle click events on checkboxes.\n *\n * @param {jQuery.Event} e\n */\nOO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) {\n\tvar $options, lastClickedIndex, nowClickedIndex, i, direction, wasSelected, items,\n\t\t$lastClicked = this.$lastClicked,\n\t\t$nowClicked = $( e.target ).closest( '.oo-ui-checkboxMultioptionWidget' )\n\t\t\t.not( '.oo-ui-widget-disabled' );\n\n\t// Allow selecting multiple options at once by Shift-clicking them\n\tif ( $lastClicked && $nowClicked.length && e.shiftKey ) {\n\t\t$options = this.$group.find( '.oo-ui-checkboxMultioptionWidget' );\n\t\tlastClickedIndex = $options.index( $lastClicked );\n\t\tnowClickedIndex = $options.index( $nowClicked );\n\t\t// If it's the same item, either the user is being silly, or it's a fake event generated\n\t\t// by the browser. In either case we don't need custom handling.\n\t\tif ( nowClickedIndex !== lastClickedIndex ) {\n\t\t\titems = this.items;\n\t\t\twasSelected = items[ nowClickedIndex ].isSelected();\n\t\t\tdirection = nowClickedIndex > lastClickedIndex ? 1 : -1;\n\n\t\t\t// This depends on the DOM order of the items and the order of the .items array being\n\t\t\t// the same.\n\t\t\tfor ( i = lastClickedIndex; i !== nowClickedIndex; i += direction ) {\n\t\t\t\tif ( !items[ i ].isDisabled() ) {\n\t\t\t\t\titems[ i ].setSelected( !wasSelected );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// For the now-clicked element, use immediate timeout to allow the browser to do its own\n\t\t\t// handling first, then set our value. The order in which events happen is different for\n\t\t\t// clicks on the <input> and on the <label> and there are additional fake clicks fired\n\t\t\t// for non-click actions that change the checkboxes.\n\t\t\te.preventDefault();\n\t\t\tsetTimeout( function () {\n\t\t\t\tif ( !items[ nowClickedIndex ].isDisabled() ) {\n\t\t\t\t\titems[ nowClickedIndex ].setSelected( !wasSelected );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\tif ( $nowClicked.length ) {\n\t\tthis.$lastClicked = $nowClicked;\n\t}\n};\n\n/**\n * Focus the widget\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.CheckboxMultiselectWidget.prototype.focus = function () {\n\tvar item;\n\tif ( !this.isDisabled() ) {\n\t\titem = this.getRelativeFocusableItem( null, 1 );\n\t\tif ( item ) {\n\t\t\titem.focus();\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectWidget.prototype.simulateLabelClick = function () {\n\tthis.focus();\n};\n","/**\n * Progress bars visually display the status of an operation, such as a download,\n * and can be either determinate or indeterminate:\n *\n * - **determinate** process bars show the percent of an operation that is complete.\n *\n * - **indeterminate** process bars use a visual display of motion to indicate that an operation\n *   is taking place. Because the extent of an indeterminate operation is unknown, the bar does\n *   not use percentages.\n *\n * The value of the `progress` configuration determines whether the bar is determinate\n * or indeterminate.\n *\n *     @example\n *     // Examples of determinate and indeterminate progress bars.\n *     var progressBar1 = new OO.ui.ProgressBarWidget( {\n *         progress: 33\n *     } );\n *     var progressBar2 = new OO.ui.ProgressBarWidget();\n *\n *     // Create a FieldsetLayout to layout progress bars.\n *     var fieldset = new OO.ui.FieldsetLayout;\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( progressBar1, {\n *             label: 'Determinate',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( progressBar2, {\n *             label: 'Indeterminate',\n *             align: 'top'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * @class\n * @extends OO.ui.Widget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number|boolean} [progress=false] The type of progress bar (determinate or indeterminate).\n *  To create a determinate progress bar, specify a number that reflects the initial\n *  percent complete.\n *  By default, the progress bar is indeterminate.\n */\nOO.ui.ProgressBarWidget = function OoUiProgressBarWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ProgressBarWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.$bar = $( '<div>' );\n\tthis.progress = null;\n\n\t// Initialization\n\tthis.setProgress( config.progress !== undefined ? config.progress : false );\n\tthis.$bar.addClass( 'oo-ui-progressBarWidget-bar' );\n\tthis.$element\n\t\t.attr( {\n\t\t\trole: 'progressbar',\n\t\t\t'aria-valuemin': 0,\n\t\t\t'aria-valuemax': 100\n\t\t} )\n\t\t.addClass( 'oo-ui-progressBarWidget' )\n\t\t.append( this.$bar );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ProgressBarWidget, OO.ui.Widget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ProgressBarWidget.static.tagName = 'div';\n\n/* Methods */\n\n/**\n * Get the percent of the progress that has been completed. Indeterminate progresses will\n * return `false`.\n *\n * @return {number|boolean} Progress percent\n */\nOO.ui.ProgressBarWidget.prototype.getProgress = function () {\n\treturn this.progress;\n};\n\n/**\n * Set the percent of the process completed or `false` for an indeterminate process.\n *\n * @param {number|boolean} progress Progress percent or `false` for indeterminate\n */\nOO.ui.ProgressBarWidget.prototype.setProgress = function ( progress ) {\n\tthis.progress = progress;\n\n\tif ( progress !== false ) {\n\t\tthis.$bar.css( 'width', this.progress + '%' );\n\t\tthis.$element.attr( 'aria-valuenow', this.progress );\n\t} else {\n\t\tthis.$bar.css( 'width', '' );\n\t\tthis.$element.removeAttr( 'aria-valuenow' );\n\t}\n\tthis.$element.toggleClass( 'oo-ui-progressBarWidget-indeterminate', progress === false );\n};\n","/**\n * InputWidget is the base class for all input widgets, which\n * include {@link OO.ui.TextInputWidget text inputs}, {@link OO.ui.CheckboxInputWidget checkbox\n * inputs}, {@link OO.ui.RadioInputWidget radio inputs}, and\n * {@link OO.ui.ButtonInputWidget button inputs}.\n * See the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.AccessKeyedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [name=''] The value of the input’s HTML `name` attribute.\n * @cfg {string} [value=''] The value of the input.\n * @cfg {string} [dir] The directionality of the input (ltr/rtl).\n * @cfg {string} [inputId] The value of the input’s HTML `id` attribute.\n * @cfg {Function} [inputFilter] The name of an input filter function. Input filters modify the\n *  value of an input before it is accepted.\n */\nOO.ui.InputWidget = function OoUiInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.InputWidget.parent.call( this, config );\n\n\t// Properties\n\t// See #reusePreInfuseDOM about config.$input\n\tthis.$input = config.$input || this.getInputElement( config );\n\tthis.value = '';\n\tthis.inputFilter = config.inputFilter;\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {\n\t\t$tabIndexed: this.$input\n\t}, config ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( {\n\t\t$titled: this.$input\n\t}, config ) );\n\tOO.ui.mixin.AccessKeyedElement.call( this, $.extend( {\n\t\t$accessKeyed: this.$input\n\t}, config ) );\n\n\t// Events\n\tthis.$input.on( 'keydown mouseup cut paste change input select', this.onEdit.bind( this ) );\n\n\t// Initialization\n\tthis.$input\n\t\t.addClass( 'oo-ui-inputWidget-input' )\n\t\t.attr( 'name', config.name )\n\t\t.prop( 'disabled', this.isDisabled() );\n\tthis.$element\n\t\t.addClass( 'oo-ui-inputWidget' )\n\t\t.append( this.$input );\n\tthis.setValue( config.value );\n\tif ( config.dir ) {\n\t\tthis.setDir( config.dir );\n\t}\n\tif ( config.inputId !== undefined ) {\n\t\tthis.setInputId( config.inputId );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.AccessKeyedElement );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.static.reusePreInfuseDOM = function ( node, config ) {\n\tconfig = OO.ui.InputWidget.parent.static.reusePreInfuseDOM( node, config );\n\t// Reusing `$input` lets browsers preserve inputted values across page reloads, see T114134.\n\tconfig.$input = $( node ).find( '.oo-ui-inputWidget-input' );\n\treturn config;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.InputWidget.parent.static.gatherPreInfuseState( node, config );\n\tif ( config.$input && config.$input.length ) {\n\t\tstate.value = config.$input.val();\n\t\t// Might be better in TabIndexedElement, but it's awkward to do there because\n\t\t// mixins are awkward\n\t\tstate.focus = config.$input.is( ':focus' );\n\t}\n\treturn state;\n};\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the value of the input changes.\n *\n * @param {string} value\n */\n\n/* Methods */\n\n/**\n * Get input element.\n *\n * Subclasses of OO.ui.InputWidget use the `config` parameter to produce different elements in\n * different circumstances. The element must have a `value` property (like form elements).\n *\n * @protected\n * @param {Object} config Configuration options\n * @return {jQuery} Input element\n */\nOO.ui.InputWidget.prototype.getInputElement = function () {\n\treturn $( '<input>' );\n};\n\n/**\n * Handle potentially value-changing events.\n *\n * @private\n * @param {jQuery.Event} e Key down, mouse up, cut, paste, change, input, or select event\n */\nOO.ui.InputWidget.prototype.onEdit = function () {\n\tvar widget = this;\n\tif ( !this.isDisabled() ) {\n\t\t// Allow the stack to clear so the value will be updated\n\t\tsetTimeout( function () {\n\t\t\twidget.setValue( widget.$input.val() );\n\t\t} );\n\t}\n};\n\n/**\n * Get the value of the input.\n *\n * @return {string} Input value\n */\nOO.ui.InputWidget.prototype.getValue = function () {\n\t// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify\n\t// it, and we won't know unless they're kind enough to trigger a 'change' event.\n\tvar value = this.$input.val();\n\tif ( this.value !== value ) {\n\t\tthis.setValue( value );\n\t}\n\treturn this.value;\n};\n\n/**\n * Set the directionality of the input.\n *\n * @param {string} dir Text directionality: 'ltr', 'rtl' or 'auto'\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.InputWidget.prototype.setDir = function ( dir ) {\n\tthis.$input.prop( 'dir', dir );\n\treturn this;\n};\n\n/**\n * Set the value of the input.\n *\n * @param {string} value New value\n * @fires change\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.InputWidget.prototype.setValue = function ( value ) {\n\tvalue = this.cleanUpValue( value );\n\t// Update the DOM if it has changed. Note that with cleanUpValue, it\n\t// is possible for the DOM value to change without this.value changing.\n\tif ( this.$input.val() !== value ) {\n\t\tthis.$input.val( value );\n\t}\n\tif ( this.value !== value ) {\n\t\tthis.value = value;\n\t\tthis.emit( 'change', this.value );\n\t}\n\t// The first time that the value is set (probably while constructing the widget),\n\t// remember it in defaultValue. This property can be later used to check whether\n\t// the value of the input has been changed since it was created.\n\tif ( this.defaultValue === undefined ) {\n\t\tthis.defaultValue = this.value;\n\t\tthis.$input[ 0 ].defaultValue = this.defaultValue;\n\t}\n\treturn this;\n};\n\n/**\n * Clean up incoming value.\n *\n * Ensures value is a string, and converts undefined and null to empty string.\n *\n * @private\n * @param {string} value Original value\n * @return {string} Cleaned up value\n */\nOO.ui.InputWidget.prototype.cleanUpValue = function ( value ) {\n\tif ( value === undefined || value === null ) {\n\t\treturn '';\n\t} else if ( this.inputFilter ) {\n\t\treturn this.inputFilter( String( value ) );\n\t} else {\n\t\treturn String( value );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.prototype.setDisabled = function ( state ) {\n\tOO.ui.InputWidget.parent.prototype.setDisabled.call( this, state );\n\tif ( this.$input ) {\n\t\tthis.$input.prop( 'disabled', this.isDisabled() );\n\t}\n\treturn this;\n};\n\n/**\n * Set the 'id' attribute of the `<input>` element.\n *\n * @param {string} id\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.InputWidget.prototype.setInputId = function ( id ) {\n\tthis.$input.attr( 'id', id );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.InputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.InputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.value !== undefined && state.value !== this.getValue() ) {\n\t\tthis.setValue( state.value );\n\t}\n\tif ( state.focus ) {\n\t\tthis.focus();\n\t}\n};\n","/**\n * Data widget intended for creating `<input type=\"hidden\">` inputs.\n *\n * @class\n * @extends OO.ui.Widget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [value=''] The value of the input.\n * @cfg {string} [name=''] The value of the input’s HTML `name` attribute.\n */\nOO.ui.HiddenInputWidget = function OoUiHiddenInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { value: '', name: '' }, config );\n\n\t// Parent constructor\n\tOO.ui.HiddenInputWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element.attr( {\n\t\ttype: 'hidden',\n\t\tvalue: config.value,\n\t\tname: config.name\n\t} );\n\tthis.$element.removeAttr( 'aria-disabled' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.HiddenInputWidget, OO.ui.Widget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.HiddenInputWidget.static.tagName = 'input';\n","/**\n * ButtonInputWidget is used to submit HTML forms and is intended to be used within\n * a OO.ui.FormLayout. If you do not need the button to work with HTML forms, you probably\n * want to use OO.ui.ButtonWidget instead. Button input widgets can be rendered as either an\n * HTML `<button>` (the default) or an HTML `<input>` tags. See the\n * [OOUI documentation on MediaWiki] [1] for more information.\n *\n *     @example\n *     // A ButtonInputWidget rendered as an HTML button, the default.\n *     var button = new OO.ui.ButtonInputWidget( {\n *         label: 'Input button',\n *         icon: 'check',\n *         value: 'check'\n *     } );\n *     $( document.body ).append( button.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs#Button_inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [type='button'] The value of the HTML `'type'` attribute:\n *  'button', 'submit' or 'reset'.\n * @cfg {boolean} [useInputTag=false] Use an `<input>` tag instead of a `<button>` tag, the default.\n *  Widgets configured to be an `<input>` do not support {@link #icon icons} and\n *  {@link #indicator indicators},\n *  non-plaintext {@link #label labels}, or {@link #value values}. In general, useInputTag should\n *  only be set to `true` when there’s need to support IE 6 in a form with multiple buttons.\n */\nOO.ui.ButtonInputWidget = function OoUiButtonInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { type: 'button', useInputTag: false }, config );\n\n\t// See InputWidget#reusePreInfuseDOM about config.$input\n\tif ( config.$input ) {\n\t\tconfig.$input.empty();\n\t}\n\n\t// Properties (must be set before parent constructor, which calls #setValue)\n\tthis.useInputTag = config.useInputTag;\n\n\t// Parent constructor\n\tOO.ui.ButtonInputWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, $.extend( {\n\t\t$button: this.$input\n\t}, config ) );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\n\t// Initialization\n\tif ( !config.useInputTag ) {\n\t\tthis.$input.append( this.$icon, this.$label, this.$indicator );\n\t}\n\tthis.$element.addClass( 'oo-ui-buttonInputWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonInputWidget, OO.ui.InputWidget );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.FlaggedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonInputWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.ButtonInputWidget.prototype.getInputElement = function ( config ) {\n\tvar type;\n\ttype = [ 'button', 'submit', 'reset' ].indexOf( config.type ) !== -1 ? config.type : 'button';\n\treturn $( '<' + ( config.useInputTag ? 'input' : 'button' ) + ' type=\"' + type + '\">' );\n};\n\n/**\n * Set label value.\n *\n * If #useInputTag is `true`, the label is set as the `value` of the `<input>` tag.\n *\n * @param {jQuery|string|Function|null} label Label nodes, text, a function that returns nodes or\n *  text, or `null` for no label\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonInputWidget.prototype.setLabel = function ( label ) {\n\tif ( typeof label === 'function' ) {\n\t\tlabel = OO.ui.resolveMsg( label );\n\t}\n\n\tif ( this.useInputTag ) {\n\t\t// Discard non-plaintext labels\n\t\tif ( typeof label !== 'string' ) {\n\t\t\tlabel = '';\n\t\t}\n\n\t\tthis.$input.val( label );\n\t}\n\n\treturn OO.ui.mixin.LabelElement.prototype.setLabel.call( this, label );\n};\n\n/**\n * Set the value of the input.\n *\n * This method is disabled for button inputs configured as {@link #useInputTag <input> tags}, as\n * they do not support {@link #value values}.\n *\n * @param {string} value New value\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ButtonInputWidget.prototype.setValue = function ( value ) {\n\tif ( !this.useInputTag ) {\n\t\tOO.ui.ButtonInputWidget.parent.prototype.setValue.call( this, value );\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ButtonInputWidget.prototype.getInputId = function () {\n\t// Disable generating `<label>` elements for buttons. One would very rarely need additional\n\t// label for a button, and it's already a big clickable target, and it causes\n\t// unexpected rendering.\n\treturn null;\n};\n","/**\n * CheckboxInputWidgets, like HTML checkboxes, can be selected and/or configured with a value.\n * Note that these {@link OO.ui.InputWidget input widgets} are best laid out\n * in {@link OO.ui.FieldLayout field layouts} that use the {@link OO.ui.FieldLayout#align inline}\n * alignment. For more information, please see the [OOUI documentation on MediaWiki][1].\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // An example of selected, unselected, and disabled checkbox inputs.\n *     var checkbox1 = new OO.ui.CheckboxInputWidget( {\n *             value: 'a',\n *              selected: true\n *         } ),\n *         checkbox2 = new OO.ui.CheckboxInputWidget( {\n *             value: 'b'\n *         } ),\n *         checkbox3 = new OO.ui.CheckboxInputWidget( {\n *             value:'c',\n *             disabled: true\n *         } ),\n *         // Create a fieldset layout with fields for each checkbox.\n *         fieldset = new OO.ui.FieldsetLayout( {\n *             label: 'Checkboxes'\n *         } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( checkbox1, { label: 'Selected checkbox', align: 'inline' } ),\n *         new OO.ui.FieldLayout( checkbox2, { label: 'Unselected checkbox', align: 'inline' } ),\n *         new OO.ui.FieldLayout( checkbox3, { label: 'Disabled checkbox', align: 'inline' } ),\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [selected=false] Select the checkbox initially. By default, the checkbox is\n *  not selected.\n * @cfg {boolean} [indeterminate=false] Whether the checkbox is in the indeterminate state.\n */\nOO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.CheckboxInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.checkIcon = new OO.ui.IconWidget( {\n\t\ticon: 'check',\n\t\tclasses: [ 'oo-ui-checkboxInputWidget-checkIcon' ]\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-checkboxInputWidget' )\n\t\t// Required for pretty styling in WikimediaUI theme\n\t\t.append( this.checkIcon.$element );\n\tthis.setSelected( config.selected !== undefined ? config.selected : false );\n\tthis.setIndeterminate( config.indeterminate !== undefined ? config.indeterminate : false );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the state of the input changes.\n *\n * @param {boolean} selected\n * @param {boolean} indeterminate\n */\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.static.tagName = 'span';\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.CheckboxInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.checked = config.$input.prop( 'checked' );\n\treturn state;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.CheckboxInputWidget.prototype.getInputElement = function () {\n\treturn $( '<input>' ).attr( 'type', 'checkbox' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.prototype.onEdit = function () {\n\tvar widget = this;\n\tif ( !this.isDisabled() ) {\n\t\t// Allow the stack to clear so the value will be updated\n\t\tsetTimeout( function () {\n\t\t\twidget.setSelected( widget.$input.prop( 'checked' ) );\n\t\t\twidget.setIndeterminate( widget.$input.prop( 'indeterminate' ) );\n\t\t} );\n\t}\n};\n\n/**\n * Set selection state of this checkbox.\n *\n * @param {boolean} state Selected state\n * @param {boolean} internal Used for internal calls to suppress events\n * @chainable\n * @return {OO.ui.CheckboxInputWidget} The widget, for chaining\n */\nOO.ui.CheckboxInputWidget.prototype.setSelected = function ( state, internal ) {\n\tstate = !!state;\n\tif ( this.selected !== state ) {\n\t\tthis.selected = state;\n\t\tthis.$input.prop( 'checked', this.selected );\n\t\tif ( !internal ) {\n\t\t\tthis.setIndeterminate( false, true );\n\t\t\tthis.emit( 'change', this.selected, this.indeterminate );\n\t\t}\n\t}\n\t// The first time that the selection state is set (probably while constructing the widget),\n\t// remember it in defaultSelected. This property can be later used to check whether\n\t// the selection state of the input has been changed since it was created.\n\tif ( this.defaultSelected === undefined ) {\n\t\tthis.defaultSelected = this.selected;\n\t\tthis.$input[ 0 ].defaultChecked = this.defaultSelected;\n\t}\n\treturn this;\n};\n\n/**\n * Check if this checkbox is selected.\n *\n * @return {boolean} Checkbox is selected\n */\nOO.ui.CheckboxInputWidget.prototype.isSelected = function () {\n\t// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify\n\t// it, and we won't know unless they're kind enough to trigger a 'change' event.\n\tvar selected = this.$input.prop( 'checked' );\n\tif ( this.selected !== selected ) {\n\t\tthis.setSelected( selected );\n\t}\n\treturn this.selected;\n};\n\n/**\n * Set indeterminate state of this checkbox.\n *\n * @param {boolean} state Indeterminate state\n * @param {boolean} internal Used for internal calls to suppress events\n * @chainable\n * @return {OO.ui.CheckboxInputWidget} The widget, for chaining\n */\nOO.ui.CheckboxInputWidget.prototype.setIndeterminate = function ( state, internal ) {\n\tstate = !!state;\n\tif ( this.indeterminate !== state ) {\n\t\tthis.indeterminate = state;\n\t\tthis.$input.prop( 'indeterminate', this.indeterminate );\n\t\tif ( !internal ) {\n\t\t\tthis.setSelected( false, true );\n\t\t\tthis.emit( 'change', this.selected, this.indeterminate );\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Check if this checkbox is selected.\n *\n * @return {boolean} Checkbox is selected\n */\nOO.ui.CheckboxInputWidget.prototype.isIndeterminate = function () {\n\t// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify\n\t// it, and we won't know unless they're kind enough to trigger a 'change' event.\n\tvar indeterminate = this.$input.prop( 'indeterminate' );\n\tif ( this.indeterminate !== indeterminate ) {\n\t\tthis.setIndeterminate( indeterminate );\n\t}\n\treturn this.indeterminate;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.prototype.simulateLabelClick = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$handle.trigger( 'click' );\n\t}\n\tthis.focus();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxInputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.CheckboxInputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.checked !== undefined && state.checked !== this.isSelected() ) {\n\t\tthis.setSelected( state.checked );\n\t}\n};\n","/**\n * DropdownInputWidget is a {@link OO.ui.DropdownWidget DropdownWidget} intended to be used\n * within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the\n * value of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for\n * more information about input widgets.\n *\n * A DropdownInputWidget always has a value (one of the options is always selected), unless there\n * are no options. If no `value` configuration option is provided, the first option is selected.\n * If you need a state representing no value (no option being selected), use a DropdownWidget.\n *\n * This and OO.ui.RadioSelectInputWidget support similar configuration options.\n *\n *     @example\n *     // A DropdownInputWidget with three options.\n *     var dropdownInput = new OO.ui.DropdownInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second', disabled: true },\n *             { optgroup: 'Group label' },\n *             { data: 'c', label: 'First sub-item)' }\n *         ]\n *     } );\n *     $( document.body ).append( dropdownInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format described above.\n * @cfg {Object} [dropdown] Configuration options for {@link OO.ui.DropdownWidget DropdownWidget}\n * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful\n *  in cases where the expanded menu is larger than its containing `<div>`. The specified overlay\n *  layer is usually on top of the containing `<div>` and has a larger area. By default, the menu\n *  uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.dropdownWidget = new OO.ui.DropdownWidget( $.extend(\n\t\t{\n\t\t\t$overlay: config.$overlay\n\t\t},\n\t\tconfig.dropdown\n\t) );\n\t// Set up the options before parent constructor, which uses them to validate config.value.\n\t// Use this instead of setOptions() because this.$input is not set up yet.\n\tthis.setOptionsData( config.options || [] );\n\n\t// Parent constructor\n\tOO.ui.DropdownInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.dropdownWidget.getMenu().connect( this, {\n\t\tselect: 'onMenuSelect'\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-dropdownInputWidget' )\n\t\t.append( this.dropdownWidget.$element );\n\tthis.setTabIndexedElement( this.dropdownWidget.$tabIndexed );\n\tthis.setTitledElement( this.dropdownWidget.$handle );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.DropdownInputWidget, OO.ui.InputWidget );\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.DropdownInputWidget.prototype.getInputElement = function () {\n\treturn $( '<select>' );\n};\n\n/**\n * Handles menu select events.\n *\n * @private\n * @param {OO.ui.MenuOptionWidget|null} item Selected menu item\n */\nOO.ui.DropdownInputWidget.prototype.onMenuSelect = function ( item ) {\n\tthis.setValue( item ? item.getData() : '' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.setValue = function ( value ) {\n\tvar selected;\n\tvalue = this.cleanUpValue( value );\n\t// Only allow setting values that are actually present in the dropdown\n\tselected = this.dropdownWidget.getMenu().findItemFromData( value ) ||\n\t\tthis.dropdownWidget.getMenu().findFirstSelectableItem();\n\tthis.dropdownWidget.getMenu().selectItem( selected );\n\tvalue = selected ? selected.getData() : '';\n\tOO.ui.DropdownInputWidget.parent.prototype.setValue.call( this, value );\n\tif ( this.optionsDirty ) {\n\t\t// We reached this from the constructor or from #setOptions.\n\t\t// We have to update the <select> element.\n\t\tthis.updateOptionsInterface();\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.setDisabled = function ( state ) {\n\tthis.dropdownWidget.setDisabled( state );\n\tOO.ui.DropdownInputWidget.parent.prototype.setDisabled.call( this, state );\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.DropdownInputWidget.prototype.setOptions = function ( options ) {\n\tvar value = this.getValue();\n\n\tthis.setOptionsData( options );\n\n\t// Re-set the value to update the visible interface (DropdownWidget and <select>).\n\t// In case the previous value is no longer an available option, select the first valid one.\n\tthis.setValue( value );\n\n\treturn this;\n};\n\n/**\n * Set the internal list of options, used e.g. by setValue() to see which options are allowed.\n *\n * This method may be called before the parent constructor, so various properties may not be\n * initialized yet.\n *\n * @param {Object[]} options Array of menu options (see #constructor for details).\n * @private\n */\nOO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar optionWidgets, optIndex, opt, previousOptgroup, optionWidget, optValue,\n\t\twidget = this;\n\n\tthis.optionsDirty = true;\n\n\t// Go through all the supplied option configs and create either\n\t// MenuSectionOption or MenuOption widgets from each.\n\toptionWidgets = [];\n\tfor ( optIndex = 0; optIndex < options.length; optIndex++ ) {\n\t\topt = options[ optIndex ];\n\n\t\tif ( opt.optgroup !== undefined ) {\n\t\t\t// Create a <optgroup> menu item.\n\t\t\toptionWidget = widget.createMenuSectionOptionWidget( opt.optgroup );\n\t\t\tpreviousOptgroup = optionWidget;\n\n\t\t} else {\n\t\t\t// Create a normal <option> menu item.\n\t\t\toptValue = widget.cleanUpValue( opt.data );\n\t\t\toptionWidget = widget.createMenuOptionWidget(\n\t\t\t\toptValue,\n\t\t\t\topt.label !== undefined ? opt.label : optValue\n\t\t\t);\n\t\t}\n\n\t\t// Disable the menu option if it is itself disabled or if its parent optgroup is disabled.\n\t\tif (\n\t\t\topt.disabled !== undefined ||\n\t\t\tpreviousOptgroup instanceof OO.ui.MenuSectionOptionWidget &&\n\t\t\tpreviousOptgroup.isDisabled()\n\t\t) {\n\t\t\toptionWidget.setDisabled( true );\n\t\t}\n\n\t\toptionWidgets.push( optionWidget );\n\t}\n\n\tthis.dropdownWidget.getMenu().clearItems().addItems( optionWidgets );\n};\n\n/**\n * Create a menu option widget.\n *\n * @protected\n * @param {string} data Item data\n * @param {string} label Item label\n * @return {OO.ui.MenuOptionWidget} Option widget\n */\nOO.ui.DropdownInputWidget.prototype.createMenuOptionWidget = function ( data, label ) {\n\treturn new OO.ui.MenuOptionWidget( {\n\t\tdata: data,\n\t\tlabel: label\n\t} );\n};\n\n/**\n * Create a menu section option widget.\n *\n * @protected\n * @param {string} label Section item label\n * @return {OO.ui.MenuSectionOptionWidget} Menu section option widget\n */\nOO.ui.DropdownInputWidget.prototype.createMenuSectionOptionWidget = function ( label ) {\n\treturn new OO.ui.MenuSectionOptionWidget( {\n\t\tlabel: label\n\t} );\n};\n\n/**\n * Update the user-visible interface to match the internal list of options and value.\n *\n * This method must only be called after the parent constructor.\n *\n * @private\n */\nOO.ui.DropdownInputWidget.prototype.updateOptionsInterface = function () {\n\tvar\n\t\t$optionsContainer = this.$input,\n\t\tdefaultValue = this.defaultValue,\n\t\twidget = this;\n\n\tthis.$input.empty();\n\n\tthis.dropdownWidget.getMenu().getItems().forEach( function ( optionWidget ) {\n\t\tvar $optionNode;\n\n\t\tif ( !( optionWidget instanceof OO.ui.MenuSectionOptionWidget ) ) {\n\t\t\t$optionNode = $( '<option>' )\n\t\t\t\t.attr( 'value', optionWidget.getData() )\n\t\t\t\t.text( optionWidget.getLabel() );\n\n\t\t\t// Remember original selection state. This property can be later used to check whether\n\t\t\t// the selection state of the input has been changed since it was created.\n\t\t\t$optionNode[ 0 ].defaultSelected = ( optionWidget.getData() === defaultValue );\n\n\t\t\t$optionsContainer.append( $optionNode );\n\t\t} else {\n\t\t\t$optionNode = $( '<optgroup>' )\n\t\t\t\t.attr( 'label', optionWidget.getLabel() );\n\t\t\twidget.$input.append( $optionNode );\n\t\t\t$optionsContainer = $optionNode;\n\t\t}\n\n\t\t// Disable the option or optgroup if required.\n\t\tif ( optionWidget.isDisabled() ) {\n\t\t\t$optionNode.prop( 'disabled', true );\n\t\t}\n\t} );\n\n\tthis.optionsDirty = false;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.focus = function () {\n\tthis.dropdownWidget.focus();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.DropdownInputWidget.prototype.blur = function () {\n\tthis.dropdownWidget.blur();\n\treturn this;\n};\n","/**\n * RadioInputWidget creates a single radio button. Because radio buttons are usually used as a set,\n * in most cases you will want to use a {@link OO.ui.RadioSelectWidget radio select}\n * with {@link OO.ui.RadioOptionWidget radio options} instead of this class. For more information,\n * please see the [OOUI documentation on MediaWiki][1].\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // An example of selected, unselected, and disabled radio inputs\n *     var radio1 = new OO.ui.RadioInputWidget( {\n *         value: 'a',\n *         selected: true\n *     } );\n *     var radio2 = new OO.ui.RadioInputWidget( {\n *         value: 'b'\n *     } );\n *     var radio3 = new OO.ui.RadioInputWidget( {\n *         value: 'c',\n *         disabled: true\n *     } );\n *     // Create a fieldset layout with fields for each radio button.\n *     var fieldset = new OO.ui.FieldsetLayout( {\n *         label: 'Radio inputs'\n *     } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( radio1, { label: 'Selected', align: 'inline' } ),\n *         new OO.ui.FieldLayout( radio2, { label: 'Unselected', align: 'inline' } ),\n *         new OO.ui.FieldLayout( radio3, { label: 'Disabled', align: 'inline' } ),\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [selected=false] Select the radio button initially. By default, the radio button\n *  is not selected.\n */\nOO.ui.RadioInputWidget = function OoUiRadioInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.RadioInputWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioInputWidget' )\n\t\t// Required for pretty styling in WikimediaUI theme\n\t\t.append( $( '<span>' ) );\n\tthis.setSelected( config.selected !== undefined ? config.selected : false );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioInputWidget, OO.ui.InputWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.static.tagName = 'span';\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.RadioInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.checked = config.$input.prop( 'checked' );\n\treturn state;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.RadioInputWidget.prototype.getInputElement = function () {\n\treturn $( '<input>' ).attr( 'type', 'radio' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.prototype.onEdit = function () {\n\t// RadioInputWidget doesn't track its state.\n};\n\n/**\n * Set selection state of this radio button.\n *\n * @param {boolean} state `true` for selected\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.RadioInputWidget.prototype.setSelected = function ( state ) {\n\t// RadioInputWidget doesn't track its state.\n\tthis.$input.prop( 'checked', state );\n\t// The first time that the selection state is set (probably while constructing the widget),\n\t// remember it in defaultSelected. This property can be later used to check whether\n\t// the selection state of the input has been changed since it was created.\n\tif ( this.defaultSelected === undefined ) {\n\t\tthis.defaultSelected = state;\n\t\tthis.$input[ 0 ].defaultChecked = this.defaultSelected;\n\t}\n\treturn this;\n};\n\n/**\n * Check if this radio button is selected.\n *\n * @return {boolean} Radio is selected\n */\nOO.ui.RadioInputWidget.prototype.isSelected = function () {\n\treturn this.$input.prop( 'checked' );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.prototype.simulateLabelClick = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$input.trigger( 'click' );\n\t}\n\tthis.focus();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioInputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.RadioInputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.checked !== undefined && state.checked !== this.isSelected() ) {\n\t\tthis.setSelected( state.checked );\n\t}\n};\n","/**\n * RadioSelectInputWidget is a {@link OO.ui.RadioSelectWidget RadioSelectWidget} intended to be\n * used within an HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with\n * the value of a hidden HTML `input` tag. Please see the [OOUI documentation on MediaWiki][1] for\n * more information about input widgets.\n *\n * This and OO.ui.DropdownInputWidget support similar configuration options.\n *\n *     @example\n *     // A RadioSelectInputWidget with three options\n *     var radioSelectInput = new OO.ui.RadioSelectInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second'},\n *             { data: 'c', label: 'Third' }\n *         ]\n *     } );\n *     $( document.body ).append( radioSelectInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`\n */\nOO.ui.RadioSelectInputWidget = function OoUiRadioSelectInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.radioSelectWidget = new OO.ui.RadioSelectWidget();\n\t// Set up the options before parent constructor, which uses them to validate config.value.\n\t// Use this instead of setOptions() because this.$input is not set up yet\n\tthis.setOptionsData( config.options || [] );\n\n\t// Parent constructor\n\tOO.ui.RadioSelectInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.radioSelectWidget.connect( this, {\n\t\tselect: 'onMenuSelect'\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-radioSelectInputWidget' )\n\t\t.append( this.radioSelectWidget.$element );\n\tthis.setTabIndexedElement( this.radioSelectWidget.$tabIndexed );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.RadioSelectInputWidget, OO.ui.InputWidget );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.RadioSelectInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.value = $( node ).find( '.oo-ui-radioInputWidget .oo-ui-inputWidget-input:checked' ).val();\n\treturn state;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.static.reusePreInfuseDOM = function ( node, config ) {\n\tconfig = OO.ui.RadioSelectInputWidget.parent.static.reusePreInfuseDOM( node, config );\n\t// Cannot reuse the `<input type=radio>` set\n\tdelete config.$input;\n\treturn config;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.RadioSelectInputWidget.prototype.getInputElement = function () {\n\t// Use this instead of <input type=\"hidden\">, because hidden inputs do not have separate\n\t// 'value' and 'defaultValue' properties, and InputWidget wants to handle 'defaultValue'.\n\treturn $( '<input>' ).addClass( 'oo-ui-element-hidden' );\n};\n\n/**\n * Handles menu select events.\n *\n * @private\n * @param {OO.ui.RadioOptionWidget} item Selected menu item\n */\nOO.ui.RadioSelectInputWidget.prototype.onMenuSelect = function ( item ) {\n\tthis.setValue( item.getData() );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.setValue = function ( value ) {\n\tvar selected;\n\tvalue = this.cleanUpValue( value );\n\t// Only allow setting values that are actually present in the dropdown\n\tselected = this.radioSelectWidget.findItemFromData( value ) ||\n\t\tthis.radioSelectWidget.findFirstSelectableItem();\n\tthis.radioSelectWidget.selectItem( selected );\n\tvalue = selected ? selected.getData() : '';\n\tOO.ui.RadioSelectInputWidget.parent.prototype.setValue.call( this, value );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.setDisabled = function ( state ) {\n\tthis.radioSelectWidget.setDisabled( state );\n\tOO.ui.RadioSelectInputWidget.parent.prototype.setDisabled.call( this, state );\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.RadioSelectInputWidget.prototype.setOptions = function ( options ) {\n\tvar value = this.getValue();\n\n\tthis.setOptionsData( options );\n\n\t// Re-set the value to update the visible interface (RadioSelectWidget).\n\t// In case the previous value is no longer an available option, select the first valid one.\n\tthis.setValue( value );\n\n\treturn this;\n};\n\n/**\n * Set the internal list of options, used e.g. by setValue() to see which options are allowed.\n *\n * This method may be called before the parent constructor, so various properties may not be\n * intialized yet.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @private\n */\nOO.ui.RadioSelectInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar widget = this;\n\n\tthis.radioSelectWidget\n\t\t.clearItems()\n\t\t.addItems( options.map( function ( opt ) {\n\t\t\tvar optValue = widget.cleanUpValue( opt.data );\n\t\t\treturn new OO.ui.RadioOptionWidget( {\n\t\t\t\tdata: optValue,\n\t\t\t\tlabel: opt.label !== undefined ? opt.label : optValue\n\t\t\t} );\n\t\t} ) );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.focus = function () {\n\tthis.radioSelectWidget.focus();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.RadioSelectInputWidget.prototype.blur = function () {\n\tthis.radioSelectWidget.blur();\n\treturn this;\n};\n","/**\n * CheckboxMultiselectInputWidget is a\n * {@link OO.ui.CheckboxMultiselectWidget CheckboxMultiselectWidget} intended to be used within a\n * HTML form, such as a OO.ui.FormLayout. The selected values are synchronized with the value of\n * HTML `<input type=checkbox>` tags. Please see the [OOUI documentation on MediaWiki][1] for\n * more information about input widgets.\n *\n *     @example\n *     // A CheckboxMultiselectInputWidget with three options.\n *     var multiselectInput = new OO.ui.CheckboxMultiselectInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second' },\n *             { data: 'c', label: 'Third' }\n *         ]\n *     } );\n *     $( document.body ).append( multiselectInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format\n *  `{ data: …, label: …, disabled: … }`\n */\nOO.ui.CheckboxMultiselectInputWidget = function OoUiCheckboxMultiselectInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be done before parent constructor which calls #setDisabled)\n\tthis.checkboxMultiselectWidget = new OO.ui.CheckboxMultiselectWidget();\n\t// Must be set before the #setOptionsData call below\n\tthis.inputName = config.name;\n\t// Set up the options before parent constructor, which uses them to validate config.value.\n\t// Use this instead of setOptions() because this.$input is not set up yet\n\tthis.setOptionsData( config.options || [] );\n\n\t// Parent constructor\n\tOO.ui.CheckboxMultiselectInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.checkboxMultiselectWidget.connect( this, {\n\t\tselect: 'onCheckboxesSelect'\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-checkboxMultiselectInputWidget' )\n\t\t.append( this.checkboxMultiselectWidget.$element );\n\t// We don't use this.$input, but rather the CheckboxInputWidgets inside each option\n\tthis.$input.detach();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CheckboxMultiselectInputWidget, OO.ui.InputWidget );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.CheckboxMultiselectInputWidget.parent.static.gatherPreInfuseState(\n\t\tnode, config\n\t);\n\tstate.value = $( node ).find( '.oo-ui-checkboxInputWidget .oo-ui-inputWidget-input:checked' )\n\t\t.toArray().map( function ( el ) { return el.value; } );\n\treturn state;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.static.reusePreInfuseDOM = function ( node, config ) {\n\tconfig = OO.ui.CheckboxMultiselectInputWidget.parent.static.reusePreInfuseDOM( node, config );\n\t// Cannot reuse the `<input type=checkbox>` set\n\tdelete config.$input;\n\treturn config;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.getInputElement = function () {\n\t// Actually unused\n\treturn $( '<unused>' );\n};\n\n/**\n * Handles CheckboxMultiselectWidget select events.\n *\n * @private\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.onCheckboxesSelect = function () {\n\tthis.setValue( this.checkboxMultiselectWidget.findSelectedItemsData() );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.getValue = function () {\n\tvar value = this.$element.find( '.oo-ui-checkboxInputWidget .oo-ui-inputWidget-input:checked' )\n\t\t.toArray().map( function ( el ) { return el.value; } );\n\tif ( this.value !== value ) {\n\t\tthis.setValue( value );\n\t}\n\treturn this.value;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setValue = function ( value ) {\n\tvalue = this.cleanUpValue( value );\n\tthis.checkboxMultiselectWidget.selectItemsByData( value );\n\tOO.ui.CheckboxMultiselectInputWidget.parent.prototype.setValue.call( this, value );\n\tif ( this.optionsDirty ) {\n\t\t// We reached this from the constructor or from #setOptions.\n\t\t// We have to update the <select> element.\n\t\tthis.updateOptionsInterface();\n\t}\n\treturn this;\n};\n\n/**\n * Clean up incoming value.\n *\n * @param {string[]} value Original value\n * @return {string[]} Cleaned up value\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.cleanUpValue = function ( value ) {\n\tvar i, singleValue,\n\t\tcleanValue = [];\n\tif ( !Array.isArray( value ) ) {\n\t\treturn cleanValue;\n\t}\n\tfor ( i = 0; i < value.length; i++ ) {\n\t\tsingleValue = OO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue\n\t\t\t.call( this, value[ i ] );\n\t\t// Remove options that we don't have here\n\t\tif ( !this.checkboxMultiselectWidget.findItemFromData( singleValue ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tcleanValue.push( singleValue );\n\t}\n\treturn cleanValue;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setDisabled = function ( state ) {\n\tthis.checkboxMultiselectWidget.setDisabled( state );\n\tOO.ui.CheckboxMultiselectInputWidget.parent.prototype.setDisabled.call( this, state );\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format\n *  `{ data: …, label: …, disabled: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setOptions = function ( options ) {\n\tvar value = this.getValue();\n\n\tthis.setOptionsData( options );\n\n\t// Re-set the value to update the visible interface (CheckboxMultiselectWidget).\n\t// This will also get rid of any stale options that we just removed.\n\tthis.setValue( value );\n\n\treturn this;\n};\n\n/**\n * Set the internal list of options, used e.g. by setValue() to see which options are allowed.\n *\n * This method may be called before the parent constructor, so various properties may not be\n * intialized yet.\n *\n * @param {Object[]} options Array of menu options in the format\n *  `{ data: …, label: … }`\n * @private\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar widget = this;\n\n\tthis.optionsDirty = true;\n\n\tthis.checkboxMultiselectWidget\n\t\t.clearItems()\n\t\t.addItems( options.map( function ( opt ) {\n\t\t\tvar optValue, item, optDisabled;\n\t\t\toptValue = OO.ui.CheckboxMultiselectInputWidget.parent.prototype.cleanUpValue\n\t\t\t\t.call( widget, opt.data );\n\t\t\toptDisabled = opt.disabled !== undefined ? opt.disabled : false;\n\t\t\titem = new OO.ui.CheckboxMultioptionWidget( {\n\t\t\t\tdata: optValue,\n\t\t\t\tlabel: opt.label !== undefined ? opt.label : optValue,\n\t\t\t\tdisabled: optDisabled\n\t\t\t} );\n\t\t\t// Set the 'name' and 'value' for form submission\n\t\t\titem.checkbox.$input.attr( 'name', widget.inputName );\n\t\t\titem.checkbox.setValue( optValue );\n\t\t\treturn item;\n\t\t} ) );\n};\n\n/**\n * Update the user-visible interface to match the internal list of options and value.\n *\n * This method must only be called after the parent constructor.\n *\n * @private\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.updateOptionsInterface = function () {\n\tvar defaultValue = this.defaultValue;\n\n\tthis.checkboxMultiselectWidget.getItems().forEach( function ( item ) {\n\t\t// Remember original selection state. This property can be later used to check whether\n\t\t// the selection state of the input has been changed since it was created.\n\t\tvar isDefault = defaultValue.indexOf( item.getData() ) !== -1;\n\t\titem.checkbox.defaultSelected = isDefault;\n\t\titem.checkbox.$input[ 0 ].defaultChecked = isDefault;\n\t} );\n\n\tthis.optionsDirty = false;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CheckboxMultiselectInputWidget.prototype.focus = function () {\n\tthis.checkboxMultiselectWidget.focus();\n\treturn this;\n};\n","/**\n * TextInputWidgets, like HTML text inputs, can be configured with options that customize the\n * size of the field as well as its presentation. In addition, these widgets can be configured\n * with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators}, an\n * optional validation-pattern (used to determine if an input value is valid or not) and an input\n * filter, which modifies incoming values rather than validating them.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // A TextInputWidget.\n *     var textInput = new OO.ui.TextInputWidget( {\n *         value: 'Text input'\n *     } );\n *     $( document.body ).append( textInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n * @class\n * @extends OO.ui.InputWidget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.PendingElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [type='text'] The value of the HTML `type` attribute: 'text', 'password'\n *  'email', 'url' or 'number'.\n * @cfg {string} [placeholder] Placeholder text\n * @cfg {boolean} [autofocus=false] Use an HTML `autofocus` attribute to\n *  instruct the browser to focus this widget.\n * @cfg {boolean} [readOnly=false] Prevent changes to the value of the text input.\n * @cfg {number} [maxLength] Maximum number of characters allowed in the input.\n *\n *  For unfortunate historical reasons, this counts the number of UTF-16 code units rather than\n *  Unicode codepoints, which means that codepoints outside the Basic Multilingual Plane (e.g.\n *  many emojis) count as 2 characters each.\n * @cfg {string} [labelPosition='after'] The position of the inline label relative to that of\n *  the value or placeholder text: `'before'` or `'after'`\n * @cfg {boolean} [required=false] Mark the field as required with `true`. Implies `indicator:\n *  'required'`. Note that `false` & setting `indicator: 'required' will result in no indicator\n *  shown.\n * @cfg {boolean} [autocomplete=true] Should the browser support autocomplete for this field\n * @cfg {boolean} [spellcheck] Should the browser support spellcheck for this field (`undefined`\n *  means leaving it up to the browser).\n * @cfg {RegExp|Function|string} [validate] Validation pattern: when string, a symbolic name of a\n *  pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer'\n *  (the value must contain only numbers); when RegExp, a regular expression that must match the\n *  value for it to be considered valid; when Function, a function receiving the value as parameter\n *  that must return true, or promise resolving to true, for it to be considered valid.\n */\nOO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\ttype: 'text',\n\t\tlabelPosition: 'after'\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.TextInputWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.PendingElement.call( this, $.extend( { $pending: this.$input }, config ) );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\n\t// Properties\n\tthis.type = this.getSaneType( config );\n\tthis.readOnly = false;\n\tthis.required = false;\n\tthis.validate = null;\n\tthis.scrollWidth = null;\n\n\tthis.setValidation( config.validate );\n\tthis.setLabelPosition( config.labelPosition );\n\n\t// Events\n\tthis.$input.on( {\n\t\tkeypress: this.onKeyPress.bind( this ),\n\t\tblur: this.onBlur.bind( this ),\n\t\tfocus: this.onFocus.bind( this )\n\t} );\n\tthis.$icon.on( 'mousedown', this.onIconMouseDown.bind( this ) );\n\tthis.$indicator.on( 'mousedown', this.onIndicatorMouseDown.bind( this ) );\n\tthis.on( 'labelChange', this.updatePosition.bind( this ) );\n\tthis.on( 'change', OO.ui.debounce( this.onDebouncedChange.bind( this ), 250 ) );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-textInputWidget oo-ui-textInputWidget-type-' + this.type )\n\t\t.append( this.$icon, this.$indicator );\n\tthis.setReadOnly( !!config.readOnly );\n\tthis.setRequired( !!config.required );\n\tif ( config.placeholder !== undefined ) {\n\t\tthis.$input.attr( 'placeholder', config.placeholder );\n\t}\n\tif ( config.maxLength !== undefined ) {\n\t\tthis.$input.attr( 'maxlength', config.maxLength );\n\t}\n\tif ( config.autofocus ) {\n\t\tthis.$input.attr( 'autofocus', 'autofocus' );\n\t}\n\tif ( config.autocomplete === false ) {\n\t\tthis.$input.attr( 'autocomplete', 'off' );\n\t\t// Turning off autocompletion also disables \"form caching\" when the user navigates to a\n\t\t// different page and then clicks \"Back\". Re-enable it when leaving.\n\t\t// Borrowed from jQuery UI.\n\t\t$( window ).on( {\n\t\t\tbeforeunload: function () {\n\t\t\t\tthis.$input.removeAttr( 'autocomplete' );\n\t\t\t}.bind( this ),\n\t\t\tpageshow: function () {\n\t\t\t\t// Browsers don't seem to actually fire this event on \"Back\", they instead just\n\t\t\t\t// reload the whole page... it shouldn't hurt, though.\n\t\t\t\tthis.$input.attr( 'autocomplete', 'off' );\n\t\t\t}.bind( this )\n\t\t} );\n\t}\n\tif ( config.spellcheck !== undefined ) {\n\t\tthis.$input.attr( 'spellcheck', config.spellcheck ? 'true' : 'false' );\n\t}\n\tif ( this.label ) {\n\t\tthis.isWaitingToBeAttached = true;\n\t\tthis.installParentChangeDetector();\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TextInputWidget, OO.ui.InputWidget );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.PendingElement );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.FlaggedElement );\n\n/* Static Properties */\n\nOO.ui.TextInputWidget.static.validationPatterns = {\n\t'non-empty': /.+/,\n\tinteger: /^\\d+$/\n};\n\n/* Events */\n\n/**\n * An `enter` event is emitted when the user presses Enter key inside the text box.\n *\n * @event enter\n */\n\n/* Methods */\n\n/**\n * Handle icon mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.TextInputWidget.prototype.onIconMouseDown = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle indicator mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.TextInputWidget.prototype.onIndicatorMouseDown = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @fires enter If Enter key is pressed\n */\nOO.ui.TextInputWidget.prototype.onKeyPress = function ( e ) {\n\tif ( e.which === OO.ui.Keys.ENTER ) {\n\t\tthis.emit( 'enter', e );\n\t}\n};\n\n/**\n * Handle blur events.\n *\n * @private\n * @param {jQuery.Event} e Blur event\n */\nOO.ui.TextInputWidget.prototype.onBlur = function () {\n\tthis.setValidityFlag();\n};\n\n/**\n * Handle focus events.\n *\n * @private\n * @param {jQuery.Event} e Focus event\n */\nOO.ui.TextInputWidget.prototype.onFocus = function () {\n\tif ( this.isWaitingToBeAttached ) {\n\t\t// If we've received focus, then we must be attached to the document, and if\n\t\t// isWaitingToBeAttached is still true, that means the handler never fired. Fire it now.\n\t\tthis.onElementAttach();\n\t}\n\tthis.setValidityFlag( true );\n};\n\n/**\n * Handle element attach events.\n *\n * @private\n * @param {jQuery.Event} e Element attach event\n */\nOO.ui.TextInputWidget.prototype.onElementAttach = function () {\n\tthis.isWaitingToBeAttached = false;\n\t// Any previously calculated size is now probably invalid if we reattached elsewhere\n\tthis.valCache = null;\n\tthis.positionLabel();\n};\n\n/**\n * Handle debounced change events.\n *\n * @param {string} value\n * @private\n */\nOO.ui.TextInputWidget.prototype.onDebouncedChange = function () {\n\tthis.setValidityFlag();\n};\n\n/**\n * Check if the input is {@link #readOnly read-only}.\n *\n * @return {boolean}\n */\nOO.ui.TextInputWidget.prototype.isReadOnly = function () {\n\treturn this.readOnly;\n};\n\n/**\n * Set the {@link #readOnly read-only} state of the input.\n *\n * @param {boolean} state Make input read-only\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.setReadOnly = function ( state ) {\n\tthis.readOnly = !!state;\n\tthis.$input.prop( 'readOnly', this.readOnly );\n\treturn this;\n};\n\n/**\n * Check if the input is {@link #required required}.\n *\n * @return {boolean}\n */\nOO.ui.TextInputWidget.prototype.isRequired = function () {\n\treturn this.required;\n};\n\n/**\n * Set the {@link #required required} state of the input.\n *\n * @param {boolean} state Make input required\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.setRequired = function ( state ) {\n\tthis.required = !!state;\n\tif ( this.required ) {\n\t\tthis.$input\n\t\t\t.prop( 'required', true )\n\t\t\t.attr( 'aria-required', 'true' );\n\t\tif ( this.getIndicator() === null ) {\n\t\t\tthis.setIndicator( 'required' );\n\t\t}\n\t} else {\n\t\tthis.$input\n\t\t\t.prop( 'required', false )\n\t\t\t.removeAttr( 'aria-required' );\n\t\tif ( this.getIndicator() === 'required' ) {\n\t\t\tthis.setIndicator( null );\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Support function for making #onElementAttach work across browsers.\n *\n * This whole function could be replaced with one line of code using the DOMNodeInsertedIntoDocument\n * event, but it's not supported by Firefox and allegedly deprecated, so we only use it as fallback.\n *\n * Due to MutationObserver performance woes, #onElementAttach is only somewhat reliably called the\n * first time that the element gets attached to the documented.\n */\nOO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {\n\tvar mutationObserver, onRemove, topmostNode, fakeParentNode,\n\t\tMutationObserver = window.MutationObserver ||\n\t\t\twindow.WebKitMutationObserver ||\n\t\t\twindow.MozMutationObserver,\n\t\twidget = this;\n\n\tif ( MutationObserver ) {\n\t\t// The new way. If only it wasn't so ugly.\n\n\t\tif ( this.isElementAttached() ) {\n\t\t\t// Widget is attached already, do nothing. This breaks the functionality of this\n\t\t\t// function when the widget is detached and reattached. Alas, doing this correctly with\n\t\t\t// MutationObserver would require observation of the whole document, which would hurt\n\t\t\t// performance of other, more important code.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find topmost node in the tree\n\t\ttopmostNode = this.$element[ 0 ];\n\t\twhile ( topmostNode.parentNode ) {\n\t\t\ttopmostNode = topmostNode.parentNode;\n\t\t}\n\n\t\t// We have no way to detect the $element being attached somewhere without observing the\n\t\t// entire DOM with subtree modifications, which would hurt performance. So we cheat: we hook\n\t\t// to the parent node of $element, and instead detect when $element is removed from it (and\n\t\t// thus probably attached somewhere else). If there is no parent, we create a \"fake\" one. If\n\t\t// it doesn't get attached, we end up back here and create the parent.\n\t\tmutationObserver = new MutationObserver( function ( mutations ) {\n\t\t\tvar i, j, removedNodes;\n\t\t\tfor ( i = 0; i < mutations.length; i++ ) {\n\t\t\t\tremovedNodes = mutations[ i ].removedNodes;\n\t\t\t\tfor ( j = 0; j < removedNodes.length; j++ ) {\n\t\t\t\t\tif ( removedNodes[ j ] === topmostNode ) {\n\t\t\t\t\t\tsetTimeout( onRemove, 0 );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tonRemove = function () {\n\t\t\t// If the node was attached somewhere else, report it\n\t\t\tif ( widget.isElementAttached() ) {\n\t\t\t\twidget.onElementAttach();\n\t\t\t}\n\t\t\tmutationObserver.disconnect();\n\t\t\twidget.installParentChangeDetector();\n\t\t};\n\n\t\t// Create a fake parent and observe it\n\t\tfakeParentNode = $( '<div>' ).append( topmostNode )[ 0 ];\n\t\tmutationObserver.observe( fakeParentNode, { childList: true } );\n\t} else {\n\t\t// Using the DOMNodeInsertedIntoDocument event is much nicer and less magical, and works for\n\t\t// detachment and reattachment, but it's not supported by Firefox and allegedly deprecated.\n\t\tthis.$element.on( 'DOMNodeInsertedIntoDocument', this.onElementAttach.bind( this ) );\n\t}\n};\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.TextInputWidget.prototype.getInputElement = function ( config ) {\n\tif ( this.getSaneType( config ) === 'number' ) {\n\t\treturn $( '<input>' )\n\t\t\t.attr( 'step', 'any' )\n\t\t\t.attr( 'type', 'number' );\n\t} else {\n\t\treturn $( '<input>' ).attr( 'type', this.getSaneType( config ) );\n\t}\n};\n\n/**\n * Get sanitized value for 'type' for given config.\n *\n * @param {Object} config Configuration options\n * @return {string|null}\n * @protected\n */\nOO.ui.TextInputWidget.prototype.getSaneType = function ( config ) {\n\tvar allowedTypes = [\n\t\t'text',\n\t\t'password',\n\t\t'email',\n\t\t'url',\n\t\t'number'\n\t];\n\treturn allowedTypes.indexOf( config.type ) !== -1 ? config.type : 'text';\n};\n\n/**\n * Focus the input and select a specified range within the text.\n *\n * @param {number} from Select from offset\n * @param {number} [to] Select to offset, defaults to from\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.selectRange = function ( from, to ) {\n\tvar isBackwards, start, end,\n\t\tinput = this.$input[ 0 ];\n\n\tto = to || from;\n\n\tisBackwards = to < from;\n\tstart = isBackwards ? to : from;\n\tend = isBackwards ? from : to;\n\n\tthis.focus();\n\n\ttry {\n\t\tinput.setSelectionRange( start, end, isBackwards ? 'backward' : 'forward' );\n\t} catch ( e ) {\n\t\t// IE throws an exception if you call setSelectionRange on a unattached DOM node.\n\t\t// Rather than expensively check if the input is attached every time, just check\n\t\t// if it was the cause of an error being thrown. If not, rethrow the error.\n\t\tif ( this.getElementDocument().body.contains( input ) ) {\n\t\t\tthrow e;\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * Get an object describing the current selection range in a directional manner\n *\n * @return {Object} Object containing 'from' and 'to' offsets\n */\nOO.ui.TextInputWidget.prototype.getRange = function () {\n\tvar input = this.$input[ 0 ],\n\t\tstart = input.selectionStart,\n\t\tend = input.selectionEnd,\n\t\tisBackwards = input.selectionDirection === 'backward';\n\n\treturn {\n\t\tfrom: isBackwards ? end : start,\n\t\tto: isBackwards ? start : end\n\t};\n};\n\n/**\n * Get the length of the text input value.\n *\n * This could differ from the length of #getValue if the\n * value gets filtered\n *\n * @return {number} Input length\n */\nOO.ui.TextInputWidget.prototype.getInputLength = function () {\n\treturn this.$input[ 0 ].value.length;\n};\n\n/**\n * Focus the input and select the entire text.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.select = function () {\n\treturn this.selectRange( 0, this.getInputLength() );\n};\n\n/**\n * Focus the input and move the cursor to the start.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.moveCursorToStart = function () {\n\treturn this.selectRange( 0 );\n};\n\n/**\n * Focus the input and move the cursor to the end.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.moveCursorToEnd = function () {\n\treturn this.selectRange( this.getInputLength() );\n};\n\n/**\n * Insert new content into the input.\n *\n * @param {string} content Content to be inserted\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.insertContent = function ( content ) {\n\tvar start, end,\n\t\trange = this.getRange(),\n\t\tvalue = this.getValue();\n\n\tstart = Math.min( range.from, range.to );\n\tend = Math.max( range.from, range.to );\n\n\tthis.setValue( value.slice( 0, start ) + content + value.slice( end ) );\n\tthis.selectRange( start + content.length );\n\treturn this;\n};\n\n/**\n * Insert new content either side of a selection.\n *\n * @param {string} pre Content to be inserted before the selection\n * @param {string} post Content to be inserted after the selection\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.encapsulateContent = function ( pre, post ) {\n\tvar start, end,\n\t\trange = this.getRange(),\n\t\toffset = pre.length;\n\n\tstart = Math.min( range.from, range.to );\n\tend = Math.max( range.from, range.to );\n\n\tthis.selectRange( start ).insertContent( pre );\n\tthis.selectRange( offset + end ).insertContent( post );\n\n\tthis.selectRange( offset + start, offset + end );\n\treturn this;\n};\n\n/**\n * Set the validation pattern.\n *\n * The validation pattern is either a regular expression, a function, or the symbolic name of a\n * pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer' (the\n * value must contain only numbers).\n *\n * @param {RegExp|Function|string|null} validate Regular expression, function, or the symbolic name\n *  of a pattern (either ‘integer’ or ‘non-empty’) defined by the class.\n */\nOO.ui.TextInputWidget.prototype.setValidation = function ( validate ) {\n\tif ( validate instanceof RegExp || validate instanceof Function ) {\n\t\tthis.validate = validate;\n\t} else {\n\t\tthis.validate = this.constructor.static.validationPatterns[ validate ] || /.*/;\n\t}\n};\n\n/**\n * Sets the 'invalid' flag appropriately.\n *\n * @param {boolean} [isValid] Optionally override validation result\n */\nOO.ui.TextInputWidget.prototype.setValidityFlag = function ( isValid ) {\n\tvar widget = this,\n\t\tsetFlag = function ( valid ) {\n\t\t\tif ( !valid ) {\n\t\t\t\twidget.$input.attr( 'aria-invalid', 'true' );\n\t\t\t} else {\n\t\t\t\twidget.$input.removeAttr( 'aria-invalid' );\n\t\t\t}\n\t\t\twidget.setFlags( { invalid: !valid } );\n\t\t};\n\n\tif ( isValid !== undefined ) {\n\t\tsetFlag( isValid );\n\t} else {\n\t\tthis.getValidity().then( function () {\n\t\t\tsetFlag( true );\n\t\t}, function () {\n\t\t\tsetFlag( false );\n\t\t} );\n\t}\n};\n\n/**\n * Get the validity of current value.\n *\n * This method returns a promise that resolves if the value is valid and rejects if\n * it isn't. Uses the {@link #validate validation pattern}  to check for validity.\n *\n * @return {jQuery.Promise} A promise that resolves if the value is valid, rejects if not.\n */\nOO.ui.TextInputWidget.prototype.getValidity = function () {\n\tvar result;\n\n\tfunction rejectOrResolve( valid ) {\n\t\tif ( valid ) {\n\t\t\treturn $.Deferred().resolve().promise();\n\t\t} else {\n\t\t\treturn $.Deferred().reject().promise();\n\t\t}\n\t}\n\n\t// Check browser validity and reject if it is invalid\n\tif (\n\t\tthis.$input[ 0 ].checkValidity !== undefined &&\n\t\tthis.$input[ 0 ].checkValidity() === false\n\t) {\n\t\treturn rejectOrResolve( false );\n\t}\n\n\t// Run our checks if the browser thinks the field is valid\n\tif ( this.validate instanceof Function ) {\n\t\tresult = this.validate( this.getValue() );\n\t\tif ( result && typeof result.promise === 'function' ) {\n\t\t\treturn result.promise().then( function ( valid ) {\n\t\t\t\treturn rejectOrResolve( valid );\n\t\t\t} );\n\t\t} else {\n\t\t\treturn rejectOrResolve( result );\n\t\t}\n\t} else {\n\t\treturn rejectOrResolve( this.getValue().match( this.validate ) );\n\t}\n};\n\n/**\n * Set the position of the inline label relative to that of the value: `‘before’` or `‘after’`.\n *\n * @param {string} labelPosition Label position, 'before' or 'after'\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.setLabelPosition = function ( labelPosition ) {\n\tthis.labelPosition = labelPosition;\n\tif ( this.label ) {\n\t\t// If there is no label and we only change the position, #updatePosition is a no-op,\n\t\t// but it takes really a lot of work to do nothing.\n\t\tthis.updatePosition();\n\t}\n\treturn this;\n};\n\n/**\n * Update the position of the inline label.\n *\n * This method is called by #setLabelPosition, and can also be called on its own if\n * something causes the label to be mispositioned.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.updatePosition = function () {\n\tvar after = this.labelPosition === 'after';\n\n\tthis.$element\n\t\t.toggleClass( 'oo-ui-textInputWidget-labelPosition-after', !!this.label && after )\n\t\t.toggleClass( 'oo-ui-textInputWidget-labelPosition-before', !!this.label && !after );\n\n\tthis.valCache = null;\n\tthis.scrollWidth = null;\n\tthis.positionLabel();\n\n\treturn this;\n};\n\n/**\n * Position the label by setting the correct padding on the input.\n *\n * @private\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TextInputWidget.prototype.positionLabel = function () {\n\tvar after, rtl, property, newCss;\n\n\tif ( this.isWaitingToBeAttached ) {\n\t\t// #onElementAttach will be called soon, which calls this method\n\t\treturn this;\n\t}\n\n\tnewCss = {\n\t\t'padding-right': '',\n\t\t'padding-left': ''\n\t};\n\n\tif ( this.label ) {\n\t\tthis.$element.append( this.$label );\n\t} else {\n\t\tthis.$label.detach();\n\t\t// Clear old values if present\n\t\tthis.$input.css( newCss );\n\t\treturn;\n\t}\n\n\tafter = this.labelPosition === 'after';\n\trtl = this.$element.css( 'direction' ) === 'rtl';\n\tproperty = after === rtl ? 'padding-left' : 'padding-right';\n\n\tnewCss[ property ] = this.$label.outerWidth( true ) + ( after ? this.scrollWidth : 0 );\n\t// We have to clear the padding on the other side, in case the element direction changed\n\tthis.$input.css( newCss );\n\n\treturn this;\n};\n","/**\n * SearchInputWidgets are TextInputWidgets with `type=\"search\"` assigned and feature a\n * {@link OO.ui.mixin.IconElement search icon} by default.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs#SearchInputWidget\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.SearchInputWidget = function OoUiSearchInputWidget( config ) {\n\tconfig = $.extend( {\n\t\ticon: 'search'\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.SearchInputWidget.parent.call( this, config );\n\n\t// Events\n\tthis.connect( this, {\n\t\tchange: 'onChange'\n\t} );\n\tthis.$indicator.on( 'click', this.onIndicatorClick.bind( this ) );\n\n\t// Initialization\n\tthis.updateSearchIndicator();\n\tthis.connect( this, {\n\t\tdisable: 'onDisable'\n\t} );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SearchInputWidget, OO.ui.TextInputWidget );\n\n/* Methods */\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.SearchInputWidget.prototype.getSaneType = function () {\n\treturn 'search';\n};\n\n/**\n * Handle click events on the indicator\n *\n * @param {jQuery.Event} e Click event\n * @return {boolean}\n */\nOO.ui.SearchInputWidget.prototype.onIndicatorClick = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\t// Clear the text field\n\t\tthis.setValue( '' );\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Update the 'clear' indicator displayed on type: 'search' text\n * fields, hiding it when the field is already empty or when it's not\n * editable.\n */\nOO.ui.SearchInputWidget.prototype.updateSearchIndicator = function () {\n\tif ( this.getValue() === '' || this.isDisabled() || this.isReadOnly() ) {\n\t\tthis.setIndicator( null );\n\t} else {\n\t\tthis.setIndicator( 'clear' );\n\t}\n};\n\n/**\n * Handle change events.\n *\n * @private\n */\nOO.ui.SearchInputWidget.prototype.onChange = function () {\n\tthis.updateSearchIndicator();\n};\n\n/**\n * Handle disable events.\n *\n * @param {boolean} disabled Element is disabled\n * @private\n */\nOO.ui.SearchInputWidget.prototype.onDisable = function () {\n\tthis.updateSearchIndicator();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SearchInputWidget.prototype.setReadOnly = function ( state ) {\n\tOO.ui.SearchInputWidget.parent.prototype.setReadOnly.call( this, state );\n\tthis.updateSearchIndicator();\n\treturn this;\n};\n","/**\n * MultilineTextInputWidgets, like HTML textareas, are featuring customization options to\n * configure number of rows visible. In addition, these widgets can be autosized to fit user\n * inputs and can show {@link OO.ui.mixin.IconElement icons} and\n * {@link OO.ui.mixin.IndicatorElement indicators}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n *     @example\n *     // A MultilineTextInputWidget.\n *     var multilineTextInput = new OO.ui.MultilineTextInputWidget( {\n *         value: 'Text input on multiple lines'\n *     } );\n *     $( document.body ).append( multilineTextInput.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs#MultilineTextInputWidget\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number} [rows] Number of visible lines in textarea. If used with `autosize`,\n *  specifies minimum number of rows to display.\n * @cfg {boolean} [autosize=false] Automatically resize the text input to fit its content.\n *  Use the #maxRows config to specify a maximum number of displayed rows.\n * @cfg {number} [maxRows] Maximum number of rows to display when #autosize is set to true.\n *  Defaults to the maximum of `10` and `2 * rows`, or `10` if `rows` isn't provided.\n */\nOO.ui.MultilineTextInputWidget = function OoUiMultilineTextInputWidget( config ) {\n\tconfig = $.extend( {\n\t\ttype: 'text'\n\t}, config );\n\t// Parent constructor\n\tOO.ui.MultilineTextInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.autosize = !!config.autosize;\n\tthis.styleHeight = null;\n\tthis.minRows = config.rows !== undefined ? config.rows : '';\n\tthis.maxRows = config.maxRows || Math.max( 2 * ( this.minRows || 0 ), 10 );\n\n\t// Clone for resizing\n\tif ( this.autosize ) {\n\t\tthis.$clone = this.$input\n\t\t\t.clone()\n\t\t\t.removeAttr( 'id' )\n\t\t\t.removeAttr( 'name' )\n\t\t\t.insertAfter( this.$input )\n\t\t\t.attr( 'aria-hidden', 'true' )\n\t\t\t.addClass( 'oo-ui-element-hidden' );\n\t}\n\n\t// Events\n\tthis.connect( this, {\n\t\tchange: 'onChange'\n\t} );\n\n\t// Initialization\n\tif ( config.rows ) {\n\t\tthis.$input.attr( 'rows', config.rows );\n\t}\n\tif ( this.autosize ) {\n\t\tthis.$input.addClass( 'oo-ui-textInputWidget-autosized' );\n\t\tthis.isWaitingToBeAttached = true;\n\t\tthis.installParentChangeDetector();\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MultilineTextInputWidget, OO.ui.TextInputWidget );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.static.gatherPreInfuseState = function ( node, config ) {\n\tvar state = OO.ui.MultilineTextInputWidget.parent.static.gatherPreInfuseState( node, config );\n\tstate.scrollTop = config.$input.scrollTop();\n\treturn state;\n};\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.prototype.onElementAttach = function () {\n\tOO.ui.MultilineTextInputWidget.parent.prototype.onElementAttach.call( this );\n\tthis.adjustSize();\n};\n\n/**\n * Handle change events.\n *\n * @private\n */\nOO.ui.MultilineTextInputWidget.prototype.onChange = function () {\n\tthis.adjustSize();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.prototype.updatePosition = function () {\n\tOO.ui.MultilineTextInputWidget.parent.prototype.updatePosition.call( this );\n\tthis.adjustSize();\n};\n\n/**\n * @inheritdoc\n *\n * Modify to emit 'enter' on Ctrl/Meta+Enter, instead of plain Enter\n */\nOO.ui.MultilineTextInputWidget.prototype.onKeyPress = function ( e ) {\n\tif (\n\t\t( e.which === OO.ui.Keys.ENTER && ( e.ctrlKey || e.metaKey ) ) ||\n\t\t// Some platforms emit keycode 10 for Control+Enter keypress in a textarea\n\t\te.which === 10\n\t) {\n\t\tthis.emit( 'enter', e );\n\t}\n};\n\n/**\n * Automatically adjust the size of the text input.\n *\n * This only affects multiline inputs that are {@link #autosize autosized}.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n * @fires resize\n */\nOO.ui.MultilineTextInputWidget.prototype.adjustSize = function () {\n\tvar scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError,\n\t\tidealHeight, newHeight, scrollWidth, property;\n\n\tif ( this.$input.val() !== this.valCache ) {\n\t\tif ( this.autosize ) {\n\t\t\tthis.$clone\n\t\t\t\t.val( this.$input.val() )\n\t\t\t\t.attr( 'rows', this.minRows )\n\t\t\t\t// Set inline height property to 0 to measure scroll height\n\t\t\t\t.css( 'height', 0 );\n\n\t\t\tthis.$clone.removeClass( 'oo-ui-element-hidden' );\n\n\t\t\tthis.valCache = this.$input.val();\n\n\t\t\tscrollHeight = this.$clone[ 0 ].scrollHeight;\n\n\t\t\t// Remove inline height property to measure natural heights\n\t\t\tthis.$clone.css( 'height', '' );\n\t\t\tinnerHeight = this.$clone.innerHeight();\n\t\t\touterHeight = this.$clone.outerHeight();\n\n\t\t\t// Measure max rows height\n\t\t\tthis.$clone\n\t\t\t\t.attr( 'rows', this.maxRows )\n\t\t\t\t.css( 'height', 'auto' )\n\t\t\t\t.val( '' );\n\t\t\tmaxInnerHeight = this.$clone.innerHeight();\n\n\t\t\t// Difference between reported innerHeight and scrollHeight with no scrollbars present.\n\t\t\t// This is sometimes non-zero on Blink-based browsers, depending on zoom level.\n\t\t\tmeasurementError = maxInnerHeight - this.$clone[ 0 ].scrollHeight;\n\t\t\tidealHeight = Math.min( maxInnerHeight, scrollHeight + measurementError );\n\n\t\t\tthis.$clone.addClass( 'oo-ui-element-hidden' );\n\n\t\t\t// Only apply inline height when expansion beyond natural height is needed\n\t\t\t// Use the difference between the inner and outer height as a buffer\n\t\t\tnewHeight = idealHeight > innerHeight ? idealHeight + ( outerHeight - innerHeight ) : '';\n\t\t\tif ( newHeight !== this.styleHeight ) {\n\t\t\t\tthis.$input.css( 'height', newHeight );\n\t\t\t\tthis.styleHeight = newHeight;\n\t\t\t\tthis.emit( 'resize' );\n\t\t\t}\n\t\t}\n\t\tscrollWidth = this.$input[ 0 ].offsetWidth - this.$input[ 0 ].clientWidth;\n\t\tif ( scrollWidth !== this.scrollWidth ) {\n\t\t\tproperty = this.$element.css( 'direction' ) === 'rtl' ? 'left' : 'right';\n\t\t\t// Reset\n\t\t\tthis.$label.css( { right: '', left: '' } );\n\t\t\tthis.$indicator.css( { right: '', left: '' } );\n\n\t\t\tif ( scrollWidth ) {\n\t\t\t\tthis.$indicator.css( property, scrollWidth );\n\t\t\t\tif ( this.labelPosition === 'after' ) {\n\t\t\t\t\tthis.$label.css( property, scrollWidth );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.scrollWidth = scrollWidth;\n\t\t\tthis.positionLabel();\n\t\t}\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n * @protected\n */\nOO.ui.MultilineTextInputWidget.prototype.getInputElement = function () {\n\treturn $( '<textarea>' );\n};\n\n/**\n * Check if the input automatically adjusts its size.\n *\n * @return {boolean}\n */\nOO.ui.MultilineTextInputWidget.prototype.isAutosizing = function () {\n\treturn !!this.autosize;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MultilineTextInputWidget.prototype.restorePreInfuseState = function ( state ) {\n\tOO.ui.MultilineTextInputWidget.parent.prototype.restorePreInfuseState.call( this, state );\n\tif ( state.scrollTop !== undefined ) {\n\t\tthis.$input.scrollTop( state.scrollTop );\n\t}\n};\n","/**\n * ComboBoxInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value\n * can be entered manually) and a {@link OO.ui.MenuSelectWidget menu of options} (from which\n * a value can be chosen instead). Users can choose options from the combo box in one of two ways:\n *\n * - by typing a value in the text input field. If the value exactly matches the value of a menu\n *   option, that option will appear to be selected.\n * - by choosing a value from the menu. The value of the chosen option will then appear in the text\n *   input field.\n *\n * After the user chooses an option, its `data` will be used as a new value for the widget.\n * A `label` also can be specified for each option: if given, it will be shown instead of the\n * `data` in the dropdown menu.\n *\n * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.\n *\n * For more information about menus and options, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // A ComboBoxInputWidget.\n *     var comboBox = new OO.ui.ComboBoxInputWidget( {\n *         value: 'Option 1',\n *         options: [\n *             { data: 'Option 1' },\n *             { data: 'Option 2' },\n *             { data: 'Option 3' }\n *         ]\n *     } );\n *     $( document.body ).append( comboBox.$element );\n *\n *     @example\n *     // Example: A ComboBoxInputWidget with additional option labels.\n *     var comboBox = new OO.ui.ComboBoxInputWidget( {\n *         value: 'Option 1',\n *         options: [\n *             {\n *                 data: 'Option 1',\n *                 label: 'Option One'\n *             },\n *             {\n *                 data: 'Option 2',\n *                 label: 'Option Two'\n *             },\n *             {\n *                 data: 'Option 3',\n *                 label: 'Option Three'\n *             }\n *         ]\n *     } );\n *     $( document.body ).append( comboBox.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Menu_selects_and_options\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`\n * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.MenuSelectWidget menu\n *  select widget}.\n * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful\n *  in cases where the expanded menu is larger than its containing `<div>`. The specified overlay\n *  layer is usually on top of the containing `<div>` and has a larger area. By default, the menu\n *  uses relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tautocomplete: false\n\t}, config );\n\n\t// ComboBoxInputWidget shouldn't support `multiline`\n\tconfig.multiline = false;\n\n\t// See InputWidget#reusePreInfuseDOM about `config.$input`\n\tif ( config.$input ) {\n\t\tconfig.$input.removeAttr( 'list' );\n\t}\n\n\t// Parent constructor\n\tOO.ui.ComboBoxInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.$overlay = ( config.$overlay === true ?\n\t\tOO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.dropdownButton = new OO.ui.ButtonWidget( {\n\t\tclasses: [ 'oo-ui-comboBoxInputWidget-dropdownButton' ],\n\t\tlabel: OO.ui.msg( 'ooui-combobox-button-label' ),\n\t\tindicator: 'down',\n\t\tinvisibleLabel: true,\n\t\tdisabled: this.disabled\n\t} );\n\tthis.menu = new OO.ui.MenuSelectWidget( $.extend(\n\t\t{\n\t\t\twidget: this,\n\t\t\tinput: this,\n\t\t\t$floatableContainer: this.$element,\n\t\t\tdisabled: this.isDisabled()\n\t\t},\n\t\tconfig.menu\n\t) );\n\n\t// Events\n\tthis.connect( this, {\n\t\tchange: 'onInputChange',\n\t\tenter: 'onInputEnter'\n\t} );\n\tthis.dropdownButton.connect( this, {\n\t\tclick: 'onDropdownButtonClick'\n\t} );\n\tthis.menu.connect( this, {\n\t\tchoose: 'onMenuChoose',\n\t\tadd: 'onMenuItemsChange',\n\t\tremove: 'onMenuItemsChange',\n\t\ttoggle: 'onMenuToggle'\n\t} );\n\n\t// Initialization\n\tthis.$input.attr( {\n\t\trole: 'combobox',\n\t\t'aria-owns': this.menu.getElementId(),\n\t\t'aria-autocomplete': 'list'\n\t} );\n\tthis.dropdownButton.$button.attr( {\n\t\t'aria-controls': this.menu.getElementId()\n\t} );\n\t// Do not override options set via config.menu.items\n\tif ( config.options !== undefined ) {\n\t\tthis.setOptions( config.options );\n\t}\n\tthis.$field = $( '<div>' )\n\t\t.addClass( 'oo-ui-comboBoxInputWidget-field' )\n\t\t.append( this.$input, this.dropdownButton.$element );\n\tthis.$element\n\t\t.addClass( 'oo-ui-comboBoxInputWidget' )\n\t\t.append( this.$field );\n\tthis.$overlay.append( this.menu.$element );\n\tthis.onMenuItemsChange();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ComboBoxInputWidget, OO.ui.TextInputWidget );\n\n/* Methods */\n\n/**\n * Get the combobox's menu.\n *\n * @return {OO.ui.MenuSelectWidget} Menu widget\n */\nOO.ui.ComboBoxInputWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Get the combobox's text input widget.\n *\n * @return {OO.ui.TextInputWidget} Text input widget\n */\nOO.ui.ComboBoxInputWidget.prototype.getInput = function () {\n\treturn this;\n};\n\n/**\n * Handle input change events.\n *\n * @private\n * @param {string} value New value\n */\nOO.ui.ComboBoxInputWidget.prototype.onInputChange = function ( value ) {\n\tvar match = this.menu.findItemFromData( value );\n\n\tthis.menu.selectItem( match );\n\tif ( this.menu.findHighlightedItem() ) {\n\t\tthis.menu.highlightItem( match );\n\t}\n\n\tif ( !this.isDisabled() ) {\n\t\tthis.menu.toggle( true );\n\t}\n};\n\n/**\n * Handle input enter events.\n *\n * @private\n */\nOO.ui.ComboBoxInputWidget.prototype.onInputEnter = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.menu.toggle( false );\n\t}\n};\n\n/**\n * Handle button click events.\n *\n * @private\n */\nOO.ui.ComboBoxInputWidget.prototype.onDropdownButtonClick = function () {\n\tthis.menu.toggle();\n\tthis.focus();\n};\n\n/**\n * Handle menu choose events.\n *\n * @private\n * @param {OO.ui.OptionWidget} item Chosen item\n */\nOO.ui.ComboBoxInputWidget.prototype.onMenuChoose = function ( item ) {\n\tthis.setValue( item.getData() );\n};\n\n/**\n * Handle menu item change events.\n *\n * @private\n */\nOO.ui.ComboBoxInputWidget.prototype.onMenuItemsChange = function () {\n\tvar match = this.menu.findItemFromData( this.getValue() );\n\tthis.menu.selectItem( match );\n\tif ( this.menu.findHighlightedItem() ) {\n\t\tthis.menu.highlightItem( match );\n\t}\n\tthis.$element.toggleClass( 'oo-ui-comboBoxInputWidget-empty', this.menu.isEmpty() );\n};\n\n/**\n * Handle menu toggle events.\n *\n * @private\n * @param {boolean} isVisible Open state of the menu\n */\nOO.ui.ComboBoxInputWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tthis.$element.toggleClass( 'oo-ui-comboBoxInputWidget-open', isVisible );\n};\n\n/**\n * Update the disabled state of the controls\n *\n * @chainable\n * @protected\n * @return {OO.ui.ComboBoxInputWidget} The widget, for chaining\n */\nOO.ui.ComboBoxInputWidget.prototype.updateControlsDisabled = function () {\n\tvar disabled = this.isDisabled() || this.isReadOnly();\n\tif ( this.dropdownButton ) {\n\t\tthis.dropdownButton.setDisabled( disabled );\n\t}\n\tif ( this.menu ) {\n\t\tthis.menu.setDisabled( disabled );\n\t}\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ComboBoxInputWidget.prototype.setDisabled = function () {\n\t// Parent method\n\tOO.ui.ComboBoxInputWidget.parent.prototype.setDisabled.apply( this, arguments );\n\tthis.updateControlsDisabled();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ComboBoxInputWidget.prototype.setReadOnly = function () {\n\t// Parent method\n\tOO.ui.ComboBoxInputWidget.parent.prototype.setReadOnly.apply( this, arguments );\n\tthis.updateControlsDisabled();\n\treturn this;\n};\n\n/**\n * Set the options available for this input.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {\n\tthis.getMenu()\n\t\t.clearItems()\n\t\t.addItems( options.map( function ( opt ) {\n\t\t\treturn new OO.ui.MenuOptionWidget( {\n\t\t\t\tdata: opt.data,\n\t\t\t\tlabel: opt.label !== undefined ? opt.label : opt.data\n\t\t\t} );\n\t\t} ) );\n\n\treturn this;\n};\n","/**\n * FieldLayouts are used with OO.ui.FieldsetLayout. Each FieldLayout requires a field-widget,\n * which is a widget that is specified by reference before any optional configuration settings.\n *\n * Field layouts can be configured with help text and/or labels. Labels are aligned in one of\n * four ways:\n *\n * - **left**: The label is placed before the field-widget and aligned with the left margin.\n *   A left-alignment is used for forms with many fields.\n * - **right**: The label is placed before the field-widget and aligned to the right margin.\n *   A right-alignment is used for long but familiar forms which users tab through,\n *   verifying the current field with a quick glance at the label.\n * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms\n *   that users fill out from top to bottom.\n * - **inline**: The label is placed after the field-widget and aligned to the left.\n *   An inline-alignment is best used with checkboxes or radio buttons.\n *\n * Help text can either be:\n *\n * - accessed via a help icon that appears in the upper right corner of the rendered field layout,\n *   or\n * - shown as a subtle explanation below the label.\n *\n * If the help text is brief, or is essential to always expose it, set `helpInline` to `true`.\n * If it is long or not essential, leave `helpInline` to its default, `false`.\n *\n * Please see the [OOUI documentation on MediaWiki] [1] for examples and more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Layouts/Fields_and_Fieldsets\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {OO.ui.Widget} fieldWidget Field widget\n * @param {Object} [config] Configuration options\n * @cfg {string} [align='left'] Alignment of the label: 'left', 'right', 'top'\n *  or 'inline'\n * @cfg {Array} [errors] Error messages about the widget, which will be\n *  displayed below the widget.\n * @cfg {Array} [warnings] Warning messages about the widget, which will be\n *  displayed below the widget.\n * @cfg {Array} [successMessages] Success messages on user interactions with the widget,\n *  which will be displayed below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @cfg {Array} [notices] Notices about the widget, which will be displayed\n *  below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n *  These are more visible than `help` messages when `helpInline` is set, and so\n *  might be good for transient messages.\n * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified\n *  and `helpInline` is `false`, a \"help\" icon will appear in the upper-right\n *  corner of the rendered field; clicking it will display the text in a popup.\n *  If `helpInline` is `true`, then a subtle description will be shown after the\n *  label.\n * @cfg {boolean} [helpInline=false] Whether or not the help should be inline,\n *  or shown when the \"help\" icon is clicked.\n * @cfg {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup, if\n * `help` is given.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n *\n * @throws {Error} An error is thrown if no widget is specified\n */\nOO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( fieldWidget ) && config === undefined ) {\n\t\tconfig = fieldWidget;\n\t\tfieldWidget = config.fieldWidget;\n\t}\n\n\t// Make sure we have required constructor arguments\n\tif ( fieldWidget === undefined ) {\n\t\tthrow new Error( 'Widget not found' );\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( { align: 'left', helpInline: false }, config );\n\n\t// Parent constructor\n\tOO.ui.FieldLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.LabelElement.call( this, $.extend( {\n\t\t$label: $( '<label>' )\n\t}, config ) );\n\tOO.ui.mixin.TitledElement.call( this, $.extend( { $titled: this.$label }, config ) );\n\n\t// Properties\n\tthis.fieldWidget = fieldWidget;\n\tthis.errors = [];\n\tthis.warnings = [];\n\tthis.successMessages = [];\n\tthis.notices = [];\n\tthis.$field = this.isFieldInline() ? $( '<span>' ) : $( '<div>' );\n\tthis.$messages = $( '<ul>' );\n\tthis.$header = $( '<span>' );\n\tthis.$body = $( '<div>' );\n\tthis.align = null;\n\tthis.helpInline = config.helpInline;\n\n\t// Events\n\tthis.fieldWidget.connect( this, {\n\t\tdisable: 'onFieldDisable'\n\t} );\n\n\t// Initialization\n\tthis.$help = config.help ?\n\t\tthis.createHelpElement( config.help, config.$overlay ) :\n\t\t$( [] );\n\tif ( this.fieldWidget.getInputId() ) {\n\t\tthis.$label.attr( 'for', this.fieldWidget.getInputId() );\n\t\tif ( this.helpInline ) {\n\t\t\tthis.$help.attr( 'for', this.fieldWidget.getInputId() );\n\t\t}\n\t} else {\n\t\tthis.$label.on( 'click', function () {\n\t\t\tthis.fieldWidget.simulateLabelClick();\n\t\t}.bind( this ) );\n\t\tif ( this.helpInline ) {\n\t\t\tthis.$help.on( 'click', function () {\n\t\t\t\tthis.fieldWidget.simulateLabelClick();\n\t\t\t}.bind( this ) );\n\t\t}\n\t}\n\tthis.$element\n\t\t.addClass( 'oo-ui-fieldLayout' )\n\t\t.toggleClass( 'oo-ui-fieldLayout-disabled', this.fieldWidget.isDisabled() )\n\t\t.append( this.$body );\n\tthis.$body.addClass( 'oo-ui-fieldLayout-body' );\n\tthis.$header.addClass( 'oo-ui-fieldLayout-header' );\n\tthis.$messages.addClass( 'oo-ui-fieldLayout-messages' );\n\tthis.$field\n\t\t.addClass( 'oo-ui-fieldLayout-field' )\n\t\t.append( this.fieldWidget.$element );\n\n\tthis.setErrors( config.errors || [] );\n\tthis.setWarnings( config.warnings || [] );\n\tthis.setSuccess( config.successMessages || [] );\n\tthis.setNotices( config.notices || [] );\n\tthis.setAlignment( config.align );\n\t// Call this again to take into account the widget's accessKey\n\tthis.updateTitle();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.FieldLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.TitledElement );\n\n/* Methods */\n\n/**\n * Handle field disable events.\n *\n * @private\n * @param {boolean} value Field is disabled\n */\nOO.ui.FieldLayout.prototype.onFieldDisable = function ( value ) {\n\tthis.$element.toggleClass( 'oo-ui-fieldLayout-disabled', value );\n};\n\n/**\n * Get the widget contained by the field.\n *\n * @return {OO.ui.Widget} Field widget\n */\nOO.ui.FieldLayout.prototype.getField = function () {\n\treturn this.fieldWidget;\n};\n\n/**\n * Return `true` if the given field widget can be used with `'inline'` alignment (see\n * #setAlignment). Return `false` if it can't or if this can't be determined.\n *\n * @return {boolean}\n */\nOO.ui.FieldLayout.prototype.isFieldInline = function () {\n\t// This is very simplistic, but should be good enough.\n\treturn this.getField().$element.prop( 'tagName' ).toLowerCase() === 'span';\n};\n\n/**\n * @protected\n * @param {string} kind 'error' or 'notice'\n * @param {string|OO.ui.HtmlSnippet} text\n * @return {jQuery}\n */\nOO.ui.FieldLayout.prototype.makeMessage = function ( kind, text ) {\n\tvar $listItem, $icon, message;\n\t$listItem = $( '<li>' );\n\tif ( kind === 'error' ) {\n\t\t$icon = new OO.ui.IconWidget( { icon: 'alert', flags: [ 'error' ] } ).$element;\n\t\t$listItem.attr( 'role', 'alert' );\n\t} else if ( kind === 'warning' ) {\n\t\t$icon = new OO.ui.IconWidget( { icon: 'alert', flags: [ 'warning' ] } ).$element;\n\t\t$listItem.attr( 'role', 'alert' );\n\t} else if ( kind === 'success' ) {\n\t\t$icon = new OO.ui.IconWidget( { icon: 'check', flags: [ 'success' ] } ).$element;\n\t} else if ( kind === 'notice' ) {\n\t\t$icon = new OO.ui.IconWidget( { icon: 'notice' } ).$element;\n\t} else {\n\t\t$icon = '';\n\t}\n\tmessage = new OO.ui.LabelWidget( { label: text } );\n\t$listItem\n\t\t.append( $icon, message.$element )\n\t\t.addClass( 'oo-ui-fieldLayout-messages-' + kind );\n\treturn $listItem;\n};\n\n/**\n * Set the field alignment mode.\n *\n * @private\n * @param {string} value Alignment mode, either 'left', 'right', 'top' or 'inline'\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setAlignment = function ( value ) {\n\tif ( value !== this.align ) {\n\t\t// Default to 'left'\n\t\tif ( [ 'left', 'right', 'top', 'inline' ].indexOf( value ) === -1 ) {\n\t\t\tvalue = 'left';\n\t\t}\n\t\t// Validate\n\t\tif ( value === 'inline' && !this.isFieldInline() ) {\n\t\t\tvalue = 'top';\n\t\t}\n\t\t// Reorder elements\n\n\t\tif ( this.helpInline ) {\n\t\t\tif ( value === 'top' ) {\n\t\t\t\tthis.$header.append( this.$label );\n\t\t\t\tthis.$body.append( this.$header, this.$field, this.$help );\n\t\t\t} else if ( value === 'inline' ) {\n\t\t\t\tthis.$header.append( this.$label, this.$help );\n\t\t\t\tthis.$body.append( this.$field, this.$header );\n\t\t\t} else {\n\t\t\t\tthis.$header.append( this.$label, this.$help );\n\t\t\t\tthis.$body.append( this.$header, this.$field );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( value === 'top' ) {\n\t\t\t\tthis.$header.append( this.$help, this.$label );\n\t\t\t\tthis.$body.append( this.$header, this.$field );\n\t\t\t} else if ( value === 'inline' ) {\n\t\t\t\tthis.$header.append( this.$help, this.$label );\n\t\t\t\tthis.$body.append( this.$field, this.$header );\n\t\t\t} else {\n\t\t\t\tthis.$header.append( this.$label );\n\t\t\t\tthis.$body.append( this.$header, this.$help, this.$field );\n\t\t\t}\n\t\t}\n\t\t// Set classes. The following classes can be used here:\n\t\t// * oo-ui-fieldLayout-align-left\n\t\t// * oo-ui-fieldLayout-align-right\n\t\t// * oo-ui-fieldLayout-align-top\n\t\t// * oo-ui-fieldLayout-align-inline\n\t\tif ( this.align ) {\n\t\t\tthis.$element.removeClass( 'oo-ui-fieldLayout-align-' + this.align );\n\t\t}\n\t\tthis.$element.addClass( 'oo-ui-fieldLayout-align-' + value );\n\t\tthis.align = value;\n\t}\n\n\treturn this;\n};\n\n/**\n * Set the list of error messages.\n *\n * @param {Array} errors Error messages about the widget, which will be displayed below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setErrors = function ( errors ) {\n\tthis.errors = errors.slice();\n\tthis.updateMessages();\n\treturn this;\n};\n\n/**\n * Set the list of warning messages.\n *\n * @param {Array} warnings Warning messages about the widget, which will be displayed below\n *  the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setWarnings = function ( warnings ) {\n\tthis.warnings = warnings.slice();\n\tthis.updateMessages();\n\treturn this;\n};\n\n/**\n * Set the list of success messages.\n *\n * @param {Array} successMessages Success messages about the widget, which will be displayed below\n *  the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setSuccess = function ( successMessages ) {\n\tthis.successMessages = successMessages.slice();\n\tthis.updateMessages();\n\treturn this;\n};\n\n/**\n * Set the list of notice messages.\n *\n * @param {Array} notices Notices about the widget, which will be displayed below the widget.\n *  The array may contain strings or OO.ui.HtmlSnippet instances.\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.FieldLayout.prototype.setNotices = function ( notices ) {\n\tthis.notices = notices.slice();\n\tthis.updateMessages();\n\treturn this;\n};\n\n/**\n * Update the rendering of error, warning, success and notice messages.\n *\n * @private\n */\nOO.ui.FieldLayout.prototype.updateMessages = function () {\n\tvar i;\n\tthis.$messages.empty();\n\n\tif (\n\t\tthis.errors.length ||\n\t\tthis.warnings.length ||\n\t\tthis.successMessages.length ||\n\t\tthis.notices.length\n\t) {\n\t\tthis.$body.after( this.$messages );\n\t} else {\n\t\tthis.$messages.remove();\n\t\treturn;\n\t}\n\n\tfor ( i = 0; i < this.errors.length; i++ ) {\n\t\tthis.$messages.append( this.makeMessage( 'error', this.errors[ i ] ) );\n\t}\n\tfor ( i = 0; i < this.warnings.length; i++ ) {\n\t\tthis.$messages.append( this.makeMessage( 'warning', this.warnings[ i ] ) );\n\t}\n\tfor ( i = 0; i < this.successMessages.length; i++ ) {\n\t\tthis.$messages.append( this.makeMessage( 'success', this.successMessages[ i ] ) );\n\t}\n\tfor ( i = 0; i < this.notices.length; i++ ) {\n\t\tthis.$messages.append( this.makeMessage( 'notice', this.notices[ i ] ) );\n\t}\n};\n\n/**\n * Include information about the widget's accessKey in our title. TitledElement calls this method.\n * (This is a bit of a hack.)\n *\n * @protected\n * @param {string} title Tooltip label for 'title' attribute\n * @return {string}\n */\nOO.ui.FieldLayout.prototype.formatTitleWithAccessKey = function ( title ) {\n\tif ( this.fieldWidget && this.fieldWidget.formatTitleWithAccessKey ) {\n\t\treturn this.fieldWidget.formatTitleWithAccessKey( title );\n\t}\n\treturn title;\n};\n\n/**\n * Creates and returns the help element. Also sets the `aria-describedby`\n * attribute on the main element of the `fieldWidget`.\n *\n * @private\n * @param {string|OO.ui.HtmlSnippet} [help] Help text.\n * @param {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup.\n * @return {jQuery} The element that should become `this.$help`.\n */\nOO.ui.FieldLayout.prototype.createHelpElement = function ( help, $overlay ) {\n\tvar helpId, helpWidget;\n\n\tif ( this.helpInline ) {\n\t\thelpWidget = new OO.ui.LabelWidget( {\n\t\t\tlabel: help,\n\t\t\tclasses: [ 'oo-ui-inline-help' ]\n\t\t} );\n\n\t\thelpId = helpWidget.getElementId();\n\t} else {\n\t\thelpWidget = new OO.ui.PopupButtonWidget( {\n\t\t\t$overlay: $overlay,\n\t\t\tpopup: {\n\t\t\t\tpadded: true\n\t\t\t},\n\t\t\tclasses: [ 'oo-ui-fieldLayout-help' ],\n\t\t\tframed: false,\n\t\t\ticon: 'info',\n\t\t\tlabel: OO.ui.msg( 'ooui-field-help' ),\n\t\t\tinvisibleLabel: true\n\t\t} );\n\t\tif ( help instanceof OO.ui.HtmlSnippet ) {\n\t\t\thelpWidget.getPopup().$body.html( help.toString() );\n\t\t} else {\n\t\t\thelpWidget.getPopup().$body.text( help );\n\t\t}\n\n\t\thelpId = helpWidget.getPopup().getBodyId();\n\t}\n\n\t// Set the 'aria-describedby' attribute on the fieldWidget\n\t// Preference given to an input or a button\n\t(\n\t\tthis.fieldWidget.$input ||\n\t\tthis.fieldWidget.$button ||\n\t\tthis.fieldWidget.$element\n\t).attr( 'aria-describedby', helpId );\n\n\treturn helpWidget.$element;\n};\n","/**\n * ActionFieldLayouts are used with OO.ui.FieldsetLayout. The layout consists of a field-widget,\n * a button, and an optional label and/or help text. The field-widget (e.g., a\n * {@link OO.ui.TextInputWidget TextInputWidget}), is required and is specified before any optional\n * configuration settings.\n *\n * Labels can be aligned in one of four ways:\n *\n * - **left**: The label is placed before the field-widget and aligned with the left margin.\n *   A left-alignment is used for forms with many fields.\n * - **right**: The label is placed before the field-widget and aligned to the right margin.\n *   A right-alignment is used for long but familiar forms which users tab through,\n *   verifying the current field with a quick glance at the label.\n * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms\n *   that users fill out from top to bottom.\n * - **inline**: The label is placed after the field-widget and aligned to the left.\n *   An inline-alignment is best used with checkboxes or radio buttons.\n *\n * Help text is accessed via a help icon that appears in the upper right corner of the rendered\n * field layout when help text is specified.\n *\n *     @example\n *     // Example of an ActionFieldLayout\n *     var actionFieldLayout = new OO.ui.ActionFieldLayout(\n *         new OO.ui.TextInputWidget( {\n *             placeholder: 'Field widget'\n *         } ),\n *         new OO.ui.ButtonWidget( {\n *             label: 'Button'\n *         } ),\n *         {\n *             label: 'An ActionFieldLayout. This label is aligned top',\n *             align: 'top',\n *             help: 'This is help text'\n *         }\n *     );\n *\n *     $( document.body ).append( actionFieldLayout.$element );\n *\n * @class\n * @extends OO.ui.FieldLayout\n *\n * @constructor\n * @param {OO.ui.Widget} fieldWidget Field widget\n * @param {OO.ui.ButtonWidget} buttonWidget Button widget\n * @param {Object} config\n */\nOO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWidget, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( fieldWidget ) && config === undefined ) {\n\t\tconfig = fieldWidget;\n\t\tfieldWidget = config.fieldWidget;\n\t\tbuttonWidget = config.buttonWidget;\n\t}\n\n\t// Parent constructor\n\tOO.ui.ActionFieldLayout.parent.call( this, fieldWidget, config );\n\n\t// Properties\n\tthis.buttonWidget = buttonWidget;\n\tthis.$button = $( '<span>' );\n\tthis.$input = this.isFieldInline() ? $( '<span>' ) : $( '<div>' );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-actionFieldLayout' );\n\tthis.$button\n\t\t.addClass( 'oo-ui-actionFieldLayout-button' )\n\t\t.append( this.buttonWidget.$element );\n\tthis.$input\n\t\t.addClass( 'oo-ui-actionFieldLayout-input' )\n\t\t.append( this.fieldWidget.$element );\n\tthis.$field.append( this.$input, this.$button );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );\n","/**\n * FieldsetLayouts are composed of one or more {@link OO.ui.FieldLayout FieldLayouts},\n * which each contain an individual widget and, optionally, a label. Each Fieldset can be\n * configured with a label as well. For more information and examples,\n * please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Example of a fieldset layout\n *     var input1 = new OO.ui.TextInputWidget( {\n *         placeholder: 'A text input field'\n *     } );\n *\n *     var input2 = new OO.ui.TextInputWidget( {\n *         placeholder: 'A text input field'\n *     } );\n *\n *     var fieldset = new OO.ui.FieldsetLayout( {\n *         label: 'Example of a fieldset layout'\n *     } );\n *\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( input1, {\n *             label: 'Field One'\n *         } ),\n *         new OO.ui.FieldLayout( input2, {\n *             label: 'Field Two'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Layouts/Fields_and_Fieldsets\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.FieldLayout[]} [items] An array of fields to add to the fieldset.\n *  See OO.ui.FieldLayout for more information about fields.\n * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a \"help\" icon\n *  will appear in the upper-right corner of the rendered field; clicking it will display the text\n *  in a popup. For important messages, you are advised to use `notices`, as they are always shown.\n * @cfg {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup, if `help` is given.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.FieldsetLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.$header = $( '<legend>' );\n\tif ( config.help ) {\n\t\tthis.popupButtonWidget = new OO.ui.PopupButtonWidget( {\n\t\t\t$overlay: config.$overlay,\n\t\t\tpopup: {\n\t\t\t\tpadded: true\n\t\t\t},\n\t\t\tclasses: [ 'oo-ui-fieldsetLayout-help' ],\n\t\t\tframed: false,\n\t\t\ticon: 'info',\n\t\t\tlabel: OO.ui.msg( 'ooui-field-help' ),\n\t\t\tinvisibleLabel: true\n\t\t} );\n\t\tif ( config.help instanceof OO.ui.HtmlSnippet ) {\n\t\t\tthis.popupButtonWidget.getPopup().$body.html( config.help.toString() );\n\t\t} else {\n\t\t\tthis.popupButtonWidget.getPopup().$body.text( config.help );\n\t\t}\n\t\tthis.$help = this.popupButtonWidget.$element;\n\t} else {\n\t\tthis.$help = $( [] );\n\t}\n\n\t// Initialization\n\tthis.$header\n\t\t.addClass( 'oo-ui-fieldsetLayout-header' )\n\t\t.append( this.$icon, this.$label, this.$help );\n\tthis.$group.addClass( 'oo-ui-fieldsetLayout-group' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-fieldsetLayout' )\n\t\t.prepend( this.$header, this.$group );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.FieldsetLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.GroupElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.FieldsetLayout.static.tagName = 'fieldset';\n","/**\n * FormLayouts are used to wrap {@link OO.ui.FieldsetLayout FieldsetLayouts} when you intend to use\n * browser-based form submission for the fields instead of handling them in JavaScript. Form layouts\n * can be configured with an HTML form action, an encoding type, and a method using the #action,\n * #enctype, and #method configs, respectively.\n * See the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * Only widgets from the {@link OO.ui.InputWidget InputWidget} family support form submission. It\n * includes standard form elements like {@link OO.ui.CheckboxInputWidget checkboxes}, {@link\n * OO.ui.RadioInputWidget radio buttons} and {@link OO.ui.TextInputWidget text fields}, as well as\n * some fancier controls. Some controls have both regular and InputWidget variants, for example\n * OO.ui.DropdownWidget and OO.ui.DropdownInputWidget – only the latter support form submission and\n * often have simplified APIs to match the capabilities of HTML forms.\n * See the [OOUI documentation on MediaWiki] [2] for more information about InputWidgets.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Layouts/Forms\n * [2]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs\n *\n *     @example\n *     // Example of a form layout that wraps a fieldset layout.\n *     var input1 = new OO.ui.TextInputWidget( {\n *             placeholder: 'Username'\n *         } ),\n *         input2 = new OO.ui.TextInputWidget( {\n *             placeholder: 'Password',\n *             type: 'password'\n *         } ),\n *         submit = new OO.ui.ButtonInputWidget( {\n *             label: 'Submit'\n *         } ),\n *         fieldset = new OO.ui.FieldsetLayout( {\n *             label: 'A form layout'\n *         } );\n *\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( input1, {\n *             label: 'Username',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( input2, {\n *             label: 'Password',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( submit )\n *     ] );\n *     var form = new OO.ui.FormLayout( {\n *         items: [ fieldset ],\n *         action: '/api/formhandler',\n *         method: 'get'\n *     } )\n *     $( document.body ).append( form.$element );\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [method] HTML form `method` attribute\n * @cfg {string} [action] HTML form `action` attribute\n * @cfg {string} [enctype] HTML form `enctype` attribute\n * @cfg {OO.ui.FieldsetLayout[]} [items] Fieldset layouts to add to the form layout.\n */\nOO.ui.FormLayout = function OoUiFormLayout( config ) {\n\tvar action;\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.FormLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( { $group: this.$element }, config ) );\n\n\t// Events\n\tthis.$element.on( 'submit', this.onFormSubmit.bind( this ) );\n\n\t// Make sure the action is safe\n\taction = config.action;\n\tif ( action !== undefined && !OO.ui.isSafeUrl( action ) ) {\n\t\taction = './' + action;\n\t}\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-formLayout' )\n\t\t.attr( {\n\t\t\tmethod: config.method,\n\t\t\taction: action,\n\t\t\tenctype: config.enctype\n\t\t} );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.FormLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.FormLayout, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * A 'submit' event is emitted when the form is submitted.\n *\n * @event submit\n */\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.FormLayout.static.tagName = 'form';\n\n/* Methods */\n\n/**\n * Handle form submit events.\n *\n * @private\n * @param {jQuery.Event} e Submit event\n * @fires submit\n * @return {OO.ui.FormLayout} The layout, for chaining\n */\nOO.ui.FormLayout.prototype.onFormSubmit = function () {\n\tif ( this.emit( 'submit' ) ) {\n\t\treturn false;\n\t}\n};\n","/**\n * PanelLayouts expand to cover the entire area of their parent. They can be configured with\n * scrolling, padding, and a frame, and are often used together with\n * {@link OO.ui.StackLayout StackLayouts}.\n *\n *     @example\n *     // Example of a panel layout\n *     var panel = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true,\n *         padded: true,\n *         $content: $( '<p>A panel layout with padding and a frame.</p>' )\n *     } );\n *     $( document.body ).append( panel.$element );\n *\n * @class\n * @extends OO.ui.Layout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [scrollable=false] Allow vertical scrolling\n * @cfg {boolean} [padded=false] Add padding between the content and the edges of the panel.\n * @cfg {boolean} [expanded=true] Expand the panel to fill the entire parent element.\n * @cfg {boolean} [framed=false] Render the panel with a frame to visually separate it from outside\n *  content.\n */\nOO.ui.PanelLayout = function OoUiPanelLayout( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tscrollable: false,\n\t\tpadded: false,\n\t\texpanded: true,\n\t\tframed: false\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.PanelLayout.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-panelLayout' );\n\tif ( config.scrollable ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-scrollable' );\n\t}\n\tif ( config.padded ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-padded' );\n\t}\n\tif ( config.expanded ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-expanded' );\n\t}\n\tif ( config.framed ) {\n\t\tthis.$element.addClass( 'oo-ui-panelLayout-framed' );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout );\n\n/* Static Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.PanelLayout.static.reusePreInfuseDOM = function ( node, config ) {\n\tconfig = OO.ui.PanelLayout.parent.static.reusePreInfuseDOM( node, config );\n\tif ( config.preserveContent !== false ) {\n\t\tconfig.$content = $( node ).contents();\n\t}\n\treturn config;\n};\n\n/* Methods */\n\n/**\n * Focus the panel layout\n *\n * The default implementation just focuses the first focusable element in the panel\n */\nOO.ui.PanelLayout.prototype.focus = function () {\n\tOO.ui.findFocusable( this.$element ).focus();\n};\n","/**\n * HorizontalLayout arranges its contents in a single line (using `display: inline-block` for its\n * items), with small margins between them. Convenient when you need to put a number of block-level\n * widgets on a single line next to each other.\n *\n * Note that inline elements, such as OO.ui.ButtonWidgets, do not need this wrapper.\n *\n *     @example\n *     // HorizontalLayout with a text input and a label.\n *     var layout = new OO.ui.HorizontalLayout( {\n *       items: [\n *         new OO.ui.LabelWidget( { label: 'Label' } ),\n *         new OO.ui.TextInputWidget( { value: 'Text' } )\n *       ]\n *     } );\n *     $( document.body ).append( layout.$element );\n *\n * @class\n * @extends OO.ui.Layout\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.Widget[]|OO.ui.Layout[]} [items] Widgets or other layouts to add to the layout.\n */\nOO.ui.HorizontalLayout = function OoUiHorizontalLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.HorizontalLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( { $group: this.$element }, config ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-horizontalLayout' );\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.HorizontalLayout, OO.ui.Layout );\nOO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement );\n","/**\n * NumberInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value\n * can be entered manually) and two {@link OO.ui.ButtonWidget button widgets}\n * (to adjust the value in increments) to allow the user to enter a number.\n *\n *     @example\n *     // A NumberInputWidget.\n *     var numberInput = new OO.ui.NumberInputWidget( {\n *         label: 'NumberInputWidget',\n *         input: { value: 5 },\n *         min: 1,\n *         max: 10\n *     } );\n *     $( document.body ).append( numberInput.$element );\n *\n * @class\n * @extends OO.ui.TextInputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {Object} [minusButton] Configuration options to pass to the\n *  {@link OO.ui.ButtonWidget decrementing button widget}.\n * @cfg {Object} [plusButton] Configuration options to pass to the\n *  {@link OO.ui.ButtonWidget incrementing button widget}.\n * @cfg {number} [min=-Infinity] Minimum allowed value\n * @cfg {number} [max=Infinity] Maximum allowed value\n * @cfg {number|null} [step] If specified, the field only accepts values that are multiples of this.\n * @cfg {number} [buttonStep=step||1] Delta when using the buttons or Up/Down arrow keys.\n *  Defaults to `step` if specified, otherwise `1`.\n * @cfg {number} [pageStep=10*buttonStep] Delta when using the Page-up/Page-down keys.\n *  Defaults to 10 times `buttonStep`.\n * @cfg {boolean} [showButtons=true] Whether to show the plus and minus buttons.\n */\nOO.ui.NumberInputWidget = function OoUiNumberInputWidget( config ) {\n\tvar $field = $( '<div>' ).addClass( 'oo-ui-numberInputWidget-field' );\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tmin: -Infinity,\n\t\tmax: Infinity,\n\t\tshowButtons: true\n\t}, config );\n\n\t// For backward compatibility\n\t$.extend( config, config.input );\n\tthis.input = this;\n\n\t// Parent constructor\n\tOO.ui.NumberInputWidget.parent.call( this, $.extend( config, {\n\t\ttype: 'number'\n\t} ) );\n\n\tif ( config.showButtons ) {\n\t\tthis.minusButton = new OO.ui.ButtonWidget( $.extend(\n\t\t\t{\n\t\t\t\tdisabled: this.isDisabled(),\n\t\t\t\ttabIndex: -1,\n\t\t\t\tclasses: [ 'oo-ui-numberInputWidget-minusButton' ],\n\t\t\t\ticon: 'subtract'\n\t\t\t},\n\t\t\tconfig.minusButton\n\t\t) );\n\t\tthis.minusButton.$element.attr( 'aria-hidden', 'true' );\n\t\tthis.plusButton = new OO.ui.ButtonWidget( $.extend(\n\t\t\t{\n\t\t\t\tdisabled: this.isDisabled(),\n\t\t\t\ttabIndex: -1,\n\t\t\t\tclasses: [ 'oo-ui-numberInputWidget-plusButton' ],\n\t\t\t\ticon: 'add'\n\t\t\t},\n\t\t\tconfig.plusButton\n\t\t) );\n\t\tthis.plusButton.$element.attr( 'aria-hidden', 'true' );\n\t}\n\n\t// Events\n\tthis.$input.on( {\n\t\tkeydown: this.onKeyDown.bind( this ),\n\t\t'wheel mousewheel DOMMouseScroll': this.onWheel.bind( this )\n\t} );\n\tif ( config.showButtons ) {\n\t\tthis.plusButton.connect( this, {\n\t\t\tclick: [ 'onButtonClick', +1 ]\n\t\t} );\n\t\tthis.minusButton.connect( this, {\n\t\t\tclick: [ 'onButtonClick', -1 ]\n\t\t} );\n\t}\n\n\t// Build the field\n\t$field.append( this.$input );\n\tif ( config.showButtons ) {\n\t\t$field\n\t\t\t.prepend( this.minusButton.$element )\n\t\t\t.append( this.plusButton.$element );\n\t}\n\n\t// Initialization\n\tif ( config.allowInteger || config.isInteger ) {\n\t\t// Backward compatibility\n\t\tconfig.step = 1;\n\t}\n\tthis.setRange( config.min, config.max );\n\tthis.setStep( config.buttonStep, config.pageStep, config.step );\n\t// Set the validation method after we set step and range\n\t// so that it doesn't immediately call setValidityFlag\n\tthis.setValidation( this.validateNumber.bind( this ) );\n\n\tthis.$element\n\t\t.addClass( 'oo-ui-numberInputWidget' )\n\t\t.toggleClass( 'oo-ui-numberInputWidget-buttoned', config.showButtons )\n\t\t.append( $field );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.NumberInputWidget, OO.ui.TextInputWidget );\n\n/* Methods */\n\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.setAllowInteger = function ( flag ) {\n\tthis.setStep( flag ? 1 : null );\n};\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.setIsInteger = OO.ui.NumberInputWidget.prototype.setAllowInteger;\n\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.getAllowInteger = function () {\n\treturn this.step === 1;\n};\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.getIsInteger = OO.ui.NumberInputWidget.prototype.getAllowInteger;\n\n/**\n * Set the range of allowed values\n *\n * @param {number} min Minimum allowed value\n * @param {number} max Maximum allowed value\n */\nOO.ui.NumberInputWidget.prototype.setRange = function ( min, max ) {\n\tif ( min > max ) {\n\t\tthrow new Error( 'Minimum (' + min + ') must not be greater than maximum (' + max + ')' );\n\t}\n\tthis.min = min;\n\tthis.max = max;\n\tthis.$input.attr( 'min', this.min );\n\tthis.$input.attr( 'max', this.max );\n\tthis.setValidityFlag();\n};\n\n/**\n * Get the current range\n *\n * @return {number[]} Minimum and maximum values\n */\nOO.ui.NumberInputWidget.prototype.getRange = function () {\n\treturn [ this.min, this.max ];\n};\n\n/**\n * Set the stepping deltas\n *\n * @param {number} [buttonStep=step||1] Delta when using the buttons or up/down arrow keys.\n *  Defaults to `step` if specified, otherwise `1`.\n * @param {number} [pageStep=10*buttonStep] Delta when using the page-up/page-down keys.\n *  Defaults to 10 times `buttonStep`.\n * @param {number|null} [step] If specified, the field only accepts values that are multiples\n *  of this.\n */\nOO.ui.NumberInputWidget.prototype.setStep = function ( buttonStep, pageStep, step ) {\n\tif ( buttonStep === undefined ) {\n\t\tbuttonStep = step || 1;\n\t}\n\tif ( pageStep === undefined ) {\n\t\tpageStep = 10 * buttonStep;\n\t}\n\tif ( step !== null && step <= 0 ) {\n\t\tthrow new Error( 'Step value, if given, must be positive' );\n\t}\n\tif ( buttonStep <= 0 ) {\n\t\tthrow new Error( 'Button step value must be positive' );\n\t}\n\tif ( pageStep <= 0 ) {\n\t\tthrow new Error( 'Page step value must be positive' );\n\t}\n\tthis.step = step;\n\tthis.buttonStep = buttonStep;\n\tthis.pageStep = pageStep;\n\tthis.$input.attr( 'step', this.step || 'any' );\n\tthis.setValidityFlag();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.NumberInputWidget.prototype.setValue = function ( value ) {\n\tif ( value === '' ) {\n\t\t// Some browsers allow a value in the input even if there isn't one reported by $input.val()\n\t\t// so here we make sure an 'empty' value is actually displayed as such.\n\t\tthis.$input.val( '' );\n\t}\n\treturn OO.ui.NumberInputWidget.parent.prototype.setValue.call( this, value );\n};\n\n/**\n * Get the current stepping values\n *\n * @return {number[]} Button step, page step, and validity step\n */\nOO.ui.NumberInputWidget.prototype.getStep = function () {\n\treturn [ this.buttonStep, this.pageStep, this.step ];\n};\n\n/**\n * Get the current value of the widget as a number\n *\n * @return {number} May be NaN, or an invalid number\n */\nOO.ui.NumberInputWidget.prototype.getNumericValue = function () {\n\treturn +this.getValue();\n};\n\n/**\n * Adjust the value of the widget\n *\n * @param {number} delta Adjustment amount\n */\nOO.ui.NumberInputWidget.prototype.adjustValue = function ( delta ) {\n\tvar n, v = this.getNumericValue();\n\n\tdelta = +delta;\n\tif ( isNaN( delta ) || !isFinite( delta ) ) {\n\t\tthrow new Error( 'Delta must be a finite number' );\n\t}\n\n\tif ( isNaN( v ) ) {\n\t\tn = 0;\n\t} else {\n\t\tn = v + delta;\n\t\tn = Math.max( Math.min( n, this.max ), this.min );\n\t\tif ( this.step ) {\n\t\t\tn = Math.round( n / this.step ) * this.step;\n\t\t}\n\t}\n\n\tif ( n !== v ) {\n\t\tthis.setValue( n );\n\t}\n};\n/**\n * Validate input\n *\n * @private\n * @param {string} value Field value\n * @return {boolean}\n */\nOO.ui.NumberInputWidget.prototype.validateNumber = function ( value ) {\n\tvar n = +value;\n\tif ( value === '' ) {\n\t\treturn !this.isRequired();\n\t}\n\n\tif ( isNaN( n ) || !isFinite( n ) ) {\n\t\treturn false;\n\t}\n\n\tif ( this.step && Math.floor( n / this.step ) !== n / this.step ) {\n\t\treturn false;\n\t}\n\n\tif ( n < this.min || n > this.max ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {number} dir +1 or -1\n */\nOO.ui.NumberInputWidget.prototype.onButtonClick = function ( dir ) {\n\tthis.adjustValue( dir * this.buttonStep );\n};\n\n/**\n * Handle mouse wheel events.\n *\n * @private\n * @param {jQuery.Event} event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.NumberInputWidget.prototype.onWheel = function ( event ) {\n\tvar delta = 0;\n\n\tif ( !this.isDisabled() && this.$input.is( ':focus' ) ) {\n\t\t// Standard 'wheel' event\n\t\tif ( event.originalEvent.deltaMode !== undefined ) {\n\t\t\tthis.sawWheelEvent = true;\n\t\t}\n\t\tif ( event.originalEvent.deltaY ) {\n\t\t\tdelta = -event.originalEvent.deltaY;\n\t\t} else if ( event.originalEvent.deltaX ) {\n\t\t\tdelta = event.originalEvent.deltaX;\n\t\t}\n\n\t\t// Non-standard events\n\t\tif ( !this.sawWheelEvent ) {\n\t\t\tif ( event.originalEvent.wheelDeltaX ) {\n\t\t\t\tdelta = -event.originalEvent.wheelDeltaX;\n\t\t\t} else if ( event.originalEvent.wheelDeltaY ) {\n\t\t\t\tdelta = event.originalEvent.wheelDeltaY;\n\t\t\t} else if ( event.originalEvent.wheelDelta ) {\n\t\t\t\tdelta = event.originalEvent.wheelDelta;\n\t\t\t} else if ( event.originalEvent.detail ) {\n\t\t\t\tdelta = -event.originalEvent.detail;\n\t\t\t}\n\t\t}\n\n\t\tif ( delta ) {\n\t\t\tdelta = delta < 0 ? -1 : 1;\n\t\t\tthis.adjustValue( delta * this.buttonStep );\n\t\t}\n\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.NumberInputWidget.prototype.onKeyDown = function ( e ) {\n\tif ( !this.isDisabled() ) {\n\t\tswitch ( e.which ) {\n\t\t\tcase OO.ui.Keys.UP:\n\t\t\t\tthis.adjustValue( this.buttonStep );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.DOWN:\n\t\t\t\tthis.adjustValue( -this.buttonStep );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.PAGEUP:\n\t\t\t\tthis.adjustValue( this.pageStep );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.PAGEDOWN:\n\t\t\t\tthis.adjustValue( -this.pageStep );\n\t\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.NumberInputWidget.prototype.setDisabled = function ( disabled ) {\n\t// Parent method\n\tOO.ui.NumberInputWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tif ( this.minusButton ) {\n\t\tthis.minusButton.setDisabled( this.isDisabled() );\n\t}\n\tif ( this.plusButton ) {\n\t\tthis.plusButton.setDisabled( this.isDisabled() );\n\t}\n\n\treturn this;\n};\n","/**\n * SelectFileInputWidgets allow for selecting files, using <input type=\"file\">. These\n * widgets can be configured with {@link OO.ui.mixin.IconElement icons}, {@link\n * OO.ui.mixin.IndicatorElement indicators} and {@link OO.ui.mixin.TitledElement titles}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * SelectFileInputWidgets must be used in HTML forms, as getValue only returns the filename.\n *\n *     @example\n *     // A file select input widget.\n *     var selectFile = new OO.ui.SelectFileInputWidget();\n *     $( document.body ).append( selectFile.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets\n *\n * @class\n * @extends OO.ui.InputWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string[]|null} [accept=null] MIME types to accept. null accepts all types.\n * @cfg {boolean} [multiple=false] Allow multiple files to be selected.\n * @cfg {string} [placeholder] Text to display when no file is selected.\n * @cfg {Object} [button] Config to pass to select file button.\n * @cfg {string} [icon] Icon to show next to file info\n */\nOO.ui.SelectFileInputWidget = function OoUiSelectFileInputWidget( config ) {\n\tvar widget = this;\n\n\tconfig = config || {};\n\n\t// Construct buttons before parent method is called (calling setDisabled)\n\tthis.selectButton = new OO.ui.ButtonWidget( $.extend( {\n\t\t$element: $( '<label>' ),\n\t\tclasses: [ 'oo-ui-selectFileInputWidget-selectButton' ],\n\t\tlabel: OO.ui.msg( 'ooui-selectfile-button-select' )\n\t}, config.button ) );\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\taccept: null,\n\t\tplaceholder: OO.ui.msg( 'ooui-selectfile-placeholder' ),\n\t\t$tabIndexed: this.selectButton.$tabIndexed\n\t}, config );\n\n\tthis.info = new OO.ui.SearchInputWidget( {\n\t\tclasses: [ 'oo-ui-selectFileInputWidget-info' ],\n\t\tplaceholder: config.placeholder,\n\t\t// Pass an empty collection so that .focus() always does nothing\n\t\t$tabIndexed: $( [] )\n\t} ).setIcon( config.icon );\n\t// Set tabindex manually on $input as $tabIndexed has been overridden\n\tthis.info.$input.attr( 'tabindex', -1 );\n\n\t// Parent constructor\n\tOO.ui.SelectFileInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.currentFiles = this.filterFiles( this.$input[ 0 ].files || [] );\n\tif ( Array.isArray( config.accept ) ) {\n\t\tthis.accept = config.accept;\n\t} else {\n\t\tthis.accept = null;\n\t}\n\tthis.multiple = !!config.multiple;\n\n\t// Events\n\tthis.info.connect( this, { change: 'onInfoChange' } );\n\tthis.selectButton.$button.on( {\n\t\tkeypress: this.onKeyPress.bind( this )\n\t} );\n\tthis.$input.on( {\n\t\tchange: this.onFileSelected.bind( this ),\n\t\t// Support: IE11\n\t\t// In IE 11, focussing a file input (by clicking on it) displays a text cursor and scrolls\n\t\t// the cursor into view (in this case, it scrolls the button, which has 'overflow: hidden').\n\t\t// Since this messes with our custom styling (the file input has large dimensions and this\n\t\t// causes the label to scroll out of view), scroll the button back to top. (T192131)\n\t\tfocus: function () {\n\t\t\twidget.$input.parent().prop( 'scrollTop', 0 );\n\t\t}\n\t} );\n\tthis.connect( this, { change: 'updateUI' } );\n\n\tthis.fieldLayout = new OO.ui.ActionFieldLayout( this.info, this.selectButton, { align: 'top' } );\n\n\tthis.$input\n\t\t.attr( {\n\t\t\ttype: 'file',\n\t\t\t// this.selectButton is tabindexed\n\t\t\ttabindex: -1,\n\t\t\t// Infused input may have previously by\n\t\t\t// TabIndexed, so remove aria-disabled attr.\n\t\t\t'aria-disabled': null\n\t\t} );\n\n\tif ( this.accept ) {\n\t\tthis.$input.attr( 'accept', this.accept.join( ', ' ) );\n\t}\n\tif ( this.multiple ) {\n\t\tthis.$input.attr( 'multiple', '' );\n\t}\n\tthis.selectButton.$button.append( this.$input );\n\n\tthis.$element\n\t\t.addClass( 'oo-ui-selectFileInputWidget' )\n\t\t.append( this.fieldLayout.$element );\n\n\tthis.updateUI();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SelectFileInputWidget, OO.ui.InputWidget );\n\n/* Static properties */\n\n// Set empty title so that browser default tooltips like \"No file chosen\" don't appear.\n// On SelectFileWidget this tooltip will often be incorrect, so create a consistent\n// experience on SelectFileInputWidget.\nOO.ui.SelectFileInputWidget.static.title = '';\n\n/* Methods */\n\n/**\n * Get the filename of the currently selected file.\n *\n * @return {string} Filename\n */\nOO.ui.SelectFileInputWidget.prototype.getFilename = function () {\n\tif ( this.currentFiles.length ) {\n\t\treturn this.currentFiles.map( function ( file ) {\n\t\t\treturn file.name;\n\t\t} ).join( ', ' );\n\t} else {\n\t\t// Try to strip leading fakepath.\n\t\treturn this.getValue().split( '\\\\' ).pop();\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileInputWidget.prototype.setValue = function ( value ) {\n\tif ( value === undefined ) {\n\t\t// Called during init, don't replace value if just infusing.\n\t\treturn;\n\t}\n\tif ( value ) {\n\t\t// We need to update this.value, but without trying to modify\n\t\t// the DOM value, which would throw an exception.\n\t\tif ( this.value !== value ) {\n\t\t\tthis.value = value;\n\t\t\tthis.emit( 'change', this.value );\n\t\t}\n\t} else {\n\t\tthis.currentFiles = [];\n\t\t// Parent method\n\t\tOO.ui.SelectFileInputWidget.super.prototype.setValue.call( this, '' );\n\t}\n};\n\n/**\n * Handle file selection from the input.\n *\n * @protected\n * @param {jQuery.Event} e\n */\nOO.ui.SelectFileInputWidget.prototype.onFileSelected = function ( e ) {\n\tthis.currentFiles = this.filterFiles( e.target.files || [] );\n};\n\n/**\n * Update the user interface when a file is selected or unselected.\n *\n * @protected\n */\nOO.ui.SelectFileInputWidget.prototype.updateUI = function () {\n\tthis.info.setValue( this.getFilename() );\n};\n\n/**\n * Determine if we should accept this file.\n *\n * @private\n * @param {FileList|File[]} files Files to filter\n * @return {File[]} Filter files\n */\nOO.ui.SelectFileInputWidget.prototype.filterFiles = function ( files ) {\n\tvar accept = this.accept;\n\n\tfunction mimeAllowed( file ) {\n\t\tvar i, mimeTest,\n\t\t\tmimeType = file.type;\n\n\t\tif ( !accept || !mimeType ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tfor ( i = 0; i < accept.length; i++ ) {\n\t\t\tmimeTest = accept[ i ];\n\t\t\tif ( mimeTest === mimeType ) {\n\t\t\t\treturn true;\n\t\t\t} else if ( mimeTest.substr( -2 ) === '/*' ) {\n\t\t\t\tmimeTest = mimeTest.substr( 0, mimeTest.length - 1 );\n\t\t\t\tif ( mimeType.substr( 0, mimeTest.length ) === mimeTest ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\treturn Array.prototype.filter.call( files, mimeAllowed );\n};\n\n/**\n * Handle info input change events\n *\n * The info widget can only be changed by the user\n * with the clear button.\n *\n * @private\n * @param {string} value\n */\nOO.ui.SelectFileInputWidget.prototype.onInfoChange = function ( value ) {\n\tif ( value === '' ) {\n\t\tthis.setValue( null );\n\t}\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileInputWidget.prototype.onKeyPress = function ( e ) {\n\tif ( !this.isDisabled() && this.$input &&\n\t\t( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )\n\t) {\n\t\t// Emit a click to open the file selector.\n\t\tthis.$input.trigger( 'click' );\n\t\t// Taking focus from the selectButton means keyUp isn't fired, so fire it manually.\n\t\tthis.selectButton.onDocumentKeyUp( e );\n\t\treturn false;\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileInputWidget.prototype.setDisabled = function ( disabled ) {\n\t// Parent method\n\tOO.ui.SelectFileInputWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tthis.selectButton.setDisabled( disabled );\n\tthis.info.setDisabled( disabled );\n\n\treturn this;\n};\n","}( OO ) );\n"]}
\ No newline at end of file
index 09ae8a8..7b6a2aa 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
 .oo-ui-tool > .oo-ui-tool-link > .oo-ui-tool-checkIcon {
   display: none;
index fd89840..909a7b3 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
 .oo-ui-tool {
   -webkit-box-sizing: border-box;
@@ -28,7 +28,7 @@
   padding-left: 2.85714286em;
 }
 .oo-ui-tool-with-label .oo-ui-tool-link {
-  padding: 1em 0.85714286em 0.92857143em 2.64285714em;
+  padding: 0.85714286em 0.85714286em 0.85714286em 2.64285714em;
 }
 .oo-ui-tool .oo-ui-iconElement-icon {
   display: block;
@@ -38,7 +38,7 @@
   left: 0.71428571em;
 }
 .oo-ui-tool .oo-ui-tool-title {
-  line-height: 1;
+  line-height: 1.28571429em;
 }
 .oo-ui-tool.oo-ui-widget-enabled {
   -webkit-transition: background-color 100ms;
   padding-left: 2.85714286em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle {
-  padding: 1em 0.85714286em 0.92857143em;
+  padding: 0.85714286em 0.85714286em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  line-height: 1;
+  line-height: 1.28571429em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle {
   padding-left: 0.71428571em;
   box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.25);
 }
 .oo-ui-popupToolGroup-tools .oo-ui-tool-link {
-  padding: 1em 0.85714286em 0.92857143em 0.85714286em;
+  padding: 0.85714286em 0.85714286em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-tools .oo-ui-tool-link {
   padding-left: 0.71428571em;
 }
 .oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-accel {
   color: #72777d;
-  line-height: 1;
+  line-height: 1.28571429em;
 }
 .oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-accel:not( :empty ) {
   padding-left: 1.28571429em;
   box-shadow: inset 0 0 0 2px #36c, inset 0 0 0 3px #fff;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
-  padding-top: 1em;
-  padding-bottom: 0.92857143em;
+  padding-top: 0.85714286em;
+  padding-bottom: 0.85714286em;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-buttonElement > .oo-ui-buttonElement-button {
   border-radius: 0;
   border-width: 0 0 0 1px;
-  padding-top: 1em;
-  padding-bottom: 0.92857143em;
+  padding-top: 0.85714286em;
+  padding-bottom: 0.85714286em;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonGroupWidget > .oo-ui-popupToolGroup.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-popupToolGroup-handle {
   color: #fff;
index 15a3254..24720b8 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:07Z
+ * Date: 2019-04-04T19:10:48Z
  */
 ( function ( OO ) {
 
 
 /**
  * Toolbars are complex interface components that permit users to easily access a variety
- * of {@link OO.ui.Tool tools} (e.g., formatting commands) and actions, which are additional commands that are
- * part of the toolbar, but not configured as tools.
+ * of {@link OO.ui.Tool tools} (e.g., formatting commands) and actions, which are additional
+ * commands that are part of the toolbar, but not configured as tools.
  *
- * Individual tools are customized and then registered with a {@link OO.ui.ToolFactory tool factory}, which creates
- * the tools on demand. Each tool has a symbolic name (used when registering the tool), a title (e.g., ‘Insert
- * image’), and an icon.
+ * Individual tools are customized and then registered with a
+ * {@link OO.ui.ToolFactory tool factory}, which creates the tools on demand. Each tool has a
+ * symbolic name (used when registering the tool), a title (e.g., ‘Insert image’), and an icon.
  *
- * Individual tools are organized in {@link OO.ui.ToolGroup toolgroups}, which can be {@link OO.ui.MenuToolGroup menus}
- * of tools, {@link OO.ui.ListToolGroup lists} of tools, or a single {@link OO.ui.BarToolGroup bar} of tools.
- * The arrangement and order of the toolgroups is customized when the toolbar is set up. Tools can be presented in
- * any order, but each can only appear once in the toolbar.
+ * Individual tools are organized in {@link OO.ui.ToolGroup toolgroups}, which can be
+ * {@link OO.ui.MenuToolGroup menus} of tools, {@link OO.ui.ListToolGroup lists} of tools, or a
+ * single {@link OO.ui.BarToolGroup bar} of tools. The arrangement and order of the toolgroups is
+ * customized when the toolbar is set up. Tools can be presented in any order, but each can only
+ * appear once in the toolbar.
  *
  * The toolbar can be synchronized with the state of the external "application", like a text
  * editor's editing area, marking tools as active/inactive (e.g. a 'bold' tool would be shown as
  * @param {OO.ui.ToolFactory} toolFactory Factory for creating tools
  * @param {OO.ui.ToolGroupFactory} toolGroupFactory Factory for creating toolgroups
  * @param {Object} [config] Configuration options
- * @cfg {boolean} [actions] Add an actions section to the toolbar. Actions are commands that are included
- *  in the toolbar, but are not configured as tools. By default, actions are displayed on the right side of
- *  the toolbar.
- * @cfg {string} [position='top'] Whether the toolbar is positioned above ('top') or below ('bottom') content.
+ * @cfg {boolean} [actions] Add an actions section to the toolbar. Actions are commands that are
+ *  included in the toolbar, but are not configured as tools. By default, actions are displayed on
+ *  the right side of the toolbar.
+ * @cfg {string} [position='top'] Whether the toolbar is positioned above ('top') or below
+ *  ('bottom') content.
  * @cfg {jQuery} [$overlay] An overlay for the popup.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
  */
@@ -327,7 +329,8 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {
        this.initialized = false;
        this.narrowThreshold = null;
        this.onWindowResizeHandler = this.onWindowResize.bind( this );
-       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
+       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) ||
+               this.$element;
 
        // Events
        this.$element
@@ -344,7 +347,9 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {
                .addClass( 'oo-ui-toolbar-bar' )
                .append( this.$group, '<div style="clear:both"></div>' );
        // Possible classes: oo-ui-toolbar-position-top, oo-ui-toolbar-position-bottom
-       this.$element.addClass( 'oo-ui-toolbar oo-ui-toolbar-position-' + this.position ).append( this.$bar );
+       this.$element
+               .addClass( 'oo-ui-toolbar oo-ui-toolbar-position-' + this.position )
+               .append( this.$bar );
        this.$overlay.append( this.$popups );
 };
 
@@ -359,9 +364,9 @@ OO.mixinClass( OO.ui.Toolbar, OO.ui.mixin.GroupElement );
 /**
  * @event updateState
  *
- * An 'updateState' event must be emitted on the Toolbar (by calling `toolbar.emit( 'updateState' )`)
- * every time the state of the application using the toolbar changes, and an update to the state of
- * tools is required.
+ * An 'updateState' event must be emitted on the Toolbar (by calling
+ * `toolbar.emit( 'updateState' )`) every time the state of the application using the toolbar
+ * changes, and an update to the state of tools is required.
  *
  * @param {...Mixed} data Application-defined parameters
  */
@@ -405,7 +410,11 @@ OO.ui.Toolbar.prototype.getToolGroupFactory = function () {
 OO.ui.Toolbar.prototype.onPointerDown = function ( e ) {
        var $closestWidgetToEvent = $( e.target ).closest( '.oo-ui-widget' ),
                $closestWidgetToToolbar = this.$element.closest( '.oo-ui-widget' );
-       if ( !$closestWidgetToEvent.length || $closestWidgetToEvent[ 0 ] === $closestWidgetToToolbar[ 0 ] ) {
+       if (
+               !$closestWidgetToEvent.length ||
+               $closestWidgetToEvent[ 0 ] ===
+               $closestWidgetToToolbar[ 0 ]
+       ) {
                return false;
        }
 };
@@ -453,9 +462,10 @@ OO.ui.Toolbar.prototype.initialize = function () {
  * Set up the toolbar.
  *
  * The toolbar is set up with a list of toolgroup configurations that specify the type of
- * toolgroup ({@link OO.ui.BarToolGroup bar}, {@link OO.ui.MenuToolGroup menu}, or {@link OO.ui.ListToolGroup list})
- * to add and which tools to include, exclude, promote, or demote within that toolgroup. Please
- * see {@link OO.ui.ToolGroup toolgroups} for more information about including tools in toolgroups.
+ * toolgroup ({@link OO.ui.BarToolGroup bar}, {@link OO.ui.MenuToolGroup menu}, or
+ * {@link OO.ui.ListToolGroup list}) to add and which tools to include, exclude, promote, or demote
+ * within that toolgroup. Please see {@link OO.ui.ToolGroup toolgroups} for more information about
+ * including tools in toolgroups.
  *
  * @param {Object.<string,Array>} groups List of toolgroup configurations
  * @param {string} [groups.name] Symbolic name for this toolgroup
@@ -486,7 +496,8 @@ OO.ui.Toolbar.prototype.setup = function ( groups ) {
                        }
                }
                // Check type has been registered
-               type = this.getToolGroupFactory().lookup( groupConfig.type ) ? groupConfig.type : defaultType;
+               type = this.getToolGroupFactory().lookup( groupConfig.type ) ?
+                       groupConfig.type : defaultType;
                toolGroup = this.getToolGroupFactory().create( type, this, groupConfig );
                items.push( toolGroup );
                if ( groupConfig.name ) {
@@ -495,7 +506,9 @@ OO.ui.Toolbar.prototype.setup = function ( groups ) {
                        // Groups without name are deprecated
                        OO.ui.warnDeprecation( 'Toolgroups must have a \'name\' property' );
                }
-               toolGroup.connect( this, { active: 'onToolGroupActive' } );
+               toolGroup.connect( this, {
+                       active: 'onToolGroupActive'
+               } );
        }
        this.addItems( items );
 };
@@ -547,8 +560,8 @@ OO.ui.Toolbar.prototype.reset = function () {
 /**
  * Destroy the toolbar.
  *
- * Destroying the toolbar removes all event handlers and DOM elements that constitute the toolbar. Call
- * this method whenever you are done using a toolbar.
+ * Destroying the toolbar removes all event handlers and DOM elements that constitute the toolbar.
+ * Call this method whenever you are done using a toolbar.
  */
 OO.ui.Toolbar.prototype.destroy = function () {
        $( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );
@@ -590,8 +603,9 @@ OO.ui.Toolbar.prototype.releaseTool = function ( tool ) {
  * Get accelerator label for tool.
  *
  * The OOUI library does not contain an accelerator system, but this is the hook for one. To
- * use an accelerator system, subclass the toolbar and override this method, which is meant to return a label
- * that describes the accelerator keys for the tool passed (by symbolic name) to the method.
+ * use an accelerator system, subclass the toolbar and override this method, which is meant to
+ * return a label that describes the accelerator keys for the tool passed (by symbolic name) to
+ * the method.
  *
  * @param {string} name Symbolic name of tool
  * @return {string|undefined} Tool accelerator label if available
@@ -601,10 +615,11 @@ OO.ui.Toolbar.prototype.getToolAccelerator = function () {
 };
 
 /**
- * Tools, together with {@link OO.ui.ToolGroup toolgroups}, constitute {@link OO.ui.Toolbar toolbars}.
- * Each tool is configured with a static name, title, and icon and is customized with the command to carry
- * out when the tool is selected. Tools must also be registered with a {@link OO.ui.ToolFactory tool factory},
- * which creates the tools on demand.
+ * Tools, together with {@link OO.ui.ToolGroup toolgroups}, constitute
+ * {@link OO.ui.Toolbar toolbars}.
+ * Each tool is configured with a static name, title, and icon and is customized with the command
+ * to carry out when the tool is selected. Tools must also be registered with a
+ * {@link OO.ui.ToolFactory tool factory}, which creates the tools on demand.
  *
  * Every Tool subclass must implement two methods:
  *
@@ -612,8 +627,9 @@ OO.ui.Toolbar.prototype.getToolAccelerator = function () {
  * - {@link #onSelect}
  *
  * Tools are added to toolgroups ({@link OO.ui.ListToolGroup ListToolGroup},
- * {@link OO.ui.BarToolGroup BarToolGroup}, or {@link OO.ui.MenuToolGroup MenuToolGroup}), which determine how
- * the tool is displayed in the toolbar. See {@link OO.ui.Toolbar toolbars} for an example.
+ * {@link OO.ui.BarToolGroup BarToolGroup}, or {@link OO.ui.MenuToolGroup MenuToolGroup}), which
+ * determine how the tool is displayed in the toolbar. See {@link OO.ui.Toolbar toolbars} for an
+ * example.
  *
  * For more information, please see the [OOUI documentation on MediaWiki][1].
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
@@ -628,16 +644,19 @@ OO.ui.Toolbar.prototype.getToolAccelerator = function () {
  * @constructor
  * @param {OO.ui.ToolGroup} toolGroup
  * @param {Object} [config] Configuration options
- * @cfg {string|Function} [title] Title text or a function that returns text. If this config is omitted, the value of
- *  the {@link #static-title static title} property is used.
+ * @cfg {string|Function} [title] Title text or a function that returns text. If this config is
+ *  omitted, the value of the {@link #static-title static title} property is used.
  *
- *  The title is used in different ways depending on the type of toolgroup that contains the tool. The
- *  title is used as a tooltip if the tool is part of a {@link OO.ui.BarToolGroup bar} toolgroup, or as the label text if the tool is
- *  part of a {@link OO.ui.ListToolGroup list} or {@link OO.ui.MenuToolGroup menu} toolgroup.
+ *  The title is used in different ways depending on the type of toolgroup that contains the tool.
+ *  The title is used as a tooltip if the tool is part of a {@link OO.ui.BarToolGroup bar}
+ *  toolgroup, or as the label text if the tool is part of a {@link OO.ui.ListToolGroup list} or
+ *  {@link OO.ui.MenuToolGroup menu} toolgroup.
  *
- *  For bar toolgroups, a description of the accelerator key is appended to the title if an accelerator key
- *  is associated with an action by the same name as the tool and accelerator functionality has been added to the application.
- *  To add accelerator key functionality, you must subclass OO.ui.Toolbar and override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method.
+ *  For bar toolgroups, a description of the accelerator key is appended to the title if an
+ *  accelerator key is associated with an action by the same name as the tool and accelerator
+ *  functionality has been added to the application.
+ *  To add accelerator key functionality, you must subclass OO.ui.Toolbar and override the
+ *  {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method.
  */
 OO.ui.Tool = function OoUiTool( toolGroup, config ) {
        // Allow passing positional parameters inside the config object
@@ -668,10 +687,14 @@ OO.ui.Tool = function OoUiTool( toolGroup, config ) {
        // Mixin constructors
        OO.ui.mixin.IconElement.call( this, config );
        OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$link } ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {
+               $tabIndexed: this.$link
+       }, config ) );
 
        // Events
-       this.toolbar.connect( this, { updateState: 'onUpdateState' } );
+       this.toolbar.connect( this, {
+               updateState: 'onUpdateState'
+       } );
 
        // Initialization
        this.$title.addClass( 'oo-ui-tool-title' );
@@ -690,7 +713,8 @@ OO.ui.Tool = function OoUiTool( toolGroup, config ) {
        this.$element
                .data( 'oo-ui-tool', this )
                .addClass( 'oo-ui-tool' )
-               .addClass( 'oo-ui-tool-name-' + this.constructor.static.name.replace( /^([^/]+)\/([^/]+).*$/, '$1-$2' ) )
+               .addClass( 'oo-ui-tool-name-' +
+                       this.constructor.static.name.replace( /^([^/]+)\/([^/]+).*$/, '$1-$2' ) )
                .toggleClass( 'oo-ui-tool-with-label', this.constructor.static.displayBothIconAndLabel )
                .append( this.$link );
        this.setTitle( config.title || this.constructor.static.title );
@@ -714,8 +738,8 @@ OO.ui.Tool.static.tagName = 'span';
 /**
  * Symbolic name of tool.
  *
- * The symbolic name is used internally to register the tool with a {@link OO.ui.ToolFactory ToolFactory}. It can
- * also be used when adding tools to toolgroups.
+ * The symbolic name is used internally to register the tool with a
+ * {@link OO.ui.ToolFactory ToolFactory}. It can also be used when adding tools to toolgroups.
  *
  * @abstract
  * @static
@@ -738,7 +762,8 @@ OO.ui.Tool.static.name = '';
 OO.ui.Tool.static.group = '';
 
 /**
- * Tool title text or a function that returns title text. The value of the static property is overridden if the #title config option is used.
+ * Tool title text or a function that returns title text. The value of the static property is
+ * overridden if the #title config option is used.
  *
  * @abstract
  * @static
@@ -921,17 +946,19 @@ OO.ui.Tool.prototype.destroy = function () {
 };
 
 /**
- * ToolGroups are collections of {@link OO.ui.Tool tools} that are used in a {@link OO.ui.Toolbar toolbar}.
- * The type of toolgroup ({@link OO.ui.ListToolGroup list}, {@link OO.ui.BarToolGroup bar}, or {@link OO.ui.MenuToolGroup menu})
- * to which a tool belongs determines how the tool is arranged and displayed in the toolbar. Toolgroups
- * themselves are created on demand with a {@link OO.ui.ToolGroupFactory toolgroup factory}.
+ * ToolGroups are collections of {@link OO.ui.Tool tools} that are used in a
+ * {@link OO.ui.Toolbar toolbar}.
+ * The type of toolgroup ({@link OO.ui.ListToolGroup list}, {@link OO.ui.BarToolGroup bar}, or
+ * {@link OO.ui.MenuToolGroup menu}) to which a tool belongs determines how the tool is arranged
+ * and displayed in the toolbar. Toolgroups themselves are created on demand with a
+ * {@link OO.ui.ToolGroupFactory toolgroup factory}.
  *
  * Toolgroups can contain individual tools, groups of tools, or all available tools, as specified
  * using the `include` config option. See OO.ui.ToolFactory#extract on documentation of the format.
  * The options `exclude`, `promote`, and `demote` support the same formats.
  *
- * See {@link OO.ui.Toolbar toolbars} for a full example. For more information about toolbars in general,
- * please see the [OOUI documentation on MediaWiki][1].
+ * See {@link OO.ui.Toolbar toolbars} for a full example. For more information about toolbars in
+ * general, please see the [OOUI documentation on MediaWiki][1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
  *
@@ -945,7 +972,8 @@ OO.ui.Tool.prototype.destroy = function () {
  * @param {Object} [config] Configuration options
  * @cfg {Array|string} [include] List of tools to include in the toolgroup, see above.
  * @cfg {Array|string} [exclude] List of tools to exclude from the toolgroup, see above.
- * @cfg {Array|string} [promote] List of tools to promote to the beginning of the toolgroup, see above.
+ * @cfg {Array|string} [promote] List of tools to promote to the beginning of the toolgroup,
+ *  see above.
  * @cfg {Array|string} [demote] List of tools to demote to the end of the toolgroup, see above.
  *  This setting is particularly useful when tools have been added to the toolgroup
  *  en masse (e.g., via the catch-all selector).
@@ -988,8 +1016,12 @@ OO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) {
                mouseover: this.onMouseOverFocus.bind( this ),
                mouseout: this.onMouseOutBlur.bind( this )
        } );
-       this.toolbar.getToolFactory().connect( this, { register: 'onToolFactoryRegister' } );
-       this.aggregate( { disable: 'itemDisable' } );
+       this.toolbar.getToolFactory().connect( this, {
+               register: 'onToolFactoryRegister'
+       } );
+       this.aggregate( {
+               disable: 'itemDisable'
+       } );
        this.connect( this, {
                itemDisable: 'updateDisabled',
                disable: 'onDisable'
@@ -1040,7 +1072,8 @@ OO.ui.ToolGroup.static.titleTooltips = false;
  * Note: The OOUI library does not include an accelerator system, but does contain
  * a hook for one. To use an accelerator system, subclass the {@link OO.ui.Toolbar toolbar} and
  * override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method, which is
- * meant to return a label that describes the accelerator keys for a given tool (e.g., 'Ctrl + M').
+ * meant to return a label that describes the accelerator keys for a given tool (e.g., Control+M
+ * key combination).
  *
  * @static
  * @inheritable
@@ -1071,7 +1104,8 @@ OO.ui.ToolGroup.static.name = null;
  * @inheritdoc
  */
 OO.ui.ToolGroup.prototype.isDisabled = function () {
-       return this.autoDisabled || OO.ui.ToolGroup.parent.prototype.isDisabled.apply( this, arguments );
+       return this.autoDisabled ||
+               OO.ui.ToolGroup.parent.prototype.isDisabled.apply( this, arguments );
 };
 
 /**
@@ -1113,14 +1147,25 @@ OO.ui.ToolGroup.prototype.onDisable = function ( isDisabled ) {
  */
 OO.ui.ToolGroup.prototype.onMouseKeyDown = function ( e ) {
        if (
-               !this.isDisabled() &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+               !this.isDisabled() && (
+                       e.which === OO.ui.MouseButtons.LEFT ||
+                       e.which === OO.ui.Keys.SPACE ||
+                       e.which === OO.ui.Keys.ENTER
+               )
        ) {
                this.pressed = this.findTargetTool( e );
                if ( this.pressed ) {
                        this.pressed.setActive( true );
-                       this.getElementDocument().addEventListener( 'mouseup', this.onDocumentMouseKeyUpHandler, true );
-                       this.getElementDocument().addEventListener( 'keyup', this.onDocumentMouseKeyUpHandler, true );
+                       this.getElementDocument().addEventListener(
+                               'mouseup',
+                               this.onDocumentMouseKeyUpHandler,
+                               true
+                       );
+                       this.getElementDocument().addEventListener(
+                               'keyup',
+                               this.onDocumentMouseKeyUpHandler,
+                               true
+                       );
                        return false;
                }
        }
@@ -1133,19 +1178,21 @@ OO.ui.ToolGroup.prototype.onMouseKeyDown = function ( e ) {
  * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event
  */
 OO.ui.ToolGroup.prototype.onDocumentMouseKeyUp = function ( e ) {
-       this.getElementDocument().removeEventListener( 'mouseup', this.onDocumentMouseKeyUpHandler, true );
-       this.getElementDocument().removeEventListener( 'keyup', this.onDocumentMouseKeyUpHandler, true );
+       this.getElementDocument().removeEventListener(
+               'mouseup',
+               this.onDocumentMouseKeyUpHandler,
+               true
+       );
+       this.getElementDocument().removeEventListener(
+               'keyup',
+               this.onDocumentMouseKeyUpHandler,
+               true
+       );
        // onMouseKeyUp may be called a second time, depending on where the mouse is when the button is
        // released, but since `this.pressed` will no longer be true, the second call will be ignored.
        this.onMouseKeyUp( e );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.ToolGroup.prototype.onCapturedMouseKeyUp = function () {
-       OO.ui.warnDeprecation( 'onCapturedMouseKeyUp is deprecated, use onDocumentMouseKeyUp instead' );
-       this.onDocumentMouseKeyUp.apply( this, arguments );
-};
-
 /**
  * Handle mouse up and key up events.
  *
@@ -1156,8 +1203,11 @@ OO.ui.ToolGroup.prototype.onMouseKeyUp = function ( e ) {
        var tool = this.findTargetTool( e );
 
        if (
-               !this.isDisabled() && this.pressed && this.pressed === tool &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+               !this.isDisabled() && this.pressed && this.pressed === tool && (
+                       e.which === OO.ui.MouseButtons.LEFT ||
+                       e.which === OO.ui.Keys.SPACE ||
+                       e.which === OO.ui.Keys.ENTER
+               )
        ) {
                this.pressed.onSelect();
                this.pressed = null;
@@ -1263,8 +1313,9 @@ OO.ui.ToolGroup.prototype.populate = function () {
                        // Tool is available or is already in this group
                        ( this.toolbar.isToolAvailable( name ) || this.tools[ name ] )
                ) {
-                       // Hack to prevent infinite recursion via ToolGroupTool. We need to reserve the tool before
-                       // creating it, but we can't call reserveTool() yet because we haven't created the tool.
+                       // Hack to prevent infinite recursion via ToolGroupTool. We need to reserve the tool
+                       // before creating it, but we can't call reserveTool() yet because we haven't created
+                       // the tool.
                        this.toolbar.tools[ name ] = true;
                        tool = this.tools[ name ];
                        if ( !tool ) {
@@ -1318,11 +1369,13 @@ OO.ui.ToolGroup.prototype.destroy = function () {
 };
 
 /**
- * A ToolFactory creates tools on demand. All tools ({@link OO.ui.Tool Tools}, {@link OO.ui.PopupTool PopupTools},
- * and {@link OO.ui.ToolGroupTool ToolGroupTools}) must be registered with a tool factory. Tools are
- * registered by their symbolic name. See {@link OO.ui.Toolbar toolbars} for an example.
+ * A ToolFactory creates tools on demand. All tools ({@link OO.ui.Tool Tools},
+ * {@link OO.ui.PopupTool PopupTools}, and {@link OO.ui.ToolGroupTool ToolGroupTools}) must be
+ * registered with a tool factory. Tools are registered by their symbolic name. See
+ * {@link OO.ui.Toolbar toolbars} for an example.
  *
- * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].
+ * For more information about toolbars in general, please see the
+ * [OOUI documentation on MediaWiki][1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
  *
@@ -1342,7 +1395,7 @@ OO.inheritClass( OO.ui.ToolFactory, OO.Factory );
 /* Methods */
 
 /**
- * Get tools from the factory
+ * Get tools from the factory.
  *
  * @param {Array|string} [include] Included tools, see #extract for format
  * @param {Array|string} [exclude] Excluded tools, see #extract for format
@@ -1454,9 +1507,9 @@ OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
 };
 
 /**
- * ToolGroupFactories create {@link OO.ui.ToolGroup toolgroups} on demand. The toolgroup classes must
- * specify a symbolic name and be registered with the factory. The following classes are registered by
- * default:
+ * ToolGroupFactories create {@link OO.ui.ToolGroup toolgroups} on demand. The toolgroup classes
+ * must specify a symbolic name and be registered with the factory. The following classes are
+ * registered by default:
  *
  * - {@link OO.ui.BarToolGroup BarToolGroups} (‘bar’)
  * - {@link OO.ui.MenuToolGroup MenuToolGroups} (‘menu’)
@@ -1464,7 +1517,8 @@ OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
  *
  * See {@link OO.ui.Toolbar toolbars} for an example.
  *
- * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].
+ * For more information about toolbars in general, please see the
+ * [OOUI documentation on MediaWiki][1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
  *
@@ -1505,9 +1559,10 @@ OO.ui.ToolGroupFactory.static.getDefaultClasses = function () {
 };
 
 /**
- * Popup tools open a popup window when they are selected from the {@link OO.ui.Toolbar toolbar}. Each popup tool is configured
- * with a static name, title, and icon, as well with as any popup configurations. Unlike other tools, popup tools do not require that developers specify
- * an #onSelect or #onUpdateState method, as these methods have been implemented already.
+ * Popup tools open a popup window when they are selected from the {@link OO.ui.Toolbar toolbar}.
+ * Each popup tool is configured with a static name, title, and icon, as well with as any popup
+ * configurations. Unlike other tools, popup tools do not require that developers specify an
+ * #onSelect or #onUpdateState method, as these methods have been implemented already.
  *
  *     // Example of a popup tool. When selected, a popup tool displays
  *     // a popup window.
@@ -1525,8 +1580,9 @@ OO.ui.ToolGroupFactory.static.getDefaultClasses = function () {
  *     HelpTool.static.title = 'Help';
  *     toolFactory.register( HelpTool );
  *
- * For an example of a toolbar that contains a popup tool, see {@link OO.ui.Toolbar toolbars}. For more information about
- * toolbars in general, please see the [OOUI documentation on MediaWiki][1].
+ * For an example of a toolbar that contains a popup tool, see {@link OO.ui.Toolbar toolbars}.
+ * For more information about toolbars in general, please see the
+ * [OOUI documentation on MediaWiki][1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
  *
@@ -1553,7 +1609,9 @@ OO.ui.PopupTool = function OoUiPopupTool( toolGroup, config ) {
        OO.ui.mixin.PopupElement.call( this, config );
 
        // Events
-       this.popup.connect( this, { toggle: 'onPopupToggle' } );
+       this.popup.connect( this, {
+               toggle: 'onPopupToggle'
+       } );
 
        // Initialization
        this.popup.setAutoFlip( false );
@@ -1607,7 +1665,8 @@ OO.ui.PopupTool.prototype.onPopupToggle = function ( isVisible ) {
  * the bar item. Included tools will be displayed in a dropdown {@link OO.ui.ListToolGroup list}
  * when the ToolGroupTool is selected.
  *
- *     // Example: ToolGroupTool with two nested tools, 'setting1' and 'setting2', defined elsewhere.
+ *     // Example: ToolGroupTool with two nested tools, 'setting1' and 'setting2',
+ *     // defined elsewhere.
  *
  *     function SettingsTool() {
  *         SettingsTool.parent.apply( this, arguments );
@@ -1715,8 +1774,8 @@ OO.ui.ToolGroupTool.prototype.onUpdateState = function () {
 /**
  * Build a {@link OO.ui.ToolGroup toolgroup} from the specified configuration.
  *
- * @param {Object.<string,Array>} group Toolgroup configuration. Please see {@link OO.ui.ToolGroup toolgroup} for
- *  more information.
+ * @param {Object.<string,Array>} group Toolgroup configuration. Please see
+ *  {@link OO.ui.ToolGroup toolgroup} for more information.
  * @return {OO.ui.ListToolGroup}
  */
 OO.ui.ToolGroupTool.prototype.createGroup = function ( group ) {
@@ -1732,13 +1791,13 @@ OO.ui.ToolGroupTool.prototype.createGroup = function ( group ) {
 
 /**
  * BarToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
- * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}
- * and {@link OO.ui.ListToolGroup ListToolGroup}). The {@link OO.ui.Tool tools} in a BarToolGroup are
- * displayed by icon in a single row. The title of the tool is displayed when users move the mouse over
- * the tool.
+ * create {@link OO.ui.Toolbar toolbars} (the other types of groups are
+ * {@link OO.ui.MenuToolGroup MenuToolGroup} and {@link OO.ui.ListToolGroup ListToolGroup}).
+ * The {@link OO.ui.Tool tools} in a BarToolGroup are displayed by icon in a single row. The
+ * title of the tool is displayed when users move the mouse over the tool.
  *
- * BarToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar is
- * set up.
+ * BarToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar
+ * is set up.
  *
  *     @example
  *     // Example of a BarToolGroup with two tools
@@ -1816,8 +1875,10 @@ OO.ui.ToolGroupTool.prototype.createGroup = function ( group ) {
  *     // document.
  *     toolbar.initialize();
  *
- * For more information about how to add tools to a bar tool group, please see {@link OO.ui.ToolGroup toolgroup}.
- * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].
+ * For more information about how to add tools to a bar tool group, please see
+ * {@link OO.ui.ToolGroup toolgroup}.
+ * For more information about toolbars in general, please see the
+ * [OOUI documentation on MediaWiki][1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
  *
@@ -1869,8 +1930,9 @@ OO.ui.BarToolGroup.static.name = 'bar';
 
 /**
  * PopupToolGroup is an abstract base class used by both {@link OO.ui.MenuToolGroup MenuToolGroup}
- * and {@link OO.ui.ListToolGroup ListToolGroup} to provide a popup (an overlaid menu or list of tools with an
- * optional icon and label). This class can be used for other base classes that also use this functionality.
+ * and {@link OO.ui.ListToolGroup ListToolGroup} to provide a popup (an overlaid menu or list of
+ * tools with an optional icon and label). This class can be used for other base classes that
+ * also use this functionality.
  *
  * @abstract
  * @class
@@ -1898,7 +1960,8 @@ OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
 
        // Configuration initialization
        config = $.extend( {
-               indicator: config.indicator === undefined ? ( toolbar.position === 'bottom' ? 'up' : 'down' ) : config.indicator
+               indicator: config.indicator === undefined ?
+                       ( toolbar.position === 'bottom' ? 'up' : 'down' ) : config.indicator
        }, config );
 
        // Parent constructor
@@ -1917,14 +1980,18 @@ OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
        OO.ui.mixin.LabelElement.call( this, config );
        OO.ui.mixin.TitledElement.call( this, config );
        OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
-       OO.ui.mixin.FloatableElement.call( this, $.extend( {}, config, {
+       OO.ui.mixin.ClippableElement.call( this, $.extend( {
+               $clippable: this.$group
+       }, config ) );
+       OO.ui.mixin.FloatableElement.call( this, $.extend( {
                $floatable: this.$group,
                $floatableContainer: this.$handle,
                hideWhenOutOfView: false,
                verticalPosition: this.toolbar.position === 'bottom' ? 'above' : 'below'
-       } ) );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
+       }, config ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {
+               $tabIndexed: this.$handle
+       }, config ) );
 
        // Events
        this.$handle.on( {
@@ -2000,20 +2067,17 @@ OO.ui.PopupToolGroup.prototype.onPopupDocumentMouseKeyUp = function ( e ) {
        this.setActive( false );
 };
 
-// Deprecated alias since 0.28.3
-OO.ui.PopupToolGroup.prototype.onBlur = function () {
-       OO.ui.warnDeprecation( 'onBlur is deprecated, use onPopupDocumentMouseKeyUp instead' );
-       this.onPopupDocumentMouseKeyUp.apply( this, arguments );
-};
-
 /**
  * @inheritdoc
  */
 OO.ui.PopupToolGroup.prototype.onMouseKeyUp = function ( e ) {
        // Only close toolgroup when a tool was actually selected
        if (
-               !this.isDisabled() && this.pressed && this.pressed === this.findTargetTool( e ) &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+               !this.isDisabled() && this.pressed && this.pressed === this.findTargetTool( e ) && (
+                       e.which === OO.ui.MouseButtons.LEFT ||
+                       e.which === OO.ui.Keys.SPACE ||
+                       e.which === OO.ui.Keys.ENTER
+               )
        ) {
                this.setActive( false );
        }
@@ -2028,7 +2092,8 @@ OO.ui.PopupToolGroup.prototype.onMouseKeyDown = function ( e ) {
        // Shift-Tab on the first tool in the group jumps to the handle.
        // Tab on the last tool in the group jumps to the next group.
        if ( !this.isDisabled() && e.which === OO.ui.Keys.TAB ) {
-               // (We can't use this.items because ListToolGroup inserts the extra fake expand/collapse tool.)
+               // We can't use this.items because ListToolGroup inserts the extra fake
+               // expand/collapse tool.
                $focused = $( document.activeElement );
                $firstFocusable = OO.ui.findFocusable( this.$group );
                if ( $focused[ 0 ] === $firstFocusable[ 0 ] && e.shiftKey ) {
@@ -2037,7 +2102,8 @@ OO.ui.PopupToolGroup.prototype.onMouseKeyDown = function ( e ) {
                }
                $lastFocusable = OO.ui.findFocusable( this.$group, true );
                if ( $focused[ 0 ] === $lastFocusable[ 0 ] && !e.shiftKey ) {
-                       // Focus this group's handle and let the browser's tab handling happen (no 'return false').
+                       // Focus this group's handle and let the browser's tab handling happen
+                       // (no 'return false').
                        // This way we don't have to fiddle with other ToolGroups' business, or worry what to do
                        // if the next group is not a PopupToolGroup or doesn't exist at all.
                        this.$handle.trigger( 'focus' );
@@ -2057,8 +2123,11 @@ OO.ui.PopupToolGroup.prototype.onMouseKeyDown = function ( e ) {
  */
 OO.ui.PopupToolGroup.prototype.onHandleMouseKeyUp = function ( e ) {
        if (
-               !this.isDisabled() &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+               !this.isDisabled() && (
+                       e.which === OO.ui.MouseButtons.LEFT ||
+                       e.which === OO.ui.Keys.SPACE ||
+                       e.which === OO.ui.Keys.ENTER
+               )
        ) {
                return false;
        }
@@ -2082,7 +2151,11 @@ OO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) {
                                return false;
                        }
                }
-               if ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) {
+               if (
+                       e.which === OO.ui.MouseButtons.LEFT ||
+                       e.which === OO.ui.Keys.SPACE ||
+                       e.which === OO.ui.Keys.ENTER
+               ) {
                        this.setActive( !this.active );
                        return false;
                }
@@ -2113,8 +2186,16 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
        if ( this.active !== value ) {
                this.active = value;
                if ( value ) {
-                       this.getElementDocument().addEventListener( 'mouseup', this.onPopupDocumentMouseKeyUpHandler, true );
-                       this.getElementDocument().addEventListener( 'keyup', this.onPopupDocumentMouseKeyUpHandler, true );
+                       this.getElementDocument().addEventListener(
+                               'mouseup',
+                               this.onPopupDocumentMouseKeyUpHandler,
+                               true
+                       );
+                       this.getElementDocument().addEventListener(
+                               'keyup',
+                               this.onPopupDocumentMouseKeyUpHandler,
+                               true
+                       );
 
                        this.$clippable.css( 'left', '' );
                        this.$element.addClass( 'oo-ui-popupToolGroup-active' );
@@ -2126,13 +2207,16 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
                        this.setHorizontalPosition( 'start' );
 
                        if ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {
-                               // Anchoring to the left caused the popup to clip, so anchor it to the right instead
+                               // Anchoring to the left caused the popup to clip, so anchor it to the
+                               // right instead.
                                this.setHorizontalPosition( 'end' );
                        }
                        if ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {
-                               // Anchoring to the right also caused the popup to clip, so just make it fill the container
+                               // Anchoring to the right also caused the popup to clip, so just make it fill the
+                               // container.
                                containerWidth = this.$clippableScrollableContainer.width();
-                               containerLeft = this.$clippableScrollableContainer[ 0 ] === document.documentElement ?
+                               containerLeft = this.$clippableScrollableContainer[ 0 ] ===
+                                       document.documentElement ?
                                        0 :
                                        this.$clippableScrollableContainer.offset().left;
 
@@ -2145,8 +2229,16 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
                                } );
                        }
                } else {
-                       this.getElementDocument().removeEventListener( 'mouseup', this.onPopupDocumentMouseKeyUpHandler, true );
-                       this.getElementDocument().removeEventListener( 'keyup', this.onPopupDocumentMouseKeyUpHandler, true );
+                       this.getElementDocument().removeEventListener(
+                               'mouseup',
+                               this.onPopupDocumentMouseKeyUpHandler,
+                               true
+                       );
+                       this.getElementDocument().removeEventListener(
+                               'keyup',
+                               this.onPopupDocumentMouseKeyUpHandler,
+                               true
+                       );
                        this.$element.removeClass( 'oo-ui-popupToolGroup-active' );
                        this.$group.removeClass( 'oo-ui-popupToolGroup-active-tools' );
                        this.togglePositioning( false );
@@ -2159,18 +2251,20 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
 
 /**
  * ListToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
- * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}
- * and {@link OO.ui.BarToolGroup BarToolGroup}). The {@link OO.ui.Tool tools} in a ListToolGroup are displayed
- * by label in a dropdown menu. The title of the tool is used as the label text. The menu itself can be configured
- * with a label, icon, indicator, header, and title.
+ * create {@link OO.ui.Toolbar toolbars} (the other types of groups are
+ * {@link OO.ui.MenuToolGroup MenuToolGroup} and {@link OO.ui.BarToolGroup BarToolGroup}).
+ * The {@link OO.ui.Tool tools} in a ListToolGroup are displayed by label in a dropdown menu.
+ * The title of the tool is used as the label text. The menu itself can be configured with a label,
+ * icon, indicator, header, and title.
  *
- * ListToolGroups can be configured to be expanded and collapsed. Collapsed lists will have a ‘More’ option that
- * users can select to see the full list of tools. If a collapsed toolgroup is expanded, a ‘Fewer’ option permits
- * users to collapse the list again.
+ * ListToolGroups can be configured to be expanded and collapsed. Collapsed lists will have a
+ * ‘More’ option that users can select to see the full list of tools. If a collapsed toolgroup is
+ * expanded, a ‘Fewer’ option permits users to collapse the list again.
  *
- * ListToolGroups are created by a {@link OO.ui.ToolGroupFactory toolgroup factory} when the toolbar is set up. The factory
- * requires the ListToolGroup's symbolic name, 'list', which is specified along with the other configurations. For more
- * information about how to add tools to a ListToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.
+ * ListToolGroups are created by a {@link OO.ui.ToolGroupFactory toolgroup factory} when the
+ * toolbar is set up. The factory requires the ListToolGroup's symbolic name, 'list', which is
+ * specified along with the other configurations. For more information about how to add tools to a
+ * ListToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.
  *
  *     @example
  *     // Example of a ListToolGroup
@@ -2210,7 +2304,8 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
  *             type: 'list',
  *             label: 'ListToolGroup',
  *             icon: 'ellipsis',
- *             title: 'This is the title, displayed when user moves the mouse over the list toolgroup',
+ *             title: 'This is the title, displayed when user moves the mouse over the list ' +
+ *                 'toolgroup',
  *             header: 'This is the header',
  *             include: [ 'settings', 'stuff' ],
  *             allowCollapse: ['stuff']
@@ -2229,7 +2324,8 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
  *     // Build the toolbar. This must be done after the toolbar has been appended to the document.
  *     toolbar.initialize();
  *
- * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].
+ * For more information about toolbars in general, please see the
+ * [OOUI documentation on MediaWiki][1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
  *
@@ -2239,16 +2335,19 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
  * @constructor
  * @param {OO.ui.Toolbar} toolbar
  * @param {Object} [config] Configuration options
- * @cfg {Array} [allowCollapse] Allow the specified tools to be collapsed. By default, collapsible tools
- *  will only be displayed if users click the ‘More’ option displayed at the bottom of the list. If
- *  the list is expanded, a ‘Fewer’ option permits users to collapse the list again. Any tools that
- *  are included in the toolgroup, but are not designated as collapsible, will always be displayed.
+ * @cfg {Array} [allowCollapse] Allow the specified tools to be collapsed. By default, collapsible
+ *  tools will only be displayed if users click the ‘More’ option displayed at the bottom of the
+ *  list. If the list is expanded, a ‘Fewer’ option permits users to collapse the list again.
+ *  Any tools that are included in the toolgroup, but are not designated as collapsible, will always
+ *  be displayed.
  *  To open a collapsible list in its expanded state, set #expanded to 'true'.
- * @cfg {Array} [forceExpand] Expand the specified tools. All other tools will be designated as collapsible.
- *  Unless #expanded is set to true, the collapsible tools will be collapsed when the list is first opened.
- * @cfg {boolean} [expanded=false] Expand collapsible tools. This config is only relevant if tools have
- *  been designated as collapsible. When expanded is set to true, all tools in the group will be displayed
- *  when the list is first opened. Users can collapse the list with a ‘Fewer’ option at the bottom.
+ * @cfg {Array} [forceExpand] Expand the specified tools. All other tools will be designated as
+ *  collapsible. Unless #expanded is set to true, the collapsible tools will be collapsed when the
+ *  list is first opened.
+ * @cfg {boolean} [expanded=false] Expand collapsible tools. This config is only relevant if tools
+ *  have been designated as collapsible. When expanded is set to true, all tools in the group will
+ *  be displayed when the list is first opened. Users can collapse the list with a ‘Fewer’ option at
+ *  the bottom.
  */
 OO.ui.ListToolGroup = function OoUiListToolGroup( toolbar, config ) {
        // Allow passing positional parameters inside the config object
@@ -2353,11 +2452,15 @@ OO.ui.ListToolGroup.prototype.getExpandCollapseTool = function () {
 OO.ui.ListToolGroup.prototype.onMouseKeyUp = function ( e ) {
        // Do not close the popup when the user wants to show more/fewer tools
        if (
-               $( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+               $( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length && (
+                       e.which === OO.ui.MouseButtons.LEFT ||
+                       e.which === OO.ui.Keys.SPACE ||
+                       e.which === OO.ui.Keys.ENTER
+               )
        ) {
-               // HACK: Prevent the popup list from being hidden. Skip the PopupToolGroup implementation (which
-               // hides the popup list when a tool is selected) and call ToolGroup's implementation directly.
+               // HACK: Prevent the popup list from being hidden. Skip the PopupToolGroup implementation
+               // (which hides the popup list when a tool is selected) and call ToolGroup's implementation
+               // directly.
                return OO.ui.ListToolGroup.parent.parent.prototype.onMouseKeyUp.call( this, e );
        } else {
                return OO.ui.ListToolGroup.parent.prototype.onMouseKeyUp.call( this, e );
@@ -2387,14 +2490,15 @@ OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
 
 /**
  * MenuToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
- * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.BarToolGroup BarToolGroup}
- * and {@link OO.ui.ListToolGroup ListToolGroup}). MenuToolGroups contain selectable {@link OO.ui.Tool tools},
- * which are displayed by label in a dropdown menu. The tool's title is used as the label text, and the
- * menu label is updated to reflect which tool or tools are currently selected. If no tools are selected,
- * the menu label is empty. The menu can be configured with an indicator, icon, title, and/or header.
+ * create {@link OO.ui.Toolbar toolbars} (the other types of groups are
+ * {@link OO.ui.BarToolGroup BarToolGroup} and {@link OO.ui.ListToolGroup ListToolGroup}).
+ * MenuToolGroups contain selectable {@link OO.ui.Tool tools}, which are displayed by label in a
+ * dropdown menu. The tool's title is used as the label text, and the menu label is updated to
+ * reflect which tool or tools are currently selected. If no tools are selected, the menu label
+ * is empty. The menu can be configured with an indicator, icon, title, and/or header.
  *
- * MenuToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar
- * is set up.
+ * MenuToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the
+ * toolbar is set up.
  *
  *     @example
  *     // Example of a MenuToolGroup
@@ -2403,7 +2507,8 @@ OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
  *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
  *
  *     // We will be placing status text in this element when tools are used
- *     var $area = $( '<p>' ).text( 'An example of a MenuToolGroup. Select a tool from the dropdown menu.' );
+ *     var $area = $( '<p>' ).text( 'An example of a MenuToolGroup. Select a tool from the '
+ *         + 'dropdown menu.' );
  *
  *     // Define the tools that we're going to place in our toolbar
  *
@@ -2476,8 +2581,10 @@ OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
  *     toolbar.initialize();
  *     toolbar.emit( 'updateState' );
  *
- * For more information about how to add tools to a MenuToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.
- * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki] [1].
+ * For more information about how to add tools to a MenuToolGroup, please see
+ * {@link OO.ui.ToolGroup toolgroup}.
+ * For more information about toolbars in general, please see the
+ * [OOUI documentation on MediaWiki] [1].
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
  *
@@ -2502,7 +2609,9 @@ OO.ui.MenuToolGroup = function OoUiMenuToolGroup( toolbar, config ) {
        OO.ui.MenuToolGroup.parent.call( this, toolbar, config );
 
        // Events
-       this.toolbar.connect( this, { updateState: 'onUpdateState' } );
+       this.toolbar.connect( this, {
+               updateState: 'onUpdateState'
+       } );
 
        // Initialization
        this.$element.addClass( 'oo-ui-menuToolGroup' );
index 54ee690..7146465 100644 (file)
@@ -1 +1 @@
-{"version":3,"sources":["../src/intro.js.txt","../src/Toolbar.js","../src/Tool.js","../src/ToolGroup.js","../src/ToolFactory.js","../src/ToolGroupFactory.js","../src/tools/PopupTool.js","../src/tools/ToolGroupTool.js","../src/toolgroups/BarToolGroup.js","../src/toolgroups/PopupToolGroup.js","../src/toolgroups/ListToolGroup.js","../src/toolgroups/MenuToolGroup.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-toolbars.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * Toolbars are complex interface components that permit users to easily access a variety\n * of {@link OO.ui.Tool tools} (e.g., formatting commands) and actions, which are additional commands that are\n * part of the toolbar, but not configured as tools.\n *\n * Individual tools are customized and then registered with a {@link OO.ui.ToolFactory tool factory}, which creates\n * the tools on demand. Each tool has a symbolic name (used when registering the tool), a title (e.g., ‘Insert\n * image’), and an icon.\n *\n * Individual tools are organized in {@link OO.ui.ToolGroup toolgroups}, which can be {@link OO.ui.MenuToolGroup menus}\n * of tools, {@link OO.ui.ListToolGroup lists} of tools, or a single {@link OO.ui.BarToolGroup bar} of tools.\n * The arrangement and order of the toolgroups is customized when the toolbar is set up. Tools can be presented in\n * any order, but each can only appear once in the toolbar.\n *\n * The toolbar can be synchronized with the state of the external \"application\", like a text\n * editor's editing area, marking tools as active/inactive (e.g. a 'bold' tool would be shown as\n * active when the text cursor was inside bolded text) or enabled/disabled (e.g. a table caption\n * tool would be disabled while the user is not editing a table). A state change is signalled by\n * emitting the {@link #event-updateState 'updateState' event}, which calls Tools'\n * {@link OO.ui.Tool#onUpdateState onUpdateState method}.\n *\n * The following is an example of a basic toolbar.\n *\n *     @example\n *     // Example of a toolbar\n *     // Create the toolbar\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'Toolbar example' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     // Create a class inheriting from OO.ui.Tool\n *     function SearchTool() {\n *         SearchTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SearchTool, OO.ui.Tool );\n *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one\n *     // of 'icon' and 'title' (displayed icon and text).\n *     SearchTool.static.name = 'search';\n *     SearchTool.static.icon = 'search';\n *     SearchTool.static.title = 'Search...';\n *     // Defines the action that will happen when this tool is selected (clicked).\n *     SearchTool.prototype.onSelect = function () {\n *         $area.text( 'Search tool clicked!' );\n *         // Never display this tool as \"active\" (selected).\n *         this.setActive( false );\n *     };\n *     SearchTool.prototype.onUpdateState = function () {};\n *     // Make this tool available in our toolFactory and thus our toolbar\n *     toolFactory.register( SearchTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         $area.text( 'Settings tool clicked!' );\n *         this.setActive( false );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'ellipsis';\n *     StuffTool.static.title = 'More stuff';\n *     StuffTool.prototype.onSelect = function () {\n *         $area.text( 'More stuff tool clicked!' );\n *         this.setActive( false );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *\n *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a\n *     // little popup window (a PopupWidget).\n *     function HelpTool( toolGroup, config ) {\n *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *             padded: true,\n *             label: 'Help',\n *             head: true\n *         } }, config ) );\n *         this.popup.$body.append( '<p>I am helpful!</p>' );\n *     }\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             // 'bar' tool groups display tools' icons only, side-by-side.\n *             type: 'bar',\n *             include: [ 'search', 'help' ]\n *         },\n *         {\n *             // 'list' tool groups display both the titles and icons, in a dropdown list.\n *             type: 'list',\n *             indicator: 'down',\n *             label: 'More',\n *             include: [ 'settings', 'stuff' ]\n *         }\n *         // Note how the tools themselves are toolgroup-agnostic - the same tool can be displayed\n *         // either in a 'list' or a 'bar'. There is a 'menu' tool group too, not showcased here,\n *         // since it's more complicated to use. (See the next example snippet on this page.)\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *     toolbar.emit( 'updateState' );\n *\n * The following example extends the previous one to illustrate 'menu' toolgroups and the usage of\n * {@link #event-updateState 'updateState' event}.\n *\n *     @example\n *     // Create the toolbar\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'Toolbar example' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     // Create a class inheriting from OO.ui.Tool\n *     function SearchTool() {\n *         SearchTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SearchTool, OO.ui.Tool );\n *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one\n *     // of 'icon' and 'title' (displayed icon and text).\n *     SearchTool.static.name = 'search';\n *     SearchTool.static.icon = 'search';\n *     SearchTool.static.title = 'Search...';\n *     // Defines the action that will happen when this tool is selected (clicked).\n *     SearchTool.prototype.onSelect = function () {\n *         $area.text( 'Search tool clicked!' );\n *         // Never display this tool as \"active\" (selected).\n *         this.setActive( false );\n *     };\n *     SearchTool.prototype.onUpdateState = function () {};\n *     // Make this tool available in our toolFactory and thus our toolbar\n *     toolFactory.register( SearchTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         $area.text( 'Settings tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'ellipsis';\n *     StuffTool.static.title = 'More stuff';\n *     StuffTool.prototype.onSelect = function () {\n *         $area.text( 'More stuff tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *\n *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a\n *     // little popup window (a PopupWidget). 'onUpdateState' is also already implemented.\n *     function HelpTool( toolGroup, config ) {\n *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *             padded: true,\n *             label: 'Help',\n *             head: true\n *         } }, config ) );\n *         this.popup.$body.append( '<p>I am helpful!</p>' );\n *     }\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             // 'bar' tool groups display tools' icons only, side-by-side.\n *             type: 'bar',\n *             include: [ 'search', 'help' ]\n *         },\n *         {\n *             // 'menu' tool groups display both the titles and icons, in a dropdown menu.\n *             // Menu label indicates which items are selected.\n *             type: 'menu',\n *             indicator: 'down',\n *             include: [ 'settings', 'stuff' ]\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *     toolbar.emit( 'updateState' );\n *\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {OO.ui.ToolFactory} toolFactory Factory for creating tools\n * @param {OO.ui.ToolGroupFactory} toolGroupFactory Factory for creating toolgroups\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [actions] Add an actions section to the toolbar. Actions are commands that are included\n *  in the toolbar, but are not configured as tools. By default, actions are displayed on the right side of\n *  the toolbar.\n * @cfg {string} [position='top'] Whether the toolbar is positioned above ('top') or below ('bottom') content.\n * @cfg {jQuery} [$overlay] An overlay for the popup.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolFactory ) && config === undefined ) {\n\t\tconfig = toolFactory;\n\t\ttoolFactory = config.toolFactory;\n\t\ttoolGroupFactory = config.toolGroupFactory;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Toolbar.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.toolFactory = toolFactory;\n\tthis.toolGroupFactory = toolGroupFactory;\n\tthis.groupsByName = {};\n\tthis.activeToolGroups = 0;\n\tthis.tools = {};\n\tthis.position = config.position || 'top';\n\tthis.$bar = $( '<div>' );\n\tthis.$actions = $( '<div>' );\n\tthis.$popups = $( '<div>' );\n\tthis.initialized = false;\n\tthis.narrowThreshold = null;\n\tthis.onWindowResizeHandler = this.onWindowResize.bind( this );\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\n\t// Events\n\tthis.$element\n\t\t.add( this.$bar ).add( this.$group ).add( this.$actions )\n\t\t.on( 'mousedown keydown', this.onPointerDown.bind( this ) );\n\n\t// Initialization\n\tthis.$group.addClass( 'oo-ui-toolbar-tools' );\n\tif ( config.actions ) {\n\t\tthis.$bar.append( this.$actions.addClass( 'oo-ui-toolbar-actions' ) );\n\t}\n\tthis.$popups.addClass( 'oo-ui-toolbar-popups' );\n\tthis.$bar\n\t\t.addClass( 'oo-ui-toolbar-bar' )\n\t\t.append( this.$group, '<div style=\"clear:both\"></div>' );\n\t// Possible classes: oo-ui-toolbar-position-top, oo-ui-toolbar-position-bottom\n\tthis.$element.addClass( 'oo-ui-toolbar oo-ui-toolbar-position-' + this.position ).append( this.$bar );\n\tthis.$overlay.append( this.$popups );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Toolbar, OO.ui.Element );\nOO.mixinClass( OO.ui.Toolbar, OO.EventEmitter );\nOO.mixinClass( OO.ui.Toolbar, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * @event updateState\n *\n * An 'updateState' event must be emitted on the Toolbar (by calling `toolbar.emit( 'updateState' )`)\n * every time the state of the application using the toolbar changes, and an update to the state of\n * tools is required.\n *\n * @param {...Mixed} data Application-defined parameters\n */\n\n/**\n * @event active\n *\n * An 'active' event is emitted when the number of active toolgroups increases from 0, or\n * returns to 0.\n *\n * @param {boolean} There are active toolgroups in this toolbar\n */\n\n/* Methods */\n\n/**\n * Get the tool factory.\n *\n * @return {OO.ui.ToolFactory} Tool factory\n */\nOO.ui.Toolbar.prototype.getToolFactory = function () {\n\treturn this.toolFactory;\n};\n\n/**\n * Get the toolgroup factory.\n *\n * @return {OO.Factory} Toolgroup factory\n */\nOO.ui.Toolbar.prototype.getToolGroupFactory = function () {\n\treturn this.toolGroupFactory;\n};\n\n/**\n * Handles mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.Toolbar.prototype.onPointerDown = function ( e ) {\n\tvar $closestWidgetToEvent = $( e.target ).closest( '.oo-ui-widget' ),\n\t\t$closestWidgetToToolbar = this.$element.closest( '.oo-ui-widget' );\n\tif ( !$closestWidgetToEvent.length || $closestWidgetToEvent[ 0 ] === $closestWidgetToToolbar[ 0 ] ) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle window resize event.\n *\n * @private\n * @param {jQuery.Event} e Window resize event\n */\nOO.ui.Toolbar.prototype.onWindowResize = function () {\n\tthis.$element.add( this.$popups ).toggleClass(\n\t\t'oo-ui-toolbar-narrow',\n\t\tthis.$bar[ 0 ].clientWidth <= this.getNarrowThreshold()\n\t);\n};\n\n/**\n * Get the (lazily-computed) width threshold for applying the oo-ui-toolbar-narrow\n * class.\n *\n * @private\n * @return {number} Width threshold in pixels\n */\nOO.ui.Toolbar.prototype.getNarrowThreshold = function () {\n\tif ( this.narrowThreshold === null ) {\n\t\tthis.narrowThreshold = this.$group[ 0 ].offsetWidth + this.$actions[ 0 ].offsetWidth;\n\t}\n\treturn this.narrowThreshold;\n};\n\n/**\n * Sets up handles and preloads required information for the toolbar to work.\n * This must be called after it is attached to a visible document and before doing anything else.\n */\nOO.ui.Toolbar.prototype.initialize = function () {\n\tif ( !this.initialized ) {\n\t\tthis.initialized = true;\n\t\t$( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler );\n\t\tthis.onWindowResize();\n\t}\n};\n\n/**\n * Set up the toolbar.\n *\n * The toolbar is set up with a list of toolgroup configurations that specify the type of\n * toolgroup ({@link OO.ui.BarToolGroup bar}, {@link OO.ui.MenuToolGroup menu}, or {@link OO.ui.ListToolGroup list})\n * to add and which tools to include, exclude, promote, or demote within that toolgroup. Please\n * see {@link OO.ui.ToolGroup toolgroups} for more information about including tools in toolgroups.\n *\n * @param {Object.<string,Array>} groups List of toolgroup configurations\n * @param {string} [groups.name] Symbolic name for this toolgroup\n * @param {string} [groups.type] Toolgroup type, should exist in the toolgroup factory\n * @param {Array|string} [groups.include] Tools to include in the toolgroup\n * @param {Array|string} [groups.exclude] Tools to exclude from the toolgroup\n * @param {Array|string} [groups.promote] Tools to promote to the beginning of the toolgroup\n * @param {Array|string} [groups.demote] Tools to demote to the end of the toolgroup\n */\nOO.ui.Toolbar.prototype.setup = function ( groups ) {\n\tvar i, len, type, toolGroup, groupConfig,\n\t\titems = [],\n\t\tdefaultType = 'bar';\n\n\t// Cleanup previous groups\n\tthis.reset();\n\n\t// Build out new groups\n\tfor ( i = 0, len = groups.length; i < len; i++ ) {\n\t\tgroupConfig = groups[ i ];\n\t\tif ( groupConfig.include === '*' ) {\n\t\t\t// Apply defaults to catch-all groups\n\t\t\tif ( groupConfig.type === undefined ) {\n\t\t\t\tgroupConfig.type = 'list';\n\t\t\t}\n\t\t\tif ( groupConfig.label === undefined ) {\n\t\t\t\tgroupConfig.label = OO.ui.msg( 'ooui-toolbar-more' );\n\t\t\t}\n\t\t}\n\t\t// Check type has been registered\n\t\ttype = this.getToolGroupFactory().lookup( groupConfig.type ) ? groupConfig.type : defaultType;\n\t\ttoolGroup = this.getToolGroupFactory().create( type, this, groupConfig );\n\t\titems.push( toolGroup );\n\t\tif ( groupConfig.name ) {\n\t\t\tthis.groupsByName[ groupConfig.name ] = toolGroup;\n\t\t} else {\n\t\t\t// Groups without name are deprecated\n\t\t\tOO.ui.warnDeprecation( 'Toolgroups must have a \\'name\\' property' );\n\t\t}\n\t\ttoolGroup.connect( this, { active: 'onToolGroupActive' } );\n\t}\n\tthis.addItems( items );\n};\n\n/**\n * Handle active events from tool groups\n *\n * @param {boolean} active Tool group has become active, inactive if false\n * @fires active\n */\nOO.ui.Toolbar.prototype.onToolGroupActive = function ( active ) {\n\tif ( active ) {\n\t\tthis.activeToolGroups++;\n\t\tif ( this.activeToolGroups === 1 ) {\n\t\t\tthis.emit( 'active', true );\n\t\t}\n\t} else {\n\t\tthis.activeToolGroups--;\n\t\tif ( this.activeToolGroups === 0 ) {\n\t\t\tthis.emit( 'active', false );\n\t\t}\n\t}\n};\n\n/**\n * Get a toolgroup by name\n *\n * @param {string} name Group name\n * @return {OO.ui.ToolGroup|null} Tool group, or null if none found by that name\n */\nOO.ui.Toolbar.prototype.getToolGroupByName = function ( name ) {\n\treturn this.groupsByName[ name ] || null;\n};\n\n/**\n * Remove all tools and toolgroups from the toolbar.\n */\nOO.ui.Toolbar.prototype.reset = function () {\n\tvar i, len;\n\n\tthis.groupsByName = {};\n\tthis.tools = {};\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tthis.items[ i ].destroy();\n\t}\n\tthis.clearItems();\n};\n\n/**\n * Destroy the toolbar.\n *\n * Destroying the toolbar removes all event handlers and DOM elements that constitute the toolbar. Call\n * this method whenever you are done using a toolbar.\n */\nOO.ui.Toolbar.prototype.destroy = function () {\n\t$( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );\n\tthis.reset();\n\tthis.$element.remove();\n};\n\n/**\n * Check if the tool is available.\n *\n * Available tools are ones that have not yet been added to the toolbar.\n *\n * @param {string} name Symbolic name of tool\n * @return {boolean} Tool is available\n */\nOO.ui.Toolbar.prototype.isToolAvailable = function ( name ) {\n\treturn !this.tools[ name ];\n};\n\n/**\n * Prevent tool from being used again.\n *\n * @param {OO.ui.Tool} tool Tool to reserve\n */\nOO.ui.Toolbar.prototype.reserveTool = function ( tool ) {\n\tthis.tools[ tool.getName() ] = tool;\n};\n\n/**\n * Allow tool to be used again.\n *\n * @param {OO.ui.Tool} tool Tool to release\n */\nOO.ui.Toolbar.prototype.releaseTool = function ( tool ) {\n\tdelete this.tools[ tool.getName() ];\n};\n\n/**\n * Get accelerator label for tool.\n *\n * The OOUI library does not contain an accelerator system, but this is the hook for one. To\n * use an accelerator system, subclass the toolbar and override this method, which is meant to return a label\n * that describes the accelerator keys for the tool passed (by symbolic name) to the method.\n *\n * @param {string} name Symbolic name of tool\n * @return {string|undefined} Tool accelerator label if available\n */\nOO.ui.Toolbar.prototype.getToolAccelerator = function () {\n\treturn undefined;\n};\n","/**\n * Tools, together with {@link OO.ui.ToolGroup toolgroups}, constitute {@link OO.ui.Toolbar toolbars}.\n * Each tool is configured with a static name, title, and icon and is customized with the command to carry\n * out when the tool is selected. Tools must also be registered with a {@link OO.ui.ToolFactory tool factory},\n * which creates the tools on demand.\n *\n * Every Tool subclass must implement two methods:\n *\n * - {@link #onUpdateState}\n * - {@link #onSelect}\n *\n * Tools are added to toolgroups ({@link OO.ui.ListToolGroup ListToolGroup},\n * {@link OO.ui.BarToolGroup BarToolGroup}, or {@link OO.ui.MenuToolGroup MenuToolGroup}), which determine how\n * the tool is displayed in the toolbar. See {@link OO.ui.Toolbar toolbars} for an example.\n *\n * For more information, please see the [OOUI documentation on MediaWiki][1].\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {OO.ui.ToolGroup} toolGroup\n * @param {Object} [config] Configuration options\n * @cfg {string|Function} [title] Title text or a function that returns text. If this config is omitted, the value of\n *  the {@link #static-title static title} property is used.\n *\n *  The title is used in different ways depending on the type of toolgroup that contains the tool. The\n *  title is used as a tooltip if the tool is part of a {@link OO.ui.BarToolGroup bar} toolgroup, or as the label text if the tool is\n *  part of a {@link OO.ui.ListToolGroup list} or {@link OO.ui.MenuToolGroup menu} toolgroup.\n *\n *  For bar toolgroups, a description of the accelerator key is appended to the title if an accelerator key\n *  is associated with an action by the same name as the tool and accelerator functionality has been added to the application.\n *  To add accelerator key functionality, you must subclass OO.ui.Toolbar and override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method.\n */\nOO.ui.Tool = function OoUiTool( toolGroup, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolGroup ) && config === undefined ) {\n\t\tconfig = toolGroup;\n\t\ttoolGroup = config.toolGroup;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Tool.parent.call( this, config );\n\n\t// Properties\n\tthis.toolGroup = toolGroup;\n\tthis.toolbar = this.toolGroup.getToolbar();\n\tthis.active = false;\n\tthis.$title = $( '<span>' );\n\tthis.$accel = $( '<span>' );\n\tthis.$link = $( '<a>' );\n\tthis.title = null;\n\tthis.checkIcon = new OO.ui.IconWidget( {\n\t\ticon: 'check',\n\t\tclasses: [ 'oo-ui-tool-checkIcon' ]\n\t} );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$link } ) );\n\n\t// Events\n\tthis.toolbar.connect( this, { updateState: 'onUpdateState' } );\n\n\t// Initialization\n\tthis.$title.addClass( 'oo-ui-tool-title' );\n\tthis.$accel\n\t\t.addClass( 'oo-ui-tool-accel' )\n\t\t.prop( {\n\t\t\t// This may need to be changed if the key names are ever localized,\n\t\t\t// but for now they are essentially written in English\n\t\t\tdir: 'ltr',\n\t\t\tlang: 'en'\n\t\t} );\n\tthis.$link\n\t\t.addClass( 'oo-ui-tool-link' )\n\t\t.append( this.checkIcon.$element, this.$icon, this.$title, this.$accel )\n\t\t.attr( 'role', 'button' );\n\tthis.$element\n\t\t.data( 'oo-ui-tool', this )\n\t\t.addClass( 'oo-ui-tool' )\n\t\t.addClass( 'oo-ui-tool-name-' + this.constructor.static.name.replace( /^([^/]+)\\/([^/]+).*$/, '$1-$2' ) )\n\t\t.toggleClass( 'oo-ui-tool-with-label', this.constructor.static.displayBothIconAndLabel )\n\t\t.append( this.$link );\n\tthis.setTitle( config.title || this.constructor.static.title );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Tool, OO.ui.Widget );\nOO.mixinClass( OO.ui.Tool, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.Tool, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.Tool, OO.ui.mixin.TabIndexedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.Tool.static.tagName = 'span';\n\n/**\n * Symbolic name of tool.\n *\n * The symbolic name is used internally to register the tool with a {@link OO.ui.ToolFactory ToolFactory}. It can\n * also be used when adding tools to toolgroups.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Tool.static.name = '';\n\n/**\n * Symbolic name of the group.\n *\n * The group name is used to associate tools with each other so that they can be selected later by\n * a {@link OO.ui.ToolGroup toolgroup}.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Tool.static.group = '';\n\n/**\n * Tool title text or a function that returns title text. The value of the static property is overridden if the #title config option is used.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string|Function}\n */\nOO.ui.Tool.static.title = '';\n\n/**\n * Display both icon and label when the tool is used in a {@link OO.ui.BarToolGroup bar} toolgroup.\n * Normally only the icon is displayed, or only the label if no icon is given.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.Tool.static.displayBothIconAndLabel = false;\n\n/**\n * Add tool to catch-all groups automatically.\n *\n * A catch-all group, which contains all tools that do not currently belong to a toolgroup,\n * can be included in a toolgroup using the wildcard selector, an asterisk (*).\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.Tool.static.autoAddToCatchall = true;\n\n/**\n * Add tool to named groups automatically.\n *\n * By default, tools that are configured with a static ‘group’ property are added\n * to that group and will be selected when the symbolic name of the group is specified (e.g., when\n * toolgroups include tools by group name).\n *\n * @static\n * @property {boolean}\n * @inheritable\n */\nOO.ui.Tool.static.autoAddToGroup = true;\n\n/**\n * Check if this tool is compatible with given data.\n *\n * This is a stub that can be overridden to provide support for filtering tools based on an\n * arbitrary piece of information  (e.g., where the cursor is in a document). The implementation\n * must also call this method so that the compatibility check can be performed.\n *\n * @static\n * @inheritable\n * @param {Mixed} data Data to check\n * @return {boolean} Tool can be used with data\n */\nOO.ui.Tool.static.isCompatibleWith = function () {\n\treturn false;\n};\n\n/* Methods */\n\n/**\n * Handle the toolbar state being updated. This method is called when the\n * {@link OO.ui.Toolbar#event-updateState 'updateState' event} is emitted on the\n * {@link OO.ui.Toolbar Toolbar} that uses this tool, and should set the state of this tool\n * depending on application state (usually by calling #setDisabled to enable or disable the tool,\n * or #setActive to mark is as currently in-use or not).\n *\n * This is an abstract method that must be overridden in a concrete subclass.\n *\n * @method\n * @protected\n * @abstract\n */\nOO.ui.Tool.prototype.onUpdateState = null;\n\n/**\n * Handle the tool being selected. This method is called when the user triggers this tool,\n * usually by clicking on its label/icon.\n *\n * This is an abstract method that must be overridden in a concrete subclass.\n *\n * @method\n * @protected\n * @abstract\n */\nOO.ui.Tool.prototype.onSelect = null;\n\n/**\n * Check if the tool is active.\n *\n * Tools become active when their #onSelect or #onUpdateState handlers change them to appear pressed\n * with the #setActive method. Additional CSS is applied to the tool to reflect the active state.\n *\n * @return {boolean} Tool is active\n */\nOO.ui.Tool.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Make the tool appear active or inactive.\n *\n * This method should be called within #onSelect or #onUpdateState event handlers to make the tool\n * appear pressed or not.\n *\n * @param {boolean} state Make tool appear active\n */\nOO.ui.Tool.prototype.setActive = function ( state ) {\n\tthis.active = !!state;\n\tthis.$element.toggleClass( 'oo-ui-tool-active', this.active );\n\tthis.updateThemeClasses();\n};\n\n/**\n * Set the tool #title.\n *\n * @param {string|Function} title Title text or a function that returns text\n * @chainable\n * @return {OO.ui.Tool} The tool, for chaining\n */\nOO.ui.Tool.prototype.setTitle = function ( title ) {\n\tthis.title = OO.ui.resolveMsg( title );\n\tthis.updateTitle();\n\treturn this;\n};\n\n/**\n * Get the tool #title.\n *\n * @return {string} Title text\n */\nOO.ui.Tool.prototype.getTitle = function () {\n\treturn this.title;\n};\n\n/**\n * Get the tool's symbolic name.\n *\n * @return {string} Symbolic name of tool\n */\nOO.ui.Tool.prototype.getName = function () {\n\treturn this.constructor.static.name;\n};\n\n/**\n * Update the title.\n */\nOO.ui.Tool.prototype.updateTitle = function () {\n\tvar titleTooltips = this.toolGroup.constructor.static.titleTooltips,\n\t\taccelTooltips = this.toolGroup.constructor.static.accelTooltips,\n\t\taccel = this.toolbar.getToolAccelerator( this.constructor.static.name ),\n\t\ttooltipParts = [];\n\n\tthis.$title.text( this.title );\n\tthis.$accel.text( accel );\n\n\tif ( titleTooltips && typeof this.title === 'string' && this.title.length ) {\n\t\ttooltipParts.push( this.title );\n\t}\n\tif ( accelTooltips && typeof accel === 'string' && accel.length ) {\n\t\ttooltipParts.push( accel );\n\t}\n\tif ( tooltipParts.length ) {\n\t\tthis.$link.attr( 'title', tooltipParts.join( ' ' ) );\n\t} else {\n\t\tthis.$link.removeAttr( 'title' );\n\t}\n};\n\n/**\n * Destroy tool.\n *\n * Destroying the tool removes all event handlers and the tool’s DOM elements.\n * Call this method whenever you are done using a tool.\n */\nOO.ui.Tool.prototype.destroy = function () {\n\tthis.toolbar.disconnect( this );\n\tthis.$element.remove();\n};\n","/**\n * ToolGroups are collections of {@link OO.ui.Tool tools} that are used in a {@link OO.ui.Toolbar toolbar}.\n * The type of toolgroup ({@link OO.ui.ListToolGroup list}, {@link OO.ui.BarToolGroup bar}, or {@link OO.ui.MenuToolGroup menu})\n * to which a tool belongs determines how the tool is arranged and displayed in the toolbar. Toolgroups\n * themselves are created on demand with a {@link OO.ui.ToolGroupFactory toolgroup factory}.\n *\n * Toolgroups can contain individual tools, groups of tools, or all available tools, as specified\n * using the `include` config option. See OO.ui.ToolFactory#extract on documentation of the format.\n * The options `exclude`, `promote`, and `demote` support the same formats.\n *\n * See {@link OO.ui.Toolbar toolbars} for a full example. For more information about toolbars in general,\n * please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n * @cfg {Array|string} [include] List of tools to include in the toolgroup, see above.\n * @cfg {Array|string} [exclude] List of tools to exclude from the toolgroup, see above.\n * @cfg {Array|string} [promote] List of tools to promote to the beginning of the toolgroup, see above.\n * @cfg {Array|string} [demote] List of tools to demote to the end of the toolgroup, see above.\n *  This setting is particularly useful when tools have been added to the toolgroup\n *  en masse (e.g., via the catch-all selector).\n */\nOO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ToolGroup.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.toolbar = toolbar;\n\tthis.tools = {};\n\tthis.pressed = null;\n\tthis.autoDisabled = false;\n\tthis.include = config.include || [];\n\tthis.exclude = config.exclude || [];\n\tthis.promote = config.promote || [];\n\tthis.demote = config.demote || [];\n\tthis.onDocumentMouseKeyUpHandler = this.onDocumentMouseKeyUp.bind( this );\n\n\t// Events\n\tthis.$group.on( {\n\t\tmousedown: this.onMouseKeyDown.bind( this ),\n\t\tmouseup: this.onMouseKeyUp.bind( this ),\n\t\tkeydown: this.onMouseKeyDown.bind( this ),\n\t\tkeyup: this.onMouseKeyUp.bind( this ),\n\t\tfocus: this.onMouseOverFocus.bind( this ),\n\t\tblur: this.onMouseOutBlur.bind( this ),\n\t\tmouseover: this.onMouseOverFocus.bind( this ),\n\t\tmouseout: this.onMouseOutBlur.bind( this )\n\t} );\n\tthis.toolbar.getToolFactory().connect( this, { register: 'onToolFactoryRegister' } );\n\tthis.aggregate( { disable: 'itemDisable' } );\n\tthis.connect( this, {\n\t\titemDisable: 'updateDisabled',\n\t\tdisable: 'onDisable'\n\t} );\n\n\t// Initialization\n\tthis.$group.addClass( 'oo-ui-toolGroup-tools' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-toolGroup' )\n\t\t.append( this.$group );\n\tthis.onDisable( this.isDisabled() );\n\tthis.populate();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolGroup, OO.ui.Widget );\nOO.mixinClass( OO.ui.ToolGroup, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * @event update\n */\n\n/**\n * @event active\n *\n * An 'active' event is emitted when any popup is shown/hidden.\n *\n * @param {boolean} The popup is visible\n */\n\n/* Static Properties */\n\n/**\n * Show labels in tooltips.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.ToolGroup.static.titleTooltips = false;\n\n/**\n * Show acceleration labels in tooltips.\n *\n * Note: The OOUI library does not include an accelerator system, but does contain\n * a hook for one. To use an accelerator system, subclass the {@link OO.ui.Toolbar toolbar} and\n * override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method, which is\n * meant to return a label that describes the accelerator keys for a given tool (e.g., 'Ctrl + M').\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.ToolGroup.static.accelTooltips = false;\n\n/**\n * Automatically disable the toolgroup when all tools are disabled\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.ToolGroup.static.autoDisable = true;\n\n/**\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.ToolGroup.static.name = null;\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ToolGroup.prototype.isDisabled = function () {\n\treturn this.autoDisabled || OO.ui.ToolGroup.parent.prototype.isDisabled.apply( this, arguments );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToolGroup.prototype.updateDisabled = function () {\n\tvar i, item, allDisabled = true;\n\n\tif ( this.constructor.static.autoDisable ) {\n\t\tfor ( i = this.items.length - 1; i >= 0; i-- ) {\n\t\t\titem = this.items[ i ];\n\t\t\tif ( !item.isDisabled() ) {\n\t\t\t\tallDisabled = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tthis.autoDisabled = allDisabled;\n\t}\n\tOO.ui.ToolGroup.parent.prototype.updateDisabled.apply( this, arguments );\n};\n\n/**\n * Handle disable events.\n *\n * @protected\n * @param {boolean} isDisabled\n */\nOO.ui.ToolGroup.prototype.onDisable = function ( isDisabled ) {\n\tthis.$group.toggleClass( 'oo-ui-toolGroup-disabled-tools', isDisabled );\n\tthis.$group.toggleClass( 'oo-ui-toolGroup-enabled-tools', !isDisabled );\n};\n\n/**\n * Handle mouse down and key down events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse down or key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.ToolGroup.prototype.onMouseKeyDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\t( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )\n\t) {\n\t\tthis.pressed = this.findTargetTool( e );\n\t\tif ( this.pressed ) {\n\t\t\tthis.pressed.setActive( true );\n\t\t\tthis.getElementDocument().addEventListener( 'mouseup', this.onDocumentMouseKeyUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'keyup', this.onDocumentMouseKeyUpHandler, true );\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Handle document mouse up and key up events.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.ToolGroup.prototype.onDocumentMouseKeyUp = function ( e ) {\n\tthis.getElementDocument().removeEventListener( 'mouseup', this.onDocumentMouseKeyUpHandler, true );\n\tthis.getElementDocument().removeEventListener( 'keyup', this.onDocumentMouseKeyUpHandler, true );\n\t// onMouseKeyUp may be called a second time, depending on where the mouse is when the button is\n\t// released, but since `this.pressed` will no longer be true, the second call will be ignored.\n\tthis.onMouseKeyUp( e );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.ToolGroup.prototype.onCapturedMouseKeyUp = function () {\n\tOO.ui.warnDeprecation( 'onCapturedMouseKeyUp is deprecated, use onDocumentMouseKeyUp instead' );\n\tthis.onDocumentMouseKeyUp.apply( this, arguments );\n};\n\n/**\n * Handle mouse up and key up events.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.ToolGroup.prototype.onMouseKeyUp = function ( e ) {\n\tvar tool = this.findTargetTool( e );\n\n\tif (\n\t\t!this.isDisabled() && this.pressed && this.pressed === tool &&\n\t\t( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )\n\t) {\n\t\tthis.pressed.onSelect();\n\t\tthis.pressed = null;\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t}\n\n\tthis.pressed = null;\n};\n\n/**\n * Handle mouse over and focus events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse over or focus event\n */\nOO.ui.ToolGroup.prototype.onMouseOverFocus = function ( e ) {\n\tvar tool = this.findTargetTool( e );\n\n\tif ( this.pressed && this.pressed === tool ) {\n\t\tthis.pressed.setActive( true );\n\t}\n};\n\n/**\n * Handle mouse out and blur events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse out or blur event\n */\nOO.ui.ToolGroup.prototype.onMouseOutBlur = function ( e ) {\n\tvar tool = this.findTargetTool( e );\n\n\tif ( this.pressed && this.pressed === tool ) {\n\t\tthis.pressed.setActive( false );\n\t}\n};\n\n/**\n * Get the closest tool to a jQuery.Event.\n *\n * Only tool links are considered, which prevents other elements in the tool such as popups from\n * triggering tool group interactions.\n *\n * @private\n * @param {jQuery.Event} e\n * @return {OO.ui.Tool|null} Tool, `null` if none was found\n */\nOO.ui.ToolGroup.prototype.findTargetTool = function ( e ) {\n\tvar tool,\n\t\t$item = $( e.target ).closest( '.oo-ui-tool-link' );\n\n\tif ( $item.length ) {\n\t\ttool = $item.parent().data( 'oo-ui-tool' );\n\t}\n\n\treturn tool && !tool.isDisabled() ? tool : null;\n};\n\n/**\n * Handle tool registry register events.\n *\n * If a tool is registered after the group is created, we must repopulate the list to account for:\n *\n * - a tool being added that may be included\n * - a tool already included being overridden\n *\n * @protected\n * @param {string} name Symbolic name of tool\n */\nOO.ui.ToolGroup.prototype.onToolFactoryRegister = function () {\n\tthis.populate();\n};\n\n/**\n * Get the toolbar that contains the toolgroup.\n *\n * @return {OO.ui.Toolbar} Toolbar that contains the toolgroup\n */\nOO.ui.ToolGroup.prototype.getToolbar = function () {\n\treturn this.toolbar;\n};\n\n/**\n * Add and remove tools based on configuration.\n */\nOO.ui.ToolGroup.prototype.populate = function () {\n\tvar i, len, name, tool,\n\t\ttoolFactory = this.toolbar.getToolFactory(),\n\t\tnames = {},\n\t\tadd = [],\n\t\tremove = [],\n\t\tlist = this.toolbar.getToolFactory().getTools(\n\t\t\tthis.include, this.exclude, this.promote, this.demote\n\t\t);\n\n\t// Build a list of needed tools\n\tfor ( i = 0, len = list.length; i < len; i++ ) {\n\t\tname = list[ i ];\n\t\tif (\n\t\t\t// Tool exists\n\t\t\ttoolFactory.lookup( name ) &&\n\t\t\t// Tool is available or is already in this group\n\t\t\t( this.toolbar.isToolAvailable( name ) || this.tools[ name ] )\n\t\t) {\n\t\t\t// Hack to prevent infinite recursion via ToolGroupTool. We need to reserve the tool before\n\t\t\t// creating it, but we can't call reserveTool() yet because we haven't created the tool.\n\t\t\tthis.toolbar.tools[ name ] = true;\n\t\t\ttool = this.tools[ name ];\n\t\t\tif ( !tool ) {\n\t\t\t\t// Auto-initialize tools on first use\n\t\t\t\tthis.tools[ name ] = tool = toolFactory.create( name, this );\n\t\t\t\ttool.updateTitle();\n\t\t\t}\n\t\t\tthis.toolbar.reserveTool( tool );\n\t\t\tadd.push( tool );\n\t\t\tnames[ name ] = true;\n\t\t}\n\t}\n\t// Remove tools that are no longer needed\n\tfor ( name in this.tools ) {\n\t\tif ( !names[ name ] ) {\n\t\t\tthis.tools[ name ].destroy();\n\t\t\tthis.toolbar.releaseTool( this.tools[ name ] );\n\t\t\tremove.push( this.tools[ name ] );\n\t\t\tdelete this.tools[ name ];\n\t\t}\n\t}\n\tif ( remove.length ) {\n\t\tthis.removeItems( remove );\n\t}\n\t// Update emptiness state\n\tif ( add.length ) {\n\t\tthis.$element.removeClass( 'oo-ui-toolGroup-empty' );\n\t} else {\n\t\tthis.$element.addClass( 'oo-ui-toolGroup-empty' );\n\t}\n\t// Re-add tools (moving existing ones to new locations)\n\tthis.addItems( add );\n\t// Disabled state may depend on items\n\tthis.updateDisabled();\n};\n\n/**\n * Destroy toolgroup.\n */\nOO.ui.ToolGroup.prototype.destroy = function () {\n\tvar name;\n\n\tthis.clearItems();\n\tthis.toolbar.getToolFactory().disconnect( this );\n\tfor ( name in this.tools ) {\n\t\tthis.toolbar.releaseTool( this.tools[ name ] );\n\t\tthis.tools[ name ].disconnect( this ).destroy();\n\t\tdelete this.tools[ name ];\n\t}\n\tthis.$element.remove();\n};\n","/**\n * A ToolFactory creates tools on demand. All tools ({@link OO.ui.Tool Tools}, {@link OO.ui.PopupTool PopupTools},\n * and {@link OO.ui.ToolGroupTool ToolGroupTools}) must be registered with a tool factory. Tools are\n * registered by their symbolic name. See {@link OO.ui.Toolbar toolbars} for an example.\n *\n * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.Factory\n * @constructor\n */\nOO.ui.ToolFactory = function OoUiToolFactory() {\n\t// Parent constructor\n\tOO.ui.ToolFactory.parent.call( this );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolFactory, OO.Factory );\n\n/* Methods */\n\n/**\n * Get tools from the factory\n *\n * @param {Array|string} [include] Included tools, see #extract for format\n * @param {Array|string} [exclude] Excluded tools, see #extract for format\n * @param {Array|string} [promote] Promoted tools, see #extract for format\n * @param {Array|string} [demote] Demoted tools, see #extract for format\n * @return {string[]} List of tools\n */\nOO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {\n\tvar i, len, included, promoted, demoted,\n\t\tauto = [],\n\t\tused = {};\n\n\t// Collect included and not excluded tools\n\tincluded = OO.simpleArrayDifference( this.extract( include ), this.extract( exclude ) );\n\n\t// Promotion\n\tpromoted = this.extract( promote, used );\n\tdemoted = this.extract( demote, used );\n\n\t// Auto\n\tfor ( i = 0, len = included.length; i < len; i++ ) {\n\t\tif ( !used[ included[ i ] ] ) {\n\t\t\tauto.push( included[ i ] );\n\t\t}\n\t}\n\n\treturn promoted.concat( auto ).concat( demoted );\n};\n\n/**\n * Get a flat list of names from a list of names or groups.\n *\n * Normally, `collection` is an array of tool specifications. Tools can be specified in the\n * following ways:\n *\n * - To include an individual tool, use the symbolic name: `{ name: 'tool-name' }` or `'tool-name'`.\n * - To include all tools in a group, use the group name: `{ group: 'group-name' }`. (To assign the\n *   tool to a group, use OO.ui.Tool.static.group.)\n *\n * Alternatively, to include all tools that are not yet assigned to any other toolgroup, use the\n * catch-all selector `'*'`.\n *\n * If `used` is passed, tool names that appear as properties in this object will be considered\n * already assigned, and will not be returned even if specified otherwise. The tool names extracted\n * by this function call will be added as new properties in the object.\n *\n * @private\n * @param {Array|string} collection List of tools, see above\n * @param {Object} [used] Object containing information about used tools, see above\n * @return {string[]} List of extracted tool names\n */\nOO.ui.ToolFactory.prototype.extract = function ( collection, used ) {\n\tvar i, len, item, name, tool,\n\t\tnames = [];\n\n\tcollection = !Array.isArray( collection ) ? [ collection ] : collection;\n\n\tfor ( i = 0, len = collection.length; i < len; i++ ) {\n\t\titem = collection[ i ];\n\t\tif ( item === '*' ) {\n\t\t\tfor ( name in this.registry ) {\n\t\t\t\ttool = this.registry[ name ];\n\t\t\t\tif (\n\t\t\t\t\t// Only add tools by group name when auto-add is enabled\n\t\t\t\t\ttool.static.autoAddToCatchall &&\n\t\t\t\t\t// Exclude already used tools\n\t\t\t\t\t( !used || !used[ name ] )\n\t\t\t\t) {\n\t\t\t\t\tnames.push( name );\n\t\t\t\t\tif ( used ) {\n\t\t\t\t\t\tused[ name ] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Allow plain strings as shorthand for named tools\n\t\t\tif ( typeof item === 'string' ) {\n\t\t\t\titem = { name: item };\n\t\t\t}\n\t\t\tif ( OO.isPlainObject( item ) ) {\n\t\t\t\tif ( item.group ) {\n\t\t\t\t\tfor ( name in this.registry ) {\n\t\t\t\t\t\ttool = this.registry[ name ];\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t// Include tools with matching group\n\t\t\t\t\t\t\ttool.static.group === item.group &&\n\t\t\t\t\t\t\t// Only add tools by group name when auto-add is enabled\n\t\t\t\t\t\t\ttool.static.autoAddToGroup &&\n\t\t\t\t\t\t\t// Exclude already used tools\n\t\t\t\t\t\t\t( !used || !used[ name ] )\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnames.push( name );\n\t\t\t\t\t\t\tif ( used ) {\n\t\t\t\t\t\t\t\tused[ name ] = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t// Include tools with matching name and exclude already used tools\n\t\t\t\t} else if ( item.name && ( !used || !used[ item.name ] ) ) {\n\t\t\t\t\tnames.push( item.name );\n\t\t\t\t\tif ( used ) {\n\t\t\t\t\t\tused[ item.name ] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn names;\n};\n","/**\n * ToolGroupFactories create {@link OO.ui.ToolGroup toolgroups} on demand. The toolgroup classes must\n * specify a symbolic name and be registered with the factory. The following classes are registered by\n * default:\n *\n * - {@link OO.ui.BarToolGroup BarToolGroups} (‘bar’)\n * - {@link OO.ui.MenuToolGroup MenuToolGroups} (‘menu’)\n * - {@link OO.ui.ListToolGroup ListToolGroups} (‘list’)\n *\n * See {@link OO.ui.Toolbar toolbars} for an example.\n *\n * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.Factory\n * @constructor\n */\nOO.ui.ToolGroupFactory = function OoUiToolGroupFactory() {\n\tvar i, l, defaultClasses;\n\t// Parent constructor\n\tOO.Factory.call( this );\n\n\tdefaultClasses = this.constructor.static.getDefaultClasses();\n\n\t// Register default toolgroups\n\tfor ( i = 0, l = defaultClasses.length; i < l; i++ ) {\n\t\tthis.register( defaultClasses[ i ] );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolGroupFactory, OO.Factory );\n\n/* Static Methods */\n\n/**\n * Get a default set of classes to be registered on construction.\n *\n * @return {Function[]} Default classes\n */\nOO.ui.ToolGroupFactory.static.getDefaultClasses = function () {\n\treturn [\n\t\tOO.ui.BarToolGroup,\n\t\tOO.ui.ListToolGroup,\n\t\tOO.ui.MenuToolGroup\n\t];\n};\n","/**\n * Popup tools open a popup window when they are selected from the {@link OO.ui.Toolbar toolbar}. Each popup tool is configured\n * with a static name, title, and icon, as well with as any popup configurations. Unlike other tools, popup tools do not require that developers specify\n * an #onSelect or #onUpdateState method, as these methods have been implemented already.\n *\n *     // Example of a popup tool. When selected, a popup tool displays\n *     // a popup window.\n *     function HelpTool( toolGroup, config ) {\n *        OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *            padded: true,\n *            label: 'Help',\n *            head: true\n *        } }, config ) );\n *        this.popup.$body.append( '<p>I am helpful!</p>' );\n *     };\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n * For an example of a toolbar that contains a popup tool, see {@link OO.ui.Toolbar toolbars}. For more information about\n * toolbars in general, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @abstract\n * @class\n * @extends OO.ui.Tool\n * @mixins OO.ui.mixin.PopupElement\n *\n * @constructor\n * @param {OO.ui.ToolGroup} toolGroup\n * @param {Object} [config] Configuration options\n */\nOO.ui.PopupTool = function OoUiPopupTool( toolGroup, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolGroup ) && config === undefined ) {\n\t\tconfig = toolGroup;\n\t\ttoolGroup = config.toolGroup;\n\t}\n\n\t// Parent constructor\n\tOO.ui.PopupTool.parent.call( this, toolGroup, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PopupElement.call( this, config );\n\n\t// Events\n\tthis.popup.connect( this, { toggle: 'onPopupToggle' } );\n\n\t// Initialization\n\tthis.popup.setAutoFlip( false );\n\tthis.popup.setPosition( toolGroup.getToolbar().position === 'bottom' ? 'above' : 'below' );\n\tthis.$element.addClass( 'oo-ui-popupTool' );\n\tthis.popup.$element.addClass( 'oo-ui-popupTool-popup' );\n\tthis.toolbar.$popups.append( this.popup.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupTool, OO.ui.Tool );\nOO.mixinClass( OO.ui.PopupTool, OO.ui.mixin.PopupElement );\n\n/* Methods */\n\n/**\n * Handle the tool being selected.\n *\n * @inheritdoc\n */\nOO.ui.PopupTool.prototype.onSelect = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.popup.toggle();\n\t}\n\treturn false;\n};\n\n/**\n * Handle the toolbar state being updated.\n *\n * @inheritdoc\n */\nOO.ui.PopupTool.prototype.onUpdateState = function () {\n};\n\n/**\n * Handle popup visibility being toggled.\n *\n * @param {boolean} isVisible\n */\nOO.ui.PopupTool.prototype.onPopupToggle = function ( isVisible ) {\n\tthis.setActive( isVisible );\n\tthis.toolGroup.emit( 'active', isVisible );\n};\n","/**\n * A ToolGroupTool is a special sort of tool that can contain other {@link OO.ui.Tool tools}\n * and {@link OO.ui.ToolGroup toolgroups}. The ToolGroupTool was specifically designed to be used\n * inside a {@link OO.ui.BarToolGroup bar} toolgroup to provide access to additional tools from\n * the bar item. Included tools will be displayed in a dropdown {@link OO.ui.ListToolGroup list}\n * when the ToolGroupTool is selected.\n *\n *     // Example: ToolGroupTool with two nested tools, 'setting1' and 'setting2', defined elsewhere.\n *\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *     };\n *     OO.inheritClass( SettingsTool, OO.ui.ToolGroupTool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.static.groupConfig = {\n *         icon: 'settings',\n *         label: 'ToolGroupTool',\n *         include: [  'setting1', 'setting2'  ]\n *     };\n *     toolFactory.register( SettingsTool );\n *\n * For more information, please see the [OOUI documentation on MediaWiki][1].\n *\n * Please note that this implementation is subject to change per [T74159] [2].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars#ToolGroupTool\n * [2]: https://phabricator.wikimedia.org/T74159\n *\n * @abstract\n * @class\n * @extends OO.ui.Tool\n *\n * @constructor\n * @param {OO.ui.ToolGroup} toolGroup\n * @param {Object} [config] Configuration options\n */\nOO.ui.ToolGroupTool = function OoUiToolGroupTool( toolGroup, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolGroup ) && config === undefined ) {\n\t\tconfig = toolGroup;\n\t\ttoolGroup = config.toolGroup;\n\t}\n\n\t// Parent constructor\n\tOO.ui.ToolGroupTool.parent.call( this, toolGroup, config );\n\n\t// Properties\n\tthis.innerToolGroup = this.createGroup( this.constructor.static.groupConfig );\n\n\t// Events\n\tthis.innerToolGroup.connect( this, {\n\t\tdisable: 'onToolGroupDisable',\n\t\t// Re-emit active events from the innerToolGroup on the parent toolGroup\n\t\tactive: this.toolGroup.emit.bind( this.toolGroup, 'active' )\n\t} );\n\n\t// Initialization\n\tthis.$link.remove();\n\tthis.$element\n\t\t.addClass( 'oo-ui-toolGroupTool' )\n\t\t.append( this.innerToolGroup.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolGroupTool, OO.ui.Tool );\n\n/* Static Properties */\n\n/**\n * Toolgroup configuration.\n *\n * The toolgroup configuration consists of the tools to include, as well as an icon and label\n * to use for the bar item. Tools can be included by symbolic name, group, or with the\n * wildcard selector. Please see {@link OO.ui.ToolGroup toolgroup} for more information.\n *\n * @property {Object.<string,Array>}\n */\nOO.ui.ToolGroupTool.static.groupConfig = {};\n\n/* Methods */\n\n/**\n * Handle the tool being selected.\n *\n * @inheritdoc\n */\nOO.ui.ToolGroupTool.prototype.onSelect = function () {\n\tthis.innerToolGroup.setActive( !this.innerToolGroup.active );\n\treturn false;\n};\n\n/**\n * Synchronize disabledness state of the tool with the inner toolgroup.\n *\n * @private\n * @param {boolean} disabled Element is disabled\n */\nOO.ui.ToolGroupTool.prototype.onToolGroupDisable = function ( disabled ) {\n\tthis.setDisabled( disabled );\n};\n\n/**\n * Handle the toolbar state being updated.\n *\n * @inheritdoc\n */\nOO.ui.ToolGroupTool.prototype.onUpdateState = function () {\n\tthis.setActive( false );\n};\n\n/**\n * Build a {@link OO.ui.ToolGroup toolgroup} from the specified configuration.\n *\n * @param {Object.<string,Array>} group Toolgroup configuration. Please see {@link OO.ui.ToolGroup toolgroup} for\n *  more information.\n * @return {OO.ui.ListToolGroup}\n */\nOO.ui.ToolGroupTool.prototype.createGroup = function ( group ) {\n\tif ( group.include === '*' ) {\n\t\t// Apply defaults to catch-all groups\n\t\tif ( group.label === undefined ) {\n\t\t\tgroup.label = OO.ui.msg( 'ooui-toolbar-more' );\n\t\t}\n\t}\n\n\treturn this.toolbar.getToolGroupFactory().create( 'list', this.toolbar, group );\n};\n","/**\n * BarToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to\n * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}\n * and {@link OO.ui.ListToolGroup ListToolGroup}). The {@link OO.ui.Tool tools} in a BarToolGroup are\n * displayed by icon in a single row. The title of the tool is displayed when users move the mouse over\n * the tool.\n *\n * BarToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar is\n * set up.\n *\n *     @example\n *     // Example of a BarToolGroup with two tools\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'Example of a BarToolGroup with two tools.' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     // Create a class inheriting from OO.ui.Tool\n *     function SearchTool() {\n *         SearchTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SearchTool, OO.ui.Tool );\n *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one\n *     // of 'icon' and 'title' (displayed icon and text).\n *     SearchTool.static.name = 'search';\n *     SearchTool.static.icon = 'search';\n *     SearchTool.static.title = 'Search...';\n *     // Defines the action that will happen when this tool is selected (clicked).\n *     SearchTool.prototype.onSelect = function () {\n *         $area.text( 'Search tool clicked!' );\n *         // Never display this tool as \"active\" (selected).\n *         this.setActive( false );\n *     };\n *     SearchTool.prototype.onUpdateState = function () {};\n *     // Make this tool available in our toolFactory and thus our toolbar\n *     toolFactory.register( SearchTool );\n *\n *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a\n *     // little popup window (a PopupWidget).\n *     function HelpTool( toolGroup, config ) {\n *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *             padded: true,\n *             label: 'Help',\n *             head: true\n *         } }, config ) );\n *         this.popup.$body.append( '<p>I am helpful!</p>' );\n *     }\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             // 'bar' tool groups display tools by icon only\n *             type: 'bar',\n *             include: [ 'search', 'help' ]\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *\n * For more information about how to add tools to a bar tool group, please see {@link OO.ui.ToolGroup toolgroup}.\n * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.ui.ToolGroup\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n */\nOO.ui.BarToolGroup = function OoUiBarToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Parent constructor\n\tOO.ui.BarToolGroup.parent.call( this, toolbar, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-barToolGroup' );\n\tthis.$group.addClass( 'oo-ui-barToolGroup-tools' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.BarToolGroup, OO.ui.ToolGroup );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.BarToolGroup.static.titleTooltips = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.BarToolGroup.static.accelTooltips = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.BarToolGroup.static.name = 'bar';\n","/**\n * PopupToolGroup is an abstract base class used by both {@link OO.ui.MenuToolGroup MenuToolGroup}\n * and {@link OO.ui.ListToolGroup ListToolGroup} to provide a popup (an overlaid menu or list of tools with an\n * optional icon and label). This class can be used for other base classes that also use this functionality.\n *\n * @abstract\n * @class\n * @extends OO.ui.ToolGroup\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.ClippableElement\n * @mixins OO.ui.mixin.FloatableElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n * @cfg {string} [header] Text to display at the top of the popup\n */\nOO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tindicator: config.indicator === undefined ? ( toolbar.position === 'bottom' ? 'up' : 'down' ) : config.indicator\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.PopupToolGroup.parent.call( this, toolbar, config );\n\n\t// Properties\n\tthis.active = false;\n\tthis.dragging = false;\n\t// Don't conflict with parent method of the same name\n\tthis.onPopupDocumentMouseKeyUpHandler = this.onPopupDocumentMouseKeyUp.bind( this );\n\tthis.$handle = $( '<span>' );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );\n\tOO.ui.mixin.FloatableElement.call( this, $.extend( {}, config, {\n\t\t$floatable: this.$group,\n\t\t$floatableContainer: this.$handle,\n\t\thideWhenOutOfView: false,\n\t\tverticalPosition: this.toolbar.position === 'bottom' ? 'above' : 'below'\n\t} ) );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );\n\n\t// Events\n\tthis.$handle.on( {\n\t\tkeydown: this.onHandleMouseKeyDown.bind( this ),\n\t\tkeyup: this.onHandleMouseKeyUp.bind( this ),\n\t\tmousedown: this.onHandleMouseKeyDown.bind( this ),\n\t\tmouseup: this.onHandleMouseKeyUp.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$handle\n\t\t.addClass( 'oo-ui-popupToolGroup-handle' )\n\t\t.attr( 'role', 'button' )\n\t\t.append( this.$icon, this.$label, this.$indicator );\n\t// If the pop-up should have a header, add it to the top of the toolGroup.\n\t// Note: If this feature is useful for other widgets, we could abstract it into an\n\t// OO.ui.HeaderedElement mixin constructor.\n\tif ( config.header !== undefined ) {\n\t\tthis.$group\n\t\t\t.prepend( $( '<span>' )\n\t\t\t\t.addClass( 'oo-ui-popupToolGroup-header' )\n\t\t\t\t.text( config.header )\n\t\t\t);\n\t}\n\tthis.$element\n\t\t.addClass( 'oo-ui-popupToolGroup' )\n\t\t.prepend( this.$handle );\n\tthis.$group.addClass( 'oo-ui-popupToolGroup-tools' );\n\tthis.toolbar.$popups.append( this.$group );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupToolGroup, OO.ui.ToolGroup );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.ClippableElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.FloatableElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupToolGroup.prototype.setDisabled = function () {\n\t// Parent method\n\tOO.ui.PopupToolGroup.parent.prototype.setDisabled.apply( this, arguments );\n\n\tif ( this.isDisabled() && this.isElementAttached() ) {\n\t\tthis.setActive( false );\n\t}\n};\n\n/**\n * Handle document mouse up and key up events.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.PopupToolGroup.prototype.onPopupDocumentMouseKeyUp = function ( e ) {\n\tvar $target = $( e.target );\n\t// Only deactivate when clicking outside the dropdown element\n\tif ( $target.closest( '.oo-ui-popupToolGroup' )[ 0 ] === this.$element[ 0 ] ) {\n\t\treturn;\n\t}\n\tif ( $target.closest( '.oo-ui-popupToolGroup-tools' )[ 0 ] === this.$group[ 0 ] ) {\n\t\treturn;\n\t}\n\tthis.setActive( false );\n};\n\n// Deprecated alias since 0.28.3\nOO.ui.PopupToolGroup.prototype.onBlur = function () {\n\tOO.ui.warnDeprecation( 'onBlur is deprecated, use onPopupDocumentMouseKeyUp instead' );\n\tthis.onPopupDocumentMouseKeyUp.apply( this, arguments );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupToolGroup.prototype.onMouseKeyUp = function ( e ) {\n\t// Only close toolgroup when a tool was actually selected\n\tif (\n\t\t!this.isDisabled() && this.pressed && this.pressed === this.findTargetTool( e ) &&\n\t\t( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )\n\t) {\n\t\tthis.setActive( false );\n\t}\n\treturn OO.ui.PopupToolGroup.parent.prototype.onMouseKeyUp.call( this, e );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupToolGroup.prototype.onMouseKeyDown = function ( e ) {\n\tvar $focused, $firstFocusable, $lastFocusable;\n\t// Shift-Tab on the first tool in the group jumps to the handle.\n\t// Tab on the last tool in the group jumps to the next group.\n\tif ( !this.isDisabled() && e.which === OO.ui.Keys.TAB ) {\n\t\t// (We can't use this.items because ListToolGroup inserts the extra fake expand/collapse tool.)\n\t\t$focused = $( document.activeElement );\n\t\t$firstFocusable = OO.ui.findFocusable( this.$group );\n\t\tif ( $focused[ 0 ] === $firstFocusable[ 0 ] && e.shiftKey ) {\n\t\t\tthis.$handle.trigger( 'focus' );\n\t\t\treturn false;\n\t\t}\n\t\t$lastFocusable = OO.ui.findFocusable( this.$group, true );\n\t\tif ( $focused[ 0 ] === $lastFocusable[ 0 ] && !e.shiftKey ) {\n\t\t\t// Focus this group's handle and let the browser's tab handling happen (no 'return false').\n\t\t\t// This way we don't have to fiddle with other ToolGroups' business, or worry what to do\n\t\t\t// if the next group is not a PopupToolGroup or doesn't exist at all.\n\t\t\tthis.$handle.trigger( 'focus' );\n\t\t\t// Close the popup so that we don't move back inside it (if this is the last group).\n\t\t\tthis.setActive( false );\n\t\t}\n\t}\n\treturn OO.ui.PopupToolGroup.parent.prototype.onMouseKeyDown.call( this, e );\n};\n\n/**\n * Handle mouse up and key up events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse up or key up event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.PopupToolGroup.prototype.onHandleMouseKeyUp = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\t( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )\n\t) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle mouse down and key down events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse down or key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) {\n\tvar $focusable;\n\tif ( !this.isDisabled() ) {\n\t\t// Tab on the handle jumps to the first tool in the group (if the popup is open).\n\t\tif ( e.which === OO.ui.Keys.TAB && !e.shiftKey ) {\n\t\t\t$focusable = OO.ui.findFocusable( this.$group );\n\t\t\tif ( $focusable.length ) {\n\t\t\t\t$focusable.trigger( 'focus' );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) {\n\t\t\tthis.setActive( !this.active );\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Check if the tool group is active.\n *\n * @return {boolean} Tool group is active\n */\nOO.ui.PopupToolGroup.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Switch into 'active' mode.\n *\n * When active, the popup is visible. A mouseup event anywhere in the document will trigger\n * deactivation.\n *\n * @param {boolean} value The active state to set\n * @fires active\n */\nOO.ui.PopupToolGroup.prototype.setActive = function ( value ) {\n\tvar containerWidth, containerLeft;\n\tvalue = !!value;\n\tif ( this.active !== value ) {\n\t\tthis.active = value;\n\t\tif ( value ) {\n\t\t\tthis.getElementDocument().addEventListener( 'mouseup', this.onPopupDocumentMouseKeyUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'keyup', this.onPopupDocumentMouseKeyUpHandler, true );\n\n\t\t\tthis.$clippable.css( 'left', '' );\n\t\t\tthis.$element.addClass( 'oo-ui-popupToolGroup-active' );\n\t\t\tthis.$group.addClass( 'oo-ui-popupToolGroup-active-tools' );\n\t\t\tthis.togglePositioning( true );\n\t\t\tthis.toggleClipping( true );\n\n\t\t\t// Try anchoring the popup to the left first\n\t\t\tthis.setHorizontalPosition( 'start' );\n\n\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t// Anchoring to the left caused the popup to clip, so anchor it to the right instead\n\t\t\t\tthis.setHorizontalPosition( 'end' );\n\t\t\t}\n\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t// Anchoring to the right also caused the popup to clip, so just make it fill the container\n\t\t\t\tcontainerWidth = this.$clippableScrollableContainer.width();\n\t\t\t\tcontainerLeft = this.$clippableScrollableContainer[ 0 ] === document.documentElement ?\n\t\t\t\t\t0 :\n\t\t\t\t\tthis.$clippableScrollableContainer.offset().left;\n\n\t\t\t\tthis.toggleClipping( false );\n\t\t\t\tthis.setHorizontalPosition( 'start' );\n\n\t\t\t\tthis.$clippable.css( {\n\t\t\t\t\t'margin-left': -( this.$element.offset().left - containerLeft ),\n\t\t\t\t\twidth: containerWidth\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.getElementDocument().removeEventListener( 'mouseup', this.onPopupDocumentMouseKeyUpHandler, true );\n\t\t\tthis.getElementDocument().removeEventListener( 'keyup', this.onPopupDocumentMouseKeyUpHandler, true );\n\t\t\tthis.$element.removeClass( 'oo-ui-popupToolGroup-active' );\n\t\t\tthis.$group.removeClass( 'oo-ui-popupToolGroup-active-tools' );\n\t\t\tthis.togglePositioning( false );\n\t\t\tthis.toggleClipping( false );\n\t\t}\n\t\tthis.emit( 'active', this.active );\n\t\tthis.updateThemeClasses();\n\t}\n};\n","/**\n * ListToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to\n * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}\n * and {@link OO.ui.BarToolGroup BarToolGroup}). The {@link OO.ui.Tool tools} in a ListToolGroup are displayed\n * by label in a dropdown menu. The title of the tool is used as the label text. The menu itself can be configured\n * with a label, icon, indicator, header, and title.\n *\n * ListToolGroups can be configured to be expanded and collapsed. Collapsed lists will have a ‘More’ option that\n * users can select to see the full list of tools. If a collapsed toolgroup is expanded, a ‘Fewer’ option permits\n * users to collapse the list again.\n *\n * ListToolGroups are created by a {@link OO.ui.ToolGroupFactory toolgroup factory} when the toolbar is set up. The factory\n * requires the ListToolGroup's symbolic name, 'list', which is specified along with the other configurations. For more\n * information about how to add tools to a ListToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.\n *\n *     @example\n *     // Example of a ListToolGroup\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // Configure and register two tools\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         this.setActive( false );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *     // Register two more tools, nothing interesting here\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'search';\n *     StuffTool.static.title = 'Change the world';\n *     StuffTool.prototype.onSelect = function () {\n *         this.setActive( false );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *     toolbar.setup( [\n *         {\n *             // Configurations for list toolgroup.\n *             type: 'list',\n *             label: 'ListToolGroup',\n *             icon: 'ellipsis',\n *             title: 'This is the title, displayed when user moves the mouse over the list toolgroup',\n *             header: 'This is the header',\n *             include: [ 'settings', 'stuff' ],\n *             allowCollapse: ['stuff']\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element\n *     );\n *     $( document.body ).append( frame.$element );\n *     // Build the toolbar. This must be done after the toolbar has been appended to the document.\n *     toolbar.initialize();\n *\n * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.ui.PopupToolGroup\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n * @cfg {Array} [allowCollapse] Allow the specified tools to be collapsed. By default, collapsible tools\n *  will only be displayed if users click the ‘More’ option displayed at the bottom of the list. If\n *  the list is expanded, a ‘Fewer’ option permits users to collapse the list again. Any tools that\n *  are included in the toolgroup, but are not designated as collapsible, will always be displayed.\n *  To open a collapsible list in its expanded state, set #expanded to 'true'.\n * @cfg {Array} [forceExpand] Expand the specified tools. All other tools will be designated as collapsible.\n *  Unless #expanded is set to true, the collapsible tools will be collapsed when the list is first opened.\n * @cfg {boolean} [expanded=false] Expand collapsible tools. This config is only relevant if tools have\n *  been designated as collapsible. When expanded is set to true, all tools in the group will be displayed\n *  when the list is first opened. Users can collapse the list with a ‘Fewer’ option at the bottom.\n */\nOO.ui.ListToolGroup = function OoUiListToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be set before parent constructor, which calls #populate)\n\tthis.allowCollapse = config.allowCollapse;\n\tthis.forceExpand = config.forceExpand;\n\tthis.expanded = config.expanded !== undefined ? config.expanded : false;\n\tthis.collapsibleTools = [];\n\n\t// Parent constructor\n\tOO.ui.ListToolGroup.parent.call( this, toolbar, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-listToolGroup' );\n\tthis.$group.addClass( 'oo-ui-listToolGroup-tools' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ListToolGroup, OO.ui.PopupToolGroup );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ListToolGroup.static.name = 'list';\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ListToolGroup.prototype.populate = function () {\n\tvar i, len, allowCollapse = [];\n\n\tOO.ui.ListToolGroup.parent.prototype.populate.call( this );\n\n\t// Update the list of collapsible tools\n\tif ( this.allowCollapse !== undefined ) {\n\t\tallowCollapse = this.allowCollapse;\n\t} else if ( this.forceExpand !== undefined ) {\n\t\tallowCollapse = OO.simpleArrayDifference( Object.keys( this.tools ), this.forceExpand );\n\t}\n\n\tthis.collapsibleTools = [];\n\tfor ( i = 0, len = allowCollapse.length; i < len; i++ ) {\n\t\tif ( this.tools[ allowCollapse[ i ] ] !== undefined ) {\n\t\t\tthis.collapsibleTools.push( this.tools[ allowCollapse[ i ] ] );\n\t\t}\n\t}\n\n\t// Keep at the end, even when tools are added\n\tthis.$group.append( this.getExpandCollapseTool().$element );\n\n\tthis.getExpandCollapseTool().toggle( this.collapsibleTools.length !== 0 );\n\tthis.updateCollapsibleState();\n};\n\n/**\n * Get the expand/collapse tool for this group\n *\n * @return {OO.ui.Tool} Expand collapse tool\n */\nOO.ui.ListToolGroup.prototype.getExpandCollapseTool = function () {\n\tvar ExpandCollapseTool;\n\tif ( this.expandCollapseTool === undefined ) {\n\t\tExpandCollapseTool = function () {\n\t\t\tExpandCollapseTool.parent.apply( this, arguments );\n\t\t};\n\n\t\tOO.inheritClass( ExpandCollapseTool, OO.ui.Tool );\n\n\t\tExpandCollapseTool.prototype.onSelect = function () {\n\t\t\tthis.toolGroup.expanded = !this.toolGroup.expanded;\n\t\t\tthis.toolGroup.updateCollapsibleState();\n\t\t\tthis.setActive( false );\n\t\t};\n\t\tExpandCollapseTool.prototype.onUpdateState = function () {\n\t\t\t// Do nothing. Tool interface requires an implementation of this function.\n\t\t};\n\n\t\tExpandCollapseTool.static.name = 'more-fewer';\n\n\t\tthis.expandCollapseTool = new ExpandCollapseTool( this );\n\t}\n\treturn this.expandCollapseTool;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ListToolGroup.prototype.onMouseKeyUp = function ( e ) {\n\t// Do not close the popup when the user wants to show more/fewer tools\n\tif (\n\t\t$( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length &&\n\t\t( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )\n\t) {\n\t\t// HACK: Prevent the popup list from being hidden. Skip the PopupToolGroup implementation (which\n\t\t// hides the popup list when a tool is selected) and call ToolGroup's implementation directly.\n\t\treturn OO.ui.ListToolGroup.parent.parent.prototype.onMouseKeyUp.call( this, e );\n\t} else {\n\t\treturn OO.ui.ListToolGroup.parent.prototype.onMouseKeyUp.call( this, e );\n\t}\n};\n\nOO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {\n\tvar i, icon, len;\n\n\tif ( this.toolbar.position !== 'bottom' ) {\n\t\ticon = this.expanded ? 'collapse' : 'expand';\n\t} else {\n\t\ticon = this.expanded ? 'expand' : 'collapse';\n\t}\n\n\tthis.getExpandCollapseTool()\n\t\t.setIcon( icon )\n\t\t.setTitle( OO.ui.msg( this.expanded ? 'ooui-toolgroup-collapse' : 'ooui-toolgroup-expand' ) );\n\n\tfor ( i = 0, len = this.collapsibleTools.length; i < len; i++ ) {\n\t\tthis.collapsibleTools[ i ].toggle( this.expanded );\n\t}\n\n\t// Re-evaluate clipping, because our height has changed\n\tthis.clip();\n};\n","/**\n * MenuToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to\n * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.BarToolGroup BarToolGroup}\n * and {@link OO.ui.ListToolGroup ListToolGroup}). MenuToolGroups contain selectable {@link OO.ui.Tool tools},\n * which are displayed by label in a dropdown menu. The tool's title is used as the label text, and the\n * menu label is updated to reflect which tool or tools are currently selected. If no tools are selected,\n * the menu label is empty. The menu can be configured with an indicator, icon, title, and/or header.\n *\n * MenuToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar\n * is set up.\n *\n *     @example\n *     // Example of a MenuToolGroup\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'An example of a MenuToolGroup. Select a tool from the dropdown menu.' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         $area.text( 'Settings tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'ellipsis';\n *     StuffTool.static.title = 'More stuff';\n *     StuffTool.prototype.onSelect = function () {\n *         $area.text( 'More stuff tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             type: 'menu',\n *             header: 'This is the (optional) header',\n *             title: 'This is the (optional) title',\n *             include: [ 'settings', 'stuff' ]\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *     toolbar.emit( 'updateState' );\n *\n * For more information about how to add tools to a MenuToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.\n * For more information about toolbars in general, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.ui.PopupToolGroup\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n */\nOO.ui.MenuToolGroup = function OoUiMenuToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MenuToolGroup.parent.call( this, toolbar, config );\n\n\t// Events\n\tthis.toolbar.connect( this, { updateState: 'onUpdateState' } );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-menuToolGroup' );\n\tthis.$group.addClass( 'oo-ui-menuToolGroup-tools' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuToolGroup, OO.ui.PopupToolGroup );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuToolGroup.static.name = 'menu';\n\n/* Methods */\n\n/**\n * Handle the toolbar state being updated.\n *\n * When the state changes, the title of each active item in the menu will be joined together and\n * used as a label for the group. The label will be empty if none of the items are active.\n *\n * @private\n */\nOO.ui.MenuToolGroup.prototype.onUpdateState = function () {\n\tvar name,\n\t\tlabelTexts = [];\n\n\tfor ( name in this.tools ) {\n\t\tif ( this.tools[ name ].isActive() ) {\n\t\t\tlabelTexts.push( this.tools[ name ].getTitle() );\n\t\t}\n\t}\n\n\tthis.setLabel( labelTexts.join( ', ' ) || ' ' );\n};\n","}( OO ) );\n"]}
\ No newline at end of file
+{"version":3,"sources":["../src/intro.js.txt","../src/Toolbar.js","../src/Tool.js","../src/ToolGroup.js","../src/ToolFactory.js","../src/ToolGroupFactory.js","../src/tools/PopupTool.js","../src/tools/ToolGroupTool.js","../src/toolgroups/BarToolGroup.js","../src/toolgroups/PopupToolGroup.js","../src/toolgroups/ListToolGroup.js","../src/toolgroups/MenuToolGroup.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-toolbars.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * Toolbars are complex interface components that permit users to easily access a variety\n * of {@link OO.ui.Tool tools} (e.g., formatting commands) and actions, which are additional\n * commands that are part of the toolbar, but not configured as tools.\n *\n * Individual tools are customized and then registered with a\n * {@link OO.ui.ToolFactory tool factory}, which creates the tools on demand. Each tool has a\n * symbolic name (used when registering the tool), a title (e.g., ‘Insert image’), and an icon.\n *\n * Individual tools are organized in {@link OO.ui.ToolGroup toolgroups}, which can be\n * {@link OO.ui.MenuToolGroup menus} of tools, {@link OO.ui.ListToolGroup lists} of tools, or a\n * single {@link OO.ui.BarToolGroup bar} of tools. The arrangement and order of the toolgroups is\n * customized when the toolbar is set up. Tools can be presented in any order, but each can only\n * appear once in the toolbar.\n *\n * The toolbar can be synchronized with the state of the external \"application\", like a text\n * editor's editing area, marking tools as active/inactive (e.g. a 'bold' tool would be shown as\n * active when the text cursor was inside bolded text) or enabled/disabled (e.g. a table caption\n * tool would be disabled while the user is not editing a table). A state change is signalled by\n * emitting the {@link #event-updateState 'updateState' event}, which calls Tools'\n * {@link OO.ui.Tool#onUpdateState onUpdateState method}.\n *\n * The following is an example of a basic toolbar.\n *\n *     @example\n *     // Example of a toolbar\n *     // Create the toolbar\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'Toolbar example' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     // Create a class inheriting from OO.ui.Tool\n *     function SearchTool() {\n *         SearchTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SearchTool, OO.ui.Tool );\n *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one\n *     // of 'icon' and 'title' (displayed icon and text).\n *     SearchTool.static.name = 'search';\n *     SearchTool.static.icon = 'search';\n *     SearchTool.static.title = 'Search...';\n *     // Defines the action that will happen when this tool is selected (clicked).\n *     SearchTool.prototype.onSelect = function () {\n *         $area.text( 'Search tool clicked!' );\n *         // Never display this tool as \"active\" (selected).\n *         this.setActive( false );\n *     };\n *     SearchTool.prototype.onUpdateState = function () {};\n *     // Make this tool available in our toolFactory and thus our toolbar\n *     toolFactory.register( SearchTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         $area.text( 'Settings tool clicked!' );\n *         this.setActive( false );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'ellipsis';\n *     StuffTool.static.title = 'More stuff';\n *     StuffTool.prototype.onSelect = function () {\n *         $area.text( 'More stuff tool clicked!' );\n *         this.setActive( false );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *\n *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a\n *     // little popup window (a PopupWidget).\n *     function HelpTool( toolGroup, config ) {\n *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *             padded: true,\n *             label: 'Help',\n *             head: true\n *         } }, config ) );\n *         this.popup.$body.append( '<p>I am helpful!</p>' );\n *     }\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             // 'bar' tool groups display tools' icons only, side-by-side.\n *             type: 'bar',\n *             include: [ 'search', 'help' ]\n *         },\n *         {\n *             // 'list' tool groups display both the titles and icons, in a dropdown list.\n *             type: 'list',\n *             indicator: 'down',\n *             label: 'More',\n *             include: [ 'settings', 'stuff' ]\n *         }\n *         // Note how the tools themselves are toolgroup-agnostic - the same tool can be displayed\n *         // either in a 'list' or a 'bar'. There is a 'menu' tool group too, not showcased here,\n *         // since it's more complicated to use. (See the next example snippet on this page.)\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *     toolbar.emit( 'updateState' );\n *\n * The following example extends the previous one to illustrate 'menu' toolgroups and the usage of\n * {@link #event-updateState 'updateState' event}.\n *\n *     @example\n *     // Create the toolbar\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'Toolbar example' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     // Create a class inheriting from OO.ui.Tool\n *     function SearchTool() {\n *         SearchTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SearchTool, OO.ui.Tool );\n *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one\n *     // of 'icon' and 'title' (displayed icon and text).\n *     SearchTool.static.name = 'search';\n *     SearchTool.static.icon = 'search';\n *     SearchTool.static.title = 'Search...';\n *     // Defines the action that will happen when this tool is selected (clicked).\n *     SearchTool.prototype.onSelect = function () {\n *         $area.text( 'Search tool clicked!' );\n *         // Never display this tool as \"active\" (selected).\n *         this.setActive( false );\n *     };\n *     SearchTool.prototype.onUpdateState = function () {};\n *     // Make this tool available in our toolFactory and thus our toolbar\n *     toolFactory.register( SearchTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         $area.text( 'Settings tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *\n *     // Register two more tools, nothing interesting here\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'ellipsis';\n *     StuffTool.static.title = 'More stuff';\n *     StuffTool.prototype.onSelect = function () {\n *         $area.text( 'More stuff tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *\n *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a\n *     // little popup window (a PopupWidget). 'onUpdateState' is also already implemented.\n *     function HelpTool( toolGroup, config ) {\n *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *             padded: true,\n *             label: 'Help',\n *             head: true\n *         } }, config ) );\n *         this.popup.$body.append( '<p>I am helpful!</p>' );\n *     }\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             // 'bar' tool groups display tools' icons only, side-by-side.\n *             type: 'bar',\n *             include: [ 'search', 'help' ]\n *         },\n *         {\n *             // 'menu' tool groups display both the titles and icons, in a dropdown menu.\n *             // Menu label indicates which items are selected.\n *             type: 'menu',\n *             indicator: 'down',\n *             include: [ 'settings', 'stuff' ]\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *     toolbar.emit( 'updateState' );\n *\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {OO.ui.ToolFactory} toolFactory Factory for creating tools\n * @param {OO.ui.ToolGroupFactory} toolGroupFactory Factory for creating toolgroups\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [actions] Add an actions section to the toolbar. Actions are commands that are\n *  included in the toolbar, but are not configured as tools. By default, actions are displayed on\n *  the right side of the toolbar.\n * @cfg {string} [position='top'] Whether the toolbar is positioned above ('top') or below\n *  ('bottom') content.\n * @cfg {jQuery} [$overlay] An overlay for the popup.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolFactory ) && config === undefined ) {\n\t\tconfig = toolFactory;\n\t\ttoolFactory = config.toolFactory;\n\t\ttoolGroupFactory = config.toolGroupFactory;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Toolbar.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.toolFactory = toolFactory;\n\tthis.toolGroupFactory = toolGroupFactory;\n\tthis.groupsByName = {};\n\tthis.activeToolGroups = 0;\n\tthis.tools = {};\n\tthis.position = config.position || 'top';\n\tthis.$bar = $( '<div>' );\n\tthis.$actions = $( '<div>' );\n\tthis.$popups = $( '<div>' );\n\tthis.initialized = false;\n\tthis.narrowThreshold = null;\n\tthis.onWindowResizeHandler = this.onWindowResize.bind( this );\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) ||\n\t\tthis.$element;\n\n\t// Events\n\tthis.$element\n\t\t.add( this.$bar ).add( this.$group ).add( this.$actions )\n\t\t.on( 'mousedown keydown', this.onPointerDown.bind( this ) );\n\n\t// Initialization\n\tthis.$group.addClass( 'oo-ui-toolbar-tools' );\n\tif ( config.actions ) {\n\t\tthis.$bar.append( this.$actions.addClass( 'oo-ui-toolbar-actions' ) );\n\t}\n\tthis.$popups.addClass( 'oo-ui-toolbar-popups' );\n\tthis.$bar\n\t\t.addClass( 'oo-ui-toolbar-bar' )\n\t\t.append( this.$group, '<div style=\"clear:both\"></div>' );\n\t// Possible classes: oo-ui-toolbar-position-top, oo-ui-toolbar-position-bottom\n\tthis.$element\n\t\t.addClass( 'oo-ui-toolbar oo-ui-toolbar-position-' + this.position )\n\t\t.append( this.$bar );\n\tthis.$overlay.append( this.$popups );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Toolbar, OO.ui.Element );\nOO.mixinClass( OO.ui.Toolbar, OO.EventEmitter );\nOO.mixinClass( OO.ui.Toolbar, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * @event updateState\n *\n * An 'updateState' event must be emitted on the Toolbar (by calling\n * `toolbar.emit( 'updateState' )`) every time the state of the application using the toolbar\n * changes, and an update to the state of tools is required.\n *\n * @param {...Mixed} data Application-defined parameters\n */\n\n/**\n * @event active\n *\n * An 'active' event is emitted when the number of active toolgroups increases from 0, or\n * returns to 0.\n *\n * @param {boolean} There are active toolgroups in this toolbar\n */\n\n/* Methods */\n\n/**\n * Get the tool factory.\n *\n * @return {OO.ui.ToolFactory} Tool factory\n */\nOO.ui.Toolbar.prototype.getToolFactory = function () {\n\treturn this.toolFactory;\n};\n\n/**\n * Get the toolgroup factory.\n *\n * @return {OO.Factory} Toolgroup factory\n */\nOO.ui.Toolbar.prototype.getToolGroupFactory = function () {\n\treturn this.toolGroupFactory;\n};\n\n/**\n * Handles mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.Toolbar.prototype.onPointerDown = function ( e ) {\n\tvar $closestWidgetToEvent = $( e.target ).closest( '.oo-ui-widget' ),\n\t\t$closestWidgetToToolbar = this.$element.closest( '.oo-ui-widget' );\n\tif (\n\t\t!$closestWidgetToEvent.length ||\n\t\t$closestWidgetToEvent[ 0 ] ===\n\t\t$closestWidgetToToolbar[ 0 ]\n\t) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle window resize event.\n *\n * @private\n * @param {jQuery.Event} e Window resize event\n */\nOO.ui.Toolbar.prototype.onWindowResize = function () {\n\tthis.$element.add( this.$popups ).toggleClass(\n\t\t'oo-ui-toolbar-narrow',\n\t\tthis.$bar[ 0 ].clientWidth <= this.getNarrowThreshold()\n\t);\n};\n\n/**\n * Get the (lazily-computed) width threshold for applying the oo-ui-toolbar-narrow\n * class.\n *\n * @private\n * @return {number} Width threshold in pixels\n */\nOO.ui.Toolbar.prototype.getNarrowThreshold = function () {\n\tif ( this.narrowThreshold === null ) {\n\t\tthis.narrowThreshold = this.$group[ 0 ].offsetWidth + this.$actions[ 0 ].offsetWidth;\n\t}\n\treturn this.narrowThreshold;\n};\n\n/**\n * Sets up handles and preloads required information for the toolbar to work.\n * This must be called after it is attached to a visible document and before doing anything else.\n */\nOO.ui.Toolbar.prototype.initialize = function () {\n\tif ( !this.initialized ) {\n\t\tthis.initialized = true;\n\t\t$( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler );\n\t\tthis.onWindowResize();\n\t}\n};\n\n/**\n * Set up the toolbar.\n *\n * The toolbar is set up with a list of toolgroup configurations that specify the type of\n * toolgroup ({@link OO.ui.BarToolGroup bar}, {@link OO.ui.MenuToolGroup menu}, or\n * {@link OO.ui.ListToolGroup list}) to add and which tools to include, exclude, promote, or demote\n * within that toolgroup. Please see {@link OO.ui.ToolGroup toolgroups} for more information about\n * including tools in toolgroups.\n *\n * @param {Object.<string,Array>} groups List of toolgroup configurations\n * @param {string} [groups.name] Symbolic name for this toolgroup\n * @param {string} [groups.type] Toolgroup type, should exist in the toolgroup factory\n * @param {Array|string} [groups.include] Tools to include in the toolgroup\n * @param {Array|string} [groups.exclude] Tools to exclude from the toolgroup\n * @param {Array|string} [groups.promote] Tools to promote to the beginning of the toolgroup\n * @param {Array|string} [groups.demote] Tools to demote to the end of the toolgroup\n */\nOO.ui.Toolbar.prototype.setup = function ( groups ) {\n\tvar i, len, type, toolGroup, groupConfig,\n\t\titems = [],\n\t\tdefaultType = 'bar';\n\n\t// Cleanup previous groups\n\tthis.reset();\n\n\t// Build out new groups\n\tfor ( i = 0, len = groups.length; i < len; i++ ) {\n\t\tgroupConfig = groups[ i ];\n\t\tif ( groupConfig.include === '*' ) {\n\t\t\t// Apply defaults to catch-all groups\n\t\t\tif ( groupConfig.type === undefined ) {\n\t\t\t\tgroupConfig.type = 'list';\n\t\t\t}\n\t\t\tif ( groupConfig.label === undefined ) {\n\t\t\t\tgroupConfig.label = OO.ui.msg( 'ooui-toolbar-more' );\n\t\t\t}\n\t\t}\n\t\t// Check type has been registered\n\t\ttype = this.getToolGroupFactory().lookup( groupConfig.type ) ?\n\t\t\tgroupConfig.type : defaultType;\n\t\ttoolGroup = this.getToolGroupFactory().create( type, this, groupConfig );\n\t\titems.push( toolGroup );\n\t\tif ( groupConfig.name ) {\n\t\t\tthis.groupsByName[ groupConfig.name ] = toolGroup;\n\t\t} else {\n\t\t\t// Groups without name are deprecated\n\t\t\tOO.ui.warnDeprecation( 'Toolgroups must have a \\'name\\' property' );\n\t\t}\n\t\ttoolGroup.connect( this, {\n\t\t\tactive: 'onToolGroupActive'\n\t\t} );\n\t}\n\tthis.addItems( items );\n};\n\n/**\n * Handle active events from tool groups\n *\n * @param {boolean} active Tool group has become active, inactive if false\n * @fires active\n */\nOO.ui.Toolbar.prototype.onToolGroupActive = function ( active ) {\n\tif ( active ) {\n\t\tthis.activeToolGroups++;\n\t\tif ( this.activeToolGroups === 1 ) {\n\t\t\tthis.emit( 'active', true );\n\t\t}\n\t} else {\n\t\tthis.activeToolGroups--;\n\t\tif ( this.activeToolGroups === 0 ) {\n\t\t\tthis.emit( 'active', false );\n\t\t}\n\t}\n};\n\n/**\n * Get a toolgroup by name\n *\n * @param {string} name Group name\n * @return {OO.ui.ToolGroup|null} Tool group, or null if none found by that name\n */\nOO.ui.Toolbar.prototype.getToolGroupByName = function ( name ) {\n\treturn this.groupsByName[ name ] || null;\n};\n\n/**\n * Remove all tools and toolgroups from the toolbar.\n */\nOO.ui.Toolbar.prototype.reset = function () {\n\tvar i, len;\n\n\tthis.groupsByName = {};\n\tthis.tools = {};\n\tfor ( i = 0, len = this.items.length; i < len; i++ ) {\n\t\tthis.items[ i ].destroy();\n\t}\n\tthis.clearItems();\n};\n\n/**\n * Destroy the toolbar.\n *\n * Destroying the toolbar removes all event handlers and DOM elements that constitute the toolbar.\n * Call this method whenever you are done using a toolbar.\n */\nOO.ui.Toolbar.prototype.destroy = function () {\n\t$( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );\n\tthis.reset();\n\tthis.$element.remove();\n};\n\n/**\n * Check if the tool is available.\n *\n * Available tools are ones that have not yet been added to the toolbar.\n *\n * @param {string} name Symbolic name of tool\n * @return {boolean} Tool is available\n */\nOO.ui.Toolbar.prototype.isToolAvailable = function ( name ) {\n\treturn !this.tools[ name ];\n};\n\n/**\n * Prevent tool from being used again.\n *\n * @param {OO.ui.Tool} tool Tool to reserve\n */\nOO.ui.Toolbar.prototype.reserveTool = function ( tool ) {\n\tthis.tools[ tool.getName() ] = tool;\n};\n\n/**\n * Allow tool to be used again.\n *\n * @param {OO.ui.Tool} tool Tool to release\n */\nOO.ui.Toolbar.prototype.releaseTool = function ( tool ) {\n\tdelete this.tools[ tool.getName() ];\n};\n\n/**\n * Get accelerator label for tool.\n *\n * The OOUI library does not contain an accelerator system, but this is the hook for one. To\n * use an accelerator system, subclass the toolbar and override this method, which is meant to\n * return a label that describes the accelerator keys for the tool passed (by symbolic name) to\n * the method.\n *\n * @param {string} name Symbolic name of tool\n * @return {string|undefined} Tool accelerator label if available\n */\nOO.ui.Toolbar.prototype.getToolAccelerator = function () {\n\treturn undefined;\n};\n","/**\n * Tools, together with {@link OO.ui.ToolGroup toolgroups}, constitute\n * {@link OO.ui.Toolbar toolbars}.\n * Each tool is configured with a static name, title, and icon and is customized with the command\n * to carry out when the tool is selected. Tools must also be registered with a\n * {@link OO.ui.ToolFactory tool factory}, which creates the tools on demand.\n *\n * Every Tool subclass must implement two methods:\n *\n * - {@link #onUpdateState}\n * - {@link #onSelect}\n *\n * Tools are added to toolgroups ({@link OO.ui.ListToolGroup ListToolGroup},\n * {@link OO.ui.BarToolGroup BarToolGroup}, or {@link OO.ui.MenuToolGroup MenuToolGroup}), which\n * determine how the tool is displayed in the toolbar. See {@link OO.ui.Toolbar toolbars} for an\n * example.\n *\n * For more information, please see the [OOUI documentation on MediaWiki][1].\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {OO.ui.ToolGroup} toolGroup\n * @param {Object} [config] Configuration options\n * @cfg {string|Function} [title] Title text or a function that returns text. If this config is\n *  omitted, the value of the {@link #static-title static title} property is used.\n *\n *  The title is used in different ways depending on the type of toolgroup that contains the tool.\n *  The title is used as a tooltip if the tool is part of a {@link OO.ui.BarToolGroup bar}\n *  toolgroup, or as the label text if the tool is part of a {@link OO.ui.ListToolGroup list} or\n *  {@link OO.ui.MenuToolGroup menu} toolgroup.\n *\n *  For bar toolgroups, a description of the accelerator key is appended to the title if an\n *  accelerator key is associated with an action by the same name as the tool and accelerator\n *  functionality has been added to the application.\n *  To add accelerator key functionality, you must subclass OO.ui.Toolbar and override the\n *  {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method.\n */\nOO.ui.Tool = function OoUiTool( toolGroup, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolGroup ) && config === undefined ) {\n\t\tconfig = toolGroup;\n\t\ttoolGroup = config.toolGroup;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Tool.parent.call( this, config );\n\n\t// Properties\n\tthis.toolGroup = toolGroup;\n\tthis.toolbar = this.toolGroup.getToolbar();\n\tthis.active = false;\n\tthis.$title = $( '<span>' );\n\tthis.$accel = $( '<span>' );\n\tthis.$link = $( '<a>' );\n\tthis.title = null;\n\tthis.checkIcon = new OO.ui.IconWidget( {\n\t\ticon: 'check',\n\t\tclasses: [ 'oo-ui-tool-checkIcon' ]\n\t} );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {\n\t\t$tabIndexed: this.$link\n\t}, config ) );\n\n\t// Events\n\tthis.toolbar.connect( this, {\n\t\tupdateState: 'onUpdateState'\n\t} );\n\n\t// Initialization\n\tthis.$title.addClass( 'oo-ui-tool-title' );\n\tthis.$accel\n\t\t.addClass( 'oo-ui-tool-accel' )\n\t\t.prop( {\n\t\t\t// This may need to be changed if the key names are ever localized,\n\t\t\t// but for now they are essentially written in English\n\t\t\tdir: 'ltr',\n\t\t\tlang: 'en'\n\t\t} );\n\tthis.$link\n\t\t.addClass( 'oo-ui-tool-link' )\n\t\t.append( this.checkIcon.$element, this.$icon, this.$title, this.$accel )\n\t\t.attr( 'role', 'button' );\n\tthis.$element\n\t\t.data( 'oo-ui-tool', this )\n\t\t.addClass( 'oo-ui-tool' )\n\t\t.addClass( 'oo-ui-tool-name-' +\n\t\t\tthis.constructor.static.name.replace( /^([^/]+)\\/([^/]+).*$/, '$1-$2' ) )\n\t\t.toggleClass( 'oo-ui-tool-with-label', this.constructor.static.displayBothIconAndLabel )\n\t\t.append( this.$link );\n\tthis.setTitle( config.title || this.constructor.static.title );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Tool, OO.ui.Widget );\nOO.mixinClass( OO.ui.Tool, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.Tool, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.Tool, OO.ui.mixin.TabIndexedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.Tool.static.tagName = 'span';\n\n/**\n * Symbolic name of tool.\n *\n * The symbolic name is used internally to register the tool with a\n * {@link OO.ui.ToolFactory ToolFactory}. It can also be used when adding tools to toolgroups.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Tool.static.name = '';\n\n/**\n * Symbolic name of the group.\n *\n * The group name is used to associate tools with each other so that they can be selected later by\n * a {@link OO.ui.ToolGroup toolgroup}.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Tool.static.group = '';\n\n/**\n * Tool title text or a function that returns title text. The value of the static property is\n * overridden if the #title config option is used.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string|Function}\n */\nOO.ui.Tool.static.title = '';\n\n/**\n * Display both icon and label when the tool is used in a {@link OO.ui.BarToolGroup bar} toolgroup.\n * Normally only the icon is displayed, or only the label if no icon is given.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.Tool.static.displayBothIconAndLabel = false;\n\n/**\n * Add tool to catch-all groups automatically.\n *\n * A catch-all group, which contains all tools that do not currently belong to a toolgroup,\n * can be included in a toolgroup using the wildcard selector, an asterisk (*).\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.Tool.static.autoAddToCatchall = true;\n\n/**\n * Add tool to named groups automatically.\n *\n * By default, tools that are configured with a static ‘group’ property are added\n * to that group and will be selected when the symbolic name of the group is specified (e.g., when\n * toolgroups include tools by group name).\n *\n * @static\n * @property {boolean}\n * @inheritable\n */\nOO.ui.Tool.static.autoAddToGroup = true;\n\n/**\n * Check if this tool is compatible with given data.\n *\n * This is a stub that can be overridden to provide support for filtering tools based on an\n * arbitrary piece of information  (e.g., where the cursor is in a document). The implementation\n * must also call this method so that the compatibility check can be performed.\n *\n * @static\n * @inheritable\n * @param {Mixed} data Data to check\n * @return {boolean} Tool can be used with data\n */\nOO.ui.Tool.static.isCompatibleWith = function () {\n\treturn false;\n};\n\n/* Methods */\n\n/**\n * Handle the toolbar state being updated. This method is called when the\n * {@link OO.ui.Toolbar#event-updateState 'updateState' event} is emitted on the\n * {@link OO.ui.Toolbar Toolbar} that uses this tool, and should set the state of this tool\n * depending on application state (usually by calling #setDisabled to enable or disable the tool,\n * or #setActive to mark is as currently in-use or not).\n *\n * This is an abstract method that must be overridden in a concrete subclass.\n *\n * @method\n * @protected\n * @abstract\n */\nOO.ui.Tool.prototype.onUpdateState = null;\n\n/**\n * Handle the tool being selected. This method is called when the user triggers this tool,\n * usually by clicking on its label/icon.\n *\n * This is an abstract method that must be overridden in a concrete subclass.\n *\n * @method\n * @protected\n * @abstract\n */\nOO.ui.Tool.prototype.onSelect = null;\n\n/**\n * Check if the tool is active.\n *\n * Tools become active when their #onSelect or #onUpdateState handlers change them to appear pressed\n * with the #setActive method. Additional CSS is applied to the tool to reflect the active state.\n *\n * @return {boolean} Tool is active\n */\nOO.ui.Tool.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Make the tool appear active or inactive.\n *\n * This method should be called within #onSelect or #onUpdateState event handlers to make the tool\n * appear pressed or not.\n *\n * @param {boolean} state Make tool appear active\n */\nOO.ui.Tool.prototype.setActive = function ( state ) {\n\tthis.active = !!state;\n\tthis.$element.toggleClass( 'oo-ui-tool-active', this.active );\n\tthis.updateThemeClasses();\n};\n\n/**\n * Set the tool #title.\n *\n * @param {string|Function} title Title text or a function that returns text\n * @chainable\n * @return {OO.ui.Tool} The tool, for chaining\n */\nOO.ui.Tool.prototype.setTitle = function ( title ) {\n\tthis.title = OO.ui.resolveMsg( title );\n\tthis.updateTitle();\n\treturn this;\n};\n\n/**\n * Get the tool #title.\n *\n * @return {string} Title text\n */\nOO.ui.Tool.prototype.getTitle = function () {\n\treturn this.title;\n};\n\n/**\n * Get the tool's symbolic name.\n *\n * @return {string} Symbolic name of tool\n */\nOO.ui.Tool.prototype.getName = function () {\n\treturn this.constructor.static.name;\n};\n\n/**\n * Update the title.\n */\nOO.ui.Tool.prototype.updateTitle = function () {\n\tvar titleTooltips = this.toolGroup.constructor.static.titleTooltips,\n\t\taccelTooltips = this.toolGroup.constructor.static.accelTooltips,\n\t\taccel = this.toolbar.getToolAccelerator( this.constructor.static.name ),\n\t\ttooltipParts = [];\n\n\tthis.$title.text( this.title );\n\tthis.$accel.text( accel );\n\n\tif ( titleTooltips && typeof this.title === 'string' && this.title.length ) {\n\t\ttooltipParts.push( this.title );\n\t}\n\tif ( accelTooltips && typeof accel === 'string' && accel.length ) {\n\t\ttooltipParts.push( accel );\n\t}\n\tif ( tooltipParts.length ) {\n\t\tthis.$link.attr( 'title', tooltipParts.join( ' ' ) );\n\t} else {\n\t\tthis.$link.removeAttr( 'title' );\n\t}\n};\n\n/**\n * Destroy tool.\n *\n * Destroying the tool removes all event handlers and the tool’s DOM elements.\n * Call this method whenever you are done using a tool.\n */\nOO.ui.Tool.prototype.destroy = function () {\n\tthis.toolbar.disconnect( this );\n\tthis.$element.remove();\n};\n","/**\n * ToolGroups are collections of {@link OO.ui.Tool tools} that are used in a\n * {@link OO.ui.Toolbar toolbar}.\n * The type of toolgroup ({@link OO.ui.ListToolGroup list}, {@link OO.ui.BarToolGroup bar}, or\n * {@link OO.ui.MenuToolGroup menu}) to which a tool belongs determines how the tool is arranged\n * and displayed in the toolbar. Toolgroups themselves are created on demand with a\n * {@link OO.ui.ToolGroupFactory toolgroup factory}.\n *\n * Toolgroups can contain individual tools, groups of tools, or all available tools, as specified\n * using the `include` config option. See OO.ui.ToolFactory#extract on documentation of the format.\n * The options `exclude`, `promote`, and `demote` support the same formats.\n *\n * See {@link OO.ui.Toolbar toolbars} for a full example. For more information about toolbars in\n * general, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n * @cfg {Array|string} [include] List of tools to include in the toolgroup, see above.\n * @cfg {Array|string} [exclude] List of tools to exclude from the toolgroup, see above.\n * @cfg {Array|string} [promote] List of tools to promote to the beginning of the toolgroup,\n *  see above.\n * @cfg {Array|string} [demote] List of tools to demote to the end of the toolgroup, see above.\n *  This setting is particularly useful when tools have been added to the toolgroup\n *  en masse (e.g., via the catch-all selector).\n */\nOO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ToolGroup.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.toolbar = toolbar;\n\tthis.tools = {};\n\tthis.pressed = null;\n\tthis.autoDisabled = false;\n\tthis.include = config.include || [];\n\tthis.exclude = config.exclude || [];\n\tthis.promote = config.promote || [];\n\tthis.demote = config.demote || [];\n\tthis.onDocumentMouseKeyUpHandler = this.onDocumentMouseKeyUp.bind( this );\n\n\t// Events\n\tthis.$group.on( {\n\t\tmousedown: this.onMouseKeyDown.bind( this ),\n\t\tmouseup: this.onMouseKeyUp.bind( this ),\n\t\tkeydown: this.onMouseKeyDown.bind( this ),\n\t\tkeyup: this.onMouseKeyUp.bind( this ),\n\t\tfocus: this.onMouseOverFocus.bind( this ),\n\t\tblur: this.onMouseOutBlur.bind( this ),\n\t\tmouseover: this.onMouseOverFocus.bind( this ),\n\t\tmouseout: this.onMouseOutBlur.bind( this )\n\t} );\n\tthis.toolbar.getToolFactory().connect( this, {\n\t\tregister: 'onToolFactoryRegister'\n\t} );\n\tthis.aggregate( {\n\t\tdisable: 'itemDisable'\n\t} );\n\tthis.connect( this, {\n\t\titemDisable: 'updateDisabled',\n\t\tdisable: 'onDisable'\n\t} );\n\n\t// Initialization\n\tthis.$group.addClass( 'oo-ui-toolGroup-tools' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-toolGroup' )\n\t\t.append( this.$group );\n\tthis.onDisable( this.isDisabled() );\n\tthis.populate();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolGroup, OO.ui.Widget );\nOO.mixinClass( OO.ui.ToolGroup, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * @event update\n */\n\n/**\n * @event active\n *\n * An 'active' event is emitted when any popup is shown/hidden.\n *\n * @param {boolean} The popup is visible\n */\n\n/* Static Properties */\n\n/**\n * Show labels in tooltips.\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.ToolGroup.static.titleTooltips = false;\n\n/**\n * Show acceleration labels in tooltips.\n *\n * Note: The OOUI library does not include an accelerator system, but does contain\n * a hook for one. To use an accelerator system, subclass the {@link OO.ui.Toolbar toolbar} and\n * override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method, which is\n * meant to return a label that describes the accelerator keys for a given tool (e.g., Control+M\n * key combination).\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.ToolGroup.static.accelTooltips = false;\n\n/**\n * Automatically disable the toolgroup when all tools are disabled\n *\n * @static\n * @inheritable\n * @property {boolean}\n */\nOO.ui.ToolGroup.static.autoDisable = true;\n\n/**\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.ToolGroup.static.name = null;\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ToolGroup.prototype.isDisabled = function () {\n\treturn this.autoDisabled ||\n\t\tOO.ui.ToolGroup.parent.prototype.isDisabled.apply( this, arguments );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToolGroup.prototype.updateDisabled = function () {\n\tvar i, item, allDisabled = true;\n\n\tif ( this.constructor.static.autoDisable ) {\n\t\tfor ( i = this.items.length - 1; i >= 0; i-- ) {\n\t\t\titem = this.items[ i ];\n\t\t\tif ( !item.isDisabled() ) {\n\t\t\t\tallDisabled = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tthis.autoDisabled = allDisabled;\n\t}\n\tOO.ui.ToolGroup.parent.prototype.updateDisabled.apply( this, arguments );\n};\n\n/**\n * Handle disable events.\n *\n * @protected\n * @param {boolean} isDisabled\n */\nOO.ui.ToolGroup.prototype.onDisable = function ( isDisabled ) {\n\tthis.$group.toggleClass( 'oo-ui-toolGroup-disabled-tools', isDisabled );\n\tthis.$group.toggleClass( 'oo-ui-toolGroup-enabled-tools', !isDisabled );\n};\n\n/**\n * Handle mouse down and key down events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse down or key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.ToolGroup.prototype.onMouseKeyDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() && (\n\t\t\te.which === OO.ui.MouseButtons.LEFT ||\n\t\t\te.which === OO.ui.Keys.SPACE ||\n\t\t\te.which === OO.ui.Keys.ENTER\n\t\t)\n\t) {\n\t\tthis.pressed = this.findTargetTool( e );\n\t\tif ( this.pressed ) {\n\t\t\tthis.pressed.setActive( true );\n\t\t\tthis.getElementDocument().addEventListener(\n\t\t\t\t'mouseup',\n\t\t\t\tthis.onDocumentMouseKeyUpHandler,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\tthis.getElementDocument().addEventListener(\n\t\t\t\t'keyup',\n\t\t\t\tthis.onDocumentMouseKeyUpHandler,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Handle document mouse up and key up events.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.ToolGroup.prototype.onDocumentMouseKeyUp = function ( e ) {\n\tthis.getElementDocument().removeEventListener(\n\t\t'mouseup',\n\t\tthis.onDocumentMouseKeyUpHandler,\n\t\ttrue\n\t);\n\tthis.getElementDocument().removeEventListener(\n\t\t'keyup',\n\t\tthis.onDocumentMouseKeyUpHandler,\n\t\ttrue\n\t);\n\t// onMouseKeyUp may be called a second time, depending on where the mouse is when the button is\n\t// released, but since `this.pressed` will no longer be true, the second call will be ignored.\n\tthis.onMouseKeyUp( e );\n};\n\n/**\n * Handle mouse up and key up events.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.ToolGroup.prototype.onMouseKeyUp = function ( e ) {\n\tvar tool = this.findTargetTool( e );\n\n\tif (\n\t\t!this.isDisabled() && this.pressed && this.pressed === tool && (\n\t\t\te.which === OO.ui.MouseButtons.LEFT ||\n\t\t\te.which === OO.ui.Keys.SPACE ||\n\t\t\te.which === OO.ui.Keys.ENTER\n\t\t)\n\t) {\n\t\tthis.pressed.onSelect();\n\t\tthis.pressed = null;\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t}\n\n\tthis.pressed = null;\n};\n\n/**\n * Handle mouse over and focus events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse over or focus event\n */\nOO.ui.ToolGroup.prototype.onMouseOverFocus = function ( e ) {\n\tvar tool = this.findTargetTool( e );\n\n\tif ( this.pressed && this.pressed === tool ) {\n\t\tthis.pressed.setActive( true );\n\t}\n};\n\n/**\n * Handle mouse out and blur events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse out or blur event\n */\nOO.ui.ToolGroup.prototype.onMouseOutBlur = function ( e ) {\n\tvar tool = this.findTargetTool( e );\n\n\tif ( this.pressed && this.pressed === tool ) {\n\t\tthis.pressed.setActive( false );\n\t}\n};\n\n/**\n * Get the closest tool to a jQuery.Event.\n *\n * Only tool links are considered, which prevents other elements in the tool such as popups from\n * triggering tool group interactions.\n *\n * @private\n * @param {jQuery.Event} e\n * @return {OO.ui.Tool|null} Tool, `null` if none was found\n */\nOO.ui.ToolGroup.prototype.findTargetTool = function ( e ) {\n\tvar tool,\n\t\t$item = $( e.target ).closest( '.oo-ui-tool-link' );\n\n\tif ( $item.length ) {\n\t\ttool = $item.parent().data( 'oo-ui-tool' );\n\t}\n\n\treturn tool && !tool.isDisabled() ? tool : null;\n};\n\n/**\n * Handle tool registry register events.\n *\n * If a tool is registered after the group is created, we must repopulate the list to account for:\n *\n * - a tool being added that may be included\n * - a tool already included being overridden\n *\n * @protected\n * @param {string} name Symbolic name of tool\n */\nOO.ui.ToolGroup.prototype.onToolFactoryRegister = function () {\n\tthis.populate();\n};\n\n/**\n * Get the toolbar that contains the toolgroup.\n *\n * @return {OO.ui.Toolbar} Toolbar that contains the toolgroup\n */\nOO.ui.ToolGroup.prototype.getToolbar = function () {\n\treturn this.toolbar;\n};\n\n/**\n * Add and remove tools based on configuration.\n */\nOO.ui.ToolGroup.prototype.populate = function () {\n\tvar i, len, name, tool,\n\t\ttoolFactory = this.toolbar.getToolFactory(),\n\t\tnames = {},\n\t\tadd = [],\n\t\tremove = [],\n\t\tlist = this.toolbar.getToolFactory().getTools(\n\t\t\tthis.include, this.exclude, this.promote, this.demote\n\t\t);\n\n\t// Build a list of needed tools\n\tfor ( i = 0, len = list.length; i < len; i++ ) {\n\t\tname = list[ i ];\n\t\tif (\n\t\t\t// Tool exists\n\t\t\ttoolFactory.lookup( name ) &&\n\t\t\t// Tool is available or is already in this group\n\t\t\t( this.toolbar.isToolAvailable( name ) || this.tools[ name ] )\n\t\t) {\n\t\t\t// Hack to prevent infinite recursion via ToolGroupTool. We need to reserve the tool\n\t\t\t// before creating it, but we can't call reserveTool() yet because we haven't created\n\t\t\t// the tool.\n\t\t\tthis.toolbar.tools[ name ] = true;\n\t\t\ttool = this.tools[ name ];\n\t\t\tif ( !tool ) {\n\t\t\t\t// Auto-initialize tools on first use\n\t\t\t\tthis.tools[ name ] = tool = toolFactory.create( name, this );\n\t\t\t\ttool.updateTitle();\n\t\t\t}\n\t\t\tthis.toolbar.reserveTool( tool );\n\t\t\tadd.push( tool );\n\t\t\tnames[ name ] = true;\n\t\t}\n\t}\n\t// Remove tools that are no longer needed\n\tfor ( name in this.tools ) {\n\t\tif ( !names[ name ] ) {\n\t\t\tthis.tools[ name ].destroy();\n\t\t\tthis.toolbar.releaseTool( this.tools[ name ] );\n\t\t\tremove.push( this.tools[ name ] );\n\t\t\tdelete this.tools[ name ];\n\t\t}\n\t}\n\tif ( remove.length ) {\n\t\tthis.removeItems( remove );\n\t}\n\t// Update emptiness state\n\tif ( add.length ) {\n\t\tthis.$element.removeClass( 'oo-ui-toolGroup-empty' );\n\t} else {\n\t\tthis.$element.addClass( 'oo-ui-toolGroup-empty' );\n\t}\n\t// Re-add tools (moving existing ones to new locations)\n\tthis.addItems( add );\n\t// Disabled state may depend on items\n\tthis.updateDisabled();\n};\n\n/**\n * Destroy toolgroup.\n */\nOO.ui.ToolGroup.prototype.destroy = function () {\n\tvar name;\n\n\tthis.clearItems();\n\tthis.toolbar.getToolFactory().disconnect( this );\n\tfor ( name in this.tools ) {\n\t\tthis.toolbar.releaseTool( this.tools[ name ] );\n\t\tthis.tools[ name ].disconnect( this ).destroy();\n\t\tdelete this.tools[ name ];\n\t}\n\tthis.$element.remove();\n};\n","/**\n * A ToolFactory creates tools on demand. All tools ({@link OO.ui.Tool Tools},\n * {@link OO.ui.PopupTool PopupTools}, and {@link OO.ui.ToolGroupTool ToolGroupTools}) must be\n * registered with a tool factory. Tools are registered by their symbolic name. See\n * {@link OO.ui.Toolbar toolbars} for an example.\n *\n * For more information about toolbars in general, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.Factory\n * @constructor\n */\nOO.ui.ToolFactory = function OoUiToolFactory() {\n\t// Parent constructor\n\tOO.ui.ToolFactory.parent.call( this );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolFactory, OO.Factory );\n\n/* Methods */\n\n/**\n * Get tools from the factory.\n *\n * @param {Array|string} [include] Included tools, see #extract for format\n * @param {Array|string} [exclude] Excluded tools, see #extract for format\n * @param {Array|string} [promote] Promoted tools, see #extract for format\n * @param {Array|string} [demote] Demoted tools, see #extract for format\n * @return {string[]} List of tools\n */\nOO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {\n\tvar i, len, included, promoted, demoted,\n\t\tauto = [],\n\t\tused = {};\n\n\t// Collect included and not excluded tools\n\tincluded = OO.simpleArrayDifference( this.extract( include ), this.extract( exclude ) );\n\n\t// Promotion\n\tpromoted = this.extract( promote, used );\n\tdemoted = this.extract( demote, used );\n\n\t// Auto\n\tfor ( i = 0, len = included.length; i < len; i++ ) {\n\t\tif ( !used[ included[ i ] ] ) {\n\t\t\tauto.push( included[ i ] );\n\t\t}\n\t}\n\n\treturn promoted.concat( auto ).concat( demoted );\n};\n\n/**\n * Get a flat list of names from a list of names or groups.\n *\n * Normally, `collection` is an array of tool specifications. Tools can be specified in the\n * following ways:\n *\n * - To include an individual tool, use the symbolic name: `{ name: 'tool-name' }` or `'tool-name'`.\n * - To include all tools in a group, use the group name: `{ group: 'group-name' }`. (To assign the\n *   tool to a group, use OO.ui.Tool.static.group.)\n *\n * Alternatively, to include all tools that are not yet assigned to any other toolgroup, use the\n * catch-all selector `'*'`.\n *\n * If `used` is passed, tool names that appear as properties in this object will be considered\n * already assigned, and will not be returned even if specified otherwise. The tool names extracted\n * by this function call will be added as new properties in the object.\n *\n * @private\n * @param {Array|string} collection List of tools, see above\n * @param {Object} [used] Object containing information about used tools, see above\n * @return {string[]} List of extracted tool names\n */\nOO.ui.ToolFactory.prototype.extract = function ( collection, used ) {\n\tvar i, len, item, name, tool,\n\t\tnames = [];\n\n\tcollection = !Array.isArray( collection ) ? [ collection ] : collection;\n\n\tfor ( i = 0, len = collection.length; i < len; i++ ) {\n\t\titem = collection[ i ];\n\t\tif ( item === '*' ) {\n\t\t\tfor ( name in this.registry ) {\n\t\t\t\ttool = this.registry[ name ];\n\t\t\t\tif (\n\t\t\t\t\t// Only add tools by group name when auto-add is enabled\n\t\t\t\t\ttool.static.autoAddToCatchall &&\n\t\t\t\t\t// Exclude already used tools\n\t\t\t\t\t( !used || !used[ name ] )\n\t\t\t\t) {\n\t\t\t\t\tnames.push( name );\n\t\t\t\t\tif ( used ) {\n\t\t\t\t\t\tused[ name ] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Allow plain strings as shorthand for named tools\n\t\t\tif ( typeof item === 'string' ) {\n\t\t\t\titem = { name: item };\n\t\t\t}\n\t\t\tif ( OO.isPlainObject( item ) ) {\n\t\t\t\tif ( item.group ) {\n\t\t\t\t\tfor ( name in this.registry ) {\n\t\t\t\t\t\ttool = this.registry[ name ];\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t// Include tools with matching group\n\t\t\t\t\t\t\ttool.static.group === item.group &&\n\t\t\t\t\t\t\t// Only add tools by group name when auto-add is enabled\n\t\t\t\t\t\t\ttool.static.autoAddToGroup &&\n\t\t\t\t\t\t\t// Exclude already used tools\n\t\t\t\t\t\t\t( !used || !used[ name ] )\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnames.push( name );\n\t\t\t\t\t\t\tif ( used ) {\n\t\t\t\t\t\t\t\tused[ name ] = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t// Include tools with matching name and exclude already used tools\n\t\t\t\t} else if ( item.name && ( !used || !used[ item.name ] ) ) {\n\t\t\t\t\tnames.push( item.name );\n\t\t\t\t\tif ( used ) {\n\t\t\t\t\t\tused[ item.name ] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn names;\n};\n","/**\n * ToolGroupFactories create {@link OO.ui.ToolGroup toolgroups} on demand. The toolgroup classes\n * must specify a symbolic name and be registered with the factory. The following classes are\n * registered by default:\n *\n * - {@link OO.ui.BarToolGroup BarToolGroups} (‘bar’)\n * - {@link OO.ui.MenuToolGroup MenuToolGroups} (‘menu’)\n * - {@link OO.ui.ListToolGroup ListToolGroups} (‘list’)\n *\n * See {@link OO.ui.Toolbar toolbars} for an example.\n *\n * For more information about toolbars in general, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.Factory\n * @constructor\n */\nOO.ui.ToolGroupFactory = function OoUiToolGroupFactory() {\n\tvar i, l, defaultClasses;\n\t// Parent constructor\n\tOO.Factory.call( this );\n\n\tdefaultClasses = this.constructor.static.getDefaultClasses();\n\n\t// Register default toolgroups\n\tfor ( i = 0, l = defaultClasses.length; i < l; i++ ) {\n\t\tthis.register( defaultClasses[ i ] );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolGroupFactory, OO.Factory );\n\n/* Static Methods */\n\n/**\n * Get a default set of classes to be registered on construction.\n *\n * @return {Function[]} Default classes\n */\nOO.ui.ToolGroupFactory.static.getDefaultClasses = function () {\n\treturn [\n\t\tOO.ui.BarToolGroup,\n\t\tOO.ui.ListToolGroup,\n\t\tOO.ui.MenuToolGroup\n\t];\n};\n","/**\n * Popup tools open a popup window when they are selected from the {@link OO.ui.Toolbar toolbar}.\n * Each popup tool is configured with a static name, title, and icon, as well with as any popup\n * configurations. Unlike other tools, popup tools do not require that developers specify an\n * #onSelect or #onUpdateState method, as these methods have been implemented already.\n *\n *     // Example of a popup tool. When selected, a popup tool displays\n *     // a popup window.\n *     function HelpTool( toolGroup, config ) {\n *        OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *            padded: true,\n *            label: 'Help',\n *            head: true\n *        } }, config ) );\n *        this.popup.$body.append( '<p>I am helpful!</p>' );\n *     };\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n * For an example of a toolbar that contains a popup tool, see {@link OO.ui.Toolbar toolbars}.\n * For more information about toolbars in general, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @abstract\n * @class\n * @extends OO.ui.Tool\n * @mixins OO.ui.mixin.PopupElement\n *\n * @constructor\n * @param {OO.ui.ToolGroup} toolGroup\n * @param {Object} [config] Configuration options\n */\nOO.ui.PopupTool = function OoUiPopupTool( toolGroup, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolGroup ) && config === undefined ) {\n\t\tconfig = toolGroup;\n\t\ttoolGroup = config.toolGroup;\n\t}\n\n\t// Parent constructor\n\tOO.ui.PopupTool.parent.call( this, toolGroup, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PopupElement.call( this, config );\n\n\t// Events\n\tthis.popup.connect( this, {\n\t\ttoggle: 'onPopupToggle'\n\t} );\n\n\t// Initialization\n\tthis.popup.setAutoFlip( false );\n\tthis.popup.setPosition( toolGroup.getToolbar().position === 'bottom' ? 'above' : 'below' );\n\tthis.$element.addClass( 'oo-ui-popupTool' );\n\tthis.popup.$element.addClass( 'oo-ui-popupTool-popup' );\n\tthis.toolbar.$popups.append( this.popup.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupTool, OO.ui.Tool );\nOO.mixinClass( OO.ui.PopupTool, OO.ui.mixin.PopupElement );\n\n/* Methods */\n\n/**\n * Handle the tool being selected.\n *\n * @inheritdoc\n */\nOO.ui.PopupTool.prototype.onSelect = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.popup.toggle();\n\t}\n\treturn false;\n};\n\n/**\n * Handle the toolbar state being updated.\n *\n * @inheritdoc\n */\nOO.ui.PopupTool.prototype.onUpdateState = function () {\n};\n\n/**\n * Handle popup visibility being toggled.\n *\n * @param {boolean} isVisible\n */\nOO.ui.PopupTool.prototype.onPopupToggle = function ( isVisible ) {\n\tthis.setActive( isVisible );\n\tthis.toolGroup.emit( 'active', isVisible );\n};\n","/**\n * A ToolGroupTool is a special sort of tool that can contain other {@link OO.ui.Tool tools}\n * and {@link OO.ui.ToolGroup toolgroups}. The ToolGroupTool was specifically designed to be used\n * inside a {@link OO.ui.BarToolGroup bar} toolgroup to provide access to additional tools from\n * the bar item. Included tools will be displayed in a dropdown {@link OO.ui.ListToolGroup list}\n * when the ToolGroupTool is selected.\n *\n *     // Example: ToolGroupTool with two nested tools, 'setting1' and 'setting2',\n *     // defined elsewhere.\n *\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *     };\n *     OO.inheritClass( SettingsTool, OO.ui.ToolGroupTool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.static.groupConfig = {\n *         icon: 'settings',\n *         label: 'ToolGroupTool',\n *         include: [  'setting1', 'setting2'  ]\n *     };\n *     toolFactory.register( SettingsTool );\n *\n * For more information, please see the [OOUI documentation on MediaWiki][1].\n *\n * Please note that this implementation is subject to change per [T74159] [2].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars#ToolGroupTool\n * [2]: https://phabricator.wikimedia.org/T74159\n *\n * @abstract\n * @class\n * @extends OO.ui.Tool\n *\n * @constructor\n * @param {OO.ui.ToolGroup} toolGroup\n * @param {Object} [config] Configuration options\n */\nOO.ui.ToolGroupTool = function OoUiToolGroupTool( toolGroup, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolGroup ) && config === undefined ) {\n\t\tconfig = toolGroup;\n\t\ttoolGroup = config.toolGroup;\n\t}\n\n\t// Parent constructor\n\tOO.ui.ToolGroupTool.parent.call( this, toolGroup, config );\n\n\t// Properties\n\tthis.innerToolGroup = this.createGroup( this.constructor.static.groupConfig );\n\n\t// Events\n\tthis.innerToolGroup.connect( this, {\n\t\tdisable: 'onToolGroupDisable',\n\t\t// Re-emit active events from the innerToolGroup on the parent toolGroup\n\t\tactive: this.toolGroup.emit.bind( this.toolGroup, 'active' )\n\t} );\n\n\t// Initialization\n\tthis.$link.remove();\n\tthis.$element\n\t\t.addClass( 'oo-ui-toolGroupTool' )\n\t\t.append( this.innerToolGroup.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToolGroupTool, OO.ui.Tool );\n\n/* Static Properties */\n\n/**\n * Toolgroup configuration.\n *\n * The toolgroup configuration consists of the tools to include, as well as an icon and label\n * to use for the bar item. Tools can be included by symbolic name, group, or with the\n * wildcard selector. Please see {@link OO.ui.ToolGroup toolgroup} for more information.\n *\n * @property {Object.<string,Array>}\n */\nOO.ui.ToolGroupTool.static.groupConfig = {};\n\n/* Methods */\n\n/**\n * Handle the tool being selected.\n *\n * @inheritdoc\n */\nOO.ui.ToolGroupTool.prototype.onSelect = function () {\n\tthis.innerToolGroup.setActive( !this.innerToolGroup.active );\n\treturn false;\n};\n\n/**\n * Synchronize disabledness state of the tool with the inner toolgroup.\n *\n * @private\n * @param {boolean} disabled Element is disabled\n */\nOO.ui.ToolGroupTool.prototype.onToolGroupDisable = function ( disabled ) {\n\tthis.setDisabled( disabled );\n};\n\n/**\n * Handle the toolbar state being updated.\n *\n * @inheritdoc\n */\nOO.ui.ToolGroupTool.prototype.onUpdateState = function () {\n\tthis.setActive( false );\n};\n\n/**\n * Build a {@link OO.ui.ToolGroup toolgroup} from the specified configuration.\n *\n * @param {Object.<string,Array>} group Toolgroup configuration. Please see\n *  {@link OO.ui.ToolGroup toolgroup} for more information.\n * @return {OO.ui.ListToolGroup}\n */\nOO.ui.ToolGroupTool.prototype.createGroup = function ( group ) {\n\tif ( group.include === '*' ) {\n\t\t// Apply defaults to catch-all groups\n\t\tif ( group.label === undefined ) {\n\t\t\tgroup.label = OO.ui.msg( 'ooui-toolbar-more' );\n\t\t}\n\t}\n\n\treturn this.toolbar.getToolGroupFactory().create( 'list', this.toolbar, group );\n};\n","/**\n * BarToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to\n * create {@link OO.ui.Toolbar toolbars} (the other types of groups are\n * {@link OO.ui.MenuToolGroup MenuToolGroup} and {@link OO.ui.ListToolGroup ListToolGroup}).\n * The {@link OO.ui.Tool tools} in a BarToolGroup are displayed by icon in a single row. The\n * title of the tool is displayed when users move the mouse over the tool.\n *\n * BarToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar\n * is set up.\n *\n *     @example\n *     // Example of a BarToolGroup with two tools\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'Example of a BarToolGroup with two tools.' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     // Create a class inheriting from OO.ui.Tool\n *     function SearchTool() {\n *         SearchTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SearchTool, OO.ui.Tool );\n *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one\n *     // of 'icon' and 'title' (displayed icon and text).\n *     SearchTool.static.name = 'search';\n *     SearchTool.static.icon = 'search';\n *     SearchTool.static.title = 'Search...';\n *     // Defines the action that will happen when this tool is selected (clicked).\n *     SearchTool.prototype.onSelect = function () {\n *         $area.text( 'Search tool clicked!' );\n *         // Never display this tool as \"active\" (selected).\n *         this.setActive( false );\n *     };\n *     SearchTool.prototype.onUpdateState = function () {};\n *     // Make this tool available in our toolFactory and thus our toolbar\n *     toolFactory.register( SearchTool );\n *\n *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a\n *     // little popup window (a PopupWidget).\n *     function HelpTool( toolGroup, config ) {\n *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {\n *             padded: true,\n *             label: 'Help',\n *             head: true\n *         } }, config ) );\n *         this.popup.$body.append( '<p>I am helpful!</p>' );\n *     }\n *     OO.inheritClass( HelpTool, OO.ui.PopupTool );\n *     HelpTool.static.name = 'help';\n *     HelpTool.static.icon = 'help';\n *     HelpTool.static.title = 'Help';\n *     toolFactory.register( HelpTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             // 'bar' tool groups display tools by icon only\n *             type: 'bar',\n *             include: [ 'search', 'help' ]\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *\n * For more information about how to add tools to a bar tool group, please see\n * {@link OO.ui.ToolGroup toolgroup}.\n * For more information about toolbars in general, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.ui.ToolGroup\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n */\nOO.ui.BarToolGroup = function OoUiBarToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Parent constructor\n\tOO.ui.BarToolGroup.parent.call( this, toolbar, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-barToolGroup' );\n\tthis.$group.addClass( 'oo-ui-barToolGroup-tools' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.BarToolGroup, OO.ui.ToolGroup );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.BarToolGroup.static.titleTooltips = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.BarToolGroup.static.accelTooltips = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.BarToolGroup.static.name = 'bar';\n","/**\n * PopupToolGroup is an abstract base class used by both {@link OO.ui.MenuToolGroup MenuToolGroup}\n * and {@link OO.ui.ListToolGroup ListToolGroup} to provide a popup (an overlaid menu or list of\n * tools with an optional icon and label). This class can be used for other base classes that\n * also use this functionality.\n *\n * @abstract\n * @class\n * @extends OO.ui.ToolGroup\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.ClippableElement\n * @mixins OO.ui.mixin.FloatableElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n * @cfg {string} [header] Text to display at the top of the popup\n */\nOO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tindicator: config.indicator === undefined ?\n\t\t\t( toolbar.position === 'bottom' ? 'up' : 'down' ) : config.indicator\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.PopupToolGroup.parent.call( this, toolbar, config );\n\n\t// Properties\n\tthis.active = false;\n\tthis.dragging = false;\n\t// Don't conflict with parent method of the same name\n\tthis.onPopupDocumentMouseKeyUpHandler = this.onPopupDocumentMouseKeyUp.bind( this );\n\tthis.$handle = $( '<span>' );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.ClippableElement.call( this, $.extend( {\n\t\t$clippable: this.$group\n\t}, config ) );\n\tOO.ui.mixin.FloatableElement.call( this, $.extend( {\n\t\t$floatable: this.$group,\n\t\t$floatableContainer: this.$handle,\n\t\thideWhenOutOfView: false,\n\t\tverticalPosition: this.toolbar.position === 'bottom' ? 'above' : 'below'\n\t}, config ) );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {\n\t\t$tabIndexed: this.$handle\n\t}, config ) );\n\n\t// Events\n\tthis.$handle.on( {\n\t\tkeydown: this.onHandleMouseKeyDown.bind( this ),\n\t\tkeyup: this.onHandleMouseKeyUp.bind( this ),\n\t\tmousedown: this.onHandleMouseKeyDown.bind( this ),\n\t\tmouseup: this.onHandleMouseKeyUp.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$handle\n\t\t.addClass( 'oo-ui-popupToolGroup-handle' )\n\t\t.attr( 'role', 'button' )\n\t\t.append( this.$icon, this.$label, this.$indicator );\n\t// If the pop-up should have a header, add it to the top of the toolGroup.\n\t// Note: If this feature is useful for other widgets, we could abstract it into an\n\t// OO.ui.HeaderedElement mixin constructor.\n\tif ( config.header !== undefined ) {\n\t\tthis.$group\n\t\t\t.prepend( $( '<span>' )\n\t\t\t\t.addClass( 'oo-ui-popupToolGroup-header' )\n\t\t\t\t.text( config.header )\n\t\t\t);\n\t}\n\tthis.$element\n\t\t.addClass( 'oo-ui-popupToolGroup' )\n\t\t.prepend( this.$handle );\n\tthis.$group.addClass( 'oo-ui-popupToolGroup-tools' );\n\tthis.toolbar.$popups.append( this.$group );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PopupToolGroup, OO.ui.ToolGroup );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TitledElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.ClippableElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.FloatableElement );\nOO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupToolGroup.prototype.setDisabled = function () {\n\t// Parent method\n\tOO.ui.PopupToolGroup.parent.prototype.setDisabled.apply( this, arguments );\n\n\tif ( this.isDisabled() && this.isElementAttached() ) {\n\t\tthis.setActive( false );\n\t}\n};\n\n/**\n * Handle document mouse up and key up events.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.PopupToolGroup.prototype.onPopupDocumentMouseKeyUp = function ( e ) {\n\tvar $target = $( e.target );\n\t// Only deactivate when clicking outside the dropdown element\n\tif ( $target.closest( '.oo-ui-popupToolGroup' )[ 0 ] === this.$element[ 0 ] ) {\n\t\treturn;\n\t}\n\tif ( $target.closest( '.oo-ui-popupToolGroup-tools' )[ 0 ] === this.$group[ 0 ] ) {\n\t\treturn;\n\t}\n\tthis.setActive( false );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupToolGroup.prototype.onMouseKeyUp = function ( e ) {\n\t// Only close toolgroup when a tool was actually selected\n\tif (\n\t\t!this.isDisabled() && this.pressed && this.pressed === this.findTargetTool( e ) && (\n\t\t\te.which === OO.ui.MouseButtons.LEFT ||\n\t\t\te.which === OO.ui.Keys.SPACE ||\n\t\t\te.which === OO.ui.Keys.ENTER\n\t\t)\n\t) {\n\t\tthis.setActive( false );\n\t}\n\treturn OO.ui.PopupToolGroup.parent.prototype.onMouseKeyUp.call( this, e );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupToolGroup.prototype.onMouseKeyDown = function ( e ) {\n\tvar $focused, $firstFocusable, $lastFocusable;\n\t// Shift-Tab on the first tool in the group jumps to the handle.\n\t// Tab on the last tool in the group jumps to the next group.\n\tif ( !this.isDisabled() && e.which === OO.ui.Keys.TAB ) {\n\t\t// We can't use this.items because ListToolGroup inserts the extra fake\n\t\t// expand/collapse tool.\n\t\t$focused = $( document.activeElement );\n\t\t$firstFocusable = OO.ui.findFocusable( this.$group );\n\t\tif ( $focused[ 0 ] === $firstFocusable[ 0 ] && e.shiftKey ) {\n\t\t\tthis.$handle.trigger( 'focus' );\n\t\t\treturn false;\n\t\t}\n\t\t$lastFocusable = OO.ui.findFocusable( this.$group, true );\n\t\tif ( $focused[ 0 ] === $lastFocusable[ 0 ] && !e.shiftKey ) {\n\t\t\t// Focus this group's handle and let the browser's tab handling happen\n\t\t\t// (no 'return false').\n\t\t\t// This way we don't have to fiddle with other ToolGroups' business, or worry what to do\n\t\t\t// if the next group is not a PopupToolGroup or doesn't exist at all.\n\t\t\tthis.$handle.trigger( 'focus' );\n\t\t\t// Close the popup so that we don't move back inside it (if this is the last group).\n\t\t\tthis.setActive( false );\n\t\t}\n\t}\n\treturn OO.ui.PopupToolGroup.parent.prototype.onMouseKeyDown.call( this, e );\n};\n\n/**\n * Handle mouse up and key up events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse up or key up event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.PopupToolGroup.prototype.onHandleMouseKeyUp = function ( e ) {\n\tif (\n\t\t!this.isDisabled() && (\n\t\t\te.which === OO.ui.MouseButtons.LEFT ||\n\t\t\te.which === OO.ui.Keys.SPACE ||\n\t\t\te.which === OO.ui.Keys.ENTER\n\t\t)\n\t) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle mouse down and key down events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse down or key down event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) {\n\tvar $focusable;\n\tif ( !this.isDisabled() ) {\n\t\t// Tab on the handle jumps to the first tool in the group (if the popup is open).\n\t\tif ( e.which === OO.ui.Keys.TAB && !e.shiftKey ) {\n\t\t\t$focusable = OO.ui.findFocusable( this.$group );\n\t\t\tif ( $focusable.length ) {\n\t\t\t\t$focusable.trigger( 'focus' );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\te.which === OO.ui.MouseButtons.LEFT ||\n\t\t\te.which === OO.ui.Keys.SPACE ||\n\t\t\te.which === OO.ui.Keys.ENTER\n\t\t) {\n\t\t\tthis.setActive( !this.active );\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Check if the tool group is active.\n *\n * @return {boolean} Tool group is active\n */\nOO.ui.PopupToolGroup.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Switch into 'active' mode.\n *\n * When active, the popup is visible. A mouseup event anywhere in the document will trigger\n * deactivation.\n *\n * @param {boolean} value The active state to set\n * @fires active\n */\nOO.ui.PopupToolGroup.prototype.setActive = function ( value ) {\n\tvar containerWidth, containerLeft;\n\tvalue = !!value;\n\tif ( this.active !== value ) {\n\t\tthis.active = value;\n\t\tif ( value ) {\n\t\t\tthis.getElementDocument().addEventListener(\n\t\t\t\t'mouseup',\n\t\t\t\tthis.onPopupDocumentMouseKeyUpHandler,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\tthis.getElementDocument().addEventListener(\n\t\t\t\t'keyup',\n\t\t\t\tthis.onPopupDocumentMouseKeyUpHandler,\n\t\t\t\ttrue\n\t\t\t);\n\n\t\t\tthis.$clippable.css( 'left', '' );\n\t\t\tthis.$element.addClass( 'oo-ui-popupToolGroup-active' );\n\t\t\tthis.$group.addClass( 'oo-ui-popupToolGroup-active-tools' );\n\t\t\tthis.togglePositioning( true );\n\t\t\tthis.toggleClipping( true );\n\n\t\t\t// Try anchoring the popup to the left first\n\t\t\tthis.setHorizontalPosition( 'start' );\n\n\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t// Anchoring to the left caused the popup to clip, so anchor it to the\n\t\t\t\t// right instead.\n\t\t\t\tthis.setHorizontalPosition( 'end' );\n\t\t\t}\n\t\t\tif ( this.isClippedHorizontally() || this.isFloatableOutOfView() ) {\n\t\t\t\t// Anchoring to the right also caused the popup to clip, so just make it fill the\n\t\t\t\t// container.\n\t\t\t\tcontainerWidth = this.$clippableScrollableContainer.width();\n\t\t\t\tcontainerLeft = this.$clippableScrollableContainer[ 0 ] ===\n\t\t\t\t\tdocument.documentElement ?\n\t\t\t\t\t0 :\n\t\t\t\t\tthis.$clippableScrollableContainer.offset().left;\n\n\t\t\t\tthis.toggleClipping( false );\n\t\t\t\tthis.setHorizontalPosition( 'start' );\n\n\t\t\t\tthis.$clippable.css( {\n\t\t\t\t\t'margin-left': -( this.$element.offset().left - containerLeft ),\n\t\t\t\t\twidth: containerWidth\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.getElementDocument().removeEventListener(\n\t\t\t\t'mouseup',\n\t\t\t\tthis.onPopupDocumentMouseKeyUpHandler,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\tthis.getElementDocument().removeEventListener(\n\t\t\t\t'keyup',\n\t\t\t\tthis.onPopupDocumentMouseKeyUpHandler,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\tthis.$element.removeClass( 'oo-ui-popupToolGroup-active' );\n\t\t\tthis.$group.removeClass( 'oo-ui-popupToolGroup-active-tools' );\n\t\t\tthis.togglePositioning( false );\n\t\t\tthis.toggleClipping( false );\n\t\t}\n\t\tthis.emit( 'active', this.active );\n\t\tthis.updateThemeClasses();\n\t}\n};\n","/**\n * ListToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to\n * create {@link OO.ui.Toolbar toolbars} (the other types of groups are\n * {@link OO.ui.MenuToolGroup MenuToolGroup} and {@link OO.ui.BarToolGroup BarToolGroup}).\n * The {@link OO.ui.Tool tools} in a ListToolGroup are displayed by label in a dropdown menu.\n * The title of the tool is used as the label text. The menu itself can be configured with a label,\n * icon, indicator, header, and title.\n *\n * ListToolGroups can be configured to be expanded and collapsed. Collapsed lists will have a\n * ‘More’ option that users can select to see the full list of tools. If a collapsed toolgroup is\n * expanded, a ‘Fewer’ option permits users to collapse the list again.\n *\n * ListToolGroups are created by a {@link OO.ui.ToolGroupFactory toolgroup factory} when the\n * toolbar is set up. The factory requires the ListToolGroup's symbolic name, 'list', which is\n * specified along with the other configurations. For more information about how to add tools to a\n * ListToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.\n *\n *     @example\n *     // Example of a ListToolGroup\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // Configure and register two tools\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         this.setActive( false );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *     // Register two more tools, nothing interesting here\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'search';\n *     StuffTool.static.title = 'Change the world';\n *     StuffTool.prototype.onSelect = function () {\n *         this.setActive( false );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *     toolbar.setup( [\n *         {\n *             // Configurations for list toolgroup.\n *             type: 'list',\n *             label: 'ListToolGroup',\n *             icon: 'ellipsis',\n *             title: 'This is the title, displayed when user moves the mouse over the list ' +\n *                 'toolgroup',\n *             header: 'This is the header',\n *             include: [ 'settings', 'stuff' ],\n *             allowCollapse: ['stuff']\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element\n *     );\n *     $( document.body ).append( frame.$element );\n *     // Build the toolbar. This must be done after the toolbar has been appended to the document.\n *     toolbar.initialize();\n *\n * For more information about toolbars in general, please see the\n * [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.ui.PopupToolGroup\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n * @cfg {Array} [allowCollapse] Allow the specified tools to be collapsed. By default, collapsible\n *  tools will only be displayed if users click the ‘More’ option displayed at the bottom of the\n *  list. If the list is expanded, a ‘Fewer’ option permits users to collapse the list again.\n *  Any tools that are included in the toolgroup, but are not designated as collapsible, will always\n *  be displayed.\n *  To open a collapsible list in its expanded state, set #expanded to 'true'.\n * @cfg {Array} [forceExpand] Expand the specified tools. All other tools will be designated as\n *  collapsible. Unless #expanded is set to true, the collapsible tools will be collapsed when the\n *  list is first opened.\n * @cfg {boolean} [expanded=false] Expand collapsible tools. This config is only relevant if tools\n *  have been designated as collapsible. When expanded is set to true, all tools in the group will\n *  be displayed when the list is first opened. Users can collapse the list with a ‘Fewer’ option at\n *  the bottom.\n */\nOO.ui.ListToolGroup = function OoUiListToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties (must be set before parent constructor, which calls #populate)\n\tthis.allowCollapse = config.allowCollapse;\n\tthis.forceExpand = config.forceExpand;\n\tthis.expanded = config.expanded !== undefined ? config.expanded : false;\n\tthis.collapsibleTools = [];\n\n\t// Parent constructor\n\tOO.ui.ListToolGroup.parent.call( this, toolbar, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-listToolGroup' );\n\tthis.$group.addClass( 'oo-ui-listToolGroup-tools' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ListToolGroup, OO.ui.PopupToolGroup );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ListToolGroup.static.name = 'list';\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ListToolGroup.prototype.populate = function () {\n\tvar i, len, allowCollapse = [];\n\n\tOO.ui.ListToolGroup.parent.prototype.populate.call( this );\n\n\t// Update the list of collapsible tools\n\tif ( this.allowCollapse !== undefined ) {\n\t\tallowCollapse = this.allowCollapse;\n\t} else if ( this.forceExpand !== undefined ) {\n\t\tallowCollapse = OO.simpleArrayDifference( Object.keys( this.tools ), this.forceExpand );\n\t}\n\n\tthis.collapsibleTools = [];\n\tfor ( i = 0, len = allowCollapse.length; i < len; i++ ) {\n\t\tif ( this.tools[ allowCollapse[ i ] ] !== undefined ) {\n\t\t\tthis.collapsibleTools.push( this.tools[ allowCollapse[ i ] ] );\n\t\t}\n\t}\n\n\t// Keep at the end, even when tools are added\n\tthis.$group.append( this.getExpandCollapseTool().$element );\n\n\tthis.getExpandCollapseTool().toggle( this.collapsibleTools.length !== 0 );\n\tthis.updateCollapsibleState();\n};\n\n/**\n * Get the expand/collapse tool for this group\n *\n * @return {OO.ui.Tool} Expand collapse tool\n */\nOO.ui.ListToolGroup.prototype.getExpandCollapseTool = function () {\n\tvar ExpandCollapseTool;\n\tif ( this.expandCollapseTool === undefined ) {\n\t\tExpandCollapseTool = function () {\n\t\t\tExpandCollapseTool.parent.apply( this, arguments );\n\t\t};\n\n\t\tOO.inheritClass( ExpandCollapseTool, OO.ui.Tool );\n\n\t\tExpandCollapseTool.prototype.onSelect = function () {\n\t\t\tthis.toolGroup.expanded = !this.toolGroup.expanded;\n\t\t\tthis.toolGroup.updateCollapsibleState();\n\t\t\tthis.setActive( false );\n\t\t};\n\t\tExpandCollapseTool.prototype.onUpdateState = function () {\n\t\t\t// Do nothing. Tool interface requires an implementation of this function.\n\t\t};\n\n\t\tExpandCollapseTool.static.name = 'more-fewer';\n\n\t\tthis.expandCollapseTool = new ExpandCollapseTool( this );\n\t}\n\treturn this.expandCollapseTool;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ListToolGroup.prototype.onMouseKeyUp = function ( e ) {\n\t// Do not close the popup when the user wants to show more/fewer tools\n\tif (\n\t\t$( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length && (\n\t\t\te.which === OO.ui.MouseButtons.LEFT ||\n\t\t\te.which === OO.ui.Keys.SPACE ||\n\t\t\te.which === OO.ui.Keys.ENTER\n\t\t)\n\t) {\n\t\t// HACK: Prevent the popup list from being hidden. Skip the PopupToolGroup implementation\n\t\t// (which hides the popup list when a tool is selected) and call ToolGroup's implementation\n\t\t// directly.\n\t\treturn OO.ui.ListToolGroup.parent.parent.prototype.onMouseKeyUp.call( this, e );\n\t} else {\n\t\treturn OO.ui.ListToolGroup.parent.prototype.onMouseKeyUp.call( this, e );\n\t}\n};\n\nOO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {\n\tvar i, icon, len;\n\n\tif ( this.toolbar.position !== 'bottom' ) {\n\t\ticon = this.expanded ? 'collapse' : 'expand';\n\t} else {\n\t\ticon = this.expanded ? 'expand' : 'collapse';\n\t}\n\n\tthis.getExpandCollapseTool()\n\t\t.setIcon( icon )\n\t\t.setTitle( OO.ui.msg( this.expanded ? 'ooui-toolgroup-collapse' : 'ooui-toolgroup-expand' ) );\n\n\tfor ( i = 0, len = this.collapsibleTools.length; i < len; i++ ) {\n\t\tthis.collapsibleTools[ i ].toggle( this.expanded );\n\t}\n\n\t// Re-evaluate clipping, because our height has changed\n\tthis.clip();\n};\n","/**\n * MenuToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to\n * create {@link OO.ui.Toolbar toolbars} (the other types of groups are\n * {@link OO.ui.BarToolGroup BarToolGroup} and {@link OO.ui.ListToolGroup ListToolGroup}).\n * MenuToolGroups contain selectable {@link OO.ui.Tool tools}, which are displayed by label in a\n * dropdown menu. The tool's title is used as the label text, and the menu label is updated to\n * reflect which tool or tools are currently selected. If no tools are selected, the menu label\n * is empty. The menu can be configured with an indicator, icon, title, and/or header.\n *\n * MenuToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the\n * toolbar is set up.\n *\n *     @example\n *     // Example of a MenuToolGroup\n *     var toolFactory = new OO.ui.ToolFactory();\n *     var toolGroupFactory = new OO.ui.ToolGroupFactory();\n *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );\n *\n *     // We will be placing status text in this element when tools are used\n *     var $area = $( '<p>' ).text( 'An example of a MenuToolGroup. Select a tool from the '\n *         + 'dropdown menu.' );\n *\n *     // Define the tools that we're going to place in our toolbar\n *\n *     function SettingsTool() {\n *         SettingsTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( SettingsTool, OO.ui.Tool );\n *     SettingsTool.static.name = 'settings';\n *     SettingsTool.static.icon = 'settings';\n *     SettingsTool.static.title = 'Change settings';\n *     SettingsTool.prototype.onSelect = function () {\n *         $area.text( 'Settings tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     SettingsTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( SettingsTool );\n *\n *     function StuffTool() {\n *         StuffTool.parent.apply( this, arguments );\n *         this.reallyActive = false;\n *     }\n *     OO.inheritClass( StuffTool, OO.ui.Tool );\n *     StuffTool.static.name = 'stuff';\n *     StuffTool.static.icon = 'ellipsis';\n *     StuffTool.static.title = 'More stuff';\n *     StuffTool.prototype.onSelect = function () {\n *         $area.text( 'More stuff tool clicked!' );\n *         // Toggle the active state on each click\n *         this.reallyActive = !this.reallyActive;\n *         this.setActive( this.reallyActive );\n *         // To update the menu label\n *         this.toolbar.emit( 'updateState' );\n *     };\n *     StuffTool.prototype.onUpdateState = function () {};\n *     toolFactory.register( StuffTool );\n *\n *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be\n *     // used once (but not all defined tools must be used).\n *     toolbar.setup( [\n *         {\n *             type: 'menu',\n *             header: 'This is the (optional) header',\n *             title: 'This is the (optional) title',\n *             include: [ 'settings', 'stuff' ]\n *         }\n *     ] );\n *\n *     // Create some UI around the toolbar and place it in the document\n *     var frame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         framed: true\n *     } );\n *     var contentFrame = new OO.ui.PanelLayout( {\n *         expanded: false,\n *         padded: true\n *     } );\n *     frame.$element.append(\n *         toolbar.$element,\n *         contentFrame.$element.append( $area )\n *     );\n *     $( document.body ).append( frame.$element );\n *\n *     // Here is where the toolbar is actually built. This must be done after inserting it into the\n *     // document.\n *     toolbar.initialize();\n *     toolbar.emit( 'updateState' );\n *\n * For more information about how to add tools to a MenuToolGroup, please see\n * {@link OO.ui.ToolGroup toolgroup}.\n * For more information about toolbars in general, please see the\n * [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars\n *\n * @class\n * @extends OO.ui.PopupToolGroup\n *\n * @constructor\n * @param {OO.ui.Toolbar} toolbar\n * @param {Object} [config] Configuration options\n */\nOO.ui.MenuToolGroup = function OoUiMenuToolGroup( toolbar, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( toolbar ) && config === undefined ) {\n\t\tconfig = toolbar;\n\t\ttoolbar = config.toolbar;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MenuToolGroup.parent.call( this, toolbar, config );\n\n\t// Events\n\tthis.toolbar.connect( this, {\n\t\tupdateState: 'onUpdateState'\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-menuToolGroup' );\n\tthis.$group.addClass( 'oo-ui-menuToolGroup-tools' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuToolGroup, OO.ui.PopupToolGroup );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MenuToolGroup.static.name = 'menu';\n\n/* Methods */\n\n/**\n * Handle the toolbar state being updated.\n *\n * When the state changes, the title of each active item in the menu will be joined together and\n * used as a label for the group. The label will be empty if none of the items are active.\n *\n * @private\n */\nOO.ui.MenuToolGroup.prototype.onUpdateState = function () {\n\tvar name,\n\t\tlabelTexts = [];\n\n\tfor ( name in this.tools ) {\n\t\tif ( this.tools[ name ].isActive() ) {\n\t\t\tlabelTexts.push( this.tools[ name ].getTitle() );\n\t\t}\n\t}\n\n\tthis.setLabel( labelTexts.join( ', ' ) || ' ' );\n};\n","}( OO ) );\n"]}
\ No newline at end of file
index a7756fb..98d5190 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
 .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
   margin-left: -2px;
 }
 
-.oo-ui-selectFileWidget {
-  display: inline-block;
-  vertical-align: middle;
-  width: 100%;
-  max-width: 50em;
-  margin-right: 0.5em;
-}
-.oo-ui-selectFileWidget-selectButton {
-  display: table-cell;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  position: relative;
-  overflow: hidden;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  width: 100%;
-  height: 100%;
-  opacity: 0;
-  z-index: 1;
-  cursor: pointer;
-  padding-top: 100px;
-}
-.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
-  display: none;
-}
-.oo-ui-selectFileWidget-info {
-  width: 100%;
-  display: table-cell;
-  vertical-align: middle;
-  position: relative;
-  overflow: hidden;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
-  cursor: default;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-}
-.oo-ui-selectFileWidget-label {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  text-overflow: ellipsis;
-}
-.oo-ui-selectFileWidget-clearButton {
-  position: absolute;
-  z-index: 2;
-}
 .oo-ui-selectFileWidget-dropTarget {
   position: relative;
   cursor: default;
   height: 8.815em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel,
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-selectButton {
   display: none;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail {
   background-repeat: no-repeat;
   background-size: contain;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail.oo-ui-pendingElement-pending {
-  background-repeat: repeat;
-  background-size: auto;
-}
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail > .oo-ui-selectFileWidget-noThumbnail-icon {
   opacity: 0.4;
   height: 7.815em;
   width: 7.815em;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-pendingElement-pending {
+  background-repeat: repeat;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-info {
   display: block;
   height: 100%;
   width: auto;
   margin-left: 8.815em;
+  margin-right: 0;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-info > .oo-ui-inputWidget-input {
   border: 0;
+  box-shadow: none;
+  background: transparent;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-label {
   display: block;
   position: relative;
   top: inherit;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-fileName {
   display: block;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-  display: none;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton {
-  display: block;
-  margin: 2.2em 1em 1em;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget {
   text-align: center;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-  margin: 0;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-info {
   display: none;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-label {
-  cursor: default;
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-selectButton {
+  display: block;
+  margin: 2.2em 1em 1em;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropLabel {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropLabel {
   display: block;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget {
   -webkit-touch-callout: none;
   -webkit-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
   user-select: none;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button {
   cursor: no-drop;
 }
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-  height: auto;
-}
-.oo-ui-selectFileWidget:last-child {
-  margin-right: 0;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  border-radius: 0 3px 3px 0;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
-  display: none;
-}
-.oo-ui-selectFileWidget-info {
-  height: 2.4em;
-  background-color: #fff;
-  border: 1px solid #ccc;
-  border-width: 1px 0 1px 1px;
-  border-radius: 3px 0 0 3px;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-  position: absolute;
-  top: 0;
-  height: 100%;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-  left: 0.3em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-  right: 0.775em;
-}
-.oo-ui-selectFileWidget-label {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-  left: 0.5em;
-  right: 2.175em;
-  line-height: 2.3em;
-  margin: 0;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-.oo-ui-selectFileWidget-clearButton {
-  top: 0;
-  right: 0;
-  height: 2.34375em;
-  margin: 0;
-}
-.oo-ui-selectFileWidget-clearButton.oo-ui-iconElement .oo-ui-buttonElement-button {
-  height: 2.34375em;
-  padding: 0;
-}
-.oo-ui-selectFileWidget-clearButton.oo-ui-iconElement .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  background-size: 12px 12px;
-  height: 2.34375em;
-  margin-top: 0;
-  margin-bottom: 0;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
-  color: #ccc;
-}
-.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-label {
-  left: 2.475em;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-  right: 4.2625em;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-clearButton {
-  right: 2.0875em;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-label {
-  right: 0.5em;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-  right: 2em;
-}
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget {
-  background-color: #e1f3ff;
-}
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-  padding: 1em;
-}
 .oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
   border: 1px solid #aaa;
   border-radius: 3px;
   vertical-align: middle;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  border-radius: 3px;
-}
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-  line-height: 1.4;
-  overflow: inherit;
-  white-space: normal;
-}
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
-  padding-top: 0.5em;
-  padding-right: 2.375em;
+.oo-ui-selectFileWidget-dropTarget.oo-ui-selectFileInputWidget-empty {
+  border-style: dashed;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
-  right: 0.5em;
+.oo-ui-selectFileWidget-dropTarget .oo-ui-pendingElement-pending {
+  background-size: 1.5625em 1.5625em;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget {
-  border-style: dashed;
+.oo-ui-selectFileWidget.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop .oo-ui-selectFileInputWidget-info > .oo-ui-inputWidget-input {
+  background-color: #e1f3ff;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget {
   background-color: #f3f3f3;
   color: #ccc;
   border-color: #ddd;
   text-shadow: 0 1px 1px #fff;
 }
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info {
-  background-color: #f3f3f3;
-  color: #ccc;
-  border-color: #ddd;
-  text-shadow: 0 1px 1px #fff;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-  opacity: 0.2;
-}
 
 
 .oo-ui-outlineOptionWidget {
 .oo-ui-outlineOptionWidget-level-2.oo-ui-iconElement .oo-ui-iconElement-icon {
   left: 5em;
 }
-.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
+.oo-ui-selectWidget-unpressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
   background-color: #a7dcff;
   text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
 }
   background-image: -moz-linear-gradient(top, #fafafa 0, #ddd 100%);
   background-image: linear-gradient(to bottom, #fafafa 0, #ddd 100%);
   color: #333;
-  width: auto;
-  max-width: 100%;
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
-  height: 1.7em;
+  width: auto;
+  max-width: 100%;
+  height: 1.71875em;
   margin: 0.1em;
   border: 1px solid #ccc;
   border-radius: 3px;
   padding: 0 0.4em;
-  line-height: 1.7em;
+  line-height: 1.640625em;
   vertical-align: middle;
 }
 .oo-ui-tagItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
index a2f011d..4a2f37e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
 .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
   background-color: #fff;
 }
 
-.oo-ui-selectFileWidget {
-  display: inline-block;
-  vertical-align: middle;
-  width: 100%;
-  max-width: 50em;
-  margin-right: 0.5em;
-}
-.oo-ui-selectFileWidget-selectButton {
-  display: table-cell;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  position: relative;
-  overflow: hidden;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  width: 100%;
-  height: 100%;
-  opacity: 0;
-  z-index: 1;
-  cursor: pointer;
-  padding-top: 100px;
-}
-.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
-  display: none;
-}
-.oo-ui-selectFileWidget-info {
-  width: 100%;
-  display: table-cell;
-  vertical-align: middle;
-  position: relative;
-  overflow: hidden;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
-  cursor: default;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-}
-.oo-ui-selectFileWidget-label {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  text-overflow: ellipsis;
-}
-.oo-ui-selectFileWidget-clearButton {
-  position: absolute;
-  z-index: 2;
-}
 .oo-ui-selectFileWidget-dropTarget {
   position: relative;
   cursor: default;
   height: 8.815em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel,
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-selectButton {
   display: none;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail {
   background-repeat: no-repeat;
   background-size: contain;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail.oo-ui-pendingElement-pending {
-  background-repeat: repeat;
-  background-size: auto;
-}
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail > .oo-ui-selectFileWidget-noThumbnail-icon {
   opacity: 0.4;
   height: 7.815em;
   width: 7.815em;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-pendingElement-pending {
+  background-repeat: repeat;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-info {
   display: block;
   height: 100%;
   width: auto;
   margin-left: 8.815em;
+  margin-right: 0;
+}
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-info > .oo-ui-inputWidget-input {
   border: 0;
+  box-shadow: none;
+  background: transparent;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-label {
   display: block;
   position: relative;
   top: inherit;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
-  display: block;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-  display: none;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton {
+.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-fileName {
   display: block;
-  margin: 2.2em 1em 1em;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget {
   text-align: center;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-  margin: 0;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-info {
   display: none;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-label {
-  cursor: default;
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileInputWidget-selectButton {
+  display: block;
+  margin: 2.2em 1em 1em;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropLabel {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropLabel {
   display: block;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget {
   -webkit-touch-callout: none;
   -webkit-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
   user-select: none;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button,
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget .oo-ui-buttonElement-button {
   cursor: no-drop;
 }
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-  height: auto;
-}
-.oo-ui-selectFileWidget:last-child {
-  margin-right: 0;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  border-radius: 0 2px 2px 0;
-}
-.oo-ui-selectFileWidget-info {
-  background-color: #fff;
-  border: 1px solid #a2a9b1;
-  border-radius: 2px 0 0 2px;
-  border-right-width: 0;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-  top: -1px;
-  left: 0.57142857em;
-  min-height: 2.28571429em;
-  margin-left: -1px;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-  top: -1px;
-  right: 0.85714286em;
-  min-height: 2.28571429em;
-}
-.oo-ui-selectFileWidget-label {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-  display: block;
-  right: 2.85714286em;
-  padding-top: 0.57142857em;
-  padding-left: 0.57142857em;
-  padding-bottom: 0.57142857em;
-  white-space: nowrap;
-}
-.oo-ui-selectFileWidget.oo-ui-labelElement .oo-ui-selectFileWidget-label {
-  line-height: 1;
-}
-.oo-ui-selectFileWidget-fileName {
-  display: block;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-.oo-ui-selectFileWidget-clearButton {
-  top: 0;
-  right: 0;
-  margin-right: 0;
-  padding-left: 0;
-}
-.oo-ui-selectFileWidget-clearButton > .oo-ui-buttonElement-button {
-  padding-top: 2em;
-}
-.oo-ui-selectFileWidget-clearButton .oo-ui-iconElement-icon {
-  background-position: center center;
-  background-size: 12px 12px;
-  height: 2em;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
-  color: #72777d;
-}
-.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-label {
-  left: 2.64285714em;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-  right: 4.57142857em;
-  padding-left: 0;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-clearButton {
-  right: 2.28571429em;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-  right: 2em;
-}
 .oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
   border: 1px solid #a2a9b1;
   vertical-align: middle;
   overflow: hidden;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  border-radius: 2px;
-}
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-  overflow: inherit;
-  white-space: normal;
-}
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
-  padding-right: 2.64285714em;
+.oo-ui-selectFileWidget-dropTarget.oo-ui-selectFileInputWidget-empty {
+  border-style: dashed;
 }
-.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
-  top: 0;
+.oo-ui-selectFileWidget-dropTarget .oo-ui-pendingElement-pending {
+  background-size: 1.42857143em 1.42857143em;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget {
+.oo-ui-selectFileWidget.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
-  border-style: dashed;
   -webkit-transition: background-color 250ms, color 250ms, border-color 250ms;
   -moz-transition: background-color 250ms, color 250ms, border-color 250ms;
   transition: background-color 250ms, color 250ms, border-color 250ms;
 }
-.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget:hover {
+.oo-ui-selectFileWidget.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 {
+.oo-ui-selectFileWidget.oo-ui-widget-enabled .oo-ui-selectFileInputWidget-info > .oo-ui-inputWidget-input {
+  -webkit-transition: background-color 250ms, color 250ms;
+  -moz-transition: background-color 250ms, color 250ms;
+  transition: background-color 250ms, color 250ms;
+}
+.oo-ui-selectFileWidget.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop .oo-ui-selectFileInputWidget-info > .oo-ui-inputWidget-input {
   background-color: #eaf3ff;
   color: #36c;
 }
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
-  background-color: #eaecf0;
-  color: #72777d;
-  border-color: #c8ccd1;
-  text-shadow: 0 1px 1px #fff;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-  opacity: 0.51;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-  opacity: 0.15;
-}
 .oo-ui-selectFileWidget.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget {
-  background-color: #eaecf0;
-  border-color: #c8ccd1;
-}
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info {
-  background-color: #eaecf0;
-  color: #222;
-  border-color: #c8ccd1;
-}
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
+.oo-ui-selectFileWidget.oo-ui-selectFileInputWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget {
   background-color: #eaecf0;
   border-color: #c8ccd1;
 }
-.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-  padding: 1em 0.85714286em;
-}
-.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropLabel {
-  display: none;
-}
 
 .oo-ui-outlineSelectWidget {
   height: 100%;
   -moz-user-select: none;
   -ms-user-select: none;
   user-select: none;
-  padding: 1em 0.85714286em 0.92857143em;
+  padding: 0.85714286em 0.85714286em;
   -webkit-transition: background-color 100ms, color 100ms;
   -moz-transition: background-color 100ms, color 100ms;
   transition: background-color 100ms, color 100ms;
 }
 .oo-ui-tabOptionWidget .oo-ui-labelElement-label {
   border-bottom: 2px solid transparent;
-  padding: 0.57142857em 0.35714286em 0.42857143em;
-  line-height: 1;
+  padding: 0.42857143em 0.35714286em 0.28571429em;
+  line-height: 1.28571429em;
   -webkit-transition: border-color 100ms;
   -moz-transition: border-color 100ms;
   transition: border-color 100ms;
   box-sizing: border-box;
   height: 2.14285714em;
   border: 0;
-  padding: 0.57142857em 0 0.57142857em 0.57142857em;
+  padding: 0.42857143em 0 0.42857143em 0.57142857em;
   font-family: inherit;
   font-size: inherit;
-  line-height: 1;
+  line-height: 1.28571429em;
   vertical-align: top;
 }
 .oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::-webkit-input-placeholder {
   border: 1px solid #a2a9b1;
   border-radius: 1.57142857em;
   padding: 0 0.57142857em;
-  line-height: 1.57142857em;
+  line-height: 1.42857143em;
   vertical-align: middle;
 }
 .oo-ui-tagItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
index 4949557..81b2a6f 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:07Z
+ * Date: 2019-04-04T19:10:48Z
  */
 ( function ( OO ) {
 
@@ -23,7 +23,8 @@
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$handle] The part of the element which can be used for dragging, defaults to the whole element
+ * @cfg {jQuery} [$handle] The part of the element which can be used for dragging, defaults to
+ *  the whole element
  * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable
  *  but the draggable state should be called from the DraggableGroupElement, which updates
  *  the whole group
@@ -58,7 +59,8 @@ OO.initClass( OO.ui.mixin.DraggableElement );
  * @event dragstart
  *
  * A dragstart event is emitted when the user clicks and begins dragging an item.
- * @param {OO.ui.mixin.DraggableElement} item The item the user has clicked and is dragging with the mouse.
+ * @param {OO.ui.mixin.DraggableElement} item The item the user has clicked and is dragging with
+ *  the mouse.
  */
 
 /**
@@ -105,7 +107,7 @@ OO.ui.mixin.DraggableElement.prototype.toggleDraggable = function ( isDraggable
 };
 
 /**
- * Check the draggable state of this widget
+ * Check the draggable state of this widget.
  *
  * @return {boolean} Widget supports draggable operations
  */
@@ -207,7 +209,7 @@ OO.ui.mixin.DraggableElement.prototype.onDragOver = function ( e ) {
 
 /**
  * Set item index.
- * Store it in the DOM so we can access from the widget drag event
+ * Store it in the DOM so we can access from the widget drag event.
  *
  * @private
  * @param {number} index Item index
@@ -220,7 +222,7 @@ OO.ui.mixin.DraggableElement.prototype.setIndex = function ( index ) {
 };
 
 /**
- * Get item index
+ * Get item index.
  *
  * @private
  * @return {number} Item index
@@ -477,15 +479,16 @@ OO.ui.mixin.DraggableGroupElement.prototype.unsetDragItem = function () {
 /**
  * Get the item that is currently being dragged.
  *
- * @return {OO.ui.mixin.DraggableElement|null} The currently dragged item, or `null` if no item is being dragged
+ * @return {OO.ui.mixin.DraggableElement|null} The currently dragged item, or `null` if no item is
+ *  being dragged
  */
 OO.ui.mixin.DraggableGroupElement.prototype.getDragItem = function () {
        return this.dragItem;
 };
 
 /**
- * RequestManager is a mixin that manages the lifecycle of a promise-backed request for a widget, such as
- * the {@link OO.ui.mixin.LookupElement}.
+ * RequestManager is a mixin that manages the lifecycle of a promise-backed request for a widget,
+ * such as the {@link OO.ui.mixin.LookupElement}.
  *
  * @class
  * @abstract
@@ -505,9 +508,9 @@ OO.initClass( OO.ui.mixin.RequestManager );
 /**
  * Get request results for the current query.
  *
- * @return {jQuery.Promise} Promise object which will be passed response data as the first argument of
- *   the done event. If the request was aborted to make way for a subsequent request, this promise
- *   may not be rejected, depending on what jQuery feels like doing.
+ * @return {jQuery.Promise} Promise object which will be passed response data as the first argument
+ *  of the done event. If the request was aborted to make way for a subsequent request, this
+ *  promise may not be rejected, depending on what jQuery feels like doing.
  */
 OO.ui.mixin.RequestManager.prototype.getRequestData = function () {
        var widget = this,
@@ -542,7 +545,8 @@ OO.ui.mixin.RequestManager.prototype.getRequestData = function () {
                                if ( ourRequest === widget.requestRequest ) {
                                        widget.requestQuery = null;
                                        widget.requestRequest = null;
-                                       widget.requestCache[ value ] = widget.getRequestCacheDataFromResponse( response );
+                                       widget.requestCache[ value ] =
+                                               widget.getRequestCacheDataFromResponse( response );
                                        deferred.resolve( widget.requestCache[ value ] );
                                }
                        } )
@@ -610,14 +614,15 @@ OO.ui.mixin.RequestManager.prototype.getRequest = null;
 OO.ui.mixin.RequestManager.prototype.getRequestCacheDataFromResponse = null;
 
 /**
- * LookupElement is a mixin that creates a {@link OO.ui.MenuSelectWidget menu} of suggested values for
- * a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on the characters the user types
- * into the text input field and, in general, the menu is only displayed when the user types. If a suggested value is chosen
- * from the lookup menu, that value becomes the value of the input field.
+ * LookupElement is a mixin that creates a {@link OO.ui.MenuSelectWidget menu} of suggested
+ * values for a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on
+ * the characters the user types into the text input field and, in general, the menu is only
+ * displayed when the user types. If a suggested value is chosen from the lookup menu, that value
+ * becomes the value of the input field.
  *
- * Note that a new menu of suggested items is displayed when a value is chosen from the lookup menu. If this is
- * not the desired behavior, disable lookup menus with the #setLookupsDisabled method, then set the value, then
- * re-enable lookups.
+ * Note that a new menu of suggested items is displayed when a value is chosen from the
+ * lookup menu. If this is not the desired behavior, disable lookup menus with the
+ * #setLookupsDisabled method, then set the value, then re-enable lookups.
  *
  * See the [OOUI demos][1] for an example.
  *
@@ -631,12 +636,16 @@ OO.ui.mixin.RequestManager.prototype.getRequestCacheDataFromResponse = null;
  * @param {Object} [config] Configuration options
  * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
- * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered beneath the specified element.
- * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.MenuSelectWidget menu select widget}
- * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the text input is empty.
+ * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered
+ *  beneath the specified element.
+ * @cfg {Object} [menu] Configuration options to pass to
+ *  {@link OO.ui.MenuSelectWidget menu select widget}
+ * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the
+ *  text input is empty.
  *  By default, the lookup menu is not generated and displayed until the user begins to type.
- * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted (so, that the user can
- *  take it over into the input with simply pressing return) automatically or not.
+ * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted
+ *  (so, that the user can take it over into the input with simply pressing return) automatically
+ *  or not.
  */
 OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
        // Configuration initialization
@@ -646,7 +655,8 @@ OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
        OO.ui.mixin.RequestManager.call( this, config );
 
        // Properties
-       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
+       this.$overlay = ( config.$overlay === true ?
+               OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
        this.lookupMenu = new OO.ui.MenuSelectWidget( $.extend( {
                widget: this,
                input: this,
@@ -665,7 +675,9 @@ OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
                blur: this.onLookupInputBlur.bind( this ),
                mousedown: this.onLookupInputMouseDown.bind( this )
        } );
-       this.connect( this, { change: 'onLookupInputChange' } );
+       this.connect( this, {
+               change: 'onLookupInputChange'
+       } );
        this.lookupMenu.connect( this, {
                toggle: 'onLookupMenuToggle',
                choose: 'onLookupMenuItemChoose'
@@ -718,7 +730,7 @@ OO.ui.mixin.LookupElement.prototype.onLookupInputBlur = function () {
  */
 OO.ui.mixin.LookupElement.prototype.onLookupInputMouseDown = function () {
        // Only open the menu if the input was already focused.
-       // This way we allow the user to open the menu again after closing it with Esc
+       // This way we allow the user to open the menu again after closing it with Escape (esc)
        // by clicking in the input. Opening (and populating) the menu when initially
        // clicking into the input is handled by the focus handler.
        if ( this.lookupInputFocused && !this.lookupMenu.isVisible() ) {
@@ -748,7 +760,7 @@ OO.ui.mixin.LookupElement.prototype.onLookupMenuToggle = function ( visible ) {
        if ( !visible ) {
                // When the menu is hidden, abort any active request and clear the menu.
                // This has to be done here in addition to closeLookupMenu(), because
-               // MenuSelectWidget will close itself when the user presses Esc.
+               // MenuSelectWidget will close itself when the user presses Escape (esc).
                this.abortLookupRequest();
                this.lookupMenu.clearItems();
        }
@@ -942,7 +954,7 @@ OO.ui.mixin.LookupElement.prototype.setReadOnly = function ( readOnly ) {
        // Note: Calling #setReadOnly this way assumes this is mixed into an OO.ui.TextInputWidget
        OO.ui.TextInputWidget.prototype.setReadOnly.call( this, readOnly );
 
-       // During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor
+       // During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor.
        if ( this.isReadOnly() && this.lookupMenu ) {
                this.closeLookupMenu();
        }
@@ -1021,8 +1033,8 @@ OO.inheritClass( OO.ui.TabPanelLayout, OO.ui.PanelLayout );
 /* Events */
 
 /**
- * An 'active' event is emitted when the tab panel becomes active. Tab panels become active when they are
- * shown in a index layout that is configured to display only one tab panel at a time.
+ * An 'active' event is emitted when the tab panel becomes active. Tab panels become active when
+ * they are shown in a index layout that is configured to display only one tab panel at a time.
  *
  * @event active
  * @param {boolean} active Tab panel is active
@@ -1042,9 +1054,9 @@ OO.ui.TabPanelLayout.prototype.getName = function () {
 /**
  * Check if tab panel is active.
  *
- * Tab panels become active when they are shown in a {@link OO.ui.IndexLayout index layout} that is configured to
- * display only one tab panel at a time. Additional CSS is applied to the tab panel's tab item to reflect the
- * active state.
+ * Tab panels become active when they are shown in a {@link OO.ui.IndexLayout index layout} that is
+ * configured to display only one tab panel at a time. Additional CSS is applied to the tab panel's
+ * tab item to reflect the active state.
  *
  * @return {boolean} Tab panel is active
  */
@@ -1056,7 +1068,8 @@ OO.ui.TabPanelLayout.prototype.isActive = function () {
  * Get tab item.
  *
  * The tab item allows users to access the tab panel from the index's tab
- * navigation. The tab item itself can be customized (with a label, level, etc.) using the #setupTabItem method.
+ * navigation. The tab item itself can be customized (with a label, level, etc.) using the
+ * #setupTabItem method.
  *
  * @return {OO.ui.TabOptionWidget|null} Tab option widget
  */
@@ -1126,13 +1139,14 @@ OO.ui.TabPanelLayout.prototype.setActive = function ( active ) {
 };
 
 /**
- * PageLayouts are used within {@link OO.ui.BookletLayout booklet layouts} to create pages that users can select and display
- * from the booklet's optional {@link OO.ui.OutlineSelectWidget outline} navigation. Pages are usually not instantiated directly,
- * rather extended to include the required content and functionality.
+ * PageLayouts are used within {@link OO.ui.BookletLayout booklet layouts} to create pages that
+ * users can select and display from the booklet's optional
+ * {@link OO.ui.OutlineSelectWidget outline} navigation. Pages are usually not instantiated
+ * directly, rather extended to include the required content and functionality.
  *
- * Each page must have a unique symbolic name, which is passed to the constructor. In addition, the page's outline
- * item is customized (with a label, outline level, etc.) using the #setupOutlineItem method. See
- * {@link OO.ui.BookletLayout BookletLayout} for an example.
+ * Each page must have a unique symbolic name, which is passed to the constructor. In addition, the
+ * page's outline item is customized (with a label, outline level, etc.) using the
+ * #setupOutlineItem method. See {@link OO.ui.BookletLayout BookletLayout} for an example.
  *
  * @class
  * @extends OO.ui.PanelLayout
@@ -1191,8 +1205,9 @@ OO.ui.PageLayout.prototype.getName = function () {
 /**
  * Check if page is active.
  *
- * Pages become active when they are shown in a {@link OO.ui.BookletLayout booklet layout} that is configured to display
- * only one page at a time. Additional CSS is applied to the page's outline item to reflect the active state.
+ * Pages become active when they are shown in a {@link OO.ui.BookletLayout booklet layout} that is
+ * configured to display only one page at a time. Additional CSS is applied to the page's outline
+ * item to reflect the active state.
  *
  * @return {boolean} Page is active
  */
@@ -1204,7 +1219,8 @@ OO.ui.PageLayout.prototype.isActive = function () {
  * Get outline item.
  *
  * The outline item allows users to access the page from the booklet's outline
- * navigation. The outline item itself can be customized (with a label, level, etc.) using the #setupOutlineItem method.
+ * navigation. The outline item itself can be customized (with a label, level, etc.) using the
+ * #setupOutlineItem method.
  *
  * @return {OO.ui.OutlineOptionWidget|null} Outline option widget
  */
@@ -1216,8 +1232,8 @@ OO.ui.PageLayout.prototype.getOutlineItem = function () {
  * Set or unset the outline item.
  *
  * Specify an {@link OO.ui.OutlineOptionWidget outline option} to set it,
- * or `null` to clear the outline item. To customize the outline item itself (e.g., to set a label or outline
- * level), use #setupOutlineItem instead of this method.
+ * or `null` to clear the outline item. To customize the outline item itself (e.g., to set a label
+ * or outline level), use #setupOutlineItem instead of this method.
  *
  * @param {OO.ui.OutlineOptionWidget|null} outlineItem Outline option widget, null to clear
  * @chainable
@@ -1234,9 +1250,9 @@ OO.ui.PageLayout.prototype.setOutlineItem = function ( outlineItem ) {
 /**
  * Set up the outline item.
  *
- * Use this method to customize the outline item (e.g., to add a label or outline level). To set or unset
- * the outline item itself (with an {@link OO.ui.OutlineOptionWidget outline option} or `null`), use
- * the #setOutlineItem method instead.
+ * Use this method to customize the outline item (e.g., to add a label or outline level). To set or
+ * unset the outline item itself (with an {@link OO.ui.OutlineOptionWidget outline option} or
+ * `null`), use the #setOutlineItem method instead.
  *
  * @param {OO.ui.OutlineOptionWidget} outlineItem Outline option widget to set up
  * @chainable
@@ -1249,9 +1265,9 @@ OO.ui.PageLayout.prototype.setupOutlineItem = function () {
 /**
  * Set the page to its 'active' state.
  *
- * Pages become active when they are shown in a booklet layout that is configured to display only one page at a time. Additional
- * CSS is applied to the outline item to reflect the page's active state. Outside of the booklet
- * context, setting the active state on a page does nothing.
+ * Pages become active when they are shown in a booklet layout that is configured to display only
+ * one page at a time. Additional CSS is applied to the outline item to reflect the page's active
+ * state. Outside of the booklet context, setting the active state on a page does nothing.
  *
  * @param {boolean} active Page is active
  * @fires active
@@ -1267,9 +1283,9 @@ OO.ui.PageLayout.prototype.setActive = function ( active ) {
 };
 
 /**
- * StackLayouts contain a series of {@link OO.ui.PanelLayout panel layouts}. By default, only one panel is displayed
- * at a time, though the stack layout can also be configured to show all contained panels, one after another,
- * by setting the #continuous option to 'true'.
+ * StackLayouts contain a series of {@link OO.ui.PanelLayout panel layouts}. By default, only one
+ * panel is displayed at a time, though the stack layout can also be configured to show all
+ * contained panels, one after another, by setting the #continuous option to 'true'.
  *
  *     @example
  *     // A stack layout with two panels, configured to be displayed continuously
@@ -1296,7 +1312,8 @@ OO.ui.PageLayout.prototype.setActive = function ( active ) {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel is displayed at a time.
+ * @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel
+ *  is displayed at a time.
  * @cfg {OO.ui.Layout[]} [items] Panel layouts to add to the stack layout.
  */
 OO.ui.StackLayout = function OoUiStackLayout( config ) {
@@ -1309,7 +1326,7 @@ OO.ui.StackLayout = function OoUiStackLayout( config ) {
        OO.ui.StackLayout.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+       OO.ui.mixin.GroupElement.call( this, $.extend( { $group: this.$element }, config ) );
 
        // Properties
        this.currentItem = null;
@@ -1430,9 +1447,9 @@ OO.ui.StackLayout.prototype.unsetCurrentItem = function () {
 /**
  * Add panel layouts to the stack layout.
  *
- * Panels will be added to the end of the stack layout array unless the optional index parameter specifies a different
- * insertion point. Adding a panel that is already in the stack will move it to the end of the array or the point specified
- * by the index.
+ * Panels will be added to the end of the stack layout array unless the optional index parameter
+ * specifies a different insertion point. Adding a panel that is already in the stack will move it
+ * to the end of the array or the point specified by the index.
  *
  * @param {OO.ui.Layout[]} items Panels to add
  * @param {number} [index] Index of the insertion point
@@ -1456,8 +1473,8 @@ OO.ui.StackLayout.prototype.addItems = function ( items, index ) {
 /**
  * Remove the specified panels from the stack layout.
  *
- * Removed panels are detached from the DOM, not removed, so that they may be reused. To remove all panels,
- * you may wish to use the #clearItems method instead.
+ * Removed panels are detached from the DOM, not removed, so that they may be reused. To remove all
+ * panels, you may wish to use the #clearItems method instead.
  *
  * @param {OO.ui.Layout[]} items Panels to remove
  * @chainable
@@ -1573,13 +1590,22 @@ OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem )
 };
 
 /**
- * MenuLayouts combine a menu and a content {@link OO.ui.PanelLayout panel}. The menu is positioned relative to the content (after, before, top, or bottom)
- * and its size is customized with the #menuSize config. The content area will fill all remaining space.
+ * MenuLayouts combine a menu and a content {@link OO.ui.PanelLayout panel}. The menu is positioned
+ * relative to the content (after, before, top, or bottom) and its size is customized with the
+ * #menuSize config. The content area will fill all remaining space.
  *
  *     @example
  *     var menuLayout,
- *         menuPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),
- *         contentPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),
+ *         menuPanel = new OO.ui.PanelLayout( {
+ *             padded: true,
+ *             expanded: true,
+ *             scrollable: true
+ *         } ),
+ *         contentPanel = new OO.ui.PanelLayout( {
+ *             padded: true,
+ *             expanded: true,
+ *             scrollable: true
+ *         } ),
  *         select = new OO.ui.SelectWidget( {
  *             items: [
  *                 new OO.ui.OptionWidget( {
@@ -1607,12 +1633,16 @@ OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem )
  *         position: 'top',
  *         menuPanel: menuPanel,
  *         contentPanel: contentPanel
- *     } )
+ *     } );
  *     menuLayout.$menu.append(
  *         menuPanel.$element.append( '<b>Menu panel</b>', select.$element )
  *     );
  *     menuLayout.$content.append(
- *         contentPanel.$element.append( '<b>Content panel</b>', '<p>Note that the menu is positioned relative to the content panel: top, bottom, after, before.</p>')
+ *         contentPanel.$element.append(
+ *             '<b>Content panel</b>',
+ *             '<p>Note that the menu is positioned relative to the content panel: ' +
+ *             'top, bottom, after, before.</p>'
+ *          )
  *     );
  *     $( document.body ).append( menuLayout.$element );
  *
@@ -1672,11 +1702,9 @@ OO.ui.MenuLayout = function OoUiMenuLayout( config ) {
        this.$content = $( '<div>' );
 
        // Initialization
-       this.$menu
-               .addClass( 'oo-ui-menuLayout-menu' );
+       this.$menu.addClass( 'oo-ui-menuLayout-menu' );
        this.$content.addClass( 'oo-ui-menuLayout-content' );
-       this.$element
-               .addClass( 'oo-ui-menuLayout' );
+       this.$element.addClass( 'oo-ui-menuLayout' );
        if ( config.expanded ) {
                this.$element.addClass( 'oo-ui-menuLayout-expanded' );
        } else {
@@ -1732,11 +1760,14 @@ OO.ui.MenuLayout.prototype.isMenuVisible = function () {
  * Set menu position.
  *
  * @param {string} position Position of menu, either `top`, `after`, `bottom` or `before`
- * @throws {Error} If position value is not supported
  * @chainable
  * @return {OO.ui.MenuLayout} The layout, for chaining
  */
 OO.ui.MenuLayout.prototype.setMenuPosition = function ( position ) {
+       if ( [ 'top', 'bottom', 'before', 'after' ].indexOf( position ) === -1 ) {
+               position = 'before';
+       }
+
        this.$element.removeClass( 'oo-ui-menuLayout-' + this.menuPosition );
        this.menuPosition = position;
        if ( this.menuPosition === 'top' || this.menuPosition === 'before' ) {
@@ -1824,7 +1855,8 @@ OO.ui.MenuLayout.prototype.resetScroll = function () {
  *
  *     function PageOneLayout( name, config ) {
  *         PageOneLayout.parent.call( this, name, config );
- *         this.$element.append( '<p>First page</p><p>(This booklet has an outline, displayed on the left)</p>' );
+ *         this.$element.append( '<p>First page</p><p>(This booklet has an outline, displayed on ' +
+ *         'the left)</p>' );
  *     }
  *     OO.inheritClass( PageOneLayout, OO.ui.PageLayout );
  *     PageOneLayout.prototype.setupOutlineItem = function () {
@@ -1856,9 +1888,11 @@ OO.ui.MenuLayout.prototype.resetScroll = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {boolean} [continuous=false] Show all pages, one after another
- * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is displayed. Disabled on mobile.
- * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the pages of the booklet.
- * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages
+ * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is
+ *  displayed. Disabled on mobile.
+ * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the
+ *  pages of the booklet.
+ * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages.
  */
 OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
        // Configuration initialization
@@ -1898,11 +1932,17 @@ OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
        this.toggleMenu( this.outlined );
 
        // Events
-       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
+       this.stackLayout.connect( this, {
+               set: 'onStackLayoutSet'
+       } );
        if ( this.outlined ) {
-               this.outlineSelectWidget.connect( this, { select: 'onOutlineSelectWidgetSelect' } );
+               this.outlineSelectWidget.connect( this, {
+                       select: 'onOutlineSelectWidgetSelect'
+               } );
                this.scrolling = false;
-               this.stackLayout.connect( this, { visibleItemChange: 'onStackLayoutVisibleItemChange' } );
+               this.stackLayout.connect( this, {
+                       visibleItemChange: 'onStackLayoutVisibleItemChange'
+               } );
        }
        if ( this.autoFocus ) {
                // Event 'focus' does not bubble, but 'focusin' does
@@ -1931,7 +1971,8 @@ OO.inheritClass( OO.ui.BookletLayout, OO.ui.MenuLayout );
 /* Events */
 
 /**
- * A 'set' event is emitted when a page is {@link #setPage set} to be displayed by the booklet layout.
+ * A 'set' event is emitted when a page is {@link #setPage set} to be displayed by the
+ * booklet layout.
  * @event set
  * @param {OO.ui.PageLayout} page Current page
  */
@@ -2110,8 +2151,9 @@ OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
                this.outlineVisible = show;
                this.toggleMenu( show );
                if ( show && this.editable ) {
-                       // HACK: Kill dumb scrollbars when the sidebar stops animating, see T161798. Only necessary when
-                       // outline controls are present, delay matches transition on `.oo-ui-menuLayout-menu`.
+                       // HACK: Kill dumb scrollbars when the sidebar stops animating, see T161798.
+                       // Only necessary when outline controls are present, delay matches transition on
+                       // `.oo-ui-menuLayout-menu`.
                        setTimeout( function () {
                                OO.ui.Element.static.reconsiderScrollbars( booklet.outlinePanel.$element[ 0 ] );
                        }, OO.ui.theme.getDialogTransitionDuration() );
@@ -2348,9 +2390,10 @@ OO.ui.BookletLayout.prototype.setPage = function ( name ) {
                        if ( previousPage ) {
                                previousPage.setActive( false );
                                // Blur anything focused if the next page doesn't have anything focusable.
-                               // This is not needed if the next page has something focusable (because once it is focused
-                               // this blur happens automatically). If the layout is non-continuous, this check is
-                               // meaningless because the next page is not visible yet and thus can't hold focus.
+                               // This is not needed if the next page has something focusable (because once it is
+                               // focused this blur happens automatically). If the layout is non-continuous, this
+                               // check is meaningless because the next page is not visible yet and thus can't
+                               // hold focus.
                                if (
                                        this.autoFocus &&
                                        !OO.ui.isMobile() &&
@@ -2367,8 +2410,9 @@ OO.ui.BookletLayout.prototype.setPage = function ( name ) {
                        page.setActive( true );
                        this.stackLayout.setItem( page );
                        if ( !this.stackLayout.continuous && previousPage ) {
-                               // This should not be necessary, since any inputs on the previous page should have been
-                               // blurred when it was hidden, but browsers are not very consistent about this.
+                               // This should not be necessary, since any inputs on the previous page should have
+                               // been blurred when it was hidden, but browsers are not very consistent about
+                               // this.
                                $focused = previousPage.$element.find( ':focus' );
                                if ( $focused.length ) {
                                        $focused[ 0 ].blur();
@@ -2388,7 +2432,11 @@ OO.ui.BookletLayout.prototype.resetScroll = function () {
        // Parent method
        OO.ui.BookletLayout.parent.prototype.resetScroll.call( this );
 
-       if ( this.outlined && this.stackLayout.continuous && this.outlineSelectWidget.findFirstSelectableItem() ) {
+       if (
+               this.outlined &&
+               this.stackLayout.continuous &&
+               this.outlineSelectWidget.findFirstSelectableItem()
+       ) {
                this.scrolling = true;
                this.outlineSelectWidget.selectItem( this.outlineSelectWidget.findFirstSelectableItem() );
                this.scrolling = false;
@@ -2412,10 +2460,10 @@ OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
 
 /**
  * IndexLayouts contain {@link OO.ui.TabPanelLayout tab panel layouts} as well as
- * {@link OO.ui.TabSelectWidget tabs} that allow users to easily navigate through the tab panels and
- * select which one to display. By default, only one tab panel is displayed at a time. When a user
- * navigates to a new tab panel, the index layout automatically focuses on the first focusable element,
- * unless the default setting is changed.
+ * {@link OO.ui.TabSelectWidget tabs} that allow users to easily navigate through the tab panels
+ * and select which one to display. By default, only one tab panel is displayed at a time. When a
+ * user navigates to a new tab panel, the index layout automatically focuses on the first focusable
+ * element, unless the default setting is changed.
  *
  * TODO: This class is similar to BookletLayout, we may want to refactor to reduce duplication
  *
@@ -2446,8 +2494,10 @@ OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.StackLayout} [contentPanel] Content stack (see MenuLayout)
  * @cfg {boolean} [continuous=false] Show all tab panels, one after another
- * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new tab panel is displayed. Disabled on mobile.
+ * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new tab panel is
+ *  displayed. Disabled on mobile.
  */
 OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
        // Configuration initialization
@@ -2458,18 +2508,20 @@ OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
 
        // Properties
        this.currentTabPanelName = null;
-       this.tabPanels = {};
+       // Allow infused widgets to pass existing tabPanels
+       this.tabPanels = config.tabPanels || {};
 
        this.ignoreFocus = false;
-       this.stackLayout = new OO.ui.StackLayout( {
+       this.stackLayout = this.contentPanel || new OO.ui.StackLayout( {
                continuous: !!config.continuous,
                expanded: this.expanded
        } );
        this.setContentPanel( this.stackLayout );
        this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
 
-       this.tabSelectWidget = new OO.ui.TabSelectWidget();
-       this.tabPanel = new OO.ui.PanelLayout( {
+       // Allow infused widgets to pass an existing tabSelectWidget
+       this.tabSelectWidget = config.tabSelectWidget || new OO.ui.TabSelectWidget();
+       this.tabPanel = this.menuPanel || new OO.ui.PanelLayout( {
                expanded: this.expanded
        } );
        this.setMenuPanel( this.tabPanel );
@@ -2477,10 +2529,14 @@ OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
        this.toggleMenu( true );
 
        // Events
-       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
-       this.tabSelectWidget.connect( this, { select: 'onTabSelectWidgetSelect' } );
+       this.stackLayout.connect( this, {
+               set: 'onStackLayoutSet'
+       } );
+       this.tabSelectWidget.connect( this, {
+               select: 'onTabSelectWidgetSelect'
+       } );
        if ( this.autoFocus ) {
-               // Event 'focus' does not bubble, but 'focusin' does
+               // Event 'focus' does not bubble, but 'focusin' does.
                this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
        }
 
@@ -2490,6 +2546,8 @@ OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
        this.tabPanel.$element
                .addClass( 'oo-ui-indexLayout-tabPanel' )
                .append( this.tabSelectWidget.$element );
+
+       this.selectFirstSelectableTabPanel();
 };
 
 /* Setup */
@@ -2499,7 +2557,9 @@ OO.inheritClass( OO.ui.IndexLayout, OO.ui.MenuLayout );
 /* Events */
 
 /**
- * A 'set' event is emitted when a tab panel is {@link #setTabPanel set} to be displayed by the index layout.
+ * A 'set' event is emitted when a tab panel is {@link #setTabPanel set} to be displayed by the
+ * index layout.
+ *
  * @event set
  * @param {OO.ui.TabPanelLayout} tabPanel Current tab panel
  */
@@ -2535,7 +2595,8 @@ OO.ui.IndexLayout.prototype.onStackLayoutFocus = function ( e ) {
        $target = $( e.target ).closest( '.oo-ui-tabPanelLayout' );
        for ( name in this.tabPanels ) {
                // Check for tab panel match, exclude current tab panel to find only tab panel changes
-               if ( this.tabPanels[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentTabPanelName ) {
+               if ( this.tabPanels[ name ].$element[ 0 ] === $target[ 0 ] &&
+                               name !== this.currentTabPanelName ) {
                        this.setTabPanel( name );
                        break;
                }
@@ -2585,7 +2646,11 @@ OO.ui.IndexLayout.prototype.focus = function ( itemIndex ) {
                return;
        }
        // Only change the focus if is not already in the current page
-       if ( !OO.ui.contains( tabPanel.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {
+       if ( !OO.ui.contains(
+               tabPanel.$element[ 0 ],
+               this.getElementDocument().activeElement,
+               true
+       ) ) {
                tabPanel.focus();
        }
 };
@@ -2681,7 +2746,7 @@ OO.ui.IndexLayout.prototype.getCurrentTabPanelName = function () {
 };
 
 /**
- * Add tab panels to the index layout
+ * Add tab panels to the index layout.
  *
  * When tab panels are added with the same names as existing tab panels, the existing tab panels
  * will be automatically removed before the new tab panels are added.
@@ -2815,9 +2880,10 @@ OO.ui.IndexLayout.prototype.setTabPanel = function ( name ) {
                        if ( previousTabPanel ) {
                                previousTabPanel.setActive( false );
                                // Blur anything focused if the next tab panel doesn't have anything focusable.
-                               // This is not needed if the next tab panel has something focusable (because once it is focused
-                               // this blur happens automatically). If the layout is non-continuous, this check is
-                               // meaningless because the next tab panel is not visible yet and thus can't hold focus.
+                               // This is not needed if the next tab panel has something focusable (because once
+                               // it is focused this blur happens automatically). If the layout is non-continuous,
+                               // this check is meaningless because the next tab panel is not visible yet and thus
+                               // can't hold focus.
                                if (
                                        this.autoFocus &&
                                        !OO.ui.isMobile() &&
@@ -2834,8 +2900,9 @@ OO.ui.IndexLayout.prototype.setTabPanel = function ( name ) {
                        tabPanel.setActive( true );
                        this.stackLayout.setItem( tabPanel );
                        if ( !this.stackLayout.continuous && previousTabPanel ) {
-                               // This should not be necessary, since any inputs on the previous tab panel should have been
-                               // blurred when it was hidden, but browsers are not very consistent about this.
+                               // This should not be necessary, since any inputs on the previous tab panel should
+                               // have been blurred when it was hidden, but browsers are not very consistent about
+                               // this.
                                $focused = previousTabPanel.$element.find( ':focus' );
                                if ( $focused.length ) {
                                        $focused[ 0 ].blur();
@@ -2940,7 +3007,8 @@ OO.ui.ToggleWidget.prototype.setValue = function ( value ) {
 /**
  * ToggleButtons are buttons that have a state (‘on’ or ‘off’) that is represented by a
  * Boolean value. Like other {@link OO.ui.ButtonWidget buttons}, toggle buttons can be
- * configured with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators},
+ * configured with {@link OO.ui.mixin.IconElement icons},
+ * {@link OO.ui.mixin.IndicatorElement indicators},
  * {@link OO.ui.mixin.TitledElement titles}, {@link OO.ui.mixin.FlaggedElement styling flags},
  * and {@link OO.ui.mixin.LabelElement labels}. Please see
  * the [OOUI documentation][1] on MediaWiki for more information.
@@ -2981,15 +3049,21 @@ OO.ui.ToggleButtonWidget = function OoUiToggleButtonWidget( config ) {
        OO.ui.ToggleButtonWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.ButtonElement.call( this, $.extend( {}, config, { active: this.active } ) );
+       OO.ui.mixin.ButtonElement.call( this, $.extend( {
+               active: this.active
+       }, config ) );
        OO.ui.mixin.IconElement.call( this, config );
        OO.ui.mixin.IndicatorElement.call( this, config );
        OO.ui.mixin.LabelElement.call( this, config );
        OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {
+               $tabIndexed: this.$button
+       }, config ) );
 
        // Events
-       this.connect( this, { click: 'onAction' } );
+       this.connect( this, {
+               click: 'onAction'
+       } );
 
        // Initialization
        this.$button.append( this.$icon, this.$label, this.$indicator );
@@ -3178,7 +3252,8 @@ OO.ui.ToggleSwitchWidget.prototype.simulateLabelClick = function () {
 };
 
 /**
- * OutlineControlsWidget is a set of controls for an {@link OO.ui.OutlineSelectWidget outline select widget}.
+ * OutlineControlsWidget is a set of controls for an
+ * {@link OO.ui.OutlineSelectWidget outline select widget}.
  * Controls include moving items up and down, removing items, and adding different kinds of items.
  *
  * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**
@@ -3236,9 +3311,15 @@ OO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, confi
                add: 'onOutlineChange',
                remove: 'onOutlineChange'
        } );
-       this.upButton.connect( this, { click: [ 'emit', 'move', -1 ] } );
-       this.downButton.connect( this, { click: [ 'emit', 'move', 1 ] } );
-       this.removeButton.connect( this, { click: [ 'emit', 'remove' ] } );
+       this.upButton.connect( this, {
+               click: [ 'emit', 'move', -1 ]
+       } );
+       this.downButton.connect( this, {
+               click: [ 'emit', 'move', 1 ]
+       } );
+       this.removeButton.connect( this, {
+               click: [ 'emit', 'remove' ]
+       } );
 
        // Initialization
        this.$element.addClass( 'oo-ui-outlineControlsWidget' );
@@ -3334,7 +3415,8 @@ OO.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {number} [level] Indentation level
- * @cfg {boolean} [movable] Allow modification from {@link OO.ui.OutlineControlsWidget outline controls}.
+ * @cfg {boolean} [movable] Allow modification from
+ *  {@link OO.ui.OutlineControlsWidget outline controls}.
  */
 OO.ui.OutlineOptionWidget = function OoUiOutlineOptionWidget( config ) {
        // Configuration initialization
@@ -3490,8 +3572,10 @@ OO.ui.OutlineOptionWidget.prototype.setLevel = function ( level ) {
 };
 
 /**
- * OutlineSelectWidget is a structured list that contains {@link OO.ui.OutlineOptionWidget outline options}
- * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls} widget.
+ * OutlineSelectWidget is a structured list that contains
+ * {@link OO.ui.OutlineOptionWidget outline options}
+ * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls}
+ * widget.
  *
  * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**
  *
@@ -3775,8 +3859,9 @@ OO.ui.TagItemWidget = function OoUiTagItemWidget( config ) {
        this.closeButton.setDisabled( this.isDisabled() );
 
        // Events
-       this.closeButton
-               .connect( this, { click: 'remove' } );
+       this.closeButton.connect( this, {
+               click: 'remove'
+       } );
        this.$element
                .on( 'click', this.select.bind( this ) )
                .on( 'keydown', this.onKeyDown.bind( this ) )
@@ -3934,7 +4019,11 @@ OO.ui.TagItemWidget.prototype.remove = function () {
 OO.ui.TagItemWidget.prototype.onKeyDown = function ( e ) {
        var movement;
 
-       if ( !this.isDisabled() && !this.isFixed() && ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE ) ) {
+       if (
+               !this.isDisabled() &&
+               !this.isFixed() &&
+               ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE )
+       ) {
                this.remove();
                return false;
        } else if ( e.keyCode === OO.ui.Keys.ENTER ) {
@@ -4004,12 +4093,13 @@ OO.ui.TagItemWidget.prototype.isValid = function () {
 };
 
 /**
- * A basic tag multiselect widget, similar in concept to {@link OO.ui.ComboBoxInputWidget combo box widget}
- * that allows the user to add multiple values that are displayed in a tag area.
+ * A basic tag multiselect widget, similar in concept to
+ * {@link OO.ui.ComboBoxInputWidget combo box widget} that allows the user to add multiple values
+ * that are displayed in a tag area.
  *
- * This widget is a base widget; see {@link OO.ui.MenuTagMultiselectWidget MenuTagMultiselectWidget} and
- * {@link OO.ui.PopupTagMultiselectWidget PopupTagMultiselectWidget} for the implementations that use
- * a menu and a popup respectively.
+ * This widget is a base widget; see {@link OO.ui.MenuTagMultiselectWidget MenuTagMultiselectWidget}
+ * and {@link OO.ui.PopupTagMultiselectWidget PopupTagMultiselectWidget} for the implementations
+ * that use a menu and a popup respectively.
  *
  *     @example
  *     // A TagMultiselectWidget.
@@ -4064,8 +4154,7 @@ OO.ui.TagMultiselectWidget = function OoUiTagMultiselectWidget( config ) {
        var inputEvents,
                rAF = window.requestAnimationFrame || setTimeout,
                widget = this,
-               $tabFocus = $( '<span>' )
-                       .addClass( 'oo-ui-tagMultiselectWidget-focusTrap' );
+               $tabFocus = $( '<span>' ).addClass( 'oo-ui-tagMultiselectWidget-focusTrap' );
 
        config = config || {};
 
@@ -4099,8 +4188,7 @@ OO.ui.TagMultiselectWidget = function OoUiTagMultiselectWidget( config ) {
        this.height = null;
        this.valid = true;
 
-       this.$content = $( '<div>' )
-               .addClass( 'oo-ui-tagMultiselectWidget-content' );
+       this.$content = $( '<div>' ).addClass( 'oo-ui-tagMultiselectWidget-content' );
        this.$handle = $( '<div>' )
                .addClass( 'oo-ui-tagMultiselectWidget-handle' )
                .append(
@@ -4108,8 +4196,7 @@ OO.ui.TagMultiselectWidget = function OoUiTagMultiselectWidget( config ) {
                        this.$icon,
                        this.$content
                                .append(
-                                       this.$group
-                                               .addClass( 'oo-ui-tagMultiselectWidget-group' )
+                                       this.$group.addClass( 'oo-ui-tagMultiselectWidget-group' )
                                )
                );
 
@@ -4295,7 +4382,7 @@ OO.ui.TagMultiselectWidget.prototype.onInputKeyDown = function ( e ) {
                };
 
        if ( !this.isDisabled() ) {
-               // 'keypress' event is not triggered for Backspace
+               // 'keypress' event is not triggered for Backspace key
                if ( e.keyCode === OO.ui.Keys.BACKSPACE ) {
                        return this.doInputBackspace( e, withMetaKey );
                } else if ( e.keyCode === OO.ui.Keys.ESCAPE ) {
@@ -4346,11 +4433,11 @@ OO.ui.TagMultiselectWidget.prototype.onInputBlur = function () {
 };
 
 /**
- * Perform an action after the enter key on the input
+ * Perform an action after the Enter key on the input
  *
  * @param {jQuery.Event} e Event data
  * @param {boolean} [withMetaKey] Whether this key was pressed with
- * a meta key like 'ctrl'
+ * a meta key like Control
  * @return {boolean} Whether to prevent defaults
  */
 OO.ui.TagMultiselectWidget.prototype.doInputEnter = function () {
@@ -4359,11 +4446,11 @@ OO.ui.TagMultiselectWidget.prototype.doInputEnter = function () {
 };
 
 /**
- * Perform an action responding to the enter key on the input
+ * Perform an action responding to the Enter key on the input
  *
  * @param {jQuery.Event} e Event data
  * @param {boolean} [withMetaKey] Whether this key was pressed with
- * a meta key like 'ctrl'
+ * a meta key like Control
  * @return {boolean} Whether to prevent defaults
  */
 OO.ui.TagMultiselectWidget.prototype.doInputBackspace = function ( e, withMetaKey ) {
@@ -4392,7 +4479,7 @@ OO.ui.TagMultiselectWidget.prototype.doInputBackspace = function ( e, withMetaKe
 };
 
 /**
- * Perform an action after the escape key on the input
+ * Perform an action after the Escape key on the input
  *
  * @param {jQuery.Event} e Event data
  */
@@ -4401,14 +4488,14 @@ OO.ui.TagMultiselectWidget.prototype.doInputEscape = function () {
 };
 
 /**
- * Perform an action after the arrow key on the input, select the previous
+ * Perform an action after the Left/Right arrow key on the input, select the previous
  * item from the input.
  * See #getPreviousItem
  *
  * @param {jQuery.Event} e Event data
  * @param {string} direction Direction of the movement; forwards or backwards
  * @param {boolean} [withMetaKey] Whether this key was pressed with
- *  a meta key like 'ctrl'
+ *  a meta key like Control
  */
 OO.ui.TagMultiselectWidget.prototype.doInputArrow = function ( e, direction ) {
        if (
@@ -4432,7 +4519,7 @@ OO.ui.TagMultiselectWidget.prototype.onTagSelect = function ( item ) {
                        this.addTagFromInput();
                }
                // 1. Get the label of the tag into the input
-               this.input.setValue( item.getData() );
+               this.input.setValue( item.getLabel() );
                // 2. Remove the tag
                this.removeItems( [ item ] );
                // 3. Focus the input
@@ -4836,8 +4923,8 @@ OO.ui.TagMultiselectWidget.prototype.updateInputSize = function () {
                                $lastItem.position().left;
                }
 
-               // Some safety margin for sanity, because I *really* don't feel like finding out where the few
-               // pixels this is off by are coming from.
+               // Some safety margin for sanity, because I *really* don't feel like finding out where the
+               // few pixels this is off by are coming from.
                bestWidth -= 13;
                if ( contentWidth > bestWidth ) {
                        // This will result in the input getting shifted to the next line
@@ -4906,8 +4993,9 @@ OO.ui.TagMultiselectWidget.prototype.isValid = function () {
 };
 
 /**
- * PopupTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget} intended
- * to use a popup. The popup can be configured to have a default input to insert values into the widget.
+ * PopupTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget}
+ * intended to use a popup. The popup can be configured to have a default input to insert values
+ * into the widget.
  *
  *     @example
  *     // A PopupTagMultiselectWidget.
@@ -4944,9 +5032,12 @@ OO.ui.PopupTagMultiselectWidget = function OoUiPopupTagMultiselectWidget( config
        config = config || {};
 
        // Parent constructor
-       OO.ui.PopupTagMultiselectWidget.parent.call( this, $.extend( { inputPosition: 'none' }, config ) );
+       OO.ui.PopupTagMultiselectWidget.parent.call( this, $.extend( {
+               inputPosition: 'none'
+       }, config ) );
 
-       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
+       this.$overlay = ( config.$overlay === true ?
+               OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
 
        if ( !config.popup ) {
                // For the default base implementation, we give a popup
@@ -4987,9 +5078,10 @@ OO.ui.PopupTagMultiselectWidget = function OoUiPopupTagMultiselectWidget( config
 
        // Events
        this.on( 'resize', this.popup.updateDimensions.bind( this.popup ) );
-       this.popup.connect( this, { toggle: 'onPopupToggle' } );
-       this.$tabIndexed
-               .on( 'focus', this.onFocus.bind( this ) );
+       this.popup.connect( this, {
+               toggle: 'onPopupToggle'
+       } );
+       this.$tabIndexed.on( 'focus', this.onFocus.bind( this ) );
 
        // Initialize
        this.$element
@@ -5067,8 +5159,8 @@ OO.ui.PopupTagMultiselectWidget.prototype.addTagByPopupValue = function ( data,
 };
 
 /**
- * MenuTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget} intended
- * to use a menu of selectable options.
+ * MenuTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget}
+ * intended to use a menu of selectable options.
  *
  *     @example
  *     // A basic MenuTagMultiselectWidget.
@@ -5095,20 +5187,30 @@ OO.ui.PopupTagMultiselectWidget.prototype.addTagByPopupValue = function ( data,
  * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
  */
 OO.ui.MenuTagMultiselectWidget = function OoUiMenuTagMultiselectWidget( config ) {
+       var $autoCloseIgnore = $( [] );
        config = config || {};
 
        // Parent constructor
        OO.ui.MenuTagMultiselectWidget.parent.call( this, config );
 
-       this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
-       this.clearInputOnChoose = config.clearInputOnChoose === undefined || !!config.clearInputOnChoose;
+       $autoCloseIgnore = $autoCloseIgnore.add( this.$group );
+       if ( this.hasInput ) {
+               $autoCloseIgnore = $autoCloseIgnore.add( this.input.$element );
+       }
+
+       this.$overlay = ( config.$overlay === true ?
+               OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
+       this.clearInputOnChoose = config.clearInputOnChoose === undefined ||
+               !!config.clearInputOnChoose;
        this.menu = this.createMenuWidget( $.extend( {
                widget: this,
+               hideOnChoose: false,
                input: this.hasInput ? this.input : null,
                $input: this.hasInput ? this.input.$input : null,
                filterFromInput: !!this.hasInput,
-               $autoCloseIgnore: this.hasInput ?
-                       this.input.$element : $( [] ),
+               highlightOnFilter: !this.allowArbitrary,
+               multiselect: true,
+               $autoCloseIgnore: $autoCloseIgnore,
                $floatableContainer: this.hasInput && this.inputPosition === 'outline' ?
                        this.input.$element : this.$element,
                $overlay: this.$overlay,
@@ -5122,20 +5224,22 @@ OO.ui.MenuTagMultiselectWidget = function OoUiMenuTagMultiselectWidget( config )
                toggle: 'onMenuToggle'
        } );
        if ( this.hasInput ) {
-               this.input.connect( this, { change: 'onInputChange' } );
+               this.input.connect( this, {
+                       change: 'onInputChange'
+               } );
        }
-       this.connect( this, { resize: 'onResize' } );
+       this.connect( this, {
+               resize: 'onResize'
+       } );
 
        // Initialization
-       this.$overlay
-               .append( this.menu.$element );
-       this.$element
-               .addClass( 'oo-ui-menuTagMultiselectWidget' );
+       this.$overlay.append( this.menu.$element );
+       this.$element.addClass( 'oo-ui-menuTagMultiselectWidget' );
        // Remove MenuSelectWidget's generic focus owner ARIA attribute
        // TODO: Should this widget have a `role` that is compatible with this attribute?
        this.menu.$focusOwner.removeAttr( 'aria-expanded' );
-       // TagMultiselectWidget already does this, but it doesn't work right because this.menu is not yet
-       // set up while the parent constructor runs, and #getAllowedValues rejects everything.
+       // TagMultiselectWidget already does this, but it doesn't work right because this.menu is
+       // not yet set up while the parent constructor runs, and #getAllowedValues rejects everything.
        if ( config.selected ) {
                this.setValue( config.selected );
        }
@@ -5165,35 +5269,31 @@ OO.ui.MenuTagMultiselectWidget.prototype.onInputFocus = function () {
        this.menu.toggle( true );
 };
 
-/**
- * @inheritdoc
- */
-OO.ui.MenuTagMultiselectWidget.prototype.onInputBlur = function () {
-       // Parent method
-       OO.ui.MenuTagMultiselectWidget.parent.prototype.onInputBlur.call( this );
-
-       this.menu.toggle( false );
-};
-
 /**
  * Respond to input change event
  */
 OO.ui.MenuTagMultiselectWidget.prototype.onInputChange = function () {
        this.menu.toggle( true );
-       this.initializeMenuSelection();
 };
 
 /**
- * Respond to menu choose event
+ * Respond to menu choose event, which is intentional by the user.
  *
- * @param {OO.ui.OptionWidget} menuItem Chosen menu item
+ * @param {OO.ui.OptionWidget} menuItem Selected menu items
+ * @param {boolean} selected Item is selected
  */
-OO.ui.MenuTagMultiselectWidget.prototype.onMenuChoose = function ( menuItem ) {
+OO.ui.MenuTagMultiselectWidget.prototype.onMenuChoose = function ( menuItem, selected ) {
        if ( this.hasInput && this.clearInputOnChoose ) {
                this.input.setValue( '' );
        }
-       // Add tag
-       this.addTag( menuItem.getData(), menuItem.getLabel() );
+
+       if ( selected && !this.findItemFromData( menuItem.getData() ) ) {
+               // The menu item is selected, add it to the tags
+               this.addTag( menuItem.getData(), menuItem.getLabel() );
+       } else {
+               // The menu item was unselected, remove the tag
+               this.removeTagByData( menuItem.getData() );
+       }
 };
 
 /**
@@ -5203,10 +5303,8 @@ OO.ui.MenuTagMultiselectWidget.prototype.onMenuChoose = function ( menuItem ) {
  */
 OO.ui.MenuTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
        if ( !isVisible ) {
-               this.menu.selectItem( null );
                this.menu.highlightItem( null );
-       } else {
-               this.initializeMenuSelection();
+               this.menu.scrollToTop();
        }
        setTimeout( function () {
                // Remove MenuSelectWidget's generic focus owner ARIA attribute
@@ -5231,16 +5329,75 @@ OO.ui.MenuTagMultiselectWidget.prototype.onTagSelect = function ( tagItem ) {
                        this.input.setValue( '' );
                }
 
-               // Select the menu item
-               this.menu.selectItem( menuItem );
-
                this.focus();
+
+               // Highlight the menu item
+               this.menu.highlightItem( menuItem );
+               this.menu.scrollItemIntoView( menuItem );
+
        } else {
                // Use the default
                OO.ui.MenuTagMultiselectWidget.parent.prototype.onTagSelect.call( this, tagItem );
        }
 };
 
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.removeItems = function ( items ) {
+       var widget = this;
+
+       // Parent
+       OO.ui.MenuTagMultiselectWidget.parent.prototype.removeItems.call( this, items );
+
+       items.forEach( function ( tagItem ) {
+               var menuItem = widget.menu.findItemFromData( tagItem.getData() );
+               if ( menuItem ) {
+                       // Synchronize the menu selection - unselect the removed tag
+                       widget.menu.unselectItem( menuItem );
+               }
+       } );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuTagMultiselectWidget.prototype.setValue = function ( valueObject ) {
+       valueObject = Array.isArray( valueObject ) ? valueObject : [ valueObject ];
+
+       // We override this method from the parent, to make sure we are adding proper
+       // menu items, and are accounting for cases where we have this widget with
+       // a menu but also 'allowArbitrary'
+       if ( !this.menu ) {
+               return;
+       }
+
+       this.clearItems();
+       valueObject.forEach( function ( obj ) {
+               var data, label, menuItem;
+
+               if ( typeof obj === 'string' ) {
+                       data = label = obj;
+               } else {
+                       data = obj.data;
+                       label = obj.label;
+               }
+
+               // Check if the item is in the menu
+               menuItem = this.menu.getItemFromLabel( label ) || this.menu.findItemFromData( data );
+               if ( menuItem ) {
+                       // Menu item found, add the menu item
+                       this.addTag( menuItem.getData(), menuItem.getLabel() );
+                       // Make sure that item is also selected
+                       this.menu.selectItem( menuItem );
+               } else if ( this.allowArbitrary ) {
+                       // If the item isn't in the menu, only add it if we
+                       // allow for arbitrary values
+                       this.addTag( data, label );
+               }
+       }.bind( this ) );
+};
+
 /**
  * @inheritdoc
  */
@@ -5261,12 +5418,17 @@ OO.ui.MenuTagMultiselectWidget.prototype.setDisabled = function ( isDisabled ) {
  * @chainable
  */
 OO.ui.MenuTagMultiselectWidget.prototype.initializeMenuSelection = function () {
-       if ( !this.menu.findSelectedItem() ) {
-               this.menu.highlightItem(
-                       this.allowArbitrary ?
-                               null :
-                               this.menu.findFirstSelectableItem()
-               );
+       var highlightedItem;
+       this.menu.highlightItem(
+               this.allowArbitrary ?
+                       null :
+                       this.menu.findFirstSelectableItem()
+       );
+
+       highlightedItem = this.menu.findHighlightedItem();
+       // Scroll to the highlighted item, if it exists
+       if ( highlightedItem ) {
+               this.menu.scrollItemIntoView( highlightedItem );
        }
 };
 
@@ -5383,6 +5545,9 @@ OO.ui.MenuTagMultiselectWidget.prototype.getAllowedValues = function () {
  * OO.ui.mixin.IndicatorElement indicators} and {@link OO.ui.mixin.TitledElement titles}.
  * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.
  *
+ * Although SelectFileWidget inherits from SelectFileInputWidget, it does not
+ * behave as an InputWidget, and can't be used in HTML forms.
+ *
  *     @example
  *     // A file select widget.
  *     var selectFile = new OO.ui.SelectFileWidget();
@@ -5391,83 +5556,55 @@ OO.ui.MenuTagMultiselectWidget.prototype.getAllowedValues = function () {
  * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets
  *
  * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
+ * @extends OO.ui.SelectFileInputWidget
  * @mixins OO.ui.mixin.PendingElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.TitledElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {string[]|null} [accept=null] MIME types to accept. null accepts all types.
- * @cfg {string} [placeholder] Text to display when no file is selected.
  * @cfg {string} [notsupported] Text to display when file support is missing in the browser.
  * @cfg {boolean} [droppable=true] Whether to accept files by drag and drop.
- * @cfg {boolean} [showDropTarget=false] Whether to show a drop target. Requires droppable to be true.
+ * @cfg {boolean} [buttonOnly=false] Show only the select file button, no info field. Requires
+ *  showDropTarget to be false.
+ * @cfg {boolean} [showDropTarget=false] Whether to show a drop target. Requires droppable to be
+ *  true. Not yet supported in multiple file mode.
  * @cfg {number} [thumbnailSizeLimit=20] File size limit in MiB above which to not try and show a
- *  preview (for performance)
+ *  preview (for performance).
  */
 OO.ui.SelectFileWidget = function OoUiSelectFileWidget( config ) {
-       var dragHandler;
+       var dragHandler, droppable,
+               isSupported = this.constructor.static.isSupported();
 
        // Configuration initialization
        config = $.extend( {
-               accept: null,
-               placeholder: OO.ui.msg( 'ooui-selectfile-placeholder' ),
                notsupported: OO.ui.msg( 'ooui-selectfile-not-supported' ),
                droppable: true,
+               buttonOnly: false,
                showDropTarget: false,
                thumbnailSizeLimit: 20
        }, config );
 
+       if ( !isSupported ) {
+               config.disabled = true;
+       }
+
        // Parent constructor
        OO.ui.SelectFileWidget.parent.call( this, config );
 
        // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$info } ) );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, config );
+       OO.ui.mixin.PendingElement.call( this );
 
-       // Properties
-       this.$info = $( '<span>' );
-       this.showDropTarget = config.showDropTarget;
-       this.thumbnailSizeLimit = config.thumbnailSizeLimit;
-       this.isSupported = this.constructor.static.isSupported();
-       this.currentFile = null;
-       if ( Array.isArray( config.accept ) ) {
-               this.accept = config.accept;
-       } else {
-               this.accept = null;
+       if ( !isSupported ) {
+               this.info.setValue( config.notsupported );
        }
-       this.placeholder = config.placeholder;
-       this.notsupported = config.notsupported;
-       this.onFileSelectedHandler = this.onFileSelected.bind( this );
-
-       this.selectButton = new OO.ui.ButtonWidget( {
-               $element: $( '<label>' ),
-               classes: [ 'oo-ui-selectFileWidget-selectButton' ],
-               label: OO.ui.msg( 'ooui-selectfile-button-select' ),
-               disabled: this.disabled || !this.isSupported
-       } );
 
-       this.clearButton = new OO.ui.ButtonWidget( {
-               classes: [ 'oo-ui-selectFileWidget-clearButton' ],
-               framed: false,
-               icon: 'clear',
-               disabled: this.disabled
-       } );
+       // Properties
+       droppable = config.droppable && isSupported;
+       // TODO: Support drop target when multiple is set
+       this.showDropTarget = droppable && config.showDropTarget && !this.multiple;
+       this.thumbnailSizeLimit = config.thumbnailSizeLimit;
 
        // Events
-       this.selectButton.$button.on( {
-               keypress: this.onKeyPress.bind( this )
-       } );
-       this.clearButton.connect( this, {
-               click: 'onClearClick'
-       } );
-       if ( config.droppable ) {
+       if ( droppable ) {
                dragHandler = this.onDragEnterOrOver.bind( this );
                this.$element.on( {
                        dragenter: dragHandler,
@@ -5478,45 +5615,45 @@ OO.ui.SelectFileWidget = function OoUiSelectFileWidget( config ) {
        }
 
        // Initialization
-       this.addInput();
-       this.$label.addClass( 'oo-ui-selectFileWidget-label' );
-       this.$info
-               .addClass( 'oo-ui-selectFileWidget-info' )
-               .append( this.$icon, this.$label, this.clearButton.$element, this.$indicator );
-
-       if ( config.droppable && config.showDropTarget ) {
+       if ( this.showDropTarget ) {
                this.selectButton.setIcon( 'upload' );
                this.$thumbnail = $( '<div>' ).addClass( 'oo-ui-selectFileWidget-thumbnail' );
                this.setPendingElement( this.$thumbnail );
                this.$element
-                       .addClass( 'oo-ui-selectFileWidget-dropTarget oo-ui-selectFileWidget' )
+                       .addClass( 'oo-ui-selectFileWidget-dropTarget' )
                        .on( {
                                click: this.onDropTargetClick.bind( this )
                        } )
                        .append(
                                this.$thumbnail,
-                               this.$info,
+                               this.info.$element,
                                this.selectButton.$element,
                                $( '<span>' )
                                        .addClass( 'oo-ui-selectFileWidget-dropLabel' )
                                        .text( OO.ui.msg( 'ooui-selectfile-dragdrop-placeholder' ) )
                        );
-       } else {
-               this.$element
-                       .addClass( 'oo-ui-selectFileWidget' )
-                       .append( this.$info, this.selectButton.$element );
+               this.fieldLayout.$element.remove();
+       } else if ( config.buttonOnly ) {
+               this.$element.append( this.selectButton.$element );
+               this.fieldLayout.$element.remove();
        }
+
+       this.$input
+               .on( 'click', function ( e ) {
+                       // Prevents dropTarget to get clicked which calls
+                       // a click on this input
+                       e.stopPropagation();
+               } );
+
+       this.$element.addClass( 'oo-ui-selectFileWidget' );
+
        this.updateUI();
 };
 
 /* Setup */
 
-OO.inheritClass( OO.ui.SelectFileWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IndicatorElement );
+OO.inheritClass( OO.ui.SelectFileWidget, OO.ui.SelectFileInputWidget );
 OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.PendingElement );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.TitledElement );
 
 /* Static Properties */
 
@@ -5552,123 +5689,110 @@ OO.ui.SelectFileWidget.static.isSupportedCache = null;
 /**
  * Get the current value of the field
  *
- * @return {File|null}
+ * For single file widgets returns a File or null.
+ * For multiple file widgets returns a list of Files.
+ *
+ * @return {File|File[]|null}
  */
 OO.ui.SelectFileWidget.prototype.getValue = function () {
-       return this.currentFile;
+       return this.multiple ? this.currentFiles : this.currentFiles[ 0 ];
 };
 
 /**
  * Set the current value of the field
  *
- * @param {File|null} file File to select
+ * @param {File[]|null} files Files to select
  */
-OO.ui.SelectFileWidget.prototype.setValue = function ( file ) {
-       if ( this.currentFile !== file ) {
-               this.currentFile = file;
-               this.updateUI();
-               this.emit( 'change', this.currentFile );
+OO.ui.SelectFileWidget.prototype.setValue = function ( files ) {
+       if ( files && !this.multiple ) {
+               files = files.slice( 0, 1 );
        }
-};
 
-/**
- * Focus the widget.
- *
- * Focusses the select file button.
- *
- * @chainable
- * @return {OO.ui.Widget} The widget, for chaining
- */
-OO.ui.SelectFileWidget.prototype.focus = function () {
-       this.selectButton.focus();
-       return this;
+       function comparableFile( file ) {
+               // Use extend to convert to plain objects so they can be compared.
+               return $.extend( {}, file );
+       }
+
+       if ( !OO.compare(
+               files && files.map( comparableFile ),
+               this.currentFiles && this.currentFiles.map( comparableFile )
+       ) ) {
+               this.currentFiles = files || [];
+               this.emit( 'change', this.currentFiles );
+       }
 };
 
 /**
- * Blur the widget.
- *
- * @chainable
- * @return {OO.ui.Widget} The widget, for chaining
+ * @inheritdoc
  */
-OO.ui.SelectFileWidget.prototype.blur = function () {
-       this.selectButton.blur();
-       return this;
+OO.ui.SelectFileWidget.prototype.getFilename = function () {
+       return this.currentFiles.map( function ( file ) {
+               return file.name;
+       } ).join( ', ' );
 };
 
 /**
+ * Disable InputWidget#onEdit listener, onFileSelected is used instead.
  * @inheritdoc
  */
-OO.ui.SelectFileWidget.prototype.simulateLabelClick = function () {
-       this.focus();
-};
+OO.ui.SelectFileWidget.prototype.onEdit = function () {};
 
 /**
- * Update the user interface when a file is selected or unselected
- *
- * @protected
+ * @inheritdoc
  */
 OO.ui.SelectFileWidget.prototype.updateUI = function () {
-       var $label;
-       if ( !this.isSupported ) {
-               this.$element.addClass( 'oo-ui-selectFileWidget-notsupported' );
-               this.$element.removeClass( 'oo-ui-selectFileWidget-empty' );
-               this.setLabel( this.notsupported );
+       // Too early, or not supported
+       if ( !this.selectButton || !this.constructor.static.isSupported() ) {
+               return;
+       }
+
+       // Parent method
+       OO.ui.SelectFileWidget.super.prototype.updateUI.call( this );
+
+       if ( this.currentFiles.length ) {
+               this.$element.removeClass( 'oo-ui-selectFileInputWidget-empty' );
+
+               if ( this.showDropTarget ) {
+                       this.pushPending();
+                       this.loadAndGetImageUrl( this.currentFiles[ 0 ] ).done( function ( url ) {
+                               this.$thumbnail.css( 'background-image', 'url( ' + url + ' )' );
+                       }.bind( this ) ).fail( function () {
+                               this.$thumbnail.append(
+                                       new OO.ui.IconWidget( {
+                                               icon: 'attachment',
+                                               classes: [ 'oo-ui-selectFileWidget-noThumbnail-icon' ]
+                                       } ).$element
+                               );
+                       }.bind( this ) ).always( function () {
+                               this.popPending();
+                       }.bind( this ) );
+                       this.$element.off( 'click' );
+               }
        } else {
-               this.$element.addClass( 'oo-ui-selectFileWidget-supported' );
-               if ( this.currentFile ) {
-                       this.$element.removeClass( 'oo-ui-selectFileWidget-empty' );
-                       $label = $( [] );
-                       $label = $label.add(
-                               $( '<span>' )
-                                       .addClass( 'oo-ui-selectFileWidget-fileName' )
-                                       .text( this.currentFile.name )
-                       );
-                       this.setLabel( $label );
-
-                       if ( this.showDropTarget ) {
-                               this.pushPending();
-                               this.loadAndGetImageUrl().done( function ( url ) {
-                                       this.$thumbnail.css( 'background-image', 'url( ' + url + ' )' );
-                               }.bind( this ) ).fail( function () {
-                                       this.$thumbnail.append(
-                                               new OO.ui.IconWidget( {
-                                                       icon: 'attachment',
-                                                       classes: [ 'oo-ui-selectFileWidget-noThumbnail-icon' ]
-                                               } ).$element
-                                       );
-                               }.bind( this ) ).always( function () {
-                                       this.popPending();
-                               }.bind( this ) );
-                               this.$element.off( 'click' );
-                       }
-               } else {
-                       if ( this.showDropTarget ) {
-                               this.$element.off( 'click' );
-                               this.$element.on( {
-                                       click: this.onDropTargetClick.bind( this )
-                               } );
-                               this.$thumbnail
-                                       .empty()
-                                       .css( 'background-image', '' );
-                       }
-                       this.$element.addClass( 'oo-ui-selectFileWidget-empty' );
-                       this.setLabel( this.placeholder );
+               if ( this.showDropTarget ) {
+                       this.$element.off( 'click' );
+                       this.$element.on( {
+                               click: this.onDropTargetClick.bind( this )
+                       } );
+                       this.$thumbnail
+                               .empty()
+                               .css( 'background-image', '' );
                }
+               this.$element.addClass( 'oo-ui-selectFileInputWidget-empty' );
        }
 };
 
 /**
  * If the selected file is an image, get its URL and load it.
  *
+ * @param {File} file File
  * @return {jQuery.Promise} Promise resolves with the image URL after it has loaded
  */
-OO.ui.SelectFileWidget.prototype.loadAndGetImageUrl = function () {
+OO.ui.SelectFileWidget.prototype.loadAndGetImageUrl = function ( file ) {
        var deferred = $.Deferred(),
-               file = this.currentFile,
                reader = new FileReader();
 
        if (
-               file &&
                ( OO.getProp( file, 'type' ) || '' ).indexOf( 'image/' ) === 0 &&
                file.size < this.thumbnailSizeLimit * 1024 * 1024
        ) {
@@ -5696,107 +5820,23 @@ OO.ui.SelectFileWidget.prototype.loadAndGetImageUrl = function () {
 };
 
 /**
- * Add the input to the widget
- *
- * @private
- */
-OO.ui.SelectFileWidget.prototype.addInput = function () {
-       if ( this.$input ) {
-               this.$input.remove();
-       }
-
-       if ( !this.isSupported ) {
-               this.$input = null;
-               return;
-       }
-
-       this.$input = $( '<input>' ).attr( 'type', 'file' );
-       this.$input.on( 'change', this.onFileSelectedHandler );
-       this.$input.on( 'click', function ( e ) {
-               // Prevents dropTarget to get clicked which calls
-               // a click on this input
-               e.stopPropagation();
-       } );
-       this.$input.attr( {
-               tabindex: -1
-       } );
-       if ( this.accept ) {
-               this.$input.attr( 'accept', this.accept.join( ', ' ) );
-       }
-       this.selectButton.$button.append( this.$input );
-};
-
-/**
- * Determine if we should accept this file
- *
- * @private
- * @param {string} mimeType File MIME type
- * @return {boolean}
- */
-OO.ui.SelectFileWidget.prototype.isAllowedType = function ( mimeType ) {
-       var i, mimeTest;
-
-       if ( !this.accept || !mimeType ) {
-               return true;
-       }
-
-       for ( i = 0; i < this.accept.length; i++ ) {
-               mimeTest = this.accept[ i ];
-               if ( mimeTest === mimeType ) {
-                       return true;
-               } else if ( mimeTest.substr( -2 ) === '/*' ) {
-                       mimeTest = mimeTest.substr( 0, mimeTest.length - 1 );
-                       if ( mimeType.substr( 0, mimeTest.length ) === mimeTest ) {
-                               return true;
-                       }
-               }
-       }
-
-       return false;
-};
-
-/**
- * Handle file selection from the input
- *
- * @private
- * @param {jQuery.Event} e
+ * @inheritdoc
  */
 OO.ui.SelectFileWidget.prototype.onFileSelected = function ( e ) {
-       var file = OO.getProp( e.target, 'files', 0 ) || null;
+       var files;
 
-       if ( file && !this.isAllowedType( file.type ) ) {
-               file = null;
+       if ( this.inputClearing ) {
+               return;
        }
 
-       this.setValue( file );
-       this.addInput();
-};
+       files = this.filterFiles( e.target.files || [] );
 
-/**
- * Handle clear button click events.
- *
- * @private
- * @return {undefined/boolean} False to prevent default if event is handled
- */
-OO.ui.SelectFileWidget.prototype.onClearClick = function () {
-       this.setValue( null );
-       return false;
-};
+       // After a file is selected clear the native widget to avoid confusion
+       this.inputClearing = true;
+       this.$input[ 0 ].value = '';
+       this.inputClearing = false;
 
-/**
- * Handle key press events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- * @return {undefined/boolean} False to prevent default if event is handled
- */
-OO.ui.SelectFileWidget.prototype.onKeyPress = function ( e ) {
-       if ( this.isSupported && !this.isDisabled() && this.$input &&
-               ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.$input.trigger( 'click' );
-               return false;
-       }
+       this.setValue( files );
 };
 
 /**
@@ -5807,7 +5847,7 @@ OO.ui.SelectFileWidget.prototype.onKeyPress = function ( e ) {
  * @return {undefined/boolean} False to prevent default if event is handled
  */
 OO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {
-       if ( this.isSupported && !this.isDisabled() && this.$input ) {
+       if ( !this.isDisabled() && this.$input ) {
                this.$input.trigger( 'click' );
                return false;
        }
@@ -5821,14 +5861,14 @@ OO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {
  * @return {undefined/boolean} False to prevent default if event is handled
  */
 OO.ui.SelectFileWidget.prototype.onDragEnterOrOver = function ( e ) {
-       var itemOrFile,
-               droppableFile = false,
+       var itemsOrFiles,
+               hasDroppableFile = false,
                dt = e.originalEvent.dataTransfer;
 
        e.preventDefault();
        e.stopPropagation();
 
-       if ( this.isDisabled() || !this.isSupported ) {
+       if ( this.isDisabled() ) {
                this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
                dt.dropEffect = 'none';
                return false;
@@ -5836,21 +5876,21 @@ OO.ui.SelectFileWidget.prototype.onDragEnterOrOver = function ( e ) {
 
        // DataTransferItem and File both have a type property, but in Chrome files
        // have no information at this point.
-       itemOrFile = OO.getProp( dt, 'items', 0 ) || OO.getProp( dt, 'files', 0 );
-       if ( itemOrFile ) {
-               if ( this.isAllowedType( itemOrFile.type ) ) {
-                       droppableFile = true;
+       itemsOrFiles = dt.items || dt.files;
+       if ( itemsOrFiles && itemsOrFiles.length ) {
+               if ( this.filterFiles( itemsOrFiles ).length ) {
+                       hasDroppableFile = true;
                }
        // dt.types is Array-like, but not an Array
        } else if ( Array.prototype.indexOf.call( OO.getProp( dt, 'types' ) || [], 'Files' ) !== -1 ) {
                // File information is not available at this point for security so just assume
                // it is acceptable for now.
                // https://bugzilla.mozilla.org/show_bug.cgi?id=640534
-               droppableFile = true;
+               hasDroppableFile = true;
        }
 
-       this.$element.toggleClass( 'oo-ui-selectFileWidget-canDrop', droppableFile );
-       if ( !droppableFile ) {
+       this.$element.toggleClass( 'oo-ui-selectFileWidget-canDrop', hasDroppableFile );
+       if ( !hasDroppableFile ) {
                dt.dropEffect = 'none';
        }
 
@@ -5875,24 +5915,19 @@ OO.ui.SelectFileWidget.prototype.onDragLeave = function () {
  * @return {undefined/boolean} False to prevent default if event is handled
  */
 OO.ui.SelectFileWidget.prototype.onDrop = function ( e ) {
-       var file = null,
+       var files,
                dt = e.originalEvent.dataTransfer;
 
        e.preventDefault();
        e.stopPropagation();
        this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
 
-       if ( this.isDisabled() || !this.isSupported ) {
+       if ( this.isDisabled() ) {
                return false;
        }
 
-       file = OO.getProp( dt, 'files', 0 );
-       if ( file && !this.isAllowedType( file.type ) ) {
-               file = null;
-       }
-       if ( file ) {
-               this.setValue( file );
-       }
+       files = this.filterFiles( dt.files || [] );
+       this.setValue( files );
 
        return false;
 };
@@ -5901,21 +5936,19 @@ OO.ui.SelectFileWidget.prototype.onDrop = function ( e ) {
  * @inheritdoc
  */
 OO.ui.SelectFileWidget.prototype.setDisabled = function ( disabled ) {
+       disabled = disabled || !this.constructor.static.isSupported();
+
+       // Parent method
        OO.ui.SelectFileWidget.parent.prototype.setDisabled.call( this, disabled );
-       if ( this.selectButton ) {
-               this.selectButton.setDisabled( disabled );
-       }
-       if ( this.clearButton ) {
-               this.clearButton.setDisabled( disabled );
-       }
-       return this;
 };
 
 /**
- * SearchWidgets combine a {@link OO.ui.TextInputWidget text input field}, where users can type a search query,
- * and a menu of search results, which is displayed beneath the query
- * field. Unlike {@link OO.ui.mixin.LookupElement lookup menus}, search result menus are always visible to the user.
- * Users can choose an item from the menu or type a query into the text field to search for a matching result item.
+ * SearchWidgets combine a {@link OO.ui.TextInputWidget text input field},
+ * where users can type a search query, and a menu of search results,
+ * which is displayed beneath the query field.
+ * Unlike {@link OO.ui.mixin.LookupElement lookup menus}, search result menus are always visible
+ * to the user. Users can choose an item from the menu or type a query into the text field to
+ * search for a matching result item.
  * In general, search widgets are used inside a separate {@link OO.ui.Dialog dialog} window.
  *
  * Each time the query is changed, the search result menu is cleared and repopulated. Please see
index f0d96b4..755bbdc 100644 (file)
@@ -1 +1 @@
-{"version":3,"sources":["../src/intro.js.txt","../src/mixins/DraggableElement.js","../src/mixins/DraggableGroupElement.js","../src/mixins/RequestManager.js","../src/mixins/LookupElement.js","../src/layouts/TabPanelLayout.js","../src/layouts/PageLayout.js","../src/layouts/StackLayout.js","../src/layouts/MenuLayout.js","../src/layouts/BookletLayout.js","../src/layouts/IndexLayout.js","../src/widgets/ToggleWidget.js","../src/widgets/ToggleButtonWidget.js","../src/widgets/ToggleSwitchWidget.js","../src/widgets/OutlineControlsWidget.js","../src/widgets/OutlineOptionWidget.js","../src/widgets/OutlineSelectWidget.js","../src/widgets/ButtonOptionWidget.js","../src/widgets/ButtonSelectWidget.js","../src/widgets/TabOptionWidget.js","../src/widgets/TabSelectWidget.js","../src/widgets/TagItemWidget.js","../src/widgets/TagMultiselectWidget.js","../src/widgets/PopupTagMultiselectWidget.js","../src/widgets/MenuTagMultiselectWidget.js","../src/widgets/SelectFileWidget.js","../src/widgets/SearchWidget.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-widgets.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * DraggableElement is a mixin class used to create elements that can be clicked\n * and dragged by a mouse to a new position within a group. This class must be used\n * in conjunction with OO.ui.mixin.DraggableGroupElement, which provides a container for\n * the draggable elements.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$handle] The part of the element which can be used for dragging, defaults to the whole element\n * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable\n *  but the draggable state should be called from the DraggableGroupElement, which updates\n *  the whole group\n */\nOO.ui.mixin.DraggableElement = function OoUiMixinDraggableElement( config ) {\n\tconfig = config || {};\n\n\t// Properties\n\tthis.index = null;\n\tthis.$handle = config.$handle || this.$element;\n\tthis.wasHandleUsed = null;\n\n\t// Initialize and events\n\tthis.$element\n\t\t.addClass( 'oo-ui-draggableElement' )\n\t\t.on( {\n\t\t\tmousedown: this.onDragMouseDown.bind( this ),\n\t\t\tdragstart: this.onDragStart.bind( this ),\n\t\t\tdragover: this.onDragOver.bind( this ),\n\t\t\tdragend: this.onDragEnd.bind( this ),\n\t\t\tdrop: this.onDrop.bind( this )\n\t\t} );\n\tthis.$handle.addClass( 'oo-ui-draggableElement-handle' );\n\tthis.toggleDraggable( config.draggable === undefined ? true : !!config.draggable );\n};\n\nOO.initClass( OO.ui.mixin.DraggableElement );\n\n/* Events */\n\n/**\n * @event dragstart\n *\n * A dragstart event is emitted when the user clicks and begins dragging an item.\n * @param {OO.ui.mixin.DraggableElement} item The item the user has clicked and is dragging with the mouse.\n */\n\n/**\n * @event dragend\n * A dragend event is emitted when the user drags an item and releases the mouse,\n * thus terminating the drag operation.\n */\n\n/**\n * @event drop\n * A drop event is emitted when the user drags an item and then releases the mouse button\n * over a valid target.\n */\n\n/* Static Properties */\n\n/**\n * @inheritdoc OO.ui.mixin.ButtonElement\n */\nOO.ui.mixin.DraggableElement.static.cancelButtonMouseDownEvents = false;\n\n/* Methods */\n\n/**\n * Change the draggable state of this widget.\n * This allows users to temporarily halt the dragging operations.\n *\n * @param {boolean} isDraggable Widget supports draggable operations\n * @fires draggable\n */\nOO.ui.mixin.DraggableElement.prototype.toggleDraggable = function ( isDraggable ) {\n\tisDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;\n\n\tif ( this.draggable !== isDraggable ) {\n\t\tthis.draggable = isDraggable;\n\n\t\tthis.$handle.toggleClass( 'oo-ui-draggableElement-undraggable', !this.draggable );\n\n\t\t// We make the entire element draggable, not just the handle, so that\n\t\t// the whole element appears to move. wasHandleUsed prevents drags from\n\t\t// starting outside the handle\n\t\tthis.$element.prop( 'draggable', this.draggable );\n\t}\n};\n\n/**\n * Check the draggable state of this widget\n *\n * @return {boolean} Widget supports draggable operations\n */\nOO.ui.mixin.DraggableElement.prototype.isDraggable = function () {\n\treturn this.draggable;\n};\n\n/**\n * Respond to mousedown event.\n *\n * @private\n * @param {jQuery.Event} e Drag event\n */\nOO.ui.mixin.DraggableElement.prototype.onDragMouseDown = function ( e ) {\n\tif ( !this.isDraggable() ) {\n\t\treturn;\n\t}\n\n\tthis.wasHandleUsed =\n\t\t// Optimization: if the handle is the whole element this is always true\n\t\tthis.$handle[ 0 ] === this.$element[ 0 ] ||\n\t\t// Check the mousedown occurred inside the handle\n\t\tOO.ui.contains( this.$handle[ 0 ], e.target, true );\n};\n\n/**\n * Respond to dragstart event.\n *\n * @private\n * @param {jQuery.Event} e Drag event\n * @return {boolean} False if the event is cancelled\n * @fires dragstart\n */\nOO.ui.mixin.DraggableElement.prototype.onDragStart = function ( e ) {\n\tvar element = this,\n\t\tdataTransfer = e.originalEvent.dataTransfer;\n\n\tif ( !this.wasHandleUsed || !this.isDraggable() ) {\n\t\treturn false;\n\t}\n\n\t// Define drop effect\n\tdataTransfer.dropEffect = 'none';\n\tdataTransfer.effectAllowed = 'move';\n\t// Support: Firefox\n\t// We must set up a dataTransfer data property or Firefox seems to\n\t// ignore the fact the element is draggable.\n\ttry {\n\t\tdataTransfer.setData( 'application-x/OOUI-draggable', this.getIndex() );\n\t} catch ( err ) {\n\t\t// The above is only for Firefox. Move on if it fails.\n\t}\n\t// Briefly add a 'clone' class to style the browser's native drag image\n\tthis.$element.addClass( 'oo-ui-draggableElement-clone' );\n\t// Add placeholder class after the browser has rendered the clone\n\tsetTimeout( function () {\n\t\telement.$element\n\t\t\t.removeClass( 'oo-ui-draggableElement-clone' )\n\t\t\t.addClass( 'oo-ui-draggableElement-placeholder' );\n\t} );\n\t// Emit event\n\tthis.emit( 'dragstart', this );\n\treturn true;\n};\n\n/**\n * Respond to dragend event.\n *\n * @private\n * @fires dragend\n */\nOO.ui.mixin.DraggableElement.prototype.onDragEnd = function () {\n\tthis.$element.removeClass( 'oo-ui-draggableElement-placeholder' );\n\tthis.emit( 'dragend' );\n};\n\n/**\n * Handle drop event.\n *\n * @private\n * @param {jQuery.Event} e Drop event\n * @fires drop\n */\nOO.ui.mixin.DraggableElement.prototype.onDrop = function ( e ) {\n\te.preventDefault();\n\tthis.emit( 'drop', e );\n};\n\n/**\n * In order for drag/drop to work, the dragover event must\n * return false and stop propogation.\n *\n * @param {jQuery.Event} e Drag event\n * @private\n */\nOO.ui.mixin.DraggableElement.prototype.onDragOver = function ( e ) {\n\te.preventDefault();\n};\n\n/**\n * Set item index.\n * Store it in the DOM so we can access from the widget drag event\n *\n * @private\n * @param {number} index Item index\n */\nOO.ui.mixin.DraggableElement.prototype.setIndex = function ( index ) {\n\tif ( this.index !== index ) {\n\t\tthis.index = index;\n\t\tthis.$element.data( 'index', index );\n\t}\n};\n\n/**\n * Get item index\n *\n * @private\n * @return {number} Item index\n */\nOO.ui.mixin.DraggableElement.prototype.getIndex = function () {\n\treturn this.index;\n};\n","/**\n * DraggableGroupElement is a mixin class used to create a group element to\n * contain draggable elements, which are items that can be clicked and dragged by a mouse.\n * The class is used with OO.ui.mixin.DraggableElement.\n *\n * @abstract\n * @class\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [orientation] Item orientation: 'horizontal' or 'vertical'. The orientation\n *  should match the layout of the items. Items displayed in a single row\n *  or in several rows should use horizontal orientation. The vertical orientation should only be\n *  used when the items are displayed in a single column. Defaults to 'vertical'\n * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable\n */\nOO.ui.mixin.DraggableGroupElement = function OoUiMixinDraggableGroupElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.orientation = config.orientation || 'vertical';\n\tthis.dragItem = null;\n\tthis.itemKeys = {};\n\tthis.dir = null;\n\tthis.itemsOrder = null;\n\tthis.draggable = config.draggable === undefined ? true : !!config.draggable;\n\n\t// Events\n\tthis.aggregate( {\n\t\tdragstart: 'itemDragStart',\n\t\tdragend: 'itemDragEnd',\n\t\tdrop: 'itemDrop'\n\t} );\n\tthis.connect( this, {\n\t\titemDragStart: 'onItemDragStart',\n\t\titemDrop: 'onItemDropOrDragEnd',\n\t\titemDragEnd: 'onItemDropOrDragEnd'\n\t} );\n\n\t// Initialize\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n\tthis.$element\n\t\t.addClass( 'oo-ui-draggableGroupElement' )\n\t\t.toggleClass( 'oo-ui-draggableGroupElement-horizontal', this.orientation === 'horizontal' );\n};\n\n/* Setup */\nOO.mixinClass( OO.ui.mixin.DraggableGroupElement, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * An item has been dragged to a new position, but not yet dropped.\n *\n * @event drag\n * @param {OO.ui.mixin.DraggableElement} item Dragged item\n * @param {number} [newIndex] New index for the item\n */\n\n/**\n * An item has been dropped at a new position.\n *\n * @event reorder\n * @param {OO.ui.mixin.DraggableElement} item Reordered item\n * @param {number} [newIndex] New index for the item\n */\n\n/**\n * Draggable state of this widget has changed.\n *\n * @event draggable\n * @param {boolean} [draggable] Widget is draggable\n */\n\n/* Methods */\n\n/**\n * Change the draggable state of this widget.\n * This allows users to temporarily halt the dragging operations.\n *\n * @param {boolean} isDraggable Widget supports draggable operations\n * @fires draggable\n */\nOO.ui.mixin.DraggableGroupElement.prototype.toggleDraggable = function ( isDraggable ) {\n\tisDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;\n\n\tif ( this.draggable !== isDraggable ) {\n\t\tthis.draggable = isDraggable;\n\n\t\t// Tell the items their draggable state changed\n\t\tthis.getItems().forEach( function ( item ) {\n\t\t\titem.toggleDraggable( this.draggable );\n\t\t}.bind( this ) );\n\n\t\t// Emit event\n\t\tthis.emit( 'draggable', this.draggable );\n\t}\n};\n\n/**\n * Check the draggable state of this widget\n *\n * @return {boolean} Widget supports draggable operations\n */\nOO.ui.mixin.DraggableGroupElement.prototype.isDraggable = function () {\n\treturn this.draggable;\n};\n\n/**\n * Respond to item drag start event\n *\n * @private\n * @param {OO.ui.mixin.DraggableElement} item Dragged item\n */\nOO.ui.mixin.DraggableGroupElement.prototype.onItemDragStart = function ( item ) {\n\tif ( !this.isDraggable() ) {\n\t\treturn;\n\t}\n\t// Make a shallow copy of this.items so we can re-order it during previews\n\t// without affecting the original array.\n\tthis.itemsOrder = this.items.slice();\n\tthis.updateIndexes();\n\tif ( this.orientation === 'horizontal' ) {\n\t\t// Calculate and cache directionality on drag start - it's a little\n\t\t// expensive and it shouldn't change while dragging.\n\t\tthis.dir = this.$element.css( 'direction' );\n\t}\n\tthis.setDragItem( item );\n};\n\n/**\n * Update the index properties of the items\n */\nOO.ui.mixin.DraggableGroupElement.prototype.updateIndexes = function () {\n\tvar i, len;\n\n\t// Map the index of each object\n\tfor ( i = 0, len = this.itemsOrder.length; i < len; i++ ) {\n\t\tthis.itemsOrder[ i ].setIndex( i );\n\t}\n};\n\n/**\n * Handle drop or dragend event and switch the order of the items accordingly\n *\n * @private\n * @param {OO.ui.mixin.DraggableElement} item Dropped item\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.DraggableGroupElement.prototype.onItemDropOrDragEnd = function () {\n\tvar targetIndex, originalIndex,\n\t\titem = this.getDragItem();\n\n\t// TODO: Figure out a way to configure a list of legally droppable\n\t// elements even if they are not yet in the list\n\tif ( item ) {\n\t\toriginalIndex = this.items.indexOf( item );\n\t\t// If the item has moved forward, add one to the index to account for the left shift\n\t\ttargetIndex = item.getIndex() + ( item.getIndex() > originalIndex ? 1 : 0 );\n\t\tif ( targetIndex !== originalIndex ) {\n\t\t\tthis.reorder( this.getDragItem(), targetIndex );\n\t\t\tthis.emit( 'reorder', this.getDragItem(), targetIndex );\n\t\t}\n\t\tthis.updateIndexes();\n\t}\n\tthis.unsetDragItem();\n\t// Return false to prevent propogation\n\treturn false;\n};\n\n/**\n * Respond to dragover event\n *\n * @private\n * @param {jQuery.Event} e Dragover event\n * @fires reorder\n */\nOO.ui.mixin.DraggableGroupElement.prototype.onDragOver = function ( e ) {\n\tvar overIndex, targetIndex,\n\t\titem = this.getDragItem(),\n\t\tdragItemIndex = item.getIndex();\n\n\t// Get the OptionWidget item we are dragging over\n\toverIndex = $( e.target ).closest( '.oo-ui-draggableElement' ).data( 'index' );\n\n\tif ( overIndex !== undefined && overIndex !== dragItemIndex ) {\n\t\ttargetIndex = overIndex + ( overIndex > dragItemIndex ? 1 : 0 );\n\n\t\tif ( targetIndex > 0 ) {\n\t\t\tthis.$group.children().eq( targetIndex - 1 ).after( item.$element );\n\t\t} else {\n\t\t\tthis.$group.prepend( item.$element );\n\t\t}\n\t\t// Move item in itemsOrder array\n\t\tthis.itemsOrder.splice( overIndex, 0,\n\t\t\tthis.itemsOrder.splice( dragItemIndex, 1 )[ 0 ]\n\t\t);\n\t\tthis.updateIndexes();\n\t\tthis.emit( 'drag', item, targetIndex );\n\t}\n\t// Prevent default\n\te.preventDefault();\n};\n\n/**\n * Reorder the items in the group\n *\n * @param {OO.ui.mixin.DraggableElement} item Reordered item\n * @param {number} newIndex New index\n */\nOO.ui.mixin.DraggableGroupElement.prototype.reorder = function ( item, newIndex ) {\n\tthis.addItems( [ item ], newIndex );\n};\n\n/**\n * Set a dragged item\n *\n * @param {OO.ui.mixin.DraggableElement} item Dragged item\n */\nOO.ui.mixin.DraggableGroupElement.prototype.setDragItem = function ( item ) {\n\tif ( this.dragItem !== item ) {\n\t\tthis.dragItem = item;\n\t\tthis.$element.on( 'dragover', this.onDragOver.bind( this ) );\n\t\tthis.$element.addClass( 'oo-ui-draggableGroupElement-dragging' );\n\t}\n};\n\n/**\n * Unset the current dragged item\n */\nOO.ui.mixin.DraggableGroupElement.prototype.unsetDragItem = function () {\n\tif ( this.dragItem ) {\n\t\tthis.dragItem = null;\n\t\tthis.$element.off( 'dragover' );\n\t\tthis.$element.removeClass( 'oo-ui-draggableGroupElement-dragging' );\n\t}\n};\n\n/**\n * Get the item that is currently being dragged.\n *\n * @return {OO.ui.mixin.DraggableElement|null} The currently dragged item, or `null` if no item is being dragged\n */\nOO.ui.mixin.DraggableGroupElement.prototype.getDragItem = function () {\n\treturn this.dragItem;\n};\n","/**\n * RequestManager is a mixin that manages the lifecycle of a promise-backed request for a widget, such as\n * the {@link OO.ui.mixin.LookupElement}.\n *\n * @class\n * @abstract\n *\n * @constructor\n */\nOO.ui.mixin.RequestManager = function OoUiMixinRequestManager() {\n\tthis.requestCache = {};\n\tthis.requestQuery = null;\n\tthis.requestRequest = null;\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.RequestManager );\n\n/**\n * Get request results for the current query.\n *\n * @return {jQuery.Promise} Promise object which will be passed response data as the first argument of\n *   the done event. If the request was aborted to make way for a subsequent request, this promise\n *   may not be rejected, depending on what jQuery feels like doing.\n */\nOO.ui.mixin.RequestManager.prototype.getRequestData = function () {\n\tvar widget = this,\n\t\tvalue = this.getRequestQuery(),\n\t\tdeferred = $.Deferred(),\n\t\tourRequest;\n\n\tthis.abortRequest();\n\tif ( Object.prototype.hasOwnProperty.call( this.requestCache, value ) ) {\n\t\tdeferred.resolve( this.requestCache[ value ] );\n\t} else {\n\t\tif ( this.pushPending ) {\n\t\t\tthis.pushPending();\n\t\t}\n\t\tthis.requestQuery = value;\n\t\tourRequest = this.requestRequest = this.getRequest();\n\t\tourRequest\n\t\t\t.always( function () {\n\t\t\t\t// We need to pop pending even if this is an old request, otherwise\n\t\t\t\t// the widget will remain pending forever.\n\t\t\t\t// TODO: this assumes that an aborted request will fail or succeed soon after\n\t\t\t\t// being aborted, or at least eventually. It would be nice if we could popPending()\n\t\t\t\t// at abort time, but only if we knew that we hadn't already called popPending()\n\t\t\t\t// for that request.\n\t\t\t\tif ( widget.popPending ) {\n\t\t\t\t\twidget.popPending();\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.done( function ( response ) {\n\t\t\t\t// If this is an old request (and aborting it somehow caused it to still succeed),\n\t\t\t\t// ignore its success completely\n\t\t\t\tif ( ourRequest === widget.requestRequest ) {\n\t\t\t\t\twidget.requestQuery = null;\n\t\t\t\t\twidget.requestRequest = null;\n\t\t\t\t\twidget.requestCache[ value ] = widget.getRequestCacheDataFromResponse( response );\n\t\t\t\t\tdeferred.resolve( widget.requestCache[ value ] );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.fail( function () {\n\t\t\t\t// If this is an old request (or a request failing because it's being aborted),\n\t\t\t\t// ignore its failure completely\n\t\t\t\tif ( ourRequest === widget.requestRequest ) {\n\t\t\t\t\twidget.requestQuery = null;\n\t\t\t\t\twidget.requestRequest = null;\n\t\t\t\t\tdeferred.reject();\n\t\t\t\t}\n\t\t\t} );\n\t}\n\treturn deferred.promise();\n};\n\n/**\n * Abort the currently pending request, if any.\n *\n * @private\n */\nOO.ui.mixin.RequestManager.prototype.abortRequest = function () {\n\tvar oldRequest = this.requestRequest;\n\tif ( oldRequest ) {\n\t\t// First unset this.requestRequest to the fail handler will notice\n\t\t// that the request is no longer current\n\t\tthis.requestRequest = null;\n\t\tthis.requestQuery = null;\n\t\toldRequest.abort();\n\t}\n};\n\n/**\n * Get the query to be made.\n *\n * @protected\n * @method\n * @abstract\n * @return {string} query to be used\n */\nOO.ui.mixin.RequestManager.prototype.getRequestQuery = null;\n\n/**\n * Get a new request object of the current query value.\n *\n * @protected\n * @method\n * @abstract\n * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method\n */\nOO.ui.mixin.RequestManager.prototype.getRequest = null;\n\n/**\n * Pre-process data returned by the request from #getRequest.\n *\n * The return value of this function will be cached, and any further queries for the given value\n * will use the cache rather than doing API requests.\n *\n * @protected\n * @method\n * @abstract\n * @param {Mixed} response Response from server\n * @return {Mixed} Cached result data\n */\nOO.ui.mixin.RequestManager.prototype.getRequestCacheDataFromResponse = null;\n","/**\n * LookupElement is a mixin that creates a {@link OO.ui.MenuSelectWidget menu} of suggested values for\n * a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on the characters the user types\n * into the text input field and, in general, the menu is only displayed when the user types. If a suggested value is chosen\n * from the lookup menu, that value becomes the value of the input field.\n *\n * Note that a new menu of suggested items is displayed when a value is chosen from the lookup menu. If this is\n * not the desired behavior, disable lookup menus with the #setLookupsDisabled method, then set the value, then\n * re-enable lookups.\n *\n * See the [OOUI demos][1] for an example.\n *\n * [1]: https://doc.wikimedia.org/oojs-ui/master/demos/#LookupElement-try-inputting-an-integer\n *\n * @class\n * @abstract\n * @mixins OO.ui.mixin.RequestManager\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered beneath the specified element.\n * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.MenuSelectWidget menu select widget}\n * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the text input is empty.\n *  By default, the lookup menu is not generated and displayed until the user begins to type.\n * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted (so, that the user can\n *  take it over into the input with simply pressing return) automatically or not.\n */\nOO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { highlightFirst: true }, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.RequestManager.call( this, config );\n\n\t// Properties\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.lookupMenu = new OO.ui.MenuSelectWidget( $.extend( {\n\t\twidget: this,\n\t\tinput: this,\n\t\t$floatableContainer: config.$container || this.$element\n\t}, config.menu ) );\n\n\tthis.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;\n\n\tthis.lookupsDisabled = false;\n\tthis.lookupInputFocused = false;\n\tthis.lookupHighlightFirstItem = config.highlightFirst;\n\n\t// Events\n\tthis.$input.on( {\n\t\tfocus: this.onLookupInputFocus.bind( this ),\n\t\tblur: this.onLookupInputBlur.bind( this ),\n\t\tmousedown: this.onLookupInputMouseDown.bind( this )\n\t} );\n\tthis.connect( this, { change: 'onLookupInputChange' } );\n\tthis.lookupMenu.connect( this, {\n\t\ttoggle: 'onLookupMenuToggle',\n\t\tchoose: 'onLookupMenuItemChoose'\n\t} );\n\n\t// Initialization\n\tthis.$input.attr( {\n\t\trole: 'combobox',\n\t\t'aria-owns': this.lookupMenu.getElementId(),\n\t\t'aria-autocomplete': 'list'\n\t} );\n\tthis.$element.addClass( 'oo-ui-lookupElement' );\n\tthis.lookupMenu.$element.addClass( 'oo-ui-lookupElement-menu' );\n\tthis.$overlay.append( this.lookupMenu.$element );\n};\n\n/* Setup */\n\nOO.mixinClass( OO.ui.mixin.LookupElement, OO.ui.mixin.RequestManager );\n\n/* Methods */\n\n/**\n * Handle input focus event.\n *\n * @protected\n * @param {jQuery.Event} e Input focus event\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputFocus = function () {\n\tthis.lookupInputFocused = true;\n\tthis.populateLookupMenu();\n};\n\n/**\n * Handle input blur event.\n *\n * @protected\n * @param {jQuery.Event} e Input blur event\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputBlur = function () {\n\tthis.closeLookupMenu();\n\tthis.lookupInputFocused = false;\n};\n\n/**\n * Handle input mouse down event.\n *\n * @protected\n * @param {jQuery.Event} e Input mouse down event\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputMouseDown = function () {\n\t// Only open the menu if the input was already focused.\n\t// This way we allow the user to open the menu again after closing it with Esc\n\t// by clicking in the input. Opening (and populating) the menu when initially\n\t// clicking into the input is handled by the focus handler.\n\tif ( this.lookupInputFocused && !this.lookupMenu.isVisible() ) {\n\t\tthis.populateLookupMenu();\n\t}\n};\n\n/**\n * Handle input change event.\n *\n * @protected\n * @param {string} value New input value\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputChange = function () {\n\tif ( this.lookupInputFocused ) {\n\t\tthis.populateLookupMenu();\n\t}\n};\n\n/**\n * Handle the lookup menu being shown/hidden.\n *\n * @protected\n * @param {boolean} visible Whether the lookup menu is now visible.\n */\nOO.ui.mixin.LookupElement.prototype.onLookupMenuToggle = function ( visible ) {\n\tif ( !visible ) {\n\t\t// When the menu is hidden, abort any active request and clear the menu.\n\t\t// This has to be done here in addition to closeLookupMenu(), because\n\t\t// MenuSelectWidget will close itself when the user presses Esc.\n\t\tthis.abortLookupRequest();\n\t\tthis.lookupMenu.clearItems();\n\t}\n};\n\n/**\n * Handle menu item 'choose' event, updating the text input value to the value of the clicked item.\n *\n * @protected\n * @param {OO.ui.MenuOptionWidget} item Selected item\n */\nOO.ui.mixin.LookupElement.prototype.onLookupMenuItemChoose = function ( item ) {\n\tthis.setValue( item.getData() );\n};\n\n/**\n * Get lookup menu.\n *\n * @private\n * @return {OO.ui.MenuSelectWidget}\n */\nOO.ui.mixin.LookupElement.prototype.getLookupMenu = function () {\n\treturn this.lookupMenu;\n};\n\n/**\n * Disable or re-enable lookups.\n *\n * When lookups are disabled, calls to #populateLookupMenu will be ignored.\n *\n * @param {boolean} disabled Disable lookups\n */\nOO.ui.mixin.LookupElement.prototype.setLookupsDisabled = function ( disabled ) {\n\tthis.lookupsDisabled = !!disabled;\n};\n\n/**\n * Open the menu. If there are no entries in the menu, this does nothing.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.openLookupMenu = function () {\n\tif ( !this.lookupMenu.isEmpty() ) {\n\t\tthis.lookupMenu.toggle( true );\n\t}\n\treturn this;\n};\n\n/**\n * Close the menu, empty it, and abort any pending request.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.closeLookupMenu = function () {\n\tthis.lookupMenu.toggle( false );\n\tthis.abortLookupRequest();\n\tthis.lookupMenu.clearItems();\n\treturn this;\n};\n\n/**\n * Request menu items based on the input's current value, and when they arrive,\n * populate the menu with these items and show the menu.\n *\n * If lookups have been disabled with #setLookupsDisabled, this function does nothing.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.populateLookupMenu = function () {\n\tvar widget = this,\n\t\tvalue = this.getValue();\n\n\tif ( this.lookupsDisabled || this.isReadOnly() ) {\n\t\treturn;\n\t}\n\n\t// If the input is empty, clear the menu, unless suggestions when empty are allowed.\n\tif ( !this.allowSuggestionsWhenEmpty && value === '' ) {\n\t\tthis.closeLookupMenu();\n\t// Skip population if there is already a request pending for the current value\n\t} else if ( value !== this.lookupQuery ) {\n\t\tthis.getLookupMenuItems()\n\t\t\t.done( function ( items ) {\n\t\t\t\twidget.lookupMenu.clearItems();\n\t\t\t\tif ( items.length ) {\n\t\t\t\t\twidget.lookupMenu\n\t\t\t\t\t\t.addItems( items )\n\t\t\t\t\t\t.toggle( true );\n\t\t\t\t\twidget.initializeLookupMenuSelection();\n\t\t\t\t} else {\n\t\t\t\t\twidget.lookupMenu.toggle( false );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.fail( function () {\n\t\t\t\twidget.lookupMenu.clearItems();\n\t\t\t\twidget.lookupMenu.toggle( false );\n\t\t\t} );\n\t}\n\n\treturn this;\n};\n\n/**\n * Highlight the first selectable item in the menu, if configured.\n *\n * @private\n * @chainable\n */\nOO.ui.mixin.LookupElement.prototype.initializeLookupMenuSelection = function () {\n\tif ( this.lookupHighlightFirstItem && !this.lookupMenu.findSelectedItem() ) {\n\t\tthis.lookupMenu.highlightItem( this.lookupMenu.findFirstSelectableItem() );\n\t}\n};\n\n/**\n * Get lookup menu items for the current query.\n *\n * @private\n * @return {jQuery.Promise} Promise object which will be passed menu items as the first argument of\n *   the done event. If the request was aborted to make way for a subsequent request, this promise\n *   will not be rejected: it will remain pending forever.\n */\nOO.ui.mixin.LookupElement.prototype.getLookupMenuItems = function () {\n\treturn this.getRequestData().then( function ( data ) {\n\t\treturn this.getLookupMenuOptionsFromData( data );\n\t}.bind( this ) );\n};\n\n/**\n * Abort the currently pending lookup request, if any.\n *\n * @private\n */\nOO.ui.mixin.LookupElement.prototype.abortLookupRequest = function () {\n\tthis.abortRequest();\n};\n\n/**\n * Get a new request object of the current lookup query value.\n *\n * @protected\n * @method\n * @abstract\n * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method\n */\nOO.ui.mixin.LookupElement.prototype.getLookupRequest = null;\n\n/**\n * Pre-process data returned by the request from #getLookupRequest.\n *\n * The return value of this function will be cached, and any further queries for the given value\n * will use the cache rather than doing API requests.\n *\n * @protected\n * @method\n * @abstract\n * @param {Mixed} response Response from server\n * @return {Mixed} Cached result data\n */\nOO.ui.mixin.LookupElement.prototype.getLookupCacheDataFromResponse = null;\n\n/**\n * Get a list of menu option widgets from the (possibly cached) data returned by\n * #getLookupCacheDataFromResponse.\n *\n * @protected\n * @method\n * @abstract\n * @param {Mixed} data Cached result data, usually an array\n * @return {OO.ui.MenuOptionWidget[]} Menu items\n */\nOO.ui.mixin.LookupElement.prototype.getLookupMenuOptionsFromData = null;\n\n/**\n * Set the read-only state of the widget.\n *\n * This will also disable/enable the lookups functionality.\n *\n * @param {boolean} readOnly Make input read-only\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.setReadOnly = function ( readOnly ) {\n\t// Parent method\n\t// Note: Calling #setReadOnly this way assumes this is mixed into an OO.ui.TextInputWidget\n\tOO.ui.TextInputWidget.prototype.setReadOnly.call( this, readOnly );\n\n\t// During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor\n\tif ( this.isReadOnly() && this.lookupMenu ) {\n\t\tthis.closeLookupMenu();\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc OO.ui.mixin.RequestManager\n */\nOO.ui.mixin.LookupElement.prototype.getRequestQuery = function () {\n\treturn this.getValue();\n};\n\n/**\n * @inheritdoc OO.ui.mixin.RequestManager\n */\nOO.ui.mixin.LookupElement.prototype.getRequest = function () {\n\treturn this.getLookupRequest();\n};\n\n/**\n * @inheritdoc OO.ui.mixin.RequestManager\n */\nOO.ui.mixin.LookupElement.prototype.getRequestCacheDataFromResponse = function ( response ) {\n\treturn this.getLookupCacheDataFromResponse( response );\n};\n","/**\n * TabPanelLayouts are used within {@link OO.ui.IndexLayout index layouts} to create tab panels that\n * users can select and display from the index's optional {@link OO.ui.TabSelectWidget tab}\n * navigation. TabPanels are usually not instantiated directly, rather extended to include the\n * required content and functionality.\n *\n * Each tab panel must have a unique symbolic name, which is passed to the constructor. In addition,\n * the tab panel's tab item is customized (with a label) using the #setupTabItem method. See\n * {@link OO.ui.IndexLayout IndexLayout} for an example.\n *\n * @class\n * @extends OO.ui.PanelLayout\n *\n * @constructor\n * @param {string} name Unique symbolic name of tab panel\n * @param {Object} [config] Configuration options\n * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] Label for tab panel's tab\n */\nOO.ui.TabPanelLayout = function OoUiTabPanelLayout( name, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( name ) && config === undefined ) {\n\t\tconfig = name;\n\t\tname = config.name;\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( { scrollable: true }, config );\n\n\t// Parent constructor\n\tOO.ui.TabPanelLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.name = name;\n\tthis.label = config.label;\n\tthis.tabItem = null;\n\tthis.active = false;\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tabPanelLayout' )\n\t\t.attr( 'role', 'tabpanel' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TabPanelLayout, OO.ui.PanelLayout );\n\n/* Events */\n\n/**\n * An 'active' event is emitted when the tab panel becomes active. Tab panels become active when they are\n * shown in a index layout that is configured to display only one tab panel at a time.\n *\n * @event active\n * @param {boolean} active Tab panel is active\n */\n\n/* Methods */\n\n/**\n * Get the symbolic name of the tab panel.\n *\n * @return {string} Symbolic name of tab panel\n */\nOO.ui.TabPanelLayout.prototype.getName = function () {\n\treturn this.name;\n};\n\n/**\n * Check if tab panel is active.\n *\n * Tab panels become active when they are shown in a {@link OO.ui.IndexLayout index layout} that is configured to\n * display only one tab panel at a time. Additional CSS is applied to the tab panel's tab item to reflect the\n * active state.\n *\n * @return {boolean} Tab panel is active\n */\nOO.ui.TabPanelLayout.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Get tab item.\n *\n * The tab item allows users to access the tab panel from the index's tab\n * navigation. The tab item itself can be customized (with a label, level, etc.) using the #setupTabItem method.\n *\n * @return {OO.ui.TabOptionWidget|null} Tab option widget\n */\nOO.ui.TabPanelLayout.prototype.getTabItem = function () {\n\treturn this.tabItem;\n};\n\n/**\n * Set or unset the tab item.\n *\n * Specify a {@link OO.ui.TabOptionWidget tab option} to set it,\n * or `null` to clear the tab item. To customize the tab item itself (e.g., to set a label or tab\n * level), use #setupTabItem instead of this method.\n *\n * @param {OO.ui.TabOptionWidget|null} tabItem Tab option widget, null to clear\n * @chainable\n * @return {OO.ui.TabPanelLayout} The layout, for chaining\n */\nOO.ui.TabPanelLayout.prototype.setTabItem = function ( tabItem ) {\n\tthis.tabItem = tabItem || null;\n\tif ( tabItem ) {\n\t\tthis.setupTabItem();\n\t}\n\treturn this;\n};\n\n/**\n * Set up the tab item.\n *\n * Use this method to customize the tab item (e.g., to add a label or tab level). To set or unset\n * the tab item itself (with a {@link OO.ui.TabOptionWidget tab option} or `null`), use\n * the #setTabItem method instead.\n *\n * @param {OO.ui.TabOptionWidget} tabItem Tab option widget to set up\n * @chainable\n * @return {OO.ui.TabPanelLayout} The layout, for chaining\n */\nOO.ui.TabPanelLayout.prototype.setupTabItem = function () {\n\tthis.$element.attr( 'aria-labelledby', this.tabItem.getElementId() );\n\n\tthis.tabItem.$element.attr( 'aria-controls', this.getElementId() );\n\n\tif ( this.label ) {\n\t\tthis.tabItem.setLabel( this.label );\n\t}\n\treturn this;\n};\n\n/**\n * Set the tab panel to its 'active' state.\n *\n * Tab panels become active when they are shown in a index layout that is configured to display only\n * one tab panel at a time. Additional CSS is applied to the tab item to reflect the tab panel's\n * active state. Outside of the index context, setting the active state on a tab panel does nothing.\n *\n * @param {boolean} active Tab panel is active\n * @fires active\n */\nOO.ui.TabPanelLayout.prototype.setActive = function ( active ) {\n\tactive = !!active;\n\n\tif ( active !== this.active ) {\n\t\tthis.active = active;\n\t\tthis.$element.toggleClass( 'oo-ui-tabPanelLayout-active', this.active );\n\t\tthis.emit( 'active', this.active );\n\t}\n};\n","/**\n * PageLayouts are used within {@link OO.ui.BookletLayout booklet layouts} to create pages that users can select and display\n * from the booklet's optional {@link OO.ui.OutlineSelectWidget outline} navigation. Pages are usually not instantiated directly,\n * rather extended to include the required content and functionality.\n *\n * Each page must have a unique symbolic name, which is passed to the constructor. In addition, the page's outline\n * item is customized (with a label, outline level, etc.) using the #setupOutlineItem method. See\n * {@link OO.ui.BookletLayout BookletLayout} for an example.\n *\n * @class\n * @extends OO.ui.PanelLayout\n *\n * @constructor\n * @param {string} name Unique symbolic name of page\n * @param {Object} [config] Configuration options\n */\nOO.ui.PageLayout = function OoUiPageLayout( name, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( name ) && config === undefined ) {\n\t\tconfig = name;\n\t\tname = config.name;\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( { scrollable: true }, config );\n\n\t// Parent constructor\n\tOO.ui.PageLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.name = name;\n\tthis.outlineItem = null;\n\tthis.active = false;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-pageLayout' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PageLayout, OO.ui.PanelLayout );\n\n/* Events */\n\n/**\n * An 'active' event is emitted when the page becomes active. Pages become active when they are\n * shown in a booklet layout that is configured to display only one page at a time.\n *\n * @event active\n * @param {boolean} active Page is active\n */\n\n/* Methods */\n\n/**\n * Get the symbolic name of the page.\n *\n * @return {string} Symbolic name of page\n */\nOO.ui.PageLayout.prototype.getName = function () {\n\treturn this.name;\n};\n\n/**\n * Check if page is active.\n *\n * Pages become active when they are shown in a {@link OO.ui.BookletLayout booklet layout} that is configured to display\n * only one page at a time. Additional CSS is applied to the page's outline item to reflect the active state.\n *\n * @return {boolean} Page is active\n */\nOO.ui.PageLayout.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Get outline item.\n *\n * The outline item allows users to access the page from the booklet's outline\n * navigation. The outline item itself can be customized (with a label, level, etc.) using the #setupOutlineItem method.\n *\n * @return {OO.ui.OutlineOptionWidget|null} Outline option widget\n */\nOO.ui.PageLayout.prototype.getOutlineItem = function () {\n\treturn this.outlineItem;\n};\n\n/**\n * Set or unset the outline item.\n *\n * Specify an {@link OO.ui.OutlineOptionWidget outline option} to set it,\n * or `null` to clear the outline item. To customize the outline item itself (e.g., to set a label or outline\n * level), use #setupOutlineItem instead of this method.\n *\n * @param {OO.ui.OutlineOptionWidget|null} outlineItem Outline option widget, null to clear\n * @chainable\n * @return {OO.ui.PageLayout} The layout, for chaining\n */\nOO.ui.PageLayout.prototype.setOutlineItem = function ( outlineItem ) {\n\tthis.outlineItem = outlineItem || null;\n\tif ( outlineItem ) {\n\t\tthis.setupOutlineItem();\n\t}\n\treturn this;\n};\n\n/**\n * Set up the outline item.\n *\n * Use this method to customize the outline item (e.g., to add a label or outline level). To set or unset\n * the outline item itself (with an {@link OO.ui.OutlineOptionWidget outline option} or `null`), use\n * the #setOutlineItem method instead.\n *\n * @param {OO.ui.OutlineOptionWidget} outlineItem Outline option widget to set up\n * @chainable\n * @return {OO.ui.PageLayout} The layout, for chaining\n */\nOO.ui.PageLayout.prototype.setupOutlineItem = function () {\n\treturn this;\n};\n\n/**\n * Set the page to its 'active' state.\n *\n * Pages become active when they are shown in a booklet layout that is configured to display only one page at a time. Additional\n * CSS is applied to the outline item to reflect the page's active state. Outside of the booklet\n * context, setting the active state on a page does nothing.\n *\n * @param {boolean} active Page is active\n * @fires active\n */\nOO.ui.PageLayout.prototype.setActive = function ( active ) {\n\tactive = !!active;\n\n\tif ( active !== this.active ) {\n\t\tthis.active = active;\n\t\tthis.$element.toggleClass( 'oo-ui-pageLayout-active', active );\n\t\tthis.emit( 'active', this.active );\n\t}\n};\n","/**\n * StackLayouts contain a series of {@link OO.ui.PanelLayout panel layouts}. By default, only one panel is displayed\n * at a time, though the stack layout can also be configured to show all contained panels, one after another,\n * by setting the #continuous option to 'true'.\n *\n *     @example\n *     // A stack layout with two panels, configured to be displayed continuously\n *     var myStack = new OO.ui.StackLayout( {\n *         items: [\n *             new OO.ui.PanelLayout( {\n *                 $content: $( '<p>Panel One</p>' ),\n *                 padded: true,\n *                 framed: true\n *             } ),\n *             new OO.ui.PanelLayout( {\n *                 $content: $( '<p>Panel Two</p>' ),\n *                 padded: true,\n *                 framed: true\n *             } )\n *         ],\n *         continuous: true\n *     } );\n *     $( document.body ).append( myStack.$element );\n *\n * @class\n * @extends OO.ui.PanelLayout\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel is displayed at a time.\n * @cfg {OO.ui.Layout[]} [items] Panel layouts to add to the stack layout.\n */\nOO.ui.StackLayout = function OoUiStackLayout( config ) {\n\t// Configuration initialization\n\t// Make the layout scrollable in continuous mode, otherwise each\n\t// panel is responsible for its own scrolling.\n\tconfig = $.extend( { scrollable: !!( config && config.continuous ) }, config );\n\n\t// Parent constructor\n\tOO.ui.StackLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );\n\n\t// Properties\n\tthis.currentItem = null;\n\tthis.continuous = !!config.continuous;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-stackLayout' );\n\tif ( this.continuous ) {\n\t\tthis.$element.addClass( 'oo-ui-stackLayout-continuous' );\n\t\tthis.$element.on( 'scroll', OO.ui.debounce( this.onScroll.bind( this ), 250 ) );\n\t}\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.StackLayout, OO.ui.PanelLayout );\nOO.mixinClass( OO.ui.StackLayout, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * A 'set' event is emitted when panels are {@link #addItems added}, {@link #removeItems removed},\n * {@link #clearItems cleared} or {@link #setItem displayed}.\n *\n * @event set\n * @param {OO.ui.Layout|null} item Current panel or `null` if no panel is shown\n */\n\n/**\n * When used in continuous mode, this event is emitted when the user scrolls down\n * far enough such that currentItem is no longer visible.\n *\n * @event visibleItemChange\n * @param {OO.ui.PanelLayout} panel The next visible item in the layout\n */\n\n/* Methods */\n\n/**\n * Handle scroll events from the layout element\n *\n * @param {jQuery.Event} e\n * @fires visibleItemChange\n */\nOO.ui.StackLayout.prototype.onScroll = function () {\n\tvar currentRect,\n\t\tlen = this.items.length,\n\t\tcurrentIndex = this.items.indexOf( this.currentItem ),\n\t\tnewIndex = currentIndex,\n\t\tcontainerRect = this.$element[ 0 ].getBoundingClientRect();\n\n\tif ( !containerRect || ( !containerRect.top && !containerRect.bottom ) ) {\n\t\t// Can't get bounding rect, possibly not attached.\n\t\treturn;\n\t}\n\n\tfunction getRect( item ) {\n\t\treturn item.$element[ 0 ].getBoundingClientRect();\n\t}\n\n\tfunction isVisible( item ) {\n\t\tvar rect = getRect( item );\n\t\treturn rect.bottom > containerRect.top && rect.top < containerRect.bottom;\n\t}\n\n\tcurrentRect = getRect( this.currentItem );\n\n\tif ( currentRect.bottom < containerRect.top ) {\n\t\t// Scrolled down past current item\n\t\twhile ( ++newIndex < len ) {\n\t\t\tif ( isVisible( this.items[ newIndex ] ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else if ( currentRect.top > containerRect.bottom ) {\n\t\t// Scrolled up past current item\n\t\twhile ( --newIndex >= 0 ) {\n\t\t\tif ( isVisible( this.items[ newIndex ] ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( newIndex !== currentIndex ) {\n\t\tthis.emit( 'visibleItemChange', this.items[ newIndex ] );\n\t}\n};\n\n/**\n * Get the current panel.\n *\n * @return {OO.ui.Layout|null}\n */\nOO.ui.StackLayout.prototype.getCurrentItem = function () {\n\treturn this.currentItem;\n};\n\n/**\n * Unset the current item.\n *\n * @private\n * @param {OO.ui.StackLayout} layout\n * @fires set\n */\nOO.ui.StackLayout.prototype.unsetCurrentItem = function () {\n\tvar prevItem = this.currentItem;\n\tif ( prevItem === null ) {\n\t\treturn;\n\t}\n\n\tthis.currentItem = null;\n\tthis.emit( 'set', null );\n};\n\n/**\n * Add panel layouts to the stack layout.\n *\n * Panels will be added to the end of the stack layout array unless the optional index parameter specifies a different\n * insertion point. Adding a panel that is already in the stack will move it to the end of the array or the point specified\n * by the index.\n *\n * @param {OO.ui.Layout[]} items Panels to add\n * @param {number} [index] Index of the insertion point\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n */\nOO.ui.StackLayout.prototype.addItems = function ( items, index ) {\n\t// Update the visibility\n\tthis.updateHiddenState( items, this.currentItem );\n\n\t// Mixin method\n\tOO.ui.mixin.GroupElement.prototype.addItems.call( this, items, index );\n\n\tif ( !this.currentItem && items.length ) {\n\t\tthis.setItem( items[ 0 ] );\n\t}\n\n\treturn this;\n};\n\n/**\n * Remove the specified panels from the stack layout.\n *\n * Removed panels are detached from the DOM, not removed, so that they may be reused. To remove all panels,\n * you may wish to use the #clearItems method instead.\n *\n * @param {OO.ui.Layout[]} items Panels to remove\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n * @fires set\n */\nOO.ui.StackLayout.prototype.removeItems = function ( items ) {\n\t// Mixin method\n\tOO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );\n\n\tif ( items.indexOf( this.currentItem ) !== -1 ) {\n\t\tif ( this.items.length ) {\n\t\t\tthis.setItem( this.items[ 0 ] );\n\t\t} else {\n\t\t\tthis.unsetCurrentItem();\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Clear all panels from the stack layout.\n *\n * Cleared panels are detached from the DOM, not removed, so that they may be reused. To remove only\n * a subset of panels, use the #removeItems method.\n *\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n * @fires set\n */\nOO.ui.StackLayout.prototype.clearItems = function () {\n\tthis.unsetCurrentItem();\n\tOO.ui.mixin.GroupElement.prototype.clearItems.call( this );\n\n\treturn this;\n};\n\n/**\n * Show the specified panel.\n *\n * If another panel is currently displayed, it will be hidden.\n *\n * @param {OO.ui.Layout} item Panel to show\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n * @fires set\n */\nOO.ui.StackLayout.prototype.setItem = function ( item ) {\n\tif ( item !== this.currentItem ) {\n\t\tthis.updateHiddenState( this.items, item );\n\n\t\tif ( this.items.indexOf( item ) !== -1 ) {\n\t\t\tthis.currentItem = item;\n\t\t\tthis.emit( 'set', item );\n\t\t} else {\n\t\t\tthis.unsetCurrentItem();\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Reset the scroll offset of all panels, or the container if continuous\n *\n * @inheritdoc\n */\nOO.ui.StackLayout.prototype.resetScroll = function () {\n\tif ( this.continuous ) {\n\t\t// Parent method\n\t\treturn OO.ui.StackLayout.parent.prototype.resetScroll.call( this );\n\t}\n\t// Reset each panel\n\tthis.getItems().forEach( function ( panel ) {\n\t\tvar hidden = panel.$element.hasClass( 'oo-ui-element-hidden' );\n\t\t// Scroll can only be reset when panel is visible\n\t\tpanel.$element.removeClass( 'oo-ui-element-hidden' );\n\t\tpanel.resetScroll();\n\t\tif ( hidden ) {\n\t\t\tpanel.$element.addClass( 'oo-ui-element-hidden' );\n\t\t}\n\t} );\n\n\treturn this;\n};\n\n/**\n * Update the visibility of all items in case of non-continuous view.\n *\n * Ensure all items are hidden except for the selected one.\n * This method does nothing when the stack is continuous.\n *\n * @private\n * @param {OO.ui.Layout[]} items Item list iterate over\n * @param {OO.ui.Layout} [selectedItem] Selected item to show\n */\nOO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem ) {\n\tvar i, len;\n\n\tif ( !this.continuous ) {\n\t\tfor ( i = 0, len = items.length; i < len; i++ ) {\n\t\t\tif ( !selectedItem || selectedItem !== items[ i ] ) {\n\t\t\t\titems[ i ].$element.addClass( 'oo-ui-element-hidden' );\n\t\t\t\titems[ i ].$element.attr( 'aria-hidden', 'true' );\n\t\t\t}\n\t\t}\n\t\tif ( selectedItem ) {\n\t\t\tselectedItem.$element.removeClass( 'oo-ui-element-hidden' );\n\t\t\tselectedItem.$element.removeAttr( 'aria-hidden' );\n\t\t}\n\t}\n};\n","/**\n * MenuLayouts combine a menu and a content {@link OO.ui.PanelLayout panel}. The menu is positioned relative to the content (after, before, top, or bottom)\n * and its size is customized with the #menuSize config. The content area will fill all remaining space.\n *\n *     @example\n *     var menuLayout,\n *         menuPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),\n *         contentPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),\n *         select = new OO.ui.SelectWidget( {\n *             items: [\n *                 new OO.ui.OptionWidget( {\n *                     data: 'before',\n *                     label: 'Before'\n *                 } ),\n *                 new OO.ui.OptionWidget( {\n *                     data: 'after',\n *                     label: 'After'\n *                 } ),\n *                 new OO.ui.OptionWidget( {\n *                     data: 'top',\n *                     label: 'Top'\n *                 } ),\n *                 new OO.ui.OptionWidget( {\n *                     data: 'bottom',\n *                     label: 'Bottom'\n *                 } )\n *              ]\n *         } ).on( 'select', function ( item ) {\n *            menuLayout.setMenuPosition( item.getData() );\n *         } );\n *\n *     menuLayout = new OO.ui.MenuLayout( {\n *         position: 'top',\n *         menuPanel: menuPanel,\n *         contentPanel: contentPanel\n *     } )\n *     menuLayout.$menu.append(\n *         menuPanel.$element.append( '<b>Menu panel</b>', select.$element )\n *     );\n *     menuLayout.$content.append(\n *         contentPanel.$element.append( '<b>Content panel</b>', '<p>Note that the menu is positioned relative to the content panel: top, bottom, after, before.</p>')\n *     );\n *     $( document.body ).append( menuLayout.$element );\n *\n * If menu size needs to be overridden, it can be accomplished using CSS similar to the snippet\n * below. MenuLayout's CSS will override the appropriate values with 'auto' or '0' to display the\n * menu correctly. If `menuPosition` is known beforehand, CSS rules corresponding to other positions\n * may be omitted.\n *\n *     .oo-ui-menuLayout-menu {\n *         width: 200px;\n *         height: 200px;\n *     }\n *\n *     .oo-ui-menuLayout-content {\n *         top: 200px;\n *         left: 200px;\n *         right: 200px;\n *         bottom: 200px;\n *     }\n *\n * @class\n * @extends OO.ui.Layout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.PanelLayout} [menuPanel] Menu panel\n * @cfg {OO.ui.PanelLayout} [contentPanel] Content panel\n * @cfg {boolean} [expanded=true] Expand the layout to fill the entire parent element.\n * @cfg {boolean} [showMenu=true] Show menu\n * @cfg {string} [menuPosition='before'] Position of menu: `top`, `after`, `bottom` or `before`\n */\nOO.ui.MenuLayout = function OoUiMenuLayout( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\texpanded: true,\n\t\tshowMenu: true,\n\t\tmenuPosition: 'before'\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.MenuLayout.parent.call( this, config );\n\n\tthis.menuPanel = null;\n\tthis.contentPanel = null;\n\tthis.expanded = !!config.expanded;\n\t/**\n\t * Menu DOM node\n\t *\n\t * @property {jQuery}\n\t */\n\tthis.$menu = $( '<div>' );\n\t/**\n\t * Content DOM node\n\t *\n\t * @property {jQuery}\n\t */\n\tthis.$content = $( '<div>' );\n\n\t// Initialization\n\tthis.$menu\n\t\t.addClass( 'oo-ui-menuLayout-menu' );\n\tthis.$content.addClass( 'oo-ui-menuLayout-content' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-menuLayout' );\n\tif ( config.expanded ) {\n\t\tthis.$element.addClass( 'oo-ui-menuLayout-expanded' );\n\t} else {\n\t\tthis.$element.addClass( 'oo-ui-menuLayout-static' );\n\t}\n\tif ( config.menuPanel ) {\n\t\tthis.setMenuPanel( config.menuPanel );\n\t}\n\tif ( config.contentPanel ) {\n\t\tthis.setContentPanel( config.contentPanel );\n\t}\n\tthis.setMenuPosition( config.menuPosition );\n\tthis.toggleMenu( config.showMenu );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuLayout, OO.ui.Layout );\n\n/* Methods */\n\n/**\n * Toggle menu.\n *\n * @param {boolean} showMenu Show menu, omit to toggle\n * @chainable\n * @return {OO.ui.MenuLayout} The layout, for chaining\n */\nOO.ui.MenuLayout.prototype.toggleMenu = function ( showMenu ) {\n\tshowMenu = showMenu === undefined ? !this.showMenu : !!showMenu;\n\n\tif ( this.showMenu !== showMenu ) {\n\t\tthis.showMenu = showMenu;\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-menuLayout-showMenu', this.showMenu )\n\t\t\t.toggleClass( 'oo-ui-menuLayout-hideMenu', !this.showMenu );\n\t\tthis.$menu.attr( 'aria-hidden', this.showMenu ? 'false' : 'true' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Check if menu is visible\n *\n * @return {boolean} Menu is visible\n */\nOO.ui.MenuLayout.prototype.isMenuVisible = function () {\n\treturn this.showMenu;\n};\n\n/**\n * Set menu position.\n *\n * @param {string} position Position of menu, either `top`, `after`, `bottom` or `before`\n * @throws {Error} If position value is not supported\n * @chainable\n * @return {OO.ui.MenuLayout} The layout, for chaining\n */\nOO.ui.MenuLayout.prototype.setMenuPosition = function ( position ) {\n\tthis.$element.removeClass( 'oo-ui-menuLayout-' + this.menuPosition );\n\tthis.menuPosition = position;\n\tif ( this.menuPosition === 'top' || this.menuPosition === 'before' ) {\n\t\tthis.$element.append( this.$menu, this.$content );\n\t} else {\n\t\tthis.$element.append( this.$content, this.$menu );\n\t}\n\tthis.$element.addClass( 'oo-ui-menuLayout-' + position );\n\n\treturn this;\n};\n\n/**\n * Get menu position.\n *\n * @return {string} Menu position\n */\nOO.ui.MenuLayout.prototype.getMenuPosition = function () {\n\treturn this.menuPosition;\n};\n\n/**\n * Set the menu panel.\n *\n * @param {OO.ui.PanelLayout} menuPanel Menu panel\n */\nOO.ui.MenuLayout.prototype.setMenuPanel = function ( menuPanel ) {\n\tthis.menuPanel = menuPanel;\n\tthis.$menu.append( this.menuPanel.$element );\n};\n\n/**\n * Set the content panel.\n *\n * @param {OO.ui.PanelLayout} contentPanel Content panel\n */\nOO.ui.MenuLayout.prototype.setContentPanel = function ( contentPanel ) {\n\tthis.contentPanel = contentPanel;\n\tthis.$content.append( this.contentPanel.$element );\n};\n\n/**\n * Clear the menu panel.\n */\nOO.ui.MenuLayout.prototype.clearMenuPanel = function () {\n\tthis.menuPanel = null;\n\tthis.$menu.empty();\n};\n\n/**\n * Clear the content panel.\n */\nOO.ui.MenuLayout.prototype.clearContentPanel = function () {\n\tthis.contentPanel = null;\n\tthis.$content.empty();\n};\n\n/**\n * Reset the scroll offset of all panels and the tab select widget\n *\n * @inheritdoc\n */\nOO.ui.MenuLayout.prototype.resetScroll = function () {\n\tif ( this.menuPanel ) {\n\t\tthis.menuPanel.resetScroll();\n\t}\n\tif ( this.contentPanel ) {\n\t\tthis.contentPanel.resetScroll();\n\t}\n\n\treturn this;\n};\n","/**\n * BookletLayouts contain {@link OO.ui.PageLayout page layouts} as well as\n * an {@link OO.ui.OutlineSelectWidget outline} that allows users to easily navigate\n * through the pages and select which one to display. By default, only one page is\n * displayed at a time and the outline is hidden. When a user navigates to a new page,\n * the booklet layout automatically focuses on the first focusable element, unless the\n * default setting is changed. Optionally, booklets can be configured to show\n * {@link OO.ui.OutlineControlsWidget controls} for adding, moving, and removing items.\n *\n *     @example\n *     // Example of a BookletLayout that contains two PageLayouts.\n *\n *     function PageOneLayout( name, config ) {\n *         PageOneLayout.parent.call( this, name, config );\n *         this.$element.append( '<p>First page</p><p>(This booklet has an outline, displayed on the left)</p>' );\n *     }\n *     OO.inheritClass( PageOneLayout, OO.ui.PageLayout );\n *     PageOneLayout.prototype.setupOutlineItem = function () {\n *         this.outlineItem.setLabel( 'Page One' );\n *     };\n *\n *     function PageTwoLayout( name, config ) {\n *         PageTwoLayout.parent.call( this, name, config );\n *         this.$element.append( '<p>Second page</p>' );\n *     }\n *     OO.inheritClass( PageTwoLayout, OO.ui.PageLayout );\n *     PageTwoLayout.prototype.setupOutlineItem = function () {\n *         this.outlineItem.setLabel( 'Page Two' );\n *     };\n *\n *     var page1 = new PageOneLayout( 'one' ),\n *         page2 = new PageTwoLayout( 'two' );\n *\n *     var booklet = new OO.ui.BookletLayout( {\n *         outlined: true\n *     } );\n *\n *     booklet.addPages( [ page1, page2 ] );\n *     $( document.body ).append( booklet.$element );\n *\n * @class\n * @extends OO.ui.MenuLayout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [continuous=false] Show all pages, one after another\n * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is displayed. Disabled on mobile.\n * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the pages of the booklet.\n * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages\n */\nOO.ui.BookletLayout = function OoUiBookletLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.BookletLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.currentPageName = null;\n\tthis.pages = {};\n\tthis.ignoreFocus = false;\n\tthis.stackLayout = new OO.ui.StackLayout( {\n\t\tcontinuous: !!config.continuous,\n\t\texpanded: this.expanded\n\t} );\n\tthis.setContentPanel( this.stackLayout );\n\tthis.autoFocus = config.autoFocus === undefined || !!config.autoFocus;\n\tthis.outlineVisible = false;\n\tthis.outlined = !!config.outlined;\n\tif ( this.outlined ) {\n\t\tthis.editable = !!config.editable;\n\t\tthis.outlineControlsWidget = null;\n\t\tthis.outlineSelectWidget = new OO.ui.OutlineSelectWidget();\n\t\tthis.outlinePanel = new OO.ui.PanelLayout( {\n\t\t\texpanded: this.expanded,\n\t\t\tscrollable: true\n\t\t} );\n\t\tthis.setMenuPanel( this.outlinePanel );\n\t\tthis.outlineVisible = true;\n\t\tif ( this.editable ) {\n\t\t\tthis.outlineControlsWidget = new OO.ui.OutlineControlsWidget(\n\t\t\t\tthis.outlineSelectWidget\n\t\t\t);\n\t\t}\n\t}\n\tthis.toggleMenu( this.outlined );\n\n\t// Events\n\tthis.stackLayout.connect( this, { set: 'onStackLayoutSet' } );\n\tif ( this.outlined ) {\n\t\tthis.outlineSelectWidget.connect( this, { select: 'onOutlineSelectWidgetSelect' } );\n\t\tthis.scrolling = false;\n\t\tthis.stackLayout.connect( this, { visibleItemChange: 'onStackLayoutVisibleItemChange' } );\n\t}\n\tif ( this.autoFocus ) {\n\t\t// Event 'focus' does not bubble, but 'focusin' does\n\t\tthis.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );\n\t}\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-bookletLayout' );\n\tthis.stackLayout.$element.addClass( 'oo-ui-bookletLayout-stackLayout' );\n\tif ( this.outlined ) {\n\t\tthis.outlinePanel.$element\n\t\t\t.addClass( 'oo-ui-bookletLayout-outlinePanel' )\n\t\t\t.append( this.outlineSelectWidget.$element );\n\t\tif ( this.editable ) {\n\t\t\tthis.outlinePanel.$element\n\t\t\t\t.addClass( 'oo-ui-bookletLayout-outlinePanel-editable' )\n\t\t\t\t.append( this.outlineControlsWidget.$element );\n\t\t}\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.BookletLayout, OO.ui.MenuLayout );\n\n/* Events */\n\n/**\n * A 'set' event is emitted when a page is {@link #setPage set} to be displayed by the booklet layout.\n * @event set\n * @param {OO.ui.PageLayout} page Current page\n */\n\n/**\n * An 'add' event is emitted when pages are {@link #addPages added} to the booklet layout.\n *\n * @event add\n * @param {OO.ui.PageLayout[]} page Added pages\n * @param {number} index Index pages were added at\n */\n\n/**\n * A 'remove' event is emitted when pages are {@link #clearPages cleared} or\n * {@link #removePages removed} from the booklet.\n *\n * @event remove\n * @param {OO.ui.PageLayout[]} pages Removed pages\n */\n\n/* Methods */\n\n/**\n * Handle stack layout focus.\n *\n * @private\n * @param {jQuery.Event} e Focusin event\n */\nOO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {\n\tvar name, $target;\n\n\t// Find the page that an element was focused within\n\t$target = $( e.target ).closest( '.oo-ui-pageLayout' );\n\tfor ( name in this.pages ) {\n\t\t// Check for page match, exclude current page to find only page changes\n\t\tif ( this.pages[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentPageName ) {\n\t\t\tthis.setPage( name );\n\t\t\tbreak;\n\t\t}\n\t}\n};\n\n/**\n * Handle visibleItemChange events from the stackLayout\n *\n * The next visible page is set as the current page by selecting it\n * in the outline\n *\n * @param {OO.ui.PageLayout} page The next visible page in the layout\n */\nOO.ui.BookletLayout.prototype.onStackLayoutVisibleItemChange = function ( page ) {\n\t// Set a flag to so that the resulting call to #onStackLayoutSet doesn't\n\t// try and scroll the item into view again.\n\tthis.scrolling = true;\n\tthis.outlineSelectWidget.selectItemByData( page.getName() );\n\tthis.scrolling = false;\n};\n\n/**\n * Handle stack layout set events.\n *\n * @private\n * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel\n */\nOO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {\n\tvar promise, layout = this;\n\t// If everything is unselected, do nothing\n\tif ( !page ) {\n\t\treturn;\n\t}\n\t// For continuous BookletLayouts, scroll the selected page into view first\n\tif ( this.stackLayout.continuous && !this.scrolling ) {\n\t\tpromise = page.scrollElementIntoView();\n\t} else {\n\t\tpromise = $.Deferred().resolve();\n\t}\n\t// Focus the first element on the newly selected panel.\n\t// Don't focus if the page was set by scrolling.\n\tif ( this.autoFocus && !OO.ui.isMobile() && !this.scrolling ) {\n\t\tpromise.done( function () {\n\t\t\tlayout.focus();\n\t\t} );\n\t}\n};\n\n/**\n * Focus the first input in the current page.\n *\n * If no page is selected, the first selectable page will be selected.\n * If the focus is already in an element on the current page, nothing will happen.\n *\n * @param {number} [itemIndex] A specific item to focus on\n */\nOO.ui.BookletLayout.prototype.focus = function ( itemIndex ) {\n\tvar page,\n\t\titems = this.stackLayout.getItems();\n\n\tif ( itemIndex !== undefined && items[ itemIndex ] ) {\n\t\tpage = items[ itemIndex ];\n\t} else {\n\t\tpage = this.stackLayout.getCurrentItem();\n\t}\n\n\tif ( !page && this.outlined ) {\n\t\tthis.selectFirstSelectablePage();\n\t\tpage = this.stackLayout.getCurrentItem();\n\t}\n\tif ( !page ) {\n\t\treturn;\n\t}\n\t// Only change the focus if is not already in the current page\n\tif ( !OO.ui.contains( page.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {\n\t\tpage.focus();\n\t}\n};\n\n/**\n * Find the first focusable input in the booklet layout and focus\n * on it.\n */\nOO.ui.BookletLayout.prototype.focusFirstFocusable = function () {\n\tOO.ui.findFocusable( this.stackLayout.$element ).focus();\n};\n\n/**\n * Handle outline widget select events.\n *\n * @private\n * @param {OO.ui.OptionWidget|null} item Selected item\n */\nOO.ui.BookletLayout.prototype.onOutlineSelectWidgetSelect = function ( item ) {\n\tif ( item ) {\n\t\tthis.setPage( item.getData() );\n\t}\n};\n\n/**\n * Check if booklet has an outline.\n *\n * @return {boolean} Booklet has an outline\n */\nOO.ui.BookletLayout.prototype.isOutlined = function () {\n\treturn this.outlined;\n};\n\n/**\n * Check if booklet has editing controls.\n *\n * @return {boolean} Booklet is editable\n */\nOO.ui.BookletLayout.prototype.isEditable = function () {\n\treturn this.editable;\n};\n\n/**\n * Check if booklet has a visible outline.\n *\n * @return {boolean} Outline is visible\n */\nOO.ui.BookletLayout.prototype.isOutlineVisible = function () {\n\treturn this.outlined && this.outlineVisible;\n};\n\n/**\n * Hide or show the outline.\n *\n * @param {boolean} [show] Show outline, omit to invert current state\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {\n\tvar booklet = this;\n\n\tif ( this.outlined ) {\n\t\tshow = show === undefined ? !this.outlineVisible : !!show;\n\t\tthis.outlineVisible = show;\n\t\tthis.toggleMenu( show );\n\t\tif ( show && this.editable ) {\n\t\t\t// HACK: Kill dumb scrollbars when the sidebar stops animating, see T161798. Only necessary when\n\t\t\t// outline controls are present, delay matches transition on `.oo-ui-menuLayout-menu`.\n\t\t\tsetTimeout( function () {\n\t\t\t\tOO.ui.Element.static.reconsiderScrollbars( booklet.outlinePanel.$element[ 0 ] );\n\t\t\t}, OO.ui.theme.getDialogTransitionDuration() );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Find the page closest to the specified page.\n *\n * @param {OO.ui.PageLayout} page Page to use as a reference point\n * @return {OO.ui.PageLayout|null} Page closest to the specified page\n */\nOO.ui.BookletLayout.prototype.findClosestPage = function ( page ) {\n\tvar next, prev, level,\n\t\tpages = this.stackLayout.getItems(),\n\t\tindex = pages.indexOf( page );\n\n\tif ( index !== -1 ) {\n\t\tnext = pages[ index + 1 ];\n\t\tprev = pages[ index - 1 ];\n\t\t// Prefer adjacent pages at the same level\n\t\tif ( this.outlined ) {\n\t\t\tlevel = this.outlineSelectWidget.findItemFromData( page.getName() ).getLevel();\n\t\t\tif (\n\t\t\t\tprev &&\n\t\t\t\tlevel === this.outlineSelectWidget.findItemFromData( prev.getName() ).getLevel()\n\t\t\t) {\n\t\t\t\treturn prev;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tnext &&\n\t\t\t\tlevel === this.outlineSelectWidget.findItemFromData( next.getName() ).getLevel()\n\t\t\t) {\n\t\t\t\treturn next;\n\t\t\t}\n\t\t}\n\t}\n\treturn prev || next || null;\n};\n\n/**\n * Get the outline widget.\n *\n * If the booklet is not outlined, the method will return `null`.\n *\n * @return {OO.ui.OutlineSelectWidget|null} Outline widget, or null if the booklet is not outlined\n */\nOO.ui.BookletLayout.prototype.getOutline = function () {\n\treturn this.outlineSelectWidget;\n};\n\n/**\n * Get the outline controls widget.\n *\n * If the outline is not editable, the method will return `null`.\n *\n * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget.\n */\nOO.ui.BookletLayout.prototype.getOutlineControls = function () {\n\treturn this.outlineControlsWidget;\n};\n\n/**\n * Get a page by its symbolic name.\n *\n * @param {string} name Symbolic name of page\n * @return {OO.ui.PageLayout|undefined} Page, if found\n */\nOO.ui.BookletLayout.prototype.getPage = function ( name ) {\n\treturn this.pages[ name ];\n};\n\n/**\n * Get the current page.\n *\n * @return {OO.ui.PageLayout|undefined} Current page, if found\n */\nOO.ui.BookletLayout.prototype.getCurrentPage = function () {\n\tvar name = this.getCurrentPageName();\n\treturn name ? this.getPage( name ) : undefined;\n};\n\n/**\n * Get the symbolic name of the current page.\n *\n * @return {string|null} Symbolic name of the current page\n */\nOO.ui.BookletLayout.prototype.getCurrentPageName = function () {\n\treturn this.currentPageName;\n};\n\n/**\n * Add pages to the booklet layout\n *\n * When pages are added with the same names as existing pages, the existing pages will be\n * automatically removed before the new pages are added.\n *\n * @param {OO.ui.PageLayout[]} pages Pages to add\n * @param {number} index Index of the insertion point\n * @fires add\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {\n\tvar i, len, name, page, item, currentIndex,\n\t\tstackLayoutPages = this.stackLayout.getItems(),\n\t\tremove = [],\n\t\titems = [];\n\n\t// Remove pages with same names\n\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\tpage = pages[ i ];\n\t\tname = page.getName();\n\n\t\tif ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) {\n\t\t\t// Correct the insertion index\n\t\t\tcurrentIndex = stackLayoutPages.indexOf( this.pages[ name ] );\n\t\t\tif ( currentIndex !== -1 && currentIndex + 1 < index ) {\n\t\t\t\tindex--;\n\t\t\t}\n\t\t\tremove.push( this.pages[ name ] );\n\t\t}\n\t}\n\tif ( remove.length ) {\n\t\tthis.removePages( remove );\n\t}\n\n\t// Add new pages\n\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\tpage = pages[ i ];\n\t\tname = page.getName();\n\t\tthis.pages[ page.getName() ] = page;\n\t\tif ( this.outlined ) {\n\t\t\titem = new OO.ui.OutlineOptionWidget( { data: name } );\n\t\t\tpage.setOutlineItem( item );\n\t\t\titems.push( item );\n\t\t}\n\t}\n\n\tif ( this.outlined && items.length ) {\n\t\tthis.outlineSelectWidget.addItems( items, index );\n\t\tthis.selectFirstSelectablePage();\n\t}\n\tthis.stackLayout.addItems( pages, index );\n\tthis.emit( 'add', pages, index );\n\n\treturn this;\n};\n\n/**\n * Remove the specified pages from the booklet layout.\n *\n * To remove all pages from the booklet, you may wish to use the #clearPages method instead.\n *\n * @param {OO.ui.PageLayout[]} pages An array of pages to remove\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.removePages = function ( pages ) {\n\tvar i, len, name, page,\n\t\titems = [];\n\n\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\tpage = pages[ i ];\n\t\tname = page.getName();\n\t\tdelete this.pages[ name ];\n\t\tif ( this.outlined ) {\n\t\t\titems.push( this.outlineSelectWidget.findItemFromData( name ) );\n\t\t\tpage.setOutlineItem( null );\n\t\t}\n\t}\n\tif ( this.outlined && items.length ) {\n\t\tthis.outlineSelectWidget.removeItems( items );\n\t\tthis.selectFirstSelectablePage();\n\t}\n\tthis.stackLayout.removeItems( pages );\n\tthis.emit( 'remove', pages );\n\n\treturn this;\n};\n\n/**\n * Clear all pages from the booklet layout.\n *\n * To remove only a subset of pages from the booklet, use the #removePages method.\n *\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.clearPages = function () {\n\tvar i, len,\n\t\tpages = this.stackLayout.getItems();\n\n\tthis.pages = {};\n\tthis.currentPageName = null;\n\tif ( this.outlined ) {\n\t\tthis.outlineSelectWidget.clearItems();\n\t\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\t\tpages[ i ].setOutlineItem( null );\n\t\t}\n\t}\n\tthis.stackLayout.clearItems();\n\n\tthis.emit( 'remove', pages );\n\n\treturn this;\n};\n\n/**\n * Set the current page by symbolic name.\n *\n * @fires set\n * @param {string} name Symbolic name of page\n */\nOO.ui.BookletLayout.prototype.setPage = function ( name ) {\n\tvar selectedItem,\n\t\t$focused,\n\t\tpage = this.pages[ name ],\n\t\tpreviousPage = this.currentPageName && this.pages[ this.currentPageName ];\n\n\tif ( name !== this.currentPageName ) {\n\t\tif ( this.outlined ) {\n\t\t\tselectedItem = this.outlineSelectWidget.findSelectedItem();\n\t\t\tif ( selectedItem && selectedItem.getData() !== name ) {\n\t\t\t\tthis.outlineSelectWidget.selectItemByData( name );\n\t\t\t}\n\t\t}\n\t\tif ( page ) {\n\t\t\tif ( previousPage ) {\n\t\t\t\tpreviousPage.setActive( false );\n\t\t\t\t// Blur anything focused if the next page doesn't have anything focusable.\n\t\t\t\t// This is not needed if the next page has something focusable (because once it is focused\n\t\t\t\t// this blur happens automatically). If the layout is non-continuous, this check is\n\t\t\t\t// meaningless because the next page is not visible yet and thus can't hold focus.\n\t\t\t\tif (\n\t\t\t\t\tthis.autoFocus &&\n\t\t\t\t\t!OO.ui.isMobile() &&\n\t\t\t\t\tthis.stackLayout.continuous &&\n\t\t\t\t\tOO.ui.findFocusable( page.$element ).length !== 0\n\t\t\t\t) {\n\t\t\t\t\t$focused = previousPage.$element.find( ':focus' );\n\t\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentPageName = name;\n\t\t\tpage.setActive( true );\n\t\t\tthis.stackLayout.setItem( page );\n\t\t\tif ( !this.stackLayout.continuous && previousPage ) {\n\t\t\t\t// This should not be necessary, since any inputs on the previous page should have been\n\t\t\t\t// blurred when it was hidden, but browsers are not very consistent about this.\n\t\t\t\t$focused = previousPage.$element.find( ':focus' );\n\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.emit( 'set', page );\n\t\t}\n\t}\n};\n\n/**\n * For outlined-continuous booklets, also reset the outlineSelectWidget to the first item.\n *\n * @inheritdoc\n */\nOO.ui.BookletLayout.prototype.resetScroll = function () {\n\t// Parent method\n\tOO.ui.BookletLayout.parent.prototype.resetScroll.call( this );\n\n\tif ( this.outlined && this.stackLayout.continuous && this.outlineSelectWidget.findFirstSelectableItem() ) {\n\t\tthis.scrolling = true;\n\t\tthis.outlineSelectWidget.selectItem( this.outlineSelectWidget.findFirstSelectableItem() );\n\t\tthis.scrolling = false;\n\t}\n\treturn this;\n};\n\n/**\n * Select the first selectable page.\n *\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {\n\tif ( !this.outlineSelectWidget.findSelectedItem() ) {\n\t\tthis.outlineSelectWidget.selectItem( this.outlineSelectWidget.findFirstSelectableItem() );\n\t}\n\n\treturn this;\n};\n","/**\n * IndexLayouts contain {@link OO.ui.TabPanelLayout tab panel layouts} as well as\n * {@link OO.ui.TabSelectWidget tabs} that allow users to easily navigate through the tab panels and\n * select which one to display. By default, only one tab panel is displayed at a time. When a user\n * navigates to a new tab panel, the index layout automatically focuses on the first focusable element,\n * unless the default setting is changed.\n *\n * TODO: This class is similar to BookletLayout, we may want to refactor to reduce duplication\n *\n *     @example\n *     // Example of a IndexLayout that contains two TabPanelLayouts.\n *\n *     function TabPanelOneLayout( name, config ) {\n *         TabPanelOneLayout.parent.call( this, name, config );\n *         this.$element.append( '<p>First tab panel</p>' );\n *     }\n *     OO.inheritClass( TabPanelOneLayout, OO.ui.TabPanelLayout );\n *     TabPanelOneLayout.prototype.setupTabItem = function () {\n *         this.tabItem.setLabel( 'Tab panel one' );\n *     };\n *\n *     var tabPanel1 = new TabPanelOneLayout( 'one' ),\n *         tabPanel2 = new OO.ui.TabPanelLayout( 'two', { label: 'Tab panel two' } );\n *\n *     tabPanel2.$element.append( '<p>Second tab panel</p>' );\n *\n *     var index = new OO.ui.IndexLayout();\n *\n *     index.addTabPanels( [ tabPanel1, tabPanel2 ] );\n *     $( document.body ).append( index.$element );\n *\n * @class\n * @extends OO.ui.MenuLayout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [continuous=false] Show all tab panels, one after another\n * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new tab panel is displayed. Disabled on mobile.\n */\nOO.ui.IndexLayout = function OoUiIndexLayout( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {}, config, { menuPosition: 'top' } );\n\n\t// Parent constructor\n\tOO.ui.IndexLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.currentTabPanelName = null;\n\tthis.tabPanels = {};\n\n\tthis.ignoreFocus = false;\n\tthis.stackLayout = new OO.ui.StackLayout( {\n\t\tcontinuous: !!config.continuous,\n\t\texpanded: this.expanded\n\t} );\n\tthis.setContentPanel( this.stackLayout );\n\tthis.autoFocus = config.autoFocus === undefined || !!config.autoFocus;\n\n\tthis.tabSelectWidget = new OO.ui.TabSelectWidget();\n\tthis.tabPanel = new OO.ui.PanelLayout( {\n\t\texpanded: this.expanded\n\t} );\n\tthis.setMenuPanel( this.tabPanel );\n\n\tthis.toggleMenu( true );\n\n\t// Events\n\tthis.stackLayout.connect( this, { set: 'onStackLayoutSet' } );\n\tthis.tabSelectWidget.connect( this, { select: 'onTabSelectWidgetSelect' } );\n\tif ( this.autoFocus ) {\n\t\t// Event 'focus' does not bubble, but 'focusin' does\n\t\tthis.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );\n\t}\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-indexLayout' );\n\tthis.stackLayout.$element.addClass( 'oo-ui-indexLayout-stackLayout' );\n\tthis.tabPanel.$element\n\t\t.addClass( 'oo-ui-indexLayout-tabPanel' )\n\t\t.append( this.tabSelectWidget.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.IndexLayout, OO.ui.MenuLayout );\n\n/* Events */\n\n/**\n * A 'set' event is emitted when a tab panel is {@link #setTabPanel set} to be displayed by the index layout.\n * @event set\n * @param {OO.ui.TabPanelLayout} tabPanel Current tab panel\n */\n\n/**\n * An 'add' event is emitted when tab panels are {@link #addTabPanels added} to the index layout.\n *\n * @event add\n * @param {OO.ui.TabPanelLayout[]} tabPanel Added tab panels\n * @param {number} index Index tab panels were added at\n */\n\n/**\n * A 'remove' event is emitted when tab panels are {@link #clearTabPanels cleared} or\n * {@link #removeTabPanels removed} from the index.\n *\n * @event remove\n * @param {OO.ui.TabPanelLayout[]} tabPanel Removed tab panels\n */\n\n/* Methods */\n\n/**\n * Handle stack layout focus.\n *\n * @private\n * @param {jQuery.Event} e Focusing event\n */\nOO.ui.IndexLayout.prototype.onStackLayoutFocus = function ( e ) {\n\tvar name, $target;\n\n\t// Find the tab panel that an element was focused within\n\t$target = $( e.target ).closest( '.oo-ui-tabPanelLayout' );\n\tfor ( name in this.tabPanels ) {\n\t\t// Check for tab panel match, exclude current tab panel to find only tab panel changes\n\t\tif ( this.tabPanels[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentTabPanelName ) {\n\t\t\tthis.setTabPanel( name );\n\t\t\tbreak;\n\t\t}\n\t}\n};\n\n/**\n * Handle stack layout set events.\n *\n * @private\n * @param {OO.ui.PanelLayout|null} tabPanel The tab panel that is now the current panel\n */\nOO.ui.IndexLayout.prototype.onStackLayoutSet = function ( tabPanel ) {\n\t// If everything is unselected, do nothing\n\tif ( !tabPanel ) {\n\t\treturn;\n\t}\n\t// Focus the first element on the newly selected panel\n\tif ( this.autoFocus && !OO.ui.isMobile() ) {\n\t\tthis.focus();\n\t}\n};\n\n/**\n * Focus the first input in the current tab panel.\n *\n * If no tab panel is selected, the first selectable tab panel will be selected.\n * If the focus is already in an element on the current tab panel, nothing will happen.\n *\n * @param {number} [itemIndex] A specific item to focus on\n */\nOO.ui.IndexLayout.prototype.focus = function ( itemIndex ) {\n\tvar tabPanel,\n\t\titems = this.stackLayout.getItems();\n\n\tif ( itemIndex !== undefined && items[ itemIndex ] ) {\n\t\ttabPanel = items[ itemIndex ];\n\t} else {\n\t\ttabPanel = this.stackLayout.getCurrentItem();\n\t}\n\n\tif ( !tabPanel ) {\n\t\tthis.selectFirstSelectableTabPanel();\n\t\ttabPanel = this.stackLayout.getCurrentItem();\n\t}\n\tif ( !tabPanel ) {\n\t\treturn;\n\t}\n\t// Only change the focus if is not already in the current page\n\tif ( !OO.ui.contains( tabPanel.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {\n\t\ttabPanel.focus();\n\t}\n};\n\n/**\n * Find the first focusable input in the index layout and focus\n * on it.\n */\nOO.ui.IndexLayout.prototype.focusFirstFocusable = function () {\n\tOO.ui.findFocusable( this.stackLayout.$element ).focus();\n};\n\n/**\n * Handle tab widget select events.\n *\n * @private\n * @param {OO.ui.OptionWidget|null} item Selected item\n */\nOO.ui.IndexLayout.prototype.onTabSelectWidgetSelect = function ( item ) {\n\tif ( item ) {\n\t\tthis.setTabPanel( item.getData() );\n\t}\n};\n\n/**\n * Get the tab panel closest to the specified tab panel.\n *\n * @param {OO.ui.TabPanelLayout} tabPanel Tab panel to use as a reference point\n * @return {OO.ui.TabPanelLayout|null} Tab panel closest to the specified\n */\nOO.ui.IndexLayout.prototype.getClosestTabPanel = function ( tabPanel ) {\n\tvar next, prev, level,\n\t\ttabPanels = this.stackLayout.getItems(),\n\t\tindex = tabPanels.indexOf( tabPanel );\n\n\tif ( index !== -1 ) {\n\t\tnext = tabPanels[ index + 1 ];\n\t\tprev = tabPanels[ index - 1 ];\n\t\t// Prefer adjacent tab panels at the same level\n\t\tlevel = this.tabSelectWidget.findItemFromData( tabPanel.getName() ).getLevel();\n\t\tif (\n\t\t\tprev &&\n\t\t\tlevel === this.tabSelectWidget.findItemFromData( prev.getName() ).getLevel()\n\t\t) {\n\t\t\treturn prev;\n\t\t}\n\t\tif (\n\t\t\tnext &&\n\t\t\tlevel === this.tabSelectWidget.findItemFromData( next.getName() ).getLevel()\n\t\t) {\n\t\t\treturn next;\n\t\t}\n\t}\n\treturn prev || next || null;\n};\n\n/**\n * Get the tabs widget.\n *\n * @return {OO.ui.TabSelectWidget} Tabs widget\n */\nOO.ui.IndexLayout.prototype.getTabs = function () {\n\treturn this.tabSelectWidget;\n};\n\n/**\n * Get a tab panel by its symbolic name.\n *\n * @param {string} name Symbolic name of tab panel\n * @return {OO.ui.TabPanelLayout|undefined} Tab panel, if found\n */\nOO.ui.IndexLayout.prototype.getTabPanel = function ( name ) {\n\treturn this.tabPanels[ name ];\n};\n\n/**\n * Get the current tab panel.\n *\n * @return {OO.ui.TabPanelLayout|undefined} Current tab panel, if found\n */\nOO.ui.IndexLayout.prototype.getCurrentTabPanel = function () {\n\tvar name = this.getCurrentTabPanelName();\n\treturn name ? this.getTabPanel( name ) : undefined;\n};\n\n/**\n * Get the symbolic name of the current tab panel.\n *\n * @return {string|null} Symbolic name of the current tab panel\n */\nOO.ui.IndexLayout.prototype.getCurrentTabPanelName = function () {\n\treturn this.currentTabPanelName;\n};\n\n/**\n * Add tab panels to the index layout\n *\n * When tab panels are added with the same names as existing tab panels, the existing tab panels\n * will be automatically removed before the new tab panels are added.\n *\n * @param {OO.ui.TabPanelLayout[]} tabPanels Tab panels to add\n * @param {number} index Index of the insertion point\n * @fires add\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.addTabPanels = function ( tabPanels, index ) {\n\tvar i, len, name, tabPanel, item, currentIndex,\n\t\tstackLayoutTabPanels = this.stackLayout.getItems(),\n\t\tremove = [],\n\t\titems = [];\n\n\t// Remove tab panels with same names\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanel = tabPanels[ i ];\n\t\tname = tabPanel.getName();\n\n\t\tif ( Object.prototype.hasOwnProperty.call( this.tabPanels, name ) ) {\n\t\t\t// Correct the insertion index\n\t\t\tcurrentIndex = stackLayoutTabPanels.indexOf( this.tabPanels[ name ] );\n\t\t\tif ( currentIndex !== -1 && currentIndex + 1 < index ) {\n\t\t\t\tindex--;\n\t\t\t}\n\t\t\tremove.push( this.tabPanels[ name ] );\n\t\t}\n\t}\n\tif ( remove.length ) {\n\t\tthis.removeTabPanels( remove );\n\t}\n\n\t// Add new tab panels\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanel = tabPanels[ i ];\n\t\tname = tabPanel.getName();\n\t\tthis.tabPanels[ tabPanel.getName() ] = tabPanel;\n\t\titem = new OO.ui.TabOptionWidget( { data: name } );\n\t\ttabPanel.setTabItem( item );\n\t\titems.push( item );\n\t}\n\n\tif ( items.length ) {\n\t\tthis.tabSelectWidget.addItems( items, index );\n\t\tthis.selectFirstSelectableTabPanel();\n\t}\n\tthis.stackLayout.addItems( tabPanels, index );\n\tthis.emit( 'add', tabPanels, index );\n\n\treturn this;\n};\n\n/**\n * Remove the specified tab panels from the index layout.\n *\n * To remove all tab panels from the index, you may wish to use the #clearTabPanels method instead.\n *\n * @param {OO.ui.TabPanelLayout[]} tabPanels An array of tab panels to remove\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.removeTabPanels = function ( tabPanels ) {\n\tvar i, len, name, tabPanel,\n\t\titems = [];\n\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanel = tabPanels[ i ];\n\t\tname = tabPanel.getName();\n\t\tdelete this.tabPanels[ name ];\n\t\titems.push( this.tabSelectWidget.findItemFromData( name ) );\n\t\ttabPanel.setTabItem( null );\n\t}\n\tif ( items.length ) {\n\t\tthis.tabSelectWidget.removeItems( items );\n\t\tthis.selectFirstSelectableTabPanel();\n\t}\n\tthis.stackLayout.removeItems( tabPanels );\n\tthis.emit( 'remove', tabPanels );\n\n\treturn this;\n};\n\n/**\n * Clear all tab panels from the index layout.\n *\n * To remove only a subset of tab panels from the index, use the #removeTabPanels method.\n *\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.clearTabPanels = function () {\n\tvar i, len,\n\t\ttabPanels = this.stackLayout.getItems();\n\n\tthis.tabPanels = {};\n\tthis.currentTabPanelName = null;\n\tthis.tabSelectWidget.clearItems();\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanels[ i ].setTabItem( null );\n\t}\n\tthis.stackLayout.clearItems();\n\n\tthis.emit( 'remove', tabPanels );\n\n\treturn this;\n};\n\n/**\n * Set the current tab panel by symbolic name.\n *\n * @fires set\n * @param {string} name Symbolic name of tab panel\n */\nOO.ui.IndexLayout.prototype.setTabPanel = function ( name ) {\n\tvar selectedItem,\n\t\t$focused,\n\t\tpreviousTabPanel,\n\t\ttabPanel = this.tabPanels[ name ];\n\n\tif ( name !== this.currentTabPanelName ) {\n\t\tpreviousTabPanel = this.getCurrentTabPanel();\n\t\tselectedItem = this.tabSelectWidget.findSelectedItem();\n\t\tif ( selectedItem && selectedItem.getData() !== name ) {\n\t\t\tthis.tabSelectWidget.selectItemByData( name );\n\t\t}\n\t\tif ( tabPanel ) {\n\t\t\tif ( previousTabPanel ) {\n\t\t\t\tpreviousTabPanel.setActive( false );\n\t\t\t\t// Blur anything focused if the next tab panel doesn't have anything focusable.\n\t\t\t\t// This is not needed if the next tab panel has something focusable (because once it is focused\n\t\t\t\t// this blur happens automatically). If the layout is non-continuous, this check is\n\t\t\t\t// meaningless because the next tab panel is not visible yet and thus can't hold focus.\n\t\t\t\tif (\n\t\t\t\t\tthis.autoFocus &&\n\t\t\t\t\t!OO.ui.isMobile() &&\n\t\t\t\t\tthis.stackLayout.continuous &&\n\t\t\t\t\tOO.ui.findFocusable( tabPanel.$element ).length !== 0\n\t\t\t\t) {\n\t\t\t\t\t$focused = previousTabPanel.$element.find( ':focus' );\n\t\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentTabPanelName = name;\n\t\t\ttabPanel.setActive( true );\n\t\t\tthis.stackLayout.setItem( tabPanel );\n\t\t\tif ( !this.stackLayout.continuous && previousTabPanel ) {\n\t\t\t\t// This should not be necessary, since any inputs on the previous tab panel should have been\n\t\t\t\t// blurred when it was hidden, but browsers are not very consistent about this.\n\t\t\t\t$focused = previousTabPanel.$element.find( ':focus' );\n\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.emit( 'set', tabPanel );\n\t\t}\n\t}\n};\n\n/**\n * Select the first selectable tab panel.\n *\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.selectFirstSelectableTabPanel = function () {\n\tif ( !this.tabSelectWidget.findSelectedItem() ) {\n\t\tthis.tabSelectWidget.selectItem( this.tabSelectWidget.findFirstSelectableItem() );\n\t}\n\n\treturn this;\n};\n","/**\n * ToggleWidget implements basic behavior of widgets with an on/off state.\n * Please see OO.ui.ToggleButtonWidget and OO.ui.ToggleSwitchWidget for examples.\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [value=false] The toggle’s initial on/off state.\n *  By default, the toggle is in the 'off' state.\n */\nOO.ui.ToggleWidget = function OoUiToggleWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ToggleWidget.parent.call( this, config );\n\n\t// Mixin constructor\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.value = null;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-toggleWidget' );\n\tthis.setValue( !!config.value );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToggleWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.ToggleWidget, OO.ui.mixin.TitledElement );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the on/off state of the toggle changes.\n *\n * @param {boolean} value Value representing the new state of the toggle\n */\n\n/* Methods */\n\n/**\n * Get the value representing the toggle’s state.\n *\n * @return {boolean} The on/off state of the toggle\n */\nOO.ui.ToggleWidget.prototype.getValue = function () {\n\treturn this.value;\n};\n\n/**\n * Set the state of the toggle: `true` for 'on', `false` for 'off'.\n *\n * @param {boolean} value The state of the toggle\n * @fires change\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ToggleWidget.prototype.setValue = function ( value ) {\n\tvalue = !!value;\n\tif ( this.value !== value ) {\n\t\tthis.value = value;\n\t\tthis.emit( 'change', value );\n\t\tthis.$element.toggleClass( 'oo-ui-toggleWidget-on', value );\n\t\tthis.$element.toggleClass( 'oo-ui-toggleWidget-off', !value );\n\t}\n\treturn this;\n};\n","/**\n * ToggleButtons are buttons that have a state (‘on’ or ‘off’) that is represented by a\n * Boolean value. Like other {@link OO.ui.ButtonWidget buttons}, toggle buttons can be\n * configured with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators},\n * {@link OO.ui.mixin.TitledElement titles}, {@link OO.ui.mixin.FlaggedElement styling flags},\n * and {@link OO.ui.mixin.LabelElement labels}. Please see\n * the [OOUI documentation][1] on MediaWiki for more information.\n *\n *     @example\n *     // Toggle buttons in the 'off' and 'on' state.\n *     var toggleButton1 = new OO.ui.ToggleButtonWidget( {\n *             label: 'Toggle Button off'\n *         } ),\n *         toggleButton2 = new OO.ui.ToggleButtonWidget( {\n *             label: 'Toggle Button on',\n *             value: true\n *         } );\n *     // Append the buttons to the DOM.\n *     $( document.body ).append( toggleButton1.$element, toggleButton2.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches#Toggle_buttons\n *\n * @class\n * @extends OO.ui.ToggleWidget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [value=false] The toggle button’s initial on/off\n *  state. By default, the button is in the 'off' state.\n */\nOO.ui.ToggleButtonWidget = function OoUiToggleButtonWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ToggleButtonWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, $.extend( {}, config, { active: this.active } ) );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );\n\n\t// Events\n\tthis.connect( this, { click: 'onAction' } );\n\n\t// Initialization\n\tthis.$button.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element\n\t\t.addClass( 'oo-ui-toggleButtonWidget' )\n\t\t.append( this.$button );\n\tthis.setTitledElement( this.$button );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToggleButtonWidget, OO.ui.ToggleWidget );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ToggleButtonWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * Handle the button action being triggered.\n *\n * @private\n */\nOO.ui.ToggleButtonWidget.prototype.onAction = function () {\n\tthis.setValue( !this.value );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleButtonWidget.prototype.setValue = function ( value ) {\n\tvalue = !!value;\n\tif ( value !== this.value ) {\n\t\t// Might be called from parent constructor before ButtonElement constructor\n\t\tif ( this.$button ) {\n\t\t\tthis.$button.attr( 'aria-pressed', value.toString() );\n\t\t}\n\t\tthis.setActive( value );\n\t}\n\n\t// Parent method\n\tOO.ui.ToggleButtonWidget.parent.prototype.setValue.call( this, value );\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleButtonWidget.prototype.setButtonElement = function ( $button ) {\n\tif ( this.$button ) {\n\t\tthis.$button.removeAttr( 'aria-pressed' );\n\t}\n\tOO.ui.mixin.ButtonElement.prototype.setButtonElement.call( this, $button );\n\tthis.$button.attr( 'aria-pressed', this.value.toString() );\n};\n","/**\n * ToggleSwitches are switches that slide on and off. Their state is represented by a Boolean\n * value (`true` for ‘on’, and `false` otherwise, the default). The ‘off’ state is represented\n * visually by a slider in the leftmost position.\n *\n *     @example\n *     // Toggle switches in the 'off' and 'on' position.\n *     var toggleSwitch1 = new OO.ui.ToggleSwitchWidget(),\n *         toggleSwitch2 = new OO.ui.ToggleSwitchWidget( {\n *             value: true\n *         } );\n *         // Create a FieldsetLayout to layout and label switches.\n *         fieldset = new OO.ui.FieldsetLayout( {\n *             label: 'Toggle switches'\n *         } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( toggleSwitch1, {\n *             label: 'Off',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( toggleSwitch2, {\n *             label: 'On',\n *             align: 'top'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * @class\n * @extends OO.ui.ToggleWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [value=false] The toggle switch’s initial on/off state.\n *  By default, the toggle switch is in the 'off' position.\n */\nOO.ui.ToggleSwitchWidget = function OoUiToggleSwitchWidget( config ) {\n\t// Parent constructor\n\tOO.ui.ToggleSwitchWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Properties\n\tthis.dragging = false;\n\tthis.dragStart = null;\n\tthis.sliding = false;\n\tthis.$glow = $( '<span>' );\n\tthis.$grip = $( '<span>' );\n\n\t// Events\n\tthis.$element.on( {\n\t\tclick: this.onClick.bind( this ),\n\t\tkeypress: this.onKeyPress.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$glow.addClass( 'oo-ui-toggleSwitchWidget-glow' );\n\tthis.$grip.addClass( 'oo-ui-toggleSwitchWidget-grip' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-toggleSwitchWidget' )\n\t\t.attr( 'role', 'checkbox' )\n\t\t.append( this.$glow, this.$grip );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToggleSwitchWidget, OO.ui.ToggleWidget );\nOO.mixinClass( OO.ui.ToggleSwitchWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {jQuery.Event} e Mouse click event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.ToggleSwitchWidget.prototype.onClick = function ( e ) {\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.setValue( !this.value );\n\t}\n\treturn false;\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.ToggleSwitchWidget.prototype.onKeyPress = function ( e ) {\n\tif ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {\n\t\tthis.setValue( !this.value );\n\t\treturn false;\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleSwitchWidget.prototype.setValue = function ( value ) {\n\tOO.ui.ToggleSwitchWidget.parent.prototype.setValue.call( this, value );\n\tthis.$element.attr( 'aria-checked', this.value.toString() );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleSwitchWidget.prototype.simulateLabelClick = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.setValue( !this.value );\n\t}\n\tthis.focus();\n};\n","/**\n * OutlineControlsWidget is a set of controls for an {@link OO.ui.OutlineSelectWidget outline select widget}.\n * Controls include moving items up and down, removing items, and adding different kinds of items.\n *\n * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {OO.ui.OutlineSelectWidget} outline Outline to control\n * @param {Object} [config] Configuration options\n * @cfg {Object} [abilities] List of abilties\n * @cfg {boolean} [abilities.move=true] Allow moving movable items\n * @cfg {boolean} [abilities.remove=true] Allow removing removable items\n */\nOO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( outline ) && config === undefined ) {\n\t\tconfig = outline;\n\t\toutline = config.outline;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.OutlineControlsWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.outline = outline;\n\tthis.$movers = $( '<div>' );\n\tthis.upButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'collapse',\n\t\ttitle: OO.ui.msg( 'ooui-outline-control-move-up' )\n\t} );\n\tthis.downButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'expand',\n\t\ttitle: OO.ui.msg( 'ooui-outline-control-move-down' )\n\t} );\n\tthis.removeButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'trash',\n\t\ttitle: OO.ui.msg( 'ooui-outline-control-remove' )\n\t} );\n\tthis.abilities = { move: true, remove: true };\n\n\t// Events\n\toutline.connect( this, {\n\t\tselect: 'onOutlineChange',\n\t\tadd: 'onOutlineChange',\n\t\tremove: 'onOutlineChange'\n\t} );\n\tthis.upButton.connect( this, { click: [ 'emit', 'move', -1 ] } );\n\tthis.downButton.connect( this, { click: [ 'emit', 'move', 1 ] } );\n\tthis.removeButton.connect( this, { click: [ 'emit', 'remove' ] } );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-outlineControlsWidget' );\n\tthis.$group.addClass( 'oo-ui-outlineControlsWidget-items' );\n\tthis.$movers\n\t\t.addClass( 'oo-ui-outlineControlsWidget-movers' )\n\t\t.append( this.removeButton.$element, this.upButton.$element, this.downButton.$element );\n\tthis.$element.append( this.$icon, this.$group, this.$movers );\n\tthis.setAbilities( config.abilities || {} );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OutlineControlsWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * @event move\n * @param {number} places Number of places to move\n */\n\n/**\n * @event remove\n */\n\n/* Methods */\n\n/**\n * Set abilities.\n *\n * @param {Object} abilities List of abilties\n * @param {boolean} [abilities.move] Allow moving movable items\n * @param {boolean} [abilities.remove] Allow removing removable items\n */\nOO.ui.OutlineControlsWidget.prototype.setAbilities = function ( abilities ) {\n\tvar ability;\n\n\tfor ( ability in this.abilities ) {\n\t\tif ( abilities[ ability ] !== undefined ) {\n\t\t\tthis.abilities[ ability ] = !!abilities[ ability ];\n\t\t}\n\t}\n\n\tthis.onOutlineChange();\n};\n\n/**\n * Handle outline change events.\n *\n * @private\n */\nOO.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {\n\tvar i, len, firstMovable, lastMovable,\n\t\titems = this.outline.getItems(),\n\t\tselectedItem = this.outline.findSelectedItem(),\n\t\tmovable = this.abilities.move && selectedItem && selectedItem.isMovable(),\n\t\tremovable = this.abilities.remove && selectedItem && selectedItem.isRemovable();\n\n\tif ( movable ) {\n\t\ti = -1;\n\t\tlen = items.length;\n\t\twhile ( ++i < len ) {\n\t\t\tif ( items[ i ].isMovable() ) {\n\t\t\t\tfirstMovable = items[ i ];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\ti = len;\n\t\twhile ( i-- ) {\n\t\t\tif ( items[ i ].isMovable() ) {\n\t\t\t\tlastMovable = items[ i ];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tthis.upButton.setDisabled( !movable || selectedItem === firstMovable );\n\tthis.downButton.setDisabled( !movable || selectedItem === lastMovable );\n\tthis.removeButton.setDisabled( !removable );\n};\n","/**\n * OutlineOptionWidget is an item in an {@link OO.ui.OutlineSelectWidget OutlineSelectWidget}.\n *\n * Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}, which contain\n * {@link OO.ui.PageLayout page layouts}. See {@link OO.ui.BookletLayout BookletLayout}\n * for an example.\n *\n * @class\n * @extends OO.ui.DecoratedOptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number} [level] Indentation level\n * @cfg {boolean} [movable] Allow modification from {@link OO.ui.OutlineControlsWidget outline controls}.\n */\nOO.ui.OutlineOptionWidget = function OoUiOutlineOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.OutlineOptionWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.level = 0;\n\tthis.movable = !!config.movable;\n\tthis.removable = !!config.removable;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-outlineOptionWidget' );\n\tthis.setLevel( config.level );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OutlineOptionWidget, OO.ui.DecoratedOptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.static.highlightable = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.static.scrollIntoViewOnSelect = true;\n\n/**\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.OutlineOptionWidget.static.levelClass = 'oo-ui-outlineOptionWidget-level-';\n\n/**\n * @static\n * @inheritable\n * @property {number}\n */\nOO.ui.OutlineOptionWidget.static.levels = 3;\n\n/* Methods */\n\n/**\n * Check if item is movable.\n *\n * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @return {boolean} Item is movable\n */\nOO.ui.OutlineOptionWidget.prototype.isMovable = function () {\n\treturn this.movable;\n};\n\n/**\n * Check if item is removable.\n *\n * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @return {boolean} Item is removable\n */\nOO.ui.OutlineOptionWidget.prototype.isRemovable = function () {\n\treturn this.removable;\n};\n\n/**\n * Get indentation level.\n *\n * @return {number} Indentation level\n */\nOO.ui.OutlineOptionWidget.prototype.getLevel = function () {\n\treturn this.level;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.prototype.setPressed = function ( state ) {\n\tOO.ui.OutlineOptionWidget.parent.prototype.setPressed.call( this, state );\n\treturn this;\n};\n\n/**\n * Set movability.\n *\n * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @param {boolean} movable Item is movable\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OutlineOptionWidget.prototype.setMovable = function ( movable ) {\n\tthis.movable = !!movable;\n\tthis.updateThemeClasses();\n\treturn this;\n};\n\n/**\n * Set removability.\n *\n * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @param {boolean} removable Item is removable\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OutlineOptionWidget.prototype.setRemovable = function ( removable ) {\n\tthis.removable = !!removable;\n\tthis.updateThemeClasses();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.OutlineOptionWidget.parent.prototype.setSelected.call( this, state );\n\treturn this;\n};\n\n/**\n * Set indentation level.\n *\n * @param {number} [level=0] Indentation level, in the range of [0,#maxLevel]\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OutlineOptionWidget.prototype.setLevel = function ( level ) {\n\tvar levels = this.constructor.static.levels,\n\t\tlevelClass = this.constructor.static.levelClass,\n\t\ti = levels;\n\n\tthis.level = level ? Math.max( 0, Math.min( levels - 1, level ) ) : 0;\n\twhile ( i-- ) {\n\t\tif ( this.level === i ) {\n\t\t\tthis.$element.addClass( levelClass + i );\n\t\t} else {\n\t\t\tthis.$element.removeClass( levelClass + i );\n\t\t}\n\t}\n\tthis.updateThemeClasses();\n\n\treturn this;\n};\n","/**\n * OutlineSelectWidget is a structured list that contains {@link OO.ui.OutlineOptionWidget outline options}\n * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls} widget.\n *\n * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.OutlineSelectWidget = function OoUiOutlineSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.OutlineSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-outlineSelectWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OutlineSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.OutlineSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * ButtonOptionWidget is a special type of {@link OO.ui.mixin.ButtonElement button element} that\n * can be selected and configured with data. The class is\n * used with OO.ui.ButtonSelectWidget to create a selection of button options. Please see the\n * [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Button_selects_and_options\n *\n * @class\n * @extends OO.ui.OptionWidget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ButtonOptionWidget = function OoUiButtonOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ButtonOptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonOptionWidget' );\n\tthis.$button.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element.append( this.$button );\n\tthis.setTitledElement( this.$button );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonOptionWidget, OO.ui.OptionWidget );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.IndicatorElement );\n\n/* Static Properties */\n\n/**\n * Allow button mouse down events to pass through so they can be handled by the parent select widget\n *\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonOptionWidget.static.cancelButtonMouseDownEvents = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonOptionWidget.static.highlightable = false;\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ButtonOptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.ButtonOptionWidget.parent.prototype.setSelected.call( this, state );\n\n\tif ( this.constructor.static.selectable ) {\n\t\tthis.setActive( state );\n\t}\n\n\treturn this;\n};\n","/**\n * ButtonSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains\n * button options and is used together with\n * OO.ui.ButtonOptionWidget. The ButtonSelectWidget provides an interface for\n * highlighting, choosing, and selecting mutually exclusive options. Please see\n * the [OOUI documentation on MediaWiki] [1] for more information.\n *\n *     @example\n *     // A ButtonSelectWidget that contains three ButtonOptionWidgets.\n *     var option1 = new OO.ui.ButtonOptionWidget( {\n *             data: 1,\n *             label: 'Option 1',\n *             title: 'Button option 1'\n *         } ),\n *         option2 = new OO.ui.ButtonOptionWidget( {\n *             data: 2,\n *             label: 'Option 2',\n *             title: 'Button option 2'\n *         } ),\n *         option3 = new OO.ui.ButtonOptionWidget( {\n *             data: 3,\n *             label: 'Option 3',\n *             title: 'Button option 3'\n *         } ),\n *         buttonSelect = new OO.ui.ButtonSelectWidget( {\n *             items: [ option1, option2, option3 ]\n *         } );\n *     $( document.body ).append( buttonSelect.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ButtonSelectWidget = function OoUiButtonSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.ButtonSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonSelectWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.ButtonSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * TabOptionWidget is an item in a {@link OO.ui.TabSelectWidget TabSelectWidget}.\n *\n * Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}, which contain\n * {@link OO.ui.TabPanelLayout tab panel layouts}. See {@link OO.ui.IndexLayout IndexLayout}\n * for an example.\n *\n * @class\n * @extends OO.ui.OptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.TabOptionWidget = function OoUiTabOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.TabOptionWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tabOptionWidget' )\n\t\t.attr( 'role', 'tab' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TabOptionWidget, OO.ui.OptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.TabOptionWidget.static.highlightable = false;\n","/**\n * TabSelectWidget is a list that contains {@link OO.ui.TabOptionWidget tab options}\n *\n * **Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}.**\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.TabSelectWidget = function OoUiTabSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.TabSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tabSelectWidget' )\n\t\t.attr( 'role', 'tablist' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TabSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.TabSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * TagItemWidgets are used within a {@link OO.ui.TagMultiselectWidget\n * TagMultiselectWidget} to display the selected items.\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.DraggableElement\n *\n * @constructor\n * @param {Object} [config] Configuration object\n * @cfg {boolean} [valid=true] Item is valid\n * @cfg {boolean} [fixed] Item is fixed. This means the item is\n *  always included in the values and cannot be removed.\n */\nOO.ui.TagItemWidget = function OoUiTagItemWidget( config ) {\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.TagItemWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ItemWidget.call( this );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\tOO.ui.mixin.DraggableElement.call( this, config );\n\n\tthis.valid = config.valid === undefined ? true : !!config.valid;\n\tthis.fixed = !!config.fixed;\n\n\tthis.closeButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'close',\n\t\ttabIndex: -1,\n\t\ttitle: OO.ui.msg( 'ooui-item-remove' )\n\t} );\n\tthis.closeButton.setDisabled( this.isDisabled() );\n\n\t// Events\n\tthis.closeButton\n\t\t.connect( this, { click: 'remove' } );\n\tthis.$element\n\t\t.on( 'click', this.select.bind( this ) )\n\t\t.on( 'keydown', this.onKeyDown.bind( this ) )\n\t\t// Prevent propagation of mousedown; the tag item \"lives\" in the\n\t\t// clickable area of the TagMultiselectWidget, which listens to\n\t\t// mousedown to open the menu or popup. We want to prevent that\n\t\t// for clicks specifically on the tag itself, so the actions taken\n\t\t// are more deliberate. When the tag is clicked, it will emit the\n\t\t// selection event (similar to how #OO.ui.MultioptionWidget emits 'change')\n\t\t// and can be handled separately.\n\t\t.on( 'mousedown', function ( e ) { e.stopPropagation(); } );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tagItemWidget' )\n\t\t.append( this.$label, this.closeButton.$element );\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.TagItemWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.DraggableElement );\n\n/* Events */\n\n/**\n * @event remove\n *\n * A remove action was performed on the item\n */\n\n/**\n * @event navigate\n * @param {string} direction Direction of the movement, forward or backwards\n *\n * A navigate action was performed on the item\n */\n\n/**\n * @event select\n *\n * The tag widget was selected. This can occur when the widget\n * is either clicked or enter was pressed on it.\n */\n\n/**\n * @event valid\n * @param {boolean} isValid Item is valid\n *\n * Item validity has changed\n */\n\n/**\n * @event fixed\n * @param {boolean} isFixed Item is fixed\n *\n * Item fixed state has changed\n */\n\n/* Methods */\n\n/**\n * Set this item as fixed, meaning it cannot be removed\n *\n * @param {string} [state] Item is fixed\n * @fires fixed\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TagItemWidget.prototype.setFixed = function ( state ) {\n\tstate = state === undefined ? !this.fixed : !!state;\n\n\tif ( this.fixed !== state ) {\n\t\tthis.fixed = state;\n\t\tif ( this.closeButton ) {\n\t\t\tthis.closeButton.toggle( !this.fixed );\n\t\t}\n\n\t\tif ( !this.fixed && this.elementGroup && !this.elementGroup.isDraggable() ) {\n\t\t\t// Only enable the state of the item if the\n\t\t\t// entire group is draggable\n\t\t\tthis.toggleDraggable( !this.fixed );\n\t\t}\n\t\tthis.$element.toggleClass( 'oo-ui-tagItemWidget-fixed', this.fixed );\n\n\t\tthis.emit( 'fixed', this.isFixed() );\n\t}\n\treturn this;\n};\n\n/**\n * Check whether the item is fixed\n * @return {boolean}\n */\nOO.ui.TagItemWidget.prototype.isFixed = function () {\n\treturn this.fixed;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.TagItemWidget.prototype.setDisabled = function ( state ) {\n\tif ( state && this.elementGroup && !this.elementGroup.isDisabled() ) {\n\t\tOO.ui.warnDeprecation( 'TagItemWidget#setDisabled: Disabling individual items is deprecated and will result in inconsistent behavior. Use #setFixed instead. See T193571.' );\n\t}\n\t// Parent method\n\tOO.ui.TagItemWidget.parent.prototype.setDisabled.call( this, state );\n\tif (\n\t\t!state &&\n\t\t// Verify we have a group, and that the widget is ready\n\t\tthis.toggleDraggable && this.elementGroup &&\n\t\t!this.isFixed() &&\n\t\t!this.elementGroup.isDraggable()\n\t) {\n\t\t// Only enable the draggable state of the item if the\n\t\t// entire group is draggable to begin with, and if the\n\t\t// item is not fixed\n\t\tthis.toggleDraggable( !state );\n\t}\n\n\tif ( this.closeButton ) {\n\t\tthis.closeButton.setDisabled( state );\n\t}\n\n\treturn this;\n};\n\n/**\n * Handle removal of the item\n *\n * This is mainly for extensibility concerns, so other children\n * of this class can change the behavior if they need to. This\n * is called by both clicking the 'remove' button but also\n * on keypress, which is harder to override if needed.\n *\n * @fires remove\n */\nOO.ui.TagItemWidget.prototype.remove = function () {\n\tif ( !this.isDisabled() && !this.isFixed() ) {\n\t\tthis.emit( 'remove' );\n\t}\n};\n\n/**\n * Handle a keydown event on the widget\n *\n * @fires navigate\n * @fires remove\n * @param {jQuery.Event} e Key down event\n * @return {boolean|undefined} false to stop the operation\n */\nOO.ui.TagItemWidget.prototype.onKeyDown = function ( e ) {\n\tvar movement;\n\n\tif ( !this.isDisabled() && !this.isFixed() && ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE ) ) {\n\t\tthis.remove();\n\t\treturn false;\n\t} else if ( e.keyCode === OO.ui.Keys.ENTER ) {\n\t\tthis.select();\n\t\treturn false;\n\t} else if (\n\t\te.keyCode === OO.ui.Keys.LEFT ||\n\t\te.keyCode === OO.ui.Keys.RIGHT\n\t) {\n\t\tif ( OO.ui.Element.static.getDir( this.$element ) === 'rtl' ) {\n\t\t\tmovement = {\n\t\t\t\tleft: 'forwards',\n\t\t\t\tright: 'backwards'\n\t\t\t};\n\t\t} else {\n\t\t\tmovement = {\n\t\t\t\tleft: 'backwards',\n\t\t\t\tright: 'forwards'\n\t\t\t};\n\t\t}\n\n\t\tthis.emit(\n\t\t\t'navigate',\n\t\t\te.keyCode === OO.ui.Keys.LEFT ?\n\t\t\t\tmovement.left : movement.right\n\t\t);\n\t\treturn false;\n\t}\n};\n\n/**\n * Select this item\n *\n * @fires select\n */\nOO.ui.TagItemWidget.prototype.select = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.emit( 'select' );\n\t}\n};\n\n/**\n * Set the valid state of this item\n *\n * @param {boolean} [valid] Item is valid\n * @fires valid\n */\nOO.ui.TagItemWidget.prototype.toggleValid = function ( valid ) {\n\tvalid = valid === undefined ? !this.valid : !!valid;\n\n\tif ( this.valid !== valid ) {\n\t\tthis.valid = valid;\n\n\t\tthis.setFlags( { invalid: !this.valid } );\n\n\t\tthis.emit( 'valid', this.valid );\n\t}\n};\n\n/**\n * Check whether the item is valid\n *\n * @return {boolean} Item is valid\n */\nOO.ui.TagItemWidget.prototype.isValid = function () {\n\treturn this.valid;\n};\n","/**\n * A basic tag multiselect widget, similar in concept to {@link OO.ui.ComboBoxInputWidget combo box widget}\n * that allows the user to add multiple values that are displayed in a tag area.\n *\n * This widget is a base widget; see {@link OO.ui.MenuTagMultiselectWidget MenuTagMultiselectWidget} and\n * {@link OO.ui.PopupTagMultiselectWidget PopupTagMultiselectWidget} for the implementations that use\n * a menu and a popup respectively.\n *\n *     @example\n *     // A TagMultiselectWidget.\n *     var widget = new OO.ui.TagMultiselectWidget( {\n *         inputPosition: 'outline',\n *         allowedValues: [ 'Option 1', 'Option 2', 'Option 3' ],\n *         selected: [ 'Option 1' ]\n *     } );\n *     $( document.body ).append( widget.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupWidget\n * @mixins OO.ui.mixin.DraggableGroupElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} config Configuration object\n * @cfg {Object} [input] Configuration options for the input widget\n * @cfg {OO.ui.InputWidget} [inputWidget] An optional input widget. If given, it will\n *  replace the input widget used in the TagMultiselectWidget. If not given,\n *  TagMultiselectWidget creates its own.\n * @cfg {boolean} [inputPosition='inline'] Position of the input. Options are:\n *  - inline: The input is invisible, but exists inside the tag list, so\n *    the user types into the tag groups to add tags.\n *  - outline: The input is underneath the tag area.\n *  - none: No input supplied\n * @cfg {boolean} [allowEditTags=true] Allow editing of the tags by clicking them\n * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if\n *  not present in the menu.\n * @cfg {Object[]} [allowedValues] An array representing the allowed items\n *  by their datas.\n * @cfg {boolean} [allowDuplicates=false] Allow duplicate items to be added\n * @cfg {boolean} [allowDisplayInvalidTags=false] Allow the display of\n *  invalid tags. These tags will display with an invalid state, and\n *  the widget as a whole will have an invalid state if any invalid tags\n *  are present.\n * @cfg {number} [tagLimit] An optional limit on the number of selected options.\n *  If 'tagLimit' is set and is reached, the input is disabled, not allowing any\n *  additions. If 'tagLimit' is unset or is 0, an unlimited number of items can be\n *  added.\n * @cfg {boolean} [allowReordering=true] Allow reordering of the items\n * @cfg {Object[]|String[]} [selected] A set of selected tags. If given,\n *  these will appear in the tag list on initialization, as long as they\n *  pass the validity tests.\n */\nOO.ui.TagMultiselectWidget = function OoUiTagMultiselectWidget( config ) {\n\tvar inputEvents,\n\t\trAF = window.requestAnimationFrame || setTimeout,\n\t\twidget = this,\n\t\t$tabFocus = $( '<span>' )\n\t\t\t.addClass( 'oo-ui-tagMultiselectWidget-focusTrap' );\n\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.TagMultiselectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupWidget.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.DraggableGroupElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\tthis.toggleDraggable(\n\t\tconfig.allowReordering === undefined ?\n\t\t\ttrue : !!config.allowReordering\n\t);\n\n\tthis.inputPosition =\n\t\tthis.constructor.static.allowedInputPositions.indexOf( config.inputPosition ) > -1 ?\n\t\t\tconfig.inputPosition : 'inline';\n\tthis.allowEditTags = config.allowEditTags === undefined ? true : !!config.allowEditTags;\n\tthis.allowArbitrary = !!config.allowArbitrary;\n\tthis.allowDuplicates = !!config.allowDuplicates;\n\tthis.allowedValues = config.allowedValues || [];\n\tthis.allowDisplayInvalidTags = config.allowDisplayInvalidTags;\n\tthis.hasInput = this.inputPosition !== 'none';\n\tthis.tagLimit = config.tagLimit;\n\tthis.height = null;\n\tthis.valid = true;\n\n\tthis.$content = $( '<div>' )\n\t\t.addClass( 'oo-ui-tagMultiselectWidget-content' );\n\tthis.$handle = $( '<div>' )\n\t\t.addClass( 'oo-ui-tagMultiselectWidget-handle' )\n\t\t.append(\n\t\t\tthis.$indicator,\n\t\t\tthis.$icon,\n\t\t\tthis.$content\n\t\t\t\t.append(\n\t\t\t\t\tthis.$group\n\t\t\t\t\t\t.addClass( 'oo-ui-tagMultiselectWidget-group' )\n\t\t\t\t)\n\t\t);\n\n\t// Events\n\tthis.aggregate( {\n\t\tremove: 'itemRemove',\n\t\tnavigate: 'itemNavigate',\n\t\tselect: 'itemSelect',\n\t\tfixed: 'itemFixed'\n\t} );\n\tthis.connect( this, {\n\t\titemRemove: 'onTagRemove',\n\t\titemSelect: 'onTagSelect',\n\t\titemFixed: 'onTagFixed',\n\t\titemNavigate: 'onTagNavigate',\n\t\tchange: 'onChangeTags'\n\t} );\n\tthis.$handle.on( {\n\t\tmousedown: this.onMouseDown.bind( this )\n\t} );\n\n\t// Initialize\n\tthis.$element\n\t\t.addClass( 'oo-ui-tagMultiselectWidget' )\n\t\t.append( this.$handle );\n\n\tif ( this.hasInput ) {\n\t\tif ( config.inputWidget ) {\n\t\t\tthis.input = config.inputWidget;\n\t\t} else {\n\t\t\tthis.input = new OO.ui.TextInputWidget( $.extend( {\n\t\t\t\tplaceholder: config.placeholder,\n\t\t\t\tclasses: [ 'oo-ui-tagMultiselectWidget-input' ]\n\t\t\t}, config.input ) );\n\t\t}\n\t\tthis.input.setDisabled( this.isDisabled() );\n\n\t\tinputEvents = {\n\t\t\tfocus: this.onInputFocus.bind( this ),\n\t\t\tblur: this.onInputBlur.bind( this ),\n\t\t\t'propertychange change click mouseup keydown keyup input cut paste select focus':\n\t\t\t\tOO.ui.debounce( this.updateInputSize.bind( this ) ),\n\t\t\tkeydown: this.onInputKeyDown.bind( this ),\n\t\t\tkeypress: this.onInputKeyPress.bind( this )\n\t\t};\n\n\t\tthis.input.$input.on( inputEvents );\n\t\tthis.inputPlaceholder = this.input.$input.attr( 'placeholder' );\n\n\t\tif ( this.inputPosition === 'outline' ) {\n\t\t\t// Override max-height for the input widget\n\t\t\t// in the case the widget is outline so it can\n\t\t\t// stretch all the way if the widget is wide\n\t\t\tthis.input.$element.css( 'max-width', 'inherit' );\n\t\t\tthis.$element\n\t\t\t\t.addClass( 'oo-ui-tagMultiselectWidget-outlined' )\n\t\t\t\t.append( this.input.$element );\n\t\t} else {\n\t\t\tthis.$element.addClass( 'oo-ui-tagMultiselectWidget-inlined' );\n\t\t\t// HACK: When the widget is using 'inline' input, the\n\t\t\t// behavior needs to only use the $input itself\n\t\t\t// so we style and size it accordingly (otherwise\n\t\t\t// the styling and sizing can get very convoluted\n\t\t\t// when the wrapping divs and other elements)\n\t\t\t// We are taking advantage of still being able to\n\t\t\t// call the widget itself for operations like\n\t\t\t// .getValue() and setDisabled() and .focus() but\n\t\t\t// having only the $input attached to the DOM\n\t\t\tthis.$content.append( this.input.$input );\n\t\t}\n\t} else {\n\t\tthis.$content.append( $tabFocus );\n\t}\n\n\tthis.setTabIndexedElement(\n\t\tthis.hasInput ?\n\t\t\tthis.input.$input :\n\t\t\t$tabFocus\n\t);\n\n\tif ( config.selected ) {\n\t\tthis.setValue( config.selected );\n\t}\n\n\t// HACK: Input size needs to be calculated after everything\n\t// else is rendered\n\trAF( function () {\n\t\tif ( widget.hasInput ) {\n\t\t\twidget.updateInputSize();\n\t\t}\n\t} );\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.TagMultiselectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.GroupWidget );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.DraggableGroupElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.TitledElement );\n\n/* Static properties */\n\n/**\n * Allowed input positions.\n * - inline: The input is inside the tag list\n * - outline: The input is under the tag list\n * - none: There is no input\n *\n * @property {Array}\n */\nOO.ui.TagMultiselectWidget.static.allowedInputPositions = [ 'inline', 'outline', 'none' ];\n\n/* Methods */\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {boolean} False to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.onMouseDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\t( !this.hasInput || e.target !== this.input.$input[ 0 ] ) &&\n\t\te.which === OO.ui.MouseButtons.LEFT\n\t) {\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {boolean} Whether to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.onInputKeyPress = function ( e ) {\n\tvar stopOrContinue,\n\t\twithMetaKey = e.metaKey || e.ctrlKey;\n\n\tif ( !this.isDisabled() ) {\n\t\tif ( e.which === OO.ui.Keys.ENTER ) {\n\t\t\tstopOrContinue = this.doInputEnter( e, withMetaKey );\n\t\t}\n\n\t\t// Make sure the input gets resized.\n\t\tsetTimeout( this.updateInputSize.bind( this ), 0 );\n\t\treturn stopOrContinue;\n\t}\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n * @return {boolean}\n */\nOO.ui.TagMultiselectWidget.prototype.onInputKeyDown = function ( e ) {\n\tvar movement, direction,\n\t\twidget = this,\n\t\twithMetaKey = e.metaKey || e.ctrlKey,\n\t\tisMovementInsideInput = function ( direction ) {\n\t\t\tvar inputRange = widget.input.getRange(),\n\t\t\t\tinputValue = widget.hasInput && widget.input.getValue();\n\n\t\t\tif ( direction === 'forwards' && inputRange.to > inputValue.length - 1 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( direction === 'backwards' && inputRange.from <= 0 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\tif ( !this.isDisabled() ) {\n\t\t// 'keypress' event is not triggered for Backspace\n\t\tif ( e.keyCode === OO.ui.Keys.BACKSPACE ) {\n\t\t\treturn this.doInputBackspace( e, withMetaKey );\n\t\t} else if ( e.keyCode === OO.ui.Keys.ESCAPE ) {\n\t\t\treturn this.doInputEscape( e );\n\t\t} else if (\n\t\t\te.keyCode === OO.ui.Keys.LEFT ||\n\t\t\te.keyCode === OO.ui.Keys.RIGHT\n\t\t) {\n\t\t\tif ( OO.ui.Element.static.getDir( this.$element ) === 'rtl' ) {\n\t\t\t\tmovement = {\n\t\t\t\t\tleft: 'forwards',\n\t\t\t\t\tright: 'backwards'\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tmovement = {\n\t\t\t\t\tleft: 'backwards',\n\t\t\t\t\tright: 'forwards'\n\t\t\t\t};\n\t\t\t}\n\t\t\tdirection = e.keyCode === OO.ui.Keys.LEFT ?\n\t\t\t\tmovement.left : movement.right;\n\n\t\t\tif ( !this.hasInput || !isMovementInsideInput( direction ) ) {\n\t\t\t\treturn this.doInputArrow( e, direction, withMetaKey );\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * Respond to input focus event\n */\nOO.ui.TagMultiselectWidget.prototype.onInputFocus = function () {\n\tthis.$element.addClass( 'oo-ui-tagMultiselectWidget-focus' );\n\t// Reset validity\n\tthis.toggleValid( true );\n};\n\n/**\n * Respond to input blur event\n */\nOO.ui.TagMultiselectWidget.prototype.onInputBlur = function () {\n\tthis.$element.removeClass( 'oo-ui-tagMultiselectWidget-focus' );\n\n\t// Set the widget as invalid if there's text in the input\n\tthis.addTagFromInput();\n\tthis.toggleValid( this.checkValidity() && ( !this.hasInput || !this.input.getValue() ) );\n};\n\n/**\n * Perform an action after the enter key on the input\n *\n * @param {jQuery.Event} e Event data\n * @param {boolean} [withMetaKey] Whether this key was pressed with\n * a meta key like 'ctrl'\n * @return {boolean} Whether to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.doInputEnter = function () {\n\tthis.addTagFromInput();\n\treturn false;\n};\n\n/**\n * Perform an action responding to the enter key on the input\n *\n * @param {jQuery.Event} e Event data\n * @param {boolean} [withMetaKey] Whether this key was pressed with\n * a meta key like 'ctrl'\n * @return {boolean} Whether to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.doInputBackspace = function ( e, withMetaKey ) {\n\tvar items, item;\n\n\tif (\n\t\tthis.inputPosition === 'inline' &&\n\t\tthis.input.getValue() === '' &&\n\t\t!this.isEmpty()\n\t) {\n\t\t// Delete the last item\n\t\titems = this.getItems();\n\t\titem = items[ items.length - 1 ];\n\n\t\tif ( !item.isDisabled() && !item.isFixed() ) {\n\t\t\tthis.removeItems( [ item ] );\n\t\t\t// If Ctrl/Cmd was pressed, delete item entirely.\n\t\t\t// Otherwise put it into the text field for editing.\n\t\t\tif ( !withMetaKey ) {\n\t\t\t\tthis.input.setValue( item.getLabel() );\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n};\n\n/**\n * Perform an action after the escape key on the input\n *\n * @param {jQuery.Event} e Event data\n */\nOO.ui.TagMultiselectWidget.prototype.doInputEscape = function () {\n\tthis.clearInput();\n};\n\n/**\n * Perform an action after the arrow key on the input, select the previous\n * item from the input.\n * See #getPreviousItem\n *\n * @param {jQuery.Event} e Event data\n * @param {string} direction Direction of the movement; forwards or backwards\n * @param {boolean} [withMetaKey] Whether this key was pressed with\n *  a meta key like 'ctrl'\n */\nOO.ui.TagMultiselectWidget.prototype.doInputArrow = function ( e, direction ) {\n\tif (\n\t\tthis.inputPosition === 'inline' &&\n\t\t!this.isEmpty() &&\n\t\tdirection === 'backwards'\n\t) {\n\t\t// Get previous item\n\t\tthis.getPreviousItem().focus();\n\t}\n};\n\n/**\n * Respond to item select event\n *\n * @param {OO.ui.TagItemWidget} item Selected item\n */\nOO.ui.TagMultiselectWidget.prototype.onTagSelect = function ( item ) {\n\tif ( this.hasInput && this.allowEditTags && !item.isFixed() ) {\n\t\tif ( this.input.getValue() ) {\n\t\t\tthis.addTagFromInput();\n\t\t}\n\t\t// 1. Get the label of the tag into the input\n\t\tthis.input.setValue( item.getData() );\n\t\t// 2. Remove the tag\n\t\tthis.removeItems( [ item ] );\n\t\t// 3. Focus the input\n\t\tthis.focus();\n\t}\n};\n\n/**\n * Respond to item fixed state change\n *\n * @param {OO.ui.TagItemWidget} item Selected item\n */\nOO.ui.TagMultiselectWidget.prototype.onTagFixed = function ( item ) {\n\tvar i,\n\t\titems = this.getItems();\n\n\t// Move item to the end of the static items\n\tfor ( i = 0; i < items.length; i++ ) {\n\t\tif ( items[ i ] !== item && !items[ i ].isFixed() ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tthis.addItems( item, i );\n};\n/**\n * Respond to change event, where items were added, removed, or cleared.\n */\nOO.ui.TagMultiselectWidget.prototype.onChangeTags = function () {\n\tvar isUnderLimit = this.isUnderLimit();\n\n\t// Reset validity\n\tthis.toggleValid(\n\t\tthis.checkValidity() &&\n\t\t!( this.hasInput && this.input.getValue() )\n\t);\n\n\tif ( this.hasInput ) {\n\t\tthis.updateInputSize();\n\t\tif ( !isUnderLimit ) {\n\t\t\t// Clear the input\n\t\t\tthis.input.setValue( '' );\n\t\t}\n\t\tif ( this.inputPosition === 'outline' ) {\n\t\t\t// Show/clear the placeholder and enable/disable the input\n\t\t\t// based on whether we are/aren't under the specified limit\n\t\t\tthis.input.$input.attr( 'placeholder', isUnderLimit ? this.inputPlaceholder : '' );\n\t\t\tthis.input.setDisabled( !isUnderLimit );\n\t\t} else {\n\t\t\t// Show/hide the input\n\t\t\tthis.input.$input.toggleClass( 'oo-ui-element-hidden', !isUnderLimit );\n\t\t}\n\t}\n\tthis.updateIfHeightChanged();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.TagMultiselectWidget.prototype.setDisabled = function ( isDisabled ) {\n\t// Parent method\n\tOO.ui.TagMultiselectWidget.parent.prototype.setDisabled.call( this, isDisabled );\n\n\tif ( this.hasInput && this.input ) {\n\t\tif ( !isDisabled ) {\n\t\t\tthis.updateInputSize();\n\t\t}\n\t\tthis.input.setDisabled( !!isDisabled && !this.isUnderLimit() );\n\t}\n\n\tif ( this.items ) {\n\t\tthis.getItems().forEach( function ( item ) {\n\t\t\titem.setDisabled( !!isDisabled );\n\t\t} );\n\t}\n};\n\n/**\n * Respond to tag remove event\n * @param {OO.ui.TagItemWidget} item Removed tag\n */\nOO.ui.TagMultiselectWidget.prototype.onTagRemove = function ( item ) {\n\tthis.removeTagByData( item.getData() );\n};\n\n/**\n * Respond to navigate event on the tag\n *\n * @param {OO.ui.TagItemWidget} item Removed tag\n * @param {string} direction Direction of movement; 'forwards' or 'backwards'\n */\nOO.ui.TagMultiselectWidget.prototype.onTagNavigate = function ( item, direction ) {\n\tvar firstItem = this.getItems()[ 0 ];\n\n\tif ( direction === 'forwards' ) {\n\t\tthis.getNextItem( item ).focus();\n\t} else if ( !this.inputPosition === 'inline' || item !== firstItem ) {\n\t\t// If the widget has an inline input, we want to stop at the starting edge\n\t\t// of the tags\n\t\tthis.getPreviousItem( item ).focus();\n\t}\n};\n\n/**\n * Add tag from input value\n */\nOO.ui.TagMultiselectWidget.prototype.addTagFromInput = function () {\n\tvar val = this.input.getValue(),\n\t\tisValid = this.isAllowedData( val );\n\n\tif ( !val ) {\n\t\treturn;\n\t}\n\n\tif ( isValid || this.allowDisplayInvalidTags ) {\n\t\tthis.clearInput();\n\t\tthis.addTag( val );\n\t}\n};\n\n/**\n * Clear the input\n */\nOO.ui.TagMultiselectWidget.prototype.clearInput = function () {\n\tthis.input.setValue( '' );\n};\n\n/**\n * Check whether the given value is a duplicate of an existing\n * tag already in the list.\n *\n * @param {string|Object} data Requested value\n * @return {boolean} Value is duplicate\n */\nOO.ui.TagMultiselectWidget.prototype.isDuplicateData = function ( data ) {\n\treturn !!this.findItemFromData( data );\n};\n\n/**\n * Check whether a given value is allowed to be added\n *\n * @param {string|Object} data Requested value\n * @return {boolean} Value is allowed\n */\nOO.ui.TagMultiselectWidget.prototype.isAllowedData = function ( data ) {\n\tif (\n\t\t!this.allowDuplicates &&\n\t\tthis.isDuplicateData( data )\n\t) {\n\t\treturn false;\n\t}\n\n\tif ( this.allowArbitrary ) {\n\t\treturn true;\n\t}\n\n\t// Check with allowed values\n\tif (\n\t\tthis.getAllowedValues().some( function ( value ) {\n\t\t\treturn data === value;\n\t\t} )\n\t) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Get the allowed values list\n *\n * @return {string[]} Allowed data values\n */\nOO.ui.TagMultiselectWidget.prototype.getAllowedValues = function () {\n\treturn this.allowedValues;\n};\n\n/**\n * Add a value to the allowed values list\n *\n * @param {string} value Allowed data value\n */\nOO.ui.TagMultiselectWidget.prototype.addAllowedValue = function ( value ) {\n\tif ( this.allowedValues.indexOf( value ) === -1 ) {\n\t\tthis.allowedValues.push( value );\n\t}\n};\n\n/**\n * Get the datas of the currently selected items\n *\n * @return {string[]|Object[]} Datas of currently selected items\n */\nOO.ui.TagMultiselectWidget.prototype.getValue = function () {\n\treturn this.getItems()\n\t\t.filter( function ( item ) {\n\t\t\treturn item.isValid();\n\t\t} )\n\t\t.map( function ( item ) {\n\t\t\treturn item.getData();\n\t\t} );\n};\n\n/**\n * Set the value of this widget by datas.\n *\n * @param {string|string[]|Object|Object[]} valueObject An object representing the data\n *  and label of the value. If the widget allows arbitrary values,\n *  the items will be added as-is. Otherwise, the data value will\n *  be checked against allowedValues.\n *  This object must contain at least a data key. Example:\n *  { data: 'foo', label: 'Foo item' }\n *  For multiple items, use an array of objects. For example:\n *  [\n *     { data: 'foo', label: 'Foo item' },\n *     { data: 'bar', label: 'Bar item' }\n *  ]\n *  Value can also be added with plaintext array, for example:\n *  [ 'foo', 'bar', 'bla' ] or a single string, like 'foo'\n */\nOO.ui.TagMultiselectWidget.prototype.setValue = function ( valueObject ) {\n\tvalueObject = Array.isArray( valueObject ) ? valueObject : [ valueObject ];\n\n\tthis.clearItems();\n\tvalueObject.forEach( function ( obj ) {\n\t\tif ( typeof obj === 'string' ) {\n\t\t\tthis.addTag( obj );\n\t\t} else {\n\t\t\tthis.addTag( obj.data, obj.label );\n\t\t}\n\t}.bind( this ) );\n};\n\n/**\n * Add tag to the display area\n *\n * @param {string|Object} data Tag data\n * @param {string} [label] Tag label. If no label is provided, the\n *  stringified version of the data will be used instead.\n * @return {boolean} Item was added successfully\n */\nOO.ui.TagMultiselectWidget.prototype.addTag = function ( data, label ) {\n\tvar newItemWidget,\n\t\tisValid = this.isAllowedData( data );\n\n\tif ( this.isUnderLimit() && ( isValid || this.allowDisplayInvalidTags ) ) {\n\t\tnewItemWidget = this.createTagItemWidget( data, label );\n\t\tnewItemWidget.toggleValid( isValid );\n\t\tthis.addItems( [ newItemWidget ] );\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Check whether the number of current tags is within the limit.\n *\n * @return {boolean} True if current tag count is within the limit or\n *  if 'tagLimit' is not set\n */\nOO.ui.TagMultiselectWidget.prototype.isUnderLimit = function () {\n\treturn !this.tagLimit ||\n\t\tthis.getItemCount() < this.tagLimit;\n};\n\n/**\n * Remove tag by its data property.\n *\n * @param {string|Object} data Tag data\n */\nOO.ui.TagMultiselectWidget.prototype.removeTagByData = function ( data ) {\n\tvar item = this.findItemFromData( data );\n\n\tthis.removeItems( [ item ] );\n};\n\n/**\n * Construct a OO.ui.TagItemWidget (or a subclass thereof) from given label and data.\n *\n * @protected\n * @param {string} data Item data\n * @param {string} label The label text.\n * @return {OO.ui.TagItemWidget}\n */\nOO.ui.TagMultiselectWidget.prototype.createTagItemWidget = function ( data, label ) {\n\tlabel = label || data;\n\n\treturn new OO.ui.TagItemWidget( { data: data, label: label } );\n};\n\n/**\n * Given an item, returns the item after it. If the item is already the\n * last item, return `this.input`. If no item is passed, returns the\n * very first item.\n *\n * @protected\n * @param {OO.ui.TagItemWidget} [item] Tag item\n * @return {OO.ui.Widget} The next widget available.\n */\nOO.ui.TagMultiselectWidget.prototype.getNextItem = function ( item ) {\n\tvar itemIndex = this.items.indexOf( item );\n\n\tif ( item === undefined || itemIndex === -1 ) {\n\t\treturn this.items[ 0 ];\n\t}\n\n\tif ( itemIndex === this.items.length - 1 ) { // Last item\n\t\tif ( this.hasInput ) {\n\t\t\treturn this.input;\n\t\t} else {\n\t\t\t// Return first item\n\t\t\treturn this.items[ 0 ];\n\t\t}\n\t} else {\n\t\treturn this.items[ itemIndex + 1 ];\n\t}\n};\n\n/**\n * Given an item, returns the item before it. If the item is already the\n * first item, return `this.input`. If no item is passed, returns the\n * very last item.\n *\n * @protected\n * @param {OO.ui.TagItemWidget} [item] Tag item\n * @return {OO.ui.Widget} The previous widget available.\n */\nOO.ui.TagMultiselectWidget.prototype.getPreviousItem = function ( item ) {\n\tvar itemIndex = this.items.indexOf( item );\n\n\tif ( item === undefined || itemIndex === -1 ) {\n\t\treturn this.items[ this.items.length - 1 ];\n\t}\n\n\tif ( itemIndex === 0 ) {\n\t\tif ( this.hasInput ) {\n\t\t\treturn this.input;\n\t\t} else {\n\t\t\t// Return the last item\n\t\t\treturn this.items[ this.items.length - 1 ];\n\t\t}\n\t} else {\n\t\treturn this.items[ itemIndex - 1 ];\n\t}\n};\n\n/**\n * Update the dimensions of the text input field to encompass all available area.\n * This is especially relevant for when the input is at the edge of a line\n * and should get smaller. The usual operation (as an inline-block with min-width)\n * does not work in that case, pushing the input downwards to the next line.\n *\n * @private\n */\nOO.ui.TagMultiselectWidget.prototype.updateInputSize = function () {\n\tvar $lastItem, direction, contentWidth, currentWidth, bestWidth;\n\tif ( this.inputPosition === 'inline' && !this.isDisabled() ) {\n\t\tif ( this.input.$input[ 0 ].scrollWidth === 0 ) {\n\t\t\t// Input appears to be attached but not visible.\n\t\t\t// Don't attempt to adjust its size, because our measurements\n\t\t\t// are going to fail anyway.\n\t\t\treturn;\n\t\t}\n\t\tthis.input.$input.css( 'width', '1em' );\n\t\t$lastItem = this.$group.children().last();\n\t\tdirection = OO.ui.Element.static.getDir( this.$handle );\n\n\t\t// Get the width of the input with the placeholder text as\n\t\t// the value and save it so that we don't keep recalculating\n\t\tif (\n\t\t\tthis.contentWidthWithPlaceholder === undefined &&\n\t\t\tthis.input.getValue() === '' &&\n\t\t\tthis.input.$input.attr( 'placeholder' ) !== undefined\n\t\t) {\n\t\t\tthis.input.setValue( this.input.$input.attr( 'placeholder' ) );\n\t\t\tthis.contentWidthWithPlaceholder = this.input.$input[ 0 ].scrollWidth;\n\t\t\tthis.input.setValue( '' );\n\n\t\t}\n\n\t\t// Always keep the input wide enough for the placeholder text\n\t\tcontentWidth = Math.max(\n\t\t\tthis.input.$input[ 0 ].scrollWidth,\n\t\t\t// undefined arguments in Math.max lead to NaN\n\t\t\t( this.contentWidthWithPlaceholder === undefined ) ?\n\t\t\t\t0 : this.contentWidthWithPlaceholder\n\t\t);\n\t\tcurrentWidth = this.input.$input.width();\n\n\t\tif ( contentWidth < currentWidth ) {\n\t\t\tthis.updateIfHeightChanged();\n\t\t\t// All is fine, don't perform expensive calculations\n\t\t\treturn;\n\t\t}\n\n\t\tif ( $lastItem.length === 0 ) {\n\t\t\tbestWidth = this.$content.innerWidth();\n\t\t} else {\n\t\t\tbestWidth = direction === 'ltr' ?\n\t\t\t\tthis.$content.innerWidth() - $lastItem.position().left - $lastItem.outerWidth() :\n\t\t\t\t$lastItem.position().left;\n\t\t}\n\n\t\t// Some safety margin for sanity, because I *really* don't feel like finding out where the few\n\t\t// pixels this is off by are coming from.\n\t\tbestWidth -= 13;\n\t\tif ( contentWidth > bestWidth ) {\n\t\t\t// This will result in the input getting shifted to the next line\n\t\t\tbestWidth = this.$content.innerWidth() - 13;\n\t\t}\n\t\tthis.input.$input.width( Math.floor( bestWidth ) );\n\t\tthis.updateIfHeightChanged();\n\t} else {\n\t\tthis.updateIfHeightChanged();\n\t}\n};\n\n/**\n * Determine if widget height changed, and if so,\n * emit the resize event. This is useful for when there are either\n * menus or popups attached to the bottom of the widget, to allow\n * them to change their positioning in case the widget moved down\n * or up.\n *\n * @private\n */\nOO.ui.TagMultiselectWidget.prototype.updateIfHeightChanged = function () {\n\tvar height = this.$element.height();\n\tif ( height !== this.height ) {\n\t\tthis.height = height;\n\t\tthis.emit( 'resize' );\n\t}\n};\n\n/**\n * Check whether all items in the widget are valid\n *\n * @return {boolean} Widget is valid\n */\nOO.ui.TagMultiselectWidget.prototype.checkValidity = function () {\n\treturn this.getItems().every( function ( item ) {\n\t\treturn item.isValid();\n\t} );\n};\n\n/**\n * Set the valid state of this item\n *\n * @param {boolean} [valid] Item is valid\n * @fires valid\n */\nOO.ui.TagMultiselectWidget.prototype.toggleValid = function ( valid ) {\n\tvalid = valid === undefined ? !this.valid : !!valid;\n\n\tif ( this.valid !== valid ) {\n\t\tthis.valid = valid;\n\n\t\tthis.setFlags( { invalid: !this.valid } );\n\n\t\tthis.emit( 'valid', this.valid );\n\t}\n};\n\n/**\n * Get the current valid state of the widget\n *\n * @return {boolean} Widget is valid\n */\nOO.ui.TagMultiselectWidget.prototype.isValid = function () {\n\treturn this.valid;\n};\n","/**\n * PopupTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget} intended\n * to use a popup. The popup can be configured to have a default input to insert values into the widget.\n *\n *     @example\n *     // A PopupTagMultiselectWidget.\n *     var widget = new OO.ui.PopupTagMultiselectWidget();\n *     $( document.body ).append( widget.$element );\n *\n *     // Example: A PopupTagMultiselectWidget with an external popup.\n *     var popupInput = new OO.ui.TextInputWidget(),\n *         widget = new OO.ui.PopupTagMultiselectWidget( {\n *            popupInput: popupInput,\n *            popup: {\n *               $content: popupInput.$element\n *            }\n *         } );\n *     $( document.body ).append( widget.$element );\n *\n * @class\n * @extends OO.ui.TagMultiselectWidget\n * @mixins OO.ui.mixin.PopupElement\n *\n * @param {Object} config Configuration object\n * @cfg {jQuery} [$overlay] An overlay for the popup.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n * @cfg {Object} [popup] Configuration options for the popup\n * @cfg {OO.ui.InputWidget} [popupInput] An input widget inside the popup that will be\n *  focused when the popup is opened and will be used as replacement for the\n *  general input in the widget.\n * @deprecated\n */\nOO.ui.PopupTagMultiselectWidget = function OoUiPopupTagMultiselectWidget( config ) {\n\tvar defaultInput,\n\t\tdefaultConfig = { popup: {} };\n\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.PopupTagMultiselectWidget.parent.call( this, $.extend( { inputPosition: 'none' }, config ) );\n\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\n\tif ( !config.popup ) {\n\t\t// For the default base implementation, we give a popup\n\t\t// with an input widget inside it. For any other use cases\n\t\t// the popup needs to be populated externally and the\n\t\t// event handled to add tags separately and manually\n\t\tdefaultInput = new OO.ui.TextInputWidget();\n\n\t\tdefaultConfig.popupInput = defaultInput;\n\t\tdefaultConfig.popup.$content = defaultInput.$element;\n\t\tdefaultConfig.popup.padded = true;\n\n\t\tthis.$element.addClass( 'oo-ui-popupTagMultiselectWidget-defaultPopup' );\n\t}\n\n\t// Add overlay, and add that to the autoCloseIgnore\n\tdefaultConfig.popup.$overlay = this.$overlay;\n\tdefaultConfig.popup.$autoCloseIgnore = this.hasInput ?\n\t\tthis.input.$element.add( this.$overlay ) : this.$overlay;\n\n\t// Allow extending any of the above\n\tconfig = $.extend( defaultConfig, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PopupElement.call( this, config );\n\n\tif ( this.hasInput ) {\n\t\tthis.input.$input.on( 'focus', this.popup.toggle.bind( this.popup, true ) );\n\t}\n\n\t// Configuration options\n\tthis.popupInput = config.popupInput;\n\tif ( this.popupInput ) {\n\t\tthis.popupInput.connect( this, {\n\t\t\tenter: 'onPopupInputEnter'\n\t\t} );\n\t}\n\n\t// Events\n\tthis.on( 'resize', this.popup.updateDimensions.bind( this.popup ) );\n\tthis.popup.connect( this, { toggle: 'onPopupToggle' } );\n\tthis.$tabIndexed\n\t\t.on( 'focus', this.onFocus.bind( this ) );\n\n\t// Initialize\n\tthis.$element\n\t\t.append( this.popup.$element )\n\t\t.addClass( 'oo-ui-popupTagMultiselectWidget' );\n\n\t// Deprecation warning\n\tOO.ui.warnDeprecation( 'PopupTagMultiselectWidget: Deprecated widget. Use MenuTagMultiselectWidget instead. See T208821.' );\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.PopupTagMultiselectWidget, OO.ui.TagMultiselectWidget );\nOO.mixinClass( OO.ui.PopupTagMultiselectWidget, OO.ui.mixin.PopupElement );\n\n/* Methods */\n\n/**\n * Focus event handler.\n *\n * @private\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onFocus = function () {\n\tthis.popup.toggle( true );\n};\n\n/**\n * Respond to popup toggle event\n *\n * @param {boolean} isVisible Popup is visible\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onPopupToggle = function ( isVisible ) {\n\tif ( isVisible && this.popupInput ) {\n\t\tthis.popupInput.focus();\n\t}\n};\n\n/**\n * Respond to popup input enter event\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onPopupInputEnter = function () {\n\tif ( this.popupInput ) {\n\t\tthis.addTagByPopupValue( this.popupInput.getValue() );\n\t\tthis.popupInput.setValue( '' );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onTagSelect = function ( item ) {\n\tif ( this.popupInput && this.allowEditTags ) {\n\t\tthis.popupInput.setValue( item.getData() );\n\t\tthis.removeItems( [ item ] );\n\n\t\tthis.popup.toggle( true );\n\t\tthis.popupInput.focus();\n\t} else {\n\t\t// Parent\n\t\tOO.ui.PopupTagMultiselectWidget.parent.prototype.onTagSelect.call( this, item );\n\t}\n};\n\n/**\n * Add a tag by the popup value.\n * Whatever is responsible for setting the value in the popup should call\n * this method to add a tag, or use the regular methods like #addTag or\n * #setValue directly.\n *\n * @param {string} data The value of item\n * @param {string} [label] The label of the tag. If not given, the data is used.\n */\nOO.ui.PopupTagMultiselectWidget.prototype.addTagByPopupValue = function ( data, label ) {\n\tthis.addTag( data, label );\n};\n","/**\n * MenuTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget} intended\n * to use a menu of selectable options.\n *\n *     @example\n *     // A basic MenuTagMultiselectWidget.\n *     var widget = new OO.ui.MenuTagMultiselectWidget( {\n *         inputPosition: 'outline',\n *         options: [\n *            { data: 'option1', label: 'Option 1', icon: 'tag' },\n *            { data: 'option2', label: 'Option 2' },\n *            { data: 'option3', label: 'Option 3' },\n *         ],\n *         selected: [ 'option1', 'option2' ]\n *     } );\n *     $( document.body ).append( widget.$element );\n *\n * @class\n * @extends OO.ui.TagMultiselectWidget\n *\n * @constructor\n * @param {Object} [config] Configuration object\n * @cfg {boolean} [clearInputOnChoose=true] Clear the text input value when a menu option is chosen\n * @cfg {Object} [menu] Configuration object for the menu widget\n * @cfg {jQuery} [$overlay] An overlay for the menu.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`\n */\nOO.ui.MenuTagMultiselectWidget = function OoUiMenuTagMultiselectWidget( config ) {\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MenuTagMultiselectWidget.parent.call( this, config );\n\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.clearInputOnChoose = config.clearInputOnChoose === undefined || !!config.clearInputOnChoose;\n\tthis.menu = this.createMenuWidget( $.extend( {\n\t\twidget: this,\n\t\tinput: this.hasInput ? this.input : null,\n\t\t$input: this.hasInput ? this.input.$input : null,\n\t\tfilterFromInput: !!this.hasInput,\n\t\t$autoCloseIgnore: this.hasInput ?\n\t\t\tthis.input.$element : $( [] ),\n\t\t$floatableContainer: this.hasInput && this.inputPosition === 'outline' ?\n\t\t\tthis.input.$element : this.$element,\n\t\t$overlay: this.$overlay,\n\t\tdisabled: this.isDisabled()\n\t}, config.menu ) );\n\tthis.addOptions( config.options || [] );\n\n\t// Events\n\tthis.menu.connect( this, {\n\t\tchoose: 'onMenuChoose',\n\t\ttoggle: 'onMenuToggle'\n\t} );\n\tif ( this.hasInput ) {\n\t\tthis.input.connect( this, { change: 'onInputChange' } );\n\t}\n\tthis.connect( this, { resize: 'onResize' } );\n\n\t// Initialization\n\tthis.$overlay\n\t\t.append( this.menu.$element );\n\tthis.$element\n\t\t.addClass( 'oo-ui-menuTagMultiselectWidget' );\n\t// Remove MenuSelectWidget's generic focus owner ARIA attribute\n\t// TODO: Should this widget have a `role` that is compatible with this attribute?\n\tthis.menu.$focusOwner.removeAttr( 'aria-expanded' );\n\t// TagMultiselectWidget already does this, but it doesn't work right because this.menu is not yet\n\t// set up while the parent constructor runs, and #getAllowedValues rejects everything.\n\tif ( config.selected ) {\n\t\tthis.setValue( config.selected );\n\t}\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.MenuTagMultiselectWidget, OO.ui.TagMultiselectWidget );\n\n/* Methods */\n\n/**\n * Respond to resize event\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onResize = function () {\n\t// Reposition the menu\n\tthis.menu.position();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onInputFocus = function () {\n\t// Parent method\n\tOO.ui.MenuTagMultiselectWidget.parent.prototype.onInputFocus.call( this );\n\n\tthis.menu.toggle( true );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onInputBlur = function () {\n\t// Parent method\n\tOO.ui.MenuTagMultiselectWidget.parent.prototype.onInputBlur.call( this );\n\n\tthis.menu.toggle( false );\n};\n\n/**\n * Respond to input change event\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onInputChange = function () {\n\tthis.menu.toggle( true );\n\tthis.initializeMenuSelection();\n};\n\n/**\n * Respond to menu choose event\n *\n * @param {OO.ui.OptionWidget} menuItem Chosen menu item\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onMenuChoose = function ( menuItem ) {\n\tif ( this.hasInput && this.clearInputOnChoose ) {\n\t\tthis.input.setValue( '' );\n\t}\n\t// Add tag\n\tthis.addTag( menuItem.getData(), menuItem.getLabel() );\n};\n\n/**\n * Respond to menu toggle event. Reset item highlights on hide.\n *\n * @param {boolean} isVisible The menu is visible\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tif ( !isVisible ) {\n\t\tthis.menu.selectItem( null );\n\t\tthis.menu.highlightItem( null );\n\t} else {\n\t\tthis.initializeMenuSelection();\n\t}\n\tsetTimeout( function () {\n\t\t// Remove MenuSelectWidget's generic focus owner ARIA attribute\n\t\t// TODO: Should this widget have a `role` that is compatible with this attribute?\n\t\tthis.menu.$focusOwner.removeAttr( 'aria-expanded' );\n\t}.bind( this ) );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onTagSelect = function ( tagItem ) {\n\tvar menuItem = this.menu.findItemFromData( tagItem.getData() );\n\tif ( !this.allowArbitrary ) {\n\t\t// Override the base behavior from TagMultiselectWidget; the base behavior\n\t\t// in TagMultiselectWidget is to remove the tag to edit it in the input,\n\t\t// but in our case, we want to utilize the menu selection behavior, and\n\t\t// definitely not remove the item.\n\n\t\t// If there is an input that is used for filtering, erase the value so we don't filter\n\t\tif ( this.hasInput && this.menu.filterFromInput ) {\n\t\t\tthis.input.setValue( '' );\n\t\t}\n\n\t\t// Select the menu item\n\t\tthis.menu.selectItem( menuItem );\n\n\t\tthis.focus();\n\t} else {\n\t\t// Use the default\n\t\tOO.ui.MenuTagMultiselectWidget.parent.prototype.onTagSelect.call( this, tagItem );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.setDisabled = function ( isDisabled ) {\n\t// Parent method\n\tOO.ui.MenuTagMultiselectWidget.parent.prototype.setDisabled.call( this, isDisabled );\n\n\tif ( this.menu ) {\n\t\t// Protect against calling setDisabled() before the menu was initialized\n\t\tthis.menu.setDisabled( isDisabled );\n\t}\n};\n\n/**\n * Highlight the first selectable item in the menu, if configured.\n *\n * @private\n * @chainable\n */\nOO.ui.MenuTagMultiselectWidget.prototype.initializeMenuSelection = function () {\n\tif ( !this.menu.findSelectedItem() ) {\n\t\tthis.menu.highlightItem(\n\t\t\tthis.allowArbitrary ?\n\t\t\t\tnull :\n\t\t\t\tthis.menu.findFirstSelectableItem()\n\t\t);\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.addTagFromInput = function () {\n\tvar val = this.input.getValue(),\n\t\t// Look for a highlighted item first\n\t\t// Then look for the element that fits the data\n\t\titem = this.menu.findHighlightedItem() || this.menu.findItemFromData( val ),\n\t\tdata = item ? item.getData() : val,\n\t\tisValid = this.isAllowedData( data );\n\n\t// Override the parent method so we add from the menu\n\t// rather than directly from the input\n\n\tif ( !val ) {\n\t\treturn;\n\t}\n\n\tif ( isValid || this.allowDisplayInvalidTags ) {\n\t\tthis.clearInput();\n\t\tif ( item ) {\n\t\t\tthis.addTag( data, item.getLabel() );\n\t\t} else {\n\t\t\tthis.addTag( val );\n\t\t}\n\t}\n};\n\n/**\n * Return the visible items in the menu. This is mainly used for when\n * the menu is filtering results.\n *\n * @return {OO.ui.MenuOptionWidget[]} Visible results\n */\nOO.ui.MenuTagMultiselectWidget.prototype.getMenuVisibleItems = function () {\n\treturn this.menu.getItems().filter( function ( menuItem ) {\n\t\treturn menuItem.isVisible();\n\t} );\n};\n\n/**\n * Create the menu for this widget. This is in a separate method so that\n * child classes can override this without polluting the constructor with\n * unnecessary extra objects that will be overidden.\n *\n * @param {Object} menuConfig Configuration options\n * @return {OO.ui.MenuSelectWidget} Menu widget\n */\nOO.ui.MenuTagMultiselectWidget.prototype.createMenuWidget = function ( menuConfig ) {\n\treturn new OO.ui.MenuSelectWidget( menuConfig );\n};\n\n/**\n * Add options to the menu\n *\n * @param {Object[]} menuOptions Object defining options\n */\nOO.ui.MenuTagMultiselectWidget.prototype.addOptions = function ( menuOptions ) {\n\tvar widget = this,\n\t\titems = menuOptions.map( function ( obj ) {\n\t\t\treturn widget.createMenuOptionWidget( obj.data, obj.label, obj.icon );\n\t\t} );\n\n\tthis.menu.addItems( items );\n};\n\n/**\n * Create a menu option widget.\n *\n * @param {string} data Item data\n * @param {string} [label] Item label\n * @param {string} [icon] Symbolic icon name\n * @return {OO.ui.OptionWidget} Option widget\n */\nOO.ui.MenuTagMultiselectWidget.prototype.createMenuOptionWidget = function ( data, label, icon ) {\n\treturn new OO.ui.MenuOptionWidget( {\n\t\tdata: data,\n\t\tlabel: label || data,\n\t\ticon: icon\n\t} );\n};\n\n/**\n * Get the menu\n *\n * @return {OO.ui.MenuSelectWidget} Menu\n */\nOO.ui.MenuTagMultiselectWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Get the allowed values list\n *\n * @return {string[]} Allowed data values\n */\nOO.ui.MenuTagMultiselectWidget.prototype.getAllowedValues = function () {\n\tvar menuDatas = [];\n\tif ( this.menu ) {\n\t\t// If the parent constructor is calling us, we're not ready yet, this.menu is not set up.\n\t\tmenuDatas = this.menu.getItems().map( function ( menuItem ) {\n\t\t\treturn menuItem.getData();\n\t\t} );\n\t}\n\treturn this.allowedValues.concat( menuDatas );\n};\n","/**\n * SelectFileWidgets allow for selecting files, using the HTML5 File API. These\n * widgets can be configured with {@link OO.ui.mixin.IconElement icons}, {@link\n * OO.ui.mixin.IndicatorElement indicators} and {@link OO.ui.mixin.TitledElement titles}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n *     @example\n *     // A file select widget.\n *     var selectFile = new OO.ui.SelectFileWidget();\n *     $( document.body ).append( selectFile.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.PendingElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string[]|null} [accept=null] MIME types to accept. null accepts all types.\n * @cfg {string} [placeholder] Text to display when no file is selected.\n * @cfg {string} [notsupported] Text to display when file support is missing in the browser.\n * @cfg {boolean} [droppable=true] Whether to accept files by drag and drop.\n * @cfg {boolean} [showDropTarget=false] Whether to show a drop target. Requires droppable to be true.\n * @cfg {number} [thumbnailSizeLimit=20] File size limit in MiB above which to not try and show a\n *  preview (for performance)\n */\nOO.ui.SelectFileWidget = function OoUiSelectFileWidget( config ) {\n\tvar dragHandler;\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\taccept: null,\n\t\tplaceholder: OO.ui.msg( 'ooui-selectfile-placeholder' ),\n\t\tnotsupported: OO.ui.msg( 'ooui-selectfile-not-supported' ),\n\t\tdroppable: true,\n\t\tshowDropTarget: false,\n\t\tthumbnailSizeLimit: 20\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.SelectFileWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$info } ) );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.$info = $( '<span>' );\n\tthis.showDropTarget = config.showDropTarget;\n\tthis.thumbnailSizeLimit = config.thumbnailSizeLimit;\n\tthis.isSupported = this.constructor.static.isSupported();\n\tthis.currentFile = null;\n\tif ( Array.isArray( config.accept ) ) {\n\t\tthis.accept = config.accept;\n\t} else {\n\t\tthis.accept = null;\n\t}\n\tthis.placeholder = config.placeholder;\n\tthis.notsupported = config.notsupported;\n\tthis.onFileSelectedHandler = this.onFileSelected.bind( this );\n\n\tthis.selectButton = new OO.ui.ButtonWidget( {\n\t\t$element: $( '<label>' ),\n\t\tclasses: [ 'oo-ui-selectFileWidget-selectButton' ],\n\t\tlabel: OO.ui.msg( 'ooui-selectfile-button-select' ),\n\t\tdisabled: this.disabled || !this.isSupported\n\t} );\n\n\tthis.clearButton = new OO.ui.ButtonWidget( {\n\t\tclasses: [ 'oo-ui-selectFileWidget-clearButton' ],\n\t\tframed: false,\n\t\ticon: 'clear',\n\t\tdisabled: this.disabled\n\t} );\n\n\t// Events\n\tthis.selectButton.$button.on( {\n\t\tkeypress: this.onKeyPress.bind( this )\n\t} );\n\tthis.clearButton.connect( this, {\n\t\tclick: 'onClearClick'\n\t} );\n\tif ( config.droppable ) {\n\t\tdragHandler = this.onDragEnterOrOver.bind( this );\n\t\tthis.$element.on( {\n\t\t\tdragenter: dragHandler,\n\t\t\tdragover: dragHandler,\n\t\t\tdragleave: this.onDragLeave.bind( this ),\n\t\t\tdrop: this.onDrop.bind( this )\n\t\t} );\n\t}\n\n\t// Initialization\n\tthis.addInput();\n\tthis.$label.addClass( 'oo-ui-selectFileWidget-label' );\n\tthis.$info\n\t\t.addClass( 'oo-ui-selectFileWidget-info' )\n\t\t.append( this.$icon, this.$label, this.clearButton.$element, this.$indicator );\n\n\tif ( config.droppable && config.showDropTarget ) {\n\t\tthis.selectButton.setIcon( 'upload' );\n\t\tthis.$thumbnail = $( '<div>' ).addClass( 'oo-ui-selectFileWidget-thumbnail' );\n\t\tthis.setPendingElement( this.$thumbnail );\n\t\tthis.$element\n\t\t\t.addClass( 'oo-ui-selectFileWidget-dropTarget oo-ui-selectFileWidget' )\n\t\t\t.on( {\n\t\t\t\tclick: this.onDropTargetClick.bind( this )\n\t\t\t} )\n\t\t\t.append(\n\t\t\t\tthis.$thumbnail,\n\t\t\t\tthis.$info,\n\t\t\t\tthis.selectButton.$element,\n\t\t\t\t$( '<span>' )\n\t\t\t\t\t.addClass( 'oo-ui-selectFileWidget-dropLabel' )\n\t\t\t\t\t.text( OO.ui.msg( 'ooui-selectfile-dragdrop-placeholder' ) )\n\t\t\t);\n\t} else {\n\t\tthis.$element\n\t\t\t.addClass( 'oo-ui-selectFileWidget' )\n\t\t\t.append( this.$info, this.selectButton.$element );\n\t}\n\tthis.updateUI();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SelectFileWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.PendingElement );\nOO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.TitledElement );\n\n/* Static Properties */\n\n/**\n * Check if this widget is supported\n *\n * @static\n * @return {boolean}\n */\nOO.ui.SelectFileWidget.static.isSupported = function () {\n\tvar $input;\n\tif ( OO.ui.SelectFileWidget.static.isSupportedCache === null ) {\n\t\t$input = $( '<input>' ).attr( 'type', 'file' );\n\t\tOO.ui.SelectFileWidget.static.isSupportedCache = $input[ 0 ].files !== undefined;\n\t}\n\treturn OO.ui.SelectFileWidget.static.isSupportedCache;\n};\n\nOO.ui.SelectFileWidget.static.isSupportedCache = null;\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the on/off state of the toggle changes.\n *\n * @param {File|null} value New value\n */\n\n/* Methods */\n\n/**\n * Get the current value of the field\n *\n * @return {File|null}\n */\nOO.ui.SelectFileWidget.prototype.getValue = function () {\n\treturn this.currentFile;\n};\n\n/**\n * Set the current value of the field\n *\n * @param {File|null} file File to select\n */\nOO.ui.SelectFileWidget.prototype.setValue = function ( file ) {\n\tif ( this.currentFile !== file ) {\n\t\tthis.currentFile = file;\n\t\tthis.updateUI();\n\t\tthis.emit( 'change', this.currentFile );\n\t}\n};\n\n/**\n * Focus the widget.\n *\n * Focusses the select file button.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectFileWidget.prototype.focus = function () {\n\tthis.selectButton.focus();\n\treturn this;\n};\n\n/**\n * Blur the widget.\n *\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.SelectFileWidget.prototype.blur = function () {\n\tthis.selectButton.blur();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileWidget.prototype.simulateLabelClick = function () {\n\tthis.focus();\n};\n\n/**\n * Update the user interface when a file is selected or unselected\n *\n * @protected\n */\nOO.ui.SelectFileWidget.prototype.updateUI = function () {\n\tvar $label;\n\tif ( !this.isSupported ) {\n\t\tthis.$element.addClass( 'oo-ui-selectFileWidget-notsupported' );\n\t\tthis.$element.removeClass( 'oo-ui-selectFileWidget-empty' );\n\t\tthis.setLabel( this.notsupported );\n\t} else {\n\t\tthis.$element.addClass( 'oo-ui-selectFileWidget-supported' );\n\t\tif ( this.currentFile ) {\n\t\t\tthis.$element.removeClass( 'oo-ui-selectFileWidget-empty' );\n\t\t\t$label = $( [] );\n\t\t\t$label = $label.add(\n\t\t\t\t$( '<span>' )\n\t\t\t\t\t.addClass( 'oo-ui-selectFileWidget-fileName' )\n\t\t\t\t\t.text( this.currentFile.name )\n\t\t\t);\n\t\t\tthis.setLabel( $label );\n\n\t\t\tif ( this.showDropTarget ) {\n\t\t\t\tthis.pushPending();\n\t\t\t\tthis.loadAndGetImageUrl().done( function ( url ) {\n\t\t\t\t\tthis.$thumbnail.css( 'background-image', 'url( ' + url + ' )' );\n\t\t\t\t}.bind( this ) ).fail( function () {\n\t\t\t\t\tthis.$thumbnail.append(\n\t\t\t\t\t\tnew OO.ui.IconWidget( {\n\t\t\t\t\t\t\ticon: 'attachment',\n\t\t\t\t\t\t\tclasses: [ 'oo-ui-selectFileWidget-noThumbnail-icon' ]\n\t\t\t\t\t\t} ).$element\n\t\t\t\t\t);\n\t\t\t\t}.bind( this ) ).always( function () {\n\t\t\t\t\tthis.popPending();\n\t\t\t\t}.bind( this ) );\n\t\t\t\tthis.$element.off( 'click' );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( this.showDropTarget ) {\n\t\t\t\tthis.$element.off( 'click' );\n\t\t\t\tthis.$element.on( {\n\t\t\t\t\tclick: this.onDropTargetClick.bind( this )\n\t\t\t\t} );\n\t\t\t\tthis.$thumbnail\n\t\t\t\t\t.empty()\n\t\t\t\t\t.css( 'background-image', '' );\n\t\t\t}\n\t\t\tthis.$element.addClass( 'oo-ui-selectFileWidget-empty' );\n\t\t\tthis.setLabel( this.placeholder );\n\t\t}\n\t}\n};\n\n/**\n * If the selected file is an image, get its URL and load it.\n *\n * @return {jQuery.Promise} Promise resolves with the image URL after it has loaded\n */\nOO.ui.SelectFileWidget.prototype.loadAndGetImageUrl = function () {\n\tvar deferred = $.Deferred(),\n\t\tfile = this.currentFile,\n\t\treader = new FileReader();\n\n\tif (\n\t\tfile &&\n\t\t( OO.getProp( file, 'type' ) || '' ).indexOf( 'image/' ) === 0 &&\n\t\tfile.size < this.thumbnailSizeLimit * 1024 * 1024\n\t) {\n\t\treader.onload = function ( event ) {\n\t\t\tvar img = document.createElement( 'img' );\n\t\t\timg.addEventListener( 'load', function () {\n\t\t\t\tif (\n\t\t\t\t\timg.naturalWidth === 0 ||\n\t\t\t\t\timg.naturalHeight === 0 ||\n\t\t\t\t\timg.complete === false\n\t\t\t\t) {\n\t\t\t\t\tdeferred.reject();\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.resolve( event.target.result );\n\t\t\t\t}\n\t\t\t} );\n\t\t\timg.src = event.target.result;\n\t\t};\n\t\treader.readAsDataURL( file );\n\t} else {\n\t\tdeferred.reject();\n\t}\n\n\treturn deferred.promise();\n};\n\n/**\n * Add the input to the widget\n *\n * @private\n */\nOO.ui.SelectFileWidget.prototype.addInput = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.remove();\n\t}\n\n\tif ( !this.isSupported ) {\n\t\tthis.$input = null;\n\t\treturn;\n\t}\n\n\tthis.$input = $( '<input>' ).attr( 'type', 'file' );\n\tthis.$input.on( 'change', this.onFileSelectedHandler );\n\tthis.$input.on( 'click', function ( e ) {\n\t\t// Prevents dropTarget to get clicked which calls\n\t\t// a click on this input\n\t\te.stopPropagation();\n\t} );\n\tthis.$input.attr( {\n\t\ttabindex: -1\n\t} );\n\tif ( this.accept ) {\n\t\tthis.$input.attr( 'accept', this.accept.join( ', ' ) );\n\t}\n\tthis.selectButton.$button.append( this.$input );\n};\n\n/**\n * Determine if we should accept this file\n *\n * @private\n * @param {string} mimeType File MIME type\n * @return {boolean}\n */\nOO.ui.SelectFileWidget.prototype.isAllowedType = function ( mimeType ) {\n\tvar i, mimeTest;\n\n\tif ( !this.accept || !mimeType ) {\n\t\treturn true;\n\t}\n\n\tfor ( i = 0; i < this.accept.length; i++ ) {\n\t\tmimeTest = this.accept[ i ];\n\t\tif ( mimeTest === mimeType ) {\n\t\t\treturn true;\n\t\t} else if ( mimeTest.substr( -2 ) === '/*' ) {\n\t\t\tmimeTest = mimeTest.substr( 0, mimeTest.length - 1 );\n\t\t\tif ( mimeType.substr( 0, mimeTest.length ) === mimeTest ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n};\n\n/**\n * Handle file selection from the input\n *\n * @private\n * @param {jQuery.Event} e\n */\nOO.ui.SelectFileWidget.prototype.onFileSelected = function ( e ) {\n\tvar file = OO.getProp( e.target, 'files', 0 ) || null;\n\n\tif ( file && !this.isAllowedType( file.type ) ) {\n\t\tfile = null;\n\t}\n\n\tthis.setValue( file );\n\tthis.addInput();\n};\n\n/**\n * Handle clear button click events.\n *\n * @private\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onClearClick = function () {\n\tthis.setValue( null );\n\treturn false;\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onKeyPress = function ( e ) {\n\tif ( this.isSupported && !this.isDisabled() && this.$input &&\n\t\t( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )\n\t) {\n\t\tthis.$input.trigger( 'click' );\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle drop target click events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {\n\tif ( this.isSupported && !this.isDisabled() && this.$input ) {\n\t\tthis.$input.trigger( 'click' );\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle drag enter and over events\n *\n * @private\n * @param {jQuery.Event} e Drag event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onDragEnterOrOver = function ( e ) {\n\tvar itemOrFile,\n\t\tdroppableFile = false,\n\t\tdt = e.originalEvent.dataTransfer;\n\n\te.preventDefault();\n\te.stopPropagation();\n\n\tif ( this.isDisabled() || !this.isSupported ) {\n\t\tthis.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );\n\t\tdt.dropEffect = 'none';\n\t\treturn false;\n\t}\n\n\t// DataTransferItem and File both have a type property, but in Chrome files\n\t// have no information at this point.\n\titemOrFile = OO.getProp( dt, 'items', 0 ) || OO.getProp( dt, 'files', 0 );\n\tif ( itemOrFile ) {\n\t\tif ( this.isAllowedType( itemOrFile.type ) ) {\n\t\t\tdroppableFile = true;\n\t\t}\n\t// dt.types is Array-like, but not an Array\n\t} else if ( Array.prototype.indexOf.call( OO.getProp( dt, 'types' ) || [], 'Files' ) !== -1 ) {\n\t\t// File information is not available at this point for security so just assume\n\t\t// it is acceptable for now.\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=640534\n\t\tdroppableFile = true;\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-selectFileWidget-canDrop', droppableFile );\n\tif ( !droppableFile ) {\n\t\tdt.dropEffect = 'none';\n\t}\n\n\treturn false;\n};\n\n/**\n * Handle drag leave events\n *\n * @private\n * @param {jQuery.Event} e Drag event\n */\nOO.ui.SelectFileWidget.prototype.onDragLeave = function () {\n\tthis.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );\n};\n\n/**\n * Handle drop events\n *\n * @private\n * @param {jQuery.Event} e Drop event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onDrop = function ( e ) {\n\tvar file = null,\n\t\tdt = e.originalEvent.dataTransfer;\n\n\te.preventDefault();\n\te.stopPropagation();\n\tthis.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );\n\n\tif ( this.isDisabled() || !this.isSupported ) {\n\t\treturn false;\n\t}\n\n\tfile = OO.getProp( dt, 'files', 0 );\n\tif ( file && !this.isAllowedType( file.type ) ) {\n\t\tfile = null;\n\t}\n\tif ( file ) {\n\t\tthis.setValue( file );\n\t}\n\n\treturn false;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileWidget.prototype.setDisabled = function ( disabled ) {\n\tOO.ui.SelectFileWidget.parent.prototype.setDisabled.call( this, disabled );\n\tif ( this.selectButton ) {\n\t\tthis.selectButton.setDisabled( disabled );\n\t}\n\tif ( this.clearButton ) {\n\t\tthis.clearButton.setDisabled( disabled );\n\t}\n\treturn this;\n};\n","/**\n * SearchWidgets combine a {@link OO.ui.TextInputWidget text input field}, where users can type a search query,\n * and a menu of search results, which is displayed beneath the query\n * field. Unlike {@link OO.ui.mixin.LookupElement lookup menus}, search result menus are always visible to the user.\n * Users can choose an item from the menu or type a query into the text field to search for a matching result item.\n * In general, search widgets are used inside a separate {@link OO.ui.Dialog dialog} window.\n *\n * Each time the query is changed, the search result menu is cleared and repopulated. Please see\n * the [OOUI demos][1] for an example.\n *\n * [1]: https://doc.wikimedia.org/oojs-ui/master/demos/#SearchInputWidget-type-search\n *\n * @class\n * @extends OO.ui.Widget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string|jQuery} [placeholder] Placeholder text for query input\n * @cfg {string} [value] Initial query value\n */\nOO.ui.SearchWidget = function OoUiSearchWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.SearchWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.query = new OO.ui.TextInputWidget( {\n\t\ticon: 'search',\n\t\tplaceholder: config.placeholder,\n\t\tvalue: config.value\n\t} );\n\tthis.results = new OO.ui.SelectWidget();\n\tthis.$query = $( '<div>' );\n\tthis.$results = $( '<div>' );\n\n\t// Events\n\tthis.query.connect( this, {\n\t\tchange: 'onQueryChange',\n\t\tenter: 'onQueryEnter'\n\t} );\n\tthis.query.$input.on( 'keydown', this.onQueryKeydown.bind( this ) );\n\n\t// Initialization\n\tthis.$query\n\t\t.addClass( 'oo-ui-searchWidget-query' )\n\t\t.append( this.query.$element );\n\tthis.$results\n\t\t.addClass( 'oo-ui-searchWidget-results' )\n\t\t.append( this.results.$element );\n\tthis.$element\n\t\t.addClass( 'oo-ui-searchWidget' )\n\t\t.append( this.$results, this.$query );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SearchWidget, OO.ui.Widget );\n\n/* Methods */\n\n/**\n * Handle query key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.SearchWidget.prototype.onQueryKeydown = function ( e ) {\n\tvar highlightedItem, nextItem,\n\t\tdir = e.which === OO.ui.Keys.DOWN ? 1 : ( e.which === OO.ui.Keys.UP ? -1 : 0 );\n\n\tif ( dir ) {\n\t\thighlightedItem = this.results.findHighlightedItem();\n\t\tif ( !highlightedItem ) {\n\t\t\thighlightedItem = this.results.findSelectedItem();\n\t\t}\n\t\tnextItem = this.results.findRelativeSelectableItem( highlightedItem, dir );\n\t\tthis.results.highlightItem( nextItem );\n\t\tnextItem.scrollElementIntoView();\n\t}\n};\n\n/**\n * Handle select widget select events.\n *\n * Clears existing results. Subclasses should repopulate items according to new query.\n *\n * @private\n * @param {string} value New value\n */\nOO.ui.SearchWidget.prototype.onQueryChange = function () {\n\t// Reset\n\tthis.results.clearItems();\n};\n\n/**\n * Handle select widget enter key events.\n *\n * Chooses highlighted item.\n *\n * @private\n * @param {string} value New value\n */\nOO.ui.SearchWidget.prototype.onQueryEnter = function () {\n\tvar highlightedItem = this.results.findHighlightedItem();\n\tif ( highlightedItem ) {\n\t\tthis.results.chooseItem( highlightedItem );\n\t}\n};\n\n/**\n * Get the query input.\n *\n * @return {OO.ui.TextInputWidget} Query input\n */\nOO.ui.SearchWidget.prototype.getQuery = function () {\n\treturn this.query;\n};\n\n/**\n * Get the search results menu.\n *\n * @return {OO.ui.SelectWidget} Menu of search results\n */\nOO.ui.SearchWidget.prototype.getResults = function () {\n\treturn this.results;\n};\n","}( OO ) );\n"]}
\ No newline at end of file
+{"version":3,"sources":["../src/intro.js.txt","../src/mixins/DraggableElement.js","../src/mixins/DraggableGroupElement.js","../src/mixins/RequestManager.js","../src/mixins/LookupElement.js","../src/layouts/TabPanelLayout.js","../src/layouts/PageLayout.js","../src/layouts/StackLayout.js","../src/layouts/MenuLayout.js","../src/layouts/BookletLayout.js","../src/layouts/IndexLayout.js","../src/widgets/ToggleWidget.js","../src/widgets/ToggleButtonWidget.js","../src/widgets/ToggleSwitchWidget.js","../src/widgets/OutlineControlsWidget.js","../src/widgets/OutlineOptionWidget.js","../src/widgets/OutlineSelectWidget.js","../src/widgets/ButtonOptionWidget.js","../src/widgets/ButtonSelectWidget.js","../src/widgets/TabOptionWidget.js","../src/widgets/TabSelectWidget.js","../src/widgets/TagItemWidget.js","../src/widgets/TagMultiselectWidget.js","../src/widgets/PopupTagMultiselectWidget.js","../src/widgets/MenuTagMultiselectWidget.js","../src/widgets/SelectFileWidget.js","../src/widgets/SearchWidget.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-widgets.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * DraggableElement is a mixin class used to create elements that can be clicked\n * and dragged by a mouse to a new position within a group. This class must be used\n * in conjunction with OO.ui.mixin.DraggableGroupElement, which provides a container for\n * the draggable elements.\n *\n * @abstract\n * @class\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$handle] The part of the element which can be used for dragging, defaults to\n *  the whole element\n * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable\n *  but the draggable state should be called from the DraggableGroupElement, which updates\n *  the whole group\n */\nOO.ui.mixin.DraggableElement = function OoUiMixinDraggableElement( config ) {\n\tconfig = config || {};\n\n\t// Properties\n\tthis.index = null;\n\tthis.$handle = config.$handle || this.$element;\n\tthis.wasHandleUsed = null;\n\n\t// Initialize and events\n\tthis.$element\n\t\t.addClass( 'oo-ui-draggableElement' )\n\t\t.on( {\n\t\t\tmousedown: this.onDragMouseDown.bind( this ),\n\t\t\tdragstart: this.onDragStart.bind( this ),\n\t\t\tdragover: this.onDragOver.bind( this ),\n\t\t\tdragend: this.onDragEnd.bind( this ),\n\t\t\tdrop: this.onDrop.bind( this )\n\t\t} );\n\tthis.$handle.addClass( 'oo-ui-draggableElement-handle' );\n\tthis.toggleDraggable( config.draggable === undefined ? true : !!config.draggable );\n};\n\nOO.initClass( OO.ui.mixin.DraggableElement );\n\n/* Events */\n\n/**\n * @event dragstart\n *\n * A dragstart event is emitted when the user clicks and begins dragging an item.\n * @param {OO.ui.mixin.DraggableElement} item The item the user has clicked and is dragging with\n *  the mouse.\n */\n\n/**\n * @event dragend\n * A dragend event is emitted when the user drags an item and releases the mouse,\n * thus terminating the drag operation.\n */\n\n/**\n * @event drop\n * A drop event is emitted when the user drags an item and then releases the mouse button\n * over a valid target.\n */\n\n/* Static Properties */\n\n/**\n * @inheritdoc OO.ui.mixin.ButtonElement\n */\nOO.ui.mixin.DraggableElement.static.cancelButtonMouseDownEvents = false;\n\n/* Methods */\n\n/**\n * Change the draggable state of this widget.\n * This allows users to temporarily halt the dragging operations.\n *\n * @param {boolean} isDraggable Widget supports draggable operations\n * @fires draggable\n */\nOO.ui.mixin.DraggableElement.prototype.toggleDraggable = function ( isDraggable ) {\n\tisDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;\n\n\tif ( this.draggable !== isDraggable ) {\n\t\tthis.draggable = isDraggable;\n\n\t\tthis.$handle.toggleClass( 'oo-ui-draggableElement-undraggable', !this.draggable );\n\n\t\t// We make the entire element draggable, not just the handle, so that\n\t\t// the whole element appears to move. wasHandleUsed prevents drags from\n\t\t// starting outside the handle\n\t\tthis.$element.prop( 'draggable', this.draggable );\n\t}\n};\n\n/**\n * Check the draggable state of this widget.\n *\n * @return {boolean} Widget supports draggable operations\n */\nOO.ui.mixin.DraggableElement.prototype.isDraggable = function () {\n\treturn this.draggable;\n};\n\n/**\n * Respond to mousedown event.\n *\n * @private\n * @param {jQuery.Event} e Drag event\n */\nOO.ui.mixin.DraggableElement.prototype.onDragMouseDown = function ( e ) {\n\tif ( !this.isDraggable() ) {\n\t\treturn;\n\t}\n\n\tthis.wasHandleUsed =\n\t\t// Optimization: if the handle is the whole element this is always true\n\t\tthis.$handle[ 0 ] === this.$element[ 0 ] ||\n\t\t// Check the mousedown occurred inside the handle\n\t\tOO.ui.contains( this.$handle[ 0 ], e.target, true );\n};\n\n/**\n * Respond to dragstart event.\n *\n * @private\n * @param {jQuery.Event} e Drag event\n * @return {boolean} False if the event is cancelled\n * @fires dragstart\n */\nOO.ui.mixin.DraggableElement.prototype.onDragStart = function ( e ) {\n\tvar element = this,\n\t\tdataTransfer = e.originalEvent.dataTransfer;\n\n\tif ( !this.wasHandleUsed || !this.isDraggable() ) {\n\t\treturn false;\n\t}\n\n\t// Define drop effect\n\tdataTransfer.dropEffect = 'none';\n\tdataTransfer.effectAllowed = 'move';\n\t// Support: Firefox\n\t// We must set up a dataTransfer data property or Firefox seems to\n\t// ignore the fact the element is draggable.\n\ttry {\n\t\tdataTransfer.setData( 'application-x/OOUI-draggable', this.getIndex() );\n\t} catch ( err ) {\n\t\t// The above is only for Firefox. Move on if it fails.\n\t}\n\t// Briefly add a 'clone' class to style the browser's native drag image\n\tthis.$element.addClass( 'oo-ui-draggableElement-clone' );\n\t// Add placeholder class after the browser has rendered the clone\n\tsetTimeout( function () {\n\t\telement.$element\n\t\t\t.removeClass( 'oo-ui-draggableElement-clone' )\n\t\t\t.addClass( 'oo-ui-draggableElement-placeholder' );\n\t} );\n\t// Emit event\n\tthis.emit( 'dragstart', this );\n\treturn true;\n};\n\n/**\n * Respond to dragend event.\n *\n * @private\n * @fires dragend\n */\nOO.ui.mixin.DraggableElement.prototype.onDragEnd = function () {\n\tthis.$element.removeClass( 'oo-ui-draggableElement-placeholder' );\n\tthis.emit( 'dragend' );\n};\n\n/**\n * Handle drop event.\n *\n * @private\n * @param {jQuery.Event} e Drop event\n * @fires drop\n */\nOO.ui.mixin.DraggableElement.prototype.onDrop = function ( e ) {\n\te.preventDefault();\n\tthis.emit( 'drop', e );\n};\n\n/**\n * In order for drag/drop to work, the dragover event must\n * return false and stop propogation.\n *\n * @param {jQuery.Event} e Drag event\n * @private\n */\nOO.ui.mixin.DraggableElement.prototype.onDragOver = function ( e ) {\n\te.preventDefault();\n};\n\n/**\n * Set item index.\n * Store it in the DOM so we can access from the widget drag event.\n *\n * @private\n * @param {number} index Item index\n */\nOO.ui.mixin.DraggableElement.prototype.setIndex = function ( index ) {\n\tif ( this.index !== index ) {\n\t\tthis.index = index;\n\t\tthis.$element.data( 'index', index );\n\t}\n};\n\n/**\n * Get item index.\n *\n * @private\n * @return {number} Item index\n */\nOO.ui.mixin.DraggableElement.prototype.getIndex = function () {\n\treturn this.index;\n};\n","/**\n * DraggableGroupElement is a mixin class used to create a group element to\n * contain draggable elements, which are items that can be clicked and dragged by a mouse.\n * The class is used with OO.ui.mixin.DraggableElement.\n *\n * @abstract\n * @class\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [orientation] Item orientation: 'horizontal' or 'vertical'. The orientation\n *  should match the layout of the items. Items displayed in a single row\n *  or in several rows should use horizontal orientation. The vertical orientation should only be\n *  used when the items are displayed in a single column. Defaults to 'vertical'\n * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable\n */\nOO.ui.mixin.DraggableGroupElement = function OoUiMixinDraggableGroupElement( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.orientation = config.orientation || 'vertical';\n\tthis.dragItem = null;\n\tthis.itemKeys = {};\n\tthis.dir = null;\n\tthis.itemsOrder = null;\n\tthis.draggable = config.draggable === undefined ? true : !!config.draggable;\n\n\t// Events\n\tthis.aggregate( {\n\t\tdragstart: 'itemDragStart',\n\t\tdragend: 'itemDragEnd',\n\t\tdrop: 'itemDrop'\n\t} );\n\tthis.connect( this, {\n\t\titemDragStart: 'onItemDragStart',\n\t\titemDrop: 'onItemDropOrDragEnd',\n\t\titemDragEnd: 'onItemDropOrDragEnd'\n\t} );\n\n\t// Initialize\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n\tthis.$element\n\t\t.addClass( 'oo-ui-draggableGroupElement' )\n\t\t.toggleClass( 'oo-ui-draggableGroupElement-horizontal', this.orientation === 'horizontal' );\n};\n\n/* Setup */\nOO.mixinClass( OO.ui.mixin.DraggableGroupElement, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * An item has been dragged to a new position, but not yet dropped.\n *\n * @event drag\n * @param {OO.ui.mixin.DraggableElement} item Dragged item\n * @param {number} [newIndex] New index for the item\n */\n\n/**\n * An item has been dropped at a new position.\n *\n * @event reorder\n * @param {OO.ui.mixin.DraggableElement} item Reordered item\n * @param {number} [newIndex] New index for the item\n */\n\n/**\n * Draggable state of this widget has changed.\n *\n * @event draggable\n * @param {boolean} [draggable] Widget is draggable\n */\n\n/* Methods */\n\n/**\n * Change the draggable state of this widget.\n * This allows users to temporarily halt the dragging operations.\n *\n * @param {boolean} isDraggable Widget supports draggable operations\n * @fires draggable\n */\nOO.ui.mixin.DraggableGroupElement.prototype.toggleDraggable = function ( isDraggable ) {\n\tisDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;\n\n\tif ( this.draggable !== isDraggable ) {\n\t\tthis.draggable = isDraggable;\n\n\t\t// Tell the items their draggable state changed\n\t\tthis.getItems().forEach( function ( item ) {\n\t\t\titem.toggleDraggable( this.draggable );\n\t\t}.bind( this ) );\n\n\t\t// Emit event\n\t\tthis.emit( 'draggable', this.draggable );\n\t}\n};\n\n/**\n * Check the draggable state of this widget\n *\n * @return {boolean} Widget supports draggable operations\n */\nOO.ui.mixin.DraggableGroupElement.prototype.isDraggable = function () {\n\treturn this.draggable;\n};\n\n/**\n * Respond to item drag start event\n *\n * @private\n * @param {OO.ui.mixin.DraggableElement} item Dragged item\n */\nOO.ui.mixin.DraggableGroupElement.prototype.onItemDragStart = function ( item ) {\n\tif ( !this.isDraggable() ) {\n\t\treturn;\n\t}\n\t// Make a shallow copy of this.items so we can re-order it during previews\n\t// without affecting the original array.\n\tthis.itemsOrder = this.items.slice();\n\tthis.updateIndexes();\n\tif ( this.orientation === 'horizontal' ) {\n\t\t// Calculate and cache directionality on drag start - it's a little\n\t\t// expensive and it shouldn't change while dragging.\n\t\tthis.dir = this.$element.css( 'direction' );\n\t}\n\tthis.setDragItem( item );\n};\n\n/**\n * Update the index properties of the items\n */\nOO.ui.mixin.DraggableGroupElement.prototype.updateIndexes = function () {\n\tvar i, len;\n\n\t// Map the index of each object\n\tfor ( i = 0, len = this.itemsOrder.length; i < len; i++ ) {\n\t\tthis.itemsOrder[ i ].setIndex( i );\n\t}\n};\n\n/**\n * Handle drop or dragend event and switch the order of the items accordingly\n *\n * @private\n * @param {OO.ui.mixin.DraggableElement} item Dropped item\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.DraggableGroupElement.prototype.onItemDropOrDragEnd = function () {\n\tvar targetIndex, originalIndex,\n\t\titem = this.getDragItem();\n\n\t// TODO: Figure out a way to configure a list of legally droppable\n\t// elements even if they are not yet in the list\n\tif ( item ) {\n\t\toriginalIndex = this.items.indexOf( item );\n\t\t// If the item has moved forward, add one to the index to account for the left shift\n\t\ttargetIndex = item.getIndex() + ( item.getIndex() > originalIndex ? 1 : 0 );\n\t\tif ( targetIndex !== originalIndex ) {\n\t\t\tthis.reorder( this.getDragItem(), targetIndex );\n\t\t\tthis.emit( 'reorder', this.getDragItem(), targetIndex );\n\t\t}\n\t\tthis.updateIndexes();\n\t}\n\tthis.unsetDragItem();\n\t// Return false to prevent propogation\n\treturn false;\n};\n\n/**\n * Respond to dragover event\n *\n * @private\n * @param {jQuery.Event} e Dragover event\n * @fires reorder\n */\nOO.ui.mixin.DraggableGroupElement.prototype.onDragOver = function ( e ) {\n\tvar overIndex, targetIndex,\n\t\titem = this.getDragItem(),\n\t\tdragItemIndex = item.getIndex();\n\n\t// Get the OptionWidget item we are dragging over\n\toverIndex = $( e.target ).closest( '.oo-ui-draggableElement' ).data( 'index' );\n\n\tif ( overIndex !== undefined && overIndex !== dragItemIndex ) {\n\t\ttargetIndex = overIndex + ( overIndex > dragItemIndex ? 1 : 0 );\n\n\t\tif ( targetIndex > 0 ) {\n\t\t\tthis.$group.children().eq( targetIndex - 1 ).after( item.$element );\n\t\t} else {\n\t\t\tthis.$group.prepend( item.$element );\n\t\t}\n\t\t// Move item in itemsOrder array\n\t\tthis.itemsOrder.splice( overIndex, 0,\n\t\t\tthis.itemsOrder.splice( dragItemIndex, 1 )[ 0 ]\n\t\t);\n\t\tthis.updateIndexes();\n\t\tthis.emit( 'drag', item, targetIndex );\n\t}\n\t// Prevent default\n\te.preventDefault();\n};\n\n/**\n * Reorder the items in the group\n *\n * @param {OO.ui.mixin.DraggableElement} item Reordered item\n * @param {number} newIndex New index\n */\nOO.ui.mixin.DraggableGroupElement.prototype.reorder = function ( item, newIndex ) {\n\tthis.addItems( [ item ], newIndex );\n};\n\n/**\n * Set a dragged item\n *\n * @param {OO.ui.mixin.DraggableElement} item Dragged item\n */\nOO.ui.mixin.DraggableGroupElement.prototype.setDragItem = function ( item ) {\n\tif ( this.dragItem !== item ) {\n\t\tthis.dragItem = item;\n\t\tthis.$element.on( 'dragover', this.onDragOver.bind( this ) );\n\t\tthis.$element.addClass( 'oo-ui-draggableGroupElement-dragging' );\n\t}\n};\n\n/**\n * Unset the current dragged item\n */\nOO.ui.mixin.DraggableGroupElement.prototype.unsetDragItem = function () {\n\tif ( this.dragItem ) {\n\t\tthis.dragItem = null;\n\t\tthis.$element.off( 'dragover' );\n\t\tthis.$element.removeClass( 'oo-ui-draggableGroupElement-dragging' );\n\t}\n};\n\n/**\n * Get the item that is currently being dragged.\n *\n * @return {OO.ui.mixin.DraggableElement|null} The currently dragged item, or `null` if no item is\n *  being dragged\n */\nOO.ui.mixin.DraggableGroupElement.prototype.getDragItem = function () {\n\treturn this.dragItem;\n};\n","/**\n * RequestManager is a mixin that manages the lifecycle of a promise-backed request for a widget,\n * such as the {@link OO.ui.mixin.LookupElement}.\n *\n * @class\n * @abstract\n *\n * @constructor\n */\nOO.ui.mixin.RequestManager = function OoUiMixinRequestManager() {\n\tthis.requestCache = {};\n\tthis.requestQuery = null;\n\tthis.requestRequest = null;\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.mixin.RequestManager );\n\n/**\n * Get request results for the current query.\n *\n * @return {jQuery.Promise} Promise object which will be passed response data as the first argument\n *  of the done event. If the request was aborted to make way for a subsequent request, this\n *  promise may not be rejected, depending on what jQuery feels like doing.\n */\nOO.ui.mixin.RequestManager.prototype.getRequestData = function () {\n\tvar widget = this,\n\t\tvalue = this.getRequestQuery(),\n\t\tdeferred = $.Deferred(),\n\t\tourRequest;\n\n\tthis.abortRequest();\n\tif ( Object.prototype.hasOwnProperty.call( this.requestCache, value ) ) {\n\t\tdeferred.resolve( this.requestCache[ value ] );\n\t} else {\n\t\tif ( this.pushPending ) {\n\t\t\tthis.pushPending();\n\t\t}\n\t\tthis.requestQuery = value;\n\t\tourRequest = this.requestRequest = this.getRequest();\n\t\tourRequest\n\t\t\t.always( function () {\n\t\t\t\t// We need to pop pending even if this is an old request, otherwise\n\t\t\t\t// the widget will remain pending forever.\n\t\t\t\t// TODO: this assumes that an aborted request will fail or succeed soon after\n\t\t\t\t// being aborted, or at least eventually. It would be nice if we could popPending()\n\t\t\t\t// at abort time, but only if we knew that we hadn't already called popPending()\n\t\t\t\t// for that request.\n\t\t\t\tif ( widget.popPending ) {\n\t\t\t\t\twidget.popPending();\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.done( function ( response ) {\n\t\t\t\t// If this is an old request (and aborting it somehow caused it to still succeed),\n\t\t\t\t// ignore its success completely\n\t\t\t\tif ( ourRequest === widget.requestRequest ) {\n\t\t\t\t\twidget.requestQuery = null;\n\t\t\t\t\twidget.requestRequest = null;\n\t\t\t\t\twidget.requestCache[ value ] =\n\t\t\t\t\t\twidget.getRequestCacheDataFromResponse( response );\n\t\t\t\t\tdeferred.resolve( widget.requestCache[ value ] );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.fail( function () {\n\t\t\t\t// If this is an old request (or a request failing because it's being aborted),\n\t\t\t\t// ignore its failure completely\n\t\t\t\tif ( ourRequest === widget.requestRequest ) {\n\t\t\t\t\twidget.requestQuery = null;\n\t\t\t\t\twidget.requestRequest = null;\n\t\t\t\t\tdeferred.reject();\n\t\t\t\t}\n\t\t\t} );\n\t}\n\treturn deferred.promise();\n};\n\n/**\n * Abort the currently pending request, if any.\n *\n * @private\n */\nOO.ui.mixin.RequestManager.prototype.abortRequest = function () {\n\tvar oldRequest = this.requestRequest;\n\tif ( oldRequest ) {\n\t\t// First unset this.requestRequest to the fail handler will notice\n\t\t// that the request is no longer current\n\t\tthis.requestRequest = null;\n\t\tthis.requestQuery = null;\n\t\toldRequest.abort();\n\t}\n};\n\n/**\n * Get the query to be made.\n *\n * @protected\n * @method\n * @abstract\n * @return {string} query to be used\n */\nOO.ui.mixin.RequestManager.prototype.getRequestQuery = null;\n\n/**\n * Get a new request object of the current query value.\n *\n * @protected\n * @method\n * @abstract\n * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method\n */\nOO.ui.mixin.RequestManager.prototype.getRequest = null;\n\n/**\n * Pre-process data returned by the request from #getRequest.\n *\n * The return value of this function will be cached, and any further queries for the given value\n * will use the cache rather than doing API requests.\n *\n * @protected\n * @method\n * @abstract\n * @param {Mixed} response Response from server\n * @return {Mixed} Cached result data\n */\nOO.ui.mixin.RequestManager.prototype.getRequestCacheDataFromResponse = null;\n","/**\n * LookupElement is a mixin that creates a {@link OO.ui.MenuSelectWidget menu} of suggested\n * values for a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on\n * the characters the user types into the text input field and, in general, the menu is only\n * displayed when the user types. If a suggested value is chosen from the lookup menu, that value\n * becomes the value of the input field.\n *\n * Note that a new menu of suggested items is displayed when a value is chosen from the\n * lookup menu. If this is not the desired behavior, disable lookup menus with the\n * #setLookupsDisabled method, then set the value, then re-enable lookups.\n *\n * See the [OOUI demos][1] for an example.\n *\n * [1]: https://doc.wikimedia.org/oojs-ui/master/demos/#LookupElement-try-inputting-an-integer\n *\n * @class\n * @abstract\n * @mixins OO.ui.mixin.RequestManager\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered\n *  beneath the specified element.\n * @cfg {Object} [menu] Configuration options to pass to\n *  {@link OO.ui.MenuSelectWidget menu select widget}\n * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the\n *  text input is empty.\n *  By default, the lookup menu is not generated and displayed until the user begins to type.\n * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted\n *  (so, that the user can take it over into the input with simply pressing return) automatically\n *  or not.\n */\nOO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { highlightFirst: true }, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.RequestManager.call( this, config );\n\n\t// Properties\n\tthis.$overlay = ( config.$overlay === true ?\n\t\tOO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.lookupMenu = new OO.ui.MenuSelectWidget( $.extend( {\n\t\twidget: this,\n\t\tinput: this,\n\t\t$floatableContainer: config.$container || this.$element\n\t}, config.menu ) );\n\n\tthis.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;\n\n\tthis.lookupsDisabled = false;\n\tthis.lookupInputFocused = false;\n\tthis.lookupHighlightFirstItem = config.highlightFirst;\n\n\t// Events\n\tthis.$input.on( {\n\t\tfocus: this.onLookupInputFocus.bind( this ),\n\t\tblur: this.onLookupInputBlur.bind( this ),\n\t\tmousedown: this.onLookupInputMouseDown.bind( this )\n\t} );\n\tthis.connect( this, {\n\t\tchange: 'onLookupInputChange'\n\t} );\n\tthis.lookupMenu.connect( this, {\n\t\ttoggle: 'onLookupMenuToggle',\n\t\tchoose: 'onLookupMenuItemChoose'\n\t} );\n\n\t// Initialization\n\tthis.$input.attr( {\n\t\trole: 'combobox',\n\t\t'aria-owns': this.lookupMenu.getElementId(),\n\t\t'aria-autocomplete': 'list'\n\t} );\n\tthis.$element.addClass( 'oo-ui-lookupElement' );\n\tthis.lookupMenu.$element.addClass( 'oo-ui-lookupElement-menu' );\n\tthis.$overlay.append( this.lookupMenu.$element );\n};\n\n/* Setup */\n\nOO.mixinClass( OO.ui.mixin.LookupElement, OO.ui.mixin.RequestManager );\n\n/* Methods */\n\n/**\n * Handle input focus event.\n *\n * @protected\n * @param {jQuery.Event} e Input focus event\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputFocus = function () {\n\tthis.lookupInputFocused = true;\n\tthis.populateLookupMenu();\n};\n\n/**\n * Handle input blur event.\n *\n * @protected\n * @param {jQuery.Event} e Input blur event\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputBlur = function () {\n\tthis.closeLookupMenu();\n\tthis.lookupInputFocused = false;\n};\n\n/**\n * Handle input mouse down event.\n *\n * @protected\n * @param {jQuery.Event} e Input mouse down event\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputMouseDown = function () {\n\t// Only open the menu if the input was already focused.\n\t// This way we allow the user to open the menu again after closing it with Escape (esc)\n\t// by clicking in the input. Opening (and populating) the menu when initially\n\t// clicking into the input is handled by the focus handler.\n\tif ( this.lookupInputFocused && !this.lookupMenu.isVisible() ) {\n\t\tthis.populateLookupMenu();\n\t}\n};\n\n/**\n * Handle input change event.\n *\n * @protected\n * @param {string} value New input value\n */\nOO.ui.mixin.LookupElement.prototype.onLookupInputChange = function () {\n\tif ( this.lookupInputFocused ) {\n\t\tthis.populateLookupMenu();\n\t}\n};\n\n/**\n * Handle the lookup menu being shown/hidden.\n *\n * @protected\n * @param {boolean} visible Whether the lookup menu is now visible.\n */\nOO.ui.mixin.LookupElement.prototype.onLookupMenuToggle = function ( visible ) {\n\tif ( !visible ) {\n\t\t// When the menu is hidden, abort any active request and clear the menu.\n\t\t// This has to be done here in addition to closeLookupMenu(), because\n\t\t// MenuSelectWidget will close itself when the user presses Escape (esc).\n\t\tthis.abortLookupRequest();\n\t\tthis.lookupMenu.clearItems();\n\t}\n};\n\n/**\n * Handle menu item 'choose' event, updating the text input value to the value of the clicked item.\n *\n * @protected\n * @param {OO.ui.MenuOptionWidget} item Selected item\n */\nOO.ui.mixin.LookupElement.prototype.onLookupMenuItemChoose = function ( item ) {\n\tthis.setValue( item.getData() );\n};\n\n/**\n * Get lookup menu.\n *\n * @private\n * @return {OO.ui.MenuSelectWidget}\n */\nOO.ui.mixin.LookupElement.prototype.getLookupMenu = function () {\n\treturn this.lookupMenu;\n};\n\n/**\n * Disable or re-enable lookups.\n *\n * When lookups are disabled, calls to #populateLookupMenu will be ignored.\n *\n * @param {boolean} disabled Disable lookups\n */\nOO.ui.mixin.LookupElement.prototype.setLookupsDisabled = function ( disabled ) {\n\tthis.lookupsDisabled = !!disabled;\n};\n\n/**\n * Open the menu. If there are no entries in the menu, this does nothing.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.openLookupMenu = function () {\n\tif ( !this.lookupMenu.isEmpty() ) {\n\t\tthis.lookupMenu.toggle( true );\n\t}\n\treturn this;\n};\n\n/**\n * Close the menu, empty it, and abort any pending request.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.closeLookupMenu = function () {\n\tthis.lookupMenu.toggle( false );\n\tthis.abortLookupRequest();\n\tthis.lookupMenu.clearItems();\n\treturn this;\n};\n\n/**\n * Request menu items based on the input's current value, and when they arrive,\n * populate the menu with these items and show the menu.\n *\n * If lookups have been disabled with #setLookupsDisabled, this function does nothing.\n *\n * @private\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.populateLookupMenu = function () {\n\tvar widget = this,\n\t\tvalue = this.getValue();\n\n\tif ( this.lookupsDisabled || this.isReadOnly() ) {\n\t\treturn;\n\t}\n\n\t// If the input is empty, clear the menu, unless suggestions when empty are allowed.\n\tif ( !this.allowSuggestionsWhenEmpty && value === '' ) {\n\t\tthis.closeLookupMenu();\n\t// Skip population if there is already a request pending for the current value\n\t} else if ( value !== this.lookupQuery ) {\n\t\tthis.getLookupMenuItems()\n\t\t\t.done( function ( items ) {\n\t\t\t\twidget.lookupMenu.clearItems();\n\t\t\t\tif ( items.length ) {\n\t\t\t\t\twidget.lookupMenu\n\t\t\t\t\t\t.addItems( items )\n\t\t\t\t\t\t.toggle( true );\n\t\t\t\t\twidget.initializeLookupMenuSelection();\n\t\t\t\t} else {\n\t\t\t\t\twidget.lookupMenu.toggle( false );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.fail( function () {\n\t\t\t\twidget.lookupMenu.clearItems();\n\t\t\t\twidget.lookupMenu.toggle( false );\n\t\t\t} );\n\t}\n\n\treturn this;\n};\n\n/**\n * Highlight the first selectable item in the menu, if configured.\n *\n * @private\n * @chainable\n */\nOO.ui.mixin.LookupElement.prototype.initializeLookupMenuSelection = function () {\n\tif ( this.lookupHighlightFirstItem && !this.lookupMenu.findSelectedItem() ) {\n\t\tthis.lookupMenu.highlightItem( this.lookupMenu.findFirstSelectableItem() );\n\t}\n};\n\n/**\n * Get lookup menu items for the current query.\n *\n * @private\n * @return {jQuery.Promise} Promise object which will be passed menu items as the first argument of\n *   the done event. If the request was aborted to make way for a subsequent request, this promise\n *   will not be rejected: it will remain pending forever.\n */\nOO.ui.mixin.LookupElement.prototype.getLookupMenuItems = function () {\n\treturn this.getRequestData().then( function ( data ) {\n\t\treturn this.getLookupMenuOptionsFromData( data );\n\t}.bind( this ) );\n};\n\n/**\n * Abort the currently pending lookup request, if any.\n *\n * @private\n */\nOO.ui.mixin.LookupElement.prototype.abortLookupRequest = function () {\n\tthis.abortRequest();\n};\n\n/**\n * Get a new request object of the current lookup query value.\n *\n * @protected\n * @method\n * @abstract\n * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method\n */\nOO.ui.mixin.LookupElement.prototype.getLookupRequest = null;\n\n/**\n * Pre-process data returned by the request from #getLookupRequest.\n *\n * The return value of this function will be cached, and any further queries for the given value\n * will use the cache rather than doing API requests.\n *\n * @protected\n * @method\n * @abstract\n * @param {Mixed} response Response from server\n * @return {Mixed} Cached result data\n */\nOO.ui.mixin.LookupElement.prototype.getLookupCacheDataFromResponse = null;\n\n/**\n * Get a list of menu option widgets from the (possibly cached) data returned by\n * #getLookupCacheDataFromResponse.\n *\n * @protected\n * @method\n * @abstract\n * @param {Mixed} data Cached result data, usually an array\n * @return {OO.ui.MenuOptionWidget[]} Menu items\n */\nOO.ui.mixin.LookupElement.prototype.getLookupMenuOptionsFromData = null;\n\n/**\n * Set the read-only state of the widget.\n *\n * This will also disable/enable the lookups functionality.\n *\n * @param {boolean} readOnly Make input read-only\n * @chainable\n * @return {OO.ui.Element} The element, for chaining\n */\nOO.ui.mixin.LookupElement.prototype.setReadOnly = function ( readOnly ) {\n\t// Parent method\n\t// Note: Calling #setReadOnly this way assumes this is mixed into an OO.ui.TextInputWidget\n\tOO.ui.TextInputWidget.prototype.setReadOnly.call( this, readOnly );\n\n\t// During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor.\n\tif ( this.isReadOnly() && this.lookupMenu ) {\n\t\tthis.closeLookupMenu();\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc OO.ui.mixin.RequestManager\n */\nOO.ui.mixin.LookupElement.prototype.getRequestQuery = function () {\n\treturn this.getValue();\n};\n\n/**\n * @inheritdoc OO.ui.mixin.RequestManager\n */\nOO.ui.mixin.LookupElement.prototype.getRequest = function () {\n\treturn this.getLookupRequest();\n};\n\n/**\n * @inheritdoc OO.ui.mixin.RequestManager\n */\nOO.ui.mixin.LookupElement.prototype.getRequestCacheDataFromResponse = function ( response ) {\n\treturn this.getLookupCacheDataFromResponse( response );\n};\n","/**\n * TabPanelLayouts are used within {@link OO.ui.IndexLayout index layouts} to create tab panels that\n * users can select and display from the index's optional {@link OO.ui.TabSelectWidget tab}\n * navigation. TabPanels are usually not instantiated directly, rather extended to include the\n * required content and functionality.\n *\n * Each tab panel must have a unique symbolic name, which is passed to the constructor. In addition,\n * the tab panel's tab item is customized (with a label) using the #setupTabItem method. See\n * {@link OO.ui.IndexLayout IndexLayout} for an example.\n *\n * @class\n * @extends OO.ui.PanelLayout\n *\n * @constructor\n * @param {string} name Unique symbolic name of tab panel\n * @param {Object} [config] Configuration options\n * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] Label for tab panel's tab\n */\nOO.ui.TabPanelLayout = function OoUiTabPanelLayout( name, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( name ) && config === undefined ) {\n\t\tconfig = name;\n\t\tname = config.name;\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( { scrollable: true }, config );\n\n\t// Parent constructor\n\tOO.ui.TabPanelLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.name = name;\n\tthis.label = config.label;\n\tthis.tabItem = null;\n\tthis.active = false;\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tabPanelLayout' )\n\t\t.attr( 'role', 'tabpanel' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TabPanelLayout, OO.ui.PanelLayout );\n\n/* Events */\n\n/**\n * An 'active' event is emitted when the tab panel becomes active. Tab panels become active when\n * they are shown in a index layout that is configured to display only one tab panel at a time.\n *\n * @event active\n * @param {boolean} active Tab panel is active\n */\n\n/* Methods */\n\n/**\n * Get the symbolic name of the tab panel.\n *\n * @return {string} Symbolic name of tab panel\n */\nOO.ui.TabPanelLayout.prototype.getName = function () {\n\treturn this.name;\n};\n\n/**\n * Check if tab panel is active.\n *\n * Tab panels become active when they are shown in a {@link OO.ui.IndexLayout index layout} that is\n * configured to display only one tab panel at a time. Additional CSS is applied to the tab panel's\n * tab item to reflect the active state.\n *\n * @return {boolean} Tab panel is active\n */\nOO.ui.TabPanelLayout.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Get tab item.\n *\n * The tab item allows users to access the tab panel from the index's tab\n * navigation. The tab item itself can be customized (with a label, level, etc.) using the\n * #setupTabItem method.\n *\n * @return {OO.ui.TabOptionWidget|null} Tab option widget\n */\nOO.ui.TabPanelLayout.prototype.getTabItem = function () {\n\treturn this.tabItem;\n};\n\n/**\n * Set or unset the tab item.\n *\n * Specify a {@link OO.ui.TabOptionWidget tab option} to set it,\n * or `null` to clear the tab item. To customize the tab item itself (e.g., to set a label or tab\n * level), use #setupTabItem instead of this method.\n *\n * @param {OO.ui.TabOptionWidget|null} tabItem Tab option widget, null to clear\n * @chainable\n * @return {OO.ui.TabPanelLayout} The layout, for chaining\n */\nOO.ui.TabPanelLayout.prototype.setTabItem = function ( tabItem ) {\n\tthis.tabItem = tabItem || null;\n\tif ( tabItem ) {\n\t\tthis.setupTabItem();\n\t}\n\treturn this;\n};\n\n/**\n * Set up the tab item.\n *\n * Use this method to customize the tab item (e.g., to add a label or tab level). To set or unset\n * the tab item itself (with a {@link OO.ui.TabOptionWidget tab option} or `null`), use\n * the #setTabItem method instead.\n *\n * @param {OO.ui.TabOptionWidget} tabItem Tab option widget to set up\n * @chainable\n * @return {OO.ui.TabPanelLayout} The layout, for chaining\n */\nOO.ui.TabPanelLayout.prototype.setupTabItem = function () {\n\tthis.$element.attr( 'aria-labelledby', this.tabItem.getElementId() );\n\n\tthis.tabItem.$element.attr( 'aria-controls', this.getElementId() );\n\n\tif ( this.label ) {\n\t\tthis.tabItem.setLabel( this.label );\n\t}\n\treturn this;\n};\n\n/**\n * Set the tab panel to its 'active' state.\n *\n * Tab panels become active when they are shown in a index layout that is configured to display only\n * one tab panel at a time. Additional CSS is applied to the tab item to reflect the tab panel's\n * active state. Outside of the index context, setting the active state on a tab panel does nothing.\n *\n * @param {boolean} active Tab panel is active\n * @fires active\n */\nOO.ui.TabPanelLayout.prototype.setActive = function ( active ) {\n\tactive = !!active;\n\n\tif ( active !== this.active ) {\n\t\tthis.active = active;\n\t\tthis.$element.toggleClass( 'oo-ui-tabPanelLayout-active', this.active );\n\t\tthis.emit( 'active', this.active );\n\t}\n};\n","/**\n * PageLayouts are used within {@link OO.ui.BookletLayout booklet layouts} to create pages that\n * users can select and display from the booklet's optional\n * {@link OO.ui.OutlineSelectWidget outline} navigation. Pages are usually not instantiated\n * directly, rather extended to include the required content and functionality.\n *\n * Each page must have a unique symbolic name, which is passed to the constructor. In addition, the\n * page's outline item is customized (with a label, outline level, etc.) using the\n * #setupOutlineItem method. See {@link OO.ui.BookletLayout BookletLayout} for an example.\n *\n * @class\n * @extends OO.ui.PanelLayout\n *\n * @constructor\n * @param {string} name Unique symbolic name of page\n * @param {Object} [config] Configuration options\n */\nOO.ui.PageLayout = function OoUiPageLayout( name, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( name ) && config === undefined ) {\n\t\tconfig = name;\n\t\tname = config.name;\n\t}\n\n\t// Configuration initialization\n\tconfig = $.extend( { scrollable: true }, config );\n\n\t// Parent constructor\n\tOO.ui.PageLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.name = name;\n\tthis.outlineItem = null;\n\tthis.active = false;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-pageLayout' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.PageLayout, OO.ui.PanelLayout );\n\n/* Events */\n\n/**\n * An 'active' event is emitted when the page becomes active. Pages become active when they are\n * shown in a booklet layout that is configured to display only one page at a time.\n *\n * @event active\n * @param {boolean} active Page is active\n */\n\n/* Methods */\n\n/**\n * Get the symbolic name of the page.\n *\n * @return {string} Symbolic name of page\n */\nOO.ui.PageLayout.prototype.getName = function () {\n\treturn this.name;\n};\n\n/**\n * Check if page is active.\n *\n * Pages become active when they are shown in a {@link OO.ui.BookletLayout booklet layout} that is\n * configured to display only one page at a time. Additional CSS is applied to the page's outline\n * item to reflect the active state.\n *\n * @return {boolean} Page is active\n */\nOO.ui.PageLayout.prototype.isActive = function () {\n\treturn this.active;\n};\n\n/**\n * Get outline item.\n *\n * The outline item allows users to access the page from the booklet's outline\n * navigation. The outline item itself can be customized (with a label, level, etc.) using the\n * #setupOutlineItem method.\n *\n * @return {OO.ui.OutlineOptionWidget|null} Outline option widget\n */\nOO.ui.PageLayout.prototype.getOutlineItem = function () {\n\treturn this.outlineItem;\n};\n\n/**\n * Set or unset the outline item.\n *\n * Specify an {@link OO.ui.OutlineOptionWidget outline option} to set it,\n * or `null` to clear the outline item. To customize the outline item itself (e.g., to set a label\n * or outline level), use #setupOutlineItem instead of this method.\n *\n * @param {OO.ui.OutlineOptionWidget|null} outlineItem Outline option widget, null to clear\n * @chainable\n * @return {OO.ui.PageLayout} The layout, for chaining\n */\nOO.ui.PageLayout.prototype.setOutlineItem = function ( outlineItem ) {\n\tthis.outlineItem = outlineItem || null;\n\tif ( outlineItem ) {\n\t\tthis.setupOutlineItem();\n\t}\n\treturn this;\n};\n\n/**\n * Set up the outline item.\n *\n * Use this method to customize the outline item (e.g., to add a label or outline level). To set or\n * unset the outline item itself (with an {@link OO.ui.OutlineOptionWidget outline option} or\n * `null`), use the #setOutlineItem method instead.\n *\n * @param {OO.ui.OutlineOptionWidget} outlineItem Outline option widget to set up\n * @chainable\n * @return {OO.ui.PageLayout} The layout, for chaining\n */\nOO.ui.PageLayout.prototype.setupOutlineItem = function () {\n\treturn this;\n};\n\n/**\n * Set the page to its 'active' state.\n *\n * Pages become active when they are shown in a booklet layout that is configured to display only\n * one page at a time. Additional CSS is applied to the outline item to reflect the page's active\n * state. Outside of the booklet context, setting the active state on a page does nothing.\n *\n * @param {boolean} active Page is active\n * @fires active\n */\nOO.ui.PageLayout.prototype.setActive = function ( active ) {\n\tactive = !!active;\n\n\tif ( active !== this.active ) {\n\t\tthis.active = active;\n\t\tthis.$element.toggleClass( 'oo-ui-pageLayout-active', active );\n\t\tthis.emit( 'active', this.active );\n\t}\n};\n","/**\n * StackLayouts contain a series of {@link OO.ui.PanelLayout panel layouts}. By default, only one\n * panel is displayed at a time, though the stack layout can also be configured to show all\n * contained panels, one after another, by setting the #continuous option to 'true'.\n *\n *     @example\n *     // A stack layout with two panels, configured to be displayed continuously\n *     var myStack = new OO.ui.StackLayout( {\n *         items: [\n *             new OO.ui.PanelLayout( {\n *                 $content: $( '<p>Panel One</p>' ),\n *                 padded: true,\n *                 framed: true\n *             } ),\n *             new OO.ui.PanelLayout( {\n *                 $content: $( '<p>Panel Two</p>' ),\n *                 padded: true,\n *                 framed: true\n *             } )\n *         ],\n *         continuous: true\n *     } );\n *     $( document.body ).append( myStack.$element );\n *\n * @class\n * @extends OO.ui.PanelLayout\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel\n *  is displayed at a time.\n * @cfg {OO.ui.Layout[]} [items] Panel layouts to add to the stack layout.\n */\nOO.ui.StackLayout = function OoUiStackLayout( config ) {\n\t// Configuration initialization\n\t// Make the layout scrollable in continuous mode, otherwise each\n\t// panel is responsible for its own scrolling.\n\tconfig = $.extend( { scrollable: !!( config && config.continuous ) }, config );\n\n\t// Parent constructor\n\tOO.ui.StackLayout.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, $.extend( { $group: this.$element }, config ) );\n\n\t// Properties\n\tthis.currentItem = null;\n\tthis.continuous = !!config.continuous;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-stackLayout' );\n\tif ( this.continuous ) {\n\t\tthis.$element.addClass( 'oo-ui-stackLayout-continuous' );\n\t\tthis.$element.on( 'scroll', OO.ui.debounce( this.onScroll.bind( this ), 250 ) );\n\t}\n\tif ( Array.isArray( config.items ) ) {\n\t\tthis.addItems( config.items );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.StackLayout, OO.ui.PanelLayout );\nOO.mixinClass( OO.ui.StackLayout, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * A 'set' event is emitted when panels are {@link #addItems added}, {@link #removeItems removed},\n * {@link #clearItems cleared} or {@link #setItem displayed}.\n *\n * @event set\n * @param {OO.ui.Layout|null} item Current panel or `null` if no panel is shown\n */\n\n/**\n * When used in continuous mode, this event is emitted when the user scrolls down\n * far enough such that currentItem is no longer visible.\n *\n * @event visibleItemChange\n * @param {OO.ui.PanelLayout} panel The next visible item in the layout\n */\n\n/* Methods */\n\n/**\n * Handle scroll events from the layout element\n *\n * @param {jQuery.Event} e\n * @fires visibleItemChange\n */\nOO.ui.StackLayout.prototype.onScroll = function () {\n\tvar currentRect,\n\t\tlen = this.items.length,\n\t\tcurrentIndex = this.items.indexOf( this.currentItem ),\n\t\tnewIndex = currentIndex,\n\t\tcontainerRect = this.$element[ 0 ].getBoundingClientRect();\n\n\tif ( !containerRect || ( !containerRect.top && !containerRect.bottom ) ) {\n\t\t// Can't get bounding rect, possibly not attached.\n\t\treturn;\n\t}\n\n\tfunction getRect( item ) {\n\t\treturn item.$element[ 0 ].getBoundingClientRect();\n\t}\n\n\tfunction isVisible( item ) {\n\t\tvar rect = getRect( item );\n\t\treturn rect.bottom > containerRect.top && rect.top < containerRect.bottom;\n\t}\n\n\tcurrentRect = getRect( this.currentItem );\n\n\tif ( currentRect.bottom < containerRect.top ) {\n\t\t// Scrolled down past current item\n\t\twhile ( ++newIndex < len ) {\n\t\t\tif ( isVisible( this.items[ newIndex ] ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else if ( currentRect.top > containerRect.bottom ) {\n\t\t// Scrolled up past current item\n\t\twhile ( --newIndex >= 0 ) {\n\t\t\tif ( isVisible( this.items[ newIndex ] ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( newIndex !== currentIndex ) {\n\t\tthis.emit( 'visibleItemChange', this.items[ newIndex ] );\n\t}\n};\n\n/**\n * Get the current panel.\n *\n * @return {OO.ui.Layout|null}\n */\nOO.ui.StackLayout.prototype.getCurrentItem = function () {\n\treturn this.currentItem;\n};\n\n/**\n * Unset the current item.\n *\n * @private\n * @param {OO.ui.StackLayout} layout\n * @fires set\n */\nOO.ui.StackLayout.prototype.unsetCurrentItem = function () {\n\tvar prevItem = this.currentItem;\n\tif ( prevItem === null ) {\n\t\treturn;\n\t}\n\n\tthis.currentItem = null;\n\tthis.emit( 'set', null );\n};\n\n/**\n * Add panel layouts to the stack layout.\n *\n * Panels will be added to the end of the stack layout array unless the optional index parameter\n * specifies a different insertion point. Adding a panel that is already in the stack will move it\n * to the end of the array or the point specified by the index.\n *\n * @param {OO.ui.Layout[]} items Panels to add\n * @param {number} [index] Index of the insertion point\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n */\nOO.ui.StackLayout.prototype.addItems = function ( items, index ) {\n\t// Update the visibility\n\tthis.updateHiddenState( items, this.currentItem );\n\n\t// Mixin method\n\tOO.ui.mixin.GroupElement.prototype.addItems.call( this, items, index );\n\n\tif ( !this.currentItem && items.length ) {\n\t\tthis.setItem( items[ 0 ] );\n\t}\n\n\treturn this;\n};\n\n/**\n * Remove the specified panels from the stack layout.\n *\n * Removed panels are detached from the DOM, not removed, so that they may be reused. To remove all\n * panels, you may wish to use the #clearItems method instead.\n *\n * @param {OO.ui.Layout[]} items Panels to remove\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n * @fires set\n */\nOO.ui.StackLayout.prototype.removeItems = function ( items ) {\n\t// Mixin method\n\tOO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );\n\n\tif ( items.indexOf( this.currentItem ) !== -1 ) {\n\t\tif ( this.items.length ) {\n\t\t\tthis.setItem( this.items[ 0 ] );\n\t\t} else {\n\t\t\tthis.unsetCurrentItem();\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Clear all panels from the stack layout.\n *\n * Cleared panels are detached from the DOM, not removed, so that they may be reused. To remove only\n * a subset of panels, use the #removeItems method.\n *\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n * @fires set\n */\nOO.ui.StackLayout.prototype.clearItems = function () {\n\tthis.unsetCurrentItem();\n\tOO.ui.mixin.GroupElement.prototype.clearItems.call( this );\n\n\treturn this;\n};\n\n/**\n * Show the specified panel.\n *\n * If another panel is currently displayed, it will be hidden.\n *\n * @param {OO.ui.Layout} item Panel to show\n * @chainable\n * @return {OO.ui.StackLayout} The layout, for chaining\n * @fires set\n */\nOO.ui.StackLayout.prototype.setItem = function ( item ) {\n\tif ( item !== this.currentItem ) {\n\t\tthis.updateHiddenState( this.items, item );\n\n\t\tif ( this.items.indexOf( item ) !== -1 ) {\n\t\t\tthis.currentItem = item;\n\t\t\tthis.emit( 'set', item );\n\t\t} else {\n\t\t\tthis.unsetCurrentItem();\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Reset the scroll offset of all panels, or the container if continuous\n *\n * @inheritdoc\n */\nOO.ui.StackLayout.prototype.resetScroll = function () {\n\tif ( this.continuous ) {\n\t\t// Parent method\n\t\treturn OO.ui.StackLayout.parent.prototype.resetScroll.call( this );\n\t}\n\t// Reset each panel\n\tthis.getItems().forEach( function ( panel ) {\n\t\tvar hidden = panel.$element.hasClass( 'oo-ui-element-hidden' );\n\t\t// Scroll can only be reset when panel is visible\n\t\tpanel.$element.removeClass( 'oo-ui-element-hidden' );\n\t\tpanel.resetScroll();\n\t\tif ( hidden ) {\n\t\t\tpanel.$element.addClass( 'oo-ui-element-hidden' );\n\t\t}\n\t} );\n\n\treturn this;\n};\n\n/**\n * Update the visibility of all items in case of non-continuous view.\n *\n * Ensure all items are hidden except for the selected one.\n * This method does nothing when the stack is continuous.\n *\n * @private\n * @param {OO.ui.Layout[]} items Item list iterate over\n * @param {OO.ui.Layout} [selectedItem] Selected item to show\n */\nOO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem ) {\n\tvar i, len;\n\n\tif ( !this.continuous ) {\n\t\tfor ( i = 0, len = items.length; i < len; i++ ) {\n\t\t\tif ( !selectedItem || selectedItem !== items[ i ] ) {\n\t\t\t\titems[ i ].$element.addClass( 'oo-ui-element-hidden' );\n\t\t\t\titems[ i ].$element.attr( 'aria-hidden', 'true' );\n\t\t\t}\n\t\t}\n\t\tif ( selectedItem ) {\n\t\t\tselectedItem.$element.removeClass( 'oo-ui-element-hidden' );\n\t\t\tselectedItem.$element.removeAttr( 'aria-hidden' );\n\t\t}\n\t}\n};\n","/**\n * MenuLayouts combine a menu and a content {@link OO.ui.PanelLayout panel}. The menu is positioned\n * relative to the content (after, before, top, or bottom) and its size is customized with the\n * #menuSize config. The content area will fill all remaining space.\n *\n *     @example\n *     var menuLayout,\n *         menuPanel = new OO.ui.PanelLayout( {\n *             padded: true,\n *             expanded: true,\n *             scrollable: true\n *         } ),\n *         contentPanel = new OO.ui.PanelLayout( {\n *             padded: true,\n *             expanded: true,\n *             scrollable: true\n *         } ),\n *         select = new OO.ui.SelectWidget( {\n *             items: [\n *                 new OO.ui.OptionWidget( {\n *                     data: 'before',\n *                     label: 'Before'\n *                 } ),\n *                 new OO.ui.OptionWidget( {\n *                     data: 'after',\n *                     label: 'After'\n *                 } ),\n *                 new OO.ui.OptionWidget( {\n *                     data: 'top',\n *                     label: 'Top'\n *                 } ),\n *                 new OO.ui.OptionWidget( {\n *                     data: 'bottom',\n *                     label: 'Bottom'\n *                 } )\n *              ]\n *         } ).on( 'select', function ( item ) {\n *            menuLayout.setMenuPosition( item.getData() );\n *         } );\n *\n *     menuLayout = new OO.ui.MenuLayout( {\n *         position: 'top',\n *         menuPanel: menuPanel,\n *         contentPanel: contentPanel\n *     } );\n *     menuLayout.$menu.append(\n *         menuPanel.$element.append( '<b>Menu panel</b>', select.$element )\n *     );\n *     menuLayout.$content.append(\n *         contentPanel.$element.append(\n *             '<b>Content panel</b>',\n *             '<p>Note that the menu is positioned relative to the content panel: ' +\n *             'top, bottom, after, before.</p>'\n *          )\n *     );\n *     $( document.body ).append( menuLayout.$element );\n *\n * If menu size needs to be overridden, it can be accomplished using CSS similar to the snippet\n * below. MenuLayout's CSS will override the appropriate values with 'auto' or '0' to display the\n * menu correctly. If `menuPosition` is known beforehand, CSS rules corresponding to other positions\n * may be omitted.\n *\n *     .oo-ui-menuLayout-menu {\n *         width: 200px;\n *         height: 200px;\n *     }\n *\n *     .oo-ui-menuLayout-content {\n *         top: 200px;\n *         left: 200px;\n *         right: 200px;\n *         bottom: 200px;\n *     }\n *\n * @class\n * @extends OO.ui.Layout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.PanelLayout} [menuPanel] Menu panel\n * @cfg {OO.ui.PanelLayout} [contentPanel] Content panel\n * @cfg {boolean} [expanded=true] Expand the layout to fill the entire parent element.\n * @cfg {boolean} [showMenu=true] Show menu\n * @cfg {string} [menuPosition='before'] Position of menu: `top`, `after`, `bottom` or `before`\n */\nOO.ui.MenuLayout = function OoUiMenuLayout( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\texpanded: true,\n\t\tshowMenu: true,\n\t\tmenuPosition: 'before'\n\t}, config );\n\n\t// Parent constructor\n\tOO.ui.MenuLayout.parent.call( this, config );\n\n\tthis.menuPanel = null;\n\tthis.contentPanel = null;\n\tthis.expanded = !!config.expanded;\n\t/**\n\t * Menu DOM node\n\t *\n\t * @property {jQuery}\n\t */\n\tthis.$menu = $( '<div>' );\n\t/**\n\t * Content DOM node\n\t *\n\t * @property {jQuery}\n\t */\n\tthis.$content = $( '<div>' );\n\n\t// Initialization\n\tthis.$menu.addClass( 'oo-ui-menuLayout-menu' );\n\tthis.$content.addClass( 'oo-ui-menuLayout-content' );\n\tthis.$element.addClass( 'oo-ui-menuLayout' );\n\tif ( config.expanded ) {\n\t\tthis.$element.addClass( 'oo-ui-menuLayout-expanded' );\n\t} else {\n\t\tthis.$element.addClass( 'oo-ui-menuLayout-static' );\n\t}\n\tif ( config.menuPanel ) {\n\t\tthis.setMenuPanel( config.menuPanel );\n\t}\n\tif ( config.contentPanel ) {\n\t\tthis.setContentPanel( config.contentPanel );\n\t}\n\tthis.setMenuPosition( config.menuPosition );\n\tthis.toggleMenu( config.showMenu );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MenuLayout, OO.ui.Layout );\n\n/* Methods */\n\n/**\n * Toggle menu.\n *\n * @param {boolean} showMenu Show menu, omit to toggle\n * @chainable\n * @return {OO.ui.MenuLayout} The layout, for chaining\n */\nOO.ui.MenuLayout.prototype.toggleMenu = function ( showMenu ) {\n\tshowMenu = showMenu === undefined ? !this.showMenu : !!showMenu;\n\n\tif ( this.showMenu !== showMenu ) {\n\t\tthis.showMenu = showMenu;\n\t\tthis.$element\n\t\t\t.toggleClass( 'oo-ui-menuLayout-showMenu', this.showMenu )\n\t\t\t.toggleClass( 'oo-ui-menuLayout-hideMenu', !this.showMenu );\n\t\tthis.$menu.attr( 'aria-hidden', this.showMenu ? 'false' : 'true' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Check if menu is visible\n *\n * @return {boolean} Menu is visible\n */\nOO.ui.MenuLayout.prototype.isMenuVisible = function () {\n\treturn this.showMenu;\n};\n\n/**\n * Set menu position.\n *\n * @param {string} position Position of menu, either `top`, `after`, `bottom` or `before`\n * @chainable\n * @return {OO.ui.MenuLayout} The layout, for chaining\n */\nOO.ui.MenuLayout.prototype.setMenuPosition = function ( position ) {\n\tif ( [ 'top', 'bottom', 'before', 'after' ].indexOf( position ) === -1 ) {\n\t\tposition = 'before';\n\t}\n\n\tthis.$element.removeClass( 'oo-ui-menuLayout-' + this.menuPosition );\n\tthis.menuPosition = position;\n\tif ( this.menuPosition === 'top' || this.menuPosition === 'before' ) {\n\t\tthis.$element.append( this.$menu, this.$content );\n\t} else {\n\t\tthis.$element.append( this.$content, this.$menu );\n\t}\n\tthis.$element.addClass( 'oo-ui-menuLayout-' + position );\n\n\treturn this;\n};\n\n/**\n * Get menu position.\n *\n * @return {string} Menu position\n */\nOO.ui.MenuLayout.prototype.getMenuPosition = function () {\n\treturn this.menuPosition;\n};\n\n/**\n * Set the menu panel.\n *\n * @param {OO.ui.PanelLayout} menuPanel Menu panel\n */\nOO.ui.MenuLayout.prototype.setMenuPanel = function ( menuPanel ) {\n\tthis.menuPanel = menuPanel;\n\tthis.$menu.append( this.menuPanel.$element );\n};\n\n/**\n * Set the content panel.\n *\n * @param {OO.ui.PanelLayout} contentPanel Content panel\n */\nOO.ui.MenuLayout.prototype.setContentPanel = function ( contentPanel ) {\n\tthis.contentPanel = contentPanel;\n\tthis.$content.append( this.contentPanel.$element );\n};\n\n/**\n * Clear the menu panel.\n */\nOO.ui.MenuLayout.prototype.clearMenuPanel = function () {\n\tthis.menuPanel = null;\n\tthis.$menu.empty();\n};\n\n/**\n * Clear the content panel.\n */\nOO.ui.MenuLayout.prototype.clearContentPanel = function () {\n\tthis.contentPanel = null;\n\tthis.$content.empty();\n};\n\n/**\n * Reset the scroll offset of all panels and the tab select widget\n *\n * @inheritdoc\n */\nOO.ui.MenuLayout.prototype.resetScroll = function () {\n\tif ( this.menuPanel ) {\n\t\tthis.menuPanel.resetScroll();\n\t}\n\tif ( this.contentPanel ) {\n\t\tthis.contentPanel.resetScroll();\n\t}\n\n\treturn this;\n};\n","/**\n * BookletLayouts contain {@link OO.ui.PageLayout page layouts} as well as\n * an {@link OO.ui.OutlineSelectWidget outline} that allows users to easily navigate\n * through the pages and select which one to display. By default, only one page is\n * displayed at a time and the outline is hidden. When a user navigates to a new page,\n * the booklet layout automatically focuses on the first focusable element, unless the\n * default setting is changed. Optionally, booklets can be configured to show\n * {@link OO.ui.OutlineControlsWidget controls} for adding, moving, and removing items.\n *\n *     @example\n *     // Example of a BookletLayout that contains two PageLayouts.\n *\n *     function PageOneLayout( name, config ) {\n *         PageOneLayout.parent.call( this, name, config );\n *         this.$element.append( '<p>First page</p><p>(This booklet has an outline, displayed on ' +\n *         'the left)</p>' );\n *     }\n *     OO.inheritClass( PageOneLayout, OO.ui.PageLayout );\n *     PageOneLayout.prototype.setupOutlineItem = function () {\n *         this.outlineItem.setLabel( 'Page One' );\n *     };\n *\n *     function PageTwoLayout( name, config ) {\n *         PageTwoLayout.parent.call( this, name, config );\n *         this.$element.append( '<p>Second page</p>' );\n *     }\n *     OO.inheritClass( PageTwoLayout, OO.ui.PageLayout );\n *     PageTwoLayout.prototype.setupOutlineItem = function () {\n *         this.outlineItem.setLabel( 'Page Two' );\n *     };\n *\n *     var page1 = new PageOneLayout( 'one' ),\n *         page2 = new PageTwoLayout( 'two' );\n *\n *     var booklet = new OO.ui.BookletLayout( {\n *         outlined: true\n *     } );\n *\n *     booklet.addPages( [ page1, page2 ] );\n *     $( document.body ).append( booklet.$element );\n *\n * @class\n * @extends OO.ui.MenuLayout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [continuous=false] Show all pages, one after another\n * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is\n *  displayed. Disabled on mobile.\n * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the\n *  pages of the booklet.\n * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages.\n */\nOO.ui.BookletLayout = function OoUiBookletLayout( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.BookletLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.currentPageName = null;\n\tthis.pages = {};\n\tthis.ignoreFocus = false;\n\tthis.stackLayout = new OO.ui.StackLayout( {\n\t\tcontinuous: !!config.continuous,\n\t\texpanded: this.expanded\n\t} );\n\tthis.setContentPanel( this.stackLayout );\n\tthis.autoFocus = config.autoFocus === undefined || !!config.autoFocus;\n\tthis.outlineVisible = false;\n\tthis.outlined = !!config.outlined;\n\tif ( this.outlined ) {\n\t\tthis.editable = !!config.editable;\n\t\tthis.outlineControlsWidget = null;\n\t\tthis.outlineSelectWidget = new OO.ui.OutlineSelectWidget();\n\t\tthis.outlinePanel = new OO.ui.PanelLayout( {\n\t\t\texpanded: this.expanded,\n\t\t\tscrollable: true\n\t\t} );\n\t\tthis.setMenuPanel( this.outlinePanel );\n\t\tthis.outlineVisible = true;\n\t\tif ( this.editable ) {\n\t\t\tthis.outlineControlsWidget = new OO.ui.OutlineControlsWidget(\n\t\t\t\tthis.outlineSelectWidget\n\t\t\t);\n\t\t}\n\t}\n\tthis.toggleMenu( this.outlined );\n\n\t// Events\n\tthis.stackLayout.connect( this, {\n\t\tset: 'onStackLayoutSet'\n\t} );\n\tif ( this.outlined ) {\n\t\tthis.outlineSelectWidget.connect( this, {\n\t\t\tselect: 'onOutlineSelectWidgetSelect'\n\t\t} );\n\t\tthis.scrolling = false;\n\t\tthis.stackLayout.connect( this, {\n\t\t\tvisibleItemChange: 'onStackLayoutVisibleItemChange'\n\t\t} );\n\t}\n\tif ( this.autoFocus ) {\n\t\t// Event 'focus' does not bubble, but 'focusin' does\n\t\tthis.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );\n\t}\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-bookletLayout' );\n\tthis.stackLayout.$element.addClass( 'oo-ui-bookletLayout-stackLayout' );\n\tif ( this.outlined ) {\n\t\tthis.outlinePanel.$element\n\t\t\t.addClass( 'oo-ui-bookletLayout-outlinePanel' )\n\t\t\t.append( this.outlineSelectWidget.$element );\n\t\tif ( this.editable ) {\n\t\t\tthis.outlinePanel.$element\n\t\t\t\t.addClass( 'oo-ui-bookletLayout-outlinePanel-editable' )\n\t\t\t\t.append( this.outlineControlsWidget.$element );\n\t\t}\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.BookletLayout, OO.ui.MenuLayout );\n\n/* Events */\n\n/**\n * A 'set' event is emitted when a page is {@link #setPage set} to be displayed by the\n * booklet layout.\n * @event set\n * @param {OO.ui.PageLayout} page Current page\n */\n\n/**\n * An 'add' event is emitted when pages are {@link #addPages added} to the booklet layout.\n *\n * @event add\n * @param {OO.ui.PageLayout[]} page Added pages\n * @param {number} index Index pages were added at\n */\n\n/**\n * A 'remove' event is emitted when pages are {@link #clearPages cleared} or\n * {@link #removePages removed} from the booklet.\n *\n * @event remove\n * @param {OO.ui.PageLayout[]} pages Removed pages\n */\n\n/* Methods */\n\n/**\n * Handle stack layout focus.\n *\n * @private\n * @param {jQuery.Event} e Focusin event\n */\nOO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {\n\tvar name, $target;\n\n\t// Find the page that an element was focused within\n\t$target = $( e.target ).closest( '.oo-ui-pageLayout' );\n\tfor ( name in this.pages ) {\n\t\t// Check for page match, exclude current page to find only page changes\n\t\tif ( this.pages[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentPageName ) {\n\t\t\tthis.setPage( name );\n\t\t\tbreak;\n\t\t}\n\t}\n};\n\n/**\n * Handle visibleItemChange events from the stackLayout\n *\n * The next visible page is set as the current page by selecting it\n * in the outline\n *\n * @param {OO.ui.PageLayout} page The next visible page in the layout\n */\nOO.ui.BookletLayout.prototype.onStackLayoutVisibleItemChange = function ( page ) {\n\t// Set a flag to so that the resulting call to #onStackLayoutSet doesn't\n\t// try and scroll the item into view again.\n\tthis.scrolling = true;\n\tthis.outlineSelectWidget.selectItemByData( page.getName() );\n\tthis.scrolling = false;\n};\n\n/**\n * Handle stack layout set events.\n *\n * @private\n * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel\n */\nOO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {\n\tvar promise, layout = this;\n\t// If everything is unselected, do nothing\n\tif ( !page ) {\n\t\treturn;\n\t}\n\t// For continuous BookletLayouts, scroll the selected page into view first\n\tif ( this.stackLayout.continuous && !this.scrolling ) {\n\t\tpromise = page.scrollElementIntoView();\n\t} else {\n\t\tpromise = $.Deferred().resolve();\n\t}\n\t// Focus the first element on the newly selected panel.\n\t// Don't focus if the page was set by scrolling.\n\tif ( this.autoFocus && !OO.ui.isMobile() && !this.scrolling ) {\n\t\tpromise.done( function () {\n\t\t\tlayout.focus();\n\t\t} );\n\t}\n};\n\n/**\n * Focus the first input in the current page.\n *\n * If no page is selected, the first selectable page will be selected.\n * If the focus is already in an element on the current page, nothing will happen.\n *\n * @param {number} [itemIndex] A specific item to focus on\n */\nOO.ui.BookletLayout.prototype.focus = function ( itemIndex ) {\n\tvar page,\n\t\titems = this.stackLayout.getItems();\n\n\tif ( itemIndex !== undefined && items[ itemIndex ] ) {\n\t\tpage = items[ itemIndex ];\n\t} else {\n\t\tpage = this.stackLayout.getCurrentItem();\n\t}\n\n\tif ( !page && this.outlined ) {\n\t\tthis.selectFirstSelectablePage();\n\t\tpage = this.stackLayout.getCurrentItem();\n\t}\n\tif ( !page ) {\n\t\treturn;\n\t}\n\t// Only change the focus if is not already in the current page\n\tif ( !OO.ui.contains( page.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {\n\t\tpage.focus();\n\t}\n};\n\n/**\n * Find the first focusable input in the booklet layout and focus\n * on it.\n */\nOO.ui.BookletLayout.prototype.focusFirstFocusable = function () {\n\tOO.ui.findFocusable( this.stackLayout.$element ).focus();\n};\n\n/**\n * Handle outline widget select events.\n *\n * @private\n * @param {OO.ui.OptionWidget|null} item Selected item\n */\nOO.ui.BookletLayout.prototype.onOutlineSelectWidgetSelect = function ( item ) {\n\tif ( item ) {\n\t\tthis.setPage( item.getData() );\n\t}\n};\n\n/**\n * Check if booklet has an outline.\n *\n * @return {boolean} Booklet has an outline\n */\nOO.ui.BookletLayout.prototype.isOutlined = function () {\n\treturn this.outlined;\n};\n\n/**\n * Check if booklet has editing controls.\n *\n * @return {boolean} Booklet is editable\n */\nOO.ui.BookletLayout.prototype.isEditable = function () {\n\treturn this.editable;\n};\n\n/**\n * Check if booklet has a visible outline.\n *\n * @return {boolean} Outline is visible\n */\nOO.ui.BookletLayout.prototype.isOutlineVisible = function () {\n\treturn this.outlined && this.outlineVisible;\n};\n\n/**\n * Hide or show the outline.\n *\n * @param {boolean} [show] Show outline, omit to invert current state\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {\n\tvar booklet = this;\n\n\tif ( this.outlined ) {\n\t\tshow = show === undefined ? !this.outlineVisible : !!show;\n\t\tthis.outlineVisible = show;\n\t\tthis.toggleMenu( show );\n\t\tif ( show && this.editable ) {\n\t\t\t// HACK: Kill dumb scrollbars when the sidebar stops animating, see T161798.\n\t\t\t// Only necessary when outline controls are present, delay matches transition on\n\t\t\t// `.oo-ui-menuLayout-menu`.\n\t\t\tsetTimeout( function () {\n\t\t\t\tOO.ui.Element.static.reconsiderScrollbars( booklet.outlinePanel.$element[ 0 ] );\n\t\t\t}, OO.ui.theme.getDialogTransitionDuration() );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Find the page closest to the specified page.\n *\n * @param {OO.ui.PageLayout} page Page to use as a reference point\n * @return {OO.ui.PageLayout|null} Page closest to the specified page\n */\nOO.ui.BookletLayout.prototype.findClosestPage = function ( page ) {\n\tvar next, prev, level,\n\t\tpages = this.stackLayout.getItems(),\n\t\tindex = pages.indexOf( page );\n\n\tif ( index !== -1 ) {\n\t\tnext = pages[ index + 1 ];\n\t\tprev = pages[ index - 1 ];\n\t\t// Prefer adjacent pages at the same level\n\t\tif ( this.outlined ) {\n\t\t\tlevel = this.outlineSelectWidget.findItemFromData( page.getName() ).getLevel();\n\t\t\tif (\n\t\t\t\tprev &&\n\t\t\t\tlevel === this.outlineSelectWidget.findItemFromData( prev.getName() ).getLevel()\n\t\t\t) {\n\t\t\t\treturn prev;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tnext &&\n\t\t\t\tlevel === this.outlineSelectWidget.findItemFromData( next.getName() ).getLevel()\n\t\t\t) {\n\t\t\t\treturn next;\n\t\t\t}\n\t\t}\n\t}\n\treturn prev || next || null;\n};\n\n/**\n * Get the outline widget.\n *\n * If the booklet is not outlined, the method will return `null`.\n *\n * @return {OO.ui.OutlineSelectWidget|null} Outline widget, or null if the booklet is not outlined\n */\nOO.ui.BookletLayout.prototype.getOutline = function () {\n\treturn this.outlineSelectWidget;\n};\n\n/**\n * Get the outline controls widget.\n *\n * If the outline is not editable, the method will return `null`.\n *\n * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget.\n */\nOO.ui.BookletLayout.prototype.getOutlineControls = function () {\n\treturn this.outlineControlsWidget;\n};\n\n/**\n * Get a page by its symbolic name.\n *\n * @param {string} name Symbolic name of page\n * @return {OO.ui.PageLayout|undefined} Page, if found\n */\nOO.ui.BookletLayout.prototype.getPage = function ( name ) {\n\treturn this.pages[ name ];\n};\n\n/**\n * Get the current page.\n *\n * @return {OO.ui.PageLayout|undefined} Current page, if found\n */\nOO.ui.BookletLayout.prototype.getCurrentPage = function () {\n\tvar name = this.getCurrentPageName();\n\treturn name ? this.getPage( name ) : undefined;\n};\n\n/**\n * Get the symbolic name of the current page.\n *\n * @return {string|null} Symbolic name of the current page\n */\nOO.ui.BookletLayout.prototype.getCurrentPageName = function () {\n\treturn this.currentPageName;\n};\n\n/**\n * Add pages to the booklet layout\n *\n * When pages are added with the same names as existing pages, the existing pages will be\n * automatically removed before the new pages are added.\n *\n * @param {OO.ui.PageLayout[]} pages Pages to add\n * @param {number} index Index of the insertion point\n * @fires add\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {\n\tvar i, len, name, page, item, currentIndex,\n\t\tstackLayoutPages = this.stackLayout.getItems(),\n\t\tremove = [],\n\t\titems = [];\n\n\t// Remove pages with same names\n\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\tpage = pages[ i ];\n\t\tname = page.getName();\n\n\t\tif ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) {\n\t\t\t// Correct the insertion index\n\t\t\tcurrentIndex = stackLayoutPages.indexOf( this.pages[ name ] );\n\t\t\tif ( currentIndex !== -1 && currentIndex + 1 < index ) {\n\t\t\t\tindex--;\n\t\t\t}\n\t\t\tremove.push( this.pages[ name ] );\n\t\t}\n\t}\n\tif ( remove.length ) {\n\t\tthis.removePages( remove );\n\t}\n\n\t// Add new pages\n\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\tpage = pages[ i ];\n\t\tname = page.getName();\n\t\tthis.pages[ page.getName() ] = page;\n\t\tif ( this.outlined ) {\n\t\t\titem = new OO.ui.OutlineOptionWidget( { data: name } );\n\t\t\tpage.setOutlineItem( item );\n\t\t\titems.push( item );\n\t\t}\n\t}\n\n\tif ( this.outlined && items.length ) {\n\t\tthis.outlineSelectWidget.addItems( items, index );\n\t\tthis.selectFirstSelectablePage();\n\t}\n\tthis.stackLayout.addItems( pages, index );\n\tthis.emit( 'add', pages, index );\n\n\treturn this;\n};\n\n/**\n * Remove the specified pages from the booklet layout.\n *\n * To remove all pages from the booklet, you may wish to use the #clearPages method instead.\n *\n * @param {OO.ui.PageLayout[]} pages An array of pages to remove\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.removePages = function ( pages ) {\n\tvar i, len, name, page,\n\t\titems = [];\n\n\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\tpage = pages[ i ];\n\t\tname = page.getName();\n\t\tdelete this.pages[ name ];\n\t\tif ( this.outlined ) {\n\t\t\titems.push( this.outlineSelectWidget.findItemFromData( name ) );\n\t\t\tpage.setOutlineItem( null );\n\t\t}\n\t}\n\tif ( this.outlined && items.length ) {\n\t\tthis.outlineSelectWidget.removeItems( items );\n\t\tthis.selectFirstSelectablePage();\n\t}\n\tthis.stackLayout.removeItems( pages );\n\tthis.emit( 'remove', pages );\n\n\treturn this;\n};\n\n/**\n * Clear all pages from the booklet layout.\n *\n * To remove only a subset of pages from the booklet, use the #removePages method.\n *\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.clearPages = function () {\n\tvar i, len,\n\t\tpages = this.stackLayout.getItems();\n\n\tthis.pages = {};\n\tthis.currentPageName = null;\n\tif ( this.outlined ) {\n\t\tthis.outlineSelectWidget.clearItems();\n\t\tfor ( i = 0, len = pages.length; i < len; i++ ) {\n\t\t\tpages[ i ].setOutlineItem( null );\n\t\t}\n\t}\n\tthis.stackLayout.clearItems();\n\n\tthis.emit( 'remove', pages );\n\n\treturn this;\n};\n\n/**\n * Set the current page by symbolic name.\n *\n * @fires set\n * @param {string} name Symbolic name of page\n */\nOO.ui.BookletLayout.prototype.setPage = function ( name ) {\n\tvar selectedItem,\n\t\t$focused,\n\t\tpage = this.pages[ name ],\n\t\tpreviousPage = this.currentPageName && this.pages[ this.currentPageName ];\n\n\tif ( name !== this.currentPageName ) {\n\t\tif ( this.outlined ) {\n\t\t\tselectedItem = this.outlineSelectWidget.findSelectedItem();\n\t\t\tif ( selectedItem && selectedItem.getData() !== name ) {\n\t\t\t\tthis.outlineSelectWidget.selectItemByData( name );\n\t\t\t}\n\t\t}\n\t\tif ( page ) {\n\t\t\tif ( previousPage ) {\n\t\t\t\tpreviousPage.setActive( false );\n\t\t\t\t// Blur anything focused if the next page doesn't have anything focusable.\n\t\t\t\t// This is not needed if the next page has something focusable (because once it is\n\t\t\t\t// focused this blur happens automatically). If the layout is non-continuous, this\n\t\t\t\t// check is meaningless because the next page is not visible yet and thus can't\n\t\t\t\t// hold focus.\n\t\t\t\tif (\n\t\t\t\t\tthis.autoFocus &&\n\t\t\t\t\t!OO.ui.isMobile() &&\n\t\t\t\t\tthis.stackLayout.continuous &&\n\t\t\t\t\tOO.ui.findFocusable( page.$element ).length !== 0\n\t\t\t\t) {\n\t\t\t\t\t$focused = previousPage.$element.find( ':focus' );\n\t\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentPageName = name;\n\t\t\tpage.setActive( true );\n\t\t\tthis.stackLayout.setItem( page );\n\t\t\tif ( !this.stackLayout.continuous && previousPage ) {\n\t\t\t\t// This should not be necessary, since any inputs on the previous page should have\n\t\t\t\t// been blurred when it was hidden, but browsers are not very consistent about\n\t\t\t\t// this.\n\t\t\t\t$focused = previousPage.$element.find( ':focus' );\n\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.emit( 'set', page );\n\t\t}\n\t}\n};\n\n/**\n * For outlined-continuous booklets, also reset the outlineSelectWidget to the first item.\n *\n * @inheritdoc\n */\nOO.ui.BookletLayout.prototype.resetScroll = function () {\n\t// Parent method\n\tOO.ui.BookletLayout.parent.prototype.resetScroll.call( this );\n\n\tif (\n\t\tthis.outlined &&\n\t\tthis.stackLayout.continuous &&\n\t\tthis.outlineSelectWidget.findFirstSelectableItem()\n\t) {\n\t\tthis.scrolling = true;\n\t\tthis.outlineSelectWidget.selectItem( this.outlineSelectWidget.findFirstSelectableItem() );\n\t\tthis.scrolling = false;\n\t}\n\treturn this;\n};\n\n/**\n * Select the first selectable page.\n *\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {\n\tif ( !this.outlineSelectWidget.findSelectedItem() ) {\n\t\tthis.outlineSelectWidget.selectItem( this.outlineSelectWidget.findFirstSelectableItem() );\n\t}\n\n\treturn this;\n};\n","/**\n * IndexLayouts contain {@link OO.ui.TabPanelLayout tab panel layouts} as well as\n * {@link OO.ui.TabSelectWidget tabs} that allow users to easily navigate through the tab panels\n * and select which one to display. By default, only one tab panel is displayed at a time. When a\n * user navigates to a new tab panel, the index layout automatically focuses on the first focusable\n * element, unless the default setting is changed.\n *\n * TODO: This class is similar to BookletLayout, we may want to refactor to reduce duplication\n *\n *     @example\n *     // Example of a IndexLayout that contains two TabPanelLayouts.\n *\n *     function TabPanelOneLayout( name, config ) {\n *         TabPanelOneLayout.parent.call( this, name, config );\n *         this.$element.append( '<p>First tab panel</p>' );\n *     }\n *     OO.inheritClass( TabPanelOneLayout, OO.ui.TabPanelLayout );\n *     TabPanelOneLayout.prototype.setupTabItem = function () {\n *         this.tabItem.setLabel( 'Tab panel one' );\n *     };\n *\n *     var tabPanel1 = new TabPanelOneLayout( 'one' ),\n *         tabPanel2 = new OO.ui.TabPanelLayout( 'two', { label: 'Tab panel two' } );\n *\n *     tabPanel2.$element.append( '<p>Second tab panel</p>' );\n *\n *     var index = new OO.ui.IndexLayout();\n *\n *     index.addTabPanels( [ tabPanel1, tabPanel2 ] );\n *     $( document.body ).append( index.$element );\n *\n * @class\n * @extends OO.ui.MenuLayout\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.ui.StackLayout} [contentPanel] Content stack (see MenuLayout)\n * @cfg {boolean} [continuous=false] Show all tab panels, one after another\n * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new tab panel is\n *  displayed. Disabled on mobile.\n */\nOO.ui.IndexLayout = function OoUiIndexLayout( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( {}, config, { menuPosition: 'top' } );\n\n\t// Parent constructor\n\tOO.ui.IndexLayout.parent.call( this, config );\n\n\t// Properties\n\tthis.currentTabPanelName = null;\n\t// Allow infused widgets to pass existing tabPanels\n\tthis.tabPanels = config.tabPanels || {};\n\n\tthis.ignoreFocus = false;\n\tthis.stackLayout = this.contentPanel || new OO.ui.StackLayout( {\n\t\tcontinuous: !!config.continuous,\n\t\texpanded: this.expanded\n\t} );\n\tthis.setContentPanel( this.stackLayout );\n\tthis.autoFocus = config.autoFocus === undefined || !!config.autoFocus;\n\n\t// Allow infused widgets to pass an existing tabSelectWidget\n\tthis.tabSelectWidget = config.tabSelectWidget || new OO.ui.TabSelectWidget();\n\tthis.tabPanel = this.menuPanel || new OO.ui.PanelLayout( {\n\t\texpanded: this.expanded\n\t} );\n\tthis.setMenuPanel( this.tabPanel );\n\n\tthis.toggleMenu( true );\n\n\t// Events\n\tthis.stackLayout.connect( this, {\n\t\tset: 'onStackLayoutSet'\n\t} );\n\tthis.tabSelectWidget.connect( this, {\n\t\tselect: 'onTabSelectWidgetSelect'\n\t} );\n\tif ( this.autoFocus ) {\n\t\t// Event 'focus' does not bubble, but 'focusin' does.\n\t\tthis.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );\n\t}\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-indexLayout' );\n\tthis.stackLayout.$element.addClass( 'oo-ui-indexLayout-stackLayout' );\n\tthis.tabPanel.$element\n\t\t.addClass( 'oo-ui-indexLayout-tabPanel' )\n\t\t.append( this.tabSelectWidget.$element );\n\n\tthis.selectFirstSelectableTabPanel();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.IndexLayout, OO.ui.MenuLayout );\n\n/* Events */\n\n/**\n * A 'set' event is emitted when a tab panel is {@link #setTabPanel set} to be displayed by the\n * index layout.\n *\n * @event set\n * @param {OO.ui.TabPanelLayout} tabPanel Current tab panel\n */\n\n/**\n * An 'add' event is emitted when tab panels are {@link #addTabPanels added} to the index layout.\n *\n * @event add\n * @param {OO.ui.TabPanelLayout[]} tabPanel Added tab panels\n * @param {number} index Index tab panels were added at\n */\n\n/**\n * A 'remove' event is emitted when tab panels are {@link #clearTabPanels cleared} or\n * {@link #removeTabPanels removed} from the index.\n *\n * @event remove\n * @param {OO.ui.TabPanelLayout[]} tabPanel Removed tab panels\n */\n\n/* Methods */\n\n/**\n * Handle stack layout focus.\n *\n * @private\n * @param {jQuery.Event} e Focusing event\n */\nOO.ui.IndexLayout.prototype.onStackLayoutFocus = function ( e ) {\n\tvar name, $target;\n\n\t// Find the tab panel that an element was focused within\n\t$target = $( e.target ).closest( '.oo-ui-tabPanelLayout' );\n\tfor ( name in this.tabPanels ) {\n\t\t// Check for tab panel match, exclude current tab panel to find only tab panel changes\n\t\tif ( this.tabPanels[ name ].$element[ 0 ] === $target[ 0 ] &&\n\t\t\t\tname !== this.currentTabPanelName ) {\n\t\t\tthis.setTabPanel( name );\n\t\t\tbreak;\n\t\t}\n\t}\n};\n\n/**\n * Handle stack layout set events.\n *\n * @private\n * @param {OO.ui.PanelLayout|null} tabPanel The tab panel that is now the current panel\n */\nOO.ui.IndexLayout.prototype.onStackLayoutSet = function ( tabPanel ) {\n\t// If everything is unselected, do nothing\n\tif ( !tabPanel ) {\n\t\treturn;\n\t}\n\t// Focus the first element on the newly selected panel\n\tif ( this.autoFocus && !OO.ui.isMobile() ) {\n\t\tthis.focus();\n\t}\n};\n\n/**\n * Focus the first input in the current tab panel.\n *\n * If no tab panel is selected, the first selectable tab panel will be selected.\n * If the focus is already in an element on the current tab panel, nothing will happen.\n *\n * @param {number} [itemIndex] A specific item to focus on\n */\nOO.ui.IndexLayout.prototype.focus = function ( itemIndex ) {\n\tvar tabPanel,\n\t\titems = this.stackLayout.getItems();\n\n\tif ( itemIndex !== undefined && items[ itemIndex ] ) {\n\t\ttabPanel = items[ itemIndex ];\n\t} else {\n\t\ttabPanel = this.stackLayout.getCurrentItem();\n\t}\n\n\tif ( !tabPanel ) {\n\t\tthis.selectFirstSelectableTabPanel();\n\t\ttabPanel = this.stackLayout.getCurrentItem();\n\t}\n\tif ( !tabPanel ) {\n\t\treturn;\n\t}\n\t// Only change the focus if is not already in the current page\n\tif ( !OO.ui.contains(\n\t\ttabPanel.$element[ 0 ],\n\t\tthis.getElementDocument().activeElement,\n\t\ttrue\n\t) ) {\n\t\ttabPanel.focus();\n\t}\n};\n\n/**\n * Find the first focusable input in the index layout and focus\n * on it.\n */\nOO.ui.IndexLayout.prototype.focusFirstFocusable = function () {\n\tOO.ui.findFocusable( this.stackLayout.$element ).focus();\n};\n\n/**\n * Handle tab widget select events.\n *\n * @private\n * @param {OO.ui.OptionWidget|null} item Selected item\n */\nOO.ui.IndexLayout.prototype.onTabSelectWidgetSelect = function ( item ) {\n\tif ( item ) {\n\t\tthis.setTabPanel( item.getData() );\n\t}\n};\n\n/**\n * Get the tab panel closest to the specified tab panel.\n *\n * @param {OO.ui.TabPanelLayout} tabPanel Tab panel to use as a reference point\n * @return {OO.ui.TabPanelLayout|null} Tab panel closest to the specified\n */\nOO.ui.IndexLayout.prototype.getClosestTabPanel = function ( tabPanel ) {\n\tvar next, prev, level,\n\t\ttabPanels = this.stackLayout.getItems(),\n\t\tindex = tabPanels.indexOf( tabPanel );\n\n\tif ( index !== -1 ) {\n\t\tnext = tabPanels[ index + 1 ];\n\t\tprev = tabPanels[ index - 1 ];\n\t\t// Prefer adjacent tab panels at the same level\n\t\tlevel = this.tabSelectWidget.findItemFromData( tabPanel.getName() ).getLevel();\n\t\tif (\n\t\t\tprev &&\n\t\t\tlevel === this.tabSelectWidget.findItemFromData( prev.getName() ).getLevel()\n\t\t) {\n\t\t\treturn prev;\n\t\t}\n\t\tif (\n\t\t\tnext &&\n\t\t\tlevel === this.tabSelectWidget.findItemFromData( next.getName() ).getLevel()\n\t\t) {\n\t\t\treturn next;\n\t\t}\n\t}\n\treturn prev || next || null;\n};\n\n/**\n * Get the tabs widget.\n *\n * @return {OO.ui.TabSelectWidget} Tabs widget\n */\nOO.ui.IndexLayout.prototype.getTabs = function () {\n\treturn this.tabSelectWidget;\n};\n\n/**\n * Get a tab panel by its symbolic name.\n *\n * @param {string} name Symbolic name of tab panel\n * @return {OO.ui.TabPanelLayout|undefined} Tab panel, if found\n */\nOO.ui.IndexLayout.prototype.getTabPanel = function ( name ) {\n\treturn this.tabPanels[ name ];\n};\n\n/**\n * Get the current tab panel.\n *\n * @return {OO.ui.TabPanelLayout|undefined} Current tab panel, if found\n */\nOO.ui.IndexLayout.prototype.getCurrentTabPanel = function () {\n\tvar name = this.getCurrentTabPanelName();\n\treturn name ? this.getTabPanel( name ) : undefined;\n};\n\n/**\n * Get the symbolic name of the current tab panel.\n *\n * @return {string|null} Symbolic name of the current tab panel\n */\nOO.ui.IndexLayout.prototype.getCurrentTabPanelName = function () {\n\treturn this.currentTabPanelName;\n};\n\n/**\n * Add tab panels to the index layout.\n *\n * When tab panels are added with the same names as existing tab panels, the existing tab panels\n * will be automatically removed before the new tab panels are added.\n *\n * @param {OO.ui.TabPanelLayout[]} tabPanels Tab panels to add\n * @param {number} index Index of the insertion point\n * @fires add\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.addTabPanels = function ( tabPanels, index ) {\n\tvar i, len, name, tabPanel, item, currentIndex,\n\t\tstackLayoutTabPanels = this.stackLayout.getItems(),\n\t\tremove = [],\n\t\titems = [];\n\n\t// Remove tab panels with same names\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanel = tabPanels[ i ];\n\t\tname = tabPanel.getName();\n\n\t\tif ( Object.prototype.hasOwnProperty.call( this.tabPanels, name ) ) {\n\t\t\t// Correct the insertion index\n\t\t\tcurrentIndex = stackLayoutTabPanels.indexOf( this.tabPanels[ name ] );\n\t\t\tif ( currentIndex !== -1 && currentIndex + 1 < index ) {\n\t\t\t\tindex--;\n\t\t\t}\n\t\t\tremove.push( this.tabPanels[ name ] );\n\t\t}\n\t}\n\tif ( remove.length ) {\n\t\tthis.removeTabPanels( remove );\n\t}\n\n\t// Add new tab panels\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanel = tabPanels[ i ];\n\t\tname = tabPanel.getName();\n\t\tthis.tabPanels[ tabPanel.getName() ] = tabPanel;\n\t\titem = new OO.ui.TabOptionWidget( { data: name } );\n\t\ttabPanel.setTabItem( item );\n\t\titems.push( item );\n\t}\n\n\tif ( items.length ) {\n\t\tthis.tabSelectWidget.addItems( items, index );\n\t\tthis.selectFirstSelectableTabPanel();\n\t}\n\tthis.stackLayout.addItems( tabPanels, index );\n\tthis.emit( 'add', tabPanels, index );\n\n\treturn this;\n};\n\n/**\n * Remove the specified tab panels from the index layout.\n *\n * To remove all tab panels from the index, you may wish to use the #clearTabPanels method instead.\n *\n * @param {OO.ui.TabPanelLayout[]} tabPanels An array of tab panels to remove\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.removeTabPanels = function ( tabPanels ) {\n\tvar i, len, name, tabPanel,\n\t\titems = [];\n\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanel = tabPanels[ i ];\n\t\tname = tabPanel.getName();\n\t\tdelete this.tabPanels[ name ];\n\t\titems.push( this.tabSelectWidget.findItemFromData( name ) );\n\t\ttabPanel.setTabItem( null );\n\t}\n\tif ( items.length ) {\n\t\tthis.tabSelectWidget.removeItems( items );\n\t\tthis.selectFirstSelectableTabPanel();\n\t}\n\tthis.stackLayout.removeItems( tabPanels );\n\tthis.emit( 'remove', tabPanels );\n\n\treturn this;\n};\n\n/**\n * Clear all tab panels from the index layout.\n *\n * To remove only a subset of tab panels from the index, use the #removeTabPanels method.\n *\n * @fires remove\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.clearTabPanels = function () {\n\tvar i, len,\n\t\ttabPanels = this.stackLayout.getItems();\n\n\tthis.tabPanels = {};\n\tthis.currentTabPanelName = null;\n\tthis.tabSelectWidget.clearItems();\n\tfor ( i = 0, len = tabPanels.length; i < len; i++ ) {\n\t\ttabPanels[ i ].setTabItem( null );\n\t}\n\tthis.stackLayout.clearItems();\n\n\tthis.emit( 'remove', tabPanels );\n\n\treturn this;\n};\n\n/**\n * Set the current tab panel by symbolic name.\n *\n * @fires set\n * @param {string} name Symbolic name of tab panel\n */\nOO.ui.IndexLayout.prototype.setTabPanel = function ( name ) {\n\tvar selectedItem,\n\t\t$focused,\n\t\tpreviousTabPanel,\n\t\ttabPanel = this.tabPanels[ name ];\n\n\tif ( name !== this.currentTabPanelName ) {\n\t\tpreviousTabPanel = this.getCurrentTabPanel();\n\t\tselectedItem = this.tabSelectWidget.findSelectedItem();\n\t\tif ( selectedItem && selectedItem.getData() !== name ) {\n\t\t\tthis.tabSelectWidget.selectItemByData( name );\n\t\t}\n\t\tif ( tabPanel ) {\n\t\t\tif ( previousTabPanel ) {\n\t\t\t\tpreviousTabPanel.setActive( false );\n\t\t\t\t// Blur anything focused if the next tab panel doesn't have anything focusable.\n\t\t\t\t// This is not needed if the next tab panel has something focusable (because once\n\t\t\t\t// it is focused this blur happens automatically). If the layout is non-continuous,\n\t\t\t\t// this check is meaningless because the next tab panel is not visible yet and thus\n\t\t\t\t// can't hold focus.\n\t\t\t\tif (\n\t\t\t\t\tthis.autoFocus &&\n\t\t\t\t\t!OO.ui.isMobile() &&\n\t\t\t\t\tthis.stackLayout.continuous &&\n\t\t\t\t\tOO.ui.findFocusable( tabPanel.$element ).length !== 0\n\t\t\t\t) {\n\t\t\t\t\t$focused = previousTabPanel.$element.find( ':focus' );\n\t\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentTabPanelName = name;\n\t\t\ttabPanel.setActive( true );\n\t\t\tthis.stackLayout.setItem( tabPanel );\n\t\t\tif ( !this.stackLayout.continuous && previousTabPanel ) {\n\t\t\t\t// This should not be necessary, since any inputs on the previous tab panel should\n\t\t\t\t// have been blurred when it was hidden, but browsers are not very consistent about\n\t\t\t\t// this.\n\t\t\t\t$focused = previousTabPanel.$element.find( ':focus' );\n\t\t\t\tif ( $focused.length ) {\n\t\t\t\t\t$focused[ 0 ].blur();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.emit( 'set', tabPanel );\n\t\t}\n\t}\n};\n\n/**\n * Select the first selectable tab panel.\n *\n * @chainable\n * @return {OO.ui.BookletLayout} The layout, for chaining\n */\nOO.ui.IndexLayout.prototype.selectFirstSelectableTabPanel = function () {\n\tif ( !this.tabSelectWidget.findSelectedItem() ) {\n\t\tthis.tabSelectWidget.selectItem( this.tabSelectWidget.findFirstSelectableItem() );\n\t}\n\n\treturn this;\n};\n","/**\n * ToggleWidget implements basic behavior of widgets with an on/off state.\n * Please see OO.ui.ToggleButtonWidget and OO.ui.ToggleSwitchWidget for examples.\n *\n * @abstract\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [value=false] The toggle’s initial on/off state.\n *  By default, the toggle is in the 'off' state.\n */\nOO.ui.ToggleWidget = function OoUiToggleWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ToggleWidget.parent.call( this, config );\n\n\t// Mixin constructor\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\t// Properties\n\tthis.value = null;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-toggleWidget' );\n\tthis.setValue( !!config.value );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToggleWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.ToggleWidget, OO.ui.mixin.TitledElement );\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the on/off state of the toggle changes.\n *\n * @param {boolean} value Value representing the new state of the toggle\n */\n\n/* Methods */\n\n/**\n * Get the value representing the toggle’s state.\n *\n * @return {boolean} The on/off state of the toggle\n */\nOO.ui.ToggleWidget.prototype.getValue = function () {\n\treturn this.value;\n};\n\n/**\n * Set the state of the toggle: `true` for 'on', `false` for 'off'.\n *\n * @param {boolean} value The state of the toggle\n * @fires change\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.ToggleWidget.prototype.setValue = function ( value ) {\n\tvalue = !!value;\n\tif ( this.value !== value ) {\n\t\tthis.value = value;\n\t\tthis.emit( 'change', value );\n\t\tthis.$element.toggleClass( 'oo-ui-toggleWidget-on', value );\n\t\tthis.$element.toggleClass( 'oo-ui-toggleWidget-off', !value );\n\t}\n\treturn this;\n};\n","/**\n * ToggleButtons are buttons that have a state (‘on’ or ‘off’) that is represented by a\n * Boolean value. Like other {@link OO.ui.ButtonWidget buttons}, toggle buttons can be\n * configured with {@link OO.ui.mixin.IconElement icons},\n * {@link OO.ui.mixin.IndicatorElement indicators},\n * {@link OO.ui.mixin.TitledElement titles}, {@link OO.ui.mixin.FlaggedElement styling flags},\n * and {@link OO.ui.mixin.LabelElement labels}. Please see\n * the [OOUI documentation][1] on MediaWiki for more information.\n *\n *     @example\n *     // Toggle buttons in the 'off' and 'on' state.\n *     var toggleButton1 = new OO.ui.ToggleButtonWidget( {\n *             label: 'Toggle Button off'\n *         } ),\n *         toggleButton2 = new OO.ui.ToggleButtonWidget( {\n *             label: 'Toggle Button on',\n *             value: true\n *         } );\n *     // Append the buttons to the DOM.\n *     $( document.body ).append( toggleButton1.$element, toggleButton2.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Buttons_and_Switches#Toggle_buttons\n *\n * @class\n * @extends OO.ui.ToggleWidget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [value=false] The toggle button’s initial on/off\n *  state. By default, the button is in the 'off' state.\n */\nOO.ui.ToggleButtonWidget = function OoUiToggleButtonWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ToggleButtonWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, $.extend( {\n\t\tactive: this.active\n\t}, config ) );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {\n\t\t$tabIndexed: this.$button\n\t}, config ) );\n\n\t// Events\n\tthis.connect( this, {\n\t\tclick: 'onAction'\n\t} );\n\n\t// Initialization\n\tthis.$button.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element\n\t\t.addClass( 'oo-ui-toggleButtonWidget' )\n\t\t.append( this.$button );\n\tthis.setTitledElement( this.$button );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToggleButtonWidget, OO.ui.ToggleWidget );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ToggleButtonWidget.static.tagName = 'span';\n\n/* Methods */\n\n/**\n * Handle the button action being triggered.\n *\n * @private\n */\nOO.ui.ToggleButtonWidget.prototype.onAction = function () {\n\tthis.setValue( !this.value );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleButtonWidget.prototype.setValue = function ( value ) {\n\tvalue = !!value;\n\tif ( value !== this.value ) {\n\t\t// Might be called from parent constructor before ButtonElement constructor\n\t\tif ( this.$button ) {\n\t\t\tthis.$button.attr( 'aria-pressed', value.toString() );\n\t\t}\n\t\tthis.setActive( value );\n\t}\n\n\t// Parent method\n\tOO.ui.ToggleButtonWidget.parent.prototype.setValue.call( this, value );\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleButtonWidget.prototype.setButtonElement = function ( $button ) {\n\tif ( this.$button ) {\n\t\tthis.$button.removeAttr( 'aria-pressed' );\n\t}\n\tOO.ui.mixin.ButtonElement.prototype.setButtonElement.call( this, $button );\n\tthis.$button.attr( 'aria-pressed', this.value.toString() );\n};\n","/**\n * ToggleSwitches are switches that slide on and off. Their state is represented by a Boolean\n * value (`true` for ‘on’, and `false` otherwise, the default). The ‘off’ state is represented\n * visually by a slider in the leftmost position.\n *\n *     @example\n *     // Toggle switches in the 'off' and 'on' position.\n *     var toggleSwitch1 = new OO.ui.ToggleSwitchWidget(),\n *         toggleSwitch2 = new OO.ui.ToggleSwitchWidget( {\n *             value: true\n *         } );\n *         // Create a FieldsetLayout to layout and label switches.\n *         fieldset = new OO.ui.FieldsetLayout( {\n *             label: 'Toggle switches'\n *         } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( toggleSwitch1, {\n *             label: 'Off',\n *             align: 'top'\n *         } ),\n *         new OO.ui.FieldLayout( toggleSwitch2, {\n *             label: 'On',\n *             align: 'top'\n *         } )\n *     ] );\n *     $( document.body ).append( fieldset.$element );\n *\n * @class\n * @extends OO.ui.ToggleWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [value=false] The toggle switch’s initial on/off state.\n *  By default, the toggle switch is in the 'off' position.\n */\nOO.ui.ToggleSwitchWidget = function OoUiToggleSwitchWidget( config ) {\n\t// Parent constructor\n\tOO.ui.ToggleSwitchWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Properties\n\tthis.dragging = false;\n\tthis.dragStart = null;\n\tthis.sliding = false;\n\tthis.$glow = $( '<span>' );\n\tthis.$grip = $( '<span>' );\n\n\t// Events\n\tthis.$element.on( {\n\t\tclick: this.onClick.bind( this ),\n\t\tkeypress: this.onKeyPress.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$glow.addClass( 'oo-ui-toggleSwitchWidget-glow' );\n\tthis.$grip.addClass( 'oo-ui-toggleSwitchWidget-grip' );\n\tthis.$element\n\t\t.addClass( 'oo-ui-toggleSwitchWidget' )\n\t\t.attr( 'role', 'checkbox' )\n\t\t.append( this.$glow, this.$grip );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ToggleSwitchWidget, OO.ui.ToggleWidget );\nOO.mixinClass( OO.ui.ToggleSwitchWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {jQuery.Event} e Mouse click event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.ToggleSwitchWidget.prototype.onClick = function ( e ) {\n\tif ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.setValue( !this.value );\n\t}\n\treturn false;\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.ToggleSwitchWidget.prototype.onKeyPress = function ( e ) {\n\tif ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {\n\t\tthis.setValue( !this.value );\n\t\treturn false;\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleSwitchWidget.prototype.setValue = function ( value ) {\n\tOO.ui.ToggleSwitchWidget.parent.prototype.setValue.call( this, value );\n\tthis.$element.attr( 'aria-checked', this.value.toString() );\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ToggleSwitchWidget.prototype.simulateLabelClick = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.setValue( !this.value );\n\t}\n\tthis.focus();\n};\n","/**\n * OutlineControlsWidget is a set of controls for an\n * {@link OO.ui.OutlineSelectWidget outline select widget}.\n * Controls include moving items up and down, removing items, and adding different kinds of items.\n *\n * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\n *\n * @constructor\n * @param {OO.ui.OutlineSelectWidget} outline Outline to control\n * @param {Object} [config] Configuration options\n * @cfg {Object} [abilities] List of abilties\n * @cfg {boolean} [abilities.move=true] Allow moving movable items\n * @cfg {boolean} [abilities.remove=true] Allow removing removable items\n */\nOO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( outline ) && config === undefined ) {\n\t\tconfig = outline;\n\t\toutline = config.outline;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.OutlineControlsWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n\n\t// Properties\n\tthis.outline = outline;\n\tthis.$movers = $( '<div>' );\n\tthis.upButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'collapse',\n\t\ttitle: OO.ui.msg( 'ooui-outline-control-move-up' )\n\t} );\n\tthis.downButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'expand',\n\t\ttitle: OO.ui.msg( 'ooui-outline-control-move-down' )\n\t} );\n\tthis.removeButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'trash',\n\t\ttitle: OO.ui.msg( 'ooui-outline-control-remove' )\n\t} );\n\tthis.abilities = { move: true, remove: true };\n\n\t// Events\n\toutline.connect( this, {\n\t\tselect: 'onOutlineChange',\n\t\tadd: 'onOutlineChange',\n\t\tremove: 'onOutlineChange'\n\t} );\n\tthis.upButton.connect( this, {\n\t\tclick: [ 'emit', 'move', -1 ]\n\t} );\n\tthis.downButton.connect( this, {\n\t\tclick: [ 'emit', 'move', 1 ]\n\t} );\n\tthis.removeButton.connect( this, {\n\t\tclick: [ 'emit', 'remove' ]\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-outlineControlsWidget' );\n\tthis.$group.addClass( 'oo-ui-outlineControlsWidget-items' );\n\tthis.$movers\n\t\t.addClass( 'oo-ui-outlineControlsWidget-movers' )\n\t\t.append( this.removeButton.$element, this.upButton.$element, this.downButton.$element );\n\tthis.$element.append( this.$icon, this.$group, this.$movers );\n\tthis.setAbilities( config.abilities || {} );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OutlineControlsWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.GroupElement );\n\n/* Events */\n\n/**\n * @event move\n * @param {number} places Number of places to move\n */\n\n/**\n * @event remove\n */\n\n/* Methods */\n\n/**\n * Set abilities.\n *\n * @param {Object} abilities List of abilties\n * @param {boolean} [abilities.move] Allow moving movable items\n * @param {boolean} [abilities.remove] Allow removing removable items\n */\nOO.ui.OutlineControlsWidget.prototype.setAbilities = function ( abilities ) {\n\tvar ability;\n\n\tfor ( ability in this.abilities ) {\n\t\tif ( abilities[ ability ] !== undefined ) {\n\t\t\tthis.abilities[ ability ] = !!abilities[ ability ];\n\t\t}\n\t}\n\n\tthis.onOutlineChange();\n};\n\n/**\n * Handle outline change events.\n *\n * @private\n */\nOO.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {\n\tvar i, len, firstMovable, lastMovable,\n\t\titems = this.outline.getItems(),\n\t\tselectedItem = this.outline.findSelectedItem(),\n\t\tmovable = this.abilities.move && selectedItem && selectedItem.isMovable(),\n\t\tremovable = this.abilities.remove && selectedItem && selectedItem.isRemovable();\n\n\tif ( movable ) {\n\t\ti = -1;\n\t\tlen = items.length;\n\t\twhile ( ++i < len ) {\n\t\t\tif ( items[ i ].isMovable() ) {\n\t\t\t\tfirstMovable = items[ i ];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\ti = len;\n\t\twhile ( i-- ) {\n\t\t\tif ( items[ i ].isMovable() ) {\n\t\t\t\tlastMovable = items[ i ];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tthis.upButton.setDisabled( !movable || selectedItem === firstMovable );\n\tthis.downButton.setDisabled( !movable || selectedItem === lastMovable );\n\tthis.removeButton.setDisabled( !removable );\n};\n","/**\n * OutlineOptionWidget is an item in an {@link OO.ui.OutlineSelectWidget OutlineSelectWidget}.\n *\n * Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}, which contain\n * {@link OO.ui.PageLayout page layouts}. See {@link OO.ui.BookletLayout BookletLayout}\n * for an example.\n *\n * @class\n * @extends OO.ui.DecoratedOptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {number} [level] Indentation level\n * @cfg {boolean} [movable] Allow modification from\n *  {@link OO.ui.OutlineControlsWidget outline controls}.\n */\nOO.ui.OutlineOptionWidget = function OoUiOutlineOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.OutlineOptionWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.level = 0;\n\tthis.movable = !!config.movable;\n\tthis.removable = !!config.removable;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-outlineOptionWidget' );\n\tthis.setLevel( config.level );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OutlineOptionWidget, OO.ui.DecoratedOptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.static.highlightable = true;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.static.scrollIntoViewOnSelect = true;\n\n/**\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.OutlineOptionWidget.static.levelClass = 'oo-ui-outlineOptionWidget-level-';\n\n/**\n * @static\n * @inheritable\n * @property {number}\n */\nOO.ui.OutlineOptionWidget.static.levels = 3;\n\n/* Methods */\n\n/**\n * Check if item is movable.\n *\n * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @return {boolean} Item is movable\n */\nOO.ui.OutlineOptionWidget.prototype.isMovable = function () {\n\treturn this.movable;\n};\n\n/**\n * Check if item is removable.\n *\n * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @return {boolean} Item is removable\n */\nOO.ui.OutlineOptionWidget.prototype.isRemovable = function () {\n\treturn this.removable;\n};\n\n/**\n * Get indentation level.\n *\n * @return {number} Indentation level\n */\nOO.ui.OutlineOptionWidget.prototype.getLevel = function () {\n\treturn this.level;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.prototype.setPressed = function ( state ) {\n\tOO.ui.OutlineOptionWidget.parent.prototype.setPressed.call( this, state );\n\treturn this;\n};\n\n/**\n * Set movability.\n *\n * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @param {boolean} movable Item is movable\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OutlineOptionWidget.prototype.setMovable = function ( movable ) {\n\tthis.movable = !!movable;\n\tthis.updateThemeClasses();\n\treturn this;\n};\n\n/**\n * Set removability.\n *\n * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.\n *\n * @param {boolean} removable Item is removable\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OutlineOptionWidget.prototype.setRemovable = function ( removable ) {\n\tthis.removable = !!removable;\n\tthis.updateThemeClasses();\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.OutlineOptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.OutlineOptionWidget.parent.prototype.setSelected.call( this, state );\n\treturn this;\n};\n\n/**\n * Set indentation level.\n *\n * @param {number} [level=0] Indentation level, in the range of [0,#maxLevel]\n * @chainable\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.OutlineOptionWidget.prototype.setLevel = function ( level ) {\n\tvar levels = this.constructor.static.levels,\n\t\tlevelClass = this.constructor.static.levelClass,\n\t\ti = levels;\n\n\tthis.level = level ? Math.max( 0, Math.min( levels - 1, level ) ) : 0;\n\twhile ( i-- ) {\n\t\tif ( this.level === i ) {\n\t\t\tthis.$element.addClass( levelClass + i );\n\t\t} else {\n\t\t\tthis.$element.removeClass( levelClass + i );\n\t\t}\n\t}\n\tthis.updateThemeClasses();\n\n\treturn this;\n};\n","/**\n * OutlineSelectWidget is a structured list that contains\n * {@link OO.ui.OutlineOptionWidget outline options}\n * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls}\n * widget.\n *\n * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.OutlineSelectWidget = function OoUiOutlineSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.OutlineSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-outlineSelectWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.OutlineSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.OutlineSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * ButtonOptionWidget is a special type of {@link OO.ui.mixin.ButtonElement button element} that\n * can be selected and configured with data. The class is\n * used with OO.ui.ButtonSelectWidget to create a selection of button options. Please see the\n * [OOUI documentation on MediaWiki] [1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options#Button_selects_and_options\n *\n * @class\n * @extends OO.ui.OptionWidget\n * @mixins OO.ui.mixin.ButtonElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.IndicatorElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ButtonOptionWidget = function OoUiButtonOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.ButtonOptionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ButtonElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonOptionWidget' );\n\tthis.$button.append( this.$icon, this.$label, this.$indicator );\n\tthis.$element.append( this.$button );\n\tthis.setTitledElement( this.$button );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonOptionWidget, OO.ui.OptionWidget );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.ButtonElement );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.IndicatorElement );\n\n/* Static Properties */\n\n/**\n * Allow button mouse down events to pass through so they can be handled by the parent select widget\n *\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonOptionWidget.static.cancelButtonMouseDownEvents = false;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.ButtonOptionWidget.static.highlightable = false;\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ButtonOptionWidget.prototype.setSelected = function ( state ) {\n\tOO.ui.ButtonOptionWidget.parent.prototype.setSelected.call( this, state );\n\n\tif ( this.constructor.static.selectable ) {\n\t\tthis.setActive( state );\n\t}\n\n\treturn this;\n};\n","/**\n * ButtonSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains\n * button options and is used together with\n * OO.ui.ButtonOptionWidget. The ButtonSelectWidget provides an interface for\n * highlighting, choosing, and selecting mutually exclusive options. Please see\n * the [OOUI documentation on MediaWiki] [1] for more information.\n *\n *     @example\n *     // A ButtonSelectWidget that contains three ButtonOptionWidgets.\n *     var option1 = new OO.ui.ButtonOptionWidget( {\n *             data: 1,\n *             label: 'Option 1',\n *             title: 'Button option 1'\n *         } ),\n *         option2 = new OO.ui.ButtonOptionWidget( {\n *             data: 2,\n *             label: 'Option 2',\n *             title: 'Button option 2'\n *         } ),\n *         option3 = new OO.ui.ButtonOptionWidget( {\n *             data: 3,\n *             label: 'Option 3',\n *             title: 'Button option 3'\n *         } ),\n *         buttonSelect = new OO.ui.ButtonSelectWidget( {\n *             items: [ option1, option2, option3 ]\n *         } );\n *     $( document.body ).append( buttonSelect.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Selects_and_Options\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ButtonSelectWidget = function OoUiButtonSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.ButtonSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-buttonSelectWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ButtonSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.ButtonSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * TabOptionWidget is an item in a {@link OO.ui.TabSelectWidget TabSelectWidget}.\n *\n * Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}, which contain\n * {@link OO.ui.TabPanelLayout tab panel layouts}. See {@link OO.ui.IndexLayout IndexLayout}\n * for an example.\n *\n * @class\n * @extends OO.ui.OptionWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.TabOptionWidget = function OoUiTabOptionWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.TabOptionWidget.parent.call( this, config );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tabOptionWidget' )\n\t\t.attr( 'role', 'tab' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TabOptionWidget, OO.ui.OptionWidget );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.TabOptionWidget.static.highlightable = false;\n","/**\n * TabSelectWidget is a list that contains {@link OO.ui.TabOptionWidget tab options}\n *\n * **Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}.**\n *\n * @class\n * @extends OO.ui.SelectWidget\n * @mixins OO.ui.mixin.TabIndexedElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.TabSelectWidget = function OoUiTabSelectWidget( config ) {\n\t// Parent constructor\n\tOO.ui.TabSelectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\n\t// Events\n\tthis.$element.on( {\n\t\tfocus: this.bindDocumentKeyDownListener.bind( this ),\n\t\tblur: this.unbindDocumentKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tabSelectWidget' )\n\t\t.attr( 'role', 'tablist' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TabSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.TabSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * TagItemWidgets are used within a {@link OO.ui.TagMultiselectWidget\n * TagMultiselectWidget} to display the selected items.\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.DraggableElement\n *\n * @constructor\n * @param {Object} [config] Configuration object\n * @cfg {boolean} [valid=true] Item is valid\n * @cfg {boolean} [fixed] Item is fixed. This means the item is\n *  always included in the values and cannot be removed.\n */\nOO.ui.TagItemWidget = function OoUiTagItemWidget( config ) {\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.TagItemWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.ItemWidget.call( this );\n\tOO.ui.mixin.LabelElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\tOO.ui.mixin.DraggableElement.call( this, config );\n\n\tthis.valid = config.valid === undefined ? true : !!config.valid;\n\tthis.fixed = !!config.fixed;\n\n\tthis.closeButton = new OO.ui.ButtonWidget( {\n\t\tframed: false,\n\t\ticon: 'close',\n\t\ttabIndex: -1,\n\t\ttitle: OO.ui.msg( 'ooui-item-remove' )\n\t} );\n\tthis.closeButton.setDisabled( this.isDisabled() );\n\n\t// Events\n\tthis.closeButton.connect( this, {\n\t\tclick: 'remove'\n\t} );\n\tthis.$element\n\t\t.on( 'click', this.select.bind( this ) )\n\t\t.on( 'keydown', this.onKeyDown.bind( this ) )\n\t\t// Prevent propagation of mousedown; the tag item \"lives\" in the\n\t\t// clickable area of the TagMultiselectWidget, which listens to\n\t\t// mousedown to open the menu or popup. We want to prevent that\n\t\t// for clicks specifically on the tag itself, so the actions taken\n\t\t// are more deliberate. When the tag is clicked, it will emit the\n\t\t// selection event (similar to how #OO.ui.MultioptionWidget emits 'change')\n\t\t// and can be handled separately.\n\t\t.on( 'mousedown', function ( e ) { e.stopPropagation(); } );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-tagItemWidget' )\n\t\t.append( this.$label, this.closeButton.$element );\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.TagItemWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.TagItemWidget, OO.ui.mixin.DraggableElement );\n\n/* Events */\n\n/**\n * @event remove\n *\n * A remove action was performed on the item\n */\n\n/**\n * @event navigate\n * @param {string} direction Direction of the movement, forward or backwards\n *\n * A navigate action was performed on the item\n */\n\n/**\n * @event select\n *\n * The tag widget was selected. This can occur when the widget\n * is either clicked or enter was pressed on it.\n */\n\n/**\n * @event valid\n * @param {boolean} isValid Item is valid\n *\n * Item validity has changed\n */\n\n/**\n * @event fixed\n * @param {boolean} isFixed Item is fixed\n *\n * Item fixed state has changed\n */\n\n/* Methods */\n\n/**\n * Set this item as fixed, meaning it cannot be removed\n *\n * @param {string} [state] Item is fixed\n * @fires fixed\n * @return {OO.ui.Widget} The widget, for chaining\n */\nOO.ui.TagItemWidget.prototype.setFixed = function ( state ) {\n\tstate = state === undefined ? !this.fixed : !!state;\n\n\tif ( this.fixed !== state ) {\n\t\tthis.fixed = state;\n\t\tif ( this.closeButton ) {\n\t\t\tthis.closeButton.toggle( !this.fixed );\n\t\t}\n\n\t\tif ( !this.fixed && this.elementGroup && !this.elementGroup.isDraggable() ) {\n\t\t\t// Only enable the state of the item if the\n\t\t\t// entire group is draggable\n\t\t\tthis.toggleDraggable( !this.fixed );\n\t\t}\n\t\tthis.$element.toggleClass( 'oo-ui-tagItemWidget-fixed', this.fixed );\n\n\t\tthis.emit( 'fixed', this.isFixed() );\n\t}\n\treturn this;\n};\n\n/**\n * Check whether the item is fixed\n * @return {boolean}\n */\nOO.ui.TagItemWidget.prototype.isFixed = function () {\n\treturn this.fixed;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.TagItemWidget.prototype.setDisabled = function ( state ) {\n\tif ( state && this.elementGroup && !this.elementGroup.isDisabled() ) {\n\t\tOO.ui.warnDeprecation( 'TagItemWidget#setDisabled: Disabling individual items is deprecated and will result in inconsistent behavior. Use #setFixed instead. See T193571.' );\n\t}\n\t// Parent method\n\tOO.ui.TagItemWidget.parent.prototype.setDisabled.call( this, state );\n\tif (\n\t\t!state &&\n\t\t// Verify we have a group, and that the widget is ready\n\t\tthis.toggleDraggable && this.elementGroup &&\n\t\t!this.isFixed() &&\n\t\t!this.elementGroup.isDraggable()\n\t) {\n\t\t// Only enable the draggable state of the item if the\n\t\t// entire group is draggable to begin with, and if the\n\t\t// item is not fixed\n\t\tthis.toggleDraggable( !state );\n\t}\n\n\tif ( this.closeButton ) {\n\t\tthis.closeButton.setDisabled( state );\n\t}\n\n\treturn this;\n};\n\n/**\n * Handle removal of the item\n *\n * This is mainly for extensibility concerns, so other children\n * of this class can change the behavior if they need to. This\n * is called by both clicking the 'remove' button but also\n * on keypress, which is harder to override if needed.\n *\n * @fires remove\n */\nOO.ui.TagItemWidget.prototype.remove = function () {\n\tif ( !this.isDisabled() && !this.isFixed() ) {\n\t\tthis.emit( 'remove' );\n\t}\n};\n\n/**\n * Handle a keydown event on the widget\n *\n * @fires navigate\n * @fires remove\n * @param {jQuery.Event} e Key down event\n * @return {boolean|undefined} false to stop the operation\n */\nOO.ui.TagItemWidget.prototype.onKeyDown = function ( e ) {\n\tvar movement;\n\n\tif (\n\t\t!this.isDisabled() &&\n\t\t!this.isFixed() &&\n\t\t( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE )\n\t) {\n\t\tthis.remove();\n\t\treturn false;\n\t} else if ( e.keyCode === OO.ui.Keys.ENTER ) {\n\t\tthis.select();\n\t\treturn false;\n\t} else if (\n\t\te.keyCode === OO.ui.Keys.LEFT ||\n\t\te.keyCode === OO.ui.Keys.RIGHT\n\t) {\n\t\tif ( OO.ui.Element.static.getDir( this.$element ) === 'rtl' ) {\n\t\t\tmovement = {\n\t\t\t\tleft: 'forwards',\n\t\t\t\tright: 'backwards'\n\t\t\t};\n\t\t} else {\n\t\t\tmovement = {\n\t\t\t\tleft: 'backwards',\n\t\t\t\tright: 'forwards'\n\t\t\t};\n\t\t}\n\n\t\tthis.emit(\n\t\t\t'navigate',\n\t\t\te.keyCode === OO.ui.Keys.LEFT ?\n\t\t\t\tmovement.left : movement.right\n\t\t);\n\t\treturn false;\n\t}\n};\n\n/**\n * Select this item\n *\n * @fires select\n */\nOO.ui.TagItemWidget.prototype.select = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.emit( 'select' );\n\t}\n};\n\n/**\n * Set the valid state of this item\n *\n * @param {boolean} [valid] Item is valid\n * @fires valid\n */\nOO.ui.TagItemWidget.prototype.toggleValid = function ( valid ) {\n\tvalid = valid === undefined ? !this.valid : !!valid;\n\n\tif ( this.valid !== valid ) {\n\t\tthis.valid = valid;\n\n\t\tthis.setFlags( { invalid: !this.valid } );\n\n\t\tthis.emit( 'valid', this.valid );\n\t}\n};\n\n/**\n * Check whether the item is valid\n *\n * @return {boolean} Item is valid\n */\nOO.ui.TagItemWidget.prototype.isValid = function () {\n\treturn this.valid;\n};\n","/**\n * A basic tag multiselect widget, similar in concept to\n * {@link OO.ui.ComboBoxInputWidget combo box widget} that allows the user to add multiple values\n * that are displayed in a tag area.\n *\n * This widget is a base widget; see {@link OO.ui.MenuTagMultiselectWidget MenuTagMultiselectWidget}\n * and {@link OO.ui.PopupTagMultiselectWidget PopupTagMultiselectWidget} for the implementations\n * that use a menu and a popup respectively.\n *\n *     @example\n *     // A TagMultiselectWidget.\n *     var widget = new OO.ui.TagMultiselectWidget( {\n *         inputPosition: 'outline',\n *         allowedValues: [ 'Option 1', 'Option 2', 'Option 3' ],\n *         selected: [ 'Option 1' ]\n *     } );\n *     $( document.body ).append( widget.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupWidget\n * @mixins OO.ui.mixin.DraggableGroupElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.IconElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.FlaggedElement\n * @mixins OO.ui.mixin.TitledElement\n *\n * @constructor\n * @param {Object} config Configuration object\n * @cfg {Object} [input] Configuration options for the input widget\n * @cfg {OO.ui.InputWidget} [inputWidget] An optional input widget. If given, it will\n *  replace the input widget used in the TagMultiselectWidget. If not given,\n *  TagMultiselectWidget creates its own.\n * @cfg {boolean} [inputPosition='inline'] Position of the input. Options are:\n *  - inline: The input is invisible, but exists inside the tag list, so\n *    the user types into the tag groups to add tags.\n *  - outline: The input is underneath the tag area.\n *  - none: No input supplied\n * @cfg {boolean} [allowEditTags=true] Allow editing of the tags by clicking them\n * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if\n *  not present in the menu.\n * @cfg {Object[]} [allowedValues] An array representing the allowed items\n *  by their datas.\n * @cfg {boolean} [allowDuplicates=false] Allow duplicate items to be added\n * @cfg {boolean} [allowDisplayInvalidTags=false] Allow the display of\n *  invalid tags. These tags will display with an invalid state, and\n *  the widget as a whole will have an invalid state if any invalid tags\n *  are present.\n * @cfg {number} [tagLimit] An optional limit on the number of selected options.\n *  If 'tagLimit' is set and is reached, the input is disabled, not allowing any\n *  additions. If 'tagLimit' is unset or is 0, an unlimited number of items can be\n *  added.\n * @cfg {boolean} [allowReordering=true] Allow reordering of the items\n * @cfg {Object[]|String[]} [selected] A set of selected tags. If given,\n *  these will appear in the tag list on initialization, as long as they\n *  pass the validity tests.\n */\nOO.ui.TagMultiselectWidget = function OoUiTagMultiselectWidget( config ) {\n\tvar inputEvents,\n\t\trAF = window.requestAnimationFrame || setTimeout,\n\t\twidget = this,\n\t\t$tabFocus = $( '<span>' ).addClass( 'oo-ui-tagMultiselectWidget-focusTrap' );\n\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.TagMultiselectWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupWidget.call( this, config );\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\tOO.ui.mixin.TabIndexedElement.call( this, config );\n\tOO.ui.mixin.FlaggedElement.call( this, config );\n\tOO.ui.mixin.DraggableGroupElement.call( this, config );\n\tOO.ui.mixin.TitledElement.call( this, config );\n\n\tthis.toggleDraggable(\n\t\tconfig.allowReordering === undefined ?\n\t\t\ttrue : !!config.allowReordering\n\t);\n\n\tthis.inputPosition =\n\t\tthis.constructor.static.allowedInputPositions.indexOf( config.inputPosition ) > -1 ?\n\t\t\tconfig.inputPosition : 'inline';\n\tthis.allowEditTags = config.allowEditTags === undefined ? true : !!config.allowEditTags;\n\tthis.allowArbitrary = !!config.allowArbitrary;\n\tthis.allowDuplicates = !!config.allowDuplicates;\n\tthis.allowedValues = config.allowedValues || [];\n\tthis.allowDisplayInvalidTags = config.allowDisplayInvalidTags;\n\tthis.hasInput = this.inputPosition !== 'none';\n\tthis.tagLimit = config.tagLimit;\n\tthis.height = null;\n\tthis.valid = true;\n\n\tthis.$content = $( '<div>' ).addClass( 'oo-ui-tagMultiselectWidget-content' );\n\tthis.$handle = $( '<div>' )\n\t\t.addClass( 'oo-ui-tagMultiselectWidget-handle' )\n\t\t.append(\n\t\t\tthis.$indicator,\n\t\t\tthis.$icon,\n\t\t\tthis.$content\n\t\t\t\t.append(\n\t\t\t\t\tthis.$group.addClass( 'oo-ui-tagMultiselectWidget-group' )\n\t\t\t\t)\n\t\t);\n\n\t// Events\n\tthis.aggregate( {\n\t\tremove: 'itemRemove',\n\t\tnavigate: 'itemNavigate',\n\t\tselect: 'itemSelect',\n\t\tfixed: 'itemFixed'\n\t} );\n\tthis.connect( this, {\n\t\titemRemove: 'onTagRemove',\n\t\titemSelect: 'onTagSelect',\n\t\titemFixed: 'onTagFixed',\n\t\titemNavigate: 'onTagNavigate',\n\t\tchange: 'onChangeTags'\n\t} );\n\tthis.$handle.on( {\n\t\tmousedown: this.onMouseDown.bind( this )\n\t} );\n\n\t// Initialize\n\tthis.$element\n\t\t.addClass( 'oo-ui-tagMultiselectWidget' )\n\t\t.append( this.$handle );\n\n\tif ( this.hasInput ) {\n\t\tif ( config.inputWidget ) {\n\t\t\tthis.input = config.inputWidget;\n\t\t} else {\n\t\t\tthis.input = new OO.ui.TextInputWidget( $.extend( {\n\t\t\t\tplaceholder: config.placeholder,\n\t\t\t\tclasses: [ 'oo-ui-tagMultiselectWidget-input' ]\n\t\t\t}, config.input ) );\n\t\t}\n\t\tthis.input.setDisabled( this.isDisabled() );\n\n\t\tinputEvents = {\n\t\t\tfocus: this.onInputFocus.bind( this ),\n\t\t\tblur: this.onInputBlur.bind( this ),\n\t\t\t'propertychange change click mouseup keydown keyup input cut paste select focus':\n\t\t\t\tOO.ui.debounce( this.updateInputSize.bind( this ) ),\n\t\t\tkeydown: this.onInputKeyDown.bind( this ),\n\t\t\tkeypress: this.onInputKeyPress.bind( this )\n\t\t};\n\n\t\tthis.input.$input.on( inputEvents );\n\t\tthis.inputPlaceholder = this.input.$input.attr( 'placeholder' );\n\n\t\tif ( this.inputPosition === 'outline' ) {\n\t\t\t// Override max-height for the input widget\n\t\t\t// in the case the widget is outline so it can\n\t\t\t// stretch all the way if the widget is wide\n\t\t\tthis.input.$element.css( 'max-width', 'inherit' );\n\t\t\tthis.$element\n\t\t\t\t.addClass( 'oo-ui-tagMultiselectWidget-outlined' )\n\t\t\t\t.append( this.input.$element );\n\t\t} else {\n\t\t\tthis.$element.addClass( 'oo-ui-tagMultiselectWidget-inlined' );\n\t\t\t// HACK: When the widget is using 'inline' input, the\n\t\t\t// behavior needs to only use the $input itself\n\t\t\t// so we style and size it accordingly (otherwise\n\t\t\t// the styling and sizing can get very convoluted\n\t\t\t// when the wrapping divs and other elements)\n\t\t\t// We are taking advantage of still being able to\n\t\t\t// call the widget itself for operations like\n\t\t\t// .getValue() and setDisabled() and .focus() but\n\t\t\t// having only the $input attached to the DOM\n\t\t\tthis.$content.append( this.input.$input );\n\t\t}\n\t} else {\n\t\tthis.$content.append( $tabFocus );\n\t}\n\n\tthis.setTabIndexedElement(\n\t\tthis.hasInput ?\n\t\t\tthis.input.$input :\n\t\t\t$tabFocus\n\t);\n\n\tif ( config.selected ) {\n\t\tthis.setValue( config.selected );\n\t}\n\n\t// HACK: Input size needs to be calculated after everything\n\t// else is rendered\n\trAF( function () {\n\t\tif ( widget.hasInput ) {\n\t\t\twidget.updateInputSize();\n\t\t}\n\t} );\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.TagMultiselectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.GroupWidget );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.DraggableGroupElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.IconElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.TagMultiselectWidget, OO.ui.mixin.TitledElement );\n\n/* Static properties */\n\n/**\n * Allowed input positions.\n * - inline: The input is inside the tag list\n * - outline: The input is under the tag list\n * - none: There is no input\n *\n * @property {Array}\n */\nOO.ui.TagMultiselectWidget.static.allowedInputPositions = [ 'inline', 'outline', 'none' ];\n\n/* Methods */\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {boolean} False to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.onMouseDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\t( !this.hasInput || e.target !== this.input.$input[ 0 ] ) &&\n\t\te.which === OO.ui.MouseButtons.LEFT\n\t) {\n\t\tthis.focus();\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {boolean} Whether to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.onInputKeyPress = function ( e ) {\n\tvar stopOrContinue,\n\t\twithMetaKey = e.metaKey || e.ctrlKey;\n\n\tif ( !this.isDisabled() ) {\n\t\tif ( e.which === OO.ui.Keys.ENTER ) {\n\t\t\tstopOrContinue = this.doInputEnter( e, withMetaKey );\n\t\t}\n\n\t\t// Make sure the input gets resized.\n\t\tsetTimeout( this.updateInputSize.bind( this ), 0 );\n\t\treturn stopOrContinue;\n\t}\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n * @return {boolean}\n */\nOO.ui.TagMultiselectWidget.prototype.onInputKeyDown = function ( e ) {\n\tvar movement, direction,\n\t\twidget = this,\n\t\twithMetaKey = e.metaKey || e.ctrlKey,\n\t\tisMovementInsideInput = function ( direction ) {\n\t\t\tvar inputRange = widget.input.getRange(),\n\t\t\t\tinputValue = widget.hasInput && widget.input.getValue();\n\n\t\t\tif ( direction === 'forwards' && inputRange.to > inputValue.length - 1 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( direction === 'backwards' && inputRange.from <= 0 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\tif ( !this.isDisabled() ) {\n\t\t// 'keypress' event is not triggered for Backspace key\n\t\tif ( e.keyCode === OO.ui.Keys.BACKSPACE ) {\n\t\t\treturn this.doInputBackspace( e, withMetaKey );\n\t\t} else if ( e.keyCode === OO.ui.Keys.ESCAPE ) {\n\t\t\treturn this.doInputEscape( e );\n\t\t} else if (\n\t\t\te.keyCode === OO.ui.Keys.LEFT ||\n\t\t\te.keyCode === OO.ui.Keys.RIGHT\n\t\t) {\n\t\t\tif ( OO.ui.Element.static.getDir( this.$element ) === 'rtl' ) {\n\t\t\t\tmovement = {\n\t\t\t\t\tleft: 'forwards',\n\t\t\t\t\tright: 'backwards'\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tmovement = {\n\t\t\t\t\tleft: 'backwards',\n\t\t\t\t\tright: 'forwards'\n\t\t\t\t};\n\t\t\t}\n\t\t\tdirection = e.keyCode === OO.ui.Keys.LEFT ?\n\t\t\t\tmovement.left : movement.right;\n\n\t\t\tif ( !this.hasInput || !isMovementInsideInput( direction ) ) {\n\t\t\t\treturn this.doInputArrow( e, direction, withMetaKey );\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * Respond to input focus event\n */\nOO.ui.TagMultiselectWidget.prototype.onInputFocus = function () {\n\tthis.$element.addClass( 'oo-ui-tagMultiselectWidget-focus' );\n\t// Reset validity\n\tthis.toggleValid( true );\n};\n\n/**\n * Respond to input blur event\n */\nOO.ui.TagMultiselectWidget.prototype.onInputBlur = function () {\n\tthis.$element.removeClass( 'oo-ui-tagMultiselectWidget-focus' );\n\n\t// Set the widget as invalid if there's text in the input\n\tthis.addTagFromInput();\n\tthis.toggleValid( this.checkValidity() && ( !this.hasInput || !this.input.getValue() ) );\n};\n\n/**\n * Perform an action after the Enter key on the input\n *\n * @param {jQuery.Event} e Event data\n * @param {boolean} [withMetaKey] Whether this key was pressed with\n * a meta key like Control\n * @return {boolean} Whether to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.doInputEnter = function () {\n\tthis.addTagFromInput();\n\treturn false;\n};\n\n/**\n * Perform an action responding to the Enter key on the input\n *\n * @param {jQuery.Event} e Event data\n * @param {boolean} [withMetaKey] Whether this key was pressed with\n * a meta key like Control\n * @return {boolean} Whether to prevent defaults\n */\nOO.ui.TagMultiselectWidget.prototype.doInputBackspace = function ( e, withMetaKey ) {\n\tvar items, item;\n\n\tif (\n\t\tthis.inputPosition === 'inline' &&\n\t\tthis.input.getValue() === '' &&\n\t\t!this.isEmpty()\n\t) {\n\t\t// Delete the last item\n\t\titems = this.getItems();\n\t\titem = items[ items.length - 1 ];\n\n\t\tif ( !item.isDisabled() && !item.isFixed() ) {\n\t\t\tthis.removeItems( [ item ] );\n\t\t\t// If Ctrl/Cmd was pressed, delete item entirely.\n\t\t\t// Otherwise put it into the text field for editing.\n\t\t\tif ( !withMetaKey ) {\n\t\t\t\tthis.input.setValue( item.getLabel() );\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n};\n\n/**\n * Perform an action after the Escape key on the input\n *\n * @param {jQuery.Event} e Event data\n */\nOO.ui.TagMultiselectWidget.prototype.doInputEscape = function () {\n\tthis.clearInput();\n};\n\n/**\n * Perform an action after the Left/Right arrow key on the input, select the previous\n * item from the input.\n * See #getPreviousItem\n *\n * @param {jQuery.Event} e Event data\n * @param {string} direction Direction of the movement; forwards or backwards\n * @param {boolean} [withMetaKey] Whether this key was pressed with\n *  a meta key like Control\n */\nOO.ui.TagMultiselectWidget.prototype.doInputArrow = function ( e, direction ) {\n\tif (\n\t\tthis.inputPosition === 'inline' &&\n\t\t!this.isEmpty() &&\n\t\tdirection === 'backwards'\n\t) {\n\t\t// Get previous item\n\t\tthis.getPreviousItem().focus();\n\t}\n};\n\n/**\n * Respond to item select event\n *\n * @param {OO.ui.TagItemWidget} item Selected item\n */\nOO.ui.TagMultiselectWidget.prototype.onTagSelect = function ( item ) {\n\tif ( this.hasInput && this.allowEditTags && !item.isFixed() ) {\n\t\tif ( this.input.getValue() ) {\n\t\t\tthis.addTagFromInput();\n\t\t}\n\t\t// 1. Get the label of the tag into the input\n\t\tthis.input.setValue( item.getLabel() );\n\t\t// 2. Remove the tag\n\t\tthis.removeItems( [ item ] );\n\t\t// 3. Focus the input\n\t\tthis.focus();\n\t}\n};\n\n/**\n * Respond to item fixed state change\n *\n * @param {OO.ui.TagItemWidget} item Selected item\n */\nOO.ui.TagMultiselectWidget.prototype.onTagFixed = function ( item ) {\n\tvar i,\n\t\titems = this.getItems();\n\n\t// Move item to the end of the static items\n\tfor ( i = 0; i < items.length; i++ ) {\n\t\tif ( items[ i ] !== item && !items[ i ].isFixed() ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tthis.addItems( item, i );\n};\n/**\n * Respond to change event, where items were added, removed, or cleared.\n */\nOO.ui.TagMultiselectWidget.prototype.onChangeTags = function () {\n\tvar isUnderLimit = this.isUnderLimit();\n\n\t// Reset validity\n\tthis.toggleValid(\n\t\tthis.checkValidity() &&\n\t\t!( this.hasInput && this.input.getValue() )\n\t);\n\n\tif ( this.hasInput ) {\n\t\tthis.updateInputSize();\n\t\tif ( !isUnderLimit ) {\n\t\t\t// Clear the input\n\t\t\tthis.input.setValue( '' );\n\t\t}\n\t\tif ( this.inputPosition === 'outline' ) {\n\t\t\t// Show/clear the placeholder and enable/disable the input\n\t\t\t// based on whether we are/aren't under the specified limit\n\t\t\tthis.input.$input.attr( 'placeholder', isUnderLimit ? this.inputPlaceholder : '' );\n\t\t\tthis.input.setDisabled( !isUnderLimit );\n\t\t} else {\n\t\t\t// Show/hide the input\n\t\t\tthis.input.$input.toggleClass( 'oo-ui-element-hidden', !isUnderLimit );\n\t\t}\n\t}\n\tthis.updateIfHeightChanged();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.TagMultiselectWidget.prototype.setDisabled = function ( isDisabled ) {\n\t// Parent method\n\tOO.ui.TagMultiselectWidget.parent.prototype.setDisabled.call( this, isDisabled );\n\n\tif ( this.hasInput && this.input ) {\n\t\tif ( !isDisabled ) {\n\t\t\tthis.updateInputSize();\n\t\t}\n\t\tthis.input.setDisabled( !!isDisabled && !this.isUnderLimit() );\n\t}\n\n\tif ( this.items ) {\n\t\tthis.getItems().forEach( function ( item ) {\n\t\t\titem.setDisabled( !!isDisabled );\n\t\t} );\n\t}\n};\n\n/**\n * Respond to tag remove event\n * @param {OO.ui.TagItemWidget} item Removed tag\n */\nOO.ui.TagMultiselectWidget.prototype.onTagRemove = function ( item ) {\n\tthis.removeTagByData( item.getData() );\n};\n\n/**\n * Respond to navigate event on the tag\n *\n * @param {OO.ui.TagItemWidget} item Removed tag\n * @param {string} direction Direction of movement; 'forwards' or 'backwards'\n */\nOO.ui.TagMultiselectWidget.prototype.onTagNavigate = function ( item, direction ) {\n\tvar firstItem = this.getItems()[ 0 ];\n\n\tif ( direction === 'forwards' ) {\n\t\tthis.getNextItem( item ).focus();\n\t} else if ( !this.inputPosition === 'inline' || item !== firstItem ) {\n\t\t// If the widget has an inline input, we want to stop at the starting edge\n\t\t// of the tags\n\t\tthis.getPreviousItem( item ).focus();\n\t}\n};\n\n/**\n * Add tag from input value\n */\nOO.ui.TagMultiselectWidget.prototype.addTagFromInput = function () {\n\tvar val = this.input.getValue(),\n\t\tisValid = this.isAllowedData( val );\n\n\tif ( !val ) {\n\t\treturn;\n\t}\n\n\tif ( isValid || this.allowDisplayInvalidTags ) {\n\t\tthis.clearInput();\n\t\tthis.addTag( val );\n\t}\n};\n\n/**\n * Clear the input\n */\nOO.ui.TagMultiselectWidget.prototype.clearInput = function () {\n\tthis.input.setValue( '' );\n};\n\n/**\n * Check whether the given value is a duplicate of an existing\n * tag already in the list.\n *\n * @param {string|Object} data Requested value\n * @return {boolean} Value is duplicate\n */\nOO.ui.TagMultiselectWidget.prototype.isDuplicateData = function ( data ) {\n\treturn !!this.findItemFromData( data );\n};\n\n/**\n * Check whether a given value is allowed to be added\n *\n * @param {string|Object} data Requested value\n * @return {boolean} Value is allowed\n */\nOO.ui.TagMultiselectWidget.prototype.isAllowedData = function ( data ) {\n\tif (\n\t\t!this.allowDuplicates &&\n\t\tthis.isDuplicateData( data )\n\t) {\n\t\treturn false;\n\t}\n\n\tif ( this.allowArbitrary ) {\n\t\treturn true;\n\t}\n\n\t// Check with allowed values\n\tif (\n\t\tthis.getAllowedValues().some( function ( value ) {\n\t\t\treturn data === value;\n\t\t} )\n\t) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Get the allowed values list\n *\n * @return {string[]} Allowed data values\n */\nOO.ui.TagMultiselectWidget.prototype.getAllowedValues = function () {\n\treturn this.allowedValues;\n};\n\n/**\n * Add a value to the allowed values list\n *\n * @param {string} value Allowed data value\n */\nOO.ui.TagMultiselectWidget.prototype.addAllowedValue = function ( value ) {\n\tif ( this.allowedValues.indexOf( value ) === -1 ) {\n\t\tthis.allowedValues.push( value );\n\t}\n};\n\n/**\n * Get the datas of the currently selected items\n *\n * @return {string[]|Object[]} Datas of currently selected items\n */\nOO.ui.TagMultiselectWidget.prototype.getValue = function () {\n\treturn this.getItems()\n\t\t.filter( function ( item ) {\n\t\t\treturn item.isValid();\n\t\t} )\n\t\t.map( function ( item ) {\n\t\t\treturn item.getData();\n\t\t} );\n};\n\n/**\n * Set the value of this widget by datas.\n *\n * @param {string|string[]|Object|Object[]} valueObject An object representing the data\n *  and label of the value. If the widget allows arbitrary values,\n *  the items will be added as-is. Otherwise, the data value will\n *  be checked against allowedValues.\n *  This object must contain at least a data key. Example:\n *  { data: 'foo', label: 'Foo item' }\n *  For multiple items, use an array of objects. For example:\n *  [\n *     { data: 'foo', label: 'Foo item' },\n *     { data: 'bar', label: 'Bar item' }\n *  ]\n *  Value can also be added with plaintext array, for example:\n *  [ 'foo', 'bar', 'bla' ] or a single string, like 'foo'\n */\nOO.ui.TagMultiselectWidget.prototype.setValue = function ( valueObject ) {\n\tvalueObject = Array.isArray( valueObject ) ? valueObject : [ valueObject ];\n\n\tthis.clearItems();\n\tvalueObject.forEach( function ( obj ) {\n\t\tif ( typeof obj === 'string' ) {\n\t\t\tthis.addTag( obj );\n\t\t} else {\n\t\t\tthis.addTag( obj.data, obj.label );\n\t\t}\n\t}.bind( this ) );\n};\n\n/**\n * Add tag to the display area\n *\n * @param {string|Object} data Tag data\n * @param {string} [label] Tag label. If no label is provided, the\n *  stringified version of the data will be used instead.\n * @return {boolean} Item was added successfully\n */\nOO.ui.TagMultiselectWidget.prototype.addTag = function ( data, label ) {\n\tvar newItemWidget,\n\t\tisValid = this.isAllowedData( data );\n\n\tif ( this.isUnderLimit() && ( isValid || this.allowDisplayInvalidTags ) ) {\n\t\tnewItemWidget = this.createTagItemWidget( data, label );\n\t\tnewItemWidget.toggleValid( isValid );\n\t\tthis.addItems( [ newItemWidget ] );\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * Check whether the number of current tags is within the limit.\n *\n * @return {boolean} True if current tag count is within the limit or\n *  if 'tagLimit' is not set\n */\nOO.ui.TagMultiselectWidget.prototype.isUnderLimit = function () {\n\treturn !this.tagLimit ||\n\t\tthis.getItemCount() < this.tagLimit;\n};\n\n/**\n * Remove tag by its data property.\n *\n * @param {string|Object} data Tag data\n */\nOO.ui.TagMultiselectWidget.prototype.removeTagByData = function ( data ) {\n\tvar item = this.findItemFromData( data );\n\n\tthis.removeItems( [ item ] );\n};\n\n/**\n * Construct a OO.ui.TagItemWidget (or a subclass thereof) from given label and data.\n *\n * @protected\n * @param {string} data Item data\n * @param {string} label The label text.\n * @return {OO.ui.TagItemWidget}\n */\nOO.ui.TagMultiselectWidget.prototype.createTagItemWidget = function ( data, label ) {\n\tlabel = label || data;\n\n\treturn new OO.ui.TagItemWidget( { data: data, label: label } );\n};\n\n/**\n * Given an item, returns the item after it. If the item is already the\n * last item, return `this.input`. If no item is passed, returns the\n * very first item.\n *\n * @protected\n * @param {OO.ui.TagItemWidget} [item] Tag item\n * @return {OO.ui.Widget} The next widget available.\n */\nOO.ui.TagMultiselectWidget.prototype.getNextItem = function ( item ) {\n\tvar itemIndex = this.items.indexOf( item );\n\n\tif ( item === undefined || itemIndex === -1 ) {\n\t\treturn this.items[ 0 ];\n\t}\n\n\tif ( itemIndex === this.items.length - 1 ) { // Last item\n\t\tif ( this.hasInput ) {\n\t\t\treturn this.input;\n\t\t} else {\n\t\t\t// Return first item\n\t\t\treturn this.items[ 0 ];\n\t\t}\n\t} else {\n\t\treturn this.items[ itemIndex + 1 ];\n\t}\n};\n\n/**\n * Given an item, returns the item before it. If the item is already the\n * first item, return `this.input`. If no item is passed, returns the\n * very last item.\n *\n * @protected\n * @param {OO.ui.TagItemWidget} [item] Tag item\n * @return {OO.ui.Widget} The previous widget available.\n */\nOO.ui.TagMultiselectWidget.prototype.getPreviousItem = function ( item ) {\n\tvar itemIndex = this.items.indexOf( item );\n\n\tif ( item === undefined || itemIndex === -1 ) {\n\t\treturn this.items[ this.items.length - 1 ];\n\t}\n\n\tif ( itemIndex === 0 ) {\n\t\tif ( this.hasInput ) {\n\t\t\treturn this.input;\n\t\t} else {\n\t\t\t// Return the last item\n\t\t\treturn this.items[ this.items.length - 1 ];\n\t\t}\n\t} else {\n\t\treturn this.items[ itemIndex - 1 ];\n\t}\n};\n\n/**\n * Update the dimensions of the text input field to encompass all available area.\n * This is especially relevant for when the input is at the edge of a line\n * and should get smaller. The usual operation (as an inline-block with min-width)\n * does not work in that case, pushing the input downwards to the next line.\n *\n * @private\n */\nOO.ui.TagMultiselectWidget.prototype.updateInputSize = function () {\n\tvar $lastItem, direction, contentWidth, currentWidth, bestWidth;\n\tif ( this.inputPosition === 'inline' && !this.isDisabled() ) {\n\t\tif ( this.input.$input[ 0 ].scrollWidth === 0 ) {\n\t\t\t// Input appears to be attached but not visible.\n\t\t\t// Don't attempt to adjust its size, because our measurements\n\t\t\t// are going to fail anyway.\n\t\t\treturn;\n\t\t}\n\t\tthis.input.$input.css( 'width', '1em' );\n\t\t$lastItem = this.$group.children().last();\n\t\tdirection = OO.ui.Element.static.getDir( this.$handle );\n\n\t\t// Get the width of the input with the placeholder text as\n\t\t// the value and save it so that we don't keep recalculating\n\t\tif (\n\t\t\tthis.contentWidthWithPlaceholder === undefined &&\n\t\t\tthis.input.getValue() === '' &&\n\t\t\tthis.input.$input.attr( 'placeholder' ) !== undefined\n\t\t) {\n\t\t\tthis.input.setValue( this.input.$input.attr( 'placeholder' ) );\n\t\t\tthis.contentWidthWithPlaceholder = this.input.$input[ 0 ].scrollWidth;\n\t\t\tthis.input.setValue( '' );\n\n\t\t}\n\n\t\t// Always keep the input wide enough for the placeholder text\n\t\tcontentWidth = Math.max(\n\t\t\tthis.input.$input[ 0 ].scrollWidth,\n\t\t\t// undefined arguments in Math.max lead to NaN\n\t\t\t( this.contentWidthWithPlaceholder === undefined ) ?\n\t\t\t\t0 : this.contentWidthWithPlaceholder\n\t\t);\n\t\tcurrentWidth = this.input.$input.width();\n\n\t\tif ( contentWidth < currentWidth ) {\n\t\t\tthis.updateIfHeightChanged();\n\t\t\t// All is fine, don't perform expensive calculations\n\t\t\treturn;\n\t\t}\n\n\t\tif ( $lastItem.length === 0 ) {\n\t\t\tbestWidth = this.$content.innerWidth();\n\t\t} else {\n\t\t\tbestWidth = direction === 'ltr' ?\n\t\t\t\tthis.$content.innerWidth() - $lastItem.position().left - $lastItem.outerWidth() :\n\t\t\t\t$lastItem.position().left;\n\t\t}\n\n\t\t// Some safety margin for sanity, because I *really* don't feel like finding out where the\n\t\t// few pixels this is off by are coming from.\n\t\tbestWidth -= 13;\n\t\tif ( contentWidth > bestWidth ) {\n\t\t\t// This will result in the input getting shifted to the next line\n\t\t\tbestWidth = this.$content.innerWidth() - 13;\n\t\t}\n\t\tthis.input.$input.width( Math.floor( bestWidth ) );\n\t\tthis.updateIfHeightChanged();\n\t} else {\n\t\tthis.updateIfHeightChanged();\n\t}\n};\n\n/**\n * Determine if widget height changed, and if so,\n * emit the resize event. This is useful for when there are either\n * menus or popups attached to the bottom of the widget, to allow\n * them to change their positioning in case the widget moved down\n * or up.\n *\n * @private\n */\nOO.ui.TagMultiselectWidget.prototype.updateIfHeightChanged = function () {\n\tvar height = this.$element.height();\n\tif ( height !== this.height ) {\n\t\tthis.height = height;\n\t\tthis.emit( 'resize' );\n\t}\n};\n\n/**\n * Check whether all items in the widget are valid\n *\n * @return {boolean} Widget is valid\n */\nOO.ui.TagMultiselectWidget.prototype.checkValidity = function () {\n\treturn this.getItems().every( function ( item ) {\n\t\treturn item.isValid();\n\t} );\n};\n\n/**\n * Set the valid state of this item\n *\n * @param {boolean} [valid] Item is valid\n * @fires valid\n */\nOO.ui.TagMultiselectWidget.prototype.toggleValid = function ( valid ) {\n\tvalid = valid === undefined ? !this.valid : !!valid;\n\n\tif ( this.valid !== valid ) {\n\t\tthis.valid = valid;\n\n\t\tthis.setFlags( { invalid: !this.valid } );\n\n\t\tthis.emit( 'valid', this.valid );\n\t}\n};\n\n/**\n * Get the current valid state of the widget\n *\n * @return {boolean} Widget is valid\n */\nOO.ui.TagMultiselectWidget.prototype.isValid = function () {\n\treturn this.valid;\n};\n","/**\n * PopupTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget}\n * intended to use a popup. The popup can be configured to have a default input to insert values\n * into the widget.\n *\n *     @example\n *     // A PopupTagMultiselectWidget.\n *     var widget = new OO.ui.PopupTagMultiselectWidget();\n *     $( document.body ).append( widget.$element );\n *\n *     // Example: A PopupTagMultiselectWidget with an external popup.\n *     var popupInput = new OO.ui.TextInputWidget(),\n *         widget = new OO.ui.PopupTagMultiselectWidget( {\n *            popupInput: popupInput,\n *            popup: {\n *               $content: popupInput.$element\n *            }\n *         } );\n *     $( document.body ).append( widget.$element );\n *\n * @class\n * @extends OO.ui.TagMultiselectWidget\n * @mixins OO.ui.mixin.PopupElement\n *\n * @param {Object} config Configuration object\n * @cfg {jQuery} [$overlay] An overlay for the popup.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n * @cfg {Object} [popup] Configuration options for the popup\n * @cfg {OO.ui.InputWidget} [popupInput] An input widget inside the popup that will be\n *  focused when the popup is opened and will be used as replacement for the\n *  general input in the widget.\n * @deprecated\n */\nOO.ui.PopupTagMultiselectWidget = function OoUiPopupTagMultiselectWidget( config ) {\n\tvar defaultInput,\n\t\tdefaultConfig = { popup: {} };\n\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.PopupTagMultiselectWidget.parent.call( this, $.extend( {\n\t\tinputPosition: 'none'\n\t}, config ) );\n\n\tthis.$overlay = ( config.$overlay === true ?\n\t\tOO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\n\tif ( !config.popup ) {\n\t\t// For the default base implementation, we give a popup\n\t\t// with an input widget inside it. For any other use cases\n\t\t// the popup needs to be populated externally and the\n\t\t// event handled to add tags separately and manually\n\t\tdefaultInput = new OO.ui.TextInputWidget();\n\n\t\tdefaultConfig.popupInput = defaultInput;\n\t\tdefaultConfig.popup.$content = defaultInput.$element;\n\t\tdefaultConfig.popup.padded = true;\n\n\t\tthis.$element.addClass( 'oo-ui-popupTagMultiselectWidget-defaultPopup' );\n\t}\n\n\t// Add overlay, and add that to the autoCloseIgnore\n\tdefaultConfig.popup.$overlay = this.$overlay;\n\tdefaultConfig.popup.$autoCloseIgnore = this.hasInput ?\n\t\tthis.input.$element.add( this.$overlay ) : this.$overlay;\n\n\t// Allow extending any of the above\n\tconfig = $.extend( defaultConfig, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PopupElement.call( this, config );\n\n\tif ( this.hasInput ) {\n\t\tthis.input.$input.on( 'focus', this.popup.toggle.bind( this.popup, true ) );\n\t}\n\n\t// Configuration options\n\tthis.popupInput = config.popupInput;\n\tif ( this.popupInput ) {\n\t\tthis.popupInput.connect( this, {\n\t\t\tenter: 'onPopupInputEnter'\n\t\t} );\n\t}\n\n\t// Events\n\tthis.on( 'resize', this.popup.updateDimensions.bind( this.popup ) );\n\tthis.popup.connect( this, {\n\t\ttoggle: 'onPopupToggle'\n\t} );\n\tthis.$tabIndexed.on( 'focus', this.onFocus.bind( this ) );\n\n\t// Initialize\n\tthis.$element\n\t\t.append( this.popup.$element )\n\t\t.addClass( 'oo-ui-popupTagMultiselectWidget' );\n\n\t// Deprecation warning\n\tOO.ui.warnDeprecation( 'PopupTagMultiselectWidget: Deprecated widget. Use MenuTagMultiselectWidget instead. See T208821.' );\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.PopupTagMultiselectWidget, OO.ui.TagMultiselectWidget );\nOO.mixinClass( OO.ui.PopupTagMultiselectWidget, OO.ui.mixin.PopupElement );\n\n/* Methods */\n\n/**\n * Focus event handler.\n *\n * @private\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onFocus = function () {\n\tthis.popup.toggle( true );\n};\n\n/**\n * Respond to popup toggle event\n *\n * @param {boolean} isVisible Popup is visible\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onPopupToggle = function ( isVisible ) {\n\tif ( isVisible && this.popupInput ) {\n\t\tthis.popupInput.focus();\n\t}\n};\n\n/**\n * Respond to popup input enter event\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onPopupInputEnter = function () {\n\tif ( this.popupInput ) {\n\t\tthis.addTagByPopupValue( this.popupInput.getValue() );\n\t\tthis.popupInput.setValue( '' );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.PopupTagMultiselectWidget.prototype.onTagSelect = function ( item ) {\n\tif ( this.popupInput && this.allowEditTags ) {\n\t\tthis.popupInput.setValue( item.getData() );\n\t\tthis.removeItems( [ item ] );\n\n\t\tthis.popup.toggle( true );\n\t\tthis.popupInput.focus();\n\t} else {\n\t\t// Parent\n\t\tOO.ui.PopupTagMultiselectWidget.parent.prototype.onTagSelect.call( this, item );\n\t}\n};\n\n/**\n * Add a tag by the popup value.\n * Whatever is responsible for setting the value in the popup should call\n * this method to add a tag, or use the regular methods like #addTag or\n * #setValue directly.\n *\n * @param {string} data The value of item\n * @param {string} [label] The label of the tag. If not given, the data is used.\n */\nOO.ui.PopupTagMultiselectWidget.prototype.addTagByPopupValue = function ( data, label ) {\n\tthis.addTag( data, label );\n};\n","/**\n * MenuTagMultiselectWidget is a {@link OO.ui.TagMultiselectWidget OO.ui.TagMultiselectWidget}\n * intended to use a menu of selectable options.\n *\n *     @example\n *     // A basic MenuTagMultiselectWidget.\n *     var widget = new OO.ui.MenuTagMultiselectWidget( {\n *         inputPosition: 'outline',\n *         options: [\n *            { data: 'option1', label: 'Option 1', icon: 'tag' },\n *            { data: 'option2', label: 'Option 2' },\n *            { data: 'option3', label: 'Option 3' },\n *         ],\n *         selected: [ 'option1', 'option2' ]\n *     } );\n *     $( document.body ).append( widget.$element );\n *\n * @class\n * @extends OO.ui.TagMultiselectWidget\n *\n * @constructor\n * @param {Object} [config] Configuration object\n * @cfg {boolean} [clearInputOnChoose=true] Clear the text input value when a menu option is chosen\n * @cfg {Object} [menu] Configuration object for the menu widget\n * @cfg {jQuery} [$overlay] An overlay for the menu.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`\n */\nOO.ui.MenuTagMultiselectWidget = function OoUiMenuTagMultiselectWidget( config ) {\n\tvar $autoCloseIgnore = $( [] );\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.MenuTagMultiselectWidget.parent.call( this, config );\n\n\t$autoCloseIgnore = $autoCloseIgnore.add( this.$group );\n\tif ( this.hasInput ) {\n\t\t$autoCloseIgnore = $autoCloseIgnore.add( this.input.$element );\n\t}\n\n\tthis.$overlay = ( config.$overlay === true ?\n\t\tOO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.clearInputOnChoose = config.clearInputOnChoose === undefined ||\n\t\t!!config.clearInputOnChoose;\n\tthis.menu = this.createMenuWidget( $.extend( {\n\t\twidget: this,\n\t\thideOnChoose: false,\n\t\tinput: this.hasInput ? this.input : null,\n\t\t$input: this.hasInput ? this.input.$input : null,\n\t\tfilterFromInput: !!this.hasInput,\n\t\thighlightOnFilter: !this.allowArbitrary,\n\t\tmultiselect: true,\n\t\t$autoCloseIgnore: $autoCloseIgnore,\n\t\t$floatableContainer: this.hasInput && this.inputPosition === 'outline' ?\n\t\t\tthis.input.$element : this.$element,\n\t\t$overlay: this.$overlay,\n\t\tdisabled: this.isDisabled()\n\t}, config.menu ) );\n\tthis.addOptions( config.options || [] );\n\n\t// Events\n\tthis.menu.connect( this, {\n\t\tchoose: 'onMenuChoose',\n\t\ttoggle: 'onMenuToggle'\n\t} );\n\tif ( this.hasInput ) {\n\t\tthis.input.connect( this, {\n\t\t\tchange: 'onInputChange'\n\t\t} );\n\t}\n\tthis.connect( this, {\n\t\tresize: 'onResize'\n\t} );\n\n\t// Initialization\n\tthis.$overlay.append( this.menu.$element );\n\tthis.$element.addClass( 'oo-ui-menuTagMultiselectWidget' );\n\t// Remove MenuSelectWidget's generic focus owner ARIA attribute\n\t// TODO: Should this widget have a `role` that is compatible with this attribute?\n\tthis.menu.$focusOwner.removeAttr( 'aria-expanded' );\n\t// TagMultiselectWidget already does this, but it doesn't work right because this.menu is\n\t// not yet set up while the parent constructor runs, and #getAllowedValues rejects everything.\n\tif ( config.selected ) {\n\t\tthis.setValue( config.selected );\n\t}\n};\n\n/* Initialization */\n\nOO.inheritClass( OO.ui.MenuTagMultiselectWidget, OO.ui.TagMultiselectWidget );\n\n/* Methods */\n\n/**\n * Respond to resize event\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onResize = function () {\n\t// Reposition the menu\n\tthis.menu.position();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onInputFocus = function () {\n\t// Parent method\n\tOO.ui.MenuTagMultiselectWidget.parent.prototype.onInputFocus.call( this );\n\n\tthis.menu.toggle( true );\n};\n\n/**\n * Respond to input change event\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onInputChange = function () {\n\tthis.menu.toggle( true );\n};\n\n/**\n * Respond to menu choose event, which is intentional by the user.\n *\n * @param {OO.ui.OptionWidget} menuItem Selected menu items\n * @param {boolean} selected Item is selected\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onMenuChoose = function ( menuItem, selected ) {\n\tif ( this.hasInput && this.clearInputOnChoose ) {\n\t\tthis.input.setValue( '' );\n\t}\n\n\tif ( selected && !this.findItemFromData( menuItem.getData() ) ) {\n\t\t// The menu item is selected, add it to the tags\n\t\tthis.addTag( menuItem.getData(), menuItem.getLabel() );\n\t} else {\n\t\t// The menu item was unselected, remove the tag\n\t\tthis.removeTagByData( menuItem.getData() );\n\t}\n};\n\n/**\n * Respond to menu toggle event. Reset item highlights on hide.\n *\n * @param {boolean} isVisible The menu is visible\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tif ( !isVisible ) {\n\t\tthis.menu.highlightItem( null );\n\t\tthis.menu.scrollToTop();\n\t}\n\tsetTimeout( function () {\n\t\t// Remove MenuSelectWidget's generic focus owner ARIA attribute\n\t\t// TODO: Should this widget have a `role` that is compatible with this attribute?\n\t\tthis.menu.$focusOwner.removeAttr( 'aria-expanded' );\n\t}.bind( this ) );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.onTagSelect = function ( tagItem ) {\n\tvar menuItem = this.menu.findItemFromData( tagItem.getData() );\n\tif ( !this.allowArbitrary ) {\n\t\t// Override the base behavior from TagMultiselectWidget; the base behavior\n\t\t// in TagMultiselectWidget is to remove the tag to edit it in the input,\n\t\t// but in our case, we want to utilize the menu selection behavior, and\n\t\t// definitely not remove the item.\n\n\t\t// If there is an input that is used for filtering, erase the value so we don't filter\n\t\tif ( this.hasInput && this.menu.filterFromInput ) {\n\t\t\tthis.input.setValue( '' );\n\t\t}\n\n\t\tthis.focus();\n\n\t\t// Highlight the menu item\n\t\tthis.menu.highlightItem( menuItem );\n\t\tthis.menu.scrollItemIntoView( menuItem );\n\n\t} else {\n\t\t// Use the default\n\t\tOO.ui.MenuTagMultiselectWidget.parent.prototype.onTagSelect.call( this, tagItem );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.removeItems = function ( items ) {\n\tvar widget = this;\n\n\t// Parent\n\tOO.ui.MenuTagMultiselectWidget.parent.prototype.removeItems.call( this, items );\n\n\titems.forEach( function ( tagItem ) {\n\t\tvar menuItem = widget.menu.findItemFromData( tagItem.getData() );\n\t\tif ( menuItem ) {\n\t\t\t// Synchronize the menu selection - unselect the removed tag\n\t\t\twidget.menu.unselectItem( menuItem );\n\t\t}\n\t} );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.setValue = function ( valueObject ) {\n\tvalueObject = Array.isArray( valueObject ) ? valueObject : [ valueObject ];\n\n\t// We override this method from the parent, to make sure we are adding proper\n\t// menu items, and are accounting for cases where we have this widget with\n\t// a menu but also 'allowArbitrary'\n\tif ( !this.menu ) {\n\t\treturn;\n\t}\n\n\tthis.clearItems();\n\tvalueObject.forEach( function ( obj ) {\n\t\tvar data, label, menuItem;\n\n\t\tif ( typeof obj === 'string' ) {\n\t\t\tdata = label = obj;\n\t\t} else {\n\t\t\tdata = obj.data;\n\t\t\tlabel = obj.label;\n\t\t}\n\n\t\t// Check if the item is in the menu\n\t\tmenuItem = this.menu.getItemFromLabel( label ) || this.menu.findItemFromData( data );\n\t\tif ( menuItem ) {\n\t\t\t// Menu item found, add the menu item\n\t\t\tthis.addTag( menuItem.getData(), menuItem.getLabel() );\n\t\t\t// Make sure that item is also selected\n\t\t\tthis.menu.selectItem( menuItem );\n\t\t} else if ( this.allowArbitrary ) {\n\t\t\t// If the item isn't in the menu, only add it if we\n\t\t\t// allow for arbitrary values\n\t\t\tthis.addTag( data, label );\n\t\t}\n\t}.bind( this ) );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.setDisabled = function ( isDisabled ) {\n\t// Parent method\n\tOO.ui.MenuTagMultiselectWidget.parent.prototype.setDisabled.call( this, isDisabled );\n\n\tif ( this.menu ) {\n\t\t// Protect against calling setDisabled() before the menu was initialized\n\t\tthis.menu.setDisabled( isDisabled );\n\t}\n};\n\n/**\n * Highlight the first selectable item in the menu, if configured.\n *\n * @private\n * @chainable\n */\nOO.ui.MenuTagMultiselectWidget.prototype.initializeMenuSelection = function () {\n\tvar highlightedItem;\n\tthis.menu.highlightItem(\n\t\tthis.allowArbitrary ?\n\t\t\tnull :\n\t\t\tthis.menu.findFirstSelectableItem()\n\t);\n\n\thighlightedItem = this.menu.findHighlightedItem();\n\t// Scroll to the highlighted item, if it exists\n\tif ( highlightedItem ) {\n\t\tthis.menu.scrollItemIntoView( highlightedItem );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.addTagFromInput = function () {\n\tvar val = this.input.getValue(),\n\t\t// Look for a highlighted item first\n\t\t// Then look for the element that fits the data\n\t\titem = this.menu.findHighlightedItem() || this.menu.findItemFromData( val ),\n\t\tdata = item ? item.getData() : val,\n\t\tisValid = this.isAllowedData( data );\n\n\t// Override the parent method so we add from the menu\n\t// rather than directly from the input\n\n\tif ( !val ) {\n\t\treturn;\n\t}\n\n\tif ( isValid || this.allowDisplayInvalidTags ) {\n\t\tthis.clearInput();\n\t\tif ( item ) {\n\t\t\tthis.addTag( data, item.getLabel() );\n\t\t} else {\n\t\t\tthis.addTag( val );\n\t\t}\n\t}\n};\n\n/**\n * Return the visible items in the menu. This is mainly used for when\n * the menu is filtering results.\n *\n * @return {OO.ui.MenuOptionWidget[]} Visible results\n */\nOO.ui.MenuTagMultiselectWidget.prototype.getMenuVisibleItems = function () {\n\treturn this.menu.getItems().filter( function ( menuItem ) {\n\t\treturn menuItem.isVisible();\n\t} );\n};\n\n/**\n * Create the menu for this widget. This is in a separate method so that\n * child classes can override this without polluting the constructor with\n * unnecessary extra objects that will be overidden.\n *\n * @param {Object} menuConfig Configuration options\n * @return {OO.ui.MenuSelectWidget} Menu widget\n */\nOO.ui.MenuTagMultiselectWidget.prototype.createMenuWidget = function ( menuConfig ) {\n\treturn new OO.ui.MenuSelectWidget( menuConfig );\n};\n\n/**\n * Add options to the menu\n *\n * @param {Object[]} menuOptions Object defining options\n */\nOO.ui.MenuTagMultiselectWidget.prototype.addOptions = function ( menuOptions ) {\n\tvar widget = this,\n\t\titems = menuOptions.map( function ( obj ) {\n\t\t\treturn widget.createMenuOptionWidget( obj.data, obj.label, obj.icon );\n\t\t} );\n\n\tthis.menu.addItems( items );\n};\n\n/**\n * Create a menu option widget.\n *\n * @param {string} data Item data\n * @param {string} [label] Item label\n * @param {string} [icon] Symbolic icon name\n * @return {OO.ui.OptionWidget} Option widget\n */\nOO.ui.MenuTagMultiselectWidget.prototype.createMenuOptionWidget = function ( data, label, icon ) {\n\treturn new OO.ui.MenuOptionWidget( {\n\t\tdata: data,\n\t\tlabel: label || data,\n\t\ticon: icon\n\t} );\n};\n\n/**\n * Get the menu\n *\n * @return {OO.ui.MenuSelectWidget} Menu\n */\nOO.ui.MenuTagMultiselectWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Get the allowed values list\n *\n * @return {string[]} Allowed data values\n */\nOO.ui.MenuTagMultiselectWidget.prototype.getAllowedValues = function () {\n\tvar menuDatas = [];\n\tif ( this.menu ) {\n\t\t// If the parent constructor is calling us, we're not ready yet, this.menu is not set up.\n\t\tmenuDatas = this.menu.getItems().map( function ( menuItem ) {\n\t\t\treturn menuItem.getData();\n\t\t} );\n\t}\n\treturn this.allowedValues.concat( menuDatas );\n};\n","/**\n * SelectFileWidgets allow for selecting files, using the HTML5 File API. These\n * widgets can be configured with {@link OO.ui.mixin.IconElement icons}, {@link\n * OO.ui.mixin.IndicatorElement indicators} and {@link OO.ui.mixin.TitledElement titles}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n * Although SelectFileWidget inherits from SelectFileInputWidget, it does not\n * behave as an InputWidget, and can't be used in HTML forms.\n *\n *     @example\n *     // A file select widget.\n *     var selectFile = new OO.ui.SelectFileWidget();\n *     $( document.body ).append( selectFile.$element );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets\n *\n * @class\n * @extends OO.ui.SelectFileInputWidget\n * @mixins OO.ui.mixin.PendingElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [notsupported] Text to display when file support is missing in the browser.\n * @cfg {boolean} [droppable=true] Whether to accept files by drag and drop.\n * @cfg {boolean} [buttonOnly=false] Show only the select file button, no info field. Requires\n *  showDropTarget to be false.\n * @cfg {boolean} [showDropTarget=false] Whether to show a drop target. Requires droppable to be\n *  true. Not yet supported in multiple file mode.\n * @cfg {number} [thumbnailSizeLimit=20] File size limit in MiB above which to not try and show a\n *  preview (for performance).\n */\nOO.ui.SelectFileWidget = function OoUiSelectFileWidget( config ) {\n\tvar dragHandler, droppable,\n\t\tisSupported = this.constructor.static.isSupported();\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tnotsupported: OO.ui.msg( 'ooui-selectfile-not-supported' ),\n\t\tdroppable: true,\n\t\tbuttonOnly: false,\n\t\tshowDropTarget: false,\n\t\tthumbnailSizeLimit: 20\n\t}, config );\n\n\tif ( !isSupported ) {\n\t\tconfig.disabled = true;\n\t}\n\n\t// Parent constructor\n\tOO.ui.SelectFileWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PendingElement.call( this );\n\n\tif ( !isSupported ) {\n\t\tthis.info.setValue( config.notsupported );\n\t}\n\n\t// Properties\n\tdroppable = config.droppable && isSupported;\n\t// TODO: Support drop target when multiple is set\n\tthis.showDropTarget = droppable && config.showDropTarget && !this.multiple;\n\tthis.thumbnailSizeLimit = config.thumbnailSizeLimit;\n\n\t// Events\n\tif ( droppable ) {\n\t\tdragHandler = this.onDragEnterOrOver.bind( this );\n\t\tthis.$element.on( {\n\t\t\tdragenter: dragHandler,\n\t\t\tdragover: dragHandler,\n\t\t\tdragleave: this.onDragLeave.bind( this ),\n\t\t\tdrop: this.onDrop.bind( this )\n\t\t} );\n\t}\n\n\t// Initialization\n\tif ( this.showDropTarget ) {\n\t\tthis.selectButton.setIcon( 'upload' );\n\t\tthis.$thumbnail = $( '<div>' ).addClass( 'oo-ui-selectFileWidget-thumbnail' );\n\t\tthis.setPendingElement( this.$thumbnail );\n\t\tthis.$element\n\t\t\t.addClass( 'oo-ui-selectFileWidget-dropTarget' )\n\t\t\t.on( {\n\t\t\t\tclick: this.onDropTargetClick.bind( this )\n\t\t\t} )\n\t\t\t.append(\n\t\t\t\tthis.$thumbnail,\n\t\t\t\tthis.info.$element,\n\t\t\t\tthis.selectButton.$element,\n\t\t\t\t$( '<span>' )\n\t\t\t\t\t.addClass( 'oo-ui-selectFileWidget-dropLabel' )\n\t\t\t\t\t.text( OO.ui.msg( 'ooui-selectfile-dragdrop-placeholder' ) )\n\t\t\t);\n\t\tthis.fieldLayout.$element.remove();\n\t} else if ( config.buttonOnly ) {\n\t\tthis.$element.append( this.selectButton.$element );\n\t\tthis.fieldLayout.$element.remove();\n\t}\n\n\tthis.$input\n\t\t.on( 'click', function ( e ) {\n\t\t\t// Prevents dropTarget to get clicked which calls\n\t\t\t// a click on this input\n\t\t\te.stopPropagation();\n\t\t} );\n\n\tthis.$element.addClass( 'oo-ui-selectFileWidget' );\n\n\tthis.updateUI();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SelectFileWidget, OO.ui.SelectFileInputWidget );\nOO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.PendingElement );\n\n/* Static Properties */\n\n/**\n * Check if this widget is supported\n *\n * @static\n * @return {boolean}\n */\nOO.ui.SelectFileWidget.static.isSupported = function () {\n\tvar $input;\n\tif ( OO.ui.SelectFileWidget.static.isSupportedCache === null ) {\n\t\t$input = $( '<input>' ).attr( 'type', 'file' );\n\t\tOO.ui.SelectFileWidget.static.isSupportedCache = $input[ 0 ].files !== undefined;\n\t}\n\treturn OO.ui.SelectFileWidget.static.isSupportedCache;\n};\n\nOO.ui.SelectFileWidget.static.isSupportedCache = null;\n\n/* Events */\n\n/**\n * @event change\n *\n * A change event is emitted when the on/off state of the toggle changes.\n *\n * @param {File|null} value New value\n */\n\n/* Methods */\n\n/**\n * Get the current value of the field\n *\n * For single file widgets returns a File or null.\n * For multiple file widgets returns a list of Files.\n *\n * @return {File|File[]|null}\n */\nOO.ui.SelectFileWidget.prototype.getValue = function () {\n\treturn this.multiple ? this.currentFiles : this.currentFiles[ 0 ];\n};\n\n/**\n * Set the current value of the field\n *\n * @param {File[]|null} files Files to select\n */\nOO.ui.SelectFileWidget.prototype.setValue = function ( files ) {\n\tif ( files && !this.multiple ) {\n\t\tfiles = files.slice( 0, 1 );\n\t}\n\n\tfunction comparableFile( file ) {\n\t\t// Use extend to convert to plain objects so they can be compared.\n\t\treturn $.extend( {}, file );\n\t}\n\n\tif ( !OO.compare(\n\t\tfiles && files.map( comparableFile ),\n\t\tthis.currentFiles && this.currentFiles.map( comparableFile )\n\t) ) {\n\t\tthis.currentFiles = files || [];\n\t\tthis.emit( 'change', this.currentFiles );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileWidget.prototype.getFilename = function () {\n\treturn this.currentFiles.map( function ( file ) {\n\t\treturn file.name;\n\t} ).join( ', ' );\n};\n\n/**\n * Disable InputWidget#onEdit listener, onFileSelected is used instead.\n * @inheritdoc\n */\nOO.ui.SelectFileWidget.prototype.onEdit = function () {};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileWidget.prototype.updateUI = function () {\n\t// Too early, or not supported\n\tif ( !this.selectButton || !this.constructor.static.isSupported() ) {\n\t\treturn;\n\t}\n\n\t// Parent method\n\tOO.ui.SelectFileWidget.super.prototype.updateUI.call( this );\n\n\tif ( this.currentFiles.length ) {\n\t\tthis.$element.removeClass( 'oo-ui-selectFileInputWidget-empty' );\n\n\t\tif ( this.showDropTarget ) {\n\t\t\tthis.pushPending();\n\t\t\tthis.loadAndGetImageUrl( this.currentFiles[ 0 ] ).done( function ( url ) {\n\t\t\t\tthis.$thumbnail.css( 'background-image', 'url( ' + url + ' )' );\n\t\t\t}.bind( this ) ).fail( function () {\n\t\t\t\tthis.$thumbnail.append(\n\t\t\t\t\tnew OO.ui.IconWidget( {\n\t\t\t\t\t\ticon: 'attachment',\n\t\t\t\t\t\tclasses: [ 'oo-ui-selectFileWidget-noThumbnail-icon' ]\n\t\t\t\t\t} ).$element\n\t\t\t\t);\n\t\t\t}.bind( this ) ).always( function () {\n\t\t\t\tthis.popPending();\n\t\t\t}.bind( this ) );\n\t\t\tthis.$element.off( 'click' );\n\t\t}\n\t} else {\n\t\tif ( this.showDropTarget ) {\n\t\t\tthis.$element.off( 'click' );\n\t\t\tthis.$element.on( {\n\t\t\t\tclick: this.onDropTargetClick.bind( this )\n\t\t\t} );\n\t\t\tthis.$thumbnail\n\t\t\t\t.empty()\n\t\t\t\t.css( 'background-image', '' );\n\t\t}\n\t\tthis.$element.addClass( 'oo-ui-selectFileInputWidget-empty' );\n\t}\n};\n\n/**\n * If the selected file is an image, get its URL and load it.\n *\n * @param {File} file File\n * @return {jQuery.Promise} Promise resolves with the image URL after it has loaded\n */\nOO.ui.SelectFileWidget.prototype.loadAndGetImageUrl = function ( file ) {\n\tvar deferred = $.Deferred(),\n\t\treader = new FileReader();\n\n\tif (\n\t\t( OO.getProp( file, 'type' ) || '' ).indexOf( 'image/' ) === 0 &&\n\t\tfile.size < this.thumbnailSizeLimit * 1024 * 1024\n\t) {\n\t\treader.onload = function ( event ) {\n\t\t\tvar img = document.createElement( 'img' );\n\t\t\timg.addEventListener( 'load', function () {\n\t\t\t\tif (\n\t\t\t\t\timg.naturalWidth === 0 ||\n\t\t\t\t\timg.naturalHeight === 0 ||\n\t\t\t\t\timg.complete === false\n\t\t\t\t) {\n\t\t\t\t\tdeferred.reject();\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.resolve( event.target.result );\n\t\t\t\t}\n\t\t\t} );\n\t\t\timg.src = event.target.result;\n\t\t};\n\t\treader.readAsDataURL( file );\n\t} else {\n\t\tdeferred.reject();\n\t}\n\n\treturn deferred.promise();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileWidget.prototype.onFileSelected = function ( e ) {\n\tvar files;\n\n\tif ( this.inputClearing ) {\n\t\treturn;\n\t}\n\n\tfiles = this.filterFiles( e.target.files || [] );\n\n\t// After a file is selected clear the native widget to avoid confusion\n\tthis.inputClearing = true;\n\tthis.$input[ 0 ].value = '';\n\tthis.inputClearing = false;\n\n\tthis.setValue( files );\n};\n\n/**\n * Handle drop target click events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {\n\tif ( !this.isDisabled() && this.$input ) {\n\t\tthis.$input.trigger( 'click' );\n\t\treturn false;\n\t}\n};\n\n/**\n * Handle drag enter and over events\n *\n * @private\n * @param {jQuery.Event} e Drag event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onDragEnterOrOver = function ( e ) {\n\tvar itemsOrFiles,\n\t\thasDroppableFile = false,\n\t\tdt = e.originalEvent.dataTransfer;\n\n\te.preventDefault();\n\te.stopPropagation();\n\n\tif ( this.isDisabled() ) {\n\t\tthis.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );\n\t\tdt.dropEffect = 'none';\n\t\treturn false;\n\t}\n\n\t// DataTransferItem and File both have a type property, but in Chrome files\n\t// have no information at this point.\n\titemsOrFiles = dt.items || dt.files;\n\tif ( itemsOrFiles && itemsOrFiles.length ) {\n\t\tif ( this.filterFiles( itemsOrFiles ).length ) {\n\t\t\thasDroppableFile = true;\n\t\t}\n\t// dt.types is Array-like, but not an Array\n\t} else if ( Array.prototype.indexOf.call( OO.getProp( dt, 'types' ) || [], 'Files' ) !== -1 ) {\n\t\t// File information is not available at this point for security so just assume\n\t\t// it is acceptable for now.\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=640534\n\t\thasDroppableFile = true;\n\t}\n\n\tthis.$element.toggleClass( 'oo-ui-selectFileWidget-canDrop', hasDroppableFile );\n\tif ( !hasDroppableFile ) {\n\t\tdt.dropEffect = 'none';\n\t}\n\n\treturn false;\n};\n\n/**\n * Handle drag leave events\n *\n * @private\n * @param {jQuery.Event} e Drag event\n */\nOO.ui.SelectFileWidget.prototype.onDragLeave = function () {\n\tthis.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );\n};\n\n/**\n * Handle drop events\n *\n * @private\n * @param {jQuery.Event} e Drop event\n * @return {undefined/boolean} False to prevent default if event is handled\n */\nOO.ui.SelectFileWidget.prototype.onDrop = function ( e ) {\n\tvar files,\n\t\tdt = e.originalEvent.dataTransfer;\n\n\te.preventDefault();\n\te.stopPropagation();\n\tthis.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );\n\n\tif ( this.isDisabled() ) {\n\t\treturn false;\n\t}\n\n\tfiles = this.filterFiles( dt.files || [] );\n\tthis.setValue( files );\n\n\treturn false;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.SelectFileWidget.prototype.setDisabled = function ( disabled ) {\n\tdisabled = disabled || !this.constructor.static.isSupported();\n\n\t// Parent method\n\tOO.ui.SelectFileWidget.parent.prototype.setDisabled.call( this, disabled );\n};\n","/**\n * SearchWidgets combine a {@link OO.ui.TextInputWidget text input field},\n * where users can type a search query, and a menu of search results,\n * which is displayed beneath the query field.\n * Unlike {@link OO.ui.mixin.LookupElement lookup menus}, search result menus are always visible\n * to the user. Users can choose an item from the menu or type a query into the text field to\n * search for a matching result item.\n * In general, search widgets are used inside a separate {@link OO.ui.Dialog dialog} window.\n *\n * Each time the query is changed, the search result menu is cleared and repopulated. Please see\n * the [OOUI demos][1] for an example.\n *\n * [1]: https://doc.wikimedia.org/oojs-ui/master/demos/#SearchInputWidget-type-search\n *\n * @class\n * @extends OO.ui.Widget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string|jQuery} [placeholder] Placeholder text for query input\n * @cfg {string} [value] Initial query value\n */\nOO.ui.SearchWidget = function OoUiSearchWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.SearchWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.query = new OO.ui.TextInputWidget( {\n\t\ticon: 'search',\n\t\tplaceholder: config.placeholder,\n\t\tvalue: config.value\n\t} );\n\tthis.results = new OO.ui.SelectWidget();\n\tthis.$query = $( '<div>' );\n\tthis.$results = $( '<div>' );\n\n\t// Events\n\tthis.query.connect( this, {\n\t\tchange: 'onQueryChange',\n\t\tenter: 'onQueryEnter'\n\t} );\n\tthis.query.$input.on( 'keydown', this.onQueryKeydown.bind( this ) );\n\n\t// Initialization\n\tthis.$query\n\t\t.addClass( 'oo-ui-searchWidget-query' )\n\t\t.append( this.query.$element );\n\tthis.$results\n\t\t.addClass( 'oo-ui-searchWidget-results' )\n\t\t.append( this.results.$element );\n\tthis.$element\n\t\t.addClass( 'oo-ui-searchWidget' )\n\t\t.append( this.$results, this.$query );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.SearchWidget, OO.ui.Widget );\n\n/* Methods */\n\n/**\n * Handle query key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.SearchWidget.prototype.onQueryKeydown = function ( e ) {\n\tvar highlightedItem, nextItem,\n\t\tdir = e.which === OO.ui.Keys.DOWN ? 1 : ( e.which === OO.ui.Keys.UP ? -1 : 0 );\n\n\tif ( dir ) {\n\t\thighlightedItem = this.results.findHighlightedItem();\n\t\tif ( !highlightedItem ) {\n\t\t\thighlightedItem = this.results.findSelectedItem();\n\t\t}\n\t\tnextItem = this.results.findRelativeSelectableItem( highlightedItem, dir );\n\t\tthis.results.highlightItem( nextItem );\n\t\tnextItem.scrollElementIntoView();\n\t}\n};\n\n/**\n * Handle select widget select events.\n *\n * Clears existing results. Subclasses should repopulate items according to new query.\n *\n * @private\n * @param {string} value New value\n */\nOO.ui.SearchWidget.prototype.onQueryChange = function () {\n\t// Reset\n\tthis.results.clearItems();\n};\n\n/**\n * Handle select widget enter key events.\n *\n * Chooses highlighted item.\n *\n * @private\n * @param {string} value New value\n */\nOO.ui.SearchWidget.prototype.onQueryEnter = function () {\n\tvar highlightedItem = this.results.findHighlightedItem();\n\tif ( highlightedItem ) {\n\t\tthis.results.chooseItem( highlightedItem );\n\t}\n};\n\n/**\n * Get the query input.\n *\n * @return {OO.ui.TextInputWidget} Query input\n */\nOO.ui.SearchWidget.prototype.getQuery = function () {\n\treturn this.query;\n};\n\n/**\n * Get the search results menu.\n *\n * @return {OO.ui.SelectWidget} Menu of search results\n */\nOO.ui.SearchWidget.prototype.getResults = function () {\n\treturn this.results;\n};\n","}( OO ) );\n"]}
\ No newline at end of file
index d9b6211..ebf0e1b 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:07Z
+ * Date: 2019-04-04T19:10:48Z
  */
 ( function ( OO ) {
 
@@ -36,10 +36,12 @@ OO.ui.WikimediaUITheme.prototype.getElementClasses = function ( element ) {
        // Parent method
        var variant, isFramed, isActive, isToolOrGroup,
                variants = {
-                       warning: false,
                        invert: false,
                        progressive: false,
-                       destructive: false
+                       destructive: false,
+                       error: false,
+                       warning: false,
+                       success: false
                },
                // Parent method
                classes = OO.ui.WikimediaUITheme.parent.prototype.getElementClasses.call( this, element );
@@ -54,22 +56,24 @@ OO.ui.WikimediaUITheme.prototype.getElementClasses = function ( element ) {
                isFramed = element.supports( [ 'isFramed' ] ) && element.isFramed();
                isActive = element.supports( [ 'isActive' ] ) && element.isActive();
                isToolOrGroup =
-                       // Check if the class exists, as classes that are not in the 'core' module may not be loaded
+                       // Check if the class exists, as classes that are not in the 'core' module may
+                       // not be loaded.
                        ( OO.ui.Tool && element instanceof OO.ui.Tool ) ||
                        ( OO.ui.ToolGroup && element instanceof OO.ui.ToolGroup );
                if (
-                       // Button with a dark background
+                       // Button with a dark background.
                        isFramed && ( isActive || element.isDisabled() || element.hasFlag( 'primary' ) ) ||
-                       // Toolbar with a dark background
+                       // Toolbar with a dark background.
                        isToolOrGroup && element.hasFlag( 'primary' )
                ) {
                        // … use white icon / indicator, regardless of other flags
                        variants.invert = true;
-               } else if ( !isFramed && element.isDisabled() ) {
-                       // Frameless disabled button, always use black icon / indicator regardless of other flags
+               } else if ( !isFramed && element.isDisabled() && !element.hasFlag( 'invert' ) ) {
+                       // Frameless disabled button, always use black icon / indicator regardless of
+                       // other flags.
                        variants.invert = false;
                } else if ( !element.isDisabled() ) {
-                       // Any other kind of button, use the right colored icon / indicator if available
+                       // Any other kind of button, use the right colored icon / indicator if available.
                        variants.progressive = element.hasFlag( 'progressive' ) ||
                                // Active tools/toolgroups
                                ( isToolOrGroup && isActive ) ||
@@ -77,14 +81,21 @@ OO.ui.WikimediaUITheme.prototype.getElementClasses = function ( element ) {
                                (
                                        (
                                                element instanceof OO.ui.MenuOptionWidget ||
-                                               // Check if the class exists, as classes that are not in the 'core' module may not be loaded
-                                               ( OO.ui.OutlineOptionWidget && element instanceof OO.ui.OutlineOptionWidget )
+                                               // Check if the class exists, as classes that are not in the 'core' module
+                                               // may not be loaded.
+                                               (
+                                                       OO.ui.OutlineOptionWidget &&
+                                                       element instanceof OO.ui.OutlineOptionWidget
+                                               )
                                        ) &&
                                        ( element.isPressed() || element.isSelected() )
                                );
 
                        variants.destructive = element.hasFlag( 'destructive' );
+                       variants.invert = element.hasFlag( 'invert' );
+                       variants.error = element.hasFlag( 'error' );
                        variants.warning = element.hasFlag( 'warning' );
+                       variants.success = element.hasFlag( 'success' );
                }
        }
 
index 861897a..13f570e 100644 (file)
@@ -1 +1 @@
-{"version":3,"sources":["../src/intro.js.txt","../src/themes/wikimediaui/WikimediaUITheme.js","../src/outro.js.txt"],"names":[],"mappings":";;;;;;;;;;AAAA,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnB;AACA,CAAC,GAAG,CAAC,MAAM,EAAE;;ACFb,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK;AACvB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AACvD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC;AAChD,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AACd,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC;AAClB,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC;AACjB,GAAG,WAAW,CAAC,CAAC,KAAK,CAAC;AACtB,GAAG,WAAW,CAAC,CAAC,KAAK;AACrB,EAAE,EAAE;AACJ,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM;AAClB,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE;AAC5F;AACA,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;AACxC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC;AACpE,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB;AAChC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG;AACtE,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG;AACtE,EAAE,aAAa,CAAC,CAAC;AACjB,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM;AAC/F,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACrD,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AAC7D,EAAE,EAAE,CAAC,CAAC;AACN,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU;AACnC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACtF,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU;AACpC,GAAG,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAChD,EAAE,CAAC,CAAC,CAAC;AACL,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AAC7D,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AAC5F,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3B,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACvC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS;AACnF,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7D,IAAI,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU;AAC9B,IAAI,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;AACpC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;AACtD,IAAI,CAAC;AACL,KAAK,CAAC;AACN,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE;AAClD,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM;AAClG,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC;AACnF,KAAK,CAAC,CAAC,EAAE;AACT,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;AACpD,IAAI,EAAE;AACN;AACA,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AAC3D,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AACnD,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;AACjF,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,OAAO,CAAC;AAChB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC,MAAM,CAAC,GAAG,CAAC;AACZ,EAAE;AACF;AACA,EAAE,CAAC,aAAa,CAAC,EAAE;AACnB;AACA,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,GAAG;;AC5F3C,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE","file":"oojs-ui-wikimediaui.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * @class\n * @extends OO.ui.Theme\n *\n * @constructor\n */\nOO.ui.WikimediaUITheme = function OoUiWikimediaUITheme() {\n\t// Parent constructor\n\tOO.ui.WikimediaUITheme.parent.call( this );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.WikimediaUITheme, OO.ui.Theme );\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.WikimediaUITheme.prototype.getElementClasses = function ( element ) {\n\t// Parent method\n\tvar variant, isFramed, isActive, isToolOrGroup,\n\t\tvariants = {\n\t\t\twarning: false,\n\t\t\tinvert: false,\n\t\t\tprogressive: false,\n\t\t\tdestructive: false\n\t\t},\n\t\t// Parent method\n\t\tclasses = OO.ui.WikimediaUITheme.parent.prototype.getElementClasses.call( this, element );\n\n\tif (\n\t\telement instanceof OO.ui.IconWidget &&\n\t\telement.$element.hasClass( 'oo-ui-checkboxInputWidget-checkIcon' )\n\t) {\n\t\t// Icon on CheckboxInputWidget\n\t\tvariants.invert = true;\n\t} else if ( element.supports( [ 'hasFlag' ] ) ) {\n\t\tisFramed = element.supports( [ 'isFramed' ] ) && element.isFramed();\n\t\tisActive = element.supports( [ 'isActive' ] ) && element.isActive();\n\t\tisToolOrGroup =\n\t\t\t// Check if the class exists, as classes that are not in the 'core' module may not be loaded\n\t\t\t( OO.ui.Tool && element instanceof OO.ui.Tool ) ||\n\t\t\t( OO.ui.ToolGroup && element instanceof OO.ui.ToolGroup );\n\t\tif (\n\t\t\t// Button with a dark background\n\t\t\tisFramed && ( isActive || element.isDisabled() || element.hasFlag( 'primary' ) ) ||\n\t\t\t// Toolbar with a dark background\n\t\t\tisToolOrGroup && element.hasFlag( 'primary' )\n\t\t) {\n\t\t\t// … use white icon / indicator, regardless of other flags\n\t\t\tvariants.invert = true;\n\t\t} else if ( !isFramed && element.isDisabled() ) {\n\t\t\t// Frameless disabled button, always use black icon / indicator regardless of other flags\n\t\t\tvariants.invert = false;\n\t\t} else if ( !element.isDisabled() ) {\n\t\t\t// Any other kind of button, use the right colored icon / indicator if available\n\t\t\tvariants.progressive = element.hasFlag( 'progressive' ) ||\n\t\t\t\t// Active tools/toolgroups\n\t\t\t\t( isToolOrGroup && isActive ) ||\n\t\t\t\t// Pressed or selected outline/menu option widgets\n\t\t\t\t(\n\t\t\t\t\t(\n\t\t\t\t\t\telement instanceof OO.ui.MenuOptionWidget ||\n\t\t\t\t\t\t// Check if the class exists, as classes that are not in the 'core' module may not be loaded\n\t\t\t\t\t\t( OO.ui.OutlineOptionWidget && element instanceof OO.ui.OutlineOptionWidget )\n\t\t\t\t\t) &&\n\t\t\t\t\t( element.isPressed() || element.isSelected() )\n\t\t\t\t);\n\n\t\t\tvariants.destructive = element.hasFlag( 'destructive' );\n\t\t\tvariants.warning = element.hasFlag( 'warning' );\n\t\t}\n\t}\n\n\tfor ( variant in variants ) {\n\t\tclasses[ variants[ variant ] ? 'on' : 'off' ].push( 'oo-ui-image-' + variant );\n\t}\n\n\treturn classes;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.WikimediaUITheme.prototype.getDialogTransitionDuration = function () {\n\treturn 250;\n};\n\n/* Instantiation */\n\nOO.ui.theme = new OO.ui.WikimediaUITheme();\n","}( OO ) );\n"]}
\ No newline at end of file
+{"version":3,"sources":["../src/intro.js.txt","../src/themes/wikimediaui/WikimediaUITheme.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-wikimediaui.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * @class\n * @extends OO.ui.Theme\n *\n * @constructor\n */\nOO.ui.WikimediaUITheme = function OoUiWikimediaUITheme() {\n\t// Parent constructor\n\tOO.ui.WikimediaUITheme.parent.call( this );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.WikimediaUITheme, OO.ui.Theme );\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.WikimediaUITheme.prototype.getElementClasses = function ( element ) {\n\t// Parent method\n\tvar variant, isFramed, isActive, isToolOrGroup,\n\t\tvariants = {\n\t\t\tinvert: false,\n\t\t\tprogressive: false,\n\t\t\tdestructive: false,\n\t\t\terror: false,\n\t\t\twarning: false,\n\t\t\tsuccess: false\n\t\t},\n\t\t// Parent method\n\t\tclasses = OO.ui.WikimediaUITheme.parent.prototype.getElementClasses.call( this, element );\n\n\tif (\n\t\telement instanceof OO.ui.IconWidget &&\n\t\telement.$element.hasClass( 'oo-ui-checkboxInputWidget-checkIcon' )\n\t) {\n\t\t// Icon on CheckboxInputWidget\n\t\tvariants.invert = true;\n\t} else if ( element.supports( [ 'hasFlag' ] ) ) {\n\t\tisFramed = element.supports( [ 'isFramed' ] ) && element.isFramed();\n\t\tisActive = element.supports( [ 'isActive' ] ) && element.isActive();\n\t\tisToolOrGroup =\n\t\t\t// Check if the class exists, as classes that are not in the 'core' module may\n\t\t\t// not be loaded.\n\t\t\t( OO.ui.Tool && element instanceof OO.ui.Tool ) ||\n\t\t\t( OO.ui.ToolGroup && element instanceof OO.ui.ToolGroup );\n\t\tif (\n\t\t\t// Button with a dark background.\n\t\t\tisFramed && ( isActive || element.isDisabled() || element.hasFlag( 'primary' ) ) ||\n\t\t\t// Toolbar with a dark background.\n\t\t\tisToolOrGroup && element.hasFlag( 'primary' )\n\t\t) {\n\t\t\t// … use white icon / indicator, regardless of other flags\n\t\t\tvariants.invert = true;\n\t\t} else if ( !isFramed && element.isDisabled() && !element.hasFlag( 'invert' ) ) {\n\t\t\t// Frameless disabled button, always use black icon / indicator regardless of\n\t\t\t// other flags.\n\t\t\tvariants.invert = false;\n\t\t} else if ( !element.isDisabled() ) {\n\t\t\t// Any other kind of button, use the right colored icon / indicator if available.\n\t\t\tvariants.progressive = element.hasFlag( 'progressive' ) ||\n\t\t\t\t// Active tools/toolgroups\n\t\t\t\t( isToolOrGroup && isActive ) ||\n\t\t\t\t// Pressed or selected outline/menu option widgets\n\t\t\t\t(\n\t\t\t\t\t(\n\t\t\t\t\t\telement instanceof OO.ui.MenuOptionWidget ||\n\t\t\t\t\t\t// Check if the class exists, as classes that are not in the 'core' module\n\t\t\t\t\t\t// may not be loaded.\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tOO.ui.OutlineOptionWidget &&\n\t\t\t\t\t\t\telement instanceof OO.ui.OutlineOptionWidget\n\t\t\t\t\t\t)\n\t\t\t\t\t) &&\n\t\t\t\t\t( element.isPressed() || element.isSelected() )\n\t\t\t\t);\n\n\t\t\tvariants.destructive = element.hasFlag( 'destructive' );\n\t\t\tvariants.invert = element.hasFlag( 'invert' );\n\t\t\tvariants.error = element.hasFlag( 'error' );\n\t\t\tvariants.warning = element.hasFlag( 'warning' );\n\t\t\tvariants.success = element.hasFlag( 'success' );\n\t\t}\n\t}\n\n\tfor ( variant in variants ) {\n\t\tclasses[ variants[ variant ] ? 'on' : 'off' ].push( 'oo-ui-image-' + variant );\n\t}\n\n\treturn classes;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.WikimediaUITheme.prototype.getDialogTransitionDuration = function () {\n\treturn 250;\n};\n\n/* Instantiation */\n\nOO.ui.theme = new OO.ui.WikimediaUITheme();\n","}( OO ) );\n"]}
\ No newline at end of file
index fcd8e4d..39744b0 100644 (file)
@@ -1,16 +1,13 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
-.oo-ui-actionWidget.oo-ui-pendingElement-pending {
-  background-image: /* @embed */ url(themes/wikimediaui/images/textures/pending.gif);
-}
 
 .oo-ui-window {
   background-color: transparent;
index 36e2f36..bb1a5b1 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:15Z
+ * Date: 2019-04-04T19:10:54Z
  */
 
 .oo-ui-window {
index d099e32..9f1caab 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.30.3
+ * OOUI v0.31.3
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-02-21T10:57:07Z
+ * Date: 2019-04-04T19:10:48Z
  */
 ( function ( OO ) {
 
@@ -85,8 +85,8 @@ OO.ui.ActionWidget.prototype.getAction = function () {
  * Get the symbolic name of the mode or modes for which the action is configured to be available.
  *
  * The current mode is set with the action set's {@link OO.ui.ActionSet#setMode setMode} method.
- * Only actions that are configured to be available in the current mode will be visible. All other actions
- * are hidden.
+ * Only actions that are configured to be available in the current mode will be visible.
+ * All other actions are hidden.
  *
  * @return {string[]}
  */
@@ -96,13 +96,16 @@ OO.ui.ActionWidget.prototype.getModes = function () {
 
 /* eslint-disable no-unused-vars */
 /**
- * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that comprise them.
+ * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that
+ * comprise them.
  * Actions can be made available for specific contexts (modes) and circumstances
  * (abilities). Action sets are primarily used with {@link OO.ui.Dialog Dialogs}.
  *
  * ActionSets contain two types of actions:
  *
- * - Special: Special actions are the first visible actions with special flags, such as 'safe' and 'primary', the default special flags. Additional special flags can be configured in subclasses with the static #specialFlags property.
+ * - Special: Special actions are the first visible actions with special flags, such as 'safe' and
+ *  'primary', the default special flags. Additional special flags can be configured in subclasses
+ *  with the static #specialFlags property.
  * - Other: Other actions include all non-special visible actions.
  *
  * See the [OOUI documentation on MediaWiki][1] for more information.
@@ -117,7 +120,10 @@ OO.ui.ActionWidget.prototype.getModes = function () {
  *     MyProcessDialog.static.name = 'myProcessDialog';
  *     // An action set that uses modes ('edit' and 'help' mode, in this example).
  *     MyProcessDialog.static.actions = [
- *         { action: 'continue', modes: 'edit', label: 'Continue', flags: [ 'primary', 'progressive' ] },
+ *         { action: 'continue', modes: 'edit', label: 'Continue',
+ *           flags: [
+ *               'primary', 'progressive'
+ *         ] },
  *         { action: 'help', modes: 'edit', label: 'Help' },
  *         { modes: 'edit', label: 'Cancel', flags: 'safe' },
  *         { action: 'back', modes: 'help', label: 'Back', flags: 'safe' }
@@ -126,9 +132,13 @@ OO.ui.ActionWidget.prototype.getModes = function () {
  *     MyProcessDialog.prototype.initialize = function () {
  *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );
  *         this.panel1 = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.panel1.$element.append( '<p>This dialog uses an action set (continue, help, cancel, back) configured with modes. This is edit mode. Click \'help\' to see help mode.</p>' );
+ *         this.panel1.$element.append( '<p>This dialog uses an action set (continue, help, ' +
+ *             'cancel, back) configured with modes. This is edit mode. Click \'help\' to see ' +
+ *             'help mode.</p>' );
  *         this.panel2 = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.panel2.$element.append( '<p>This is help mode. Only the \'back\' action widget is configured to be visible here. Click \'back\' to return to \'edit\' mode.</p>' );
+ *         this.panel2.$element.append( '<p>This is help mode. Only the \'back\' action widget ' +
+ *              'is configured to be visible here. Click \'back\' to return to \'edit\' mode.' +
+ *              '</p>' );
  *         this.stackLayout = new OO.ui.StackLayout( {
  *             items: [ this.panel1, this.panel2 ]
  *         } );
@@ -249,7 +259,8 @@ OO.ui.ActionSet.static.specialFlags = [ 'safe', 'primary' ];
  * @event change
  *
  * A 'change' event is emitted when actions are {@link #method-add added}, {@link #clear cleared},
- * or {@link #method-remove removed} from the action set or when the {@link #setMode mode} is changed.
+ * or {@link #method-remove removed} from the action set or when the {@link #setMode mode}
+ * is changed.
  *
  */
 
@@ -352,7 +363,8 @@ OO.ui.ActionSet.prototype.get = function ( filters ) {
 /**
  * Get 'special' actions.
  *
- * Special actions are the first visible action widgets with special flags, such as 'safe' and 'primary'.
+ * Special actions are the first visible action widgets with special flags, such as 'safe' and
+ * 'primary'.
  * Special flags can be configured in subclasses by changing the static #specialFlags property.
  *
  * @return {OO.ui.ActionWidget[]|null} 'Special' action widgets.
@@ -601,16 +613,17 @@ OO.ui.ActionSet.prototype.organize = function () {
 };
 
 /**
- * Errors contain a required message (either a string or jQuery selection) that is used to describe what went wrong
- * in a {@link OO.ui.Process process}. The error's #recoverable and #warning configurations are used to customize the
- * appearance and functionality of the error interface.
+ * Errors contain a required message (either a string or jQuery selection) that is used to describe
+ * what went wrong in a {@link OO.ui.Process process}. The error's #recoverable and #warning
+ * configurations are used to customize the appearance and functionality of the error interface.
  *
- * The basic error interface contains a formatted error message as well as two buttons: 'Dismiss' and 'Try again' (i.e., the error
- * is 'recoverable' by default). If the error is not recoverable, the 'Try again' button will not be rendered and the widget
- * that initiated the failed process will be disabled.
+ * The basic error interface contains a formatted error message as well as two buttons: 'Dismiss'
+ * and 'Try again' (i.e., the error is 'recoverable' by default). If the error is not recoverable,
+ * the 'Try again' button will not be rendered and the widget that initiated the failed process will
+ * be disabled.
  *
- * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button, which will try the
- * process again.
+ * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button,
+ * which will try the process again.
  *
  * For an example of error interfaces, please see the [OOUI documentation on MediaWiki][1].
  *
@@ -625,8 +638,8 @@ OO.ui.ActionSet.prototype.organize = function () {
  *  By default, errors are recoverable, and users can try the process again.
  * @cfg {boolean} [warning=false] Error is a warning.
  *  If the error is a warning, the error interface will include a
- *  'Dismiss' and a 'Continue' button. It is the responsibility of the developer to ensure that the warning
- *  is not triggered a second time if the user chooses to continue.
+ *  'Dismiss' and a 'Continue' button. It is the responsibility of the developer to ensure that the
+ *  warning is not triggered a second time if the user chooses to continue.
  */
 OO.ui.Error = function OoUiError( message, config ) {
        // Allow passing positional parameters inside the config object
@@ -693,27 +706,28 @@ OO.ui.Error.prototype.getMessageText = function () {
 };
 
 /**
- * A Process is a list of steps that are called in sequence. The step can be a number, a jQuery promise,
- * or a function:
+ * A Process is a list of steps that are called in sequence. The step can be a number, a
+ * jQuery promise, or a function:
  *
  * - **number**: the process will wait for the specified number of milliseconds before proceeding.
- * - **promise**: the process will continue to the next step when the promise is successfully resolved
- *  or stop if the promise is rejected.
- * - **function**: the process will execute the function. The process will stop if the function returns
- *  either a boolean `false` or a promise that is rejected; if the function returns a number, the process
- *  will wait for that number of milliseconds before proceeding.
+ * - **promise**: the process will continue to the next step when the promise is successfully
+ *  resolved or stop if the promise is rejected.
+ * - **function**: the process will execute the function. The process will stop if the function
+ *  returns either a boolean `false` or a promise that is rejected; if the function returns a
+ *  number, the process will wait for that number of milliseconds before proceeding.
  *
  * If the process fails, an {@link OO.ui.Error error} is generated. Depending on how the error is
- * configured, users can dismiss the error and try the process again, or not. If a process is stopped,
- * its remaining steps will not be performed.
+ * configured, users can dismiss the error and try the process again, or not. If a process is
+ * stopped, its remaining steps will not be performed.
  *
  * @class
  *
  * @constructor
- * @param {number|jQuery.Promise|Function} step Number of milliseconds to wait before proceeding, promise
- *  that must be resolved before proceeding, or a function to execute. See #createStep for more information. see #createStep for more information
- * @param {Object} [context=null] Execution context of the function. The context is ignored if the step is
- *  a number or promise.
+ * @param {number|jQuery.Promise|Function} step Number of milliseconds to wait before proceeding,
+ *  promise that must be resolved before proceeding, or a function to execute. See #createStep for
+ *  more information. See #createStep for more information.
+ * @param {Object} [context=null] Execution context of the function. The context is ignored if the
+ *  step is a number or promise.
  */
 OO.ui.Process = function ( step, context ) {
        // Properties
@@ -735,8 +749,8 @@ OO.initClass( OO.ui.Process );
  * Start the process.
  *
  * @return {jQuery.Promise} Promise that is resolved when all steps have successfully completed.
- *  If any of the steps return a promise that is rejected or a boolean false, this promise is rejected
- *  and any remaining steps are not performed.
+ *  If any of the steps return a promise that is rejected or a boolean false, this promise is
+ *  rejected and any remaining steps are not performed.
  */
 OO.ui.Process.prototype.execute = function () {
        var i, len, promise;
@@ -958,9 +972,10 @@ OO.ui.WindowInstance.prototype.isClosed = function () {
 };
 
 /**
- * Window managers are used to open and close {@link OO.ui.Window windows} and control their presentation.
- * Managed windows are mutually exclusive. If a new window is opened while a current window is opening
- * or is opened, the current window will be closed and any ongoing {@link OO.ui.Process process} will be cancelled. Windows
+ * Window managers are used to open and close {@link OO.ui.Window windows} and control their
+ * presentation. Managed windows are mutually exclusive. If a new window is opened while a current
+ * window is opening or is opened, the current window will be closed and any on-going
+ * {@link OO.ui.Process process} will be cancelled. Windows
  * themselves are persistent and—rather than being torn down when closed—can be repopulated with the
  * pertinent data and reused.
  *
@@ -971,11 +986,13 @@ OO.ui.WindowInstance.prototype.isClosed = function () {
  * {@link OO.ui.Window#open open} method is used, and the window manager begins to open the window.
  *
  * - an `opening` event is emitted with an `opening` promise
- * - the #getSetupDelay method is called and the returned value is used to time a pause in execution before the
- *   window’s {@link OO.ui.Window#method-setup setup} method is called which executes OO.ui.Window#getSetupProcess.
+ * - the #getSetupDelay method is called and the returned value is used to time a pause in execution
+ *   before the window’s {@link OO.ui.Window#method-setup setup} method is called which executes
+ *   OO.ui.Window#getSetupProcess.
  * - a `setup` progress notification is emitted from the `opening` promise
- * - the #getReadyDelay method is called the returned value is used to time a pause in execution before the
- *   window’s {@link OO.ui.Window#method-ready ready} method is called which executes OO.ui.Window#getReadyProcess.
+ * - the #getReadyDelay method is called the returned value is used to time a pause in execution
+ *   before the window’s {@link OO.ui.Window#method-ready ready} method is called which executes
+ *   OO.ui.Window#getReadyProcess.
  * - a `ready` progress notification is emitted from the `opening` promise
  * - the `opening` promise is resolved with an `opened` promise
  *
@@ -986,13 +1003,13 @@ OO.ui.WindowInstance.prototype.isClosed = function () {
  * to close the window.
  *
  * - the `opened` promise is resolved with `closing` promise and a `closing` event is emitted
- * - the #getHoldDelay method is called and the returned value is used to time a pause in execution before
- *   the window's {@link OO.ui.Window#getHoldProcess getHoldProcess} method is called on the
+ * - the #getHoldDelay method is called and the returned value is used to time a pause in execution
+ *   before the window's {@link OO.ui.Window#getHoldProcess getHoldProcess} method is called on the
  *   window and its result executed
  * - a `hold` progress notification is emitted from the `closing` promise
- * - the #getTeardownDelay() method is called and the returned value is used to time a pause in execution before
- *   the window's {@link OO.ui.Window#getTeardownProcess getTeardownProcess} method is called on the
- *   window and its result executed
+ * - the #getTeardownDelay() method is called and the returned value is used to time a pause in
+ *   execution before the window's {@link OO.ui.Window#getTeardownProcess getTeardownProcess} method
+ *   is called on the window and its result executed
  * - a `teardown` progress notification is emitted from the `closing` promise
  * - the `closing` promise is resolved. The window is now closed
  *
@@ -1059,9 +1076,10 @@ OO.mixinClass( OO.ui.WindowManager, OO.EventEmitter );
  *
  * @event opening
  * @param {OO.ui.Window} win Window that's being opened
- * @param {jQuery.Promise} opened A promise resolved with a value when the window is opened successfully.
- *  This promise also emits `setup` and `ready` notifications. When this promise is resolved, the first
- *  argument of the value is an 'closed' promise, the second argument is the opening data.
+ * @param {jQuery.Promise} opened A promise resolved with a value when the window is opened
+ *  successfully. This promise also emits `setup` and `ready` notifications. When this promise is
+ *  resolved, the first argument of the value is an 'closed' promise, the second argument is the
+ *  opening data.
  * @param {Object} data Window opening data
  */
 
@@ -1070,9 +1088,9 @@ OO.mixinClass( OO.ui.WindowManager, OO.EventEmitter );
  *
  * @event closing
  * @param {OO.ui.Window} win Window that's being closed
- * @param {jQuery.Promise} closed A promise resolved with a value when the window is closed successfully.
- *  This promise also emits `hold` and `teardown` notifications. When this promise is resolved, the first
- *  argument of its value is the closing data.
+ * @param {jQuery.Promise} closed A promise resolved with a value when the window is closed
+ *  successfully. This promise also emits `hold` and `teardown` notifications. When this promise is
+ *  resolved, the first argument of its value is the closing data.
  * @param {Object} data Window closing data
  */
 
@@ -1149,7 +1167,7 @@ OO.ui.WindowManager.prototype.afterWindowResize = function () {
 
                // Restore focus to the original element if it has changed.
                // When a layout change is made on resize inputs lose focus
-               // on Android (Chrome and Firefox). See T162127.
+               // on Android (Chrome and Firefox), see T162127.
                if ( currentFocusedElement !== document.activeElement ) {
                        currentFocusedElement.focus();
                }
@@ -1219,7 +1237,8 @@ OO.ui.WindowManager.prototype.getSetupDelay = function () {
 };
 
 /**
- * Get the number of milliseconds to wait after setup has finished before executing the ‘ready’ process.
+ * Get the number of milliseconds to wait after setup has finished before executing the ‘ready’
+ * process.
  *
  * @param {OO.ui.Window} win Window being opened
  * @param {Object} [data] Window opening data
@@ -1230,7 +1249,8 @@ OO.ui.WindowManager.prototype.getReadyDelay = function () {
 };
 
 /**
- * Get the number of milliseconds to wait after closing has begun before executing the 'hold' process.
+ * Get the number of milliseconds to wait after closing has begun before executing the 'hold'
+ * process.
  *
  * @param {OO.ui.Window} win Window being closed
  * @param {Object} [data] Window closing data
@@ -1255,9 +1275,9 @@ OO.ui.WindowManager.prototype.getTeardownDelay = function () {
 /**
  * Get a window by its symbolic name.
  *
- * If the window is not yet instantiated and its symbolic name is recognized by a factory, it will be
- * instantiated and added to the window manager automatically. Please see the [OOUI documentation on MediaWiki][3]
- * for more information about using factories.
+ * If the window is not yet instantiated and its symbolic name is recognized by a factory, it will
+ * be instantiated and added to the window manager automatically. Please see the [OOUI documentation
+ * on MediaWiki][3] for more information about using factories.
  * [3]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers
  *
  * @param {string} name Symbolic name of the window
@@ -1307,12 +1327,12 @@ OO.ui.WindowManager.prototype.getCurrentWindow = function () {
  *
  * @param {OO.ui.Window|string} win Window object or symbolic name of window to open
  * @param {Object} [data] Window opening data
- * @param {jQuery|null} [data.$returnFocusTo] Element to which the window will return focus when closed.
- *  Defaults the current activeElement. If set to null, focus isn't changed on close.
+ * @param {jQuery|null} [data.$returnFocusTo] Element to which the window will return focus when
+ *  closed. Defaults the current activeElement. If set to null, focus isn't changed on close.
  * @return {OO.ui.WindowInstance} A lifecycle object representing this particular
- *  opening of the window. For backwards-compatibility, then object is also a Thenable that is resolved
- *  when the window is done opening, with nested promise for when closing starts. This behaviour
- *  is deprecated and is not compatible with jQuery 3. See T163510.
+ *  opening of the window. For backwards-compatibility, then object is also a Thenable that is
+ *  resolved when the window is done opening, with nested promise for when closing starts. This
+ *  behaviour is deprecated and is not compatible with jQuery 3, see T163510.
  * @fires opening
  */
 OO.ui.WindowManager.prototype.openWindow = function ( win, data, lifecycle, compatOpening ) {
@@ -1376,7 +1396,9 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data, lifecycle, comp
                        manager.toggleGlobalEvents( true );
                        manager.toggleAriaIsolation( true );
                }
-               manager.$returnFocusTo = data.$returnFocusTo !== undefined ? data.$returnFocusTo : $( document.activeElement );
+               manager.$returnFocusTo = data.$returnFocusTo !== undefined ?
+                       data.$returnFocusTo :
+                       $( document.activeElement );
                manager.currentWindow = win;
                manager.lifecycle = lifecycle;
                manager.preparingToOpen = null;
@@ -1414,8 +1436,8 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data, lifecycle, comp
  * @param {OO.ui.Window|string} win Window object or symbolic name of window to close
  * @param {Object} [data] Window closing data
  * @return {OO.ui.WindowInstance} A lifecycle object representing this particular
- *  opening of the window. For backwards-compatibility, the object is also a Thenable that is resolved
- *  when the window is done closing, see T163510.
+ *  opening of the window. For backwards-compatibility, the object is also a Thenable that is
+ *  resolved when the window is done closing, see T163510.
  * @fires closing
  */
 OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
@@ -1516,7 +1538,7 @@ OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
  *
  * This function can be called in two manners:
  *
- * 1. `.addWindows( [ windowA, windowB, ... ] )` (where `windowA`, `windowB` are OO.ui.Window objects)
+ * 1. `.addWindows( [ winA, winB, ... ] )` (where `winA`, `winB` are OO.ui.Window objects)
  *
  *    This syntax registers windows under the symbolic names defined in their `.static.name`
  *    properties. For example, if `windowA.constructor.static.name` is `'nameA'`, calling
@@ -1525,7 +1547,7 @@ OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
  *
  *    This is the recommended way, as it allows for an easier switch to using a window factory.
  *
- * 2. `.addWindows( { nameA: windowA, nameB: windowB, ... } )`
+ * 2. `.addWindows( { nameA: winA, nameB: winB, ... } )`
  *
  *    This syntax registers windows under the explicitly given symbolic names. In this example,
  *    calling `.openWindow( 'nameA' )` afterwards will open the window `windowA`, regardless of what
@@ -1583,9 +1605,9 @@ OO.ui.WindowManager.prototype.addWindows = function ( windows ) {
 /**
  * Remove the specified windows from the windows manager.
  *
- * Windows will be closed before they are removed. If you wish to remove all windows, you may wish to use
- * the #clearWindows method instead. If you no longer need the window manager and want to ensure that it no
- * longer listens to events, use the #destroy method.
+ * Windows will be closed before they are removed. If you wish to remove all windows, you may wish
+ * to use the #clearWindows method instead. If you no longer need the window manager and want to
+ * ensure that it no longer listens to events, use the #destroy method.
  *
  * @param {string[]} names Symbolic names of windows to remove
  * @return {jQuery.Promise} Promise resolved when window is closed and removed
@@ -1616,9 +1638,9 @@ OO.ui.WindowManager.prototype.removeWindows = function ( names ) {
 /**
  * Remove all windows from the window manager.
  *
- * Windows will be closed before they are removed. Note that the window manager, though not in use, will still
- * listen to events. If the window manager will not be used again, you may wish to use the #destroy method instead.
- * To remove just a subset of windows, use the #removeWindows method.
+ * Windows will be closed before they are removed. Note that the window manager, though not in use,
+ * will still listen to events. If the window manager will not be used again, you may wish to use
+ * the #destroy method instead. To remove just a subset of windows, use the #removeWindows method.
  *
  * @return {jQuery.Promise} Promise resolved when all windows are closed and removed
  */
@@ -1747,9 +1769,9 @@ OO.ui.WindowManager.prototype.toggleAriaIsolation = function ( isolate ) {
 /**
  * Destroy the window manager.
  *
- * Destroying the window manager ensures that it will no longer listen to events. If you would like to
- * continue using the window manager, but wish to remove all windows from it, use the #clearWindows method
- * instead.
+ * Destroying the window manager ensures that it will no longer listen to events. If you would like
+ * to continue using the window manager, but wish to remove all windows from it, use the
+ * #clearWindows method instead.
  */
 OO.ui.WindowManager.prototype.destroy = function () {
        this.toggleGlobalEvents( false );
@@ -1761,16 +1783,16 @@ OO.ui.WindowManager.prototype.destroy = function () {
 /**
  * A window is a container for elements that are in a child frame. They are used with
  * a window manager (OO.ui.WindowManager), which is used to open and close the window and control
- * its presentation. The size of a window is specified using a symbolic name (e.g., ‘small’, ‘medium’,
- * ‘large’), which is interpreted by the window manager. If the requested size is not recognized,
- * the window manager will choose a sensible fallback.
+ * its presentation. The size of a window is specified using a symbolic name (e.g., ‘small’,
+ * ‘medium’, ‘large’), which is interpreted by the window manager. If the requested size is not
+ * recognized, the window manager will choose a sensible fallback.
  *
  * The lifecycle of a window has three primary stages (opening, opened, and closing) in which
  * different processes are executed:
  *
- * **opening**: The opening stage begins when the window manager's {@link OO.ui.WindowManager#openWindow
- * openWindow} or the window's {@link #open open} methods are used, and the window manager begins to open
- * the window.
+ * **opening**: The opening stage begins when the window manager's
+ * {@link OO.ui.WindowManager#openWindow openWindow} or the window's {@link #open open} methods are
+ * used, and the window manager begins to open the window.
  *
  * - {@link #getSetupProcess} method is called and its result executed
  * - {@link #getReadyProcess} method is called and its result executed
@@ -1779,15 +1801,17 @@ OO.ui.WindowManager.prototype.destroy = function () {
  *
  * **closing**: The closing stage begins when the window manager's
  * {@link OO.ui.WindowManager#closeWindow closeWindow}
- * or the window's {@link #close} methods are used, and the window manager begins to close the window.
+ * or the window's {@link #close} methods are used, and the window manager begins to close the
+ * window.
  *
  * - {@link #getHoldProcess} method is called and its result executed
  * - {@link #getTeardownProcess} method is called and its result executed. The window is now closed
  *
  * Each of the window's processes (setup, ready, hold, and teardown) can be extended in subclasses
- * by overriding the window's #getSetupProcess, #getReadyProcess, #getHoldProcess and #getTeardownProcess
- * methods. Note that each {@link OO.ui.Process process} is executed in series, so asynchronous
- * processing can complete. Always assume window processes are executed asynchronously.
+ * by overriding the window's #getSetupProcess, #getReadyProcess, #getHoldProcess and
+ * #getTeardownProcess methods. Note that each {@link OO.ui.Process process} is executed in series,
+ * so asynchronous processing can complete. Always assume window processes are executed
+ * asynchronously.
  *
  * For more information, please see the [OOUI documentation on MediaWiki] [1].
  *
@@ -1819,7 +1843,7 @@ OO.ui.Window = function OoUiWindow( config ) {
        this.$frame = $( '<div>' );
        /**
         * Overlay element to use for the `$overlay` configuration option of widgets that support it.
-        * Things put inside of it are overlaid on top of the window and are not bound to its dimensions.
+        * Things put inside it are overlaid on top of the window and are not bound to its dimensions.
         * See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
         *
         *     MyDialog.prototype.initialize = function () {
@@ -1828,7 +1852,7 @@ OO.ui.Window = function OoUiWindow( config ) {
         *         $overlay: this.$overlay,
         *         label: 'Popup button',
         *         popup: {
-        *           $content: $( '<p>Popup contents.</p><p>Popup contents.</p><p>Popup contents.</p>' ),
+        *           $content: $( '<p>Popup content.</p><p>More content.</p><p>Yet more content.</p>' ),
         *           padded: true
         *         }
         *       } );
@@ -1852,7 +1876,6 @@ OO.ui.Window = function OoUiWindow( config ) {
        this.$frame
                .addClass( 'oo-ui-window-frame' )
                .append( this.$focusTrapBefore, this.$content, this.$focusTrapAfter );
-
        this.$element
                .addClass( 'oo-ui-window' )
                .append( this.$frame, this.$overlay );
@@ -1921,8 +1944,8 @@ OO.ui.Window.prototype.isVisible = function () {
 /**
  * Check if the window is opening.
  *
- * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpening isOpening}
- * method.
+ * This method is a wrapper around the window manager's
+ * {@link OO.ui.WindowManager#isOpening isOpening} method.
  *
  * @return {boolean} Window is opening
  */
@@ -1933,7 +1956,8 @@ OO.ui.Window.prototype.isOpening = function () {
 /**
  * Check if the window is closing.
  *
- * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isClosing isClosing} method.
+ * This method is a wrapper around the window manager's
+ * {@link OO.ui.WindowManager#isClosing isClosing} method.
  *
  * @return {boolean} Window is closing
  */
@@ -1944,7 +1968,8 @@ OO.ui.Window.prototype.isClosing = function () {
 /**
  * Check if the window is opened.
  *
- * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpened isOpened} method.
+ * This method is a wrapper around the window manager's
+ * {@link OO.ui.WindowManager#isOpened isOpened} method.
  *
  * @return {boolean} Window is opened
  */
@@ -2417,7 +2442,9 @@ OO.ui.Window.prototype.hold = function ( data ) {
 
        return this.getHoldProcess( data ).execute().then( function () {
                // Get the focused element within the window's content
-               var $focus = win.$content.find( OO.ui.Element.static.getDocument( win.$content ).activeElement );
+               var $focus = win.$content.find(
+                       OO.ui.Element.static.getDocument( win.$content ).activeElement
+               );
 
                // Blur the focused element
                if ( $focus.length ) {
@@ -2433,8 +2460,8 @@ OO.ui.Window.prototype.hold = function ( data ) {
 /**
  * Teardown window.
  *
- * This is called by OO.ui.WindowManager during window closing (after the animation), and should not be called directly
- * by other systems.
+ * This is called by OO.ui.WindowManager during window closing (after the animation), and should not
+ * be called directly by other systems.
  *
  * @param {Object} [data] Window closing data
  * @return {jQuery.Promise} Promise resolved when window is torn down
@@ -2454,7 +2481,7 @@ OO.ui.Window.prototype.teardown = function ( data ) {
 /**
  * The Dialog class serves as the base class for the other types of dialogs.
  * Unless extended to include controls, the rendered dialog box is a simple window
- * that users can close by hitting the ‘Esc’ key. Dialog windows are used with OO.ui.WindowManager,
+ * that users can close by hitting the Escape key. Dialog windows are used with OO.ui.WindowManager,
  * which opens, closes, and controls the presentation of the window. See the
  * [OOUI documentation on MediaWiki] [1] for more information.
  *
@@ -2468,7 +2495,8 @@ OO.ui.Window.prototype.teardown = function ( data ) {
  *     MyDialog.prototype.initialize = function () {
  *         MyDialog.parent.prototype.initialize.call( this );
  *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.content.$element.append( '<p>A simple dialog window. Press \'Esc\' to close.</p>' );
+ *         this.content.$element.append( '<p>A simple dialog window. Press Escape key to ' +
+ *             'close.</p>' );
  *         this.$body.append( this.content.$element );
  *     };
  *     MyDialog.prototype.getBodyHeight = function () {
@@ -2544,9 +2572,10 @@ OO.ui.Dialog.static.name = '';
 /**
  * The dialog title.
  *
- * The title can be specified as a plaintext string, a {@link OO.ui.mixin.LabelElement Label} node, or a function
- * that will produce a Label node or string. The title can also be specified with data passed to the
- * constructor (see #getSetupProcess). In this case, the static value will be overridden.
+ * The title can be specified as a plaintext string, a {@link OO.ui.mixin.LabelElement Label} node,
+ * or a function that will produce a Label node or string. The title can also be specified with data
+ * passed to the constructor (see #getSetupProcess). In this case, the static value will be
+ * overridden.
  *
  * @abstract
  * @static
@@ -2558,8 +2587,8 @@ OO.ui.Dialog.static.title = '';
 /**
  * An array of configured {@link OO.ui.ActionWidget action widgets}.
  *
- * Actions can also be specified with data passed to the constructor (see #getSetupProcess). In this case, the static
- * value will be overridden.
+ * Actions can also be specified with data passed to the constructor (see #getSetupProcess). In this
+ * case, the static value will be overridden.
  *
  * [2]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets
  *
@@ -2570,7 +2599,7 @@ OO.ui.Dialog.static.title = '';
 OO.ui.Dialog.static.actions = [];
 
 /**
- * Close the dialog when the 'Esc' key is pressed.
+ * Close the dialog when the Escape key is pressed.
  *
  * @static
  * @abstract
@@ -2643,9 +2672,10 @@ OO.ui.Dialog.prototype.getActions = function () {
 /**
  * Get a process for taking action.
  *
- * When you override this method, you can create a new OO.ui.Process and return it, or add additional
- * accept steps to the process the parent method provides using the {@link OO.ui.Process#first 'first'}
- * and {@link OO.ui.Process#next 'next'} methods of OO.ui.Process.
+ * When you override this method, you can create a new OO.ui.Process and return it, or add
+ * additional accept steps to the process the parent method provides using the
+ * {@link OO.ui.Process#first 'first'} and {@link OO.ui.Process#next 'next'} methods of
+ * OO.ui.Process.
  *
  * @param {string} [action] Symbolic name of action
  * @return {OO.ui.Process} Action process
@@ -2805,10 +2835,10 @@ OO.ui.Dialog.prototype.executeAction = function ( action ) {
  *
  * There are two basic types of message dialogs, confirmation and alert:
  *
- * - **confirmation**: the dialog title describes what a progressive action will do and the message provides
- *  more details about the consequences.
- * - **alert**: the dialog title describes which event occurred and the message provides more information
- *  about why the event occurred.
+ * - **confirmation**: the dialog title describes what a progressive action will do and the message
+ *   provides more details about the consequences.
+ * - **alert**: the dialog title describes which event occurred and the message provides more
+ *   information about why the event occurred.
  *
  * The MessageDialog class specifies two actions: ‘accept’, the primary
  * action (e.g., ‘ok’) and ‘reject,’ the safe action (e.g., ‘cancel’). Both will close the window,
@@ -2944,7 +2974,7 @@ OO.ui.MessageDialog.prototype.getActionProcess = function ( action ) {
  * @param {jQuery|string|Function|null} [data.message] Description of the action's consequence
  * @param {string} [data.size] Symbolic name of the dialog size, see OO.ui.Window
  * @param {Object[]} [data.actions] List of OO.ui.ActionOptionWidget configuration options for each
- *   action item
+ *  action item
  */
 OO.ui.MessageDialog.prototype.getSetupProcess = function ( data ) {
        data = data || {};
@@ -3134,16 +3164,17 @@ OO.ui.MessageDialog.prototype.fitActions = function () {
 /**
  * ProcessDialog windows encapsulate a {@link OO.ui.Process process} and all of the code necessary
  * to complete it. If the process terminates with an error, a customizable {@link OO.ui.Error error
- * interface} alerts users to the trouble, permitting the user to dismiss the error and try again when
- * relevant. The ProcessDialog class is always extended and customized with the actions and content
- * required for each process.
+ * interface} alerts users to the trouble, permitting the user to dismiss the error and try again
+ * when relevant. The ProcessDialog class is always extended and customized with the actions and
+ * content required for each process.
  *
  * The process dialog box consists of a header that visually represents the ‘working’ state of long
  * processes with an animation. The header contains the dialog title as well as
  * two {@link OO.ui.ActionWidget action widgets}:  a ‘safe’ action on the left (e.g., ‘Cancel’) and
  * a ‘primary’ action on the right (e.g., ‘Done’).
  *
- * Like other windows, the process dialog is managed by a {@link OO.ui.WindowManager window manager}.
+ * Like other windows, the process dialog is managed by a
+ * {@link OO.ui.WindowManager window manager}.
  * Please see the [OOUI documentation on MediaWiki][1] for more information and examples.
  *
  *     @example
@@ -3163,7 +3194,9 @@ OO.ui.MessageDialog.prototype.fitActions = function () {
  *     MyProcessDialog.prototype.initialize = function () {
  *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );
  *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.content.$element.append( '<p>This is a process dialog window. The header contains the title and two buttons: \'Cancel\' (a safe action) on the left and \'Done\' (a primary action)  on the right.</p>' );
+ *         this.content.$element.append( '<p>This is a process dialog window. The header ' +
+ *             'contains the title and two buttons: \'Cancel\' (a safe action) on the left and ' +
+ *             '\'Done\' (a primary action)  on the right.</p>' );
  *         this.$body.append( this.content.$element );
  *     };
  *     MyProcessDialog.prototype.getActionProcess = function ( action ) {
@@ -3253,9 +3286,15 @@ OO.ui.ProcessDialog.prototype.initialize = function () {
        this.$errorsTitle = $( '<div>' );
 
        // Events
-       this.dismissButton.connect( this, { click: 'onDismissErrorButtonClick' } );
-       this.retryButton.connect( this, { click: 'onRetryButtonClick' } );
-       this.title.connect( this, { labelChange: 'fitLabel' } );
+       this.dismissButton.connect( this, {
+               click: 'onDismissErrorButtonClick'
+       } );
+       this.retryButton.connect( this, {
+               click: 'onRetryButtonClick'
+       } );
+       this.title.connect( this, {
+               labelChange: 'fitLabel'
+       } );
 
        // Initialization
        this.title.$element.addClass( 'oo-ui-processDialog-title' );
@@ -3296,7 +3335,10 @@ OO.ui.ProcessDialog.prototype.getActionWidgetConfig = function ( config ) {
        // Change back buttons to icon only on mobile
        if (
                isMobile &&
-               ( config.flags === 'back' || ( Array.isArray( config.flags ) && config.flags.indexOf( 'back' ) !== -1 ) )
+               (
+                       config.flags === 'back' ||
+                       ( Array.isArray( config.flags ) && config.flags.indexOf( 'back' ) !== -1 )
+               )
        ) {
                $.extend( config, {
                        icon: 'previous',
@@ -3352,8 +3394,9 @@ OO.ui.ProcessDialog.prototype.setDimensions = function () {
 
        this.fitLabel();
 
-       // If there are many actions, they might be shown on multiple lines. Their layout can change when
-       // resizing the dialog and when changing the actions. Adjust the height of the footer to fit them.
+       // If there are many actions, they might be shown on multiple lines. Their layout can change
+       // when resizing the dialog and when changing the actions. Adjust the height of the footer to
+       // fit them.
        dialog.$body.css( 'bottom', dialog.$foot.outerHeight( true ) );
        // Wait for CSS transition to finish and do it again :(
        setTimeout( function () {
@@ -3400,7 +3443,8 @@ OO.ui.ProcessDialog.prototype.fitLabel = function () {
                // We have enough space to center the label
                leftWidth = rightWidth = biggerWidth;
        } else {
-               // Let's hope we at least have enough space not to overlap, because we can't wrap the label…
+               // Let's hope we at least have enough space not to overlap, because we can't wrap
+               // the label.
                if ( this.getDir() === 'ltr' ) {
                        leftWidth = safeWidth;
                        rightWidth = primaryWidth;
@@ -3447,7 +3491,7 @@ OO.ui.ProcessDialog.prototype.showErrors = function ( errors ) {
        this.$errorItems = $( items );
        if ( recoverable ) {
                abilities[ this.currentAction ] = true;
-               // Copy the flags from the first matching action
+               // Copy the flags from the first matching action.
                actions = this.actions.get( { actions: this.currentAction } );
                if ( actions.length ) {
                        this.retryButton.clearFlags().setFlags( actions[ 0 ].getFlags() );
@@ -3486,7 +3530,7 @@ OO.ui.ProcessDialog.prototype.getTeardownProcess = function ( data ) {
        // Parent method
        return OO.ui.ProcessDialog.parent.prototype.getTeardownProcess.call( this, data )
                .first( function () {
-                       // Make sure to hide errors
+                       // Make sure to hide errors.
                        this.hideErrors();
                        this.fitOnOpen = false;
                }, this );
@@ -3573,13 +3617,15 @@ OO.ui.confirm = function ( text, options ) {
 /**
  * Display a quick modal prompt dialog, using a OO.ui.MessageDialog. While the dialog is open,
  * the rest of the page will be dimmed out and the user won't be able to interact with it. The
- * dialog has a text input widget and two action buttons, one to confirm an operation (labelled "OK")
- * and one to cancel it (labelled "Cancel").
+ * dialog has a text input widget and two action buttons, one to confirm an operation
+ * (labelled "OK") and one to cancel it (labelled "Cancel").
  *
  * A window manager is created automatically when this function is called for the first time.
  *
  *     @example
- *     OO.ui.prompt( 'Choose a line to go to', { textInput: { placeholder: 'Line number' } } ).done( function ( result ) {
+ *     OO.ui.prompt( 'Choose a line to go to', {
+ *         textInput: { placeholder: 'Line number' }
+ *     } ).done( function ( result ) {
  *         if ( result !== null ) {
  *             console.log( 'User typed "' + result + '" then clicked "OK".' );
  *         } else {
@@ -3589,7 +3635,8 @@ OO.ui.confirm = function ( text, options ) {
  *
  * @param {jQuery|string} text Message text to display
  * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
- * @param {Object} [options.textInput] Additional options for text input widget, see OO.ui.TextInputWidget
+ * @param {Object} [options.textInput] Additional options for text input widget,
+ *  see OO.ui.TextInputWidget
  * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to
  *  confirm, the promise will resolve with the value of the text input widget; otherwise, it will
  *  resolve to `null`.
index f6dac08..fd3c4b6 100644 (file)
@@ -1 +1 @@
-{"version":3,"sources":["../src/intro.js.txt","../src/widgets/ActionWidget.js","../src/ActionSet.js","../src/Error.js","../src/Process.js","../src/WindowInstance.js","../src/WindowManager.js","../src/Window.js","../src/Dialog.js","../src/dialogs/MessageDialog.js","../src/dialogs/ProcessDialog.js","../src/windows.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-windows.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * An ActionWidget is a {@link OO.ui.ButtonWidget button widget} that executes an action.\n * Action widgets are used with OO.ui.ActionSet, which manages the behavior and availability\n * of the actions.\n *\n * Both actions and action sets are primarily used with {@link OO.ui.Dialog Dialogs}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information\n * and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets\n *\n * @class\n * @extends OO.ui.ButtonWidget\n * @mixins OO.ui.mixin.PendingElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [action] Symbolic name of the action (e.g., ‘continue’ or ‘cancel’).\n * @cfg {string[]} [modes] Symbolic names of the modes (e.g., ‘edit’ or ‘read’) in which the action\n *  should be made available. See the action set's {@link OO.ui.ActionSet#setMode setMode} method\n *  for more information about setting modes.\n * @cfg {boolean} [framed=false] Render the action button with a frame\n */\nOO.ui.ActionWidget = function OoUiActionWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { framed: false }, config );\n\n\t// Parent constructor\n\tOO.ui.ActionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PendingElement.call( this, config );\n\n\t// Properties\n\tthis.action = config.action || '';\n\tthis.modes = config.modes || [];\n\tthis.width = 0;\n\tthis.height = 0;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-actionWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ActionWidget, OO.ui.ButtonWidget );\nOO.mixinClass( OO.ui.ActionWidget, OO.ui.mixin.PendingElement );\n\n/* Methods */\n\n/**\n * Check if the action is configured to be available in the specified `mode`.\n *\n * @param {string} mode Name of mode\n * @return {boolean} The action is configured with the mode\n */\nOO.ui.ActionWidget.prototype.hasMode = function ( mode ) {\n\treturn this.modes.indexOf( mode ) !== -1;\n};\n\n/**\n * Get the symbolic name of the action (e.g., ‘continue’ or ‘cancel’).\n *\n * @return {string}\n */\nOO.ui.ActionWidget.prototype.getAction = function () {\n\treturn this.action;\n};\n\n/**\n * Get the symbolic name of the mode or modes for which the action is configured to be available.\n *\n * The current mode is set with the action set's {@link OO.ui.ActionSet#setMode setMode} method.\n * Only actions that are configured to be available in the current mode will be visible. All other actions\n * are hidden.\n *\n * @return {string[]}\n */\nOO.ui.ActionWidget.prototype.getModes = function () {\n\treturn this.modes.slice();\n};\n","/* eslint-disable no-unused-vars */\n/**\n * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that comprise them.\n * Actions can be made available for specific contexts (modes) and circumstances\n * (abilities). Action sets are primarily used with {@link OO.ui.Dialog Dialogs}.\n *\n * ActionSets contain two types of actions:\n *\n * - Special: Special actions are the first visible actions with special flags, such as 'safe' and 'primary', the default special flags. Additional special flags can be configured in subclasses with the static #specialFlags property.\n * - Other: Other actions include all non-special visible actions.\n *\n * See the [OOUI documentation on MediaWiki][1] for more information.\n *\n *     @example\n *     // Example: An action set used in a process dialog\n *     function MyProcessDialog( config ) {\n *         MyProcessDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );\n *     MyProcessDialog.static.title = 'An action set in a process dialog';\n *     MyProcessDialog.static.name = 'myProcessDialog';\n *     // An action set that uses modes ('edit' and 'help' mode, in this example).\n *     MyProcessDialog.static.actions = [\n *         { action: 'continue', modes: 'edit', label: 'Continue', flags: [ 'primary', 'progressive' ] },\n *         { action: 'help', modes: 'edit', label: 'Help' },\n *         { modes: 'edit', label: 'Cancel', flags: 'safe' },\n *         { action: 'back', modes: 'help', label: 'Back', flags: 'safe' }\n *     ];\n *\n *     MyProcessDialog.prototype.initialize = function () {\n *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );\n *         this.panel1 = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.panel1.$element.append( '<p>This dialog uses an action set (continue, help, cancel, back) configured with modes. This is edit mode. Click \\'help\\' to see help mode.</p>' );\n *         this.panel2 = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.panel2.$element.append( '<p>This is help mode. Only the \\'back\\' action widget is configured to be visible here. Click \\'back\\' to return to \\'edit\\' mode.</p>' );\n *         this.stackLayout = new OO.ui.StackLayout( {\n *             items: [ this.panel1, this.panel2 ]\n *         } );\n *         this.$body.append( this.stackLayout.$element );\n *     };\n *     MyProcessDialog.prototype.getSetupProcess = function ( data ) {\n *         return MyProcessDialog.parent.prototype.getSetupProcess.call( this, data )\n *             .next( function () {\n *                 this.actions.setMode( 'edit' );\n *             }, this );\n *     };\n *     MyProcessDialog.prototype.getActionProcess = function ( action ) {\n *         if ( action === 'help' ) {\n *             this.actions.setMode( 'help' );\n *             this.stackLayout.setItem( this.panel2 );\n *         } else if ( action === 'back' ) {\n *             this.actions.setMode( 'edit' );\n *             this.stackLayout.setItem( this.panel1 );\n *         } else if ( action === 'continue' ) {\n *             var dialog = this;\n *             return new OO.ui.Process( function () {\n *                 dialog.close();\n *             } );\n *         }\n *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );\n *     };\n *     MyProcessDialog.prototype.getBodyHeight = function () {\n *         return this.panel1.$element.outerHeight( true );\n *     };\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *     var dialog = new MyProcessDialog( {\n *         size: 'medium'\n *     } );\n *     windowManager.addWindows( [ dialog ] );\n *     windowManager.openWindow( dialog );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets\n *\n * @abstract\n * @class\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ActionSet = function OoUiActionSet( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.list = [];\n\tthis.categories = {\n\t\tactions: 'getAction',\n\t\tflags: 'getFlags',\n\t\tmodes: 'getModes'\n\t};\n\tthis.categorized = {};\n\tthis.special = {};\n\tthis.others = [];\n\tthis.organized = false;\n\tthis.changing = false;\n\tthis.changed = false;\n};\n/* eslint-enable no-unused-vars */\n\n/* Setup */\n\nOO.mixinClass( OO.ui.ActionSet, OO.EventEmitter );\n\n/* Static Properties */\n\n/**\n * Symbolic name of the flags used to identify special actions. Special actions are displayed in the\n *  header of a {@link OO.ui.ProcessDialog process dialog}.\n *  See the [OOUI documentation on MediaWiki][2] for more information and examples.\n *\n *  [2]:https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.ActionSet.static.specialFlags = [ 'safe', 'primary' ];\n\n/* Events */\n\n/**\n * @event click\n *\n * A 'click' event is emitted when an action is clicked.\n *\n * @param {OO.ui.ActionWidget} action Action that was clicked\n */\n\n/**\n * @event add\n *\n * An 'add' event is emitted when actions are {@link #method-add added} to the action set.\n *\n * @param {OO.ui.ActionWidget[]} added Actions added\n */\n\n/**\n * @event remove\n *\n * A 'remove' event is emitted when actions are {@link #method-remove removed}\n *  or {@link #clear cleared}.\n *\n * @param {OO.ui.ActionWidget[]} added Actions removed\n */\n\n/**\n * @event change\n *\n * A 'change' event is emitted when actions are {@link #method-add added}, {@link #clear cleared},\n * or {@link #method-remove removed} from the action set or when the {@link #setMode mode} is changed.\n *\n */\n\n/* Methods */\n\n/**\n * Handle action change events.\n *\n * @private\n * @fires change\n */\nOO.ui.ActionSet.prototype.onActionChange = function () {\n\tthis.organized = false;\n\tif ( this.changing ) {\n\t\tthis.changed = true;\n\t} else {\n\t\tthis.emit( 'change' );\n\t}\n};\n\n/**\n * Check if an action is one of the special actions.\n *\n * @param {OO.ui.ActionWidget} action Action to check\n * @return {boolean} Action is special\n */\nOO.ui.ActionSet.prototype.isSpecial = function ( action ) {\n\tvar flag;\n\n\tfor ( flag in this.special ) {\n\t\tif ( action === this.special[ flag ] ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n};\n\n/**\n * Get action widgets based on the specified filter: ‘actions’, ‘flags’, ‘modes’, ‘visible’,\n *  or ‘disabled’.\n *\n * @param {Object} [filters] Filters to use, omit to get all actions\n * @param {string|string[]} [filters.actions] Actions that action widgets must have\n * @param {string|string[]} [filters.flags] Flags that action widgets must have (e.g., 'safe')\n * @param {string|string[]} [filters.modes] Modes that action widgets must have\n * @param {boolean} [filters.visible] Action widgets must be visible\n * @param {boolean} [filters.disabled] Action widgets must be disabled\n * @return {OO.ui.ActionWidget[]} Action widgets matching all criteria\n */\nOO.ui.ActionSet.prototype.get = function ( filters ) {\n\tvar i, len, list, category, actions, index, match, matches;\n\n\tif ( filters ) {\n\t\tthis.organize();\n\n\t\t// Collect category candidates\n\t\tmatches = [];\n\t\tfor ( category in this.categorized ) {\n\t\t\tlist = filters[ category ];\n\t\t\tif ( list ) {\n\t\t\t\tif ( !Array.isArray( list ) ) {\n\t\t\t\t\tlist = [ list ];\n\t\t\t\t}\n\t\t\t\tfor ( i = 0, len = list.length; i < len; i++ ) {\n\t\t\t\t\tactions = this.categorized[ category ][ list[ i ] ];\n\t\t\t\t\tif ( Array.isArray( actions ) ) {\n\t\t\t\t\t\tmatches.push.apply( matches, actions );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Remove by boolean filters\n\t\tfor ( i = 0, len = matches.length; i < len; i++ ) {\n\t\t\tmatch = matches[ i ];\n\t\t\tif (\n\t\t\t\t( filters.visible !== undefined && match.isVisible() !== filters.visible ) ||\n\t\t\t\t( filters.disabled !== undefined && match.isDisabled() !== filters.disabled )\n\t\t\t) {\n\t\t\t\tmatches.splice( i, 1 );\n\t\t\t\tlen--;\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t\t// Remove duplicates\n\t\tfor ( i = 0, len = matches.length; i < len; i++ ) {\n\t\t\tmatch = matches[ i ];\n\t\t\tindex = matches.lastIndexOf( match );\n\t\t\twhile ( index !== i ) {\n\t\t\t\tmatches.splice( index, 1 );\n\t\t\t\tlen--;\n\t\t\t\tindex = matches.lastIndexOf( match );\n\t\t\t}\n\t\t}\n\t\treturn matches;\n\t}\n\treturn this.list.slice();\n};\n\n/**\n * Get 'special' actions.\n *\n * Special actions are the first visible action widgets with special flags, such as 'safe' and 'primary'.\n * Special flags can be configured in subclasses by changing the static #specialFlags property.\n *\n * @return {OO.ui.ActionWidget[]|null} 'Special' action widgets.\n */\nOO.ui.ActionSet.prototype.getSpecial = function () {\n\tthis.organize();\n\treturn $.extend( {}, this.special );\n};\n\n/**\n * Get 'other' actions.\n *\n * Other actions include all non-special visible action widgets.\n *\n * @return {OO.ui.ActionWidget[]} 'Other' action widgets\n */\nOO.ui.ActionSet.prototype.getOthers = function () {\n\tthis.organize();\n\treturn this.others.slice();\n};\n\n/**\n * Set the mode  (e.g., ‘edit’ or ‘view’). Only {@link OO.ui.ActionWidget#modes actions} configured\n * to be available in the specified mode will be made visible. All other actions will be hidden.\n *\n * @param {string} mode The mode. Only actions configured to be available in the specified\n *  mode will be made visible.\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires toggle\n * @fires change\n */\nOO.ui.ActionSet.prototype.setMode = function ( mode ) {\n\tvar i, len, action;\n\n\tthis.changing = true;\n\tfor ( i = 0, len = this.list.length; i < len; i++ ) {\n\t\taction = this.list[ i ];\n\t\taction.toggle( action.hasMode( mode ) );\n\t}\n\n\tthis.organized = false;\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Set the abilities of the specified actions.\n *\n * Action widgets that are configured with the specified actions will be enabled\n * or disabled based on the boolean values specified in the `actions`\n * parameter.\n *\n * @param {Object.<string,boolean>} actions A list keyed by action name with boolean\n *  values that indicate whether or not the action should be enabled.\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n */\nOO.ui.ActionSet.prototype.setAbilities = function ( actions ) {\n\tvar i, len, action, item;\n\n\tfor ( i = 0, len = this.list.length; i < len; i++ ) {\n\t\titem = this.list[ i ];\n\t\taction = item.getAction();\n\t\tif ( actions[ action ] !== undefined ) {\n\t\t\titem.setDisabled( !actions[ action ] );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Executes a function once per action.\n *\n * When making changes to multiple actions, use this method instead of iterating over the actions\n * manually to defer emitting a #change event until after all actions have been changed.\n *\n * @param {Object|null} filter Filters to use to determine which actions to iterate over; see #get\n * @param {Function} callback Callback to run for each action; callback is invoked with three\n *   arguments: the action, the action's index, the list of actions being iterated over\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n */\nOO.ui.ActionSet.prototype.forEach = function ( filter, callback ) {\n\tthis.changed = false;\n\tthis.changing = true;\n\tthis.get( filter ).forEach( callback );\n\tthis.changing = false;\n\tif ( this.changed ) {\n\t\tthis.emit( 'change' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Add action widgets to the action set.\n *\n * @param {OO.ui.ActionWidget[]} actions Action widgets to add\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires add\n * @fires change\n */\nOO.ui.ActionSet.prototype.add = function ( actions ) {\n\tvar i, len, action;\n\n\tthis.changing = true;\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\taction = actions[ i ];\n\t\taction.connect( this, {\n\t\t\tclick: [ 'emit', 'click', action ],\n\t\t\ttoggle: [ 'onActionChange' ]\n\t\t} );\n\t\tthis.list.push( action );\n\t}\n\tthis.organized = false;\n\tthis.emit( 'add', actions );\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Remove action widgets from the set.\n *\n * To remove all actions, you may wish to use the #clear method instead.\n *\n * @param {OO.ui.ActionWidget[]} actions Action widgets to remove\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires remove\n * @fires change\n */\nOO.ui.ActionSet.prototype.remove = function ( actions ) {\n\tvar i, len, index, action;\n\n\tthis.changing = true;\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\taction = actions[ i ];\n\t\tindex = this.list.indexOf( action );\n\t\tif ( index !== -1 ) {\n\t\t\taction.disconnect( this );\n\t\t\tthis.list.splice( index, 1 );\n\t\t}\n\t}\n\tthis.organized = false;\n\tthis.emit( 'remove', actions );\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Remove all action widgets from the set.\n *\n * To remove only specified actions, use the {@link #method-remove remove} method instead.\n *\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires remove\n * @fires change\n */\nOO.ui.ActionSet.prototype.clear = function () {\n\tvar i, len, action,\n\t\tremoved = this.list.slice();\n\n\tthis.changing = true;\n\tfor ( i = 0, len = this.list.length; i < len; i++ ) {\n\t\taction = this.list[ i ];\n\t\taction.disconnect( this );\n\t}\n\n\tthis.list = [];\n\n\tthis.organized = false;\n\tthis.emit( 'remove', removed );\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Organize actions.\n *\n * This is called whenever organized information is requested. It will only reorganize the actions\n * if something has changed since the last time it ran.\n *\n * @private\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n */\nOO.ui.ActionSet.prototype.organize = function () {\n\tvar i, iLen, j, jLen, flag, action, category, list, item, special,\n\t\tspecialFlags = this.constructor.static.specialFlags;\n\n\tif ( !this.organized ) {\n\t\tthis.categorized = {};\n\t\tthis.special = {};\n\t\tthis.others = [];\n\t\tfor ( i = 0, iLen = this.list.length; i < iLen; i++ ) {\n\t\t\taction = this.list[ i ];\n\t\t\tif ( action.isVisible() ) {\n\t\t\t\t// Populate categories\n\t\t\t\tfor ( category in this.categories ) {\n\t\t\t\t\tif ( !this.categorized[ category ] ) {\n\t\t\t\t\t\tthis.categorized[ category ] = {};\n\t\t\t\t\t}\n\t\t\t\t\tlist = action[ this.categories[ category ] ]();\n\t\t\t\t\tif ( !Array.isArray( list ) ) {\n\t\t\t\t\t\tlist = [ list ];\n\t\t\t\t\t}\n\t\t\t\t\tfor ( j = 0, jLen = list.length; j < jLen; j++ ) {\n\t\t\t\t\t\titem = list[ j ];\n\t\t\t\t\t\tif ( !this.categorized[ category ][ item ] ) {\n\t\t\t\t\t\t\tthis.categorized[ category ][ item ] = [];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.categorized[ category ][ item ].push( action );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Populate special/others\n\t\t\t\tspecial = false;\n\t\t\t\tfor ( j = 0, jLen = specialFlags.length; j < jLen; j++ ) {\n\t\t\t\t\tflag = specialFlags[ j ];\n\t\t\t\t\tif ( !this.special[ flag ] && action.hasFlag( flag ) ) {\n\t\t\t\t\t\tthis.special[ flag ] = action;\n\t\t\t\t\t\tspecial = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( !special ) {\n\t\t\t\t\tthis.others.push( action );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.organized = true;\n\t}\n\n\treturn this;\n};\n","/**\n * Errors contain a required message (either a string or jQuery selection) that is used to describe what went wrong\n * in a {@link OO.ui.Process process}. The error's #recoverable and #warning configurations are used to customize the\n * appearance and functionality of the error interface.\n *\n * The basic error interface contains a formatted error message as well as two buttons: 'Dismiss' and 'Try again' (i.e., the error\n * is 'recoverable' by default). If the error is not recoverable, the 'Try again' button will not be rendered and the widget\n * that initiated the failed process will be disabled.\n *\n * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button, which will try the\n * process again.\n *\n * For an example of error interfaces, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Processes_and_errors\n *\n * @class\n *\n * @constructor\n * @param {string|jQuery} message Description of error\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [recoverable=true] Error is recoverable.\n *  By default, errors are recoverable, and users can try the process again.\n * @cfg {boolean} [warning=false] Error is a warning.\n *  If the error is a warning, the error interface will include a\n *  'Dismiss' and a 'Continue' button. It is the responsibility of the developer to ensure that the warning\n *  is not triggered a second time if the user chooses to continue.\n */\nOO.ui.Error = function OoUiError( message, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( message ) && config === undefined ) {\n\t\tconfig = message;\n\t\tmessage = config.message;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.message = message instanceof $ ? message : String( message );\n\tthis.recoverable = config.recoverable === undefined || !!config.recoverable;\n\tthis.warning = !!config.warning;\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Error );\n\n/* Methods */\n\n/**\n * Check if the error is recoverable.\n *\n * If the error is recoverable, users are able to try the process again.\n *\n * @return {boolean} Error is recoverable\n */\nOO.ui.Error.prototype.isRecoverable = function () {\n\treturn this.recoverable;\n};\n\n/**\n * Check if the error is a warning.\n *\n * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button.\n *\n * @return {boolean} Error is warning\n */\nOO.ui.Error.prototype.isWarning = function () {\n\treturn this.warning;\n};\n\n/**\n * Get error message as DOM nodes.\n *\n * @return {jQuery} Error message in DOM nodes\n */\nOO.ui.Error.prototype.getMessage = function () {\n\treturn this.message instanceof $ ?\n\t\tthis.message.clone() :\n\t\t$( '<div>' ).text( this.message ).contents();\n};\n\n/**\n * Get the error message text.\n *\n * @return {string} Error message\n */\nOO.ui.Error.prototype.getMessageText = function () {\n\treturn this.message instanceof $ ? this.message.text() : this.message;\n};\n","/**\n * A Process is a list of steps that are called in sequence. The step can be a number, a jQuery promise,\n * or a function:\n *\n * - **number**: the process will wait for the specified number of milliseconds before proceeding.\n * - **promise**: the process will continue to the next step when the promise is successfully resolved\n *  or stop if the promise is rejected.\n * - **function**: the process will execute the function. The process will stop if the function returns\n *  either a boolean `false` or a promise that is rejected; if the function returns a number, the process\n *  will wait for that number of milliseconds before proceeding.\n *\n * If the process fails, an {@link OO.ui.Error error} is generated. Depending on how the error is\n * configured, users can dismiss the error and try the process again, or not. If a process is stopped,\n * its remaining steps will not be performed.\n *\n * @class\n *\n * @constructor\n * @param {number|jQuery.Promise|Function} step Number of milliseconds to wait before proceeding, promise\n *  that must be resolved before proceeding, or a function to execute. See #createStep for more information. see #createStep for more information\n * @param {Object} [context=null] Execution context of the function. The context is ignored if the step is\n *  a number or promise.\n */\nOO.ui.Process = function ( step, context ) {\n\t// Properties\n\tthis.steps = [];\n\n\t// Initialization\n\tif ( step !== undefined ) {\n\t\tthis.next( step, context );\n\t}\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Process );\n\n/* Methods */\n\n/**\n * Start the process.\n *\n * @return {jQuery.Promise} Promise that is resolved when all steps have successfully completed.\n *  If any of the steps return a promise that is rejected or a boolean false, this promise is rejected\n *  and any remaining steps are not performed.\n */\nOO.ui.Process.prototype.execute = function () {\n\tvar i, len, promise;\n\n\t/**\n\t * Continue execution.\n\t *\n\t * @ignore\n\t * @param {Array} step A function and the context it should be called in\n\t * @return {Function} Function that continues the process\n\t */\n\tfunction proceed( step ) {\n\t\treturn function () {\n\t\t\t// Execute step in the correct context\n\t\t\tvar deferred,\n\t\t\t\tresult = step.callback.call( step.context );\n\n\t\t\tif ( result === false ) {\n\t\t\t\t// Use rejected promise for boolean false results\n\t\t\t\treturn $.Deferred().reject( [] ).promise();\n\t\t\t}\n\t\t\tif ( typeof result === 'number' ) {\n\t\t\t\tif ( result < 0 ) {\n\t\t\t\t\tthrow new Error( 'Cannot go back in time: flux capacitor is out of service' );\n\t\t\t\t}\n\t\t\t\t// Use a delayed promise for numbers, expecting them to be in milliseconds\n\t\t\t\tdeferred = $.Deferred();\n\t\t\t\tsetTimeout( deferred.resolve, result );\n\t\t\t\treturn deferred.promise();\n\t\t\t}\n\t\t\tif ( result instanceof OO.ui.Error ) {\n\t\t\t\t// Use rejected promise for error\n\t\t\t\treturn $.Deferred().reject( [ result ] ).promise();\n\t\t\t}\n\t\t\tif ( Array.isArray( result ) && result.length && result[ 0 ] instanceof OO.ui.Error ) {\n\t\t\t\t// Use rejected promise for list of errors\n\t\t\t\treturn $.Deferred().reject( result ).promise();\n\t\t\t}\n\t\t\t// Duck-type the object to see if it can produce a promise\n\t\t\tif ( result && typeof result.promise === 'function' ) {\n\t\t\t\t// Use a promise generated from the result\n\t\t\t\treturn result.promise();\n\t\t\t}\n\t\t\t// Use resolved promise for other results\n\t\t\treturn $.Deferred().resolve().promise();\n\t\t};\n\t}\n\n\tif ( this.steps.length ) {\n\t\t// Generate a chain reaction of promises\n\t\tpromise = proceed( this.steps[ 0 ] )();\n\t\tfor ( i = 1, len = this.steps.length; i < len; i++ ) {\n\t\t\tpromise = promise.then( proceed( this.steps[ i ] ) );\n\t\t}\n\t} else {\n\t\tpromise = $.Deferred().resolve().promise();\n\t}\n\n\treturn promise;\n};\n\n/**\n * Create a process step.\n *\n * @private\n * @param {number|jQuery.Promise|Function} step\n *\n * - Number of milliseconds to wait before proceeding\n * - Promise that must be resolved before proceeding\n * - Function to execute\n *   - If the function returns a boolean false the process will stop\n *   - If the function returns a promise, the process will continue to the next\n *     step when the promise is resolved or stop if the promise is rejected\n *   - If the function returns a number, the process will wait for that number of\n *     milliseconds before proceeding\n * @param {Object} [context=null] Execution context of the function. The context is\n *  ignored if the step is a number or promise.\n * @return {Object} Step object, with `callback` and `context` properties\n */\nOO.ui.Process.prototype.createStep = function ( step, context ) {\n\tif ( typeof step === 'number' || typeof step.promise === 'function' ) {\n\t\treturn {\n\t\t\tcallback: function () {\n\t\t\t\treturn step;\n\t\t\t},\n\t\t\tcontext: null\n\t\t};\n\t}\n\tif ( typeof step === 'function' ) {\n\t\treturn {\n\t\t\tcallback: step,\n\t\t\tcontext: context\n\t\t};\n\t}\n\tthrow new Error( 'Cannot create process step: number, promise or function expected' );\n};\n\n/**\n * Add step to the beginning of the process.\n *\n * @inheritdoc #createStep\n * @return {OO.ui.Process} this\n * @chainable\n */\nOO.ui.Process.prototype.first = function ( step, context ) {\n\tthis.steps.unshift( this.createStep( step, context ) );\n\treturn this;\n};\n\n/**\n * Add step to the end of the process.\n *\n * @inheritdoc #createStep\n * @return {OO.ui.Process} this\n * @chainable\n */\nOO.ui.Process.prototype.next = function ( step, context ) {\n\tthis.steps.push( this.createStep( step, context ) );\n\treturn this;\n};\n","/**\n * A window instance represents the life cycle for one single opening of a window\n * until its closing.\n *\n * While OO.ui.WindowManager will reuse OO.ui.Window objects, each time a window is\n * opened, a new lifecycle starts.\n *\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows\n *\n * @class\n *\n * @constructor\n */\nOO.ui.WindowInstance = function OoUiWindowInstance() {\n\tvar deferreds = {\n\t\topening: $.Deferred(),\n\t\topened: $.Deferred(),\n\t\tclosing: $.Deferred(),\n\t\tclosed: $.Deferred()\n\t};\n\n\t/**\n\t * @private\n\t * @property {Object}\n\t */\n\tthis.deferreds = deferreds;\n\n\t// Set these up as chained promises so that rejecting of\n\t// an earlier stage automatically rejects the subsequent\n\t// would-be stages as well.\n\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.opening = deferreds.opening.promise();\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.opened = this.opening.then( function () {\n\t\treturn deferreds.opened;\n\t} );\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.closing = this.opened.then( function () {\n\t\treturn deferreds.closing;\n\t} );\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.closed = this.closing.then( function () {\n\t\treturn deferreds.closed;\n\t} );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.WindowInstance );\n\n/**\n * Check if window is opening.\n *\n * @return {boolean} Window is opening\n */\nOO.ui.WindowInstance.prototype.isOpening = function () {\n\treturn this.deferreds.opened.state() === 'pending';\n};\n\n/**\n * Check if window is opened.\n *\n * @return {boolean} Window is opened\n */\nOO.ui.WindowInstance.prototype.isOpened = function () {\n\treturn this.deferreds.opened.state() === 'resolved' &&\n\t\tthis.deferreds.closing.state() === 'pending';\n};\n\n/**\n * Check if window is closing.\n *\n * @return {boolean} Window is closing\n */\nOO.ui.WindowInstance.prototype.isClosing = function () {\n\treturn this.deferreds.closing.state() === 'resolved' &&\n\t\tthis.deferreds.closed.state() === 'pending';\n};\n\n/**\n * Check if window is closed.\n *\n * @return {boolean} Window is closed\n */\nOO.ui.WindowInstance.prototype.isClosed = function () {\n\treturn this.deferreds.closed.state() === 'resolved';\n};\n","/**\n * Window managers are used to open and close {@link OO.ui.Window windows} and control their presentation.\n * Managed windows are mutually exclusive. If a new window is opened while a current window is opening\n * or is opened, the current window will be closed and any ongoing {@link OO.ui.Process process} will be cancelled. Windows\n * themselves are persistent and—rather than being torn down when closed—can be repopulated with the\n * pertinent data and reused.\n *\n * Over the lifecycle of a window, the window manager makes available three promises: `opening`,\n * `opened`, and `closing`, which represent the primary stages of the cycle:\n *\n * **Opening**: the opening stage begins when the window manager’s #openWindow or a window’s\n * {@link OO.ui.Window#open open} method is used, and the window manager begins to open the window.\n *\n * - an `opening` event is emitted with an `opening` promise\n * - the #getSetupDelay method is called and the returned value is used to time a pause in execution before the\n *   window’s {@link OO.ui.Window#method-setup setup} method is called which executes OO.ui.Window#getSetupProcess.\n * - a `setup` progress notification is emitted from the `opening` promise\n * - the #getReadyDelay method is called the returned value is used to time a pause in execution before the\n *   window’s {@link OO.ui.Window#method-ready ready} method is called which executes OO.ui.Window#getReadyProcess.\n * - a `ready` progress notification is emitted from the `opening` promise\n * - the `opening` promise is resolved with an `opened` promise\n *\n * **Opened**: the window is now open.\n *\n * **Closing**: the closing stage begins when the window manager's #closeWindow or the\n * window's {@link OO.ui.Window#close close} methods is used, and the window manager begins\n * to close the window.\n *\n * - the `opened` promise is resolved with `closing` promise and a `closing` event is emitted\n * - the #getHoldDelay method is called and the returned value is used to time a pause in execution before\n *   the window's {@link OO.ui.Window#getHoldProcess getHoldProcess} method is called on the\n *   window and its result executed\n * - a `hold` progress notification is emitted from the `closing` promise\n * - the #getTeardownDelay() method is called and the returned value is used to time a pause in execution before\n *   the window's {@link OO.ui.Window#getTeardownProcess getTeardownProcess} method is called on the\n *   window and its result executed\n * - a `teardown` progress notification is emitted from the `closing` promise\n * - the `closing` promise is resolved. The window is now closed\n *\n * See the [OOUI documentation on MediaWiki][1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.Factory} [factory] Window factory to use for automatic instantiation\n *  Note that window classes that are instantiated with a factory must have\n *  a {@link OO.ui.Dialog#static-name static name} property that specifies a symbolic name.\n * @cfg {boolean} [modal=true] Prevent interaction outside the dialog\n */\nOO.ui.WindowManager = function OoUiWindowManager( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.WindowManager.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.factory = config.factory;\n\tthis.modal = config.modal === undefined || !!config.modal;\n\tthis.windows = {};\n\t// Deprecated placeholder promise given to compatOpening in openWindow()\n\t// that is resolved in closeWindow().\n\tthis.compatOpened = null;\n\tthis.preparingToOpen = null;\n\tthis.preparingToClose = null;\n\tthis.currentWindow = null;\n\tthis.globalEvents = false;\n\tthis.$returnFocusTo = null;\n\tthis.$ariaHidden = null;\n\tthis.onWindowResizeTimeout = null;\n\tthis.onWindowResizeHandler = this.onWindowResize.bind( this );\n\tthis.afterWindowResizeHandler = this.afterWindowResize.bind( this );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-windowManager' )\n\t\t.toggleClass( 'oo-ui-windowManager-modal', this.modal );\n\tif ( this.modal ) {\n\t\tthis.$element.attr( 'aria-hidden', true );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.WindowManager, OO.ui.Element );\nOO.mixinClass( OO.ui.WindowManager, OO.EventEmitter );\n\n/* Events */\n\n/**\n * An 'opening' event is emitted when the window begins to be opened.\n *\n * @event opening\n * @param {OO.ui.Window} win Window that's being opened\n * @param {jQuery.Promise} opened A promise resolved with a value when the window is opened successfully.\n *  This promise also emits `setup` and `ready` notifications. When this promise is resolved, the first\n *  argument of the value is an 'closed' promise, the second argument is the opening data.\n * @param {Object} data Window opening data\n */\n\n/**\n * A 'closing' event is emitted when the window begins to be closed.\n *\n * @event closing\n * @param {OO.ui.Window} win Window that's being closed\n * @param {jQuery.Promise} closed A promise resolved with a value when the window is closed successfully.\n *  This promise also emits `hold` and `teardown` notifications. When this promise is resolved, the first\n *  argument of its value is the closing data.\n * @param {Object} data Window closing data\n */\n\n/**\n * A 'resize' event is emitted when a window is resized.\n *\n * @event resize\n * @param {OO.ui.Window} win Window that was resized\n */\n\n/* Static Properties */\n\n/**\n * Map of the symbolic name of each window size and its CSS properties.\n *\n * @static\n * @inheritable\n * @property {Object}\n */\nOO.ui.WindowManager.static.sizes = {\n\tsmall: {\n\t\twidth: 300\n\t},\n\tmedium: {\n\t\twidth: 500\n\t},\n\tlarge: {\n\t\twidth: 700\n\t},\n\tlarger: {\n\t\twidth: 900\n\t},\n\tfull: {\n\t\t// These can be non-numeric because they are never used in calculations\n\t\twidth: '100%',\n\t\theight: '100%'\n\t}\n};\n\n/**\n * Symbolic name of the default window size.\n *\n * The default size is used if the window's requested size is not recognized.\n *\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.WindowManager.static.defaultSize = 'medium';\n\n/* Methods */\n\n/**\n * Handle window resize events.\n *\n * @private\n * @param {jQuery.Event} e Window resize event\n */\nOO.ui.WindowManager.prototype.onWindowResize = function () {\n\tclearTimeout( this.onWindowResizeTimeout );\n\tthis.onWindowResizeTimeout = setTimeout( this.afterWindowResizeHandler, 200 );\n};\n\n/**\n * Handle window resize events.\n *\n * @private\n * @param {jQuery.Event} e Window resize event\n */\nOO.ui.WindowManager.prototype.afterWindowResize = function () {\n\tvar currentFocusedElement = document.activeElement;\n\tif ( this.currentWindow ) {\n\t\tthis.updateWindowSize( this.currentWindow );\n\n\t\t// Restore focus to the original element if it has changed.\n\t\t// When a layout change is made on resize inputs lose focus\n\t\t// on Android (Chrome and Firefox). See T162127.\n\t\tif ( currentFocusedElement !== document.activeElement ) {\n\t\t\tcurrentFocusedElement.focus();\n\t\t}\n\t}\n};\n\n/**\n * Check if window is opening.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is opening\n */\nOO.ui.WindowManager.prototype.isOpening = function ( win ) {\n\treturn win === this.currentWindow && !!this.lifecycle &&\n\t\tthis.lifecycle.isOpening();\n};\n\n/**\n * Check if window is closing.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is closing\n */\nOO.ui.WindowManager.prototype.isClosing = function ( win ) {\n\treturn win === this.currentWindow && !!this.lifecycle &&\n\t\tthis.lifecycle.isClosing();\n};\n\n/**\n * Check if window is opened.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is opened\n */\nOO.ui.WindowManager.prototype.isOpened = function ( win ) {\n\treturn win === this.currentWindow && !!this.lifecycle &&\n\t\tthis.lifecycle.isOpened();\n};\n\n/**\n * Check if a window is being managed.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is being managed\n */\nOO.ui.WindowManager.prototype.hasWindow = function ( win ) {\n\tvar name;\n\n\tfor ( name in this.windows ) {\n\t\tif ( this.windows[ name ] === win ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n};\n\n/**\n * Get the number of milliseconds to wait after opening begins before executing the ‘setup’ process.\n *\n * @param {OO.ui.Window} win Window being opened\n * @param {Object} [data] Window opening data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getSetupDelay = function () {\n\treturn 0;\n};\n\n/**\n * Get the number of milliseconds to wait after setup has finished before executing the ‘ready’ process.\n *\n * @param {OO.ui.Window} win Window being opened\n * @param {Object} [data] Window opening data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getReadyDelay = function () {\n\treturn this.modal ? OO.ui.theme.getDialogTransitionDuration() : 0;\n};\n\n/**\n * Get the number of milliseconds to wait after closing has begun before executing the 'hold' process.\n *\n * @param {OO.ui.Window} win Window being closed\n * @param {Object} [data] Window closing data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getHoldDelay = function () {\n\treturn 0;\n};\n\n/**\n * Get the number of milliseconds to wait after the ‘hold’ process has finished before\n * executing the ‘teardown’ process.\n *\n * @param {OO.ui.Window} win Window being closed\n * @param {Object} [data] Window closing data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getTeardownDelay = function () {\n\treturn this.modal ? OO.ui.theme.getDialogTransitionDuration() : 0;\n};\n\n/**\n * Get a window by its symbolic name.\n *\n * If the window is not yet instantiated and its symbolic name is recognized by a factory, it will be\n * instantiated and added to the window manager automatically. Please see the [OOUI documentation on MediaWiki][3]\n * for more information about using factories.\n * [3]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * @param {string} name Symbolic name of the window\n * @return {jQuery.Promise} Promise resolved with matching window, or rejected with an OO.ui.Error\n * @throws {Error} An error is thrown if the symbolic name is not recognized by the factory.\n * @throws {Error} An error is thrown if the named window is not recognized as a managed window.\n */\nOO.ui.WindowManager.prototype.getWindow = function ( name ) {\n\tvar deferred = $.Deferred(),\n\t\twin = this.windows[ name ];\n\n\tif ( !( win instanceof OO.ui.Window ) ) {\n\t\tif ( this.factory ) {\n\t\t\tif ( !this.factory.lookup( name ) ) {\n\t\t\t\tdeferred.reject( new OO.ui.Error(\n\t\t\t\t\t'Cannot auto-instantiate window: symbolic name is unrecognized by the factory'\n\t\t\t\t) );\n\t\t\t} else {\n\t\t\t\twin = this.factory.create( name );\n\t\t\t\tthis.addWindows( [ win ] );\n\t\t\t\tdeferred.resolve( win );\n\t\t\t}\n\t\t} else {\n\t\t\tdeferred.reject( new OO.ui.Error(\n\t\t\t\t'Cannot get unmanaged window: symbolic name unrecognized as a managed window'\n\t\t\t) );\n\t\t}\n\t} else {\n\t\tdeferred.resolve( win );\n\t}\n\n\treturn deferred.promise();\n};\n\n/**\n * Get current window.\n *\n * @return {OO.ui.Window|null} Currently opening/opened/closing window\n */\nOO.ui.WindowManager.prototype.getCurrentWindow = function () {\n\treturn this.currentWindow;\n};\n\n/* eslint-disable valid-jsdoc */\n/**\n * Open a window.\n *\n * @param {OO.ui.Window|string} win Window object or symbolic name of window to open\n * @param {Object} [data] Window opening data\n * @param {jQuery|null} [data.$returnFocusTo] Element to which the window will return focus when closed.\n *  Defaults the current activeElement. If set to null, focus isn't changed on close.\n * @return {OO.ui.WindowInstance} A lifecycle object representing this particular\n *  opening of the window. For backwards-compatibility, then object is also a Thenable that is resolved\n *  when the window is done opening, with nested promise for when closing starts. This behaviour\n *  is deprecated and is not compatible with jQuery 3. See T163510.\n * @fires opening\n */\nOO.ui.WindowManager.prototype.openWindow = function ( win, data, lifecycle, compatOpening ) {\n\t/* eslint-enable valid-jsdoc */\n\tvar error,\n\t\tmanager = this;\n\tdata = data || {};\n\n\t// Internal parameter 'lifecycle' allows this method to always return\n\t// a lifecycle even if the window still needs to be created\n\t// asynchronously when 'win' is a string.\n\tlifecycle = lifecycle || new OO.ui.WindowInstance();\n\tcompatOpening = compatOpening || $.Deferred();\n\n\t// Turn lifecycle into a Thenable for backwards-compatibility with\n\t// the deprecated nested-promise behaviour, see T163510.\n\t[ 'state', 'always', 'catch', 'pipe', 'then', 'promise', 'progress', 'done', 'fail' ]\n\t\t.forEach( function ( method ) {\n\t\t\tlifecycle[ method ] = function () {\n\t\t\t\tOO.ui.warnDeprecation(\n\t\t\t\t\t'Using the return value of openWindow as a promise is deprecated. ' +\n\t\t\t\t\t'Use .openWindow( ... ).opening.' + method + '( ... ) instead.'\n\t\t\t\t);\n\t\t\t\treturn compatOpening[ method ].apply( this, arguments );\n\t\t\t};\n\t\t} );\n\n\t// Argument handling\n\tif ( typeof win === 'string' ) {\n\t\tthis.getWindow( win ).then(\n\t\t\tfunction ( win ) {\n\t\t\t\tmanager.openWindow( win, data, lifecycle, compatOpening );\n\t\t\t},\n\t\t\tfunction ( err ) {\n\t\t\t\tlifecycle.deferreds.opening.reject( err );\n\t\t\t}\n\t\t);\n\t\treturn lifecycle;\n\t}\n\n\t// Error handling\n\tif ( !this.hasWindow( win ) ) {\n\t\terror = 'Cannot open window: window is not attached to manager';\n\t} else if ( this.lifecycle && this.lifecycle.isOpened() ) {\n\t\terror = 'Cannot open window: another window is open';\n\t} else if ( this.preparingToOpen || ( this.lifecycle && this.lifecycle.isOpening() ) ) {\n\t\terror = 'Cannot open window: another window is opening';\n\t}\n\n\tif ( error ) {\n\t\tcompatOpening.reject( new OO.ui.Error( error ) );\n\t\tlifecycle.deferreds.opening.reject( new OO.ui.Error( error ) );\n\t\treturn lifecycle;\n\t}\n\n\t// If a window is currently closing, wait for it to complete\n\tthis.preparingToOpen = $.when( this.lifecycle && this.lifecycle.closed );\n\t// Ensure handlers get called after preparingToOpen is set\n\tthis.preparingToOpen.done( function () {\n\t\tif ( manager.modal ) {\n\t\t\tmanager.toggleGlobalEvents( true );\n\t\t\tmanager.toggleAriaIsolation( true );\n\t\t}\n\t\tmanager.$returnFocusTo = data.$returnFocusTo !== undefined ? data.$returnFocusTo : $( document.activeElement );\n\t\tmanager.currentWindow = win;\n\t\tmanager.lifecycle = lifecycle;\n\t\tmanager.preparingToOpen = null;\n\t\tmanager.emit( 'opening', win, compatOpening, data );\n\t\tlifecycle.deferreds.opening.resolve( data );\n\t\tsetTimeout( function () {\n\t\t\tmanager.compatOpened = $.Deferred();\n\t\t\twin.setup( data ).then( function () {\n\t\t\t\tcompatOpening.notify( { state: 'setup' } );\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\twin.ready( data ).then( function () {\n\t\t\t\t\t\tcompatOpening.notify( { state: 'ready' } );\n\t\t\t\t\t\tlifecycle.deferreds.opened.resolve( data );\n\t\t\t\t\t\tcompatOpening.resolve( manager.compatOpened.promise(), data );\n\t\t\t\t\t}, function () {\n\t\t\t\t\t\tlifecycle.deferreds.opened.reject();\n\t\t\t\t\t\tcompatOpening.reject();\n\t\t\t\t\t\tmanager.closeWindow( win );\n\t\t\t\t\t} );\n\t\t\t\t}, manager.getReadyDelay() );\n\t\t\t}, function () {\n\t\t\t\tlifecycle.deferreds.opened.reject();\n\t\t\t\tcompatOpening.reject();\n\t\t\t\tmanager.closeWindow( win );\n\t\t\t} );\n\t\t}, manager.getSetupDelay() );\n\t} );\n\n\treturn lifecycle;\n};\n\n/**\n * Close a window.\n *\n * @param {OO.ui.Window|string} win Window object or symbolic name of window to close\n * @param {Object} [data] Window closing data\n * @return {OO.ui.WindowInstance} A lifecycle object representing this particular\n *  opening of the window. For backwards-compatibility, the object is also a Thenable that is resolved\n *  when the window is done closing, see T163510.\n * @fires closing\n */\nOO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {\n\tvar error,\n\t\tmanager = this,\n\t\tcompatClosing = $.Deferred(),\n\t\tlifecycle = this.lifecycle,\n\t\tcompatOpened;\n\n\t// Argument handling\n\tif ( typeof win === 'string' ) {\n\t\twin = this.windows[ win ];\n\t} else if ( !this.hasWindow( win ) ) {\n\t\twin = null;\n\t}\n\n\t// Error handling\n\tif ( !lifecycle ) {\n\t\terror = 'Cannot close window: no window is currently open';\n\t} else if ( !win ) {\n\t\terror = 'Cannot close window: window is not attached to manager';\n\t} else if ( win !== this.currentWindow || this.lifecycle.isClosed() ) {\n\t\terror = 'Cannot close window: window already closed with different data';\n\t} else if ( this.preparingToClose || this.lifecycle.isClosing() ) {\n\t\terror = 'Cannot close window: window already closing with different data';\n\t}\n\n\tif ( error ) {\n\t\t// This function was called for the wrong window and we don't want to mess with the current\n\t\t// window's state.\n\t\tlifecycle = new OO.ui.WindowInstance();\n\t\t// Pretend the window has been opened, so that we can pretend to fail to close it.\n\t\tlifecycle.deferreds.opening.resolve( {} );\n\t\tlifecycle.deferreds.opened.resolve( {} );\n\t}\n\n\t// Turn lifecycle into a Thenable for backwards-compatibility with\n\t// the deprecated nested-promise behaviour, see T163510.\n\t[ 'state', 'always', 'catch', 'pipe', 'then', 'promise', 'progress', 'done', 'fail' ]\n\t\t.forEach( function ( method ) {\n\t\t\tlifecycle[ method ] = function () {\n\t\t\t\tOO.ui.warnDeprecation(\n\t\t\t\t\t'Using the return value of closeWindow as a promise is deprecated. ' +\n\t\t\t\t\t'Use .closeWindow( ... ).closed.' + method + '( ... ) instead.'\n\t\t\t\t);\n\t\t\t\treturn compatClosing[ method ].apply( this, arguments );\n\t\t\t};\n\t\t} );\n\n\tif ( error ) {\n\t\tcompatClosing.reject( new OO.ui.Error( error ) );\n\t\tlifecycle.deferreds.closing.reject( new OO.ui.Error( error ) );\n\t\treturn lifecycle;\n\t}\n\n\t// If the window is currently opening, close it when it's done\n\tthis.preparingToClose = $.when( this.lifecycle.opened );\n\t// Ensure handlers get called after preparingToClose is set\n\tthis.preparingToClose.always( function () {\n\t\tmanager.preparingToClose = null;\n\t\tmanager.emit( 'closing', win, compatClosing, data );\n\t\tlifecycle.deferreds.closing.resolve( data );\n\t\tcompatOpened = manager.compatOpened;\n\t\tmanager.compatOpened = null;\n\t\tcompatOpened.resolve( compatClosing.promise(), data );\n\t\tsetTimeout( function () {\n\t\t\twin.hold( data ).then( function () {\n\t\t\t\tcompatClosing.notify( { state: 'hold' } );\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\twin.teardown( data ).then( function () {\n\t\t\t\t\t\tcompatClosing.notify( { state: 'teardown' } );\n\t\t\t\t\t\tif ( manager.modal ) {\n\t\t\t\t\t\t\tmanager.toggleGlobalEvents( false );\n\t\t\t\t\t\t\tmanager.toggleAriaIsolation( false );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( manager.$returnFocusTo && manager.$returnFocusTo.length ) {\n\t\t\t\t\t\t\tmanager.$returnFocusTo[ 0 ].focus();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmanager.currentWindow = null;\n\t\t\t\t\t\tmanager.lifecycle = null;\n\t\t\t\t\t\tlifecycle.deferreds.closed.resolve( data );\n\t\t\t\t\t\tcompatClosing.resolve( data );\n\t\t\t\t\t} );\n\t\t\t\t}, manager.getTeardownDelay() );\n\t\t\t} );\n\t\t}, manager.getHoldDelay() );\n\t} );\n\n\treturn lifecycle;\n};\n\n/**\n * Add windows to the window manager.\n *\n * Windows can be added by reference, symbolic name, or explicitly defined symbolic names.\n * See the [OOUI documentation on MediaWiki] [2] for examples.\n * [2]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * This function can be called in two manners:\n *\n * 1. `.addWindows( [ windowA, windowB, ... ] )` (where `windowA`, `windowB` are OO.ui.Window objects)\n *\n *    This syntax registers windows under the symbolic names defined in their `.static.name`\n *    properties. For example, if `windowA.constructor.static.name` is `'nameA'`, calling\n *    `.openWindow( 'nameA' )` afterwards will open the window `windowA`. This syntax requires the\n *    static name to be set, otherwise an exception will be thrown.\n *\n *    This is the recommended way, as it allows for an easier switch to using a window factory.\n *\n * 2. `.addWindows( { nameA: windowA, nameB: windowB, ... } )`\n *\n *    This syntax registers windows under the explicitly given symbolic names. In this example,\n *    calling `.openWindow( 'nameA' )` afterwards will open the window `windowA`, regardless of what\n *    its `.static.name` is set to. The static name is not required to be set.\n *\n *    This should only be used if you need to override the default symbolic names.\n *\n * Example:\n *\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *\n *     // Add a window under the default name: see OO.ui.MessageDialog.static.name\n *     windowManager.addWindows( [ new OO.ui.MessageDialog() ] );\n *     // Add a window under an explicit name\n *     windowManager.addWindows( { myMessageDialog: new OO.ui.MessageDialog() } );\n *\n *     // Open window by default name\n *     windowManager.openWindow( 'message' );\n *     // Open window by explicitly given name\n *     windowManager.openWindow( 'myMessageDialog' );\n *\n *\n * @param {Object.<string,OO.ui.Window>|OO.ui.Window[]} windows An array of window objects specified\n *  by reference, symbolic name, or explicitly defined symbolic names.\n * @throws {Error} An error is thrown if a window is added by symbolic name, but has neither an\n *  explicit nor a statically configured symbolic name.\n */\nOO.ui.WindowManager.prototype.addWindows = function ( windows ) {\n\tvar i, len, win, name, list;\n\n\tif ( Array.isArray( windows ) ) {\n\t\t// Convert to map of windows by looking up symbolic names from static configuration\n\t\tlist = {};\n\t\tfor ( i = 0, len = windows.length; i < len; i++ ) {\n\t\t\tname = windows[ i ].constructor.static.name;\n\t\t\tif ( !name ) {\n\t\t\t\tthrow new Error( 'Windows must have a `name` static property defined.' );\n\t\t\t}\n\t\t\tlist[ name ] = windows[ i ];\n\t\t}\n\t} else if ( OO.isPlainObject( windows ) ) {\n\t\tlist = windows;\n\t}\n\n\t// Add windows\n\tfor ( name in list ) {\n\t\twin = list[ name ];\n\t\tthis.windows[ name ] = win.toggle( false );\n\t\tthis.$element.append( win.$element );\n\t\twin.setManager( this );\n\t}\n};\n\n/**\n * Remove the specified windows from the windows manager.\n *\n * Windows will be closed before they are removed. If you wish to remove all windows, you may wish to use\n * the #clearWindows method instead. If you no longer need the window manager and want to ensure that it no\n * longer listens to events, use the #destroy method.\n *\n * @param {string[]} names Symbolic names of windows to remove\n * @return {jQuery.Promise} Promise resolved when window is closed and removed\n * @throws {Error} An error is thrown if the named windows are not managed by the window manager.\n */\nOO.ui.WindowManager.prototype.removeWindows = function ( names ) {\n\tvar i, len, win, name, cleanupWindow,\n\t\tmanager = this,\n\t\tpromises = [],\n\t\tcleanup = function ( name, win ) {\n\t\t\tdelete manager.windows[ name ];\n\t\t\twin.$element.detach();\n\t\t};\n\n\tfor ( i = 0, len = names.length; i < len; i++ ) {\n\t\tname = names[ i ];\n\t\twin = this.windows[ name ];\n\t\tif ( !win ) {\n\t\t\tthrow new Error( 'Cannot remove window' );\n\t\t}\n\t\tcleanupWindow = cleanup.bind( null, name, win );\n\t\tpromises.push( this.closeWindow( name ).closed.then( cleanupWindow, cleanupWindow ) );\n\t}\n\n\treturn $.when.apply( $, promises );\n};\n\n/**\n * Remove all windows from the window manager.\n *\n * Windows will be closed before they are removed. Note that the window manager, though not in use, will still\n * listen to events. If the window manager will not be used again, you may wish to use the #destroy method instead.\n * To remove just a subset of windows, use the #removeWindows method.\n *\n * @return {jQuery.Promise} Promise resolved when all windows are closed and removed\n */\nOO.ui.WindowManager.prototype.clearWindows = function () {\n\treturn this.removeWindows( Object.keys( this.windows ) );\n};\n\n/**\n * Set dialog size. In general, this method should not be called directly.\n *\n * Fullscreen mode will be used if the dialog is too wide to fit in the screen.\n *\n * @param {OO.ui.Window} win Window to update, should be the current window\n * @chainable\n * @return {OO.ui.WindowManager} The manager, for chaining\n */\nOO.ui.WindowManager.prototype.updateWindowSize = function ( win ) {\n\tvar isFullscreen;\n\n\t// Bypass for non-current, and thus invisible, windows\n\tif ( win !== this.currentWindow ) {\n\t\treturn;\n\t}\n\n\tisFullscreen = win.getSize() === 'full';\n\n\tthis.$element.toggleClass( 'oo-ui-windowManager-fullscreen', isFullscreen );\n\tthis.$element.toggleClass( 'oo-ui-windowManager-floating', !isFullscreen );\n\twin.setDimensions( win.getSizeProperties() );\n\n\tthis.emit( 'resize', win );\n\n\treturn this;\n};\n\n/**\n * Bind or unbind global events for scrolling.\n *\n * @private\n * @param {boolean} [on] Bind global events\n * @chainable\n * @return {OO.ui.WindowManager} The manager, for chaining\n */\nOO.ui.WindowManager.prototype.toggleGlobalEvents = function ( on ) {\n\tvar scrollWidth, bodyMargin,\n\t\t$body = $( this.getElementDocument().body ),\n\t\t// We could have multiple window managers open so only modify\n\t\t// the body css at the bottom of the stack\n\t\tstackDepth = $body.data( 'windowManagerGlobalEvents' ) || 0;\n\n\ton = on === undefined ? !!this.globalEvents : !!on;\n\n\tif ( on ) {\n\t\tif ( !this.globalEvents ) {\n\t\t\t$( this.getElementWindow() ).on( {\n\t\t\t\t// Start listening for top-level window dimension changes\n\t\t\t\t'orientationchange resize': this.onWindowResizeHandler\n\t\t\t} );\n\t\t\tif ( stackDepth === 0 ) {\n\t\t\t\tscrollWidth = window.innerWidth - document.documentElement.clientWidth;\n\t\t\t\tbodyMargin = parseFloat( $body.css( 'margin-right' ) ) || 0;\n\t\t\t\t$body.addClass( 'oo-ui-windowManager-modal-active' );\n\t\t\t\t$body.css( 'margin-right', bodyMargin + scrollWidth );\n\t\t\t}\n\t\t\tstackDepth++;\n\t\t\tthis.globalEvents = true;\n\t\t}\n\t} else if ( this.globalEvents ) {\n\t\t$( this.getElementWindow() ).off( {\n\t\t\t// Stop listening for top-level window dimension changes\n\t\t\t'orientationchange resize': this.onWindowResizeHandler\n\t\t} );\n\t\tstackDepth--;\n\t\tif ( stackDepth === 0 ) {\n\t\t\t$body.removeClass( 'oo-ui-windowManager-modal-active' );\n\t\t\t$body.css( 'margin-right', '' );\n\t\t}\n\t\tthis.globalEvents = false;\n\t}\n\t$body.data( 'windowManagerGlobalEvents', stackDepth );\n\n\treturn this;\n};\n\n/**\n * Toggle screen reader visibility of content other than the window manager.\n *\n * @private\n * @param {boolean} [isolate] Make only the window manager visible to screen readers\n * @chainable\n * @return {OO.ui.WindowManager} The manager, for chaining\n */\nOO.ui.WindowManager.prototype.toggleAriaIsolation = function ( isolate ) {\n\tvar $topLevelElement;\n\tisolate = isolate === undefined ? !this.$ariaHidden : !!isolate;\n\n\tif ( isolate ) {\n\t\tif ( !this.$ariaHidden ) {\n\t\t\t// Find the top level element containing the window manager or the\n\t\t\t// window manager's element itself in case its a direct child of body\n\t\t\t$topLevelElement = this.$element.parentsUntil( 'body' ).last();\n\t\t\t$topLevelElement = $topLevelElement.length === 0 ? this.$element : $topLevelElement;\n\n\t\t\t// In case previously set by another window manager\n\t\t\tthis.$element.removeAttr( 'aria-hidden' );\n\n\t\t\t// Hide everything other than the window manager from screen readers\n\t\t\tthis.$ariaHidden = $( document.body )\n\t\t\t\t.children()\n\t\t\t\t.not( 'script' )\n\t\t\t\t.not( $topLevelElement )\n\t\t\t\t.attr( 'aria-hidden', true );\n\t\t}\n\t} else if ( this.$ariaHidden ) {\n\t\t// Restore screen reader visibility\n\t\tthis.$ariaHidden.removeAttr( 'aria-hidden' );\n\t\tthis.$ariaHidden = null;\n\n\t\t// and hide the window manager\n\t\tthis.$element.attr( 'aria-hidden', true );\n\t}\n\n\treturn this;\n};\n\n/**\n * Destroy the window manager.\n *\n * Destroying the window manager ensures that it will no longer listen to events. If you would like to\n * continue using the window manager, but wish to remove all windows from it, use the #clearWindows method\n * instead.\n */\nOO.ui.WindowManager.prototype.destroy = function () {\n\tthis.toggleGlobalEvents( false );\n\tthis.toggleAriaIsolation( false );\n\tthis.clearWindows();\n\tthis.$element.remove();\n};\n","/**\n * A window is a container for elements that are in a child frame. They are used with\n * a window manager (OO.ui.WindowManager), which is used to open and close the window and control\n * its presentation. The size of a window is specified using a symbolic name (e.g., ‘small’, ‘medium’,\n * ‘large’), which is interpreted by the window manager. If the requested size is not recognized,\n * the window manager will choose a sensible fallback.\n *\n * The lifecycle of a window has three primary stages (opening, opened, and closing) in which\n * different processes are executed:\n *\n * **opening**: The opening stage begins when the window manager's {@link OO.ui.WindowManager#openWindow\n * openWindow} or the window's {@link #open open} methods are used, and the window manager begins to open\n * the window.\n *\n * - {@link #getSetupProcess} method is called and its result executed\n * - {@link #getReadyProcess} method is called and its result executed\n *\n * **opened**: The window is now open\n *\n * **closing**: The closing stage begins when the window manager's\n * {@link OO.ui.WindowManager#closeWindow closeWindow}\n * or the window's {@link #close} methods are used, and the window manager begins to close the window.\n *\n * - {@link #getHoldProcess} method is called and its result executed\n * - {@link #getTeardownProcess} method is called and its result executed. The window is now closed\n *\n * Each of the window's processes (setup, ready, hold, and teardown) can be extended in subclasses\n * by overriding the window's #getSetupProcess, #getReadyProcess, #getHoldProcess and #getTeardownProcess\n * methods. Note that each {@link OO.ui.Process process} is executed in series, so asynchronous\n * processing can complete. Always assume window processes are executed asynchronously.\n *\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows\n *\n * @abstract\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [size] Symbolic name of the dialog size: `small`, `medium`, `large`, `larger` or\n *  `full`.  If omitted, the value of the {@link #static-size static size} property will be used.\n */\nOO.ui.Window = function OoUiWindow( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Window.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.manager = null;\n\tthis.size = config.size || this.constructor.static.size;\n\tthis.$frame = $( '<div>' );\n\t/**\n\t * Overlay element to use for the `$overlay` configuration option of widgets that support it.\n\t * Things put inside of it are overlaid on top of the window and are not bound to its dimensions.\n\t * See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n\t *\n\t *     MyDialog.prototype.initialize = function () {\n\t *       ...\n\t *       var popupButton = new OO.ui.PopupButtonWidget( {\n\t *         $overlay: this.$overlay,\n\t *         label: 'Popup button',\n\t *         popup: {\n\t *           $content: $( '<p>Popup contents.</p><p>Popup contents.</p><p>Popup contents.</p>' ),\n\t *           padded: true\n\t *         }\n\t *       } );\n\t *       ...\n\t *     };\n\t *\n\t * @property {jQuery}\n\t */\n\tthis.$overlay = $( '<div>' );\n\tthis.$content = $( '<div>' );\n\n\tthis.$focusTrapBefore = $( '<div>' ).prop( 'tabIndex', 0 );\n\tthis.$focusTrapAfter = $( '<div>' ).prop( 'tabIndex', 0 );\n\tthis.$focusTraps = this.$focusTrapBefore.add( this.$focusTrapAfter );\n\n\t// Initialization\n\tthis.$overlay.addClass( 'oo-ui-window-overlay' );\n\tthis.$content\n\t\t.addClass( 'oo-ui-window-content' )\n\t\t.attr( 'tabindex', 0 );\n\tthis.$frame\n\t\t.addClass( 'oo-ui-window-frame' )\n\t\t.append( this.$focusTrapBefore, this.$content, this.$focusTrapAfter );\n\n\tthis.$element\n\t\t.addClass( 'oo-ui-window' )\n\t\t.append( this.$frame, this.$overlay );\n\n\t// Initially hidden - using #toggle may cause errors if subclasses override toggle with methods\n\t// that reference properties not initialized at that time of parent class construction\n\t// TODO: Find a better way to handle post-constructor setup\n\tthis.visible = false;\n\tthis.$element.addClass( 'oo-ui-element-hidden' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Window, OO.ui.Element );\nOO.mixinClass( OO.ui.Window, OO.EventEmitter );\n\n/* Static Properties */\n\n/**\n * Symbolic name of the window size: `small`, `medium`, `large`, `larger` or `full`.\n *\n * The static size is used if no #size is configured during construction.\n *\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Window.static.size = 'medium';\n\n/* Methods */\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.onMouseDown = function ( e ) {\n\t// Prevent clicking on the click-block from stealing focus\n\tif ( e.target === this.$element[ 0 ] ) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Check if the window has been initialized.\n *\n * Initialization occurs when a window is added to a manager.\n *\n * @return {boolean} Window has been initialized\n */\nOO.ui.Window.prototype.isInitialized = function () {\n\treturn !!this.manager;\n};\n\n/**\n * Check if the window is visible.\n *\n * @return {boolean} Window is visible\n */\nOO.ui.Window.prototype.isVisible = function () {\n\treturn this.visible;\n};\n\n/**\n * Check if the window is opening.\n *\n * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpening isOpening}\n * method.\n *\n * @return {boolean} Window is opening\n */\nOO.ui.Window.prototype.isOpening = function () {\n\treturn this.manager.isOpening( this );\n};\n\n/**\n * Check if the window is closing.\n *\n * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isClosing isClosing} method.\n *\n * @return {boolean} Window is closing\n */\nOO.ui.Window.prototype.isClosing = function () {\n\treturn this.manager.isClosing( this );\n};\n\n/**\n * Check if the window is opened.\n *\n * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpened isOpened} method.\n *\n * @return {boolean} Window is opened\n */\nOO.ui.Window.prototype.isOpened = function () {\n\treturn this.manager.isOpened( this );\n};\n\n/**\n * Get the window manager.\n *\n * All windows must be attached to a window manager, which is used to open\n * and close the window and control its presentation.\n *\n * @return {OO.ui.WindowManager} Manager of window\n */\nOO.ui.Window.prototype.getManager = function () {\n\treturn this.manager;\n};\n\n/**\n * Get the symbolic name of the window size (e.g., `small` or `medium`).\n *\n * @return {string} Symbolic name of the size: `small`, `medium`, `large`, `larger`, `full`\n */\nOO.ui.Window.prototype.getSize = function () {\n\tvar viewport = OO.ui.Element.static.getDimensions( this.getElementWindow() ),\n\t\tsizes = this.manager.constructor.static.sizes,\n\t\tsize = this.size;\n\n\tif ( !sizes[ size ] ) {\n\t\tsize = this.manager.constructor.static.defaultSize;\n\t}\n\tif ( size !== 'full' && viewport.rect.right - viewport.rect.left < sizes[ size ].width ) {\n\t\tsize = 'full';\n\t}\n\n\treturn size;\n};\n\n/**\n * Get the size properties associated with the current window size\n *\n * @return {Object} Size properties\n */\nOO.ui.Window.prototype.getSizeProperties = function () {\n\treturn this.manager.constructor.static.sizes[ this.getSize() ];\n};\n\n/**\n * Disable transitions on window's frame for the duration of the callback function, then enable them\n * back.\n *\n * @private\n * @param {Function} callback Function to call while transitions are disabled\n */\nOO.ui.Window.prototype.withoutSizeTransitions = function ( callback ) {\n\t// Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.\n\t// Disable transitions first, otherwise we'll get values from when the window was animating.\n\t// We need to build the transition CSS properties using these specific properties since\n\t// Firefox doesn't return anything useful when asked just for 'transition'.\n\tvar oldTransition = this.$frame.css( 'transition-property' ) + ' ' +\n\t\tthis.$frame.css( 'transition-duration' ) + ' ' +\n\t\tthis.$frame.css( 'transition-timing-function' ) + ' ' +\n\t\tthis.$frame.css( 'transition-delay' );\n\n\tthis.$frame.css( 'transition', 'none' );\n\tcallback();\n\n\t// Force reflow to make sure the style changes done inside callback\n\t// really are not transitioned\n\tthis.$frame.height();\n\tthis.$frame.css( 'transition', oldTransition );\n};\n\n/**\n * Get the height of the full window contents (i.e., the window head, body and foot together).\n *\n * What constitutes the head, body, and foot varies depending on the window type.\n * A {@link OO.ui.MessageDialog message dialog} displays a title and message in its body,\n * and any actions in the foot. A {@link OO.ui.ProcessDialog process dialog} displays a title\n * and special actions in the head, and dialog content in the body.\n *\n * To get just the height of the dialog body, use the #getBodyHeight method.\n *\n * @return {number} The height of the window contents (the dialog head, body and foot) in pixels\n */\nOO.ui.Window.prototype.getContentHeight = function () {\n\tvar bodyHeight,\n\t\twin = this,\n\t\tbodyStyleObj = this.$body[ 0 ].style,\n\t\tframeStyleObj = this.$frame[ 0 ].style;\n\n\t// Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.\n\t// Disable transitions first, otherwise we'll get values from when the window was animating.\n\tthis.withoutSizeTransitions( function () {\n\t\tvar oldHeight = frameStyleObj.height,\n\t\t\toldPosition = bodyStyleObj.position;\n\t\tframeStyleObj.height = '1px';\n\t\t// Force body to resize to new width\n\t\tbodyStyleObj.position = 'relative';\n\t\tbodyHeight = win.getBodyHeight();\n\t\tframeStyleObj.height = oldHeight;\n\t\tbodyStyleObj.position = oldPosition;\n\t} );\n\n\treturn (\n\t\t// Add buffer for border\n\t\t( this.$frame.outerHeight() - this.$frame.innerHeight() ) +\n\t\t// Use combined heights of children\n\t\t( this.$head.outerHeight( true ) + bodyHeight + this.$foot.outerHeight( true ) )\n\t);\n};\n\n/**\n * Get the height of the window body.\n *\n * To get the height of the full window contents (the window body, head, and foot together),\n * use #getContentHeight.\n *\n * When this function is called, the window will temporarily have been resized\n * to height=1px, so .scrollHeight measurements can be taken accurately.\n *\n * @return {number} Height of the window body in pixels\n */\nOO.ui.Window.prototype.getBodyHeight = function () {\n\treturn this.$body[ 0 ].scrollHeight;\n};\n\n/**\n * Get the directionality of the frame (right-to-left or left-to-right).\n *\n * @return {string} Directionality: `'ltr'` or `'rtl'`\n */\nOO.ui.Window.prototype.getDir = function () {\n\treturn OO.ui.Element.static.getDir( this.$content ) || 'ltr';\n};\n\n/**\n * Get the 'setup' process.\n *\n * The setup process is used to set up a window for use in a particular context, based on the `data`\n * argument. This method is called during the opening phase of the window’s lifecycle (before the\n * opening animation). You can add elements to the window in this process or set their default\n * values.\n *\n * Override this method to add additional steps to the ‘setup’ process the parent method provides\n * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods\n * of OO.ui.Process.\n *\n * To add window content that persists between openings, you may wish to use the #initialize method\n * instead.\n *\n * @param {Object} [data] Window opening data\n * @return {OO.ui.Process} Setup process\n */\nOO.ui.Window.prototype.getSetupProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Get the ‘ready’ process.\n *\n * The ready process is used to ready a window for use in a particular context, based on the `data`\n * argument. This method is called during the opening phase of the window’s lifecycle, after the\n * window has been {@link #getSetupProcess setup} (after the opening animation). You can focus\n * elements in the window in this process, or open their dropdowns.\n *\n * Override this method to add additional steps to the ‘ready’ process the parent method\n * provides using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next}\n * methods of OO.ui.Process.\n *\n * @param {Object} [data] Window opening data\n * @return {OO.ui.Process} Ready process\n */\nOO.ui.Window.prototype.getReadyProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Get the 'hold' process.\n *\n * The hold process is used to keep a window from being used in a particular context, based on the\n * `data` argument. This method is called during the closing phase of the window’s lifecycle (before\n * the closing animation). You can close dropdowns of elements in the window in this process, if\n * they do not get closed automatically.\n *\n * Override this method to add additional steps to the 'hold' process the parent method provides\n * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods\n * of OO.ui.Process.\n *\n * @param {Object} [data] Window closing data\n * @return {OO.ui.Process} Hold process\n */\nOO.ui.Window.prototype.getHoldProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Get the ‘teardown’ process.\n *\n * The teardown process is used to teardown a window after use. During teardown, user interactions\n * within the window are conveyed and the window is closed, based on the `data` argument. This\n * method is called during the closing phase of the window’s lifecycle (after the closing\n * animation). You can remove elements in the window in this process or clear their values.\n *\n * Override this method to add additional steps to the ‘teardown’ process the parent method provides\n * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods\n * of OO.ui.Process.\n *\n * @param {Object} [data] Window closing data\n * @return {OO.ui.Process} Teardown process\n */\nOO.ui.Window.prototype.getTeardownProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Set the window manager.\n *\n * This will cause the window to initialize. Calling it more than once will cause an error.\n *\n * @param {OO.ui.WindowManager} manager Manager for this window\n * @throws {Error} An error is thrown if the method is called more than once\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.setManager = function ( manager ) {\n\tif ( this.manager ) {\n\t\tthrow new Error( 'Cannot set window manager, window already has a manager' );\n\t}\n\n\tthis.manager = manager;\n\tthis.initialize();\n\n\treturn this;\n};\n\n/**\n * Set the window size by symbolic name (e.g., 'small' or 'medium')\n *\n * @param {string} size Symbolic name of size: `small`, `medium`, `large`, `larger` or\n *  `full`\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.setSize = function ( size ) {\n\tthis.size = size;\n\tthis.updateSize();\n\treturn this;\n};\n\n/**\n * Update the window size.\n *\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.updateSize = function () {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot update window size, must be attached to a manager' );\n\t}\n\n\tthis.manager.updateWindowSize( this );\n\n\treturn this;\n};\n\n/**\n * Set window dimensions. This method is called by the {@link OO.ui.WindowManager window manager}\n * when the window is opening. In general, setDimensions should not be called directly.\n *\n * To set the size of the window, use the #setSize method.\n *\n * @param {Object} dim CSS dimension properties\n * @param {string|number} [dim.width] Width\n * @param {string|number} [dim.minWidth] Minimum width\n * @param {string|number} [dim.maxWidth] Maximum width\n * @param {string|number} [dim.height] Height, omit to set based on height of contents\n * @param {string|number} [dim.minHeight] Minimum height\n * @param {string|number} [dim.maxHeight] Maximum height\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.setDimensions = function ( dim ) {\n\tvar height,\n\t\twin = this,\n\t\tstyleObj = this.$frame[ 0 ].style;\n\n\t// Calculate the height we need to set using the correct width\n\tif ( dim.height === undefined ) {\n\t\tthis.withoutSizeTransitions( function () {\n\t\t\tvar oldWidth = styleObj.width;\n\t\t\twin.$frame.css( 'width', dim.width || '' );\n\t\t\theight = win.getContentHeight();\n\t\t\tstyleObj.width = oldWidth;\n\t\t} );\n\t} else {\n\t\theight = dim.height;\n\t}\n\n\tthis.$frame.css( {\n\t\twidth: dim.width || '',\n\t\tminWidth: dim.minWidth || '',\n\t\tmaxWidth: dim.maxWidth || '',\n\t\theight: height || '',\n\t\tminHeight: dim.minHeight || '',\n\t\tmaxHeight: dim.maxHeight || ''\n\t} );\n\n\treturn this;\n};\n\n/**\n * Initialize window contents.\n *\n * Before the window is opened for the first time, #initialize is called so that content that\n * persists between openings can be added to the window.\n *\n * To set up a window with new content each time the window opens, use #getSetupProcess.\n *\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.initialize = function () {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot initialize window, must be attached to a manager' );\n\t}\n\n\t// Properties\n\tthis.$head = $( '<div>' );\n\tthis.$body = $( '<div>' );\n\tthis.$foot = $( '<div>' );\n\tthis.$document = $( this.getElementDocument() );\n\n\t// Events\n\tthis.$element.on( 'mousedown', this.onMouseDown.bind( this ) );\n\n\t// Initialization\n\tthis.$head.addClass( 'oo-ui-window-head' );\n\tthis.$body.addClass( 'oo-ui-window-body' );\n\tthis.$foot.addClass( 'oo-ui-window-foot' );\n\tthis.$content.append( this.$head, this.$body, this.$foot );\n\n\treturn this;\n};\n\n/**\n * Called when someone tries to focus the hidden element at the end of the dialog.\n * Sends focus back to the start of the dialog.\n *\n * @param {jQuery.Event} event Focus event\n */\nOO.ui.Window.prototype.onFocusTrapFocused = function ( event ) {\n\tvar backwards = this.$focusTrapBefore.is( event.target ),\n\t\telement = OO.ui.findFocusable( this.$content, backwards );\n\tif ( element ) {\n\t\t// There's a focusable element inside the content, at the front or\n\t\t// back depending on which focus trap we hit; select it.\n\t\telement.focus();\n\t} else {\n\t\t// There's nothing focusable inside the content. As a fallback,\n\t\t// this.$content is focusable, and focusing it will keep our focus\n\t\t// properly trapped. It's not a *meaningful* focus, since it's just\n\t\t// the content-div for the Window, but it's better than letting focus\n\t\t// escape into the page.\n\t\tthis.$content.trigger( 'focus' );\n\t}\n};\n\n/**\n * Open the window.\n *\n * This method is a wrapper around a call to the window\n * manager’s {@link OO.ui.WindowManager#openWindow openWindow} method.\n *\n * To customize the window each time it opens, use #getSetupProcess or #getReadyProcess.\n *\n * @param {Object} [data] Window opening data\n * @return {OO.ui.WindowInstance} See OO.ui.WindowManager#openWindow\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n */\nOO.ui.Window.prototype.open = function ( data ) {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot open window, must be attached to a manager' );\n\t}\n\n\treturn this.manager.openWindow( this, data );\n};\n\n/**\n * Close the window.\n *\n * This method is a wrapper around a call to the window\n * manager’s {@link OO.ui.WindowManager#closeWindow closeWindow} method.\n *\n * The window's #getHoldProcess and #getTeardownProcess methods are called during the closing\n * phase of the window’s lifecycle and can be used to specify closing behavior each time\n * the window closes.\n *\n * @param {Object} [data] Window closing data\n * @return {OO.ui.WindowInstance} See OO.ui.WindowManager#closeWindow\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n */\nOO.ui.Window.prototype.close = function ( data ) {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot close window, must be attached to a manager' );\n\t}\n\n\treturn this.manager.closeWindow( this, data );\n};\n\n/**\n * Setup window.\n *\n * This is called by OO.ui.WindowManager during window opening (before the animation), and should\n * not be called directly by other systems.\n *\n * @param {Object} [data] Window opening data\n * @return {jQuery.Promise} Promise resolved when window is setup\n */\nOO.ui.Window.prototype.setup = function ( data ) {\n\tvar win = this;\n\n\tthis.toggle( true );\n\n\tthis.focusTrapHandler = OO.ui.bind( this.onFocusTrapFocused, this );\n\tthis.$focusTraps.on( 'focus', this.focusTrapHandler );\n\n\treturn this.getSetupProcess( data ).execute().then( function () {\n\t\twin.updateSize();\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.addClass( 'oo-ui-window-active oo-ui-window-setup' ).width();\n\t\twin.$content.addClass( 'oo-ui-window-content-setup' ).width();\n\t} );\n};\n\n/**\n * Ready window.\n *\n * This is called by OO.ui.WindowManager during window opening (after the animation), and should not\n * be called directly by other systems.\n *\n * @param {Object} [data] Window opening data\n * @return {jQuery.Promise} Promise resolved when window is ready\n */\nOO.ui.Window.prototype.ready = function ( data ) {\n\tvar win = this;\n\n\tthis.$content.trigger( 'focus' );\n\treturn this.getReadyProcess( data ).execute().then( function () {\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.addClass( 'oo-ui-window-ready' ).width();\n\t\twin.$content.addClass( 'oo-ui-window-content-ready' ).width();\n\t} );\n};\n\n/**\n * Hold window.\n *\n * This is called by OO.ui.WindowManager during window closing (before the animation), and should\n * not be called directly by other systems.\n *\n * @param {Object} [data] Window closing data\n * @return {jQuery.Promise} Promise resolved when window is held\n */\nOO.ui.Window.prototype.hold = function ( data ) {\n\tvar win = this;\n\n\treturn this.getHoldProcess( data ).execute().then( function () {\n\t\t// Get the focused element within the window's content\n\t\tvar $focus = win.$content.find( OO.ui.Element.static.getDocument( win.$content ).activeElement );\n\n\t\t// Blur the focused element\n\t\tif ( $focus.length ) {\n\t\t\t$focus[ 0 ].blur();\n\t\t}\n\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.removeClass( 'oo-ui-window-ready oo-ui-window-setup' ).width();\n\t\twin.$content.removeClass( 'oo-ui-window-content-ready oo-ui-window-content-setup' ).width();\n\t} );\n};\n\n/**\n * Teardown window.\n *\n * This is called by OO.ui.WindowManager during window closing (after the animation), and should not be called directly\n * by other systems.\n *\n * @param {Object} [data] Window closing data\n * @return {jQuery.Promise} Promise resolved when window is torn down\n */\nOO.ui.Window.prototype.teardown = function ( data ) {\n\tvar win = this;\n\n\treturn this.getTeardownProcess( data ).execute().then( function () {\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.removeClass( 'oo-ui-window-active' ).width();\n\n\t\twin.$focusTraps.off( 'focus', win.focusTrapHandler );\n\t\twin.toggle( false );\n\t} );\n};\n","/**\n * The Dialog class serves as the base class for the other types of dialogs.\n * Unless extended to include controls, the rendered dialog box is a simple window\n * that users can close by hitting the ‘Esc’ key. Dialog windows are used with OO.ui.WindowManager,\n * which opens, closes, and controls the presentation of the window. See the\n * [OOUI documentation on MediaWiki] [1] for more information.\n *\n *     @example\n *     // A simple dialog window.\n *     function MyDialog( config ) {\n *         MyDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MyDialog, OO.ui.Dialog );\n *     MyDialog.static.name = 'myDialog';\n *     MyDialog.prototype.initialize = function () {\n *         MyDialog.parent.prototype.initialize.call( this );\n *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.content.$element.append( '<p>A simple dialog window. Press \\'Esc\\' to close.</p>' );\n *         this.$body.append( this.content.$element );\n *     };\n *     MyDialog.prototype.getBodyHeight = function () {\n *         return this.content.$element.outerHeight( true );\n *     };\n *     var myDialog = new MyDialog( {\n *         size: 'medium'\n *     } );\n *     // Create and append a window manager, which opens and closes the window.\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *     windowManager.addWindows( [ myDialog ] );\n *     // Open the window!\n *     windowManager.openWindow( myDialog );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Dialogs\n *\n * @abstract\n * @class\n * @extends OO.ui.Window\n * @mixins OO.ui.mixin.PendingElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.Dialog = function OoUiDialog( config ) {\n\t// Parent constructor\n\tOO.ui.Dialog.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PendingElement.call( this );\n\n\t// Properties\n\tthis.actions = new OO.ui.ActionSet();\n\tthis.attachedActions = [];\n\tthis.currentAction = null;\n\tthis.onDialogKeyDownHandler = this.onDialogKeyDown.bind( this );\n\n\t// Events\n\tthis.actions.connect( this, {\n\t\tclick: 'onActionClick',\n\t\tchange: 'onActionsChange'\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-dialog' )\n\t\t.attr( 'role', 'dialog' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Dialog, OO.ui.Window );\nOO.mixinClass( OO.ui.Dialog, OO.ui.mixin.PendingElement );\n\n/* Static Properties */\n\n/**\n * Symbolic name of dialog.\n *\n * The dialog class must have a symbolic name in order to be registered with OO.Factory.\n * Please see the [OOUI documentation on MediaWiki] [3] for more information.\n *\n * [3]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Dialog.static.name = '';\n\n/**\n * The dialog title.\n *\n * The title can be specified as a plaintext string, a {@link OO.ui.mixin.LabelElement Label} node, or a function\n * that will produce a Label node or string. The title can also be specified with data passed to the\n * constructor (see #getSetupProcess). In this case, the static value will be overridden.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {jQuery|string|Function}\n */\nOO.ui.Dialog.static.title = '';\n\n/**\n * An array of configured {@link OO.ui.ActionWidget action widgets}.\n *\n * Actions can also be specified with data passed to the constructor (see #getSetupProcess). In this case, the static\n * value will be overridden.\n *\n * [2]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets\n *\n * @static\n * @inheritable\n * @property {Object[]}\n */\nOO.ui.Dialog.static.actions = [];\n\n/**\n * Close the dialog when the 'Esc' key is pressed.\n *\n * @static\n * @abstract\n * @inheritable\n * @property {boolean}\n */\nOO.ui.Dialog.static.escapable = true;\n\n/* Methods */\n\n/**\n * Handle frame document key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.Dialog.prototype.onDialogKeyDown = function ( e ) {\n\tvar actions;\n\tif ( e.which === OO.ui.Keys.ESCAPE && this.constructor.static.escapable ) {\n\t\tthis.executeAction( '' );\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t} else if ( e.which === OO.ui.Keys.ENTER && ( e.ctrlKey || e.metaKey ) ) {\n\t\tactions = this.actions.get( { flags: 'primary', visible: true, disabled: false } );\n\t\tif ( actions.length > 0 ) {\n\t\t\tthis.executeAction( actions[ 0 ].getAction() );\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t}\n\t}\n};\n\n/**\n * Handle action click events.\n *\n * @private\n * @param {OO.ui.ActionWidget} action Action that was clicked\n */\nOO.ui.Dialog.prototype.onActionClick = function ( action ) {\n\tif ( !this.isPending() ) {\n\t\tthis.executeAction( action.getAction() );\n\t}\n};\n\n/**\n * Handle actions change event.\n *\n * @private\n */\nOO.ui.Dialog.prototype.onActionsChange = function () {\n\tthis.detachActions();\n\tif ( !this.isClosing() ) {\n\t\tthis.attachActions();\n\t\tif ( !this.isOpening() ) {\n\t\t\t// If the dialog is currently opening, this will be called automatically soon.\n\t\t\tthis.updateSize();\n\t\t}\n\t}\n};\n\n/**\n * Get the set of actions used by the dialog.\n *\n * @return {OO.ui.ActionSet}\n */\nOO.ui.Dialog.prototype.getActions = function () {\n\treturn this.actions;\n};\n\n/**\n * Get a process for taking action.\n *\n * When you override this method, you can create a new OO.ui.Process and return it, or add additional\n * accept steps to the process the parent method provides using the {@link OO.ui.Process#first 'first'}\n * and {@link OO.ui.Process#next 'next'} methods of OO.ui.Process.\n *\n * @param {string} [action] Symbolic name of action\n * @return {OO.ui.Process} Action process\n */\nOO.ui.Dialog.prototype.getActionProcess = function ( action ) {\n\treturn new OO.ui.Process()\n\t\t.next( function () {\n\t\t\tif ( !action ) {\n\t\t\t\t// An empty action always closes the dialog without data, which should always be\n\t\t\t\t// safe and make no changes\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n *\n * @param {Object} [data] Dialog opening data\n * @param {jQuery|string|Function|null} [data.title] Dialog title, omit to use\n *  the {@link #static-title static title}\n * @param {Object[]} [data.actions] List of configuration options for each\n *   {@link OO.ui.ActionWidget action widget}, omit to use {@link #static-actions static actions}.\n */\nOO.ui.Dialog.prototype.getSetupProcess = function ( data ) {\n\tdata = data || {};\n\n\t// Parent method\n\treturn OO.ui.Dialog.parent.prototype.getSetupProcess.call( this, data )\n\t\t.next( function () {\n\t\t\tvar config = this.constructor.static,\n\t\t\t\tactions = data.actions !== undefined ? data.actions : config.actions,\n\t\t\t\ttitle = data.title !== undefined ? data.title : config.title;\n\n\t\t\tthis.title.setLabel( title ).setTitle( title );\n\t\t\tthis.actions.add( this.getActionWidgets( actions ) );\n\n\t\t\tthis.$element.on( 'keydown', this.onDialogKeyDownHandler );\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.Dialog.prototype.getTeardownProcess = function ( data ) {\n\t// Parent method\n\treturn OO.ui.Dialog.parent.prototype.getTeardownProcess.call( this, data )\n\t\t.first( function () {\n\t\t\tthis.$element.off( 'keydown', this.onDialogKeyDownHandler );\n\n\t\t\tthis.actions.clear();\n\t\t\tthis.currentAction = null;\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.Dialog.prototype.initialize = function () {\n\t// Parent method\n\tOO.ui.Dialog.parent.prototype.initialize.call( this );\n\n\t// Properties\n\tthis.title = new OO.ui.LabelWidget();\n\n\t// Initialization\n\tthis.$content.addClass( 'oo-ui-dialog-content' );\n\tthis.$element.attr( 'aria-labelledby', this.title.getElementId() );\n\tthis.setPendingElement( this.$head );\n};\n\n/**\n * Get action widgets from a list of configs\n *\n * @param {Object[]} actions Action widget configs\n * @return {OO.ui.ActionWidget[]} Action widgets\n */\nOO.ui.Dialog.prototype.getActionWidgets = function ( actions ) {\n\tvar i, len, widgets = [];\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\twidgets.push( this.getActionWidget( actions[ i ] ) );\n\t}\n\treturn widgets;\n};\n\n/**\n * Get action widget from config\n *\n * Override this method to change the action widget class used.\n *\n * @param {Object} config Action widget config\n * @return {OO.ui.ActionWidget} Action widget\n */\nOO.ui.Dialog.prototype.getActionWidget = function ( config ) {\n\treturn new OO.ui.ActionWidget( this.getActionWidgetConfig( config ) );\n};\n\n/**\n * Get action widget config\n *\n * Override this method to modify the action widget config\n *\n * @param {Object} config Initial action widget config\n * @return {Object} Action widget config\n */\nOO.ui.Dialog.prototype.getActionWidgetConfig = function ( config ) {\n\treturn config;\n};\n\n/**\n * Attach action actions.\n *\n * @protected\n */\nOO.ui.Dialog.prototype.attachActions = function () {\n\t// Remember the list of potentially attached actions\n\tthis.attachedActions = this.actions.get();\n};\n\n/**\n * Detach action actions.\n *\n * @protected\n * @chainable\n * @return {OO.ui.Dialog} The dialog, for chaining\n */\nOO.ui.Dialog.prototype.detachActions = function () {\n\tvar i, len;\n\n\t// Detach all actions that may have been previously attached\n\tfor ( i = 0, len = this.attachedActions.length; i < len; i++ ) {\n\t\tthis.attachedActions[ i ].$element.detach();\n\t}\n\tthis.attachedActions = [];\n\n\treturn this;\n};\n\n/**\n * Execute an action.\n *\n * @param {string} action Symbolic name of action to execute\n * @return {jQuery.Promise} Promise resolved when action completes, rejected if it fails\n */\nOO.ui.Dialog.prototype.executeAction = function ( action ) {\n\tthis.pushPending();\n\tthis.currentAction = action;\n\treturn this.getActionProcess( action ).execute()\n\t\t.always( this.popPending.bind( this ) );\n};\n","/**\n * MessageDialogs display a confirmation or alert message. By default, the rendered dialog box\n * consists of a header that contains the dialog title, a body with the message, and a footer that\n * contains any {@link OO.ui.ActionWidget action widgets}. The MessageDialog class is the only type\n * of {@link OO.ui.Dialog dialog} that is usually instantiated directly.\n *\n * There are two basic types of message dialogs, confirmation and alert:\n *\n * - **confirmation**: the dialog title describes what a progressive action will do and the message provides\n *  more details about the consequences.\n * - **alert**: the dialog title describes which event occurred and the message provides more information\n *  about why the event occurred.\n *\n * The MessageDialog class specifies two actions: ‘accept’, the primary\n * action (e.g., ‘ok’) and ‘reject,’ the safe action (e.g., ‘cancel’). Both will close the window,\n * passing along the selected action.\n *\n * For more information and examples, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Example: Creating and opening a message dialog window.\n *     var messageDialog = new OO.ui.MessageDialog();\n *\n *     // Create and append a window manager.\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *     windowManager.addWindows( [ messageDialog ] );\n *     // Open the window.\n *     windowManager.openWindow( messageDialog, {\n *         title: 'Basic message dialog',\n *         message: 'This is the message'\n *     } );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Message_Dialogs\n *\n * @class\n * @extends OO.ui.Dialog\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.MessageDialog = function OoUiMessageDialog( config ) {\n\t// Parent constructor\n\tOO.ui.MessageDialog.parent.call( this, config );\n\n\t// Properties\n\tthis.verticalActionLayout = null;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-messageDialog' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MessageDialog, OO.ui.Dialog );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MessageDialog.static.name = 'message';\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MessageDialog.static.size = 'small';\n\n/**\n * Dialog title.\n *\n * The title of a confirmation dialog describes what a progressive action will do. The\n * title of an alert dialog describes which event occurred.\n *\n * @static\n * @inheritable\n * @property {jQuery|string|Function|null}\n */\nOO.ui.MessageDialog.static.title = null;\n\n/**\n * The message displayed in the dialog body.\n *\n * A confirmation message describes the consequences of a progressive action. An alert\n * message describes why an event occurred.\n *\n * @static\n * @inheritable\n * @property {jQuery|string|Function|null}\n */\nOO.ui.MessageDialog.static.message = null;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MessageDialog.static.actions = [\n\t// Note that OO.ui.alert() and OO.ui.confirm() rely on these.\n\t{ action: 'accept', label: OO.ui.deferMsg( 'ooui-dialog-message-accept' ), flags: 'primary' },\n\t{ action: 'reject', label: OO.ui.deferMsg( 'ooui-dialog-message-reject' ), flags: 'safe' }\n];\n\n/* Methods */\n\n/**\n * Toggle action layout between vertical and horizontal.\n *\n * @private\n * @param {boolean} [value] Layout actions vertically, omit to toggle\n * @chainable\n * @return {OO.ui.MessageDialog} The dialog, for chaining\n */\nOO.ui.MessageDialog.prototype.toggleVerticalActionLayout = function ( value ) {\n\tvalue = value === undefined ? !this.verticalActionLayout : !!value;\n\n\tif ( value !== this.verticalActionLayout ) {\n\t\tthis.verticalActionLayout = value;\n\t\tthis.$actions\n\t\t\t.toggleClass( 'oo-ui-messageDialog-actions-vertical', value )\n\t\t\t.toggleClass( 'oo-ui-messageDialog-actions-horizontal', !value );\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getActionProcess = function ( action ) {\n\tif ( action ) {\n\t\treturn new OO.ui.Process( function () {\n\t\t\tthis.close( { action: action } );\n\t\t}, this );\n\t}\n\treturn OO.ui.MessageDialog.parent.prototype.getActionProcess.call( this, action );\n};\n\n/**\n * @inheritdoc\n *\n * @param {Object} [data] Dialog opening data\n * @param {jQuery|string|Function|null} [data.title] Description of the action being confirmed\n * @param {jQuery|string|Function|null} [data.message] Description of the action's consequence\n * @param {string} [data.size] Symbolic name of the dialog size, see OO.ui.Window\n * @param {Object[]} [data.actions] List of OO.ui.ActionOptionWidget configuration options for each\n *   action item\n */\nOO.ui.MessageDialog.prototype.getSetupProcess = function ( data ) {\n\tdata = data || {};\n\n\t// Parent method\n\treturn OO.ui.MessageDialog.parent.prototype.getSetupProcess.call( this, data )\n\t\t.next( function () {\n\t\t\tthis.title.setLabel(\n\t\t\t\tdata.title !== undefined ? data.title : this.constructor.static.title\n\t\t\t);\n\t\t\tthis.message.setLabel(\n\t\t\t\tdata.message !== undefined ? data.message : this.constructor.static.message\n\t\t\t);\n\t\t\tthis.size = data.size !== undefined ? data.size : this.constructor.static.size;\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getReadyProcess = function ( data ) {\n\tdata = data || {};\n\n\t// Parent method\n\treturn OO.ui.MessageDialog.parent.prototype.getReadyProcess.call( this, data )\n\t\t.next( function () {\n\t\t\t// Focus the primary action button\n\t\t\tvar actions = this.actions.get();\n\t\t\tactions = actions.filter( function ( action ) {\n\t\t\t\treturn action.getFlags().indexOf( 'primary' ) > -1;\n\t\t\t} );\n\t\t\tif ( actions.length > 0 ) {\n\t\t\t\tactions[ 0 ].focus();\n\t\t\t}\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getBodyHeight = function () {\n\tvar bodyHeight, oldOverflow,\n\t\t$scrollable = this.container.$element;\n\n\toldOverflow = $scrollable[ 0 ].style.overflow;\n\t$scrollable[ 0 ].style.overflow = 'hidden';\n\n\tOO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );\n\n\tbodyHeight = this.text.$element.outerHeight( true );\n\t$scrollable[ 0 ].style.overflow = oldOverflow;\n\n\treturn bodyHeight;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.setDimensions = function ( dim ) {\n\tvar\n\t\tdialog = this,\n\t\t$scrollable = this.container.$element;\n\tOO.ui.MessageDialog.parent.prototype.setDimensions.call( this, dim );\n\n\t// Twiddle the overflow property, otherwise an unnecessary scrollbar will be produced.\n\t// Need to do it after transition completes (250ms), add 50ms just in case.\n\tsetTimeout( function () {\n\t\tvar oldOverflow = $scrollable[ 0 ].style.overflow,\n\t\t\tactiveElement = document.activeElement;\n\n\t\t$scrollable[ 0 ].style.overflow = 'hidden';\n\n\t\tOO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );\n\n\t\t// Check reconsiderScrollbars didn't destroy our focus, as we\n\t\t// are doing this after the ready process.\n\t\tif ( activeElement && activeElement !== document.activeElement && activeElement.focus ) {\n\t\t\tactiveElement.focus();\n\t\t}\n\n\t\t$scrollable[ 0 ].style.overflow = oldOverflow;\n\t}, 300 );\n\n\tdialog.fitActions();\n\t// Wait for CSS transition to finish and do it again :(\n\tsetTimeout( function () {\n\t\tdialog.fitActions();\n\t}, 300 );\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.initialize = function () {\n\t// Parent method\n\tOO.ui.MessageDialog.parent.prototype.initialize.call( this );\n\n\t// Properties\n\tthis.$actions = $( '<div>' );\n\tthis.container = new OO.ui.PanelLayout( {\n\t\tscrollable: true, classes: [ 'oo-ui-messageDialog-container' ]\n\t} );\n\tthis.text = new OO.ui.PanelLayout( {\n\t\tpadded: true, expanded: false, classes: [ 'oo-ui-messageDialog-text' ]\n\t} );\n\tthis.message = new OO.ui.LabelWidget( {\n\t\tclasses: [ 'oo-ui-messageDialog-message' ]\n\t} );\n\n\t// Initialization\n\tthis.title.$element.addClass( 'oo-ui-messageDialog-title' );\n\tthis.$content.addClass( 'oo-ui-messageDialog-content' );\n\tthis.container.$element.append( this.text.$element );\n\tthis.text.$element.append( this.title.$element, this.message.$element );\n\tthis.$body.append( this.container.$element );\n\tthis.$actions.addClass( 'oo-ui-messageDialog-actions' );\n\tthis.$foot.append( this.$actions );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getActionWidgetConfig = function ( config ) {\n\t// Force unframed\n\treturn $.extend( {}, config, { framed: false } );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.attachActions = function () {\n\tvar i, len, special, others;\n\n\t// Parent method\n\tOO.ui.MessageDialog.parent.prototype.attachActions.call( this );\n\n\tspecial = this.actions.getSpecial();\n\tothers = this.actions.getOthers();\n\n\tif ( special.safe ) {\n\t\tthis.$actions.append( special.safe.$element );\n\t\tspecial.safe.toggleFramed( true );\n\t}\n\tfor ( i = 0, len = others.length; i < len; i++ ) {\n\t\tthis.$actions.append( others[ i ].$element );\n\t\tothers[ i ].toggleFramed( true );\n\t}\n\tif ( special.primary ) {\n\t\tthis.$actions.append( special.primary.$element );\n\t\tspecial.primary.toggleFramed( true );\n\t}\n};\n\n/**\n * Fit action actions into columns or rows.\n *\n * Columns will be used if all labels can fit without overflow, otherwise rows will be used.\n *\n * @private\n */\nOO.ui.MessageDialog.prototype.fitActions = function () {\n\tvar i, len, action,\n\t\tprevious = this.verticalActionLayout,\n\t\tactions = this.actions.get();\n\n\t// Detect clipping\n\tthis.toggleVerticalActionLayout( false );\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\taction = actions[ i ];\n\t\tif ( action.$element[ 0 ].scrollWidth > action.$element[ 0 ].clientWidth ) {\n\t\t\tthis.toggleVerticalActionLayout( true );\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Move the body out of the way of the foot\n\tthis.$body.css( 'bottom', this.$foot.outerHeight( true ) );\n\n\tif ( this.verticalActionLayout !== previous ) {\n\t\t// We changed the layout, window height might need to be updated.\n\t\tthis.updateSize();\n\t}\n};\n","/**\n * ProcessDialog windows encapsulate a {@link OO.ui.Process process} and all of the code necessary\n * to complete it. If the process terminates with an error, a customizable {@link OO.ui.Error error\n * interface} alerts users to the trouble, permitting the user to dismiss the error and try again when\n * relevant. The ProcessDialog class is always extended and customized with the actions and content\n * required for each process.\n *\n * The process dialog box consists of a header that visually represents the ‘working’ state of long\n * processes with an animation. The header contains the dialog title as well as\n * two {@link OO.ui.ActionWidget action widgets}:  a ‘safe’ action on the left (e.g., ‘Cancel’) and\n * a ‘primary’ action on the right (e.g., ‘Done’).\n *\n * Like other windows, the process dialog is managed by a {@link OO.ui.WindowManager window manager}.\n * Please see the [OOUI documentation on MediaWiki][1] for more information and examples.\n *\n *     @example\n *     // Example: Creating and opening a process dialog window.\n *     function MyProcessDialog( config ) {\n *         MyProcessDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );\n *\n *     MyProcessDialog.static.name = 'myProcessDialog';\n *     MyProcessDialog.static.title = 'Process dialog';\n *     MyProcessDialog.static.actions = [\n *         { action: 'save', label: 'Done', flags: 'primary' },\n *         { label: 'Cancel', flags: 'safe' }\n *     ];\n *\n *     MyProcessDialog.prototype.initialize = function () {\n *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );\n *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.content.$element.append( '<p>This is a process dialog window. The header contains the title and two buttons: \\'Cancel\\' (a safe action) on the left and \\'Done\\' (a primary action)  on the right.</p>' );\n *         this.$body.append( this.content.$element );\n *     };\n *     MyProcessDialog.prototype.getActionProcess = function ( action ) {\n *         var dialog = this;\n *         if ( action ) {\n *             return new OO.ui.Process( function () {\n *                 dialog.close( { action: action } );\n *             } );\n *         }\n *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );\n *     };\n *\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *\n *     var dialog = new MyProcessDialog();\n *     windowManager.addWindows( [ dialog ] );\n *     windowManager.openWindow( dialog );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n *\n * @abstract\n * @class\n * @extends OO.ui.Dialog\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ProcessDialog = function OoUiProcessDialog( config ) {\n\t// Parent constructor\n\tOO.ui.ProcessDialog.parent.call( this, config );\n\n\t// Properties\n\tthis.fitOnOpen = false;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-processDialog' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ProcessDialog, OO.ui.Dialog );\n\n/* Methods */\n\n/**\n * Handle dismiss button click events.\n *\n * Hides errors.\n *\n * @private\n */\nOO.ui.ProcessDialog.prototype.onDismissErrorButtonClick = function () {\n\tthis.hideErrors();\n};\n\n/**\n * Handle retry button click events.\n *\n * Hides errors and then tries again.\n *\n * @private\n */\nOO.ui.ProcessDialog.prototype.onRetryButtonClick = function () {\n\tthis.hideErrors();\n\tthis.executeAction( this.currentAction );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.initialize = function () {\n\t// Parent method\n\tOO.ui.ProcessDialog.parent.prototype.initialize.call( this );\n\n\t// Properties\n\tthis.$navigation = $( '<div>' );\n\tthis.$location = $( '<div>' );\n\tthis.$safeActions = $( '<div>' );\n\tthis.$primaryActions = $( '<div>' );\n\tthis.$otherActions = $( '<div>' );\n\tthis.dismissButton = new OO.ui.ButtonWidget( {\n\t\tlabel: OO.ui.msg( 'ooui-dialog-process-dismiss' )\n\t} );\n\tthis.retryButton = new OO.ui.ButtonWidget();\n\tthis.$errors = $( '<div>' );\n\tthis.$errorsTitle = $( '<div>' );\n\n\t// Events\n\tthis.dismissButton.connect( this, { click: 'onDismissErrorButtonClick' } );\n\tthis.retryButton.connect( this, { click: 'onRetryButtonClick' } );\n\tthis.title.connect( this, { labelChange: 'fitLabel' } );\n\n\t// Initialization\n\tthis.title.$element.addClass( 'oo-ui-processDialog-title' );\n\tthis.$location\n\t\t.append( this.title.$element )\n\t\t.addClass( 'oo-ui-processDialog-location' );\n\tthis.$safeActions.addClass( 'oo-ui-processDialog-actions-safe' );\n\tthis.$primaryActions.addClass( 'oo-ui-processDialog-actions-primary' );\n\tthis.$otherActions.addClass( 'oo-ui-processDialog-actions-other' );\n\tthis.$errorsTitle\n\t\t.addClass( 'oo-ui-processDialog-errors-title' )\n\t\t.text( OO.ui.msg( 'ooui-dialog-process-error' ) );\n\tthis.$errors\n\t\t.addClass( 'oo-ui-processDialog-errors oo-ui-element-hidden' )\n\t\t.append( this.$errorsTitle, this.dismissButton.$element, this.retryButton.$element );\n\tthis.$content\n\t\t.addClass( 'oo-ui-processDialog-content' )\n\t\t.append( this.$errors );\n\tthis.$navigation\n\t\t.addClass( 'oo-ui-processDialog-navigation' )\n\t\t// Note: Order of appends below is important. These are in the order\n\t\t// we want tab to go through them. Display-order is handled entirely\n\t\t// by CSS absolute-positioning. As such, primary actions like \"done\"\n\t\t// should go first.\n\t\t.append( this.$primaryActions, this.$location, this.$safeActions );\n\tthis.$head.append( this.$navigation );\n\tthis.$foot.append( this.$otherActions );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.getActionWidgetConfig = function ( config ) {\n\tvar isMobile = OO.ui.isMobile();\n\n\t// Default to unframed on mobile\n\tconfig = $.extend( { framed: !isMobile }, config );\n\t// Change back buttons to icon only on mobile\n\tif (\n\t\tisMobile &&\n\t\t( config.flags === 'back' || ( Array.isArray( config.flags ) && config.flags.indexOf( 'back' ) !== -1 ) )\n\t) {\n\t\t$.extend( config, {\n\t\t\ticon: 'previous',\n\t\t\tlabel: ''\n\t\t} );\n\t}\n\n\treturn config;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.attachActions = function () {\n\tvar i, len, other, special, others;\n\n\t// Parent method\n\tOO.ui.ProcessDialog.parent.prototype.attachActions.call( this );\n\n\tspecial = this.actions.getSpecial();\n\tothers = this.actions.getOthers();\n\tif ( special.primary ) {\n\t\tthis.$primaryActions.append( special.primary.$element );\n\t}\n\tfor ( i = 0, len = others.length; i < len; i++ ) {\n\t\tother = others[ i ];\n\t\tthis.$otherActions.append( other.$element );\n\t}\n\tif ( special.safe ) {\n\t\tthis.$safeActions.append( special.safe.$element );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.executeAction = function ( action ) {\n\tvar process = this;\n\treturn OO.ui.ProcessDialog.parent.prototype.executeAction.call( this, action )\n\t\t.fail( function ( errors ) {\n\t\t\tprocess.showErrors( errors || [] );\n\t\t} );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.setDimensions = function () {\n\tvar dialog = this;\n\n\t// Parent method\n\tOO.ui.ProcessDialog.parent.prototype.setDimensions.apply( this, arguments );\n\n\tthis.fitLabel();\n\n\t// If there are many actions, they might be shown on multiple lines. Their layout can change when\n\t// resizing the dialog and when changing the actions. Adjust the height of the footer to fit them.\n\tdialog.$body.css( 'bottom', dialog.$foot.outerHeight( true ) );\n\t// Wait for CSS transition to finish and do it again :(\n\tsetTimeout( function () {\n\t\tdialog.$body.css( 'bottom', dialog.$foot.outerHeight( true ) );\n\t}, 300 );\n};\n\n/**\n * Fit label between actions.\n *\n * @private\n * @chainable\n * @return {OO.ui.MessageDialog} The dialog, for chaining\n */\nOO.ui.ProcessDialog.prototype.fitLabel = function () {\n\tvar safeWidth, primaryWidth, biggerWidth, labelWidth, navigationWidth, leftWidth, rightWidth,\n\t\tsize = this.getSizeProperties();\n\n\tif ( typeof size.width !== 'number' ) {\n\t\tif ( this.isOpened() ) {\n\t\t\tnavigationWidth = this.$head.width() - 20;\n\t\t} else if ( this.isOpening() ) {\n\t\t\tif ( !this.fitOnOpen ) {\n\t\t\t\t// Size is relative and the dialog isn't open yet, so wait.\n\t\t\t\t// FIXME: This should ideally be handled by setup somehow.\n\t\t\t\tthis.manager.lifecycle.opened.done( this.fitLabel.bind( this ) );\n\t\t\t\tthis.fitOnOpen = true;\n\t\t\t}\n\t\t\treturn;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\tnavigationWidth = size.width - 20;\n\t}\n\n\tsafeWidth = this.$safeActions.is( ':visible' ) ? this.$safeActions.width() : 0;\n\tprimaryWidth = this.$primaryActions.is( ':visible' ) ? this.$primaryActions.width() : 0;\n\tbiggerWidth = Math.max( safeWidth, primaryWidth );\n\n\tlabelWidth = this.title.$element.width();\n\n\tif ( 2 * biggerWidth + labelWidth < navigationWidth ) {\n\t\t// We have enough space to center the label\n\t\tleftWidth = rightWidth = biggerWidth;\n\t} else {\n\t\t// Let's hope we at least have enough space not to overlap, because we can't wrap the label…\n\t\tif ( this.getDir() === 'ltr' ) {\n\t\t\tleftWidth = safeWidth;\n\t\t\trightWidth = primaryWidth;\n\t\t} else {\n\t\t\tleftWidth = primaryWidth;\n\t\t\trightWidth = safeWidth;\n\t\t}\n\t}\n\n\tthis.$location.css( { paddingLeft: leftWidth, paddingRight: rightWidth } );\n\n\treturn this;\n};\n\n/**\n * Handle errors that occurred during accept or reject processes.\n *\n * @private\n * @param {OO.ui.Error[]|OO.ui.Error} errors Errors to be handled\n */\nOO.ui.ProcessDialog.prototype.showErrors = function ( errors ) {\n\tvar i, len, $item, actions,\n\t\titems = [],\n\t\tabilities = {},\n\t\trecoverable = true,\n\t\twarning = false;\n\n\tif ( errors instanceof OO.ui.Error ) {\n\t\terrors = [ errors ];\n\t}\n\n\tfor ( i = 0, len = errors.length; i < len; i++ ) {\n\t\tif ( !errors[ i ].isRecoverable() ) {\n\t\t\trecoverable = false;\n\t\t}\n\t\tif ( errors[ i ].isWarning() ) {\n\t\t\twarning = true;\n\t\t}\n\t\t$item = $( '<div>' )\n\t\t\t.addClass( 'oo-ui-processDialog-error' )\n\t\t\t.append( errors[ i ].getMessage() );\n\t\titems.push( $item[ 0 ] );\n\t}\n\tthis.$errorItems = $( items );\n\tif ( recoverable ) {\n\t\tabilities[ this.currentAction ] = true;\n\t\t// Copy the flags from the first matching action\n\t\tactions = this.actions.get( { actions: this.currentAction } );\n\t\tif ( actions.length ) {\n\t\t\tthis.retryButton.clearFlags().setFlags( actions[ 0 ].getFlags() );\n\t\t}\n\t} else {\n\t\tabilities[ this.currentAction ] = false;\n\t\tthis.actions.setAbilities( abilities );\n\t}\n\tif ( warning ) {\n\t\tthis.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-continue' ) );\n\t} else {\n\t\tthis.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-retry' ) );\n\t}\n\tthis.retryButton.toggle( recoverable );\n\tthis.$errorsTitle.after( this.$errorItems );\n\tthis.$errors.removeClass( 'oo-ui-element-hidden' ).scrollTop( 0 );\n};\n\n/**\n * Hide errors.\n *\n * @private\n */\nOO.ui.ProcessDialog.prototype.hideErrors = function () {\n\tthis.$errors.addClass( 'oo-ui-element-hidden' );\n\tif ( this.$errorItems ) {\n\t\tthis.$errorItems.remove();\n\t\tthis.$errorItems = null;\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.getTeardownProcess = function ( data ) {\n\t// Parent method\n\treturn OO.ui.ProcessDialog.parent.prototype.getTeardownProcess.call( this, data )\n\t\t.first( function () {\n\t\t\t// Make sure to hide errors\n\t\t\tthis.hideErrors();\n\t\t\tthis.fitOnOpen = false;\n\t\t}, this );\n};\n","/**\n * @class OO.ui\n */\n\n/**\n * Lazy-initialize and return a global OO.ui.WindowManager instance, used by OO.ui.alert and\n * OO.ui.confirm.\n *\n * @private\n * @return {OO.ui.WindowManager}\n */\nOO.ui.getWindowManager = function () {\n\tif ( !OO.ui.windowManager ) {\n\t\tOO.ui.windowManager = new OO.ui.WindowManager();\n\t\t$( document.body ).append( OO.ui.windowManager.$element );\n\t\tOO.ui.windowManager.addWindows( [ new OO.ui.MessageDialog() ] );\n\t}\n\treturn OO.ui.windowManager;\n};\n\n/**\n * Display a quick modal alert dialog, using a OO.ui.MessageDialog. While the dialog is open, the\n * rest of the page will be dimmed out and the user won't be able to interact with it. The dialog\n * has only one action button, labelled \"OK\", clicking it will simply close the dialog.\n *\n * A window manager is created automatically when this function is called for the first time.\n *\n *     @example\n *     OO.ui.alert( 'Something happened!' ).done( function () {\n *         console.log( 'User closed the dialog.' );\n *     } );\n *\n *     OO.ui.alert( 'Something larger happened!', { size: 'large' } );\n *\n * @param {jQuery|string} text Message text to display\n * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess\n * @return {jQuery.Promise} Promise resolved when the user closes the dialog\n */\nOO.ui.alert = function ( text, options ) {\n\treturn OO.ui.getWindowManager().openWindow( 'message', $.extend( {\n\t\tmessage: text,\n\t\tactions: [ OO.ui.MessageDialog.static.actions[ 0 ] ]\n\t}, options ) ).closed.then( function () {\n\t\treturn undefined;\n\t} );\n};\n\n/**\n * Display a quick modal confirmation dialog, using a OO.ui.MessageDialog. While the dialog is open,\n * the rest of the page will be dimmed out and the user won't be able to interact with it. The\n * dialog has two action buttons, one to confirm an operation (labelled \"OK\") and one to cancel it\n * (labelled \"Cancel\").\n *\n * A window manager is created automatically when this function is called for the first time.\n *\n *     @example\n *     OO.ui.confirm( 'Are you sure?' ).done( function ( confirmed ) {\n *         if ( confirmed ) {\n *             console.log( 'User clicked \"OK\"!' );\n *         } else {\n *             console.log( 'User clicked \"Cancel\" or closed the dialog.' );\n *         }\n *     } );\n *\n * @param {jQuery|string} text Message text to display\n * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess\n * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to\n *  confirm, the promise will resolve to boolean `true`; otherwise, it will resolve to boolean\n *  `false`.\n */\nOO.ui.confirm = function ( text, options ) {\n\treturn OO.ui.getWindowManager().openWindow( 'message', $.extend( {\n\t\tmessage: text\n\t}, options ) ).closed.then( function ( data ) {\n\t\treturn !!( data && data.action === 'accept' );\n\t} );\n};\n\n/**\n * Display a quick modal prompt dialog, using a OO.ui.MessageDialog. While the dialog is open,\n * the rest of the page will be dimmed out and the user won't be able to interact with it. The\n * dialog has a text input widget and two action buttons, one to confirm an operation (labelled \"OK\")\n * and one to cancel it (labelled \"Cancel\").\n *\n * A window manager is created automatically when this function is called for the first time.\n *\n *     @example\n *     OO.ui.prompt( 'Choose a line to go to', { textInput: { placeholder: 'Line number' } } ).done( function ( result ) {\n *         if ( result !== null ) {\n *             console.log( 'User typed \"' + result + '\" then clicked \"OK\".' );\n *         } else {\n *             console.log( 'User clicked \"Cancel\" or closed the dialog.' );\n *         }\n *     } );\n *\n * @param {jQuery|string} text Message text to display\n * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess\n * @param {Object} [options.textInput] Additional options for text input widget, see OO.ui.TextInputWidget\n * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to\n *  confirm, the promise will resolve with the value of the text input widget; otherwise, it will\n *  resolve to `null`.\n */\nOO.ui.prompt = function ( text, options ) {\n\tvar instance,\n\t\tmanager = OO.ui.getWindowManager(),\n\t\ttextInput = new OO.ui.TextInputWidget( ( options && options.textInput ) || {} ),\n\t\ttextField = new OO.ui.FieldLayout( textInput, {\n\t\t\talign: 'top',\n\t\t\tlabel: text\n\t\t} );\n\n\tinstance = manager.openWindow( 'message', $.extend( {\n\t\tmessage: textField.$element\n\t}, options ) );\n\n\t// TODO: This is a little hacky, and could be done by extending MessageDialog instead.\n\tinstance.opened.then( function () {\n\t\ttextInput.on( 'enter', function () {\n\t\t\tmanager.getCurrentWindow().close( { action: 'accept' } );\n\t\t} );\n\t\ttextInput.focus();\n\t} );\n\n\treturn instance.closed.then( function ( data ) {\n\t\treturn data && data.action === 'accept' ? textInput.getValue() : null;\n\t} );\n};\n","}( OO ) );\n"]}
\ No newline at end of file
+{"version":3,"sources":["../src/intro.js.txt","../src/widgets/ActionWidget.js","../src/ActionSet.js","../src/Error.js","../src/Process.js","../src/WindowInstance.js","../src/WindowManager.js","../src/Window.js","../src/Dialog.js","../src/dialogs/MessageDialog.js","../src/dialogs/ProcessDialog.js","../src/windows.js","../src/outro.js.txt"],"names":[],"mappings":"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","file":"oojs-ui-windows.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * An ActionWidget is a {@link OO.ui.ButtonWidget button widget} that executes an action.\n * Action widgets are used with OO.ui.ActionSet, which manages the behavior and availability\n * of the actions.\n *\n * Both actions and action sets are primarily used with {@link OO.ui.Dialog Dialogs}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information\n * and examples.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets\n *\n * @class\n * @extends OO.ui.ButtonWidget\n * @mixins OO.ui.mixin.PendingElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [action] Symbolic name of the action (e.g., ‘continue’ or ‘cancel’).\n * @cfg {string[]} [modes] Symbolic names of the modes (e.g., ‘edit’ or ‘read’) in which the action\n *  should be made available. See the action set's {@link OO.ui.ActionSet#setMode setMode} method\n *  for more information about setting modes.\n * @cfg {boolean} [framed=false] Render the action button with a frame\n */\nOO.ui.ActionWidget = function OoUiActionWidget( config ) {\n\t// Configuration initialization\n\tconfig = $.extend( { framed: false }, config );\n\n\t// Parent constructor\n\tOO.ui.ActionWidget.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PendingElement.call( this, config );\n\n\t// Properties\n\tthis.action = config.action || '';\n\tthis.modes = config.modes || [];\n\tthis.width = 0;\n\tthis.height = 0;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-actionWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ActionWidget, OO.ui.ButtonWidget );\nOO.mixinClass( OO.ui.ActionWidget, OO.ui.mixin.PendingElement );\n\n/* Methods */\n\n/**\n * Check if the action is configured to be available in the specified `mode`.\n *\n * @param {string} mode Name of mode\n * @return {boolean} The action is configured with the mode\n */\nOO.ui.ActionWidget.prototype.hasMode = function ( mode ) {\n\treturn this.modes.indexOf( mode ) !== -1;\n};\n\n/**\n * Get the symbolic name of the action (e.g., ‘continue’ or ‘cancel’).\n *\n * @return {string}\n */\nOO.ui.ActionWidget.prototype.getAction = function () {\n\treturn this.action;\n};\n\n/**\n * Get the symbolic name of the mode or modes for which the action is configured to be available.\n *\n * The current mode is set with the action set's {@link OO.ui.ActionSet#setMode setMode} method.\n * Only actions that are configured to be available in the current mode will be visible.\n * All other actions are hidden.\n *\n * @return {string[]}\n */\nOO.ui.ActionWidget.prototype.getModes = function () {\n\treturn this.modes.slice();\n};\n","/* eslint-disable no-unused-vars */\n/**\n * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that\n * comprise them.\n * Actions can be made available for specific contexts (modes) and circumstances\n * (abilities). Action sets are primarily used with {@link OO.ui.Dialog Dialogs}.\n *\n * ActionSets contain two types of actions:\n *\n * - Special: Special actions are the first visible actions with special flags, such as 'safe' and\n *  'primary', the default special flags. Additional special flags can be configured in subclasses\n *  with the static #specialFlags property.\n * - Other: Other actions include all non-special visible actions.\n *\n * See the [OOUI documentation on MediaWiki][1] for more information.\n *\n *     @example\n *     // Example: An action set used in a process dialog\n *     function MyProcessDialog( config ) {\n *         MyProcessDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );\n *     MyProcessDialog.static.title = 'An action set in a process dialog';\n *     MyProcessDialog.static.name = 'myProcessDialog';\n *     // An action set that uses modes ('edit' and 'help' mode, in this example).\n *     MyProcessDialog.static.actions = [\n *         { action: 'continue', modes: 'edit', label: 'Continue',\n *           flags: [\n *               'primary', 'progressive'\n *         ] },\n *         { action: 'help', modes: 'edit', label: 'Help' },\n *         { modes: 'edit', label: 'Cancel', flags: 'safe' },\n *         { action: 'back', modes: 'help', label: 'Back', flags: 'safe' }\n *     ];\n *\n *     MyProcessDialog.prototype.initialize = function () {\n *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );\n *         this.panel1 = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.panel1.$element.append( '<p>This dialog uses an action set (continue, help, ' +\n *             'cancel, back) configured with modes. This is edit mode. Click \\'help\\' to see ' +\n *             'help mode.</p>' );\n *         this.panel2 = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.panel2.$element.append( '<p>This is help mode. Only the \\'back\\' action widget ' +\n *              'is configured to be visible here. Click \\'back\\' to return to \\'edit\\' mode.' +\n *              '</p>' );\n *         this.stackLayout = new OO.ui.StackLayout( {\n *             items: [ this.panel1, this.panel2 ]\n *         } );\n *         this.$body.append( this.stackLayout.$element );\n *     };\n *     MyProcessDialog.prototype.getSetupProcess = function ( data ) {\n *         return MyProcessDialog.parent.prototype.getSetupProcess.call( this, data )\n *             .next( function () {\n *                 this.actions.setMode( 'edit' );\n *             }, this );\n *     };\n *     MyProcessDialog.prototype.getActionProcess = function ( action ) {\n *         if ( action === 'help' ) {\n *             this.actions.setMode( 'help' );\n *             this.stackLayout.setItem( this.panel2 );\n *         } else if ( action === 'back' ) {\n *             this.actions.setMode( 'edit' );\n *             this.stackLayout.setItem( this.panel1 );\n *         } else if ( action === 'continue' ) {\n *             var dialog = this;\n *             return new OO.ui.Process( function () {\n *                 dialog.close();\n *             } );\n *         }\n *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );\n *     };\n *     MyProcessDialog.prototype.getBodyHeight = function () {\n *         return this.panel1.$element.outerHeight( true );\n *     };\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *     var dialog = new MyProcessDialog( {\n *         size: 'medium'\n *     } );\n *     windowManager.addWindows( [ dialog ] );\n *     windowManager.openWindow( dialog );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets\n *\n * @abstract\n * @class\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ActionSet = function OoUiActionSet( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.list = [];\n\tthis.categories = {\n\t\tactions: 'getAction',\n\t\tflags: 'getFlags',\n\t\tmodes: 'getModes'\n\t};\n\tthis.categorized = {};\n\tthis.special = {};\n\tthis.others = [];\n\tthis.organized = false;\n\tthis.changing = false;\n\tthis.changed = false;\n};\n/* eslint-enable no-unused-vars */\n\n/* Setup */\n\nOO.mixinClass( OO.ui.ActionSet, OO.EventEmitter );\n\n/* Static Properties */\n\n/**\n * Symbolic name of the flags used to identify special actions. Special actions are displayed in the\n *  header of a {@link OO.ui.ProcessDialog process dialog}.\n *  See the [OOUI documentation on MediaWiki][2] for more information and examples.\n *\n *  [2]:https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.ActionSet.static.specialFlags = [ 'safe', 'primary' ];\n\n/* Events */\n\n/**\n * @event click\n *\n * A 'click' event is emitted when an action is clicked.\n *\n * @param {OO.ui.ActionWidget} action Action that was clicked\n */\n\n/**\n * @event add\n *\n * An 'add' event is emitted when actions are {@link #method-add added} to the action set.\n *\n * @param {OO.ui.ActionWidget[]} added Actions added\n */\n\n/**\n * @event remove\n *\n * A 'remove' event is emitted when actions are {@link #method-remove removed}\n *  or {@link #clear cleared}.\n *\n * @param {OO.ui.ActionWidget[]} added Actions removed\n */\n\n/**\n * @event change\n *\n * A 'change' event is emitted when actions are {@link #method-add added}, {@link #clear cleared},\n * or {@link #method-remove removed} from the action set or when the {@link #setMode mode}\n * is changed.\n *\n */\n\n/* Methods */\n\n/**\n * Handle action change events.\n *\n * @private\n * @fires change\n */\nOO.ui.ActionSet.prototype.onActionChange = function () {\n\tthis.organized = false;\n\tif ( this.changing ) {\n\t\tthis.changed = true;\n\t} else {\n\t\tthis.emit( 'change' );\n\t}\n};\n\n/**\n * Check if an action is one of the special actions.\n *\n * @param {OO.ui.ActionWidget} action Action to check\n * @return {boolean} Action is special\n */\nOO.ui.ActionSet.prototype.isSpecial = function ( action ) {\n\tvar flag;\n\n\tfor ( flag in this.special ) {\n\t\tif ( action === this.special[ flag ] ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n};\n\n/**\n * Get action widgets based on the specified filter: ‘actions’, ‘flags’, ‘modes’, ‘visible’,\n *  or ‘disabled’.\n *\n * @param {Object} [filters] Filters to use, omit to get all actions\n * @param {string|string[]} [filters.actions] Actions that action widgets must have\n * @param {string|string[]} [filters.flags] Flags that action widgets must have (e.g., 'safe')\n * @param {string|string[]} [filters.modes] Modes that action widgets must have\n * @param {boolean} [filters.visible] Action widgets must be visible\n * @param {boolean} [filters.disabled] Action widgets must be disabled\n * @return {OO.ui.ActionWidget[]} Action widgets matching all criteria\n */\nOO.ui.ActionSet.prototype.get = function ( filters ) {\n\tvar i, len, list, category, actions, index, match, matches;\n\n\tif ( filters ) {\n\t\tthis.organize();\n\n\t\t// Collect category candidates\n\t\tmatches = [];\n\t\tfor ( category in this.categorized ) {\n\t\t\tlist = filters[ category ];\n\t\t\tif ( list ) {\n\t\t\t\tif ( !Array.isArray( list ) ) {\n\t\t\t\t\tlist = [ list ];\n\t\t\t\t}\n\t\t\t\tfor ( i = 0, len = list.length; i < len; i++ ) {\n\t\t\t\t\tactions = this.categorized[ category ][ list[ i ] ];\n\t\t\t\t\tif ( Array.isArray( actions ) ) {\n\t\t\t\t\t\tmatches.push.apply( matches, actions );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Remove by boolean filters\n\t\tfor ( i = 0, len = matches.length; i < len; i++ ) {\n\t\t\tmatch = matches[ i ];\n\t\t\tif (\n\t\t\t\t( filters.visible !== undefined && match.isVisible() !== filters.visible ) ||\n\t\t\t\t( filters.disabled !== undefined && match.isDisabled() !== filters.disabled )\n\t\t\t) {\n\t\t\t\tmatches.splice( i, 1 );\n\t\t\t\tlen--;\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t\t// Remove duplicates\n\t\tfor ( i = 0, len = matches.length; i < len; i++ ) {\n\t\t\tmatch = matches[ i ];\n\t\t\tindex = matches.lastIndexOf( match );\n\t\t\twhile ( index !== i ) {\n\t\t\t\tmatches.splice( index, 1 );\n\t\t\t\tlen--;\n\t\t\t\tindex = matches.lastIndexOf( match );\n\t\t\t}\n\t\t}\n\t\treturn matches;\n\t}\n\treturn this.list.slice();\n};\n\n/**\n * Get 'special' actions.\n *\n * Special actions are the first visible action widgets with special flags, such as 'safe' and\n * 'primary'.\n * Special flags can be configured in subclasses by changing the static #specialFlags property.\n *\n * @return {OO.ui.ActionWidget[]|null} 'Special' action widgets.\n */\nOO.ui.ActionSet.prototype.getSpecial = function () {\n\tthis.organize();\n\treturn $.extend( {}, this.special );\n};\n\n/**\n * Get 'other' actions.\n *\n * Other actions include all non-special visible action widgets.\n *\n * @return {OO.ui.ActionWidget[]} 'Other' action widgets\n */\nOO.ui.ActionSet.prototype.getOthers = function () {\n\tthis.organize();\n\treturn this.others.slice();\n};\n\n/**\n * Set the mode  (e.g., ‘edit’ or ‘view’). Only {@link OO.ui.ActionWidget#modes actions} configured\n * to be available in the specified mode will be made visible. All other actions will be hidden.\n *\n * @param {string} mode The mode. Only actions configured to be available in the specified\n *  mode will be made visible.\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires toggle\n * @fires change\n */\nOO.ui.ActionSet.prototype.setMode = function ( mode ) {\n\tvar i, len, action;\n\n\tthis.changing = true;\n\tfor ( i = 0, len = this.list.length; i < len; i++ ) {\n\t\taction = this.list[ i ];\n\t\taction.toggle( action.hasMode( mode ) );\n\t}\n\n\tthis.organized = false;\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Set the abilities of the specified actions.\n *\n * Action widgets that are configured with the specified actions will be enabled\n * or disabled based on the boolean values specified in the `actions`\n * parameter.\n *\n * @param {Object.<string,boolean>} actions A list keyed by action name with boolean\n *  values that indicate whether or not the action should be enabled.\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n */\nOO.ui.ActionSet.prototype.setAbilities = function ( actions ) {\n\tvar i, len, action, item;\n\n\tfor ( i = 0, len = this.list.length; i < len; i++ ) {\n\t\titem = this.list[ i ];\n\t\taction = item.getAction();\n\t\tif ( actions[ action ] !== undefined ) {\n\t\t\titem.setDisabled( !actions[ action ] );\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * Executes a function once per action.\n *\n * When making changes to multiple actions, use this method instead of iterating over the actions\n * manually to defer emitting a #change event until after all actions have been changed.\n *\n * @param {Object|null} filter Filters to use to determine which actions to iterate over; see #get\n * @param {Function} callback Callback to run for each action; callback is invoked with three\n *   arguments: the action, the action's index, the list of actions being iterated over\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n */\nOO.ui.ActionSet.prototype.forEach = function ( filter, callback ) {\n\tthis.changed = false;\n\tthis.changing = true;\n\tthis.get( filter ).forEach( callback );\n\tthis.changing = false;\n\tif ( this.changed ) {\n\t\tthis.emit( 'change' );\n\t}\n\n\treturn this;\n};\n\n/**\n * Add action widgets to the action set.\n *\n * @param {OO.ui.ActionWidget[]} actions Action widgets to add\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires add\n * @fires change\n */\nOO.ui.ActionSet.prototype.add = function ( actions ) {\n\tvar i, len, action;\n\n\tthis.changing = true;\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\taction = actions[ i ];\n\t\taction.connect( this, {\n\t\t\tclick: [ 'emit', 'click', action ],\n\t\t\ttoggle: [ 'onActionChange' ]\n\t\t} );\n\t\tthis.list.push( action );\n\t}\n\tthis.organized = false;\n\tthis.emit( 'add', actions );\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Remove action widgets from the set.\n *\n * To remove all actions, you may wish to use the #clear method instead.\n *\n * @param {OO.ui.ActionWidget[]} actions Action widgets to remove\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires remove\n * @fires change\n */\nOO.ui.ActionSet.prototype.remove = function ( actions ) {\n\tvar i, len, index, action;\n\n\tthis.changing = true;\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\taction = actions[ i ];\n\t\tindex = this.list.indexOf( action );\n\t\tif ( index !== -1 ) {\n\t\t\taction.disconnect( this );\n\t\t\tthis.list.splice( index, 1 );\n\t\t}\n\t}\n\tthis.organized = false;\n\tthis.emit( 'remove', actions );\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Remove all action widgets from the set.\n *\n * To remove only specified actions, use the {@link #method-remove remove} method instead.\n *\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n * @fires remove\n * @fires change\n */\nOO.ui.ActionSet.prototype.clear = function () {\n\tvar i, len, action,\n\t\tremoved = this.list.slice();\n\n\tthis.changing = true;\n\tfor ( i = 0, len = this.list.length; i < len; i++ ) {\n\t\taction = this.list[ i ];\n\t\taction.disconnect( this );\n\t}\n\n\tthis.list = [];\n\n\tthis.organized = false;\n\tthis.emit( 'remove', removed );\n\tthis.changing = false;\n\tthis.emit( 'change' );\n\n\treturn this;\n};\n\n/**\n * Organize actions.\n *\n * This is called whenever organized information is requested. It will only reorganize the actions\n * if something has changed since the last time it ran.\n *\n * @private\n * @chainable\n * @return {OO.ui.ActionSet} The widget, for chaining\n */\nOO.ui.ActionSet.prototype.organize = function () {\n\tvar i, iLen, j, jLen, flag, action, category, list, item, special,\n\t\tspecialFlags = this.constructor.static.specialFlags;\n\n\tif ( !this.organized ) {\n\t\tthis.categorized = {};\n\t\tthis.special = {};\n\t\tthis.others = [];\n\t\tfor ( i = 0, iLen = this.list.length; i < iLen; i++ ) {\n\t\t\taction = this.list[ i ];\n\t\t\tif ( action.isVisible() ) {\n\t\t\t\t// Populate categories\n\t\t\t\tfor ( category in this.categories ) {\n\t\t\t\t\tif ( !this.categorized[ category ] ) {\n\t\t\t\t\t\tthis.categorized[ category ] = {};\n\t\t\t\t\t}\n\t\t\t\t\tlist = action[ this.categories[ category ] ]();\n\t\t\t\t\tif ( !Array.isArray( list ) ) {\n\t\t\t\t\t\tlist = [ list ];\n\t\t\t\t\t}\n\t\t\t\t\tfor ( j = 0, jLen = list.length; j < jLen; j++ ) {\n\t\t\t\t\t\titem = list[ j ];\n\t\t\t\t\t\tif ( !this.categorized[ category ][ item ] ) {\n\t\t\t\t\t\t\tthis.categorized[ category ][ item ] = [];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.categorized[ category ][ item ].push( action );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Populate special/others\n\t\t\t\tspecial = false;\n\t\t\t\tfor ( j = 0, jLen = specialFlags.length; j < jLen; j++ ) {\n\t\t\t\t\tflag = specialFlags[ j ];\n\t\t\t\t\tif ( !this.special[ flag ] && action.hasFlag( flag ) ) {\n\t\t\t\t\t\tthis.special[ flag ] = action;\n\t\t\t\t\t\tspecial = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( !special ) {\n\t\t\t\t\tthis.others.push( action );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.organized = true;\n\t}\n\n\treturn this;\n};\n","/**\n * Errors contain a required message (either a string or jQuery selection) that is used to describe\n * what went wrong in a {@link OO.ui.Process process}. The error's #recoverable and #warning\n * configurations are used to customize the appearance and functionality of the error interface.\n *\n * The basic error interface contains a formatted error message as well as two buttons: 'Dismiss'\n * and 'Try again' (i.e., the error is 'recoverable' by default). If the error is not recoverable,\n * the 'Try again' button will not be rendered and the widget that initiated the failed process will\n * be disabled.\n *\n * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button,\n * which will try the process again.\n *\n * For an example of error interfaces, please see the [OOUI documentation on MediaWiki][1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Processes_and_errors\n *\n * @class\n *\n * @constructor\n * @param {string|jQuery} message Description of error\n * @param {Object} [config] Configuration options\n * @cfg {boolean} [recoverable=true] Error is recoverable.\n *  By default, errors are recoverable, and users can try the process again.\n * @cfg {boolean} [warning=false] Error is a warning.\n *  If the error is a warning, the error interface will include a\n *  'Dismiss' and a 'Continue' button. It is the responsibility of the developer to ensure that the\n *  warning is not triggered a second time if the user chooses to continue.\n */\nOO.ui.Error = function OoUiError( message, config ) {\n\t// Allow passing positional parameters inside the config object\n\tif ( OO.isPlainObject( message ) && config === undefined ) {\n\t\tconfig = message;\n\t\tmessage = config.message;\n\t}\n\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Properties\n\tthis.message = message instanceof $ ? message : String( message );\n\tthis.recoverable = config.recoverable === undefined || !!config.recoverable;\n\tthis.warning = !!config.warning;\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Error );\n\n/* Methods */\n\n/**\n * Check if the error is recoverable.\n *\n * If the error is recoverable, users are able to try the process again.\n *\n * @return {boolean} Error is recoverable\n */\nOO.ui.Error.prototype.isRecoverable = function () {\n\treturn this.recoverable;\n};\n\n/**\n * Check if the error is a warning.\n *\n * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button.\n *\n * @return {boolean} Error is warning\n */\nOO.ui.Error.prototype.isWarning = function () {\n\treturn this.warning;\n};\n\n/**\n * Get error message as DOM nodes.\n *\n * @return {jQuery} Error message in DOM nodes\n */\nOO.ui.Error.prototype.getMessage = function () {\n\treturn this.message instanceof $ ?\n\t\tthis.message.clone() :\n\t\t$( '<div>' ).text( this.message ).contents();\n};\n\n/**\n * Get the error message text.\n *\n * @return {string} Error message\n */\nOO.ui.Error.prototype.getMessageText = function () {\n\treturn this.message instanceof $ ? this.message.text() : this.message;\n};\n","/**\n * A Process is a list of steps that are called in sequence. The step can be a number, a\n * jQuery promise, or a function:\n *\n * - **number**: the process will wait for the specified number of milliseconds before proceeding.\n * - **promise**: the process will continue to the next step when the promise is successfully\n *  resolved or stop if the promise is rejected.\n * - **function**: the process will execute the function. The process will stop if the function\n *  returns either a boolean `false` or a promise that is rejected; if the function returns a\n *  number, the process will wait for that number of milliseconds before proceeding.\n *\n * If the process fails, an {@link OO.ui.Error error} is generated. Depending on how the error is\n * configured, users can dismiss the error and try the process again, or not. If a process is\n * stopped, its remaining steps will not be performed.\n *\n * @class\n *\n * @constructor\n * @param {number|jQuery.Promise|Function} step Number of milliseconds to wait before proceeding,\n *  promise that must be resolved before proceeding, or a function to execute. See #createStep for\n *  more information. See #createStep for more information.\n * @param {Object} [context=null] Execution context of the function. The context is ignored if the\n *  step is a number or promise.\n */\nOO.ui.Process = function ( step, context ) {\n\t// Properties\n\tthis.steps = [];\n\n\t// Initialization\n\tif ( step !== undefined ) {\n\t\tthis.next( step, context );\n\t}\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.Process );\n\n/* Methods */\n\n/**\n * Start the process.\n *\n * @return {jQuery.Promise} Promise that is resolved when all steps have successfully completed.\n *  If any of the steps return a promise that is rejected or a boolean false, this promise is\n *  rejected and any remaining steps are not performed.\n */\nOO.ui.Process.prototype.execute = function () {\n\tvar i, len, promise;\n\n\t/**\n\t * Continue execution.\n\t *\n\t * @ignore\n\t * @param {Array} step A function and the context it should be called in\n\t * @return {Function} Function that continues the process\n\t */\n\tfunction proceed( step ) {\n\t\treturn function () {\n\t\t\t// Execute step in the correct context\n\t\t\tvar deferred,\n\t\t\t\tresult = step.callback.call( step.context );\n\n\t\t\tif ( result === false ) {\n\t\t\t\t// Use rejected promise for boolean false results\n\t\t\t\treturn $.Deferred().reject( [] ).promise();\n\t\t\t}\n\t\t\tif ( typeof result === 'number' ) {\n\t\t\t\tif ( result < 0 ) {\n\t\t\t\t\tthrow new Error( 'Cannot go back in time: flux capacitor is out of service' );\n\t\t\t\t}\n\t\t\t\t// Use a delayed promise for numbers, expecting them to be in milliseconds\n\t\t\t\tdeferred = $.Deferred();\n\t\t\t\tsetTimeout( deferred.resolve, result );\n\t\t\t\treturn deferred.promise();\n\t\t\t}\n\t\t\tif ( result instanceof OO.ui.Error ) {\n\t\t\t\t// Use rejected promise for error\n\t\t\t\treturn $.Deferred().reject( [ result ] ).promise();\n\t\t\t}\n\t\t\tif ( Array.isArray( result ) && result.length && result[ 0 ] instanceof OO.ui.Error ) {\n\t\t\t\t// Use rejected promise for list of errors\n\t\t\t\treturn $.Deferred().reject( result ).promise();\n\t\t\t}\n\t\t\t// Duck-type the object to see if it can produce a promise\n\t\t\tif ( result && typeof result.promise === 'function' ) {\n\t\t\t\t// Use a promise generated from the result\n\t\t\t\treturn result.promise();\n\t\t\t}\n\t\t\t// Use resolved promise for other results\n\t\t\treturn $.Deferred().resolve().promise();\n\t\t};\n\t}\n\n\tif ( this.steps.length ) {\n\t\t// Generate a chain reaction of promises\n\t\tpromise = proceed( this.steps[ 0 ] )();\n\t\tfor ( i = 1, len = this.steps.length; i < len; i++ ) {\n\t\t\tpromise = promise.then( proceed( this.steps[ i ] ) );\n\t\t}\n\t} else {\n\t\tpromise = $.Deferred().resolve().promise();\n\t}\n\n\treturn promise;\n};\n\n/**\n * Create a process step.\n *\n * @private\n * @param {number|jQuery.Promise|Function} step\n *\n * - Number of milliseconds to wait before proceeding\n * - Promise that must be resolved before proceeding\n * - Function to execute\n *   - If the function returns a boolean false the process will stop\n *   - If the function returns a promise, the process will continue to the next\n *     step when the promise is resolved or stop if the promise is rejected\n *   - If the function returns a number, the process will wait for that number of\n *     milliseconds before proceeding\n * @param {Object} [context=null] Execution context of the function. The context is\n *  ignored if the step is a number or promise.\n * @return {Object} Step object, with `callback` and `context` properties\n */\nOO.ui.Process.prototype.createStep = function ( step, context ) {\n\tif ( typeof step === 'number' || typeof step.promise === 'function' ) {\n\t\treturn {\n\t\t\tcallback: function () {\n\t\t\t\treturn step;\n\t\t\t},\n\t\t\tcontext: null\n\t\t};\n\t}\n\tif ( typeof step === 'function' ) {\n\t\treturn {\n\t\t\tcallback: step,\n\t\t\tcontext: context\n\t\t};\n\t}\n\tthrow new Error( 'Cannot create process step: number, promise or function expected' );\n};\n\n/**\n * Add step to the beginning of the process.\n *\n * @inheritdoc #createStep\n * @return {OO.ui.Process} this\n * @chainable\n */\nOO.ui.Process.prototype.first = function ( step, context ) {\n\tthis.steps.unshift( this.createStep( step, context ) );\n\treturn this;\n};\n\n/**\n * Add step to the end of the process.\n *\n * @inheritdoc #createStep\n * @return {OO.ui.Process} this\n * @chainable\n */\nOO.ui.Process.prototype.next = function ( step, context ) {\n\tthis.steps.push( this.createStep( step, context ) );\n\treturn this;\n};\n","/**\n * A window instance represents the life cycle for one single opening of a window\n * until its closing.\n *\n * While OO.ui.WindowManager will reuse OO.ui.Window objects, each time a window is\n * opened, a new lifecycle starts.\n *\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows\n *\n * @class\n *\n * @constructor\n */\nOO.ui.WindowInstance = function OoUiWindowInstance() {\n\tvar deferreds = {\n\t\topening: $.Deferred(),\n\t\topened: $.Deferred(),\n\t\tclosing: $.Deferred(),\n\t\tclosed: $.Deferred()\n\t};\n\n\t/**\n\t * @private\n\t * @property {Object}\n\t */\n\tthis.deferreds = deferreds;\n\n\t// Set these up as chained promises so that rejecting of\n\t// an earlier stage automatically rejects the subsequent\n\t// would-be stages as well.\n\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.opening = deferreds.opening.promise();\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.opened = this.opening.then( function () {\n\t\treturn deferreds.opened;\n\t} );\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.closing = this.opened.then( function () {\n\t\treturn deferreds.closing;\n\t} );\n\t/**\n\t * @property {jQuery.Promise}\n\t */\n\tthis.closed = this.closing.then( function () {\n\t\treturn deferreds.closed;\n\t} );\n};\n\n/* Setup */\n\nOO.initClass( OO.ui.WindowInstance );\n\n/**\n * Check if window is opening.\n *\n * @return {boolean} Window is opening\n */\nOO.ui.WindowInstance.prototype.isOpening = function () {\n\treturn this.deferreds.opened.state() === 'pending';\n};\n\n/**\n * Check if window is opened.\n *\n * @return {boolean} Window is opened\n */\nOO.ui.WindowInstance.prototype.isOpened = function () {\n\treturn this.deferreds.opened.state() === 'resolved' &&\n\t\tthis.deferreds.closing.state() === 'pending';\n};\n\n/**\n * Check if window is closing.\n *\n * @return {boolean} Window is closing\n */\nOO.ui.WindowInstance.prototype.isClosing = function () {\n\treturn this.deferreds.closing.state() === 'resolved' &&\n\t\tthis.deferreds.closed.state() === 'pending';\n};\n\n/**\n * Check if window is closed.\n *\n * @return {boolean} Window is closed\n */\nOO.ui.WindowInstance.prototype.isClosed = function () {\n\treturn this.deferreds.closed.state() === 'resolved';\n};\n","/**\n * Window managers are used to open and close {@link OO.ui.Window windows} and control their\n * presentation. Managed windows are mutually exclusive. If a new window is opened while a current\n * window is opening or is opened, the current window will be closed and any on-going\n * {@link OO.ui.Process process} will be cancelled. Windows\n * themselves are persistent and—rather than being torn down when closed—can be repopulated with the\n * pertinent data and reused.\n *\n * Over the lifecycle of a window, the window manager makes available three promises: `opening`,\n * `opened`, and `closing`, which represent the primary stages of the cycle:\n *\n * **Opening**: the opening stage begins when the window manager’s #openWindow or a window’s\n * {@link OO.ui.Window#open open} method is used, and the window manager begins to open the window.\n *\n * - an `opening` event is emitted with an `opening` promise\n * - the #getSetupDelay method is called and the returned value is used to time a pause in execution\n *   before the window’s {@link OO.ui.Window#method-setup setup} method is called which executes\n *   OO.ui.Window#getSetupProcess.\n * - a `setup` progress notification is emitted from the `opening` promise\n * - the #getReadyDelay method is called the returned value is used to time a pause in execution\n *   before the window’s {@link OO.ui.Window#method-ready ready} method is called which executes\n *   OO.ui.Window#getReadyProcess.\n * - a `ready` progress notification is emitted from the `opening` promise\n * - the `opening` promise is resolved with an `opened` promise\n *\n * **Opened**: the window is now open.\n *\n * **Closing**: the closing stage begins when the window manager's #closeWindow or the\n * window's {@link OO.ui.Window#close close} methods is used, and the window manager begins\n * to close the window.\n *\n * - the `opened` promise is resolved with `closing` promise and a `closing` event is emitted\n * - the #getHoldDelay method is called and the returned value is used to time a pause in execution\n *   before the window's {@link OO.ui.Window#getHoldProcess getHoldProcess} method is called on the\n *   window and its result executed\n * - a `hold` progress notification is emitted from the `closing` promise\n * - the #getTeardownDelay() method is called and the returned value is used to time a pause in\n *   execution before the window's {@link OO.ui.Window#getTeardownProcess getTeardownProcess} method\n *   is called on the window and its result executed\n * - a `teardown` progress notification is emitted from the `closing` promise\n * - the `closing` promise is resolved. The window is now closed\n *\n * See the [OOUI documentation on MediaWiki][1] for more information.\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {OO.Factory} [factory] Window factory to use for automatic instantiation\n *  Note that window classes that are instantiated with a factory must have\n *  a {@link OO.ui.Dialog#static-name static name} property that specifies a symbolic name.\n * @cfg {boolean} [modal=true] Prevent interaction outside the dialog\n */\nOO.ui.WindowManager = function OoUiWindowManager( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.WindowManager.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.factory = config.factory;\n\tthis.modal = config.modal === undefined || !!config.modal;\n\tthis.windows = {};\n\t// Deprecated placeholder promise given to compatOpening in openWindow()\n\t// that is resolved in closeWindow().\n\tthis.compatOpened = null;\n\tthis.preparingToOpen = null;\n\tthis.preparingToClose = null;\n\tthis.currentWindow = null;\n\tthis.globalEvents = false;\n\tthis.$returnFocusTo = null;\n\tthis.$ariaHidden = null;\n\tthis.onWindowResizeTimeout = null;\n\tthis.onWindowResizeHandler = this.onWindowResize.bind( this );\n\tthis.afterWindowResizeHandler = this.afterWindowResize.bind( this );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-windowManager' )\n\t\t.toggleClass( 'oo-ui-windowManager-modal', this.modal );\n\tif ( this.modal ) {\n\t\tthis.$element.attr( 'aria-hidden', true );\n\t}\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.WindowManager, OO.ui.Element );\nOO.mixinClass( OO.ui.WindowManager, OO.EventEmitter );\n\n/* Events */\n\n/**\n * An 'opening' event is emitted when the window begins to be opened.\n *\n * @event opening\n * @param {OO.ui.Window} win Window that's being opened\n * @param {jQuery.Promise} opened A promise resolved with a value when the window is opened\n *  successfully. This promise also emits `setup` and `ready` notifications. When this promise is\n *  resolved, the first argument of the value is an 'closed' promise, the second argument is the\n *  opening data.\n * @param {Object} data Window opening data\n */\n\n/**\n * A 'closing' event is emitted when the window begins to be closed.\n *\n * @event closing\n * @param {OO.ui.Window} win Window that's being closed\n * @param {jQuery.Promise} closed A promise resolved with a value when the window is closed\n *  successfully. This promise also emits `hold` and `teardown` notifications. When this promise is\n *  resolved, the first argument of its value is the closing data.\n * @param {Object} data Window closing data\n */\n\n/**\n * A 'resize' event is emitted when a window is resized.\n *\n * @event resize\n * @param {OO.ui.Window} win Window that was resized\n */\n\n/* Static Properties */\n\n/**\n * Map of the symbolic name of each window size and its CSS properties.\n *\n * @static\n * @inheritable\n * @property {Object}\n */\nOO.ui.WindowManager.static.sizes = {\n\tsmall: {\n\t\twidth: 300\n\t},\n\tmedium: {\n\t\twidth: 500\n\t},\n\tlarge: {\n\t\twidth: 700\n\t},\n\tlarger: {\n\t\twidth: 900\n\t},\n\tfull: {\n\t\t// These can be non-numeric because they are never used in calculations\n\t\twidth: '100%',\n\t\theight: '100%'\n\t}\n};\n\n/**\n * Symbolic name of the default window size.\n *\n * The default size is used if the window's requested size is not recognized.\n *\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.WindowManager.static.defaultSize = 'medium';\n\n/* Methods */\n\n/**\n * Handle window resize events.\n *\n * @private\n * @param {jQuery.Event} e Window resize event\n */\nOO.ui.WindowManager.prototype.onWindowResize = function () {\n\tclearTimeout( this.onWindowResizeTimeout );\n\tthis.onWindowResizeTimeout = setTimeout( this.afterWindowResizeHandler, 200 );\n};\n\n/**\n * Handle window resize events.\n *\n * @private\n * @param {jQuery.Event} e Window resize event\n */\nOO.ui.WindowManager.prototype.afterWindowResize = function () {\n\tvar currentFocusedElement = document.activeElement;\n\tif ( this.currentWindow ) {\n\t\tthis.updateWindowSize( this.currentWindow );\n\n\t\t// Restore focus to the original element if it has changed.\n\t\t// When a layout change is made on resize inputs lose focus\n\t\t// on Android (Chrome and Firefox), see T162127.\n\t\tif ( currentFocusedElement !== document.activeElement ) {\n\t\t\tcurrentFocusedElement.focus();\n\t\t}\n\t}\n};\n\n/**\n * Check if window is opening.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is opening\n */\nOO.ui.WindowManager.prototype.isOpening = function ( win ) {\n\treturn win === this.currentWindow && !!this.lifecycle &&\n\t\tthis.lifecycle.isOpening();\n};\n\n/**\n * Check if window is closing.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is closing\n */\nOO.ui.WindowManager.prototype.isClosing = function ( win ) {\n\treturn win === this.currentWindow && !!this.lifecycle &&\n\t\tthis.lifecycle.isClosing();\n};\n\n/**\n * Check if window is opened.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is opened\n */\nOO.ui.WindowManager.prototype.isOpened = function ( win ) {\n\treturn win === this.currentWindow && !!this.lifecycle &&\n\t\tthis.lifecycle.isOpened();\n};\n\n/**\n * Check if a window is being managed.\n *\n * @param {OO.ui.Window} win Window to check\n * @return {boolean} Window is being managed\n */\nOO.ui.WindowManager.prototype.hasWindow = function ( win ) {\n\tvar name;\n\n\tfor ( name in this.windows ) {\n\t\tif ( this.windows[ name ] === win ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n};\n\n/**\n * Get the number of milliseconds to wait after opening begins before executing the ‘setup’ process.\n *\n * @param {OO.ui.Window} win Window being opened\n * @param {Object} [data] Window opening data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getSetupDelay = function () {\n\treturn 0;\n};\n\n/**\n * Get the number of milliseconds to wait after setup has finished before executing the ‘ready’\n * process.\n *\n * @param {OO.ui.Window} win Window being opened\n * @param {Object} [data] Window opening data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getReadyDelay = function () {\n\treturn this.modal ? OO.ui.theme.getDialogTransitionDuration() : 0;\n};\n\n/**\n * Get the number of milliseconds to wait after closing has begun before executing the 'hold'\n * process.\n *\n * @param {OO.ui.Window} win Window being closed\n * @param {Object} [data] Window closing data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getHoldDelay = function () {\n\treturn 0;\n};\n\n/**\n * Get the number of milliseconds to wait after the ‘hold’ process has finished before\n * executing the ‘teardown’ process.\n *\n * @param {OO.ui.Window} win Window being closed\n * @param {Object} [data] Window closing data\n * @return {number} Milliseconds to wait\n */\nOO.ui.WindowManager.prototype.getTeardownDelay = function () {\n\treturn this.modal ? OO.ui.theme.getDialogTransitionDuration() : 0;\n};\n\n/**\n * Get a window by its symbolic name.\n *\n * If the window is not yet instantiated and its symbolic name is recognized by a factory, it will\n * be instantiated and added to the window manager automatically. Please see the [OOUI documentation\n * on MediaWiki][3] for more information about using factories.\n * [3]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * @param {string} name Symbolic name of the window\n * @return {jQuery.Promise} Promise resolved with matching window, or rejected with an OO.ui.Error\n * @throws {Error} An error is thrown if the symbolic name is not recognized by the factory.\n * @throws {Error} An error is thrown if the named window is not recognized as a managed window.\n */\nOO.ui.WindowManager.prototype.getWindow = function ( name ) {\n\tvar deferred = $.Deferred(),\n\t\twin = this.windows[ name ];\n\n\tif ( !( win instanceof OO.ui.Window ) ) {\n\t\tif ( this.factory ) {\n\t\t\tif ( !this.factory.lookup( name ) ) {\n\t\t\t\tdeferred.reject( new OO.ui.Error(\n\t\t\t\t\t'Cannot auto-instantiate window: symbolic name is unrecognized by the factory'\n\t\t\t\t) );\n\t\t\t} else {\n\t\t\t\twin = this.factory.create( name );\n\t\t\t\tthis.addWindows( [ win ] );\n\t\t\t\tdeferred.resolve( win );\n\t\t\t}\n\t\t} else {\n\t\t\tdeferred.reject( new OO.ui.Error(\n\t\t\t\t'Cannot get unmanaged window: symbolic name unrecognized as a managed window'\n\t\t\t) );\n\t\t}\n\t} else {\n\t\tdeferred.resolve( win );\n\t}\n\n\treturn deferred.promise();\n};\n\n/**\n * Get current window.\n *\n * @return {OO.ui.Window|null} Currently opening/opened/closing window\n */\nOO.ui.WindowManager.prototype.getCurrentWindow = function () {\n\treturn this.currentWindow;\n};\n\n/* eslint-disable valid-jsdoc */\n/**\n * Open a window.\n *\n * @param {OO.ui.Window|string} win Window object or symbolic name of window to open\n * @param {Object} [data] Window opening data\n * @param {jQuery|null} [data.$returnFocusTo] Element to which the window will return focus when\n *  closed. Defaults the current activeElement. If set to null, focus isn't changed on close.\n * @return {OO.ui.WindowInstance} A lifecycle object representing this particular\n *  opening of the window. For backwards-compatibility, then object is also a Thenable that is\n *  resolved when the window is done opening, with nested promise for when closing starts. This\n *  behaviour is deprecated and is not compatible with jQuery 3, see T163510.\n * @fires opening\n */\nOO.ui.WindowManager.prototype.openWindow = function ( win, data, lifecycle, compatOpening ) {\n\t/* eslint-enable valid-jsdoc */\n\tvar error,\n\t\tmanager = this;\n\tdata = data || {};\n\n\t// Internal parameter 'lifecycle' allows this method to always return\n\t// a lifecycle even if the window still needs to be created\n\t// asynchronously when 'win' is a string.\n\tlifecycle = lifecycle || new OO.ui.WindowInstance();\n\tcompatOpening = compatOpening || $.Deferred();\n\n\t// Turn lifecycle into a Thenable for backwards-compatibility with\n\t// the deprecated nested-promise behaviour, see T163510.\n\t[ 'state', 'always', 'catch', 'pipe', 'then', 'promise', 'progress', 'done', 'fail' ]\n\t\t.forEach( function ( method ) {\n\t\t\tlifecycle[ method ] = function () {\n\t\t\t\tOO.ui.warnDeprecation(\n\t\t\t\t\t'Using the return value of openWindow as a promise is deprecated. ' +\n\t\t\t\t\t'Use .openWindow( ... ).opening.' + method + '( ... ) instead.'\n\t\t\t\t);\n\t\t\t\treturn compatOpening[ method ].apply( this, arguments );\n\t\t\t};\n\t\t} );\n\n\t// Argument handling\n\tif ( typeof win === 'string' ) {\n\t\tthis.getWindow( win ).then(\n\t\t\tfunction ( win ) {\n\t\t\t\tmanager.openWindow( win, data, lifecycle, compatOpening );\n\t\t\t},\n\t\t\tfunction ( err ) {\n\t\t\t\tlifecycle.deferreds.opening.reject( err );\n\t\t\t}\n\t\t);\n\t\treturn lifecycle;\n\t}\n\n\t// Error handling\n\tif ( !this.hasWindow( win ) ) {\n\t\terror = 'Cannot open window: window is not attached to manager';\n\t} else if ( this.lifecycle && this.lifecycle.isOpened() ) {\n\t\terror = 'Cannot open window: another window is open';\n\t} else if ( this.preparingToOpen || ( this.lifecycle && this.lifecycle.isOpening() ) ) {\n\t\terror = 'Cannot open window: another window is opening';\n\t}\n\n\tif ( error ) {\n\t\tcompatOpening.reject( new OO.ui.Error( error ) );\n\t\tlifecycle.deferreds.opening.reject( new OO.ui.Error( error ) );\n\t\treturn lifecycle;\n\t}\n\n\t// If a window is currently closing, wait for it to complete\n\tthis.preparingToOpen = $.when( this.lifecycle && this.lifecycle.closed );\n\t// Ensure handlers get called after preparingToOpen is set\n\tthis.preparingToOpen.done( function () {\n\t\tif ( manager.modal ) {\n\t\t\tmanager.toggleGlobalEvents( true );\n\t\t\tmanager.toggleAriaIsolation( true );\n\t\t}\n\t\tmanager.$returnFocusTo = data.$returnFocusTo !== undefined ?\n\t\t\tdata.$returnFocusTo :\n\t\t\t$( document.activeElement );\n\t\tmanager.currentWindow = win;\n\t\tmanager.lifecycle = lifecycle;\n\t\tmanager.preparingToOpen = null;\n\t\tmanager.emit( 'opening', win, compatOpening, data );\n\t\tlifecycle.deferreds.opening.resolve( data );\n\t\tsetTimeout( function () {\n\t\t\tmanager.compatOpened = $.Deferred();\n\t\t\twin.setup( data ).then( function () {\n\t\t\t\tcompatOpening.notify( { state: 'setup' } );\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\twin.ready( data ).then( function () {\n\t\t\t\t\t\tcompatOpening.notify( { state: 'ready' } );\n\t\t\t\t\t\tlifecycle.deferreds.opened.resolve( data );\n\t\t\t\t\t\tcompatOpening.resolve( manager.compatOpened.promise(), data );\n\t\t\t\t\t}, function () {\n\t\t\t\t\t\tlifecycle.deferreds.opened.reject();\n\t\t\t\t\t\tcompatOpening.reject();\n\t\t\t\t\t\tmanager.closeWindow( win );\n\t\t\t\t\t} );\n\t\t\t\t}, manager.getReadyDelay() );\n\t\t\t}, function () {\n\t\t\t\tlifecycle.deferreds.opened.reject();\n\t\t\t\tcompatOpening.reject();\n\t\t\t\tmanager.closeWindow( win );\n\t\t\t} );\n\t\t}, manager.getSetupDelay() );\n\t} );\n\n\treturn lifecycle;\n};\n\n/**\n * Close a window.\n *\n * @param {OO.ui.Window|string} win Window object or symbolic name of window to close\n * @param {Object} [data] Window closing data\n * @return {OO.ui.WindowInstance} A lifecycle object representing this particular\n *  opening of the window. For backwards-compatibility, the object is also a Thenable that is\n *  resolved when the window is done closing, see T163510.\n * @fires closing\n */\nOO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {\n\tvar error,\n\t\tmanager = this,\n\t\tcompatClosing = $.Deferred(),\n\t\tlifecycle = this.lifecycle,\n\t\tcompatOpened;\n\n\t// Argument handling\n\tif ( typeof win === 'string' ) {\n\t\twin = this.windows[ win ];\n\t} else if ( !this.hasWindow( win ) ) {\n\t\twin = null;\n\t}\n\n\t// Error handling\n\tif ( !lifecycle ) {\n\t\terror = 'Cannot close window: no window is currently open';\n\t} else if ( !win ) {\n\t\terror = 'Cannot close window: window is not attached to manager';\n\t} else if ( win !== this.currentWindow || this.lifecycle.isClosed() ) {\n\t\terror = 'Cannot close window: window already closed with different data';\n\t} else if ( this.preparingToClose || this.lifecycle.isClosing() ) {\n\t\terror = 'Cannot close window: window already closing with different data';\n\t}\n\n\tif ( error ) {\n\t\t// This function was called for the wrong window and we don't want to mess with the current\n\t\t// window's state.\n\t\tlifecycle = new OO.ui.WindowInstance();\n\t\t// Pretend the window has been opened, so that we can pretend to fail to close it.\n\t\tlifecycle.deferreds.opening.resolve( {} );\n\t\tlifecycle.deferreds.opened.resolve( {} );\n\t}\n\n\t// Turn lifecycle into a Thenable for backwards-compatibility with\n\t// the deprecated nested-promise behaviour, see T163510.\n\t[ 'state', 'always', 'catch', 'pipe', 'then', 'promise', 'progress', 'done', 'fail' ]\n\t\t.forEach( function ( method ) {\n\t\t\tlifecycle[ method ] = function () {\n\t\t\t\tOO.ui.warnDeprecation(\n\t\t\t\t\t'Using the return value of closeWindow as a promise is deprecated. ' +\n\t\t\t\t\t'Use .closeWindow( ... ).closed.' + method + '( ... ) instead.'\n\t\t\t\t);\n\t\t\t\treturn compatClosing[ method ].apply( this, arguments );\n\t\t\t};\n\t\t} );\n\n\tif ( error ) {\n\t\tcompatClosing.reject( new OO.ui.Error( error ) );\n\t\tlifecycle.deferreds.closing.reject( new OO.ui.Error( error ) );\n\t\treturn lifecycle;\n\t}\n\n\t// If the window is currently opening, close it when it's done\n\tthis.preparingToClose = $.when( this.lifecycle.opened );\n\t// Ensure handlers get called after preparingToClose is set\n\tthis.preparingToClose.always( function () {\n\t\tmanager.preparingToClose = null;\n\t\tmanager.emit( 'closing', win, compatClosing, data );\n\t\tlifecycle.deferreds.closing.resolve( data );\n\t\tcompatOpened = manager.compatOpened;\n\t\tmanager.compatOpened = null;\n\t\tcompatOpened.resolve( compatClosing.promise(), data );\n\t\tsetTimeout( function () {\n\t\t\twin.hold( data ).then( function () {\n\t\t\t\tcompatClosing.notify( { state: 'hold' } );\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\twin.teardown( data ).then( function () {\n\t\t\t\t\t\tcompatClosing.notify( { state: 'teardown' } );\n\t\t\t\t\t\tif ( manager.modal ) {\n\t\t\t\t\t\t\tmanager.toggleGlobalEvents( false );\n\t\t\t\t\t\t\tmanager.toggleAriaIsolation( false );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( manager.$returnFocusTo && manager.$returnFocusTo.length ) {\n\t\t\t\t\t\t\tmanager.$returnFocusTo[ 0 ].focus();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmanager.currentWindow = null;\n\t\t\t\t\t\tmanager.lifecycle = null;\n\t\t\t\t\t\tlifecycle.deferreds.closed.resolve( data );\n\t\t\t\t\t\tcompatClosing.resolve( data );\n\t\t\t\t\t} );\n\t\t\t\t}, manager.getTeardownDelay() );\n\t\t\t} );\n\t\t}, manager.getHoldDelay() );\n\t} );\n\n\treturn lifecycle;\n};\n\n/**\n * Add windows to the window manager.\n *\n * Windows can be added by reference, symbolic name, or explicitly defined symbolic names.\n * See the [OOUI documentation on MediaWiki] [2] for examples.\n * [2]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * This function can be called in two manners:\n *\n * 1. `.addWindows( [ winA, winB, ... ] )` (where `winA`, `winB` are OO.ui.Window objects)\n *\n *    This syntax registers windows under the symbolic names defined in their `.static.name`\n *    properties. For example, if `windowA.constructor.static.name` is `'nameA'`, calling\n *    `.openWindow( 'nameA' )` afterwards will open the window `windowA`. This syntax requires the\n *    static name to be set, otherwise an exception will be thrown.\n *\n *    This is the recommended way, as it allows for an easier switch to using a window factory.\n *\n * 2. `.addWindows( { nameA: winA, nameB: winB, ... } )`\n *\n *    This syntax registers windows under the explicitly given symbolic names. In this example,\n *    calling `.openWindow( 'nameA' )` afterwards will open the window `windowA`, regardless of what\n *    its `.static.name` is set to. The static name is not required to be set.\n *\n *    This should only be used if you need to override the default symbolic names.\n *\n * Example:\n *\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *\n *     // Add a window under the default name: see OO.ui.MessageDialog.static.name\n *     windowManager.addWindows( [ new OO.ui.MessageDialog() ] );\n *     // Add a window under an explicit name\n *     windowManager.addWindows( { myMessageDialog: new OO.ui.MessageDialog() } );\n *\n *     // Open window by default name\n *     windowManager.openWindow( 'message' );\n *     // Open window by explicitly given name\n *     windowManager.openWindow( 'myMessageDialog' );\n *\n *\n * @param {Object.<string,OO.ui.Window>|OO.ui.Window[]} windows An array of window objects specified\n *  by reference, symbolic name, or explicitly defined symbolic names.\n * @throws {Error} An error is thrown if a window is added by symbolic name, but has neither an\n *  explicit nor a statically configured symbolic name.\n */\nOO.ui.WindowManager.prototype.addWindows = function ( windows ) {\n\tvar i, len, win, name, list;\n\n\tif ( Array.isArray( windows ) ) {\n\t\t// Convert to map of windows by looking up symbolic names from static configuration\n\t\tlist = {};\n\t\tfor ( i = 0, len = windows.length; i < len; i++ ) {\n\t\t\tname = windows[ i ].constructor.static.name;\n\t\t\tif ( !name ) {\n\t\t\t\tthrow new Error( 'Windows must have a `name` static property defined.' );\n\t\t\t}\n\t\t\tlist[ name ] = windows[ i ];\n\t\t}\n\t} else if ( OO.isPlainObject( windows ) ) {\n\t\tlist = windows;\n\t}\n\n\t// Add windows\n\tfor ( name in list ) {\n\t\twin = list[ name ];\n\t\tthis.windows[ name ] = win.toggle( false );\n\t\tthis.$element.append( win.$element );\n\t\twin.setManager( this );\n\t}\n};\n\n/**\n * Remove the specified windows from the windows manager.\n *\n * Windows will be closed before they are removed. If you wish to remove all windows, you may wish\n * to use the #clearWindows method instead. If you no longer need the window manager and want to\n * ensure that it no longer listens to events, use the #destroy method.\n *\n * @param {string[]} names Symbolic names of windows to remove\n * @return {jQuery.Promise} Promise resolved when window is closed and removed\n * @throws {Error} An error is thrown if the named windows are not managed by the window manager.\n */\nOO.ui.WindowManager.prototype.removeWindows = function ( names ) {\n\tvar i, len, win, name, cleanupWindow,\n\t\tmanager = this,\n\t\tpromises = [],\n\t\tcleanup = function ( name, win ) {\n\t\t\tdelete manager.windows[ name ];\n\t\t\twin.$element.detach();\n\t\t};\n\n\tfor ( i = 0, len = names.length; i < len; i++ ) {\n\t\tname = names[ i ];\n\t\twin = this.windows[ name ];\n\t\tif ( !win ) {\n\t\t\tthrow new Error( 'Cannot remove window' );\n\t\t}\n\t\tcleanupWindow = cleanup.bind( null, name, win );\n\t\tpromises.push( this.closeWindow( name ).closed.then( cleanupWindow, cleanupWindow ) );\n\t}\n\n\treturn $.when.apply( $, promises );\n};\n\n/**\n * Remove all windows from the window manager.\n *\n * Windows will be closed before they are removed. Note that the window manager, though not in use,\n * will still listen to events. If the window manager will not be used again, you may wish to use\n * the #destroy method instead. To remove just a subset of windows, use the #removeWindows method.\n *\n * @return {jQuery.Promise} Promise resolved when all windows are closed and removed\n */\nOO.ui.WindowManager.prototype.clearWindows = function () {\n\treturn this.removeWindows( Object.keys( this.windows ) );\n};\n\n/**\n * Set dialog size. In general, this method should not be called directly.\n *\n * Fullscreen mode will be used if the dialog is too wide to fit in the screen.\n *\n * @param {OO.ui.Window} win Window to update, should be the current window\n * @chainable\n * @return {OO.ui.WindowManager} The manager, for chaining\n */\nOO.ui.WindowManager.prototype.updateWindowSize = function ( win ) {\n\tvar isFullscreen;\n\n\t// Bypass for non-current, and thus invisible, windows\n\tif ( win !== this.currentWindow ) {\n\t\treturn;\n\t}\n\n\tisFullscreen = win.getSize() === 'full';\n\n\tthis.$element.toggleClass( 'oo-ui-windowManager-fullscreen', isFullscreen );\n\tthis.$element.toggleClass( 'oo-ui-windowManager-floating', !isFullscreen );\n\twin.setDimensions( win.getSizeProperties() );\n\n\tthis.emit( 'resize', win );\n\n\treturn this;\n};\n\n/**\n * Bind or unbind global events for scrolling.\n *\n * @private\n * @param {boolean} [on] Bind global events\n * @chainable\n * @return {OO.ui.WindowManager} The manager, for chaining\n */\nOO.ui.WindowManager.prototype.toggleGlobalEvents = function ( on ) {\n\tvar scrollWidth, bodyMargin,\n\t\t$body = $( this.getElementDocument().body ),\n\t\t// We could have multiple window managers open so only modify\n\t\t// the body css at the bottom of the stack\n\t\tstackDepth = $body.data( 'windowManagerGlobalEvents' ) || 0;\n\n\ton = on === undefined ? !!this.globalEvents : !!on;\n\n\tif ( on ) {\n\t\tif ( !this.globalEvents ) {\n\t\t\t$( this.getElementWindow() ).on( {\n\t\t\t\t// Start listening for top-level window dimension changes\n\t\t\t\t'orientationchange resize': this.onWindowResizeHandler\n\t\t\t} );\n\t\t\tif ( stackDepth === 0 ) {\n\t\t\t\tscrollWidth = window.innerWidth - document.documentElement.clientWidth;\n\t\t\t\tbodyMargin = parseFloat( $body.css( 'margin-right' ) ) || 0;\n\t\t\t\t$body.addClass( 'oo-ui-windowManager-modal-active' );\n\t\t\t\t$body.css( 'margin-right', bodyMargin + scrollWidth );\n\t\t\t}\n\t\t\tstackDepth++;\n\t\t\tthis.globalEvents = true;\n\t\t}\n\t} else if ( this.globalEvents ) {\n\t\t$( this.getElementWindow() ).off( {\n\t\t\t// Stop listening for top-level window dimension changes\n\t\t\t'orientationchange resize': this.onWindowResizeHandler\n\t\t} );\n\t\tstackDepth--;\n\t\tif ( stackDepth === 0 ) {\n\t\t\t$body.removeClass( 'oo-ui-windowManager-modal-active' );\n\t\t\t$body.css( 'margin-right', '' );\n\t\t}\n\t\tthis.globalEvents = false;\n\t}\n\t$body.data( 'windowManagerGlobalEvents', stackDepth );\n\n\treturn this;\n};\n\n/**\n * Toggle screen reader visibility of content other than the window manager.\n *\n * @private\n * @param {boolean} [isolate] Make only the window manager visible to screen readers\n * @chainable\n * @return {OO.ui.WindowManager} The manager, for chaining\n */\nOO.ui.WindowManager.prototype.toggleAriaIsolation = function ( isolate ) {\n\tvar $topLevelElement;\n\tisolate = isolate === undefined ? !this.$ariaHidden : !!isolate;\n\n\tif ( isolate ) {\n\t\tif ( !this.$ariaHidden ) {\n\t\t\t// Find the top level element containing the window manager or the\n\t\t\t// window manager's element itself in case its a direct child of body\n\t\t\t$topLevelElement = this.$element.parentsUntil( 'body' ).last();\n\t\t\t$topLevelElement = $topLevelElement.length === 0 ? this.$element : $topLevelElement;\n\n\t\t\t// In case previously set by another window manager\n\t\t\tthis.$element.removeAttr( 'aria-hidden' );\n\n\t\t\t// Hide everything other than the window manager from screen readers\n\t\t\tthis.$ariaHidden = $( document.body )\n\t\t\t\t.children()\n\t\t\t\t.not( 'script' )\n\t\t\t\t.not( $topLevelElement )\n\t\t\t\t.attr( 'aria-hidden', true );\n\t\t}\n\t} else if ( this.$ariaHidden ) {\n\t\t// Restore screen reader visibility\n\t\tthis.$ariaHidden.removeAttr( 'aria-hidden' );\n\t\tthis.$ariaHidden = null;\n\n\t\t// and hide the window manager\n\t\tthis.$element.attr( 'aria-hidden', true );\n\t}\n\n\treturn this;\n};\n\n/**\n * Destroy the window manager.\n *\n * Destroying the window manager ensures that it will no longer listen to events. If you would like\n * to continue using the window manager, but wish to remove all windows from it, use the\n * #clearWindows method instead.\n */\nOO.ui.WindowManager.prototype.destroy = function () {\n\tthis.toggleGlobalEvents( false );\n\tthis.toggleAriaIsolation( false );\n\tthis.clearWindows();\n\tthis.$element.remove();\n};\n","/**\n * A window is a container for elements that are in a child frame. They are used with\n * a window manager (OO.ui.WindowManager), which is used to open and close the window and control\n * its presentation. The size of a window is specified using a symbolic name (e.g., ‘small’,\n * ‘medium’, ‘large’), which is interpreted by the window manager. If the requested size is not\n * recognized, the window manager will choose a sensible fallback.\n *\n * The lifecycle of a window has three primary stages (opening, opened, and closing) in which\n * different processes are executed:\n *\n * **opening**: The opening stage begins when the window manager's\n * {@link OO.ui.WindowManager#openWindow openWindow} or the window's {@link #open open} methods are\n * used, and the window manager begins to open the window.\n *\n * - {@link #getSetupProcess} method is called and its result executed\n * - {@link #getReadyProcess} method is called and its result executed\n *\n * **opened**: The window is now open\n *\n * **closing**: The closing stage begins when the window manager's\n * {@link OO.ui.WindowManager#closeWindow closeWindow}\n * or the window's {@link #close} methods are used, and the window manager begins to close the\n * window.\n *\n * - {@link #getHoldProcess} method is called and its result executed\n * - {@link #getTeardownProcess} method is called and its result executed. The window is now closed\n *\n * Each of the window's processes (setup, ready, hold, and teardown) can be extended in subclasses\n * by overriding the window's #getSetupProcess, #getReadyProcess, #getHoldProcess and\n * #getTeardownProcess methods. Note that each {@link OO.ui.Process process} is executed in series,\n * so asynchronous processing can complete. Always assume window processes are executed\n * asynchronously.\n *\n * For more information, please see the [OOUI documentation on MediaWiki] [1].\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows\n *\n * @abstract\n * @class\n * @extends OO.ui.Element\n * @mixins OO.EventEmitter\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [size] Symbolic name of the dialog size: `small`, `medium`, `large`, `larger` or\n *  `full`.  If omitted, the value of the {@link #static-size static size} property will be used.\n */\nOO.ui.Window = function OoUiWindow( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.Window.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.EventEmitter.call( this );\n\n\t// Properties\n\tthis.manager = null;\n\tthis.size = config.size || this.constructor.static.size;\n\tthis.$frame = $( '<div>' );\n\t/**\n\t * Overlay element to use for the `$overlay` configuration option of widgets that support it.\n\t * Things put inside it are overlaid on top of the window and are not bound to its dimensions.\n\t * See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n\t *\n\t *     MyDialog.prototype.initialize = function () {\n\t *       ...\n\t *       var popupButton = new OO.ui.PopupButtonWidget( {\n\t *         $overlay: this.$overlay,\n\t *         label: 'Popup button',\n\t *         popup: {\n\t *           $content: $( '<p>Popup content.</p><p>More content.</p><p>Yet more content.</p>' ),\n\t *           padded: true\n\t *         }\n\t *       } );\n\t *       ...\n\t *     };\n\t *\n\t * @property {jQuery}\n\t */\n\tthis.$overlay = $( '<div>' );\n\tthis.$content = $( '<div>' );\n\n\tthis.$focusTrapBefore = $( '<div>' ).prop( 'tabIndex', 0 );\n\tthis.$focusTrapAfter = $( '<div>' ).prop( 'tabIndex', 0 );\n\tthis.$focusTraps = this.$focusTrapBefore.add( this.$focusTrapAfter );\n\n\t// Initialization\n\tthis.$overlay.addClass( 'oo-ui-window-overlay' );\n\tthis.$content\n\t\t.addClass( 'oo-ui-window-content' )\n\t\t.attr( 'tabindex', 0 );\n\tthis.$frame\n\t\t.addClass( 'oo-ui-window-frame' )\n\t\t.append( this.$focusTrapBefore, this.$content, this.$focusTrapAfter );\n\tthis.$element\n\t\t.addClass( 'oo-ui-window' )\n\t\t.append( this.$frame, this.$overlay );\n\n\t// Initially hidden - using #toggle may cause errors if subclasses override toggle with methods\n\t// that reference properties not initialized at that time of parent class construction\n\t// TODO: Find a better way to handle post-constructor setup\n\tthis.visible = false;\n\tthis.$element.addClass( 'oo-ui-element-hidden' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Window, OO.ui.Element );\nOO.mixinClass( OO.ui.Window, OO.EventEmitter );\n\n/* Static Properties */\n\n/**\n * Symbolic name of the window size: `small`, `medium`, `large`, `larger` or `full`.\n *\n * The static size is used if no #size is configured during construction.\n *\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Window.static.size = 'medium';\n\n/* Methods */\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.onMouseDown = function ( e ) {\n\t// Prevent clicking on the click-block from stealing focus\n\tif ( e.target === this.$element[ 0 ] ) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Check if the window has been initialized.\n *\n * Initialization occurs when a window is added to a manager.\n *\n * @return {boolean} Window has been initialized\n */\nOO.ui.Window.prototype.isInitialized = function () {\n\treturn !!this.manager;\n};\n\n/**\n * Check if the window is visible.\n *\n * @return {boolean} Window is visible\n */\nOO.ui.Window.prototype.isVisible = function () {\n\treturn this.visible;\n};\n\n/**\n * Check if the window is opening.\n *\n * This method is a wrapper around the window manager's\n * {@link OO.ui.WindowManager#isOpening isOpening} method.\n *\n * @return {boolean} Window is opening\n */\nOO.ui.Window.prototype.isOpening = function () {\n\treturn this.manager.isOpening( this );\n};\n\n/**\n * Check if the window is closing.\n *\n * This method is a wrapper around the window manager's\n * {@link OO.ui.WindowManager#isClosing isClosing} method.\n *\n * @return {boolean} Window is closing\n */\nOO.ui.Window.prototype.isClosing = function () {\n\treturn this.manager.isClosing( this );\n};\n\n/**\n * Check if the window is opened.\n *\n * This method is a wrapper around the window manager's\n * {@link OO.ui.WindowManager#isOpened isOpened} method.\n *\n * @return {boolean} Window is opened\n */\nOO.ui.Window.prototype.isOpened = function () {\n\treturn this.manager.isOpened( this );\n};\n\n/**\n * Get the window manager.\n *\n * All windows must be attached to a window manager, which is used to open\n * and close the window and control its presentation.\n *\n * @return {OO.ui.WindowManager} Manager of window\n */\nOO.ui.Window.prototype.getManager = function () {\n\treturn this.manager;\n};\n\n/**\n * Get the symbolic name of the window size (e.g., `small` or `medium`).\n *\n * @return {string} Symbolic name of the size: `small`, `medium`, `large`, `larger`, `full`\n */\nOO.ui.Window.prototype.getSize = function () {\n\tvar viewport = OO.ui.Element.static.getDimensions( this.getElementWindow() ),\n\t\tsizes = this.manager.constructor.static.sizes,\n\t\tsize = this.size;\n\n\tif ( !sizes[ size ] ) {\n\t\tsize = this.manager.constructor.static.defaultSize;\n\t}\n\tif ( size !== 'full' && viewport.rect.right - viewport.rect.left < sizes[ size ].width ) {\n\t\tsize = 'full';\n\t}\n\n\treturn size;\n};\n\n/**\n * Get the size properties associated with the current window size\n *\n * @return {Object} Size properties\n */\nOO.ui.Window.prototype.getSizeProperties = function () {\n\treturn this.manager.constructor.static.sizes[ this.getSize() ];\n};\n\n/**\n * Disable transitions on window's frame for the duration of the callback function, then enable them\n * back.\n *\n * @private\n * @param {Function} callback Function to call while transitions are disabled\n */\nOO.ui.Window.prototype.withoutSizeTransitions = function ( callback ) {\n\t// Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.\n\t// Disable transitions first, otherwise we'll get values from when the window was animating.\n\t// We need to build the transition CSS properties using these specific properties since\n\t// Firefox doesn't return anything useful when asked just for 'transition'.\n\tvar oldTransition = this.$frame.css( 'transition-property' ) + ' ' +\n\t\tthis.$frame.css( 'transition-duration' ) + ' ' +\n\t\tthis.$frame.css( 'transition-timing-function' ) + ' ' +\n\t\tthis.$frame.css( 'transition-delay' );\n\n\tthis.$frame.css( 'transition', 'none' );\n\tcallback();\n\n\t// Force reflow to make sure the style changes done inside callback\n\t// really are not transitioned\n\tthis.$frame.height();\n\tthis.$frame.css( 'transition', oldTransition );\n};\n\n/**\n * Get the height of the full window contents (i.e., the window head, body and foot together).\n *\n * What constitutes the head, body, and foot varies depending on the window type.\n * A {@link OO.ui.MessageDialog message dialog} displays a title and message in its body,\n * and any actions in the foot. A {@link OO.ui.ProcessDialog process dialog} displays a title\n * and special actions in the head, and dialog content in the body.\n *\n * To get just the height of the dialog body, use the #getBodyHeight method.\n *\n * @return {number} The height of the window contents (the dialog head, body and foot) in pixels\n */\nOO.ui.Window.prototype.getContentHeight = function () {\n\tvar bodyHeight,\n\t\twin = this,\n\t\tbodyStyleObj = this.$body[ 0 ].style,\n\t\tframeStyleObj = this.$frame[ 0 ].style;\n\n\t// Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.\n\t// Disable transitions first, otherwise we'll get values from when the window was animating.\n\tthis.withoutSizeTransitions( function () {\n\t\tvar oldHeight = frameStyleObj.height,\n\t\t\toldPosition = bodyStyleObj.position;\n\t\tframeStyleObj.height = '1px';\n\t\t// Force body to resize to new width\n\t\tbodyStyleObj.position = 'relative';\n\t\tbodyHeight = win.getBodyHeight();\n\t\tframeStyleObj.height = oldHeight;\n\t\tbodyStyleObj.position = oldPosition;\n\t} );\n\n\treturn (\n\t\t// Add buffer for border\n\t\t( this.$frame.outerHeight() - this.$frame.innerHeight() ) +\n\t\t// Use combined heights of children\n\t\t( this.$head.outerHeight( true ) + bodyHeight + this.$foot.outerHeight( true ) )\n\t);\n};\n\n/**\n * Get the height of the window body.\n *\n * To get the height of the full window contents (the window body, head, and foot together),\n * use #getContentHeight.\n *\n * When this function is called, the window will temporarily have been resized\n * to height=1px, so .scrollHeight measurements can be taken accurately.\n *\n * @return {number} Height of the window body in pixels\n */\nOO.ui.Window.prototype.getBodyHeight = function () {\n\treturn this.$body[ 0 ].scrollHeight;\n};\n\n/**\n * Get the directionality of the frame (right-to-left or left-to-right).\n *\n * @return {string} Directionality: `'ltr'` or `'rtl'`\n */\nOO.ui.Window.prototype.getDir = function () {\n\treturn OO.ui.Element.static.getDir( this.$content ) || 'ltr';\n};\n\n/**\n * Get the 'setup' process.\n *\n * The setup process is used to set up a window for use in a particular context, based on the `data`\n * argument. This method is called during the opening phase of the window’s lifecycle (before the\n * opening animation). You can add elements to the window in this process or set their default\n * values.\n *\n * Override this method to add additional steps to the ‘setup’ process the parent method provides\n * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods\n * of OO.ui.Process.\n *\n * To add window content that persists between openings, you may wish to use the #initialize method\n * instead.\n *\n * @param {Object} [data] Window opening data\n * @return {OO.ui.Process} Setup process\n */\nOO.ui.Window.prototype.getSetupProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Get the ‘ready’ process.\n *\n * The ready process is used to ready a window for use in a particular context, based on the `data`\n * argument. This method is called during the opening phase of the window’s lifecycle, after the\n * window has been {@link #getSetupProcess setup} (after the opening animation). You can focus\n * elements in the window in this process, or open their dropdowns.\n *\n * Override this method to add additional steps to the ‘ready’ process the parent method\n * provides using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next}\n * methods of OO.ui.Process.\n *\n * @param {Object} [data] Window opening data\n * @return {OO.ui.Process} Ready process\n */\nOO.ui.Window.prototype.getReadyProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Get the 'hold' process.\n *\n * The hold process is used to keep a window from being used in a particular context, based on the\n * `data` argument. This method is called during the closing phase of the window’s lifecycle (before\n * the closing animation). You can close dropdowns of elements in the window in this process, if\n * they do not get closed automatically.\n *\n * Override this method to add additional steps to the 'hold' process the parent method provides\n * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods\n * of OO.ui.Process.\n *\n * @param {Object} [data] Window closing data\n * @return {OO.ui.Process} Hold process\n */\nOO.ui.Window.prototype.getHoldProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Get the ‘teardown’ process.\n *\n * The teardown process is used to teardown a window after use. During teardown, user interactions\n * within the window are conveyed and the window is closed, based on the `data` argument. This\n * method is called during the closing phase of the window’s lifecycle (after the closing\n * animation). You can remove elements in the window in this process or clear their values.\n *\n * Override this method to add additional steps to the ‘teardown’ process the parent method provides\n * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods\n * of OO.ui.Process.\n *\n * @param {Object} [data] Window closing data\n * @return {OO.ui.Process} Teardown process\n */\nOO.ui.Window.prototype.getTeardownProcess = function () {\n\treturn new OO.ui.Process();\n};\n\n/**\n * Set the window manager.\n *\n * This will cause the window to initialize. Calling it more than once will cause an error.\n *\n * @param {OO.ui.WindowManager} manager Manager for this window\n * @throws {Error} An error is thrown if the method is called more than once\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.setManager = function ( manager ) {\n\tif ( this.manager ) {\n\t\tthrow new Error( 'Cannot set window manager, window already has a manager' );\n\t}\n\n\tthis.manager = manager;\n\tthis.initialize();\n\n\treturn this;\n};\n\n/**\n * Set the window size by symbolic name (e.g., 'small' or 'medium')\n *\n * @param {string} size Symbolic name of size: `small`, `medium`, `large`, `larger` or\n *  `full`\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.setSize = function ( size ) {\n\tthis.size = size;\n\tthis.updateSize();\n\treturn this;\n};\n\n/**\n * Update the window size.\n *\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.updateSize = function () {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot update window size, must be attached to a manager' );\n\t}\n\n\tthis.manager.updateWindowSize( this );\n\n\treturn this;\n};\n\n/**\n * Set window dimensions. This method is called by the {@link OO.ui.WindowManager window manager}\n * when the window is opening. In general, setDimensions should not be called directly.\n *\n * To set the size of the window, use the #setSize method.\n *\n * @param {Object} dim CSS dimension properties\n * @param {string|number} [dim.width] Width\n * @param {string|number} [dim.minWidth] Minimum width\n * @param {string|number} [dim.maxWidth] Maximum width\n * @param {string|number} [dim.height] Height, omit to set based on height of contents\n * @param {string|number} [dim.minHeight] Minimum height\n * @param {string|number} [dim.maxHeight] Maximum height\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.setDimensions = function ( dim ) {\n\tvar height,\n\t\twin = this,\n\t\tstyleObj = this.$frame[ 0 ].style;\n\n\t// Calculate the height we need to set using the correct width\n\tif ( dim.height === undefined ) {\n\t\tthis.withoutSizeTransitions( function () {\n\t\t\tvar oldWidth = styleObj.width;\n\t\t\twin.$frame.css( 'width', dim.width || '' );\n\t\t\theight = win.getContentHeight();\n\t\t\tstyleObj.width = oldWidth;\n\t\t} );\n\t} else {\n\t\theight = dim.height;\n\t}\n\n\tthis.$frame.css( {\n\t\twidth: dim.width || '',\n\t\tminWidth: dim.minWidth || '',\n\t\tmaxWidth: dim.maxWidth || '',\n\t\theight: height || '',\n\t\tminHeight: dim.minHeight || '',\n\t\tmaxHeight: dim.maxHeight || ''\n\t} );\n\n\treturn this;\n};\n\n/**\n * Initialize window contents.\n *\n * Before the window is opened for the first time, #initialize is called so that content that\n * persists between openings can be added to the window.\n *\n * To set up a window with new content each time the window opens, use #getSetupProcess.\n *\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n * @chainable\n * @return {OO.ui.Window} The window, for chaining\n */\nOO.ui.Window.prototype.initialize = function () {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot initialize window, must be attached to a manager' );\n\t}\n\n\t// Properties\n\tthis.$head = $( '<div>' );\n\tthis.$body = $( '<div>' );\n\tthis.$foot = $( '<div>' );\n\tthis.$document = $( this.getElementDocument() );\n\n\t// Events\n\tthis.$element.on( 'mousedown', this.onMouseDown.bind( this ) );\n\n\t// Initialization\n\tthis.$head.addClass( 'oo-ui-window-head' );\n\tthis.$body.addClass( 'oo-ui-window-body' );\n\tthis.$foot.addClass( 'oo-ui-window-foot' );\n\tthis.$content.append( this.$head, this.$body, this.$foot );\n\n\treturn this;\n};\n\n/**\n * Called when someone tries to focus the hidden element at the end of the dialog.\n * Sends focus back to the start of the dialog.\n *\n * @param {jQuery.Event} event Focus event\n */\nOO.ui.Window.prototype.onFocusTrapFocused = function ( event ) {\n\tvar backwards = this.$focusTrapBefore.is( event.target ),\n\t\telement = OO.ui.findFocusable( this.$content, backwards );\n\tif ( element ) {\n\t\t// There's a focusable element inside the content, at the front or\n\t\t// back depending on which focus trap we hit; select it.\n\t\telement.focus();\n\t} else {\n\t\t// There's nothing focusable inside the content. As a fallback,\n\t\t// this.$content is focusable, and focusing it will keep our focus\n\t\t// properly trapped. It's not a *meaningful* focus, since it's just\n\t\t// the content-div for the Window, but it's better than letting focus\n\t\t// escape into the page.\n\t\tthis.$content.trigger( 'focus' );\n\t}\n};\n\n/**\n * Open the window.\n *\n * This method is a wrapper around a call to the window\n * manager’s {@link OO.ui.WindowManager#openWindow openWindow} method.\n *\n * To customize the window each time it opens, use #getSetupProcess or #getReadyProcess.\n *\n * @param {Object} [data] Window opening data\n * @return {OO.ui.WindowInstance} See OO.ui.WindowManager#openWindow\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n */\nOO.ui.Window.prototype.open = function ( data ) {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot open window, must be attached to a manager' );\n\t}\n\n\treturn this.manager.openWindow( this, data );\n};\n\n/**\n * Close the window.\n *\n * This method is a wrapper around a call to the window\n * manager’s {@link OO.ui.WindowManager#closeWindow closeWindow} method.\n *\n * The window's #getHoldProcess and #getTeardownProcess methods are called during the closing\n * phase of the window’s lifecycle and can be used to specify closing behavior each time\n * the window closes.\n *\n * @param {Object} [data] Window closing data\n * @return {OO.ui.WindowInstance} See OO.ui.WindowManager#closeWindow\n * @throws {Error} An error is thrown if the window is not attached to a window manager\n */\nOO.ui.Window.prototype.close = function ( data ) {\n\tif ( !this.manager ) {\n\t\tthrow new Error( 'Cannot close window, must be attached to a manager' );\n\t}\n\n\treturn this.manager.closeWindow( this, data );\n};\n\n/**\n * Setup window.\n *\n * This is called by OO.ui.WindowManager during window opening (before the animation), and should\n * not be called directly by other systems.\n *\n * @param {Object} [data] Window opening data\n * @return {jQuery.Promise} Promise resolved when window is setup\n */\nOO.ui.Window.prototype.setup = function ( data ) {\n\tvar win = this;\n\n\tthis.toggle( true );\n\n\tthis.focusTrapHandler = OO.ui.bind( this.onFocusTrapFocused, this );\n\tthis.$focusTraps.on( 'focus', this.focusTrapHandler );\n\n\treturn this.getSetupProcess( data ).execute().then( function () {\n\t\twin.updateSize();\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.addClass( 'oo-ui-window-active oo-ui-window-setup' ).width();\n\t\twin.$content.addClass( 'oo-ui-window-content-setup' ).width();\n\t} );\n};\n\n/**\n * Ready window.\n *\n * This is called by OO.ui.WindowManager during window opening (after the animation), and should not\n * be called directly by other systems.\n *\n * @param {Object} [data] Window opening data\n * @return {jQuery.Promise} Promise resolved when window is ready\n */\nOO.ui.Window.prototype.ready = function ( data ) {\n\tvar win = this;\n\n\tthis.$content.trigger( 'focus' );\n\treturn this.getReadyProcess( data ).execute().then( function () {\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.addClass( 'oo-ui-window-ready' ).width();\n\t\twin.$content.addClass( 'oo-ui-window-content-ready' ).width();\n\t} );\n};\n\n/**\n * Hold window.\n *\n * This is called by OO.ui.WindowManager during window closing (before the animation), and should\n * not be called directly by other systems.\n *\n * @param {Object} [data] Window closing data\n * @return {jQuery.Promise} Promise resolved when window is held\n */\nOO.ui.Window.prototype.hold = function ( data ) {\n\tvar win = this;\n\n\treturn this.getHoldProcess( data ).execute().then( function () {\n\t\t// Get the focused element within the window's content\n\t\tvar $focus = win.$content.find(\n\t\t\tOO.ui.Element.static.getDocument( win.$content ).activeElement\n\t\t);\n\n\t\t// Blur the focused element\n\t\tif ( $focus.length ) {\n\t\t\t$focus[ 0 ].blur();\n\t\t}\n\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.removeClass( 'oo-ui-window-ready oo-ui-window-setup' ).width();\n\t\twin.$content.removeClass( 'oo-ui-window-content-ready oo-ui-window-content-setup' ).width();\n\t} );\n};\n\n/**\n * Teardown window.\n *\n * This is called by OO.ui.WindowManager during window closing (after the animation), and should not\n * be called directly by other systems.\n *\n * @param {Object} [data] Window closing data\n * @return {jQuery.Promise} Promise resolved when window is torn down\n */\nOO.ui.Window.prototype.teardown = function ( data ) {\n\tvar win = this;\n\n\treturn this.getTeardownProcess( data ).execute().then( function () {\n\t\t// Force redraw by asking the browser to measure the elements' widths\n\t\twin.$element.removeClass( 'oo-ui-window-active' ).width();\n\n\t\twin.$focusTraps.off( 'focus', win.focusTrapHandler );\n\t\twin.toggle( false );\n\t} );\n};\n","/**\n * The Dialog class serves as the base class for the other types of dialogs.\n * Unless extended to include controls, the rendered dialog box is a simple window\n * that users can close by hitting the Escape key. Dialog windows are used with OO.ui.WindowManager,\n * which opens, closes, and controls the presentation of the window. See the\n * [OOUI documentation on MediaWiki] [1] for more information.\n *\n *     @example\n *     // A simple dialog window.\n *     function MyDialog( config ) {\n *         MyDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MyDialog, OO.ui.Dialog );\n *     MyDialog.static.name = 'myDialog';\n *     MyDialog.prototype.initialize = function () {\n *         MyDialog.parent.prototype.initialize.call( this );\n *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.content.$element.append( '<p>A simple dialog window. Press Escape key to ' +\n *             'close.</p>' );\n *         this.$body.append( this.content.$element );\n *     };\n *     MyDialog.prototype.getBodyHeight = function () {\n *         return this.content.$element.outerHeight( true );\n *     };\n *     var myDialog = new MyDialog( {\n *         size: 'medium'\n *     } );\n *     // Create and append a window manager, which opens and closes the window.\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *     windowManager.addWindows( [ myDialog ] );\n *     // Open the window!\n *     windowManager.openWindow( myDialog );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Dialogs\n *\n * @abstract\n * @class\n * @extends OO.ui.Window\n * @mixins OO.ui.mixin.PendingElement\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.Dialog = function OoUiDialog( config ) {\n\t// Parent constructor\n\tOO.ui.Dialog.parent.call( this, config );\n\n\t// Mixin constructors\n\tOO.ui.mixin.PendingElement.call( this );\n\n\t// Properties\n\tthis.actions = new OO.ui.ActionSet();\n\tthis.attachedActions = [];\n\tthis.currentAction = null;\n\tthis.onDialogKeyDownHandler = this.onDialogKeyDown.bind( this );\n\n\t// Events\n\tthis.actions.connect( this, {\n\t\tclick: 'onActionClick',\n\t\tchange: 'onActionsChange'\n\t} );\n\n\t// Initialization\n\tthis.$element\n\t\t.addClass( 'oo-ui-dialog' )\n\t\t.attr( 'role', 'dialog' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.Dialog, OO.ui.Window );\nOO.mixinClass( OO.ui.Dialog, OO.ui.mixin.PendingElement );\n\n/* Static Properties */\n\n/**\n * Symbolic name of dialog.\n *\n * The dialog class must have a symbolic name in order to be registered with OO.Factory.\n * Please see the [OOUI documentation on MediaWiki] [3] for more information.\n *\n * [3]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers\n *\n * @abstract\n * @static\n * @inheritable\n * @property {string}\n */\nOO.ui.Dialog.static.name = '';\n\n/**\n * The dialog title.\n *\n * The title can be specified as a plaintext string, a {@link OO.ui.mixin.LabelElement Label} node,\n * or a function that will produce a Label node or string. The title can also be specified with data\n * passed to the constructor (see #getSetupProcess). In this case, the static value will be\n * overridden.\n *\n * @abstract\n * @static\n * @inheritable\n * @property {jQuery|string|Function}\n */\nOO.ui.Dialog.static.title = '';\n\n/**\n * An array of configured {@link OO.ui.ActionWidget action widgets}.\n *\n * Actions can also be specified with data passed to the constructor (see #getSetupProcess). In this\n * case, the static value will be overridden.\n *\n * [2]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets\n *\n * @static\n * @inheritable\n * @property {Object[]}\n */\nOO.ui.Dialog.static.actions = [];\n\n/**\n * Close the dialog when the Escape key is pressed.\n *\n * @static\n * @abstract\n * @inheritable\n * @property {boolean}\n */\nOO.ui.Dialog.static.escapable = true;\n\n/* Methods */\n\n/**\n * Handle frame document key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.Dialog.prototype.onDialogKeyDown = function ( e ) {\n\tvar actions;\n\tif ( e.which === OO.ui.Keys.ESCAPE && this.constructor.static.escapable ) {\n\t\tthis.executeAction( '' );\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t} else if ( e.which === OO.ui.Keys.ENTER && ( e.ctrlKey || e.metaKey ) ) {\n\t\tactions = this.actions.get( { flags: 'primary', visible: true, disabled: false } );\n\t\tif ( actions.length > 0 ) {\n\t\t\tthis.executeAction( actions[ 0 ].getAction() );\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t}\n\t}\n};\n\n/**\n * Handle action click events.\n *\n * @private\n * @param {OO.ui.ActionWidget} action Action that was clicked\n */\nOO.ui.Dialog.prototype.onActionClick = function ( action ) {\n\tif ( !this.isPending() ) {\n\t\tthis.executeAction( action.getAction() );\n\t}\n};\n\n/**\n * Handle actions change event.\n *\n * @private\n */\nOO.ui.Dialog.prototype.onActionsChange = function () {\n\tthis.detachActions();\n\tif ( !this.isClosing() ) {\n\t\tthis.attachActions();\n\t\tif ( !this.isOpening() ) {\n\t\t\t// If the dialog is currently opening, this will be called automatically soon.\n\t\t\tthis.updateSize();\n\t\t}\n\t}\n};\n\n/**\n * Get the set of actions used by the dialog.\n *\n * @return {OO.ui.ActionSet}\n */\nOO.ui.Dialog.prototype.getActions = function () {\n\treturn this.actions;\n};\n\n/**\n * Get a process for taking action.\n *\n * When you override this method, you can create a new OO.ui.Process and return it, or add\n * additional accept steps to the process the parent method provides using the\n * {@link OO.ui.Process#first 'first'} and {@link OO.ui.Process#next 'next'} methods of\n * OO.ui.Process.\n *\n * @param {string} [action] Symbolic name of action\n * @return {OO.ui.Process} Action process\n */\nOO.ui.Dialog.prototype.getActionProcess = function ( action ) {\n\treturn new OO.ui.Process()\n\t\t.next( function () {\n\t\t\tif ( !action ) {\n\t\t\t\t// An empty action always closes the dialog without data, which should always be\n\t\t\t\t// safe and make no changes\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n *\n * @param {Object} [data] Dialog opening data\n * @param {jQuery|string|Function|null} [data.title] Dialog title, omit to use\n *  the {@link #static-title static title}\n * @param {Object[]} [data.actions] List of configuration options for each\n *   {@link OO.ui.ActionWidget action widget}, omit to use {@link #static-actions static actions}.\n */\nOO.ui.Dialog.prototype.getSetupProcess = function ( data ) {\n\tdata = data || {};\n\n\t// Parent method\n\treturn OO.ui.Dialog.parent.prototype.getSetupProcess.call( this, data )\n\t\t.next( function () {\n\t\t\tvar config = this.constructor.static,\n\t\t\t\tactions = data.actions !== undefined ? data.actions : config.actions,\n\t\t\t\ttitle = data.title !== undefined ? data.title : config.title;\n\n\t\t\tthis.title.setLabel( title ).setTitle( title );\n\t\t\tthis.actions.add( this.getActionWidgets( actions ) );\n\n\t\t\tthis.$element.on( 'keydown', this.onDialogKeyDownHandler );\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.Dialog.prototype.getTeardownProcess = function ( data ) {\n\t// Parent method\n\treturn OO.ui.Dialog.parent.prototype.getTeardownProcess.call( this, data )\n\t\t.first( function () {\n\t\t\tthis.$element.off( 'keydown', this.onDialogKeyDownHandler );\n\n\t\t\tthis.actions.clear();\n\t\t\tthis.currentAction = null;\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.Dialog.prototype.initialize = function () {\n\t// Parent method\n\tOO.ui.Dialog.parent.prototype.initialize.call( this );\n\n\t// Properties\n\tthis.title = new OO.ui.LabelWidget();\n\n\t// Initialization\n\tthis.$content.addClass( 'oo-ui-dialog-content' );\n\tthis.$element.attr( 'aria-labelledby', this.title.getElementId() );\n\tthis.setPendingElement( this.$head );\n};\n\n/**\n * Get action widgets from a list of configs\n *\n * @param {Object[]} actions Action widget configs\n * @return {OO.ui.ActionWidget[]} Action widgets\n */\nOO.ui.Dialog.prototype.getActionWidgets = function ( actions ) {\n\tvar i, len, widgets = [];\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\twidgets.push( this.getActionWidget( actions[ i ] ) );\n\t}\n\treturn widgets;\n};\n\n/**\n * Get action widget from config\n *\n * Override this method to change the action widget class used.\n *\n * @param {Object} config Action widget config\n * @return {OO.ui.ActionWidget} Action widget\n */\nOO.ui.Dialog.prototype.getActionWidget = function ( config ) {\n\treturn new OO.ui.ActionWidget( this.getActionWidgetConfig( config ) );\n};\n\n/**\n * Get action widget config\n *\n * Override this method to modify the action widget config\n *\n * @param {Object} config Initial action widget config\n * @return {Object} Action widget config\n */\nOO.ui.Dialog.prototype.getActionWidgetConfig = function ( config ) {\n\treturn config;\n};\n\n/**\n * Attach action actions.\n *\n * @protected\n */\nOO.ui.Dialog.prototype.attachActions = function () {\n\t// Remember the list of potentially attached actions\n\tthis.attachedActions = this.actions.get();\n};\n\n/**\n * Detach action actions.\n *\n * @protected\n * @chainable\n * @return {OO.ui.Dialog} The dialog, for chaining\n */\nOO.ui.Dialog.prototype.detachActions = function () {\n\tvar i, len;\n\n\t// Detach all actions that may have been previously attached\n\tfor ( i = 0, len = this.attachedActions.length; i < len; i++ ) {\n\t\tthis.attachedActions[ i ].$element.detach();\n\t}\n\tthis.attachedActions = [];\n\n\treturn this;\n};\n\n/**\n * Execute an action.\n *\n * @param {string} action Symbolic name of action to execute\n * @return {jQuery.Promise} Promise resolved when action completes, rejected if it fails\n */\nOO.ui.Dialog.prototype.executeAction = function ( action ) {\n\tthis.pushPending();\n\tthis.currentAction = action;\n\treturn this.getActionProcess( action ).execute()\n\t\t.always( this.popPending.bind( this ) );\n};\n","/**\n * MessageDialogs display a confirmation or alert message. By default, the rendered dialog box\n * consists of a header that contains the dialog title, a body with the message, and a footer that\n * contains any {@link OO.ui.ActionWidget action widgets}. The MessageDialog class is the only type\n * of {@link OO.ui.Dialog dialog} that is usually instantiated directly.\n *\n * There are two basic types of message dialogs, confirmation and alert:\n *\n * - **confirmation**: the dialog title describes what a progressive action will do and the message\n *   provides more details about the consequences.\n * - **alert**: the dialog title describes which event occurred and the message provides more\n *   information about why the event occurred.\n *\n * The MessageDialog class specifies two actions: ‘accept’, the primary\n * action (e.g., ‘ok’) and ‘reject,’ the safe action (e.g., ‘cancel’). Both will close the window,\n * passing along the selected action.\n *\n * For more information and examples, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Example: Creating and opening a message dialog window.\n *     var messageDialog = new OO.ui.MessageDialog();\n *\n *     // Create and append a window manager.\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *     windowManager.addWindows( [ messageDialog ] );\n *     // Open the window.\n *     windowManager.openWindow( messageDialog, {\n *         title: 'Basic message dialog',\n *         message: 'This is the message'\n *     } );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Message_Dialogs\n *\n * @class\n * @extends OO.ui.Dialog\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.MessageDialog = function OoUiMessageDialog( config ) {\n\t// Parent constructor\n\tOO.ui.MessageDialog.parent.call( this, config );\n\n\t// Properties\n\tthis.verticalActionLayout = null;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-messageDialog' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.MessageDialog, OO.ui.Dialog );\n\n/* Static Properties */\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MessageDialog.static.name = 'message';\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MessageDialog.static.size = 'small';\n\n/**\n * Dialog title.\n *\n * The title of a confirmation dialog describes what a progressive action will do. The\n * title of an alert dialog describes which event occurred.\n *\n * @static\n * @inheritable\n * @property {jQuery|string|Function|null}\n */\nOO.ui.MessageDialog.static.title = null;\n\n/**\n * The message displayed in the dialog body.\n *\n * A confirmation message describes the consequences of a progressive action. An alert\n * message describes why an event occurred.\n *\n * @static\n * @inheritable\n * @property {jQuery|string|Function|null}\n */\nOO.ui.MessageDialog.static.message = null;\n\n/**\n * @static\n * @inheritdoc\n */\nOO.ui.MessageDialog.static.actions = [\n\t// Note that OO.ui.alert() and OO.ui.confirm() rely on these.\n\t{ action: 'accept', label: OO.ui.deferMsg( 'ooui-dialog-message-accept' ), flags: 'primary' },\n\t{ action: 'reject', label: OO.ui.deferMsg( 'ooui-dialog-message-reject' ), flags: 'safe' }\n];\n\n/* Methods */\n\n/**\n * Toggle action layout between vertical and horizontal.\n *\n * @private\n * @param {boolean} [value] Layout actions vertically, omit to toggle\n * @chainable\n * @return {OO.ui.MessageDialog} The dialog, for chaining\n */\nOO.ui.MessageDialog.prototype.toggleVerticalActionLayout = function ( value ) {\n\tvalue = value === undefined ? !this.verticalActionLayout : !!value;\n\n\tif ( value !== this.verticalActionLayout ) {\n\t\tthis.verticalActionLayout = value;\n\t\tthis.$actions\n\t\t\t.toggleClass( 'oo-ui-messageDialog-actions-vertical', value )\n\t\t\t.toggleClass( 'oo-ui-messageDialog-actions-horizontal', !value );\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getActionProcess = function ( action ) {\n\tif ( action ) {\n\t\treturn new OO.ui.Process( function () {\n\t\t\tthis.close( { action: action } );\n\t\t}, this );\n\t}\n\treturn OO.ui.MessageDialog.parent.prototype.getActionProcess.call( this, action );\n};\n\n/**\n * @inheritdoc\n *\n * @param {Object} [data] Dialog opening data\n * @param {jQuery|string|Function|null} [data.title] Description of the action being confirmed\n * @param {jQuery|string|Function|null} [data.message] Description of the action's consequence\n * @param {string} [data.size] Symbolic name of the dialog size, see OO.ui.Window\n * @param {Object[]} [data.actions] List of OO.ui.ActionOptionWidget configuration options for each\n *  action item\n */\nOO.ui.MessageDialog.prototype.getSetupProcess = function ( data ) {\n\tdata = data || {};\n\n\t// Parent method\n\treturn OO.ui.MessageDialog.parent.prototype.getSetupProcess.call( this, data )\n\t\t.next( function () {\n\t\t\tthis.title.setLabel(\n\t\t\t\tdata.title !== undefined ? data.title : this.constructor.static.title\n\t\t\t);\n\t\t\tthis.message.setLabel(\n\t\t\t\tdata.message !== undefined ? data.message : this.constructor.static.message\n\t\t\t);\n\t\t\tthis.size = data.size !== undefined ? data.size : this.constructor.static.size;\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getReadyProcess = function ( data ) {\n\tdata = data || {};\n\n\t// Parent method\n\treturn OO.ui.MessageDialog.parent.prototype.getReadyProcess.call( this, data )\n\t\t.next( function () {\n\t\t\t// Focus the primary action button\n\t\t\tvar actions = this.actions.get();\n\t\t\tactions = actions.filter( function ( action ) {\n\t\t\t\treturn action.getFlags().indexOf( 'primary' ) > -1;\n\t\t\t} );\n\t\t\tif ( actions.length > 0 ) {\n\t\t\t\tactions[ 0 ].focus();\n\t\t\t}\n\t\t}, this );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getBodyHeight = function () {\n\tvar bodyHeight, oldOverflow,\n\t\t$scrollable = this.container.$element;\n\n\toldOverflow = $scrollable[ 0 ].style.overflow;\n\t$scrollable[ 0 ].style.overflow = 'hidden';\n\n\tOO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );\n\n\tbodyHeight = this.text.$element.outerHeight( true );\n\t$scrollable[ 0 ].style.overflow = oldOverflow;\n\n\treturn bodyHeight;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.setDimensions = function ( dim ) {\n\tvar\n\t\tdialog = this,\n\t\t$scrollable = this.container.$element;\n\tOO.ui.MessageDialog.parent.prototype.setDimensions.call( this, dim );\n\n\t// Twiddle the overflow property, otherwise an unnecessary scrollbar will be produced.\n\t// Need to do it after transition completes (250ms), add 50ms just in case.\n\tsetTimeout( function () {\n\t\tvar oldOverflow = $scrollable[ 0 ].style.overflow,\n\t\t\tactiveElement = document.activeElement;\n\n\t\t$scrollable[ 0 ].style.overflow = 'hidden';\n\n\t\tOO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );\n\n\t\t// Check reconsiderScrollbars didn't destroy our focus, as we\n\t\t// are doing this after the ready process.\n\t\tif ( activeElement && activeElement !== document.activeElement && activeElement.focus ) {\n\t\t\tactiveElement.focus();\n\t\t}\n\n\t\t$scrollable[ 0 ].style.overflow = oldOverflow;\n\t}, 300 );\n\n\tdialog.fitActions();\n\t// Wait for CSS transition to finish and do it again :(\n\tsetTimeout( function () {\n\t\tdialog.fitActions();\n\t}, 300 );\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.initialize = function () {\n\t// Parent method\n\tOO.ui.MessageDialog.parent.prototype.initialize.call( this );\n\n\t// Properties\n\tthis.$actions = $( '<div>' );\n\tthis.container = new OO.ui.PanelLayout( {\n\t\tscrollable: true, classes: [ 'oo-ui-messageDialog-container' ]\n\t} );\n\tthis.text = new OO.ui.PanelLayout( {\n\t\tpadded: true, expanded: false, classes: [ 'oo-ui-messageDialog-text' ]\n\t} );\n\tthis.message = new OO.ui.LabelWidget( {\n\t\tclasses: [ 'oo-ui-messageDialog-message' ]\n\t} );\n\n\t// Initialization\n\tthis.title.$element.addClass( 'oo-ui-messageDialog-title' );\n\tthis.$content.addClass( 'oo-ui-messageDialog-content' );\n\tthis.container.$element.append( this.text.$element );\n\tthis.text.$element.append( this.title.$element, this.message.$element );\n\tthis.$body.append( this.container.$element );\n\tthis.$actions.addClass( 'oo-ui-messageDialog-actions' );\n\tthis.$foot.append( this.$actions );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.getActionWidgetConfig = function ( config ) {\n\t// Force unframed\n\treturn $.extend( {}, config, { framed: false } );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MessageDialog.prototype.attachActions = function () {\n\tvar i, len, special, others;\n\n\t// Parent method\n\tOO.ui.MessageDialog.parent.prototype.attachActions.call( this );\n\n\tspecial = this.actions.getSpecial();\n\tothers = this.actions.getOthers();\n\n\tif ( special.safe ) {\n\t\tthis.$actions.append( special.safe.$element );\n\t\tspecial.safe.toggleFramed( true );\n\t}\n\tfor ( i = 0, len = others.length; i < len; i++ ) {\n\t\tthis.$actions.append( others[ i ].$element );\n\t\tothers[ i ].toggleFramed( true );\n\t}\n\tif ( special.primary ) {\n\t\tthis.$actions.append( special.primary.$element );\n\t\tspecial.primary.toggleFramed( true );\n\t}\n};\n\n/**\n * Fit action actions into columns or rows.\n *\n * Columns will be used if all labels can fit without overflow, otherwise rows will be used.\n *\n * @private\n */\nOO.ui.MessageDialog.prototype.fitActions = function () {\n\tvar i, len, action,\n\t\tprevious = this.verticalActionLayout,\n\t\tactions = this.actions.get();\n\n\t// Detect clipping\n\tthis.toggleVerticalActionLayout( false );\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\taction = actions[ i ];\n\t\tif ( action.$element[ 0 ].scrollWidth > action.$element[ 0 ].clientWidth ) {\n\t\t\tthis.toggleVerticalActionLayout( true );\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Move the body out of the way of the foot\n\tthis.$body.css( 'bottom', this.$foot.outerHeight( true ) );\n\n\tif ( this.verticalActionLayout !== previous ) {\n\t\t// We changed the layout, window height might need to be updated.\n\t\tthis.updateSize();\n\t}\n};\n","/**\n * ProcessDialog windows encapsulate a {@link OO.ui.Process process} and all of the code necessary\n * to complete it. If the process terminates with an error, a customizable {@link OO.ui.Error error\n * interface} alerts users to the trouble, permitting the user to dismiss the error and try again\n * when relevant. The ProcessDialog class is always extended and customized with the actions and\n * content required for each process.\n *\n * The process dialog box consists of a header that visually represents the ‘working’ state of long\n * processes with an animation. The header contains the dialog title as well as\n * two {@link OO.ui.ActionWidget action widgets}:  a ‘safe’ action on the left (e.g., ‘Cancel’) and\n * a ‘primary’ action on the right (e.g., ‘Done’).\n *\n * Like other windows, the process dialog is managed by a\n * {@link OO.ui.WindowManager window manager}.\n * Please see the [OOUI documentation on MediaWiki][1] for more information and examples.\n *\n *     @example\n *     // Example: Creating and opening a process dialog window.\n *     function MyProcessDialog( config ) {\n *         MyProcessDialog.parent.call( this, config );\n *     }\n *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );\n *\n *     MyProcessDialog.static.name = 'myProcessDialog';\n *     MyProcessDialog.static.title = 'Process dialog';\n *     MyProcessDialog.static.actions = [\n *         { action: 'save', label: 'Done', flags: 'primary' },\n *         { label: 'Cancel', flags: 'safe' }\n *     ];\n *\n *     MyProcessDialog.prototype.initialize = function () {\n *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );\n *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );\n *         this.content.$element.append( '<p>This is a process dialog window. The header ' +\n *             'contains the title and two buttons: \\'Cancel\\' (a safe action) on the left and ' +\n *             '\\'Done\\' (a primary action)  on the right.</p>' );\n *         this.$body.append( this.content.$element );\n *     };\n *     MyProcessDialog.prototype.getActionProcess = function ( action ) {\n *         var dialog = this;\n *         if ( action ) {\n *             return new OO.ui.Process( function () {\n *                 dialog.close( { action: action } );\n *             } );\n *         }\n *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );\n *     };\n *\n *     var windowManager = new OO.ui.WindowManager();\n *     $( document.body ).append( windowManager.$element );\n *\n *     var dialog = new MyProcessDialog();\n *     windowManager.addWindows( [ dialog ] );\n *     windowManager.openWindow( dialog );\n *\n * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n *\n * @abstract\n * @class\n * @extends OO.ui.Dialog\n *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.ProcessDialog = function OoUiProcessDialog( config ) {\n\t// Parent constructor\n\tOO.ui.ProcessDialog.parent.call( this, config );\n\n\t// Properties\n\tthis.fitOnOpen = false;\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-processDialog' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ProcessDialog, OO.ui.Dialog );\n\n/* Methods */\n\n/**\n * Handle dismiss button click events.\n *\n * Hides errors.\n *\n * @private\n */\nOO.ui.ProcessDialog.prototype.onDismissErrorButtonClick = function () {\n\tthis.hideErrors();\n};\n\n/**\n * Handle retry button click events.\n *\n * Hides errors and then tries again.\n *\n * @private\n */\nOO.ui.ProcessDialog.prototype.onRetryButtonClick = function () {\n\tthis.hideErrors();\n\tthis.executeAction( this.currentAction );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.initialize = function () {\n\t// Parent method\n\tOO.ui.ProcessDialog.parent.prototype.initialize.call( this );\n\n\t// Properties\n\tthis.$navigation = $( '<div>' );\n\tthis.$location = $( '<div>' );\n\tthis.$safeActions = $( '<div>' );\n\tthis.$primaryActions = $( '<div>' );\n\tthis.$otherActions = $( '<div>' );\n\tthis.dismissButton = new OO.ui.ButtonWidget( {\n\t\tlabel: OO.ui.msg( 'ooui-dialog-process-dismiss' )\n\t} );\n\tthis.retryButton = new OO.ui.ButtonWidget();\n\tthis.$errors = $( '<div>' );\n\tthis.$errorsTitle = $( '<div>' );\n\n\t// Events\n\tthis.dismissButton.connect( this, {\n\t\tclick: 'onDismissErrorButtonClick'\n\t} );\n\tthis.retryButton.connect( this, {\n\t\tclick: 'onRetryButtonClick'\n\t} );\n\tthis.title.connect( this, {\n\t\tlabelChange: 'fitLabel'\n\t} );\n\n\t// Initialization\n\tthis.title.$element.addClass( 'oo-ui-processDialog-title' );\n\tthis.$location\n\t\t.append( this.title.$element )\n\t\t.addClass( 'oo-ui-processDialog-location' );\n\tthis.$safeActions.addClass( 'oo-ui-processDialog-actions-safe' );\n\tthis.$primaryActions.addClass( 'oo-ui-processDialog-actions-primary' );\n\tthis.$otherActions.addClass( 'oo-ui-processDialog-actions-other' );\n\tthis.$errorsTitle\n\t\t.addClass( 'oo-ui-processDialog-errors-title' )\n\t\t.text( OO.ui.msg( 'ooui-dialog-process-error' ) );\n\tthis.$errors\n\t\t.addClass( 'oo-ui-processDialog-errors oo-ui-element-hidden' )\n\t\t.append( this.$errorsTitle, this.dismissButton.$element, this.retryButton.$element );\n\tthis.$content\n\t\t.addClass( 'oo-ui-processDialog-content' )\n\t\t.append( this.$errors );\n\tthis.$navigation\n\t\t.addClass( 'oo-ui-processDialog-navigation' )\n\t\t// Note: Order of appends below is important. These are in the order\n\t\t// we want tab to go through them. Display-order is handled entirely\n\t\t// by CSS absolute-positioning. As such, primary actions like \"done\"\n\t\t// should go first.\n\t\t.append( this.$primaryActions, this.$location, this.$safeActions );\n\tthis.$head.append( this.$navigation );\n\tthis.$foot.append( this.$otherActions );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.getActionWidgetConfig = function ( config ) {\n\tvar isMobile = OO.ui.isMobile();\n\n\t// Default to unframed on mobile\n\tconfig = $.extend( { framed: !isMobile }, config );\n\t// Change back buttons to icon only on mobile\n\tif (\n\t\tisMobile &&\n\t\t(\n\t\t\tconfig.flags === 'back' ||\n\t\t\t( Array.isArray( config.flags ) && config.flags.indexOf( 'back' ) !== -1 )\n\t\t)\n\t) {\n\t\t$.extend( config, {\n\t\t\ticon: 'previous',\n\t\t\tlabel: ''\n\t\t} );\n\t}\n\n\treturn config;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.attachActions = function () {\n\tvar i, len, other, special, others;\n\n\t// Parent method\n\tOO.ui.ProcessDialog.parent.prototype.attachActions.call( this );\n\n\tspecial = this.actions.getSpecial();\n\tothers = this.actions.getOthers();\n\tif ( special.primary ) {\n\t\tthis.$primaryActions.append( special.primary.$element );\n\t}\n\tfor ( i = 0, len = others.length; i < len; i++ ) {\n\t\tother = others[ i ];\n\t\tthis.$otherActions.append( other.$element );\n\t}\n\tif ( special.safe ) {\n\t\tthis.$safeActions.append( special.safe.$element );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.executeAction = function ( action ) {\n\tvar process = this;\n\treturn OO.ui.ProcessDialog.parent.prototype.executeAction.call( this, action )\n\t\t.fail( function ( errors ) {\n\t\t\tprocess.showErrors( errors || [] );\n\t\t} );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.setDimensions = function () {\n\tvar dialog = this;\n\n\t// Parent method\n\tOO.ui.ProcessDialog.parent.prototype.setDimensions.apply( this, arguments );\n\n\tthis.fitLabel();\n\n\t// If there are many actions, they might be shown on multiple lines. Their layout can change\n\t// when resizing the dialog and when changing the actions. Adjust the height of the footer to\n\t// fit them.\n\tdialog.$body.css( 'bottom', dialog.$foot.outerHeight( true ) );\n\t// Wait for CSS transition to finish and do it again :(\n\tsetTimeout( function () {\n\t\tdialog.$body.css( 'bottom', dialog.$foot.outerHeight( true ) );\n\t}, 300 );\n};\n\n/**\n * Fit label between actions.\n *\n * @private\n * @chainable\n * @return {OO.ui.MessageDialog} The dialog, for chaining\n */\nOO.ui.ProcessDialog.prototype.fitLabel = function () {\n\tvar safeWidth, primaryWidth, biggerWidth, labelWidth, navigationWidth, leftWidth, rightWidth,\n\t\tsize = this.getSizeProperties();\n\n\tif ( typeof size.width !== 'number' ) {\n\t\tif ( this.isOpened() ) {\n\t\t\tnavigationWidth = this.$head.width() - 20;\n\t\t} else if ( this.isOpening() ) {\n\t\t\tif ( !this.fitOnOpen ) {\n\t\t\t\t// Size is relative and the dialog isn't open yet, so wait.\n\t\t\t\t// FIXME: This should ideally be handled by setup somehow.\n\t\t\t\tthis.manager.lifecycle.opened.done( this.fitLabel.bind( this ) );\n\t\t\t\tthis.fitOnOpen = true;\n\t\t\t}\n\t\t\treturn;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\tnavigationWidth = size.width - 20;\n\t}\n\n\tsafeWidth = this.$safeActions.is( ':visible' ) ? this.$safeActions.width() : 0;\n\tprimaryWidth = this.$primaryActions.is( ':visible' ) ? this.$primaryActions.width() : 0;\n\tbiggerWidth = Math.max( safeWidth, primaryWidth );\n\n\tlabelWidth = this.title.$element.width();\n\n\tif ( 2 * biggerWidth + labelWidth < navigationWidth ) {\n\t\t// We have enough space to center the label\n\t\tleftWidth = rightWidth = biggerWidth;\n\t} else {\n\t\t// Let's hope we at least have enough space not to overlap, because we can't wrap\n\t\t// the label.\n\t\tif ( this.getDir() === 'ltr' ) {\n\t\t\tleftWidth = safeWidth;\n\t\t\trightWidth = primaryWidth;\n\t\t} else {\n\t\t\tleftWidth = primaryWidth;\n\t\t\trightWidth = safeWidth;\n\t\t}\n\t}\n\n\tthis.$location.css( { paddingLeft: leftWidth, paddingRight: rightWidth } );\n\n\treturn this;\n};\n\n/**\n * Handle errors that occurred during accept or reject processes.\n *\n * @private\n * @param {OO.ui.Error[]|OO.ui.Error} errors Errors to be handled\n */\nOO.ui.ProcessDialog.prototype.showErrors = function ( errors ) {\n\tvar i, len, $item, actions,\n\t\titems = [],\n\t\tabilities = {},\n\t\trecoverable = true,\n\t\twarning = false;\n\n\tif ( errors instanceof OO.ui.Error ) {\n\t\terrors = [ errors ];\n\t}\n\n\tfor ( i = 0, len = errors.length; i < len; i++ ) {\n\t\tif ( !errors[ i ].isRecoverable() ) {\n\t\t\trecoverable = false;\n\t\t}\n\t\tif ( errors[ i ].isWarning() ) {\n\t\t\twarning = true;\n\t\t}\n\t\t$item = $( '<div>' )\n\t\t\t.addClass( 'oo-ui-processDialog-error' )\n\t\t\t.append( errors[ i ].getMessage() );\n\t\titems.push( $item[ 0 ] );\n\t}\n\tthis.$errorItems = $( items );\n\tif ( recoverable ) {\n\t\tabilities[ this.currentAction ] = true;\n\t\t// Copy the flags from the first matching action.\n\t\tactions = this.actions.get( { actions: this.currentAction } );\n\t\tif ( actions.length ) {\n\t\t\tthis.retryButton.clearFlags().setFlags( actions[ 0 ].getFlags() );\n\t\t}\n\t} else {\n\t\tabilities[ this.currentAction ] = false;\n\t\tthis.actions.setAbilities( abilities );\n\t}\n\tif ( warning ) {\n\t\tthis.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-continue' ) );\n\t} else {\n\t\tthis.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-retry' ) );\n\t}\n\tthis.retryButton.toggle( recoverable );\n\tthis.$errorsTitle.after( this.$errorItems );\n\tthis.$errors.removeClass( 'oo-ui-element-hidden' ).scrollTop( 0 );\n};\n\n/**\n * Hide errors.\n *\n * @private\n */\nOO.ui.ProcessDialog.prototype.hideErrors = function () {\n\tthis.$errors.addClass( 'oo-ui-element-hidden' );\n\tif ( this.$errorItems ) {\n\t\tthis.$errorItems.remove();\n\t\tthis.$errorItems = null;\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.ProcessDialog.prototype.getTeardownProcess = function ( data ) {\n\t// Parent method\n\treturn OO.ui.ProcessDialog.parent.prototype.getTeardownProcess.call( this, data )\n\t\t.first( function () {\n\t\t\t// Make sure to hide errors.\n\t\t\tthis.hideErrors();\n\t\t\tthis.fitOnOpen = false;\n\t\t}, this );\n};\n","/**\n * @class OO.ui\n */\n\n/**\n * Lazy-initialize and return a global OO.ui.WindowManager instance, used by OO.ui.alert and\n * OO.ui.confirm.\n *\n * @private\n * @return {OO.ui.WindowManager}\n */\nOO.ui.getWindowManager = function () {\n\tif ( !OO.ui.windowManager ) {\n\t\tOO.ui.windowManager = new OO.ui.WindowManager();\n\t\t$( document.body ).append( OO.ui.windowManager.$element );\n\t\tOO.ui.windowManager.addWindows( [ new OO.ui.MessageDialog() ] );\n\t}\n\treturn OO.ui.windowManager;\n};\n\n/**\n * Display a quick modal alert dialog, using a OO.ui.MessageDialog. While the dialog is open, the\n * rest of the page will be dimmed out and the user won't be able to interact with it. The dialog\n * has only one action button, labelled \"OK\", clicking it will simply close the dialog.\n *\n * A window manager is created automatically when this function is called for the first time.\n *\n *     @example\n *     OO.ui.alert( 'Something happened!' ).done( function () {\n *         console.log( 'User closed the dialog.' );\n *     } );\n *\n *     OO.ui.alert( 'Something larger happened!', { size: 'large' } );\n *\n * @param {jQuery|string} text Message text to display\n * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess\n * @return {jQuery.Promise} Promise resolved when the user closes the dialog\n */\nOO.ui.alert = function ( text, options ) {\n\treturn OO.ui.getWindowManager().openWindow( 'message', $.extend( {\n\t\tmessage: text,\n\t\tactions: [ OO.ui.MessageDialog.static.actions[ 0 ] ]\n\t}, options ) ).closed.then( function () {\n\t\treturn undefined;\n\t} );\n};\n\n/**\n * Display a quick modal confirmation dialog, using a OO.ui.MessageDialog. While the dialog is open,\n * the rest of the page will be dimmed out and the user won't be able to interact with it. The\n * dialog has two action buttons, one to confirm an operation (labelled \"OK\") and one to cancel it\n * (labelled \"Cancel\").\n *\n * A window manager is created automatically when this function is called for the first time.\n *\n *     @example\n *     OO.ui.confirm( 'Are you sure?' ).done( function ( confirmed ) {\n *         if ( confirmed ) {\n *             console.log( 'User clicked \"OK\"!' );\n *         } else {\n *             console.log( 'User clicked \"Cancel\" or closed the dialog.' );\n *         }\n *     } );\n *\n * @param {jQuery|string} text Message text to display\n * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess\n * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to\n *  confirm, the promise will resolve to boolean `true`; otherwise, it will resolve to boolean\n *  `false`.\n */\nOO.ui.confirm = function ( text, options ) {\n\treturn OO.ui.getWindowManager().openWindow( 'message', $.extend( {\n\t\tmessage: text\n\t}, options ) ).closed.then( function ( data ) {\n\t\treturn !!( data && data.action === 'accept' );\n\t} );\n};\n\n/**\n * Display a quick modal prompt dialog, using a OO.ui.MessageDialog. While the dialog is open,\n * the rest of the page will be dimmed out and the user won't be able to interact with it. The\n * dialog has a text input widget and two action buttons, one to confirm an operation\n * (labelled \"OK\") and one to cancel it (labelled \"Cancel\").\n *\n * A window manager is created automatically when this function is called for the first time.\n *\n *     @example\n *     OO.ui.prompt( 'Choose a line to go to', {\n *         textInput: { placeholder: 'Line number' }\n *     } ).done( function ( result ) {\n *         if ( result !== null ) {\n *             console.log( 'User typed \"' + result + '\" then clicked \"OK\".' );\n *         } else {\n *             console.log( 'User clicked \"Cancel\" or closed the dialog.' );\n *         }\n *     } );\n *\n * @param {jQuery|string} text Message text to display\n * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess\n * @param {Object} [options.textInput] Additional options for text input widget,\n *  see OO.ui.TextInputWidget\n * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to\n *  confirm, the promise will resolve with the value of the text input widget; otherwise, it will\n *  resolve to `null`.\n */\nOO.ui.prompt = function ( text, options ) {\n\tvar instance,\n\t\tmanager = OO.ui.getWindowManager(),\n\t\ttextInput = new OO.ui.TextInputWidget( ( options && options.textInput ) || {} ),\n\t\ttextField = new OO.ui.FieldLayout( textInput, {\n\t\t\talign: 'top',\n\t\t\tlabel: text\n\t\t} );\n\n\tinstance = manager.openWindow( 'message', $.extend( {\n\t\tmessage: textField.$element\n\t}, options ) );\n\n\t// TODO: This is a little hacky, and could be done by extending MessageDialog instead.\n\tinstance.opened.then( function () {\n\t\ttextInput.on( 'enter', function () {\n\t\t\tmanager.getCurrentWindow().close( { action: 'accept' } );\n\t\t} );\n\t\ttextInput.focus();\n\t} );\n\n\treturn instance.closed.then( function ( data ) {\n\t\treturn data && data.action === 'accept' ? textInput.getValue() : null;\n\t} );\n};\n","}( OO ) );\n"]}
\ No newline at end of file
index 74cb6f9..8e440cb 100644 (file)
@@ -8,6 +8,9 @@
                "bell": {
                        "file": "../wikimediaui/images/icons/bell.svg"
                },
+               "error": {
+                       "file": "../wikimediaui/images/icons/error.svg"
+               },
                "message": {
                        "file": "../wikimediaui/images/icons/message.svg"
                },
index 52c4422..36590b7 100644 (file)
@@ -14,6 +14,9 @@
                                "rtl": "../wikimediaui/images/icons/articles-rtl.svg"
                        }
                },
+               "articleAdd": {
+                       "file": "../wikimediaui/images/icons/articleAdd.svg"
+               },
                "articleCheck": {
                        "file": "../wikimediaui/images/icons/articleCheck.svg"
                },
index d2a0a08..59a9a18 100644 (file)
@@ -20,9 +20,6 @@
                                "rtl": "../wikimediaui/images/icons/newspaper-rtl.svg"
                        }
                },
-               "web": {
-                       "file": "../wikimediaui/images/icons/web.svg"
-               },
                "reference": {
                        "file": "../wikimediaui/images/icons/reference.svg"
                },
                                "ltr": "../wikimediaui/images/icons/references-ltr.svg",
                                "rtl": "../wikimediaui/images/icons/references-rtl.svg"
                        }
+               },
+               "web": {
+                       "file": "../wikimediaui/images/icons/web.svg",
+                       "deprecated": "Deprecated since v0.30.2, use 'browser' from 'interactions' pack instead."
                }
        }
 }
index b1608c3..64d6bac 100644 (file)
                },
                "helpNotice": {
                        "file": {
-                               "ltr": "../wikimediaui/images/icons/helpOutlined-ltr.svg",
-                               "rtl": "../wikimediaui/images/icons/helpOutlined-rtl.svg",
+                               "ltr": "../wikimediaui/images/icons/helpNotice-ltr.svg",
+                               "rtl": "../wikimediaui/images/icons/helpNotice-rtl.svg",
                                "lang": {
-                                       "he,yi": "../wikimediaui/images/icons/helpOutlined-ltr.svg"
+                                       "he,yi": "../wikimediaui/images/icons/helpNotice-ltr.svg"
                                }
                        }
                },
index f62e3e6..9b5e986 100644 (file)
                },
                "required": {
                        "file": "../wikimediaui/images/indicators/required.svg"
-               },
-               "search": {
-                       "file": "../wikimediaui/images/indicators/search.svg",
-                       "deprecated": "This will be removed in v0.31.0."
                }
        }
 }
index 82dedb6..b4999e2 100644 (file)
@@ -2,7 +2,13 @@
        "prefix": "oo-ui-texture",
        "intro": "@import '../../../../src/styles/common';",
        "images": {
-               "pending": { "file": "../wikimediaui/images/textures/pending.gif" },
-               "transparency": { "file": "../wikimediaui/images/textures/transparency.svg" }
+               "pending": {
+                       "file": "../wikimediaui/images/textures/pending.gif",
+                       "deprecated": "Deprecated since v0.31.1."
+               },
+               "transparency": {
+                       "file": "../wikimediaui/images/textures/transparency.svg",
+                       "deprecated": "Deprecated since v0.31.1."
+               }
        }
 }
index bb4ff3c..899c01d 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 4f97043..97489da 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
                "alert": {
                        "file": "images/icons/alert.svg",
-                       "variants": [ "warning" ]
+                       "variants": [
+                               "error",
+                               "warning"
+                       ]
                },
                "bell": {
                        "file": "images/icons/bell.svg"
                },
+               "error": {
+                       "file": "images/icons/error.svg"
+               },
                "message": {
                        "file": "images/icons/message.svg"
                },
index 0e4f131..b7570fe 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
@@ -31,6 +37,9 @@
                                "rtl": "images/icons/articles-rtl.svg"
                        }
                },
+               "articleAdd": {
+                       "file": "images/icons/articleAdd.svg"
+               },
                "articleCheck": {
                        "file": "images/icons/articleCheck.svg"
                },
                                "ltr": "images/icons/tag-ltr.svg",
                                "rtl": "images/icons/tag-rtl.svg"
                        },
-                       "variants": [ "destructive", "warning" ]
+                       "variants": [
+                               "destructive",
+                               "error",
+                               "warning"
+                       ]
                },
                "upload": {
                        "file": "images/icons/upload.svg"
index 696fbf2..4f4fd4e 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
                "hieroglyph": {
                        "file": "images/icons/hieroglyph.svg"
                },
+               "imageLayoutBasic": {
+                       "file": "images/icons/imageLayoutBasic.svg"
+               },
+               "imageLayoutFrame": {
+                       "file": "images/icons/imageLayoutFrame.svg"
+               },
+               "imageLayoutFrameless": {
+                       "file": "images/icons/imageLayoutFrameless.svg"
+               },
+               "imageLayoutThumbnail": {
+                       "file": "images/icons/imageLayoutThumbnail.svg"
+               },
                "language": {
                        "file": "images/icons/language.svg"
                },
index bf91573..9cb14c1 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
@@ -37,9 +43,6 @@
                                "rtl": "images/icons/newspaper-rtl.svg"
                        }
                },
-               "web": {
-                       "file": "images/icons/web.svg"
-               },
                "reference": {
                        "file": "images/icons/reference.svg"
                },
                                "ltr": "images/icons/references-ltr.svg",
                                "rtl": "images/icons/references-rtl.svg"
                        }
+               },
+               "web": {
+                       "file": "images/icons/web.svg",
+                       "deprecated": "Deprecated since v0.30.2, use 'browser' from 'interactions' pack instead."
                }
        }
 }
index 4380c33..269e9fb 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 78090e8..df02f77 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 02c5ee4..90821ea 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 2cd0477..b460429 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
@@ -34,7 +40,7 @@
                },
                "check": {
                        "file": "images/icons/check.svg",
-                       "variants": [ "destructive" ]
+                       "variants": [ "destructive", "success" ]
                },
                "checkAll": {
                        "file": "images/icons/checkAll.svg"
                },
                "helpNotice": {
                        "file": {
-                               "ltr": "images/icons/helpOutlined-ltr.svg",
-                               "rtl": "images/icons/helpOutlined-rtl.svg",
+                               "ltr": "images/icons/helpNotice-ltr.svg",
+                               "rtl": "images/icons/helpNotice-rtl.svg",
                                "lang": {
-                                       "he,yi": "images/icons/helpOutlined-ltr.svg"
+                                       "he,yi": "images/icons/helpNotice-ltr.svg"
                                }
                        }
                },
index 3542dd6..4e39f91 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index dd5c64f..7c9bf1b 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 64631cc..21381ef 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index da88b8b..f9c3904 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 4f223a6..9486250 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index af4d5c0..0e4fe16 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 6e7fff2..4b529ed 100644 (file)
                "destructive": {
                        "color": "#d33"
                },
+               "error": {
+                       "color": "#d33"
+               },
                "warning": {
-                       "color": "#ff5d00"
+                       "color": "#fc3"
+               },
+               "success": {
+                       "color": "#14866d"
                }
        },
        "images": {
index 56526d2..5794445 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add</title><path fill="#fff" d="M16 9h-5V4H9v5H4v2h5v5h2v-5h5V9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add</title><path fill="#fff" d="M11 9V4H9v5H4v2h5v5h2v-5h5V9z"/></svg>
\ No newline at end of file
index 4c84858..5e9adad 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add</title><path fill="#36c" d="M16 9h-5V4H9v5H4v2h5v5h2v-5h5V9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add</title><path fill="#36c" d="M11 9V4H9v5H4v2h5v5h2v-5h5V9z"/></svg>
\ No newline at end of file
index ac82608..4306eb3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/add.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/add.png differ
index 9ba48c9..c3b2f55 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add</title><path d="M16 9h-5V4H9v5H4v2h5v5h2v-5h5V9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add</title><path d="M11 9V4H9v5H4v2h5v5h2v-5h5V9z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/alert-error.png b/resources/lib/ooui/themes/wikimediaui/images/icons/alert-error.png
new file mode 100644 (file)
index 0000000..075500e
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/alert-error.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/alert-error.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/alert-error.svg
new file mode 100644 (file)
index 0000000..c73f0da
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path fill="#d33" d="M11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
index 87bf141..1d9917b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alert-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alert-invert.png differ
index bc4b616..f1f94f9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path fill="#fff" d="M19.64 16.36L11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path fill="#fff" d="M11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
index 4407349..7451848 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path fill="#36c" d="M19.64 16.36L11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path fill="#36c" d="M11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
index cc31bff..f5ab8c1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alert-warning.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alert-warning.png differ
index 3ca3a0a..b49c48e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path fill="#ff5d00" d="M19.64 16.36L11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path fill="#fc3" d="M11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
index 3019a1e..3d51b2c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alert.png differ
index d5db1ed..b21dbc0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path d="M19.64 16.36L11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>alert</title><path d="M11.53 2.3A1.85 1.85 0 0 0 10 1.21 1.85 1.85 0 0 0 8.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/></svg>
\ No newline at end of file
index 11fad13..9bc265d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter-invert.png differ
index ee87522..fcdae4c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align center</title><g fill="#fff"><path d="M1 15h18v2H1zM1 3h18v2H1z"/><rect width="8" height="6" x="6" y="7" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align center</title><g fill="#fff"><path d="M1 15h18v2H1zM1 3h18v2H1z"/><rect width="8" height="6" x="6" y="7" rx="1"/></g></svg>
\ No newline at end of file
index d0ea168..90e29af 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align center</title><g fill="#36c"><path d="M1 15h18v2H1zM1 3h18v2H1z"/><rect width="8" height="6" x="6" y="7" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align center</title><g fill="#36c"><path d="M1 15h18v2H1zM1 3h18v2H1z"/><rect width="8" height="6" x="6" y="7" rx="1"/></g></svg>
\ No newline at end of file
index 229393b..8cfecfb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alignCenter.png differ
index e9ac55d..e519130 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align center</title><path d="M1 15h18v2H1zM1 3h18v2H1z"/><rect width="8" height="6" x="6" y="7" rx="1" ry="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align center</title><path d="M1 15h18v2H1zM1 3h18v2H1z"/><rect width="8" height="6" x="6" y="7" rx="1"/></svg>
\ No newline at end of file
index c0e90ae..caf6720 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft-invert.png differ
index f55dd0a..081d8f7 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align left</title><g fill="#fff"><path d="M1 15h18v2H1zm11-8h7v2h-7zm0 4h7v2h-7zM1 3h18v2H1z"/><rect width="8" height="6" x="1" y="7" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align left</title><g fill="#fff"><path d="M1 15h18v2H1zm11-8h7v2h-7zm0 4h7v2h-7zM1 3h18v2H1z"/><rect width="8" height="6" x="1" y="7" rx="1"/></g></svg>
\ No newline at end of file
index 663d8da..92d5bc5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align left</title><g fill="#36c"><path d="M1 15h18v2H1zm11-8h7v2h-7zm0 4h7v2h-7zM1 3h18v2H1z"/><rect width="8" height="6" x="1" y="7" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align left</title><g fill="#36c"><path d="M1 15h18v2H1zm11-8h7v2h-7zm0 4h7v2h-7zM1 3h18v2H1z"/><rect width="8" height="6" x="1" y="7" rx="1"/></g></svg>
\ No newline at end of file
index c181873..2cb2d2d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alignLeft.png differ
index c116ab8..663133d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align left</title><path d="M1 15h18v2H1zm11-8h7v2h-7zm0 4h7v2h-7zM1 3h18v2H1z"/><rect width="8" height="6" x="1" y="7" rx="1" ry="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align left</title><path d="M1 15h18v2H1zm11-8h7v2h-7zm0 4h7v2h-7zM1 3h18v2H1z"/><rect width="8" height="6" x="1" y="7" rx="1"/></svg>
\ No newline at end of file
index fa2e966..b52c6ba 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alignRight-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alignRight-invert.png differ
index bfb01b6..0ed79cf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align right</title><g fill="#fff"><path d="M1 15h18v2H1zm0-8h7v2H1zm0 4h7v2H1zm0-8h18v2H1z"/><rect width="8" height="6" x="11" y="7" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align right</title><g fill="#fff"><path d="M1 15h18v2H1zm0-8h7v2H1zm0 4h7v2H1zm0-8h18v2H1z"/><rect width="8" height="6" x="11" y="7" rx="1"/></g></svg>
\ No newline at end of file
index 801e7ff..8bf2cfb 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align right</title><g fill="#36c"><path d="M1 15h18v2H1zm0-8h7v2H1zm0 4h7v2H1zm0-8h18v2H1z"/><rect width="8" height="6" x="11" y="7" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align right</title><g fill="#36c"><path d="M1 15h18v2H1zm0-8h7v2H1zm0 4h7v2H1zm0-8h18v2H1z"/><rect width="8" height="6" x="11" y="7" rx="1"/></g></svg>
\ No newline at end of file
index 9d04733..951ae5c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/alignRight.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/alignRight.png differ
index b6f747e..ee35987 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align right</title><path d="M1 15h18v2H1zm0-8h7v2H1zm0 4h7v2H1zm0-8h18v2H1z"/><rect width="8" height="6" x="11" y="7" rx="1" ry="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>align right</title><path d="M1 15h18v2H1zm0-8h7v2H1zm0 4h7v2H1zm0-8h18v2H1z"/><rect width="8" height="6" x="11" y="7" rx="1"/></svg>
\ No newline at end of file
index 0ccf7c0..a5ec26d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr-invert.png differ
index c58e800..e76b455 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>next</title><path fill="#fff" d="M10 2L8.59 3.42 14.17 9H2v2h12.17l-5.58 5.59L10 18l8-8-8-8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>next</title><path fill="#fff" d="M8.59 3.42L14.17 9H2v2h12.17l-5.58 5.59L10 18l8-8-8-8z"/></svg>
\ No newline at end of file
index a0c8843..db462b8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>next</title><path fill="#36c" d="M10 2L8.59 3.42 14.17 9H2v2h12.17l-5.58 5.59L10 18l8-8-8-8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>next</title><path fill="#36c" d="M8.59 3.42L14.17 9H2v2h12.17l-5.58 5.59L10 18l8-8-8-8z"/></svg>
\ No newline at end of file
index 6b9ea3d..4455845 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-ltr.png differ
index a9f9745..8eb80f1 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>next</title><path d="M10 2L8.59 3.42 14.17 9H2v2h12.17l-5.58 5.59L10 18l8-8-8-8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>next</title><path d="M8.59 3.42L14.17 9H2v2h12.17l-5.58 5.59L10 18l8-8-8-8z"/></svg>
\ No newline at end of file
index b6c6622..255550d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-rtl-invert.png differ
index dbc77f2..5f76614 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowNext-rtl.png differ
index f7b46b7..83bcc56 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr-invert.png differ
index 0c5952c..746a91d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>previous</title><path fill="#fff" d="M18 9H5.83l5.58-5.58L10 2l-8 8 8 8 1.41-1.41L5.83 11H18V9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>previous</title><path fill="#fff" d="M5.83 9l5.58-5.58L10 2l-8 8 8 8 1.41-1.41L5.83 11H18V9z"/></svg>
\ No newline at end of file
index efa9e50..91e9b68 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>previous</title><path fill="#36c" d="M18 9H5.83l5.58-5.58L10 2l-8 8 8 8 1.41-1.41L5.83 11H18V9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>previous</title><path fill="#36c" d="M5.83 9l5.58-5.58L10 2l-8 8 8 8 1.41-1.41L5.83 11H18V9z"/></svg>
\ No newline at end of file
index d3c39ce..949726e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-ltr.png differ
index d95b511..5f0c082 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>previous</title><path d="M18 9H5.83l5.58-5.58L10 2l-8 8 8 8 1.41-1.41L5.83 11H18V9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>previous</title><path d="M5.83 9l5.58-5.58L10 2l-8 8 8 8 1.41-1.41L5.83 11H18V9z"/></svg>
\ No newline at end of file
index 6248ca7..804b9cc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-rtl-invert.png differ
index 979a01b..473f184 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/arrowPrevious-rtl.png differ
index f161068..4b61a19 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr-invert.png differ
index 36ca5e3..290967a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#fff" d="M15 1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zM5 4h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#fff" d="M5 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 3h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"/></svg>
\ No newline at end of file
index 76c8d03..1a3049c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#36c" d="M15 1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zM5 4h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#36c" d="M5 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 3h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"/></svg>
\ No newline at end of file
index aa63663..2c84d5b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/article-ltr.png differ
index e370aee..a983fe0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path d="M15 1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zM5 4h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path d="M5 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 3h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"/></svg>
\ No newline at end of file
index b2ee4d3..f2ab7e7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl-invert.png differ
index d565d97..c62ac1c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#fff" d="M3 3v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2zm12 2h-5V4h5zm0 2h-5V6h5zm0 2h-5V8h5zM5 14h10v1H5zm0-2h10v1H5zm0-2h10v1H5zm0-6h4v5H5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#fff" d="M3 17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2zM15 5h-5V4h5zm0 2h-5V6h5zm0 2h-5V8h5zM5 14h10v1H5zm0-2h10v1H5zm0-2h10v1H5zm0-6h4v5H5z"/></svg>
\ No newline at end of file
index 0062f6b..f312c60 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#36c" d="M3 3v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2zm12 2h-5V4h5zm0 2h-5V6h5zm0 2h-5V8h5zM5 14h10v1H5zm0-2h10v1H5zm0-2h10v1H5zm0-6h4v5H5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path fill="#36c" d="M3 17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2zM15 5h-5V4h5zm0 2h-5V6h5zm0 2h-5V8h5zM5 14h10v1H5zm0-2h10v1H5zm0-2h10v1H5zm0-6h4v5H5z"/></svg>
\ No newline at end of file
index 8b06dd8..8ee6879 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/article-rtl.png differ
index 1ef6e18..6b97553 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path d="M3 3v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2zm12 2h-5V4h5zm0 2h-5V6h5zm0 2h-5V8h5zM5 14h10v1H5zm0-2h10v1H5zm0-2h10v1H5zm0-6h4v5H5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article</title><path d="M3 17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2zM15 5h-5V4h5zm0 2h-5V6h5zm0 2h-5V8h5zM5 14h10v1H5zm0-2h10v1H5zm0-2h10v1H5zm0-6h4v5H5z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-invert.png
new file mode 100644 (file)
index 0000000..7ce0598
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-invert.svg
new file mode 100644 (file)
index 0000000..b83ed2b
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add article</title><path fill="#fff" d="M5 1c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm10 10h-4v4H9v-4H5V9h4V5h2v4h4z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-progressive.png
new file mode 100644 (file)
index 0000000..94d09ac
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd-progressive.svg
new file mode 100644 (file)
index 0000000..c25c622
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add article</title><path fill="#36c" d="M5 1c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm10 10h-4v4H9v-4H5V9h4V5h2v4h4z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd.png b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd.png
new file mode 100644 (file)
index 0000000..0e8c754
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/articleAdd.svg
new file mode 100644 (file)
index 0000000..a9ad603
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add article</title><path d="M5 1c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm10 10h-4v4H9v-4H5V9h4V5h2v4h4z"/></svg>
\ No newline at end of file
index c2186e3..0b248b1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck-invert.png differ
index 890a8f2..567fe1e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck-progressive.png differ
index 48581b8..9717839 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleCheck.png differ
index 7ae6435..706097c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr-invert.png differ
index d30485e..0a838b0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#fff" d="M15 1H5a2 2 0 0 0-2 2v1c0 5 2 8 7 8V9l5 4-5 4v-3c-3.18 0-5.51-.85-7-2.68V17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#fff" d="M5 1a2 2 0 0 0-2 2v1c0 5 2 8 7 8V9l5 4-5 4v-3c-3.18 0-5.51-.85-7-2.68V17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index 3075f61..14e438f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#36c" d="M15 1H5a2 2 0 0 0-2 2v1c0 5 2 8 7 8V9l5 4-5 4v-3c-3.18 0-5.51-.85-7-2.68V17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#36c" d="M5 1a2 2 0 0 0-2 2v1c0 5 2 8 7 8V9l5 4-5 4v-3c-3.18 0-5.51-.85-7-2.68V17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index 28a431b..7f61dd3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-ltr.png differ
index 3ec9a9c..666dac2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path d="M15 1H5a2 2 0 0 0-2 2v1c0 5 2 8 7 8V9l5 4-5 4v-3c-3.18 0-5.51-.85-7-2.68V17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path d="M5 1a2 2 0 0 0-2 2v1c0 5 2 8 7 8V9l5 4-5 4v-3c-3.18 0-5.51-.85-7-2.68V17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index fd45441..549be0e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl-invert.png differ
index c74f93b..13cd649 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#fff" d="M3 3v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-5.7c-1.5 1.8-3.8 2.7-7 2.7v3l-5-4 5-4v3c5 0 7-3 7-8V3c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#fff" d="M3 17c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-5.7c-1.5 1.8-3.8 2.7-7 2.7v3l-5-4 5-4v3c5 0 7-3 7-8V3c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2z"/></svg>
\ No newline at end of file
index aec619b..162dec3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#36c" d="M3 3v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-5.7c-1.5 1.8-3.8 2.7-7 2.7v3l-5-4 5-4v3c5 0 7-3 7-8V3c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path fill="#36c" d="M3 17c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-5.7c-1.5 1.8-3.8 2.7-7 2.7v3l-5-4 5-4v3c5 0 7-3 7-8V3c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2z"/></svg>
\ No newline at end of file
index 2954f69..b187d77 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleRedirect-rtl.png differ
index feb8ee7..b5c5064 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path d="M3 3v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-5.7c-1.5 1.8-3.8 2.7-7 2.7v3l-5-4 5-4v3c5 0 7-3 7-8V3c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path d="M3 17c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-5.7c-1.5 1.8-3.8 2.7-7 2.7v3l-5-4 5-4v3c5 0 7-3 7-8V3c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2z"/></svg>
\ No newline at end of file
index e4d81df..bed533d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleSearch-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleSearch-invert.png differ
index 45f729d..2d08904 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articleSearch.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articleSearch.png differ
index 9efb90d..4fcbc9c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr-invert.png differ
index 8e0800e..3a02aa1 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#fff"><path d="M16 0H5v2h11v14h2V2a2 2 0 0 0-2-2z"/><path d="M4 20h9a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2zM9 5h4v5H9zM4 5h4v1H4zm0 2h4v1H4zm0 2h4v1H4zm0 2h9v1H4zm0 2h9v1H4zm0 2h9v1H4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#fff"><path d="M5 0v2h11v14h2V2a2 2 0 0 0-2-2z"/><path d="M13 20a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2zM9 5h4v5H9zM4 5h4v1H4zm0 2h4v1H4zm0 2h4v1H4zm0 2h9v1H4zm0 2h9v1H4zm0 2h9v1H4z"/></g></svg>
\ No newline at end of file
index 383d905..9475ce8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#36c"><path d="M16 0H5v2h11v14h2V2a2 2 0 0 0-2-2z"/><path d="M4 20h9a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2zM9 5h4v5H9zM4 5h4v1H4zm0 2h4v1H4zm0 2h4v1H4zm0 2h9v1H4zm0 2h9v1H4zm0 2h9v1H4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#36c"><path d="M5 0v2h11v14h2V2a2 2 0 0 0-2-2z"/><path d="M13 20a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2zM9 5h4v5H9zM4 5h4v1H4zm0 2h4v1H4zm0 2h4v1H4zm0 2h9v1H4zm0 2h9v1H4zm0 2h9v1H4z"/></g></svg>
\ No newline at end of file
index eb9a4c2..8783dba 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articles-ltr.png differ
index a3b0833..8de6f28 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><path d="M16 0H5v2h11v14h2V2a2 2 0 0 0-2-2z"/><path d="M4 20h9a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2zM9 5h4v5H9zM4 5h4v1H4zm0 2h4v1H4zm0 2h4v1H4zm0 2h9v1H4zm0 2h9v1H4zm0 2h9v1H4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><path d="M5 0v2h11v14h2V2a2 2 0 0 0-2-2z"/><path d="M13 20a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2zM9 5h4v5H9zM4 5h4v1H4zm0 2h4v1H4zm0 2h4v1H4zm0 2h9v1H4zm0 2h9v1H4zm0 2h9v1H4z"/></svg>
\ No newline at end of file
index 47cf8b7..d255680 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl-invert.png differ
index 24f6eb0..edbd240 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#fff"><path d="M4 0h11v2H4v14H2V2a2 2 0 0 1 2-2z"/><path d="M18 18V5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2zm-7-8H7V5h4zm5-4h-4V5h4zm0 2h-4V7h4zm0 2h-4V9h4zm0 2H7v-1h9zm0 2H7v-1h9zm0 2H7v-1h9z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#fff"><path d="M15 0v2H4v14H2V2a2 2 0 0 1 2-2z"/><path d="M18 5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2zm-7 5H7V5h4zm5-4h-4V5h4zm0 2h-4V7h4zm0 2h-4V9h4zm0 2H7v-1h9zm0 2H7v-1h9zm0 2H7v-1h9z"/></g></svg>
\ No newline at end of file
index 81c3a48..ca72eab 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#36c"><path d="M4 0h11v2H4v14H2V2a2 2 0 0 1 2-2z"/><path d="M18 18V5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2zm-7-8H7V5h4zm5-4h-4V5h4zm0 2h-4V7h4zm0 2h-4V9h4zm0 2H7v-1h9zm0 2H7v-1h9zm0 2H7v-1h9z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><g fill="#36c"><path d="M15 0v2H4v14H2V2a2 2 0 0 1 2-2z"/><path d="M18 5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2zm-7 5H7V5h4zm5-4h-4V5h4zm0 2h-4V7h4zm0 2h-4V9h4zm0 2H7v-1h9zm0 2H7v-1h9zm0 2H7v-1h9z"/></g></svg>
\ No newline at end of file
index 3f9acf1..c2ebc9c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/articles-rtl.png differ
index 522e646..2983357 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><path d="M4 0h11v2H4v14H2V2a2 2 0 0 1 2-2z"/><path d="M18 18V5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2zm-7-8H7V5h4zm5-4h-4V5h4zm0 2h-4V7h4zm0 2h-4V9h4zm0 2H7v-1h9zm0 2H7v-1h9zm0 2H7v-1h9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>articles</title><path d="M15 0v2H4v14H2V2a2 2 0 0 1 2-2z"/><path d="M18 5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2zm-7 5H7V5h4zm5-4h-4V5h4zm0 2h-4V7h4zm0 2h-4V9h4zm0 2H7v-1h9zm0 2H7v-1h9zm0 2H7v-1h9z"/></svg>
\ No newline at end of file
index 2d07f48..3de7c7c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/attachment-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/attachment-invert.png differ
index f75ebed..922f8fb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/attachment-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/attachment-progressive.png differ
index 056f1de..78aca8d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/attachment.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/attachment.png differ
index d9a788e..28c5ae3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-invert.png differ
index ab0fbe3..107ffa8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>beaker</title><path fill="#fff" d="M18.86 17.49L13 7.61V3h1V1H6v2h1v4.61l-5.86 9.88A1 1 0 0 0 2 19h16a1 1 0 0 0 .86-1.51zm-10-9.09A1 1 0 0 0 9 7.89V3h2v4.89a1 1 0 0 0 .14.51l2.14 3.6H6.72z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>beaker</title><path fill="#fff" d="M13 7.61V3h1V1H6v2h1v4.61l-5.86 9.88A1 1 0 0 0 2 19h16a1 1 0 0 0 .86-1.51zm-4.2.88a1 1 0 0 0 .2-.6V3h2v4.89a1 1 0 0 0 .14.51l2.14 3.6H6.72z"/></svg>
\ No newline at end of file
index 2d2ed6f..4bde9bf 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker-progressive.png differ
index 80d57a1..0ef3edf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>beaker</title><path fill="#36c" d="M18.86 17.49L13 7.61V3h1V1H6v2h1v4.61l-5.86 9.88A1 1 0 0 0 2 19h16a1 1 0 0 0 .86-1.51zm-10-9.09A1 1 0 0 0 9 7.89V3h2v4.89a1 1 0 0 0 .14.51l2.14 3.6H6.72z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>beaker</title><path fill="#36c" d="M13 7.61V3h1V1H6v2h1v4.61l-5.86 9.88A1 1 0 0 0 2 19h16a1 1 0 0 0 .86-1.51zm-4.2.88a1 1 0 0 0 .2-.6V3h2v4.89a1 1 0 0 0 .14.51l2.14 3.6H6.72z"/></svg>
\ No newline at end of file
index 121e18c..dcc30c2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/beaker.png differ
index dadaac3..6796523 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>beaker</title><path d="M18.86 17.49L13 7.61V3h1V1H6v2h1v4.61l-5.86 9.88A1 1 0 0 0 2 19h16a1 1 0 0 0 .86-1.51zm-10-9.09A1 1 0 0 0 9 7.89V3h2v4.89a1 1 0 0 0 .14.51l2.14 3.6H6.72z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>beaker</title><path d="M13 7.61V3h1V1H6v2h1v4.61l-5.86 9.88A1 1 0 0 0 2 19h16a1 1 0 0 0 .86-1.51zm-4.2.88a1 1 0 0 0 .2-.6V3h2v4.89a1 1 0 0 0 .14.51l2.14 3.6H6.72z"/></svg>
\ No newline at end of file
index db3f924..801f0a3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bell-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bell-invert.png differ
index 580ac6b..877d348 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bell.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bell.png differ
index 8f7244a..f5e23f6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bigger-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bigger-invert.png differ
index e9f5745..2761894 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bigger</title><path fill="#fff" d="M14 18h-1.57a.66.66 0 0 1-.44-.13.87.87 0 0 1-.25-.34l-1-2.77H5.3l-1 2.77a.83.83 0 0 1-.24.32.65.65 0 0 1-.44.15H2L7 5.47h2zm-3.85-4.7L8.42 8.72A12.66 12.66 0 0 1 8 7.37q-.1.41-.21.75t-.21.6L5.85 13.3zM15 2l3 4h-6l3-4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bigger</title><path fill="#fff" d="M14 18h-1.57a.66.66 0 0 1-.44-.13.87.87 0 0 1-.25-.34l-1-2.77H5.3l-1 2.77a.83.83 0 0 1-.24.32.65.65 0 0 1-.44.15H2L7 5.47h2zm-3.85-4.7L8.42 8.72A12.66 12.66 0 0 1 8 7.37q-.1.41-.21.75t-.21.6L5.85 13.3zM15 2l3 4h-6z"/></svg>
\ No newline at end of file
index f03fab7..ac61d07 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bigger</title><path fill="#36c" d="M14 18h-1.57a.66.66 0 0 1-.44-.13.87.87 0 0 1-.25-.34l-1-2.77H5.3l-1 2.77a.83.83 0 0 1-.24.32.65.65 0 0 1-.44.15H2L7 5.47h2zm-3.85-4.7L8.42 8.72A12.66 12.66 0 0 1 8 7.37q-.1.41-.21.75t-.21.6L5.85 13.3zM15 2l3 4h-6l3-4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bigger</title><path fill="#36c" d="M14 18h-1.57a.66.66 0 0 1-.44-.13.87.87 0 0 1-.25-.34l-1-2.77H5.3l-1 2.77a.83.83 0 0 1-.24.32.65.65 0 0 1-.44.15H2L7 5.47h2zm-3.85-4.7L8.42 8.72A12.66 12.66 0 0 1 8 7.37q-.1.41-.21.75t-.21.6L5.85 13.3zM15 2l3 4h-6z"/></svg>
\ No newline at end of file
index 00f25df..26177e8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bigger.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bigger.png differ
index 19400ae..0831060 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bigger</title><path d="M14 18h-1.57a.66.66 0 0 1-.44-.13.87.87 0 0 1-.25-.34l-1-2.77H5.3l-1 2.77a.83.83 0 0 1-.24.32.65.65 0 0 1-.44.15H2L7 5.47h2zm-3.85-4.7L8.42 8.72A12.66 12.66 0 0 1 8 7.37q-.1.41-.21.75t-.21.6L5.85 13.3zM15 2l3 4h-6l3-4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bigger</title><path d="M14 18h-1.57a.66.66 0 0 1-.44-.13.87.87 0 0 1-.25-.34l-1-2.77H5.3l-1 2.77a.83.83 0 0 1-.24.32.65.65 0 0 1-.44.15H2L7 5.47h2zm-3.85-4.7L8.42 8.72A12.66 12.66 0 0 1 8 7.37q-.1.41-.21.75t-.21.6L5.85 13.3zM15 2l3 4h-6z"/></svg>
\ No newline at end of file
index 5912926..2f01eb2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/block-destructive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/block-destructive.png differ
index bdb7ced..95397bb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/block-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/block-invert.png differ
index 79c8202..4b9936f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/block.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/block.png differ
index 7234541..240e051 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-a-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-a-invert.png differ
index 4ef6559..d36755b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-a.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-a.png differ
index 8775055..375eb59 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-ain-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-ain-invert.png differ
index 7e83240..385d387 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-ain.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-ain.png differ
index 0c7fe82..336c6b2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-dad-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-dad-invert.png differ
index 7e57f6f..aea2365 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-dad.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-dad.png differ
index d92f2de..c7af68f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-jeem-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-jeem-invert.png differ
index b750385..d345ad9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-jeem.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-arab-jeem.png differ
index 7b24908..b5f5be3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-armn-to-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-armn-to-invert.png differ
index c1ebd77..f9e76af 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-armn-to.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-armn-to.png differ
index e0f9a03..f08869a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-b-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-b-invert.png differ
index de799b3..c7a9835 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-b.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-b.png differ
index a748116..ad6e634 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-be-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-be-invert.png differ
index 4818f18..949b9d2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-be.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-be.png differ
index 8c1a107..a2dc2cc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.png differ
index f015dfc..9b2defa 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-palochka.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-palochka.png differ
index fb50470..f0a8650 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-te-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-te-invert.png differ
index 66317d1..b581d4a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-te.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-te.png differ
index 8c94fee..8d2ed2e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-zhe-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-zhe-invert.png differ
index 94d09a3..30342ed 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-zhe.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-cyrl-zhe.png differ
index 3dcee26..80c1335 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-f-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-f-invert.png differ
index 3fece80..4070c27 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-f.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-f.png differ
index f7cd6d1..11cf982 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-g-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-g-invert.png differ
index a11610a..278edf7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-g.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-g.png differ
index b96228d..2620e20 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-geor-man-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-geor-man-invert.png differ
index 2ca0584..86b2b1d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-geor-man.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-geor-man.png differ
index e1b29e4..5f15b5c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>bold</title><path d="M5 17V3h3v12h7v2"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>bold</title><path d="M5 17V3h3v12h7v2z"/></g></svg>
\ No newline at end of file
index 862f225..286435a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>bold</title><path d="M5 17V3h3v12h7v2"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>bold</title><path d="M5 17V3h3v12h7v2z"/></g></svg>
\ No newline at end of file
index d35d80e..21a5041 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-l.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-l.png differ
index 4007c81..ee3a0a8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bold</title><path d="M5 17V3h3v12h7v2"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bold</title><path d="M5 17V3h3v12h7v2z"/></svg>
\ No newline at end of file
index 7a0ad92..bf6e4c6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-n-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-n-invert.png differ
index 41001c8..9c3aaa2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>bold</title><path d="M4 17V3h3l6 9.333V3h3v14h-3L7 7.667V17H4"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>bold</title><path d="M4 3h3l6 9.333V3h3v14h-3L7 7.667V17H4z"/></g></svg>
\ No newline at end of file
index 7823bd7..c990385 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>bold</title><path d="M4 17V3h3l6 9.333V3h3v14h-3L7 7.667V17H4"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>bold</title><path d="M4 3h3l6 9.333V3h3v14h-3L7 7.667V17H4z"/></g></svg>
\ No newline at end of file
index 87430d6..d140ebe 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-n.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-n.png differ
index c10c55e..4e76bc3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bold</title><path d="M4 17V3h3l6 9.333V3h3v14h-3L7 7.667V17H4"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bold</title><path d="M4 3h3l6 9.333V3h3v14h-3L7 7.667V17H4z"/></svg>
\ No newline at end of file
index c9a19cf..c51ab2f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-v-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-v-invert.png differ
index 9bc0ea5..d88776a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>bold</title><path d="M8.25 17L3 3h3.5l3.5 9.333L13.5 3H17l-5.25 14"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>bold</title><path d="M3 3h3.5l3.5 9.333L13.5 3H17l-5.25 14h-3.5z"/></g></svg>
\ No newline at end of file
index 881bb06..354465e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>bold</title><path d="M8.25 17L3 3h3.5l3.5 9.333L13.5 3H17l-5.25 14"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>bold</title><path d="M3 3h3.5l3.5 9.333L13.5 3H17l-5.25 14h-3.5z"/></g></svg>
\ No newline at end of file
index c1127a1..3dfebcc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bold-v.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bold-v.png differ
index 0283db1..3e1eab8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bold</title><path d="M8.25 17L3 3h3.5l3.5 9.333L13.5 3H17l-5.25 14"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bold</title><path d="M3 3h3.5l3.5 9.333L13.5 3H17l-5.25 14h-3.5z"/></svg>
\ No newline at end of file
index f6f04fc..9185871 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/book-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/book-ltr-invert.png differ
index 160726b..402ac57 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/book-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/book-ltr.png differ
index 14bd401..4db9a80 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/book-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/book-rtl-invert.png differ
index 1580e00..8d83486 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/book-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/book-rtl.png differ
index a628a39..e8e5926 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bookmark-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bookmark-invert.png differ
index d10dfb1..be0ccbb 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark</title><path fill="#fff" d="M15 1H5a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark</title><path fill="#fff" d="M5 1a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index d79220f..8b60b1f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark</title><path fill="#36c" d="M15 1H5a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark</title><path fill="#36c" d="M5 1a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index ace5d8c..be12ecc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bookmark.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bookmark.png differ
index d5d0797..27d6c45 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark</title><path d="M15 1H5a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark</title><path d="M5 1a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index 4f047b1..86e37df 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline-invert.png differ
index 62ad078..7b78416 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark outlined</title><path fill="#fff" d="M15 1H5a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2zm0 14.25l-5-3.5-5 3.5V3h10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark outlined</title><path fill="#fff" d="M5 1a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2zm10 14.25l-5-3.5-5 3.5V3h10z"/></svg>
\ No newline at end of file
index ba60c95..0e31efa 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark outlined</title><path fill="#36c" d="M15 1H5a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2zm0 14.25l-5-3.5-5 3.5V3h10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark outlined</title><path fill="#36c" d="M5 1a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2zm10 14.25l-5-3.5-5 3.5V3h10z"/></svg>
\ No newline at end of file
index 232ca46..a58109f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bookmarkOutline.png differ
index 04d8d28..6431f72 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark outlined</title><path d="M15 1H5a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2zm0 14.25l-5-3.5-5 3.5V3h10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bookmark outlined</title><path d="M5 1a2 2 0 0 0-2 2v16l7-5 7 5V3a2 2 0 0 0-2-2zm10 14.25l-5-3.5-5 3.5V3h10z"/></svg>
\ No newline at end of file
index 6c8c9d3..086e80a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bright-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bright-invert.png differ
index ba9e59d..bf076f6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bright-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bright-progressive.png differ
index 433f59c..77ba581 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/bright.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/bright.png differ
index 1cc9427..2da4824 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr-invert.png differ
index 19357ac..12db77e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#fff" d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM4 3.5A1.5 1.5 0 1 1 2.5 5 1.5 1.5 0 0 1 4 3.5zM18 16H2V8h16z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#fff" d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm2 1.5A1.5 1.5 0 1 1 2.5 5 1.5 1.5 0 0 1 4 3.5zM18 16H2V8h16z"/></svg>
\ No newline at end of file
index 1d7228f..7206f6f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#36c" d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM4 3.5A1.5 1.5 0 1 1 2.5 5 1.5 1.5 0 0 1 4 3.5zM18 16H2V8h16z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#36c" d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm2 1.5A1.5 1.5 0 1 1 2.5 5 1.5 1.5 0 0 1 4 3.5zM18 16H2V8h16z"/></svg>
\ No newline at end of file
index 624a897..7f08a05 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/browser-ltr.png differ
index c496ab7..a74b5f3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM4 3.5A1.5 1.5 0 1 1 2.5 5 1.5 1.5 0 0 1 4 3.5zM18 16H2V8h16z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm2 1.5A1.5 1.5 0 1 1 2.5 5 1.5 1.5 0 0 1 4 3.5zM18 16H2V8h16z"/></svg>
\ No newline at end of file
index bb04d76..36fcc45 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl-invert.png differ
index 4691bd6..a15b911 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#fff" d="M0 4v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zm17.5 1c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.7 1.5 1.5zM2 8h16v8H2V8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#fff" d="M0 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zM17.5 5c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.7 1.5 1.5zM2 8h16v8H2z"/></svg>
\ No newline at end of file
index dc5417c..1730c98 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#36c" d="M0 4v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zm17.5 1c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.7 1.5 1.5zM2 8h16v8H2V8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path fill="#36c" d="M0 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zM17.5 5c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.7 1.5 1.5zM2 8h16v8H2z"/></svg>
\ No newline at end of file
index d3f9453..8b3c40f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/browser-rtl.png differ
index 738d05c..3108da6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path d="M0 4v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zm17.5 1c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.7 1.5 1.5zM2 8h16v8H2V8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>browser</title><path d="M0 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zM17.5 5c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.7 1.5 1.5zM2 8h16v8H2z"/></svg>
\ No newline at end of file
index ddab182..867b44e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/calendar-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/calendar-invert.png differ
index 4c88b00..20c7da0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>calendar</title><path fill="#fff" d="M18 3h-3V1h-2v2H7V1H5v2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm0 14H2V8h16zm-2-6h-4v4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>calendar</title><path fill="#fff" d="M15 3V1h-2v2H7V1H5v2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm3 14H2V8h16zm-2-6h-4v4h4z"/></svg>
\ No newline at end of file
index 0e20e6a..8102a8b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>calendar</title><path fill="#36c" d="M18 3h-3V1h-2v2H7V1H5v2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm0 14H2V8h16zm-2-6h-4v4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>calendar</title><path fill="#36c" d="M15 3V1h-2v2H7V1H5v2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm3 14H2V8h16zm-2-6h-4v4h4z"/></svg>
\ No newline at end of file
index bfc5f98..315c4fb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/calendar.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/calendar.png differ
index a818b0b..5733191 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>calendar</title><path d="M18 3h-3V1h-2v2H7V1H5v2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm0 14H2V8h16zm-2-6h-4v4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>calendar</title><path d="M15 3V1h-2v2H7V1H5v2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm3 14H2V8h16zm-2-6h-4v4h4z"/></svg>
\ No newline at end of file
index e5d859f..4627259 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/camera-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/camera-invert.png differ
index 7fa9e3a..321cca5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>camera</title><path fill="#fff" d="M13 11a3 3 0 1 0-3 3 3 3 0 0 0 3-3zm-3 5a5 5 0 1 1 5-5 5 5 0 0 1-5 5zM6.42 2.56l-.67.64a2 2 0 0 1-1.38.56H2a1.89 1.89 0 0 0-2 1.75v10.54a1.89 1.89 0 0 0 2 1.76h16a1.89 1.89 0 0 0 2-1.76V5.51a1.89 1.89 0 0 0-2-1.76h-2.37a2 2 0 0 1-1.38-.56l-.67-.64A2 2 0 0 0 12.2 2H7.8a2 2 0 0 0-1.38.56z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>camera</title><g fill="#fff"><path d="M10 16c-4.455 0-6.685-5.386-3.535-8.535C9.615 4.315 15 6.545 15 11a5 5 0 0 1-5 5zM6.42 2.56l-.67.64c-.37.357-.865.808-1.38.81H2C.914 4 0 4.712 0 5.76v10.48C0 17.27 1 18 2 18h16c1 0 2-.716 2-1.76V5.76C20 4.723 19 4 18 4h-2.37c-.515-.002-1.01-.453-1.38-.81l-.67-.64A2 2 0 0 0 12.2 2H7.8a2 2 0 0 0-1.38.56z"/><circle cx="10" cy="11" r="3"/></g></svg>
\ No newline at end of file
index 9471792..ce8e437 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/camera-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/camera-progressive.png differ
index c988602..a464567 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>camera</title><path fill="#36c" d="M13 11a3 3 0 1 0-3 3 3 3 0 0 0 3-3zm-3 5a5 5 0 1 1 5-5 5 5 0 0 1-5 5zM6.42 2.56l-.67.64a2 2 0 0 1-1.38.56H2a1.89 1.89 0 0 0-2 1.75v10.54a1.89 1.89 0 0 0 2 1.76h16a1.89 1.89 0 0 0 2-1.76V5.51a1.89 1.89 0 0 0-2-1.76h-2.37a2 2 0 0 1-1.38-.56l-.67-.64A2 2 0 0 0 12.2 2H7.8a2 2 0 0 0-1.38.56z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>camera</title><g fill="#36c"><path d="M10 16c-4.455 0-6.685-5.386-3.535-8.535C9.615 4.315 15 6.545 15 11a5 5 0 0 1-5 5zM6.42 2.56l-.67.64c-.37.357-.865.808-1.38.81H2C.914 4 0 4.712 0 5.76v10.48C0 17.27 1 18 2 18h16c1 0 2-.716 2-1.76V5.76C20 4.723 19 4 18 4h-2.37c-.515-.002-1.01-.453-1.38-.81l-.67-.64A2 2 0 0 0 12.2 2H7.8a2 2 0 0 0-1.38.56z"/><circle cx="10" cy="11" r="3"/></g></svg>
\ No newline at end of file
index 4a8109d..ff083ba 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/camera.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/camera.png differ
index 63046f7..8c9ab42 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>camera</title><path d="M13 11a3 3 0 1 0-3 3 3 3 0 0 0 3-3zm-3 5a5 5 0 1 1 5-5 5 5 0 0 1-5 5zM6.42 2.56l-.67.64a2 2 0 0 1-1.38.56H2a1.89 1.89 0 0 0-2 1.75v10.54a1.89 1.89 0 0 0 2 1.76h16a1.89 1.89 0 0 0 2-1.76V5.51a1.89 1.89 0 0 0-2-1.76h-2.37a2 2 0 0 1-1.38-.56l-.67-.64A2 2 0 0 0 12.2 2H7.8a2 2 0 0 0-1.38.56z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>camera</title><path d="M10 16c-4.455 0-6.685-5.386-3.535-8.535C9.615 4.315 15 6.545 15 11a5 5 0 0 1-5 5zM6.42 2.56l-.67.64c-.37.357-.865.808-1.38.81H2C.914 4 0 4.712 0 5.76v10.48C0 17.27 1 18 2 18h16c1 0 2-.716 2-1.76V5.76C20 4.723 19 4 18 4h-2.37c-.515-.002-1.01-.453-1.38-.81l-.67-.64A2 2 0 0 0 12.2 2H7.8a2 2 0 0 0-1.38.56z"/><circle cx="10" cy="11" r="3"/></svg>
\ No newline at end of file
index c230d1a..d07b416 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/cancel-destructive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/cancel-destructive.png differ
index 2e068e9..017a2c6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/cancel-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/cancel-invert.png differ
index ad8a4e6..9e16ce2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/cancel-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/cancel-progressive.png differ
index 354365e..0cbbfdc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/cancel.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/cancel.png differ
index c992483..9583ce0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/chart-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/chart-invert.png differ
index e5167ad..a4e1e21 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>chart</title><g fill="#fff"><path d="M3 17V3H1v16h18v-2H3z"/><path d="M18 5l-7 6-3-2-4 4v3h14V5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>chart</title><g fill="#fff"><path d="M3 3H1v16h18v-2H3z"/><path d="M11 11L8 9l-4 4v3h14V5z"/></g></svg>
\ No newline at end of file
index 9233478..787de0c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>chart</title><g fill="#36c"><path d="M3 17V3H1v16h18v-2H3z"/><path d="M18 5l-7 6-3-2-4 4v3h14V5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>chart</title><g fill="#36c"><path d="M3 3H1v16h18v-2H3z"/><path d="M11 11L8 9l-4 4v3h14V5z"/></g></svg>
\ No newline at end of file
index 5ef35b1..c74c26c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/chart.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/chart.png differ
index a979a4c..58a2a13 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>chart</title><path d="M3 17V3H1v16h18v-2H3z"/><path d="M18 5l-7 6-3-2-4 4v3h14V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>chart</title><path d="M3 3H1v16h18v-2H3z"/><path d="M11 11L8 9l-4 4v3h14V5z"/></svg>
\ No newline at end of file
index 0414d6b..e03f6f0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path fill="#d33" d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42L7 14.17z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path fill="#d33" d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42z"/></svg>
\ No newline at end of file
index dc85bfb..b44c099 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/check-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/check-invert.png differ
index 8ae3020..847cebc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path fill="#fff" d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42L7 14.17z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path fill="#fff" d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42z"/></svg>
\ No newline at end of file
index 73dbdf1..3ab6190 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path fill="#36c" d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42L7 14.17z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path fill="#36c" d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/check-success.png b/resources/lib/ooui/themes/wikimediaui/images/icons/check-success.png
new file mode 100644 (file)
index 0000000..24d57f3
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/check-success.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/check-success.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/check-success.svg
new file mode 100644 (file)
index 0000000..f361b93
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path fill="#14866d" d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42z"/></svg>
\ No newline at end of file
index 109c85e..4d9b36b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/check.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/check.png differ
index 77ff858..62a0337 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42L7 14.17z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check</title><path d="M7 14.17L2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42z"/></svg>
\ No newline at end of file
index 94bbd85..a03b199 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/checkAll-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/checkAll-invert.png differ
index d5dc113..dfd4579 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check all</title><path fill="#fff" d="M4.07 16.49L.29 12.71l1.42-1.42 2.22 2.22 8.3-10.14 1.54 1.26-9.7 11.86zM12 10h5v2h-5zm-3 4h5v2H9zm6-8h5v2h-5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check all</title><path fill="#fff" d="M.29 12.71l1.42-1.42 2.22 2.22 8.3-10.14 1.54 1.26-9.7 11.86zM12 10h5v2h-5zm-3 4h5v2H9zm6-8h5v2h-5z"/></svg>
\ No newline at end of file
index 92bdbaf..1df0d4f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check all</title><path fill="#36c" d="M4.07 16.49L.29 12.71l1.42-1.42 2.22 2.22 8.3-10.14 1.54 1.26-9.7 11.86zM12 10h5v2h-5zm-3 4h5v2H9zm6-8h5v2h-5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check all</title><path fill="#36c" d="M.29 12.71l1.42-1.42 2.22 2.22 8.3-10.14 1.54 1.26-9.7 11.86zM12 10h5v2h-5zm-3 4h5v2H9zm6-8h5v2h-5z"/></svg>
\ No newline at end of file
index f5505f0..ae9ea81 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/checkAll.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/checkAll.png differ
index de8ee4b..6fe1464 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check all</title><path d="M4.07 16.49L.29 12.71l1.42-1.42 2.22 2.22 8.3-10.14 1.54 1.26-9.7 11.86zM12 10h5v2h-5zm-3 4h5v2H9zm6-8h5v2h-5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>check all</title><path d="M.29 12.71l1.42-1.42 2.22 2.22 8.3-10.14 1.54 1.26-9.7 11.86zM12 10h5v2h-5zm-3 4h5v2H9zm6-8h5v2h-5z"/></svg>
\ No newline at end of file
index e3f1ea0..35ec009 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/clear-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/clear-invert.png differ
index 7c904c2..dd54e33 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/clear-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/clear-progressive.png differ
index dc8c7e0..8d5b321 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/clear.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/clear.png differ
index 205a9dc..1311ba3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/clock-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/clock-invert.png differ
index 66280aa..61e67e5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/clock-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/clock-progressive.png differ
index 5e12f53..b6cd755 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/clock.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/clock.png differ
index 786cd2a..a23474b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/close-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/close-invert.png differ
index 4518e84..56a65ef 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/close.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/close.png differ
index edda550..d18a050 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/code-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/code-invert.png differ
index 7d273a1..e35be71 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>code</title><g fill="#fff"><path id="left-bracket" d="M1 10.08V8.92h1.15c1.15 0 1.15 0 1.15-1.15V5a7.42 7.42 0 0 1 .09-1.3 2 2 0 0 1 .3-.7 1.84 1.84 0 0 1 .93-.68A6.44 6.44 0 0 1 6.74 2h1.18v1.15h-.86A1.32 1.32 0 0 0 6 3.62a1.71 1.71 0 0 0-.36 1.23V7a3.22 3.22 0 0 1-.28 1.72 2 2 0 0 1-1.26.77 2.15 2.15 0 0 1 1.26.79A3.26 3.26 0 0 1 5.62 12v3.15A1.67 1.67 0 0 0 6 16.37a1.31 1.31 0 0 0 1.08.47h.87V18H6.74a6.3 6.3 0 0 1-2.12-.29 1.82 1.82 0 0 1-.93-.71 1.94 1.94 0 0 1-.3-.72A7.46 7.46 0 0 1 3.31 15v-3.77c0-1.15 0-1.15-1.15-1.15zm18 0V8.92h-1.15c-1.15 0-1.15 0-1.15-1.15V5a7.42 7.42 0 0 0-.08-1.32 2 2 0 0 0-.3-.73 1.84 1.84 0 0 0-.93-.68A6.44 6.44 0 0 0 13.26 2h-1.18v1.15h.87a1.32 1.32 0 0 1 1.05.47 1.71 1.71 0 0 1 .36 1.23V7a3.22 3.22 0 0 0 .28 1.72 2 2 0 0 0 1.26.77 2.15 2.15 0 0 0-1.26.79 3.26 3.26 0 0 0-.26 1.72v3.15a1.67 1.67 0 0 1-.38 1.22 1.31 1.31 0 0 1-1.08.47h-.87V18h1.19a6.3 6.3 0 0 0 2.12-.29 1.82 1.82 0 0 0 .93-.68 1.94 1.94 0 0 0 .3-.72 7.46 7.46 0 0 0 .1-1.31v-3.77c0-1.15 0-1.15 1.15-1.15z"/><use id="right-bracket" width="20" height="20" transform="matrix(-1 0 0 1 20 0)" xlink:href="#left-bracket"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>code</title><g fill="#fff"><path id="a" d="M1 10.08V8.92h1.15c1.15 0 1.15 0 1.15-1.15V5a7.42 7.42 0 0 1 .09-1.3 2 2 0 0 1 .3-.7 1.84 1.84 0 0 1 .93-.68A6.44 6.44 0 0 1 6.74 2h1.18v1.15h-.86A1.32 1.32 0 0 0 6 3.62a1.71 1.71 0 0 0-.36 1.23V7a3.22 3.22 0 0 1-.28 1.72 2 2 0 0 1-1.26.77 2.15 2.15 0 0 1 1.26.79A3.26 3.26 0 0 1 5.62 12v3.15A1.67 1.67 0 0 0 6 16.37a1.31 1.31 0 0 0 1.08.47h.87V18H6.74a6.3 6.3 0 0 1-2.12-.29 1.82 1.82 0 0 1-.93-.71 1.94 1.94 0 0 1-.3-.72A7.46 7.46 0 0 1 3.31 15v-3.77c0-1.15 0-1.15-1.15-1.15zm18 0V8.92h-1.15c-1.15 0-1.15 0-1.15-1.15V5a7.42 7.42 0 0 0-.08-1.32 2 2 0 0 0-.3-.73 1.84 1.84 0 0 0-.93-.68A6.44 6.44 0 0 0 13.26 2h-1.18v1.15h.87a1.32 1.32 0 0 1 1.05.47 1.71 1.71 0 0 1 .36 1.23V7a3.22 3.22 0 0 0 .28 1.72 2 2 0 0 0 1.26.77 2.15 2.15 0 0 0-1.26.79 3.26 3.26 0 0 0-.26 1.72v3.15a1.67 1.67 0 0 1-.38 1.22 1.31 1.31 0 0 1-1.08.47h-.87V18h1.19a6.3 6.3 0 0 0 2.12-.29 1.82 1.82 0 0 0 .93-.68 1.94 1.94 0 0 0 .3-.72 7.46 7.46 0 0 0 .1-1.31v-3.77c0-1.15 0-1.15 1.15-1.15z"/><use transform="matrix(-1 0 0 1 20 0)" xlink:href="#a"/></g></svg>
\ No newline at end of file
index fb29ed2..ac9175a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/code-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/code-progressive.png differ
index c4be1b7..1f8e2b6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>code</title><g fill="#36c"><path id="left-bracket" d="M1 10.08V8.92h1.15c1.15 0 1.15 0 1.15-1.15V5a7.42 7.42 0 0 1 .09-1.3 2 2 0 0 1 .3-.7 1.84 1.84 0 0 1 .93-.68A6.44 6.44 0 0 1 6.74 2h1.18v1.15h-.86A1.32 1.32 0 0 0 6 3.62a1.71 1.71 0 0 0-.36 1.23V7a3.22 3.22 0 0 1-.28 1.72 2 2 0 0 1-1.26.77 2.15 2.15 0 0 1 1.26.79A3.26 3.26 0 0 1 5.62 12v3.15A1.67 1.67 0 0 0 6 16.37a1.31 1.31 0 0 0 1.08.47h.87V18H6.74a6.3 6.3 0 0 1-2.12-.29 1.82 1.82 0 0 1-.93-.71 1.94 1.94 0 0 1-.3-.72A7.46 7.46 0 0 1 3.31 15v-3.77c0-1.15 0-1.15-1.15-1.15zm18 0V8.92h-1.15c-1.15 0-1.15 0-1.15-1.15V5a7.42 7.42 0 0 0-.08-1.32 2 2 0 0 0-.3-.73 1.84 1.84 0 0 0-.93-.68A6.44 6.44 0 0 0 13.26 2h-1.18v1.15h.87a1.32 1.32 0 0 1 1.05.47 1.71 1.71 0 0 1 .36 1.23V7a3.22 3.22 0 0 0 .28 1.72 2 2 0 0 0 1.26.77 2.15 2.15 0 0 0-1.26.79 3.26 3.26 0 0 0-.26 1.72v3.15a1.67 1.67 0 0 1-.38 1.22 1.31 1.31 0 0 1-1.08.47h-.87V18h1.19a6.3 6.3 0 0 0 2.12-.29 1.82 1.82 0 0 0 .93-.68 1.94 1.94 0 0 0 .3-.72 7.46 7.46 0 0 0 .1-1.31v-3.77c0-1.15 0-1.15 1.15-1.15z"/><use id="right-bracket" width="20" height="20" transform="matrix(-1 0 0 1 20 0)" xlink:href="#left-bracket"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>code</title><g fill="#36c"><path id="a" d="M1 10.08V8.92h1.15c1.15 0 1.15 0 1.15-1.15V5a7.42 7.42 0 0 1 .09-1.3 2 2 0 0 1 .3-.7 1.84 1.84 0 0 1 .93-.68A6.44 6.44 0 0 1 6.74 2h1.18v1.15h-.86A1.32 1.32 0 0 0 6 3.62a1.71 1.71 0 0 0-.36 1.23V7a3.22 3.22 0 0 1-.28 1.72 2 2 0 0 1-1.26.77 2.15 2.15 0 0 1 1.26.79A3.26 3.26 0 0 1 5.62 12v3.15A1.67 1.67 0 0 0 6 16.37a1.31 1.31 0 0 0 1.08.47h.87V18H6.74a6.3 6.3 0 0 1-2.12-.29 1.82 1.82 0 0 1-.93-.71 1.94 1.94 0 0 1-.3-.72A7.46 7.46 0 0 1 3.31 15v-3.77c0-1.15 0-1.15-1.15-1.15zm18 0V8.92h-1.15c-1.15 0-1.15 0-1.15-1.15V5a7.42 7.42 0 0 0-.08-1.32 2 2 0 0 0-.3-.73 1.84 1.84 0 0 0-.93-.68A6.44 6.44 0 0 0 13.26 2h-1.18v1.15h.87a1.32 1.32 0 0 1 1.05.47 1.71 1.71 0 0 1 .36 1.23V7a3.22 3.22 0 0 0 .28 1.72 2 2 0 0 0 1.26.77 2.15 2.15 0 0 0-1.26.79 3.26 3.26 0 0 0-.26 1.72v3.15a1.67 1.67 0 0 1-.38 1.22 1.31 1.31 0 0 1-1.08.47h-.87V18h1.19a6.3 6.3 0 0 0 2.12-.29 1.82 1.82 0 0 0 .93-.68 1.94 1.94 0 0 0 .3-.72 7.46 7.46 0 0 0 .1-1.31v-3.77c0-1.15 0-1.15 1.15-1.15z"/><use transform="matrix(-1 0 0 1 20 0)" xlink:href="#a"/></g></svg>
\ No newline at end of file
index 02bde42..13e692c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/code.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/code.png differ
index ba930ed..0501aa3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>code</title><path id="left-bracket" d="M1 10.08V8.92h1.15c1.15 0 1.15 0 1.15-1.15V5a7.42 7.42 0 0 1 .09-1.3 2 2 0 0 1 .3-.7 1.84 1.84 0 0 1 .93-.68A6.44 6.44 0 0 1 6.74 2h1.18v1.15h-.86A1.32 1.32 0 0 0 6 3.62a1.71 1.71 0 0 0-.36 1.23V7a3.22 3.22 0 0 1-.28 1.72 2 2 0 0 1-1.26.77 2.15 2.15 0 0 1 1.26.79A3.26 3.26 0 0 1 5.62 12v3.15A1.67 1.67 0 0 0 6 16.37a1.31 1.31 0 0 0 1.08.47h.87V18H6.74a6.3 6.3 0 0 1-2.12-.29 1.82 1.82 0 0 1-.93-.71 1.94 1.94 0 0 1-.3-.72A7.46 7.46 0 0 1 3.31 15v-3.77c0-1.15 0-1.15-1.15-1.15zm18 0V8.92h-1.15c-1.15 0-1.15 0-1.15-1.15V5a7.42 7.42 0 0 0-.08-1.32 2 2 0 0 0-.3-.73 1.84 1.84 0 0 0-.93-.68A6.44 6.44 0 0 0 13.26 2h-1.18v1.15h.87a1.32 1.32 0 0 1 1.05.47 1.71 1.71 0 0 1 .36 1.23V7a3.22 3.22 0 0 0 .28 1.72 2 2 0 0 0 1.26.77 2.15 2.15 0 0 0-1.26.79 3.26 3.26 0 0 0-.26 1.72v3.15a1.67 1.67 0 0 1-.38 1.22 1.31 1.31 0 0 1-1.08.47h-.87V18h1.19a6.3 6.3 0 0 0 2.12-.29 1.82 1.82 0 0 0 .93-.68 1.94 1.94 0 0 0 .3-.72 7.46 7.46 0 0 0 .1-1.31v-3.77c0-1.15 0-1.15 1.15-1.15z"/><use id="right-bracket" width="20" height="20" transform="matrix(-1 0 0 1 20 0)" xlink:href="#left-bracket"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>code</title><path id="a" d="M1 10.08V8.92h1.15c1.15 0 1.15 0 1.15-1.15V5a7.42 7.42 0 0 1 .09-1.3 2 2 0 0 1 .3-.7 1.84 1.84 0 0 1 .93-.68A6.44 6.44 0 0 1 6.74 2h1.18v1.15h-.86A1.32 1.32 0 0 0 6 3.62a1.71 1.71 0 0 0-.36 1.23V7a3.22 3.22 0 0 1-.28 1.72 2 2 0 0 1-1.26.77 2.15 2.15 0 0 1 1.26.79A3.26 3.26 0 0 1 5.62 12v3.15A1.67 1.67 0 0 0 6 16.37a1.31 1.31 0 0 0 1.08.47h.87V18H6.74a6.3 6.3 0 0 1-2.12-.29 1.82 1.82 0 0 1-.93-.71 1.94 1.94 0 0 1-.3-.72A7.46 7.46 0 0 1 3.31 15v-3.77c0-1.15 0-1.15-1.15-1.15zm18 0V8.92h-1.15c-1.15 0-1.15 0-1.15-1.15V5a7.42 7.42 0 0 0-.08-1.32 2 2 0 0 0-.3-.73 1.84 1.84 0 0 0-.93-.68A6.44 6.44 0 0 0 13.26 2h-1.18v1.15h.87a1.32 1.32 0 0 1 1.05.47 1.71 1.71 0 0 1 .36 1.23V7a3.22 3.22 0 0 0 .28 1.72 2 2 0 0 0 1.26.77 2.15 2.15 0 0 0-1.26.79 3.26 3.26 0 0 0-.26 1.72v3.15a1.67 1.67 0 0 1-.38 1.22 1.31 1.31 0 0 1-1.08.47h-.87V18h1.19a6.3 6.3 0 0 0 2.12-.29 1.82 1.82 0 0 0 .93-.68 1.94 1.94 0 0 0 .3-.72 7.46 7.46 0 0 0 .1-1.31v-3.77c0-1.15 0-1.15 1.15-1.15z"/><use transform="matrix(-1 0 0 1 20 0)" xlink:href="#a"/></svg>
\ No newline at end of file
index be86bd9..c4d4e5f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/collapse-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/collapse-invert.png differ
index fbf35c3..603d4c3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>collapse</title><path fill="#fff" d="M1 13.75l1.5 1.5 7.5-7.5 7.5 7.5 1.5-1.5-9-9-9 9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>collapse</title><path fill="#fff" d="M2.5 15.25l7.5-7.5 7.5 7.5 1.5-1.5-9-9-9 9z"/></svg>
\ No newline at end of file
index 2109697..0855d79 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>collapse</title><path fill="#36c" d="M1 13.75l1.5 1.5 7.5-7.5 7.5 7.5 1.5-1.5-9-9-9 9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>collapse</title><path fill="#36c" d="M2.5 15.25l7.5-7.5 7.5 7.5 1.5-1.5-9-9-9 9z"/></svg>
\ No newline at end of file
index aad3498..3acb608 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/collapse.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/collapse.png differ
index 580736c..c49bfe5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>collapse</title><path d="M1 13.75l1.5 1.5 7.5-7.5 7.5 7.5 1.5-1.5-9-9-9 9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>collapse</title><path d="M2.5 15.25l7.5-7.5 7.5 7.5 1.5-1.5-9-9-9 9z"/></svg>
\ No newline at end of file
index ebae499..35aa024 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/die-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/die-invert.png differ
index 7c7b3a2..5c19b63 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>die</title><path fill="#fff" d="M17 1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zM5 17a2 2 0 1 1 2-2 2 2 0 0 1-2 2zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-10a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>die</title><path fill="#fff" d="M3 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm2 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-10a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 681cbfc..549c40a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>die</title><path fill="#36c" d="M17 1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zM5 17a2 2 0 1 1 2-2 2 2 0 0 1-2 2zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-10a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>die</title><path fill="#36c" d="M3 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm2 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-10a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index d52000c..393712e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/die.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/die.png differ
index 9fc0b03..8fec5b2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>die</title><path d="M17 1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zM5 17a2 2 0 1 1 2-2 2 2 0 0 1-2 2zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-10a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>die</title><path d="M3 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm2 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm5 5a2 2 0 1 1 2-2 2 2 0 0 1-2 2zm0-10a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 8fdacba..a14c2ce 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle-invert.png differ
index 57b6f84..d974665 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>down triangle</title><path fill="#fff" d="M10 15L2 5h16l-8 10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>down triangle</title><path fill="#fff" d="M10 15L2 5h16z"/></svg>
\ No newline at end of file
index 152cbb7..db8ce20 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>down triangle</title><path fill="#36c" d="M10 15L2 5h16l-8 10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>down triangle</title><path fill="#36c" d="M10 15L2 5h16z"/></svg>
\ No newline at end of file
index bb6b0a6..7c412ac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/downTriangle.png differ
index 852ea6b..3b512ab 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>down triangle</title><path d="M10 15L2 5h16l-8 10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>down triangle</title><path d="M10 15L2 5h16z"/></svg>
\ No newline at end of file
index d817244..db7acd8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/download-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/download-invert.png differ
index 130b84c..28d279c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>download</title><g fill="#fff"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 15l5-6h-4V1H9v8H5l5 6z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>download</title><g fill="#fff"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M15 9h-4V1H9v8H5l5 6z"/></g></svg>
\ No newline at end of file
index 3551d9b..01aa1ad 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>download</title><g fill="#36c"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 15l5-6h-4V1H9v8H5l5 6z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>download</title><g fill="#36c"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M15 9h-4V1H9v8H5l5 6z"/></g></svg>
\ No newline at end of file
index 69a0bde..4f4502a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/download.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/download.png differ
index 9023c6a..f3c94d4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>download</title><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 15l5-6h-4V1H9v8H5l5 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>download</title><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M15 9h-4V1H9v8H5l5 6z"/></svg>
\ No newline at end of file
index e6d4d41..372ae5b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/draggable-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/draggable-invert.png differ
index 31503f0..2f4352f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>draggable</title><path fill="#fff" d="M2 11h16v2H2zm0-4h16v2H2zm8 11l3-3H7l3 3zm0-16L7 5h6l-3-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>draggable</title><path fill="#fff" d="M2 11h16v2H2zm0-4h16v2H2zm11 8H7l3 3zM7 5h6l-3-3z"/></svg>
\ No newline at end of file
index 34bd4d7..9c57fe3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>draggable</title><path fill="#36c" d="M2 11h16v2H2zm0-4h16v2H2zm8 11l3-3H7l3 3zm0-16L7 5h6l-3-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>draggable</title><path fill="#36c" d="M2 11h16v2H2zm0-4h16v2H2zm11 8H7l3 3zM7 5h6l-3-3z"/></svg>
\ No newline at end of file
index 3ee5fad..8c075da 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/draggable.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/draggable.png differ
index 9b4ca86..c6e128a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>draggable</title><path d="M2 11h16v2H2zm0-4h16v2H2zm8 11l3-3H7l3 3zm0-16L7 5h6l-3-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>draggable</title><path d="M2 11h16v2H2zm0-4h16v2H2zm11 8H7l3 3zM7 5h6l-3-3z"/></svg>
\ No newline at end of file
index 6e2e1ba..a55e332 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/edit-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/edit-invert.png differ
index 6117de9..4b87a48 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>edit</title><path fill="#fff" d="M16.77 8l1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zm-5.81-3.71L1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>edit</title><path fill="#fff" d="M16.77 8l1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zM1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/></svg>
\ No newline at end of file
index 21aa633..c14305e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>edit</title><path fill="#36c" d="M16.77 8l1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zm-5.81-3.71L1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>edit</title><path fill="#36c" d="M16.77 8l1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zM1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/></svg>
\ No newline at end of file
index 3fb8c12..a75e798 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/edit.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/edit.png differ
index cc29f6e..a6f305f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>edit</title><path d="M16.77 8l1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zm-5.81-3.71L1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>edit</title><path d="M16.77 8l1.94-2a1 1 0 0 0 0-1.41l-3.34-3.3a1 1 0 0 0-1.41 0L12 3.23zM1 14.25V19h4.75l9.96-9.96-4.75-4.75z"/></svg>
\ No newline at end of file
index 634ae6d..f83ae97 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/editLock-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/editLock-invert.png differ
index efe691e..9149b9d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/editLock-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/editLock-progressive.png differ
index db1ff4e..2e74d37 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/editLock.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/editLock.png differ
index a5f07d1..9dda8d5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr-invert.png differ
index 0c3b396..86e9198 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path fill="#fff" d="M8.81 6.44L1 14.25V19h4.75l8.33-8.33-5.27-4.23zm5.05-3.58H13V0L8 4l5 4V5h.86c2.29 0 4 1.43 4 4.29H20a6.51 6.51 0 0 0-6.14-6.43z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path fill="#fff" d="M1 14.25V19h4.75l8.33-8.33-5.27-4.23zM13 2.86V0L8 4l5 4V5h.86c2.29 0 4 1.43 4 4.29H20a6.51 6.51 0 0 0-6.14-6.43z"/></svg>
\ No newline at end of file
index b18e215..396b656 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path fill="#36c" d="M8.81 6.44L1 14.25V19h4.75l8.33-8.33-5.27-4.23zm5.05-3.58H13V0L8 4l5 4V5h.86c2.29 0 4 1.43 4 4.29H20a6.51 6.51 0 0 0-6.14-6.43z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path fill="#36c" d="M1 14.25V19h4.75l8.33-8.33-5.27-4.23zM13 2.86V0L8 4l5 4V5h.86c2.29 0 4 1.43 4 4.29H20a6.51 6.51 0 0 0-6.14-6.43z"/></svg>
\ No newline at end of file
index a798c0b..543f8f8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-ltr.png differ
index 1e52a45..ec86e2e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path d="M8.81 6.44L1 14.25V19h4.75l8.33-8.33-5.27-4.23zm5.05-3.58H13V0L8 4l5 4V5h.86c2.29 0 4 1.43 4 4.29H20a6.51 6.51 0 0 0-6.14-6.43z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path d="M1 14.25V19h4.75l8.33-8.33-5.27-4.23zM13 2.86V0L8 4l5 4V5h.86c2.29 0 4 1.43 4 4.29H20a6.51 6.51 0 0 0-6.14-6.43z"/></svg>
\ No newline at end of file
index f37add5..a153648 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl-invert.png differ
index 0fb064d..e25470a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><g fill="#fff"><path d="M10.81 7.44L3 15.25V20h4.75l8.33-8.33-5.27-4.23z"/><path d="M12.14 2.86H13V0l5 4-5 4V5h-.86c-2.28 0-4 1.43-4 4.29H6a6.51 6.51 0 0 1 6.14-6.43z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><g fill="#fff"><path d="M3 15.25V20h4.75l8.33-8.33-5.27-4.23z"/><path d="M13 2.86V0l5 4-5 4V5h-.86c-2.28 0-4 1.43-4 4.29H6a6.51 6.51 0 0 1 6.14-6.43z"/></g></svg>
\ No newline at end of file
index 9da6a88..c65bd8a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><g fill="#36c"><path d="M10.81 7.44L3 15.25V20h4.75l8.33-8.33-5.27-4.23z"/><path d="M12.14 2.86H13V0l5 4-5 4V5h-.86c-2.28 0-4 1.43-4 4.29H6a6.51 6.51 0 0 1 6.14-6.43z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><g fill="#36c"><path d="M3 15.25V20h4.75l8.33-8.33-5.27-4.23z"/><path d="M13 2.86V0l5 4-5 4V5h-.86c-2.28 0-4 1.43-4 4.29H6a6.51 6.51 0 0 1 6.14-6.43z"/></g></svg>
\ No newline at end of file
index 51b35cf..6dcf0c6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/editUndo-rtl.png differ
index 5a6859b..67d75bd 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path d="M10.81 7.44L3 15.25V20h4.75l8.33-8.33-5.27-4.23z"/><path d="M12.14 2.86H13V0l5 4-5 4V5h-.86c-2.28 0-4 1.43-4 4.29H6a6.51 6.51 0 0 1 6.14-6.43z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo edit</title><path d="M3 15.25V20h4.75l8.33-8.33-5.27-4.23z"/><path d="M13 2.86V0l5 4-5 4V5h-.86c-2.28 0-4 1.43-4 4.29H6a6.51 6.51 0 0 1 6.14-6.43z"/></svg>
\ No newline at end of file
index 776634f..93552af 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/ellipsis-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/ellipsis-invert.png differ
index 90e3270..208b27c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/ellipsis.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/ellipsis.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/error-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/error-invert.png
new file mode 100644 (file)
index 0000000..40502b3
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/error-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/error-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/error-invert.svg
new file mode 100644 (file)
index 0000000..bf7cf7e
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>error</title><path fill="#fff" d="M13.728 1H6.272L1 6.272v7.456L6.272 19h7.456L19 13.728V6.272zM11 15H9v-2h2zm0-4H9V5h2z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/error-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/error-progressive.png
new file mode 100644 (file)
index 0000000..ee87517
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/error-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/error-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/error-progressive.svg
new file mode 100644 (file)
index 0000000..2072f16
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>error</title><path fill="#36c" d="M13.728 1H6.272L1 6.272v7.456L6.272 19h7.456L19 13.728V6.272zM11 15H9v-2h2zm0-4H9V5h2z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/error.png b/resources/lib/ooui/themes/wikimediaui/images/icons/error.png
new file mode 100644 (file)
index 0000000..0d575fb
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/error.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/error.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/error.svg
new file mode 100644 (file)
index 0000000..69f4d9b
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>error</title><path d="M13.728 1H6.272L1 6.272v7.456L6.272 19h7.456L19 13.728V6.272zM11 15H9v-2h2zm0-4H9V5h2z"/></svg>
\ No newline at end of file
index eaa617b..8c2085a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>exit fullscreen</title><path fill="#fff" d="M7 7V1H5v4H1v2h6zM5 19h2v-6H1v2h4v4zm10-4h4v-2h-6v6h2v-4zm0-8h4V5h-4V1h-2v6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>exit fullscreen</title><path fill="#fff" d="M7 7V1H5v4H1v2zM5 19h2v-6H1v2h4zm10-4h4v-2h-6v6h2zm0-8h4V5h-4V1h-2v6z"/></svg>
\ No newline at end of file
index e8744a6..426f673 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>exit fullscreen</title><path fill="#36c" d="M7 7V1H5v4H1v2h6zM5 19h2v-6H1v2h4v4zm10-4h4v-2h-6v6h2v-4zm0-8h4V5h-4V1h-2v6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>exit fullscreen</title><path fill="#36c" d="M7 7V1H5v4H1v2zM5 19h2v-6H1v2h4zm10-4h4v-2h-6v6h2zm0-8h4V5h-4V1h-2v6z"/></svg>
\ No newline at end of file
index 5ec1f58..6dea677 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/exitFullscreen.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/exitFullscreen.png differ
index 6822a68..2c79c28 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>exit fullscreen</title><path d="M7 7V1H5v4H1v2h6zM5 19h2v-6H1v2h4v4zm10-4h4v-2h-6v6h2v-4zm0-8h4V5h-4V1h-2v6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>exit fullscreen</title><path d="M7 7V1H5v4H1v2zM5 19h2v-6H1v2h4zm10-4h4v-2h-6v6h2zm0-8h4V5h-4V1h-2v6z"/></svg>
\ No newline at end of file
index 2b4a678..b130da8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/expand-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/expand-invert.png differ
index 58d85fa..04b3108 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>expand</title><path fill="#fff" d="M19 6.25l-1.5-1.5-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>expand</title><path fill="#fff" d="M17.5 4.75l-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/></svg>
\ No newline at end of file
index ff08194..84744af 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>expand</title><path fill="#36c" d="M19 6.25l-1.5-1.5-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>expand</title><path fill="#36c" d="M17.5 4.75l-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/></svg>
\ No newline at end of file
index 4496478..2c65406 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/expand.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/expand.png differ
index 94bc7c1..eec9c6a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>expand</title><path d="M19 6.25l-1.5-1.5-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>expand</title><path d="M17.5 4.75l-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/></svg>
\ No newline at end of file
index 78d0f3a..6761a71 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/eye-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/eye-invert.png differ
index 55b6690..4c15481 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye</title><path fill="#fff" d="M10 7.5a2.5 2.5 0 1 0 2.5 2.5A2.5 2.5 0 0 0 10 7.5zm0 7a4.5 4.5 0 1 1 4.5-4.5 4.5 4.5 0 0 1-4.5 4.5zM10 3C3 3 0 10 0 10s3 7 10 7 10-7 10-7-3-7-10-7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye</title><g fill="#fff"><path d="M10 14.5a4.5 4.5 0 1 1 4.5-4.5 4.5 4.5 0 0 1-4.5 4.5zM10 3C3 3 0 10 0 10s3 7 10 7 10-7 10-7-3-7-10-7z"/><circle cx="10" cy="10" r="2.5"/></g></svg>
\ No newline at end of file
index a62e85d..d19ffe9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/eye-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/eye-progressive.png differ
index 0850af4..0c3e41a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye</title><path fill="#36c" d="M10 7.5a2.5 2.5 0 1 0 2.5 2.5A2.5 2.5 0 0 0 10 7.5zm0 7a4.5 4.5 0 1 1 4.5-4.5 4.5 4.5 0 0 1-4.5 4.5zM10 3C3 3 0 10 0 10s3 7 10 7 10-7 10-7-3-7-10-7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye</title><g fill="#36c"><path d="M10 14.5a4.5 4.5 0 1 1 4.5-4.5 4.5 4.5 0 0 1-4.5 4.5zM10 3C3 3 0 10 0 10s3 7 10 7 10-7 10-7-3-7-10-7z"/><circle cx="10" cy="10" r="2.5"/></g></svg>
\ No newline at end of file
index 153beb5..af25994 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/eye.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/eye.png differ
index be0c4e6..a53e51f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye</title><path d="M10 7.5a2.5 2.5 0 1 0 2.5 2.5A2.5 2.5 0 0 0 10 7.5zm0 7a4.5 4.5 0 1 1 4.5-4.5 4.5 4.5 0 0 1-4.5 4.5zM10 3C3 3 0 10 0 10s3 7 10 7 10-7 10-7-3-7-10-7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye</title><path d="M10 14.5a4.5 4.5 0 1 1 4.5-4.5 4.5 4.5 0 0 1-4.5 4.5zM10 3C3 3 0 10 0 10s3 7 10 7 10-7 10-7-3-7-10-7z"/><circle cx="10" cy="10" r="2.5"/></svg>
\ No newline at end of file
index df60737..c013939 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-invert.png differ
index 5a5611d..6f54e9f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye closed</title><g fill="#fff"><path d="M9.91 7.51l2.58 2.43A2.5 2.5 0 0 0 10 7.5z"/><path d="M8.2 5.9a4.38 4.38 0 0 1 1.8-.4 4.5 4.5 0 0 1 4.5 4.5 4.34 4.34 0 0 1-.29 1.55L17 14.14A14 14 0 0 0 20 10s-3-7-10-7a9.63 9.63 0 0 0-4 .85zm7.67 9.15L13 12.36l-1-.91-3.56-3.39L7 6.69 4.71 4.55 2 2 1 3l2.55 2.4A13.89 13.89 0 0 0 0 10s3 7 10 7a9.67 9.67 0 0 0 4.64-1.16L18 19l1-1-3.13-2.95zM10 14.5A4.5 4.5 0 0 1 5.5 10a4.45 4.45 0 0 1 .6-2.2l1.53 1.44a2.47 2.47 0 0 0-.13.76 2.49 2.49 0 0 0 3.41 2.32l1.54 1.45a4.47 4.47 0 0 1-2.45.73z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye closed</title><g fill="#fff"><path d="M12.49 9.94A2.5 2.5 0 0 0 10 7.5z"/><path d="M8.2 5.9a4.38 4.38 0 0 1 1.8-.4 4.5 4.5 0 0 1 4.5 4.5 4.34 4.34 0 0 1-.29 1.55L17 14.14A14 14 0 0 0 20 10s-3-7-10-7a9.63 9.63 0 0 0-4 .85zM2 2L1 3l2.55 2.4A13.89 13.89 0 0 0 0 10s3 7 10 7a9.67 9.67 0 0 0 4.64-1.16L18 19l1-1zm8 12.5A4.5 4.5 0 0 1 5.5 10a4.45 4.45 0 0 1 .6-2.2l1.53 1.44a2.47 2.47 0 0 0-.13.76 2.49 2.49 0 0 0 3.41 2.32l1.54 1.45a4.47 4.47 0 0 1-2.45.73z"/></g></svg>
\ No newline at end of file
index 2a6756e..2495104 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed-progressive.png differ
index 6e2fa34..6a9a76d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye closed</title><g fill="#36c"><path d="M9.91 7.51l2.58 2.43A2.5 2.5 0 0 0 10 7.5z"/><path d="M8.2 5.9a4.38 4.38 0 0 1 1.8-.4 4.5 4.5 0 0 1 4.5 4.5 4.34 4.34 0 0 1-.29 1.55L17 14.14A14 14 0 0 0 20 10s-3-7-10-7a9.63 9.63 0 0 0-4 .85zm7.67 9.15L13 12.36l-1-.91-3.56-3.39L7 6.69 4.71 4.55 2 2 1 3l2.55 2.4A13.89 13.89 0 0 0 0 10s3 7 10 7a9.67 9.67 0 0 0 4.64-1.16L18 19l1-1-3.13-2.95zM10 14.5A4.5 4.5 0 0 1 5.5 10a4.45 4.45 0 0 1 .6-2.2l1.53 1.44a2.47 2.47 0 0 0-.13.76 2.49 2.49 0 0 0 3.41 2.32l1.54 1.45a4.47 4.47 0 0 1-2.45.73z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye closed</title><g fill="#36c"><path d="M12.49 9.94A2.5 2.5 0 0 0 10 7.5z"/><path d="M8.2 5.9a4.38 4.38 0 0 1 1.8-.4 4.5 4.5 0 0 1 4.5 4.5 4.34 4.34 0 0 1-.29 1.55L17 14.14A14 14 0 0 0 20 10s-3-7-10-7a9.63 9.63 0 0 0-4 .85zM2 2L1 3l2.55 2.4A13.89 13.89 0 0 0 0 10s3 7 10 7a9.67 9.67 0 0 0 4.64-1.16L18 19l1-1zm8 12.5A4.5 4.5 0 0 1 5.5 10a4.45 4.45 0 0 1 .6-2.2l1.53 1.44a2.47 2.47 0 0 0-.13.76 2.49 2.49 0 0 0 3.41 2.32l1.54 1.45a4.47 4.47 0 0 1-2.45.73z"/></g></svg>
\ No newline at end of file
index d6f4c72..6eacf5a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/eyeClosed.png differ
index f1df4ac..f5c53f5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye closed</title><path d="M9.91 7.51l2.58 2.43A2.5 2.5 0 0 0 10 7.5z"/><path d="M8.2 5.9a4.38 4.38 0 0 1 1.8-.4 4.5 4.5 0 0 1 4.5 4.5 4.34 4.34 0 0 1-.29 1.55L17 14.14A14 14 0 0 0 20 10s-3-7-10-7a9.63 9.63 0 0 0-4 .85zm7.67 9.15L13 12.36l-1-.91-3.56-3.39L7 6.69 4.71 4.55 2 2 1 3l2.55 2.4A13.89 13.89 0 0 0 0 10s3 7 10 7a9.67 9.67 0 0 0 4.64-1.16L18 19l1-1-3.13-2.95zM10 14.5A4.5 4.5 0 0 1 5.5 10a4.45 4.45 0 0 1 .6-2.2l1.53 1.44a2.47 2.47 0 0 0-.13.76 2.49 2.49 0 0 0 3.41 2.32l1.54 1.45a4.47 4.47 0 0 1-2.45.73z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>eye closed</title><path d="M12.49 9.94A2.5 2.5 0 0 0 10 7.5z"/><path d="M8.2 5.9a4.38 4.38 0 0 1 1.8-.4 4.5 4.5 0 0 1 4.5 4.5 4.34 4.34 0 0 1-.29 1.55L17 14.14A14 14 0 0 0 20 10s-3-7-10-7a9.63 9.63 0 0 0-4 .85zM2 2L1 3l2.55 2.4A13.89 13.89 0 0 0 0 10s3 7 10 7a9.67 9.67 0 0 0 4.64-1.16L18 19l1-1zm8 12.5A4.5 4.5 0 0 1 5.5 10a4.45 4.45 0 0 1 .6-2.2l1.53 1.44a2.47 2.47 0 0 0-.13.76 2.49 2.49 0 0 0 3.41 2.32l1.54 1.45a4.47 4.47 0 0 1-2.45.73z"/></svg>
\ No newline at end of file
index 0f8e493..8329c30 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr-invert.png differ
index b6beaf5..6ad2719 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#fff"><path d="M19 16L2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/><rect width="4" height="8" x="4" y="9" rx="2" ry="2"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#fff"><path d="M19 16L2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/><rect width="4" height="8" x="4" y="9" rx="2"/></g></svg>
\ No newline at end of file
index e7ac225..41ad160 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#36c"><path d="M19 16L2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/><rect width="4" height="8" x="4" y="9" rx="2" ry="2"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#36c"><path d="M19 16L2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/><rect width="4" height="8" x="4" y="9" rx="2"/></g></svg>
\ No newline at end of file
index c6bfc7d..e05dd95 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-ltr.png differ
index c759cfa..8cbf125 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><path d="M19 16L2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/><rect width="4" height="8" x="4" y="9" rx="2" ry="2"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><path d="M19 16L2 12a3.83 3.83 0 0 1-1-2.5A3.83 3.83 0 0 1 2 7l17-4z"/><rect width="4" height="8" x="4" y="9" rx="2"/></svg>
\ No newline at end of file
index ddfd6bc..5b934d0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-invert.png differ
index d53abe9..80924b2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#fff"><path d="M1 3l17 4c.6.7 1 1.6 1 2.5 0 .9-.4 1.8-1 2.5L1 16V3z"/><path d="M16 11v4c0 1.1-.9 2-2 2s-2-.9-2-2v-4c0-1.1.9-2 2-2s2 .9 2 2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#fff"><path d="M18 7c.6.7 1 1.6 1 2.5 0 .9-.4 1.8-1 2.5L1 16V3z"/><rect width="4" height="8" x="12" y="9" rx="2"/></g></svg>
\ No newline at end of file
index 5a4f522..a7bd327 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl-progressive.png differ
index 2ff53d2..7fed87d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#36c"><path d="M1 3l17 4c.6.7 1 1.6 1 2.5 0 .9-.4 1.8-1 2.5L1 16V3z"/><path d="M16 11v4c0 1.1-.9 2-2 2s-2-.9-2-2v-4c0-1.1.9-2 2-2s2 .9 2 2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><g fill="#36c"><path d="M18 7c.6.7 1 1.6 1 2.5 0 .9-.4 1.8-1 2.5L1 16V3z"/><rect width="4" height="8" x="12" y="9" rx="2"/></g></svg>
\ No newline at end of file
index 641a0ac..21c6cba 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/feedback-rtl.png differ
index a05c2cb..7a0c7e0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><path d="M1 3l17 4c.6.7 1 1.6 1 2.5 0 .9-.4 1.8-1 2.5L1 16V3z"/><path d="M16 11v4c0 1.1-.9 2-2 2s-2-.9-2-2v-4c0-1.1.9-2 2-2s2 .9 2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>feedback</title><path d="M18 7c.6.7 1 1.6 1 2.5 0 .9-.4 1.8-1 2.5L1 16V3z"/><rect width="4" height="8" x="12" y="9" rx="2"/></svg>
\ No newline at end of file
index f7881fa..58f0a7e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr-invert.png differ
index e7fa1a9..a19df35 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#fff" d="M17 6L3 1v18h2v-6.87L17 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#fff" d="M17 6L3 1v18h2v-6.87z"/></svg>
\ No newline at end of file
index dd98fc6..2e1a8c1 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#36c" d="M17 6L3 1v18h2v-6.87L17 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#36c" d="M17 6L3 1v18h2v-6.87z"/></svg>
\ No newline at end of file
index 6fdc061..709986b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/flag-ltr.png differ
index d19bed5..e900492 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path d="M17 6L3 1v18h2v-6.87L17 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path d="M17 6L3 1v18h2v-6.87z"/></svg>
\ No newline at end of file
index bcab507..8760b04 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl-invert.png differ
index dc80534..bbcc880 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#fff" d="M3 6l14-5v18h-2v-6.87L3 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#fff" d="M3 6l14-5v18h-2v-6.87z"/></svg>
\ No newline at end of file
index 4497644..53dd777 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#36c" d="M3 6l14-5v18h-2v-6.87L3 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path fill="#36c" d="M3 6l14-5v18h-2v-6.87z"/></svg>
\ No newline at end of file
index c1df6f0..bbec233 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/flag-rtl.png differ
index a58bb92..9851df4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path d="M3 6l14-5v18h-2v-6.87L3 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>flag</title><path d="M3 6l14-5v18h-2v-6.87z"/></svg>
\ No newline at end of file
index cc6e054..a8417e4 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-invert.png differ
index b98beb1..2f851c9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path fill="#fff" d="M8 2H2C.9 2 0 2.9 0 4v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-8L8 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><g fill="#fff"><path d="M8 2H2a2 2 0 0 0-2 2v2h12z"/><rect width="20" height="14" y="4" rx="2"/></g></svg>
\ No newline at end of file
index b963fe8..a9ee109 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr-progressive.png differ
index 8c89d06..a5a6dab 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path fill="#36c" d="M8 2H2C.9 2 0 2.9 0 4v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-8L8 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><g fill="#36c"><path d="M8 2H2a2 2 0 0 0-2 2v2h12z"/><rect width="20" height="14" y="4" rx="2"/></g></svg>
\ No newline at end of file
index 7a5de55..58178a5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-ltr.png differ
index 6ebe28e..5bea197 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path d="M8 2H2C.9 2 0 2.9 0 4v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-8L8 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path d="M8 2H2a2 2 0 0 0-2 2v2h12z"/><rect width="20" height="14" y="4" rx="2"/></svg>
\ No newline at end of file
index 52ada78..6af8060 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-invert.png differ
index 5887d6d..3a1bbad 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path fill="#fff" d="M10 4H2C.9 4 0 4.9 0 6v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2h-6l-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><g fill="#fff"><path d="M8 6h12V4a2 2 0 0 0-2-2h-6z"/><rect width="20" height="14" y="4" rx="2"/></g></svg>
\ No newline at end of file
index 7667dc5..6003746 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl-progressive.png differ
index 3634463..59a2928 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path fill="#36c" d="M10 4H2C.9 4 0 4.9 0 6v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2h-6l-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><g fill="#36c"><path d="M8 6h12V4a2 2 0 0 0-2-2h-6z"/><rect width="20" height="14" y="4" rx="2"/></g></svg>
\ No newline at end of file
index 7ed6508..e74c0f1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/folderPlaceholder-rtl.png differ
index f92ef93..fceff11 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path d="M10 4H2C.9 4 0 4.9 0 6v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2h-6l-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>folder placeholder</title><path d="M8 6h12V4a2 2 0 0 0-2-2h-6z"/><rect width="20" height="14" y="4" rx="2"/></svg>
\ No newline at end of file
index d1d2cc1..966f1d2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>fullscreen</title><path fill="#fff" d="M1 1v6h2V3h4V1H1zm2 12H1v6h6v-2H3v-4zm14 4h-4v2h6v-6h-2v4zm0-16h-4v2h4v4h2V1h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>fullscreen</title><path fill="#fff" d="M1 1v6h2V3h4V1zm2 12H1v6h6v-2H3zm14 4h-4v2h6v-6h-2zm0-16h-4v2h4v4h2V1z"/></svg>
\ No newline at end of file
index 68331db..3bc2142 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>fullscreen</title><path fill="#36c" d="M1 1v6h2V3h4V1H1zm2 12H1v6h6v-2H3v-4zm14 4h-4v2h6v-6h-2v4zm0-16h-4v2h4v4h2V1h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>fullscreen</title><path fill="#36c" d="M1 1v6h2V3h4V1zm2 12H1v6h6v-2H3zm14 4h-4v2h6v-6h-2zm0-16h-4v2h4v4h2V1z"/></svg>
\ No newline at end of file
index 52c5a5c..d9a5834 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/fullScreen.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/fullScreen.png differ
index ebb18a1..5981f5e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>fullscreen</title><path d="M1 1v6h2V3h4V1H1zm2 12H1v6h6v-2H3v-4zm14 4h-4v2h6v-6h-2v4zm0-16h-4v2h4v4h2V1h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>fullscreen</title><path d="M1 1v6h2V3h4V1zm2 12H1v6h6v-2H3zm14 4h-4v2h6v-6h-2zm0-16h-4v2h4v4h2V1z"/></svg>
\ No newline at end of file
index 1905b0b..94a5b86 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr-invert.png differ
index c14f604..7cf23e0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>funnel</title><g fill="#fff"><path d="M10 13L1 1h18l-9 12z"/><path d="M12 9H8v8l4 2V9z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>funnel</title><g fill="#fff"><path d="M10 13L1 1h18z"/><path d="M8 9v8l4 2V9z"/></g></svg>
\ No newline at end of file
index ec81fff..c2085da 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>funnel</title><g fill="#36c"><path d="M10 13L1 1h18l-9 12z"/><path d="M12 9H8v8l4 2V9z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>funnel</title><g fill="#36c"><path d="M10 13L1 1h18z"/><path d="M8 9v8l4 2V9z"/></g></svg>
\ No newline at end of file
index 96a3755..c71f6b3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-ltr.png differ
index 52008ae..c0bbada 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>funnel</title><path d="M10 13L1 1h18l-9 12z"/><path d="M12 9H8v8l4 2V9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>funnel</title><path d="M10 13L1 1h18z"/><path d="M8 9v8l4 2V9z"/></svg>
\ No newline at end of file
index 9365f4e..e140fc7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-rtl-invert.png differ
index 5fac08b..ccd1e11 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/funnel-rtl.png differ
index edc1854..b33db75 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/globe-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/globe-invert.png differ
index a06bfb5..75002fe 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/globe-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/globe-progressive.png differ
index 9c6e5f9..77d86cb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/globe.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/globe.png differ
index d04a503..51c5ae9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-ltr-invert.png differ
index 734ea3d..62b5ee7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-ltr.png differ
index 5440b17..bc07043 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl-invert.png differ
index aad5b35..e41c235 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half bright</title><path fill="#fff" d="M.1 9.6L3 12.5V17h4.2l2.9 2.9L13 17h4v-4.5l2.9-2.9L17 6.7V3h-3.9L10.2.1 7.2 3H3v3.7L.1 9.6zm3.9 0c.1-3.3 2.7-5.9 6-6v12c-3.3-.1-5.9-2.7-6-6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half bright</title><path fill="#fff" d="M.1 9.6L3 12.5V17h4.2l2.9 2.9L13 17h4v-4.5l2.9-2.9L17 6.7V3h-3.9L10.2.1 7.2 3H3v3.7zm3.9 0c.1-3.3 2.7-5.9 6-6v12c-3.3-.1-5.9-2.7-6-6z"/></svg>
\ No newline at end of file
index 4d676aa..ef1a55b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half bright</title><path fill="#36c" d="M.1 9.6L3 12.5V17h4.2l2.9 2.9L13 17h4v-4.5l2.9-2.9L17 6.7V3h-3.9L10.2.1 7.2 3H3v3.7L.1 9.6zm3.9 0c.1-3.3 2.7-5.9 6-6v12c-3.3-.1-5.9-2.7-6-6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half bright</title><path fill="#36c" d="M.1 9.6L3 12.5V17h4.2l2.9 2.9L13 17h4v-4.5l2.9-2.9L17 6.7V3h-3.9L10.2.1 7.2 3H3v3.7zm3.9 0c.1-3.3 2.7-5.9 6-6v12c-3.3-.1-5.9-2.7-6-6z"/></svg>
\ No newline at end of file
index 797a870..6edfb08 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfBright-rtl.png differ
index 59a010a..4664802 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half bright</title><path d="M.1 9.6L3 12.5V17h4.2l2.9 2.9L13 17h4v-4.5l2.9-2.9L17 6.7V3h-3.9L10.2.1 7.2 3H3v3.7L.1 9.6zm3.9 0c.1-3.3 2.7-5.9 6-6v12c-3.3-.1-5.9-2.7-6-6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half bright</title><path d="M.1 9.6L3 12.5V17h4.2l2.9 2.9L13 17h4v-4.5l2.9-2.9L17 6.7V3h-3.9L10.2.1 7.2 3H3v3.7zm3.9 0c.1-3.3 2.7-5.9 6-6v12c-3.3-.1-5.9-2.7-6-6z"/></svg>
\ No newline at end of file
index a566d99..e67dd27 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-ltr-invert.png differ
index dec2db0..902ddb9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-ltr.png differ
index b9a8300..b11b28c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl-invert.png differ
index 2ab3c41..d6e6c47 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half star</title><path fill="#fff" d="M5.4 12.5l-1.6 7 6.2-3.7 6.2 3.7-1.6-7L20 7h-7L10 .5 7 7H0l5.4 5.5zm.8 3.7l1-4.3-3.7-3.4h4.6L10 4.6v9.3l-3.8 2.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half star</title><path fill="#fff" d="M5.4 12.5l-1.6 7 6.2-3.7 6.2 3.7-1.6-7L20 7h-7L10 .5 7 7H0zm.8 3.7l1-4.3-3.7-3.4h4.6L10 4.6v9.3z"/></svg>
\ No newline at end of file
index 2c535a9..d5227a8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half star</title><path fill="#36c" d="M5.4 12.5l-1.6 7 6.2-3.7 6.2 3.7-1.6-7L20 7h-7L10 .5 7 7H0l5.4 5.5zm.8 3.7l1-4.3-3.7-3.4h4.6L10 4.6v9.3l-3.8 2.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half star</title><path fill="#36c" d="M5.4 12.5l-1.6 7 6.2-3.7 6.2 3.7-1.6-7L20 7h-7L10 .5 7 7H0zm.8 3.7l1-4.3-3.7-3.4h4.6L10 4.6v9.3z"/></svg>
\ No newline at end of file
index 09580ec..51daff7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/halfStar-rtl.png differ
index d6bdfbb..2e87ef3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half star</title><path d="M5.4 12.5l-1.6 7 6.2-3.7 6.2 3.7-1.6-7L20 7h-7L10 .5 7 7H0l5.4 5.5zm.8 3.7l1-4.3-3.7-3.4h4.6L10 4.6v9.3l-3.8 2.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>half star</title><path d="M5.4 12.5l-1.6 7 6.2-3.7 6.2 3.7-1.6-7L20 7h-7L10 .5 7 7H0zm.8 3.7l1-4.3-3.7-3.4h4.6L10 4.6v9.3z"/></svg>
\ No newline at end of file
index 6e03775..19381f8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/heart-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/heart-invert.png differ
index 3693ab3..da22719 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/heart.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/heart.png differ
index 967525a..dac9382 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-invert.png differ
index 5a18a63..cdbdad8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>help</title><path d="M10.06 1C13 1 15 2.89 15 5.53a4.59 4.59 0 0 1-2.29 4.08c-1.42.92-1.82 1.53-1.82 2.71V13H8.38v-.81a3.84 3.84 0 0 1 2-3.84c1.34-.9 1.79-1.53 1.79-2.71a2.1 2.1 0 0 0-2.08-2.14h-.17a2.3 2.3 0 0 0-2.38 2.22v.17H5A4.71 4.71 0 0 1 9.51 1a5 5 0 0 1 .55 0zM8 17a1.89 1.89 0 0 1 1.77-2H10a1.87 1.87 0 0 1 2 1.73 1.22 1.22 0 0 1 0 .27 1.87 1.87 0 0 1-1.73 2 1.22 1.22 0 0 1-.27 0 1.88 1.88 0 0 1-2-1.75A1 1 0 0 1 8 17z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>help</title><path d="M10.06 1C13 1 15 2.89 15 5.53a4.59 4.59 0 0 1-2.29 4.08c-1.42.92-1.82 1.53-1.82 2.71V13H8.38v-.81a3.84 3.84 0 0 1 2-3.84c1.34-.9 1.79-1.53 1.79-2.71a2.1 2.1 0 0 0-2.08-2.14h-.17a2.3 2.3 0 0 0-2.38 2.22v.17H5A4.71 4.71 0 0 1 9.51 1a5 5 0 0 1 .55 0z"/><circle cx="10" cy="17" r="2"/></g></svg>
\ No newline at end of file
index 51feab8..ec8e4da 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr-progressive.png differ
index dfc1709..79b12c5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>help</title><path d="M10.06 1C13 1 15 2.89 15 5.53a4.59 4.59 0 0 1-2.29 4.08c-1.42.92-1.82 1.53-1.82 2.71V13H8.38v-.81a3.84 3.84 0 0 1 2-3.84c1.34-.9 1.79-1.53 1.79-2.71a2.1 2.1 0 0 0-2.08-2.14h-.17a2.3 2.3 0 0 0-2.38 2.22v.17H5A4.71 4.71 0 0 1 9.51 1a5 5 0 0 1 .55 0zM8 17a1.89 1.89 0 0 1 1.77-2H10a1.87 1.87 0 0 1 2 1.73 1.22 1.22 0 0 1 0 .27 1.87 1.87 0 0 1-1.73 2 1.22 1.22 0 0 1-.27 0 1.88 1.88 0 0 1-2-1.75A1 1 0 0 1 8 17z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>help</title><path d="M10.06 1C13 1 15 2.89 15 5.53a4.59 4.59 0 0 1-2.29 4.08c-1.42.92-1.82 1.53-1.82 2.71V13H8.38v-.81a3.84 3.84 0 0 1 2-3.84c1.34-.9 1.79-1.53 1.79-2.71a2.1 2.1 0 0 0-2.08-2.14h-.17a2.3 2.3 0 0 0-2.38 2.22v.17H5A4.71 4.71 0 0 1 9.51 1a5 5 0 0 1 .55 0z"/><circle cx="10" cy="17" r="2"/></g></svg>
\ No newline at end of file
index 3731019..2610f62 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/help-ltr.png differ
index 6172357..81c79b2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M10.06 1C13 1 15 2.89 15 5.53a4.59 4.59 0 0 1-2.29 4.08c-1.42.92-1.82 1.53-1.82 2.71V13H8.38v-.81a3.84 3.84 0 0 1 2-3.84c1.34-.9 1.79-1.53 1.79-2.71a2.1 2.1 0 0 0-2.08-2.14h-.17a2.3 2.3 0 0 0-2.38 2.22v.17H5A4.71 4.71 0 0 1 9.51 1a5 5 0 0 1 .55 0zM8 17a1.89 1.89 0 0 1 1.77-2H10a1.87 1.87 0 0 1 2 1.73 1.22 1.22 0 0 1 0 .27 1.87 1.87 0 0 1-1.73 2 1.22 1.22 0 0 1-.27 0 1.88 1.88 0 0 1-2-1.75A1 1 0 0 1 8 17z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M10.06 1C13 1 15 2.89 15 5.53a4.59 4.59 0 0 1-2.29 4.08c-1.42.92-1.82 1.53-1.82 2.71V13H8.38v-.81a3.84 3.84 0 0 1 2-3.84c1.34-.9 1.79-1.53 1.79-2.71a2.1 2.1 0 0 0-2.08-2.14h-.17a2.3 2.3 0 0 0-2.38 2.22v.17H5A4.71 4.71 0 0 1 9.51 1a5 5 0 0 1 .55 0z"/><circle cx="10" cy="17" r="2"/></svg>
\ No newline at end of file
index b090e0c..643e1b5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-invert.png differ
index 764ec21..b4bd8bc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path fill="#fff" d="M5.49.01A4.72 4.72 0 0 1 10 4.9H7.46v-.17a2.31 2.31 0 0 0-2.38-2.22h-.19a2.1 2.1 0 0 0-2.06 2.14c0 1.18.45 1.81 1.79 2.71a3.86 3.86 0 0 1 2 3.84v.81H4.11v-.68c0-1.18-.4-1.79-1.82-2.71A4.59 4.59 0 0 1 0 4.54C0 1.9 2 .01 4.94.01a5 5 0 0 1 .55 0zM7 16.26a1.88 1.88 0 0 1-2 1.75 1.22 1.22 0 0 1-.27 0 1.86 1.86 0 0 1-1.73-2 1.22 1.22 0 0 1 0-.27 1.87 1.87 0 0 1 2-1.73h.23a1.89 1.89 0 0 1 1.77 2 1 1 0 0 1 0 .25z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><g fill="#fff"><path d="M5.49.01A4.72 4.72 0 0 1 10 4.9H7.46v-.17a2.31 2.31 0 0 0-2.38-2.22h-.19a2.1 2.1 0 0 0-2.06 2.14c0 1.18.45 1.81 1.79 2.71a3.86 3.86 0 0 1 2 3.84v.81H4.11v-.68c0-1.18-.4-1.79-1.82-2.71A4.59 4.59 0 0 1 0 4.54C0 1.9 2 .01 4.94.01a5 5 0 0 1 .55 0z"/><circle cx="5" cy="16" r="2"/></g></svg>
\ No newline at end of file
index 0279d07..2d12e47 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl-progressive.png differ
index a05675e..694389e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path fill="#36c" d="M5.49.01A4.72 4.72 0 0 1 10 4.9H7.46v-.17a2.31 2.31 0 0 0-2.38-2.22h-.19a2.1 2.1 0 0 0-2.06 2.14c0 1.18.45 1.81 1.79 2.71a3.86 3.86 0 0 1 2 3.84v.81H4.11v-.68c0-1.18-.4-1.79-1.82-2.71A4.59 4.59 0 0 1 0 4.54C0 1.9 2 .01 4.94.01a5 5 0 0 1 .55 0zM7 16.26a1.88 1.88 0 0 1-2 1.75 1.22 1.22 0 0 1-.27 0 1.86 1.86 0 0 1-1.73-2 1.22 1.22 0 0 1 0-.27 1.87 1.87 0 0 1 2-1.73h.23a1.89 1.89 0 0 1 1.77 2 1 1 0 0 1 0 .25z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><g fill="#36c"><path d="M5.49.01A4.72 4.72 0 0 1 10 4.9H7.46v-.17a2.31 2.31 0 0 0-2.38-2.22h-.19a2.1 2.1 0 0 0-2.06 2.14c0 1.18.45 1.81 1.79 2.71a3.86 3.86 0 0 1 2 3.84v.81H4.11v-.68c0-1.18-.4-1.79-1.82-2.71A4.59 4.59 0 0 1 0 4.54C0 1.9 2 .01 4.94.01a5 5 0 0 1 .55 0z"/><circle cx="5" cy="16" r="2"/></g></svg>
\ No newline at end of file
index ab64237..9f652db 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/help-rtl.png differ
index 23f3dba..57f7f7b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M5.49.01A4.72 4.72 0 0 1 10 4.9H7.46v-.17a2.31 2.31 0 0 0-2.38-2.22h-.19a2.1 2.1 0 0 0-2.06 2.14c0 1.18.45 1.81 1.79 2.71a3.86 3.86 0 0 1 2 3.84v.81H4.11v-.68c0-1.18-.4-1.79-1.82-2.71A4.59 4.59 0 0 1 0 4.54C0 1.9 2 .01 4.94.01a5 5 0 0 1 .55 0zM7 16.26a1.88 1.88 0 0 1-2 1.75 1.22 1.22 0 0 1-.27 0 1.86 1.86 0 0 1-1.73-2 1.22 1.22 0 0 1 0-.27 1.87 1.87 0 0 1 2-1.73h.23a1.89 1.89 0 0 1 1.77 2 1 1 0 0 1 0 .25z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M5.49.01A4.72 4.72 0 0 1 10 4.9H7.46v-.17a2.31 2.31 0 0 0-2.38-2.22h-.19a2.1 2.1 0 0 0-2.06 2.14c0 1.18.45 1.81 1.79 2.71a3.86 3.86 0 0 1 2 3.84v.81H4.11v-.68c0-1.18-.4-1.79-1.82-2.71A4.59 4.59 0 0 1 0 4.54C0 1.9 2 .01 4.94.01a5 5 0 0 1 .55 0z"/><circle cx="5" cy="16" r="2"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-invert.png
new file mode 100644 (file)
index 0000000..d1ec002
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-invert.svg
new file mode 100644 (file)
index 0000000..a350188
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>help</title><path d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm1 16H9v-2h2zm2.71-7.6a2.64 2.64 0 0 1-.33.74 3.16 3.16 0 0 1-.48.55l-.54.48c-.21.18-.41.35-.58.52a2.54 2.54 0 0 0-.47.56A2.3 2.3 0 0 0 11 12a3.79 3.79 0 0 0-.11 1H9.08a8.9 8.9 0 0 1 .07-1.25 3.28 3.28 0 0 1 .25-.9 2.79 2.79 0 0 1 .41-.67 4 4 0 0 1 .58-.58c.17-.16.34-.3.51-.44a3 3 0 0 0 .43-.44 1.83 1.83 0 0 0 .3-.55 2 2 0 0 0 .11-.72 2.06 2.06 0 0 0-.17-.86 1.71 1.71 0 0 0-1-.9 1.7 1.7 0 0 0-.5-.1 1.77 1.77 0 0 0-1.53.68 3 3 0 0 0-.5 1.82H6.16a4.74 4.74 0 0 1 .28-1.68 3.56 3.56 0 0 1 .8-1.29 3.88 3.88 0 0 1 1.28-.83A4.59 4.59 0 0 1 10.18 4a4.44 4.44 0 0 1 1.44.23 3.51 3.51 0 0 1 1.15.65 3.08 3.08 0 0 1 .78 1.06 3.54 3.54 0 0 1 .29 1.45 3.39 3.39 0 0 1-.13 1.01z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-progressive.png
new file mode 100644 (file)
index 0000000..eaa1be9
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr-progressive.svg
new file mode 100644 (file)
index 0000000..73fe34c
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>help</title><path d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm1 16H9v-2h2zm2.71-7.6a2.64 2.64 0 0 1-.33.74 3.16 3.16 0 0 1-.48.55l-.54.48c-.21.18-.41.35-.58.52a2.54 2.54 0 0 0-.47.56A2.3 2.3 0 0 0 11 12a3.79 3.79 0 0 0-.11 1H9.08a8.9 8.9 0 0 1 .07-1.25 3.28 3.28 0 0 1 .25-.9 2.79 2.79 0 0 1 .41-.67 4 4 0 0 1 .58-.58c.17-.16.34-.3.51-.44a3 3 0 0 0 .43-.44 1.83 1.83 0 0 0 .3-.55 2 2 0 0 0 .11-.72 2.06 2.06 0 0 0-.17-.86 1.71 1.71 0 0 0-1-.9 1.7 1.7 0 0 0-.5-.1 1.77 1.77 0 0 0-1.53.68 3 3 0 0 0-.5 1.82H6.16a4.74 4.74 0 0 1 .28-1.68 3.56 3.56 0 0 1 .8-1.29 3.88 3.88 0 0 1 1.28-.83A4.59 4.59 0 0 1 10.18 4a4.44 4.44 0 0 1 1.44.23 3.51 3.51 0 0 1 1.15.65 3.08 3.08 0 0 1 .78 1.06 3.54 3.54 0 0 1 .29 1.45 3.39 3.39 0 0 1-.13 1.01z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr.png
new file mode 100644 (file)
index 0000000..3ac0da5
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-ltr.svg
new file mode 100644 (file)
index 0000000..807cb84
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm1 16H9v-2h2zm2.71-7.6a2.64 2.64 0 0 1-.33.74 3.16 3.16 0 0 1-.48.55l-.54.48c-.21.18-.41.35-.58.52a2.54 2.54 0 0 0-.47.56A2.3 2.3 0 0 0 11 12a3.79 3.79 0 0 0-.11 1H9.08a8.9 8.9 0 0 1 .07-1.25 3.28 3.28 0 0 1 .25-.9 2.79 2.79 0 0 1 .41-.67 4 4 0 0 1 .58-.58c.17-.16.34-.3.51-.44a3 3 0 0 0 .43-.44 1.83 1.83 0 0 0 .3-.55 2 2 0 0 0 .11-.72 2.06 2.06 0 0 0-.17-.86 1.71 1.71 0 0 0-1-.9 1.7 1.7 0 0 0-.5-.1 1.77 1.77 0 0 0-1.53.68 3 3 0 0 0-.5 1.82H6.16a4.74 4.74 0 0 1 .28-1.68 3.56 3.56 0 0 1 .8-1.29 3.88 3.88 0 0 1 1.28-.83A4.59 4.59 0 0 1 10.18 4a4.44 4.44 0 0 1 1.44.23 3.51 3.51 0 0 1 1.15.65 3.08 3.08 0 0 1 .78 1.06 3.54 3.54 0 0 1 .29 1.45 3.39 3.39 0 0 1-.13 1.01z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-invert.png
new file mode 100644 (file)
index 0000000..2459a4c
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-invert.svg
new file mode 100644 (file)
index 0000000..9f79d18
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path fill="#fff" d="M0 10A10 10 0 1 0 10 0 10 10 0 0 0 0 10zm9 4h2v2H9zM6.16 7.39a3.54 3.54 0 0 1 .29-1.45 3.08 3.08 0 0 1 .78-1.06 3.51 3.51 0 0 1 1.15-.65A4.44 4.44 0 0 1 9.82 4a4.59 4.59 0 0 1 1.66.29 3.88 3.88 0 0 1 1.28.83 3.56 3.56 0 0 1 .8 1.29 4.74 4.74 0 0 1 .28 1.68h-1.91a3 3 0 0 0-.5-1.82 1.77 1.77 0 0 0-1.53-.68 1.7 1.7 0 0 0-.5.1 1.71 1.71 0 0 0-1 .9 2.06 2.06 0 0 0-.17.86 2 2 0 0 0 .11.72 1.83 1.83 0 0 0 .3.55 3 3 0 0 0 .43.44c.17.14.34.28.51.44a4 4 0 0 1 .58.58 2.79 2.79 0 0 1 .41.67 3.28 3.28 0 0 1 .25.9 8.9 8.9 0 0 1 .1 1.25H9.11A3.79 3.79 0 0 0 9 12a2.3 2.3 0 0 0-.31-.73 2.54 2.54 0 0 0-.47-.56c-.17-.17-.37-.34-.58-.52l-.54-.5a3.16 3.16 0 0 1-.48-.55 2.64 2.64 0 0 1-.33-.74 3.39 3.39 0 0 1-.13-1.01z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-progressive.png
new file mode 100644 (file)
index 0000000..e1dc9f7
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl-progressive.svg
new file mode 100644 (file)
index 0000000..f71e0be
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path fill="#36c" d="M0 10A10 10 0 1 0 10 0 10 10 0 0 0 0 10zm9 4h2v2H9zM6.16 7.39a3.54 3.54 0 0 1 .29-1.45 3.08 3.08 0 0 1 .78-1.06 3.51 3.51 0 0 1 1.15-.65A4.44 4.44 0 0 1 9.82 4a4.59 4.59 0 0 1 1.66.29 3.88 3.88 0 0 1 1.28.83 3.56 3.56 0 0 1 .8 1.29 4.74 4.74 0 0 1 .28 1.68h-1.91a3 3 0 0 0-.5-1.82 1.77 1.77 0 0 0-1.53-.68 1.7 1.7 0 0 0-.5.1 1.71 1.71 0 0 0-1 .9 2.06 2.06 0 0 0-.17.86 2 2 0 0 0 .11.72 1.83 1.83 0 0 0 .3.55 3 3 0 0 0 .43.44c.17.14.34.28.51.44a4 4 0 0 1 .58.58 2.79 2.79 0 0 1 .41.67 3.28 3.28 0 0 1 .25.9 8.9 8.9 0 0 1 .1 1.25H9.11A3.79 3.79 0 0 0 9 12a2.3 2.3 0 0 0-.31-.73 2.54 2.54 0 0 0-.47-.56c-.17-.17-.37-.34-.58-.52l-.54-.5a3.16 3.16 0 0 1-.48-.55 2.64 2.64 0 0 1-.33-.74 3.39 3.39 0 0 1-.13-1.01z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl.png
new file mode 100644 (file)
index 0000000..e60b61a
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpNotice-rtl.svg
new file mode 100644 (file)
index 0000000..7e400cb
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M0 10A10 10 0 1 0 10 0 10 10 0 0 0 0 10zm9 4h2v2H9zM6.16 7.39a3.54 3.54 0 0 1 .29-1.45 3.08 3.08 0 0 1 .78-1.06 3.51 3.51 0 0 1 1.15-.65A4.44 4.44 0 0 1 9.82 4a4.59 4.59 0 0 1 1.66.29 3.88 3.88 0 0 1 1.28.83 3.56 3.56 0 0 1 .8 1.29 4.74 4.74 0 0 1 .28 1.68h-1.91a3 3 0 0 0-.5-1.82 1.77 1.77 0 0 0-1.53-.68 1.7 1.7 0 0 0-.5.1 1.71 1.71 0 0 0-1 .9 2.06 2.06 0 0 0-.17.86 2 2 0 0 0 .11.72 1.83 1.83 0 0 0 .3.55 3 3 0 0 0 .43.44c.17.14.34.28.51.44a4 4 0 0 1 .58.58 2.79 2.79 0 0 1 .41.67 3.28 3.28 0 0 1 .25.9 8.9 8.9 0 0 1 .1 1.25H9.11A3.79 3.79 0 0 0 9 12a2.3 2.3 0 0 0-.31-.73 2.54 2.54 0 0 0-.47-.56c-.17-.17-.37-.34-.58-.52l-.54-.5a3.16 3.16 0 0 1-.48-.55 2.64 2.64 0 0 1-.33-.74 3.39 3.39 0 0 1-.13-1.01z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-invert.png
deleted file mode 100644 (file)
index 13bc8f0..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-invert.svg
deleted file mode 100644 (file)
index a350188..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>help</title><path d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm1 16H9v-2h2zm2.71-7.6a2.64 2.64 0 0 1-.33.74 3.16 3.16 0 0 1-.48.55l-.54.48c-.21.18-.41.35-.58.52a2.54 2.54 0 0 0-.47.56A2.3 2.3 0 0 0 11 12a3.79 3.79 0 0 0-.11 1H9.08a8.9 8.9 0 0 1 .07-1.25 3.28 3.28 0 0 1 .25-.9 2.79 2.79 0 0 1 .41-.67 4 4 0 0 1 .58-.58c.17-.16.34-.3.51-.44a3 3 0 0 0 .43-.44 1.83 1.83 0 0 0 .3-.55 2 2 0 0 0 .11-.72 2.06 2.06 0 0 0-.17-.86 1.71 1.71 0 0 0-1-.9 1.7 1.7 0 0 0-.5-.1 1.77 1.77 0 0 0-1.53.68 3 3 0 0 0-.5 1.82H6.16a4.74 4.74 0 0 1 .28-1.68 3.56 3.56 0 0 1 .8-1.29 3.88 3.88 0 0 1 1.28-.83A4.59 4.59 0 0 1 10.18 4a4.44 4.44 0 0 1 1.44.23 3.51 3.51 0 0 1 1.15.65 3.08 3.08 0 0 1 .78 1.06 3.54 3.54 0 0 1 .29 1.45 3.39 3.39 0 0 1-.13 1.01z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-progressive.png
deleted file mode 100644 (file)
index 0f0fbd9..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-progressive.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr-progressive.svg
deleted file mode 100644 (file)
index 73fe34c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>help</title><path d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm1 16H9v-2h2zm2.71-7.6a2.64 2.64 0 0 1-.33.74 3.16 3.16 0 0 1-.48.55l-.54.48c-.21.18-.41.35-.58.52a2.54 2.54 0 0 0-.47.56A2.3 2.3 0 0 0 11 12a3.79 3.79 0 0 0-.11 1H9.08a8.9 8.9 0 0 1 .07-1.25 3.28 3.28 0 0 1 .25-.9 2.79 2.79 0 0 1 .41-.67 4 4 0 0 1 .58-.58c.17-.16.34-.3.51-.44a3 3 0 0 0 .43-.44 1.83 1.83 0 0 0 .3-.55 2 2 0 0 0 .11-.72 2.06 2.06 0 0 0-.17-.86 1.71 1.71 0 0 0-1-.9 1.7 1.7 0 0 0-.5-.1 1.77 1.77 0 0 0-1.53.68 3 3 0 0 0-.5 1.82H6.16a4.74 4.74 0 0 1 .28-1.68 3.56 3.56 0 0 1 .8-1.29 3.88 3.88 0 0 1 1.28-.83A4.59 4.59 0 0 1 10.18 4a4.44 4.44 0 0 1 1.44.23 3.51 3.51 0 0 1 1.15.65 3.08 3.08 0 0 1 .78 1.06 3.54 3.54 0 0 1 .29 1.45 3.39 3.39 0 0 1-.13 1.01z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr.png
deleted file mode 100644 (file)
index 9a71070..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-ltr.svg
deleted file mode 100644 (file)
index 807cb84..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm1 16H9v-2h2zm2.71-7.6a2.64 2.64 0 0 1-.33.74 3.16 3.16 0 0 1-.48.55l-.54.48c-.21.18-.41.35-.58.52a2.54 2.54 0 0 0-.47.56A2.3 2.3 0 0 0 11 12a3.79 3.79 0 0 0-.11 1H9.08a8.9 8.9 0 0 1 .07-1.25 3.28 3.28 0 0 1 .25-.9 2.79 2.79 0 0 1 .41-.67 4 4 0 0 1 .58-.58c.17-.16.34-.3.51-.44a3 3 0 0 0 .43-.44 1.83 1.83 0 0 0 .3-.55 2 2 0 0 0 .11-.72 2.06 2.06 0 0 0-.17-.86 1.71 1.71 0 0 0-1-.9 1.7 1.7 0 0 0-.5-.1 1.77 1.77 0 0 0-1.53.68 3 3 0 0 0-.5 1.82H6.16a4.74 4.74 0 0 1 .28-1.68 3.56 3.56 0 0 1 .8-1.29 3.88 3.88 0 0 1 1.28-.83A4.59 4.59 0 0 1 10.18 4a4.44 4.44 0 0 1 1.44.23 3.51 3.51 0 0 1 1.15.65 3.08 3.08 0 0 1 .78 1.06 3.54 3.54 0 0 1 .29 1.45 3.39 3.39 0 0 1-.13 1.01z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-invert.png
deleted file mode 100644 (file)
index 462122f..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-invert.svg
deleted file mode 100644 (file)
index 9f79d18..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path fill="#fff" d="M0 10A10 10 0 1 0 10 0 10 10 0 0 0 0 10zm9 4h2v2H9zM6.16 7.39a3.54 3.54 0 0 1 .29-1.45 3.08 3.08 0 0 1 .78-1.06 3.51 3.51 0 0 1 1.15-.65A4.44 4.44 0 0 1 9.82 4a4.59 4.59 0 0 1 1.66.29 3.88 3.88 0 0 1 1.28.83 3.56 3.56 0 0 1 .8 1.29 4.74 4.74 0 0 1 .28 1.68h-1.91a3 3 0 0 0-.5-1.82 1.77 1.77 0 0 0-1.53-.68 1.7 1.7 0 0 0-.5.1 1.71 1.71 0 0 0-1 .9 2.06 2.06 0 0 0-.17.86 2 2 0 0 0 .11.72 1.83 1.83 0 0 0 .3.55 3 3 0 0 0 .43.44c.17.14.34.28.51.44a4 4 0 0 1 .58.58 2.79 2.79 0 0 1 .41.67 3.28 3.28 0 0 1 .25.9 8.9 8.9 0 0 1 .1 1.25H9.11A3.79 3.79 0 0 0 9 12a2.3 2.3 0 0 0-.31-.73 2.54 2.54 0 0 0-.47-.56c-.17-.17-.37-.34-.58-.52l-.54-.5a3.16 3.16 0 0 1-.48-.55 2.64 2.64 0 0 1-.33-.74 3.39 3.39 0 0 1-.13-1.01z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-progressive.png
deleted file mode 100644 (file)
index e1dc9f7..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-progressive.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl-progressive.svg
deleted file mode 100644 (file)
index f71e0be..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path fill="#36c" d="M0 10A10 10 0 1 0 10 0 10 10 0 0 0 0 10zm9 4h2v2H9zM6.16 7.39a3.54 3.54 0 0 1 .29-1.45 3.08 3.08 0 0 1 .78-1.06 3.51 3.51 0 0 1 1.15-.65A4.44 4.44 0 0 1 9.82 4a4.59 4.59 0 0 1 1.66.29 3.88 3.88 0 0 1 1.28.83 3.56 3.56 0 0 1 .8 1.29 4.74 4.74 0 0 1 .28 1.68h-1.91a3 3 0 0 0-.5-1.82 1.77 1.77 0 0 0-1.53-.68 1.7 1.7 0 0 0-.5.1 1.71 1.71 0 0 0-1 .9 2.06 2.06 0 0 0-.17.86 2 2 0 0 0 .11.72 1.83 1.83 0 0 0 .3.55 3 3 0 0 0 .43.44c.17.14.34.28.51.44a4 4 0 0 1 .58.58 2.79 2.79 0 0 1 .41.67 3.28 3.28 0 0 1 .25.9 8.9 8.9 0 0 1 .1 1.25H9.11A3.79 3.79 0 0 0 9 12a2.3 2.3 0 0 0-.31-.73 2.54 2.54 0 0 0-.47-.56c-.17-.17-.37-.34-.58-.52l-.54-.5a3.16 3.16 0 0 1-.48-.55 2.64 2.64 0 0 1-.33-.74 3.39 3.39 0 0 1-.13-1.01z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl.png b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl.png
deleted file mode 100644 (file)
index 65ec6d6..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/helpOutlined-rtl.svg
deleted file mode 100644 (file)
index 7e400cb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>help</title><path d="M0 10A10 10 0 1 0 10 0 10 10 0 0 0 0 10zm9 4h2v2H9zM6.16 7.39a3.54 3.54 0 0 1 .29-1.45 3.08 3.08 0 0 1 .78-1.06 3.51 3.51 0 0 1 1.15-.65A4.44 4.44 0 0 1 9.82 4a4.59 4.59 0 0 1 1.66.29 3.88 3.88 0 0 1 1.28.83 3.56 3.56 0 0 1 .8 1.29 4.74 4.74 0 0 1 .28 1.68h-1.91a3 3 0 0 0-.5-1.82 1.77 1.77 0 0 0-1.53-.68 1.7 1.7 0 0 0-.5.1 1.71 1.71 0 0 0-1 .9 2.06 2.06 0 0 0-.17.86 2 2 0 0 0 .11.72 1.83 1.83 0 0 0 .3.55 3 3 0 0 0 .43.44c.17.14.34.28.51.44a4 4 0 0 1 .58.58 2.79 2.79 0 0 1 .41.67 3.28 3.28 0 0 1 .25.9 8.9 8.9 0 0 1 .1 1.25H9.11A3.79 3.79 0 0 0 9 12a2.3 2.3 0 0 0-.31-.73 2.54 2.54 0 0 0-.47-.56c-.17-.17-.37-.34-.58-.52l-.54-.5a3.16 3.16 0 0 1-.48-.55 2.64 2.64 0 0 1-.33-.74 3.39 3.39 0 0 1-.13-1.01z"/></svg>
\ No newline at end of file
index 93b00ea..cba2ad1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/hieroglyph-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/hieroglyph-invert.png differ
index 8762716..bee8758 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/hieroglyph.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/hieroglyph.png differ
index 239d187..da9e57c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/highlight-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/highlight-invert.png differ
index eade031..874d401 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>highlight</title><path fill="#fff" d="M18.73 5.86l-3.59-3.59a1 1 0 0 0-1.41 0l-10 10a1 1 0 0 0 0 1.41L4 14l-3 4h5l1-1 .29.29a1 1 0 0 0 1.41 0l10-10a1 1 0 0 0 .03-1.43zM7 15l-2-2 9-9 2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>highlight</title><path fill="#fff" d="M15.14 2.27a1 1 0 0 0-1.41 0l-10 10a1 1 0 0 0 0 1.41L4 14l-3 4h5l1-1 .29.29a1 1 0 0 0 1.41 0l10-10a1 1 0 0 0 .03-1.43zM7 15l-2-2 9-9 2 2z"/></svg>
\ No newline at end of file
index 57f0199..94d6bcc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>highlight</title><path fill="#36c" d="M18.73 5.86l-3.59-3.59a1 1 0 0 0-1.41 0l-10 10a1 1 0 0 0 0 1.41L4 14l-3 4h5l1-1 .29.29a1 1 0 0 0 1.41 0l10-10a1 1 0 0 0 .03-1.43zM7 15l-2-2 9-9 2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>highlight</title><path fill="#36c" d="M15.14 2.27a1 1 0 0 0-1.41 0l-10 10a1 1 0 0 0 0 1.41L4 14l-3 4h5l1-1 .29.29a1 1 0 0 0 1.41 0l10-10a1 1 0 0 0 .03-1.43zM7 15l-2-2 9-9 2 2z"/></svg>
\ No newline at end of file
index 92ba183..fc50efe 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/highlight.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/highlight.png differ
index 17774d2..331785d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>highlight</title><path d="M18.73 5.86l-3.59-3.59a1 1 0 0 0-1.41 0l-10 10a1 1 0 0 0 0 1.41L4 14l-3 4h5l1-1 .29.29a1 1 0 0 0 1.41 0l10-10a1 1 0 0 0 .03-1.43zM7 15l-2-2 9-9 2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>highlight</title><path d="M15.14 2.27a1 1 0 0 0-1.41 0l-10 10a1 1 0 0 0 0 1.41L4 14l-3 4h5l1-1 .29.29a1 1 0 0 0 1.41 0l10-10a1 1 0 0 0 .03-1.43zM7 15l-2-2 9-9 2 2z"/></svg>
\ No newline at end of file
index d9c79b5..310f8ab 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/history-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/history-invert.png differ
index 7728c43..b8d4522 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>history</title><g fill="#fff"><path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6H9z"/><path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>history</title><g fill="#fff"><path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6z"/><path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/></g></svg>
\ No newline at end of file
index 40d4df1..a1ef1d2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/history-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/history-progressive.png differ
index 576e55f..9bbe3bd 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>history</title><g fill="#36c"><path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6H9z"/><path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>history</title><g fill="#36c"><path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6z"/><path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/></g></svg>
\ No newline at end of file
index 2a345f6..7822882 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/history.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/history.png differ
index 48a8b29..c2844cf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>history</title><path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6H9z"/><path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>history</title><path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6z"/><path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/></svg>
\ No newline at end of file
index 268561f..ac4a2a5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/image-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/image-invert.png differ
index edc3401..1d3fc52 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image</title><path fill="#fff" d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM1.83 15l4.09-5.25 2.92 3.51L12.92 8l5.25 7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image</title><path fill="#fff" d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm-.17 13l4.09-5.25 2.92 3.51L12.92 8l5.25 7z"/></svg>
\ No newline at end of file
index 40d8f4e..b004eff 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image</title><path fill="#36c" d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM1.83 15l4.09-5.25 2.92 3.51L12.92 8l5.25 7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image</title><path fill="#36c" d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm-.17 13l4.09-5.25 2.92 3.51L12.92 8l5.25 7z"/></svg>
\ No newline at end of file
index 76ad2db..16ca74d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/image.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/image.png differ
index 32f2476..a33fab2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image</title><path d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM1.83 15l4.09-5.25 2.92 3.51L12.92 8l5.25 7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image</title><path d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm-.17 13l4.09-5.25 2.92 3.51L12.92 8l5.25 7z"/></svg>
\ No newline at end of file
index d646757..0c0a431 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr-invert.png differ
index a9d0f21..7467e6c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><g fill="#fff"><path d="M16 17H2l3.5-4.5 2.5 3 3.5-4.5.5.67V8H8V6H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-5.75z"/><path d="M16 4V0h-2v4h-4v2h4v4h2V6h4V4h-4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><g fill="#fff"><path d="M16 17H2l3.5-4.5 2.5 3 3.5-4.5.5.67V8H8V6H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-5.75z"/><path d="M16 4V0h-2v4h-4v2h4v4h2V6h4V4z"/></g></svg>
\ No newline at end of file
index 06015ed..9ecbb76 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><g fill="#36c"><path d="M16 17H2l3.5-4.5 2.5 3 3.5-4.5.5.67V8H8V6H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-5.75z"/><path d="M16 4V0h-2v4h-4v2h4v4h2V6h4V4h-4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><g fill="#36c"><path d="M16 17H2l3.5-4.5 2.5 3 3.5-4.5.5.67V8H8V6H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-5.75z"/><path d="M16 4V0h-2v4h-4v2h4v4h2V6h4V4z"/></g></svg>
\ No newline at end of file
index 295a70d..0ab2358 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-ltr.png differ
index 7a3bf7a..6f764dc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path d="M16 17H2l3.5-4.5 2.5 3 3.5-4.5.5.67V8H8V6H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-5.75z"/><path d="M16 4V0h-2v4h-4v2h4v4h2V6h4V4h-4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path d="M16 17H2l3.5-4.5 2.5 3 3.5-4.5.5.67V8H8V6H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-5.75z"/><path d="M16 4V0h-2v4h-4v2h4v4h2V6h4V4z"/></svg>
\ No newline at end of file
index a8e341a..074ea9b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl-invert.png differ
index 4ade668..2dda10d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path fill="#fff" d="M18 6h-6v2H8v4H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM3.83 17l3.55-4.5 2.52 3 3.55-4.5L18 17zM4 10h2V6h4V4H6V0H4v4H0v2h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path fill="#fff" d="M16v2H8v4H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM3.83 17l3.55-4.5 2.52 3 3.55-4.5L18 17zM4 10h2V6h4V4H6V0H4v4H0v2h4z"/></svg>
\ No newline at end of file
index a9fd6a8..d83a180 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path fill="#36c" d="M18 6h-6v2H8v4H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM3.83 17l3.55-4.5 2.52 3 3.55-4.5L18 17zM4 10h2V6h4V4H6V0H4v4H0v2h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path fill="#36c" d="M16v2H8v4H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM3.83 17l3.55-4.5 2.52 3 3.55-4.5L18 17zM4 10h2V6h4V4H6V0H4v4H0v2h4z"/></svg>
\ No newline at end of file
index 8c47e19..d066719 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageAdd-rtl.png differ
index a7ded5c..ee49dff 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path d="M18 6h-6v2H8v4H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM3.83 17l3.55-4.5 2.52 3 3.55-4.5L18 17zM4 10h2V6h4V4H6V0H4v4H0v2h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add image</title><path d="M16v2H8v4H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM3.83 17l3.55-4.5 2.52 3 3.55-4.5L18 17zM4 10h2V6h4V4H6V0H4v4H0v2h4z"/></svg>
\ No newline at end of file
index 6675454..e4a109e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken-invert.png differ
index 1a8b459..e145fcc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>broken image</title><g fill="#fff"><path d="M16.67 9.47L20 12.13v4.09A2 2 0 0 1 17.78 18H2.22A2 2 0 0 1 0 16.22v-5.86L3.33 13l4.45-3.53L12.22 13z"/><path d="M20 3.78v5.86L16.67 7l-4.44 3.56L7.78 7l-4.45 3.53L0 7.87V3.78A2 2 0 0 1 2.22 2h15.56A2 2 0 0 1 20 3.78z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>broken image</title><g fill="#fff"><path d="M16.67 9.47L20 12.13v4.09A2 2 0 0 1 17.78 18H2.22A2 2 0 0 1 0 16.22v-5.86L3.33 13l4.45-3.53L12.22 13z"/><path d="M20 9.64L16.67 7l-4.44 3.56L7.78 7l-4.45 3.53L0 7.87V3.78A2 2 0 0 1 2.22 2h15.56A2 2 0 0 1 20 3.78z"/></g></svg>
\ No newline at end of file
index d67fee5..2590e29 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>broken image</title><g fill="#36c"><path d="M16.67 9.47L20 12.13v4.09A2 2 0 0 1 17.78 18H2.22A2 2 0 0 1 0 16.22v-5.86L3.33 13l4.45-3.53L12.22 13z"/><path d="M20 3.78v5.86L16.67 7l-4.44 3.56L7.78 7l-4.45 3.53L0 7.87V3.78A2 2 0 0 1 2.22 2h15.56A2 2 0 0 1 20 3.78z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>broken image</title><g fill="#36c"><path d="M16.67 9.47L20 12.13v4.09A2 2 0 0 1 17.78 18H2.22A2 2 0 0 1 0 16.22v-5.86L3.33 13l4.45-3.53L12.22 13z"/><path d="M20 9.64L16.67 7l-4.44 3.56L7.78 7l-4.45 3.53L0 7.87V3.78A2 2 0 0 1 2.22 2h15.56A2 2 0 0 1 20 3.78z"/></g></svg>
\ No newline at end of file
index 002707f..74b5fb2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageBroken.png differ
index bae885b..83ea4bf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>broken image</title><path d="M16.67 9.47L20 12.13v4.09A2 2 0 0 1 17.78 18H2.22A2 2 0 0 1 0 16.22v-5.86L3.33 13l4.45-3.53L12.22 13z"/><path d="M20 3.78v5.86L16.67 7l-4.44 3.56L7.78 7l-4.45 3.53L0 7.87V3.78A2 2 0 0 1 2.22 2h15.56A2 2 0 0 1 20 3.78z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>broken image</title><path d="M16.67 9.47L20 12.13v4.09A2 2 0 0 1 17.78 18H2.22A2 2 0 0 1 0 16.22v-5.86L3.33 13l4.45-3.53L12.22 13z"/><path d="M20 9.64L16.67 7l-4.44 3.56L7.78 7l-4.45 3.53L0 7.87V3.78A2 2 0 0 1 2.22 2h15.56A2 2 0 0 1 20 3.78z"/></svg>
\ No newline at end of file
index 801ce96..589e933 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery-invert.png differ
index 9e737c0..5d4b87b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image gallery</title><path fill="#fff" d="M17 5H3a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zM3 16l3.5-4.5 2.5 3 3.5-4.5 4.5 6zM4 2h12a2 2 0 0 1 2 2H2a2 2 0 0 1 2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image gallery</title><path fill="#fff" d="M3 5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zm0 11l3.5-4.5 2.5 3 3.5-4.5 4.5 6zM16 2a2 2 0 0 1 2 2H2a2 2 0 0 1 2-2z"/></svg>
\ No newline at end of file
index bd6684a..f35a09e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image gallery</title><path fill="#36c" d="M17 5H3a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zM3 16l3.5-4.5 2.5 3 3.5-4.5 4.5 6zM4 2h12a2 2 0 0 1 2 2H2a2 2 0 0 1 2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image gallery</title><path fill="#36c" d="M3 5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zm0 11l3.5-4.5 2.5 3 3.5-4.5 4.5 6zM16 2a2 2 0 0 1 2 2H2a2 2 0 0 1 2-2z"/></svg>
\ No newline at end of file
index 790cd29..d5ee1ac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageGallery.png differ
index 29f9faa..8116eda 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image gallery</title><path d="M17 5H3a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zM3 16l3.5-4.5 2.5 3 3.5-4.5 4.5 6zM4 2h12a2 2 0 0 1 2 2H2a2 2 0 0 1 2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image gallery</title><path d="M3 5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zm0 11l3.5-4.5 2.5 3 3.5-4.5 4.5 6zM16 2a2 2 0 0 1 2 2H2a2 2 0 0 1 2-2z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-invert.png
new file mode 100644 (file)
index 0000000..db04815
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-invert.svg
new file mode 100644 (file)
index 0000000..9698785
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout basic</title><g fill="#fff"><path d="M1 3v14h18V3zm17 13H2V4h16z"/><path d="M8.58 14h.81l3.11-4 3 4H17l-4.5-6L9 12.51 6.5 9.5 3 14h1.56l1.94-2.5z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-progressive.png
new file mode 100644 (file)
index 0000000..0df2640
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic-progressive.svg
new file mode 100644 (file)
index 0000000..97ec295
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout basic</title><g fill="#36c"><path d="M1 3v14h18V3zm17 13H2V4h16z"/><path d="M8.58 14h.81l3.11-4 3 4H17l-4.5-6L9 12.51 6.5 9.5 3 14h1.56l1.94-2.5z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic.png
new file mode 100644 (file)
index 0000000..1a4f57c
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutBasic.svg
new file mode 100644 (file)
index 0000000..3f85f6b
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout basic</title><path d="M1 3v14h18V3zm17 13H2V4h16z"/><path d="M8.58 14h.81l3.11-4 3 4H17l-4.5-6L9 12.51 6.5 9.5 3 14h1.56l1.94-2.5z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-invert.png
new file mode 100644 (file)
index 0000000..4520efd
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-invert.svg
new file mode 100644 (file)
index 0000000..0590320
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout frame</title><g fill="#fff"><path d="M3 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 15a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1z"/><path d="M17 4H3v12h14zM5 13l2.5-3 2 2L12 9l3 4z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-progressive.png
new file mode 100644 (file)
index 0000000..faae680
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame-progressive.svg
new file mode 100644 (file)
index 0000000..93ff30c
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout frame</title><g fill="#36c"><path d="M3 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 15a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1z"/><path d="M17 4H3v12h14zM5 13l2.5-3 2 2L12 9l3 4z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame.png
new file mode 100644 (file)
index 0000000..c54993b
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrame.svg
new file mode 100644 (file)
index 0000000..47f7d95
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout frame</title><path d="M3 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 15a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1z"/><path d="M17 4H3v12h14zM5 13l2.5-3 2 2L12 9l3 4z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-invert.png
new file mode 100644 (file)
index 0000000..a5ce258
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-invert.svg
new file mode 100644 (file)
index 0000000..32179fe
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout frameless</title><g fill="#fff"><path d="M19 3H1v14h18zM3 14l3.5-4.5 2.5 3L12.5 8l4.5 6z"/><path d="M19 5H1V3h18zm0 12H1v-2h18z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-progressive.png
new file mode 100644 (file)
index 0000000..4703b2b
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless-progressive.svg
new file mode 100644 (file)
index 0000000..239b85a
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout frameless</title><g fill="#36c"><path d="M19 3H1v14h18zM3 14l3.5-4.5 2.5 3L12.5 8l4.5 6z"/><path d="M19 5H1V3h18zm0 12H1v-2h18z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless.png
new file mode 100644 (file)
index 0000000..ea21d74
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutFrameless.svg
new file mode 100644 (file)
index 0000000..1753774
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout frameless</title><path d="M19 3H1v14h18zM3 14l3.5-4.5 2.5 3L12.5 8l4.5 6z"/><path d="M19 5H1V3h18zm0 12H1v-2h18z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-invert.png
new file mode 100644 (file)
index 0000000..afb4d02
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-invert.svg
new file mode 100644 (file)
index 0000000..328f497
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout thumbnail</title><g fill="#fff"><path d="M3 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 15a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1z"/><path d="M17 4H3v10h14zM5 12l2.5-3 2 2L12 8l3 4zm-1 3h12v1H4z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-progressive.png
new file mode 100644 (file)
index 0000000..53cea83
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail-progressive.svg
new file mode 100644 (file)
index 0000000..4dc5e29
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout thumbnail</title><g fill="#36c"><path d="M3 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 15a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1z"/><path d="M17 4H3v10h14zM5 12l2.5-3 2 2L12 8l3 4zm-1 3h12v1H4z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail.png b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail.png
new file mode 100644 (file)
index 0000000..5e414f9
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLayoutThumbnail.svg
new file mode 100644 (file)
index 0000000..6902b1a
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image layout thumbnail</title><path d="M3 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 15a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1z"/><path d="M17 4H3v10h14zM5 12l2.5-3 2 2L12 8l3 4zm-1 3h12v1H4z"/></svg>
\ No newline at end of file
index fbc9d82..27b9164 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-ltr-invert.png differ
index 838bd9c..f044cfd 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-ltr.png differ
index 3206847..2524b27 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl-invert.png differ
index 96b7e3e..23aa9fb 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image locked</title><path fill="#fff" d="M8 9V5a1 1 0 0 0-1-1h-.5V2.5A2.45 2.45 0 0 0 4 0a2.45 2.45 0 0 0-2.5 2.5V4H1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1zM4 8a1 1 0 1 1 1-1 1 1 0 0 1-1 1zm1.5-4h-3V2.75C2.5 2 2.5 1 4 1s1.5 1 1.5 1.75zM18 6h-8v4a2 2 0 0 1-2 2H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM4 17l3.54-4.5 2.53 3 3.54-4.5 4.56 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image locked</title><path fill="#fff" d="M8 5a1 1 0 0 0-1-1h-.5V2.5A2.45 2.45 0 0 0 4 0a2.45 2.45 0 0 0-2.5 2.5V4H1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1zM4 8a1 1 0 1 1 1-1 1 1 0 0 1-1 1zm1.5-4h-3V2.75C2.5 2 2.5 1 4 1s1.5 1 1.5 1.75zM10 6v4a2 2 0 0 1-2 2H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM4 17l3.54-4.5 2.53 3 3.54-4.5 4.56 6z"/></svg>
\ No newline at end of file
index 057bfc7..92a7fff 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image locked</title><path fill="#36c" d="M8 9V5a1 1 0 0 0-1-1h-.5V2.5A2.45 2.45 0 0 0 4 0a2.45 2.45 0 0 0-2.5 2.5V4H1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1zM4 8a1 1 0 1 1 1-1 1 1 0 0 1-1 1zm1.5-4h-3V2.75C2.5 2 2.5 1 4 1s1.5 1 1.5 1.75zM18 6h-8v4a2 2 0 0 1-2 2H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM4 17l3.54-4.5 2.53 3 3.54-4.5 4.56 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image locked</title><path fill="#36c" d="M8 5a1 1 0 0 0-1-1h-.5V2.5A2.45 2.45 0 0 0 4 0a2.45 2.45 0 0 0-2.5 2.5V4H1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1zM4 8a1 1 0 1 1 1-1 1 1 0 0 1-1 1zm1.5-4h-3V2.75C2.5 2 2.5 1 4 1s1.5 1 1.5 1.75zM10 6v4a2 2 0 0 1-2 2H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM4 17l3.54-4.5 2.53 3 3.54-4.5 4.56 6z"/></svg>
\ No newline at end of file
index 2c584b8..ebb1944 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/imageLock-rtl.png differ
index 7898ea4..8961ca2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image locked</title><path d="M8 9V5a1 1 0 0 0-1-1h-.5V2.5A2.45 2.45 0 0 0 4 0a2.45 2.45 0 0 0-2.5 2.5V4H1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1zM4 8a1 1 0 1 1 1-1 1 1 0 0 1-1 1zm1.5-4h-3V2.75C2.5 2 2.5 1 4 1s1.5 1 1.5 1.75zM18 6h-8v4a2 2 0 0 1-2 2H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM4 17l3.54-4.5 2.53 3 3.54-4.5 4.56 6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>image locked</title><path d="M8 5a1 1 0 0 0-1-1h-.5V2.5A2.45 2.45 0 0 0 4 0a2.45 2.45 0 0 0-2.5 2.5V4H1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1zM4 8a1 1 0 1 1 1-1 1 1 0 0 1-1 1zm1.5-4h-3V2.75C2.5 2 2.5 1 4 1s1.5 1 1.5 1.75zM10 6v4a2 2 0 0 1-2 2H2v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2zM4 17l3.54-4.5 2.53 3 3.54-4.5 4.56 6z"/></svg>
\ No newline at end of file
index 467259e..ebcc511 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr-invert.png differ
index f8f15ca..3fc928e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>indent</title><path fill="#fff" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm5 8l-5 4V6l5 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>indent</title><path fill="#fff" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm5 8l-5 4V6z"/></svg>
\ No newline at end of file
index 4cd14a2..da5d250 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>indent</title><path fill="#36c" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm5 8l-5 4V6l5 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>indent</title><path fill="#36c" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm5 8l-5 4V6z"/></svg>
\ No newline at end of file
index 4812920..bc2be0b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/indent-ltr.png differ
index 18ab051..52447bc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>indent</title><path d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm5 8l-5 4V6l5 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>indent</title><path d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm5 8l-5 4V6z"/></svg>
\ No newline at end of file
index 03b4174..36ab637 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/indent-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/indent-rtl-invert.png differ
index b991583..28a14eb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/indent-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/indent-rtl.png differ
index 7510cc9..42fef5e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/info-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/info-invert.png differ
index fd15ab1..8578c66 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/info-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/info-progressive.png differ
index c3da6db..5c68b2d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/info.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/info.png differ
index 9a71fef..05342d3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-a-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-a-invert.png differ
index 75c68b1..95d1ee5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-a.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-a.png differ
index d94da3a..79c2588 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-keheh-jeem-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-keheh-jeem-invert.png differ
index f011f53..debb4fe 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-keheh-jeem.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-keheh-jeem.png differ
index 38034de..f2a4196 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-meem-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-meem-invert.png differ
index 05750c1..5a23e91 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-meem.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-meem.png differ
index 11a52b6..346e128 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-teh-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-teh-invert.png differ
index 40fc57a..056f378 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-teh.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-arab-teh.png differ
index af77130..9961b7a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-armn-sha-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-armn-sha-invert.png differ
index bf67c04..3461607 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-armn-sha.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-armn-sha.png differ
index e1431d9..6a22cf3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-c-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-c-invert.png differ
index dff2c34..0cbd7c0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-c.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-c.png differ
index 2920406..283a206 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-d-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-d-invert.png differ
index 854d451..eb40f0d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-d.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-d.png differ
index 60b9f31..19cd419 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-e-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-e-invert.png differ
index ad22cfb..0c33951 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>italic</title><path d="M3.583 17L6.47 3h9.947l-.33 1.595H7.983l-.875 4.238h7.105l-.327 1.595H6.78l-1.027 4.985h8.68L14.104 17H3.584"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>italic</title><path d="M3.583 17L6.47 3h9.947l-.33 1.595H7.983l-.875 4.238h7.105l-.327 1.595H6.78l-1.027 4.985h8.68L14.104 17z"/></g></svg>
\ No newline at end of file
index cf35ec2..be8f8b4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>italic</title><path d="M3.583 17L6.47 3h9.947l-.33 1.595H7.983l-.875 4.238h7.105l-.327 1.595H6.78l-1.027 4.985h8.68L14.104 17H3.584"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>italic</title><path d="M3.583 17L6.47 3h9.947l-.33 1.595H7.983l-.875 4.238h7.105l-.327 1.595H6.78l-1.027 4.985h8.68L14.104 17z"/></g></svg>
\ No newline at end of file
index bb9cbb0..3e59cb2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-e.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-e.png differ
index 9946b38..e7dd4c4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>italic</title><path d="M3.583 17L6.47 3h9.947l-.33 1.595H7.983l-.875 4.238h7.105l-.327 1.595H6.78l-1.027 4.985h8.68L14.104 17H3.584"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>italic</title><path d="M3.583 17L6.47 3h9.947l-.33 1.595H7.983l-.875 4.238h7.105l-.327 1.595H6.78l-1.027 4.985h8.68L14.104 17z"/></svg>
\ No newline at end of file
index 8140548..9d5febb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-geor-kan-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-geor-kan-invert.png differ
index ff176ca..b292b31 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-geor-kan.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-geor-kan.png differ
index 5897d5e..80478d5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-i-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-i-invert.png differ
index 3762341..1b7e5b7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-i.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-i.png differ
index c05bbe1..8a9383e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-k-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-k-invert.png differ
index 9992fb6..851b601 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-k.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-k.png differ
index d1df4df..01c78e7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-s-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-s-invert.png differ
index 6c7390c..9f84042 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/italic-s.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/italic-s.png differ
index 93263bc..49eb3e1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr-invert.png differ
index 8a91ec2..1af5437 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#fff" d="M2 1.5v17A1.5 1.5 0 0 0 3.5 20H5V0H3.5A1.5 1.5 0 0 0 2 1.5zM16 0H6v20h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm-3 8H8V7h5zm3-2H8V5h8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#fff" d="M2 18.5A1.5 1.5 0 0 0 3.5 20H5V0H3.5A1.5 1.5 0 0 0 2 1.5zM6 0v20h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm7 8H8V7h5zm3-2H8V5h8z"/></svg>
\ No newline at end of file
index 8850d02..aee51bc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#36c" d="M2 1.5v17A1.5 1.5 0 0 0 3.5 20H5V0H3.5A1.5 1.5 0 0 0 2 1.5zM16 0H6v20h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm-3 8H8V7h5zm3-2H8V5h8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#36c" d="M2 18.5A1.5 1.5 0 0 0 3.5 20H5V0H3.5A1.5 1.5 0 0 0 2 1.5zM6 0v20h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm7 8H8V7h5zm3-2H8V5h8z"/></svg>
\ No newline at end of file
index 6c8d905..5c43337 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/journal-ltr.png differ
index 70e7c36..bba4760 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path d="M2 1.5v17A1.5 1.5 0 0 0 3.5 20H5V0H3.5A1.5 1.5 0 0 0 2 1.5zM16 0H6v20h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm-3 8H8V7h5zm3-2H8V5h8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path d="M2 18.5A1.5 1.5 0 0 0 3.5 20H5V0H3.5A1.5 1.5 0 0 0 2 1.5zM6 0v20h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm7 8H8V7h5zm3-2H8V5h8z"/></svg>
\ No newline at end of file
index 0e79818..522b8fd 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl-invert.png differ
index c845f3e..473739d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#fff" d="M16.5 0H15v20h1.5c.8 0 1.5-.7 1.5-1.5v-17c0-.8-.7-1.5-1.5-1.5zM2 2v16c0 1.1.9 2 2 2h10V0H4C2.9 0 2 .9 2 2zm5 5h5v1H7V7zM4 5h8v1H4V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#fff" d="M15 0v20h1.5c.8 0 1.5-.7 1.5-1.5v-17c0-.8-.7-1.5-1.5-1.5zM2 18c0 1.1.9 2 2 2h10V0H4C2.9 0 2 .9 2 2zM4 5h8v1H4zm3 2h5v1H7z"/></svg>
\ No newline at end of file
index 076915c..d4b7e32 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#36c" d="M16.5 0H15v20h1.5c.8 0 1.5-.7 1.5-1.5v-17c0-.8-.7-1.5-1.5-1.5zM2 2v16c0 1.1.9 2 2 2h10V0H4C2.9 0 2 .9 2 2zm5 5h5v1H7V7zM4 5h8v1H4V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path fill="#36c" d="M15 0v20h1.5c.8 0 1.5-.7 1.5-1.5v-17c0-.8-.7-1.5-1.5-1.5zM2 18c0 1.1.9 2 2 2h10V0H4C2.9 0 2 .9 2 2zM4 5h8v1H4zm3 2h5v1H7z"/></svg>
\ No newline at end of file
index 5760e60..33eb670 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/journal-rtl.png differ
index e032c26..258df36 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path d="M16.5 0H15v20h1.5c.8 0 1.5-.7 1.5-1.5v-17c0-.8-.7-1.5-1.5-1.5zM2 2v16c0 1.1.9 2 2 2h10V0H4C2.9 0 2 .9 2 2zm5 5h5v1H7V7zM4 5h8v1H4V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>journal</title><path d="M15 0v20h1.5c.8 0 1.5-.7 1.5-1.5v-17c0-.8-.7-1.5-1.5-1.5zM2 18c0 1.1.9 2 2 2h10V0H4C2.9 0 2 .9 2 2zM4 5h8v1H4zm3 2h5v1H7z"/></svg>
\ No newline at end of file
index 1e9875d..57e2326 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/key-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/key-invert.png differ
index 8522187..f17e14d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/key.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/key.png differ
index ab3fa60..e783317 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/keyboard-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/keyboard-invert.png differ
index eb07935..3cc1b1b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>keyboard</title><path fill="#fff" d="M0 5v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2zm9 1h2v2H9zm0 3h2v2H9zM6 6h2v2H6zm0 3h2v2H6zm-1 5H3v-2h2zm0-3H3V9h2zm0-3H3V6h2zm9 6H6v-2h8zm0-3h-2V9h2zm0-3h-2V6h2zm3 6h-2v-2h2zm0-3h-2V9h2zm0-3h-2V6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>keyboard</title><path fill="#fff" d="M0 15a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2zm9-9h2v2H9zm0 3h2v2H9zM6 6h2v2H6zm0 3h2v2H6zm-1 5H3v-2h2zm0-3H3V9h2zm0-3H3V6h2zm9 6H6v-2h8zm0-3h-2V9h2zm0-3h-2V6h2zm3 6h-2v-2h2zm0-3h-2V9h2zm0-3h-2V6h2z"/></svg>
\ No newline at end of file
index 8a72746..14f7a37 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>keyboard</title><path fill="#36c" d="M0 5v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2zm9 1h2v2H9zm0 3h2v2H9zM6 6h2v2H6zm0 3h2v2H6zm-1 5H3v-2h2zm0-3H3V9h2zm0-3H3V6h2zm9 6H6v-2h8zm0-3h-2V9h2zm0-3h-2V6h2zm3 6h-2v-2h2zm0-3h-2V9h2zm0-3h-2V6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>keyboard</title><path fill="#36c" d="M0 15a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2zm9-9h2v2H9zm0 3h2v2H9zM6 6h2v2H6zm0 3h2v2H6zm-1 5H3v-2h2zm0-3H3V9h2zm0-3H3V6h2zm9 6H6v-2h8zm0-3h-2V9h2zm0-3h-2V6h2zm3 6h-2v-2h2zm0-3h-2V9h2zm0-3h-2V6h2z"/></svg>
\ No newline at end of file
index 82819fa..5c93ae8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/keyboard.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/keyboard.png differ
index fa60a80..f499141 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>keyboard</title><path d="M0 5v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2zm9 1h2v2H9zm0 3h2v2H9zM6 6h2v2H6zm0 3h2v2H6zm-1 5H3v-2h2zm0-3H3V9h2zm0-3H3V6h2zm9 6H6v-2h8zm0-3h-2V9h2zm0-3h-2V6h2zm3 6h-2v-2h2zm0-3h-2V9h2zm0-3h-2V6h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>keyboard</title><path d="M0 15a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2zm9-9h2v2H9zm0 3h2v2H9zM6 6h2v2H6zm0 3h2v2H6zm-1 5H3v-2h2zm0-3H3V9h2zm0-3H3V6h2zm9 6H6v-2h8zm0-3h-2V9h2zm0-3h-2V6h2zm3 6h-2v-2h2zm0-3h-2V9h2zm0-3h-2V6h2z"/></svg>
\ No newline at end of file
index 36566c1..b32b00e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/language-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/language-invert.png differ
index 4db871a..0b01507 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/language-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/language-progressive.png differ
index 9de3301..e61b0e7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/language.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/language.png differ
index 0f43324..b89462b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/largerText-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/largerText-invert.png differ
index 590a450..e22966b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/largerText.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/largerText.png differ
index 3033beb..f2dd0fe 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#fff"><path d="M8 12V1H1v18h18v-7H8z"/><path d="M11 1v8h8V1zm6 6h-4V3h4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#fff"><path d="M8 12V1H1v18h18v-7z"/><path d="M11 1v8h8V1zm6 6h-4V3h4z"/></g></svg>
\ No newline at end of file
index 0736564..7721244 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#36c"><path d="M8 12V1H1v18h18v-7H8z"/><path d="M11 1v8h8V1zm6 6h-4V3h4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#36c"><path d="M8 12V1H1v18h18v-7z"/><path d="M11 1v8h8V1zm6 6h-4V3h4z"/></g></svg>
\ No newline at end of file
index 268e5ef..a056a4a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/layout-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/layout-ltr.png differ
index 791076d..e32139e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><path d="M8 12V1H1v18h18v-7H8z"/><path d="M11 1v8h8V1zm6 6h-4V3h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><path d="M8 12V1H1v18h18v-7z"/><path d="M11 1v8h8V1zm6 6h-4V3h4z"/></svg>
\ No newline at end of file
index 2d0048b..fd61819 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#fff"><path d="M1 12v7h18V1h-7v11z"/><path d="M1 1v8h8V1H1zm2 2h4v4H3V3z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#fff"><path d="M1 12v7h18V1h-7v11z"/><path d="M1 1v8h8V1zm2 2h4v4H3z"/></g></svg>
\ No newline at end of file
index 82c1626..aa4de11 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#36c"><path d="M1 12v7h18V1h-7v11z"/><path d="M1 1v8h8V1H1zm2 2h4v4H3V3z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><g fill="#36c"><path d="M1 12v7h18V1h-7v11z"/><path d="M1 1v8h8V1zm2 2h4v4H3z"/></g></svg>
\ No newline at end of file
index ac3d519..7d61e1a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/layout-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/layout-rtl.png differ
index 133945c..07e51de 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><path d="M1 12v7h18V1h-7v11z"/><path d="M1 1v8h8V1H1zm2 2h4v4H3V3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>layout</title><path d="M1 12v7h18V1h-7v11z"/><path d="M1 1v8h8V1zm2 2h4v4H3z"/></svg>
\ No newline at end of file
index c976789..41c4926 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/lightbulb-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/lightbulb-invert.png differ
index cefcd16..59978be 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/lightbulb.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/lightbulb.png differ
index 39770cc..0a8107b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/link-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/link-invert.png differ
index bfd6677..dbe127d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/link-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/link-progressive.png differ
index bfc6936..28f0446 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/link.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/link.png differ
index b2c62a5..182aecc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr-invert.png differ
index 3dc2985..af616f9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#fff"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M19 1h-8l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#fff"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M11 1l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
index e9f1f30..fe8552d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#36c"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M19 1h-8l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#36c"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M11 1l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
index f51c501..b64e15c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-ltr.png differ
index c6648f4..5259462 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M19 1h-8l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M11 1l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></svg>
\ No newline at end of file
index 866c7e3..899dc14 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl-invert.png differ
index 7b56588..3777796 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#fff"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3v-5z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#fff"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
index c6d8fdf..3af3291 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#36c"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3v-5z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><g fill="#36c"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
index c5493d2..3b8d93c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/linkExternal-rtl.png differ
index cf2d5d2..7bf3b43 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3v-5z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>external link</title><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></svg>
\ No newline at end of file
index 1e247a7..0f3e8f3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/linkSecure-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/linkSecure-invert.png differ
index 8ade157..4aa7955 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/linkSecure.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/linkSecure.png differ
index a40b12e..8eafa13 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-ltr-invert.png differ
index 60dfe52..6ff7bfa 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-ltr.png differ
index ed1d3ee..8c30bd5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-rtl-invert.png differ
index cd6c52e..15fa504 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listBullet-rtl.png differ
index 7d12572..177d01e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr-invert.png differ
index 266b6e2..5540c3d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#fff" d="M7 15h12v2H7zm0-6h12v2H7zm0-6h12v2H7zM2 6h1V1H1v1h1v4zm-1 9h2v1H2v1h1v1H1v1h3v-5H1v1zm2.5-7H1v1h2v1H1.5a.5.5 0 0 0-.5.5V13h3v-1H2v-1h1.5a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#fff" d="M7 15h12v2H7zm0-6h12v2H7zm0-6h12v2H7zM2 6h1V1H1v1h1zm1 9v1H2v1h1v1H1v1h3v-5H1v1zM1 8v1h2v1H1.5a.5.5 0 0 0-.5.5V13h3v-1H2v-1h1.5a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
index d5edc7d..89bfe22 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#36c" d="M7 15h12v2H7zm0-6h12v2H7zm0-6h12v2H7zM2 6h1V1H1v1h1v4zm-1 9h2v1H2v1h1v1H1v1h3v-5H1v1zm2.5-7H1v1h2v1H1.5a.5.5 0 0 0-.5.5V13h3v-1H2v-1h1.5a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#36c" d="M7 15h12v2H7zm0-6h12v2H7zm0-6h12v2H7zM2 6h1V1H1v1h1zm1 9v1H2v1h1v1H1v1h3v-5H1v1zM1 8v1h2v1H1.5a.5.5 0 0 0-.5.5V13h3v-1H2v-1h1.5a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
index ba72137..24b37c6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-ltr.png differ
index 44c67d2..63c5ad2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path d="M7 15h12v2H7zm0-6h12v2H7zm0-6h12v2H7zM2 6h1V1H1v1h1v4zm-1 9h2v1H2v1h1v1H1v1h3v-5H1v1zm2.5-7H1v1h2v1H1.5a.5.5 0 0 0-.5.5V13h3v-1H2v-1h1.5a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path d="M7 15h12v2H7zm0-6h12v2H7zm0-6h12v2H7zM2 6h1V1H1v1h1zm1 9v1H2v1h1v1H1v1h3v-5H1v1zM1 8v1h2v1H1.5a.5.5 0 0 0-.5.5V13h3v-1H2v-1h1.5a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
index 4e9e7fb..a889865 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl-invert.png differ
index 8dc921f..9a2a040 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#fff" d="M2 15h11v2H2zm0-6h11v2H2zm0-6h11v2H2zm15-2h-1v1h1v4h1V1zm-2 12v1h2v1h-1v1h1v1h-2v1h3v-5zm2.5-6H15v1h2v1h-1.5c-.3 0-.5.2-.5.5V12h3v-1h-2v-1h1.5c.3 0 .5-.2.5-.5v-2c0-.3-.2-.5-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#fff" d="M2 15h11v2H2zm0-6h11v2H2zm0-6h11v2H2zm15-2h-1v1h1v4h1V1zm-2 12v1h2v1h-1v1h1v1h-2v1h3v-5zm0-6v1h2v1h-1.5c-.3 0-.5.2-.5.5V12h3v-1h-2v-1h1.5c.3 0 .5-.2.5-.5v-2c0-.3-.2-.5-.5-.5z"/></svg>
\ No newline at end of file
index 15c6e87..bdb0c37 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#36c" d="M2 15h11v2H2zm0-6h11v2H2zm0-6h11v2H2zm15-2h-1v1h1v4h1V1zm-2 12v1h2v1h-1v1h1v1h-2v1h3v-5zm2.5-6H15v1h2v1h-1.5c-.3 0-.5.2-.5.5V12h3v-1h-2v-1h1.5c.3 0 .5-.2.5-.5v-2c0-.3-.2-.5-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path fill="#36c" d="M2 15h11v2H2zm0-6h11v2H2zm0-6h11v2H2zm15-2h-1v1h1v4h1V1zm-2 12v1h2v1h-1v1h1v1h-2v1h3v-5zm0-6v1h2v1h-1.5c-.3 0-.5.2-.5.5V12h3v-1h-2v-1h1.5c.3 0 .5-.2.5-.5v-2c0-.3-.2-.5-.5-.5z"/></svg>
\ No newline at end of file
index c668441..7bdab56 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/listNumbered-rtl.png differ
index 4d97d39..986e212 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path d="M2 15h11v2H2zm0-6h11v2H2zm0-6h11v2H2zm15-2h-1v1h1v4h1V1zm-2 12v1h2v1h-1v1h1v1h-2v1h3v-5zm2.5-6H15v1h2v1h-1.5c-.3 0-.5.2-.5.5V12h3v-1h-2v-1h1.5c.3 0 .5-.2.5-.5v-2c0-.3-.2-.5-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>numbered list</title><path d="M2 15h11v2H2zm0-6h11v2H2zm0-6h11v2H2zm15-2h-1v1h1v4h1V1zm-2 12v1h2v1h-1v1h1v1h-2v1h3v-5zm0-6v1h2v1h-1.5c-.3 0-.5.2-.5.5V12h3v-1h-2v-1h1.5c.3 0 .5-.2.5-.5v-2c0-.3-.2-.5-.5-.5z"/></svg>
\ No newline at end of file
index 1e247a7..0f3e8f3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/lock-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/lock-invert.png differ
index 8ade157..4aa7955 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/lock.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/lock.png differ
index d2288de..36522ad 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr-invert.png differ
index 976da4a..fdd9ad7 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#fff"><path d="M3 3h8V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8v-2H3z"/><path d="M19 10l-6-5v4H5v2h8v4l6-5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#fff"><path d="M3 3h8V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8v-2H3z"/><path d="M15v4H5v2h8v4l6-5z"/></g></svg>
\ No newline at end of file
index 8500617..c630231 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#36c"><path d="M3 3h8V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8v-2H3z"/><path d="M19 10l-6-5v4H5v2h8v4l6-5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#36c"><path d="M3 3h8V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8v-2H3z"/><path d="M15v4H5v2h8v4l6-5z"/></g></svg>
\ No newline at end of file
index f275937..70c4391 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-ltr.png differ
index d071225..3a7a533 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><path d="M3 3h8V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8v-2H3z"/><path d="M19 10l-6-5v4H5v2h8v4l6-5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><path d="M3 3h8V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8v-2H3z"/><path d="M15v4H5v2h8v4l6-5z"/></svg>
\ No newline at end of file
index 1a7e26e..ae8bc7f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl-invert.png differ
index bca7d74..a665569 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#fff"><path d="M17 17H9v2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2H9v2h8v14z"/><path d="M7 15v-4h8V9H7V5l-6 5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#fff"><path d="M17 17H9v2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2H9v2h8z"/><path d="M7 15v-4h8V9H7V5l-6 5z"/></g></svg>
\ No newline at end of file
index a8ac02f..80bf1dd 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#36c"><path d="M17 17H9v2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2H9v2h8v14z"/><path d="M7 15v-4h8V9H7V5l-6 5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><g fill="#36c"><path d="M17 17H9v2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2H9v2h8z"/><path d="M7 15v-4h8V9H7V5l-6 5z"/></g></svg>
\ No newline at end of file
index 6baca66..90df0b8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logOut-rtl.png differ
index cb11921..5261d66 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><path d="M17 17H9v2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2H9v2h8v14z"/><path d="M7 15v-4h8V9H7V5l-6 5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>log out</title><path d="M17 17H9v2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2H9v2h8z"/><path d="M7 15v-4h8V9H7V5l-6 5z"/></svg>
\ No newline at end of file
index 61a745e..2c3f389 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-CC-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-CC-invert.png differ
index 45ac76d..986851b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-CC.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-CC.png differ
index c89b0e6..767f879 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikidata-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikidata-invert.png differ
index c89b0e6..767f879 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikidata.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikidata.png differ
index ffabbf4..877abc4 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Commons-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Commons-invert.png differ
index 82a0211..860cc5e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Commons.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Commons.png differ
index 4932faa..c4e3b1f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Discovery-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Discovery-invert.png differ
index 70061aa..a668cfa 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Discovery.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-Discovery.png differ
index bbe3379..36b1fd8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia-invert.png differ
index 8fde89f..94b36a3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikimedia logo</title><g fill="#fff"><clipPath id="a"><path d="M0-33l471 471v363h82V438l471-471v1057H0"/></clipPath><g clip-path="url(#a)" transform="matrix(.021 0 0 .021 -.756 -.588)"><path d="M511 224a288 288 0 1 0 2 0"/><path fill="none" stroke="#000" stroke-width="116" d="M511 102a410 410 0 1 0 2 0"/></g><path d="M9.979 0a3.32 3.32 0 1 0 .042 0z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikimedia logo</title><g fill="#fff"><clipPath id="a"><path d="M0-33l471 471v363h82V438l471-471v1057H0"/></clipPath><g clip-path="url(#a)" transform="matrix(.021 0 0 .021 -.756 -.588)"><path d="M511 224a288 288 0 1 0 2 0"/><path fill="none" stroke="#000" stroke-width="116" d="M511 102a410 410 0 1 0 2 0"/></g><circle cx="10" cy="3.32" r="3.32"/></g></svg>
\ No newline at end of file
index 65dfccd..8ca248a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikimedia.png differ
index 01e0a75..c0fa0f1 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikimedia logo</title><clipPath id="a"><path d="M0-33l471 471v363h82V438l471-471v1057H0"/></clipPath><g clip-path="url(#a)" transform="matrix(.021 0 0 .021 -.756 -.588)"><path d="M511 224a288 288 0 1 0 2 0"/><path fill="none" stroke="#000" stroke-width="116" d="M511 102a410 410 0 1 0 2 0"/></g><path d="M9.979 0a3.32 3.32 0 1 0 .042 0z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikimedia logo</title><clipPath id="a"><path d="M0-33l471 471v363h82V438l471-471v1057H0"/></clipPath><g clip-path="url(#a)" transform="matrix(.021 0 0 .021 -.756 -.588)"><path d="M511 224a288 288 0 1 0 2 0"/><path fill="none" stroke="#000" stroke-width="116" d="M511 102a410 410 0 1 0 2 0"/></g><circle cx="10" cy="3.32" r="3.32"/></svg>
\ No newline at end of file
index 33d6696..9e45019 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikipedia-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikipedia-invert.png differ
index 3e70e2c..3883e1a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikipedia.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/logo-Wikipedia.png differ
index 41fab87..ce82422 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/map-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/map-ltr-invert.png differ
index dae2b89..7db0417 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/map-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/map-ltr.png differ
index e4bc311..a5a9d32 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/map-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/map-rtl-invert.png differ
index e621d20..f448e84 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/map-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/map-rtl.png differ
index b555bda..f8ad53d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapPin-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapPin-invert.png differ
index b42f935..142eb01 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapPin-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapPin-progressive.png differ
index 7cb142c..05ecfbe 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapPin.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapPin.png differ
index 9dfc373..0311484 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapPinAdd-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapPinAdd-invert.png differ
index 72312b8..98ae9e9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapPinAdd.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapPinAdd.png differ
index 4238a56..bc90fbc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-invert.png differ
index b4317eb..6123f57 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>map trail</title><g fill="#fff"><path d="M20 6l-1-1-1.5 1.5L16 5l-1 1 1.5 1.5L15 9l1 1 1.5-1.5L19 10l1-1-1.5-1.5L20 6zm-9 8.5A3.54 3.54 0 0 1 7.5 18a3.5 3.5 0 0 1 0-7 3.54 3.54 0 0 1 3.5 3.5z"/><circle cx="7" cy="3" r="2"/><circle cx="13" cy="7" r="1"/><circle cx="10" cy="6" r="1"/><circle cx="3" cy="3" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="1" cy="9" r="1"/><circle cx="3" cy="12" r="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>map trail</title><g fill="#fff"><path d="M20 6l-1-1-1.5 1.5L16 5l-1 1 1.5 1.5L15 9l1 1 1.5-1.5L19 10l1-1-1.5-1.5z"/><circle cx="7.5" cy="14.5" r="3.5"/><circle cx="7" cy="3" r="2"/><circle cx="13" cy="7" r="1"/><circle cx="10" cy="6" r="1"/><circle cx="3" cy="3" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="1" cy="9" r="1"/><circle cx="3" cy="12" r="1"/></g></svg>
\ No newline at end of file
index 9e55791..7fd2061 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail-progressive.png differ
index 29c0b7f..c7bd4db 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>map trail</title><g fill="#36c"><path d="M20 6l-1-1-1.5 1.5L16 5l-1 1 1.5 1.5L15 9l1 1 1.5-1.5L19 10l1-1-1.5-1.5L20 6zm-9 8.5A3.54 3.54 0 0 1 7.5 18a3.5 3.5 0 0 1 0-7 3.54 3.54 0 0 1 3.5 3.5z"/><circle cx="7" cy="3" r="2"/><circle cx="13" cy="7" r="1"/><circle cx="10" cy="6" r="1"/><circle cx="3" cy="3" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="1" cy="9" r="1"/><circle cx="3" cy="12" r="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>map trail</title><g fill="#36c"><path d="M20 6l-1-1-1.5 1.5L16 5l-1 1 1.5 1.5L15 9l1 1 1.5-1.5L19 10l1-1-1.5-1.5z"/><circle cx="7.5" cy="14.5" r="3.5"/><circle cx="7" cy="3" r="2"/><circle cx="13" cy="7" r="1"/><circle cx="10" cy="6" r="1"/><circle cx="3" cy="3" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="1" cy="9" r="1"/><circle cx="3" cy="12" r="1"/></g></svg>
\ No newline at end of file
index 7acd145..1b201f0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mapTrail.png differ
index 3c4726b..9fffe9b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>map trail</title><path d="M20 6l-1-1-1.5 1.5L16 5l-1 1 1.5 1.5L15 9l1 1 1.5-1.5L19 10l1-1-1.5-1.5L20 6zm-9 8.5A3.54 3.54 0 0 1 7.5 18a3.5 3.5 0 0 1 0-7 3.54 3.54 0 0 1 3.5 3.5z"/><circle cx="7" cy="3" r="2"/><circle cx="13" cy="7" r="1"/><circle cx="10" cy="6" r="1"/><circle cx="3" cy="3" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="1" cy="9" r="1"/><circle cx="3" cy="12" r="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>map trail</title><path d="M20 6l-1-1-1.5 1.5L16 5l-1 1 1.5 1.5L15 9l1 1 1.5-1.5L19 10l1-1-1.5-1.5z"/><circle cx="7.5" cy="14.5" r="3.5"/><circle cx="7" cy="3" r="2"/><circle cx="13" cy="7" r="1"/><circle cx="10" cy="6" r="1"/><circle cx="3" cy="3" r="1"/><circle cx="1" cy="6" r="1"/><circle cx="1" cy="9" r="1"/><circle cx="3" cy="12" r="1"/></svg>
\ No newline at end of file
index 172ccfb..4a523f3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/markup-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/markup-invert.png differ
index 4a0f3fb..0669bfa 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>markup</title><path fill="#fff" d="M6.5 3.5l-5 5L0 10l1.5 1.5 5 5L8 15l-5-5 5-5-1.5-1.5zm12 5l-5-5L12 5l5 5-5 5 1.5 1.5 5-5L20 10l-1.5-1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>markup</title><path fill="#fff" d="M6.5 3.5L0 10l1.5 1.5 5 5L8 15l-5-5 5-5zm7 0L12 5l5 5-5 5 1.5 1.5L20 10z"/></svg>
\ No newline at end of file
index 3195886..f2100c6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>markup</title><path fill="#36c" d="M6.5 3.5l-5 5L0 10l1.5 1.5 5 5L8 15l-5-5 5-5-1.5-1.5zm12 5l-5-5L12 5l5 5-5 5 1.5 1.5 5-5L20 10l-1.5-1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>markup</title><path fill="#36c" d="M6.5 3.5L0 10l1.5 1.5 5 5L8 15l-5-5 5-5zm7 0L12 5l5 5-5 5 1.5 1.5L20 10z"/></svg>
\ No newline at end of file
index 7b873fa..92da3b4 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/markup.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/markup.png differ
index 8a6e84a..032d63c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>markup</title><path d="M6.5 3.5l-5 5L0 10l1.5 1.5 5 5L8 15l-5-5 5-5-1.5-1.5zm12 5l-5-5L12 5l5 5-5 5 1.5 1.5 5-5L20 10l-1.5-1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>markup</title><path d="M6.5 3.5L0 10l1.5 1.5 5 5L8 15l-5-5 5-5zm7 0L12 5l5 5-5 5 1.5 1.5L20 10z"/></svg>
\ No newline at end of file
index 7888925..f66f8ce 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematics-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematics-invert.png differ
index e6320d4..0b7a5d2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula</title><path fill="#fff" d="M14 2H4l5 8-5 8h12v-4h-2v2H8.25L12 10 8.25 4H14v2h2V2h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula</title><path fill="#fff" d="M14 2H4l5 8-5 8h12v-4h-2v2H8.25L12 10 8.25 4H14v2h2V2z"/></svg>
\ No newline at end of file
index 62dde43..6b5114d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula</title><path fill="#36c" d="M14 2H4l5 8-5 8h12v-4h-2v2H8.25L12 10 8.25 4H14v2h2V2h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula</title><path fill="#36c" d="M14 2H4l5 8-5 8h12v-4h-2v2H8.25L12 10 8.25 4H14v2h2V2z"/></svg>
\ No newline at end of file
index ec09fa6..8a0a9d5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematics.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematics.png differ
index c7ef385..23c519a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula</title><path d="M14 2H4l5 8-5 8h12v-4h-2v2H8.25L12 10 8.25 4H14v2h2V2h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula</title><path d="M14 2H4l5 8-5 8h12v-4h-2v2H8.25L12 10 8.25 4H14v2h2V2z"/></svg>
\ No newline at end of file
index 85596c1..54ab9e1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock-invert.png differ
index bcdd566..b6bab67 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed block</title><path fill="#fff" d="M13 5H5l3 5-3 5h10v-3h-2v1H9.2l1.8-3-1.8-3H13v1h2V5h-2zM2 1h16v2H2zm0 16h16v2H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed block</title><path fill="#fff" d="M13 5H5l3 5-3 5h10v-3h-2v1H9.2l1.8-3-1.8-3H13v1h2V5zM2 1h16v2H2zm0 16h16v2H2z"/></svg>
\ No newline at end of file
index 696e026..1eaa33e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed block</title><path fill="#36c" d="M13 5H5l3 5-3 5h10v-3h-2v1H9.2l1.8-3-1.8-3H13v1h2V5h-2zM2 1h16v2H2zm0 16h16v2H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed block</title><path fill="#36c" d="M13 5H5l3 5-3 5h10v-3h-2v1H9.2l1.8-3-1.8-3H13v1h2V5zM2 1h16v2H2zm0 16h16v2H2z"/></svg>
\ No newline at end of file
index a917380..3908603 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayBlock.png differ
index 5bf6084..0413075 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed block</title><path d="M13 5H5l3 5-3 5h10v-3h-2v1H9.2l1.8-3-1.8-3H13v1h2V5h-2zM2 1h16v2H2zm0 16h16v2H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed block</title><path d="M13 5H5l3 5-3 5h10v-3h-2v1H9.2l1.8-3-1.8-3H13v1h2V5zM2 1h16v2H2zm0 16h16v2H2z"/></svg>
\ No newline at end of file
index c5126b1..2618d11 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault-invert.png differ
index 6f01e5a..6938ddd 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed default</title><path fill="#fff" d="M12 5H4l3 5-3 5h10v-3h-2v1H8.2l1.8-3-1.8-3H12v1h2V5h-2zM1 9h3v2H1zm15 0h3v2h-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed default</title><path fill="#fff" d="M12 5H4l3 5-3 5h10v-3h-2v1H8.2l1.8-3-1.8-3H12v1h2V5zM1 9h3v2H1zm15 0h3v2h-3z"/></svg>
\ No newline at end of file
index d090c5c..6257edf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed default</title><path fill="#36c" d="M12 5H4l3 5-3 5h10v-3h-2v1H8.2l1.8-3-1.8-3H12v1h2V5h-2zM1 9h3v2H1zm15 0h3v2h-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed default</title><path fill="#36c" d="M12 5H4l3 5-3 5h10v-3h-2v1H8.2l1.8-3-1.8-3H12v1h2V5zM1 9h3v2H1zm15 0h3v2h-3z"/></svg>
\ No newline at end of file
index 9967e0f..ca84aac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayDefault.png differ
index 4ca06cd..f514457 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed default</title><path d="M12 5H4l3 5-3 5h10v-3h-2v1H8.2l1.8-3-1.8-3H12v1h2V5h-2zM1 9h3v2H1zm15 0h3v2h-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed default</title><path d="M12 5H4l3 5-3 5h10v-3h-2v1H8.2l1.8-3-1.8-3H12v1h2V5zM1 9h3v2H1zm15 0h3v2h-3z"/></svg>
\ No newline at end of file
index 323bfb0..cfa8c16 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline-invert.png differ
index 1018e46..7473b05 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed inline</title><path fill="#fff" d="M4 13H0V7h4v6zm12-6h4v6h-4zm-3-1H6l3 4-3 4h8v-3h-2v1H9.5l1.5-2-1.5-2H12v1h2V6h-1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed inline</title><path fill="#fff" d="M4 13H0V7h4zm12-6h4v6h-4zM6 6l3 4-3 4h8v-3h-2v1H9.5l1.5-2-1.5-2H12v1h2V6z"/></svg>
\ No newline at end of file
index 4b941e1..cd1da2a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed inline</title><path fill="#36c" d="M4 13H0V7h4v6zm12-6h4v6h-4zm-3-1H6l3 4-3 4h8v-3h-2v1H9.5l1.5-2-1.5-2H12v1h2V6h-1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed inline</title><path fill="#36c" d="M4 13H0V7h4zm12-6h4v6h-4zM6 6l3 4-3 4h8v-3h-2v1H9.5l1.5-2-1.5-2H12v1h2V6z"/></svg>
\ No newline at end of file
index ef7dfbc..1e2d5c6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/mathematicsDisplayInline.png differ
index d189571..96ad25c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed inline</title><path d="M4 13H0V7h4v6zm12-6h4v6h-4zm-3-1H6l3 4-3 4h8v-3h-2v1H9.5l1.5-2-1.5-2H12v1h2V6h-1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>mathematics formula displayed inline</title><path d="M4 13H0V7h4zm12-6h4v6h-4zM6 6l3 4-3 4h8v-3h-2v1H9.5l1.5-2-1.5-2H12v1h2V6z"/></svg>
\ No newline at end of file
index dd344df..c45040c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/menu-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/menu-invert.png differ
index 9fcb3be..4be6087 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/menu.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/menu.png differ
index 276ba02..6824015 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/message-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/message-invert.png differ
index 0fc1a12..d730b17 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>message</title><g fill="#fff"><path d="M0 8v8a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-10 4z"/><path d="M18 2H2a2 2 0 0 0-2 2v2l10 4 10-4V4a2 2 0 0 0-2-2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>message</title><g fill="#fff"><path d="M0 8v8a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-10 4z"/><path d="M2a2 2 0 0 0-2 2v2l10 4 10-4V4a2 2 0 0 0-2-2z"/></g></svg>
\ No newline at end of file
index fe012fc..fc659bf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>message</title><g fill="#36c"><path d="M0 8v8a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-10 4z"/><path d="M18 2H2a2 2 0 0 0-2 2v2l10 4 10-4V4a2 2 0 0 0-2-2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>message</title><g fill="#36c"><path d="M0 8v8a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-10 4z"/><path d="M2a2 2 0 0 0-2 2v2l10 4 10-4V4a2 2 0 0 0-2-2z"/></g></svg>
\ No newline at end of file
index d2b4d2b..9c1b3c0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/message.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/message.png differ
index 0b9691c..1918658 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>message</title><path d="M0 8v8a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-10 4z"/><path d="M18 2H2a2 2 0 0 0-2 2v2l10 4 10-4V4a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>message</title><path d="M0 8v8a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-10 4z"/><path d="M2a2 2 0 0 0-2 2v2l10 4 10-4V4a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index 8bc33ae..bf864d4 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moon-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moon-invert.png differ
index 6936506..1d4302e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moon.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moon.png differ
index 85f6293..527e18a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/move-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/move-invert.png differ
index 9342df1..99bf518 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>move</title><path fill="#fff" d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2l4-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>move</title><path fill="#fff" d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2z"/></svg>
\ No newline at end of file
index a8b62a3..37dd588 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>move</title><path fill="#36c" d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2l4-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>move</title><path fill="#36c" d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2z"/></svg>
\ No newline at end of file
index f5471a9..3089bf1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/move.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/move.png differ
index 03975f8..e01347d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>move</title><path d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2l4-3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>move</title><path d="M19 10l-4-3v2h-4V5h2l-3-4-3 4h2v4H5V7l-4 3 4 3v-2h4v4H7l3 4 3-4h-2v-4h4v2z"/></svg>
\ No newline at end of file
index d07f436..c3a32d9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-invert.png differ
index 1f02679..d6342fc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#fff" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10l7.5-7.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#fff" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10z"/></svg>
\ No newline at end of file
index a262b95..e89fe54 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr-progressive.png differ
index dd8eec5..3e1c680 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#36c" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10l7.5-7.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#36c" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10z"/></svg>
\ No newline at end of file
index 9509568..30d3c2a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-ltr.png differ
index d7d116e..aa0b1fc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10l7.5-7.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10z"/></svg>
\ No newline at end of file
index 64e36be..a7dfa3b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-invert.png differ
index 6984974..0eaab17 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#fff" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9-1.5 1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#fff" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9z"/></svg>
\ No newline at end of file
index 320855a..0d36d88 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl-progressive.png differ
index 1cf9152..7c7821a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#36c" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9-1.5 1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#36c" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9z"/></svg>
\ No newline at end of file
index f30b318..cf82fd0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveFirst-rtl.png differ
index 88dfe2c..02e2d18 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9-1.5 1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9z"/></svg>
\ No newline at end of file
index 64e36be..a7dfa3b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-invert.png differ
index bc636d8..7463141 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>last</title><path fill="#fff" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9-1.5 1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>last</title><path fill="#fff" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9z"/></svg>
\ No newline at end of file
index 320855a..0d36d88 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr-progressive.png differ
index f5c3892..63aab84 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>last</title><path fill="#36c" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9-1.5 1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>last</title><path fill="#36c" d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9z"/></svg>
\ No newline at end of file
index f30b318..cf82fd0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-ltr.png differ
index cb0a473..326f655 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>last</title><path d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9-1.5 1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>last</title><path d="M15 1h2v18h-2zM3.5 2.5L11 10l-7.5 7.5L5 19l9-9-9-9z"/></svg>
\ No newline at end of file
index d07f436..c3a32d9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-invert.png differ
index 1f02679..d6342fc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#fff" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10l7.5-7.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#fff" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10z"/></svg>
\ No newline at end of file
index a262b95..e89fe54 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl-progressive.png differ
index dd8eec5..3e1c680 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#36c" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10l7.5-7.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path fill="#36c" d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10z"/></svg>
\ No newline at end of file
index 9509568..30d3c2a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/moveLast-rtl.png differ
index d7d116e..aa0b1fc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10l7.5-7.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>first</title><path d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10z"/></svg>
\ No newline at end of file
index e72604d..f0779c3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/musicalScore-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/musicalScore-invert.png differ
index f7c74e5..ec74f67 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/musicalScore.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/musicalScore.png differ
index b2c62a5..182aecc 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr-invert.png differ
index 39f14b2..dcc968d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#fff"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M19 1h-8l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#fff"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M11 1l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
index 1ff23cb..dc72dc2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#36c"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M19 1h-8l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#36c"><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M11 1l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></g></svg>
\ No newline at end of file
index f51c501..b64e15c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-ltr.png differ
index af0056a..2a6e8de 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M19 1h-8l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><path d="M17 17H3V3h5V1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5h-2z"/><path d="M11 1l3.29 3.29-5.73 5.73 1.42 1.42 5.73-5.73L19 9V1z"/></svg>
\ No newline at end of file
index 866c7e3..899dc14 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl-invert.png differ
index bf03df3..946f9fb 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#fff"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3v-5z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#fff"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
index effb557..3b53f6b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#36c"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3v-5z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><g fill="#36c"><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></g></svg>
\ No newline at end of file
index c5493d2..3b8d93c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newWindow-rtl.png differ
index 6d98eec..9003288 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3v-5z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>new window</title><path d="M3 12H1v5c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2h-5v2h5v14H3z"/><path d="M1 9l3.3-3.3 5.7 5.7 1.4-1.4-5.7-5.7L9 1H1z"/></svg>
\ No newline at end of file
index 26b5912..e116738 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr-invert.png differ
index b045271..7958ab8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newline</title><path fill="#fff" d="M17 4v6H7V6l-6 5 6 5v-4h12V4h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newline</title><path fill="#fff" d="M17 4v6H7V6l-6 5 6 5v-4h12V4z"/></svg>
\ No newline at end of file
index fce413a..228a43d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newline</title><path fill="#36c" d="M17 4v6H7V6l-6 5 6 5v-4h12V4h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newline</title><path fill="#36c" d="M17 4v6H7V6l-6 5 6 5v-4h12V4z"/></svg>
\ No newline at end of file
index fea69c9..5e097cb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newline-ltr.png differ
index 98affee..dcd0883 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newline</title><path d="M17 4v6H7V6l-6 5 6 5v-4h12V4h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newline</title><path d="M17 4v6H7V6l-6 5 6 5v-4h12V4z"/></svg>
\ No newline at end of file
index 77d0dca..b039431 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newline-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newline-rtl-invert.png differ
index 343b271..194f08c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newline-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newline-rtl.png differ
index 4ce2b0f..852690d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr-invert.png differ
index de0088b..15a4f68 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#fff" d="M18 2H5a2 2 0 0 0-2 2v12a1 1 0 0 1-1-1V5h-.5A1.5 1.5 0 0 0 0 6.5v10A1.5 1.5 0 0 0 1.5 18H18a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm-6 13H6v-1h6zm0-2H6v-1h6zm0-2H6v-1h6zm5 4h-4v-5h4zm0-7H6V4h11z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#fff" d="M5 2a2 2 0 0 0-2 2v12a1 1 0 0 1-1-1V5h-.5A1.5 1.5 0 0 0 0 6.5v10A1.5 1.5 0 0 0 1.5 18H18a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm1 2h11v4H6zm0 6h6v1H6zm0 2h6v1H6zm0 2h6v1H6zm7-4h4v5h-4z"/></svg>
\ No newline at end of file
index 35e6344..9057bbb 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#36c" d="M18 2H5a2 2 0 0 0-2 2v12a1 1 0 0 1-1-1V5h-.5A1.5 1.5 0 0 0 0 6.5v10A1.5 1.5 0 0 0 1.5 18H18a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm-6 13H6v-1h6zm0-2H6v-1h6zm0-2H6v-1h6zm5 4h-4v-5h4zm0-7H6V4h11z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#36c" d="M5 2a2 2 0 0 0-2 2v12a1 1 0 0 1-1-1V5h-.5A1.5 1.5 0 0 0 0 6.5v10A1.5 1.5 0 0 0 1.5 18H18a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm1 2h11v4H6zm0 6h6v1H6zm0 2h6v1H6zm0 2h6v1H6zm7-4h4v5h-4z"/></svg>
\ No newline at end of file
index 3865644..05f748a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-ltr.png differ
index 439ea96..fdc92e4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path d="M18 2H5a2 2 0 0 0-2 2v12a1 1 0 0 1-1-1V5h-.5A1.5 1.5 0 0 0 0 6.5v10A1.5 1.5 0 0 0 1.5 18H18a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm-6 13H6v-1h6zm0-2H6v-1h6zm0-2H6v-1h6zm5 4h-4v-5h4zm0-7H6V4h11z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path d="M5 2a2 2 0 0 0-2 2v12a1 1 0 0 1-1-1V5h-.5A1.5 1.5 0 0 0 0 6.5v10A1.5 1.5 0 0 0 1.5 18H18a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm1 2h11v4H6zm0 6h6v1H6zm0 2h6v1H6zm0 2h6v1H6zm7-4h4v5h-4z"/></svg>
\ No newline at end of file
index 1cf9576..2fc655e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl-invert.png differ
index 609a027..6a8bab7 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#fff" d="M0 4v12c0 1.1.9 2 2 2h16.5c.8 0 1.5-.7 1.5-1.5v-10c0-.8-.7-1.5-1.5-1.5H18v10c0 .6-.4 1-1 1V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zm8 10h6v1H8v-1zm0-2h6v1H8v-1zm0-2h6v1H8v-1zm-5 0h4v5H3v-5zm0-6h11v4H3V4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#fff" d="M0 16c0 1.1.9 2 2 2h16.5c.8 0 1.5-.7 1.5-1.5v-10c0-.8-.7-1.5-1.5-1.5H18v10c0 .6-.4 1-1 1V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zM3 4h11v4H3zm0 6h4v5H3zm5 0h6v1H8zm0 2h6v1H8zm0 2h6v1H8z"/></svg>
\ No newline at end of file
index bda8a99..2c8eba4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#36c" d="M0 4v12c0 1.1.9 2 2 2h16.5c.8 0 1.5-.7 1.5-1.5v-10c0-.8-.7-1.5-1.5-1.5H18v10c0 .6-.4 1-1 1V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zm8 10h6v1H8v-1zm0-2h6v1H8v-1zm0-2h6v1H8v-1zm-5 0h4v5H3v-5zm0-6h11v4H3V4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path fill="#36c" d="M0 16c0 1.1.9 2 2 2h16.5c.8 0 1.5-.7 1.5-1.5v-10c0-.8-.7-1.5-1.5-1.5H18v10c0 .6-.4 1-1 1V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zM3 4h11v4H3zm0 6h4v5H3zm5 0h6v1H8zm0 2h6v1H8zm0 2h6v1H8z"/></svg>
\ No newline at end of file
index 4abde64..c11038c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/newspaper-rtl.png differ
index 76a8535..815dcc6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path d="M0 4v12c0 1.1.9 2 2 2h16.5c.8 0 1.5-.7 1.5-1.5v-10c0-.8-.7-1.5-1.5-1.5H18v10c0 .6-.4 1-1 1V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zm8 10h6v1H8v-1zm0-2h6v1H8v-1zm0-2h6v1H8v-1zm-5 0h4v5H3v-5zm0-6h11v4H3V4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>newspaper</title><path d="M0 16c0 1.1.9 2 2 2h16.5c.8 0 1.5-.7 1.5-1.5v-10c0-.8-.7-1.5-1.5-1.5H18v10c0 .6-.4 1-1 1V4c0-1.1-.9-2-2-2H2C.9 2 0 2.9 0 4zM3 4h11v4H3zm0 6h4v5H3zm5 0h6v1H8zm0 2h6v1H8zm0 2h6v1H8z"/></svg>
\ No newline at end of file
index 6e0098d..1c13f93 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr-invert.png differ
index eba3ede..1a9772f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr-progressive.png differ
index a75d1e5..937e0f9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/next-ltr.png differ
index 7feb22f..bafd9ff 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/next-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/next-rtl-invert.png differ
index 7666934..057b036 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/next-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/next-rtl.png differ
index 02c44e3..620adb1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-invert.png differ
index eb2f017..d58b406 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>no WikiText</title><path fill="#fff" d="M16 3v2h1v10l2 2V3zM9 5V3H5l2 2zM1 1L0 2l1 1v14h3v-2H3V5l2 2v10h4v-2H7V9l6 6h-2v2h4l3 3 1-1-3-3zm12 10l2 2V3h-4v2h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>no WikiText</title><path fill="#fff" d="M16 3v2h1v10l2 2V3zM9 5V3H5l2 2zM1 1L0 2l1 1v14h3v-2H3V5l2 2v10h4v-2H7V9l6 6h-2v2h4l3 3 1-1zm12 10l2 2V3h-4v2h2z"/></svg>
\ No newline at end of file
index 8c08646..e369d23 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText-progressive.png differ
index dff68df..9486955 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>no WikiText</title><path fill="#36c" d="M16 3v2h1v10l2 2V3zM9 5V3H5l2 2zM1 1L0 2l1 1v14h3v-2H3V5l2 2v10h4v-2H7V9l6 6h-2v2h4l3 3 1-1-3-3zm12 10l2 2V3h-4v2h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>no WikiText</title><path fill="#36c" d="M16 3v2h1v10l2 2V3zM9 5V3H5l2 2zM1 1L0 2l1 1v14h3v-2H3V5l2 2v10h4v-2H7V9l6 6h-2v2h4l3 3 1-1zm12 10l2 2V3h-4v2h2z"/></svg>
\ No newline at end of file
index ebac502..cc3417d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/noWikiText.png differ
index b32048f..cb98c78 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>no WikiText</title><path d="M16 3v2h1v10l2 2V3zM9 5V3H5l2 2zM1 1L0 2l1 1v14h3v-2H3V5l2 2v10h4v-2H7V9l6 6h-2v2h4l3 3 1-1-3-3zm12 10l2 2V3h-4v2h2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>no WikiText</title><path d="M16 3v2h1v10l2 2V3zM9 5V3H5l2 2zM1 1L0 2l1 1v14h3v-2H3V5l2 2v10h4v-2H7V9l6 6h-2v2h4l3 3 1-1zm12 10l2 2V3h-4v2h2z"/></svg>
\ No newline at end of file
index b405b7f..ea478ac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/notBright-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/notBright-invert.png differ
index 453f050..ff7a961 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>not bright</title><path fill="#fff" d="M9.85 1a9 9 0 1 0 9 9 9 9 0 0 0-9-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>not bright</title><circle cx="9.85" cy="10" r="9" fill="#fff"/></svg>
\ No newline at end of file
index 6aa2ace..f765253 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/notBright-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/notBright-progressive.png differ
index a283587..1b4e517 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>not bright</title><path fill="#36c" d="M9.85 1a9 9 0 1 0 9 9 9 9 0 0 0-9-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>not bright</title><circle cx="9.85" cy="10" r="9" fill="#36c"/></svg>
\ No newline at end of file
index f56a820..4297f20 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/notBright.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/notBright.png differ
index 3944b53..d0610bd 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>not bright</title><path d="M9.85 1a9 9 0 1 0 9 9 9 9 0 0 0-9-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>not bright</title><circle cx="9.85" cy="10" r="9"/></svg>
\ No newline at end of file
index 6f1b8eb..7d3e573 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/notice-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/notice-invert.png differ
index 1d8def4..f5ef63b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/notice-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/notice-progressive.png differ
index f845ec1..2a397bb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/notice.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/notice.png differ
index 061581e..c748a28 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr-invert.png differ
index 81b90f6..0d48fb6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#fff" d="M18 0H2a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM5 9.06a1.39 1.39 0 1 1 1.37-1.39A1.39 1.39 0 0 1 5 9.06zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#fff" d="M2 0a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm3 9.06a1.39 1.39 0 1 1 1.37-1.39A1.39 1.39 0 0 1 5 9.06zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39z"/></svg>
\ No newline at end of file
index c4318b1..bad6547 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#36c" d="M18 0H2a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM5 9.06a1.39 1.39 0 1 1 1.37-1.39A1.39 1.39 0 0 1 5 9.06zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#36c" d="M2 0a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm3 9.06a1.39 1.39 0 1 1 1.37-1.39A1.39 1.39 0 0 1 5 9.06zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39z"/></svg>
\ No newline at end of file
index 5bbfe3a..1d2e691 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-ltr.png differ
index c4bc4da..b02924a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path d="M18 0H2a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM5 9.06a1.39 1.39 0 1 1 1.37-1.39A1.39 1.39 0 0 1 5 9.06zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path d="M2 0a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm3 9.06a1.39 1.39 0 1 1 1.37-1.39A1.39 1.39 0 0 1 5 9.06zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39zm5.16 0a1.39 1.39 0 1 1 1.39-1.39 1.39 1.39 0 0 1-1.42 1.39z"/></svg>
\ No newline at end of file
index 5e14856..5ff335c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl-invert.png differ
index 30fe996..7f0ccd0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#fff" d="M0 2v12c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2zm13.6 5.7c0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.6 1.4-1.4 1.4c-.8-.1-1.4-.7-1.4-1.4zM9.9 9.1s-.1 0 0 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.7 1.4-1.4 1.4zm-5.2 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4 0 .7-.7 1.4-1.4 1.4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#fff" d="M0 14c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2zm13.6-6.3c0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.6 1.4-1.4 1.4c-.8-.1-1.4-.7-1.4-1.4zM9.9 9.1s-.1 0 0 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.7 1.4-1.4 1.4zm-5.2 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4 0 .7-.7 1.4-1.4 1.4z"/></svg>
\ No newline at end of file
index 5e50d81..0fa6cf2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#36c" d="M0 2v12c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2zm13.6 5.7c0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.6 1.4-1.4 1.4c-.8-.1-1.4-.7-1.4-1.4zM9.9 9.1s-.1 0 0 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.7 1.4-1.4 1.4zm-5.2 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4 0 .7-.7 1.4-1.4 1.4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path fill="#36c" d="M0 14c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2zm13.6-6.3c0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.6 1.4-1.4 1.4c-.8-.1-1.4-.7-1.4-1.4zM9.9 9.1s-.1 0 0 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.7 1.4-1.4 1.4zm-5.2 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4 0 .7-.7 1.4-1.4 1.4z"/></svg>
\ No newline at end of file
index 4f2c8f0..ce28b18 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/ongoingConversation-rtl.png differ
index 707353f..4130e12 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path d="M0 2v12c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2zm13.6 5.7c0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.6 1.4-1.4 1.4c-.8-.1-1.4-.7-1.4-1.4zM9.9 9.1s-.1 0 0 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.7 1.4-1.4 1.4zm-5.2 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4 0 .7-.7 1.4-1.4 1.4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>ongoing conversation</title><path d="M0 14c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2zm13.6-6.3c0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.6 1.4-1.4 1.4c-.8-.1-1.4-.7-1.4-1.4zM9.9 9.1s-.1 0 0 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4s-.7 1.4-1.4 1.4zm-5.2 0c-.8 0-1.4-.6-1.4-1.4 0-.8.6-1.4 1.4-1.4.8 0 1.4.6 1.4 1.4 0 .7-.7 1.4-1.4 1.4z"/></svg>
\ No newline at end of file
index 506a955..cd5207c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr-invert.png differ
index 3d0b9a9..ebfe91d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outdent</title><path fill="#fff" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm0 8l5 4V6l-5 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outdent</title><path fill="#fff" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm0 8l5 4V6z"/></svg>
\ No newline at end of file
index b7bc829..13e2b1d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outdent</title><path fill="#36c" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm0 8l5 4V6l-5 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outdent</title><path fill="#36c" d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm0 8l5 4V6z"/></svg>
\ No newline at end of file
index 05c6681..7c4de60 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-ltr.png differ
index 8abc234..eef683e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outdent</title><path d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm0 8l5 4V6l-5 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outdent</title><path d="M1 16h18v2H1zm8-9h10v2H9zm0 4h10v2H9zM1 2h18v2H1zm0 8l5 4V6z"/></svg>
\ No newline at end of file
index 1a652dc..91f8fb7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-rtl-invert.png differ
index f883d13..a6c5a4d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/outdent-rtl.png differ
index 673fcf6..1581727 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/outline-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/outline-ltr.png differ
index 99a9fd6..3c54aba 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outline</title><path fill="#fff" d="M1 12h18v7H1zM11 1v8h8V1h-8zm2 2h4v4h-4V3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outline</title><path fill="#fff" d="M1 12h18v7H1zM11 1v8h8V1zm2 2h4v4h-4z"/></svg>
\ No newline at end of file
index 638405f..f63caa8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outline</title><path fill="#36c" d="M1 12h18v7H1zM11 1v8h8V1h-8zm2 2h4v4h-4V3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outline</title><path fill="#36c" d="M1 12h18v7H1zM11 1v8h8V1zm2 2h4v4h-4z"/></svg>
\ No newline at end of file
index 1e38852..b183b90 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/outline-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/outline-rtl.png differ
index 2340bcd..5993fe2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outline</title><path d="M1 12h18v7H1zM11 1v8h8V1h-8zm2 2h4v4h-4V3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>outline</title><path d="M1 12h18v7H1zM11 1v8h8V1zm2 2h4v4h-4z"/></svg>
\ No newline at end of file
index 701c523..641fcac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/pageSettings-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/pageSettings-invert.png differ
index 9ed701f..fefebd9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/pageSettings.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/pageSettings.png differ
index 7173cae..4e29b51 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/pause-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/pause-invert.png differ
index af430ef..dd389a8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>pause</title><g fill="#fff"><rect width="6" height="16" x="3" y="2" rx="1" ry="1"/><rect width="6" height="16" x="11" y="2" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>pause</title><g fill="#fff"><rect width="6" height="16" x="3" y="2" rx="1"/><rect width="6" height="16" x="11" y="2" rx="1"/></g></svg>
\ No newline at end of file
index 40d4334..6788b5f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>pause</title><g fill="#36c"><rect width="6" height="16" x="3" y="2" rx="1" ry="1"/><rect width="6" height="16" x="11" y="2" rx="1" ry="1"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>pause</title><g fill="#36c"><rect width="6" height="16" x="3" y="2" rx="1"/><rect width="6" height="16" x="11" y="2" rx="1"/></g></svg>
\ No newline at end of file
index fe6efdf..67a95ec 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/pause.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/pause.png differ
index fd74112..d9be81a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>pause</title><rect width="6" height="16" x="3" y="2" rx="1" ry="1"/><rect width="6" height="16" x="11" y="2" rx="1" ry="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>pause</title><rect width="6" height="16" x="3" y="2" rx="1"/><rect width="6" height="16" x="11" y="2" rx="1"/></svg>
\ No newline at end of file
index 47be562..7677e6d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/play-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/play-invert.png differ
index d29be30..47c622f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>play</title><path fill="#fff" d="M16.75 10.83L4.55 19A1 1 0 0 1 3 18.13V1.87A1 1 0 0 1 4.55 1l12.2 8.13a1 1 0 0 1 0 1.7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>play</title><path fill="#fff" d="M4.55 19A1 1 0 0 1 3 18.13V1.87A1 1 0 0 1 4.55 1l12.2 8.13a1 1 0 0 1 0 1.7z"/></svg>
\ No newline at end of file
index 79090c5..9568f53 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>play</title><path fill="#36c" d="M16.75 10.83L4.55 19A1 1 0 0 1 3 18.13V1.87A1 1 0 0 1 4.55 1l12.2 8.13a1 1 0 0 1 0 1.7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>play</title><path fill="#36c" d="M4.55 19A1 1 0 0 1 3 18.13V1.87A1 1 0 0 1 4.55 1l12.2 8.13a1 1 0 0 1 0 1.7z"/></svg>
\ No newline at end of file
index 63d2912..0ccf367 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/play.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/play.png differ
index a04ff2a..30e7698 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>play</title><path d="M16.75 10.83L4.55 19A1 1 0 0 1 3 18.13V1.87A1 1 0 0 1 4.55 1l12.2 8.13a1 1 0 0 1 0 1.7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>play</title><path d="M4.55 19A1 1 0 0 1 3 18.13V1.87A1 1 0 0 1 4.55 1l12.2 8.13a1 1 0 0 1 0 1.7z"/></svg>
\ No newline at end of file
index 7feb22f..bafd9ff 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/previous-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/previous-ltr-invert.png differ
index 7666934..057b036 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/previous-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/previous-ltr.png differ
index 6e0098d..1c13f93 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl-invert.png differ
index eba3ede..1a9772f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl-progressive.png differ
index a75d1e5..937e0f9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/previous-rtl.png differ
index 27e843c..298e0a6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/printer-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/printer-invert.png differ
index c8ef32c..69cb48d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>printer</title><path fill="#fff" d="M5 1h10v4H5zm12 5H3a2 2 0 0 0-2 2v7h4v4h10v-4h4V8a2 2 0 0 0-2-2zm-3 12H6v-6h8zm2-8a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>printer</title><path fill="#fff" d="M5 1h10v4H5zM3 6a2 2 0 0 0-2 2v7h4v4h10v-4h4V8a2 2 0 0 0-2-2zm11 12H6v-6h8zm2-8a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"/></svg>
\ No newline at end of file
index cf32cea..e96b9b6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>printer</title><path fill="#36c" d="M5 1h10v4H5zm12 5H3a2 2 0 0 0-2 2v7h4v4h10v-4h4V8a2 2 0 0 0-2-2zm-3 12H6v-6h8zm2-8a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>printer</title><path fill="#36c" d="M5 1h10v4H5zM3 6a2 2 0 0 0-2 2v7h4v4h10v-4h4V8a2 2 0 0 0-2-2zm11 12H6v-6h8zm2-8a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"/></svg>
\ No newline at end of file
index 8a62ebb..b9574cd 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/printer.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/printer.png differ
index 98ebf1e..8d0d99f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>printer</title><path d="M5 1h10v4H5zm12 5H3a2 2 0 0 0-2 2v7h4v4h10v-4h4V8a2 2 0 0 0-2-2zm-3 12H6v-6h8zm2-8a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>printer</title><path d="M5 1h10v4H5zM3 6a2 2 0 0 0-2 2v7h4v4h10v-4h4V8a2 2 0 0 0-2-2zm11 12H6v-6h8zm2-8a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"/></svg>
\ No newline at end of file
index 07eb257..e0d91a5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/pushPin-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/pushPin-invert.png differ
index b97d0d6..a6a6d79 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>push pin</title><path fill="#fff" d="M14 8h-1V2a2 2 0 0 0 2-2H5a2 2 0 0 0 2 2v6H6a2 2 0 0 0-2 2v1h5v5l1 4 1-4v-5h5v-1a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>push pin</title><path fill="#fff" d="M13 8V2a2 2 0 0 0 2-2H5a2 2 0 0 0 2 2v6H6a2 2 0 0 0-2 2v1h5v5l1 4 1-4v-5h5v-1a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index 06af606..9ba35bf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>push pin</title><path fill="#36c" d="M14 8h-1V2a2 2 0 0 0 2-2H5a2 2 0 0 0 2 2v6H6a2 2 0 0 0-2 2v1h5v5l1 4 1-4v-5h5v-1a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>push pin</title><path fill="#36c" d="M13 8V2a2 2 0 0 0 2-2H5a2 2 0 0 0 2 2v6H6a2 2 0 0 0-2 2v1h5v5l1 4 1-4v-5h5v-1a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index 87c7141..90bcfd7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/pushPin.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/pushPin.png differ
index 37d0292..8b72199 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>push pin</title><path d="M14 8h-1V2a2 2 0 0 0 2-2H5a2 2 0 0 0 2 2v6H6a2 2 0 0 0-2 2v1h5v5l1 4 1-4v-5h5v-1a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>push pin</title><path d="M13 8V2a2 2 0 0 0 2-2H5a2 2 0 0 0 2 2v6H6a2 2 0 0 0-2 2v1h5v5l1 4 1-4v-5h5v-1a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index ff817b5..4d3a107 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-ltr-invert.png differ
index 8369ec3..224e717 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-ltr.png differ
index 21e0a5d..9a1eabe 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-rtl-invert.png differ
index a63b567..e624996 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/puzzle-rtl.png differ
index 1d237d1..fee4f02 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-ltr-invert.png differ
index e461bed..3c9a66b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-ltr.png differ
index 798d4d0..c8eaa79 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl-invert.png differ
index 03c637c..f106ede 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path fill="#fff" d="M15 9h-4v7h7V9c0-2.2-1.8-5-4-5h-2l1 2s2 0 2 3zM2 9v7h7V9c0-2.2-1.8-5-4-5H3l1 2s2 0 2 3H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path fill="#fff" d="M11 9v7h7V9c0-2.2-1.8-5-4-5h-2l1 2s2 0 2 3zM2 9v7h7V9c0-2.2-1.8-5-4-5H3l1 2s2 0 2 3z"/></svg>
\ No newline at end of file
index 63a7ce7..eb32248 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path fill="#36c" d="M15 9h-4v7h7V9c0-2.2-1.8-5-4-5h-2l1 2s2 0 2 3zM2 9v7h7V9c0-2.2-1.8-5-4-5H3l1 2s2 0 2 3H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path fill="#36c" d="M11 9v7h7V9c0-2.2-1.8-5-4-5h-2l1 2s2 0 2 3zM2 9v7h7V9c0-2.2-1.8-5-4-5H3l1 2s2 0 2 3z"/></svg>
\ No newline at end of file
index 7d1c4e2..b926aa7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/quotes-rtl.png differ
index 9741d1d..5605328 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path d="M15 9h-4v7h7V9c0-2.2-1.8-5-4-5h-2l1 2s2 0 2 3zM2 9v7h7V9c0-2.2-1.8-5-4-5H3l1 2s2 0 2 3H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path d="M11 9v7h7V9c0-2.2-1.8-5-4-5h-2l1 2s2 0 2 3zM2 9v7h7V9c0-2.2-1.8-5-4-5H3l1 2s2 0 2 3z"/></svg>
\ No newline at end of file
index 80194f8..c8b8a32 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr-invert.png differ
index 5e09475..a036d29 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#fff" d="M19 8.5L12 3v11l7-5.5zM12 7v3h-1c-4 0-7 2-7 6v1H1v-1c0-6 5-9 10-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#fff" d="M19 8.5L12 3v11zM12 7v3h-1c-4 0-7 2-7 6v1H1v-1c0-6 5-9 10-9z"/></svg>
\ No newline at end of file
index ef12c25..dacd10a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#36c" d="M19 8.5L12 3v11l7-5.5zM12 7v3h-1c-4 0-7 2-7 6v1H1v-1c0-6 5-9 10-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#36c" d="M19 8.5L12 3v11zM12 7v3h-1c-4 0-7 2-7 6v1H1v-1c0-6 5-9 10-9z"/></svg>
\ No newline at end of file
index a197ca4..aef78be 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/redo-ltr.png differ
index 3543eea..97c3a3b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path d="M19 8.5L12 3v11l7-5.5zM12 7v3h-1c-4 0-7 2-7 6v1H1v-1c0-6 5-9 10-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path d="M19 8.5L12 3v11zM12 7v3h-1c-4 0-7 2-7 6v1H1v-1c0-6 5-9 10-9z"/></svg>
\ No newline at end of file
index de3c8f2..b4e7595 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl-invert.png differ
index 00569fb..a079784 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#fff" d="M1 8.5L8 3v11L1 8.5zM8 7v3h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#fff" d="M1 8.5L8 3v11zM8 7v3h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9z"/></svg>
\ No newline at end of file
index 45a654b..85e4d0a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#36c" d="M1 8.5L8 3v11L1 8.5zM8 7v3h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path fill="#36c" d="M1 8.5L8 3v11zM8 7v3h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9z"/></svg>
\ No newline at end of file
index 3fdb6f7..336ae4a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/redo-rtl.png differ
index cd8c70d..dc627cf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path d="M1 8.5L8 3v11L1 8.5zM8 7v3h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>redo</title><path d="M1 8.5L8 3v11zM8 7v3h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9z"/></svg>
\ No newline at end of file
index 9642546..a080a73 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/reference-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/reference-invert.png differ
index b0b6bd1..3915527 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>reference</title><path fill="#fff" d="M15 1v9l-2.78-2.78L9.44 10V1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>reference</title><path fill="#fff" d="M15 10l-2.78-2.78L9.44 10V1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index a854dd0..0542626 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>reference</title><path fill="#36c" d="M15 1v9l-2.78-2.78L9.44 10V1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>reference</title><path fill="#36c" d="M15 10l-2.78-2.78L9.44 10V1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index 95f8dcd..5340929 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/reference.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/reference.png differ
index 6aab8f5..ef7c1b9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>reference</title><path d="M15 1v9l-2.78-2.78L9.44 10V1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>reference</title><path d="M15 10l-2.78-2.78L9.44 10V1H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
index c4aa0ed..7916b8f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr-invert.png differ
index b743725..ed0aa35 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#fff"><path d="M16 0v9l-2.8-2.8L10.4 9V0H7C5.9 0 5 .9 5 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2z"/><path d="M4 4H2v14c0 1.1.9 2 2 2h11v-2H4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#fff"><path d="M16 9l-2.8-2.8L10.4 9V0H7C5.9 0 5 .9 5 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2z"/><path d="M4 4H2v14c0 1.1.9 2 2 2h11v-2H4z"/></g></svg>
\ No newline at end of file
index d07dbcc..7898e43 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#36c"><path d="M16 0v9l-2.8-2.8L10.4 9V0H7C5.9 0 5 .9 5 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2z"/><path d="M4 4H2v14c0 1.1.9 2 2 2h11v-2H4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#36c"><path d="M16 9l-2.8-2.8L10.4 9V0H7C5.9 0 5 .9 5 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2z"/><path d="M4 4H2v14c0 1.1.9 2 2 2h11v-2H4z"/></g></svg>
\ No newline at end of file
index 8996f70..36d5ce9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-ltr.png differ
index 5f7908a..e1e68cf 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><path d="M16 0v9l-2.8-2.8L10.4 9V0H7C5.9 0 5 .9 5 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2z"/><path d="M4 4H2v14c0 1.1.9 2 2 2h11v-2H4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><path d="M16 9l-2.8-2.8L10.4 9V0H7C5.9 0 5 .9 5 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2z"/><path d="M4 4H2v14c0 1.1.9 2 2 2h11v-2H4z"/></svg>
\ No newline at end of file
index 9d3bbde..35f2e5b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl-invert.png differ
index 66eacb4..111056f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#fff"><path d="M2 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2v9l-2.8-2.8L7.4 9V0H4C2.4 0 2 1.6 2 2z"/><path d="M16 18H5v2h11c1.1 0 2-.9 2-2V4h-2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#fff"><path d="M2 15c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2v9l-2.8-2.8L7.4 9V0H4C2.4 0 2 1.6 2 2z"/><path d="M16 18H5v2h11c1.1 0 2-.9 2-2V4h-2z"/></g></svg>
\ No newline at end of file
index a2fe7a6..5a5d9d4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#36c"><path d="M2 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2v9l-2.8-2.8L7.4 9V0H4C2.4 0 2 1.6 2 2z"/><path d="M16 18H5v2h11c1.1 0 2-.9 2-2V4h-2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><g fill="#36c"><path d="M2 15c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2v9l-2.8-2.8L7.4 9V0H4C2.4 0 2 1.6 2 2z"/><path d="M16 18H5v2h11c1.1 0 2-.9 2-2V4h-2z"/></g></svg>
\ No newline at end of file
index 4a5bdbf..d6f36ff 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/referenceExisting-rtl.png differ
index 808fd89..fcff3a9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><path d="M2 2v13c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2v9l-2.8-2.8L7.4 9V0H4C2.4 0 2 1.6 2 2z"/><path d="M16 18H5v2h11c1.1 0 2-.9 2-2V4h-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>existing reference</title><path d="M2 15c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2v9l-2.8-2.8L7.4 9V0H4C2.4 0 2 1.6 2 2z"/><path d="M16 18H5v2h11c1.1 0 2-.9 2-2V4h-2z"/></svg>
\ No newline at end of file
index 2ea0199..8440852 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/references-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/references-ltr-invert.png differ
index 9a8c2c8..8b19c6e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/references-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/references-ltr.png differ
index 6ca8fbd..2925e91 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/references-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/references-rtl-invert.png differ
index 6151b1c..9bf68b9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/references-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/references-rtl.png differ
index 688a062..0e39900 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/reload-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/reload-invert.png differ
index eb01f0f..f9a656f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/reload.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/reload.png differ
index 306987a..2f69606 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/robot-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/robot-invert.png differ
index 7d6fcac..cc2b27b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>robot</title><path fill="#fff" d="M10.5 5h6.505C18.107 5 19 5.896 19 6.997V14h-7v2h5.005c1.102 0 1.995.888 1.995 2v2H1v-2c0-1.105.893-2 1.995-2H8v-2H1V6.997C1 5.894 1.893 5 2.995 5H9.5V2.915a1.5 1.5 0 1 1 1 0V5zm-4 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>robot</title><path fill="#fff" d="M10.5 5h6.505C18.107 5 19 5.896 19 6.997V14h-7v2h5.005c1.102 0 1.995.888 1.995 2v2H1v-2c0-1.105.893-2 1.995-2H8v-2H1V6.997C1 5.894 1.893 5 2.995 5H9.5V2.915a1.5 1.5 0 1 1 1 0zm-4 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/></svg>
\ No newline at end of file
index 1f09f64..5fb8619 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/robot-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/robot-progressive.png differ
index bef3c8a..20bc085 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>robot</title><path fill="#36c" d="M10.5 5h6.505C18.107 5 19 5.896 19 6.997V14h-7v2h5.005c1.102 0 1.995.888 1.995 2v2H1v-2c0-1.105.893-2 1.995-2H8v-2H1V6.997C1 5.894 1.893 5 2.995 5H9.5V2.915a1.5 1.5 0 1 1 1 0V5zm-4 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>robot</title><path fill="#36c" d="M10.5 5h6.505C18.107 5 19 5.896 19 6.997V14h-7v2h5.005c1.102 0 1.995.888 1.995 2v2H1v-2c0-1.105.893-2 1.995-2H8v-2H1V6.997C1 5.894 1.893 5 2.995 5H9.5V2.915a1.5 1.5 0 1 1 1 0zm-4 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/></svg>
\ No newline at end of file
index 1087d13..3bf6253 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/robot.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/robot.png differ
index 6f1072b..498d3a3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>robot</title><path d="M10.5 5h6.505C18.107 5 19 5.896 19 6.997V14h-7v2h5.005c1.102 0 1.995.888 1.995 2v2H1v-2c0-1.105.893-2 1.995-2H8v-2H1V6.997C1 5.894 1.893 5 2.995 5H9.5V2.915a1.5 1.5 0 1 1 1 0V5zm-4 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>robot</title><path d="M10.5 5h6.505C18.107 5 19 5.896 19 6.997V14h-7v2h5.005c1.102 0 1.995.888 1.995 2v2H1v-2c0-1.105.893-2 1.995-2H8v-2H1V6.997C1 5.894 1.893 5 2.995 5H9.5V2.915a1.5 1.5 0 1 1 1 0zm-4 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/></svg>
\ No newline at end of file
index 5201eb1..91dc0c4 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/search-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/search-invert.png differ
index b2ae15b..fe88ca2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/search.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/search.png differ
index 004d9cc..188efc0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive-invert.png differ
index b52715c..98b2625 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive-progressive.png differ
index 485a899..cce75ac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchCaseSensitive.png differ
index 85d87d3..c4cec68 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchDiacritics-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchDiacritics-invert.png differ
index 35007eb..9b10244 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchDiacritics.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchDiacritics.png differ
index ffbc420..8faa99a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-invert.png differ
index 0b0a4fd..923456e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search regular expression</title><path fill="#fff" d="M1.62 10a13.63 13.63 0 0 0 .45 3.51A13.39 13.39 0 0 0 3.4 16.7a.91.91 0 0 1 .1.27.41.41 0 0 1 0 .21.38.38 0 0 1-.1.15l-.14.11-.83.5a14.89 14.89 0 0 1-1.11-2 13.62 13.62 0 0 1-.74-2 13.22 13.22 0 0 1-.42-2 16.4 16.4 0 0 1 0-4.14 13.22 13.22 0 0 1 .42-2 13.84 13.84 0 0 1 .74-2A14.94 14.94 0 0 1 2.4 2l.83.51.14.11a.4.4 0 0 1 .1.15.41.41 0 0 1 0 .21.93.93 0 0 1-.1.27A13.6 13.6 0 0 0 1.62 10zM5 13.51a1.53 1.53 0 0 1 .11-.59 1.5 1.5 0 0 1 .31-.48 1.5 1.5 0 0 1 1.65-.32 1.51 1.51 0 0 1 .8.8 1.47 1.47 0 0 1 .12.59 1.46 1.46 0 0 1-.12.59 1.56 1.56 0 0 1-.32.48 1.46 1.46 0 0 1-.48.32 1.57 1.57 0 0 1-1.18 0 1.4 1.4 0 0 1-.47-.32A1.5 1.5 0 0 1 5 13.51zm10.8-4.72l-.54.94-1.75-1-.34-.23a1.38 1.38 0 0 1-.27-.26A1.84 1.84 0 0 1 13 9v2h-1V9a2.16 2.16 0 0 1 .12-.76 1.82 1.82 0 0 1-.58.48l-1.74 1-.54-.94 1.73-1a2.25 2.25 0 0 1 .75-.29 1.77 1.77 0 0 1-.75-.28L9.2 6.2l.54-.94 1.75 1 .33.24a1.64 1.64 0 0 1 .27.27A2 2 0 0 1 12 6V4h1v2a2.93 2.93 0 0 1 0 .4 1.36 1.36 0 0 1-.1.36 2.24 2.24 0 0 1 .59-.49l1.74-1 .54.94-1.73 1-.36.18a1.29 1.29 0 0 1-.36.1 2.11 2.11 0 0 1 .36.1 2 2 0 0 1 .36.19zM18.37 10a13.65 13.65 0 0 0-.45-3.51 13.81 13.81 0 0 0-1.32-3.27.93.93 0 0 1-.1-.27.45.45 0 0 1 0-.21.36.36 0 0 1 .1-.15l.14-.11.86-.48a15.54 15.54 0 0 1 1.1 2 13.79 13.79 0 0 1 .74 2 13.18 13.18 0 0 1 .42 2 16.16 16.16 0 0 1 .14 2 16.21 16.21 0 0 1-.13 2 13.18 13.18 0 0 1-.42 2 13.57 13.57 0 0 1-.74 2 15.49 15.49 0 0 1-1.1 2l-.84-.5-.14-.11a.35.35 0 0 1-.1-.15.44.44 0 0 1 0-.21.91.91 0 0 1 .1-.27 13.62 13.62 0 0 0 1.31-3.23 13.69 13.69 0 0 0 .43-3.53z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search regular expression</title><g fill="#fff"><path d="M1.62 10a13.63 13.63 0 0 0 .45 3.51A13.39 13.39 0 0 0 3.4 16.7a.91.91 0 0 1 .1.27.41.41 0 0 1 0 .21.38.38 0 0 1-.1.15l-.14.11-.83.5a14.89 14.89 0 0 1-1.11-2 13.62 13.62 0 0 1-.74-2 13.22 13.22 0 0 1-.42-2 16.4 16.4 0 0 1 0-4.14 13.22 13.22 0 0 1 .42-2 13.84 13.84 0 0 1 .74-2A14.94 14.94 0 0 1 2.4 2l.83.51.14.11a.4.4 0 0 1 .1.15.41.41 0 0 1 0 .21.93.93 0 0 1-.1.27A13.6 13.6 0 0 0 1.62 10zM15.8 8.79l-.54.94-1.75-1-.34-.23a1.38 1.38 0 0 1-.27-.26A1.84 1.84 0 0 1 13 9v2h-1V9a2.16 2.16 0 0 1 .12-.76 1.82 1.82 0 0 1-.58.48l-1.74 1-.54-.94 1.73-1a2.25 2.25 0 0 1 .75-.29 1.77 1.77 0 0 1-.75-.28L9.2 6.2l.54-.94 1.75 1 .33.24a1.64 1.64 0 0 1 .27.27A2 2 0 0 1 12 6V4h1v2a2.93 2.93 0 0 1 0 .4 1.36 1.36 0 0 1-.1.36 2.24 2.24 0 0 1 .59-.49l1.74-1 .54.94-1.73 1-.36.18a1.29 1.29 0 0 1-.36.1 2.11 2.11 0 0 1 .36.1 2 2 0 0 1 .36.19zM18.37 10a13.65 13.65 0 0 0-.45-3.51 13.81 13.81 0 0 0-1.32-3.27.93.93 0 0 1-.1-.27.45.45 0 0 1 0-.21.36.36 0 0 1 .1-.15l.14-.11.86-.48a15.54 15.54 0 0 1 1.1 2 13.79 13.79 0 0 1 .74 2 13.18 13.18 0 0 1 .42 2 16.16 16.16 0 0 1 .14 2 16.21 16.21 0 0 1-.13 2 13.18 13.18 0 0 1-.42 2 13.57 13.57 0 0 1-.74 2 15.49 15.49 0 0 1-1.1 2l-.84-.5-.14-.11a.35.35 0 0 1-.1-.15.44.44 0 0 1 0-.21.91.91 0 0 1 .1-.27 13.62 13.62 0 0 0 1.31-3.23 13.69 13.69 0 0 0 .43-3.53z"/><circle cx="6.5" cy="13.5" r="1.5"/></g></svg>
\ No newline at end of file
index 6f7af96..0a83e94 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression-progressive.png differ
index 8a5b221..032e5f5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search regular expression</title><path fill="#36c" d="M1.62 10a13.63 13.63 0 0 0 .45 3.51A13.39 13.39 0 0 0 3.4 16.7a.91.91 0 0 1 .1.27.41.41 0 0 1 0 .21.38.38 0 0 1-.1.15l-.14.11-.83.5a14.89 14.89 0 0 1-1.11-2 13.62 13.62 0 0 1-.74-2 13.22 13.22 0 0 1-.42-2 16.4 16.4 0 0 1 0-4.14 13.22 13.22 0 0 1 .42-2 13.84 13.84 0 0 1 .74-2A14.94 14.94 0 0 1 2.4 2l.83.51.14.11a.4.4 0 0 1 .1.15.41.41 0 0 1 0 .21.93.93 0 0 1-.1.27A13.6 13.6 0 0 0 1.62 10zM5 13.51a1.53 1.53 0 0 1 .11-.59 1.5 1.5 0 0 1 .31-.48 1.5 1.5 0 0 1 1.65-.32 1.51 1.51 0 0 1 .8.8 1.47 1.47 0 0 1 .12.59 1.46 1.46 0 0 1-.12.59 1.56 1.56 0 0 1-.32.48 1.46 1.46 0 0 1-.48.32 1.57 1.57 0 0 1-1.18 0 1.4 1.4 0 0 1-.47-.32A1.5 1.5 0 0 1 5 13.51zm10.8-4.72l-.54.94-1.75-1-.34-.23a1.38 1.38 0 0 1-.27-.26A1.84 1.84 0 0 1 13 9v2h-1V9a2.16 2.16 0 0 1 .12-.76 1.82 1.82 0 0 1-.58.48l-1.74 1-.54-.94 1.73-1a2.25 2.25 0 0 1 .75-.29 1.77 1.77 0 0 1-.75-.28L9.2 6.2l.54-.94 1.75 1 .33.24a1.64 1.64 0 0 1 .27.27A2 2 0 0 1 12 6V4h1v2a2.93 2.93 0 0 1 0 .4 1.36 1.36 0 0 1-.1.36 2.24 2.24 0 0 1 .59-.49l1.74-1 .54.94-1.73 1-.36.18a1.29 1.29 0 0 1-.36.1 2.11 2.11 0 0 1 .36.1 2 2 0 0 1 .36.19zM18.37 10a13.65 13.65 0 0 0-.45-3.51 13.81 13.81 0 0 0-1.32-3.27.93.93 0 0 1-.1-.27.45.45 0 0 1 0-.21.36.36 0 0 1 .1-.15l.14-.11.86-.48a15.54 15.54 0 0 1 1.1 2 13.79 13.79 0 0 1 .74 2 13.18 13.18 0 0 1 .42 2 16.16 16.16 0 0 1 .14 2 16.21 16.21 0 0 1-.13 2 13.18 13.18 0 0 1-.42 2 13.57 13.57 0 0 1-.74 2 15.49 15.49 0 0 1-1.1 2l-.84-.5-.14-.11a.35.35 0 0 1-.1-.15.44.44 0 0 1 0-.21.91.91 0 0 1 .1-.27 13.62 13.62 0 0 0 1.31-3.23 13.69 13.69 0 0 0 .43-3.53z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search regular expression</title><g fill="#36c"><path d="M1.62 10a13.63 13.63 0 0 0 .45 3.51A13.39 13.39 0 0 0 3.4 16.7a.91.91 0 0 1 .1.27.41.41 0 0 1 0 .21.38.38 0 0 1-.1.15l-.14.11-.83.5a14.89 14.89 0 0 1-1.11-2 13.62 13.62 0 0 1-.74-2 13.22 13.22 0 0 1-.42-2 16.4 16.4 0 0 1 0-4.14 13.22 13.22 0 0 1 .42-2 13.84 13.84 0 0 1 .74-2A14.94 14.94 0 0 1 2.4 2l.83.51.14.11a.4.4 0 0 1 .1.15.41.41 0 0 1 0 .21.93.93 0 0 1-.1.27A13.6 13.6 0 0 0 1.62 10zM15.8 8.79l-.54.94-1.75-1-.34-.23a1.38 1.38 0 0 1-.27-.26A1.84 1.84 0 0 1 13 9v2h-1V9a2.16 2.16 0 0 1 .12-.76 1.82 1.82 0 0 1-.58.48l-1.74 1-.54-.94 1.73-1a2.25 2.25 0 0 1 .75-.29 1.77 1.77 0 0 1-.75-.28L9.2 6.2l.54-.94 1.75 1 .33.24a1.64 1.64 0 0 1 .27.27A2 2 0 0 1 12 6V4h1v2a2.93 2.93 0 0 1 0 .4 1.36 1.36 0 0 1-.1.36 2.24 2.24 0 0 1 .59-.49l1.74-1 .54.94-1.73 1-.36.18a1.29 1.29 0 0 1-.36.1 2.11 2.11 0 0 1 .36.1 2 2 0 0 1 .36.19zM18.37 10a13.65 13.65 0 0 0-.45-3.51 13.81 13.81 0 0 0-1.32-3.27.93.93 0 0 1-.1-.27.45.45 0 0 1 0-.21.36.36 0 0 1 .1-.15l.14-.11.86-.48a15.54 15.54 0 0 1 1.1 2 13.79 13.79 0 0 1 .74 2 13.18 13.18 0 0 1 .42 2 16.16 16.16 0 0 1 .14 2 16.21 16.21 0 0 1-.13 2 13.18 13.18 0 0 1-.42 2 13.57 13.57 0 0 1-.74 2 15.49 15.49 0 0 1-1.1 2l-.84-.5-.14-.11a.35.35 0 0 1-.1-.15.44.44 0 0 1 0-.21.91.91 0 0 1 .1-.27 13.62 13.62 0 0 0 1.31-3.23 13.69 13.69 0 0 0 .43-3.53z"/><circle cx="6.5" cy="13.5" r="1.5"/></g></svg>
\ No newline at end of file
index 7be8f3d..8183b1a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/searchRegularExpression.png differ
index b6d101f..8212db0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search regular expression</title><path d="M1.62 10a13.63 13.63 0 0 0 .45 3.51A13.39 13.39 0 0 0 3.4 16.7a.91.91 0 0 1 .1.27.41.41 0 0 1 0 .21.38.38 0 0 1-.1.15l-.14.11-.83.5a14.89 14.89 0 0 1-1.11-2 13.62 13.62 0 0 1-.74-2 13.22 13.22 0 0 1-.42-2 16.4 16.4 0 0 1 0-4.14 13.22 13.22 0 0 1 .42-2 13.84 13.84 0 0 1 .74-2A14.94 14.94 0 0 1 2.4 2l.83.51.14.11a.4.4 0 0 1 .1.15.41.41 0 0 1 0 .21.93.93 0 0 1-.1.27A13.6 13.6 0 0 0 1.62 10zM5 13.51a1.53 1.53 0 0 1 .11-.59 1.5 1.5 0 0 1 .31-.48 1.5 1.5 0 0 1 1.65-.32 1.51 1.51 0 0 1 .8.8 1.47 1.47 0 0 1 .12.59 1.46 1.46 0 0 1-.12.59 1.56 1.56 0 0 1-.32.48 1.46 1.46 0 0 1-.48.32 1.57 1.57 0 0 1-1.18 0 1.4 1.4 0 0 1-.47-.32A1.5 1.5 0 0 1 5 13.51zm10.8-4.72l-.54.94-1.75-1-.34-.23a1.38 1.38 0 0 1-.27-.26A1.84 1.84 0 0 1 13 9v2h-1V9a2.16 2.16 0 0 1 .12-.76 1.82 1.82 0 0 1-.58.48l-1.74 1-.54-.94 1.73-1a2.25 2.25 0 0 1 .75-.29 1.77 1.77 0 0 1-.75-.28L9.2 6.2l.54-.94 1.75 1 .33.24a1.64 1.64 0 0 1 .27.27A2 2 0 0 1 12 6V4h1v2a2.93 2.93 0 0 1 0 .4 1.36 1.36 0 0 1-.1.36 2.24 2.24 0 0 1 .59-.49l1.74-1 .54.94-1.73 1-.36.18a1.29 1.29 0 0 1-.36.1 2.11 2.11 0 0 1 .36.1 2 2 0 0 1 .36.19zM18.37 10a13.65 13.65 0 0 0-.45-3.51 13.81 13.81 0 0 0-1.32-3.27.93.93 0 0 1-.1-.27.45.45 0 0 1 0-.21.36.36 0 0 1 .1-.15l.14-.11.86-.48a15.54 15.54 0 0 1 1.1 2 13.79 13.79 0 0 1 .74 2 13.18 13.18 0 0 1 .42 2 16.16 16.16 0 0 1 .14 2 16.21 16.21 0 0 1-.13 2 13.18 13.18 0 0 1-.42 2 13.57 13.57 0 0 1-.74 2 15.49 15.49 0 0 1-1.1 2l-.84-.5-.14-.11a.35.35 0 0 1-.1-.15.44.44 0 0 1 0-.21.91.91 0 0 1 .1-.27 13.62 13.62 0 0 0 1.31-3.23 13.69 13.69 0 0 0 .43-3.53z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search regular expression</title><path d="M1.62 10a13.63 13.63 0 0 0 .45 3.51A13.39 13.39 0 0 0 3.4 16.7a.91.91 0 0 1 .1.27.41.41 0 0 1 0 .21.38.38 0 0 1-.1.15l-.14.11-.83.5a14.89 14.89 0 0 1-1.11-2 13.62 13.62 0 0 1-.74-2 13.22 13.22 0 0 1-.42-2 16.4 16.4 0 0 1 0-4.14 13.22 13.22 0 0 1 .42-2 13.84 13.84 0 0 1 .74-2A14.94 14.94 0 0 1 2.4 2l.83.51.14.11a.4.4 0 0 1 .1.15.41.41 0 0 1 0 .21.93.93 0 0 1-.1.27A13.6 13.6 0 0 0 1.62 10zM15.8 8.79l-.54.94-1.75-1-.34-.23a1.38 1.38 0 0 1-.27-.26A1.84 1.84 0 0 1 13 9v2h-1V9a2.16 2.16 0 0 1 .12-.76 1.82 1.82 0 0 1-.58.48l-1.74 1-.54-.94 1.73-1a2.25 2.25 0 0 1 .75-.29 1.77 1.77 0 0 1-.75-.28L9.2 6.2l.54-.94 1.75 1 .33.24a1.64 1.64 0 0 1 .27.27A2 2 0 0 1 12 6V4h1v2a2.93 2.93 0 0 1 0 .4 1.36 1.36 0 0 1-.1.36 2.24 2.24 0 0 1 .59-.49l1.74-1 .54.94-1.73 1-.36.18a1.29 1.29 0 0 1-.36.1 2.11 2.11 0 0 1 .36.1 2 2 0 0 1 .36.19zM18.37 10a13.65 13.65 0 0 0-.45-3.51 13.81 13.81 0 0 0-1.32-3.27.93.93 0 0 1-.1-.27.45.45 0 0 1 0-.21.36.36 0 0 1 .1-.15l.14-.11.86-.48a15.54 15.54 0 0 1 1.1 2 13.79 13.79 0 0 1 .74 2 13.18 13.18 0 0 1 .42 2 16.16 16.16 0 0 1 .14 2 16.21 16.21 0 0 1-.13 2 13.18 13.18 0 0 1-.42 2 13.57 13.57 0 0 1-.74 2 15.49 15.49 0 0 1-1.1 2l-.84-.5-.14-.11a.35.35 0 0 1-.1-.15.44.44 0 0 1 0-.21.91.91 0 0 1 .1-.27 13.62 13.62 0 0 0 1.31-3.23 13.69 13.69 0 0 0 .43-3.53z"/><circle cx="6.5" cy="13.5" r="1.5"/></svg>
\ No newline at end of file
index d0ea817..26d83fd 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/settings-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/settings-invert.png differ
index 3fea1b9..18d7c79 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>settings</title><g fill="#fff"><path d="M10 2.5a7.5 7.5 0 1 0 7.5 7.5A7.5 7.5 0 0 0 10 2.5zm0 11a3.5 3.5 0 1 1 3.5-3.5 3.5 3.5 0 0 1-3.5 3.5z"/><path d="M12 3.29L11.5 0h-3L8 3.29a7 7 0 0 1 4 0zM8 16.71L8.5 20h3l.5-3.29a7 7 0 0 1-4 0zm8.16-10.04l2-2.68L16 1.87l-2.68 2a7 7 0 0 1 2.83 2.83zM3.84 13.33L1.87 16 4 18.13l2.68-2a7 7 0 0 1-2.83-2.83zM16.71 12l3.29-.5v-3L16.71 8a7 7 0 0 1 0 4zM3.29 8L0 8.5v3l3.29.5a7 7 0 0 1 0-4zm10.04 8.16l2.68 2L18.13 16l-2-2.68a7 7 0 0 1-2.83 2.83zM6.67 3.84L4 1.87 1.87 4l2 2.68a7 7 0 0 1 2.8-2.84z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>settings</title><g fill="#fff"><path d="M10 2.5a7.5 7.5 0 1 0 7.5 7.5A7.5 7.5 0 0 0 10 2.5zm0 11a3.5 3.5 0 1 1 3.5-3.5 3.5 3.5 0 0 1-3.5 3.5z"/><path d="M12.5 6.5l-1-6.5h-3l-1 6.5m0 7l1 6.5h3l1-6.5m1-1l6.5-1v-3l-6.5-1m-7 0L0 8.5v3l6.5 1m7.743-3.207l3.889-5.303-2.122-2.122-5.303 3.89m-4.95 4.95L1.868 16.01l2.122 2.122 5.303-3.89m0-8.485L3.99 1.868 1.868 3.99l3.89 5.303m4.95 4.95l5.302 3.889 2.122-2.122-3.89-5.303"/></g></svg>
\ No newline at end of file
index ba7944e..933f8ce 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/settings-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/settings-progressive.png differ
index 50ce6a2..6ba9245 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>settings</title><g fill="#36c"><path d="M10 2.5a7.5 7.5 0 1 0 7.5 7.5A7.5 7.5 0 0 0 10 2.5zm0 11a3.5 3.5 0 1 1 3.5-3.5 3.5 3.5 0 0 1-3.5 3.5z"/><path d="M12 3.29L11.5 0h-3L8 3.29a7 7 0 0 1 4 0zM8 16.71L8.5 20h3l.5-3.29a7 7 0 0 1-4 0zm8.16-10.04l2-2.68L16 1.87l-2.68 2a7 7 0 0 1 2.83 2.83zM3.84 13.33L1.87 16 4 18.13l2.68-2a7 7 0 0 1-2.83-2.83zM16.71 12l3.29-.5v-3L16.71 8a7 7 0 0 1 0 4zM3.29 8L0 8.5v3l3.29.5a7 7 0 0 1 0-4zm10.04 8.16l2.68 2L18.13 16l-2-2.68a7 7 0 0 1-2.83 2.83zM6.67 3.84L4 1.87 1.87 4l2 2.68a7 7 0 0 1 2.8-2.84z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>settings</title><g fill="#36c"><path d="M10 2.5a7.5 7.5 0 1 0 7.5 7.5A7.5 7.5 0 0 0 10 2.5zm0 11a3.5 3.5 0 1 1 3.5-3.5 3.5 3.5 0 0 1-3.5 3.5z"/><path d="M12.5 6.5l-1-6.5h-3l-1 6.5m0 7l1 6.5h3l1-6.5m1-1l6.5-1v-3l-6.5-1m-7 0L0 8.5v3l6.5 1m7.743-3.207l3.889-5.303-2.122-2.122-5.303 3.89m-4.95 4.95L1.868 16.01l2.122 2.122 5.303-3.89m0-8.485L3.99 1.868 1.868 3.99l3.89 5.303m4.95 4.95l5.302 3.889 2.122-2.122-3.89-5.303"/></g></svg>
\ No newline at end of file
index c0379e8..8c8e16a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/settings.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/settings.png differ
index bdc37cf..c58f812 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>settings</title><path d="M10 2.5a7.5 7.5 0 1 0 7.5 7.5A7.5 7.5 0 0 0 10 2.5zm0 11a3.5 3.5 0 1 1 3.5-3.5 3.5 3.5 0 0 1-3.5 3.5z"/><path d="M12 3.29L11.5 0h-3L8 3.29a7 7 0 0 1 4 0zM8 16.71L8.5 20h3l.5-3.29a7 7 0 0 1-4 0zm8.16-10.04l2-2.68L16 1.87l-2.68 2a7 7 0 0 1 2.83 2.83zM3.84 13.33L1.87 16 4 18.13l2.68-2a7 7 0 0 1-2.83-2.83zM16.71 12l3.29-.5v-3L16.71 8a7 7 0 0 1 0 4zM3.29 8L0 8.5v3l3.29.5a7 7 0 0 1 0-4zm10.04 8.16l2.68 2L18.13 16l-2-2.68a7 7 0 0 1-2.83 2.83zM6.67 3.84L4 1.87 1.87 4l2 2.68a7 7 0 0 1 2.8-2.84z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>settings</title><path d="M10 2.5a7.5 7.5 0 1 0 7.5 7.5A7.5 7.5 0 0 0 10 2.5zm0 11a3.5 3.5 0 1 1 3.5-3.5 3.5 3.5 0 0 1-3.5 3.5z"/><path d="M12.5 6.5l-1-6.5h-3l-1 6.5m0 7l1 6.5h3l1-6.5m1-1l6.5-1v-3l-6.5-1m-7 0L0 8.5v3l6.5 1m7.743-3.207l3.889-5.303-2.122-2.122-5.303 3.89m-4.95 4.95L1.868 16.01l2.122 2.122 5.303-3.89m0-8.485L3.99 1.868 1.868 3.99l3.89 5.303m4.95 4.95l5.302 3.889 2.122-2.122-3.89-5.303"/></svg>
\ No newline at end of file
index cbf867a..da9e38c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr-invert.png differ
index c37fc61..9a08c1c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr-progressive.png differ
index c53ad5d..ebb9a09 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/signature-ltr.png differ
index 6f9ea07..8caf326 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl-invert.png differ
index 1de7923..d001287 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl-progressive.png differ
index 4fa395f..c9443e2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/signature-rtl.png differ
index 7be944b..964b0ff 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/smaller-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/smaller-invert.png differ
index ef33db2..f615042 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>smaller</title><path fill="#fff" d="M12 16h-1.05a.44.44 0 0 1-.29-.09.58.58 0 0 1-.17-.22l-.7-1.84H6.2l-.7 1.84a.56.56 0 0 1-.16.21.43.43 0 0 1-.29.1H4l3.31-8.35h1.38zm-2.57-3.13L8.28 9.82a8.5 8.5 0 0 1-.28-.9q-.06.27-.14.5l-.14.4-1.15 3zM15 6l3-4h-6l3 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>smaller</title><path fill="#fff" d="M12 16h-1.05a.44.44 0 0 1-.29-.09.58.58 0 0 1-.17-.22l-.7-1.84H6.2l-.7 1.84a.56.56 0 0 1-.16.21.43.43 0 0 1-.29.1H4l3.31-8.35h1.38zm-2.57-3.13L8.28 9.82a8.5 8.5 0 0 1-.28-.9q-.06.27-.14.5l-.14.4-1.15 3zM15 6l3-4h-6z"/></svg>
\ No newline at end of file
index ee35f8f..0ced2c0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>smaller</title><path fill="#36c" d="M12 16h-1.05a.44.44 0 0 1-.29-.09.58.58 0 0 1-.17-.22l-.7-1.84H6.2l-.7 1.84a.56.56 0 0 1-.16.21.43.43 0 0 1-.29.1H4l3.31-8.35h1.38zm-2.57-3.13L8.28 9.82a8.5 8.5 0 0 1-.28-.9q-.06.27-.14.5l-.14.4-1.15 3zM15 6l3-4h-6l3 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>smaller</title><path fill="#36c" d="M12 16h-1.05a.44.44 0 0 1-.29-.09.58.58 0 0 1-.17-.22l-.7-1.84H6.2l-.7 1.84a.56.56 0 0 1-.16.21.43.43 0 0 1-.29.1H4l3.31-8.35h1.38zm-2.57-3.13L8.28 9.82a8.5 8.5 0 0 1-.28-.9q-.06.27-.14.5l-.14.4-1.15 3zM15 6l3-4h-6z"/></svg>
\ No newline at end of file
index bb5a8db..1378f59 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/smaller.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/smaller.png differ
index e498829..94203dc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>smaller</title><path d="M12 16h-1.05a.44.44 0 0 1-.29-.09.58.58 0 0 1-.17-.22l-.7-1.84H6.2l-.7 1.84a.56.56 0 0 1-.16.21.43.43 0 0 1-.29.1H4l3.31-8.35h1.38zm-2.57-3.13L8.28 9.82a8.5 8.5 0 0 1-.28-.9q-.06.27-.14.5l-.14.4-1.15 3zM15 6l3-4h-6l3 4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>smaller</title><path d="M12 16h-1.05a.44.44 0 0 1-.29-.09.58.58 0 0 1-.17-.22l-.7-1.84H6.2l-.7 1.84a.56.56 0 0 1-.16.21.43.43 0 0 1-.29.1H4l3.31-8.35h1.38zm-2.57-3.13L8.28 9.82a8.5 8.5 0 0 1-.28-.9q-.06.27-.14.5l-.14.4-1.15 3zM15 6l3-4h-6z"/></svg>
\ No newline at end of file
index e00ab01..30071c0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/smallerText-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/smallerText-invert.png differ
index 997b4de..910ee15 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/smallerText.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/smallerText.png differ
index e1954ce..c81e6b7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/specialCharacter-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/specialCharacter-invert.png differ
index 9137cac..673bffb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/specialCharacter.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/specialCharacter.png differ
index 13360c1..aa7d64b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-invert.png differ
index 74204f1..585a5de 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path fill="#fff" d="M18 0H2a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><g fill="#fff"><path d="M6 14H0v6z"/><rect width="20" height="16" rx="2"/></g></svg>
\ No newline at end of file
index 9b60865..2e2bb83 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr-progressive.png differ
index ad6c192..d608028 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path fill="#36c" d="M18 0H2a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><g fill="#36c"><path d="M6 14H0v6z"/><rect width="20" height="16" rx="2"/></g></svg>
\ No newline at end of file
index 87bc57d..5cbcb90 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-ltr.png differ
index 0b55276..750767a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path d="M18 0H2a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path d="M6 14H0v6z"/><rect width="20" height="16" rx="2"/></svg>
\ No newline at end of file
index 86171f1..ec5232c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-invert.png differ
index 590a316..c171c5f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path fill="#fff" d="M0 2v12c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><g fill="#fff"><path d="M14 14h6v6z"/><rect width="20" height="16" rx="2"/></g></svg>
\ No newline at end of file
index c5019da..e1c4cbf 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl-progressive.png differ
index 4a29ccf..133358f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path fill="#36c" d="M0 2v12c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><g fill="#36c"><path d="M14 14h6v6z"/><rect width="20" height="16" rx="2"/></g></svg>
\ No newline at end of file
index e8f187c..c16b560 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubble-rtl.png differ
index eae7171..c3f3095 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path d="M0 2v12c0 1.1.9 2 2 2h14l4 4V2c0-1.1-.9-2-2-2H2C.9 0 0 .9 0 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubble</title><path d="M14 14h6v6z"/><rect width="20" height="16" rx="2"/></svg>
\ No newline at end of file
index bf72832..082aff0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr-invert.png differ
index 58f9c0b..102881c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#fff" d="M17 1H3a2 2 0 0 0-2 2v16l4-4h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm-2 8h-4v4H9V9H5V7h4V3h2v4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#fff" d="M3 1a2 2 0 0 0-2 2v16l4-4h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm12 8h-4v4H9V9H5V7h4V3h2v4h4z"/></svg>
\ No newline at end of file
index 1d7e3ab..4c22e79 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#36c" d="M17 1H3a2 2 0 0 0-2 2v16l4-4h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm-2 8h-4v4H9V9H5V7h4V3h2v4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#36c" d="M3 1a2 2 0 0 0-2 2v16l4-4h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm12 8h-4v4H9V9H5V7h4V3h2v4h4z"/></svg>
\ No newline at end of file
index a361f49..1bc0c91 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-ltr.png differ
index ed3dc5a..67351e6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path d="M17 1H3a2 2 0 0 0-2 2v16l4-4h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm-2 8h-4v4H9V9H5V7h4V3h2v4h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path d="M3 1a2 2 0 0 0-2 2v16l4-4h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm12 8h-4v4H9V9H5V7h4V3h2v4h4z"/></svg>
\ No newline at end of file
index 39271e1..4cba028 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl-invert.png differ
index de48255..3755f4f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#fff" d="M1 3v10c0 1.1.9 2 2 2h12l4 4V3c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2zm4 4h4V3h2v4h4v2h-4v4H9V9H5V7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#fff" d="M1 3v10c0 1.1.9 2 2 2h12l4 4V3c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2zm4 4h4V3h2v4h4v2h-4v4H9V9H5z"/></svg>
\ No newline at end of file
index db6c3bd..358222b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#36c" d="M1 3v10c0 1.1.9 2 2 2h12l4 4V3c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2zm4 4h4V3h2v4h4v2h-4v4H9V9H5V7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path fill="#36c" d="M1 3v10c0 1.1.9 2 2 2h12l4 4V3c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2zm4 4h4V3h2v4h4v2h-4v4H9V9H5z"/></svg>
\ No newline at end of file
index 9d5bb21..5de5177 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbleAdd-rtl.png differ
index ac5a8f7..3c6aad2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path d="M1 3v10c0 1.1.9 2 2 2h12l4 4V3c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2zm4 4h4V3h2v4h4v2h-4v4H9V9H5V7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add speech bubble</title><path d="M1 3v10c0 1.1.9 2 2 2h12l4 4V3c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2zm4 4h4V3h2v4h4v2h-4v4H9V9H5z"/></svg>
\ No newline at end of file
index 83aa9da..a0cb357 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-invert.png differ
index 3008518..197c0ac 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#fff"><path d="M18 4h-1v7a2 2 0 0 1-2 2H4v1a2 2 0 0 0 2 2h10l4 4V6a2 2 0 0 0-2-2z"/><path d="M14 0H2a2 2 0 0 0-2 2v14l4-4h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#fff"><path d="M17 4v7a2 2 0 0 1-2 2H4v1a2 2 0 0 0 2 2h10l4 4V6a2 2 0 0 0-2-2zM6 10H0v6z"/><rect width="16" height="12" rx="2"/></g></svg>
\ No newline at end of file
index 3a8911c..1424b22 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr-progressive.png differ
index 53e111f..5d02383 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#36c"><path d="M18 4h-1v7a2 2 0 0 1-2 2H4v1a2 2 0 0 0 2 2h10l4 4V6a2 2 0 0 0-2-2z"/><path d="M14 0H2a2 2 0 0 0-2 2v14l4-4h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#36c"><path d="M17 4v7a2 2 0 0 1-2 2H4v1a2 2 0 0 0 2 2h10l4 4V6a2 2 0 0 0-2-2zM6 10H0v6z"/><rect width="16" height="12" rx="2"/></g></svg>
\ No newline at end of file
index 148e525..09f6008 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-ltr.png differ
index eb1a817..d738920 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><path d="M18 4h-1v7a2 2 0 0 1-2 2H4v1a2 2 0 0 0 2 2h10l4 4V6a2 2 0 0 0-2-2z"/><path d="M14 0H2a2 2 0 0 0-2 2v14l4-4h10a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><path d="M17 4v7a2 2 0 0 1-2 2H4v1a2 2 0 0 0 2 2h10l4 4V6a2 2 0 0 0-2-2zM6 10H0v6z"/><rect width="16" height="12" rx="2"/></svg>
\ No newline at end of file
index c175602..39ccc22 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-invert.png differ
index 954fde0..ceb9e2f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#fff"><path d="M0 6v14l4-4h10c1.1 0 2-.9 2-2v-1H5c-1.1 0-2-.9-2-2V4H2C.9 4 0 4.9 0 6z"/><path d="M4 2v8c0 1.1.9 2 2 2h10l4 4V2c0-1.1-.9-2-2-2H6C4.9 0 4 .9 4 2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#fff"><path d="M0 20l4-4h10c1.1 0 2-.9 2-2v-1H5c-1.1 0-2-.9-2-2V4H2C.9 4 0 4.9 0 6zm14-10h6v6z"/><rect width="16" height="12" x="4" rx="2"/></g></svg>
\ No newline at end of file
index de49d4a..2013f44 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl-progressive.png differ
index 6fbd55c..d36b28d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#36c"><path d="M0 6v14l4-4h10c1.1 0 2-.9 2-2v-1H5c-1.1 0-2-.9-2-2V4H2C.9 4 0 4.9 0 6z"/><path d="M4 2v8c0 1.1.9 2 2 2h10l4 4V2c0-1.1-.9-2-2-2H6C4.9 0 4 .9 4 2z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><g fill="#36c"><path d="M0 20l4-4h10c1.1 0 2-.9 2-2v-1H5c-1.1 0-2-.9-2-2V4H2C.9 4 0 4.9 0 6zm14-10h6v6z"/><rect width="16" height="12" x="4" rx="2"/></g></svg>
\ No newline at end of file
index 6ac7730..c5951df 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/speechBubbles-rtl.png differ
index a816817..32d7302 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><path d="M0 6v14l4-4h10c1.1 0 2-.9 2-2v-1H5c-1.1 0-2-.9-2-2V4H2C.9 4 0 4.9 0 6z"/><path d="M4 2v8c0 1.1.9 2 2 2h10l4 4V2c0-1.1-.9-2-2-2H6C4.9 0 4 .9 4 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>speech bubbles</title><path d="M0 20l4-4h10c1.1 0 2-.9 2-2v-1H5c-1.1 0-2-.9-2-2V4H2C.9 4 0 4.9 0 6zm14-10h6v6z"/><rect width="16" height="12" x="4" rx="2"/></svg>
\ No newline at end of file
index ac66cd5..3f1f8d6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/star-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/star-invert.png differ
index 4bcc0dd..8f87a43 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/star.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/star.png differ
index 486a53b..c453b79 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stop-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stop-invert.png differ
index f504fd9..76695c6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>stop</title><rect width="16" height="16" x="2" y="2" fill="#fff" rx="1" ry="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>stop</title><rect width="16" height="16" x="2" y="2" fill="#fff" rx="1"/></svg>
\ No newline at end of file
index 42e64e5..d3fba4f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>stop</title><rect width="16" height="16" x="2" y="2" fill="#36c" rx="1" ry="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>stop</title><rect width="16" height="16" x="2" y="2" fill="#36c" rx="1"/></svg>
\ No newline at end of file
index 90294bb..dc8feb2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stop.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stop.png differ
index 8c50cce..4a2652d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>stop</title><rect width="16" height="16" x="2" y="2" rx="1" ry="1"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>stop</title><rect width="16" height="16" x="2" y="2" rx="1"/></svg>
\ No newline at end of file
index 6fb30b4..495aeb2 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a-invert.png differ
index 1e09d18..aa145c8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path fill="#fff" d="M8.285 2L5.928 8H8.59L10 3.979 11.41 8h2.662l-2.357-6h-3.43zM1 10v2h3.357L2 18h3.06l1.622-4.566h6.636L14.94 18H18l-2.357-6H19v-2H1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path fill="#fff" d="M5.928 8H8.59L10 3.979 11.41 8h2.662l-2.357-6h-3.43zM1 10v2h3.357L2 18h3.06l1.622-4.566h6.636L14.94 18H18l-2.357-6H19v-2z"/></svg>
\ No newline at end of file
index bb9cf1a..f13286d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path fill="#36c" d="M8.285 2L5.928 8H8.59L10 3.979 11.41 8h2.662l-2.357-6h-3.43zM1 10v2h3.357L2 18h3.06l1.622-4.566h6.636L14.94 18H18l-2.357-6H19v-2H1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path fill="#36c" d="M5.928 8H8.59L10 3.979 11.41 8h2.662l-2.357-6h-3.43zM1 10v2h3.357L2 18h3.06l1.622-4.566h6.636L14.94 18H18l-2.357-6H19v-2z"/></svg>
\ No newline at end of file
index 5a9960c..768544d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-a.png differ
index f9f5d04..acf4205 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path d="M8.285 2L5.928 8H8.59L10 3.979 11.41 8h2.662l-2.357-6h-3.43zM1 10v2h3.357L2 18h3.06l1.622-4.566h6.636L14.94 18H18l-2.357-6H19v-2H1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path d="M5.928 8H8.59L10 3.979 11.41 8h2.662l-2.357-6h-3.43zM1 10v2h3.357L2 18h3.06l1.622-4.566h6.636L14.94 18H18l-2.357-6H19v-2z"/></svg>
\ No newline at end of file
index 0ea4dfe..471c0ed 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-s-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-s-invert.png differ
index 3bad145..68187b7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-s.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-s.png differ
index b754ff8..0deb378 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y-invert.png differ
index 7ec7023..416943d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>strikethrough</title><path d="M3.334 2l4.004 6h2.29L5.634 2h-2.3zm11.033 0l-3.969 6h2.264l4.004-6h-2.299zM1 10v2h7.926v6h2.148v-6H19v-2H1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#fff"><title>strikethrough</title><path d="M7.338 8h2.29L5.634 2h-2.3zm3.06 0h2.264l4.004-6h-2.299zM1 10v2h7.926v6h2.148v-6H19v-2z"/></g></svg>
\ No newline at end of file
index f3707a8..6e84c3a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>strikethrough</title><path d="M3.334 2l4.004 6h2.29L5.634 2h-2.3zm11.033 0l-3.969 6h2.264l4.004-6h-2.299zM1 10v2h7.926v6h2.148v-6H19v-2H1z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g fill="#36c"><title>strikethrough</title><path d="M7.338 8h2.29L5.634 2h-2.3zm3.06 0h2.264l4.004-6h-2.299zM1 10v2h7.926v6h2.148v-6H19v-2z"/></g></svg>
\ No newline at end of file
index e4a3383..c092879 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/strikethrough-y.png differ
index 045f04f..e5e76f2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path d="M3.334 2l4.004 6h2.29L5.634 2h-2.3zm11.033 0l-3.969 6h2.264l4.004-6h-2.299zM1 10v2h7.926v6h2.148v-6H19v-2H1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>strikethrough</title><path d="M7.338 8h2.29L5.634 2h-2.3zm3.06 0h2.264l4.004-6h-2.299zM1 10v2h7.926v6h2.148v-6H19v-2z"/></svg>
\ No newline at end of file
index 499a46a..abeab20 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeFlow-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeFlow-ltr.png differ
index 33b9eed..7910216 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeFlow-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeFlow-rtl.png differ
index 48f0fe8..b2b16ac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-ltr.png differ
index 1f7bbb9..ea942c6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-rtl-invert.png differ
index 320acf8..65e842f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeSummary-rtl.png differ
index 48f6b18..9d81869 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr-invert.png differ
index ba56edd..cfe8605 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr-progressive.png differ
index 92883cb..f5b6418 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-ltr.png differ
index bdf0abb..8f47db5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/stripeToC-rtl.png differ
index c8d2ad9..6091579 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-ltr-invert.png differ
index 0e20332..2c16c43 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-ltr.png differ
index fcfa7f7..ae8a86c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl-invert.png differ
index 37577c7..40aeb2d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>subscript</title><path fill="#fff" d="M10.5 9.7L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3l4.2-6.3zM3 12.5v6c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.2.6.4 1 .4H5v-1h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5v-1h-.5c-.4 0-.7.1-1 .4-.3-.2-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>subscript</title><path fill="#fff" d="M10.5 9.7L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3zM3 18.5c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.2.6.4 1 .4H5v-1h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5v-1h-.5c-.4 0-.7.1-1 .4-.3-.2-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5z"/></svg>
\ No newline at end of file
index 1d52184..de4fe27 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>subscript</title><path fill="#36c" d="M10.5 9.7L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3l4.2-6.3zM3 12.5v6c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.2.6.4 1 .4H5v-1h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5v-1h-.5c-.4 0-.7.1-1 .4-.3-.2-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>subscript</title><path fill="#36c" d="M10.5 9.7L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3zM3 18.5c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.2.6.4 1 .4H5v-1h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5v-1h-.5c-.4 0-.7.1-1 .4-.3-.2-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5z"/></svg>
\ No newline at end of file
index 8d9618f..74acd61 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/subscript-rtl.png differ
index 80a1468..80e9319 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>subscript</title><path d="M10.5 9.7L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3l4.2-6.3zM3 12.5v6c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.2.6.4 1 .4H5v-1h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5v-1h-.5c-.4 0-.7.1-1 .4-.3-.2-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>subscript</title><path d="M10.5 9.7L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3zM3 18.5c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.2.6.4 1 .4H5v-1h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5v-1h-.5c-.4 0-.7.1-1 .4-.3-.2-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5z"/></svg>
\ No newline at end of file
index 9b07a86..77485a1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/subtract.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/subtract.png differ
index 4b080d6..3f6a344 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr-invert.png differ
index b0006cf..473ef32 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#fff" d="M17.5 1h.5V0h-.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H15v1h.5a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H15v1h.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39h.5V8h-.5a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5zm-3.82 15h-2.42a.67.67 0 0 1-.46-.15 1.33 1.33 0 0 1-.28-.34l-2.77-4.44a2.65 2.65 0 0 1-.28.69L5 15.51a2.22 2.22 0 0 1-.29.34.58.58 0 0 1-.42.15H2l4.15-6.19L2.17 4h2.42a.81.81 0 0 1 .41.09.8.8 0 0 1 .24.26L8 8.59a2.71 2.71 0 0 1 .33-.74L10.6 4.4a.69.69 0 0 1 .6-.4h2.32l-4 5.71z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#fff" d="M18 1V0h-.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H15v1h.5a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H15v1h.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39h.5V8h-.5a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5zm-4.32 15h-2.42a.67.67 0 0 1-.46-.15 1.33 1.33 0 0 1-.28-.34l-2.77-4.44a2.65 2.65 0 0 1-.28.69L5 15.51a2.22 2.22 0 0 1-.29.34.58.58 0 0 1-.42.15H2l4.15-6.19L2.17 4h2.42a.81.81 0 0 1 .41.09.8.8 0 0 1 .24.26L8 8.59a2.71 2.71 0 0 1 .33-.74L10.6 4.4a.69.69 0 0 1 .6-.4h2.32l-4 5.71z"/></svg>
\ No newline at end of file
index 095bd6a..4e31a3d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#36c" d="M17.5 1h.5V0h-.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H15v1h.5a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H15v1h.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39h.5V8h-.5a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5zm-3.82 15h-2.42a.67.67 0 0 1-.46-.15 1.33 1.33 0 0 1-.28-.34l-2.77-4.44a2.65 2.65 0 0 1-.28.69L5 15.51a2.22 2.22 0 0 1-.29.34.58.58 0 0 1-.42.15H2l4.15-6.19L2.17 4h2.42a.81.81 0 0 1 .41.09.8.8 0 0 1 .24.26L8 8.59a2.71 2.71 0 0 1 .33-.74L10.6 4.4a.69.69 0 0 1 .6-.4h2.32l-4 5.71z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#36c" d="M18 1V0h-.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H15v1h.5a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H15v1h.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39h.5V8h-.5a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5zm-4.32 15h-2.42a.67.67 0 0 1-.46-.15 1.33 1.33 0 0 1-.28-.34l-2.77-4.44a2.65 2.65 0 0 1-.28.69L5 15.51a2.22 2.22 0 0 1-.29.34.58.58 0 0 1-.42.15H2l4.15-6.19L2.17 4h2.42a.81.81 0 0 1 .41.09.8.8 0 0 1 .24.26L8 8.59a2.71 2.71 0 0 1 .33-.74L10.6 4.4a.69.69 0 0 1 .6-.4h2.32l-4 5.71z"/></svg>
\ No newline at end of file
index d1894ce..a808fcf 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-ltr.png differ
index ef58222..79c1317 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path d="M17.5 1h.5V0h-.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H15v1h.5a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H15v1h.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39h.5V8h-.5a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5zm-3.82 15h-2.42a.67.67 0 0 1-.46-.15 1.33 1.33 0 0 1-.28-.34l-2.77-4.44a2.65 2.65 0 0 1-.28.69L5 15.51a2.22 2.22 0 0 1-.29.34.58.58 0 0 1-.42.15H2l4.15-6.19L2.17 4h2.42a.81.81 0 0 1 .41.09.8.8 0 0 1 .24.26L8 8.59a2.71 2.71 0 0 1 .33-.74L10.6 4.4a.69.69 0 0 1 .6-.4h2.32l-4 5.71z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path d="M18 1V0h-.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H15v1h.5a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H15v1h.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39h.5V8h-.5a.5.5 0 0 1-.5-.5v-6a.5.5 0 0 1 .5-.5zm-4.32 15h-2.42a.67.67 0 0 1-.46-.15 1.33 1.33 0 0 1-.28-.34l-2.77-4.44a2.65 2.65 0 0 1-.28.69L5 15.51a2.22 2.22 0 0 1-.29.34.58.58 0 0 1-.42.15H2l4.15-6.19L2.17 4h2.42a.81.81 0 0 1 .41.09.8.8 0 0 1 .24.26L8 8.59a2.71 2.71 0 0 1 .33-.74L10.6 4.4a.69.69 0 0 1 .6-.4h2.32l-4 5.71z"/></svg>
\ No newline at end of file
index 7ca6eca..a1b2164 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl-invert.png differ
index 051d732..16c0a06 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#fff" d="M3 1.5v6c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.3.6.4 1 .4H5V8h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5V0h-.5c-.4 0-.7.1-1 .4-.3-.3-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5zm7.5 8.2L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3l4.2-6.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#fff" d="M3 7.5c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.3.6.4 1 .4H5V8h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5V0h-.5c-.4 0-.7.1-1 .4-.3-.3-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5zm7.5 2.2L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3z"/></svg>
\ No newline at end of file
index e31ba3e..9f396a1 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#36c" d="M3 1.5v6c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.3.6.4 1 .4H5V8h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5V0h-.5c-.4 0-.7.1-1 .4-.3-.3-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5zm7.5 8.2L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3l4.2-6.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path fill="#36c" d="M3 7.5c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.3.6.4 1 .4H5V8h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5V0h-.5c-.4 0-.7.1-1 .4-.3-.3-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5zm7.5 2.2L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3z"/></svg>
\ No newline at end of file
index 2a3f15c..5e26e4c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/superscript-rtl.png differ
index 51659b9..14ed9be 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path d="M3 1.5v6c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.3.6.4 1 .4H5V8h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5V0h-.5c-.4 0-.7.1-1 .4-.3-.3-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5zm7.5 8.2L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3l4.2-6.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>superscript</title><path d="M3 7.5c0 .3-.2.5-.5.5H2v1h.5c.4 0 .7-.1 1-.4.3.3.6.4 1 .4H5V8h-.5c-.3 0-.5-.2-.5-.5v-6c0-.3.2-.5.5-.5H5V0h-.5c-.4 0-.7.1-1 .4-.3-.3-.6-.4-1-.4H2v1h.5c.3 0 .5.2.5.5zm7.5 2.2L6.5 4h2.3c.3 0 .5.2.6.4l2.3 3.5c.1.2.3.5.3.7l2.8-4.2c.1-.1.1-.2.2-.3.1-.1.3-.1.4-.1h2.4l-4 5.8L18 16h-2.3c-.2 0-.3 0-.4-.1l-.3-.3-2.5-3.8c-.1-.2-.2-.4-.3-.7l-2.8 4.4-.3.3c0 .2-.2.2-.4.2H6.3z"/></svg>
\ No newline at end of file
index 63b265b..85eaef1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/table-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/table-invert.png differ
index 831ab0b..886b78b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table</title><path fill="#fff" d="M19.66 2.88a2 2 0 0 0-.54-.54A2 2 0 0 0 18 2H2a2 2 0 0 0-1.12.34 2 2 0 0 0-.54.54A2 2 0 0 0 0 4v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-.34-1.12zM2 6h7v4H2zm0 10v-4h7v4zm16 0h-7v-4h7zm0-6h-7V6h7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table</title><path fill="#fff" d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 4h7v4H2zm0 10v-4h7v4zm16 0h-7v-4h7zm0-6h-7V6h7z"/></svg>
\ No newline at end of file
index 897b9d3..75bb3ac 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/table-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/table-progressive.png differ
index 6654f6b..3b22056 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table</title><path fill="#36c" d="M19.66 2.88a2 2 0 0 0-.54-.54A2 2 0 0 0 18 2H2a2 2 0 0 0-1.12.34 2 2 0 0 0-.54.54A2 2 0 0 0 0 4v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-.34-1.12zM2 6h7v4H2zm0 10v-4h7v4zm16 0h-7v-4h7zm0-6h-7V6h7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table</title><path fill="#36c" d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 4h7v4H2zm0 10v-4h7v4zm16 0h-7v-4h7zm0-6h-7V6h7z"/></svg>
\ No newline at end of file
index 218308d..cd5f4d7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/table.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/table.png differ
index 37caa1e..1b7c1c0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table</title><path d="M19.66 2.88a2 2 0 0 0-.54-.54A2 2 0 0 0 18 2H2a2 2 0 0 0-1.12.34 2 2 0 0 0-.54.54A2 2 0 0 0 0 4v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-.34-1.12zM2 6h7v4H2zm0 10v-4h7v4zm16 0h-7v-4h7zm0-6h-7V6h7z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table</title><path d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 4h7v4H2zm0 10v-4h7v4zm16 0h-7v-4h7zm0-6h-7V6h7z"/></svg>
\ No newline at end of file
index 613ec45..5119dec 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add column after</title><path fill="#fff" d="M0 3v14h8v1h12V2H8v1H0zm10 6h3V6h2v3h3v2h-3v3h-2v-3h-3zM6 5h2v10H6zM2 5h2v10H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add column after</title><path fill="#fff" d="M0 3v14h8v1h12V2H8v1zm10 6h3V6h2v3h3v2h-3v3h-2v-3h-3zM6 5h2v10H6zM2 5h2v10H2z"/></svg>
\ No newline at end of file
index 8058717..03aa11e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add column after</title><path fill="#36c" d="M0 3v14h8v1h12V2H8v1H0zm10 6h3V6h2v3h3v2h-3v3h-2v-3h-3zM6 5h2v10H6zM2 5h2v10H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add column after</title><path fill="#36c" d="M0 3v14h8v1h12V2H8v1zm10 6h3V6h2v3h3v2h-3v3h-2v-3h-3zM6 5h2v10H6zM2 5h2v10H2z"/></svg>
\ No newline at end of file
index 9b0a24f..b227e34 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnAfter.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnAfter.png differ
index 7215082..8c57e81 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add column after</title><path d="M0 3v14h8v1h12V2H8v1H0zm10 6h3V6h2v3h3v2h-3v3h-2v-3h-3zM6 5h2v10H6zM2 5h2v10H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add column after</title><path d="M0 3v14h8v1h12V2H8v1zm10 6h3V6h2v3h3v2h-3v3h-2v-3h-3zM6 5h2v10H6zM2 5h2v10H2z"/></svg>
\ No newline at end of file
index 643ff90..3a214bd 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnBefore.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddColumnBefore.png differ
index f3d6c4f..1188d92 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row after</title><path fill="#fff" d="M17 0H3v8H2v12h16V8h-1V0zm-6 10v3h3v2h-3v3H9v-3H6v-2h3v-3zm4-4v2H5V6zm0-4v2H5V2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row after</title><path fill="#fff" d="M3 0v8H2v12h16V8h-1V0zm8 10v3h3v2h-3v3H9v-3H6v-2h3v-3zm4-4v2H5V6zm0-4v2H5V2z"/></svg>
\ No newline at end of file
index e80330b..594d4fe 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row after</title><path fill="#36c" d="M17 0H3v8H2v12h16V8h-1V0zm-6 10v3h3v2h-3v3H9v-3H6v-2h3v-3zm4-4v2H5V6zm0-4v2H5V2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row after</title><path fill="#36c" d="M3 0v8H2v12h16V8h-1V0zm8 10v3h3v2h-3v3H9v-3H6v-2h3v-3zm4-4v2H5V6zm0-4v2H5V2z"/></svg>
\ No newline at end of file
index c4f6944..b28d3ec 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowAfter.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowAfter.png differ
index bb00198..2aa1bda 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row after</title><path d="M17 0H3v8H2v12h16V8h-1V0zm-6 10v3h3v2h-3v3H9v-3H6v-2h3v-3zm4-4v2H5V6zm0-4v2H5V2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row after</title><path d="M3 0v8H2v12h16V8h-1V0zm8 10v3h3v2h-3v3H9v-3H6v-2h3v-3zm4-4v2H5V6zm0-4v2H5V2z"/></svg>
\ No newline at end of file
index a8bad65..3d20cd8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row before</title><path fill="#fff" d="M3 20h14v-8h1V0H2v12h1v8zm6-10V7H6V5h3V2h2v3h3v2h-3v3zm-4 4v-2h10v2zm0 4v-2h10v2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row before</title><path fill="#fff" d="M17 20v-8h1V0H2v12h1v8zM9 10V7H6V5h3V2h2v3h3v2h-3v3zm-4 4v-2h10v2zm0 4v-2h10v2z"/></svg>
\ No newline at end of file
index facc564..200791c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row before</title><path fill="#36c" d="M3 20h14v-8h1V0H2v12h1v8zm6-10V7H6V5h3V2h2v3h3v2h-3v3zm-4 4v-2h10v2zm0 4v-2h10v2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row before</title><path fill="#36c" d="M17 20v-8h1V0H2v12h1v8zM9 10V7H6V5h3V2h2v3h3v2h-3v3zm-4 4v-2h10v2zm0 4v-2h10v2z"/></svg>
\ No newline at end of file
index e3e551a..fc4fe98 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowBefore.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableAddRowBefore.png differ
index 22ade23..b9ab81d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row before</title><path d="M3 20h14v-8h1V0H2v12h1v8zm6-10V7H6V5h3V2h2v3h3v2h-3v3zm-4 4v-2h10v2zm0 4v-2h10v2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table add row before</title><path d="M17 20v-8h1V0H2v12h1v8zM9 10V7H6V5h3V2h2v3h3v2h-3v3zm-4 4v-2h10v2zm0 4v-2h10v2z"/></svg>
\ No newline at end of file
index 7a8736f..f48940d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption-invert.png differ
index 18bfa35..f59b37b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table caption</title><path fill="#fff" d="M18 8H2a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zM2 10h7v2H2zm0 6v-2h7v2zm16 0h-7v-2h7zm0-4h-7v-2h7zM2 2h16v4H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table caption</title><path fill="#fff" d="M2 8a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zm0 2h7v2H2zm0 6v-2h7v2zm16 0h-7v-2h7zm0-4h-7v-2h7zM2 2h16v4H2z"/></svg>
\ No newline at end of file
index 5b6dedc..2c4fca0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table caption</title><path fill="#36c" d="M18 8H2a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zM2 10h7v2H2zm0 6v-2h7v2zm16 0h-7v-2h7zm0-4h-7v-2h7zM2 2h16v4H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table caption</title><path fill="#36c" d="M2 8a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zm0 2h7v2H2zm0 6v-2h7v2zm16 0h-7v-2h7zm0-4h-7v-2h7zM2 2h16v4H2z"/></svg>
\ No newline at end of file
index cfcea42..7e6058e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableCaption.png differ
index bd04d3d..fec5086 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table caption</title><path d="M18 8H2a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zM2 10h7v2H2zm0 6v-2h7v2zm16 0h-7v-2h7zm0-4h-7v-2h7zM2 2h16v4H2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table caption</title><path d="M2 8a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zm0 2h7v2H2zm0 6v-2h7v2zm16 0h-7v-2h7zm0-4h-7v-2h7zM2 2h16v4H2z"/></svg>
\ No newline at end of file
index 4ad0e91..a9bc71d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells-invert.png differ
index 0453287..96ecc43 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>merge cells</title><g fill="#fff"><path d="M4 11v3l5-4-5-4v3H0v2h4zm12 0v3l-5-4 5-4v3h4v2h-4zM2 16v-3H0v5h8v-2H2z"/><path d="M0 2v5h2V4h6V2H0zm18 11v3h-6v2h8v-5h-2zM12 2v2h6v3h2V2h-8z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>merge cells</title><g fill="#fff"><path id="a" d="M9 10L4 6v3H0v2h4v3zm-7 3H0v5h8v-2H2zM0 2v5h2V4h6V2z"/><use transform="matrix(-1 0 0 1 20 0)" xlink:href="#a"/></g></svg>
\ No newline at end of file
index c840b39..f12a2b4 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>merge cells</title><g fill="#36c"><path d="M4 11v3l5-4-5-4v3H0v2h4zm12 0v3l-5-4 5-4v3h4v2h-4zM2 16v-3H0v5h8v-2H2z"/><path d="M0 2v5h2V4h6V2H0zm18 11v3h-6v2h8v-5h-2zM12 2v2h6v3h2V2h-8z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>merge cells</title><g fill="#36c"><path id="a" d="M9 10L4 6v3H0v2h4v3zm-7 3H0v5h8v-2H2zM0 2v5h2V4h6V2z"/><use transform="matrix(-1 0 0 1 20 0)" xlink:href="#a"/></g></svg>
\ No newline at end of file
index 0ba51dd..f6f00d0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMergeCells.png differ
index af7721f..53549c7 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>merge cells</title><path d="M4 11v3l5-4-5-4v3H0v2h4zm12 0v3l-5-4 5-4v3h4v2h-4zM2 16v-3H0v5h8v-2H2z"/><path d="M0 2v5h2V4h6V2H0zm18 11v3h-6v2h8v-5h-2zM12 2v2h6v3h2V2h-8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20"><title>merge cells</title><path id="a" d="M9 10L4 6v3H0v2h4v3zm-7 3H0v5h8v-2H2zM0 2v5h2V4h6V2z"/><use transform="matrix(-1 0 0 1 20 0)" xlink:href="#a"/></svg>
\ No newline at end of file
index 71206f0..911a240 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter-invert.png differ
index 34ba5eb..a668a7a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column after</title><g fill="#fff"><path d="M11 11v3l5-4-5-4v3H6v2h5z"/><path d="M18 2h-8v2h8v12h-8v2h10V2h-2zM2 18h5v-2H5V4h2V2H0v16h2z"/><path d="M8 12H5v6h5v-6H8zM5 2v6h5V2H5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column after</title><g fill="#fff"><path d="M16 10l-5-4v3H6v2h5v3z"/><path d="M0 2h20v16H0zm5 6v4h5v4h8V4h-8v4z"/></g></svg>
\ No newline at end of file
index 61c0be4..9f41077 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column after</title><g fill="#36c"><path d="M11 11v3l5-4-5-4v3H6v2h5z"/><path d="M18 2h-8v2h8v12h-8v2h10V2h-2zM2 18h5v-2H5V4h2V2H0v16h2z"/><path d="M8 12H5v6h5v-6H8zM5 2v6h5V2H5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column after</title><g fill="#36c"><path d="M16 10l-5-4v3H6v2h5v3z"/><path d="M0 2h20v16H0zm5 6v4h5v4h8V4h-8v4z"/></g></svg>
\ No newline at end of file
index 14c244e..fe87945 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnAfter.png differ
index 5669189..8e873da 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column after</title><path d="M11 11v3l5-4-5-4v3H6v2h5z"/><path d="M18 2h-8v2h8v12h-8v2h10V2h-2zM2 18h5v-2H5V4h2V2H0v16h2z"/><path d="M8 12H5v6h5v-6H8zM5 2v6h5V2H5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column after</title><path d="M16 10l-5-4v3H6v2h5v3z"/><path d="M0 2h20v16H0zm5 6v4h5v4h8V4h-8v4z"/></svg>
\ No newline at end of file
index 30f875a..5f645a7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore-invert.png differ
index 07c1437..ca5dc6f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column before</title><g fill="#fff"><path d="M9 11v3l-5-4 5-4v3h5v2H9z"/><path d="M2 2h8v2H2v12h8v2H0V2h2zm16 16h-5v-2h2V4h-2V2h7v16h-2z"/><path d="M12 12h3v6h-5v-6h2zm3-10v6h-5V2h5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column before</title><g fill="#fff"><path d="M4 10l5-4v3h5v2H9v3z"/><path d="M0 2v16h20V2zm2 2h8v4h5v4h-5v4H2z"/></g></svg>
\ No newline at end of file
index 364fa23..a9129a2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column before</title><g fill="#36c"><path d="M9 11v3l-5-4 5-4v3h5v2H9z"/><path d="M2 2h8v2H2v12h8v2H0V2h2zm16 16h-5v-2h2V4h-2V2h7v16h-2z"/><path d="M12 12h3v6h-5v-6h2zm3-10v6h-5V2h5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column before</title><g fill="#36c"><path d="M4 10l5-4v3h5v2H9v3z"/><path d="M0 2v16h20V2zm2 2h8v4h5v4h-5v4H2z"/></g></svg>
\ No newline at end of file
index ffa0f95..62b06cb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveColumnBefore.png differ
index 8a216bf..adc3c03 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column before</title><path d="M9 11v3l-5-4 5-4v3h5v2H9z"/><path d="M2 2h8v2H2v12h8v2H0V2h2zm16 16h-5v-2h2V4h-2V2h7v16h-2z"/><path d="M12 12h3v6h-5v-6h2zm3-10v6h-5V2h5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move column before</title><path d="M4 10l5-4v3h5v2H9v3z"/><path d="M0 2v16h20V2zm2 2h8v4h5v4h-5v4H2z"/></svg>
\ No newline at end of file
index 4844264..66d5dce 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter-invert.png differ
index 00e21df..4abd889 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row after</title><g fill="#fff"><path d="M11 11h3l-4 5-4-5h3V6h2v5z"/><path d="M2 18v-8h2v8h12v-8h2v10H2v-2zM18 2v5h-2V5H4v2H2V0h16v2z"/><path d="M12 8V5h6v5h-6V8zM2 5h6v5H2V5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row after</title><g fill="#fff"><path d="M10 16l-4-5h3V6h2v5h3z"/><path d="M2 0v20h16V0zm2 10h4V5h4v5h4v8H4z"/></g></svg>
\ No newline at end of file
index 0579966..79d28d9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row after</title><g fill="#36c"><path d="M11 11h3l-4 5-4-5h3V6h2v5z"/><path d="M2 18v-8h2v8h12v-8h2v10H2v-2zM18 2v5h-2V5H4v2H2V0h16v2z"/><path d="M12 8V5h6v5h-6V8zM2 5h6v5H2V5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row after</title><g fill="#36c"><path d="M10 16l-4-5h3V6h2v5h3z"/><path d="M2 0v20h16V0zm2 10h4V5h4v5h4v8H4z"/></g></svg>
\ No newline at end of file
index ad16a02..c140bef 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowAfter.png differ
index 82691a9..e9d6ef0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row after</title><path d="M11 11h3l-4 5-4-5h3V6h2v5z"/><path d="M2 18v-8h2v8h12v-8h2v10H2v-2zM18 2v5h-2V5H4v2H2V0h16v2z"/><path d="M12 8V5h6v5h-6V8zM2 5h6v5H2V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row after</title><path d="M10 16l-4-5h3V6h2v5h3z"/><path d="M2 0v20h16V0zm2 10h4V5h4v5h4v8H4z"/></svg>
\ No newline at end of file
index 06487bb..aebf9d5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore-invert.png differ
index cb8899c..ea39632 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row before</title><g fill="#fff"><path d="M9 9H6l4-5 4 5h-3v5H9V9z"/><path d="M18 2v8h-2V2H4v8H2V0h16v2zM2 18v-5h2v2h12v-2h2v7H2v-2z"/><path d="M8 12v3H2v-5h6v2zm10 3h-6v-5h6v5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row before</title><g fill="#fff"><path d="M9 9H6l4-5 4 5h-3v5H9z"/><path d="M2 0h16v20H2zm2 2v8h4v5h4v-5h4V2z"/></g></svg>
\ No newline at end of file
index 099f9db..2eaede1 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row before</title><g fill="#36c"><path d="M9 9H6l4-5 4 5h-3v5H9V9z"/><path d="M18 2v8h-2V2H4v8H2V0h16v2zM2 18v-5h2v2h12v-2h2v7H2v-2z"/><path d="M8 12v3H2v-5h6v2zm10 3h-6v-5h6v5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row before</title><g fill="#36c"><path d="M9 9H6l4-5 4 5h-3v5H9z"/><path d="M2 0h16v20H2zm2 2v8h4v5h4v-5h4V2z"/></g></svg>
\ No newline at end of file
index 3b1f015..5aec135 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tableMoveRowBefore.png differ
index 316dd56..7753c6e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row before</title><path d="M9 9H6l4-5 4 5h-3v5H9V9z"/><path d="M18 2v8h-2V2H4v8H2V0h16v2zM2 18v-5h2v2h12v-2h2v7H2v-2z"/><path d="M8 12v3H2v-5h6v2zm10 3h-6v-5h6v5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>table move row before</title><path d="M9 9H6l4-5 4 5h-3v5H9z"/><path d="M2 0h16v20H2zm2 2v8h4v5h4v-5h4V2z"/></svg>
\ No newline at end of file
index 3716589..aa7a95f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-destructive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-destructive.png differ
index c812ede..67fd674 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#d33" d="M18.72 11L9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#d33" d="M9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-error.png b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-error.png
new file mode 100644 (file)
index 0000000..aa7a95f
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-error.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-error.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-error.svg
new file mode 100644 (file)
index 0000000..67fd674
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#d33" d="M9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 7d0bcbf..9d17a62 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-invert.png differ
index af677b2..e78e8d8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#fff" d="M18.72 11L9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#fff" d="M9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 815a430..3143e98 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-progressive.png differ
index ce714af..6cf532e 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#36c" d="M18.72 11L9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#36c" d="M9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index a02fb4d..8dd4129 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-warning.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr-warning.png differ
index 288d622..ddc2764 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#ff5d00" d="M18.72 11L9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#fc3" d="M9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 3afb23f..baffb07 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-ltr.png differ
index 0740438..f094226 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path d="M18.72 11L9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path d="M9 1.28A1 1 0 0 0 8.35 1H2a1 1 0 0 0-1 1v6.35a1 1 0 0 0 .28.65L11 18.72a1 1 0 0 0 1.37 0l6.38-6.38a1 1 0 0 0-.03-1.34zM5 7a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 99a786b..34946dd 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-destructive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-destructive.png differ
index 3a6134a..145a398 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#d33" d="M1.2 12.3l6.4 6.4c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#d33" d="M7.6 18.7c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-error.png b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-error.png
new file mode 100644 (file)
index 0000000..34946dd
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-error.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-error.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-error.svg
new file mode 100644 (file)
index 0000000..145a398
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#d33" d="M7.6 18.7c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
index 5e8b4e3..ed64638 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-invert.png differ
index 1e65d63..c694b71 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#fff" d="M1.2 12.3l6.4 6.4c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#fff" d="M7.6 18.7c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
index d4a0989..cdbe6a9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-progressive.png differ
index c859d06..658571f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#36c" d="M1.2 12.3l6.4 6.4c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#36c" d="M7.6 18.7c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
index 7f562c0..5d58c98 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-warning.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl-warning.png differ
index c6c39b2..1ce8505 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#ff5d00" d="M1.2 12.3l6.4 6.4c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path fill="#fc3" d="M7.6 18.7c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
index 888f8c8..22a35ce 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tag-rtl.png differ
index d7b75e8..af3b9f9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path d="M1.2 12.3l6.4 6.4c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tag</title><path d="M7.6 18.7c.4.4 1 .4 1.4 0L18.7 9c.2-.2.3-.4.3-.6V2c0-.6-.4-1-1-1h-6.4c-.2 0-.5.1-.6.3L1.3 11c-.4.4-.4 1-.1 1.3zM13 5c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2z"/></svg>
\ No newline at end of file
index 808e2ea..7cce295 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add template</title><g fill="#fff"><path d="M20 5h-4V1h-2v4h-4v2h4v4h2V7h4V5z"/><path d="M16 17H0V5h8v2H2v8h12v-2h2v4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add template</title><g fill="#fff"><path d="M16 5V1h-2v4h-4v2h4v4h2V7h4V5z"/><path d="M0 17V5h8v2H2v8h12v-2h2v4z"/></g></svg>
\ No newline at end of file
index 9d7d6c9..99c2400 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add template</title><g fill="#36c"><path d="M20 5h-4V1h-2v4h-4v2h4v4h2V7h4V5z"/><path d="M16 17H0V5h8v2H2v8h12v-2h2v4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add template</title><g fill="#36c"><path d="M16 5V1h-2v4h-4v2h4v4h2V7h4V5z"/><path d="M0 17V5h8v2H2v8h12v-2h2v4z"/></g></svg>
\ No newline at end of file
index 902326d..8683adb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-ltr.png differ
index 895ba0b..5723129 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add template</title><path d="M20 5h-4V1h-2v4h-4v2h4v4h2V7h4V5z"/><path d="M16 17H0V5h8v2H2v8h12v-2h2v4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>add template</title><path d="M16 5V1h-2v4h-4v2h4v4h2V7h4V5z"/><path d="M0 17V5h8v2H2v8h12v-2h2v4z"/></svg>
\ No newline at end of file
index 785fac0..d1b27be 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/templateAdd-rtl.png differ
index a056831..be89e70 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR-invert.png differ
index 24042cb..bed0cd8 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction left-to-right</title><path fill="#fff" d="M13 11v4l6-5-6-5v4H6v2h7zM4.5 2H6V1H4.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H1v1h1.5a.5.5 0 0 1 .5.5v15a.5.5 0 0 1-.5.5H1v1h1.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39H6v-1H4.5a.5.5 0 0 1-.5-.5v-15a.5.5 0 0 1 .5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction left-to-right</title><path fill="#fff" d="M19 10l-6-5v4H6v2h7v4zM6 2V1H4.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H1v1h1.5a.5.5 0 0 1 .5.5v15a.5.5 0 0 1-.5.5H1v1h1.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39H6v-1H4.5a.5.5 0 0 1-.5-.5v-15a.5.5 0 0 1 .5-.5z"/></svg>
\ No newline at end of file
index 8cdc020..cc0e9bd 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction left-to-right</title><path fill="#36c" d="M13 11v4l6-5-6-5v4H6v2h7zM4.5 2H6V1H4.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H1v1h1.5a.5.5 0 0 1 .5.5v15a.5.5 0 0 1-.5.5H1v1h1.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39H6v-1H4.5a.5.5 0 0 1-.5-.5v-15a.5.5 0 0 1 .5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction left-to-right</title><path fill="#36c" d="M19 10l-6-5v4H6v2h7v4zM6 2V1H4.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H1v1h1.5a.5.5 0 0 1 .5.5v15a.5.5 0 0 1-.5.5H1v1h1.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39H6v-1H4.5a.5.5 0 0 1-.5-.5v-15a.5.5 0 0 1 .5-.5z"/></svg>
\ No newline at end of file
index 87bd416..c3f2a17 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/textDirLTR.png differ
index 5eab5bc..5b521ed 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction left-to-right</title><path d="M13 11v4l6-5-6-5v4H6v2h7zM4.5 2H6V1H4.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H1v1h1.5a.5.5 0 0 1 .5.5v15a.5.5 0 0 1-.5.5H1v1h1.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39H6v-1H4.5a.5.5 0 0 1-.5-.5v-15a.5.5 0 0 1 .5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction left-to-right</title><path d="M19 10l-6-5v4H6v2h7v4zM6 2V1H4.5a1.49 1.49 0 0 0-1 .39 1.49 1.49 0 0 0-1-.39H1v1h1.5a.5.5 0 0 1 .5.5v15a.5.5 0 0 1-.5.5H1v1h1.5a1.49 1.49 0 0 0 1-.39 1.49 1.49 0 0 0 1 .39H6v-1H4.5a.5.5 0 0 1-.5-.5v-15a.5.5 0 0 1 .5-.5z"/></svg>
\ No newline at end of file
index a70fa52..5c4505d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL-invert.png differ
index 9f04cb8..f486d78 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction right-to-left</title><path fill="#fff" d="M7 11v4l-6-5 6-5v4h7v2H7zm8.5-9H14V1h1.5a1.49 1.49 0 0 1 1 .39 1.49 1.49 0 0 1 1-.39H19v1h-1.5a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5H19v1h-1.5a1.49 1.49 0 0 1-1-.39 1.49 1.49 0 0 1-1 .39H14v-1h1.5a.5.5 0 0 0 .5-.5v-15a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction right-to-left</title><path fill="#fff" d="M1 10l6-5v4h7v2H7v4zm13-8V1h1.5a1.49 1.49 0 0 1 1 .39 1.49 1.49 0 0 1 1-.39H19v1h-1.5a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5H19v1h-1.5a1.49 1.49 0 0 1-1-.39 1.49 1.49 0 0 1-1 .39H14v-1h1.5a.5.5 0 0 0 .5-.5v-15a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
index 012edce..e3750f1 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction right-to-left</title><path fill="#36c" d="M7 11v4l-6-5 6-5v4h7v2H7zm8.5-9H14V1h1.5a1.49 1.49 0 0 1 1 .39 1.49 1.49 0 0 1 1-.39H19v1h-1.5a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5H19v1h-1.5a1.49 1.49 0 0 1-1-.39 1.49 1.49 0 0 1-1 .39H14v-1h1.5a.5.5 0 0 0 .5-.5v-15a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction right-to-left</title><path fill="#36c" d="M1 10l6-5v4h7v2H7v4zm13-8V1h1.5a1.49 1.49 0 0 1 1 .39 1.49 1.49 0 0 1 1-.39H19v1h-1.5a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5H19v1h-1.5a1.49 1.49 0 0 1-1-.39 1.49 1.49 0 0 1-1 .39H14v-1h1.5a.5.5 0 0 0 .5-.5v-15a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
index 280dc77..2503298 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/textDirRTL.png differ
index dc570fd..8a50d48 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction right-to-left</title><path d="M7 11v4l-6-5 6-5v4h7v2H7zm8.5-9H14V1h1.5a1.49 1.49 0 0 1 1 .39 1.49 1.49 0 0 1 1-.39H19v1h-1.5a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5H19v1h-1.5a1.49 1.49 0 0 1-1-.39 1.49 1.49 0 0 1-1 .39H14v-1h1.5a.5.5 0 0 0 .5-.5v-15a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>text direction right-to-left</title><path d="M1 10l6-5v4h7v2H7v4zm13-8V1h1.5a1.49 1.49 0 0 1 1 .39 1.49 1.49 0 0 1 1-.39H19v1h-1.5a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5H19v1h-1.5a1.49 1.49 0 0 1-1-.39 1.49 1.49 0 0 1-1 .39H14v-1h1.5a.5.5 0 0 0 .5-.5v-15a.5.5 0 0 0-.5-.5z"/></svg>
\ No newline at end of file
index eac54c8..3154793 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/textStyle-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/textStyle-invert.png differ
index b959d6c..7ecc0e1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/textStyle.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/textStyle.png differ
index 1a5d50c..460cd2c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/trash-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/trash-invert.png differ
index d5db2ec..abc492a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/trash.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/trash.png differ
index 32f3af3..3849300 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tray-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tray-invert.png differ
index 7c748c5..ec1642f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tray</title><path fill="#fff" d="M17 1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 12h-4l-1 2H8l-1-2H3V3h14z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tray</title><path fill="#fff" d="M3 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm14 12h-4l-1 2H8l-1-2H3V3h14z"/></svg>
\ No newline at end of file
index 21229ba..9ee3e48 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tray</title><path fill="#36c" d="M17 1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 12h-4l-1 2H8l-1-2H3V3h14z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tray</title><path fill="#36c" d="M3 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm14 12h-4l-1 2H8l-1-2H3V3h14z"/></svg>
\ No newline at end of file
index b3340be..db7a03a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/tray.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/tray.png differ
index 4b74cd1..cb360f5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tray</title><path d="M17 1H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 12h-4l-1 2H8l-1-2H3V3h14z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>tray</title><path d="M3 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm14 12h-4l-1 2H8l-1-2H3V3h14z"/></svg>
\ No newline at end of file
index a9e733a..98f9f37 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-invert.png differ
index e0d79ba..9dac17a 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>unblock</title><path fill="#fff" d="M16.94 15.72L12.22 11l-2-2-5.94-5.94L1.22 0 0 1.22l3.06 3.06a9 9 0 0 0 12.66 12.66L18.78 20 20 18.78zM5 11V9h2.78l2 2zm5-10a9 9 0 0 0-4.26 1.08L12.66 9H15v2h-.34l3.26 3.26A9 9 0 0 0 10 1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>unblock</title><path fill="#fff" d="M1.22 0L0 1.22l3.06 3.06a9 9 0 0 0 12.66 12.66L18.78 20 20 18.78zM5 11V9h2.78l2 2zm5-10a9 9 0 0 0-4.26 1.08L12.66 9H15v2h-.34l3.26 3.26A9 9 0 0 0 10 1z"/></svg>
\ No newline at end of file
index ca6adcf..1a56e9a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unBlock-progressive.png differ
index 007b1ea..3ffa2f5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>unblock</title><path fill="#36c" d="M16.94 15.72L12.22 11l-2-2-5.94-5.94L1.22 0 0 1.22l3.06 3.06a9 9 0 0 0 12.66 12.66L18.78 20 20 18.78zM5 11V9h2.78l2 2zm5-10a9 9 0 0 0-4.26 1.08L12.66 9H15v2h-.34l3.26 3.26A9 9 0 0 0 10 1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>unblock</title><path fill="#36c" d="M1.22 0L0 1.22l3.06 3.06a9 9 0 0 0 12.66 12.66L18.78 20 20 18.78zM5 11V9h2.78l2 2zm5-10a9 9 0 0 0-4.26 1.08L12.66 9H15v2h-.34l3.26 3.26A9 9 0 0 0 10 1z"/></svg>
\ No newline at end of file
index 1621170..97cd078 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unBlock.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unBlock.png differ
index f75bf9a..72778fe 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>unblock</title><path d="M16.94 15.72L12.22 11l-2-2-5.94-5.94L1.22 0 0 1.22l3.06 3.06a9 9 0 0 0 12.66 12.66L18.78 20 20 18.78zM5 11V9h2.78l2 2zm5-10a9 9 0 0 0-4.26 1.08L12.66 9H15v2h-.34l3.26 3.26A9 9 0 0 0 10 1z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>unblock</title><path d="M1.22 0L0 1.22l3.06 3.06a9 9 0 0 0 12.66 12.66L18.78 20 20 18.78zM5 11V9h2.78l2 2zm5-10a9 9 0 0 0-4.26 1.08L12.66 9H15v2h-.34l3.26 3.26A9 9 0 0 0 10 1z"/></svg>
\ No newline at end of file
index a00d836..47ec5f8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-invert.png differ
index d11d4d4..ae1a8b0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-flag</title><path fill="#fff" d="M12.14 8.48L17 6 5.58 1.92l.16.16 6.4 6.4zm-1.61.82L3 1.78 1.22 0 0 1.22l3 3V19h2v-6.87l3.91-2L18.78 20 20 18.78 10.53 9.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-flag</title><path fill="#fff" d="M12.14 8.48L17 6 5.58 1.92zM1.22 0L0 1.22l3 3V19h2v-6.87l3.91-2L18.78 20 20 18.78z"/></svg>
\ No newline at end of file
index 3de43ad..6ff759a 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr-progressive.png differ
index 9c967fb..61e78a3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-flag</title><path fill="#36c" d="M12.14 8.48L17 6 5.58 1.92l.16.16 6.4 6.4zm-1.61.82L3 1.78 1.22 0 0 1.22l3 3V19h2v-6.87l3.91-2L18.78 20 20 18.78 10.53 9.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-flag</title><path fill="#36c" d="M12.14 8.48L17 6 5.58 1.92zM1.22 0L0 1.22l3 3V19h2v-6.87l3.91-2L18.78 20 20 18.78z"/></svg>
\ No newline at end of file
index 08aeb57..97008f8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-ltr.png differ
index fd3be33..47054e0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-flag</title><path d="M12.14 8.48L17 6 5.58 1.92l.16.16 6.4 6.4zm-1.61.82L3 1.78 1.22 0 0 1.22l3 3V19h2v-6.87l3.91-2L18.78 20 20 18.78 10.53 9.3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-flag</title><path d="M12.14 8.48L17 6 5.58 1.92zM1.22 0L0 1.22l3 3V19h2v-6.87l3.91-2L18.78 20 20 18.78z"/></svg>
\ No newline at end of file
index 4c71f1d..76ed4f5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-rtl-invert.png differ
index a767ba7..07633b1 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unFlag-rtl.png differ
index 92dba5c..93a7aa0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path fill="#d33" d="M16.07 8H15V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zM10 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path fill="#d33" d="M15 8V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zm-5 8a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 5ac7f9b..da10633 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unLock-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unLock-invert.png differ
index 685746f..ef4482b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path fill="#fff" d="M16.07 8H15V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zM10 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path fill="#fff" d="M15 8V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zm-5 8a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 541701f..756a7e0 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path fill="#36c" d="M16.07 8H15V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zM10 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path fill="#36c" d="M15 8V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zm-5 8a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index fb22138..4a7554e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unLock.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unLock.png differ
index 94892e2..fd1db92 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path d="M16.07 8H15V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zM10 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>un-lock</title><path d="M15 8V5s0-5-5-5a4.63 4.63 0 0 0-4.88 4h2C7.31 2.93 8 2 10 2c3 0 3 2 3 3.5V8H3.93A1.93 1.93 0 0 0 2 9.93v8.15A1.93 1.93 0 0 0 3.93 20h12.14A1.93 1.93 0 0 0 18 18.07V9.93A1.93 1.93 0 0 0 16.07 8zm-5 8a2 2 0 1 1 2-2 2 2 0 0 1-2 2z"/></svg>
\ No newline at end of file
index 4f27750..b8d8a7c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unStar-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unStar-invert.png differ
index 8c91074..c0a93e6 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unStar.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unStar.png differ
index 890d029..d9c1cba 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-invert.png differ
index d6bc046..3aadb9b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undelete</title><path fill="#fff" d="M16 14.78L6.22 5l-1-1-2-2-2-2L0 1.22l4 4V17a2 2 0 0 0 2 2h8a2 2 0 0 0 2-1.8l2.8 2.8 1.2-1.22zM17 4V2h-3.5l-1-1h-5l-1 1h-.84l2 2H17zm-1 1H8.66L16 12.34V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undelete</title><path fill="#fff" d="M1.22 0L0 1.22l4 4V17a2 2 0 0 0 2 2h8a2 2 0 0 0 2-1.8l2.8 2.8 1.2-1.22zM17 4V2h-3.5l-1-1h-5l-1 1h-.84l2 2zM8.66 5H16v7.34z"/></svg>
\ No newline at end of file
index c385295..4b94456 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unTrash-progressive.png differ
index 36adbcb..c80deb6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undelete</title><path fill="#36c" d="M16 14.78L6.22 5l-1-1-2-2-2-2L0 1.22l4 4V17a2 2 0 0 0 2 2h8a2 2 0 0 0 2-1.8l2.8 2.8 1.2-1.22zM17 4V2h-3.5l-1-1h-5l-1 1h-.84l2 2H17zm-1 1H8.66L16 12.34V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undelete</title><path fill="#36c" d="M1.22 0L0 1.22l4 4V17a2 2 0 0 0 2 2h8a2 2 0 0 0 2-1.8l2.8 2.8 1.2-1.22zM17 4V2h-3.5l-1-1h-5l-1 1h-.84l2 2zM8.66 5H16v7.34z"/></svg>
\ No newline at end of file
index 8dd4395..ae731f4 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/unTrash.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/unTrash.png differ
index 156e125..b5c8eb3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undelete</title><path d="M16 14.78L6.22 5l-1-1-2-2-2-2L0 1.22l4 4V17a2 2 0 0 0 2 2h8a2 2 0 0 0 2-1.8l2.8 2.8 1.2-1.22zM17 4V2h-3.5l-1-1h-5l-1 1h-.84l2 2H17zm-1 1H8.66L16 12.34V5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undelete</title><path d="M1.22 0L0 1.22l4 4V17a2 2 0 0 0 2 2h8a2 2 0 0 0 2-1.8l2.8 2.8 1.2-1.22zM17 4V2h-3.5l-1-1h-5l-1 1h-.84l2 2zM8.66 5H16v7.34z"/></svg>
\ No newline at end of file
index ecf5e73..d795f6f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/underline-a-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/underline-a-invert.png differ
index e229f3b..dc37074 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/underline-a.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/underline-a.png differ
index 80e283c..b54573b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/underline-u-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/underline-u-invert.png differ
index e4290b1..5f2e3e0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/underline-u.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/underline-u.png differ
index 07a32cd..28173b0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr-invert.png differ
index b84a8cf..31ad6fc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#fff" d="M8 3L1 8.5 8 14v-4h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9H8V3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#fff" d="M1 8.5L8 14v-4h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9H8V3z"/></svg>
\ No newline at end of file
index a6e9292..a99589c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#36c" d="M8 3L1 8.5 8 14v-4h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9H8V3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#36c" d="M1 8.5L8 14v-4h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9H8V3z"/></svg>
\ No newline at end of file
index 60dea74..c06298d 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/undo-ltr.png differ
index d9c1991..8d05848 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path d="M8 3L1 8.5 8 14v-4h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9H8V3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path d="M1 8.5L8 14v-4h1c4 0 7 2 7 6v1h3v-1c0-6-5-9-10-9H8V3z"/></svg>
\ No newline at end of file
index 90ba12a..c230889 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl-invert.png differ
index 7c0db1d..88e2ec5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#fff" d="M12 3v4h-1C6 7 1 10 1 16v1h3v-1c0-4 3-6 7-6h1v4l7-5.5L12 3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#fff" d="M12 3v4h-1C6 7 1 10 1 16v1h3v-1c0-4 3-6 7-6h1v4l7-5.5z"/></svg>
\ No newline at end of file
index db98918..47fab52 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#36c" d="M12 3v4h-1C6 7 1 10 1 16v1h3v-1c0-4 3-6 7-6h1v4l7-5.5L12 3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path fill="#36c" d="M12 3v4h-1C6 7 1 10 1 16v1h3v-1c0-4 3-6 7-6h1v4l7-5.5z"/></svg>
\ No newline at end of file
index 8e0f431..4bcac19 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/undo-rtl.png differ
index 45b0869..b04df7c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path d="M12 3v4h-1C6 7 1 10 1 16v1h3v-1c0-4 3-6 7-6h1v4l7-5.5L12 3z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>undo</title><path d="M12 3v4h-1C6 7 1 10 1 16v1h3v-1c0-4 3-6 7-6h1v4l7-5.5z"/></svg>
\ No newline at end of file
index cff2fa9..51827ab 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle-invert.png differ
index 5bdd2be..9d36592 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>triangle upwards</title><path fill="#fff" d="M10 5l8 10H2l8-10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>triangle upwards</title><path fill="#fff" d="M10 5l8 10H2z"/></svg>
\ No newline at end of file
index a22e88b..e94f9fc 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>triangle upwards</title><path fill="#36c" d="M10 5l8 10H2l8-10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>triangle upwards</title><path fill="#36c" d="M10 5l8 10H2z"/></svg>
\ No newline at end of file
index e2aff97..acbe373 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/upTriangle.png differ
index 90a88b2..a39fb75 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>triangle upwards</title><path d="M10 5l8 10H2l8-10z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>triangle upwards</title><path d="M10 5l8 10H2z"/></svg>
\ No newline at end of file
index 3c75235..00d0ddb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/upload-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/upload-invert.png differ
index d30ee5f..9102c8b 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>upload</title><g fill="#fff"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M15 7l-5-6-5 6h4v8h2V7h4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>upload</title><g fill="#fff"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 1L5 7h4v8h2V7h4z"/></g></svg>
\ No newline at end of file
index b1128bd..48f23b7 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>upload</title><g fill="#36c"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M15 7l-5-6-5 6h4v8h2V7h4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>upload</title><g fill="#36c"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 1L5 7h4v8h2V7h4z"/></g></svg>
\ No newline at end of file
index 17983b8..48ae15f 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/upload.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/upload.png differ
index e50fc79..3133d6c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>upload</title><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M15 7l-5-6-5 6h4v8h2V7h4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>upload</title><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 1L5 7h4v8h2V7h4z"/></svg>
\ No newline at end of file
index cd8113e..55ccdfb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-invert.png differ
index 7aac3b4..7a73136 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>anonynmous user</title><g fill="#fff"><path d="M15 2H5L4 8h12l-1-6zM0 10s2 1 10 1 10-1 10-1l-4-2H4zm6 2a3 3 0 1 0 3 3 3 3 0 0 0-3-3zm8 0a3 3 0 1 0 3 3 3 3 0 0 0-3-3z"/><path d="M8 14h4v1H8z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>anonynmous user</title><g fill="#fff"><path d="M15 2H5L4 8h12zM0 10s2 1 10 1 10-1 10-1l-4-2H4zm8 4h4v1H8z"/><circle cx="6" cy="15" r="3"/><circle cx="14" cy="15" r="3"/></g></svg>
\ No newline at end of file
index f807208..7c955a9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous-progressive.png differ
index 783ec55..6c4fa41 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>anonynmous user</title><g fill="#36c"><path d="M15 2H5L4 8h12l-1-6zM0 10s2 1 10 1 10-1 10-1l-4-2H4zm6 2a3 3 0 1 0 3 3 3 3 0 0 0-3-3zm8 0a3 3 0 1 0 3 3 3 3 0 0 0-3-3z"/><path d="M8 14h4v1H8z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>anonynmous user</title><g fill="#36c"><path d="M15 2H5L4 8h12zM0 10s2 1 10 1 10-1 10-1l-4-2H4zm8 4h4v1H8z"/><circle cx="6" cy="15" r="3"/><circle cx="14" cy="15" r="3"/></g></svg>
\ No newline at end of file
index ad783be..63db808 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAnonymous.png differ
index 6d957bf..4992c77 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>anonynmous user</title><path d="M15 2H5L4 8h12l-1-6zM0 10s2 1 10 1 10-1 10-1l-4-2H4zm6 2a3 3 0 1 0 3 3 3 3 0 0 0-3-3zm8 0a3 3 0 1 0 3 3 3 3 0 0 0-3-3z"/><path d="M8 14h4v1H8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>anonynmous user</title><path d="M15 2H5L4 8h12zM0 10s2 1 10 1 10-1 10-1l-4-2H4zm8 4h4v1H8z"/><circle cx="6" cy="15" r="3"/><circle cx="14" cy="15" r="3"/></svg>
\ No newline at end of file
index 661efeb..9255c46 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatar-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatar-invert.png differ
index e935851..f78d7f5 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatar.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatar.png differ
index f698db4..5914531 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-ltr-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-ltr-invert.png differ
index 36bb713..758d409 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-ltr.png differ
index cf65243..69302bb 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-rtl-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-rtl-invert.png differ
index 73cd17f..2ffdad0 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/userTalk-rtl.png differ
index d625efa..272352e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/viewCompact.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/viewCompact.png differ
index 3670abc..e88e67c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-ltr.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-ltr.png differ
index 3010c5e..38bffb3 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>view details</title><path fill="#fff" d="M12 8H3V6h9v2zm0-3H1V3h11v2zm1-2h6v6h-6zm-1 13H3v-2h9v2zm0-3H1v-2h11v2zm1-2h6v6h-6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>view details</title><path fill="#fff" d="M3 8V6h9v2zm9-3H1V3h11zm1-2h6v6h-6zm-1 13H3v-2h9zm0-3H1v-2h11zm1-2h6v6h-6z"/></svg>
\ No newline at end of file
index 37baa8e..54dc977 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>view details</title><path fill="#36c" d="M12 8H3V6h9v2zm0-3H1V3h11v2zm1-2h6v6h-6zm-1 13H3v-2h9v2zm0-3H1v-2h11v2zm1-2h6v6h-6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>view details</title><path fill="#36c" d="M3 8V6h9v2zm9-3H1V3h11zm1-2h6v6h-6zm-1 13H3v-2h9zm0-3H1v-2h11zm1-2h6v6h-6z"/></svg>
\ No newline at end of file
index 9ac8e73..8669fdd 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-rtl.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/viewDetails-rtl.png differ
index bcae7e0..49ad890 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>view details</title><path d="M12 8H3V6h9v2zm0-3H1V3h11v2zm1-2h6v6h-6zm-1 13H3v-2h9v2zm0-3H1v-2h11v2zm1-2h6v6h-6z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>view details</title><path d="M3 8V6h9v2zm9-3H1V3h11zm1-2h6v6h-6zm-1 13H3v-2h9zm0-3H1v-2h11zm1-2h6v6h-6z"/></svg>
\ No newline at end of file
index a0a0daa..4049184 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/visionSimulator-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/visionSimulator-invert.png differ
index 3dab87d..ca74315 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/visionSimulator.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/visionSimulator.png differ
index ca052de..09f408c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/web-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/web-invert.png differ
index 8e66c81..bc33d11 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="2 2 20 20"><title>web</title><g fill="#fff"><path id="laptop" d="M22.78 18.46L21 16V4H3v12l-1.757 2.463a.974.974 0 0 0-.157 1.043c.157.347.533.494.914.494h20c.382 0 .783-.148.94-.496a.976.976 0 0 0-.16-1.044zM4 18l1-2V6h14v10l1 2H4z"/><path id="window" d="M7 16h10V8H7v8zm2-2v-3h6v3H9z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>web</title><g fill="#fff"><path d="M19 14V2H1v12l-1 1.4V18h20v-2.6zM3 14V4h14v10l1 2H2z"/><path d="M5 14h10V6H5zm2-5h6v3H7z"/></g></svg>
\ No newline at end of file
index 430f06c..0bb1bed 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/web-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/web-progressive.png differ
index 3324d9c..f566113 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="2 2 20 20"><title>web</title><g fill="#36c"><path id="laptop" d="M22.78 18.46L21 16V4H3v12l-1.757 2.463a.974.974 0 0 0-.157 1.043c.157.347.533.494.914.494h20c.382 0 .783-.148.94-.496a.976.976 0 0 0-.16-1.044zM4 18l1-2V6h14v10l1 2H4z"/><path id="window" d="M7 16h10V8H7v8zm2-2v-3h6v3H9z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>web</title><g fill="#36c"><path d="M19 14V2H1v12l-1 1.4V18h20v-2.6zM3 14V4h14v10l1 2H2z"/><path d="M5 14h10V6H5zm2-5h6v3H7z"/></g></svg>
\ No newline at end of file
index 94f38be..e2cb0e3 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/web.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/web.png differ
index f6724db..9ad5056 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="2 2 20 20"><title>web</title><path id="laptop" d="M22.78 18.46L21 16V4H3v12l-1.757 2.463a.974.974 0 0 0-.157 1.043c.157.347.533.494.914.494h20c.382 0 .783-.148.94-.496a.976.976 0 0 0-.16-1.044zM4 18l1-2V6h14v10l1 2H4z"/><path id="window" d="M7 16h10V8H7v8zm2-2v-3h6v3H9z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>web</title><path d="M19 14V2H1v12l-1 1.4V18h20v-2.6zM3 14V4h14v10l1 2H2z"/><path d="M5 14h10V6H5zm2-5h6v3H7z"/></svg>
\ No newline at end of file
index f39b1c9..1a89ede 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikitext</title><path fill="#fff" d="M1 3v14h3v-2H3V5h1V3H1zm4 0v14h4v-2H7V5h2V3H5zm12 0h-1v2h1v10h-1v2h3V3h-2zm-6 0v2h2v10h-2v2h4V3h-4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikitext</title><path fill="#fff" d="M1 3v14h3v-2H3V5h1V3zm4 0v14h4v-2H7V5h2V3zm11 0v2h1v10h-1v2h3V3zm-5 0v2h2v10h-2v2h4V3z"/></svg>
\ No newline at end of file
index 5bf99f2..579ad04 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikitext</title><path fill="#36c" d="M1 3v14h3v-2H3V5h1V3H1zm4 0v14h4v-2H7V5h2V3H5zm12 0h-1v2h1v10h-1v2h3V3h-2zm-6 0v2h2v10h-2v2h4V3h-4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikitext</title><path fill="#36c" d="M1 3v14h3v-2H3V5h1V3zm4 0v14h4v-2H7V5h2V3zm11 0v2h1v10h-1v2h3V3zm-5 0v2h2v10h-2v2h4V3z"/></svg>
\ No newline at end of file
index 6c5a696..b5b32d8 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/wikiText.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/wikiText.png differ
index 612805e..3e9b08d 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikitext</title><path d="M1 3v14h3v-2H3V5h1V3H1zm4 0v14h4v-2H7V5h2V3H5zm12 0h-1v2h1v10h-1v2h3V3h-2zm-6 0v2h2v10h-2v2h4V3h-4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikitext</title><path d="M1 3v14h3v-2H3V5h1V3zm4 0v14h4v-2H7V5h2V3zm11 0v2h1v10h-1v2h3V3zm-5 0v2h2v10h-2v2h4V3z"/></svg>
\ No newline at end of file
index efb1fd5..84b42da 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/window-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/window-invert.png differ
index a867897..39d2c8c 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>window</title><g fill="#fff"><path d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 14H2V4h16z"/><path d="M4 6h12v2H4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>window</title><g fill="#fff"><path d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 2h16v12H2z"/><path d="M4 6h12v2H4z"/></g></svg>
\ No newline at end of file
index 6923d4b..f4745c5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>window</title><g fill="#36c"><path d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 14H2V4h16z"/><path d="M4 6h12v2H4z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>window</title><g fill="#36c"><path d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 2h16v12H2z"/><path d="M4 6h12v2H4z"/></g></svg>
\ No newline at end of file
index e0f1d7b..74d20ed 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/window.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/window.png differ
index 879dfba..ef76d55 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>window</title><path d="M18 2H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 14H2V4h16z"/><path d="M4 6h12v2H4z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>window</title><path d="M2 2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 2h16v12H2z"/><path d="M4 6h12v2H4z"/></svg>
\ No newline at end of file
index fe29c99..c386c84 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-invert.png differ
index ce56928..d4f8199 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>zoom in</title><g fill="#fff"><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.49 4.49 0 0 1 3.5 8z"/><path d="M11 7.25H8.75V5h-1.5v2.25H5v1.5h2.25V11h1.5V8.75H11v-1.5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>zoom in</title><g fill="#fff"><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.49 4.49 0 0 1 3.5 8z"/><path d="M11 7.25H8.75V5h-1.5v2.25H5v1.5h2.25V11h1.5V8.75H11z"/></g></svg>
\ No newline at end of file
index f73280c..4f2dc5b 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn-progressive.png differ
index 8288b28..25695b9 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>zoom in</title><g fill="#36c"><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.49 4.49 0 0 1 3.5 8z"/><path d="M11 7.25H8.75V5h-1.5v2.25H5v1.5h2.25V11h1.5V8.75H11v-1.5z"/></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>zoom in</title><g fill="#36c"><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.49 4.49 0 0 1 3.5 8z"/><path d="M11 7.25H8.75V5h-1.5v2.25H5v1.5h2.25V11h1.5V8.75H11z"/></g></svg>
\ No newline at end of file
index d80131c..8e4d5ab 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/zoomIn.png differ
index 6638012..673f753 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>zoom in</title><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.49 4.49 0 0 1 3.5 8z"/><path d="M11 7.25H8.75V5h-1.5v2.25H5v1.5h2.25V11h1.5V8.75H11v-1.5z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>zoom in</title><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.49 4.49 0 0 1 3.5 8z"/><path d="M11 7.25H8.75V5h-1.5v2.25H5v1.5h2.25V11h1.5V8.75H11z"/></svg>
\ No newline at end of file
index 972d287..b76e52c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut-invert.png differ
index 31ead17..7697b1e 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut-progressive.png differ
index 78b1204..28bad5c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/zoomOut.png differ
index e3f1ea0..35ec009 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/clear-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/clear-invert.png differ
index dc8c7e0..8d5b321 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/clear.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/clear.png differ
index fb4140a..d2fb78c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/down-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/down-invert.png differ
index 96414b5..91a0fcd 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>down</title><path fill="#fff" d="M11.05 3.996l-.965-1.053-4.035 3.86-3.947-3.86L1.05 3.996l5 5 5-5"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>down</title><path fill="#fff" d="M10.085 2.943L6.05 6.803l-3.947-3.86L1.05 3.996l5 5 5-5z"/></svg>
\ No newline at end of file
index acb40d9..8f4ef96 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/down.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/down.png differ
index dbb5298..cbc28e5 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>down</title><path d="M11.05 3.996l-.965-1.053-4.035 3.86-3.947-3.86L1.05 3.996l5 5 5-5"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>down</title><path d="M10.085 2.943L6.05 6.803l-3.947-3.86L1.05 3.996l5 5 5-5z"/></svg>
\ No newline at end of file
index ee70c03..6a0bea9 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/required-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/required-invert.png differ
index b7f517d..497d4f7 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/required.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/required.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/indicators/search-invert.png b/resources/lib/ooui/themes/wikimediaui/images/indicators/search-invert.png
deleted file mode 100644 (file)
index 5201eb1..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/search-invert.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/indicators/search-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/indicators/search-invert.svg
deleted file mode 100644 (file)
index 16c3438..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path fill="#fff" d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.5 4.5 0 0 1 3.5 8z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/indicators/search.png b/resources/lib/ooui/themes/wikimediaui/images/indicators/search.png
deleted file mode 100644 (file)
index b2ae15b..0000000
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/search.png and /dev/null differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/indicators/search.svg b/resources/lib/ooui/themes/wikimediaui/images/indicators/search.svg
deleted file mode 100644 (file)
index 293f53f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.5 4.5 0 0 1 3.5 8z"/></svg>
\ No newline at end of file
index c5e320d..60eaa4c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/up-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/up-invert.png differ
index 78d875c..1f354a2 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>up</title><path fill="#fff" d="M11 7.974l-.965 1.052L6 5.168 2.053 9.026 1 7.974l5-5 5 5"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>up</title><path fill="#fff" d="M10.035 9.026L6 5.168 2.053 9.026 1 7.974l5-5 5 5z"/></svg>
\ No newline at end of file
index 046a247..a148a5c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/indicators/up.png and b/resources/lib/ooui/themes/wikimediaui/images/indicators/up.png differ
index a8ec388..e541e23 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>up</title><path d="M11 7.974l-.965 1.052L6 5.168 2.053 9.026 1 7.974l5-5 5 5"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><title>up</title><path d="M10.035 9.026L6 5.168 2.053 9.026 1 7.974l5-5 5 5z"/></svg>
\ No newline at end of file
index 7a9b53a..0559ca7 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="#c8ccd1" d="M0 0h8v8H0zm8 8h8v8H8z"/><path fill="#fff" d="M8 0h8v8H8zM0 8h8v8H0z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="#c8ccd1" d="M0 0h16v16H0z"/><path fill="#fff" d="M8 0h8v8H0v8h8z"/></svg>
\ No newline at end of file
index 7bc0618..2d07315 100644 (file)
                },
                "required": {
                        "file": "images/indicators/required.svg"
-               },
-               "search": {
-                       "file": "images/indicators/search.svg",
-                       "deprecated": "This will be removed in v0.31.0."
                }
        }
 }
index e90730a..146cebe 100644 (file)
@@ -2,7 +2,13 @@
        "prefix": "oo-ui-texture",
        "intro": "@import '../../../../src/styles/common';",
        "images": {
-               "pending": { "file": "images/textures/pending.gif" },
-               "transparency": { "file": "images/textures/transparency.svg" }
+               "pending": {
+                       "file": "images/textures/pending.gif",
+                       "deprecated": "Deprecated since v0.31.1."
+               },
+               "transparency": {
+                       "file": "images/textures/transparency.svg",
+                       "deprecated": "Deprecated since v0.31.1."
+               }
        }
 }
diff --git a/resources/src/jquery.spinner/images/spinner-large.gif b/resources/src/jquery.spinner/images/spinner-large.gif
deleted file mode 100644 (file)
index 72203fd..0000000
Binary files a/resources/src/jquery.spinner/images/spinner-large.gif and /dev/null differ
diff --git a/resources/src/jquery.spinner/images/spinner.gif b/resources/src/jquery.spinner/images/spinner.gif
deleted file mode 100644 (file)
index 6146be4..0000000
Binary files a/resources/src/jquery.spinner/images/spinner.gif and /dev/null differ
diff --git a/resources/src/jquery.spinner/spinner.css b/resources/src/jquery.spinner/spinner.css
deleted file mode 100644 (file)
index 9c819a6..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-.mw-spinner {
-       background-color: transparent;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-
-.mw-spinner-small {
-       /* @embed */
-       background-image: url( images/spinner.gif );
-       height: 20px;
-       width: 20px;
-       /* Avoid issues with .mw-spinner-block when floated without width. */
-       min-width: 20px;
-}
-
-.mw-spinner-large {
-       /* @embed */
-       background-image: url( images/spinner-large.gif );
-       height: 32px;
-       width: 32px;
-       /* Avoid issues with .mw-spinner-block when floated without width. */
-       min-width: 32px;
-}
-
-.mw-spinner-block {
-       display: block;
-       /* This overrides width from .mw-spinner-large / .mw-spinner-small,
-        * This is where the min-width kicks in.
-        */
-       width: 100%;
-}
-
-.mw-spinner-inline {
-       display: inline-block;
-       vertical-align: middle;
-}
index 5dfbab7..8cccedb 100644 (file)
@@ -59,7 +59,7 @@
                 * @return {jQuery}
                 */
                createSpinner: function ( opts ) {
-                       var $spinner;
+                       var i, $spinner, $container;
 
                        if ( typeof opts === 'string' ) {
                                opts = {
                                $spinner.attr( 'id', 'mw-spinner-' + opts.id );
                        }
 
-                       $spinner.addClass( opts.size === 'large' ? 'mw-spinner-large' : 'mw-spinner-small' );
-                       $spinner.addClass( opts.type === 'block' ? 'mw-spinner-block' : 'mw-spinner-inline' );
+                       $spinner
+                               .addClass( opts.size === 'large' ? 'mw-spinner-large' : 'mw-spinner-small' )
+                               .addClass( opts.type === 'block' ? 'mw-spinner-block' : 'mw-spinner-inline' );
+
+                       $container = $( '<div>' ).addClass( 'mw-spinner-container' ).appendTo( $spinner );
+                       for ( i = 0; i < 12; i++ ) {
+                               $container.append( $( '<div>' ) );
+                       }
 
                        return $spinner;
                },
diff --git a/resources/src/jquery.spinner/spinner.less b/resources/src/jquery.spinner/spinner.less
new file mode 100644 (file)
index 0000000..596858e
--- /dev/null
@@ -0,0 +1,143 @@
+.mw-spinner {
+       position: relative;
+
+       > .mw-spinner-container {
+               transform-origin: 0 0;
+       }
+}
+
+@mw-spinner-small-size: 20px;
+@mw-spinner-large-size: 32px;
+
+.mw-spinner-small {
+       width: @mw-spinner-small-size;
+       height: @mw-spinner-small-size;
+
+       > .mw-spinner-container {
+               transform: scale( unit( @mw-spinner-small-size / 64 ) );
+       }
+}
+
+.mw-spinner-large {
+       width: @mw-spinner-large-size;
+       height: @mw-spinner-large-size;
+
+       > .mw-spinner-container {
+               transform: scale( unit( @mw-spinner-large-size / 64 ) );
+       }
+}
+
+.mw-spinner-block {
+       display: block;
+       width: 100%;
+       text-align: center;
+
+       > .mw-spinner-container {
+               display: inline-block;
+               vertical-align: top;
+       }
+
+       &.mw-spinner-small > .mw-spinner-container {
+               min-width: @mw-spinner-small-size;
+       }
+
+       &.mw-spinner-large > .mw-spinner-container {
+               min-width: @mw-spinner-large-size;
+       }
+}
+
+.mw-spinner-inline {
+       display: inline-block;
+       vertical-align: middle;
+}
+
+/**
+ * CSS loading spinner adapted from loadingio, CC0
+ * https://github.com/loadingio/css-spinner/
+ */
+.mw-spinner-container > div {
+       transform-origin: 32px 32px;
+       animation: mw-spinner 1.2s linear infinite;
+}
+
+.mw-spinner-container > div:after {
+       content: ' ';
+       display: block;
+       position: absolute;
+       top: 3px;
+       left: 29px;
+       width: 5px;
+       height: 14px;
+       border-radius: 20%;
+       background: #000;
+}
+
+.mw-spinner-container > div:nth-child( 1 ) {
+       transform: rotate( 0deg );
+       animation-delay: -1.1s;
+}
+
+.mw-spinner-container > div:nth-child( 2 ) {
+       transform: rotate( 30deg );
+       animation-delay: -1s;
+}
+
+.mw-spinner-container > div:nth-child( 3 ) {
+       transform: rotate( 60deg );
+       animation-delay: -0.9s;
+}
+
+.mw-spinner-container > div:nth-child( 4 ) {
+       transform: rotate( 90deg );
+       animation-delay: -0.8s;
+}
+
+.mw-spinner-container > div:nth-child( 5 ) {
+       transform: rotate( 120deg );
+       animation-delay: -0.7s;
+}
+
+.mw-spinner-container > div:nth-child( 6 ) {
+       transform: rotate( 150deg );
+       animation-delay: -0.6s;
+}
+
+.mw-spinner-container > div:nth-child( 7 ) {
+       transform: rotate( 180deg );
+       animation-delay: -0.5s;
+}
+
+.mw-spinner-container > div:nth-child( 8 ) {
+       transform: rotate( 210deg );
+       animation-delay: -0.4s;
+}
+
+.mw-spinner-container > div:nth-child( 9 ) {
+       transform: rotate( 240deg );
+       animation-delay: -0.3s;
+}
+
+.mw-spinner-container > div:nth-child( 10 ) {
+       transform: rotate( 270deg );
+       animation-delay: -0.2s;
+}
+
+.mw-spinner-container > div:nth-child( 11 ) {
+       transform: rotate( 300deg );
+       animation-delay: -0.1s;
+}
+
+.mw-spinner-container > div:nth-child( 12 ) {
+       transform: rotate( 330deg );
+       animation-delay: 0s;
+}
+
+@keyframes mw-spinner {
+       0% {
+               opacity: 1;
+       }
+
+       100% {
+               opacity: 0;
+       }
+}
index 6107af1..c1b83fd 100644 (file)
                return false;
        }
 
+       /**
+        * @param {HTMLElement} node
+        * @return {string}
+        */
        function getElementSortKey( node ) {
-               var $node = $( node ),
-                       // Use data-sort-value attribute.
-                       // Use data() instead of attr() so that live value changes
-                       // are processed as well (T40152).
-                       data = $node.data( 'sortValue' );
+               // Get data-sort-value attribute. Uses jQuery to allow live value
+               // changes from other code paths via data(), which reside only in jQuery.
+               // Must use $().data() instead of $.data(), as the latter *only*
+               // accesses the live values, without reading HTML5 attribs first (T40152).
+               var data = $( node ).data( 'sortValue' );
 
                if ( data !== null && data !== undefined ) {
                        // Cast any numbers or other stuff to a string, methods
                        // like charAt, toLowerCase and split are expected.
                        return String( data );
                }
-               if ( !node ) {
-                       return $node.text();
-               }
                if ( node.tagName.toLowerCase() === 'img' ) {
-                       return $node.attr( 'alt' ) || ''; // handle undefined alt
+                       return node.alt;
                }
-               return $.makeArray( node.childNodes ).map( function ( elem ) {
+               // Iterate the NodeList (not an array).
+               // Also uses null-return as filter in the same pass.
+               // eslint-disable-next-line no-jquery/no-map-util
+               return $.map( node.childNodes, function ( elem ) {
                        if ( elem.nodeType === Node.ELEMENT_NODE ) {
                                if ( $( elem ).hasClass( 'reference' ) ) {
                                        return null;
-                               } else {
-                                       return getElementSortKey( elem );
                                }
+                               return getElementSortKey( elem );
                        }
-                       return $.text( elem );
+                       if ( elem.nodeType === Node.TEXT_NODE ) {
+                               return elem.textContent;
+                       }
+                       // Ignore other node types, such as HTML comments.
+                       return null;
                } ).join( '' );
        }
 
                                        $table = $( table ),
                                        firstTime = true;
 
+                               // Don't construct twice on the same table
+                               if ( $.data( table, 'tablesorter' ) ) {
+                                       return;
+                               }
                                // Quit if no tbody
                                if ( !table.tBodies ) {
                                        return;
index 028b4b9..08bb601 100644 (file)
@@ -36,6 +36,7 @@
         *     the first parameter and 'yes' or 'no' as the second.
         * @param {Function} [options.handler] Callback to fire when the action is confirmed (user clicks
         *     the 'Yes' button).
+        * @param {string} [options.delegate] Optional selector used for jQuery event delegation
         * @param {string} [options.i18n] Text to use for interface elements.
         * @param {string} [options.i18n.space] Word separator to place between the three text messages.
         * @param {string} [options.i18n.confirm] Text to use for the confirmation question.
        $.fn.confirmable = function ( options ) {
                options = $.extend( true, {}, $.fn.confirmable.defaultOptions, options || {} );
 
-               return this.on( options.events, function ( e ) {
-                       var $element, $text, $buttonYes, $buttonNo, $wrapper, $interface, $elementClone,
-                               interfaceWidth, elementWidth, rtl, positionOffscreen, positionRestore, sideMargin;
+               if ( options.delegate === null ) {
+                       return this.on( options.events, function ( e ) {
+                               $.fn.confirmable.handler( e, options );
+                       } );
+               }
 
-                       $element = $( this );
+               return this.on( options.events, options.delegate, function ( e ) {
+                       $.fn.confirmable.handler( e, options );
+               } );
+       };
 
-                       if ( $element.data( 'jquery-confirmable-button' ) ) {
-                               // We're running on a clone of this element that represents the 'Yes' or 'No' button.
-                               // (This should never happen for the 'No' case unless calling code does bad things.)
-                               return;
-                       }
+       $.fn.confirmable.handler = function ( event, options ) {
+               var $element, $text, $buttonYes, $buttonNo, $wrapper, $interface, $elementClone,
+                       interfaceWidth, elementWidth, rtl, positionOffscreen, positionRestore, sideMargin;
 
-                       // Only prevent native event handling. Stopping other JavaScript event handlers
-                       // is impossible because they might have already run (we have no control over the order).
-                       e.preventDefault();
+               $element = $( event.target );
 
-                       rtl = $element.css( 'direction' ) === 'rtl';
-                       if ( rtl ) {
-                               positionOffscreen = { position: 'absolute', right: '-9999px' };
-                               positionRestore = { position: '', right: '' };
-                               sideMargin = 'marginRight';
-                       } else {
-                               positionOffscreen = { position: 'absolute', left: '-9999px' };
-                               positionRestore = { position: '', left: '' };
-                               sideMargin = 'marginLeft';
-                       }
+               if ( $element.data( 'jquery-confirmable-button' ) ) {
+                       // We're running on a clone of this element that represents the 'Yes' or 'No' button.
+                       // (This should never happen for the 'No' case unless calling code does bad things.)
+                       return;
+               }
 
-                       if ( $element.hasClass( 'jquery-confirmable-element' ) ) {
-                               $wrapper = $element.closest( '.jquery-confirmable-wrapper' );
-                               $interface = $wrapper.find( '.jquery-confirmable-interface' );
-                               $text = $interface.find( '.jquery-confirmable-text' );
-                               $buttonYes = $interface.find( '.jquery-confirmable-button-yes' );
-                               $buttonNo = $interface.find( '.jquery-confirmable-button-no' );
+               // Only prevent native event handling. Stopping other JavaScript event handlers
+               // is impossible because they might have already run (we have no control over the order).
+               event.preventDefault();
+
+               rtl = $element.css( 'direction' ) === 'rtl';
+               if ( rtl ) {
+                       positionOffscreen = { position: 'absolute', right: '-9999px' };
+                       positionRestore = { position: '', right: '' };
+                       sideMargin = 'marginRight';
+               } else {
+                       positionOffscreen = { position: 'absolute', left: '-9999px' };
+                       positionRestore = { position: '', left: '' };
+                       sideMargin = 'marginLeft';
+               }
 
-                               interfaceWidth = $interface.data( 'jquery-confirmable-width' );
-                               elementWidth = $element.data( 'jquery-confirmable-width' );
+               if ( $element.hasClass( 'jquery-confirmable-element' ) ) {
+                       $wrapper = $element.closest( '.jquery-confirmable-wrapper' );
+                       $interface = $wrapper.find( '.jquery-confirmable-interface' );
+                       $text = $interface.find( '.jquery-confirmable-text' );
+                       $buttonYes = $interface.find( '.jquery-confirmable-button-yes' );
+                       $buttonNo = $interface.find( '.jquery-confirmable-button-no' );
+
+                       interfaceWidth = $interface.data( 'jquery-confirmable-width' );
+                       elementWidth = $element.data( 'jquery-confirmable-width' );
+               } else {
+                       $elementClone = $element.clone( true );
+                       $element.addClass( 'jquery-confirmable-element' );
+
+                       elementWidth = $element.width();
+                       $element.data( 'jquery-confirmable-width', elementWidth );
+
+                       $wrapper = $( '<span>' )
+                               .addClass( 'jquery-confirmable-wrapper' );
+                       $element.wrap( $wrapper );
+
+                       // Build the mini-dialog
+                       $text = $( '<span>' )
+                               .addClass( 'jquery-confirmable-text' )
+                               .text( options.i18n.confirm );
+
+                       // Clone original element along with event handlers to easily replicate its behavior.
+                       // We could fiddle with .trigger() etc., but that is troublesome especially since
+                       // Safari doesn't implement .click() on <a> links and jQuery follows suit.
+                       $buttonYes = $elementClone.clone( true )
+                               .addClass( 'jquery-confirmable-button jquery-confirmable-button-yes' )
+                               .data( 'jquery-confirmable-button', true )
+                               .text( options.i18n.yes );
+                       if ( options.handler ) {
+                               $buttonYes.on( options.events, options.handler );
+                       }
+                       if ( options.i18n.yesTitle ) {
+                               $buttonYes.attr( 'title', options.i18n.yesTitle );
+                       }
+                       $buttonYes = options.buttonCallback( $buttonYes, 'yes' );
+
+                       // Clone it without any events and prevent default action to represent the 'No' button.
+                       $buttonNo = $elementClone.clone( false )
+                               .addClass( 'jquery-confirmable-button jquery-confirmable-button-no' )
+                               .data( 'jquery-confirmable-button', true )
+                               .text( options.i18n.no )
+                               .on( options.events, function ( e ) {
+                                       $element.css( sideMargin, 0 );
+                                       $interface.css( 'width', 0 );
+                                       e.preventDefault();
+                               } );
+                       if ( options.i18n.noTitle ) {
+                               $buttonNo.attr( 'title', options.i18n.noTitle );
                        } else {
-                               $elementClone = $element.clone( true );
-                               $element.addClass( 'jquery-confirmable-element' );
-
-                               elementWidth = $element.width();
-                               $element.data( 'jquery-confirmable-width', elementWidth );
-
-                               $wrapper = $( '<span>' )
-                                       .addClass( 'jquery-confirmable-wrapper' );
-                               $element.wrap( $wrapper );
-
-                               // Build the mini-dialog
-                               $text = $( '<span>' )
-                                       .addClass( 'jquery-confirmable-text' )
-                                       .text( options.i18n.confirm );
-
-                               // Clone original element along with event handlers to easily replicate its behavior.
-                               // We could fiddle with .trigger() etc., but that is troublesome especially since
-                               // Safari doesn't implement .click() on <a> links and jQuery follows suit.
-                               $buttonYes = $elementClone.clone( true )
-                                       .addClass( 'jquery-confirmable-button jquery-confirmable-button-yes' )
-                                       .data( 'jquery-confirmable-button', true )
-                                       .text( options.i18n.yes );
-                               if ( options.handler ) {
-                                       $buttonYes.on( options.events, options.handler );
-                               }
-                               if ( options.i18n.yesTitle ) {
-                                       $buttonYes.attr( 'title', options.i18n.yesTitle );
-                               }
-                               $buttonYes = options.buttonCallback( $buttonYes, 'yes' );
-
-                               // Clone it without any events and prevent default action to represent the 'No' button.
-                               $buttonNo = $elementClone.clone( false )
-                                       .addClass( 'jquery-confirmable-button jquery-confirmable-button-no' )
-                                       .data( 'jquery-confirmable-button', true )
-                                       .text( options.i18n.no )
-                                       .on( options.events, function ( e ) {
-                                               $element.css( sideMargin, 0 );
-                                               $interface.css( 'width', 0 );
-                                               e.preventDefault();
-                                       } );
-                               if ( options.i18n.noTitle ) {
-                                       $buttonNo.attr( 'title', options.i18n.noTitle );
-                               } else {
-                                       $buttonNo.removeAttr( 'title' );
-                               }
-                               $buttonNo = options.buttonCallback( $buttonNo, 'no' );
-
-                               // Prevent memory leaks
-                               $elementClone.remove();
-
-                               $interface = $( '<span>' )
-                                       .addClass( 'jquery-confirmable-interface' )
-                                       .append( $text, options.i18n.space, $buttonYes, options.i18n.space, $buttonNo );
-                               $interface = options.wrapperCallback( $interface );
-
-                               // Render offscreen to measure real width
-                               $interface.css( positionOffscreen );
-                               // Insert it in the correct place while we're at it
-                               $element.after( $interface );
-                               interfaceWidth = $interface.width();
-                               $interface.data( 'jquery-confirmable-width', interfaceWidth );
-                               $interface.css( positionRestore );
-
-                               // Hide to animate the transition later
-                               $interface.css( 'width', 0 );
+                               $buttonNo.removeAttr( 'title' );
                        }
+                       $buttonNo = options.buttonCallback( $buttonNo, 'no' );
+
+                       // Prevent memory leaks
+                       $elementClone.remove();
+
+                       $interface = $( '<span>' )
+                               .addClass( 'jquery-confirmable-interface' )
+                               .append( $text, options.i18n.space, $buttonYes, options.i18n.space, $buttonNo );
+                       $interface = options.wrapperCallback( $interface );
+
+                       // Render offscreen to measure real width
+                       $interface.css( positionOffscreen );
+                       // Insert it in the correct place while we're at it
+                       $element.after( $interface );
+                       interfaceWidth = $interface.width();
+                       $interface.data( 'jquery-confirmable-width', interfaceWidth );
+                       $interface.css( positionRestore );
+
+                       // Hide to animate the transition later
+                       $interface.css( 'width', 0 );
+               }
 
-                       // Hide element, show interface. This triggers both transitions.
-                       // In a timeout to trigger the 'width' transition.
-                       setTimeout( function () {
-                               $element.css( sideMargin, -elementWidth );
-                               $interface.css( 'width', interfaceWidth );
-                       }, 1 );
-               } );
+               // Hide element, show interface. This triggers both transitions.
+               // In a timeout to trigger the 'width' transition.
+               setTimeout( function () {
+                       $element.css( sideMargin, -elementWidth );
+                       $interface.css( 'width', interfaceWidth );
+               }, 1 );
        };
 
        /**
                wrapperCallback: identity,
                buttonCallback: identity,
                handler: null,
+               delegate: null,
                i18n: {
                        space: ' ',
                        confirm: 'Are you sure?',
diff --git a/resources/src/jquery/jquery.hidpi.js b/resources/src/jquery/jquery.hidpi.js
deleted file mode 100644 (file)
index 025e6c2..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * Responsive images based on `srcset` and `window.devicePixelRatio` emulation where needed.
- *
- * Call `.hidpi()` on a document or part of a document to proces image srcsets within that section.
- *
- * `$.devicePixelRatio()` can be used as a substitute for `window.devicePixelRatio`.
- * It provides a familiar interface to retrieve the pixel ratio for browsers that don't
- * implement `window.devicePixelRatio` but do have a different way of getting it.
- *
- * @class jQuery.plugin.hidpi
- */
-( function () {
-
-       /**
-        * Get reported or approximate device pixel ratio.
-        *
-        * - 1.0 means 1 CSS pixel is 1 hardware pixel
-        * - 2.0 means 1 CSS pixel is 2 hardware pixels
-        * - etc.
-        *
-        * Uses `window.devicePixelRatio` if available, or CSS media queries on IE.
-        *
-        * @static
-        * @inheritable
-        * @return {number} Device pixel ratio
-        */
-       $.devicePixelRatio = function () {
-               if ( window.devicePixelRatio !== undefined ) {
-                       // Most web browsers:
-                       // * WebKit/Blink (Safari, Chrome, Android browser, etc)
-                       // * Opera
-                       // * Firefox 18+
-                       // * Microsoft Edge (Windows 10)
-                       return window.devicePixelRatio;
-               } else if ( window.msMatchMedia !== undefined ) {
-                       // Windows 8 desktops / tablets, probably Windows Phone 8
-                       //
-                       // IE 10/11 doesn't report pixel ratio directly, but we can get the
-                       // screen DPI and divide by 96. We'll bracket to [1, 1.5, 2.0] for
-                       // simplicity, but you may get different values depending on zoom
-                       // factor, size of screen and orientation in Metro IE.
-                       if ( window.msMatchMedia( '(min-resolution: 192dpi)' ).matches ) {
-                               return 2;
-                       } else if ( window.msMatchMedia( '(min-resolution: 144dpi)' ).matches ) {
-                               return 1.5;
-                       } else {
-                               return 1;
-                       }
-               } else {
-                       // Legacy browsers...
-                       // Assume 1 if unknown.
-                       return 1;
-               }
-       };
-
-       /**
-        * Bracket a given device pixel ratio to one of [1, 1.5, 2].
-        *
-        * This is useful for grabbing images on the fly with sizes based on the display
-        * density, without causing slowdown and extra thumbnail renderings on devices
-        * that are slightly different from the most common sizes.
-        *
-        * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
-        * so will be consistent with default renderings.
-        *
-        * @static
-        * @inheritable
-        * @param {number} baseRatio Base ratio
-        * @return {number} Device pixel ratio
-        */
-       $.bracketDevicePixelRatio = function ( baseRatio ) {
-               if ( baseRatio > 1.5 ) {
-                       return 2;
-               } else if ( baseRatio > 1 ) {
-                       return 1.5;
-               } else {
-                       return 1;
-               }
-       };
-
-       /**
-        * Get reported or approximate device pixel ratio, bracketed to [1, 1.5, 2].
-        *
-        * This is useful for grabbing images on the fly with sizes based on the display
-        * density, without causing slowdown and extra thumbnail renderings on devices
-        * that are slightly different from the most common sizes.
-        *
-        * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
-        * so will be consistent with default renderings.
-        *
-        * - 1.0 means 1 CSS pixel is 1 hardware pixel
-        * - 1.5 means 1 CSS pixel is 1.5 hardware pixels
-        * - 2.0 means 1 CSS pixel is 2 hardware pixels
-        *
-        * @static
-        * @inheritable
-        * @return {number} Device pixel ratio
-        */
-       $.bracketedDevicePixelRatio = function () {
-               return $.bracketDevicePixelRatio( $.devicePixelRatio() );
-       };
-
-       /**
-        * Implement responsive images based on srcset attributes, if browser has no
-        * native srcset support.
-        *
-        * @return {jQuery} This selection
-        * @chainable
-        */
-       $.fn.hidpi = function () {
-               var $target = this,
-                       // TODO add support for dpi media query checks on Firefox, IE
-                       devicePixelRatio = $.devicePixelRatio(),
-                       testImage = new Image();
-
-               if ( devicePixelRatio > 1 && testImage.srcset === undefined ) {
-                       // No native srcset support.
-                       $target.find( 'img' ).each( function () {
-                               var $img = $( this ),
-                                       srcset = $img.attr( 'srcset' ),
-                                       match;
-                               if ( typeof srcset === 'string' && srcset !== '' ) {
-                                       match = $.matchSrcSet( devicePixelRatio, srcset );
-                                       if ( match !== null ) {
-                                               $img.attr( 'src', match );
-                                       }
-                               }
-                       } );
-               }
-
-               return $target;
-       };
-
-       /**
-        * Match a srcset entry for the given device pixel ratio
-        *
-        * Exposed for testing.
-        *
-        * @private
-        * @static
-        * @param {number} devicePixelRatio
-        * @param {string} srcset
-        * @return {Mixed} null or the matching src string
-        */
-       $.matchSrcSet = function ( devicePixelRatio, srcset ) {
-               var candidates,
-                       candidate,
-                       bits,
-                       src,
-                       i,
-                       ratioStr,
-                       ratio,
-                       selectedRatio = 1,
-                       selectedSrc = null;
-               candidates = srcset.split( / *, */ );
-               for ( i = 0; i < candidates.length; i++ ) {
-                       candidate = candidates[ i ];
-                       bits = candidate.split( / +/ );
-                       src = bits[ 0 ];
-                       if ( bits.length > 1 && bits[ 1 ].charAt( bits[ 1 ].length - 1 ) === 'x' ) {
-                               ratioStr = bits[ 1 ].slice( 0, -1 );
-                               ratio = parseFloat( ratioStr );
-                               if ( ratio <= devicePixelRatio && ratio > selectedRatio ) {
-                                       selectedRatio = ratio;
-                                       selectedSrc = src;
-                               }
-                       }
-               }
-               return selectedSrc;
-       };
-
-       /**
-        * @class jQuery
-        * @mixins jQuery.plugin.hidpi
-        */
-
-}() );
index ec96cb6..0f922c9 100644 (file)
@@ -124,6 +124,12 @@ li,
        }
 }
 
+fieldset.mw-collapsible .mw-collapsible-toggle {
+       position: absolute;
+       right: 0;
+       z-index: 1;
+}
+
 // special treatment for list items to match above
 // !important necessary to override overly-specific float left and right above.
 ol.mw-collapsible:not( @{exclude} ):before,
diff --git a/resources/src/mediawiki.Title/.eslintrc.json b/resources/src/mediawiki.Title/.eslintrc.json
new file mode 100644 (file)
index 0000000..ad8dbb3
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "parserOptions": {
+               "sourceType": "module"
+       }
+}
index 6bb3bce..900dab2 100644 (file)
 /*!
  * @author Neil Kandalgaonkar, 2010
- * @author Timo Tijhof
  * @since 1.18
  */
 
-( function () {
-       /**
-        * Parse titles into an object structure. Note that when using the constructor
-        * directly, passing invalid titles will result in an exception. Use #newFromText to use the
-        * logic directly and get null for invalid titles which is easier to work with.
-        *
-        * Note that in the constructor and #newFromText method, `namespace` is the **default** namespace
-        * only, and can be overridden by a namespace prefix in `title`. If you do not want this behavior,
-        * use #makeTitle. Compare:
-        *
-        *     new mw.Title( 'Foo', NS_TEMPLATE ).getPrefixedText();                  // => 'Template:Foo'
-        *     mw.Title.newFromText( 'Foo', NS_TEMPLATE ).getPrefixedText();          // => 'Template:Foo'
-        *     mw.Title.makeTitle( NS_TEMPLATE, 'Foo' ).getPrefixedText();            // => 'Template:Foo'
-        *
-        *     new mw.Title( 'Category:Foo', NS_TEMPLATE ).getPrefixedText();         // => 'Category:Foo'
-        *     mw.Title.newFromText( 'Category:Foo', NS_TEMPLATE ).getPrefixedText(); // => 'Category:Foo'
-        *     mw.Title.makeTitle( NS_TEMPLATE, 'Category:Foo' ).getPrefixedText();   // => 'Template:Category:Foo'
-        *
-        *     new mw.Title( 'Template:Foo', NS_TEMPLATE ).getPrefixedText();         // => 'Template:Foo'
-        *     mw.Title.newFromText( 'Template:Foo', NS_TEMPLATE ).getPrefixedText(); // => 'Template:Foo'
-        *     mw.Title.makeTitle( NS_TEMPLATE, 'Template:Foo' ).getPrefixedText();   // => 'Template:Template:Foo'
-        *
-        * @class mw.Title
-        */
-
-       /* Private members */
-
-       var
-               mwString = require( 'mediawiki.String' ),
-
-               namespaceIds = mw.config.get( 'wgNamespaceIds' ),
-
-               /**
-                * @private
-                * @static
-                * @property NS_MAIN
-                */
-               NS_MAIN = namespaceIds[ '' ],
-
-               /**
-                * @private
-                * @static
-                * @property NS_TALK
-                */
-               NS_TALK = namespaceIds.talk,
-
-               /**
-                * @private
-                * @static
-                * @property NS_SPECIAL
-                */
-               NS_SPECIAL = namespaceIds.special,
-
-               /**
-                * @private
-                * @static
-                * @property NS_MEDIA
-                */
-               NS_MEDIA = namespaceIds.media,
-
-               /**
-                * @private
-                * @static
-                * @property NS_FILE
-                */
-               NS_FILE = namespaceIds.file,
-
-               /**
-                * @private
-                * @static
-                * @property FILENAME_MAX_BYTES
-                */
-               FILENAME_MAX_BYTES = 240,
-
-               /**
-                * @private
-                * @static
-                * @property TITLE_MAX_BYTES
-                */
-               TITLE_MAX_BYTES = 255,
-
-               /**
-                * Get the namespace id from a namespace name (either from the localized, canonical or alias
-                * name).
-                *
-                * Example: On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or
-                * even 'Bild'.
-                *
-                * @private
-                * @static
-                * @method getNsIdByName
-                * @param {string} ns Namespace name (case insensitive, leading/trailing space ignored)
-                * @return {number|boolean} Namespace id or boolean false
-                */
-               getNsIdByName = function ( ns ) {
-                       var id;
-
-                       // Don't cast non-strings to strings, because null or undefined should not result in
-                       // returning the id of a potential namespace called "Null:" (e.g. on null.example.org/wiki)
-                       // Also, toLowerCase throws exception on null/undefined, because it is a String method.
-                       if ( typeof ns !== 'string' ) {
-                               return false;
-                       }
-                       // TODO: Should just use local var namespaceIds here but it
-                       // breaks test which modify the config
-                       id = mw.config.get( 'wgNamespaceIds' )[ ns.toLowerCase() ];
-                       if ( id === undefined ) {
-                               return false;
-                       }
-                       return id;
-               },
-
-               /**
-                * @private
-                * @method getNamespacePrefix_
-                * @param {number} namespace
-                * @return {string}
-                */
-               getNamespacePrefix = function ( namespace ) {
-                       return namespace === NS_MAIN ?
-                               '' :
-                               ( mw.config.get( 'wgFormattedNamespaces' )[ namespace ].replace( / /g, '_' ) + ':' );
-               },
-
-               rUnderscoreTrim = /^_+|_+$/g,
-
-               rSplit = /^(.+?)_*:_*(.*)$/,
-
-               // See MediaWikiTitleCodec.php#getTitleInvalidRegex
-               rInvalid = new RegExp(
-                       '[^' + mw.config.get( 'wgLegalTitleChars' ) + ']' +
-                       // URL percent encoding sequences interfere with the ability
-                       // to round-trip titles -- you can't link to them consistently.
-                       '|%[0-9A-Fa-f]{2}' +
-                       // XML/HTML character references produce similar issues.
-                       '|&[A-Za-z0-9\u0080-\uFFFF]+;' +
-                       '|&#[0-9]+;' +
-                       '|&#x[0-9A-Fa-f]+;'
-               ),
-
-               // From MediaWikiTitleCodec::splitTitleString() in PHP
-               // Note that this is not equivalent to /\s/, e.g. underscore is included, tab is not included.
-               rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g,
-
-               // From MediaWikiTitleCodec::splitTitleString() in PHP
-               rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]/g,
-
-               /**
-                * Slightly modified from Flinfo. Credit goes to Lupo and Flominator.
-                * @private
-                * @static
-                * @property sanitationRules
-                */
-               sanitationRules = [
-                       // "signature"
-                       {
-                               pattern: /~{3}/g,
-                               replace: '',
-                               generalRule: true
-                       },
-                       // control characters
-                       {
-                               // eslint-disable-next-line no-control-regex
-                               pattern: /[\x00-\x1f\x7f]/g,
-                               replace: '',
-                               generalRule: true
-                       },
-                       // URL encoding (possibly)
-                       {
-                               pattern: /%([0-9A-Fa-f]{2})/g,
-                               replace: '% $1',
-                               generalRule: true
-                       },
-                       // HTML-character-entities
-                       {
-                               pattern: /&(([A-Za-z0-9\x80-\xff]+|#[0-9]+|#x[0-9A-Fa-f]+);)/g,
-                               replace: '& $1',
-                               generalRule: true
-                       },
-                       // slash, colon (not supported by file systems like NTFS/Windows, Mac OS 9 [:], ext4 [/])
-                       {
-                               pattern: new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']', 'g' ),
-                               replace: '-',
-                               fileRule: true
-                       },
-                       // brackets, greater than
-                       {
-                               pattern: /[}\]>]/g,
-                               replace: ')',
-                               generalRule: true
-                       },
-                       // brackets, lower than
-                       {
-                               pattern: /[{[<]/g,
-                               replace: '(',
-                               generalRule: true
-                       },
-                       // everything that wasn't covered yet
-                       {
-                               pattern: new RegExp( rInvalid.source, 'g' ),
-                               replace: '-',
-                               generalRule: true
-                       },
-                       // directory structures
-                       {
-                               pattern: /^(\.|\.\.|\.\/.*|\.\.\/.*|.*\/\.\/.*|.*\/\.\.\/.*|.*\/\.|.*\/\.\.)$/g,
-                               replace: '',
-                               generalRule: true
-                       }
-               ],
-
-               /**
-                * Internal helper for #constructor and #newFromText.
-                *
-                * Based on Title.php#secureAndSplit
-                *
-                * @private
-                * @static
-                * @method parse
-                * @param {string} title
-                * @param {number} [defaultNamespace=NS_MAIN]
-                * @return {Object|boolean}
-                */
-               parse = function ( title, defaultNamespace ) {
-                       var namespace, m, id, i, fragment, ext;
-
-                       namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
-
-                       title = title
-                               // Strip Unicode bidi override characters
-                               .replace( rUnicodeBidi, '' )
-                               // Normalise whitespace to underscores and remove duplicates
-                               .replace( rWhitespace, '_' )
-                               // Trim underscores
-                               .replace( rUnderscoreTrim, '' );
-
-                       // Process initial colon
-                       if ( title !== '' && title[ 0 ] === ':' ) {
-                               // Initial colon means main namespace instead of specified default
-                               namespace = NS_MAIN;
-                               title = title
-                                       // Strip colon
-                                       .slice( 1 )
-                                       // Trim underscores
-                                       .replace( rUnderscoreTrim, '' );
-                       }
-
-                       if ( title === '' ) {
-                               return false;
-                       }
-
-                       // Process namespace prefix (if any)
-                       m = title.match( rSplit );
-                       if ( m ) {
-                               id = getNsIdByName( m[ 1 ] );
-                               if ( id !== false ) {
-                                       // Ordinary namespace
-                                       namespace = id;
-                                       title = m[ 2 ];
-
-                                       // For Talk:X pages, make sure X has no "namespace" prefix
-                                       if ( namespace === NS_TALK && ( m = title.match( rSplit ) ) ) {
-                                               // Disallow titles like Talk:File:x (subject should roundtrip: talk:file:x -> file:x -> file_talk:x)
-                                               if ( getNsIdByName( m[ 1 ] ) !== false ) {
-                                                       return false;
-                                               }
-                                       }
-                               }
-                       }
-
-                       // Process fragment
-                       i = title.indexOf( '#' );
-                       if ( i === -1 ) {
-                               fragment = null;
-                       } else {
-                               fragment = title
-                                       // Get segment starting after the hash
-                                       .slice( i + 1 )
-                                       // Convert to text
-                                       // NB: Must not be trimmed ("Example#_foo" is not the same as "Example#foo")
-                                       .replace( /_/g, ' ' );
-
-                               title = title
-                                       // Strip hash
-                                       .slice( 0, i )
-                                       // Trim underscores, again (strips "_" from "bar" in "Foo_bar_#quux")
-                                       .replace( rUnderscoreTrim, '' );
-                       }
-
-                       // Reject illegal characters
-                       if ( title.match( rInvalid ) ) {
-                               return false;
-                       }
-
-                       // Disallow titles that browsers or servers might resolve as directory navigation
-                       if (
-                               title.indexOf( '.' ) !== -1 && (
-                                       title === '.' || title === '..' ||
-                                       title.indexOf( './' ) === 0 ||
-                                       title.indexOf( '../' ) === 0 ||
-                                       title.indexOf( '/./' ) !== -1 ||
-                                       title.indexOf( '/../' ) !== -1 ||
-                                       title.slice( -2 ) === '/.' ||
-                                       title.slice( -3 ) === '/..'
-                               )
-                       ) {
-                               return false;
-                       }
-
-                       // Disallow magic tilde sequence
-                       if ( title.indexOf( '~~~' ) !== -1 ) {
-                               return false;
-                       }
-
-                       // Disallow titles exceeding the TITLE_MAX_BYTES byte size limit (size of underlying database field)
-                       // Except for special pages, e.g. [[Special:Block/Long name]]
-                       // Note: The PHP implementation also asserts that even in NS_SPECIAL, the title should
-                       // be less than 512 bytes.
-                       if ( namespace !== NS_SPECIAL && mwString.byteLength( title ) > TITLE_MAX_BYTES ) {
-                               return false;
-                       }
+/**
+ * Parse titles into an object structure. Note that when using the constructor
+ * directly, passing invalid titles will result in an exception. Use #newFromText to use the
+ * logic directly and get null for invalid titles which is easier to work with.
+ *
+ * Note that in the constructor and #newFromText method, `namespace` is the **default** namespace
+ * only, and can be overridden by a namespace prefix in `title`. If you do not want this behavior,
+ * use #makeTitle. Compare:
+ *
+ *     new mw.Title( 'Foo', NS_TEMPLATE ).getPrefixedText();                  // => 'Template:Foo'
+ *     mw.Title.newFromText( 'Foo', NS_TEMPLATE ).getPrefixedText();          // => 'Template:Foo'
+ *     mw.Title.makeTitle( NS_TEMPLATE, 'Foo' ).getPrefixedText();            // => 'Template:Foo'
+ *
+ *     new mw.Title( 'Category:Foo', NS_TEMPLATE ).getPrefixedText();         // => 'Category:Foo'
+ *     mw.Title.newFromText( 'Category:Foo', NS_TEMPLATE ).getPrefixedText(); // => 'Category:Foo'
+ *     mw.Title.makeTitle( NS_TEMPLATE, 'Category:Foo' ).getPrefixedText();   // => 'Template:Category:Foo'
+ *
+ *     new mw.Title( 'Template:Foo', NS_TEMPLATE ).getPrefixedText();         // => 'Template:Foo'
+ *     mw.Title.newFromText( 'Template:Foo', NS_TEMPLATE ).getPrefixedText(); // => 'Template:Foo'
+ *     mw.Title.makeTitle( NS_TEMPLATE, 'Template:Foo' ).getPrefixedText();   // => 'Template:Template:Foo'
+ *
+ * @class mw.Title
+ */
 
-                       // Can't make a link to a namespace alone.
-                       if ( title === '' && namespace !== NS_MAIN ) {
-                               return false;
-                       }
+/* Private members */
 
-                       // Any remaining initial :s are illegal.
-                       if ( title[ 0 ] === ':' ) {
-                               return false;
-                       }
+var
+       mwString = require( 'mediawiki.String' ),
 
-                       // For backwards-compatibility with old mw.Title, we separate the extension from the
-                       // rest of the title.
-                       i = title.lastIndexOf( '.' );
-                       if ( i === -1 || title.length <= i + 1 ) {
-                               // Extensions are the non-empty segment after the last dot
-                               ext = null;
-                       } else {
-                               ext = title.slice( i + 1 );
-                               title = title.slice( 0, i );
-                       }
+       toUpperMapping = require( './phpCharToUpper.json' ),
 
-                       return {
-                               namespace: namespace,
-                               title: title,
-                               ext: ext,
-                               fragment: fragment
-                       };
-               },
+       namespaceIds = mw.config.get( 'wgNamespaceIds' ),
 
-               /**
-                * Convert db-key to readable text.
-                *
-                * @private
-                * @static
-                * @method text
-                * @param {string} s
-                * @return {string}
-                */
-               text = function ( s ) {
-                       return s.replace( /_/g, ' ' );
-               },
+       /**
+        * @private
+        * @static
+        * @property NS_MAIN
+        */
+       NS_MAIN = namespaceIds[ '' ],
 
-               /**
-                * Sanitizes a string based on a rule set and a filter
-                *
-                * @private
-                * @static
-                * @method sanitize
-                * @param {string} s
-                * @param {Array} filter
-                * @return {string}
-                */
-               sanitize = function ( s, filter ) {
-                       var i, ruleLength, rule, m, filterLength,
-                               rules = sanitationRules;
-
-                       for ( i = 0, ruleLength = rules.length; i < ruleLength; ++i ) {
-                               rule = rules[ i ];
-                               for ( m = 0, filterLength = filter.length; m < filterLength; ++m ) {
-                                       if ( rule[ filter[ m ] ] ) {
-                                               s = s.replace( rule.pattern, rule.replace );
-                                       }
-                               }
-                       }
-                       return s;
-               },
+       /**
+        * @private
+        * @static
+        * @property NS_TALK
+        */
+       NS_TALK = namespaceIds.talk,
 
-               /**
-                * Cuts a string to a specific byte length, assuming UTF-8
-                * or less, if the last character is a multi-byte one
-                *
-                * @private
-                * @static
-                * @method trimToByteLength
-                * @param {string} s
-                * @param {number} length
-                * @return {string}
-                */
-               trimToByteLength = function ( s, length ) {
-                       return mwString.trimByteLength( '', s, length ).newVal;
-               },
+       /**
+        * @private
+        * @static
+        * @property NS_SPECIAL
+        */
+       NS_SPECIAL = namespaceIds.special,
 
-               /**
-                * Cuts a file name to a specific byte length
-                *
-                * @private
-                * @static
-                * @method trimFileNameToByteLength
-                * @param {string} name without extension
-                * @param {string} extension file extension
-                * @return {string} The full name, including extension
-                */
-               trimFileNameToByteLength = function ( name, extension ) {
-                       // There is a special byte limit for file names and ... remember the dot
-                       return trimToByteLength( name, FILENAME_MAX_BYTES - extension.length - 1 ) + '.' + extension;
-               };
+       /**
+        * @private
+        * @static
+        * @property NS_MEDIA
+        */
+       NS_MEDIA = namespaceIds.media,
 
        /**
-        * @method constructor
-        * @param {string} title Title of the page. If no second argument given,
-        *  this will be searched for a namespace
-        * @param {number} [namespace=NS_MAIN] If given, will used as default namespace for the given title
-        * @throws {Error} When the title is invalid
+        * @private
+        * @static
+        * @property NS_FILE
         */
-       function Title( title, namespace ) {
-               var parsed = parse( title, namespace );
-               if ( !parsed ) {
-                       throw new Error( 'Unable to parse title' );
-               }
+       NS_FILE = namespaceIds.file,
 
-               this.namespace = parsed.namespace;
-               this.title = parsed.title;
-               this.ext = parsed.ext;
-               this.fragment = parsed.fragment;
-       }
+       /**
+        * @private
+        * @static
+        * @property FILENAME_MAX_BYTES
+        */
+       FILENAME_MAX_BYTES = 240,
 
-       /* Static members */
+       /**
+        * @private
+        * @static
+        * @property TITLE_MAX_BYTES
+        */
+       TITLE_MAX_BYTES = 255,
 
        /**
-        * Constructor for Title objects with a null return instead of an exception for invalid titles.
+        * Get the namespace id from a namespace name (either from the localized, canonical or alias
+        * name).
         *
-        * Note that `namespace` is the **default** namespace only, and can be overridden by a namespace
-        * prefix in `title`. If you do not want this behavior, use #makeTitle. See #constructor for
-        * details.
+        * Example: On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or
+        * even 'Bild'.
         *
+        * @private
         * @static
-        * @param {string} title
-        * @param {number} [namespace=NS_MAIN] Default namespace
-        * @return {mw.Title|null} A valid Title object or null if the title is invalid
+        * @method getNsIdByName
+        * @param {string} ns Namespace name (case insensitive, leading/trailing space ignored)
+        * @return {number|boolean} Namespace id or boolean false
         */
-       Title.newFromText = function ( title, namespace ) {
-               var t, parsed = parse( title, namespace );
-               if ( !parsed ) {
-                       return null;
+       getNsIdByName = function ( ns ) {
+               var id;
+
+               // Don't cast non-strings to strings, because null or undefined should not result in
+               // returning the id of a potential namespace called "Null:" (e.g. on null.example.org/wiki)
+               // Also, toLowerCase throws exception on null/undefined, because it is a String method.
+               if ( typeof ns !== 'string' ) {
+                       return false;
                }
+               // TODO: Should just use local var namespaceIds here but it
+               // breaks test which modify the config
+               id = mw.config.get( 'wgNamespaceIds' )[ ns.toLowerCase() ];
+               if ( id === undefined ) {
+                       return false;
+               }
+               return id;
+       },
 
-               t = Object.create( Title.prototype );
-               t.namespace = parsed.namespace;
-               t.title = parsed.title;
-               t.ext = parsed.ext;
-               t.fragment = parsed.fragment;
-
-               return t;
-       };
+       /**
+        * @private
+        * @method getNamespacePrefix_
+        * @param {number} namespace
+        * @return {string}
+        */
+       getNamespacePrefix = function ( namespace ) {
+               return namespace === NS_MAIN ?
+                       '' :
+                       ( mw.config.get( 'wgFormattedNamespaces' )[ namespace ].replace( / /g, '_' ) + ':' );
+       },
+
+       rUnderscoreTrim = /^_+|_+$/g,
+
+       rSplit = /^(.+?)_*:_*(.*)$/,
+
+       // See MediaWikiTitleCodec.php#getTitleInvalidRegex
+       rInvalid = new RegExp(
+               '[^' + mw.config.get( 'wgLegalTitleChars' ) + ']' +
+               // URL percent encoding sequences interfere with the ability
+               // to round-trip titles -- you can't link to them consistently.
+               '|%[0-9A-Fa-f]{2}' +
+               // XML/HTML character references produce similar issues.
+               '|&[A-Za-z0-9\u0080-\uFFFF]+;' +
+               '|&#[0-9]+;' +
+               '|&#x[0-9A-Fa-f]+;'
+       ),
+
+       // From MediaWikiTitleCodec::splitTitleString() in PHP
+       // Note that this is not equivalent to /\s/, e.g. underscore is included, tab is not included.
+       rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g,
+
+       // From MediaWikiTitleCodec::splitTitleString() in PHP
+       rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]/g,
 
        /**
-        * Constructor for Title objects with predefined namespace.
-        *
-        * Unlike #newFromText or #constructor, this function doesn't allow the given `namespace` to be
-        * overridden by a namespace prefix in `title`. See #constructor for details about this behavior.
-        *
-        * The single exception to this is when `namespace` is 0, indicating the main namespace. The
-        * function behaves like #newFromText in that case.
-        *
+        * Slightly modified from Flinfo. Credit goes to Lupo and Flominator.
+        * @private
         * @static
-        * @param {number} namespace Namespace to use for the title
-        * @param {string} title
-        * @return {mw.Title|null} A valid Title object or null if the title is invalid
+        * @property sanitationRules
         */
-       Title.makeTitle = function ( namespace, title ) {
-               return mw.Title.newFromText( getNamespacePrefix( namespace ) + title );
-       };
+       sanitationRules = [
+               // "signature"
+               {
+                       pattern: /~{3}/g,
+                       replace: '',
+                       generalRule: true
+               },
+               // control characters
+               {
+                       // eslint-disable-next-line no-control-regex
+                       pattern: /[\x00-\x1f\x7f]/g,
+                       replace: '',
+                       generalRule: true
+               },
+               // URL encoding (possibly)
+               {
+                       pattern: /%([0-9A-Fa-f]{2})/g,
+                       replace: '% $1',
+                       generalRule: true
+               },
+               // HTML-character-entities
+               {
+                       pattern: /&(([A-Za-z0-9\x80-\xff]+|#[0-9]+|#x[0-9A-Fa-f]+);)/g,
+                       replace: '& $1',
+                       generalRule: true
+               },
+               // slash, colon (not supported by file systems like NTFS/Windows, Mac OS 9 [:], ext4 [/])
+               {
+                       pattern: new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']', 'g' ),
+                       replace: '-',
+                       fileRule: true
+               },
+               // brackets, greater than
+               {
+                       pattern: /[}\]>]/g,
+                       replace: ')',
+                       generalRule: true
+               },
+               // brackets, lower than
+               {
+                       pattern: /[{[<]/g,
+                       replace: '(',
+                       generalRule: true
+               },
+               // everything that wasn't covered yet
+               {
+                       pattern: new RegExp( rInvalid.source, 'g' ),
+                       replace: '-',
+                       generalRule: true
+               },
+               // directory structures
+               {
+                       pattern: /^(\.|\.\.|\.\/.*|\.\.\/.*|.*\/\.\/.*|.*\/\.\.\/.*|.*\/\.|.*\/\.\.)$/g,
+                       replace: '',
+                       generalRule: true
+               }
+       ],
 
        /**
-        * Constructor for Title objects from user input altering that input to
-        * produce a title that MediaWiki will accept as legal
+        * Internal helper for #constructor and #newFromText.
+        *
+        * Based on Title.php#secureAndSplit
         *
+        * @private
         * @static
+        * @method parse
         * @param {string} title
-        * @param {number|Object} [defaultNamespaceOrOptions=NS_MAIN]
-        *  If given, will used as default namespace for the given title.
-        *  This method can also be called with two arguments, in which case
-        *  this becomes options (see below).
-        * @param {Object} [options] additional options
-        * @param {boolean} [options.forUploading=true]
-        *  Makes sure that a file is uploadable under the title returned.
-        *  There are pages in the file namespace under which file upload is impossible.
-        *  Automatically assumed if the title is created in the Media namespace.
-        * @return {mw.Title|null} A valid Title object or null if the input cannot be turned into a valid title
+        * @param {number} [defaultNamespace=NS_MAIN]
+        * @return {Object|boolean}
         */
-       Title.newFromUserInput = function ( title, defaultNamespaceOrOptions, options ) {
-               var namespace, m, id, ext, parts,
-                       defaultNamespace;
-
-               // defaultNamespace is optional; check whether options moves up
-               if ( arguments.length < 3 && typeof defaultNamespace === 'object' ) {
-                       options = defaultNamespaceOrOptions;
-               } else {
-                       defaultNamespace = defaultNamespaceOrOptions;
-               }
-
-               // merge options into defaults
-               options = $.extend( {
-                       forUploading: true
-               }, options );
+       parse = function ( title, defaultNamespace ) {
+               var namespace, m, id, i, fragment, ext;
 
                namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
 
-               // Normalise additional whitespace
-               title = title.replace( /\s/g, ' ' ).trim();
+               title = title
+                       // Strip Unicode bidi override characters
+                       .replace( rUnicodeBidi, '' )
+                       // Normalise whitespace to underscores and remove duplicates
+                       .replace( rWhitespace, '_' )
+                       // Trim underscores
+                       .replace( rUnderscoreTrim, '' );
 
                // Process initial colon
                if ( title !== '' && title[ 0 ] === ':' ) {
                        namespace = NS_MAIN;
                        title = title
                                // Strip colon
-                               .substr( 1 )
+                               .slice( 1 )
                                // Trim underscores
                                .replace( rUnderscoreTrim, '' );
                }
 
+               if ( title === '' ) {
+                       return false;
+               }
+
                // Process namespace prefix (if any)
                m = title.match( rSplit );
                if ( m ) {
                                // Ordinary namespace
                                namespace = id;
                                title = m[ 2 ];
+
+                               // For Talk:X pages, make sure X has no "namespace" prefix
+                               if ( namespace === NS_TALK && ( m = title.match( rSplit ) ) ) {
+                                       // Disallow titles like Talk:File:x (subject should roundtrip: talk:file:x -> file:x -> file_talk:x)
+                                       if ( getNsIdByName( m[ 1 ] ) !== false ) {
+                                               return false;
+                                       }
+                               }
                        }
                }
 
-               if (
-                       namespace === NS_MEDIA ||
-                       ( options.forUploading && ( namespace === NS_FILE ) )
-               ) {
-
-                       title = sanitize( title, [ 'generalRule', 'fileRule' ] );
+               // Process fragment
+               i = title.indexOf( '#' );
+               if ( i === -1 ) {
+                       fragment = null;
+               } else {
+                       fragment = title
+                               // Get segment starting after the hash
+                               .slice( i + 1 )
+                               // Convert to text
+                               // NB: Must not be trimmed ("Example#_foo" is not the same as "Example#foo")
+                               .replace( /_/g, ' ' );
 
-                       // Operate on the file extension
-                       // Although it is possible having spaces between the name and the ".ext" this isn't nice for
-                       // operating systems hiding file extensions -> strip them later on
-                       parts = title.split( '.' );
+                       title = title
+                               // Strip hash
+                               .slice( 0, i )
+                               // Trim underscores, again (strips "_" from "bar" in "Foo_bar_#quux")
+                               .replace( rUnderscoreTrim, '' );
+               }
 
-                       if ( parts.length > 1 ) {
+               // Reject illegal characters
+               if ( title.match( rInvalid ) ) {
+                       return false;
+               }
 
-                               // Get the last part, which is supposed to be the file extension
-                               ext = parts.pop();
+               // Disallow titles that browsers or servers might resolve as directory navigation
+               if (
+                       title.indexOf( '.' ) !== -1 && (
+                               title === '.' || title === '..' ||
+                               title.indexOf( './' ) === 0 ||
+                               title.indexOf( '../' ) === 0 ||
+                               title.indexOf( '/./' ) !== -1 ||
+                               title.indexOf( '/../' ) !== -1 ||
+                               title.slice( -2 ) === '/.' ||
+                               title.slice( -3 ) === '/..'
+                       )
+               ) {
+                       return false;
+               }
 
-                               // Remove whitespace of the name part (that W/O extension)
-                               title = parts.join( '.' ).trim();
+               // Disallow magic tilde sequence
+               if ( title.indexOf( '~~~' ) !== -1 ) {
+                       return false;
+               }
 
-                               // Cut, if too long and append file extension
-                               title = trimFileNameToByteLength( title, ext );
+               // Disallow titles exceeding the TITLE_MAX_BYTES byte size limit (size of underlying database field)
+               // Except for special pages, e.g. [[Special:Block/Long name]]
+               // Note: The PHP implementation also asserts that even in NS_SPECIAL, the title should
+               // be less than 512 bytes.
+               if ( namespace !== NS_SPECIAL && mwString.byteLength( title ) > TITLE_MAX_BYTES ) {
+                       return false;
+               }
 
-                       } else {
+               // Can't make a link to a namespace alone.
+               if ( title === '' && namespace !== NS_MAIN ) {
+                       return false;
+               }
 
-                               // Missing file extension
-                               title = parts.join( '.' ).trim();
+               // Any remaining initial :s are illegal.
+               if ( title[ 0 ] === ':' ) {
+                       return false;
+               }
 
-                               // Name has no file extension and a fallback wasn't provided either
-                               return null;
-                       }
+               // For backwards-compatibility with old mw.Title, we separate the extension from the
+               // rest of the title.
+               i = title.lastIndexOf( '.' );
+               if ( i === -1 || title.length <= i + 1 ) {
+                       // Extensions are the non-empty segment after the last dot
+                       ext = null;
                } else {
-
-                       title = sanitize( title, [ 'generalRule' ] );
-
-                       // Cut titles exceeding the TITLE_MAX_BYTES byte size limit
-                       // (size of underlying database field)
-                       if ( namespace !== NS_SPECIAL ) {
-                               title = trimToByteLength( title, TITLE_MAX_BYTES );
-                       }
+                       ext = title.slice( i + 1 );
+                       title = title.slice( 0, i );
                }
 
-               // Any remaining initial :s are illegal.
-               title = title.replace( /^:+/, '' );
-
-               return Title.newFromText( title, namespace );
-       };
+               return {
+                       namespace: namespace,
+                       title: title,
+                       ext: ext,
+                       fragment: fragment
+               };
+       },
 
        /**
-        * Sanitizes a file name as supplied by the user, originating in the user's file system
-        * so it is most likely a valid MediaWiki title and file name after processing.
-        * Returns null on fatal errors.
+        * Convert db-key to readable text.
         *
+        * @private
         * @static
-        * @param {string} uncleanName The unclean file name including file extension but
-        *   without namespace
-        * @return {mw.Title|null} A valid Title object or null if the title is invalid
+        * @method text
+        * @param {string} s
+        * @return {string}
         */
-       Title.newFromFileName = function ( uncleanName ) {
+       text = function ( s ) {
+               return s.replace( /_/g, ' ' );
+       },
 
-               return Title.newFromUserInput( 'File:' + uncleanName, {
-                       forUploading: true
-               } );
-       };
+       /**
+        * Sanitizes a string based on a rule set and a filter
+        *
+        * @private
+        * @static
+        * @method sanitize
+        * @param {string} s
+        * @param {Array} filter
+        * @return {string}
+        */
+       sanitize = function ( s, filter ) {
+               var i, ruleLength, rule, m, filterLength,
+                       rules = sanitationRules;
+
+               for ( i = 0, ruleLength = rules.length; i < ruleLength; ++i ) {
+                       rule = rules[ i ];
+                       for ( m = 0, filterLength = filter.length; m < filterLength; ++m ) {
+                               if ( rule[ filter[ m ] ] ) {
+                                       s = s.replace( rule.pattern, rule.replace );
+                               }
+                       }
+               }
+               return s;
+       },
 
        /**
-        * Get the file title from an image element
+        * Cuts a string to a specific byte length, assuming UTF-8
+        * or less, if the last character is a multi-byte one
         *
-        *     var title = mw.Title.newFromImg( $( 'img:first' ) );
+        * @private
+        * @static
+        * @method trimToByteLength
+        * @param {string} s
+        * @param {number} length
+        * @return {string}
+        */
+       trimToByteLength = function ( s, length ) {
+               return mwString.trimByteLength( '', s, length ).newVal;
+       },
+
+       /**
+        * Cuts a file name to a specific byte length
         *
+        * @private
         * @static
-        * @param {HTMLElement|jQuery} img The image to use as a base
-        * @return {mw.Title|null} The file title or null if unsuccessful
+        * @method trimFileNameToByteLength
+        * @param {string} name without extension
+        * @param {string} extension file extension
+        * @return {string} The full name, including extension
         */
-       Title.newFromImg = function ( img ) {
-               var matches, i, regex, src, decodedSrc,
+       trimFileNameToByteLength = function ( name, extension ) {
+               // There is a special byte limit for file names and ... remember the dot
+               return trimToByteLength( name, FILENAME_MAX_BYTES - extension.length - 1 ) + '.' + extension;
+       };
+
+/**
+ * @method constructor
+ * @param {string} title Title of the page. If no second argument given,
+ *  this will be searched for a namespace
+ * @param {number} [namespace=NS_MAIN] If given, will used as default namespace for the given title
+ * @throws {Error} When the title is invalid
+ */
+function Title( title, namespace ) {
+       var parsed = parse( title, namespace );
+       if ( !parsed ) {
+               throw new Error( 'Unable to parse title' );
+       }
+
+       this.namespace = parsed.namespace;
+       this.title = parsed.title;
+       this.ext = parsed.ext;
+       this.fragment = parsed.fragment;
+}
+
+/* Static members */
+
+/**
+ * Constructor for Title objects with a null return instead of an exception for invalid titles.
+ *
+ * Note that `namespace` is the **default** namespace only, and can be overridden by a namespace
+ * prefix in `title`. If you do not want this behavior, use #makeTitle. See #constructor for
+ * details.
+ *
+ * @static
+ * @param {string} title
+ * @param {number} [namespace=NS_MAIN] Default namespace
+ * @return {mw.Title|null} A valid Title object or null if the title is invalid
+ */
+Title.newFromText = function ( title, namespace ) {
+       var t, parsed = parse( title, namespace );
+       if ( !parsed ) {
+               return null;
+       }
+
+       t = Object.create( Title.prototype );
+       t.namespace = parsed.namespace;
+       t.title = parsed.title;
+       t.ext = parsed.ext;
+       t.fragment = parsed.fragment;
+
+       return t;
+};
+
+/**
+ * Constructor for Title objects with predefined namespace.
+ *
+ * Unlike #newFromText or #constructor, this function doesn't allow the given `namespace` to be
+ * overridden by a namespace prefix in `title`. See #constructor for details about this behavior.
+ *
+ * The single exception to this is when `namespace` is 0, indicating the main namespace. The
+ * function behaves like #newFromText in that case.
+ *
+ * @static
+ * @param {number} namespace Namespace to use for the title
+ * @param {string} title
+ * @return {mw.Title|null} A valid Title object or null if the title is invalid
+ */
+Title.makeTitle = function ( namespace, title ) {
+       return mw.Title.newFromText( getNamespacePrefix( namespace ) + title );
+};
+
+/**
+ * Constructor for Title objects from user input altering that input to
+ * produce a title that MediaWiki will accept as legal
+ *
+ * @static
+ * @param {string} title
+ * @param {number|Object} [defaultNamespaceOrOptions=NS_MAIN]
+ *  If given, will used as default namespace for the given title.
+ *  This method can also be called with two arguments, in which case
+ *  this becomes options (see below).
+ * @param {Object} [options] additional options
+ * @param {boolean} [options.forUploading=true]
+ *  Makes sure that a file is uploadable under the title returned.
+ *  There are pages in the file namespace under which file upload is impossible.
+ *  Automatically assumed if the title is created in the Media namespace.
+ * @return {mw.Title|null} A valid Title object or null if the input cannot be turned into a valid title
+ */
+Title.newFromUserInput = function ( title, defaultNamespaceOrOptions, options ) {
+       var namespace, m, id, ext, parts,
+               defaultNamespace;
+
+       // defaultNamespace is optional; check whether options moves up
+       if ( arguments.length < 3 && typeof defaultNamespace === 'object' ) {
+               options = defaultNamespaceOrOptions;
+       } else {
+               defaultNamespace = defaultNamespaceOrOptions;
+       }
+
+       // merge options into defaults
+       options = $.extend( {
+               forUploading: true
+       }, options );
+
+       namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
+
+       // Normalise additional whitespace
+       title = title.replace( /\s/g, ' ' ).trim();
+
+       // Process initial colon
+       if ( title !== '' && title[ 0 ] === ':' ) {
+               // Initial colon means main namespace instead of specified default
+               namespace = NS_MAIN;
+               title = title
+                       // Strip colon
+                       .substr( 1 )
+                       // Trim underscores
+                       .replace( rUnderscoreTrim, '' );
+       }
+
+       // Process namespace prefix (if any)
+       m = title.match( rSplit );
+       if ( m ) {
+               id = getNsIdByName( m[ 1 ] );
+               if ( id !== false ) {
+                       // Ordinary namespace
+                       namespace = id;
+                       title = m[ 2 ];
+               }
+       }
+
+       if (
+               namespace === NS_MEDIA ||
+               ( options.forUploading && ( namespace === NS_FILE ) )
+       ) {
 
-                       // thumb.php-generated thumbnails
-                       thumbPhpRegex = /thumb\.php/,
-                       regexes = [
-                               // Thumbnails
-                               /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)\/[^\s/]+-[^\s/]*$/,
+               title = sanitize( title, [ 'generalRule', 'fileRule' ] );
 
-                               // Full size images
-                               /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)$/,
+               // Operate on the file extension
+               // Although it is possible having spaces between the name and the ".ext" this isn't nice for
+               // operating systems hiding file extensions -> strip them later on
+               parts = title.split( '.' );
 
-                               // Thumbnails in non-hashed upload directories
-                               /\/([^\s/]+)\/[^\s/]+-(?:\1|thumbnail)[^\s/]*$/,
+               if ( parts.length > 1 ) {
 
-                               // Full-size images in non-hashed upload directories
-                               /\/([^\s/]+)$/
-                       ],
+                       // Get the last part, which is supposed to be the file extension
+                       ext = parts.pop();
 
-                       recount = regexes.length;
+                       // Remove whitespace of the name part (that W/O extension)
+                       title = parts.join( '.' ).trim();
 
-               src = img.jquery ? img[ 0 ].src : img.src;
+                       // Cut, if too long and append file extension
+                       title = trimFileNameToByteLength( title, ext );
 
-               matches = src.match( thumbPhpRegex );
+               } else {
 
-               if ( matches ) {
-                       return mw.Title.newFromText( 'File:' + mw.util.getParamValue( 'f', src ) );
+                       // Missing file extension
+                       title = parts.join( '.' ).trim();
+
+                       // Name has no file extension and a fallback wasn't provided either
+                       return null;
                }
+       } else {
 
-               decodedSrc = decodeURIComponent( src );
+               title = sanitize( title, [ 'generalRule' ] );
 
-               for ( i = 0; i < recount; i++ ) {
-                       regex = regexes[ i ];
-                       matches = decodedSrc.match( regex );
+               // Cut titles exceeding the TITLE_MAX_BYTES byte size limit
+               // (size of underlying database field)
+               if ( namespace !== NS_SPECIAL ) {
+                       title = trimToByteLength( title, TITLE_MAX_BYTES );
+               }
+       }
 
-                       if ( matches && matches[ 1 ] ) {
-                               return mw.Title.newFromText( 'File:' + matches[ 1 ] );
-                       }
+       // Any remaining initial :s are illegal.
+       title = title.replace( /^:+/, '' );
+
+       return Title.newFromText( title, namespace );
+};
+
+/**
+ * Sanitizes a file name as supplied by the user, originating in the user's file system
+ * so it is most likely a valid MediaWiki title and file name after processing.
+ * Returns null on fatal errors.
+ *
+ * @static
+ * @param {string} uncleanName The unclean file name including file extension but
+ *   without namespace
+ * @return {mw.Title|null} A valid Title object or null if the title is invalid
+ */
+Title.newFromFileName = function ( uncleanName ) {
+
+       return Title.newFromUserInput( 'File:' + uncleanName, {
+               forUploading: true
+       } );
+};
+
+/**
+ * Get the file title from an image element
+ *
+ *     var title = mw.Title.newFromImg( $( 'img:first' ) );
+ *
+ * @static
+ * @param {HTMLElement|jQuery} img The image to use as a base
+ * @return {mw.Title|null} The file title or null if unsuccessful
+ */
+Title.newFromImg = function ( img ) {
+       var matches, i, regex, src, decodedSrc,
+
+               // thumb.php-generated thumbnails
+               thumbPhpRegex = /thumb\.php/,
+               regexes = [
+                       // Thumbnails
+                       /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)\/[^\s/]+-[^\s/]*$/,
+
+                       // Full size images
+                       /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)$/,
+
+                       // Thumbnails in non-hashed upload directories
+                       /\/([^\s/]+)\/[^\s/]+-(?:\1|thumbnail)[^\s/]*$/,
+
+                       // Full-size images in non-hashed upload directories
+                       /\/([^\s/]+)$/
+               ],
+
+               recount = regexes.length;
+
+       src = img.jquery ? img[ 0 ].src : img.src;
+
+       matches = src.match( thumbPhpRegex );
+
+       if ( matches ) {
+               return mw.Title.newFromText( 'File:' + mw.util.getParamValue( 'f', src ) );
+       }
+
+       decodedSrc = decodeURIComponent( src );
+
+       for ( i = 0; i < recount; i++ ) {
+               regex = regexes[ i ];
+               matches = decodedSrc.match( regex );
+
+               if ( matches && matches[ 1 ] ) {
+                       return mw.Title.newFromText( 'File:' + matches[ 1 ] );
                }
+       }
+
+       return null;
+};
+
+/**
+ * Check if a given namespace is a talk namespace
+ *
+ * See MWNamespace::isTalk in PHP
+ *
+ * @param {number} namespaceId Namespace ID
+ * @return {boolean} Namespace is a talk namespace
+ */
+Title.isTalkNamespace = function ( namespaceId ) {
+       return !!( namespaceId > NS_MAIN && namespaceId % 2 );
+};
+
+/**
+ * Check if signature buttons should be shown in a given namespace
+ *
+ * See MWNamespace::wantSignatures in PHP
+ *
+ * @param {number} namespaceId Namespace ID
+ * @return {boolean} Namespace is a signature namespace
+ */
+Title.wantSignaturesNamespace = function ( namespaceId ) {
+       return Title.isTalkNamespace( namespaceId ) ||
+               mw.config.get( 'wgExtraSignatureNamespaces' ).indexOf( namespaceId ) !== -1;
+};
+
+/**
+ * Whether this title exists on the wiki.
+ *
+ * @static
+ * @param {string|mw.Title} title prefixed db-key name (string) or instance of Title
+ * @return {boolean|null} Boolean if the information is available, otherwise null
+ * @throws {Error} If title is not a string or mw.Title
+ */
+Title.exists = function ( title ) {
+       var match,
+               obj = Title.exist.pages;
+
+       if ( typeof title === 'string' ) {
+               match = obj[ title ];
+       } else if ( title instanceof Title ) {
+               match = obj[ title.toString() ];
+       } else {
+               throw new Error( 'mw.Title.exists: title must be a string or an instance of Title' );
+       }
 
+       if ( typeof match !== 'boolean' ) {
                return null;
-       };
+       }
+
+       return match;
+};
+
+/**
+ * Store page existence
+ *
+ * @static
+ * @property {Object} exist
+ * @property {Object} exist.pages Keyed by title. Boolean true value indicates page does exist.
+ *
+ * @property {Function} exist.set The setter function.
+ *
+ *  Example to declare existing titles:
+ *
+ *     Title.exist.set( ['User:John_Doe', ...] );
+ *
+ *  Example to declare titles nonexistent:
+ *
+ *     Title.exist.set( ['File:Foo_bar.jpg', ...], false );
+ *
+ * @property {string|Array} exist.set.titles Title(s) in strict prefixedDb title form
+ * @property {boolean} [exist.set.state=true] State of the given titles
+ * @return {boolean}
+ */
+Title.exist = {
+       pages: {},
+
+       set: function ( titles, state ) {
+               var i, len,
+                       pages = this.pages;
+
+               titles = Array.isArray( titles ) ? titles : [ titles ];
+               state = state === undefined ? true : !!state;
+
+               for ( i = 0, len = titles.length; i < len; i++ ) {
+                       pages[ titles[ i ] ] = state;
+               }
+               return true;
+       }
+};
+
+/**
+ * Normalize a file extension to the common form, making it lowercase and checking some synonyms,
+ * and ensure it's clean. Extensions with non-alphanumeric characters will be discarded.
+ * Keep in sync with File::normalizeExtension() in PHP.
+ *
+ * @param {string} extension File extension (without the leading dot)
+ * @return {string} File extension in canonical form
+ */
+Title.normalizeExtension = function ( extension ) {
+       var
+               lower = extension.toLowerCase(),
+               squish = {
+                       htm: 'html',
+                       jpeg: 'jpg',
+                       mpeg: 'mpg',
+                       tiff: 'tif',
+                       ogv: 'ogg'
+               };
+       if ( Object.prototype.hasOwnProperty.call( squish, lower ) ) {
+               return squish[ lower ];
+       } else if ( /^[0-9a-z]+$/.test( lower ) ) {
+               return lower;
+       } else {
+               return '';
+       }
+};
+
+/**
+ * PHP's strtoupper differs from String.toUpperCase in a number of cases (T147646).
+ *
+ * @param {string} chr Unicode character
+ * @return {string} Unicode character, in upper case, according to the same rules as in PHP
+ */
+Title.phpCharToUpper = function ( chr ) {
+       var mapped = toUpperMapping[ chr ];
+       return mapped || chr.toUpperCase();
+};
+
+/* Public members */
+
+Title.prototype = {
+       constructor: Title,
 
        /**
-        * Check if a given namespace is a talk namespace
+        * Get the namespace number
         *
-        * See MWNamespace::isTalk in PHP
+        * Example: 6 for "File:Example_image.svg".
         *
-        * @param {number} namespaceId Namespace ID
-        * @return {boolean} Namespace is a talk namespace
+        * @return {number}
         */
-       Title.isTalkNamespace = function ( namespaceId ) {
-               return !!( namespaceId > NS_MAIN && namespaceId % 2 );
-       };
+       getNamespaceId: function () {
+               return this.namespace;
+       },
 
        /**
-        * Check if signature buttons should be shown in a given namespace
+        * Get the namespace prefix (in the content language)
         *
-        * See MWNamespace::wantSignatures in PHP
+        * Example: "File:" for "File:Example_image.svg".
+        * In #NS_MAIN this is '', otherwise namespace name plus ':'
         *
-        * @param {number} namespaceId Namespace ID
-        * @return {boolean} Namespace is a signature namespace
+        * @return {string}
         */
-       Title.wantSignaturesNamespace = function ( namespaceId ) {
-               return Title.isTalkNamespace( namespaceId ) ||
-                       mw.config.get( 'wgExtraSignatureNamespaces' ).indexOf( namespaceId ) !== -1;
-       };
+       getNamespacePrefix: function () {
+               return getNamespacePrefix( this.namespace );
+       },
 
        /**
-        * Whether this title exists on the wiki.
+        * Get the page name without extension or namespace prefix
         *
-        * @static
-        * @param {string|mw.Title} title prefixed db-key name (string) or instance of Title
-        * @return {boolean|null} Boolean if the information is available, otherwise null
-        * @throws {Error} If title is not a string or mw.Title
+        * Example: "Example_image" for "File:Example_image.svg".
+        *
+        * For the page title (full page name without namespace prefix), see #getMain.
+        *
+        * @return {string}
         */
-       Title.exists = function ( title ) {
-               var match,
-                       obj = Title.exist.pages;
-
-               if ( typeof title === 'string' ) {
-                       match = obj[ title ];
-               } else if ( title instanceof Title ) {
-                       match = obj[ title.toString() ];
-               } else {
-                       throw new Error( 'mw.Title.exists: title must be a string or an instance of Title' );
-               }
-
-               if ( typeof match !== 'boolean' ) {
-                       return null;
+       getName: function () {
+               if (
+                       mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( this.namespace ) !== -1 ||
+                       !this.title.length
+               ) {
+                       return this.title;
                }
-
-               return match;
-       };
+               return mw.Title.phpCharToUpper( this.title[ 0 ] ) + this.title.slice( 1 );
+       },
 
        /**
-        * Store page existence
+        * Get the page name (transformed by #text)
         *
-        * @static
-        * @property {Object} exist
-        * @property {Object} exist.pages Keyed by title. Boolean true value indicates page does exist.
+        * Example: "Example image" for "File:Example_image.svg".
         *
-        * @property {Function} exist.set The setter function.
+        * For the page title (full page name without namespace prefix), see #getMainText.
         *
-        *  Example to declare existing titles:
+        * @return {string}
+        */
+       getNameText: function () {
+               return text( this.getName() );
+       },
+
+       /**
+        * Get the extension of the page name (if any)
         *
-        *     Title.exist.set( ['User:John_Doe', ...] );
+        * @return {string|null} Name extension or null if there is none
+        */
+       getExtension: function () {
+               return this.ext;
+       },
+
+       /**
+        * Shortcut for appendable string to form the main page name.
         *
-        *  Example to declare titles nonexistent:
+        * Returns a string like ".json", or "" if no extension.
         *
-        *     Title.exist.set( ['File:Foo_bar.jpg', ...], false );
+        * @return {string}
+        */
+       getDotExtension: function () {
+               return this.ext === null ? '' : '.' + this.ext;
+       },
+
+       /**
+        * Get the main page name
+        *
+        * Example: "Example_image.svg" for "File:Example_image.svg".
         *
-        * @property {string|Array} exist.set.titles Title(s) in strict prefixedDb title form
-        * @property {boolean} [exist.set.state=true] State of the given titles
-        * @return {boolean}
+        * @return {string}
         */
-       Title.exist = {
-               pages: {},
+       getMain: function () {
+               return this.getName() + this.getDotExtension();
+       },
 
-               set: function ( titles, state ) {
-                       var i, len,
-                               pages = this.pages;
+       /**
+        * Get the main page name (transformed by #text)
+        *
+        * Example: "Example image.svg" for "File:Example_image.svg".
+        *
+        * @return {string}
+        */
+       getMainText: function () {
+               return text( this.getMain() );
+       },
 
-                       titles = Array.isArray( titles ) ? titles : [ titles ];
-                       state = state === undefined ? true : !!state;
+       /**
+        * Get the full page name
+        *
+        * Example: "File:Example_image.svg".
+        * Most useful for API calls, anything that must identify the "title".
+        *
+        * @return {string}
+        */
+       getPrefixedDb: function () {
+               return this.getNamespacePrefix() + this.getMain();
+       },
 
-                       for ( i = 0, len = titles.length; i < len; i++ ) {
-                               pages[ titles[ i ] ] = state;
-                       }
-                       return true;
-               }
-       };
+       /**
+        * Get the full page name (transformed by #text)
+        *
+        * Example: "File:Example image.svg" for "File:Example_image.svg".
+        *
+        * @return {string}
+        */
+       getPrefixedText: function () {
+               return text( this.getPrefixedDb() );
+       },
 
        /**
-        * Normalize a file extension to the common form, making it lowercase and checking some synonyms,
-        * and ensure it's clean. Extensions with non-alphanumeric characters will be discarded.
-        * Keep in sync with File::normalizeExtension() in PHP.
+        * Get the page name relative to a namespace
+        *
+        * Example:
         *
-        * @param {string} extension File extension (without the leading dot)
-        * @return {string} File extension in canonical form
+        * - "Foo:Bar" relative to the Foo namespace becomes "Bar".
+        * - "Bar" relative to any non-main namespace becomes ":Bar".
+        * - "Foo:Bar" relative to any namespace other than Foo stays "Foo:Bar".
+        *
+        * @param {number} namespace The namespace to be relative to
+        * @return {string}
         */
-       Title.normalizeExtension = function ( extension ) {
-               var
-                       lower = extension.toLowerCase(),
-                       squish = {
-                               htm: 'html',
-                               jpeg: 'jpg',
-                               mpeg: 'mpg',
-                               tiff: 'tif',
-                               ogv: 'ogg'
-                       };
-               if ( Object.prototype.hasOwnProperty.call( squish, lower ) ) {
-                       return squish[ lower ];
-               } else if ( /^[0-9a-z]+$/.test( lower ) ) {
-                       return lower;
+       getRelativeText: function ( namespace ) {
+               if ( this.getNamespaceId() === namespace ) {
+                       return this.getMainText();
+               } else if ( this.getNamespaceId() === NS_MAIN ) {
+                       return ':' + this.getPrefixedText();
                } else {
-                       return '';
+                       return this.getPrefixedText();
                }
-       };
-
-       /* Public members */
-
-       Title.prototype = {
-               constructor: Title,
-
-               /**
-                * Get the namespace number
-                *
-                * Example: 6 for "File:Example_image.svg".
-                *
-                * @return {number}
-                */
-               getNamespaceId: function () {
-                       return this.namespace;
-               },
-
-               /**
-                * Get the namespace prefix (in the content language)
-                *
-                * Example: "File:" for "File:Example_image.svg".
-                * In #NS_MAIN this is '', otherwise namespace name plus ':'
-                *
-                * @return {string}
-                */
-               getNamespacePrefix: function () {
-                       return getNamespacePrefix( this.namespace );
-               },
-
-               /**
-                * Get the page name without extension or namespace prefix
-                *
-                * Example: "Example_image" for "File:Example_image.svg".
-                *
-                * For the page title (full page name without namespace prefix), see #getMain.
-                *
-                * @return {string}
-                */
-               getName: function () {
-                       if (
-                               mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( this.namespace ) !== -1 ||
-                               !this.title.length
-                       ) {
-                               return this.title;
-                       }
-                       // PHP's strtoupper differs from String.toUpperCase in a number of cases
-                       // Bug: T147646
-                       return mw.Title.phpCharToUpper( this.title[ 0 ] ) + this.title.slice( 1 );
-               },
-
-               /**
-                * Get the page name (transformed by #text)
-                *
-                * Example: "Example image" for "File:Example_image.svg".
-                *
-                * For the page title (full page name without namespace prefix), see #getMainText.
-                *
-                * @return {string}
-                */
-               getNameText: function () {
-                       return text( this.getName() );
-               },
-
-               /**
-                * Get the extension of the page name (if any)
-                *
-                * @return {string|null} Name extension or null if there is none
-                */
-               getExtension: function () {
-                       return this.ext;
-               },
-
-               /**
-                * Shortcut for appendable string to form the main page name.
-                *
-                * Returns a string like ".json", or "" if no extension.
-                *
-                * @return {string}
-                */
-               getDotExtension: function () {
-                       return this.ext === null ? '' : '.' + this.ext;
-               },
-
-               /**
-                * Get the main page name
-                *
-                * Example: "Example_image.svg" for "File:Example_image.svg".
-                *
-                * @return {string}
-                */
-               getMain: function () {
-                       return this.getName() + this.getDotExtension();
-               },
-
-               /**
-                * Get the main page name (transformed by #text)
-                *
-                * Example: "Example image.svg" for "File:Example_image.svg".
-                *
-                * @return {string}
-                */
-               getMainText: function () {
-                       return text( this.getMain() );
-               },
-
-               /**
-                * Get the full page name
-                *
-                * Example: "File:Example_image.svg".
-                * Most useful for API calls, anything that must identify the "title".
-                *
-                * @return {string}
-                */
-               getPrefixedDb: function () {
-                       return this.getNamespacePrefix() + this.getMain();
-               },
-
-               /**
-                * Get the full page name (transformed by #text)
-                *
-                * Example: "File:Example image.svg" for "File:Example_image.svg".
-                *
-                * @return {string}
-                */
-               getPrefixedText: function () {
-                       return text( this.getPrefixedDb() );
-               },
-
-               /**
-                * Get the page name relative to a namespace
-                *
-                * Example:
-                *
-                * - "Foo:Bar" relative to the Foo namespace becomes "Bar".
-                * - "Bar" relative to any non-main namespace becomes ":Bar".
-                * - "Foo:Bar" relative to any namespace other than Foo stays "Foo:Bar".
-                *
-                * @param {number} namespace The namespace to be relative to
-                * @return {string}
-                */
-               getRelativeText: function ( namespace ) {
-                       if ( this.getNamespaceId() === namespace ) {
-                               return this.getMainText();
-                       } else if ( this.getNamespaceId() === NS_MAIN ) {
-                               return ':' + this.getPrefixedText();
-                       } else {
-                               return this.getPrefixedText();
-                       }
-               },
-
-               /**
-                * Get the fragment (if any).
-                *
-                * Note that this method (by design) does not include the hash character and
-                * the value is not url encoded.
-                *
-                * @return {string|null}
-                */
-               getFragment: function () {
-                       return this.fragment;
-               },
-
-               /**
-                * Get the URL to this title
-                *
-                * @see mw.util#getUrl
-                * @param {Object} [params] A mapping of query parameter names to values,
-                *     e.g. `{ action: 'edit' }`.
-                * @return {string}
-                */
-               getUrl: function ( params ) {
-                       var fragment = this.getFragment();
-                       if ( fragment ) {
-                               return mw.util.getUrl( this.toString() + '#' + fragment, params );
-                       } else {
-                               return mw.util.getUrl( this.toString(), params );
-                       }
-               },
-
-               /**
-                * Check if the title is in a talk namespace
-                *
-                * @return {boolean} The title is in a talk namespace
-                */
-               isTalkPage: function () {
-                       return Title.isTalkNamespace( this.getNamespaceId() );
-               },
+       },
 
-               /**
-                * Get the title for the associated talk page
-                *
-                * @return {mw.Title|null} The title for the associated talk page, null if not available
-                */
-               getTalkPage: function () {
-                       if ( !this.canHaveTalkPage() ) {
-                               return null;
-                       }
-                       return this.isTalkPage() ?
-                               this :
-                               Title.makeTitle( this.getNamespaceId() + 1, this.getMainText() );
-               },
+       /**
+        * Get the fragment (if any).
+        *
+        * Note that this method (by design) does not include the hash character and
+        * the value is not url encoded.
+        *
+        * @return {string|null}
+        */
+       getFragment: function () {
+               return this.fragment;
+       },
 
-               /**
-                * Get the title for the subject page of a talk page
-                *
-                * @return {mw.Title|null} The title for the subject page of a talk page, null if not available
-                */
-               getSubjectPage: function () {
-                       return this.isTalkPage() ?
-                               Title.makeTitle( this.getNamespaceId() - 1, this.getMainText() ) :
-                               this;
-               },
+       /**
+        * Get the URL to this title
+        *
+        * @see mw.util#getUrl
+        * @param {Object} [params] A mapping of query parameter names to values,
+        *     e.g. `{ action: 'edit' }`.
+        * @return {string}
+        */
+       getUrl: function ( params ) {
+               var fragment = this.getFragment();
+               if ( fragment ) {
+                       return mw.util.getUrl( this.toString() + '#' + fragment, params );
+               } else {
+                       return mw.util.getUrl( this.toString(), params );
+               }
+       },
 
-               /**
-                * Check the the title can have an associated talk page
-                *
-                * @return {boolean} The title can have an associated talk page
-                */
-               canHaveTalkPage: function () {
-                       return this.getNamespaceId() >= NS_MAIN;
-               },
+       /**
+        * Check if the title is in a talk namespace
+        *
+        * @return {boolean} The title is in a talk namespace
+        */
+       isTalkPage: function () {
+               return Title.isTalkNamespace( this.getNamespaceId() );
+       },
 
-               /**
-                * Whether this title exists on the wiki.
-                *
-                * @see #static-method-exists
-                * @return {boolean|null} Boolean if the information is available, otherwise null
-                */
-               exists: function () {
-                       return Title.exists( this );
+       /**
+        * Get the title for the associated talk page
+        *
+        * @return {mw.Title|null} The title for the associated talk page, null if not available
+        */
+       getTalkPage: function () {
+               if ( !this.canHaveTalkPage() ) {
+                       return null;
                }
-       };
+               return this.isTalkPage() ?
+                       this :
+                       Title.makeTitle( this.getNamespaceId() + 1, this.getMainText() );
+       },
 
        /**
-        * @alias #getPrefixedDb
-        * @method
+        * Get the title for the subject page of a talk page
+        *
+        * @return {mw.Title|null} The title for the subject page of a talk page, null if not available
         */
-       Title.prototype.toString = Title.prototype.getPrefixedDb;
+       getSubjectPage: function () {
+               return this.isTalkPage() ?
+                       Title.makeTitle( this.getNamespaceId() - 1, this.getMainText() ) :
+                       this;
+       },
 
        /**
-        * @alias #getPrefixedText
-        * @method
+        * Check the the title can have an associated talk page
+        *
+        * @return {boolean} The title can have an associated talk page
         */
-       Title.prototype.toText = Title.prototype.getPrefixedText;
+       canHaveTalkPage: function () {
+               return this.getNamespaceId() >= NS_MAIN;
+       },
 
-       // Expose
-       mw.Title = Title;
+       /**
+        * Whether this title exists on the wiki.
+        *
+        * @see #static-method-exists
+        * @return {boolean|null} Boolean if the information is available, otherwise null
+        */
+       exists: function () {
+               return Title.exists( this );
+       }
+};
+
+/**
+ * @alias #getPrefixedDb
+ * @method
+ */
+Title.prototype.toString = Title.prototype.getPrefixedDb;
+
+/**
+ * @alias #getPrefixedText
+ * @method
+ */
+Title.prototype.toText = Title.prototype.getPrefixedText;
 
-}() );
+// Expose
+mw.Title = Title;
diff --git a/resources/src/mediawiki.Title/phpCharToUpper.js b/resources/src/mediawiki.Title/phpCharToUpper.js
deleted file mode 100644 (file)
index ed700f0..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-// This file can't be parsed by JSDuck due to <https://github.com/tenderlove/rkelly/issues/35>.
-// (It is excluded in jsduck.json.)
-// ESLint suggests unquoting some object keys, which would render the file unparseable by Opera 12.
-/* eslint-disable quote-props */
-( function () {
-       var toUpperMapping = {
-               'ß': 'ß',
-               'ʼn': 'ʼn',
-               'Dž': 'Dž',
-               'dž': 'Dž',
-               'Lj': 'Lj',
-               'lj': 'Lj',
-               'Nj': 'Nj',
-               'nj': 'Nj',
-               'ǰ': 'ǰ',
-               'Dz': 'Dz',
-               'dz': 'Dz',
-               'ʝ': 'Ʝ',
-               'ͅ': 'ͅ',
-               'ΐ': 'ΐ',
-               'ΰ': 'ΰ',
-               'և': 'և',
-               'ᏸ': 'Ᏸ',
-               'ᏹ': 'Ᏹ',
-               'ᏺ': 'Ᏺ',
-               'ᏻ': 'Ᏻ',
-               'ᏼ': 'Ᏼ',
-               'ᏽ': 'Ᏽ',
-               'ẖ': 'ẖ',
-               'ẗ': 'ẗ',
-               'ẘ': 'ẘ',
-               'ẙ': 'ẙ',
-               'ẚ': 'ẚ',
-               'ὐ': 'ὐ',
-               'ὒ': 'ὒ',
-               'ὔ': 'ὔ',
-               'ὖ': 'ὖ',
-               'ᾀ': 'ᾈ',
-               'ᾁ': 'ᾉ',
-               'ᾂ': 'ᾊ',
-               'ᾃ': 'ᾋ',
-               'ᾄ': 'ᾌ',
-               'ᾅ': 'ᾍ',
-               'ᾆ': 'ᾎ',
-               'ᾇ': 'ᾏ',
-               'ᾈ': 'ᾈ',
-               'ᾉ': 'ᾉ',
-               'ᾊ': 'ᾊ',
-               'ᾋ': 'ᾋ',
-               'ᾌ': 'ᾌ',
-               'ᾍ': 'ᾍ',
-               'ᾎ': 'ᾎ',
-               'ᾏ': 'ᾏ',
-               'ᾐ': 'ᾘ',
-               'ᾑ': 'ᾙ',
-               'ᾒ': 'ᾚ',
-               'ᾓ': 'ᾛ',
-               'ᾔ': 'ᾜ',
-               'ᾕ': 'ᾝ',
-               'ᾖ': 'ᾞ',
-               'ᾗ': 'ᾟ',
-               'ᾘ': 'ᾘ',
-               'ᾙ': 'ᾙ',
-               'ᾚ': 'ᾚ',
-               'ᾛ': 'ᾛ',
-               'ᾜ': 'ᾜ',
-               'ᾝ': 'ᾝ',
-               'ᾞ': 'ᾞ',
-               'ᾟ': 'ᾟ',
-               'ᾠ': 'ᾨ',
-               'ᾡ': 'ᾩ',
-               'ᾢ': 'ᾪ',
-               'ᾣ': 'ᾫ',
-               'ᾤ': 'ᾬ',
-               'ᾥ': 'ᾭ',
-               'ᾦ': 'ᾮ',
-               'ᾧ': 'ᾯ',
-               'ᾨ': 'ᾨ',
-               'ᾩ': 'ᾩ',
-               'ᾪ': 'ᾪ',
-               'ᾫ': 'ᾫ',
-               'ᾬ': 'ᾬ',
-               'ᾭ': 'ᾭ',
-               'ᾮ': 'ᾮ',
-               'ᾯ': 'ᾯ',
-               'ᾲ': 'ᾲ',
-               'ᾳ': 'ᾼ',
-               'ᾴ': 'ᾴ',
-               'ᾶ': 'ᾶ',
-               'ᾷ': 'ᾷ',
-               'ᾼ': 'ᾼ',
-               'ῂ': 'ῂ',
-               'ῃ': 'ῌ',
-               'ῄ': 'ῄ',
-               'ῆ': 'ῆ',
-               'ῇ': 'ῇ',
-               'ῌ': 'ῌ',
-               'ῒ': 'ῒ',
-               'ΐ': 'ΐ',
-               'ῖ': 'ῖ',
-               'ῗ': 'ῗ',
-               'ῢ': 'ῢ',
-               'ΰ': 'ΰ',
-               'ῤ': 'ῤ',
-               'ῦ': 'ῦ',
-               'ῧ': 'ῧ',
-               'ῲ': 'ῲ',
-               'ῳ': 'ῼ',
-               'ῴ': 'ῴ',
-               'ῶ': 'ῶ',
-               'ῷ': 'ῷ',
-               'ῼ': 'ῼ',
-               'ⅰ': 'ⅰ',
-               'ⅱ': 'ⅱ',
-               'ⅲ': 'ⅲ',
-               'ⅳ': 'ⅳ',
-               'ⅴ': 'ⅴ',
-               'ⅵ': 'ⅵ',
-               'ⅶ': 'ⅶ',
-               'ⅷ': 'ⅷ',
-               'ⅸ': 'ⅸ',
-               'ⅹ': 'ⅹ',
-               'ⅺ': 'ⅺ',
-               'ⅻ': 'ⅻ',
-               'ⅼ': 'ⅼ',
-               'ⅽ': 'ⅽ',
-               'ⅾ': 'ⅾ',
-               'ⅿ': 'ⅿ',
-               'ⓐ': 'ⓐ',
-               'ⓑ': 'ⓑ',
-               'ⓒ': 'ⓒ',
-               'ⓓ': 'ⓓ',
-               'ⓔ': 'ⓔ',
-               'ⓕ': 'ⓕ',
-               'ⓖ': 'ⓖ',
-               'ⓗ': 'ⓗ',
-               'ⓘ': 'ⓘ',
-               'ⓙ': 'ⓙ',
-               'ⓚ': 'ⓚ',
-               'ⓛ': 'ⓛ',
-               'ⓜ': 'ⓜ',
-               'ⓝ': 'ⓝ',
-               'ⓞ': 'ⓞ',
-               'ⓟ': 'ⓟ',
-               'ⓠ': 'ⓠ',
-               'ⓡ': 'ⓡ',
-               'ⓢ': 'ⓢ',
-               'ⓣ': 'ⓣ',
-               'ⓤ': 'ⓤ',
-               'ⓥ': 'ⓥ',
-               'ⓦ': 'ⓦ',
-               'ⓧ': 'ⓧ',
-               'ⓨ': 'ⓨ',
-               'ⓩ': 'ⓩ',
-               'ꞵ': 'Ꞵ',
-               'ꞷ': 'Ꞷ',
-               'ꭓ': 'Ꭓ',
-               'ꭰ': 'Ꭰ',
-               'ꭱ': 'Ꭱ',
-               'ꭲ': 'Ꭲ',
-               'ꭳ': 'Ꭳ',
-               'ꭴ': 'Ꭴ',
-               'ꭵ': 'Ꭵ',
-               'ꭶ': 'Ꭶ',
-               'ꭷ': 'Ꭷ',
-               'ꭸ': 'Ꭸ',
-               'ꭹ': 'Ꭹ',
-               'ꭺ': 'Ꭺ',
-               'ꭻ': 'Ꭻ',
-               'ꭼ': 'Ꭼ',
-               'ꭽ': 'Ꭽ',
-               'ꭾ': 'Ꭾ',
-               'ꭿ': 'Ꭿ',
-               'ꮀ': 'Ꮀ',
-               'ꮁ': 'Ꮁ',
-               'ꮂ': 'Ꮂ',
-               'ꮃ': 'Ꮃ',
-               'ꮄ': 'Ꮄ',
-               'ꮅ': 'Ꮅ',
-               'ꮆ': 'Ꮆ',
-               'ꮇ': 'Ꮇ',
-               'ꮈ': 'Ꮈ',
-               'ꮉ': 'Ꮉ',
-               'ꮊ': 'Ꮊ',
-               'ꮋ': 'Ꮋ',
-               'ꮌ': 'Ꮌ',
-               'ꮍ': 'Ꮍ',
-               'ꮎ': 'Ꮎ',
-               'ꮏ': 'Ꮏ',
-               'ꮐ': 'Ꮐ',
-               'ꮑ': 'Ꮑ',
-               'ꮒ': 'Ꮒ',
-               'ꮓ': 'Ꮓ',
-               'ꮔ': 'Ꮔ',
-               'ꮕ': 'Ꮕ',
-               'ꮖ': 'Ꮖ',
-               'ꮗ': 'Ꮗ',
-               'ꮘ': 'Ꮘ',
-               'ꮙ': 'Ꮙ',
-               'ꮚ': 'Ꮚ',
-               'ꮛ': 'Ꮛ',
-               'ꮜ': 'Ꮜ',
-               'ꮝ': 'Ꮝ',
-               'ꮞ': 'Ꮞ',
-               'ꮟ': 'Ꮟ',
-               'ꮠ': 'Ꮠ',
-               'ꮡ': 'Ꮡ',
-               'ꮢ': 'Ꮢ',
-               'ꮣ': 'Ꮣ',
-               'ꮤ': 'Ꮤ',
-               'ꮥ': 'Ꮥ',
-               'ꮦ': 'Ꮦ',
-               'ꮧ': 'Ꮧ',
-               'ꮨ': 'Ꮨ',
-               'ꮩ': 'Ꮩ',
-               'ꮪ': 'Ꮪ',
-               'ꮫ': 'Ꮫ',
-               'ꮬ': 'Ꮬ',
-               'ꮭ': 'Ꮭ',
-               'ꮮ': 'Ꮮ',
-               'ꮯ': 'Ꮯ',
-               'ꮰ': 'Ꮰ',
-               'ꮱ': 'Ꮱ',
-               'ꮲ': 'Ꮲ',
-               'ꮳ': 'Ꮳ',
-               'ꮴ': 'Ꮴ',
-               'ꮵ': 'Ꮵ',
-               'ꮶ': 'Ꮶ',
-               'ꮷ': 'Ꮷ',
-               'ꮸ': 'Ꮸ',
-               'ꮹ': 'Ꮹ',
-               'ꮺ': 'Ꮺ',
-               'ꮻ': 'Ꮻ',
-               'ꮼ': 'Ꮼ',
-               'ꮽ': 'Ꮽ',
-               'ꮾ': 'Ꮾ',
-               'ꮿ': 'Ꮿ',
-               'ff': 'ff',
-               'fi': 'fi',
-               'fl': 'fl',
-               'ffi': 'ffi',
-               'ffl': 'ffl',
-               'ſt': 'ſt',
-               'st': 'st',
-               'ﬓ': 'ﬓ',
-               'ﬔ': 'ﬔ',
-               'ﬕ': 'ﬕ',
-               'ﬖ': 'ﬖ',
-               'ﬗ': 'ﬗ'
-       };
-       mw.Title.phpCharToUpper = function ( chr ) {
-               var mapped = toUpperMapping[ chr ];
-               return mapped || chr.toUpperCase();
-       };
-}() );
diff --git a/resources/src/mediawiki.Title/phpCharToUpper.json b/resources/src/mediawiki.Title/phpCharToUpper.json
new file mode 100644 (file)
index 0000000..b0887fa
--- /dev/null
@@ -0,0 +1,245 @@
+{
+       "ß": "ß",
+       "ʼn": "ʼn",
+       "Dž": "Dž",
+       "dž": "Dž",
+       "Lj": "Lj",
+       "lj": "Lj",
+       "Nj": "Nj",
+       "nj": "Nj",
+       "ǰ": "ǰ",
+       "Dz": "Dz",
+       "dz": "Dz",
+       "ʝ": "Ʝ",
+       "ͅ": "ͅ",
+       "ΐ": "ΐ",
+       "ΰ": "ΰ",
+       "և": "և",
+       "ᏸ": "Ᏸ",
+       "ᏹ": "Ᏹ",
+       "ᏺ": "Ᏺ",
+       "ᏻ": "Ᏻ",
+       "ᏼ": "Ᏼ",
+       "ᏽ": "Ᏽ",
+       "ẖ": "ẖ",
+       "ẗ": "ẗ",
+       "ẘ": "ẘ",
+       "ẙ": "ẙ",
+       "ẚ": "ẚ",
+       "ὐ": "ὐ",
+       "ὒ": "ὒ",
+       "ὔ": "ὔ",
+       "ὖ": "ὖ",
+       "ᾀ": "ᾈ",
+       "ᾁ": "ᾉ",
+       "ᾂ": "ᾊ",
+       "ᾃ": "ᾋ",
+       "ᾄ": "ᾌ",
+       "ᾅ": "ᾍ",
+       "ᾆ": "ᾎ",
+       "ᾇ": "ᾏ",
+       "ᾈ": "ᾈ",
+       "ᾉ": "ᾉ",
+       "ᾊ": "ᾊ",
+       "ᾋ": "ᾋ",
+       "ᾌ": "ᾌ",
+       "ᾍ": "ᾍ",
+       "ᾎ": "ᾎ",
+       "ᾏ": "ᾏ",
+       "ᾐ": "ᾘ",
+       "ᾑ": "ᾙ",
+       "ᾒ": "ᾚ",
+       "ᾓ": "ᾛ",
+       "ᾔ": "ᾜ",
+       "ᾕ": "ᾝ",
+       "ᾖ": "ᾞ",
+       "ᾗ": "ᾟ",
+       "ᾘ": "ᾘ",
+       "ᾙ": "ᾙ",
+       "ᾚ": "ᾚ",
+       "ᾛ": "ᾛ",
+       "ᾜ": "ᾜ",
+       "ᾝ": "ᾝ",
+       "ᾞ": "ᾞ",
+       "ᾟ": "ᾟ",
+       "ᾠ": "ᾨ",
+       "ᾡ": "ᾩ",
+       "ᾢ": "ᾪ",
+       "ᾣ": "ᾫ",
+       "ᾤ": "ᾬ",
+       "ᾥ": "ᾭ",
+       "ᾦ": "ᾮ",
+       "ᾧ": "ᾯ",
+       "ᾨ": "ᾨ",
+       "ᾩ": "ᾩ",
+       "ᾪ": "ᾪ",
+       "ᾫ": "ᾫ",
+       "ᾬ": "ᾬ",
+       "ᾭ": "ᾭ",
+       "ᾮ": "ᾮ",
+       "ᾯ": "ᾯ",
+       "ᾲ": "ᾲ",
+       "ᾳ": "ᾼ",
+       "ᾴ": "ᾴ",
+       "ᾶ": "ᾶ",
+       "ᾷ": "ᾷ",
+       "ᾼ": "ᾼ",
+       "ῂ": "ῂ",
+       "ῃ": "ῌ",
+       "ῄ": "ῄ",
+       "ῆ": "ῆ",
+       "ῇ": "ῇ",
+       "ῌ": "ῌ",
+       "ῒ": "ῒ",
+       "ΐ": "ΐ",
+       "ῖ": "ῖ",
+       "ῗ": "ῗ",
+       "ῢ": "ῢ",
+       "ΰ": "ΰ",
+       "ῤ": "ῤ",
+       "ῦ": "ῦ",
+       "ῧ": "ῧ",
+       "ῲ": "ῲ",
+       "ῳ": "ῼ",
+       "ῴ": "ῴ",
+       "ῶ": "ῶ",
+       "ῷ": "ῷ",
+       "ῼ": "ῼ",
+       "ⅰ": "ⅰ",
+       "ⅱ": "ⅱ",
+       "ⅲ": "ⅲ",
+       "ⅳ": "ⅳ",
+       "ⅴ": "ⅴ",
+       "ⅵ": "ⅵ",
+       "ⅶ": "ⅶ",
+       "ⅷ": "ⅷ",
+       "ⅸ": "ⅸ",
+       "ⅹ": "ⅹ",
+       "ⅺ": "ⅺ",
+       "ⅻ": "ⅻ",
+       "ⅼ": "ⅼ",
+       "ⅽ": "ⅽ",
+       "ⅾ": "ⅾ",
+       "ⅿ": "ⅿ",
+       "ⓐ": "ⓐ",
+       "ⓑ": "ⓑ",
+       "ⓒ": "ⓒ",
+       "ⓓ": "ⓓ",
+       "ⓔ": "ⓔ",
+       "ⓕ": "ⓕ",
+       "ⓖ": "ⓖ",
+       "ⓗ": "ⓗ",
+       "ⓘ": "ⓘ",
+       "ⓙ": "ⓙ",
+       "ⓚ": "ⓚ",
+       "ⓛ": "ⓛ",
+       "ⓜ": "ⓜ",
+       "ⓝ": "ⓝ",
+       "ⓞ": "ⓞ",
+       "ⓟ": "ⓟ",
+       "ⓠ": "ⓠ",
+       "ⓡ": "ⓡ",
+       "ⓢ": "ⓢ",
+       "ⓣ": "ⓣ",
+       "ⓤ": "ⓤ",
+       "ⓥ": "ⓥ",
+       "ⓦ": "ⓦ",
+       "ⓧ": "ⓧ",
+       "ⓨ": "ⓨ",
+       "ⓩ": "ⓩ",
+       "ꞵ": "Ꞵ",
+       "ꞷ": "Ꞷ",
+       "ꭓ": "Ꭓ",
+       "ꭰ": "Ꭰ",
+       "ꭱ": "Ꭱ",
+       "ꭲ": "Ꭲ",
+       "ꭳ": "Ꭳ",
+       "ꭴ": "Ꭴ",
+       "ꭵ": "Ꭵ",
+       "ꭶ": "Ꭶ",
+       "ꭷ": "Ꭷ",
+       "ꭸ": "Ꭸ",
+       "ꭹ": "Ꭹ",
+       "ꭺ": "Ꭺ",
+       "ꭻ": "Ꭻ",
+       "ꭼ": "Ꭼ",
+       "ꭽ": "Ꭽ",
+       "ꭾ": "Ꭾ",
+       "ꭿ": "Ꭿ",
+       "ꮀ": "Ꮀ",
+       "ꮁ": "Ꮁ",
+       "ꮂ": "Ꮂ",
+       "ꮃ": "Ꮃ",
+       "ꮄ": "Ꮄ",
+       "ꮅ": "Ꮅ",
+       "ꮆ": "Ꮆ",
+       "ꮇ": "Ꮇ",
+       "ꮈ": "Ꮈ",
+       "ꮉ": "Ꮉ",
+       "ꮊ": "Ꮊ",
+       "ꮋ": "Ꮋ",
+       "ꮌ": "Ꮌ",
+       "ꮍ": "Ꮍ",
+       "ꮎ": "Ꮎ",
+       "ꮏ": "Ꮏ",
+       "ꮐ": "Ꮐ",
+       "ꮑ": "Ꮑ",
+       "ꮒ": "Ꮒ",
+       "ꮓ": "Ꮓ",
+       "ꮔ": "Ꮔ",
+       "ꮕ": "Ꮕ",
+       "ꮖ": "Ꮖ",
+       "ꮗ": "Ꮗ",
+       "ꮘ": "Ꮘ",
+       "ꮙ": "Ꮙ",
+       "ꮚ": "Ꮚ",
+       "ꮛ": "Ꮛ",
+       "ꮜ": "Ꮜ",
+       "ꮝ": "Ꮝ",
+       "ꮞ": "Ꮞ",
+       "ꮟ": "Ꮟ",
+       "ꮠ": "Ꮠ",
+       "ꮡ": "Ꮡ",
+       "ꮢ": "Ꮢ",
+       "ꮣ": "Ꮣ",
+       "ꮤ": "Ꮤ",
+       "ꮥ": "Ꮥ",
+       "ꮦ": "Ꮦ",
+       "ꮧ": "Ꮧ",
+       "ꮨ": "Ꮨ",
+       "ꮩ": "Ꮩ",
+       "ꮪ": "Ꮪ",
+       "ꮫ": "Ꮫ",
+       "ꮬ": "Ꮬ",
+       "ꮭ": "Ꮭ",
+       "ꮮ": "Ꮮ",
+       "ꮯ": "Ꮯ",
+       "ꮰ": "Ꮰ",
+       "ꮱ": "Ꮱ",
+       "ꮲ": "Ꮲ",
+       "ꮳ": "Ꮳ",
+       "ꮴ": "Ꮴ",
+       "ꮵ": "Ꮵ",
+       "ꮶ": "Ꮶ",
+       "ꮷ": "Ꮷ",
+       "ꮸ": "Ꮸ",
+       "ꮹ": "Ꮹ",
+       "ꮺ": "Ꮺ",
+       "ꮻ": "Ꮻ",
+       "ꮼ": "Ꮼ",
+       "ꮽ": "Ꮽ",
+       "ꮾ": "Ꮾ",
+       "ꮿ": "Ꮿ",
+       "ff": "ff",
+       "fi": "fi",
+       "fl": "fl",
+       "ffi": "ffi",
+       "ffl": "ffl",
+       "ſt": "ſt",
+       "st": "st",
+       "ﬓ": "ﬓ",
+       "ﬔ": "ﬔ",
+       "ﬕ": "ﬕ",
+       "ﬖ": "ﬖ",
+       "ﬗ": "ﬗ"
+}
index a370881..af4b897 100644 (file)
                                }
                                if ( response.parse.modules ) {
                                        mw.loader.load( response.parse.modules.concat(
-                                               response.parse.modulescripts,
                                                response.parse.modulestyles
                                        ) );
                                }
diff --git a/resources/src/mediawiki.action/mediawiki.action.history.styles.css b/resources/src/mediawiki.action/mediawiki.action.history.styles.css
deleted file mode 100644 (file)
index 257f153..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Basic styles for the history page */
-
-#pagehistory .history-user {
-       margin-left: 0.4em;
-       margin-right: 0.2em;
-}
-
-#pagehistory li {
-       border: 1px solid #fff;
-}
-
-#pagehistory li.selected {
-       background-color: #f8f9fa;
-       color: #222;
-       border: 1px dashed #a2a9b1;
-}
-
-.mw-history-revisionactions {
-       float: right;
-}
-
-.updatedmarker {
-       background-color: #b7f430;
-}
diff --git a/resources/src/mediawiki.action/mediawiki.action.history.styles.less b/resources/src/mediawiki.action/mediawiki.action.history.styles.less
new file mode 100644 (file)
index 0000000..af91818
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Basic styles for the edit revision history page 'HistoryAction.php'
+ */
+
+// Trigger only when collapsible & JS is available via `.mw-collapsed`.
+#mw-history-search.mw-collapsed .oo-ui-fieldsetLayout-header .oo-ui-labelElement-label {
+       margin-bottom: 0;
+}
+
+#pagehistory .history-user {
+       margin-left: 0.4em;
+       margin-right: 0.2em;
+}
+
+#pagehistory li {
+       border: 1px solid #fff;
+}
+
+#pagehistory li.selected {
+       background-color: #f8f9fa;
+       color: #222;
+       border: 1px dashed #a2a9b1;
+}
+
+.mw-history-revisionactions {
+       float: right;
+}
+
+.updatedmarker {
+       background-color: #b7f430;
+}
index 107ab33..9016c7c 100644 (file)
                var deferred = $.Deferred();
 
                // Allow calling with a single dependency as a string
-               if ( typeof dependencies === 'string' ) {
+               if ( !Array.isArray( dependencies ) ) {
                        dependencies = [ dependencies ];
                }
 
                        return deferred.reject( e ).promise();
                }
 
-               mw.loader.enqueue( dependencies, function () {
-                       deferred.resolve( mw.loader.require );
-               }, deferred.reject );
+               mw.loader.enqueue(
+                       dependencies,
+                       function () { deferred.resolve( mw.loader.require ); },
+                       deferred.reject
+               );
 
                return deferred.promise();
        };
 
+       /**
+        * Load a script by URL.
+        *
+        * Example:
+        *
+        *     mw.loader.getScript(
+        *         'https://example.org/x-1.0.0.js'
+        *     )
+        *         .then( function () {
+        *             // Script succeeded. You can use X now.
+        *         }, function ( e ) {
+        *             // Script failed. X is not avaiable
+        *             mw.log.error( e.message ); // => "Failed to load script"
+        *         } );
+        *     } );
+        *
+        * @member mw.loader
+        * @param {string} url Script URL
+        * @return {jQuery.Promise} Resolved when the script is loaded
+        */
+       mw.loader.getScript = function ( url ) {
+               return $.ajax( url, { dataType: 'script', cache: true } )
+                       .catch( function () {
+                               throw new Error( 'Failed to load script' );
+                       } );
+       };
+
        // Alias $j to jQuery for backwards compatibility
        // @deprecated since 1.23 Use $ or jQuery instead
        mw.log.deprecate( window, '$j', $, 'Use $ or jQuery instead.' );
diff --git a/resources/src/mediawiki.cldr/index.js b/resources/src/mediawiki.cldr/index.js
new file mode 100644 (file)
index 0000000..5054810
--- /dev/null
@@ -0,0 +1,32 @@
+( function () {
+       'use strict';
+
+       /**
+        * Namespace for CLDR-related utility methods.
+        *
+        * @class
+        * @singleton
+        */
+       mw.cldr = {
+               /**
+                * Get the plural form index for the number.
+                *
+                * In case none of the rules passed, we return `pluralRules.length` -
+                * that means it is the "other" form.
+                *
+                * @param {number} number
+                * @param {Array} pluralRules
+                * @return {number} plural form index
+                */
+               getPluralForm: function ( number, pluralRules ) {
+                       var i, pluralRuleParser = require( 'mediawiki.libs.pluralruleparser' );
+                       for ( i = 0; i < pluralRules.length; i++ ) {
+                               if ( pluralRuleParser( pluralRules[ i ], number ) ) {
+                                       break;
+                               }
+                       }
+                       return i;
+               }
+       };
+
+}() );
diff --git a/resources/src/mediawiki.cookie.js b/resources/src/mediawiki.cookie.js
deleted file mode 100644 (file)
index 76038f6..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-( function () {
-       'use strict';
-
-       /**
-        * Provides an API for getting and setting cookies that is
-        * syntactically and functionally similar to the server-side cookie
-        * API (`WebRequest#getCookie` and `WebResponse#setcookie`).
-        *
-        * @author Sam Smith <samsmith@wikimedia.org>
-        * @author Matthew Flaschen <mflaschen@wikimedia.org>
-        * @author Timo Tijhof <krinklemail@gmail.com>
-        *
-        * @class mw.cookie
-        * @singleton
-        */
-       mw.cookie = {
-
-               /**
-                * Set or delete a cookie.
-                *
-                * While this is natural in JavaScript, contrary to `WebResponse#setcookie` in PHP, the
-                * default values for the `options` properties only apply if that property isn't set
-                * already in your options object (e.g. passing `{ secure: null }` or `{ secure: undefined }`
-                * overrides the default value for `options.secure`).
-                *
-                * @param {string} key
-                * @param {string|null} value Value of cookie. If `value` is `null` then this method will
-                *   instead remove a cookie by name of `key`.
-                * @param {Object|Date|number} [options] Options object, or expiry date
-                * @param {Date|number|null} [options.expires] The expiry date of the cookie, or lifetime in seconds.
-                *
-                *   If `options.expires` is null, then a session cookie is set.
-                *
-                *   By default cookie expiration is based on `wgCookieExpiration`. Similar to `WebResponse`
-                *   in PHP, we set a session cookie if `wgCookieExpiration` is 0. And for non-zero values
-                *   it is interpreted as lifetime in seconds.
-                *
-                * @param {string} [options.prefix=wgCookiePrefix] The prefix of the key
-                * @param {string} [options.domain=wgCookieDomain] The domain attribute of the cookie
-                * @param {string} [options.path=wgCookiePath] The path attribute of the cookie
-                * @param {boolean} [options.secure=false] Whether or not to include the secure attribute.
-                *   (Does **not** use the wgCookieSecure configuration variable)
-                */
-               set: function ( key, value, options ) {
-                       var config, defaultOptions, date;
-
-                       // wgCookieSecure is not used for now, since 'detect' could not work with
-                       // ResourceLoaderStartUpModule, as module cache is not fragmented by protocol.
-                       config = mw.config.get( [
-                               'wgCookiePrefix',
-                               'wgCookieDomain',
-                               'wgCookiePath',
-                               'wgCookieExpiration'
-                       ] );
-
-                       defaultOptions = {
-                               prefix: config.wgCookiePrefix,
-                               domain: config.wgCookieDomain,
-                               path: config.wgCookiePath,
-                               secure: false
-                       };
-
-                       // Options argument can also be a shortcut for the expiry
-                       // Expiry can be a Date, number or null
-                       if ( !options || options instanceof Date || typeof options === 'number' ) {
-                               // Also takes care of options = undefined, in which case we also don't need $.extend()
-                               defaultOptions.expires = options;
-                               options = defaultOptions;
-                       } else {
-                               options = $.extend( defaultOptions, options );
-                       }
-
-                       // Default to using wgCookieExpiration (lifetime in seconds).
-                       // If wgCookieExpiration is 0, that is considered a special value indicating
-                       // all cookies should be session cookies by default.
-                       if ( options.expires === undefined && config.wgCookieExpiration !== 0 ) {
-                               date = new Date();
-                               date.setTime( Number( date ) + ( config.wgCookieExpiration * 1000 ) );
-                               options.expires = date;
-                       } else if ( typeof options.expires === 'number' ) {
-                               // Lifetime in seconds
-                               date = new Date();
-                               date.setTime( Number( date ) + ( options.expires * 1000 ) );
-                               options.expires = date;
-                       } else if ( options.expires === null ) {
-                               // $.cookie makes a session cookie when options.expires is omitted
-                               delete options.expires;
-                       }
-
-                       // Process prefix
-                       key = options.prefix + key;
-                       delete options.prefix;
-
-                       // Process value
-                       if ( value !== null ) {
-                               value = String( value );
-                       }
-
-                       // Other options are handled by $.cookie
-                       $.cookie( key, value, options );
-               },
-
-               /**
-                * Get the value of a cookie.
-                *
-                * @param {string} key
-                * @param {string} [prefix=wgCookiePrefix] The prefix of the key. If `prefix` is
-                *   `undefined` or `null`, then `wgCookiePrefix` is used
-                * @param {Mixed} [defaultValue=null]
-                * @return {string|null|Mixed} If the cookie exists, then the value of the
-                *   cookie, otherwise `defaultValue`
-                */
-               get: function ( key, prefix, defaultValue ) {
-                       var result;
-
-                       if ( prefix === undefined || prefix === null ) {
-                               prefix = mw.config.get( 'wgCookiePrefix' );
-                       }
-
-                       // Was defaultValue omitted?
-                       if ( arguments.length < 3 ) {
-                               defaultValue = null;
-                       }
-
-                       result = $.cookie( prefix + key );
-
-                       return result !== null ? result : defaultValue;
-               }
-       };
-
-}() );
diff --git a/resources/src/mediawiki.cookie/.eslintrc.json b/resources/src/mediawiki.cookie/.eslintrc.json
new file mode 100644 (file)
index 0000000..ad8dbb3
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "parserOptions": {
+               "sourceType": "module"
+       }
+}
diff --git a/resources/src/mediawiki.cookie/index.js b/resources/src/mediawiki.cookie/index.js
new file mode 100644 (file)
index 0000000..b04b57a
--- /dev/null
@@ -0,0 +1,113 @@
+'use strict';
+
+var config = require( './config.json' ),
+       defaults = {
+               prefix: config.prefix,
+               domain: config.domain,
+               path: config.path,
+               expires: config.expires,
+               secure: false
+       };
+
+/**
+ * Manage cookies in a way that is syntactically and functionally similar
+ * to the `WebRequest#getCookie` and `WebResponse#setcookie` methods in PHP.
+ *
+ * @author Sam Smith <samsmith@wikimedia.org>
+ * @author Matthew Flaschen <mflaschen@wikimedia.org>
+ *
+ * @class mw.cookie
+ * @singleton
+ */
+mw.cookie = {
+
+       /**
+        * Set or delete a cookie.
+        *
+        * **Note:** If explicitly passing `null` or `undefined` for an options key,
+        * that will override the default. This is natural in JavaScript, but noted
+        * here because it is contrary to MediaWiki's `WebResponse#setcookie()` method
+        * in PHP.
+        *
+        * @param {string} key
+        * @param {string|null} value Value of cookie. If `value` is `null` then this method will
+        *   instead remove a cookie by name of `key`.
+        * @param {Object|Date|number} [options] Options object, or expiry date
+        * @param {Date|number|null} [options.expires=wgCookieExpiration] The expiry date of the cookie,
+        *  or lifetime in seconds. If `options.expires` is null or 0, then a session cookie is set.
+        * @param {string} [options.prefix=wgCookiePrefix] The prefix of the key
+        * @param {string} [options.domain=wgCookieDomain] The domain attribute of the cookie
+        * @param {string} [options.path=wgCookiePath] The path attribute of the cookie
+        * @param {boolean} [options.secure=false] Whether or not to include the secure attribute.
+        *   (Does **not** use the wgCookieSecure configuration variable)
+        */
+       set: function ( key, value, options ) {
+               var date;
+
+               // The 'options' parameter may be a shortcut for the expiry.
+               if ( arguments.length > 2 && ( !options || options instanceof Date || typeof options === 'number' ) ) {
+                       options = { expires: options };
+               }
+               // Apply defaults
+               options = $.extend( {}, defaults, options );
+
+               // Handle prefix
+               key = options.prefix + key;
+               // Don't pass invalid option to $.cookie
+               delete options.prefix;
+
+               if ( !options.expires ) {
+                       // Session cookie (null or zero)
+                       // Normalize to absent (undefined) for $.cookie.
+                       delete options.expires;
+               } else if ( typeof options.expires === 'number' ) {
+                       // Lifetime in seconds
+                       date = new Date();
+                       date.setTime( Number( date ) + ( options.expires * 1000 ) );
+                       options.expires = date;
+               }
+
+               if ( value !== null ) {
+                       value = String( value );
+               }
+
+               $.cookie( key, value, options );
+       },
+
+       /**
+        * Get the value of a cookie.
+        *
+        * @param {string} key
+        * @param {string} [prefix=wgCookiePrefix] The prefix of the key. If `prefix` is
+        *   `undefined` or `null`, then `wgCookiePrefix` is used
+        * @param {Mixed} [defaultValue=null]
+        * @return {string|null|Mixed} If the cookie exists, then the value of the
+        *   cookie, otherwise `defaultValue`
+        */
+       get: function ( key, prefix, defaultValue ) {
+               var result;
+
+               if ( prefix === undefined || prefix === null ) {
+                       prefix = defaults.prefix;
+               }
+
+               // Was defaultValue omitted?
+               if ( arguments.length < 3 ) {
+                       defaultValue = null;
+               }
+
+               result = $.cookie( prefix + key );
+
+               return result !== null ? result : defaultValue;
+       }
+};
+
+if ( window.QUnit ) {
+       module.exports = {
+               setDefaults: function ( value ) {
+                       var prev = defaults;
+                       defaults = value;
+                       return prev;
+               }
+       };
+}
index 92e1d04..c2d4835 100644 (file)
@@ -1,13 +1,3 @@
-.feedback-spinner {
-       display: inline-block;
-       zoom: 1;
-       *display: inline; /* IE7 and below */ /* stylelint-disable declaration-block-no-duplicate-properties */
-       /* @embed */
-       background: url( images/spinner.gif );
-       width: 18px;
-       height: 18px;
-}
-
 .mw-feedbackDialog-welcome-message,
 .mw-feedbackDialog-feedback-terms {
        line-height: 1.4;
index 5b73e7c..3ffc496 100644 (file)
                        padded: true
                } );
 
-               this.$spinner = $( '<div>' )
-                       .addClass( 'feedback-spinner' );
-
                // Feedback form
                this.feedbackMessageLabel = new OO.ui.LabelWidget( {
                        classes: [ 'mw-feedbackDialog-welcome-message' ]
diff --git a/resources/src/mediawiki.feedback/images/spinner.gif b/resources/src/mediawiki.feedback/images/spinner.gif
deleted file mode 100644 (file)
index aed0ea4..0000000
Binary files a/resources/src/mediawiki.feedback/images/spinner.gif and /dev/null differ
index 4eed90a..dd50106 100644 (file)
@@ -1,11 +1,11 @@
 @import 'mediawiki.mixins';
 
 #mw-indicator-mw-helplink a {
-       .background-image-svg('images/help.svg', 'images/help.png');
-       background-repeat: no-repeat;
+       .background-image-svg('images/helpNotice.svg', 'images/helpNotice.png');
        background-position: left center;
-       padding-left: 28px;
+       background-repeat: no-repeat;
        display: inline-block;
-       height: 24px;
-       line-height: 24px;
+       height: 20px;
+       padding-left: 25px;
+       line-height: 20px;
 }
diff --git a/resources/src/mediawiki.helplink/images/help.png b/resources/src/mediawiki.helplink/images/help.png
deleted file mode 100644 (file)
index 301e23b..0000000
Binary files a/resources/src/mediawiki.helplink/images/help.png and /dev/null differ
diff --git a/resources/src/mediawiki.helplink/images/help.svg b/resources/src/mediawiki.helplink/images/help.svg
deleted file mode 100644 (file)
index 4fc6a0c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-       <path d="M12.001 2.085a9.914 9.914 0 0 0-9.916 9.916c0 5.476 4.438 9.914 9.916 9.914a9.913 9.913 0 0 0 9.914-9.914c0-5.478-4.438-9.916-9.914-9.916zm.001 18a8.083 8.083 0 1 1 0-16.167 8.083 8.083 0 0 1 0 16.167z"/>
-       <path d="M11.766 6.688c-2.5 0-3.219 2.188-3.219 2.188l1.411.854s.298-.791.901-1.229c.516-.375 1.625-.625 2.219.125.701.885-.17 1.587-1.078 2.719C11.047 12.531 11 15 11 15h1.969s.135-2.318 1.041-3.381c.603-.707 1.443-1.338 1.443-2.494s-1.187-2.437-3.687-2.437zM11 16h2v2h-2z"/>
-</svg>
diff --git a/resources/src/mediawiki.helplink/images/helpNotice.png b/resources/src/mediawiki.helplink/images/helpNotice.png
new file mode 100644 (file)
index 0000000..ef1d713
Binary files /dev/null and b/resources/src/mediawiki.helplink/images/helpNotice.png differ
diff --git a/resources/src/mediawiki.helplink/images/helpNotice.svg b/resources/src/mediawiki.helplink/images/helpNotice.svg
new file mode 100644 (file)
index 0000000..8f0c3dc
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+       <title>
+               help
+       </title>
+       <path d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm1 16H9v-2h2zm2.71-7.6a2.64 2.64 0 0 1-.33.74 3.16 3.16 0 0 1-.48.55l-.54.48c-.21.18-.41.35-.58.52a2.54 2.54 0 0 0-.47.56A2.3 2.3 0 0 0 11 12a3.79 3.79 0 0 0-.11 1H9.08a8.9 8.9 0 0 1 .07-1.25 3.28 3.28 0 0 1 .25-.9 2.79 2.79 0 0 1 .41-.67 4 4 0 0 1 .58-.58c.17-.16.34-.3.51-.44a3 3 0 0 0 .43-.44 1.83 1.83 0 0 0 .3-.55 2 2 0 0 0 .11-.72 2.06 2.06 0 0 0-.17-.86 1.71 1.71 0 0 0-1-.9 1.7 1.7 0 0 0-.5-.1 1.77 1.77 0 0 0-1.53.68 3 3 0 0 0-.5 1.82H6.16a4.74 4.74 0 0 1 .28-1.68 3.56 3.56 0 0 1 .8-1.29 3.88 3.88 0 0 1 1.28-.83A4.59 4.59 0 0 1 10.18 4a4.44 4.44 0 0 1 1.44.23 3.51 3.51 0 0 1 1.15.65 3.08 3.08 0 0 1 .78 1.06 3.54 3.54 0 0 1 .29 1.45 3.39 3.39 0 0 1-.13 1.01z"/>
+</svg>
index 78e9f5f..ecaddd8 100644 (file)
@@ -73,7 +73,7 @@
 
                if ( value === '' ) {
                        this.currentValue = value;
-                       this.setErrors( [] );
+                       this.setErrors( true, [] );
                        return;
                }
 
 
                                that.currentValue = value;
 
-                               if ( info.valid ) {
-                                       that.setErrors( [], forceReplacement );
-                               } else {
-                                       that.setErrors( info.messages, forceReplacement );
-                               }
+                               that.setErrors( info.valid, info.messages, forceReplacement );
                        } ).fail( function () {
                                that.currentValue = null;
-                               that.setErrors( [] );
+                               that.setErrors( true, [] );
                        } );
 
                return currentRequestInternal;
 
        /**
         * Display errors associated with the form element
+        * @param {boolean} valid Whether the input is still valid regardless of the messages
         * @param {Array} errors Error messages. Each error message will be appended to a
         *  `<span>` or `<li>`, as with jQuery.append().
         * @param {boolean} [forceReplacement] Set true to force a visual replacement even
         * @return {mw.htmlform.Checker}
         * @chainable
         */
-       mw.htmlform.Checker.prototype.setErrors = function ( errors, forceReplacement ) {
+       mw.htmlform.Checker.prototype.setErrors = function ( valid, errors, forceReplacement ) {
                var $oldErrorBox, tagName, showFunc, text, replace,
                        $errorBox = this.$errorBox;
 
                                // FIXME: Use CSS transition
                                // eslint-disable-next-line no-jquery/no-slide
                                $errorBox
-                                       .attr( 'class', 'error' )
+                                       .attr( 'class', valid ? 'warning' : 'error' )
                                        .empty()
                                        .append( errors.map( function ( e ) {
                                                return errors.length === 1 ? e : $( '<li>' ).append( e );
                                        } ) )
                                        .slideDown();
                        };
-                       if ( $oldErrorBox !== $errorBox && $oldErrorBox.hasClass( 'error' ) ) {
+                       if (
+                               $oldErrorBox !== $errorBox &&
+                               ( $oldErrorBox.hasClass( 'error' ) || $oldErrorBox.hasClass( 'warning' ) )
+                       ) {
                                // eslint-disable-next-line no-jquery/no-slide
                                $oldErrorBox.slideUp( showFunc );
                        } else {
diff --git a/resources/src/mediawiki.jqueryMsg/.eslintrc.json b/resources/src/mediawiki.jqueryMsg/.eslintrc.json
new file mode 100644 (file)
index 0000000..ad8dbb3
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "parserOptions": {
+               "sourceType": "module"
+       }
+}
index 3b89a74..6416612 100644 (file)
 * @author neilk@wikimedia.org
 * @author mflaschen@wikimedia.org
 */
-( function () {
-       /**
-        * @class mw.jqueryMsg
-        * @singleton
-        */
 
-       var oldParser,
-               slice = Array.prototype.slice,
-               parserDefaults = {
-                       // Magic words and their expansions. Server-side data is added to this below.
-                       magic: {
-                               PAGENAME: mw.config.get( 'wgPageName' ),
-                               PAGENAMEE: mw.util.wikiUrlencode( mw.config.get( 'wgPageName' ) )
-                       },
-                       // Whitelist for allowed HTML elements in wikitext.
-                       // Self-closing tags are not currently supported.
-                       // Filled in with server-side data below
-                       allowedHtmlElements: [],
-                       // Key tag name, value allowed attributes for that tag.
-                       // See Sanitizer::setupAttributeWhitelist
-                       allowedHtmlCommonAttributes: [
-                               // HTML
-                               'id',
-                               'class',
-                               'style',
-                               'lang',
-                               'dir',
-                               'title',
-
-                               // WAI-ARIA
-                               'role'
-                       ],
-
-                       // Attributes allowed for specific elements.
-                       // Key is element name in lower case
-                       // Value is array of allowed attributes for that element
-                       allowedHtmlAttributesByElement: {},
-                       messages: mw.messages,
-                       language: mw.language,
-
-                       // Same meaning as in mediawiki.js.
-                       //
-                       // Only 'text', 'parse', and 'escaped' are supported, and the
-                       // actual escaping for 'escaped' is done by other code (generally
-                       // through mediawiki.js).
-                       //
-                       // However, note that this default only
-                       // applies to direct calls to jqueryMsg. The default for mediawiki.js itself
-                       // is 'text', including when it uses jqueryMsg.
-                       format: 'parse'
-               };
-
-       // Add in server-side data (allowedHtmlElements and magic words)
-       $.extend( true, parserDefaults, require( './parserDefaults.json' ) );
+/**
+ * @class mw.jqueryMsg
+ * @singleton
+ */
+
+var oldParser,
+       slice = Array.prototype.slice,
+       parserDefaults = {
+               // Magic words and their expansions. Server-side data is added to this below.
+               magic: {
+                       PAGENAME: mw.config.get( 'wgPageName' ),
+                       PAGENAMEE: mw.util.wikiUrlencode( mw.config.get( 'wgPageName' ) )
+               },
+               // Whitelist for allowed HTML elements in wikitext.
+               // Self-closing tags are not currently supported.
+               // Filled in with server-side data below
+               allowedHtmlElements: [],
+               // Key tag name, value allowed attributes for that tag.
+               // See Sanitizer::setupAttributeWhitelist
+               allowedHtmlCommonAttributes: [
+                       // HTML
+                       'id',
+                       'class',
+                       'style',
+                       'lang',
+                       'dir',
+                       'title',
+
+                       // WAI-ARIA
+                       'role'
+               ],
+
+               // Attributes allowed for specific elements.
+               // Key is element name in lower case
+               // Value is array of allowed attributes for that element
+               allowedHtmlAttributesByElement: {},
+               messages: mw.messages,
+               language: mw.language,
+
+               // Same meaning as in mediawiki.js.
+               //
+               // Only 'text', 'parse', and 'escaped' are supported, and the
+               // actual escaping for 'escaped' is done by other code (generally
+               // through mediawiki.js).
+               //
+               // However, note that this default only
+               // applies to direct calls to jqueryMsg. The default for mediawiki.js itself
+               // is 'text', including when it uses jqueryMsg.
+               format: 'parse'
+       };
 
-       /**
-        * Wrapper around jQuery append that converts all non-objects to TextNode so append will not
-        * convert what it detects as an htmlString to an element.
-        *
-        * If our own HtmlEmitter jQuery object is given, its children will be unwrapped and appended to
-        * new parent.
-        *
-        * Object elements of children (jQuery, HTMLElement, TextNode, etc.) will be left as is.
-        *
-        * @private
-        * @param {jQuery} $parent Parent node wrapped by jQuery
-        * @param {Object|string|Array} children What to append, with the same possible types as jQuery
-        * @return {jQuery} $parent
-        */
-       function appendWithoutParsing( $parent, children ) {
-               var i, len;
+// Add in server-side data (allowedHtmlElements and magic words)
+$.extend( true, parserDefaults, require( './parserDefaults.json' ) );
+
+/**
+ * Wrapper around jQuery append that converts all non-objects to TextNode so append will not
+ * convert what it detects as an htmlString to an element.
+ *
+ * If our own HtmlEmitter jQuery object is given, its children will be unwrapped and appended to
+ * new parent.
+ *
+ * Object elements of children (jQuery, HTMLElement, TextNode, etc.) will be left as is.
+ *
+ * @private
+ * @param {jQuery} $parent Parent node wrapped by jQuery
+ * @param {Object|string|Array} children What to append, with the same possible types as jQuery
+ * @return {jQuery} $parent
+ */
+function appendWithoutParsing( $parent, children ) {
+       var i, len;
+
+       if ( !Array.isArray( children ) ) {
+               children = [ children ];
+       }
 
-               if ( !Array.isArray( children ) ) {
-                       children = [ children ];
+       for ( i = 0, len = children.length; i < len; i++ ) {
+               if ( typeof children[ i ] !== 'object' ) {
+                       children[ i ] = document.createTextNode( children[ i ] );
                }
-
-               for ( i = 0, len = children.length; i < len; i++ ) {
-                       if ( typeof children[ i ] !== 'object' ) {
-                               children[ i ] = document.createTextNode( children[ i ] );
-                       }
-                       if ( children[ i ] instanceof $ && children[ i ].hasClass( 'mediaWiki_htmlEmitter' ) ) {
-                               children[ i ] = children[ i ].contents();
-                       }
+               if ( children[ i ] instanceof $ && children[ i ].hasClass( 'mediaWiki_htmlEmitter' ) ) {
+                       children[ i ] = children[ i ].contents();
                }
-
-               return $parent.append( children );
        }
 
-       /**
-        * Decodes the main HTML entities, those encoded by mw.html.escape.
-        *
-        * @private
-        * @param {string} encoded Encoded string
-        * @return {string} String with those entities decoded
-        */
-       function decodePrimaryHtmlEntities( encoded ) {
-               return encoded
-                       .replace( /&#039;/g, '\'' )
-                       .replace( /&quot;/g, '"' )
-                       .replace( /&lt;/g, '<' )
-                       .replace( /&gt;/g, '>' )
-                       .replace( /&amp;/g, '&' );
+       return $parent.append( children );
+}
+
+/**
+ * Decodes the main HTML entities, those encoded by mw.html.escape.
+ *
+ * @private
+ * @param {string} encoded Encoded string
+ * @return {string} String with those entities decoded
+ */
+function decodePrimaryHtmlEntities( encoded ) {
+       return encoded
+               .replace( /&#039;/g, '\'' )
+               .replace( /&quot;/g, '"' )
+               .replace( /&lt;/g, '<' )
+               .replace( /&gt;/g, '>' )
+               .replace( /&amp;/g, '&' );
+}
+
+/**
+ * Turn input into a string.
+ *
+ * @private
+ * @param {string|jQuery} input
+ * @return {string} Textual value of input
+ */
+function textify( input ) {
+       if ( input instanceof $ ) {
+               input = input.text();
        }
-
-       /**
-        * Turn input into a string.
-        *
-        * @private
-        * @param {string|jQuery} input
-        * @return {string} Textual value of input
-        */
-       function textify( input ) {
-               if ( input instanceof $ ) {
-                       input = input.text();
+       return String( input );
+}
+
+/**
+ * Given parser options, return a function that parses a key and replacements, returning jQuery object
+ *
+ * Try to parse a key and optional replacements, returning a jQuery object that may be a tree of jQuery nodes.
+ * If there was an error parsing, return the key and the error message (wrapped in jQuery). This should put the error right into
+ * the interface, without causing the page to halt script execution, and it hopefully should be clearer how to fix it.
+ *
+ * @private
+ * @param {Object} options Parser options
+ * @return {Function}
+ * @return {Array} return.args First element is the key, replacements may be in array in 2nd element, or remaining elements.
+ * @return {jQuery} return.return
+ */
+function getFailableParserFn( options ) {
+       return function ( args ) {
+               var fallback,
+                       parser = new mw.jqueryMsg.Parser( options ),
+                       key = args[ 0 ],
+                       argsArray = Array.isArray( args[ 1 ] ) ? args[ 1 ] : slice.call( args, 1 );
+               try {
+                       return parser.parse( key, argsArray );
+               } catch ( e ) {
+                       fallback = parser.settings.messages.get( key );
+                       mw.log.warn( 'mediawiki.jqueryMsg: ' + key + ': ' + e.message );
+                       mw.track( 'mediawiki.jqueryMsg.error', {
+                               messageKey: key,
+                               errorMessage: e.message
+                       } );
+                       return $( '<span>' ).text( fallback );
                }
-               return String( input );
+       };
+}
+
+mw.jqueryMsg = {};
+
+/**
+ * Initialize parser defaults.
+ *
+ * ResourceLoaderJqueryMsgModule calls this to provide default values from
+ * Sanitizer.php for allowed HTML elements. To override this data for individual
+ * parsers, pass the relevant options to mw.jqueryMsg.Parser.
+ *
+ * @private
+ * @param {Object} data New data to extend parser defaults with
+ * @param {boolean} [deep=false] Whether the extend is done recursively (deep)
+ */
+mw.jqueryMsg.setParserDefaults = function ( data, deep ) {
+       if ( deep ) {
+               $.extend( true, parserDefaults, data );
+       } else {
+               $.extend( parserDefaults, data );
        }
-
-       /**
-        * Given parser options, return a function that parses a key and replacements, returning jQuery object
-        *
-        * Try to parse a key and optional replacements, returning a jQuery object that may be a tree of jQuery nodes.
-        * If there was an error parsing, return the key and the error message (wrapped in jQuery). This should put the error right into
-        * the interface, without causing the page to halt script execution, and it hopefully should be clearer how to fix it.
-        *
-        * @private
-        * @param {Object} options Parser options
-        * @return {Function}
-        * @return {Array} return.args First element is the key, replacements may be in array in 2nd element, or remaining elements.
-        * @return {jQuery} return.return
-        */
-       function getFailableParserFn( options ) {
-               return function ( args ) {
-                       var fallback,
-                               parser = new mw.jqueryMsg.Parser( options ),
-                               key = args[ 0 ],
-                               argsArray = Array.isArray( args[ 1 ] ) ? args[ 1 ] : slice.call( args, 1 );
-                       try {
-                               return parser.parse( key, argsArray );
-                       } catch ( e ) {
-                               fallback = parser.settings.messages.get( key );
-                               mw.log.warn( 'mediawiki.jqueryMsg: ' + key + ': ' + e.message );
-                               mw.track( 'mediawiki.jqueryMsg.error', {
-                                       messageKey: key,
-                                       errorMessage: e.message
-                               } );
-                               return $( '<span>' ).text( fallback );
-                       }
-               };
+};
+
+/**
+ * Get current parser defaults.
+ *
+ * Primarily used for the unit test. Returns a copy.
+ *
+ * @private
+ * @return {Object}
+ */
+mw.jqueryMsg.getParserDefaults = function () {
+       return $.extend( {}, parserDefaults );
+};
+
+/**
+ * Returns a function suitable for static use, to construct strings from a message key (and optional replacements).
+ *
+ * Example:
+ *
+ *       var format = mediaWiki.jqueryMsg.getMessageFunction( options );
+ *       $( '#example' ).text( format( 'hello-user', username ) );
+ *
+ * Tthis returns only strings, so it destroys any bindings. If you want to preserve bindings, use the
+ * jQuery plugin version instead. This was originally created to ease migration from `window.gM()`,
+ * from a time when the parser used by `mw.message` was not extendable.
+ *
+ * N.B. replacements are variadic arguments or an array in second parameter. In other words:
+ *    somefunction( a, b, c, d )
+ * is equivalent to
+ *    somefunction( a, [b, c, d] )
+ *
+ * @param {Object} options parser options
+ * @return {Function} Function The message formatter
+ * @return {string} return.key Message key.
+ * @return {Array|Mixed} return.replacements Optional variable replacements (variadically or an array).
+ * @return {string} return.return Rendered HTML.
+ */
+mw.jqueryMsg.getMessageFunction = function ( options ) {
+       var failableParserFn, format;
+
+       if ( options && options.format !== undefined ) {
+               format = options.format;
+       } else {
+               format = parserDefaults.format;
        }
 
-       mw.jqueryMsg = {};
-
-       /**
-        * Initialize parser defaults.
-        *
-        * ResourceLoaderJqueryMsgModule calls this to provide default values from
-        * Sanitizer.php for allowed HTML elements. To override this data for individual
-        * parsers, pass the relevant options to mw.jqueryMsg.Parser.
-        *
-        * @private
-        * @param {Object} data New data to extend parser defaults with
-        * @param {boolean} [deep=false] Whether the extend is done recursively (deep)
-        */
-       mw.jqueryMsg.setParserDefaults = function ( data, deep ) {
-               if ( deep ) {
-                       $.extend( true, parserDefaults, data );
+       return function () {
+               var failableResult;
+               if ( !failableParserFn ) {
+                       failableParserFn = getFailableParserFn( options );
+               }
+               failableResult = failableParserFn( arguments );
+               if ( format === 'text' || format === 'escaped' ) {
+                       return failableResult.text();
                } else {
-                       $.extend( parserDefaults, data );
+                       return failableResult.html();
                }
        };
-
+};
+
+/**
+ * Returns a jQuery plugin which parses the message in the message key, doing replacements optionally, and appends the nodes to
+ * the current selector. Bindings to passed-in jquery elements are preserved. Functions become click handlers for [$1 linktext] links.
+ * e.g.
+ *
+ *        $.fn.msg = mediaWiki.jqueryMsg.getPlugin( options );
+ *        var $userlink = $( '<a>' ).click( function () { alert( "hello!!" ) } );
+ *        $( 'p#headline' ).msg( 'hello-user', $userlink );
+ *
+ * N.B. replacements are variadic arguments or an array in second parameter. In other words:
+ *    somefunction( a, b, c, d )
+ * is equivalent to
+ *    somefunction( a, [b, c, d] )
+ *
+ * We append to 'this', which in a jQuery plugin context will be the selected elements.
+ *
+ * @param {Object} options Parser options
+ * @return {Function} Function suitable for assigning to jQuery plugin, such as jQuery#msg
+ * @return {string} return.key Message key.
+ * @return {Array|Mixed} return.replacements Optional variable replacements (variadically or an array).
+ * @return {jQuery} return.return
+ */
+mw.jqueryMsg.getPlugin = function ( options ) {
+       var failableParserFn;
+
+       return function () {
+               var $target;
+               if ( !failableParserFn ) {
+                       failableParserFn = getFailableParserFn( options );
+               }
+               $target = this.empty();
+               appendWithoutParsing( $target, failableParserFn( arguments ) );
+               return $target;
+       };
+};
+
+/**
+ * The parser itself.
+ * Describes an object, whose primary duty is to .parse() message keys.
+ *
+ * @class
+ * @private
+ * @param {Object} options
+ */
+mw.jqueryMsg.Parser = function ( options ) {
+       this.settings = $.extend( {}, parserDefaults, options );
+       this.settings.onlyCurlyBraceTransform = ( this.settings.format === 'text' || this.settings.format === 'escaped' );
+       this.astCache = {};
+
+       this.emitter = new mw.jqueryMsg.HtmlEmitter( this.settings.language, this.settings.magic );
+};
+// Backwards-compatible alias
+// @deprecated since 1.31
+mw.jqueryMsg.parser = mw.jqueryMsg.Parser;
+
+mw.jqueryMsg.Parser.prototype = {
        /**
-        * Get current parser defaults.
-        *
-        * Primarily used for the unit test. Returns a copy.
+        * Where the magic happens.
+        * Parses a message from the key, and swaps in replacements as necessary, wraps in jQuery
+        * If an error is thrown, returns original key, and logs the error
         *
-        * @private
-        * @return {Object}
+        * @param {string} key Message key.
+        * @param {Array} replacements Variable replacements for $1, $2... $n
+        * @return {jQuery}
         */
-       mw.jqueryMsg.getParserDefaults = function () {
-               return $.extend( {}, parserDefaults );
-       };
+       parse: function ( key, replacements ) {
+               var ast = this.getAst( key, replacements );
+               return this.emitter.emit( ast, replacements );
+       },
 
        /**
-        * Returns a function suitable for static use, to construct strings from a message key (and optional replacements).
-        *
-        * Example:
-        *
-        *       var format = mediaWiki.jqueryMsg.getMessageFunction( options );
-        *       $( '#example' ).text( format( 'hello-user', username ) );
-        *
-        * Tthis returns only strings, so it destroys any bindings. If you want to preserve bindings, use the
-        * jQuery plugin version instead. This was originally created to ease migration from `window.gM()`,
-        * from a time when the parser used by `mw.message` was not extendable.
+        * Fetch the message string associated with a key, return parsed structure. Memoized.
+        * Note that we pass '⧼' + key + '⧽' back for a missing message here.
         *
-        * N.B. replacements are variadic arguments or an array in second parameter. In other words:
-        *    somefunction( a, b, c, d )
-        * is equivalent to
-        *    somefunction( a, [b, c, d] )
-        *
-        * @param {Object} options parser options
-        * @return {Function} Function The message formatter
-        * @return {string} return.key Message key.
-        * @return {Array|Mixed} return.replacements Optional variable replacements (variadically or an array).
-        * @return {string} return.return Rendered HTML.
+        * @param {string} key
+        * @param {Array} replacements Variable replacements for $1, $2... $n
+        * @return {string|Array} string of '⧼key⧽' if message missing, simple string if possible, array of arrays if needs parsing
         */
-       mw.jqueryMsg.getMessageFunction = function ( options ) {
-               var failableParserFn, format;
-
-               if ( options && options.format !== undefined ) {
-                       format = options.format;
-               } else {
-                       format = parserDefaults.format;
-               }
+       getAst: function ( key, replacements ) {
+               var wikiText;
 
-               return function () {
-                       var failableResult;
-                       if ( !failableParserFn ) {
-                               failableParserFn = getFailableParserFn( options );
-                       }
-                       failableResult = failableParserFn( arguments );
-                       if ( format === 'text' || format === 'escaped' ) {
-                               return failableResult.text();
+               if ( !Object.prototype.hasOwnProperty.call( this.astCache, key ) ) {
+                       if ( mw.config.get( 'wgUserLanguage' ) === 'qqx' ) {
+                               wikiText = '(' + key + '$*)';
                        } else {
-                               return failableResult.html();
+                               wikiText = this.settings.messages.get( key );
+                               if ( typeof wikiText !== 'string' ) {
+                                       wikiText = '⧼' + key + '⧽';
+                               }
                        }
-               };
-       };
+                       wikiText = mw.internalDoTransformFormatForQqx( wikiText, replacements );
+                       this.astCache[ key ] = this.wikiTextToAst( wikiText );
+               }
+               return this.astCache[ key ];
+       },
 
        /**
-        * Returns a jQuery plugin which parses the message in the message key, doing replacements optionally, and appends the nodes to
-        * the current selector. Bindings to passed-in jquery elements are preserved. Functions become click handlers for [$1 linktext] links.
-        * e.g.
-        *
-        *        $.fn.msg = mediaWiki.jqueryMsg.getPlugin( options );
-        *        var $userlink = $( '<a>' ).click( function () { alert( "hello!!" ) } );
-        *        $( 'p#headline' ).msg( 'hello-user', $userlink );
-        *
-        * N.B. replacements are variadic arguments or an array in second parameter. In other words:
-        *    somefunction( a, b, c, d )
-        * is equivalent to
-        *    somefunction( a, [b, c, d] )
+        * Parses the input wikiText into an abstract syntax tree, essentially an s-expression.
         *
-        * We append to 'this', which in a jQuery plugin context will be the selected elements.
-        *
-        * @param {Object} options Parser options
-        * @return {Function} Function suitable for assigning to jQuery plugin, such as jQuery#msg
-        * @return {string} return.key Message key.
-        * @return {Array|Mixed} return.replacements Optional variable replacements (variadically or an array).
-        * @return {jQuery} return.return
-        */
-       mw.jqueryMsg.getPlugin = function ( options ) {
-               var failableParserFn;
-
-               return function () {
-                       var $target;
-                       if ( !failableParserFn ) {
-                               failableParserFn = getFailableParserFn( options );
-                       }
-                       $target = this.empty();
-                       appendWithoutParsing( $target, failableParserFn( arguments ) );
-                       return $target;
-               };
-       };
-
-       /**
-        * The parser itself.
-        * Describes an object, whose primary duty is to .parse() message keys.
+        * CAVEAT: This does not parse all wikitext. It could be more efficient, but it's pretty good already.
+        * n.b. We want to move this functionality to the server. Nothing here is required to be on the client.
         *
-        * @class
-        * @private
-        * @param {Object} options
+        * @param {string} input Message string wikitext
+        * @throws Error
+        * @return {Mixed} abstract syntax tree
         */
-       mw.jqueryMsg.Parser = function ( options ) {
-               this.settings = $.extend( {}, parserDefaults, options );
-               this.settings.onlyCurlyBraceTransform = ( this.settings.format === 'text' || this.settings.format === 'escaped' );
-               this.astCache = {};
-
-               this.emitter = new mw.jqueryMsg.HtmlEmitter( this.settings.language, this.settings.magic );
-       };
-       // Backwards-compatible alias
-       // @deprecated since 1.31
-       mw.jqueryMsg.parser = mw.jqueryMsg.Parser;
+       wikiTextToAst: function ( input ) {
+               var pos,
+                       regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, regularLiteralWithSquareBrackets,
+                       doubleQuote, singleQuote, backslash, anyCharacter, asciiAlphabetLiteral,
+                       escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
+                       whitespace, dollar, digits, htmlDoubleQuoteAttributeValue, htmlSingleQuoteAttributeValue,
+                       htmlAttributeEquals, openHtmlStartTag, optionalForwardSlash, openHtmlEndTag, closeHtmlTag,
+                       openExtlink, closeExtlink, wikilinkContents, openWikilink, closeWikilink, templateName, pipe, colon,
+                       templateContents, openTemplate, closeTemplate,
+                       nonWhitespaceExpression, paramExpression, expression, curlyBraceTransformExpression, result,
+                       settings = this.settings,
+                       concat = Array.prototype.concat;
+
+               // Indicates current position in input as we parse through it.
+               // Shared among all parsing functions below.
+               pos = 0;
+
+               // =========================================================
+               // parsing combinators - could be a library on its own
+               // =========================================================
 
-       mw.jqueryMsg.Parser.prototype = {
                /**
-                * Where the magic happens.
-                * Parses a message from the key, and swaps in replacements as necessary, wraps in jQuery
-                * If an error is thrown, returns original key, and logs the error
+                * Try parsers until one works, if none work return null
                 *
-                * @param {string} key Message key.
-                * @param {Array} replacements Variable replacements for $1, $2... $n
-                * @return {jQuery}
+                * @private
+                * @param {Function[]} ps
+                * @return {string|null}
                 */
-               parse: function ( key, replacements ) {
-                       var ast = this.getAst( key, replacements );
-                       return this.emitter.emit( ast, replacements );
-               },
+               function choice( ps ) {
+                       return function () {
+                               var i, result;
+                               for ( i = 0; i < ps.length; i++ ) {
+                                       result = ps[ i ]();
+                                       if ( result !== null ) {
+                                               return result;
+                                       }
+                               }
+                               return null;
+                       };
+               }
 
                /**
-                * Fetch the message string associated with a key, return parsed structure. Memoized.
-                * Note that we pass '⧼' + key + '⧽' back for a missing message here.
+                * Try several ps in a row, all must succeed or return null.
+                * This is the only eager one.
                 *
-                * @param {string} key
-                * @param {Array} replacements Variable replacements for $1, $2... $n
-                * @return {string|Array} string of '⧼key⧽' if message missing, simple string if possible, array of arrays if needs parsing
+                * @private
+                * @param {Function[]} ps
+                * @return {string|null}
                 */
-               getAst: function ( key, replacements ) {
-                       var wikiText;
-
-                       if ( !Object.prototype.hasOwnProperty.call( this.astCache, key ) ) {
-                               if ( mw.config.get( 'wgUserLanguage' ) === 'qqx' ) {
-                                       wikiText = '(' + key + '$*)';
-                               } else {
-                                       wikiText = this.settings.messages.get( key );
-                                       if ( typeof wikiText !== 'string' ) {
-                                               wikiText = '⧼' + key + '⧽';
-                                       }
+               function sequence( ps ) {
+                       var i, res,
+                               originalPos = pos,
+                               result = [];
+                       for ( i = 0; i < ps.length; i++ ) {
+                               res = ps[ i ]();
+                               if ( res === null ) {
+                                       pos = originalPos;
+                                       return null;
                                }
-                               wikiText = mw.internalDoTransformFormatForQqx( wikiText, replacements );
-                               this.astCache[ key ] = this.wikiTextToAst( wikiText );
+                               result.push( res );
                        }
-                       return this.astCache[ key ];
-               },
+                       return result;
+               }
 
                /**
-                * Parses the input wikiText into an abstract syntax tree, essentially an s-expression.
-                *
-                * CAVEAT: This does not parse all wikitext. It could be more efficient, but it's pretty good already.
-                * n.b. We want to move this functionality to the server. Nothing here is required to be on the client.
+                * Run the same parser over and over until it fails.
+                * Must succeed a minimum of n times or return null.
                 *
-                * @param {string} input Message string wikitext
-                * @throws Error
-                * @return {Mixed} abstract syntax tree
+                * @private
+                * @param {number} n
+                * @param {Function} p
+                * @return {string|null}
                 */
-               wikiTextToAst: function ( input ) {
-                       var pos,
-                               regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, regularLiteralWithSquareBrackets,
-                               doubleQuote, singleQuote, backslash, anyCharacter, asciiAlphabetLiteral,
-                               escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
-                               whitespace, dollar, digits, htmlDoubleQuoteAttributeValue, htmlSingleQuoteAttributeValue,
-                               htmlAttributeEquals, openHtmlStartTag, optionalForwardSlash, openHtmlEndTag, closeHtmlTag,
-                               openExtlink, closeExtlink, wikilinkContents, openWikilink, closeWikilink, templateName, pipe, colon,
-                               templateContents, openTemplate, closeTemplate,
-                               nonWhitespaceExpression, paramExpression, expression, curlyBraceTransformExpression, result,
-                               settings = this.settings,
-                               concat = Array.prototype.concat;
-
-                       // Indicates current position in input as we parse through it.
-                       // Shared among all parsing functions below.
-                       pos = 0;
-
-                       // =========================================================
-                       // parsing combinators - could be a library on its own
-                       // =========================================================
-
-                       /**
-                        * Try parsers until one works, if none work return null
-                        *
-                        * @private
-                        * @param {Function[]} ps
-                        * @return {string|null}
-                        */
-                       function choice( ps ) {
-                               return function () {
-                                       var i, result;
-                                       for ( i = 0; i < ps.length; i++ ) {
-                                               result = ps[ i ]();
-                                               if ( result !== null ) {
-                                                       return result;
-                                               }
-                                       }
+               function nOrMore( n, p ) {
+                       return function () {
+                               var originalPos = pos,
+                                       result = [],
+                                       parsed = p();
+                               while ( parsed !== null ) {
+                                       result.push( parsed );
+                                       parsed = p();
+                               }
+                               if ( result.length < n ) {
+                                       pos = originalPos;
                                        return null;
-                               };
-                       }
-
-                       /**
-                        * Try several ps in a row, all must succeed or return null.
-                        * This is the only eager one.
-                        *
-                        * @private
-                        * @param {Function[]} ps
-                        * @return {string|null}
-                        */
-                       function sequence( ps ) {
-                               var i, res,
-                                       originalPos = pos,
-                                       result = [];
-                               for ( i = 0; i < ps.length; i++ ) {
-                                       res = ps[ i ]();
-                                       if ( res === null ) {
-                                               pos = originalPos;
-                                               return null;
-                                       }
-                                       result.push( res );
                                }
                                return result;
-                       }
-
-                       /**
-                        * Run the same parser over and over until it fails.
-                        * Must succeed a minimum of n times or return null.
-                        *
-                        * @private
-                        * @param {number} n
-                        * @param {Function} p
-                        * @return {string|null}
-                        */
-                       function nOrMore( n, p ) {
-                               return function () {
-                                       var originalPos = pos,
-                                               result = [],
-                                               parsed = p();
-                                       while ( parsed !== null ) {
-                                               result.push( parsed );
-                                               parsed = p();
-                                       }
-                                       if ( result.length < n ) {
-                                               pos = originalPos;
-                                               return null;
-                                       }
-                                       return result;
-                               };
-                       }
+                       };
+               }
 
-                       /**
-                        * There is a general pattern -- parse a thing, if that worked, apply transform, otherwise return null.
-                        *
-                        * TODO: But using this as a combinator seems to cause problems when combined with #nOrMore().
-                        * May be some scoping issue
-                        *
-                        * @private
-                        * @param {Function} p
-                        * @param {Function} fn
-                        * @return {string|null}
-                        */
-                       function transform( p, fn ) {
-                               return function () {
-                                       var result = p();
-                                       return result === null ? null : fn( result );
-                               };
-                       }
+               /**
+                * There is a general pattern -- parse a thing, if that worked, apply transform, otherwise return null.
+                *
+                * TODO: But using this as a combinator seems to cause problems when combined with #nOrMore().
+                * May be some scoping issue
+                *
+                * @private
+                * @param {Function} p
+                * @param {Function} fn
+                * @return {string|null}
+                */
+               function transform( p, fn ) {
+                       return function () {
+                               var result = p();
+                               return result === null ? null : fn( result );
+                       };
+               }
 
-                       /**
-                        * Just make parsers out of simpler JS builtin types
-                        *
-                        * @private
-                        * @param {string} s
-                        * @return {Function}
-                        * @return {string} return.return
-                        */
-                       function makeStringParser( s ) {
-                               var len = s.length;
-                               return function () {
-                                       var result = null;
-                                       if ( input.substr( pos, len ) === s ) {
-                                               result = s;
-                                               pos += len;
-                                       }
-                                       return result;
-                               };
-                       }
+               /**
+                * Just make parsers out of simpler JS builtin types
+                *
+                * @private
+                * @param {string} s
+                * @return {Function}
+                * @return {string} return.return
+                */
+               function makeStringParser( s ) {
+                       var len = s.length;
+                       return function () {
+                               var result = null;
+                               if ( input.substr( pos, len ) === s ) {
+                                       result = s;
+                                       pos += len;
+                               }
+                               return result;
+                       };
+               }
 
-                       /**
-                        * Makes a regex parser, given a RegExp object.
-                        * The regex being passed in should start with a ^ to anchor it to the start
-                        * of the string.
-                        *
-                        * @private
-                        * @param {RegExp} regex anchored regex
-                        * @return {Function} function to parse input based on the regex
-                        */
-                       function makeRegexParser( regex ) {
-                               return function () {
-                                       var matches = input.slice( pos ).match( regex );
-                                       if ( matches === null ) {
-                                               return null;
-                                       }
-                                       pos += matches[ 0 ].length;
-                                       return matches[ 0 ];
-                               };
-                       }
+               /**
+                * Makes a regex parser, given a RegExp object.
+                * The regex being passed in should start with a ^ to anchor it to the start
+                * of the string.
+                *
+                * @private
+                * @param {RegExp} regex anchored regex
+                * @return {Function} function to parse input based on the regex
+                */
+               function makeRegexParser( regex ) {
+                       return function () {
+                               var matches = input.slice( pos ).match( regex );
+                               if ( matches === null ) {
+                                       return null;
+                               }
+                               pos += matches[ 0 ].length;
+                               return matches[ 0 ];
+                       };
+               }
 
-                       // ===================================================================
-                       // General patterns above this line -- wikitext specific parsers below
-                       // ===================================================================
-
-                       // Parsing functions follow. All parsing functions work like this:
-                       // They don't accept any arguments.
-                       // Instead, they just operate non destructively on the string 'input'
-                       // As they can consume parts of the string, they advance the shared variable pos,
-                       // and return tokens (or whatever else they want to return).
-                       // some things are defined as closures and other things as ordinary functions
-                       // converting everything to a closure makes it a lot harder to debug... errors pop up
-                       // but some debuggers can't tell you exactly where they come from. Also the mutually
-                       // recursive functions seem not to work in all browsers then. (Tested IE6-7, Opera, Safari, FF)
-                       // This may be because, to save code, memoization was removed
-
-                       /* eslint-disable no-useless-escape */
-                       regularLiteral = makeRegexParser( /^[^{}\[\]$<\\]/ );
-                       regularLiteralWithoutBar = makeRegexParser( /^[^{}\[\]$\\|]/ );
-                       regularLiteralWithoutSpace = makeRegexParser( /^[^{}\[\]$\s]/ );
-                       regularLiteralWithSquareBrackets = makeRegexParser( /^[^{}$\\]/ );
-                       /* eslint-enable no-useless-escape */
-
-                       backslash = makeStringParser( '\\' );
-                       doubleQuote = makeStringParser( '"' );
-                       singleQuote = makeStringParser( '\'' );
-                       anyCharacter = makeRegexParser( /^./ );
-
-                       openHtmlStartTag = makeStringParser( '<' );
-                       optionalForwardSlash = makeRegexParser( /^\/?/ );
-                       openHtmlEndTag = makeStringParser( '</' );
-                       htmlAttributeEquals = makeRegexParser( /^\s*=\s*/ );
-                       closeHtmlTag = makeRegexParser( /^\s*>/ );
-
-                       function escapedLiteral() {
-                               var result = sequence( [
-                                       backslash,
-                                       anyCharacter
-                               ] );
-                               return result === null ? null : result[ 1 ];
-                       }
-                       escapedOrLiteralWithoutSpace = choice( [
-                               escapedLiteral,
-                               regularLiteralWithoutSpace
-                       ] );
-                       escapedOrLiteralWithoutBar = choice( [
-                               escapedLiteral,
-                               regularLiteralWithoutBar
-                       ] );
-                       escapedOrRegularLiteral = choice( [
-                               escapedLiteral,
-                               regularLiteral
+               // ===================================================================
+               // General patterns above this line -- wikitext specific parsers below
+               // ===================================================================
+
+               // Parsing functions follow. All parsing functions work like this:
+               // They don't accept any arguments.
+               // Instead, they just operate non destructively on the string 'input'
+               // As they can consume parts of the string, they advance the shared variable pos,
+               // and return tokens (or whatever else they want to return).
+               // some things are defined as closures and other things as ordinary functions
+               // converting everything to a closure makes it a lot harder to debug... errors pop up
+               // but some debuggers can't tell you exactly where they come from. Also the mutually
+               // recursive functions seem not to work in all browsers then. (Tested IE6-7, Opera, Safari, FF)
+               // This may be because, to save code, memoization was removed
+
+               /* eslint-disable no-useless-escape */
+               regularLiteral = makeRegexParser( /^[^{}\[\]$<\\]/ );
+               regularLiteralWithoutBar = makeRegexParser( /^[^{}\[\]$\\|]/ );
+               regularLiteralWithoutSpace = makeRegexParser( /^[^{}\[\]$\s]/ );
+               regularLiteralWithSquareBrackets = makeRegexParser( /^[^{}$\\]/ );
+               /* eslint-enable no-useless-escape */
+
+               backslash = makeStringParser( '\\' );
+               doubleQuote = makeStringParser( '"' );
+               singleQuote = makeStringParser( '\'' );
+               anyCharacter = makeRegexParser( /^./ );
+
+               openHtmlStartTag = makeStringParser( '<' );
+               optionalForwardSlash = makeRegexParser( /^\/?/ );
+               openHtmlEndTag = makeStringParser( '</' );
+               htmlAttributeEquals = makeRegexParser( /^\s*=\s*/ );
+               closeHtmlTag = makeRegexParser( /^\s*>/ );
+
+               function escapedLiteral() {
+                       var result = sequence( [
+                               backslash,
+                               anyCharacter
                        ] );
-                       // Used to define "literals" without spaces, in space-delimited situations
-                       function literalWithoutSpace() {
-                               var result = nOrMore( 1, escapedOrLiteralWithoutSpace )();
-                               return result === null ? null : result.join( '' );
-                       }
-                       // Used to define "literals" within template parameters. The pipe character is the parameter delimeter, so by default
-                       // it is not a literal in the parameter
-                       function literalWithoutBar() {
-                               var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
-                               return result === null ? null : result.join( '' );
-                       }
+                       return result === null ? null : result[ 1 ];
+               }
+               escapedOrLiteralWithoutSpace = choice( [
+                       escapedLiteral,
+                       regularLiteralWithoutSpace
+               ] );
+               escapedOrLiteralWithoutBar = choice( [
+                       escapedLiteral,
+                       regularLiteralWithoutBar
+               ] );
+               escapedOrRegularLiteral = choice( [
+                       escapedLiteral,
+                       regularLiteral
+               ] );
+               // Used to define "literals" without spaces, in space-delimited situations
+               function literalWithoutSpace() {
+                       var result = nOrMore( 1, escapedOrLiteralWithoutSpace )();
+                       return result === null ? null : result.join( '' );
+               }
+               // Used to define "literals" within template parameters. The pipe character is the parameter delimeter, so by default
+               // it is not a literal in the parameter
+               function literalWithoutBar() {
+                       var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
+                       return result === null ? null : result.join( '' );
+               }
 
-                       function literal() {
-                               var result = nOrMore( 1, escapedOrRegularLiteral )();
-                               return result === null ? null : result.join( '' );
-                       }
+               function literal() {
+                       var result = nOrMore( 1, escapedOrRegularLiteral )();
+                       return result === null ? null : result.join( '' );
+               }
 
-                       function curlyBraceTransformExpressionLiteral() {
-                               var result = nOrMore( 1, regularLiteralWithSquareBrackets )();
-                               return result === null ? null : result.join( '' );
-                       }
+               function curlyBraceTransformExpressionLiteral() {
+                       var result = nOrMore( 1, regularLiteralWithSquareBrackets )();
+                       return result === null ? null : result.join( '' );
+               }
 
-                       asciiAlphabetLiteral = makeRegexParser( /^[A-Za-z]+/ );
-                       htmlDoubleQuoteAttributeValue = makeRegexParser( /^[^"]*/ );
-                       htmlSingleQuoteAttributeValue = makeRegexParser( /^[^']*/ );
+               asciiAlphabetLiteral = makeRegexParser( /^[A-Za-z]+/ );
+               htmlDoubleQuoteAttributeValue = makeRegexParser( /^[^"]*/ );
+               htmlSingleQuoteAttributeValue = makeRegexParser( /^[^']*/ );
 
-                       whitespace = makeRegexParser( /^\s+/ );
-                       dollar = makeStringParser( '$' );
-                       digits = makeRegexParser( /^\d+/ );
+               whitespace = makeRegexParser( /^\s+/ );
+               dollar = makeStringParser( '$' );
+               digits = makeRegexParser( /^\d+/ );
 
-                       function replacement() {
-                               var result = sequence( [
-                                       dollar,
-                                       digits
-                               ] );
-                               if ( result === null ) {
-                                       return null;
-                               }
-                               return [ 'REPLACE', parseInt( result[ 1 ], 10 ) - 1 ];
-                       }
-                       openExtlink = makeStringParser( '[' );
-                       closeExtlink = makeStringParser( ']' );
-                       // this extlink MUST have inner contents, e.g. [foo] not allowed; [foo bar] [foo <i>bar</i>], etc. are allowed
-                       function extlink() {
-                               var result, parsedResult, target;
-                               result = null;
-                               parsedResult = sequence( [
-                                       openExtlink,
-                                       nOrMore( 1, nonWhitespaceExpression ),
-                                       whitespace,
-                                       nOrMore( 1, expression ),
-                                       closeExtlink
-                               ] );
-                               if ( parsedResult !== null ) {
-                                       // When the entire link target is a single parameter, we can't use CONCAT, as we allow
-                                       // passing fancy parameters (like a whole jQuery object or a function) to use for the
-                                       // link. Check only if it's a single match, since we can either do CONCAT or not for
-                                       // singles with the same effect.
-                                       target = parsedResult[ 1 ].length === 1 ?
-                                               parsedResult[ 1 ][ 0 ] :
-                                               [ 'CONCAT' ].concat( parsedResult[ 1 ] );
-                                       result = [
-                                               'EXTLINK',
-                                               target,
-                                               [ 'CONCAT' ].concat( parsedResult[ 3 ] )
-                                       ];
-                               }
-                               return result;
-                       }
-                       openWikilink = makeStringParser( '[[' );
-                       closeWikilink = makeStringParser( ']]' );
-                       pipe = makeStringParser( '|' );
-
-                       function template() {
-                               var result = sequence( [
-                                       openTemplate,
-                                       templateContents,
-                                       closeTemplate
-                               ] );
-                               return result === null ? null : result[ 1 ];
+               function replacement() {
+                       var result = sequence( [
+                               dollar,
+                               digits
+                       ] );
+                       if ( result === null ) {
+                               return null;
                        }
-
-                       function pipedWikilink() {
-                               var result = sequence( [
-                                       nOrMore( 1, paramExpression ),
-                                       pipe,
-                                       nOrMore( 1, expression )
-                               ] );
-                               return result === null ? null : [
-                                       [ 'CONCAT' ].concat( result[ 0 ] ),
-                                       [ 'CONCAT' ].concat( result[ 2 ] )
+                       return [ 'REPLACE', parseInt( result[ 1 ], 10 ) - 1 ];
+               }
+               openExtlink = makeStringParser( '[' );
+               closeExtlink = makeStringParser( ']' );
+               // this extlink MUST have inner contents, e.g. [foo] not allowed; [foo bar] [foo <i>bar</i>], etc. are allowed
+               function extlink() {
+                       var result, parsedResult, target;
+                       result = null;
+                       parsedResult = sequence( [
+                               openExtlink,
+                               nOrMore( 1, nonWhitespaceExpression ),
+                               whitespace,
+                               nOrMore( 1, expression ),
+                               closeExtlink
+                       ] );
+                       if ( parsedResult !== null ) {
+                               // When the entire link target is a single parameter, we can't use CONCAT, as we allow
+                               // passing fancy parameters (like a whole jQuery object or a function) to use for the
+                               // link. Check only if it's a single match, since we can either do CONCAT or not for
+                               // singles with the same effect.
+                               target = parsedResult[ 1 ].length === 1 ?
+                                       parsedResult[ 1 ][ 0 ] :
+                                       [ 'CONCAT' ].concat( parsedResult[ 1 ] );
+                               result = [
+                                       'EXTLINK',
+                                       target,
+                                       [ 'CONCAT' ].concat( parsedResult[ 3 ] )
                                ];
                        }
+                       return result;
+               }
+               openWikilink = makeStringParser( '[[' );
+               closeWikilink = makeStringParser( ']]' );
+               pipe = makeStringParser( '|' );
+
+               function template() {
+                       var result = sequence( [
+                               openTemplate,
+                               templateContents,
+                               closeTemplate
+                       ] );
+                       return result === null ? null : result[ 1 ];
+               }
 
-                       function unpipedWikilink() {
-                               var result = sequence( [
-                                       nOrMore( 1, paramExpression )
-                               ] );
-                               return result === null ? null : [
-                                       [ 'CONCAT' ].concat( result[ 0 ] )
-                               ];
-                       }
+               function pipedWikilink() {
+                       var result = sequence( [
+                               nOrMore( 1, paramExpression ),
+                               pipe,
+                               nOrMore( 1, expression )
+                       ] );
+                       return result === null ? null : [
+                               [ 'CONCAT' ].concat( result[ 0 ] ),
+                               [ 'CONCAT' ].concat( result[ 2 ] )
+                       ];
+               }
 
-                       wikilinkContents = choice( [
-                               pipedWikilink,
-                               unpipedWikilink
+               function unpipedWikilink() {
+                       var result = sequence( [
+                               nOrMore( 1, paramExpression )
                        ] );
+                       return result === null ? null : [
+                               [ 'CONCAT' ].concat( result[ 0 ] )
+                       ];
+               }
 
-                       function wikilink() {
-                               var result, parsedResult, parsedLinkContents;
-                               result = null;
+               wikilinkContents = choice( [
+                       pipedWikilink,
+                       unpipedWikilink
+               ] );
 
-                               parsedResult = sequence( [
-                                       openWikilink,
-                                       wikilinkContents,
-                                       closeWikilink
-                               ] );
-                               if ( parsedResult !== null ) {
-                                       parsedLinkContents = parsedResult[ 1 ];
-                                       result = [ 'WIKILINK' ].concat( parsedLinkContents );
-                               }
-                               return result;
-                       }
+               function wikilink() {
+                       var result, parsedResult, parsedLinkContents;
+                       result = null;
 
-                       // TODO: Support data- if appropriate
-                       function doubleQuotedHtmlAttributeValue() {
-                               var parsedResult = sequence( [
-                                       doubleQuote,
-                                       htmlDoubleQuoteAttributeValue,
-                                       doubleQuote
-                               ] );
-                               return parsedResult === null ? null : parsedResult[ 1 ];
+                       parsedResult = sequence( [
+                               openWikilink,
+                               wikilinkContents,
+                               closeWikilink
+                       ] );
+                       if ( parsedResult !== null ) {
+                               parsedLinkContents = parsedResult[ 1 ];
+                               result = [ 'WIKILINK' ].concat( parsedLinkContents );
                        }
+                       return result;
+               }
 
-                       function singleQuotedHtmlAttributeValue() {
-                               var parsedResult = sequence( [
-                                       singleQuote,
-                                       htmlSingleQuoteAttributeValue,
-                                       singleQuote
-                               ] );
-                               return parsedResult === null ? null : parsedResult[ 1 ];
-                       }
+               // TODO: Support data- if appropriate
+               function doubleQuotedHtmlAttributeValue() {
+                       var parsedResult = sequence( [
+                               doubleQuote,
+                               htmlDoubleQuoteAttributeValue,
+                               doubleQuote
+                       ] );
+                       return parsedResult === null ? null : parsedResult[ 1 ];
+               }
 
-                       function htmlAttribute() {
-                               var parsedResult = sequence( [
-                                       whitespace,
-                                       asciiAlphabetLiteral,
-                                       htmlAttributeEquals,
-                                       choice( [
-                                               doubleQuotedHtmlAttributeValue,
-                                               singleQuotedHtmlAttributeValue
-                                       ] )
-                               ] );
-                               return parsedResult === null ? null : [ parsedResult[ 1 ], parsedResult[ 3 ] ];
-                       }
+               function singleQuotedHtmlAttributeValue() {
+                       var parsedResult = sequence( [
+                               singleQuote,
+                               htmlSingleQuoteAttributeValue,
+                               singleQuote
+                       ] );
+                       return parsedResult === null ? null : parsedResult[ 1 ];
+               }
 
-                       /**
-                        * Checks if HTML is allowed
-                        *
-                        * @param {string} startTagName HTML start tag name
-                        * @param {string} endTagName HTML start tag name
-                        * @param {Object} attributes array of consecutive key value pairs,
-                        *  with index 2 * n being a name and 2 * n + 1 the associated value
-                        * @return {boolean} true if this is HTML is allowed, false otherwise
-                        */
-                       function isAllowedHtml( startTagName, endTagName, attributes ) {
-                               var i, len, attributeName;
-
-                               startTagName = startTagName.toLowerCase();
-                               endTagName = endTagName.toLowerCase();
-                               if ( startTagName !== endTagName || settings.allowedHtmlElements.indexOf( startTagName ) === -1 ) {
-                                       return false;
-                               }
+               function htmlAttribute() {
+                       var parsedResult = sequence( [
+                               whitespace,
+                               asciiAlphabetLiteral,
+                               htmlAttributeEquals,
+                               choice( [
+                                       doubleQuotedHtmlAttributeValue,
+                                       singleQuotedHtmlAttributeValue
+                               ] )
+                       ] );
+                       return parsedResult === null ? null : [ parsedResult[ 1 ], parsedResult[ 3 ] ];
+               }
 
-                               for ( i = 0, len = attributes.length; i < len; i += 2 ) {
-                                       attributeName = attributes[ i ];
-                                       if ( settings.allowedHtmlCommonAttributes.indexOf( attributeName ) === -1 &&
-                                               ( settings.allowedHtmlAttributesByElement[ startTagName ] || [] ).indexOf( attributeName ) === -1 ) {
-                                               return false;
-                                       }
-                               }
+               /**
+                * Checks if HTML is allowed
+                *
+                * @param {string} startTagName HTML start tag name
+                * @param {string} endTagName HTML start tag name
+                * @param {Object} attributes array of consecutive key value pairs,
+                *  with index 2 * n being a name and 2 * n + 1 the associated value
+                * @return {boolean} true if this is HTML is allowed, false otherwise
+                */
+               function isAllowedHtml( startTagName, endTagName, attributes ) {
+                       var i, len, attributeName;
 
-                               return true;
+                       startTagName = startTagName.toLowerCase();
+                       endTagName = endTagName.toLowerCase();
+                       if ( startTagName !== endTagName || settings.allowedHtmlElements.indexOf( startTagName ) === -1 ) {
+                               return false;
                        }
 
-                       function htmlAttributes() {
-                               var parsedResult = nOrMore( 0, htmlAttribute )();
-                               // Un-nest attributes array due to structure of jQueryMsg operations (see emit).
-                               return concat.apply( [ 'HTMLATTRIBUTES' ], parsedResult );
+                       for ( i = 0, len = attributes.length; i < len; i += 2 ) {
+                               attributeName = attributes[ i ];
+                               if ( settings.allowedHtmlCommonAttributes.indexOf( attributeName ) === -1 &&
+                                       ( settings.allowedHtmlAttributesByElement[ startTagName ] || [] ).indexOf( attributeName ) === -1 ) {
+                                       return false;
+                               }
                        }
 
-                       // Subset of allowed HTML markup.
-                       // Most elements and many attributes allowed on the server are not supported yet.
-                       function html() {
-                               var parsedOpenTagResult, parsedHtmlContents, parsedCloseTagResult,
-                                       wrappedAttributes, attributes, startTagName, endTagName, startOpenTagPos,
-                                       startCloseTagPos, endOpenTagPos, endCloseTagPos,
-                                       result = null;
-
-                               // Break into three sequence calls.  That should allow accurate reconstruction of the original HTML, and requiring an exact tag name match.
-                               // 1. open through closeHtmlTag
-                               // 2. expression
-                               // 3. openHtmlEnd through close
-                               // This will allow recording the positions to reconstruct if HTML is to be treated as text.
-
-                               startOpenTagPos = pos;
-                               parsedOpenTagResult = sequence( [
-                                       openHtmlStartTag,
-                                       asciiAlphabetLiteral,
-                                       htmlAttributes,
-                                       optionalForwardSlash,
-                                       closeHtmlTag
-                               ] );
+                       return true;
+               }
 
-                               if ( parsedOpenTagResult === null ) {
-                                       return null;
-                               }
+               function htmlAttributes() {
+                       var parsedResult = nOrMore( 0, htmlAttribute )();
+                       // Un-nest attributes array due to structure of jQueryMsg operations (see emit).
+                       return concat.apply( [ 'HTMLATTRIBUTES' ], parsedResult );
+               }
 
-                               endOpenTagPos = pos;
-                               startTagName = parsedOpenTagResult[ 1 ];
+               // Subset of allowed HTML markup.
+               // Most elements and many attributes allowed on the server are not supported yet.
+               function html() {
+                       var parsedOpenTagResult, parsedHtmlContents, parsedCloseTagResult,
+                               wrappedAttributes, attributes, startTagName, endTagName, startOpenTagPos,
+                               startCloseTagPos, endOpenTagPos, endCloseTagPos,
+                               result = null;
 
-                               parsedHtmlContents = nOrMore( 0, expression )();
+                       // Break into three sequence calls.  That should allow accurate reconstruction of the original HTML, and requiring an exact tag name match.
+                       // 1. open through closeHtmlTag
+                       // 2. expression
+                       // 3. openHtmlEnd through close
+                       // This will allow recording the positions to reconstruct if HTML is to be treated as text.
+
+                       startOpenTagPos = pos;
+                       parsedOpenTagResult = sequence( [
+                               openHtmlStartTag,
+                               asciiAlphabetLiteral,
+                               htmlAttributes,
+                               optionalForwardSlash,
+                               closeHtmlTag
+                       ] );
 
-                               startCloseTagPos = pos;
-                               parsedCloseTagResult = sequence( [
-                                       openHtmlEndTag,
-                                       asciiAlphabetLiteral,
-                                       closeHtmlTag
-                               ] );
+                       if ( parsedOpenTagResult === null ) {
+                               return null;
+                       }
 
-                               if ( parsedCloseTagResult === null ) {
-                                       // Closing tag failed.  Return the start tag and contents.
-                                       return [ 'CONCAT', input.slice( startOpenTagPos, endOpenTagPos ) ]
-                                               .concat( parsedHtmlContents );
-                               }
+                       endOpenTagPos = pos;
+                       startTagName = parsedOpenTagResult[ 1 ];
 
-                               endCloseTagPos = pos;
-                               endTagName = parsedCloseTagResult[ 1 ];
-                               wrappedAttributes = parsedOpenTagResult[ 2 ];
-                               attributes = wrappedAttributes.slice( 1 );
-                               if ( isAllowedHtml( startTagName, endTagName, attributes ) ) {
-                                       result = [ 'HTMLELEMENT', startTagName, wrappedAttributes ]
-                                               .concat( parsedHtmlContents );
-                               } else {
-                                       // HTML is not allowed, so contents will remain how
-                                       // it was, while HTML markup at this level will be
-                                       // treated as text
-                                       // E.g. assuming script tags are not allowed:
-                                       //
-                                       // <script>[[Foo|bar]]</script>
-                                       //
-                                       // results in '&lt;script&gt;' and '&lt;/script&gt;'
-                                       // (not treated as an HTML tag), surrounding a fully
-                                       // parsed HTML link.
-                                       //
-                                       // Concatenate everything from the tag, flattening the contents.
-                                       result = [ 'CONCAT', input.slice( startOpenTagPos, endOpenTagPos ) ]
-                                               .concat( parsedHtmlContents, input.slice( startCloseTagPos, endCloseTagPos ) );
-                               }
+                       parsedHtmlContents = nOrMore( 0, expression )();
 
-                               return result;
+                       startCloseTagPos = pos;
+                       parsedCloseTagResult = sequence( [
+                               openHtmlEndTag,
+                               asciiAlphabetLiteral,
+                               closeHtmlTag
+                       ] );
+
+                       if ( parsedCloseTagResult === null ) {
+                               // Closing tag failed.  Return the start tag and contents.
+                               return [ 'CONCAT', input.slice( startOpenTagPos, endOpenTagPos ) ]
+                                       .concat( parsedHtmlContents );
                        }
 
-                       // <nowiki>...</nowiki> tag. The tags are stripped and the contents are returned unparsed.
-                       function nowiki() {
-                               var parsedResult, plainText,
-                                       result = null;
+                       endCloseTagPos = pos;
+                       endTagName = parsedCloseTagResult[ 1 ];
+                       wrappedAttributes = parsedOpenTagResult[ 2 ];
+                       attributes = wrappedAttributes.slice( 1 );
+                       if ( isAllowedHtml( startTagName, endTagName, attributes ) ) {
+                               result = [ 'HTMLELEMENT', startTagName, wrappedAttributes ]
+                                       .concat( parsedHtmlContents );
+                       } else {
+                               // HTML is not allowed, so contents will remain how
+                               // it was, while HTML markup at this level will be
+                               // treated as text
+                               // E.g. assuming script tags are not allowed:
+                               //
+                               // <script>[[Foo|bar]]</script>
+                               //
+                               // results in '&lt;script&gt;' and '&lt;/script&gt;'
+                               // (not treated as an HTML tag), surrounding a fully
+                               // parsed HTML link.
+                               //
+                               // Concatenate everything from the tag, flattening the contents.
+                               result = [ 'CONCAT', input.slice( startOpenTagPos, endOpenTagPos ) ]
+                                       .concat( parsedHtmlContents, input.slice( startCloseTagPos, endCloseTagPos ) );
+                       }
 
-                               parsedResult = sequence( [
-                                       makeStringParser( '<nowiki>' ),
-                                       // We use a greedy non-backtracking parser, so we must ensure here that we don't take too much
-                                       makeRegexParser( /^.*?(?=<\/nowiki>)/ ),
-                                       makeStringParser( '</nowiki>' )
-                               ] );
-                               if ( parsedResult !== null ) {
-                                       plainText = parsedResult[ 1 ];
-                                       result = [ 'CONCAT' ].concat( plainText );
-                               }
+                       return result;
+               }
 
-                               return result;
+               // <nowiki>...</nowiki> tag. The tags are stripped and the contents are returned unparsed.
+               function nowiki() {
+                       var parsedResult, plainText,
+                               result = null;
+
+                       parsedResult = sequence( [
+                               makeStringParser( '<nowiki>' ),
+                               // We use a greedy non-backtracking parser, so we must ensure here that we don't take too much
+                               makeRegexParser( /^.*?(?=<\/nowiki>)/ ),
+                               makeStringParser( '</nowiki>' )
+                       ] );
+                       if ( parsedResult !== null ) {
+                               plainText = parsedResult[ 1 ];
+                               result = [ 'CONCAT' ].concat( plainText );
                        }
 
-                       templateName = transform(
-                               // see $wgLegalTitleChars
-                               // not allowing : due to the need to catch "PLURAL:$1"
-                               makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ),
-                               function ( result ) { return result.toString(); }
-                       );
-                       function templateParam() {
-                               var expr, result;
-                               result = sequence( [
-                                       pipe,
-                                       nOrMore( 0, paramExpression )
-                               ] );
-                               if ( result === null ) {
-                                       return null;
-                               }
-                               expr = result[ 1 ];
-                               // use a CONCAT operator if there are multiple nodes, otherwise return the first node, raw.
-                               return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[ 0 ];
+                       return result;
+               }
+
+               templateName = transform(
+                       // see $wgLegalTitleChars
+                       // not allowing : due to the need to catch "PLURAL:$1"
+                       makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ),
+                       function ( result ) { return result.toString(); }
+               );
+               function templateParam() {
+                       var expr, result;
+                       result = sequence( [
+                               pipe,
+                               nOrMore( 0, paramExpression )
+                       ] );
+                       if ( result === null ) {
+                               return null;
                        }
+                       expr = result[ 1 ];
+                       // use a CONCAT operator if there are multiple nodes, otherwise return the first node, raw.
+                       return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[ 0 ];
+               }
 
-                       function templateWithReplacement() {
-                               var result = sequence( [
-                                       templateName,
-                                       colon,
-                                       replacement
+               function templateWithReplacement() {
+                       var result = sequence( [
+                               templateName,
+                               colon,
+                               replacement
+                       ] );
+                       return result === null ? null : [ result[ 0 ], result[ 2 ] ];
+               }
+               function templateWithOutReplacement() {
+                       var result = sequence( [
+                               templateName,
+                               colon,
+                               paramExpression
+                       ] );
+                       return result === null ? null : [ result[ 0 ], result[ 2 ] ];
+               }
+               function templateWithOutFirstParameter() {
+                       var result = sequence( [
+                               templateName,
+                               colon
+                       ] );
+                       return result === null ? null : [ result[ 0 ], '' ];
+               }
+               colon = makeStringParser( ':' );
+               templateContents = choice( [
+                       function () {
+                               var res = sequence( [
+                                       // templates can have placeholders for dynamic replacement eg: {{PLURAL:$1|one car|$1 cars}}
+                                       // or no placeholders eg: {{GRAMMAR:genitive|{{SITENAME}}}
+                                       choice( [ templateWithReplacement, templateWithOutReplacement, templateWithOutFirstParameter ] ),
+                                       nOrMore( 0, templateParam )
                                ] );
-                               return result === null ? null : [ result[ 0 ], result[ 2 ] ];
-                       }
-                       function templateWithOutReplacement() {
-                               var result = sequence( [
+                               return res === null ? null : res[ 0 ].concat( res[ 1 ] );
+                       },
+                       function () {
+                               var res = sequence( [
                                        templateName,
-                                       colon,
-                                       paramExpression
+                                       nOrMore( 0, templateParam )
                                ] );
-                               return result === null ? null : [ result[ 0 ], result[ 2 ] ];
+                               if ( res === null ) {
+                                       return null;
+                               }
+                               return [ res[ 0 ] ].concat( res[ 1 ] );
                        }
-                       function templateWithOutFirstParameter() {
-                               var result = sequence( [
-                                       templateName,
-                                       colon
-                               ] );
-                               return result === null ? null : [ result[ 0 ], '' ];
+               ] );
+               openTemplate = makeStringParser( '{{' );
+               closeTemplate = makeStringParser( '}}' );
+               nonWhitespaceExpression = choice( [
+                       template,
+                       wikilink,
+                       extlink,
+                       replacement,
+                       literalWithoutSpace
+               ] );
+               paramExpression = choice( [
+                       template,
+                       wikilink,
+                       extlink,
+                       replacement,
+                       literalWithoutBar
+               ] );
+
+               expression = choice( [
+                       template,
+                       wikilink,
+                       extlink,
+                       replacement,
+                       nowiki,
+                       html,
+                       literal
+               ] );
+
+               // Used when only {{-transformation is wanted, for 'text'
+               // or 'escaped' formats
+               curlyBraceTransformExpression = choice( [
+                       template,
+                       replacement,
+                       curlyBraceTransformExpressionLiteral
+               ] );
+
+               /**
+                * Starts the parse
+                *
+                * @param {Function} rootExpression Root parse function
+                * @return {Array|null}
+                */
+               function start( rootExpression ) {
+                       var result = nOrMore( 0, rootExpression )();
+                       if ( result === null ) {
+                               return null;
                        }
-                       colon = makeStringParser( ':' );
-                       templateContents = choice( [
-                               function () {
-                                       var res = sequence( [
-                                               // templates can have placeholders for dynamic replacement eg: {{PLURAL:$1|one car|$1 cars}}
-                                               // or no placeholders eg: {{GRAMMAR:genitive|{{SITENAME}}}
-                                               choice( [ templateWithReplacement, templateWithOutReplacement, templateWithOutFirstParameter ] ),
-                                               nOrMore( 0, templateParam )
-                                       ] );
-                                       return res === null ? null : res[ 0 ].concat( res[ 1 ] );
-                               },
-                               function () {
-                                       var res = sequence( [
-                                               templateName,
-                                               nOrMore( 0, templateParam )
-                                       ] );
-                                       if ( res === null ) {
-                                               return null;
-                                       }
-                                       return [ res[ 0 ] ].concat( res[ 1 ] );
-                               }
-                       ] );
-                       openTemplate = makeStringParser( '{{' );
-                       closeTemplate = makeStringParser( '}}' );
-                       nonWhitespaceExpression = choice( [
-                               template,
-                               wikilink,
-                               extlink,
-                               replacement,
-                               literalWithoutSpace
-                       ] );
-                       paramExpression = choice( [
-                               template,
-                               wikilink,
-                               extlink,
-                               replacement,
-                               literalWithoutBar
-                       ] );
+                       return [ 'CONCAT' ].concat( result );
+               }
+               // everything above this point is supposed to be stateless/static, but
+               // I am deferring the work of turning it into prototypes & objects. It's quite fast enough
+               // finally let's do some actual work...
 
-                       expression = choice( [
-                               template,
-                               wikilink,
-                               extlink,
-                               replacement,
-                               nowiki,
-                               html,
-                               literal
-                       ] );
+               result = start( this.settings.onlyCurlyBraceTransform ? curlyBraceTransformExpression : expression );
 
-                       // Used when only {{-transformation is wanted, for 'text'
-                       // or 'escaped' formats
-                       curlyBraceTransformExpression = choice( [
-                               template,
-                               replacement,
-                               curlyBraceTransformExpressionLiteral
-                       ] );
+               /*
+                * For success, the p must have gotten to the end of the input
+                * and returned a non-null.
+                * n.b. This is part of language infrastructure, so we do not throw an internationalizable message.
+                */
+               if ( result === null || pos !== input.length ) {
+                       throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + input );
+               }
+               return result;
+       }
 
-                       /**
-                        * Starts the parse
-                        *
-                        * @param {Function} rootExpression Root parse function
-                        * @return {Array|null}
-                        */
-                       function start( rootExpression ) {
-                               var result = nOrMore( 0, rootExpression )();
-                               if ( result === null ) {
-                                       return null;
+};
+
+/**
+ * Class that primarily exists to emit HTML from parser ASTs.
+ *
+ * @private
+ * @class
+ * @param {Object} language
+ * @param {Object} magic
+ */
+mw.jqueryMsg.HtmlEmitter = function ( language, magic ) {
+       var jmsg = this;
+       this.language = language;
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( magic, function ( key, val ) {
+               jmsg[ key.toLowerCase() ] = function () {
+                       return val;
+               };
+       } );
+
+       /**
+        * (We put this method definition here, and not in prototype, to make sure it's not overwritten by any magic.)
+        * Walk entire node structure, applying replacements and template functions when appropriate
+        *
+        * @param {Mixed} node Abstract syntax tree (top node or subnode)
+        * @param {Array} replacements for $1, $2, ... $n
+        * @return {Mixed} single-string node or array of nodes suitable for jQuery appending
+        */
+       this.emit = function ( node, replacements ) {
+               var ret, subnodes, operation,
+                       jmsg = this;
+               switch ( typeof node ) {
+                       case 'string':
+                       case 'number':
+                               ret = node;
+                               break;
+                       // typeof returns object for arrays
+                       case 'object':
+                               // node is an array of nodes
+                               // eslint-disable-next-line no-jquery/no-map-util
+                               subnodes = $.map( node.slice( 1 ), function ( n ) {
+                                       return jmsg.emit( n, replacements );
+                               } );
+                               operation = node[ 0 ].toLowerCase();
+                               if ( typeof jmsg[ operation ] === 'function' ) {
+                                       ret = jmsg[ operation ]( subnodes, replacements );
+                               } else {
+                                       throw new Error( 'Unknown operation "' + operation + '"' );
                                }
-                               return [ 'CONCAT' ].concat( result );
-                       }
-                       // everything above this point is supposed to be stateless/static, but
-                       // I am deferring the work of turning it into prototypes & objects. It's quite fast enough
-                       // finally let's do some actual work...
-
-                       result = start( this.settings.onlyCurlyBraceTransform ? curlyBraceTransformExpression : expression );
-
-                       /*
-                        * For success, the p must have gotten to the end of the input
-                        * and returned a non-null.
-                        * n.b. This is part of language infrastructure, so we do not throw an internationalizable message.
-                        */
-                       if ( result === null || pos !== input.length ) {
-                               throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + input );
-                       }
-                       return result;
+                               break;
+                       case 'undefined':
+                               // Parsing the empty string (as an entire expression, or as a paramExpression in a template) results in undefined
+                               // Perhaps a more clever parser can detect this, and return the empty string? Or is that useful information?
+                               // The logical thing is probably to return the empty string here when we encounter undefined.
+                               ret = '';
+                               break;
+                       default:
+                               throw new Error( 'Unexpected type in AST: ' + typeof node );
                }
-
+               return ret;
        };
-
+};
+
+// For everything in input that follows double-open-curly braces, there should be an equivalent parser
+// function. For instance {{PLURAL ... }} will be processed by 'plural'.
+// If you have 'magic words' then configure the parser to have them upon creation.
+//
+// An emitter method takes the parent node, the array of subnodes and the array of replacements (the values that $1, $2... should translate to).
+// Note: all such functions must be pure, with the exception of referring to other pure functions via this.language (convertPlural and so on)
+mw.jqueryMsg.HtmlEmitter.prototype = {
        /**
-        * Class that primarily exists to emit HTML from parser ASTs.
+        * Parsing has been applied depth-first we can assume that all nodes here are single nodes
+        * Must return a single node to parents -- a jQuery with synthetic span
+        * However, unwrap any other synthetic spans in our children and pass them upwards
         *
-        * @private
-        * @class
-        * @param {Object} language
-        * @param {Object} magic
+        * @param {Mixed[]} nodes Some single nodes, some arrays of nodes
+        * @return {jQuery}
         */
-       mw.jqueryMsg.HtmlEmitter = function ( language, magic ) {
-               var jmsg = this;
-               this.language = language;
+       concat: function ( nodes ) {
+               var $span = $( '<span>' ).addClass( 'mediaWiki_htmlEmitter' );
                // eslint-disable-next-line no-jquery/no-each-util
-               $.each( magic, function ( key, val ) {
-                       jmsg[ key.toLowerCase() ] = function () {
-                               return val;
-                       };
+               $.each( nodes, function ( i, node ) {
+                       // Let jQuery append nodes, arrays of nodes and jQuery objects
+                       // other things (strings, numbers, ..) are appended as text nodes (not as HTML strings)
+                       appendWithoutParsing( $span, node );
                } );
+               return $span;
+       },
 
-               /**
-                * (We put this method definition here, and not in prototype, to make sure it's not overwritten by any magic.)
-                * Walk entire node structure, applying replacements and template functions when appropriate
-                *
-                * @param {Mixed} node Abstract syntax tree (top node or subnode)
-                * @param {Array} replacements for $1, $2, ... $n
-                * @return {Mixed} single-string node or array of nodes suitable for jQuery appending
-                */
-               this.emit = function ( node, replacements ) {
-                       var ret, subnodes, operation,
-                               jmsg = this;
-                       switch ( typeof node ) {
-                               case 'string':
-                               case 'number':
-                                       ret = node;
-                                       break;
-                               // typeof returns object for arrays
-                               case 'object':
-                                       // node is an array of nodes
-                                       // eslint-disable-next-line no-jquery/no-map-util
-                                       subnodes = $.map( node.slice( 1 ), function ( n ) {
-                                               return jmsg.emit( n, replacements );
-                                       } );
-                                       operation = node[ 0 ].toLowerCase();
-                                       if ( typeof jmsg[ operation ] === 'function' ) {
-                                               ret = jmsg[ operation ]( subnodes, replacements );
-                                       } else {
-                                               throw new Error( 'Unknown operation "' + operation + '"' );
-                                       }
-                                       break;
-                               case 'undefined':
-                                       // Parsing the empty string (as an entire expression, or as a paramExpression in a template) results in undefined
-                                       // Perhaps a more clever parser can detect this, and return the empty string? Or is that useful information?
-                                       // The logical thing is probably to return the empty string here when we encounter undefined.
-                                       ret = '';
-                                       break;
-                               default:
-                                       throw new Error( 'Unexpected type in AST: ' + typeof node );
-                       }
-                       return ret;
-               };
-       };
-
-       // For everything in input that follows double-open-curly braces, there should be an equivalent parser
-       // function. For instance {{PLURAL ... }} will be processed by 'plural'.
-       // If you have 'magic words' then configure the parser to have them upon creation.
-       //
-       // An emitter method takes the parent node, the array of subnodes and the array of replacements (the values that $1, $2... should translate to).
-       // Note: all such functions must be pure, with the exception of referring to other pure functions via this.language (convertPlural and so on)
-       mw.jqueryMsg.HtmlEmitter.prototype = {
-               /**
-                * Parsing has been applied depth-first we can assume that all nodes here are single nodes
-                * Must return a single node to parents -- a jQuery with synthetic span
-                * However, unwrap any other synthetic spans in our children and pass them upwards
-                *
-                * @param {Mixed[]} nodes Some single nodes, some arrays of nodes
-                * @return {jQuery}
-                */
-               concat: function ( nodes ) {
-                       var $span = $( '<span>' ).addClass( 'mediaWiki_htmlEmitter' );
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( nodes, function ( i, node ) {
-                               // Let jQuery append nodes, arrays of nodes and jQuery objects
-                               // other things (strings, numbers, ..) are appended as text nodes (not as HTML strings)
-                               appendWithoutParsing( $span, node );
-                       } );
-                       return $span;
-               },
+       /**
+        * Return escaped replacement of correct index, or string if unavailable.
+        * Note that we expect the parsed parameter to be zero-based. i.e. $1 should have become [ 0 ].
+        * if the specified parameter is not found return the same string
+        * (e.g. "$99" -> parameter 98 -> not found -> return "$99" )
+        *
+        * TODO: Throw error if nodes.length > 1 ?
+        *
+        * @param {Array} nodes List of one element, integer, n >= 0
+        * @param {Array} replacements List of at least n strings
+        * @return {string|jQuery} replacement
+        */
+       replace: function ( nodes, replacements ) {
+               var index = parseInt( nodes[ 0 ], 10 );
 
-               /**
-                * Return escaped replacement of correct index, or string if unavailable.
-                * Note that we expect the parsed parameter to be zero-based. i.e. $1 should have become [ 0 ].
-                * if the specified parameter is not found return the same string
-                * (e.g. "$99" -> parameter 98 -> not found -> return "$99" )
-                *
-                * TODO: Throw error if nodes.length > 1 ?
-                *
-                * @param {Array} nodes List of one element, integer, n >= 0
-                * @param {Array} replacements List of at least n strings
-                * @return {string|jQuery} replacement
-                */
-               replace: function ( nodes, replacements ) {
-                       var index = parseInt( nodes[ 0 ], 10 );
+               if ( index < replacements.length ) {
+                       return replacements[ index ];
+               } else {
+                       // index not found, fallback to displaying variable
+                       return '$' + ( index + 1 );
+               }
+       },
 
-                       if ( index < replacements.length ) {
-                               return replacements[ index ];
-                       } else {
-                               // index not found, fallback to displaying variable
-                               return '$' + ( index + 1 );
-                       }
-               },
+       /**
+        * Transform wiki-link
+        *
+        * TODO:
+        * It only handles basic cases, either no pipe, or a pipe with an explicit
+        * anchor.
+        *
+        * It does not attempt to handle features like the pipe trick.
+        * However, the pipe trick should usually not be present in wikitext retrieved
+        * from the server, since the replacement is done at save time.
+        * It may, though, if the wikitext appears in extension-controlled content.
+        *
+        * @param {string[]} nodes
+        * @return {jQuery}
+        */
+       wikilink: function ( nodes ) {
+               var page, anchor, url, $el;
+
+               page = textify( nodes[ 0 ] );
+               // Strip leading ':', which is used to suppress special behavior in wikitext links,
+               // e.g. [[:Category:Foo]] or [[:File:Foo.jpg]]
+               if ( page.charAt( 0 ) === ':' ) {
+                       page = page.slice( 1 );
+               }
+               url = mw.util.getUrl( page );
 
-               /**
-                * Transform wiki-link
-                *
-                * TODO:
-                * It only handles basic cases, either no pipe, or a pipe with an explicit
-                * anchor.
-                *
-                * It does not attempt to handle features like the pipe trick.
-                * However, the pipe trick should usually not be present in wikitext retrieved
-                * from the server, since the replacement is done at save time.
-                * It may, though, if the wikitext appears in extension-controlled content.
-                *
-                * @param {string[]} nodes
-                * @return {jQuery}
-                */
-               wikilink: function ( nodes ) {
-                       var page, anchor, url, $el;
-
-                       page = textify( nodes[ 0 ] );
-                       // Strip leading ':', which is used to suppress special behavior in wikitext links,
-                       // e.g. [[:Category:Foo]] or [[:File:Foo.jpg]]
-                       if ( page.charAt( 0 ) === ':' ) {
-                               page = page.slice( 1 );
-                       }
-                       url = mw.util.getUrl( page );
+               if ( nodes.length === 1 ) {
+                       // [[Some Page]] or [[Namespace:Some Page]]
+                       anchor = page;
+               } else {
+                       // [[Some Page|anchor text]] or [[Namespace:Some Page|anchor]]
+                       anchor = nodes[ 1 ];
+               }
 
-                       if ( nodes.length === 1 ) {
-                               // [[Some Page]] or [[Namespace:Some Page]]
-                               anchor = page;
-                       } else {
-                               // [[Some Page|anchor text]] or [[Namespace:Some Page|anchor]]
-                               anchor = nodes[ 1 ];
-                       }
+               $el = $( '<a>' ).attr( {
+                       title: page,
+                       href: url
+               } );
+               return appendWithoutParsing( $el, anchor );
+       },
 
-                       $el = $( '<a>' ).attr( {
-                               title: page,
-                               href: url
-                       } );
-                       return appendWithoutParsing( $el, anchor );
-               },
+       /**
+        * Converts array of HTML element key value pairs to object
+        *
+        * @param {Array} nodes Array of consecutive key value pairs, with index 2 * n being a
+        *  name and 2 * n + 1 the associated value
+        * @return {Object} Object mapping attribute name to attribute value
+        */
+       htmlattributes: function ( nodes ) {
+               var i, len, mapping = {};
+               for ( i = 0, len = nodes.length; i < len; i += 2 ) {
+                       mapping[ nodes[ i ] ] = decodePrimaryHtmlEntities( nodes[ i + 1 ] );
+               }
+               return mapping;
+       },
 
-               /**
-                * Converts array of HTML element key value pairs to object
-                *
-                * @param {Array} nodes Array of consecutive key value pairs, with index 2 * n being a
-                *  name and 2 * n + 1 the associated value
-                * @return {Object} Object mapping attribute name to attribute value
-                */
-               htmlattributes: function ( nodes ) {
-                       var i, len, mapping = {};
-                       for ( i = 0, len = nodes.length; i < len; i += 2 ) {
-                               mapping[ nodes[ i ] ] = decodePrimaryHtmlEntities( nodes[ i + 1 ] );
-                       }
-                       return mapping;
-               },
+       /**
+        * Handles an (already-validated) HTML element.
+        *
+        * @param {Array} nodes Nodes to process when creating element
+        * @return {jQuery}
+        */
+       htmlelement: function ( nodes ) {
+               var tagName, attributes, contents, $element;
 
-               /**
-                * Handles an (already-validated) HTML element.
-                *
-                * @param {Array} nodes Nodes to process when creating element
-                * @return {jQuery}
-                */
-               htmlelement: function ( nodes ) {
-                       var tagName, attributes, contents, $element;
-
-                       tagName = nodes.shift();
-                       attributes = nodes.shift();
-                       contents = nodes;
-                       $element = $( document.createElement( tagName ) ).attr( attributes );
-                       return appendWithoutParsing( $element, contents );
-               },
+               tagName = nodes.shift();
+               attributes = nodes.shift();
+               contents = nodes;
+               $element = $( document.createElement( tagName ) ).attr( attributes );
+               return appendWithoutParsing( $element, contents );
+       },
 
-               /**
-                * Transform parsed structure into external link.
-                *
-                * The "href" can be:
-                * - a jQuery object, treat it as "enclosing" the link text.
-                * - a function, treat it as the click handler.
-                * - a string, or our HtmlEmitter jQuery object, treat it as a URI after stringifying.
-                *
-                * TODO: throw an error if nodes.length > 2 ?
-                *
-                * @param {Array} nodes List of two elements, {jQuery|Function|String} and {string}
-                * @return {jQuery}
-                */
-               extlink: function ( nodes ) {
-                       var $el,
-                               arg = nodes[ 0 ],
-                               contents = nodes[ 1 ];
-                       if ( arg instanceof $ && !arg.hasClass( 'mediaWiki_htmlEmitter' ) ) {
-                               $el = arg;
+       /**
+        * Transform parsed structure into external link.
+        *
+        * The "href" can be:
+        * - a jQuery object, treat it as "enclosing" the link text.
+        * - a function, treat it as the click handler.
+        * - a string, or our HtmlEmitter jQuery object, treat it as a URI after stringifying.
+        *
+        * TODO: throw an error if nodes.length > 2 ?
+        *
+        * @param {Array} nodes List of two elements, {jQuery|Function|String} and {string}
+        * @return {jQuery}
+        */
+       extlink: function ( nodes ) {
+               var $el,
+                       arg = nodes[ 0 ],
+                       contents = nodes[ 1 ];
+               if ( arg instanceof $ && !arg.hasClass( 'mediaWiki_htmlEmitter' ) ) {
+                       $el = arg;
+               } else {
+                       $el = $( '<a>' );
+                       if ( typeof arg === 'function' ) {
+                               $el.attr( {
+                                       role: 'button',
+                                       tabindex: 0
+                               } ).on( 'click keypress', function ( e ) {
+                                       if (
+                                               e.type === 'click' ||
+                                               e.type === 'keypress' && e.which === 13
+                                       ) {
+                                               arg.call( this, e );
+                                       }
+                               } );
                        } else {
-                               $el = $( '<a>' );
-                               if ( typeof arg === 'function' ) {
-                                       $el.attr( {
-                                               role: 'button',
-                                               tabindex: 0
-                                       } ).on( 'click keypress', function ( e ) {
-                                               if (
-                                                       e.type === 'click' ||
-                                                       e.type === 'keypress' && e.which === 13
-                                               ) {
-                                                       arg.call( this, e );
-                                               }
-                                       } );
-                               } else {
-                                       $el.attr( 'href', textify( arg ) );
-                               }
+                               $el.attr( 'href', textify( arg ) );
                        }
-                       return appendWithoutParsing( $el.empty(), contents );
-               },
-
-               /**
-                * Transform parsed structure into pluralization
-                * n.b. The first node may be a non-integer (for instance, a string representing an Arabic number).
-                * So convert it back with the current language's convertNumber.
-                *
-                * @param {Array} nodes List of nodes, [ {string|number}, {string}, {string} ... ]
-                * @return {string|jQuery} selected pluralized form according to current language
-                */
-               plural: function ( nodes ) {
-                       var forms, firstChild, firstChildText, explicitPluralFormNumber, formIndex, form, count,
-                               explicitPluralForms = {};
+               }
+               return appendWithoutParsing( $el.empty(), contents );
+       },
 
-                       count = parseFloat( this.language.convertNumber( textify( nodes[ 0 ] ), true ) );
-                       forms = nodes.slice( 1 );
-                       for ( formIndex = 0; formIndex < forms.length; formIndex++ ) {
-                               form = forms[ formIndex ];
-
-                               if ( form instanceof $ && form.hasClass( 'mediaWiki_htmlEmitter' ) ) {
-                                       // This is a nested node, may be an explicit plural form like 5=[$2 linktext]
-                                       firstChild = form.contents().get( 0 );
-                                       if ( firstChild && firstChild.nodeType === Node.TEXT_NODE ) {
-                                               firstChildText = firstChild.textContent;
-                                               if ( /^\d+=/.test( firstChildText ) ) {
-                                                       explicitPluralFormNumber = parseInt( firstChildText.split( /=/ )[ 0 ], 10 );
-                                                       // Use the digit part as key and rest of first text node and
-                                                       // rest of child nodes as value.
-                                                       firstChild.textContent = firstChildText.slice( firstChildText.indexOf( '=' ) + 1 );
-                                                       explicitPluralForms[ explicitPluralFormNumber ] = form;
-                                                       forms[ formIndex ] = undefined;
-                                               }
+       /**
+        * Transform parsed structure into pluralization
+        * n.b. The first node may be a non-integer (for instance, a string representing an Arabic number).
+        * So convert it back with the current language's convertNumber.
+        *
+        * @param {Array} nodes List of nodes, [ {string|number}, {string}, {string} ... ]
+        * @return {string|jQuery} selected pluralized form according to current language
+        */
+       plural: function ( nodes ) {
+               var forms, firstChild, firstChildText, explicitPluralFormNumber, formIndex, form, count,
+                       explicitPluralForms = {};
+
+               count = parseFloat( this.language.convertNumber( textify( nodes[ 0 ] ), true ) );
+               forms = nodes.slice( 1 );
+               for ( formIndex = 0; formIndex < forms.length; formIndex++ ) {
+                       form = forms[ formIndex ];
+
+                       if ( form instanceof $ && form.hasClass( 'mediaWiki_htmlEmitter' ) ) {
+                               // This is a nested node, may be an explicit plural form like 5=[$2 linktext]
+                               firstChild = form.contents().get( 0 );
+                               if ( firstChild && firstChild.nodeType === Node.TEXT_NODE ) {
+                                       firstChildText = firstChild.textContent;
+                                       if ( /^\d+=/.test( firstChildText ) ) {
+                                               explicitPluralFormNumber = parseInt( firstChildText.split( /=/ )[ 0 ], 10 );
+                                               // Use the digit part as key and rest of first text node and
+                                               // rest of child nodes as value.
+                                               firstChild.textContent = firstChildText.slice( firstChildText.indexOf( '=' ) + 1 );
+                                               explicitPluralForms[ explicitPluralFormNumber ] = form;
+                                               forms[ formIndex ] = undefined;
                                        }
-                               } else if ( /^\d+=/.test( form ) ) {
-                                       // Simple explicit plural forms like 12=a dozen
-                                       explicitPluralFormNumber = parseInt( form.split( /=/ )[ 0 ], 10 );
-                                       explicitPluralForms[ explicitPluralFormNumber ] = form.slice( form.indexOf( '=' ) + 1 );
-                                       forms[ formIndex ] = undefined;
                                }
+                       } else if ( /^\d+=/.test( form ) ) {
+                               // Simple explicit plural forms like 12=a dozen
+                               explicitPluralFormNumber = parseInt( form.split( /=/ )[ 0 ], 10 );
+                               explicitPluralForms[ explicitPluralFormNumber ] = form.slice( form.indexOf( '=' ) + 1 );
+                               forms[ formIndex ] = undefined;
                        }
+               }
 
-                       // Remove explicit plural forms from the forms. They were set undefined in the above loop.
-                       // eslint-disable-next-line no-jquery/no-map-util
-                       forms = $.map( forms, function ( form ) {
-                               return form;
-                       } );
-
-                       return this.language.convertPlural( count, forms, explicitPluralForms );
-               },
-
-               /**
-                * Transform parsed structure according to gender.
-                *
-                * Usage: {{gender:[ mw.user object | '' | 'male' | 'female' | 'unknown' ] | masculine form | feminine form | neutral form}}.
-                *
-                * The first node must be one of:
-                * - the mw.user object (or a compatible one)
-                * - an empty string - indicating the current user, same effect as passing the mw.user object
-                * - a gender string ('male', 'female' or 'unknown')
-                *
-                * @param {Array} nodes List of nodes, [ {string|mw.user}, {string}, {string}, {string} ]
-                * @return {string|jQuery} Selected gender form according to current language
-                */
-               gender: function ( nodes ) {
-                       var gender,
-                               maybeUser = nodes[ 0 ],
-                               forms = nodes.slice( 1 );
-
-                       if ( maybeUser === '' ) {
-                               maybeUser = mw.user;
-                       }
-
-                       // If we are passed a mw.user-like object, check their gender.
-                       // Otherwise, assume the gender string itself was passed .
-                       if ( maybeUser && maybeUser.options instanceof mw.Map ) {
-                               gender = maybeUser.options.get( 'gender' );
-                       } else {
-                               gender = textify( maybeUser );
-                       }
-
-                       return this.language.gender( gender, forms );
-               },
+               // Remove explicit plural forms from the forms. They were set undefined in the above loop.
+               // eslint-disable-next-line no-jquery/no-map-util
+               forms = $.map( forms, function ( form ) {
+                       return form;
+               } );
 
-               /**
-                * Transform parsed structure into grammar conversion.
-                * Invoked by putting `{{grammar:form|word}}` in a message
-                *
-                * @param {Array} nodes List of nodes [{Grammar case eg: genitive}, {string word}]
-                * @return {string|jQuery} selected grammatical form according to current language
-                */
-               grammar: function ( nodes ) {
-                       var form = nodes[ 0 ],
-                               word = nodes[ 1 ];
-                       // These could be jQuery objects (passed as message parameters),
-                       // in which case we can't transform them (like rawParams() in PHP).
-                       if ( typeof form === 'string' && typeof word === 'string' ) {
-                               return this.language.convertGrammar( word, form );
-                       }
-                       return word;
-               },
+               return this.language.convertPlural( count, forms, explicitPluralForms );
+       },
 
-               /**
-                * Tranform parsed structure into a int: (interface language) message include
-                * Invoked by putting `{{int:othermessage}}` into a message
-                *
-                * TODO Syntax in the included message is not parsed, this seems like a bug?
-                *
-                * @param {Array} nodes List of nodes
-                * @return {string} Other message
-                */
-               int: function ( nodes ) {
-                       var msg = textify( nodes[ 0 ] );
-                       return mw.jqueryMsg.getMessageFunction()( msg.charAt( 0 ).toLowerCase() + msg.slice( 1 ) );
-               },
+       /**
+        * Transform parsed structure according to gender.
+        *
+        * Usage: {{gender:[ mw.user object | '' | 'male' | 'female' | 'unknown' ] | masculine form | feminine form | neutral form}}.
+        *
+        * The first node must be one of:
+        * - the mw.user object (or a compatible one)
+        * - an empty string - indicating the current user, same effect as passing the mw.user object
+        * - a gender string ('male', 'female' or 'unknown')
+        *
+        * @param {Array} nodes List of nodes, [ {string|mw.user}, {string}, {string}, {string} ]
+        * @return {string|jQuery} Selected gender form according to current language
+        */
+       gender: function ( nodes ) {
+               var gender,
+                       maybeUser = nodes[ 0 ],
+                       forms = nodes.slice( 1 );
 
-               /**
-                * Get localized namespace name from canonical name or namespace number.
-                * Invoked by putting `{{ns:foo}}` into a message
-                *
-                * @param {Array} nodes List of nodes
-                * @return {string} Localized namespace name
-                */
-               ns: function ( nodes ) {
-                       var ns = textify( nodes[ 0 ] ).trim();
-                       if ( !/^\d+$/.test( ns ) ) {
-                               ns = mw.config.get( 'wgNamespaceIds' )[ ns.replace( / /g, '_' ).toLowerCase() ];
-                       }
-                       ns = mw.config.get( 'wgFormattedNamespaces' )[ ns ];
-                       return ns || '';
-               },
+               if ( maybeUser === '' ) {
+                       maybeUser = mw.user;
+               }
 
-               /**
-                * Takes an unformatted number (arab, no group separators and . as decimal separator)
-                * and outputs it in the localized digit script and formatted with decimal
-                * separator, according to the current language.
-                *
-                * @param {Array} nodes List of nodes
-                * @return {number|string|jQuery} Formatted number
-                */
-               formatnum: function ( nodes ) {
-                       var isInteger = !!nodes[ 1 ] && nodes[ 1 ] === 'R',
-                               number = nodes[ 0 ];
-
-                       // These could be jQuery objects (passed as message parameters),
-                       // in which case we can't transform them (like rawParams() in PHP).
-                       if ( typeof number === 'string' || typeof number === 'number' ) {
-                               return this.language.convertNumber( number, isInteger );
-                       }
-                       return number;
-               },
+               // If we are passed a mw.user-like object, check their gender.
+               // Otherwise, assume the gender string itself was passed .
+               if ( maybeUser && maybeUser.options instanceof mw.Map ) {
+                       gender = maybeUser.options.get( 'gender' );
+               } else {
+                       gender = textify( maybeUser );
+               }
 
-               /**
-                * Lowercase text
-                *
-                * @param {Array} nodes List of nodes
-                * @return {string} The given text, all in lowercase
-                */
-               lc: function ( nodes ) {
-                       return textify( nodes[ 0 ] ).toLowerCase();
-               },
+               return this.language.gender( gender, forms );
+       },
 
-               /**
-                * Uppercase text
-                *
-                * @param {Array} nodes List of nodes
-                * @return {string} The given text, all in uppercase
-                */
-               uc: function ( nodes ) {
-                       return textify( nodes[ 0 ] ).toUpperCase();
-               },
+       /**
+        * Transform parsed structure into grammar conversion.
+        * Invoked by putting `{{grammar:form|word}}` in a message
+        *
+        * @param {Array} nodes List of nodes [{Grammar case eg: genitive}, {string word}]
+        * @return {string|jQuery} selected grammatical form according to current language
+        */
+       grammar: function ( nodes ) {
+               var form = nodes[ 0 ],
+                       word = nodes[ 1 ];
+               // These could be jQuery objects (passed as message parameters),
+               // in which case we can't transform them (like rawParams() in PHP).
+               if ( typeof form === 'string' && typeof word === 'string' ) {
+                       return this.language.convertGrammar( word, form );
+               }
+               return word;
+       },
 
-               /**
-                * Lowercase first letter of input, leaving the rest unchanged
-                *
-                * @param {Array} nodes List of nodes
-                * @return {string} The given text, with the first character in lowercase
-                */
-               lcfirst: function ( nodes ) {
-                       var text = textify( nodes[ 0 ] );
-                       return text.charAt( 0 ).toLowerCase() + text.slice( 1 );
-               },
+       /**
+        * Tranform parsed structure into a int: (interface language) message include
+        * Invoked by putting `{{int:othermessage}}` into a message
+        *
+        * TODO Syntax in the included message is not parsed, this seems like a bug?
+        *
+        * @param {Array} nodes List of nodes
+        * @return {string} Other message
+        */
+       int: function ( nodes ) {
+               var msg = textify( nodes[ 0 ] );
+               return mw.jqueryMsg.getMessageFunction()( msg.charAt( 0 ).toLowerCase() + msg.slice( 1 ) );
+       },
 
-               /**
-                * Uppercase first letter of input, leaving the rest unchanged
-                *
-                * @param {Array} nodes List of nodes
-                * @return {string} The given text, with the first character in uppercase
-                */
-               ucfirst: function ( nodes ) {
-                       var text = textify( nodes[ 0 ] );
-                       return text.charAt( 0 ).toUpperCase() + text.slice( 1 );
+       /**
+        * Get localized namespace name from canonical name or namespace number.
+        * Invoked by putting `{{ns:foo}}` into a message
+        *
+        * @param {Array} nodes List of nodes
+        * @return {string} Localized namespace name
+        */
+       ns: function ( nodes ) {
+               var ns = textify( nodes[ 0 ] ).trim();
+               if ( !/^\d+$/.test( ns ) ) {
+                       ns = mw.config.get( 'wgNamespaceIds' )[ ns.replace( / /g, '_' ).toLowerCase() ];
                }
-       };
+               ns = mw.config.get( 'wgFormattedNamespaces' )[ ns ];
+               return ns || '';
+       },
 
        /**
-        * @method
-        * @member jQuery
-        * @see mw.jqueryMsg#getPlugin
+        * Takes an unformatted number (arab, no group separators and . as decimal separator)
+        * and outputs it in the localized digit script and formatted with decimal
+        * separator, according to the current language.
+        *
+        * @param {Array} nodes List of nodes
+        * @return {number|string|jQuery} Formatted number
         */
-       $.fn.msg = mw.jqueryMsg.getPlugin();
-
-       // Replace the default message parser with jqueryMsg
-       oldParser = mw.Message.prototype.parser;
-       mw.Message.prototype.parser = function () {
-               // Fall back to mw.msg's simple parser where possible
-               if (
-                       // Plain text output always uses the simple parser
-                       this.format === 'plain' ||
-                       (
-                               // jqueryMsg parser is needed for messages containing wikitext
-                               !/\{\{|[<>[&]/.test( this.map.get( this.key ) ) &&
-                               // jqueryMsg parser is needed when jQuery objects or DOM nodes are passed in as parameters
-                               !this.parameters.some( function ( param ) {
-                                       return param instanceof $ || ( param && param.nodeType !== undefined );
-                               } )
-                       )
-               ) {
-                       return oldParser.apply( this );
+       formatnum: function ( nodes ) {
+               var isInteger = !!nodes[ 1 ] && nodes[ 1 ] === 'R',
+                       number = nodes[ 0 ];
+
+               // These could be jQuery objects (passed as message parameters),
+               // in which case we can't transform them (like rawParams() in PHP).
+               if ( typeof number === 'string' || typeof number === 'number' ) {
+                       return this.language.convertNumber( number, isInteger );
                }
+               return number;
+       },
 
-               if ( !Object.prototype.hasOwnProperty.call( this.map, this.format ) ) {
-                       this.map[ this.format ] = mw.jqueryMsg.getMessageFunction( {
-                               messages: this.map,
-                               // For format 'escaped', escaping part is handled by mediawiki.js
-                               format: this.format
-                       } );
-               }
-               return this.map[ this.format ]( this.key, this.parameters );
-       };
+       /**
+        * Lowercase text
+        *
+        * @param {Array} nodes List of nodes
+        * @return {string} The given text, all in lowercase
+        */
+       lc: function ( nodes ) {
+               return textify( nodes[ 0 ] ).toLowerCase();
+       },
 
        /**
-        * Parse the message to DOM nodes, rather than HTML string like #parse.
+        * Uppercase text
         *
-        * This method is only available when jqueryMsg is loaded.
+        * @param {Array} nodes List of nodes
+        * @return {string} The given text, all in uppercase
+        */
+       uc: function ( nodes ) {
+               return textify( nodes[ 0 ] ).toUpperCase();
+       },
+
+       /**
+        * Lowercase first letter of input, leaving the rest unchanged
         *
-        * @since 1.27
-        * @method parseDom
-        * @member mw.Message
-        * @return {jQuery}
+        * @param {Array} nodes List of nodes
+        * @return {string} The given text, with the first character in lowercase
         */
-       mw.Message.prototype.parseDom = ( function () {
-               var $wrapper = $( '<div>' );
-               return function () {
-                       return $wrapper.msg( this.key, this.parameters ).contents().detach();
-               };
-       }() );
+       lcfirst: function ( nodes ) {
+               var text = textify( nodes[ 0 ] );
+               return text.charAt( 0 ).toLowerCase() + text.slice( 1 );
+       },
+
+       /**
+        * Uppercase first letter of input, leaving the rest unchanged
+        *
+        * @param {Array} nodes List of nodes
+        * @return {string} The given text, with the first character in uppercase
+        */
+       ucfirst: function ( nodes ) {
+               var text = textify( nodes[ 0 ] );
+               return text.charAt( 0 ).toUpperCase() + text.slice( 1 );
+       }
+};
+
+/**
+ * @method
+ * @member jQuery
+ * @see mw.jqueryMsg#getPlugin
+ */
+$.fn.msg = mw.jqueryMsg.getPlugin();
+
+// Replace the default message parser with jqueryMsg
+oldParser = mw.Message.prototype.parser;
+mw.Message.prototype.parser = function () {
+       // Fall back to mw.msg's simple parser where possible
+       if (
+               // Plain text output always uses the simple parser
+               this.format === 'plain' ||
+               (
+                       // jqueryMsg parser is needed for messages containing wikitext
+                       !/\{\{|[<>[&]/.test( this.map.get( this.key ) ) &&
+                       // jqueryMsg parser is needed when jQuery objects or DOM nodes are passed in as parameters
+                       !this.parameters.some( function ( param ) {
+                               return param instanceof $ || ( param && param.nodeType !== undefined );
+                       } )
+               )
+       ) {
+               return oldParser.apply( this );
+       }
 
+       if ( !Object.prototype.hasOwnProperty.call( this.map, this.format ) ) {
+               this.map[ this.format ] = mw.jqueryMsg.getMessageFunction( {
+                       messages: this.map,
+                       // For format 'escaped', escaping part is handled by mediawiki.js
+                       format: this.format
+               } );
+       }
+       return this.map[ this.format ]( this.key, this.parameters );
+};
+
+/**
+ * Parse the message to DOM nodes, rather than HTML string like #parse.
+ *
+ * This method is only available when jqueryMsg is loaded.
+ *
+ * @since 1.27
+ * @method parseDom
+ * @member mw.Message
+ * @return {jQuery}
+ */
+mw.Message.prototype.parseDom = ( function () {
+       var $wrapper = $( '<div>' );
+       return function () {
+               return $wrapper.msg( this.key, this.parameters ).contents().detach();
+       };
 }() );
diff --git a/resources/src/mediawiki.language/mediawiki.cldr.js b/resources/src/mediawiki.language/mediawiki.cldr.js
deleted file mode 100644 (file)
index 5054810..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-( function () {
-       'use strict';
-
-       /**
-        * Namespace for CLDR-related utility methods.
-        *
-        * @class
-        * @singleton
-        */
-       mw.cldr = {
-               /**
-                * Get the plural form index for the number.
-                *
-                * In case none of the rules passed, we return `pluralRules.length` -
-                * that means it is the "other" form.
-                *
-                * @param {number} number
-                * @param {Array} pluralRules
-                * @return {number} plural form index
-                */
-               getPluralForm: function ( number, pluralRules ) {
-                       var i, pluralRuleParser = require( 'mediawiki.libs.pluralruleparser' );
-                       for ( i = 0; i < pluralRules.length; i++ ) {
-                               if ( pluralRuleParser( pluralRules[ i ], number ) ) {
-                                       break;
-                               }
-                       }
-                       return i;
-               }
-       };
-
-}() );
index 1d0e335..6988576 100644 (file)
 ( function () {
-       var ProtectionForm,
-               config = require( './config.json' ),
+       var config = require( './config.json' ),
                reasonCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
                reasonByteLimit = mw.config.get( 'wgCommentByteLimit' );
 
-       ProtectionForm = window.ProtectionForm = {
-               /**
-                * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
-                * on the protection form
-                *
-                * @return {boolean}
-                */
-               init: function () {
-                       var $cell = $( '<td>' ),
-                               $row = $( '<tr>' ).append( $cell );
-
-                       if ( !$( '#mwProtectSet' ).length ) {
+       /**
+        * Get a list of all protection selectors on the page
+        *
+        * @return {jQuery}
+        */
+       function getLevelSelectors() {
+               return $( 'select[id ^= mwProtect-level-]' );
+       }
+
+       /**
+        * Get a list of all expiry inputs on the page
+        *
+        * @return {jQuery}
+        */
+       function getExpiryInputs() {
+               return $( 'input[id ^= mwProtect-][id $= -expires]' );
+       }
+
+       /**
+        * Get a list of all expiry selector lists on the page
+        *
+        * @return {jQuery}
+        */
+       function getExpirySelectors() {
+               return $( 'select[id ^= mwProtectExpirySelection-]' );
+       }
+
+       /**
+        * Enable/disable protection selectors and expiry inputs
+        *
+        * @param {boolean} val Enable?
+        */
+       function toggleUnchainedInputs( val ) {
+               var setDisabled = function () {
+                       this.disabled = !val;
+               };
+               getLevelSelectors().slice( 1 ).each( setDisabled );
+               getExpiryInputs().slice( 1 ).each( setDisabled );
+               getExpirySelectors().slice( 1 ).each( setDisabled );
+       }
+
+       /**
+        * Checks if a certain protection level is cascadeable.
+        *
+        * @param {string} level
+        * @return {boolean}
+        */
+       function isCascadeableLevel( level ) {
+               return config.CascadingRestrictionLevels.indexOf( level ) !== -1;
+       }
+
+       /**
+        * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
+        */
+       function updateCascadeCheckbox() {
+               getLevelSelectors().each( function () {
+                       if ( !isCascadeableLevel( $( this ).val() ) ) {
+                               $( '#mwProtect-cascade' ).prop( { checked: false, disabled: true } );
                                return false;
+                       } else {
+                               $( '#mwProtect-cascade' ).prop( 'disabled', false );
                        }
+               } );
+       }
+
+       /**
+        * Returns true if the named attribute in all objects in the given array are matching
+        *
+        * @param {Object[]} objects
+        * @param {string} attrName
+        * @return {boolean}
+        */
+       function matchAttribute( objects, attrName ) {
+               // eslint-disable-next-line no-jquery/no-map-util
+               return $.map( objects, function ( object ) {
+                       return object[ attrName ];
+               } ).filter( function ( item, index, a ) {
+                       return index === a.indexOf( item );
+               } ).length === 1;
+       }
+
+       /**
+        * Are all actions protected at the same level, with the same expiry time?
+        *
+        * @return {boolean}
+        */
+       function areAllTypesMatching() {
+               return matchAttribute( getLevelSelectors(), 'selectedIndex' ) &&
+                       matchAttribute( getExpirySelectors(), 'selectedIndex' ) &&
+                       matchAttribute( getExpiryInputs(), 'value' );
+       }
+
+       /**
+        * Is protection chaining off?
+        *
+        * @return {boolean}
+        */
+       function isUnchained() {
+               var element = document.getElementById( 'mwProtectUnchained' );
+               return element ?
+                       element.checked :
+                       true; // No control, so we need to let the user set both levels
+       }
+
+       /**
+        * Find the highest protection level in any selector
+        *
+        * @return {number}
+        */
+       function getMaxLevel() {
+               return Math.max.apply( Math, getLevelSelectors().map( function () {
+                       return this.selectedIndex;
+               } ) );
+       }
+
+       /**
+        * Protect all actions at the specified level
+        *
+        * @param {number} index Protection level
+        */
+       function setAllSelectors( index ) {
+               getLevelSelectors().prop( 'selectedIndex', index );
+       }
+
+       /**
+        * When protection levels are locked together, update the rest
+        * when one action's level changes
+        *
+        * @param {Event} event Level selector that changed
+        */
+       function updateLevels( event ) {
+               if ( !isUnchained() ) {
+                       setAllSelectors( event.target.selectedIndex );
+               }
+               updateCascadeCheckbox();
+       }
+
+       /**
+        * When protection levels are locked together, update the
+        * expiries when one changes
+        *
+        * @param {Event} event Expiry input that changed
+        */
+       function updateExpiry( event ) {
+               if ( !isUnchained() ) {
+                       getExpiryInputs().val( event.target.value );
+               }
+               if ( isUnchained() ) {
+                       $( '#' + event.target.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' ) ).val( 'othertime' );
+               } else {
+                       getExpirySelectors().val( 'othertime' );
+               }
+       }
+
+       /**
+        * When protection levels are locked together, update the
+        * expiry lists when one changes and clear the custom inputs
+        *
+        * @param {Event} event Expiry selector that changed
+        */
+       function updateExpiryList( event ) {
+               if ( !isUnchained() ) {
+                       getExpirySelectors().val( event.target.value );
+                       getExpiryInputs().val( '' );
+               }
+       }
+
+       /**
+        * Update chain status and enable/disable various bits of the UI
+        * when the user changes the "unlock move permissions" checkbox
+        */
+       function onChainClick() {
+               toggleUnchainedInputs( isUnchained() );
+               if ( !isUnchained() ) {
+                       setAllSelectors( getMaxLevel() );
+               }
+               updateCascadeCheckbox();
+       }
+
+       /**
+        * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
+        * on the protection form
+        */
+       function init() {
+               var $cell = $( '<td>' ),
+                       $row = $( '<tr>' ).append( $cell );
+
+               if ( !$( '#mwProtectSet' ).length ) {
+                       return;
+               }
 
-                       $( 'form#mw-Protect-Form' ).on( 'submit', this.toggleUnchainedInputs.bind( ProtectionForm, true ) );
-                       this.getExpirySelectors().each( function () {
-                               $( this ).on( 'change', ProtectionForm.updateExpiryList.bind( ProtectionForm, this ) );
-                       } );
-                       this.getExpiryInputs().each( function () {
-                               $( this ).on( 'keyup change', ProtectionForm.updateExpiry.bind( ProtectionForm, this ) );
-                       } );
-                       this.getLevelSelectors().each( function () {
-                               $( this ).on( 'change', ProtectionForm.updateLevels.bind( ProtectionForm, this ) );
-                       } );
-
-                       $( '#mwProtectSet > tbody > tr:first' ).after( $row );
-
-                       // If there is only one protection type, there is nothing to chain
-                       if ( $( '[id ^= mw-protect-table-]' ).length > 1 ) {
-                               $cell.append(
-                                       $( '<input>' )
-                                               .attr( { id: 'mwProtectUnchained', type: 'checkbox' } )
-                                               .on( 'click', this.onChainClick.bind( this ) )
-                                               .prop( 'checked', !this.areAllTypesMatching() ),
-                                       document.createTextNode( ' ' ),
-                                       $( '<label>' )
-                                               .attr( 'for', 'mwProtectUnchained' )
-                                               .text( mw.msg( 'protect-unchain-permissions' ) )
-                               );
-
-                               this.toggleUnchainedInputs( !this.areAllTypesMatching() );
-                       }
-
-                       // Arbitrary 75 to leave some space for the autogenerated null edit's summary
-                       if ( reasonCodePointLimit ) {
-                               $( '#mwProtect-reason' ).codePointLimit( reasonCodePointLimit - 75 );
-                       } else if ( reasonByteLimit ) {
-                               $( '#mwProtect-reason' ).byteLimit( reasonByteLimit - 75 );
-                       }
+               $( 'form#mw-Protect-Form' ).on( 'submit', toggleUnchainedInputs.bind( this, true ) );
+               getExpirySelectors().on( 'change', updateExpiryList );
+               getExpiryInputs().on( 'input change', updateExpiry );
+               getLevelSelectors().on( 'change', updateLevels );
+
+               $( '#mwProtectSet > tbody > tr:first' ).after( $row );
+
+               // If there is only one protection type, there is nothing to chain
+               if ( $( '[id ^= mw-protect-table-]' ).length > 1 ) {
+                       $cell.append(
+                               $( '<input>' )
+                                       .attr( { id: 'mwProtectUnchained', type: 'checkbox' } )
+                                       .on( 'click', onChainClick )
+                                       .prop( 'checked', !areAllTypesMatching() ),
+                               document.createTextNode( ' ' ),
+                               $( '<label>' )
+                                       .attr( 'for', 'mwProtectUnchained' )
+                                       .text( mw.msg( 'protect-unchain-permissions' ) )
+                       );
+
+                       toggleUnchainedInputs( !areAllTypesMatching() );
+               }
 
-                       this.updateCascadeCheckbox();
-                       return true;
-               },
-
-               /**
-                * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
-                */
-               updateCascadeCheckbox: function () {
-                       this.getLevelSelectors().each( function () {
-                               if ( !ProtectionForm.isCascadeableLevel( $( this ).val() ) ) {
-                                       $( '#mwProtect-cascade' ).prop( { checked: false, disabled: true } );
-                                       return false;
-                               } else {
-                                       $( '#mwProtect-cascade' ).prop( 'disabled', false );
-                               }
-                       } );
-               },
-
-               /**
-                * Checks if a certain protection level is cascadeable.
-                *
-                * @param {string} level
-                * @return {boolean}
-                */
-               isCascadeableLevel: function ( level ) {
-                       return config.CascadingRestrictionLevels.indexOf( level ) !== -1;
-               },
-
-               /**
-                * When protection levels are locked together, update the rest
-                * when one action's level changes
-                *
-                * @param {Element} source Level selector that changed
-                */
-               updateLevels: function ( source ) {
-                       if ( !this.isUnchained() ) {
-                               this.setAllSelectors( source.selectedIndex );
-                       }
-                       this.updateCascadeCheckbox();
-               },
-
-               /**
-                * When protection levels are locked together, update the
-                * expiries when one changes
-                *
-                * @param {Element} source expiry input that changed
-                */
-
-               updateExpiry: function ( source ) {
-                       if ( !this.isUnchained() ) {
-                               this.getExpiryInputs().each( function () {
-                                       this.value = source.value;
-                               } );
-                       }
-                       if ( this.isUnchained() ) {
-                               $( '#' + source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' ) ).val( 'othertime' );
-                       } else {
-                               this.getExpirySelectors().each( function () {
-                                       this.value = 'othertime';
-                               } );
-                       }
-               },
-
-               /**
-                * When protection levels are locked together, update the
-                * expiry lists when one changes and clear the custom inputs
-                *
-                * @param {Element} source Expiry selector that changed
-                */
-               updateExpiryList: function ( source ) {
-                       if ( !this.isUnchained() ) {
-                               this.getExpirySelectors().each( function () {
-                                       this.value = source.value;
-                               } );
-                               this.getExpiryInputs().each( function () {
-                                       this.value = '';
-                               } );
-                       }
-               },
-
-               /**
-                * Update chain status and enable/disable various bits of the UI
-                * when the user changes the "unlock move permissions" checkbox
-                */
-               onChainClick: function () {
-                       this.toggleUnchainedInputs( this.isUnchained() );
-                       if ( !this.isUnchained() ) {
-                               this.setAllSelectors( this.getMaxLevel() );
-                       }
-                       this.updateCascadeCheckbox();
-               },
-
-               /**
-                * Returns true if the named attribute in all objects in the given array are matching
-                *
-                * @param {Object[]} objects
-                * @param {string} attrName
-                * @return {boolean}
-                */
-               matchAttribute: function ( objects, attrName ) {
-                       // eslint-disable-next-line no-jquery/no-map-util
-                       return $.map( objects, function ( object ) {
-                               return object[ attrName ];
-                       } ).filter( function ( item, index, a ) {
-                               return index === a.indexOf( item );
-                       } ).length === 1;
-               },
-
-               /**
-                * Are all actions protected at the same level, with the same expiry time?
-                *
-                * @return {boolean}
-                */
-               areAllTypesMatching: function () {
-                       return this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' ) &&
-                               this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' ) &&
-                               this.matchAttribute( this.getExpiryInputs(), 'value' );
-               },
-
-               /**
-                * Is protection chaining off?
-                *
-                * @return {boolean}
-                */
-               isUnchained: function () {
-                       var element = document.getElementById( 'mwProtectUnchained' );
-                       return element ?
-                               element.checked :
-                               true; // No control, so we need to let the user set both levels
-               },
-
-               /**
-                * Find the highest protection level in any selector
-                *
-                * @return {number}
-                */
-               getMaxLevel: function () {
-                       return Math.max.apply( Math, this.getLevelSelectors().map( function () {
-                               return this.selectedIndex;
-                       } ) );
-               },
-
-               /**
-                * Protect all actions at the specified level
-                *
-                * @param {number} index Protection level
-                */
-               setAllSelectors: function ( index ) {
-                       this.getLevelSelectors().each( function () {
-                               this.selectedIndex = index;
-                       } );
-               },
-
-               /**
-                * Get a list of all protection selectors on the page
-                *
-                * @return {jQuery}
-                */
-               getLevelSelectors: function () {
-                       return $( 'select[id ^= mwProtect-level-]' );
-               },
-
-               /**
-                * Get a list of all expiry inputs on the page
-                *
-                * @return {jQuery}
-                */
-               getExpiryInputs: function () {
-                       return $( 'input[id ^= mwProtect-][id $= -expires]' );
-               },
-
-               /**
-                * Get a list of all expiry selector lists on the page
-                *
-                * @return {jQuery}
-                */
-               getExpirySelectors: function () {
-                       return $( 'select[id ^= mwProtectExpirySelection-]' );
-               },
-
-               /**
-                * Enable/disable protection selectors and expiry inputs
-                *
-                * @param {boolean} val Enable?
-                */
-               toggleUnchainedInputs: function ( val ) {
-                       var setDisabled = function () {
-                               this.disabled = !val;
-                       };
-                       this.getLevelSelectors().slice( 1 ).each( setDisabled );
-                       this.getExpiryInputs().slice( 1 ).each( setDisabled );
-                       this.getExpirySelectors().slice( 1 ).each( setDisabled );
+               // Arbitrary 75 to leave some space for the autogenerated null edit's summary
+               if ( reasonCodePointLimit ) {
+                       $( '#mwProtect-reason' ).codePointLimit( reasonCodePointLimit - 75 );
+               } else if ( reasonByteLimit ) {
+                       $( '#mwProtect-reason' ).byteLimit( reasonByteLimit - 75 );
                }
-       };
 
-       $( ProtectionForm.init.bind( ProtectionForm ) );
+               updateCascadeCheckbox();
+       }
+
+       $( init );
 
 }() );
index 5f20cf9..a63c5c6 100644 (file)
@@ -462,7 +462,7 @@ a.new {
 }
 
 .mw-datatable th {
-       background-color: #ddf;
+       background-color: #eaeeff;
 }
 
 .mw-datatable td {
index fe5647f..4684ea2 100644 (file)
        background-image: e( '/* @embed */' ) url( @url );
 }
 
-// Deprecated in MW 1.27
-.background-size( @width, @height ) {
-       // Vendor prefix is added to support Android 2
-       -webkit-background-size: @width @height;
-       background-size: @width @height;
-}
-
 .vertical-gradient( @startColor: gray, @endColor: white, @startPos: 0, @endPos: 100% ) {
        background-color: @endColor;
        background-image: -webkit-linear-gradient( top, @startColor @startPos, @endColor @endPos ); // Safari 5.1+, Chrome 10+
        list-style-image: e( '/* @embed */' ) url( @url );
 }
 
-.list-style-image-svg( @svg, @fallback ) {
-       list-style-image: e( '/* @embed */' ) url( @svg );
-       /* Fallback to PNG bullet for IE 8 and below using CSS hack */
-       list-style-image: e( '/* @embed */' ) url( @fallback ) e( '\9' );
-}
-
 .hyphens( @value: auto ) {
        & when ( @value = auto ) {
                // Legacy `word-wrap`; IE 6-11, Edge 12+, Firefox 3.5+, Chrome 4+, Safari 3.1+,
diff --git a/resources/src/mediawiki.page.rollback.js b/resources/src/mediawiki.page.rollback.js
deleted file mode 100644 (file)
index 2896f40..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*!
- * Enhance rollback links by using asynchronous API requests,
- * rather than navigating to an action page.
- *
- * @since 1.28
- * @author Timo Tijhof
- */
-( function () {
-
-       $( function () {
-               $( '.mw-rollback-link' ).on( 'click', 'a[data-mw="interface"]', function ( e ) {
-                       var api, $spinner,
-                               $link = $( this ),
-                               url = this.href,
-                               page = mw.util.getParamValue( 'title', url ),
-                               user = mw.util.getParamValue( 'from', url );
-
-                       if ( !page || user === null ) {
-                               // Let native browsing handle the link
-                               return true;
-                       }
-
-                       // Preload the notification module for mw.notify
-                       mw.loader.load( 'mediawiki.notification' );
-
-                       // Remove event handler so that next click (re-try) uses server action
-                       $( e.delegateTarget ).off( 'click' );
-
-                       // Hide the link and create a spinner to show it inside the brackets.
-                       $spinner = $.createSpinner( { size: 'small', type: 'inline' } );
-                       $link.hide().after( $spinner );
-
-                       // @todo: data.messageHtml is no more. Convert to using errorformat=html.
-                       api = new mw.Api();
-                       api.rollback( page, user )
-                               .then( function ( data ) {
-                                       mw.notify( $.parseHTML( data.messageHtml ), {
-                                               title: mw.msg( 'actioncomplete' )
-                                       } );
-
-                                       // Remove link container and the subsequent text node containing " | ".
-                                       if ( e.delegateTarget.nextSibling && e.delegateTarget.nextSibling.nodeType === Node.TEXT_NODE ) {
-                                               $( e.delegateTarget.nextSibling ).remove();
-                                       }
-                                       $( e.delegateTarget ).remove();
-                               }, function ( errorCode, data ) {
-                                       var message = data && data.error && data.error.messageHtml ?
-                                                       $.parseHTML( data.error.messageHtml ) :
-                                                       mw.msg( 'rollbackfailed' ),
-                                               type = errorCode === 'alreadyrolled' ? 'warn' : 'error';
-
-                                       mw.notify( message, {
-                                               type: type,
-                                               title: mw.msg( 'rollbackfailed' ),
-                                               autoHide: false
-                                       } );
-
-                                       // Restore the link (enables user to try again)
-                                       $spinner.remove();
-                                       $link.show();
-                               } );
-
-                       e.preventDefault();
-               } );
-       } );
-
-}() );
index a8ab818..1cccb88 100644 (file)
@@ -5,26 +5,23 @@
 
 @import 'mediawiki.mixins';
 
-.TablePager {
+// TablePager uses `.mw-datatable` and is loaded in the right order by RL
+.mw-datatable {
        min-width: 80%;
 
-       // Remove as soon as `.mw-datatable` receives this `padding`, see T214208
-       td,
-       th {
-               padding: 0.2em 0.4em;
+       &-is-sorted a {
+               background-position: left center;
+               background-repeat: no-repeat;
+               padding-left: 15px;
        }
-}
 
-.TablePager .TablePager_sort-ascending a {
-       padding-left: 15px;
-       background: none left center no-repeat;
-       .background-image-svg('images/arrow-sort-ascending.svg', 'images/arrow-sort-ascending.png');
-}
+       &-is-ascending a {
+               .background-image-svg( 'images/arrow-sort-ascending.svg', 'images/arrow-sort-ascending.png' );
+       }
 
-.TablePager .TablePager_sort-descending a {
-       padding-left: 15px;
-       background: none left center no-repeat;
-       .background-image-svg('images/arrow-sort-descending.svg', 'images/arrow-sort-descending.png');
+       &-is-descending a {
+               .background-image-svg( 'images/arrow-sort-descending.svg', 'images/arrow-sort-descending.png' );
+       }
 }
 
 .TablePager_nav {
diff --git a/resources/src/mediawiki.rcfilters/.eslintrc.json b/resources/src/mediawiki.rcfilters/.eslintrc.json
new file mode 100644 (file)
index 0000000..ad8dbb3
--- /dev/null
@@ -0,0 +1,5 @@
+{
+       "parserOptions": {
+               "sourceType": "module"
+       }
+}
index ce5d407..97b73ae 100644 (file)
-( function () {
-
-       var byteLength = require( 'mediawiki.String' ).byteLength,
-               UriProcessor = require( './UriProcessor.js' ),
-               Controller;
-
-       /* eslint no-underscore-dangle: "off" */
-       /**
-        * Controller for the filters in Recent Changes
-        * @class mw.rcfilters.Controller
-        *
-        * @constructor
-        * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model
-        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel Changes list view model
-        * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
-        * @param {Object} config Additional configuration
-        * @cfg {string} savedQueriesPreferenceName Where to save the saved queries
-        * @cfg {string} daysPreferenceName Preference name for the days filter
-        * @cfg {string} limitPreferenceName Preference name for the limit filter
-        * @cfg {string} collapsedPreferenceName Preference name for collapsing and showing
-        *  the active filters area
-        * @cfg {boolean} [normalizeTarget] Dictates whether or not to go through the
-        *  title normalization to separate title subpage/parts into the target= url
-        *  parameter
-        */
-       Controller = function MwRcfiltersController( filtersModel, changesListModel, savedQueriesModel, config ) {
-               this.filtersModel = filtersModel;
-               this.changesListModel = changesListModel;
-               this.savedQueriesModel = savedQueriesModel;
-               this.savedQueriesPreferenceName = config.savedQueriesPreferenceName;
-               this.daysPreferenceName = config.daysPreferenceName;
-               this.limitPreferenceName = config.limitPreferenceName;
-               this.collapsedPreferenceName = config.collapsedPreferenceName;
-               this.normalizeTarget = !!config.normalizeTarget;
-
-               this.pollingRate = require( './config.json' ).StructuredChangeFiltersLiveUpdatePollingRate;
-
-               this.requestCounter = {};
-               this.baseFilterState = {};
-               this.uriProcessor = null;
-               this.initialized = false;
-               this.wereSavedQueriesSaved = false;
-
-               this.prevLoggedItems = [];
-
-               this.FILTER_CHANGE = 'filterChange';
-               this.SHOW_NEW_CHANGES = 'showNewChanges';
-               this.LIVE_UPDATE = 'liveUpdate';
-       };
-
-       /* Initialization */
-       OO.initClass( Controller );
-
-       /**
-        * Initialize the filter and parameter states
-        *
-        * @param {Array} filterStructure Filter definition and structure for the model
-        * @param {Object} [namespaceStructure] Namespace definition
-        * @param {Object} [tagList] Tag definition
-        * @param {Object} [conditionalViews] Conditional view definition
-        */
-       Controller.prototype.initialize = function ( filterStructure, namespaceStructure, tagList, conditionalViews ) {
-               var parsedSavedQueries, pieces,
-                       displayConfig = mw.config.get( 'StructuredChangeFiltersDisplayConfig' ),
-                       defaultSavedQueryExists = mw.config.get( 'wgStructuredChangeFiltersDefaultSavedQueryExists' ),
-                       controller = this,
-                       views = $.extend( true, {}, conditionalViews ),
-                       items = [],
-                       uri = new mw.Uri();
-
-               // Prepare views
-               if ( namespaceStructure ) {
-                       items = [];
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( namespaceStructure, function ( namespaceID, label ) {
-                               // Build and clean up the individual namespace items definition
-                               items.push( {
-                                       name: namespaceID,
-                                       label: label || mw.msg( 'blanknamespace' ),
-                                       description: '',
-                                       identifiers: [
-                                               mw.Title.isTalkNamespace( namespaceID ) ?
-                                                       'talk' : 'subject'
-                                       ],
-                                       cssClass: 'mw-changeslist-ns-' + namespaceID
-                               } );
+var byteLength = require( 'mediawiki.String' ).byteLength,
+       UriProcessor = require( './UriProcessor.js' ),
+       Controller;
+
+/* eslint no-underscore-dangle: "off" */
+/**
+ * Controller for the filters in Recent Changes
+ * @class mw.rcfilters.Controller
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model
+ * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel Changes list view model
+ * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
+ * @param {Object} config Additional configuration
+ * @cfg {string} savedQueriesPreferenceName Where to save the saved queries
+ * @cfg {string} daysPreferenceName Preference name for the days filter
+ * @cfg {string} limitPreferenceName Preference name for the limit filter
+ * @cfg {string} collapsedPreferenceName Preference name for collapsing and showing
+ *  the active filters area
+ * @cfg {boolean} [normalizeTarget] Dictates whether or not to go through the
+ *  title normalization to separate title subpage/parts into the target= url
+ *  parameter
+ */
+Controller = function MwRcfiltersController( filtersModel, changesListModel, savedQueriesModel, config ) {
+       this.filtersModel = filtersModel;
+       this.changesListModel = changesListModel;
+       this.savedQueriesModel = savedQueriesModel;
+       this.savedQueriesPreferenceName = config.savedQueriesPreferenceName;
+       this.daysPreferenceName = config.daysPreferenceName;
+       this.limitPreferenceName = config.limitPreferenceName;
+       this.collapsedPreferenceName = config.collapsedPreferenceName;
+       this.normalizeTarget = !!config.normalizeTarget;
+
+       this.pollingRate = require( './config.json' ).StructuredChangeFiltersLiveUpdatePollingRate;
+
+       this.requestCounter = {};
+       this.uriProcessor = null;
+       this.initialized = false;
+       this.wereSavedQueriesSaved = false;
+
+       this.prevLoggedItems = [];
+
+       this.FILTER_CHANGE = 'filterChange';
+       this.SHOW_NEW_CHANGES = 'showNewChanges';
+       this.LIVE_UPDATE = 'liveUpdate';
+};
+
+/* Initialization */
+OO.initClass( Controller );
+
+/**
+ * Initialize the filter and parameter states
+ *
+ * @param {Array} filterStructure Filter definition and structure for the model
+ * @param {Object} [namespaceStructure] Namespace definition
+ * @param {Object} [tagList] Tag definition
+ * @param {Object} [conditionalViews] Conditional view definition
+ */
+Controller.prototype.initialize = function ( filterStructure, namespaceStructure, tagList, conditionalViews ) {
+       var parsedSavedQueries, pieces,
+               displayConfig = mw.config.get( 'StructuredChangeFiltersDisplayConfig' ),
+               defaultSavedQueryExists = mw.config.get( 'wgStructuredChangeFiltersDefaultSavedQueryExists' ),
+               controller = this,
+               views = $.extend( true, {}, conditionalViews ),
+               items = [],
+               uri = new mw.Uri();
+
+       // Prepare views
+       if ( namespaceStructure ) {
+               items = [];
+               // eslint-disable-next-line no-jquery/no-each-util
+               $.each( namespaceStructure, function ( namespaceID, label ) {
+                       // Build and clean up the individual namespace items definition
+                       items.push( {
+                               name: namespaceID,
+                               label: label || mw.msg( 'blanknamespace' ),
+                               description: '',
+                               identifiers: [
+                                       mw.Title.isTalkNamespace( namespaceID ) ?
+                                               'talk' : 'subject'
+                               ],
+                               cssClass: 'mw-changeslist-ns-' + namespaceID
                        } );
+               } );
 
-                       views.namespaces = {
+               views.namespaces = {
+                       title: mw.msg( 'namespaces' ),
+                       trigger: ':',
+                       groups: [ {
+                               // Group definition (single group)
+                               name: 'namespace', // parameter name is singular
+                               type: 'string_options',
                                title: mw.msg( 'namespaces' ),
-                               trigger: ':',
-                               groups: [ {
-                                       // Group definition (single group)
-                                       name: 'namespace', // parameter name is singular
-                                       type: 'string_options',
-                                       title: mw.msg( 'namespaces' ),
-                                       labelPrefixKey: { default: 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' },
-                                       separator: ';',
-                                       fullCoverage: true,
-                                       filters: items
-                               } ]
-                       };
-                       views.invert = {
-                               groups: [
-                                       {
-                                               name: 'invertGroup',
-                                               type: 'boolean',
-                                               hidden: true,
-                                               filters: [ {
-                                                       name: 'invert',
-                                                       default: '0'
-                                               } ]
-                                       } ]
-                       };
-               }
-               if ( tagList ) {
-                       views.tags = {
-                               title: mw.msg( 'rcfilters-view-tags' ),
-                               trigger: '#',
-                               groups: [ {
-                                       // Group definition (single group)
-                                       name: 'tagfilter', // Parameter name
-                                       type: 'string_options',
-                                       title: 'rcfilters-view-tags', // Message key
-                                       labelPrefixKey: 'rcfilters-tag-prefix-tags',
-                                       separator: '|',
-                                       fullCoverage: false,
-                                       filters: tagList
-                               } ]
-                       };
-               }
-
-               // Add parameter range operations
-               views.range = {
-                       groups: [
-                               {
-                                       name: 'limit',
-                                       type: 'single_option',
-                                       title: '', // Because it's a hidden group, this title actually appears nowhere
-                                       hidden: true,
-                                       allowArbitrary: true,
-                                       // FIXME: $.isNumeric is deprecated
-                                       validate: $.isNumeric,
-                                       range: {
-                                               min: 0, // The server normalizes negative numbers to 0 results
-                                               max: 1000
-                                       },
-                                       sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); },
-                                       default: mw.user.options.get( this.limitPreferenceName, displayConfig.limitDefault ),
-                                       sticky: true,
-                                       filters: displayConfig.limitArray.map( function ( num ) {
-                                               return controller._createFilterDataFromNumber( num, num );
-                                       } )
-                               },
-                               {
-                                       name: 'days',
-                                       type: 'single_option',
-                                       title: '', // Because it's a hidden group, this title actually appears nowhere
-                                       hidden: true,
-                                       allowArbitrary: true,
-                                       // FIXME: $.isNumeric is deprecated
-                                       validate: $.isNumeric,
-                                       range: {
-                                               min: 0,
-                                               max: displayConfig.maxDays
-                                       },
-                                       sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); },
-                                       numToLabelFunc: function ( i ) {
-                                               return Number( i ) < 1 ?
-                                                       ( Number( i ) * 24 ).toFixed( 2 ) :
-                                                       Number( i );
-                                       },
-                                       default: mw.user.options.get( this.daysPreferenceName, displayConfig.daysDefault ),
-                                       sticky: true,
-                                       filters: [
-                                               // Hours (1, 2, 6, 12)
-                                               0.04166, 0.0833, 0.25, 0.5
-                                       // Days
-                                       ].concat( displayConfig.daysArray )
-                                               .map( function ( num ) {
-                                                       return controller._createFilterDataFromNumber(
-                                                               num,
-                                                               // Convert fractions of days to number of hours for the labels
-                                                               num < 1 ? Math.round( num * 24 ) : num
-                                                       );
-                                               } )
-                               }
-                       ]
+                               labelPrefixKey: { default: 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' },
+                               separator: ';',
+                               fullCoverage: true,
+                               filters: items
+                       } ]
                };
-
-               views.display = {
+               views.invert = {
                        groups: [
                                {
-                                       name: 'display',
+                                       name: 'invertGroup',
                                        type: 'boolean',
-                                       title: '', // Because it's a hidden group, this title actually appears nowhere
                                        hidden: true,
-                                       sticky: true,
-                                       filters: [
-                                               {
-                                                       name: 'enhanced',
-                                                       default: String( mw.user.options.get( 'usenewrc', 0 ) )
-                                               }
-                                       ]
-                               }
-                       ]
+                                       filters: [ {
+                                               name: 'invert',
+                                               default: '0'
+                                       } ]
+                               } ]
                };
-
-               // Before we do anything, we need to see if we require additional items in the
-               // groups that have 'AllowArbitrary'. For the moment, those are only single_option
-               // groups; if we ever expand it, this might need further generalization:
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( views, function ( viewName, viewData ) {
-                       viewData.groups.forEach( function ( groupData ) {
-                               var extraValues = [];
-                               if ( groupData.allowArbitrary ) {
-                                       // If the value in the URI isn't in the group, add it
-                                       if ( uri.query[ groupData.name ] !== undefined ) {
-                                               extraValues.push( uri.query[ groupData.name ] );
-                                       }
-                                       // If the default value isn't in the group, add it
-                                       if ( groupData.default !== undefined ) {
-                                               extraValues.push( String( groupData.default ) );
-                                       }
-                                       controller.addNumberValuesToGroup( groupData, extraValues );
-                               }
-                       } );
-               } );
-
-               // Initialize the model
-               this.filtersModel.initializeFilters( filterStructure, views );
-
-               this.uriProcessor = new UriProcessor(
-                       this.filtersModel,
-                       { normalizeTarget: this.normalizeTarget }
-               );
-
-               if ( !mw.user.isAnon() ) {
-                       try {
-                               parsedSavedQueries = JSON.parse( mw.user.options.get( this.savedQueriesPreferenceName ) || '{}' );
-                       } catch ( err ) {
-                               parsedSavedQueries = {};
-                       }
-
-                       // Initialize saved queries
-                       this.savedQueriesModel.initialize( parsedSavedQueries );
-                       if ( this.savedQueriesModel.isConverted() ) {
-                               // Since we know we converted, we're going to re-save
-                               // the queries so they are now migrated to the new format
-                               this._saveSavedQueries();
-                       }
-               }
-
-               if ( defaultSavedQueryExists ) {
-                       // This came from the server, meaning that we have a default
-                       // saved query, but the server could not load it, probably because
-                       // it was pre-conversion to the new format.
-                       // We need to load this query again
-                       this.applySavedQuery( this.savedQueriesModel.getDefault() );
-               } else {
-                       // There are either recognized parameters in the URL
-                       // or there are none, but there is also no default
-                       // saved query (so defaults are from the backend)
-                       // We want to update the state but not fetch results
-                       // again
-                       this.updateStateFromUrl( false );
-
-                       pieces = this._extractChangesListInfo( $( '#mw-content-text' ) );
-
-                       // Update the changes list with the existing data
-                       // so it gets processed
-                       this.changesListModel.update(
-                               pieces.changes,
-                               pieces.fieldset,
-                               pieces.noResultsDetails,
-                               true // We're using existing DOM elements
-                       );
-               }
-
-               this.initialized = true;
-               this.switchView( 'default' );
-
-               if ( this.pollingRate ) {
-                       this._scheduleLiveUpdate();
-               }
-       };
-
-       /**
-        * Check if the controller has finished initializing.
-        * @return {boolean} Controller is initialized
-        */
-       Controller.prototype.isInitialized = function () {
-               return this.initialized;
-       };
-
-       /**
-        * Extracts information from the changes list DOM
-        *
-        * @param {jQuery} $root Root DOM to find children from
-        * @param {boolean} [statusCode] Server response status code
-        * @return {Object} Information about changes list
-        * @return {Object|string} return.changes Changes list, or 'NO_RESULTS' if there are no results
-        *   (either normally or as an error)
-        * @return {string} [return.noResultsDetails] 'NO_RESULTS_NORMAL' for a normal 0-result set,
-        *   'NO_RESULTS_TIMEOUT' for no results due to a timeout, or omitted for more than 0 results
-        * @return {jQuery} return.fieldset Fieldset
-        */
-       Controller.prototype._extractChangesListInfo = function ( $root, statusCode ) {
-               var info,
-                       $changesListContents = $root.find( '.mw-changeslist' ).first().contents(),
-                       areResults = !!$changesListContents.length,
-                       checkForLogout = !areResults && statusCode === 200;
-
-               // We check if user logged out on different tab/browser or the session has expired.
-               // 205 status code returned from the server, which indicates that we need to reload the page
-               // is not usable on WL page, because we get redirected to login page, which gives 200 OK
-               // status code (if everything else goes well).
-               // Bug: T177717
-               if ( checkForLogout && !!$root.find( '#wpName1' ).length ) {
-                       location.reload( false );
-                       return;
-               }
-
-               info = {
-                       changes: $changesListContents.length ? $changesListContents : 'NO_RESULTS',
-                       fieldset: $root.find( 'fieldset.cloptions' ).first()
+       }
+       if ( tagList ) {
+               views.tags = {
+                       title: mw.msg( 'rcfilters-view-tags' ),
+                       trigger: '#',
+                       groups: [ {
+                               // Group definition (single group)
+                               name: 'tagfilter', // Parameter name
+                               type: 'string_options',
+                               title: 'rcfilters-view-tags', // Message key
+                               labelPrefixKey: 'rcfilters-tag-prefix-tags',
+                               separator: '|',
+                               fullCoverage: false,
+                               filters: tagList
+                       } ]
                };
+       }
 
-               if ( !areResults ) {
-                       if ( $root.find( '.mw-changeslist-timeout' ).length ) {
-                               info.noResultsDetails = 'NO_RESULTS_TIMEOUT';
-                       } else if ( $root.find( '.mw-changeslist-notargetpage' ).length ) {
-                               info.noResultsDetails = 'NO_RESULTS_NO_TARGET_PAGE';
-                       } else if ( $root.find( '.mw-changeslist-invalidtargetpage' ).length ) {
-                               info.noResultsDetails = 'NO_RESULTS_INVALID_TARGET_PAGE';
-                       } else {
-                               info.noResultsDetails = 'NO_RESULTS_NORMAL';
+       // Add parameter range operations
+       views.range = {
+               groups: [
+                       {
+                               name: 'limit',
+                               type: 'single_option',
+                               title: '', // Because it's a hidden group, this title actually appears nowhere
+                               hidden: true,
+                               allowArbitrary: true,
+                               // FIXME: $.isNumeric is deprecated
+                               validate: $.isNumeric,
+                               range: {
+                                       min: 0, // The server normalizes negative numbers to 0 results
+                                       max: 1000
+                               },
+                               sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); },
+                               default: mw.user.options.get( this.limitPreferenceName, displayConfig.limitDefault ),
+                               sticky: true,
+                               filters: displayConfig.limitArray.map( function ( num ) {
+                                       return controller._createFilterDataFromNumber( num, num );
+                               } )
+                       },
+                       {
+                               name: 'days',
+                               type: 'single_option',
+                               title: '', // Because it's a hidden group, this title actually appears nowhere
+                               hidden: true,
+                               allowArbitrary: true,
+                               // FIXME: $.isNumeric is deprecated
+                               validate: $.isNumeric,
+                               range: {
+                                       min: 0,
+                                       max: displayConfig.maxDays
+                               },
+                               sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); },
+                               numToLabelFunc: function ( i ) {
+                                       return Number( i ) < 1 ?
+                                               ( Number( i ) * 24 ).toFixed( 2 ) :
+                                               Number( i );
+                               },
+                               default: mw.user.options.get( this.daysPreferenceName, displayConfig.daysDefault ),
+                               sticky: true,
+                               filters: [
+                                       // Hours (1, 2, 6, 12)
+                                       0.04166, 0.0833, 0.25, 0.5
+                               // Days
+                               ].concat( displayConfig.daysArray )
+                                       .map( function ( num ) {
+                                               return controller._createFilterDataFromNumber(
+                                                       num,
+                                                       // Convert fractions of days to number of hours for the labels
+                                                       num < 1 ? Math.round( num * 24 ) : num
+                                               );
+                                       } )
                        }
-               }
-
-               return info;
+               ]
        };
 
-       /**
-        * Create filter data from a number, for the filters that are numerical value
-        *
-        * @param {number} num Number
-        * @param {number} numForDisplay Number for the label
-        * @return {Object} Filter data
-        */
-       Controller.prototype._createFilterDataFromNumber = function ( num, numForDisplay ) {
-               return {
-                       name: String( num ),
-                       label: mw.language.convertNumber( numForDisplay )
-               };
+       views.display = {
+               groups: [
+                       {
+                               name: 'display',
+                               type: 'boolean',
+                               title: '', // Because it's a hidden group, this title actually appears nowhere
+                               hidden: true,
+                               sticky: true,
+                               filters: [
+                                       {
+                                               name: 'enhanced',
+                                               default: String( mw.user.options.get( 'usenewrc', 0 ) )
+                                       }
+                               ]
+                       }
+               ]
        };
 
-       /**
-        * Add an arbitrary values to groups that allow arbitrary values
-        *
-        * @param {Object} groupData Group data
-        * @param {string|string[]} arbitraryValues An array of arbitrary values to add to the group
-        */
-       Controller.prototype.addNumberValuesToGroup = function ( groupData, arbitraryValues ) {
-               var controller = this,
-                       normalizeWithinRange = function ( range, val ) {
-                               if ( val < range.min ) {
-                                       return range.min; // Min
-                               } else if ( val >= range.max ) {
-                                       return range.max; // Max
+       // Before we do anything, we need to see if we require additional items in the
+       // groups that have 'AllowArbitrary'. For the moment, those are only single_option
+       // groups; if we ever expand it, this might need further generalization:
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( views, function ( viewName, viewData ) {
+               viewData.groups.forEach( function ( groupData ) {
+                       var extraValues = [];
+                       if ( groupData.allowArbitrary ) {
+                               // If the value in the URI isn't in the group, add it
+                               if ( uri.query[ groupData.name ] !== undefined ) {
+                                       extraValues.push( uri.query[ groupData.name ] );
                                }
-                               return val;
-                       };
-
-               arbitraryValues = Array.isArray( arbitraryValues ) ? arbitraryValues : [ arbitraryValues ];
-
-               // Normalize the arbitrary values and the default value for a range
-               if ( groupData.range ) {
-                       arbitraryValues = arbitraryValues.map( function ( val ) {
-                               return normalizeWithinRange( groupData.range, val );
-                       } );
-
-                       // Normalize the default, since that's user defined
-                       if ( groupData.default !== undefined ) {
-                               groupData.default = String( normalizeWithinRange( groupData.range, groupData.default ) );
-                       }
-               }
-
-               // This is only true for single_option group
-               // We assume these are the only groups that will allow for
-               // arbitrary, since it doesn't make any sense for the other
-               // groups.
-               arbitraryValues.forEach( function ( val ) {
-                       if (
-                               // If the group allows for arbitrary data
-                               groupData.allowArbitrary &&
-                               // and it is single_option (or string_options, but we
-                               // don't have cases of those yet, nor do we plan to)
-                               groupData.type === 'single_option' &&
-                               // and, if there is a validate method and it passes on
-                               // the data
-                               ( !groupData.validate || groupData.validate( val ) ) &&
-                               // but if that value isn't already in the definition
-                               groupData.filters
-                                       .map( function ( filterData ) {
-                                               return String( filterData.name );
-                                       } )
-                                       .indexOf( String( val ) ) === -1
-                       ) {
-                               // Add the filter information
-                               groupData.filters.push( controller._createFilterDataFromNumber(
-                                       val,
-                                       groupData.numToLabelFunc ?
-                                               groupData.numToLabelFunc( val ) :
-                                               val
-                               ) );
-
-                               // If there's a sort function set up, re-sort the values
-                               if ( groupData.sortFunc ) {
-                                       groupData.filters.sort( groupData.sortFunc );
+                               // If the default value isn't in the group, add it
+                               if ( groupData.default !== undefined ) {
+                                       extraValues.push( String( groupData.default ) );
                                }
+                               controller.addNumberValuesToGroup( groupData, extraValues );
                        }
                } );
-       };
+       } );
 
-       /**
-        * Reset to default filters
-        */
-       Controller.prototype.resetToDefaults = function () {
-               var params = this._getDefaultParams();
-               if ( this.applyParamChange( params ) ) {
-                       // Only update the changes list if there was a change to actual filters
-                       this.updateChangesList();
-               } else {
-                       this.uriProcessor.updateURL( params );
-               }
-       };
-
-       /**
-        * Check whether the default values of the filters are all false.
-        *
-        * @return {boolean} Defaults are all false
-        */
-       Controller.prototype.areDefaultsEmpty = function () {
-               return $.isEmptyObject( this._getDefaultParams() );
-       };
+       // Initialize the model
+       this.filtersModel.initializeFilters( filterStructure, views );
 
-       /**
-        * Empty all selected filters
-        */
-       Controller.prototype.emptyFilters = function () {
-               var highlightedFilterNames = this.filtersModel.getHighlightedItems()
-                       .map( function ( filterItem ) { return { name: filterItem.getName() }; } );
+       this.uriProcessor = new UriProcessor(
+               this.filtersModel,
+               { normalizeTarget: this.normalizeTarget }
+       );
 
-               if ( this.applyParamChange( {} ) ) {
-                       // Only update the changes list if there was a change to actual filters
-                       this.updateChangesList();
-               } else {
-                       this.uriProcessor.updateURL();
+       if ( !mw.user.isAnon() ) {
+               try {
+                       parsedSavedQueries = JSON.parse( mw.user.options.get( this.savedQueriesPreferenceName ) || '{}' );
+               } catch ( err ) {
+                       parsedSavedQueries = {};
                }
 
-               if ( highlightedFilterNames ) {
-                       this._trackHighlight( 'clearAll', highlightedFilterNames );
+               // Initialize saved queries
+               this.savedQueriesModel.initialize( parsedSavedQueries );
+               if ( this.savedQueriesModel.isConverted() ) {
+                       // Since we know we converted, we're going to re-save
+                       // the queries so they are now migrated to the new format
+                       this._saveSavedQueries();
                }
+       }
+
+       if ( defaultSavedQueryExists ) {
+               // This came from the server, meaning that we have a default
+               // saved query, but the server could not load it, probably because
+               // it was pre-conversion to the new format.
+               // We need to load this query again
+               this.applySavedQuery( this.savedQueriesModel.getDefault() );
+       } else {
+               // There are either recognized parameters in the URL
+               // or there are none, but there is also no default
+               // saved query (so defaults are from the backend)
+               // We want to update the state but not fetch results
+               // again
+               this.updateStateFromUrl( false );
+
+               pieces = this._extractChangesListInfo( $( '#mw-content-text' ) );
+
+               // Update the changes list with the existing data
+               // so it gets processed
+               this.changesListModel.update(
+                       pieces.changes,
+                       pieces.fieldset,
+                       pieces.noResultsDetails,
+                       true // We're using existing DOM elements
+               );
+       }
+
+       this.initialized = true;
+       this.switchView( 'default' );
+
+       if ( this.pollingRate ) {
+               this._scheduleLiveUpdate();
+       }
+};
+
+/**
+ * Check if the controller has finished initializing.
+ * @return {boolean} Controller is initialized
+ */
+Controller.prototype.isInitialized = function () {
+       return this.initialized;
+};
+
+/**
+ * Extracts information from the changes list DOM
+ *
+ * @param {jQuery} $root Root DOM to find children from
+ * @param {boolean} [statusCode] Server response status code
+ * @return {Object} Information about changes list
+ * @return {Object|string} return.changes Changes list, or 'NO_RESULTS' if there are no results
+ *   (either normally or as an error)
+ * @return {string} [return.noResultsDetails] 'NO_RESULTS_NORMAL' for a normal 0-result set,
+ *   'NO_RESULTS_TIMEOUT' for no results due to a timeout, or omitted for more than 0 results
+ * @return {jQuery} return.fieldset Fieldset
+ */
+Controller.prototype._extractChangesListInfo = function ( $root, statusCode ) {
+       var info,
+               $changesListContents = $root.find( '.mw-changeslist' ).first().contents(),
+               areResults = !!$changesListContents.length,
+               checkForLogout = !areResults && statusCode === 200;
+
+       // We check if user logged out on different tab/browser or the session has expired.
+       // 205 status code returned from the server, which indicates that we need to reload the page
+       // is not usable on WL page, because we get redirected to login page, which gives 200 OK
+       // status code (if everything else goes well).
+       // Bug: T177717
+       if ( checkForLogout && !!$root.find( '#wpName1' ).length ) {
+               location.reload( false );
+               return;
+       }
+
+       info = {
+               changes: $changesListContents.length ? $changesListContents : 'NO_RESULTS',
+               fieldset: $root.find( 'fieldset.cloptions' ).first()
        };
 
-       /**
-        * Update the selected state of a filter
-        *
-        * @param {string} filterName Filter name
-        * @param {boolean} [isSelected] Filter selected state
-        */
-       Controller.prototype.toggleFilterSelect = function ( filterName, isSelected ) {
-               var filterItem = this.filtersModel.getItemByName( filterName );
-
-               if ( !filterItem ) {
-                       // If no filter was found, break
-                       return;
-               }
-
-               isSelected = isSelected === undefined ? !filterItem.isSelected() : isSelected;
-
-               if ( filterItem.isSelected() !== isSelected ) {
-                       this.filtersModel.toggleFilterSelected( filterName, isSelected );
-
-                       this.updateChangesList();
-
-                       // Check filter interactions
-                       this.filtersModel.reassessFilterInteractions( filterItem );
+       if ( !areResults ) {
+               if ( $root.find( '.mw-changeslist-timeout' ).length ) {
+                       info.noResultsDetails = 'NO_RESULTS_TIMEOUT';
+               } else if ( $root.find( '.mw-changeslist-notargetpage' ).length ) {
+                       info.noResultsDetails = 'NO_RESULTS_NO_TARGET_PAGE';
+               } else if ( $root.find( '.mw-changeslist-invalidtargetpage' ).length ) {
+                       info.noResultsDetails = 'NO_RESULTS_INVALID_TARGET_PAGE';
+               } else {
+                       info.noResultsDetails = 'NO_RESULTS_NORMAL';
                }
+       }
+
+       return info;
+};
+
+/**
+ * Create filter data from a number, for the filters that are numerical value
+ *
+ * @param {number} num Number
+ * @param {number} numForDisplay Number for the label
+ * @return {Object} Filter data
+ */
+Controller.prototype._createFilterDataFromNumber = function ( num, numForDisplay ) {
+       return {
+               name: String( num ),
+               label: mw.language.convertNumber( numForDisplay )
        };
-
-       /**
-        * Clear both highlight and selection of a filter
-        *
-        * @param {string} filterName Name of the filter item
-        */
-       Controller.prototype.clearFilter = function ( filterName ) {
-               var filterItem = this.filtersModel.getItemByName( filterName ),
-                       isHighlighted = filterItem.isHighlighted(),
-                       isSelected = filterItem.isSelected();
-
-               if ( isSelected || isHighlighted ) {
-                       this.filtersModel.clearHighlightColor( filterName );
-                       this.filtersModel.toggleFilterSelected( filterName, false );
-
-                       if ( isSelected ) {
-                               // Only update the changes list if the filter changed
-                               // its selection state. If it only changed its highlight
-                               // then don't reload
-                               this.updateChangesList();
+};
+
+/**
+ * Add an arbitrary values to groups that allow arbitrary values
+ *
+ * @param {Object} groupData Group data
+ * @param {string|string[]} arbitraryValues An array of arbitrary values to add to the group
+ */
+Controller.prototype.addNumberValuesToGroup = function ( groupData, arbitraryValues ) {
+       var controller = this,
+               normalizeWithinRange = function ( range, val ) {
+                       if ( val < range.min ) {
+                               return range.min; // Min
+                       } else if ( val >= range.max ) {
+                               return range.max; // Max
                        }
+                       return val;
+               };
 
-                       this.filtersModel.reassessFilterInteractions( filterItem );
-
-                       // Log filter grouping
-                       this.trackFilterGroupings( 'removefilter' );
-               }
-
-               if ( isHighlighted ) {
-                       this._trackHighlight( 'clear', filterName );
-               }
-       };
+       arbitraryValues = Array.isArray( arbitraryValues ) ? arbitraryValues : [ arbitraryValues ];
 
-       /**
-        * Toggle the highlight feature on and off
-        */
-       Controller.prototype.toggleHighlight = function () {
-               this.filtersModel.toggleHighlight();
-               this.uriProcessor.updateURL();
+       // Normalize the arbitrary values and the default value for a range
+       if ( groupData.range ) {
+               arbitraryValues = arbitraryValues.map( function ( val ) {
+                       return normalizeWithinRange( groupData.range, val );
+               } );
 
-               if ( this.filtersModel.isHighlightEnabled() ) {
-                       mw.hook( 'RcFilters.highlight.enable' ).fire();
+               // Normalize the default, since that's user defined
+               if ( groupData.default !== undefined ) {
+                       groupData.default = String( normalizeWithinRange( groupData.range, groupData.default ) );
                }
-       };
+       }
 
-       /**
-        * Toggle the namespaces inverted feature on and off
-        */
-       Controller.prototype.toggleInvertedNamespaces = function () {
-               this.filtersModel.toggleInvertedNamespaces();
+       // This is only true for single_option group
+       // We assume these are the only groups that will allow for
+       // arbitrary, since it doesn't make any sense for the other
+       // groups.
+       arbitraryValues.forEach( function ( val ) {
                if (
-                       this.filtersModel.getFiltersByView( 'namespaces' ).filter(
-                               function ( filterItem ) { return filterItem.isSelected(); }
-                       ).length
+                       // If the group allows for arbitrary data
+                       groupData.allowArbitrary &&
+                       // and it is single_option (or string_options, but we
+                       // don't have cases of those yet, nor do we plan to)
+                       groupData.type === 'single_option' &&
+                       // and, if there is a validate method and it passes on
+                       // the data
+                       ( !groupData.validate || groupData.validate( val ) ) &&
+                       // but if that value isn't already in the definition
+                       groupData.filters
+                               .map( function ( filterData ) {
+                                       return String( filterData.name );
+                               } )
+                               .indexOf( String( val ) ) === -1
                ) {
-                       // Only re-fetch results if there are namespace items that are actually selected
-                       this.updateChangesList();
-               } else {
-                       this.uriProcessor.updateURL();
-               }
-       };
-
-       /**
-        * Set the value of the 'showlinkedto' parameter
-        * @param {boolean} value
-        */
-       Controller.prototype.setShowLinkedTo = function ( value ) {
-               var targetItem = this.filtersModel.getGroup( 'page' ).getItemByParamName( 'target' ),
-                       showLinkedToItem = this.filtersModel.getGroup( 'toOrFrom' ).getItemByParamName( 'showlinkedto' );
-
-               this.filtersModel.toggleFilterSelected( showLinkedToItem.getName(), value );
-               this.uriProcessor.updateURL();
-               // reload the results only when target is set
-               if ( targetItem.getValue() ) {
-                       this.updateChangesList();
+                       // Add the filter information
+                       groupData.filters.push( controller._createFilterDataFromNumber(
+                               val,
+                               groupData.numToLabelFunc ?
+                                       groupData.numToLabelFunc( val ) :
+                                       val
+                       ) );
+
+                       // If there's a sort function set up, re-sort the values
+                       if ( groupData.sortFunc ) {
+                               groupData.filters.sort( groupData.sortFunc );
+                       }
                }
-       };
-
-       /**
-        * Set the target page
-        * @param {string} page
       */
-       Controller.prototype.setTargetPage = function ( page ) {
-               var targetItem = this.filtersModel.getGroup( 'page' ).getItemByParamName( 'target' );
-               targetItem.setValue( page );
-               this.uriProcessor.updateURL();
+       } );
+};
+
+/**
+ * Reset to default filters
+ */
+Controller.prototype.resetToDefaults = function () {
+       var params = this._getDefaultParams();
+       if ( this.applyParamChange( params ) ) {
+               // Only update the changes list if there was a change to actual filters
                this.updateChangesList();
-       };
-
-       /**
-        * Set the highlight color for a filter item
-        *
-        * @param {string} filterName Name of the filter item
-        * @param {string} color Selected color
-        */
-       Controller.prototype.setHighlightColor = function ( filterName, color ) {
-               this.filtersModel.setHighlightColor( filterName, color );
-               this.uriProcessor.updateURL();
-               this._trackHighlight( 'set', { name: filterName, color: color } );
-       };
-
-       /**
-        * Clear highlight for a filter item
-        *
-        * @param {string} filterName Name of the filter item
-        */
-       Controller.prototype.clearHighlightColor = function ( filterName ) {
-               this.filtersModel.clearHighlightColor( filterName );
+       } else {
+               this.uriProcessor.updateURL( params );
+       }
+};
+
+/**
+ * Check whether the default values of the filters are all false.
+ *
+ * @return {boolean} Defaults are all false
+ */
+Controller.prototype.areDefaultsEmpty = function () {
+       return $.isEmptyObject( this._getDefaultParams() );
+};
+
+/**
+ * Empty all selected filters
+ */
+Controller.prototype.emptyFilters = function () {
+       var highlightedFilterNames = this.filtersModel.getHighlightedItems()
+               .map( function ( filterItem ) { return { name: filterItem.getName() }; } );
+
+       if ( this.applyParamChange( {} ) ) {
+               // Only update the changes list if there was a change to actual filters
+               this.updateChangesList();
+       } else {
                this.uriProcessor.updateURL();
-               this._trackHighlight( 'clear', filterName );
-       };
+       }
 
-       /**
-        * Enable or disable live updates.
-        * @param {boolean} enable True to enable, false to disable
-        */
-       Controller.prototype.toggleLiveUpdate = function ( enable ) {
-               this.changesListModel.toggleLiveUpdate( enable );
-               if ( this.changesListModel.getLiveUpdate() && this.changesListModel.getNewChangesExist() ) {
-                       this.updateChangesList( null, this.LIVE_UPDATE );
-               }
-       };
+       if ( highlightedFilterNames ) {
+               this._trackHighlight( 'clearAll', highlightedFilterNames );
+       }
+};
 
-       /**
-        * Set a timeout for the next live update.
-        * @private
-        */
-       Controller.prototype._scheduleLiveUpdate = function () {
-               setTimeout( this._doLiveUpdate.bind( this ), this.pollingRate * 1000 );
-       };
+/**
+ * Update the selected state of a filter
+ *
+ * @param {string} filterName Filter name
+ * @param {boolean} [isSelected] Filter selected state
+ */
+Controller.prototype.toggleFilterSelect = function ( filterName, isSelected ) {
+       var filterItem = this.filtersModel.getItemByName( filterName );
 
-       /**
-        * Perform a live update.
-        * @private
-        */
-       Controller.prototype._doLiveUpdate = function () {
-               if ( !this._shouldCheckForNewChanges() ) {
-                       // skip this turn and check back later
-                       this._scheduleLiveUpdate();
-                       return;
-               }
+       if ( !filterItem ) {
+               // If no filter was found, break
+               return;
+       }
 
-               this._checkForNewChanges()
-                       .then( function ( statusCode ) {
-                               // no result is 204 with the 'peek' param
-                               // logged out is 205
-                               var newChanges = statusCode === 200;
+       isSelected = isSelected === undefined ? !filterItem.isSelected() : isSelected;
 
-                               if ( !this._shouldCheckForNewChanges() ) {
-                                       // by the time the response is received,
-                                       // it may not be appropriate anymore
-                                       return;
-                               }
+       if ( filterItem.isSelected() !== isSelected ) {
+               this.filtersModel.toggleFilterSelected( filterName, isSelected );
 
-                               // 205 is the status code returned from server when user's logged in/out
-                               // status is not matching while fetching live update changes.
-                               // This works only on Recent Changes page. For WL, look _extractChangesListInfo.
-                               // Bug: T177717
-                               if ( statusCode === 205 ) {
-                                       location.reload( false );
-                                       return;
-                               }
-
-                               if ( newChanges ) {
-                                       if ( this.changesListModel.getLiveUpdate() ) {
-                                               return this.updateChangesList( null, this.LIVE_UPDATE );
-                                       } else {
-                                               this.changesListModel.setNewChangesExist( true );
-                                       }
-                               }
-                       }.bind( this ) )
-                       .always( this._scheduleLiveUpdate.bind( this ) );
-       };
-
-       /**
-        * @return {boolean} It's appropriate to check for new changes now
-        * @private
-        */
-       Controller.prototype._shouldCheckForNewChanges = function () {
-               return !document.hidden &&
-                       !this.filtersModel.hasConflict() &&
-                       !this.changesListModel.getNewChangesExist() &&
-                       !this.updatingChangesList &&
-                       this.changesListModel.getNextFrom();
-       };
-
-       /**
-        * Check if new changes, newer than those currently shown, are available
-        *
-        * @return {jQuery.Promise} Promise object that resolves with a bool
-        *   specifying if there are new changes or not
-        *
-        * @private
-        */
-       Controller.prototype._checkForNewChanges = function () {
-               var params = {
-                       limit: 1,
-                       peek: 1, // bypasses ChangesList specific UI
-                       from: this.changesListModel.getNextFrom(),
-                       isAnon: mw.user.isAnon()
-               };
-               return this._queryChangesList( 'liveUpdate', params ).then(
-                       function ( data ) {
-                               return data.status;
-                       }
-               );
-       };
-
-       /**
-        * Show the new changes
-        *
-        * @return {jQuery.Promise} Promise object that resolves after
-        * fetching and showing the new changes
-        */
-       Controller.prototype.showNewChanges = function () {
-               return this.updateChangesList( null, this.SHOW_NEW_CHANGES );
-       };
-
-       /**
-        * Save the current model state as a saved query
-        *
-        * @param {string} [label] Label of the saved query
-        * @param {boolean} [setAsDefault=false] This query should be set as the default
-        */
-       Controller.prototype.saveCurrentQuery = function ( label, setAsDefault ) {
-               // Add item
-               this.savedQueriesModel.addNewQuery(
-                       label || mw.msg( 'rcfilters-savedqueries-defaultlabel' ),
-                       this.filtersModel.getCurrentParameterState( true ),
-                       setAsDefault
-               );
-
-               // Save item
-               this._saveSavedQueries();
-       };
-
-       /**
-        * Remove a saved query
-        *
-        * @param {string} queryID Query id
-        */
-       Controller.prototype.removeSavedQuery = function ( queryID ) {
-               this.savedQueriesModel.removeQuery( queryID );
-
-               this._saveSavedQueries();
-       };
-
-       /**
-        * Rename a saved query
-        *
-        * @param {string} queryID Query id
-        * @param {string} newLabel New label for the query
-        */
-       Controller.prototype.renameSavedQuery = function ( queryID, newLabel ) {
-               var queryItem = this.savedQueriesModel.getItemByID( queryID );
-
-               if ( queryItem ) {
-                       queryItem.updateLabel( newLabel );
-               }
-               this._saveSavedQueries();
-       };
-
-       /**
-        * Set a saved query as default
-        *
-        * @param {string} queryID Query Id. If null is given, default
-        *  query is reset.
-        */
-       Controller.prototype.setDefaultSavedQuery = function ( queryID ) {
-               this.savedQueriesModel.setDefault( queryID );
-               this._saveSavedQueries();
-       };
-
-       /**
-        * Load a saved query
-        *
-        * @param {string} queryID Query id
-        */
-       Controller.prototype.applySavedQuery = function ( queryID ) {
-               var currentMatchingQuery,
-                       params = this.savedQueriesModel.getItemParams( queryID );
-
-               currentMatchingQuery = this.findQueryMatchingCurrentState();
+               this.updateChangesList();
 
-               if (
-                       currentMatchingQuery &&
-                       currentMatchingQuery.getID() === queryID
-               ) {
-                       // If the query we want to load is the one that is already
-                       // loaded, don't reload it
-                       return;
-               }
+               // Check filter interactions
+               this.filtersModel.reassessFilterInteractions( filterItem );
+       }
+};
+
+/**
+ * Clear both highlight and selection of a filter
+ *
+ * @param {string} filterName Name of the filter item
+ */
+Controller.prototype.clearFilter = function ( filterName ) {
+       var filterItem = this.filtersModel.getItemByName( filterName ),
+               isHighlighted = filterItem.isHighlighted(),
+               isSelected = filterItem.isSelected();
+
+       if ( isSelected || isHighlighted ) {
+               this.filtersModel.clearHighlightColor( filterName );
+               this.filtersModel.toggleFilterSelected( filterName, false );
 
-               if ( this.applyParamChange( params ) ) {
-                       // Update changes list only if there was a difference in filter selection
+               if ( isSelected ) {
+                       // Only update the changes list if the filter changed
+                       // its selection state. If it only changed its highlight
+                       // then don't reload
                        this.updateChangesList();
-               } else {
-                       this.uriProcessor.updateURL( params );
-               }
-
-               // Log filter grouping
-               this.trackFilterGroupings( 'savedfilters' );
-       };
-
-       /**
-        * Check whether the current filter and highlight state exists
-        * in the saved queries model.
-        *
-        * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
-        */
-       Controller.prototype.findQueryMatchingCurrentState = function () {
-               return this.savedQueriesModel.findMatchingQuery(
-                       this.filtersModel.getCurrentParameterState( true )
-               );
-       };
-
-       /**
-        * Save the current state of the saved queries model with all
-        * query item representation in the user settings.
-        */
-       Controller.prototype._saveSavedQueries = function () {
-               var stringified, oldPrefValue,
-                       backupPrefName = this.savedQueriesPreferenceName + '-versionbackup',
-                       state = this.savedQueriesModel.getState();
-
-               // Stringify state
-               stringified = JSON.stringify( state );
-
-               if ( byteLength( stringified ) > 65535 ) {
-                       // Sanity check, since the preference can only hold that.
-                       return;
                }
 
-               if ( !this.wereSavedQueriesSaved && this.savedQueriesModel.isConverted() ) {
-                       // The queries were converted from the previous version
-                       // Keep the old string in the [prefname]-versionbackup
-                       oldPrefValue = mw.user.options.get( this.savedQueriesPreferenceName );
+               this.filtersModel.reassessFilterInteractions( filterItem );
 
-                       // Save the old preference in the backup preference
-                       new mw.Api().saveOption( backupPrefName, oldPrefValue );
-                       // Update the preference for this session
-                       mw.user.options.set( backupPrefName, oldPrefValue );
-               }
-
-               // Save the preference
-               new mw.Api().saveOption( this.savedQueriesPreferenceName, stringified );
-               // Update the preference for this session
-               mw.user.options.set( this.savedQueriesPreferenceName, stringified );
-
-               // Tag as already saved so we don't do this again
-               this.wereSavedQueriesSaved = true;
-       };
-
-       /**
-        * Update sticky preferences with current model state
-        */
-       Controller.prototype.updateStickyPreferences = function () {
-               // Update default sticky values with selected, whether they came from
-               // the initial defaults or from the URL value that is being normalized
-               this.updateDaysDefault( this.filtersModel.getGroup( 'days' ).findSelectedItems()[ 0 ].getParamName() );
-               this.updateLimitDefault( this.filtersModel.getGroup( 'limit' ).findSelectedItems()[ 0 ].getParamName() );
-
-               // TODO: Make these automatic by having the model go over sticky
-               // items and update their default values automatically
-       };
-
-       /**
-        * Update the limit default value
-        *
-        * @param {number} newValue New value
-        */
-       Controller.prototype.updateLimitDefault = function ( newValue ) {
-               this.updateNumericPreference( this.limitPreferenceName, newValue );
-       };
-
-       /**
-        * Update the days default value
-        *
-        * @param {number} newValue New value
-        */
-       Controller.prototype.updateDaysDefault = function ( newValue ) {
-               this.updateNumericPreference( this.daysPreferenceName, newValue );
-       };
-
-       /**
-        * Update the group by page default value
-        *
-        * @param {boolean} newValue New value
-        */
-       Controller.prototype.updateGroupByPageDefault = function ( newValue ) {
-               this.updateNumericPreference( 'usenewrc', Number( newValue ) );
-       };
-
-       /**
-        * Update the collapsed state value
-        *
-        * @param {boolean} isCollapsed Filter area is collapsed
-        */
-       Controller.prototype.updateCollapsedState = function ( isCollapsed ) {
-               this.updateNumericPreference( this.collapsedPreferenceName, Number( isCollapsed ) );
-       };
-
-       /**
-        * Update a numeric preference with a new value
-        *
-        * @param {string} prefName Preference name
-        * @param {number|string} newValue New value
-        */
-       Controller.prototype.updateNumericPreference = function ( prefName, newValue ) {
-               // FIXME: $.isNumeric is deprecated
-               // eslint-disable-next-line no-jquery/no-is-numeric
-               if ( !$.isNumeric( newValue ) ) {
-                       return;
-               }
-
-               newValue = Number( newValue );
-
-               if ( mw.user.options.get( prefName ) !== newValue ) {
-                       // Save the preference
-                       new mw.Api().saveOption( prefName, newValue );
-                       // Update the preference for this session
-                       mw.user.options.set( prefName, newValue );
-               }
-       };
+               // Log filter grouping
+               this.trackFilterGroupings( 'removefilter' );
+       }
 
-       /**
-        * Synchronize the URL with the current state of the filters
-        * without adding an history entry.
-        */
-       Controller.prototype.replaceUrl = function () {
+       if ( isHighlighted ) {
+               this._trackHighlight( 'clear', filterName );
+       }
+};
+
+/**
+ * Toggle the highlight feature on and off
+ */
+Controller.prototype.toggleHighlight = function () {
+       this.filtersModel.toggleHighlight();
+       this.uriProcessor.updateURL();
+
+       if ( this.filtersModel.isHighlightEnabled() ) {
+               mw.hook( 'RcFilters.highlight.enable' ).fire();
+       }
+};
+
+/**
+ * Toggle the namespaces inverted feature on and off
+ */
+Controller.prototype.toggleInvertedNamespaces = function () {
+       this.filtersModel.toggleInvertedNamespaces();
+       if (
+               this.filtersModel.getFiltersByView( 'namespaces' ).filter(
+                       function ( filterItem ) { return filterItem.isSelected(); }
+               ).length
+       ) {
+               // Only re-fetch results if there are namespace items that are actually selected
+               this.updateChangesList();
+       } else {
                this.uriProcessor.updateURL();
-       };
-
-       /**
-        * Update filter state (selection and highlighting) based
-        * on current URL values.
-        *
-        * @param {boolean} [fetchChangesList=true] Fetch new results into the changes
-        *  list based on the updated model.
-        */
-       Controller.prototype.updateStateFromUrl = function ( fetchChangesList ) {
-               fetchChangesList = fetchChangesList === undefined ? true : !!fetchChangesList;
-
-               this.uriProcessor.updateModelBasedOnQuery();
-
-               // Update the sticky preferences, in case we received a value
-               // from the URL
-               this.updateStickyPreferences();
+       }
+};
+
+/**
+ * Set the value of the 'showlinkedto' parameter
+ * @param {boolean} value
+ */
+Controller.prototype.setShowLinkedTo = function ( value ) {
+       var targetItem = this.filtersModel.getGroup( 'page' ).getItemByParamName( 'target' ),
+               showLinkedToItem = this.filtersModel.getGroup( 'toOrFrom' ).getItemByParamName( 'showlinkedto' );
+
+       this.filtersModel.toggleFilterSelected( showLinkedToItem.getName(), value );
+       this.uriProcessor.updateURL();
+       // reload the results only when target is set
+       if ( targetItem.getValue() ) {
+               this.updateChangesList();
+       }
+};
+
+/**
+ * Set the target page
+ * @param {string} page
+ */
+Controller.prototype.setTargetPage = function ( page ) {
+       var targetItem = this.filtersModel.getGroup( 'page' ).getItemByParamName( 'target' );
+       targetItem.setValue( page );
+       this.uriProcessor.updateURL();
+       this.updateChangesList();
+};
+
+/**
+ * Set the highlight color for a filter item
+ *
+ * @param {string} filterName Name of the filter item
+ * @param {string} color Selected color
+ */
+Controller.prototype.setHighlightColor = function ( filterName, color ) {
+       this.filtersModel.setHighlightColor( filterName, color );
+       this.uriProcessor.updateURL();
+       this._trackHighlight( 'set', { name: filterName, color: color } );
+};
+
+/**
+ * Clear highlight for a filter item
+ *
+ * @param {string} filterName Name of the filter item
+ */
+Controller.prototype.clearHighlightColor = function ( filterName ) {
+       this.filtersModel.clearHighlightColor( filterName );
+       this.uriProcessor.updateURL();
+       this._trackHighlight( 'clear', filterName );
+};
+
+/**
+ * Enable or disable live updates.
+ * @param {boolean} enable True to enable, false to disable
+ */
+Controller.prototype.toggleLiveUpdate = function ( enable ) {
+       this.changesListModel.toggleLiveUpdate( enable );
+       if ( this.changesListModel.getLiveUpdate() && this.changesListModel.getNewChangesExist() ) {
+               this.updateChangesList( null, this.LIVE_UPDATE );
+       }
+};
+
+/**
+ * Set a timeout for the next live update.
+ * @private
+ */
+Controller.prototype._scheduleLiveUpdate = function () {
+       setTimeout( this._doLiveUpdate.bind( this ), this.pollingRate * 1000 );
+};
+
+/**
+ * Perform a live update.
+ * @private
+ */
+Controller.prototype._doLiveUpdate = function () {
+       if ( !this._shouldCheckForNewChanges() ) {
+               // skip this turn and check back later
+               this._scheduleLiveUpdate();
+               return;
+       }
+
+       this._checkForNewChanges()
+               .then( function ( statusCode ) {
+                       // no result is 204 with the 'peek' param
+                       // logged out is 205
+                       var newChanges = statusCode === 200;
+
+                       if ( !this._shouldCheckForNewChanges() ) {
+                               // by the time the response is received,
+                               // it may not be appropriate anymore
+                               return;
+                       }
 
-               // Only update and fetch new results if it is requested
-               if ( fetchChangesList ) {
-                       this.updateChangesList();
-               }
-       };
+                       // 205 is the status code returned from server when user's logged in/out
+                       // status is not matching while fetching live update changes.
+                       // This works only on Recent Changes page. For WL, look _extractChangesListInfo.
+                       // Bug: T177717
+                       if ( statusCode === 205 ) {
+                               location.reload( false );
+                               return;
+                       }
 
-       /**
-        * Update the list of changes and notify the model
-        *
-        * @param {Object} [params] Extra parameters to add to the API call
-        * @param {string} [updateMode='filterChange'] One of 'filterChange', 'liveUpdate', 'showNewChanges', 'markSeen'
-        * @return {jQuery.Promise} Promise that is resolved when the update is complete
-        */
-       Controller.prototype.updateChangesList = function ( params, updateMode ) {
-               updateMode = updateMode === undefined ? this.FILTER_CHANGE : updateMode;
-
-               if ( updateMode === this.FILTER_CHANGE ) {
-                       this.uriProcessor.updateURL( params );
-               }
-               if ( updateMode === this.FILTER_CHANGE || updateMode === this.SHOW_NEW_CHANGES ) {
-                       this.changesListModel.invalidate();
-               }
-               this.changesListModel.setNewChangesExist( false );
-               this.updatingChangesList = true;
-               return this._fetchChangesList()
-                       .then(
-                               // Success
-                               function ( pieces ) {
-                                       var $changesListContent = pieces.changes,
-                                               $fieldset = pieces.fieldset;
-                                       this.changesListModel.update(
-                                               $changesListContent,
-                                               $fieldset,
-                                               pieces.noResultsDetails,
-                                               false,
-                                               // separator between old and new changes
-                                               updateMode === this.SHOW_NEW_CHANGES || updateMode === this.LIVE_UPDATE
-                                       );
-                               }.bind( this )
-                               // Do nothing for failure
-                       )
-                       .always( function () {
-                               this.updatingChangesList = false;
-                       }.bind( this ) );
+                       if ( newChanges ) {
+                               if ( this.changesListModel.getLiveUpdate() ) {
+                                       return this.updateChangesList( null, this.LIVE_UPDATE );
+                               } else {
+                                       this.changesListModel.setNewChangesExist( true );
+                               }
+                       }
+               }.bind( this ) )
+               .always( this._scheduleLiveUpdate.bind( this ) );
+};
+
+/**
+ * @return {boolean} It's appropriate to check for new changes now
+ * @private
+ */
+Controller.prototype._shouldCheckForNewChanges = function () {
+       return !document.hidden &&
+               !this.filtersModel.hasConflict() &&
+               !this.changesListModel.getNewChangesExist() &&
+               !this.updatingChangesList &&
+               this.changesListModel.getNextFrom();
+};
+
+/**
+ * Check if new changes, newer than those currently shown, are available
+ *
+ * @return {jQuery.Promise} Promise object that resolves with a bool
+ *   specifying if there are new changes or not
+ *
+ * @private
+ */
+Controller.prototype._checkForNewChanges = function () {
+       var params = {
+               limit: 1,
+               peek: 1, // bypasses ChangesList specific UI
+               from: this.changesListModel.getNextFrom(),
+               isAnon: mw.user.isAnon()
        };
-
-       /**
-        * Get an object representing the default parameter state, whether
-        * it is from the model defaults or from the saved queries.
-        *
-        * @return {Object} Default parameters
-        */
-       Controller.prototype._getDefaultParams = function () {
-               if ( this.savedQueriesModel.getDefault() ) {
-                       return this.savedQueriesModel.getDefaultParams();
-               } else {
-                       return this.filtersModel.getDefaultParams();
+       return this._queryChangesList( 'liveUpdate', params ).then(
+               function ( data ) {
+                       return data.status;
                }
-       };
+       );
+};
+
+/**
+ * Show the new changes
+ *
+ * @return {jQuery.Promise} Promise object that resolves after
+ * fetching and showing the new changes
+ */
+Controller.prototype.showNewChanges = function () {
+       return this.updateChangesList( null, this.SHOW_NEW_CHANGES );
+};
+
+/**
+ * Save the current model state as a saved query
+ *
+ * @param {string} [label] Label of the saved query
+ * @param {boolean} [setAsDefault=false] This query should be set as the default
+ */
+Controller.prototype.saveCurrentQuery = function ( label, setAsDefault ) {
+       // Add item
+       this.savedQueriesModel.addNewQuery(
+               label || mw.msg( 'rcfilters-savedqueries-defaultlabel' ),
+               this.filtersModel.getCurrentParameterState( true ),
+               setAsDefault
+       );
+
+       // Save item
+       this._saveSavedQueries();
+};
+
+/**
+ * Remove a saved query
+ *
+ * @param {string} queryID Query id
+ */
+Controller.prototype.removeSavedQuery = function ( queryID ) {
+       this.savedQueriesModel.removeQuery( queryID );
+
+       this._saveSavedQueries();
+};
+
+/**
+ * Rename a saved query
+ *
+ * @param {string} queryID Query id
+ * @param {string} newLabel New label for the query
+ */
+Controller.prototype.renameSavedQuery = function ( queryID, newLabel ) {
+       var queryItem = this.savedQueriesModel.getItemByID( queryID );
+
+       if ( queryItem ) {
+               queryItem.updateLabel( newLabel );
+       }
+       this._saveSavedQueries();
+};
+
+/**
+ * Set a saved query as default
+ *
+ * @param {string} queryID Query Id. If null is given, default
+ *  query is reset.
+ */
+Controller.prototype.setDefaultSavedQuery = function ( queryID ) {
+       this.savedQueriesModel.setDefault( queryID );
+       this._saveSavedQueries();
+};
+
+/**
+ * Load a saved query
+ *
+ * @param {string} queryID Query id
+ */
+Controller.prototype.applySavedQuery = function ( queryID ) {
+       var currentMatchingQuery,
+               params = this.savedQueriesModel.getItemParams( queryID );
+
+       currentMatchingQuery = this.findQueryMatchingCurrentState();
+
+       if (
+               currentMatchingQuery &&
+               currentMatchingQuery.getID() === queryID
+       ) {
+               // If the query we want to load is the one that is already
+               // loaded, don't reload it
+               return;
+       }
+
+       if ( this.applyParamChange( params ) ) {
+               // Update changes list only if there was a difference in filter selection
+               this.updateChangesList();
+       } else {
+               this.uriProcessor.updateURL( params );
+       }
+
+       // Log filter grouping
+       this.trackFilterGroupings( 'savedfilters' );
+};
+
+/**
+ * Check whether the current filter and highlight state exists
+ * in the saved queries model.
+ *
+ * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
+ */
+Controller.prototype.findQueryMatchingCurrentState = function () {
+       return this.savedQueriesModel.findMatchingQuery(
+               this.filtersModel.getCurrentParameterState( true )
+       );
+};
+
+/**
+ * Save the current state of the saved queries model with all
+ * query item representation in the user settings.
+ */
+Controller.prototype._saveSavedQueries = function () {
+       var stringified, oldPrefValue,
+               backupPrefName = this.savedQueriesPreferenceName + '-versionbackup',
+               state = this.savedQueriesModel.getState();
+
+       // Stringify state
+       stringified = JSON.stringify( state );
+
+       if ( byteLength( stringified ) > 65535 ) {
+               // Sanity check, since the preference can only hold that.
+               return;
+       }
+
+       if ( !this.wereSavedQueriesSaved && this.savedQueriesModel.isConverted() ) {
+               // The queries were converted from the previous version
+               // Keep the old string in the [prefname]-versionbackup
+               oldPrefValue = mw.user.options.get( this.savedQueriesPreferenceName );
+
+               // Save the old preference in the backup preference
+               new mw.Api().saveOption( backupPrefName, oldPrefValue );
+               // Update the preference for this session
+               mw.user.options.set( backupPrefName, oldPrefValue );
+       }
+
+       // Save the preference
+       new mw.Api().saveOption( this.savedQueriesPreferenceName, stringified );
+       // Update the preference for this session
+       mw.user.options.set( this.savedQueriesPreferenceName, stringified );
+
+       // Tag as already saved so we don't do this again
+       this.wereSavedQueriesSaved = true;
+};
+
+/**
+ * Update sticky preferences with current model state
+ */
+Controller.prototype.updateStickyPreferences = function () {
+       // Update default sticky values with selected, whether they came from
+       // the initial defaults or from the URL value that is being normalized
+       this.updateDaysDefault( this.filtersModel.getGroup( 'days' ).findSelectedItems()[ 0 ].getParamName() );
+       this.updateLimitDefault( this.filtersModel.getGroup( 'limit' ).findSelectedItems()[ 0 ].getParamName() );
+
+       // TODO: Make these automatic by having the model go over sticky
+       // items and update their default values automatically
+};
+
+/**
+ * Update the limit default value
+ *
+ * @param {number} newValue New value
+ */
+Controller.prototype.updateLimitDefault = function ( newValue ) {
+       this.updateNumericPreference( this.limitPreferenceName, newValue );
+};
+
+/**
+ * Update the days default value
+ *
+ * @param {number} newValue New value
+ */
+Controller.prototype.updateDaysDefault = function ( newValue ) {
+       this.updateNumericPreference( this.daysPreferenceName, newValue );
+};
+
+/**
+ * Update the group by page default value
+ *
+ * @param {boolean} newValue New value
+ */
+Controller.prototype.updateGroupByPageDefault = function ( newValue ) {
+       this.updateNumericPreference( 'usenewrc', Number( newValue ) );
+};
+
+/**
+ * Update the collapsed state value
+ *
+ * @param {boolean} isCollapsed Filter area is collapsed
+ */
+Controller.prototype.updateCollapsedState = function ( isCollapsed ) {
+       this.updateNumericPreference( this.collapsedPreferenceName, Number( isCollapsed ) );
+};
+
+/**
+ * Update a numeric preference with a new value
+ *
+ * @param {string} prefName Preference name
+ * @param {number|string} newValue New value
+ */
+Controller.prototype.updateNumericPreference = function ( prefName, newValue ) {
+       // FIXME: $.isNumeric is deprecated
+       // eslint-disable-next-line no-jquery/no-is-numeric
+       if ( !$.isNumeric( newValue ) ) {
+               return;
+       }
+
+       newValue = Number( newValue );
+
+       if ( mw.user.options.get( prefName ) !== newValue ) {
+               // Save the preference
+               new mw.Api().saveOption( prefName, newValue );
+               // Update the preference for this session
+               mw.user.options.set( prefName, newValue );
+       }
+};
+
+/**
+ * Synchronize the URL with the current state of the filters
+ * without adding an history entry.
+ */
+Controller.prototype.replaceUrl = function () {
+       this.uriProcessor.updateURL();
+};
+
+/**
+ * Update filter state (selection and highlighting) based
+ * on current URL values.
+ *
+ * @param {boolean} [fetchChangesList=true] Fetch new results into the changes
+ *  list based on the updated model.
+ */
+Controller.prototype.updateStateFromUrl = function ( fetchChangesList ) {
+       fetchChangesList = fetchChangesList === undefined ? true : !!fetchChangesList;
+
+       this.uriProcessor.updateModelBasedOnQuery();
+
+       // Update the sticky preferences, in case we received a value
+       // from the URL
+       this.updateStickyPreferences();
+
+       // Only update and fetch new results if it is requested
+       if ( fetchChangesList ) {
+               this.updateChangesList();
+       }
+};
+
+/**
+ * Update the list of changes and notify the model
+ *
+ * @param {Object} [params] Extra parameters to add to the API call
+ * @param {string} [updateMode='filterChange'] One of 'filterChange', 'liveUpdate', 'showNewChanges', 'markSeen'
+ * @return {jQuery.Promise} Promise that is resolved when the update is complete
+ */
+Controller.prototype.updateChangesList = function ( params, updateMode ) {
+       updateMode = updateMode === undefined ? this.FILTER_CHANGE : updateMode;
+
+       if ( updateMode === this.FILTER_CHANGE ) {
+               this.uriProcessor.updateURL( params );
+       }
+       if ( updateMode === this.FILTER_CHANGE || updateMode === this.SHOW_NEW_CHANGES ) {
+               this.changesListModel.invalidate();
+       }
+       this.changesListModel.setNewChangesExist( false );
+       this.updatingChangesList = true;
+       return this._fetchChangesList()
+               .then(
+                       // Success
+                       function ( pieces ) {
+                               var $changesListContent = pieces.changes,
+                                       $fieldset = pieces.fieldset;
+                               this.changesListModel.update(
+                                       $changesListContent,
+                                       $fieldset,
+                                       pieces.noResultsDetails,
+                                       false,
+                                       // separator between old and new changes
+                                       updateMode === this.SHOW_NEW_CHANGES || updateMode === this.LIVE_UPDATE
+                               );
+                       }.bind( this )
+                       // Do nothing for failure
+               )
+               .always( function () {
+                       this.updatingChangesList = false;
+               }.bind( this ) );
+};
+
+/**
+ * Get an object representing the default parameter state, whether
+ * it is from the model defaults or from the saved queries.
+ *
+ * @return {Object} Default parameters
+ */
+Controller.prototype._getDefaultParams = function () {
+       if ( this.savedQueriesModel.getDefault() ) {
+               return this.savedQueriesModel.getDefaultParams();
+       } else {
+               return this.filtersModel.getDefaultParams();
+       }
+};
+
+/**
+ * Query the list of changes from the server for the current filters
+ *
+ * @param {string} counterId Id for this request. To allow concurrent requests
+ *  not to invalidate each other.
+ * @param {Object} [params={}] Parameters to add to the query
+ *
+ * @return {jQuery.Promise} Promise object resolved with { content, status }
+ */
+Controller.prototype._queryChangesList = function ( counterId, params ) {
+       var uri = this.uriProcessor.getUpdatedUri(),
+               stickyParams = this.filtersModel.getStickyParamsValues(),
+               requestId,
+               latestRequest;
+
+       params = params || {};
+       params.action = 'render'; // bypasses MW chrome
+
+       uri.extend( params );
+
+       this.requestCounter[ counterId ] = this.requestCounter[ counterId ] || 0;
+       requestId = ++this.requestCounter[ counterId ];
+       latestRequest = function () {
+               return requestId === this.requestCounter[ counterId ];
+       }.bind( this );
+
+       // Sticky parameters override the URL params
+       // this is to make sure that whether we represent
+       // the sticky params in the URL or not (they may
+       // be normalized out) the sticky parameters are
+       // always being sent to the server with their
+       // current/default values
+       uri.extend( stickyParams );
+
+       return $.ajax( uri.toString(), { contentType: 'html' } )
+               .then(
+                       function ( content, message, jqXHR ) {
+                               if ( !latestRequest() ) {
+                                       return $.Deferred().reject();
+                               }
+                               return {
+                                       content: content,
+                                       status: jqXHR.status
+                               };
+                       },
+                       // RC returns 404 when there is no results
+                       function ( jqXHR ) {
+                               if ( latestRequest() ) {
+                                       return $.Deferred().resolve(
+                                               {
+                                                       content: jqXHR.responseText,
+                                                       status: jqXHR.status
+                                               }
+                                       ).promise();
+                               }
+                       }
+               );
+};
+
+/**
+ * Fetch the list of changes from the server for the current filters
+ *
+ * @return {jQuery.Promise} Promise object that will resolve with the changes list
+ *  and the fieldset.
+ */
+Controller.prototype._fetchChangesList = function () {
+       return this._queryChangesList( 'updateChangesList' )
+               .then(
+                       function ( data ) {
+                               var $parsed;
 
-       /**
-        * Query the list of changes from the server for the current filters
-        *
-        * @param {string} counterId Id for this request. To allow concurrent requests
-        *  not to invalidate each other.
-        * @param {Object} [params={}] Parameters to add to the query
-        *
-        * @return {jQuery.Promise} Promise object resolved with { content, status }
-        */
-       Controller.prototype._queryChangesList = function ( counterId, params ) {
-               var uri = this.uriProcessor.getUpdatedUri(),
-                       stickyParams = this.filtersModel.getStickyParamsValues(),
-                       requestId,
-                       latestRequest;
-
-               params = params || {};
-               params.action = 'render'; // bypasses MW chrome
-
-               uri.extend( params );
-
-               this.requestCounter[ counterId ] = this.requestCounter[ counterId ] || 0;
-               requestId = ++this.requestCounter[ counterId ];
-               latestRequest = function () {
-                       return requestId === this.requestCounter[ counterId ];
-               }.bind( this );
-
-               // Sticky parameters override the URL params
-               // this is to make sure that whether we represent
-               // the sticky params in the URL or not (they may
-               // be normalized out) the sticky parameters are
-               // always being sent to the server with their
-               // current/default values
-               uri.extend( stickyParams );
-
-               return $.ajax( uri.toString(), { contentType: 'html' } )
-                       .then(
-                               function ( content, message, jqXHR ) {
-                                       if ( !latestRequest() ) {
-                                               return $.Deferred().reject();
-                                       }
+                               // Status code 0 is not HTTP status code,
+                               // but is valid value of XMLHttpRequest status.
+                               // It is used for variety of network errors, for example
+                               // when an AJAX call was cancelled before getting the response
+                               if ( data && data.status === 0 ) {
                                        return {
-                                               content: content,
-                                               status: jqXHR.status
+                                               changes: 'NO_RESULTS',
+                                               // We need empty result set, to avoid exceptions because of undefined value
+                                               fieldset: $( [] ),
+                                               noResultsDetails: 'NO_RESULTS_NETWORK_ERROR'
                                        };
-                               },
-                               // RC returns 404 when there is no results
-                               function ( jqXHR ) {
-                                       if ( latestRequest() ) {
-                                               return $.Deferred().resolve(
-                                                       {
-                                                               content: jqXHR.responseText,
-                                                               status: jqXHR.status
-                                                       }
-                                               ).promise();
-                                       }
                                }
-                       );
-       };
-
-       /**
-        * Fetch the list of changes from the server for the current filters
-        *
-        * @return {jQuery.Promise} Promise object that will resolve with the changes list
-        *  and the fieldset.
-        */
-       Controller.prototype._fetchChangesList = function () {
-               return this._queryChangesList( 'updateChangesList' )
-                       .then(
-                               function ( data ) {
-                                       var $parsed;
-
-                                       // Status code 0 is not HTTP status code,
-                                       // but is valid value of XMLHttpRequest status.
-                                       // It is used for variety of network errors, for example
-                                       // when an AJAX call was cancelled before getting the response
-                                       if ( data && data.status === 0 ) {
-                                               return {
-                                                       changes: 'NO_RESULTS',
-                                                       // We need empty result set, to avoid exceptions because of undefined value
-                                                       fieldset: $( [] ),
-                                                       noResultsDetails: 'NO_RESULTS_NETWORK_ERROR'
-                                               };
-                                       }
-
-                                       $parsed = $( '<div>' ).append( $( $.parseHTML(
-                                               data ? data.content : ''
-                                       ) ) );
 
-                                       return this._extractChangesListInfo( $parsed, data.status );
-                               }.bind( this )
-                       );
-       };
+                               $parsed = $( '<div>' ).append( $( $.parseHTML(
+                                       data ? data.content : ''
+                               ) ) );
 
-       /**
-        * Track usage of highlight feature
-        *
-        * @param {string} action
-        * @param {Array|Object|string} filters
-        */
-       Controller.prototype._trackHighlight = function ( action, filters ) {
-               filters = typeof filters === 'string' ? { name: filters } : filters;
-               filters = !Array.isArray( filters ) ? [ filters ] : filters;
-               mw.track(
-                       'event.ChangesListHighlights',
-                       {
-                               action: action,
-                               filters: filters,
-                               userId: mw.user.getId()
-                       }
+                               return this._extractChangesListInfo( $parsed, data.status );
+                       }.bind( this )
                );
-       };
-
-       /**
-        * Track filter grouping usage
-        *
-        * @param {string} action Action taken
-        */
-       Controller.prototype.trackFilterGroupings = function ( action ) {
-               var controller = this,
-                       rightNow = new Date().getTime(),
-                       randomIdentifier = String( mw.user.sessionId() ) + String( rightNow ) + String( Math.random() ),
-                       // Get all current filters
-                       filters = this.filtersModel.findSelectedItems().map( function ( item ) {
-                               return item.getName();
-                       } );
-
-               action = action || 'filtermenu';
-
-               // Check if these filters were the ones we just logged previously
-               // (Don't log the same grouping twice, in case the user opens/closes)
-               // the menu without action, or with the same result
-               if (
-                       // Only log if the two arrays are different in size
-                       filters.length !== this.prevLoggedItems.length ||
-                       // Or if any filters are not the same as the cached filters
-                       filters.some( function ( filterName ) {
-                               return controller.prevLoggedItems.indexOf( filterName ) === -1;
-                       } ) ||
-                       // Or if any cached filters are not the same as given filters
-                       this.prevLoggedItems.some( function ( filterName ) {
-                               return filters.indexOf( filterName ) === -1;
-                       } )
-               ) {
-                       filters.forEach( function ( filterName ) {
-                               mw.track(
-                                       'event.ChangesListFilterGrouping',
-                                       {
-                                               action: action,
-                                               groupIdentifier: randomIdentifier,
-                                               filter: filterName,
-                                               userId: mw.user.getId()
-                                       }
-                               );
-                       } );
-
-                       // Cache the filter names
-                       this.prevLoggedItems = filters;
+};
+
+/**
+ * Track usage of highlight feature
+ *
+ * @param {string} action
+ * @param {Array|Object|string} filters
+ */
+Controller.prototype._trackHighlight = function ( action, filters ) {
+       filters = typeof filters === 'string' ? { name: filters } : filters;
+       filters = !Array.isArray( filters ) ? [ filters ] : filters;
+       mw.track(
+               'event.ChangesListHighlights',
+               {
+                       action: action,
+                       filters: filters,
+                       userId: mw.user.getId()
                }
-       };
-
-       /**
-        * Apply a change of parameters to the model state, and check whether
-        * the new state is different than the old state.
-        *
-        * @param  {Object} newParamState New parameter state to apply
-        * @return {boolean} New applied model state is different than the previous state
-        */
-       Controller.prototype.applyParamChange = function ( newParamState ) {
-               var after,
-                       before = this.filtersModel.getSelectedState();
-
-               this.filtersModel.updateStateFromParams( newParamState );
-
-               after = this.filtersModel.getSelectedState();
-
-               return !OO.compare( before, after );
-       };
-
-       /**
-        * Mark all changes as seen on Watchlist
-        */
-       Controller.prototype.markAllChangesAsSeen = function () {
-               var api = new mw.Api();
-               api.postWithToken( 'csrf', {
-                       formatversion: 2,
-                       action: 'setnotificationtimestamp',
-                       entirewatchlist: true
-               } ).then( function () {
-                       this.updateChangesList( null, 'markSeen' );
-               }.bind( this ) );
-       };
-
-       /**
-        * Set the current search for the system.
-        *
-        * @param {string} searchQuery Search query, including triggers
-        */
-       Controller.prototype.setSearch = function ( searchQuery ) {
-               this.filtersModel.setSearch( searchQuery );
-       };
-
-       /**
-        * Switch the view by changing the search query trigger
-        * without changing the search term
-        *
-        * @param  {string} view View to change to
-        */
-       Controller.prototype.switchView = function ( view ) {
-               this.setSearch(
-                       this.filtersModel.getViewTrigger( view ) +
-                       this.filtersModel.removeViewTriggers( this.filtersModel.getSearch() )
-               );
-       };
+       );
+};
+
+/**
+ * Track filter grouping usage
+ *
+ * @param {string} action Action taken
+ */
+Controller.prototype.trackFilterGroupings = function ( action ) {
+       var controller = this,
+               rightNow = new Date().getTime(),
+               randomIdentifier = String( mw.user.sessionId() ) + String( rightNow ) + String( Math.random() ),
+               // Get all current filters
+               filters = this.filtersModel.findSelectedItems().map( function ( item ) {
+                       return item.getName();
+               } );
 
-       /**
-        * Reset the search for a specific view. This means we null the search query
-        * and replace it with the relevant trigger for the requested view
-        *
-        * @param  {string} [view='default'] View to change to
-        */
-       Controller.prototype.resetSearchForView = function ( view ) {
-               view = view || 'default';
-
-               this.setSearch(
-                       this.filtersModel.getViewTrigger( view )
-               );
-       };
+       action = action || 'filtermenu';
+
+       // Check if these filters were the ones we just logged previously
+       // (Don't log the same grouping twice, in case the user opens/closes)
+       // the menu without action, or with the same result
+       if (
+               // Only log if the two arrays are different in size
+               filters.length !== this.prevLoggedItems.length ||
+               // Or if any filters are not the same as the cached filters
+               filters.some( function ( filterName ) {
+                       return controller.prevLoggedItems.indexOf( filterName ) === -1;
+               } ) ||
+               // Or if any cached filters are not the same as given filters
+               this.prevLoggedItems.some( function ( filterName ) {
+                       return filters.indexOf( filterName ) === -1;
+               } )
+       ) {
+               filters.forEach( function ( filterName ) {
+                       mw.track(
+                               'event.ChangesListFilterGrouping',
+                               {
+                                       action: action,
+                                       groupIdentifier: randomIdentifier,
+                                       filter: filterName,
+                                       userId: mw.user.getId()
+                               }
+                       );
+               } );
 
-       module.exports = Controller;
-}() );
+               // Cache the filter names
+               this.prevLoggedItems = filters;
+       }
+};
+
+/**
+ * Apply a change of parameters to the model state, and check whether
+ * the new state is different than the old state.
+ *
+ * @param  {Object} newParamState New parameter state to apply
+ * @return {boolean} New applied model state is different than the previous state
+ */
+Controller.prototype.applyParamChange = function ( newParamState ) {
+       var after,
+               before = this.filtersModel.getSelectedState();
+
+       this.filtersModel.updateStateFromParams( newParamState );
+
+       after = this.filtersModel.getSelectedState();
+
+       return !OO.compare( before, after );
+};
+
+/**
+ * Mark all changes as seen on Watchlist
+ */
+Controller.prototype.markAllChangesAsSeen = function () {
+       var api = new mw.Api();
+       api.postWithToken( 'csrf', {
+               formatversion: 2,
+               action: 'setnotificationtimestamp',
+               entirewatchlist: true
+       } ).then( function () {
+               this.updateChangesList( null, 'markSeen' );
+       }.bind( this ) );
+};
+
+/**
+ * Set the current search for the system.
+ *
+ * @param {string} searchQuery Search query, including triggers
+ */
+Controller.prototype.setSearch = function ( searchQuery ) {
+       this.filtersModel.setSearch( searchQuery );
+};
+
+/**
+ * Switch the view by changing the search query trigger
+ * without changing the search term
+ *
+ * @param  {string} view View to change to
+ */
+Controller.prototype.switchView = function ( view ) {
+       this.setSearch(
+               this.filtersModel.getViewTrigger( view ) +
+               this.filtersModel.removeViewTriggers( this.filtersModel.getSearch() )
+       );
+};
+
+/**
+ * Reset the search for a specific view. This means we null the search query
+ * and replace it with the relevant trigger for the requested view
+ *
+ * @param  {string} [view='default'] View to change to
+ */
+Controller.prototype.resetSearchForView = function ( view ) {
+       view = view || 'default';
+
+       this.setSearch(
+               this.filtersModel.getViewTrigger( view )
+       );
+};
+
+module.exports = Controller;
index a4ef73b..42bfae6 100644 (file)
@@ -1,12 +1,10 @@
-( function () {
-       /**
-        * Supported highlight colors.
-        * Warning: These are also hardcoded in "styles/mw.rcfilters.variables.less"
-        *
-        * @member mw.rcfilters
-        * @property {string[]}
-        */
-       var HighlightColors = [ 'c1', 'c2', 'c3', 'c4', 'c5' ];
+/**
+ * Supported highlight colors.
+ * Warning: These are also hardcoded in "styles/mw.rcfilters.variables.less"
+ *
+ * @member mw.rcfilters
+ * @property {string[]}
+ */
+var HighlightColors = [ 'c1', 'c2', 'c3', 'c4', 'c5' ];
 
-       module.exports = HighlightColors;
-}() );
+module.exports = HighlightColors;
index 37874d5..3b69654 100644 (file)
-( function () {
-       /* eslint no-underscore-dangle: "off" */
-       /**
-        * URI Processor for RCFilters
-        *
-        * @class mw.rcfilters.UriProcessor
-        *
-        * @constructor
-        * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model
-        * @param {Object} [config] Configuration object
-        * @cfg {boolean} [normalizeTarget] Dictates whether or not to go through the
-        *  title normalization to separate title subpage/parts into the target= url
-        *  parameter
-        */
-       var UriProcessor = function MwRcfiltersController( filtersModel, config ) {
-               config = config || {};
-               this.filtersModel = filtersModel;
-
-               this.normalizeTarget = !!config.normalizeTarget;
-       };
-
-       /* Initialization */
-       OO.initClass( UriProcessor );
-
-       /* Static methods */
-
-       /**
-        * Replace the url history through replaceState
-        *
-        * @param {mw.Uri} newUri New URI to replace
-        */
-       UriProcessor.static.replaceState = function ( newUri ) {
-               window.history.replaceState(
-                       { tag: 'rcfilters' },
-                       document.title,
-                       newUri.toString()
-               );
-       };
-
-       /**
-        * Push the url to history through pushState
-        *
-        * @param {mw.Uri} newUri New URI to push
-        */
-       UriProcessor.static.pushState = function ( newUri ) {
-               window.history.pushState(
-                       { tag: 'rcfilters' },
-                       document.title,
-                       newUri.toString()
-               );
-       };
-
-       /* Methods */
-
-       /**
-        * Get the version that this URL query is tagged with.
-        *
-        * @param {Object} [uriQuery] URI query
-        * @return {number} URL version
-        */
-       UriProcessor.prototype.getVersion = function ( uriQuery ) {
-               uriQuery = uriQuery || new mw.Uri().query;
-
-               return Number( uriQuery.urlversion || 1 );
-       };
-
-       /**
-        * Get an updated mw.Uri object based on the model state
-        *
-        * @param {mw.Uri} [uri] An external URI to build the new uri
-        *  with. This is mainly for tests, to be able to supply external query
-        *  parameters and make sure they are retained.
-        * @return {mw.Uri} Updated Uri
-        */
-       UriProcessor.prototype.getUpdatedUri = function ( uri ) {
-               var normalizedUri = this._normalizeTargetInUri( uri || new mw.Uri() ),
-                       unrecognizedParams = this.getUnrecognizedParams( normalizedUri.query );
-
-               normalizedUri.query = this.filtersModel.getMinimizedParamRepresentation(
-                       $.extend(
-                               true,
-                               {},
-                               normalizedUri.query,
-                               // The representation must be expanded so it can
-                               // override the uri query params but we then output
-                               // a minimized version for the entire URI representation
-                               // for the method
-                               this.filtersModel.getExpandedParamRepresentation()
-                       )
-               );
-
-               // Reapply unrecognized params and url version
-               normalizedUri.query = $.extend(
+/* eslint no-underscore-dangle: "off" */
+/**
+ * URI Processor for RCFilters
+ *
+ * @class mw.rcfilters.UriProcessor
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model
+ * @param {Object} [config] Configuration object
+ * @cfg {boolean} [normalizeTarget] Dictates whether or not to go through the
+ *  title normalization to separate title subpage/parts into the target= url
+ *  parameter
+ */
+var UriProcessor = function MwRcfiltersController( filtersModel, config ) {
+       config = config || {};
+       this.filtersModel = filtersModel;
+
+       this.normalizeTarget = !!config.normalizeTarget;
+};
+
+/* Initialization */
+OO.initClass( UriProcessor );
+
+/* Static methods */
+
+/**
+ * Replace the url history through replaceState
+ *
+ * @param {mw.Uri} newUri New URI to replace
+ */
+UriProcessor.static.replaceState = function ( newUri ) {
+       window.history.replaceState(
+               { tag: 'rcfilters' },
+               document.title,
+               newUri.toString()
+       );
+};
+
+/**
+ * Push the url to history through pushState
+ *
+ * @param {mw.Uri} newUri New URI to push
+ */
+UriProcessor.static.pushState = function ( newUri ) {
+       window.history.pushState(
+               { tag: 'rcfilters' },
+               document.title,
+               newUri.toString()
+       );
+};
+
+/* Methods */
+
+/**
+ * Get the version that this URL query is tagged with.
+ *
+ * @param {Object} [uriQuery] URI query
+ * @return {number} URL version
+ */
+UriProcessor.prototype.getVersion = function ( uriQuery ) {
+       uriQuery = uriQuery || new mw.Uri().query;
+
+       return Number( uriQuery.urlversion || 1 );
+};
+
+/**
+ * Get an updated mw.Uri object based on the model state
+ *
+ * @param {mw.Uri} [uri] An external URI to build the new uri
+ *  with. This is mainly for tests, to be able to supply external query
+ *  parameters and make sure they are retained.
+ * @return {mw.Uri} Updated Uri
+ */
+UriProcessor.prototype.getUpdatedUri = function ( uri ) {
+       var normalizedUri = this._normalizeTargetInUri( uri || new mw.Uri() ),
+               unrecognizedParams = this.getUnrecognizedParams( normalizedUri.query );
+
+       normalizedUri.query = this.filtersModel.getMinimizedParamRepresentation(
+               $.extend(
                        true,
                        {},
                        normalizedUri.query,
-                       unrecognizedParams,
-                       { urlversion: '2' }
-               );
-
-               return normalizedUri;
-       };
-
-       /**
-        * Move the subpage to the target parameter
-        *
-        * @param {mw.Uri} uri
-        * @return {mw.Uri}
-        * @private
-        */
-       UriProcessor.prototype._normalizeTargetInUri = function ( uri ) {
-               var parts,
-                       // matches [/wiki/]SpecialNS:RCL/[Namespace:]Title/Subpage/Subsubpage/etc
-                       re = /^((?:\/.+?\/)?.*?:.*?)\/(.*)$/;
-
-               if ( !this.normalizeTarget ) {
-                       return uri;
-               }
-
-               // target in title param
-               if ( uri.query.title ) {
-                       parts = uri.query.title.match( re );
-                       if ( parts ) {
-                               uri.query.title = parts[ 1 ];
-                               uri.query.target = parts[ 2 ];
-                       }
-               }
+                       // The representation must be expanded so it can
+                       // override the uri query params but we then output
+                       // a minimized version for the entire URI representation
+                       // for the method
+                       this.filtersModel.getExpandedParamRepresentation()
+               )
+       );
+
+       // Reapply unrecognized params and url version
+       normalizedUri.query = $.extend(
+               true,
+               {},
+               normalizedUri.query,
+               unrecognizedParams,
+               { urlversion: '2' }
+       );
+
+       return normalizedUri;
+};
+
+/**
+ * Move the subpage to the target parameter
+ *
+ * @param {mw.Uri} uri
+ * @return {mw.Uri}
+ * @private
+ */
+UriProcessor.prototype._normalizeTargetInUri = function ( uri ) {
+       var parts,
+               // matches [/wiki/]SpecialNS:RCL/[Namespace:]Title/Subpage/Subsubpage/etc
+               re = /^((?:\/.+?\/)?.*?:.*?)\/(.*)$/;
+
+       if ( !this.normalizeTarget ) {
+               return uri;
+       }
 
-               // target in path
-               parts = mw.Uri.decode( uri.path ).match( re );
+       // target in title param
+       if ( uri.query.title ) {
+               parts = uri.query.title.match( re );
                if ( parts ) {
-                       uri.path = parts[ 1 ];
+                       uri.query.title = parts[ 1 ];
                        uri.query.target = parts[ 2 ];
                }
-
-               return uri;
-       };
-
-       /**
-        * Get an object representing given parameters that are unrecognized by the model
-        *
-        * @param  {Object} params Full params object
-        * @return {Object} Unrecognized params
-        */
-       UriProcessor.prototype.getUnrecognizedParams = function ( params ) {
-               // Start with full representation
-               var givenParamNames = Object.keys( params ),
-                       unrecognizedParams = $.extend( true, {}, params );
-
-               // Extract unrecognized parameters
-               Object.keys( this.filtersModel.getEmptyParameterState() ).forEach( function ( paramName ) {
-                       // Remove recognized params
-                       if ( givenParamNames.indexOf( paramName ) > -1 ) {
-                               delete unrecognizedParams[ paramName ];
-                       }
-               } );
-
-               return unrecognizedParams;
-       };
-
-       /**
-        * 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.
-        *
-        * @param {Object} [params] Extra parameters to add to the API call
-        */
-       UriProcessor.prototype.updateURL = function ( params ) {
-               var currentUri = new mw.Uri(),
-                       updatedUri = this.getUpdatedUri();
-
-               updatedUri.extend( params || {} );
-
-               if (
-                       this.getVersion( currentUri.query ) !== 2 ||
-                       this.isNewState( currentUri.query, updatedUri.query )
-               ) {
-                       this.constructor.static.replaceState( updatedUri );
+       }
+
+       // target in path
+       parts = mw.Uri.decode( uri.path ).match( re );
+       if ( parts ) {
+               uri.path = parts[ 1 ];
+               uri.query.target = parts[ 2 ];
+       }
+
+       return uri;
+};
+
+/**
+ * Get an object representing given parameters that are unrecognized by the model
+ *
+ * @param  {Object} params Full params object
+ * @return {Object} Unrecognized params
+ */
+UriProcessor.prototype.getUnrecognizedParams = function ( params ) {
+       // Start with full representation
+       var givenParamNames = Object.keys( params ),
+               unrecognizedParams = $.extend( true, {}, params );
+
+       // Extract unrecognized parameters
+       Object.keys( this.filtersModel.getEmptyParameterState() ).forEach( function ( paramName ) {
+               // Remove recognized params
+               if ( givenParamNames.indexOf( paramName ) > -1 ) {
+                       delete unrecognizedParams[ paramName ];
                }
-       };
-
-       /**
-        * Update the filters model based on the URI query
-        * This happens on initialization, and from this moment on,
-        * we consider the system synchronized, and the model serves
-        * as the source of truth for the URL.
-        *
-        * This methods should only be called once on initialization.
-        * After initialization, the model updates the URL, not the
-        * other way around.
-        *
-        * @param {Object} [uriQuery] URI query
-        */
-       UriProcessor.prototype.updateModelBasedOnQuery = function ( uriQuery ) {
-               uriQuery = uriQuery || this._normalizeTargetInUri( new mw.Uri() ).query;
-               this.filtersModel.updateStateFromParams(
-                       this._getNormalizedQueryParams( uriQuery )
-               );
-       };
-
-       /**
-        * Compare two URI queries to decide whether they are different
-        * enough to represent a new state.
-        *
-        * @param {Object} currentUriQuery Current Uri query
-        * @param {Object} updatedUriQuery Updated Uri query
-        * @return {boolean} This is a new state
-        */
-       UriProcessor.prototype.isNewState = function ( currentUriQuery, updatedUriQuery ) {
-               var currentParamState, updatedParamState,
-                       notEquivalent = function ( obj1, obj2 ) {
-                               var keys = Object.keys( obj1 ).concat( Object.keys( obj2 ) );
-                               return keys.some( function ( key ) {
-                                       return obj1[ key ] != obj2[ key ]; // eslint-disable-line eqeqeq
-                               } );
-                       };
-
-               // Compare states instead of parameters
-               // This will allow us to always have a proper check of whether
-               // the requested new url is one to change or not, regardless of
-               // actual parameter visibility/representation in the URL
-               currentParamState = $.extend(
-                       true,
-                       {},
-                       this.filtersModel.getMinimizedParamRepresentation( currentUriQuery ),
-                       this.getUnrecognizedParams( currentUriQuery )
-               );
-               updatedParamState = $.extend(
-                       true,
-                       {},
-                       this.filtersModel.getMinimizedParamRepresentation( updatedUriQuery ),
-                       this.getUnrecognizedParams( updatedUriQuery )
-               );
-
-               return notEquivalent( currentParamState, updatedParamState );
-       };
-
-       /**
-        * Check whether the given query has parameters that are
-        * recognized as parameters we should load the system with
-        *
-        * @param {mw.Uri} [uriQuery] Given URI query
-        * @return {boolean} Query contains valid recognized parameters
-        */
-       UriProcessor.prototype.doesQueryContainRecognizedParams = function ( uriQuery ) {
-               var anyValidInUrl,
-                       validParameterNames = Object.keys( this.filtersModel.getEmptyParameterState() );
-
-               uriQuery = uriQuery || new mw.Uri().query;
-
-               anyValidInUrl = Object.keys( uriQuery ).some( function ( parameter ) {
-                       return validParameterNames.indexOf( parameter ) > -1;
-               } );
-
-               // URL version 2 is allowed to be empty or within nonrecognized params
-               return anyValidInUrl || this.getVersion( uriQuery ) === 2;
-       };
-
-       /**
-        * Get the adjusted URI params based on the url version
-        * If the urlversion is not 2, the parameters are merged with
-        * the model's defaults.
-        * Always merge in the hidden parameter defaults.
-        *
-        * @private
-        * @param {Object} uriQuery Current URI query
-        * @return {Object} Normalized parameters
-        */
-       UriProcessor.prototype._getNormalizedQueryParams = function ( uriQuery ) {
-               // Check whether we are dealing with urlversion=2
-               // If we are, we do not merge the initial request with
-               // defaults. Not having urlversion=2 means we need to
-               // reproduce the server-side request and merge the
-               // requested parameters (or starting state) with the
-               // wiki default.
-               // Any subsequent change of the URL through the RCFilters
-               // system will receive 'urlversion=2'
-               var base = this.getVersion( uriQuery ) === 2 ?
-                       {} :
-                       this.filtersModel.getDefaultParams();
-
-               return $.extend(
-                       true,
-                       {},
-                       this.filtersModel.getMinimizedParamRepresentation(
-                               $.extend( true, {}, base, uriQuery )
-                       ),
-                       { urlversion: '2' }
-               );
-       };
-
-       module.exports = UriProcessor;
-}() );
+       } );
+
+       return unrecognizedParams;
+};
+
+/**
+ * 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.
+ *
+ * @param {Object} [params] Extra parameters to add to the API call
+ */
+UriProcessor.prototype.updateURL = function ( params ) {
+       var currentUri = new mw.Uri(),
+               updatedUri = this.getUpdatedUri();
+
+       updatedUri.extend( params || {} );
+
+       if (
+               this.getVersion( currentUri.query ) !== 2 ||
+               this.isNewState( currentUri.query, updatedUri.query )
+       ) {
+               this.constructor.static.replaceState( updatedUri );
+       }
+};
+
+/**
+ * Update the filters model based on the URI query
+ * This happens on initialization, and from this moment on,
+ * we consider the system synchronized, and the model serves
+ * as the source of truth for the URL.
+ *
+ * This methods should only be called once on initialization.
+ * After initialization, the model updates the URL, not the
+ * other way around.
+ *
+ * @param {Object} [uriQuery] URI query
+ */
+UriProcessor.prototype.updateModelBasedOnQuery = function ( uriQuery ) {
+       uriQuery = uriQuery || this._normalizeTargetInUri( new mw.Uri() ).query;
+       this.filtersModel.updateStateFromParams(
+               this._getNormalizedQueryParams( uriQuery )
+       );
+};
+
+/**
+ * Compare two URI queries to decide whether they are different
+ * enough to represent a new state.
+ *
+ * @param {Object} currentUriQuery Current Uri query
+ * @param {Object} updatedUriQuery Updated Uri query
+ * @return {boolean} This is a new state
+ */
+UriProcessor.prototype.isNewState = function ( currentUriQuery, updatedUriQuery ) {
+       var currentParamState, updatedParamState,
+               notEquivalent = function ( obj1, obj2 ) {
+                       var keys = Object.keys( obj1 ).concat( Object.keys( obj2 ) );
+                       return keys.some( function ( key ) {
+                               return obj1[ key ] != obj2[ key ]; // eslint-disable-line eqeqeq
+                       } );
+               };
+
+       // Compare states instead of parameters
+       // This will allow us to always have a proper check of whether
+       // the requested new url is one to change or not, regardless of
+       // actual parameter visibility/representation in the URL
+       currentParamState = $.extend(
+               true,
+               {},
+               this.filtersModel.getMinimizedParamRepresentation( currentUriQuery ),
+               this.getUnrecognizedParams( currentUriQuery )
+       );
+       updatedParamState = $.extend(
+               true,
+               {},
+               this.filtersModel.getMinimizedParamRepresentation( updatedUriQuery ),
+               this.getUnrecognizedParams( updatedUriQuery )
+       );
+
+       return notEquivalent( currentParamState, updatedParamState );
+};
+
+/**
+ * Check whether the given query has parameters that are
+ * recognized as parameters we should load the system with
+ *
+ * @param {mw.Uri} [uriQuery] Given URI query
+ * @return {boolean} Query contains valid recognized parameters
+ */
+UriProcessor.prototype.doesQueryContainRecognizedParams = function ( uriQuery ) {
+       var anyValidInUrl,
+               validParameterNames = Object.keys( this.filtersModel.getEmptyParameterState() );
+
+       uriQuery = uriQuery || new mw.Uri().query;
+
+       anyValidInUrl = Object.keys( uriQuery ).some( function ( parameter ) {
+               return validParameterNames.indexOf( parameter ) > -1;
+       } );
+
+       // URL version 2 is allowed to be empty or within nonrecognized params
+       return anyValidInUrl || this.getVersion( uriQuery ) === 2;
+};
+
+/**
+ * Get the adjusted URI params based on the url version
+ * If the urlversion is not 2, the parameters are merged with
+ * the model's defaults.
+ * Always merge in the hidden parameter defaults.
+ *
+ * @private
+ * @param {Object} uriQuery Current URI query
+ * @return {Object} Normalized parameters
+ */
+UriProcessor.prototype._getNormalizedQueryParams = function ( uriQuery ) {
+       // Check whether we are dealing with urlversion=2
+       // If we are, we do not merge the initial request with
+       // defaults. Not having urlversion=2 means we need to
+       // reproduce the server-side request and merge the
+       // requested parameters (or starting state) with the
+       // wiki default.
+       // Any subsequent change of the URL through the RCFilters
+       // system will receive 'urlversion=2'
+       var base = this.getVersion( uriQuery ) === 2 ?
+               {} :
+               this.filtersModel.getDefaultParams();
+
+       return $.extend(
+               true,
+               {},
+               this.filtersModel.getMinimizedParamRepresentation(
+                       $.extend( true, {}, base, uriQuery )
+               ),
+               { urlversion: '2' }
+       );
+};
+
+module.exports = UriProcessor;
index 64d2e79..70677b9 100644 (file)
-( function () {
-       /**
-        * View model for the changes list
-        *
-        * @class mw.rcfilters.dm.ChangesListViewModel
-        * @mixins OO.EventEmitter
-        *
-        * @param {jQuery} $initialFieldset The initial server-generated legacy form content
-        * @constructor
-        */
-       var ChangesListViewModel = function MwRcfiltersDmChangesListViewModel( $initialFieldset ) {
-               // Mixin constructor
-               OO.EventEmitter.call( this );
-
-               this.valid = true;
-               this.newChangesExist = false;
-               this.liveUpdate = false;
-               this.unseenWatchedChanges = false;
-
-               this.extractNextFrom( $initialFieldset );
-       };
-
-       /* Initialization */
-       OO.initClass( ChangesListViewModel );
-       OO.mixinClass( ChangesListViewModel, OO.EventEmitter );
-
-       /* Events */
-
-       /**
-        * @event invalidate
-        *
-        * The list of changes is now invalid (out of date)
-        */
-
-       /**
-        * @event update
-        * @param {jQuery|string} $changesListContent List of changes
-        * @param {jQuery} $fieldset Server-generated form
-        * @param {string} noResultsDetails Type of no result error
-        * @param {boolean} isInitialDOM Whether the previous dom variables are from the initial page load
-        * @param {boolean} fromLiveUpdate These are new changes fetched via Live Update
-        *
-        * The list of changes has been updated
-        */
-
-       /**
-        * @event newChangesExist
-        * @param {boolean} newChangesExist
-        *
-        * The existence of changes newer than those currently displayed has changed.
-        */
-
-       /**
-        * @event liveUpdateChange
-        * @param {boolean} enable
-        *
-        * The state of the 'live update' feature has changed.
-        */
-
-       /* Methods */
-
-       /**
-        * Invalidate the list of changes
-        *
-        * @fires invalidate
-        */
-       ChangesListViewModel.prototype.invalidate = function () {
-               if ( this.valid ) {
-                       this.valid = false;
-                       this.emit( 'invalidate' );
-               }
-       };
-
-       /**
-        * Update the model with an updated list of changes
-        *
-        * @param {jQuery|string} changesListContent
-        * @param {jQuery} $fieldset
-        * @param {string} noResultsDetails Type of no result error
-        * @param {boolean} [isInitialDOM] Using the initial (already attached) DOM elements
-        * @param {boolean} [separateOldAndNew] Whether a logical separation between old and new changes is needed
-        * @fires update
-        */
-       ChangesListViewModel.prototype.update = function ( changesListContent, $fieldset, noResultsDetails, isInitialDOM, separateOldAndNew ) {
-               var from = this.nextFrom;
-               this.valid = true;
-               this.extractNextFrom( $fieldset );
-               this.checkForUnseenWatchedChanges( changesListContent );
-               this.emit( 'update', changesListContent, $fieldset, noResultsDetails, isInitialDOM, separateOldAndNew ? from : null );
-       };
-
-       /**
-        * Specify whether new changes exist
-        *
-        * @param {boolean} newChangesExist
-        * @fires newChangesExist
-        */
-       ChangesListViewModel.prototype.setNewChangesExist = function ( newChangesExist ) {
-               if ( newChangesExist !== this.newChangesExist ) {
-                       this.newChangesExist = newChangesExist;
-                       this.emit( 'newChangesExist', newChangesExist );
-               }
-       };
-
-       /**
-        * @return {boolean} Whether new changes exist
-        */
-       ChangesListViewModel.prototype.getNewChangesExist = function () {
-               return this.newChangesExist;
-       };
-
-       /**
-        * Extract the value of the 'from' parameter from a link in the field set
-        *
-        * @param {jQuery} $fieldset
-        */
-       ChangesListViewModel.prototype.extractNextFrom = function ( $fieldset ) {
-               var data = $fieldset.find( '.rclistfrom > a, .wlinfo' ).data( 'params' );
-               if ( data && data.from ) {
-                       this.nextFrom = data.from;
-               }
-       };
-
-       /**
-        * @return {string} The 'from' parameter that can be used to query new changes
-        */
-       ChangesListViewModel.prototype.getNextFrom = function () {
-               return this.nextFrom;
-       };
-
-       /**
-        * Toggle the 'live update' feature on/off
-        *
-        * @param {boolean} enable
-        */
-       ChangesListViewModel.prototype.toggleLiveUpdate = function ( enable ) {
-               enable = enable === undefined ? !this.liveUpdate : enable;
-               if ( enable !== this.liveUpdate ) {
-                       this.liveUpdate = enable;
-                       this.emit( 'liveUpdateChange', this.liveUpdate );
-               }
-       };
-
-       /**
-        * @return {boolean} The 'live update' feature is enabled
-        */
-       ChangesListViewModel.prototype.getLiveUpdate = function () {
-               return this.liveUpdate;
-       };
-
-       /**
-        * Check if some of the given changes watched and unseen
-        *
-        * @param {jQuery|string} changeslistContent
-        */
-       ChangesListViewModel.prototype.checkForUnseenWatchedChanges = function ( changeslistContent ) {
-               this.unseenWatchedChanges = changeslistContent !== 'NO_RESULTS' &&
-                       changeslistContent.find( '.mw-changeslist-line-watched' ).length > 0;
-       };
-
-       /**
-        * @return {boolean} Whether some of the current changes are watched and unseen
-        */
-       ChangesListViewModel.prototype.hasUnseenWatchedChanges = function () {
-               return this.unseenWatchedChanges;
-       };
-
-       module.exports = ChangesListViewModel;
-}() );
+/**
+ * View model for the changes list
+ *
+ * @class mw.rcfilters.dm.ChangesListViewModel
+ * @mixins OO.EventEmitter
+ *
+ * @param {jQuery} $initialFieldset The initial server-generated legacy form content
+ * @constructor
+ */
+var ChangesListViewModel = function MwRcfiltersDmChangesListViewModel( $initialFieldset ) {
+       // Mixin constructor
+       OO.EventEmitter.call( this );
+
+       this.valid = true;
+       this.newChangesExist = false;
+       this.liveUpdate = false;
+       this.unseenWatchedChanges = false;
+
+       this.extractNextFrom( $initialFieldset );
+};
+
+/* Initialization */
+OO.initClass( ChangesListViewModel );
+OO.mixinClass( ChangesListViewModel, OO.EventEmitter );
+
+/* Events */
+
+/**
+ * @event invalidate
+ *
+ * The list of changes is now invalid (out of date)
+ */
+
+/**
+ * @event update
+ * @param {jQuery|string} $changesListContent List of changes
+ * @param {jQuery} $fieldset Server-generated form
+ * @param {string} noResultsDetails Type of no result error
+ * @param {boolean} isInitialDOM Whether the previous dom variables are from the initial page load
+ * @param {boolean} fromLiveUpdate These are new changes fetched via Live Update
+ *
+ * The list of changes has been updated
+ */
+
+/**
+ * @event newChangesExist
+ * @param {boolean} newChangesExist
+ *
+ * The existence of changes newer than those currently displayed has changed.
+ */
+
+/**
+ * @event liveUpdateChange
+ * @param {boolean} enable
+ *
+ * The state of the 'live update' feature has changed.
+ */
+
+/* Methods */
+
+/**
+ * Invalidate the list of changes
+ *
+ * @fires invalidate
+ */
+ChangesListViewModel.prototype.invalidate = function () {
+       if ( this.valid ) {
+               this.valid = false;
+               this.emit( 'invalidate' );
+       }
+};
+
+/**
+ * Update the model with an updated list of changes
+ *
+ * @param {jQuery|string} changesListContent
+ * @param {jQuery} $fieldset
+ * @param {string} noResultsDetails Type of no result error
+ * @param {boolean} [isInitialDOM] Using the initial (already attached) DOM elements
+ * @param {boolean} [separateOldAndNew] Whether a logical separation between old and new changes is needed
+ * @fires update
+ */
+ChangesListViewModel.prototype.update = function ( changesListContent, $fieldset, noResultsDetails, isInitialDOM, separateOldAndNew ) {
+       var from = this.nextFrom;
+       this.valid = true;
+       this.extractNextFrom( $fieldset );
+       this.checkForUnseenWatchedChanges( changesListContent );
+       this.emit( 'update', changesListContent, $fieldset, noResultsDetails, isInitialDOM, separateOldAndNew ? from : null );
+};
+
+/**
+ * Specify whether new changes exist
+ *
+ * @param {boolean} newChangesExist
+ * @fires newChangesExist
+ */
+ChangesListViewModel.prototype.setNewChangesExist = function ( newChangesExist ) {
+       if ( newChangesExist !== this.newChangesExist ) {
+               this.newChangesExist = newChangesExist;
+               this.emit( 'newChangesExist', newChangesExist );
+       }
+};
+
+/**
+ * @return {boolean} Whether new changes exist
+ */
+ChangesListViewModel.prototype.getNewChangesExist = function () {
+       return this.newChangesExist;
+};
+
+/**
+ * Extract the value of the 'from' parameter from a link in the field set
+ *
+ * @param {jQuery} $fieldset
+ */
+ChangesListViewModel.prototype.extractNextFrom = function ( $fieldset ) {
+       var data = $fieldset.find( '.rclistfrom > a, .wlinfo' ).data( 'params' );
+       if ( data && data.from ) {
+               this.nextFrom = data.from;
+       }
+};
+
+/**
+ * @return {string} The 'from' parameter that can be used to query new changes
+ */
+ChangesListViewModel.prototype.getNextFrom = function () {
+       return this.nextFrom;
+};
+
+/**
+ * Toggle the 'live update' feature on/off
+ *
+ * @param {boolean} enable
+ */
+ChangesListViewModel.prototype.toggleLiveUpdate = function ( enable ) {
+       enable = enable === undefined ? !this.liveUpdate : enable;
+       if ( enable !== this.liveUpdate ) {
+               this.liveUpdate = enable;
+               this.emit( 'liveUpdateChange', this.liveUpdate );
+       }
+};
+
+/**
+ * @return {boolean} The 'live update' feature is enabled
+ */
+ChangesListViewModel.prototype.getLiveUpdate = function () {
+       return this.liveUpdate;
+};
+
+/**
+ * Check if some of the given changes watched and unseen
+ *
+ * @param {jQuery|string} changeslistContent
+ */
+ChangesListViewModel.prototype.checkForUnseenWatchedChanges = function ( changeslistContent ) {
+       this.unseenWatchedChanges = changeslistContent !== 'NO_RESULTS' &&
+               changeslistContent.find( '.mw-changeslist-line-watched' ).length > 0;
+};
+
+/**
+ * @return {boolean} Whether some of the current changes are watched and unseen
+ */
+ChangesListViewModel.prototype.hasUnseenWatchedChanges = function () {
+       return this.unseenWatchedChanges;
+};
+
+module.exports = ChangesListViewModel;
index db504b5..d1f700c 100644 (file)
-( function () {
-       var FilterItem = require( './FilterItem.js' ),
-               FilterGroup;
-
-       /**
-        * View model for a filter group
-        *
-        * @class mw.rcfilters.dm.FilterGroup
-        * @mixins OO.EventEmitter
-        * @mixins OO.EmitterList
-        *
-        * @constructor
-        * @param {string} name Group name
-        * @param {Object} [config] Configuration options
-        * @cfg {string} [type='send_unselected_if_any'] Group type
-        * @cfg {string} [view='default'] Name of the display group this group
-        *  is a part of.
-        * @cfg {boolean} [sticky] This group is 'sticky'. It is synchronized
-        *  with a preference, does not participate in Saved Queries, and is
-        *  not shown in the active filters area.
-        * @cfg {string} [title] Group title
-        * @cfg {boolean} [hidden] This group is hidden from the regular menu views
-        *  and the active filters area.
-        * @cfg {boolean} [allowArbitrary] Allows for an arbitrary value to be added to the
-        *  group from the URL, even if it wasn't initially set up.
-        * @cfg {number} [range] An object defining minimum and maximum values for numeric
-        *  groups. { min: x, max: y }
-        * @cfg {number} [minValue] Minimum value for numeric groups
-        * @cfg {string} [separator='|'] Value separator for 'string_options' groups
-        * @cfg {boolean} [active] Group is active
-        * @cfg {boolean} [fullCoverage] This filters in this group collectively cover all results
-        * @cfg {Object} [conflicts] Defines the conflicts for this filter group
-        * @cfg {string|Object} [labelPrefixKey] An i18n key defining the prefix label for this
-        *  group. If the prefix has 'invert' state, the parameter is expected to be an object
-        *  with 'default' and 'inverted' as keys.
-        * @cfg {Object} [whatsThis] Defines the messages that should appear for the 'what's this' popup
-        * @cfg {string} [whatsThis.header] The header of the whatsThis popup message
-        * @cfg {string} [whatsThis.body] The body of the whatsThis popup message
-        * @cfg {string} [whatsThis.url] The url for the link in the whatsThis popup message
-        * @cfg {string} [whatsThis.linkMessage] The text for the link in the whatsThis popup message
-        * @cfg {boolean} [visible=true] The visibility of the group
-        */
-       FilterGroup = function MwRcfiltersDmFilterGroup( name, config ) {
-               config = config || {};
-
-               // Mixin constructor
-               OO.EventEmitter.call( this );
-               OO.EmitterList.call( this );
-
-               this.name = name;
-               this.type = config.type || 'send_unselected_if_any';
-               this.view = config.view || 'default';
-               this.sticky = !!config.sticky;
-               this.title = config.title || name;
-               this.hidden = !!config.hidden;
-               this.allowArbitrary = !!config.allowArbitrary;
-               this.numericRange = config.range;
-               this.separator = config.separator || '|';
-               this.labelPrefixKey = config.labelPrefixKey;
-               this.visible = config.visible === undefined ? true : !!config.visible;
-
-               this.currSelected = null;
-               this.active = !!config.active;
-               this.fullCoverage = !!config.fullCoverage;
-
-               this.whatsThis = config.whatsThis || {};
-
-               this.conflicts = config.conflicts || {};
-               this.defaultParams = {};
-               this.defaultFilters = {};
-
-               this.aggregate( { update: 'filterItemUpdate' } );
-               this.connect( this, { filterItemUpdate: 'onFilterItemUpdate' } );
-       };
-
-       /* Initialization */
-       OO.initClass( FilterGroup );
-       OO.mixinClass( FilterGroup, OO.EventEmitter );
-       OO.mixinClass( FilterGroup, OO.EmitterList );
-
-       /* Events */
-
-       /**
-        * @event update
-        *
-        * Group state has been updated
-        */
-
-       /* Methods */
-
-       /**
-        * Initialize the group and create its filter items
-        *
-        * @param {Object} filterDefinition Filter definition for this group
-        * @param {string|Object} [groupDefault] Definition of the group default
-        */
-       FilterGroup.prototype.initializeFilters = function ( filterDefinition, groupDefault ) {
-               var defaultParam,
-                       supersetMap = {},
-                       model = this,
-                       items = [];
-
-               filterDefinition.forEach( function ( filter ) {
-                       // Instantiate an item
-                       var subsetNames = [],
-                               filterItem = new FilterItem( filter.name, model, {
-                                       group: model.getName(),
-                                       label: filter.label || filter.name,
-                                       description: filter.description || '',
-                                       labelPrefixKey: model.labelPrefixKey,
-                                       cssClass: filter.cssClass,
-                                       identifiers: filter.identifiers,
-                                       defaultHighlightColor: filter.defaultHighlightColor
-                               } );
-
-                       if ( filter.subset ) {
-                               filter.subset = filter.subset.map( function ( el ) {
-                                       return el.filter;
-                               } );
-
-                               subsetNames = [];
-
-                               filter.subset.forEach( function ( subsetFilterName ) {
-                                       // Subsets (unlike conflicts) are always inside the same group
-                                       // We can re-map the names of the filters we are getting from
-                                       // the subsets with the group prefix
-                                       var subsetName = model.getPrefixedName( subsetFilterName );
-                                       // For convenience, we should store each filter's "supersets" -- these are
-                                       // the filters that have that item in their subset list. This will just
-                                       // make it easier to go through whether the item has any other items
-                                       // that affect it (and are selected) at any given time
-                                       supersetMap[ subsetName ] = supersetMap[ subsetName ] || [];
-                                       mw.rcfilters.utils.addArrayElementsUnique(
-                                               supersetMap[ subsetName ],
-                                               filterItem.getName()
-                                       );
-
-                                       // Translate subset param name to add the group name, so we
-                                       // get consistent naming. We know that subsets are only within
-                                       // the same group
-                                       subsetNames.push( subsetName );
-                               } );
-
-                               // Set translated subset
-                               filterItem.setSubset( subsetNames );
-                       }
-
-                       items.push( filterItem );
-
-                       // Store default parameter state; in this case, default is defined per filter
-                       if (
-                               model.getType() === 'send_unselected_if_any' ||
-                               model.getType() === 'boolean'
-                       ) {
-                               // Store the default parameter state
-                               // For this group type, parameter values are direct
-                               // We need to convert from a boolean to a string ('1' and '0')
-                               model.defaultParams[ filter.name ] = String( Number( filter.default || 0 ) );
-                       } else if ( model.getType() === 'any_value' ) {
-                               model.defaultParams[ filter.name ] = filter.default;
-                       }
-               } );
-
-               // Add items
-               this.addItems( items );
-
-               // Now that we have all items, we can apply the superset map
-               this.getItems().forEach( function ( filterItem ) {
-                       filterItem.setSuperset( supersetMap[ filterItem.getName() ] );
-               } );
-
-               // Store default parameter state; in this case, default is defined per the
-               // entire group, given by groupDefault method parameter
-               if ( this.getType() === 'string_options' ) {
-                       // Store the default parameter group state
-                       // For this group, the parameter is group name and value is the names
-                       // of selected items
-                       this.defaultParams[ this.getName() ] = mw.rcfilters.utils.normalizeParamOptions(
-                               // Current values
-                               groupDefault ?
-                                       groupDefault.split( this.getSeparator() ) :
-                                       [],
-                               // Legal values
-                               this.getItems().map( function ( item ) {
-                                       return item.getParamName();
-                               } )
-                       ).join( this.getSeparator() );
-               } else if ( this.getType() === 'single_option' ) {
-                       defaultParam = groupDefault !== undefined ?
-                               groupDefault : this.getItems()[ 0 ].getParamName();
-
-                       // For this group, the parameter is the group name,
-                       // and a single item can be selected: default or first item
-                       this.defaultParams[ this.getName() ] = defaultParam;
-               }
-
-               // add highlights to defaultParams
-               this.getItems().forEach( function ( filterItem ) {
-                       if ( filterItem.isHighlighted() ) {
-                               this.defaultParams[ filterItem.getName() + '_color' ] = filterItem.getHighlightColor();
-                       }
-               }.bind( this ) );
-
-               // Store default filter state based on default params
-               this.defaultFilters = this.getFilterRepresentation( this.getDefaultParams() );
+var FilterItem = require( './FilterItem.js' ),
+       FilterGroup;
+
+/**
+ * View model for a filter group
+ *
+ * @class mw.rcfilters.dm.FilterGroup
+ * @mixins OO.EventEmitter
+ * @mixins OO.EmitterList
+ *
+ * @constructor
+ * @param {string} name Group name
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [type='send_unselected_if_any'] Group type
+ * @cfg {string} [view='default'] Name of the display group this group
+ *  is a part of.
+ * @cfg {boolean} [sticky] This group is 'sticky'. It is synchronized
+ *  with a preference, does not participate in Saved Queries, and is
+ *  not shown in the active filters area.
+ * @cfg {string} [title] Group title
+ * @cfg {boolean} [hidden] This group is hidden from the regular menu views
+ *  and the active filters area.
+ * @cfg {boolean} [allowArbitrary] Allows for an arbitrary value to be added to the
+ *  group from the URL, even if it wasn't initially set up.
+ * @cfg {number} [range] An object defining minimum and maximum values for numeric
+ *  groups. { min: x, max: y }
+ * @cfg {number} [minValue] Minimum value for numeric groups
+ * @cfg {string} [separator='|'] Value separator for 'string_options' groups
+ * @cfg {boolean} [active] Group is active
+ * @cfg {boolean} [fullCoverage] This filters in this group collectively cover all results
+ * @cfg {Object} [conflicts] Defines the conflicts for this filter group
+ * @cfg {string|Object} [labelPrefixKey] An i18n key defining the prefix label for this
+ *  group. If the prefix has 'invert' state, the parameter is expected to be an object
+ *  with 'default' and 'inverted' as keys.
+ * @cfg {Object} [whatsThis] Defines the messages that should appear for the 'what's this' popup
+ * @cfg {string} [whatsThis.header] The header of the whatsThis popup message
+ * @cfg {string} [whatsThis.body] The body of the whatsThis popup message
+ * @cfg {string} [whatsThis.url] The url for the link in the whatsThis popup message
+ * @cfg {string} [whatsThis.linkMessage] The text for the link in the whatsThis popup message
+ * @cfg {boolean} [visible=true] The visibility of the group
+ */
+FilterGroup = function MwRcfiltersDmFilterGroup( name, config ) {
+       config = config || {};
+
+       // Mixin constructor
+       OO.EventEmitter.call( this );
+       OO.EmitterList.call( this );
+
+       this.name = name;
+       this.type = config.type || 'send_unselected_if_any';
+       this.view = config.view || 'default';
+       this.sticky = !!config.sticky;
+       this.title = config.title || name;
+       this.hidden = !!config.hidden;
+       this.allowArbitrary = !!config.allowArbitrary;
+       this.numericRange = config.range;
+       this.separator = config.separator || '|';
+       this.labelPrefixKey = config.labelPrefixKey;
+       this.visible = config.visible === undefined ? true : !!config.visible;
+
+       this.currSelected = null;
+       this.active = !!config.active;
+       this.fullCoverage = !!config.fullCoverage;
+
+       this.whatsThis = config.whatsThis || {};
+
+       this.conflicts = config.conflicts || {};
+       this.defaultParams = {};
+       this.defaultFilters = {};
+
+       this.aggregate( { update: 'filterItemUpdate' } );
+       this.connect( this, { filterItemUpdate: 'onFilterItemUpdate' } );
+};
+
+/* Initialization */
+OO.initClass( FilterGroup );
+OO.mixinClass( FilterGroup, OO.EventEmitter );
+OO.mixinClass( FilterGroup, OO.EmitterList );
+
+/* Events */
+
+/**
+ * @event update
+ *
+ * Group state has been updated
+ */
+
+/* Methods */
+
+/**
+ * Initialize the group and create its filter items
+ *
+ * @param {Object} filterDefinition Filter definition for this group
+ * @param {string|Object} [groupDefault] Definition of the group default
+ */
+FilterGroup.prototype.initializeFilters = function ( filterDefinition, groupDefault ) {
+       var defaultParam,
+               supersetMap = {},
+               model = this,
+               items = [];
+
+       filterDefinition.forEach( function ( filter ) {
+               // Instantiate an item
+               var subsetNames = [],
+                       filterItem = new FilterItem( filter.name, model, {
+                               group: model.getName(),
+                               label: filter.label || filter.name,
+                               description: filter.description || '',
+                               labelPrefixKey: model.labelPrefixKey,
+                               cssClass: filter.cssClass,
+                               identifiers: filter.identifiers,
+                               defaultHighlightColor: filter.defaultHighlightColor
+                       } );
 
-               // Check for filters that should be initially selected by their default value
-               if ( this.isSticky() ) {
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( this.defaultFilters, function ( filterName, filterValue ) {
-                               model.getItemByName( filterName ).toggleSelected( filterValue );
+               if ( filter.subset ) {
+                       filter.subset = filter.subset.map( function ( el ) {
+                               return el.filter;
                        } );
-               }
 
-               // Verify that single_option group has at least one item selected
-               if (
-                       this.getType() === 'single_option' &&
-                       this.findSelectedItems().length === 0
-               ) {
-                       defaultParam = groupDefault !== undefined ?
-                               groupDefault : this.getItems()[ 0 ].getParamName();
+                       subsetNames = [];
+
+                       filter.subset.forEach( function ( subsetFilterName ) {
+                               // Subsets (unlike conflicts) are always inside the same group
+                               // We can re-map the names of the filters we are getting from
+                               // the subsets with the group prefix
+                               var subsetName = model.getPrefixedName( subsetFilterName );
+                               // For convenience, we should store each filter's "supersets" -- these are
+                               // the filters that have that item in their subset list. This will just
+                               // make it easier to go through whether the item has any other items
+                               // that affect it (and are selected) at any given time
+                               supersetMap[ subsetName ] = supersetMap[ subsetName ] || [];
+                               mw.rcfilters.utils.addArrayElementsUnique(
+                                       supersetMap[ subsetName ],
+                                       filterItem.getName()
+                               );
+
+                               // Translate subset param name to add the group name, so we
+                               // get consistent naming. We know that subsets are only within
+                               // the same group
+                               subsetNames.push( subsetName );
+                       } );
 
-                       // Single option means there must be a single option
-                       // selected, so we have to either select the default
-                       // or select the first option
-                       this.selectItemByParamName( defaultParam );
-               }
-       };
-
-       /**
-        * Respond to filterItem update event
-        *
-        * @param {mw.rcfilters.dm.FilterItem} item Updated filter item
-        * @fires update
-        */
-       FilterGroup.prototype.onFilterItemUpdate = function ( item ) {
-               // Update state
-               var changed = false,
-                       active = this.areAnySelected(),
-                       model = this;
-
-               if ( this.getType() === 'single_option' ) {
-                       // This group must have one item selected always
-                       // and must never have more than one item selected at a time
-                       if ( this.findSelectedItems().length === 0 ) {
-                               // Nothing is selected anymore
-                               // Select the default or the first item
-                               this.currSelected = this.getItemByParamName( this.defaultParams[ this.getName() ] ) ||
-                                       this.getItems()[ 0 ];
-                               this.currSelected.toggleSelected( true );
-                               changed = true;
-                       } else if ( this.findSelectedItems().length > 1 ) {
-                               // There is more than one item selected
-                               // This should only happen if the item given
-                               // is the one that is selected, so unselect
-                               // all items that is not it
-                               this.findSelectedItems().forEach( function ( itemModel ) {
-                                       // Note that in case the given item is actually
-                                       // not selected, this loop will end up unselecting
-                                       // all items, which would trigger the case above
-                                       // when the last item is unselected anyways
-                                       var selected = itemModel.getName() === item.getName() &&
-                                               item.isSelected();
-
-                                       itemModel.toggleSelected( selected );
-                                       if ( selected ) {
-                                               model.currSelected = itemModel;
-                                       }
-                               } );
-                               changed = true;
-                       }
+                       // Set translated subset
+                       filterItem.setSubset( subsetNames );
                }
 
-               if ( this.isSticky() ) {
-                       // If this group is sticky, then change the default according to the
-                       // current selection.
-                       this.defaultParams = this.getParamRepresentation( this.getSelectedState() );
-               }
+               items.push( filterItem );
 
+               // Store default parameter state; in this case, default is defined per filter
                if (
-                       changed ||
-                       this.active !== active ||
-                       this.currSelected !== item
+                       model.getType() === 'send_unselected_if_any' ||
+                       model.getType() === 'boolean'
                ) {
-                       this.active = active;
-                       this.currSelected = item;
-
-                       this.emit( 'update' );
+                       // Store the default parameter state
+                       // For this group type, parameter values are direct
+                       // We need to convert from a boolean to a string ('1' and '0')
+                       model.defaultParams[ filter.name ] = String( Number( filter.default || 0 ) );
+               } else if ( model.getType() === 'any_value' ) {
+                       model.defaultParams[ filter.name ] = filter.default;
                }
-       };
-
-       /**
-        * Get group active state
-        *
-        * @return {boolean} Active state
-        */
-       FilterGroup.prototype.isActive = function () {
-               return this.active;
-       };
-
-       /**
-        * Get group hidden state
-        *
-        * @return {boolean} Hidden state
-        */
-       FilterGroup.prototype.isHidden = function () {
-               return this.hidden;
-       };
-
-       /**
-        * Get group allow arbitrary state
-        *
-        * @return {boolean} Group allows an arbitrary value from the URL
-        */
-       FilterGroup.prototype.isAllowArbitrary = function () {
-               return this.allowArbitrary;
-       };
-
-       /**
-        * Get group maximum value for numeric groups
-        *
-        * @return {number|null} Group max value
-        */
-       FilterGroup.prototype.getMaxValue = function () {
-               return this.numericRange && this.numericRange.max !== undefined ?
-                       this.numericRange.max : null;
-       };
-
-       /**
-        * Get group minimum value for numeric groups
-        *
-        * @return {number|null} Group max value
-        */
-       FilterGroup.prototype.getMinValue = function () {
-               return this.numericRange && this.numericRange.min !== undefined ?
-                       this.numericRange.min : null;
-       };
-
-       /**
-        * Get group name
-        *
-        * @return {string} Group name
-        */
-       FilterGroup.prototype.getName = function () {
-               return this.name;
-       };
-
-       /**
-        * Get the default param state of this group
-        *
-        * @return {Object} Default param state
-        */
-       FilterGroup.prototype.getDefaultParams = function () {
-               return this.defaultParams;
-       };
-
-       /**
-        * Get the default filter state of this group
-        *
-        * @return {Object} Default filter state
-        */
-       FilterGroup.prototype.getDefaultFilters = function () {
-               return this.defaultFilters;
-       };
-
-       /**
-        * This is for a single_option and string_options group types
-        * it returns the value of the default
-        *
-        * @return {string} Value of the default
-        */
-       FilterGroup.prototype.getDefaulParamValue = function () {
-               return this.defaultParams[ this.getName() ];
-       };
-       /**
-        * Get the messags defining the 'whats this' popup for this group
-        *
-        * @return {Object} What's this messages
-        */
-       FilterGroup.prototype.getWhatsThis = function () {
-               return this.whatsThis;
-       };
-
-       /**
-        * Check whether this group has a 'what's this' message
-        *
-        * @return {boolean} This group has a what's this message
-        */
-       FilterGroup.prototype.hasWhatsThis = function () {
-               return !!this.whatsThis.body;
-       };
-
-       /**
-        * Get the conflicts associated with the entire group.
-        * Conflict object is set up by filter name keys and conflict
-        * definition. For example:
-        * [
-        *     {
-        *         filterName: {
-        *             filter: filterName,
-        *             group: group1
-        *         }
-        *     },
-        *     {
-        *         filterName2: {
-        *             filter: filterName2,
-        *             group: group2
-        *         }
-        *     }
-        * ]
-        * @return {Object} Conflict definition
-        */
-       FilterGroup.prototype.getConflicts = function () {
-               return this.conflicts;
-       };
-
-       /**
-        * Set conflicts for this group. See #getConflicts for the expected
-        * structure of the definition.
-        *
-        * @param {Object} conflicts Conflicts for this group
-        */
-       FilterGroup.prototype.setConflicts = function ( conflicts ) {
-               this.conflicts = conflicts;
-       };
-
-       /**
-        * Set conflicts for each filter item in the group based on the
-        * given conflict map
-        *
-        * @param {Object} conflicts Object representing the conflict map,
-        *  keyed by the item name, where its value is an object for all its conflicts
-        */
-       FilterGroup.prototype.setFilterConflicts = function ( conflicts ) {
-               this.getItems().forEach( function ( filterItem ) {
-                       if ( conflicts[ filterItem.getName() ] ) {
-                               filterItem.setConflicts( conflicts[ filterItem.getName() ] );
-                       }
-               } );
-       };
-
-       /**
-        * Check whether this item has a potential conflict with the given item
-        *
-        * This checks whether the given item is in the list of conflicts of
-        * the current item, but makes no judgment about whether the conflict
-        * is currently at play (either one of the items may not be selected)
-        *
-        * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item
-        * @return {boolean} This item has a conflict with the given item
-        */
-       FilterGroup.prototype.existsInConflicts = function ( filterItem ) {
-               return Object.prototype.hasOwnProperty.call( this.getConflicts(), filterItem.getName() );
-       };
-
-       /**
-        * Check whether there are any items selected
-        *
-        * @return {boolean} Any items in the group are selected
-        */
-       FilterGroup.prototype.areAnySelected = function () {
-               return this.getItems().some( function ( filterItem ) {
-                       return filterItem.isSelected();
-               } );
-       };
+       } );
+
+       // Add items
+       this.addItems( items );
+
+       // Now that we have all items, we can apply the superset map
+       this.getItems().forEach( function ( filterItem ) {
+               filterItem.setSuperset( supersetMap[ filterItem.getName() ] );
+       } );
+
+       // Store default parameter state; in this case, default is defined per the
+       // entire group, given by groupDefault method parameter
+       if ( this.getType() === 'string_options' ) {
+               // Store the default parameter group state
+               // For this group, the parameter is group name and value is the names
+               // of selected items
+               this.defaultParams[ this.getName() ] = mw.rcfilters.utils.normalizeParamOptions(
+                       // Current values
+                       groupDefault ?
+                               groupDefault.split( this.getSeparator() ) :
+                               [],
+                       // Legal values
+                       this.getItems().map( function ( item ) {
+                               return item.getParamName();
+                       } )
+               ).join( this.getSeparator() );
+       } else if ( this.getType() === 'single_option' ) {
+               defaultParam = groupDefault !== undefined ?
+                       groupDefault : this.getItems()[ 0 ].getParamName();
+
+               // For this group, the parameter is the group name,
+               // and a single item can be selected: default or first item
+               this.defaultParams[ this.getName() ] = defaultParam;
+       }
+
+       // add highlights to defaultParams
+       this.getItems().forEach( function ( filterItem ) {
+               if ( filterItem.isHighlighted() ) {
+                       this.defaultParams[ filterItem.getName() + '_color' ] = filterItem.getHighlightColor();
+               }
+       }.bind( this ) );
 
-       /**
-        * Check whether all items selected
-        *
-        * @return {boolean} All items are selected
-        */
-       FilterGroup.prototype.areAllSelected = function () {
-               var selected = [],
-                       unselected = [];
+       // Store default filter state based on default params
+       this.defaultFilters = this.getFilterRepresentation( this.getDefaultParams() );
 
-               this.getItems().forEach( function ( filterItem ) {
-                       if ( filterItem.isSelected() ) {
-                               selected.push( filterItem );
-                       } else {
-                               unselected.push( filterItem );
-                       }
+       // Check for filters that should be initially selected by their default value
+       if ( this.isSticky() ) {
+               // eslint-disable-next-line no-jquery/no-each-util
+               $.each( this.defaultFilters, function ( filterName, filterValue ) {
+                       model.getItemByName( filterName ).toggleSelected( filterValue );
                } );
-
-               if ( unselected.length === 0 ) {
-                       return true;
+       }
+
+       // Verify that single_option group has at least one item selected
+       if (
+               this.getType() === 'single_option' &&
+               this.findSelectedItems().length === 0
+       ) {
+               defaultParam = groupDefault !== undefined ?
+                       groupDefault : this.getItems()[ 0 ].getParamName();
+
+               // Single option means there must be a single option
+               // selected, so we have to either select the default
+               // or select the first option
+               this.selectItemByParamName( defaultParam );
+       }
+};
+
+/**
+ * Respond to filterItem update event
+ *
+ * @param {mw.rcfilters.dm.FilterItem} item Updated filter item
+ * @fires update
+ */
+FilterGroup.prototype.onFilterItemUpdate = function ( item ) {
+       // Update state
+       var changed = false,
+               active = this.areAnySelected(),
+               model = this;
+
+       if ( this.getType() === 'single_option' ) {
+               // This group must have one item selected always
+               // and must never have more than one item selected at a time
+               if ( this.findSelectedItems().length === 0 ) {
+                       // Nothing is selected anymore
+                       // Select the default or the first item
+                       this.currSelected = this.getItemByParamName( this.defaultParams[ this.getName() ] ) ||
+                               this.getItems()[ 0 ];
+                       this.currSelected.toggleSelected( true );
+                       changed = true;
+               } else if ( this.findSelectedItems().length > 1 ) {
+                       // There is more than one item selected
+                       // This should only happen if the item given
+                       // is the one that is selected, so unselect
+                       // all items that is not it
+                       this.findSelectedItems().forEach( function ( itemModel ) {
+                               // Note that in case the given item is actually
+                               // not selected, this loop will end up unselecting
+                               // all items, which would trigger the case above
+                               // when the last item is unselected anyways
+                               var selected = itemModel.getName() === item.getName() &&
+                                       item.isSelected();
+
+                               itemModel.toggleSelected( selected );
+                               if ( selected ) {
+                                       model.currSelected = itemModel;
+                               }
+                       } );
+                       changed = true;
                }
+       }
+
+       if ( this.isSticky() ) {
+               // If this group is sticky, then change the default according to the
+               // current selection.
+               this.defaultParams = this.getParamRepresentation( this.getSelectedState() );
+       }
+
+       if (
+               changed ||
+               this.active !== active ||
+               this.currSelected !== item
+       ) {
+               this.active = active;
+               this.currSelected = item;
+
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Get group active state
+ *
+ * @return {boolean} Active state
+ */
+FilterGroup.prototype.isActive = function () {
+       return this.active;
+};
+
+/**
+ * Get group hidden state
+ *
+ * @return {boolean} Hidden state
+ */
+FilterGroup.prototype.isHidden = function () {
+       return this.hidden;
+};
+
+/**
+ * Get group allow arbitrary state
+ *
+ * @return {boolean} Group allows an arbitrary value from the URL
+ */
+FilterGroup.prototype.isAllowArbitrary = function () {
+       return this.allowArbitrary;
+};
+
+/**
+ * Get group maximum value for numeric groups
+ *
+ * @return {number|null} Group max value
+ */
+FilterGroup.prototype.getMaxValue = function () {
+       return this.numericRange && this.numericRange.max !== undefined ?
+               this.numericRange.max : null;
+};
+
+/**
+ * Get group minimum value for numeric groups
+ *
+ * @return {number|null} Group max value
+ */
+FilterGroup.prototype.getMinValue = function () {
+       return this.numericRange && this.numericRange.min !== undefined ?
+               this.numericRange.min : null;
+};
+
+/**
+ * Get group name
+ *
+ * @return {string} Group name
+ */
+FilterGroup.prototype.getName = function () {
+       return this.name;
+};
+
+/**
+ * Get the default param state of this group
+ *
+ * @return {Object} Default param state
+ */
+FilterGroup.prototype.getDefaultParams = function () {
+       return this.defaultParams;
+};
+
+/**
+ * Get the default filter state of this group
+ *
+ * @return {Object} Default filter state
+ */
+FilterGroup.prototype.getDefaultFilters = function () {
+       return this.defaultFilters;
+};
+
+/**
+ * Get the messags defining the 'whats this' popup for this group
+ *
+ * @return {Object} What's this messages
+ */
+FilterGroup.prototype.getWhatsThis = function () {
+       return this.whatsThis;
+};
+
+/**
+ * Check whether this group has a 'what's this' message
+ *
+ * @return {boolean} This group has a what's this message
+ */
+FilterGroup.prototype.hasWhatsThis = function () {
+       return !!this.whatsThis.body;
+};
+
+/**
+ * Get the conflicts associated with the entire group.
+ * Conflict object is set up by filter name keys and conflict
+ * definition. For example:
+ * [
+ *     {
+ *         filterName: {
+ *             filter: filterName,
+ *             group: group1
+ *         }
+ *     },
+ *     {
+ *         filterName2: {
+ *             filter: filterName2,
+ *             group: group2
+ *         }
+ *     }
+ * ]
+ * @return {Object} Conflict definition
+ */
+FilterGroup.prototype.getConflicts = function () {
+       return this.conflicts;
+};
+
+/**
+ * Set conflicts for this group. See #getConflicts for the expected
+ * structure of the definition.
+ *
+ * @param {Object} conflicts Conflicts for this group
+ */
+FilterGroup.prototype.setConflicts = function ( conflicts ) {
+       this.conflicts = conflicts;
+};
+
+/**
+ * Check whether this item has a potential conflict with the given item
+ *
+ * This checks whether the given item is in the list of conflicts of
+ * the current item, but makes no judgment about whether the conflict
+ * is currently at play (either one of the items may not be selected)
+ *
+ * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item
+ * @return {boolean} This item has a conflict with the given item
+ */
+FilterGroup.prototype.existsInConflicts = function ( filterItem ) {
+       return Object.prototype.hasOwnProperty.call( this.getConflicts(), filterItem.getName() );
+};
+
+/**
+ * Check whether there are any items selected
+ *
+ * @return {boolean} Any items in the group are selected
+ */
+FilterGroup.prototype.areAnySelected = function () {
+       return this.getItems().some( function ( filterItem ) {
+               return filterItem.isSelected();
+       } );
+};
+
+/**
+ * Check whether all items selected
+ *
+ * @return {boolean} All items are selected
+ */
+FilterGroup.prototype.areAllSelected = function () {
+       var selected = [],
+               unselected = [];
+
+       this.getItems().forEach( function ( filterItem ) {
+               if ( filterItem.isSelected() ) {
+                       selected.push( filterItem );
+               } else {
+                       unselected.push( filterItem );
+               }
+       } );
 
-               // check if every unselected is a subset of a selected
-               return unselected.every( function ( unselectedFilterItem ) {
-                       return selected.some( function ( selectedFilterItem ) {
-                               return selectedFilterItem.existsInSubset( unselectedFilterItem.getName() );
-                       } );
-               } );
-       };
-
-       /**
-        * Get all selected items in this group
-        *
-        * @param {mw.rcfilters.dm.FilterItem} [excludeItem] Item to exclude from the list
-        * @return {mw.rcfilters.dm.FilterItem[]} Selected items
-        */
-       FilterGroup.prototype.findSelectedItems = function ( excludeItem ) {
-               var excludeName = ( excludeItem && excludeItem.getName() ) || '';
-
-               return this.getItems().filter( function ( item ) {
-                       return item.getName() !== excludeName && item.isSelected();
+       if ( unselected.length === 0 ) {
+               return true;
+       }
+
+       // check if every unselected is a subset of a selected
+       return unselected.every( function ( unselectedFilterItem ) {
+               return selected.some( function ( selectedFilterItem ) {
+                       return selectedFilterItem.existsInSubset( unselectedFilterItem.getName() );
                } );
-       };
-
-       /**
-        * Check whether all selected items are in conflict with the given item
-        *
-        * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item to test
-        * @return {boolean} All selected items are in conflict with this item
-        */
-       FilterGroup.prototype.areAllSelectedInConflictWith = function ( filterItem ) {
-               var selectedItems = this.findSelectedItems( filterItem );
-
-               return selectedItems.length > 0 &&
-                       (
-                               // The group as a whole is in conflict with this item
-                               this.existsInConflicts( filterItem ) ||
-                               // All selected items are in conflict individually
-                               selectedItems.every( function ( selectedFilter ) {
-                                       return selectedFilter.existsInConflicts( filterItem );
-                               } )
-                       );
-       };
-
-       /**
-        * Check whether any of the selected items are in conflict with the given item
-        *
-        * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item to test
-        * @return {boolean} Any of the selected items are in conflict with this item
-        */
-       FilterGroup.prototype.areAnySelectedInConflictWith = function ( filterItem ) {
-               var selectedItems = this.findSelectedItems( filterItem );
-
-               return selectedItems.length > 0 && (
+       } );
+};
+
+/**
+ * Get all selected items in this group
+ *
+ * @param {mw.rcfilters.dm.FilterItem} [excludeItem] Item to exclude from the list
+ * @return {mw.rcfilters.dm.FilterItem[]} Selected items
+ */
+FilterGroup.prototype.findSelectedItems = function ( excludeItem ) {
+       var excludeName = ( excludeItem && excludeItem.getName() ) || '';
+
+       return this.getItems().filter( function ( item ) {
+               return item.getName() !== excludeName && item.isSelected();
+       } );
+};
+
+/**
+ * Check whether all selected items are in conflict with the given item
+ *
+ * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item to test
+ * @return {boolean} All selected items are in conflict with this item
+ */
+FilterGroup.prototype.areAllSelectedInConflictWith = function ( filterItem ) {
+       var selectedItems = this.findSelectedItems( filterItem );
+
+       return selectedItems.length > 0 &&
+               (
                        // The group as a whole is in conflict with this item
                        this.existsInConflicts( filterItem ) ||
-                       // Any selected items are in conflict individually
-                       selectedItems.some( function ( selectedFilter ) {
+                       // All selected items are in conflict individually
+                       selectedItems.every( function ( selectedFilter ) {
                                return selectedFilter.existsInConflicts( filterItem );
                        } )
                );
-       };
-
-       /**
-        * Get the parameter representation from this group
-        *
-        * @param {Object} [filterRepresentation] An object defining the state
-        *  of the filters in this group, keyed by their name and current selected
-        *  state value.
-        * @return {Object} Parameter representation
-        */
-       FilterGroup.prototype.getParamRepresentation = function ( filterRepresentation ) {
-               var values,
-                       areAnySelected = false,
-                       buildFromCurrentState = !filterRepresentation,
-                       defaultFilters = this.getDefaultFilters(),
-                       result = {},
-                       model = this,
-                       filterParamNames = {},
-                       getSelectedParameter = function ( filters ) {
-                               var item,
-                                       selected = [];
-
-                               // Find if any are selected
-                               // eslint-disable-next-line no-jquery/no-each-util
-                               $.each( filters, function ( name, value ) {
-                                       if ( value ) {
-                                               selected.push( name );
-                                       }
-                               } );
-
-                               item = model.getItemByName( selected[ 0 ] );
-                               return ( item && item.getParamName() ) || '';
-                       };
-
-               filterRepresentation = filterRepresentation || {};
-
-               // Create or complete the filterRepresentation definition
-               this.getItems().forEach( function ( item ) {
-                       // Map filter names to their parameter names
-                       filterParamNames[ item.getName() ] = item.getParamName();
-
-                       if ( buildFromCurrentState ) {
-                               // This means we have not been given a filter representation
-                               // so we are building one based on current state
-                               filterRepresentation[ item.getName() ] = item.getValue();
-                       } else if ( filterRepresentation[ item.getName() ] === undefined ) {
-                               // We are given a filter representation, but we have to make
-                               // sure that we fill in the missing filters if there are any
-                               // we will assume they are all falsey
-                               if ( model.isSticky() ) {
-                                       filterRepresentation[ item.getName() ] = !!defaultFilters[ item.getName() ];
-                               } else {
-                                       filterRepresentation[ item.getName() ] = false;
-                               }
-                       }
-
-                       if ( filterRepresentation[ item.getName() ] ) {
-                               areAnySelected = true;
-                       }
-               } );
-
-               // Build result
-               if (
-                       this.getType() === 'send_unselected_if_any' ||
-                       this.getType() === 'boolean' ||
-                       this.getType() === 'any_value'
-               ) {
-                       // First, check if any of the items are selected at all.
-                       // If none is selected, we're treating it as if they are
-                       // all false
-
-                       // Go over the items and define the correct values
+};
+
+/**
+ * Check whether any of the selected items are in conflict with the given item
+ *
+ * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item to test
+ * @return {boolean} Any of the selected items are in conflict with this item
+ */
+FilterGroup.prototype.areAnySelectedInConflictWith = function ( filterItem ) {
+       var selectedItems = this.findSelectedItems( filterItem );
+
+       return selectedItems.length > 0 && (
+               // The group as a whole is in conflict with this item
+               this.existsInConflicts( filterItem ) ||
+               // Any selected items are in conflict individually
+               selectedItems.some( function ( selectedFilter ) {
+                       return selectedFilter.existsInConflicts( filterItem );
+               } )
+       );
+};
+
+/**
+ * Get the parameter representation from this group
+ *
+ * @param {Object} [filterRepresentation] An object defining the state
+ *  of the filters in this group, keyed by their name and current selected
+ *  state value.
+ * @return {Object} Parameter representation
+ */
+FilterGroup.prototype.getParamRepresentation = function ( filterRepresentation ) {
+       var values,
+               areAnySelected = false,
+               buildFromCurrentState = !filterRepresentation,
+               defaultFilters = this.getDefaultFilters(),
+               result = {},
+               model = this,
+               filterParamNames = {},
+               getSelectedParameter = function ( filters ) {
+                       var item,
+                               selected = [];
+
+                       // Find if any are selected
                        // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( filterRepresentation, function ( name, value ) {
-                               // We must store all parameter values as strings '0' or '1'
-                               if ( model.getType() === 'send_unselected_if_any' ) {
-                                       result[ filterParamNames[ name ] ] = areAnySelected ?
-                                               String( Number( !value ) ) :
-                                               '0';
-                               } else if ( model.getType() === 'boolean' ) {
-                                       // Representation is straight-forward and direct from
-                                       // the parameter value to the filter state
-                                       result[ filterParamNames[ name ] ] = String( Number( !!value ) );
-                               } else if ( model.getType() === 'any_value' ) {
-                                       result[ filterParamNames[ name ] ] = value;
-                               }
-                       } );
-               } else if ( this.getType() === 'string_options' ) {
-                       values = [];
-
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( filterRepresentation, function ( name, value ) {
-                               // Collect values
+                       $.each( filters, function ( name, value ) {
                                if ( value ) {
-                                       values.push( filterParamNames[ name ] );
+                                       selected.push( name );
                                }
                        } );
 
-                       result[ this.getName() ] = ( values.length === Object.keys( filterRepresentation ).length ) ?
-                               'all' : values.join( this.getSeparator() );
-               } else if ( this.getType() === 'single_option' ) {
-                       result[ this.getName() ] = getSelectedParameter( filterRepresentation );
-               }
-
-               return result;
-       };
-
-       /**
-        * Get the filter representation this group would provide
-        * based on given parameter states.
-        *
-        * @param {Object} [paramRepresentation] An object defining a parameter
-        *  state to translate the filter state from. If not given, an object
-        *  representing all filters as falsey is returned; same as if the parameter
-        *  given were an empty object, or had some of the filters missing.
-        * @return {Object} Filter representation
-        */
-       FilterGroup.prototype.getFilterRepresentation = function ( paramRepresentation ) {
-               var areAnySelected, paramValues, item, currentValue,
-                       oneWasSelected = false,
-                       defaultParams = this.getDefaultParams(),
-                       expandedParams = $.extend( true, {}, paramRepresentation ),
-                       model = this,
-                       paramToFilterMap = {},
-                       result = {};
-
-               if ( this.isSticky() ) {
-                       // If the group is sticky, check if all parameters are represented
-                       // and for those that aren't represented, add them with their default
-                       // values
-                       paramRepresentation = $.extend( true, {}, this.getDefaultParams(), paramRepresentation );
+                       item = model.getItemByName( selected[ 0 ] );
+                       return ( item && item.getParamName() ) || '';
+               };
+
+       filterRepresentation = filterRepresentation || {};
+
+       // Create or complete the filterRepresentation definition
+       this.getItems().forEach( function ( item ) {
+               // Map filter names to their parameter names
+               filterParamNames[ item.getName() ] = item.getParamName();
+
+               if ( buildFromCurrentState ) {
+                       // This means we have not been given a filter representation
+                       // so we are building one based on current state
+                       filterRepresentation[ item.getName() ] = item.getValue();
+               } else if ( filterRepresentation[ item.getName() ] === undefined ) {
+                       // We are given a filter representation, but we have to make
+                       // sure that we fill in the missing filters if there are any
+                       // we will assume they are all falsey
+                       if ( model.isSticky() ) {
+                               filterRepresentation[ item.getName() ] = !!defaultFilters[ item.getName() ];
+                       } else {
+                               filterRepresentation[ item.getName() ] = false;
+                       }
                }
 
-               paramRepresentation = paramRepresentation || {};
-               if (
-                       this.getType() === 'send_unselected_if_any' ||
-                       this.getType() === 'boolean' ||
-                       this.getType() === 'any_value'
-               ) {
-                       // Go over param representation; map and check for selections
-                       this.getItems().forEach( function ( filterItem ) {
-                               var paramName = filterItem.getParamName();
-
-                               expandedParams[ paramName ] = paramRepresentation[ paramName ] || '0';
-                               paramToFilterMap[ paramName ] = filterItem;
-
-                               if ( Number( paramRepresentation[ filterItem.getParamName() ] ) ) {
-                                       areAnySelected = true;
-                               }
-                       } );
-
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( expandedParams, function ( paramName, paramValue ) {
-                               var filterItem = paramToFilterMap[ paramName ];
-
-                               if ( model.getType() === 'send_unselected_if_any' ) {
-                                       // Flip the definition between the parameter
-                                       // state and the filter state
-                                       // This is what the 'toggleSelected' value of the filter is
-                                       result[ filterItem.getName() ] = areAnySelected ?
-                                               !Number( paramValue ) :
-                                               // Otherwise, there are no selected items in the
-                                               // group, which means the state is false
-                                               false;
-                               } else if ( model.getType() === 'boolean' ) {
-                                       // Straight-forward definition of state
-                                       result[ filterItem.getName() ] = !!Number( paramRepresentation[ filterItem.getParamName() ] );
-                               } else if ( model.getType() === 'any_value' ) {
-                                       result[ filterItem.getName() ] = paramRepresentation[ filterItem.getParamName() ];
-                               }
-                       } );
-               } else if ( this.getType() === 'string_options' ) {
-                       currentValue = paramRepresentation[ this.getName() ] || '';
-
-                       // Normalize the given parameter values
-                       paramValues = mw.rcfilters.utils.normalizeParamOptions(
-                               // Given
-                               currentValue.split(
-                                       this.getSeparator()
-                               ),
-                               // Allowed values
-                               this.getItems().map( function ( filterItem ) {
-                                       return filterItem.getParamName();
-                               } )
-                       );
-                       // Translate the parameter values into a filter selection state
-                       this.getItems().forEach( function ( filterItem ) {
-                               // All true (either because all values are written or the term 'all' is written)
-                               // is the same as all filters set to true
-                               result[ filterItem.getName() ] = (
-                                       // If it is the word 'all'
-                                       paramValues.length === 1 && paramValues[ 0 ] === 'all' ||
-                                       // All values are written
-                                       paramValues.length === model.getItemCount()
-                               ) ?
-                                       true :
-                                       // Otherwise, the filter is selected only if it appears in the parameter values
-                                       paramValues.indexOf( filterItem.getParamName() ) > -1;
-                       } );
-               } else if ( this.getType() === 'single_option' ) {
-                       // There is parameter that fits a single filter and if not, get the default
-                       this.getItems().forEach( function ( filterItem ) {
-                               var selected = filterItem.getParamName() === paramRepresentation[ model.getName() ];
-
-                               result[ filterItem.getName() ] = selected;
-                               oneWasSelected = oneWasSelected || selected;
-                       } );
+               if ( filterRepresentation[ item.getName() ] ) {
+                       areAnySelected = true;
                }
-
-               // Go over result and make sure all filters are represented.
-               // If any filters are missing, they will get a falsey value
-               this.getItems().forEach( function ( filterItem ) {
-                       if ( result[ filterItem.getName() ] === undefined ) {
-                               result[ filterItem.getName() ] = this.getFalsyValue();
+       } );
+
+       // Build result
+       if (
+               this.getType() === 'send_unselected_if_any' ||
+               this.getType() === 'boolean' ||
+               this.getType() === 'any_value'
+       ) {
+               // First, check if any of the items are selected at all.
+               // If none is selected, we're treating it as if they are
+               // all false
+
+               // Go over the items and define the correct values
+               // eslint-disable-next-line no-jquery/no-each-util
+               $.each( filterRepresentation, function ( name, value ) {
+                       // We must store all parameter values as strings '0' or '1'
+                       if ( model.getType() === 'send_unselected_if_any' ) {
+                               result[ filterParamNames[ name ] ] = areAnySelected ?
+                                       String( Number( !value ) ) :
+                                       '0';
+                       } else if ( model.getType() === 'boolean' ) {
+                               // Representation is straight-forward and direct from
+                               // the parameter value to the filter state
+                               result[ filterParamNames[ name ] ] = String( Number( !!value ) );
+                       } else if ( model.getType() === 'any_value' ) {
+                               result[ filterParamNames[ name ] ] = value;
                        }
-               }.bind( this ) );
-
-               // Make sure that at least one option is selected in
-               // single_option groups, no matter what path was taken
-               // If none was selected by the given definition, then
-               // we need to select the one in the base state -- either
-               // the default given, or the first item
-               if (
-                       this.getType() === 'single_option' &&
-                       !oneWasSelected
-               ) {
-                       item = this.getItems()[ 0 ];
-                       if ( defaultParams[ this.getName() ] ) {
-                               item = this.getItemByParamName( defaultParams[ this.getName() ] );
+               } );
+       } else if ( this.getType() === 'string_options' ) {
+               values = [];
+
+               // eslint-disable-next-line no-jquery/no-each-util
+               $.each( filterRepresentation, function ( name, value ) {
+                       // Collect values
+                       if ( value ) {
+                               values.push( filterParamNames[ name ] );
                        }
+               } );
 
-                       result[ item.getName() ] = true;
-               }
-
-               return result;
-       };
-
-       /**
-        * @return {*} The appropriate falsy value for this group type
-        */
-       FilterGroup.prototype.getFalsyValue = function () {
-               return this.getType() === 'any_value' ? '' : false;
-       };
+               result[ this.getName() ] = ( values.length === Object.keys( filterRepresentation ).length ) ?
+                       'all' : values.join( this.getSeparator() );
+       } else if ( this.getType() === 'single_option' ) {
+               result[ this.getName() ] = getSelectedParameter( filterRepresentation );
+       }
+
+       return result;
+};
+
+/**
+ * Get the filter representation this group would provide
+ * based on given parameter states.
+ *
+ * @param {Object} [paramRepresentation] An object defining a parameter
+ *  state to translate the filter state from. If not given, an object
+ *  representing all filters as falsey is returned; same as if the parameter
+ *  given were an empty object, or had some of the filters missing.
+ * @return {Object} Filter representation
+ */
+FilterGroup.prototype.getFilterRepresentation = function ( paramRepresentation ) {
+       var areAnySelected, paramValues, item, currentValue,
+               oneWasSelected = false,
+               defaultParams = this.getDefaultParams(),
+               expandedParams = $.extend( true, {}, paramRepresentation ),
+               model = this,
+               paramToFilterMap = {},
+               result = {};
+
+       if ( this.isSticky() ) {
+               // If the group is sticky, check if all parameters are represented
+               // and for those that aren't represented, add them with their default
+               // values
+               paramRepresentation = $.extend( true, {}, this.getDefaultParams(), paramRepresentation );
+       }
+
+       paramRepresentation = paramRepresentation || {};
+       if (
+               this.getType() === 'send_unselected_if_any' ||
+               this.getType() === 'boolean' ||
+               this.getType() === 'any_value'
+       ) {
+               // Go over param representation; map and check for selections
+               this.getItems().forEach( function ( filterItem ) {
+                       var paramName = filterItem.getParamName();
 
-       /**
-        * Get current selected state of all filter items in this group
-        *
-        * @return {Object} Selected state
-        */
-       FilterGroup.prototype.getSelectedState = function () {
-               var state = {};
+                       expandedParams[ paramName ] = paramRepresentation[ paramName ] || '0';
+                       paramToFilterMap[ paramName ] = filterItem;
 
-               this.getItems().forEach( function ( filterItem ) {
-                       state[ filterItem.getName() ] = filterItem.getValue();
+                       if ( Number( paramRepresentation[ filterItem.getParamName() ] ) ) {
+                               areAnySelected = true;
+                       }
                } );
 
-               return state;
-       };
-
-       /**
-        * Get item by its filter name
-        *
-        * @param {string} filterName Filter name
-        * @return {mw.rcfilters.dm.FilterItem} Filter item
-        */
-       FilterGroup.prototype.getItemByName = function ( filterName ) {
-               return this.getItems().filter( function ( item ) {
-                       return item.getName() === filterName;
-               } )[ 0 ];
-       };
-
-       /**
-        * Select an item by its parameter name
-        *
-        * @param {string} paramName Filter parameter name
-        */
-       FilterGroup.prototype.selectItemByParamName = function ( paramName ) {
-               this.getItems().forEach( function ( item ) {
-                       item.toggleSelected( item.getParamName() === String( paramName ) );
+               // eslint-disable-next-line no-jquery/no-each-util
+               $.each( expandedParams, function ( paramName, paramValue ) {
+                       var filterItem = paramToFilterMap[ paramName ];
+
+                       if ( model.getType() === 'send_unselected_if_any' ) {
+                               // Flip the definition between the parameter
+                               // state and the filter state
+                               // This is what the 'toggleSelected' value of the filter is
+                               result[ filterItem.getName() ] = areAnySelected ?
+                                       !Number( paramValue ) :
+                                       // Otherwise, there are no selected items in the
+                                       // group, which means the state is false
+                                       false;
+                       } else if ( model.getType() === 'boolean' ) {
+                               // Straight-forward definition of state
+                               result[ filterItem.getName() ] = !!Number( paramRepresentation[ filterItem.getParamName() ] );
+                       } else if ( model.getType() === 'any_value' ) {
+                               result[ filterItem.getName() ] = paramRepresentation[ filterItem.getParamName() ];
+                       }
                } );
-       };
-
-       /**
-        * Get item by its parameter name
-        *
-        * @param {string} paramName Parameter name
-        * @return {mw.rcfilters.dm.FilterItem} Filter item
-        */
-       FilterGroup.prototype.getItemByParamName = function ( paramName ) {
-               return this.getItems().filter( function ( item ) {
-                       return item.getParamName() === String( paramName );
-               } )[ 0 ];
-       };
-
-       /**
-        * Get group type
-        *
-        * @return {string} Group type
-        */
-       FilterGroup.prototype.getType = function () {
-               return this.type;
-       };
-
-       /**
-        * Check whether this group is represented by a single parameter
-        * or whether each item is its own parameter
-        *
-        * @return {boolean} This group is a single parameter
-        */
-       FilterGroup.prototype.isPerGroupRequestParameter = function () {
-               return (
-                       this.getType() === 'string_options' ||
-                       this.getType() === 'single_option'
+       } else if ( this.getType() === 'string_options' ) {
+               currentValue = paramRepresentation[ this.getName() ] || '';
+
+               // Normalize the given parameter values
+               paramValues = mw.rcfilters.utils.normalizeParamOptions(
+                       // Given
+                       currentValue.split(
+                               this.getSeparator()
+                       ),
+                       // Allowed values
+                       this.getItems().map( function ( filterItem ) {
+                               return filterItem.getParamName();
+                       } )
                );
-       };
-
-       /**
-        * Get display group
-        *
-        * @return {string} Display group
-        */
-       FilterGroup.prototype.getView = function () {
-               return this.view;
-       };
-
-       /**
-        * Get the prefix used for the filter names inside this group.
-        *
-        * @param {string} [name] Filter name to prefix
-        * @return {string} Group prefix
-        */
-       FilterGroup.prototype.getNamePrefix = function () {
-               return this.getName() + '__';
-       };
-
-       /**
-        * Get a filter name with the prefix used for the filter names inside this group.
-        *
-        * @param {string} name Filter name to prefix
-        * @return {string} Group prefix
-        */
-       FilterGroup.prototype.getPrefixedName = function ( name ) {
-               return this.getNamePrefix() + name;
-       };
-
-       /**
-        * Get group's title
-        *
-        * @return {string} Title
-        */
-       FilterGroup.prototype.getTitle = function () {
-               return this.title;
-       };
-
-       /**
-        * Get group's values separator
-        *
-        * @return {string} Values separator
-        */
-       FilterGroup.prototype.getSeparator = function () {
-               return this.separator;
-       };
-
-       /**
-        * Check whether the group is defined as full coverage
-        *
-        * @return {boolean} Group is full coverage
-        */
-       FilterGroup.prototype.isFullCoverage = function () {
-               return this.fullCoverage;
-       };
-
-       /**
-        * Check whether the group is defined as sticky default
-        *
-        * @return {boolean} Group is sticky default
-        */
-       FilterGroup.prototype.isSticky = function () {
-               return this.sticky;
-       };
-
-       /**
-        * Normalize a value given to this group. This is mostly for correcting
-        * arbitrary values for 'single option' groups, given by the user settings
-        * or the URL that can go outside the limits that are allowed.
-        *
-        * @param  {string} value Given value
-        * @return {string} Corrected value
-        */
-       FilterGroup.prototype.normalizeArbitraryValue = function ( value ) {
-               if (
-                       this.getType() === 'single_option' &&
-                       this.isAllowArbitrary()
-               ) {
-                       if (
-                               this.getMaxValue() !== null &&
-                               value > this.getMaxValue()
-                       ) {
-                               // Change the value to the actual max value
-                               return String( this.getMaxValue() );
-                       } else if (
-                               this.getMinValue() !== null &&
-                               value < this.getMinValue()
-                       ) {
-                               // Change the value to the actual min value
-                               return String( this.getMinValue() );
-                       }
-               }
-
-               return value;
-       };
+               // Translate the parameter values into a filter selection state
+               this.getItems().forEach( function ( filterItem ) {
+                       // All true (either because all values are written or the term 'all' is written)
+                       // is the same as all filters set to true
+                       result[ filterItem.getName() ] = (
+                               // If it is the word 'all'
+                               paramValues.length === 1 && paramValues[ 0 ] === 'all' ||
+                               // All values are written
+                               paramValues.length === model.getItemCount()
+                       ) ?
+                               true :
+                               // Otherwise, the filter is selected only if it appears in the parameter values
+                               paramValues.indexOf( filterItem.getParamName() ) > -1;
+               } );
+       } else if ( this.getType() === 'single_option' ) {
+               // There is parameter that fits a single filter and if not, get the default
+               this.getItems().forEach( function ( filterItem ) {
+                       var selected = filterItem.getParamName() === paramRepresentation[ model.getName() ];
 
-       /**
-        * Toggle the visibility of this group
-        *
-        * @param {boolean} [isVisible] Item is visible
-        */
-       FilterGroup.prototype.toggleVisible = function ( isVisible ) {
-               isVisible = isVisible === undefined ? !this.visible : isVisible;
+                       result[ filterItem.getName() ] = selected;
+                       oneWasSelected = oneWasSelected || selected;
+               } );
+       }
 
-               if ( this.visible !== isVisible ) {
-                       this.visible = isVisible;
-                       this.emit( 'update' );
+       // Go over result and make sure all filters are represented.
+       // If any filters are missing, they will get a falsey value
+       this.getItems().forEach( function ( filterItem ) {
+               if ( result[ filterItem.getName() ] === undefined ) {
+                       result[ filterItem.getName() ] = this.getFalsyValue();
+               }
+       }.bind( this ) );
+
+       // Make sure that at least one option is selected in
+       // single_option groups, no matter what path was taken
+       // If none was selected by the given definition, then
+       // we need to select the one in the base state -- either
+       // the default given, or the first item
+       if (
+               this.getType() === 'single_option' &&
+               !oneWasSelected
+       ) {
+               item = this.getItems()[ 0 ];
+               if ( defaultParams[ this.getName() ] ) {
+                       item = this.getItemByParamName( defaultParams[ this.getName() ] );
                }
-       };
-
-       /**
-        * Check whether the group is visible
-        *
-        * @return {boolean} Group is visible
-        */
-       FilterGroup.prototype.isVisible = function () {
-               return this.visible;
-       };
-
-       /**
-        * Set the visibility of the items under this group by the given items array
-        *
-        * @param {mw.rcfilters.dm.ItemModel[]} visibleItems An array of visible items
-        */
-       FilterGroup.prototype.setVisibleItems = function ( visibleItems ) {
-               this.getItems().forEach( function ( itemModel ) {
-                       itemModel.toggleVisible( visibleItems.indexOf( itemModel ) !== -1 );
-               } );
-       };
 
-       module.exports = FilterGroup;
-}() );
+               result[ item.getName() ] = true;
+       }
+
+       return result;
+};
+
+/**
+ * @return {*} The appropriate falsy value for this group type
+ */
+FilterGroup.prototype.getFalsyValue = function () {
+       return this.getType() === 'any_value' ? '' : false;
+};
+
+/**
+ * Get current selected state of all filter items in this group
+ *
+ * @return {Object} Selected state
+ */
+FilterGroup.prototype.getSelectedState = function () {
+       var state = {};
+
+       this.getItems().forEach( function ( filterItem ) {
+               state[ filterItem.getName() ] = filterItem.getValue();
+       } );
+
+       return state;
+};
+
+/**
+ * Get item by its filter name
+ *
+ * @param {string} filterName Filter name
+ * @return {mw.rcfilters.dm.FilterItem} Filter item
+ */
+FilterGroup.prototype.getItemByName = function ( filterName ) {
+       return this.getItems().filter( function ( item ) {
+               return item.getName() === filterName;
+       } )[ 0 ];
+};
+
+/**
+ * Select an item by its parameter name
+ *
+ * @param {string} paramName Filter parameter name
+ */
+FilterGroup.prototype.selectItemByParamName = function ( paramName ) {
+       this.getItems().forEach( function ( item ) {
+               item.toggleSelected( item.getParamName() === String( paramName ) );
+       } );
+};
+
+/**
+ * Get item by its parameter name
+ *
+ * @param {string} paramName Parameter name
+ * @return {mw.rcfilters.dm.FilterItem} Filter item
+ */
+FilterGroup.prototype.getItemByParamName = function ( paramName ) {
+       return this.getItems().filter( function ( item ) {
+               return item.getParamName() === String( paramName );
+       } )[ 0 ];
+};
+
+/**
+ * Get group type
+ *
+ * @return {string} Group type
+ */
+FilterGroup.prototype.getType = function () {
+       return this.type;
+};
+
+/**
+ * Check whether this group is represented by a single parameter
+ * or whether each item is its own parameter
+ *
+ * @return {boolean} This group is a single parameter
+ */
+FilterGroup.prototype.isPerGroupRequestParameter = function () {
+       return (
+               this.getType() === 'string_options' ||
+               this.getType() === 'single_option'
+       );
+};
+
+/**
+ * Get display group
+ *
+ * @return {string} Display group
+ */
+FilterGroup.prototype.getView = function () {
+       return this.view;
+};
+
+/**
+ * Get the prefix used for the filter names inside this group.
+ *
+ * @return {string} Group prefix
+ */
+FilterGroup.prototype.getNamePrefix = function () {
+       return this.getName() + '__';
+};
+
+/**
+ * Get a filter name with the prefix used for the filter names inside this group.
+ *
+ * @param {string} name Filter name to prefix
+ * @return {string} Group prefix
+ */
+FilterGroup.prototype.getPrefixedName = function ( name ) {
+       return this.getNamePrefix() + name;
+};
+
+/**
+ * Get group's title
+ *
+ * @return {string} Title
+ */
+FilterGroup.prototype.getTitle = function () {
+       return this.title;
+};
+
+/**
+ * Get group's values separator
+ *
+ * @return {string} Values separator
+ */
+FilterGroup.prototype.getSeparator = function () {
+       return this.separator;
+};
+
+/**
+ * Check whether the group is defined as full coverage
+ *
+ * @return {boolean} Group is full coverage
+ */
+FilterGroup.prototype.isFullCoverage = function () {
+       return this.fullCoverage;
+};
+
+/**
+ * Check whether the group is defined as sticky default
+ *
+ * @return {boolean} Group is sticky default
+ */
+FilterGroup.prototype.isSticky = function () {
+       return this.sticky;
+};
+
+/**
+ * Normalize a value given to this group. This is mostly for correcting
+ * arbitrary values for 'single option' groups, given by the user settings
+ * or the URL that can go outside the limits that are allowed.
+ *
+ * @param  {string} value Given value
+ * @return {string} Corrected value
+ */
+FilterGroup.prototype.normalizeArbitraryValue = function ( value ) {
+       if (
+               this.getType() === 'single_option' &&
+               this.isAllowArbitrary()
+       ) {
+               if (
+                       this.getMaxValue() !== null &&
+                       value > this.getMaxValue()
+               ) {
+                       // Change the value to the actual max value
+                       return String( this.getMaxValue() );
+               } else if (
+                       this.getMinValue() !== null &&
+                       value < this.getMinValue()
+               ) {
+                       // Change the value to the actual min value
+                       return String( this.getMinValue() );
+               }
+       }
+
+       return value;
+};
+
+/**
+ * Toggle the visibility of this group
+ *
+ * @param {boolean} [isVisible] Item is visible
+ */
+FilterGroup.prototype.toggleVisible = function ( isVisible ) {
+       isVisible = isVisible === undefined ? !this.visible : isVisible;
+
+       if ( this.visible !== isVisible ) {
+               this.visible = isVisible;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Check whether the group is visible
+ *
+ * @return {boolean} Group is visible
+ */
+FilterGroup.prototype.isVisible = function () {
+       return this.visible;
+};
+
+/**
+ * Set the visibility of the items under this group by the given items array
+ *
+ * @param {mw.rcfilters.dm.ItemModel[]} visibleItems An array of visible items
+ */
+FilterGroup.prototype.setVisibleItems = function ( visibleItems ) {
+       this.getItems().forEach( function ( itemModel ) {
+               itemModel.toggleVisible( visibleItems.indexOf( itemModel ) !== -1 );
+       } );
+};
+
+module.exports = FilterGroup;
index 1138c4e..50057af 100644 (file)
-( function () {
-       var ItemModel = require( './ItemModel.js' ),
-               FilterItem;
-
-       /**
-        * Filter item model
-        *
-        * @class mw.rcfilters.dm.FilterItem
-        * @extends mw.rcfilters.dm.ItemModel
-        *
-        * @constructor
-        * @param {string} param Filter param name
-        * @param {mw.rcfilters.dm.FilterGroup} groupModel Filter group model
-        * @param {Object} config Configuration object
-        * @cfg {string[]} [excludes=[]] A list of filter names this filter, if
-        *  selected, makes inactive.
-        * @cfg {string[]} [subset] Defining the names of filters that are a subset of this filter
-        * @cfg {Object} [conflicts] Defines the conflicts for this filter
-        * @cfg {boolean} [visible=true] The visibility of the group
-        */
-       FilterItem = function MwRcfiltersDmFilterItem( param, groupModel, config ) {
-               config = config || {};
-
-               this.groupModel = groupModel;
-
-               // Parent
-               FilterItem.parent.call( this, param, $.extend( {
-                       namePrefix: this.groupModel.getNamePrefix()
-               }, config ) );
-               // Mixin constructor
-               OO.EventEmitter.call( this );
-
-               // Interaction definitions
-               this.subset = config.subset || [];
-               this.conflicts = config.conflicts || {};
-               this.superset = [];
-               this.visible = config.visible === undefined ? true : !!config.visible;
-
-               // Interaction states
-               this.included = false;
-               this.conflicted = false;
-               this.fullyCovered = false;
+var ItemModel = require( './ItemModel.js' ),
+       FilterItem;
+
+/**
+ * Filter item model
+ *
+ * @class mw.rcfilters.dm.FilterItem
+ * @extends mw.rcfilters.dm.ItemModel
+ *
+ * @constructor
+ * @param {string} param Filter param name
+ * @param {mw.rcfilters.dm.FilterGroup} groupModel Filter group model
+ * @param {Object} config Configuration object
+ * @cfg {string[]} [excludes=[]] A list of filter names this filter, if
+ *  selected, makes inactive.
+ * @cfg {string[]} [subset] Defining the names of filters that are a subset of this filter
+ * @cfg {Object} [conflicts] Defines the conflicts for this filter
+ * @cfg {boolean} [visible=true] The visibility of the group
+ */
+FilterItem = function MwRcfiltersDmFilterItem( param, groupModel, config ) {
+       config = config || {};
+
+       this.groupModel = groupModel;
+
+       // Parent
+       FilterItem.parent.call( this, param, $.extend( {
+               namePrefix: this.groupModel.getNamePrefix()
+       }, config ) );
+       // Mixin constructor
+       OO.EventEmitter.call( this );
+
+       // Interaction definitions
+       this.subset = config.subset || [];
+       this.conflicts = config.conflicts || {};
+       this.superset = [];
+       this.visible = config.visible === undefined ? true : !!config.visible;
+
+       // Interaction states
+       this.included = false;
+       this.conflicted = false;
+       this.fullyCovered = false;
+};
+
+/* Initialization */
+
+OO.inheritClass( FilterItem, ItemModel );
+
+/* Methods */
+
+/**
+ * Return the representation of the state of this item.
+ *
+ * @return {Object} State of the object
+ */
+FilterItem.prototype.getState = function () {
+       return {
+               selected: this.isSelected(),
+               included: this.isIncluded(),
+               conflicted: this.isConflicted(),
+               fullyCovered: this.isFullyCovered()
        };
-
-       /* Initialization */
-
-       OO.inheritClass( FilterItem, ItemModel );
-
-       /* Methods */
-
-       /**
-        * Return the representation of the state of this item.
-        *
-        * @return {Object} State of the object
-        */
-       FilterItem.prototype.getState = function () {
-               return {
-                       selected: this.isSelected(),
-                       included: this.isIncluded(),
-                       conflicted: this.isConflicted(),
-                       fullyCovered: this.isFullyCovered()
-               };
-       };
-
-       /**
-        * Get the message for the display area for the currently active conflict
-        *
-        * @private
-        * @return {string} Conflict result message key
-        */
-       FilterItem.prototype.getCurrentConflictResultMessage = function () {
-               var details = {};
-
-               // First look in filter's own conflicts
-               details = this.getConflictDetails( this.getOwnConflicts(), 'globalDescription' );
-               if ( !details.message ) {
-                       // Fall back onto conflicts in the group
-                       details = this.getConflictDetails( this.getGroupModel().getConflicts(), 'globalDescription' );
-               }
-
-               return details.message;
-       };
-
-       /**
-        * Get the details of the active conflict on this filter
-        *
-        * @private
-        * @param {Object} conflicts Conflicts to examine
-        * @param {string} [key='contextDescription'] Message key
-        * @return {Object} Object with conflict message and conflict items
-        * @return {string} return.message Conflict message
-        * @return {string[]} return.names Conflicting item labels
-        */
-       FilterItem.prototype.getConflictDetails = function ( conflicts, key ) {
-               var group,
-                       conflictMessage = '',
-                       itemLabels = [];
-
-               key = key || 'contextDescription';
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( conflicts, function ( filterName, conflict ) {
-                       if ( !conflict.item.isSelected() ) {
-                               return;
-                       }
-
-                       if ( !conflictMessage ) {
-                               conflictMessage = conflict[ key ];
-                               group = conflict.group;
-                       }
-
-                       if ( group === conflict.group ) {
-                               itemLabels.push( mw.msg( 'quotation-marks', conflict.item.getLabel() ) );
-                       }
-               } );
-
-               return {
-                       message: conflictMessage,
-                       names: itemLabels
-               };
-
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterItem.prototype.getStateMessage = function () {
-               var messageKey, details, superset,
-                       affectingItems = [];
-
-               if ( this.isSelected() ) {
-                       if ( this.isConflicted() ) {
-                               // First look in filter's own conflicts
-                               details = this.getConflictDetails( this.getOwnConflicts() );
-                               if ( !details.message ) {
-                                       // Fall back onto conflicts in the group
-                                       details = this.getConflictDetails( this.getGroupModel().getConflicts() );
-                               }
-
-                               messageKey = details.message;
-                               affectingItems = details.names;
-                       } else if ( this.isIncluded() && !this.isHighlighted() ) {
-                               // We only show the 'no effect' full-coverage message
-                               // if the item is also not highlighted. See T161273
-                               superset = this.getSuperset();
-                               // For this message we need to collect the affecting superset
-                               affectingItems = this.getGroupModel().findSelectedItems( this )
-                                       .filter( function ( item ) {
-                                               return superset.indexOf( item.getName() ) !== -1;
-                                       } )
-                                       .map( function ( item ) {
-                                               return mw.msg( 'quotation-marks', item.getLabel() );
-                                       } );
-
-                               messageKey = 'rcfilters-state-message-subset';
-                       } else if ( this.isFullyCovered() && !this.isHighlighted() ) {
-                               affectingItems = this.getGroupModel().findSelectedItems( this )
-                                       .map( function ( item ) {
-                                               return mw.msg( 'quotation-marks', item.getLabel() );
-                                       } );
-
-                               messageKey = 'rcfilters-state-message-fullcoverage';
-                       }
+};
+
+/**
+ * Get the message for the display area for the currently active conflict
+ *
+ * @return {string} Conflict result message key
+ */
+FilterItem.prototype.getCurrentConflictResultMessage = function () {
+       var details;
+
+       // First look in filter's own conflicts
+       details = this.getConflictDetails( this.getOwnConflicts(), 'globalDescription' );
+       if ( !details.message ) {
+               // Fall back onto conflicts in the group
+               details = this.getConflictDetails( this.getGroupModel().getConflicts(), 'globalDescription' );
+       }
+
+       return details.message;
+};
+
+/**
+ * Get the details of the active conflict on this filter
+ *
+ * @private
+ * @param {Object} conflicts Conflicts to examine
+ * @param {string} [key='contextDescription'] Message key
+ * @return {Object} Object with conflict message and conflict items
+ * @return {string} return.message Conflict message
+ * @return {string[]} return.names Conflicting item labels
+ */
+FilterItem.prototype.getConflictDetails = function ( conflicts, key ) {
+       var group,
+               conflictMessage = '',
+               itemLabels = [];
+
+       key = key || 'contextDescription';
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( conflicts, function ( filterName, conflict ) {
+               if ( !conflict.item.isSelected() ) {
+                       return;
                }
 
-               if ( messageKey ) {
-                       // Build message
-                       return mw.msg(
-                               messageKey,
-                               mw.language.listToText( affectingItems ),
-                               affectingItems.length
-                       );
+               if ( !conflictMessage ) {
+                       conflictMessage = conflict[ key ];
+                       group = conflict.group;
                }
 
-               // Display description
-               return this.getDescription();
-       };
-
-       /**
-        * Get the model of the group this filter belongs to
-        *
-        * @return {mw.rcfilters.dm.FilterGroup} Filter group model
-        */
-       FilterItem.prototype.getGroupModel = function () {
-               return this.groupModel;
-       };
-
-       /**
-        * Get the group name this filter belongs to
-        *
-        * @return {string} Filter group name
-        */
-       FilterItem.prototype.getGroupName = function () {
-               return this.groupModel.getName();
-       };
-
-       /**
-        * Get filter subset
-        * This is a list of filter names that are defined to be included
-        * when this filter is selected.
-        *
-        * @return {string[]} Filter subset
-        */
-       FilterItem.prototype.getSubset = function () {
-               return this.subset;
-       };
-
-       /**
-        * Get filter superset
-        * This is a generated list of filters that define this filter
-        * to be included when either of them is selected.
-        *
-        * @return {string[]} Filter superset
-        */
-       FilterItem.prototype.getSuperset = function () {
-               return this.superset;
-       };
-
-       /**
-        * Check whether the filter is currently in a conflict state
-        *
-        * @return {boolean} Filter is in conflict state
-        */
-       FilterItem.prototype.isConflicted = function () {
-               return this.conflicted;
-       };
-
-       /**
-        * Check whether the filter is currently in an already included subset
-        *
-        * @return {boolean} Filter is in an already-included subset
-        */
-       FilterItem.prototype.isIncluded = function () {
-               return this.included;
-       };
-
-       /**
-        * Check whether the filter is currently fully covered
-        *
-        * @return {boolean} Filter is in fully-covered state
-        */
-       FilterItem.prototype.isFullyCovered = function () {
-               return this.fullyCovered;
-       };
-
-       /**
-        * Get all conflicts associated with this filter or its group
-        *
-        * Conflict object is set up by filter name keys and conflict
-        * definition. For example:
-        *
-        *  {
-        *      filterName: {
-        *          filter: filterName,
-        *          group: group1,
-        *          label: itemLabel,
-        *          item: itemModel
-        *      }
-        *      filterName2: {
-        *          filter: filterName2,
-        *          group: group2
-        *          label: itemLabel2,
-        *          item: itemModel2
-        *      }
-        *  }
-        *
-        * @return {Object} Filter conflicts
-        */
-       FilterItem.prototype.getConflicts = function () {
-               return $.extend( {}, this.conflicts, this.getGroupModel().getConflicts() );
-       };
-
-       /**
-        * Get the conflicts associated with this filter
-        *
-        * @return {Object} Filter conflicts
-        */
-       FilterItem.prototype.getOwnConflicts = function () {
-               return this.conflicts;
-       };
-
-       /**
-        * Set conflicts for this filter. See #getConflicts for the expected
-        * structure of the definition.
-        *
-        * @param {Object} conflicts Conflicts for this filter
-        */
-       FilterItem.prototype.setConflicts = function ( conflicts ) {
-               this.conflicts = conflicts || {};
-       };
-
-       /**
-        * Set filter superset
-        *
-        * @param {string[]} superset Filter superset
-        */
-       FilterItem.prototype.setSuperset = function ( superset ) {
-               this.superset = superset || [];
-       };
-
-       /**
-        * Set filter subset
-        *
-        * @param {string[]} subset Filter subset
-        */
-       FilterItem.prototype.setSubset = function ( subset ) {
-               this.subset = subset || [];
-       };
-
-       /**
-        * Check whether a filter exists in the subset list for this filter
-        *
-        * @param {string} filterName Filter name
-        * @return {boolean} Filter name is in the subset list
-        */
-       FilterItem.prototype.existsInSubset = function ( filterName ) {
-               return this.subset.indexOf( filterName ) > -1;
-       };
-
-       /**
-        * Check whether this item has a potential conflict with the given item
-        *
-        * This checks whether the given item is in the list of conflicts of
-        * the current item, but makes no judgment about whether the conflict
-        * is currently at play (either one of the items may not be selected)
-        *
-        * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item
-        * @return {boolean} This item has a conflict with the given item
-        */
-       FilterItem.prototype.existsInConflicts = function ( filterItem ) {
-               return Object.prototype.hasOwnProperty.call( this.getConflicts(), filterItem.getName() );
-       };
-
-       /**
-        * Set the state of this filter as being conflicted
-        * (This means any filters in its conflicts are selected)
-        *
-        * @param {boolean} [conflicted] Filter is in conflict state
-        * @fires update
-        */
-       FilterItem.prototype.toggleConflicted = function ( conflicted ) {
-               conflicted = conflicted === undefined ? !this.conflicted : conflicted;
-
-               if ( this.conflicted !== conflicted ) {
-                       this.conflicted = conflicted;
-                       this.emit( 'update' );
+               if ( group === conflict.group ) {
+                       itemLabels.push( mw.msg( 'quotation-marks', conflict.item.getLabel() ) );
                }
-       };
+       } );
 
-       /**
-        * Set the state of this filter as being already included
-        * (This means any filters in its superset are selected)
-        *
-        * @param {boolean} [included] Filter is included as part of a subset
-        * @fires update
-        */
-       FilterItem.prototype.toggleIncluded = function ( included ) {
-               included = included === undefined ? !this.included : included;
-
-               if ( this.included !== included ) {
-                       this.included = included;
-                       this.emit( 'update' );
-               }
+       return {
+               message: conflictMessage,
+               names: itemLabels
        };
 
-       /**
-        * Toggle the fully covered state of the item
-        *
-        * @param {boolean} [isFullyCovered] Filter is fully covered
-        * @fires update
-        */
-       FilterItem.prototype.toggleFullyCovered = function ( isFullyCovered ) {
-               isFullyCovered = isFullyCovered === undefined ? !this.fullycovered : isFullyCovered;
-
-               if ( this.fullyCovered !== isFullyCovered ) {
-                       this.fullyCovered = isFullyCovered;
-                       this.emit( 'update' );
-               }
-       };
+};
+
+/**
+ * @inheritdoc
+ */
+FilterItem.prototype.getStateMessage = function () {
+       var messageKey, details, superset,
+               affectingItems = [];
+
+       if ( this.isSelected() ) {
+               if ( this.isConflicted() ) {
+                       // First look in filter's own conflicts
+                       details = this.getConflictDetails( this.getOwnConflicts() );
+                       if ( !details.message ) {
+                               // Fall back onto conflicts in the group
+                               details = this.getConflictDetails( this.getGroupModel().getConflicts() );
+                       }
 
-       /**
-        * Toggle the visibility of this item
-        *
-        * @param {boolean} [isVisible] Item is visible
-        */
-       FilterItem.prototype.toggleVisible = function ( isVisible ) {
-               isVisible = isVisible === undefined ? !this.visible : !!isVisible;
-
-               if ( this.visible !== isVisible ) {
-                       this.visible = isVisible;
-                       this.emit( 'update' );
+                       messageKey = details.message;
+                       affectingItems = details.names;
+               } else if ( this.isIncluded() && !this.isHighlighted() ) {
+                       // We only show the 'no effect' full-coverage message
+                       // if the item is also not highlighted. See T161273
+                       superset = this.getSuperset();
+                       // For this message we need to collect the affecting superset
+                       affectingItems = this.getGroupModel().findSelectedItems( this )
+                               .filter( function ( item ) {
+                                       return superset.indexOf( item.getName() ) !== -1;
+                               } )
+                               .map( function ( item ) {
+                                       return mw.msg( 'quotation-marks', item.getLabel() );
+                               } );
+
+                       messageKey = 'rcfilters-state-message-subset';
+               } else if ( this.isFullyCovered() && !this.isHighlighted() ) {
+                       affectingItems = this.getGroupModel().findSelectedItems( this )
+                               .map( function ( item ) {
+                                       return mw.msg( 'quotation-marks', item.getLabel() );
+                               } );
+
+                       messageKey = 'rcfilters-state-message-fullcoverage';
                }
-       };
-
-       /**
-        * Check whether the item is visible
-        *
-        * @return {boolean} Item is visible
-        */
-       FilterItem.prototype.isVisible = function () {
-               return this.visible;
-       };
-
-       module.exports = FilterItem;
-
-}() );
+       }
+
+       if ( messageKey ) {
+               // Build message
+               return mw.msg(
+                       messageKey,
+                       mw.language.listToText( affectingItems ),
+                       affectingItems.length
+               );
+       }
+
+       // Display description
+       return this.getDescription();
+};
+
+/**
+ * Get the model of the group this filter belongs to
+ *
+ * @return {mw.rcfilters.dm.FilterGroup} Filter group model
+ */
+FilterItem.prototype.getGroupModel = function () {
+       return this.groupModel;
+};
+
+/**
+ * Get the group name this filter belongs to
+ *
+ * @return {string} Filter group name
+ */
+FilterItem.prototype.getGroupName = function () {
+       return this.groupModel.getName();
+};
+
+/**
+ * Get filter subset
+ * This is a list of filter names that are defined to be included
+ * when this filter is selected.
+ *
+ * @return {string[]} Filter subset
+ */
+FilterItem.prototype.getSubset = function () {
+       return this.subset;
+};
+
+/**
+ * Get filter superset
+ * This is a generated list of filters that define this filter
+ * to be included when either of them is selected.
+ *
+ * @return {string[]} Filter superset
+ */
+FilterItem.prototype.getSuperset = function () {
+       return this.superset;
+};
+
+/**
+ * Check whether the filter is currently in a conflict state
+ *
+ * @return {boolean} Filter is in conflict state
+ */
+FilterItem.prototype.isConflicted = function () {
+       return this.conflicted;
+};
+
+/**
+ * Check whether the filter is currently in an already included subset
+ *
+ * @return {boolean} Filter is in an already-included subset
+ */
+FilterItem.prototype.isIncluded = function () {
+       return this.included;
+};
+
+/**
+ * Check whether the filter is currently fully covered
+ *
+ * @return {boolean} Filter is in fully-covered state
+ */
+FilterItem.prototype.isFullyCovered = function () {
+       return this.fullyCovered;
+};
+
+/**
+ * Get all conflicts associated with this filter or its group
+ *
+ * Conflict object is set up by filter name keys and conflict
+ * definition. For example:
+ *
+ *  {
+ *      filterName: {
+ *          filter: filterName,
+ *          group: group1,
+ *          label: itemLabel,
+ *          item: itemModel
+ *      }
+ *      filterName2: {
+ *          filter: filterName2,
+ *          group: group2
+ *          label: itemLabel2,
+ *          item: itemModel2
+ *      }
+ *  }
+ *
+ * @return {Object} Filter conflicts
+ */
+FilterItem.prototype.getConflicts = function () {
+       return $.extend( {}, this.conflicts, this.getGroupModel().getConflicts() );
+};
+
+/**
+ * Get the conflicts associated with this filter
+ *
+ * @return {Object} Filter conflicts
+ */
+FilterItem.prototype.getOwnConflicts = function () {
+       return this.conflicts;
+};
+
+/**
+ * Set conflicts for this filter. See #getConflicts for the expected
+ * structure of the definition.
+ *
+ * @param {Object} conflicts Conflicts for this filter
+ */
+FilterItem.prototype.setConflicts = function ( conflicts ) {
+       this.conflicts = conflicts || {};
+};
+
+/**
+ * Set filter superset
+ *
+ * @param {string[]} superset Filter superset
+ */
+FilterItem.prototype.setSuperset = function ( superset ) {
+       this.superset = superset || [];
+};
+
+/**
+ * Set filter subset
+ *
+ * @param {string[]} subset Filter subset
+ */
+FilterItem.prototype.setSubset = function ( subset ) {
+       this.subset = subset || [];
+};
+
+/**
+ * Check whether a filter exists in the subset list for this filter
+ *
+ * @param {string} filterName Filter name
+ * @return {boolean} Filter name is in the subset list
+ */
+FilterItem.prototype.existsInSubset = function ( filterName ) {
+       return this.subset.indexOf( filterName ) > -1;
+};
+
+/**
+ * Check whether this item has a potential conflict with the given item
+ *
+ * This checks whether the given item is in the list of conflicts of
+ * the current item, but makes no judgment about whether the conflict
+ * is currently at play (either one of the items may not be selected)
+ *
+ * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item
+ * @return {boolean} This item has a conflict with the given item
+ */
+FilterItem.prototype.existsInConflicts = function ( filterItem ) {
+       return Object.prototype.hasOwnProperty.call( this.getConflicts(), filterItem.getName() );
+};
+
+/**
+ * Set the state of this filter as being conflicted
+ * (This means any filters in its conflicts are selected)
+ *
+ * @param {boolean} [conflicted] Filter is in conflict state
+ * @fires update
+ */
+FilterItem.prototype.toggleConflicted = function ( conflicted ) {
+       conflicted = conflicted === undefined ? !this.conflicted : conflicted;
+
+       if ( this.conflicted !== conflicted ) {
+               this.conflicted = conflicted;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Set the state of this filter as being already included
+ * (This means any filters in its superset are selected)
+ *
+ * @param {boolean} [included] Filter is included as part of a subset
+ * @fires update
+ */
+FilterItem.prototype.toggleIncluded = function ( included ) {
+       included = included === undefined ? !this.included : included;
+
+       if ( this.included !== included ) {
+               this.included = included;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Toggle the fully covered state of the item
+ *
+ * @param {boolean} [isFullyCovered] Filter is fully covered
+ * @fires update
+ */
+FilterItem.prototype.toggleFullyCovered = function ( isFullyCovered ) {
+       isFullyCovered = isFullyCovered === undefined ? !this.fullycovered : isFullyCovered;
+
+       if ( this.fullyCovered !== isFullyCovered ) {
+               this.fullyCovered = isFullyCovered;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Toggle the visibility of this item
+ *
+ * @param {boolean} [isVisible] Item is visible
+ */
+FilterItem.prototype.toggleVisible = function ( isVisible ) {
+       isVisible = isVisible === undefined ? !this.visible : !!isVisible;
+
+       if ( this.visible !== isVisible ) {
+               this.visible = isVisible;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Check whether the item is visible
+ *
+ * @return {boolean} Item is visible
+ */
+FilterItem.prototype.isVisible = function () {
+       return this.visible;
+};
+
+module.exports = FilterItem;
index d1b9f7a..4b219de 100644 (file)
-( function () {
-       var FilterGroup = require( './FilterGroup.js' ),
-               FilterItem = require( './FilterItem.js' ),
-               FiltersViewModel;
-
-       /**
-        * View model for the filters selection and display
-        *
-        * @class mw.rcfilters.dm.FiltersViewModel
-        * @mixins OO.EventEmitter
-        * @mixins OO.EmitterList
-        *
-        * @constructor
-        */
-       FiltersViewModel = function MwRcfiltersDmFiltersViewModel() {
-               // Mixin constructor
-               OO.EventEmitter.call( this );
-               OO.EmitterList.call( this );
-
-               this.groups = {};
-               this.defaultParams = {};
-               this.highlightEnabled = false;
-               this.parameterMap = {};
-               this.emptyParameterState = null;
-
-               this.views = {};
-               this.currentView = 'default';
-               this.searchQuery = null;
-
-               // Events
-               this.aggregate( { update: 'filterItemUpdate' } );
-               this.connect( this, { filterItemUpdate: [ 'emit', 'itemUpdate' ] } );
-       };
-
-       /* Initialization */
-       OO.initClass( FiltersViewModel );
-       OO.mixinClass( FiltersViewModel, OO.EventEmitter );
-       OO.mixinClass( FiltersViewModel, OO.EmitterList );
-
-       /* Events */
-
-       /**
-        * @event initialize
-        *
-        * Filter list is initialized
-        */
-
-       /**
-        * @event update
-        *
-        * Model has been updated
-        */
-
-       /**
-        * @event itemUpdate
-        * @param {mw.rcfilters.dm.FilterItem} item Filter item updated
-        *
-        * Filter item has changed
-        */
-
-       /**
-        * @event highlightChange
-        * @param {boolean} Highlight feature is enabled
-        *
-        * Highlight feature has been toggled enabled or disabled
-        */
-
-       /* Methods */
-
-       /**
-        * Re-assess the states of filter items based on the interactions between them
-        *
-        * @param {mw.rcfilters.dm.FilterItem} [item] Changed item. If not given, the
-        *  method will go over the state of all items
-        */
-       FiltersViewModel.prototype.reassessFilterInteractions = function ( item ) {
-               var allSelected,
-                       model = this,
-                       iterationItems = item !== undefined ? [ item ] : this.getItems();
-
-               iterationItems.forEach( function ( checkedItem ) {
-                       var allCheckedItems = checkedItem.getSubset().concat( [ checkedItem.getName() ] ),
-                               groupModel = checkedItem.getGroupModel();
-
-                       // Check for subsets (included filters) plus the item itself:
-                       allCheckedItems.forEach( function ( filterItemName ) {
-                               var itemInSubset = model.getItemByName( filterItemName );
-
-                               itemInSubset.toggleIncluded(
-                                       // If any of itemInSubset's supersets are selected, this item
-                                       // is included
-                                       itemInSubset.getSuperset().some( function ( supersetName ) {
-                                               return ( model.getItemByName( supersetName ).isSelected() );
+var FilterGroup = require( './FilterGroup.js' ),
+       FilterItem = require( './FilterItem.js' ),
+       FiltersViewModel;
+
+/**
+ * View model for the filters selection and display
+ *
+ * @class mw.rcfilters.dm.FiltersViewModel
+ * @mixins OO.EventEmitter
+ * @mixins OO.EmitterList
+ *
+ * @constructor
+ */
+FiltersViewModel = function MwRcfiltersDmFiltersViewModel() {
+       // Mixin constructor
+       OO.EventEmitter.call( this );
+       OO.EmitterList.call( this );
+
+       this.groups = {};
+       this.defaultParams = {};
+       this.highlightEnabled = false;
+       this.parameterMap = {};
+       this.emptyParameterState = null;
+
+       this.views = {};
+       this.currentView = 'default';
+       this.searchQuery = null;
+
+       // Events
+       this.aggregate( { update: 'filterItemUpdate' } );
+       this.connect( this, { filterItemUpdate: [ 'emit', 'itemUpdate' ] } );
+};
+
+/* Initialization */
+OO.initClass( FiltersViewModel );
+OO.mixinClass( FiltersViewModel, OO.EventEmitter );
+OO.mixinClass( FiltersViewModel, OO.EmitterList );
+
+/* Events */
+
+/**
+ * @event initialize
+ *
+ * Filter list is initialized
+ */
+
+/**
+ * @event update
+ *
+ * Model has been updated
+ */
+
+/**
+ * @event itemUpdate
+ * @param {mw.rcfilters.dm.FilterItem} item Filter item updated
+ *
+ * Filter item has changed
+ */
+
+/**
+ * @event highlightChange
+ * @param {boolean} Highlight feature is enabled
+ *
+ * Highlight feature has been toggled enabled or disabled
+ */
+
+/* Methods */
+
+/**
+ * Re-assess the states of filter items based on the interactions between them
+ *
+ * @param {mw.rcfilters.dm.FilterItem} [item] Changed item. If not given, the
+ *  method will go over the state of all items
+ */
+FiltersViewModel.prototype.reassessFilterInteractions = function ( item ) {
+       var allSelected,
+               model = this,
+               iterationItems = item !== undefined ? [ item ] : this.getItems();
+
+       iterationItems.forEach( function ( checkedItem ) {
+               var allCheckedItems = checkedItem.getSubset().concat( [ checkedItem.getName() ] ),
+                       groupModel = checkedItem.getGroupModel();
+
+               // Check for subsets (included filters) plus the item itself:
+               allCheckedItems.forEach( function ( filterItemName ) {
+                       var itemInSubset = model.getItemByName( filterItemName );
+
+                       itemInSubset.toggleIncluded(
+                               // If any of itemInSubset's supersets are selected, this item
+                               // is included
+                               itemInSubset.getSuperset().some( function ( supersetName ) {
+                                       return ( model.getItemByName( supersetName ).isSelected() );
+                               } )
+                       );
+               } );
+
+               // Update coverage for the changed group
+               if ( groupModel.isFullCoverage() ) {
+                       allSelected = groupModel.areAllSelected();
+                       groupModel.getItems().forEach( function ( filterItem ) {
+                               filterItem.toggleFullyCovered( allSelected );
+                       } );
+               }
+       } );
+
+       // Check for conflicts
+       // In this case, we must go over all items, since
+       // conflicts are bidirectional and depend not only on
+       // individual items, but also on the selected states of
+       // the groups they're in.
+       this.getItems().forEach( function ( filterItem ) {
+               var inConflict = false,
+                       filterItemGroup = filterItem.getGroupModel();
+
+               // For each item, see if that item is still conflicting
+               // eslint-disable-next-line no-jquery/no-each-util
+               $.each( model.groups, function ( groupName, groupModel ) {
+                       if ( filterItem.getGroupName() === groupName ) {
+                               // Check inside the group
+                               inConflict = groupModel.areAnySelectedInConflictWith( filterItem );
+                       } else {
+                               // According to the spec, if two items conflict from two different
+                               // groups, the conflict only lasts if the groups **only have selected
+                               // items that are conflicting**. If a group has selected items that
+                               // are conflicting and non-conflicting, the scope of the result has
+                               // expanded enough to completely remove the conflict.
+
+                               // For example, see two groups with conflicts:
+                               // userExpLevel: [
+                               //   {
+                               //     name: 'experienced',
+                               //     conflicts: [ 'unregistered' ]
+                               //   }
+                               // ],
+                               // registration: [
+                               //   {
+                               //     name: 'registered',
+                               //   },
+                               //   {
+                               //     name: 'unregistered',
+                               //   }
+                               // ]
+                               // If we select 'experienced', then 'unregistered' is in conflict (and vice versa),
+                               // because, inherently, 'experienced' filter only includes registered users, and so
+                               // both filters are in conflict with one another.
+                               // However, the minute we select 'registered', the scope of our results
+                               // has expanded to no longer have a conflict with 'experienced' filter, and
+                               // so the conflict is removed.
+
+                               // In our case, we need to check if the entire group conflicts with
+                               // the entire item's group, so we follow the above spec
+                               inConflict = (
+                                       // The foreign group is in conflict with this item
+                                       groupModel.areAllSelectedInConflictWith( filterItem ) &&
+                                       // Every selected member of the item's own group is also
+                                       // in conflict with the other group
+                                       filterItemGroup.findSelectedItems().every( function ( otherGroupItem ) {
+                                               return groupModel.areAllSelectedInConflictWith( otherGroupItem );
                                        } )
                                );
-                       } );
-
-                       // Update coverage for the changed group
-                       if ( groupModel.isFullCoverage() ) {
-                               allSelected = groupModel.areAllSelected();
-                               groupModel.getItems().forEach( function ( filterItem ) {
-                                       filterItem.toggleFullyCovered( allSelected );
-                               } );
                        }
+
+                       // If we're in conflict, this will return 'false' which
+                       // will break the loop. Otherwise, we're not in conflict
+                       // and the loop continues
+                       return !inConflict;
                } );
 
-               // Check for conflicts
-               // In this case, we must go over all items, since
-               // conflicts are bidirectional and depend not only on
-               // individual items, but also on the selected states of
-               // the groups they're in.
-               this.getItems().forEach( function ( filterItem ) {
-                       var inConflict = false,
-                               filterItemGroup = filterItem.getGroupModel();
+               // Toggle the item state
+               filterItem.toggleConflicted( inConflict );
+       } );
+};
+
+/**
+ * Get whether the model has any conflict in its items
+ *
+ * @return {boolean} There is a conflict
+ */
+FiltersViewModel.prototype.hasConflict = function () {
+       return this.getItems().some( function ( filterItem ) {
+               return filterItem.isSelected() && filterItem.isConflicted();
+       } );
+};
+
+/**
+ * Get the first item with a current conflict
+ *
+ * @return {mw.rcfilters.dm.FilterItem|undefined} Conflicted item or undefined when not found
+ */
+FiltersViewModel.prototype.getFirstConflictedItem = function () {
+       var i, filterItem, items = this.getItems();
+       for ( i = 0; i < items.length; i++ ) {
+               filterItem = items[ i ];
+               if ( filterItem.isSelected() && filterItem.isConflicted() ) {
+                       return filterItem;
+               }
+       }
+};
+
+/**
+ * Set filters and preserve a group relationship based on
+ * the definition given by an object
+ *
+ * @param {Array} filterGroups Filters definition
+ * @param {Object} [views] Extra views definition
+ *  Expected in the following format:
+ *  {
+ *     namespaces: {
+ *       label: 'namespaces', // Message key
+ *       trigger: ':',
+ *       groups: [
+ *         {
+ *            // Group info
+ *            name: 'namespaces' // Parameter name
+ *            title: 'namespaces' // Message key
+ *            type: 'string_options',
+ *            separator: ';',
+ *            labelPrefixKey: { 'default': 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' },
+ *            fullCoverage: true
+ *            items: []
+ *         }
+ *       ]
+ *     }
+ *  }
+ */
+FiltersViewModel.prototype.initializeFilters = function ( filterGroups, views ) {
+       var filterConflictResult, groupConflictResult,
+               allViews,
+               model = this,
+               items = [],
+               groupConflictMap = {},
+               filterConflictMap = {},
+               /*!
+                * Expand a conflict definition from group name to
+                * the list of all included filters in that group.
+                * We do this so that the direct relationship in the
+                * models are consistently item->items rather than
+                * mixing item->group with item->item.
+                *
+                * @param {Object} obj Conflict definition
+                * @return {Object} Expanded conflict definition
+                */
+               expandConflictDefinitions = function ( obj ) {
+                       var result = {};
 
-                       // For each item, see if that item is still conflicting
                        // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( model.groups, function ( groupName, groupModel ) {
-                               if ( filterItem.getGroupName() === groupName ) {
-                                       // Check inside the group
-                                       inConflict = groupModel.areAnySelectedInConflictWith( filterItem );
-                               } else {
-                                       // According to the spec, if two items conflict from two different
-                                       // groups, the conflict only lasts if the groups **only have selected
-                                       // items that are conflicting**. If a group has selected items that
-                                       // are conflicting and non-conflicting, the scope of the result has
-                                       // expanded enough to completely remove the conflict.
-
-                                       // For example, see two groups with conflicts:
-                                       // userExpLevel: [
-                                       //   {
-                                       //     name: 'experienced',
-                                       //     conflicts: [ 'unregistered' ]
-                                       //   }
-                                       // ],
-                                       // registration: [
-                                       //   {
-                                       //     name: 'registered',
-                                       //   },
-                                       //   {
-                                       //     name: 'unregistered',
-                                       //   }
-                                       // ]
-                                       // If we select 'experienced', then 'unregistered' is in conflict (and vice versa),
-                                       // because, inherently, 'experienced' filter only includes registered users, and so
-                                       // both filters are in conflict with one another.
-                                       // However, the minute we select 'registered', the scope of our results
-                                       // has expanded to no longer have a conflict with 'experienced' filter, and
-                                       // so the conflict is removed.
-
-                                       // In our case, we need to check if the entire group conflicts with
-                                       // the entire item's group, so we follow the above spec
-                                       inConflict = (
-                                               // The foreign group is in conflict with this item
-                                               groupModel.areAllSelectedInConflictWith( filterItem ) &&
-                                               // Every selected member of the item's own group is also
-                                               // in conflict with the other group
-                                               filterItemGroup.findSelectedItems().every( function ( otherGroupItem ) {
-                                                       return groupModel.areAllSelectedInConflictWith( otherGroupItem );
-                                               } )
-                                       );
-                               }
-
-                               // If we're in conflict, this will return 'false' which
-                               // will break the loop. Otherwise, we're not in conflict
-                               // and the loop continues
-                               return !inConflict;
-                       } );
-
-                       // Toggle the item state
-                       filterItem.toggleConflicted( inConflict );
-               } );
-       };
-
-       /**
-        * Get whether the model has any conflict in its items
-        *
-        * @return {boolean} There is a conflict
-        */
-       FiltersViewModel.prototype.hasConflict = function () {
-               return this.getItems().some( function ( filterItem ) {
-                       return filterItem.isSelected() && filterItem.isConflicted();
-               } );
-       };
-
-       /**
-        * Get the first item with a current conflict
-        *
-        * @return {mw.rcfilters.dm.FilterItem|undefined} Conflicted item or undefined when not found
-        */
-       FiltersViewModel.prototype.getFirstConflictedItem = function () {
-               var i, filterItem, items = this.getItems();
-               for ( i = 0; i < items.length; i++ ) {
-                       filterItem = items[ i ];
-                       if ( filterItem.isSelected() && filterItem.isConflicted() ) {
-                               return filterItem;
-                       }
-               }
-       };
-
-       /**
-        * Set filters and preserve a group relationship based on
-        * the definition given by an object
-        *
-        * @param {Array} filterGroups Filters definition
-        * @param {Object} [views] Extra views definition
-        *  Expected in the following format:
-        *  {
-        *     namespaces: {
-        *       label: 'namespaces', // Message key
-        *       trigger: ':',
-        *       groups: [
-        *         {
-        *            // Group info
-        *            name: 'namespaces' // Parameter name
-        *            title: 'namespaces' // Message key
-        *            type: 'string_options',
-        *            separator: ';',
-        *            labelPrefixKey: { 'default': 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' },
-        *            fullCoverage: true
-        *            items: []
-        *         }
-        *       ]
-        *     }
-        *  }
-        */
-       FiltersViewModel.prototype.initializeFilters = function ( filterGroups, views ) {
-               var filterConflictResult, groupConflictResult,
-                       allViews = {},
-                       model = this,
-                       items = [],
-                       groupConflictMap = {},
-                       filterConflictMap = {},
-                       /*!
-                        * Expand a conflict definition from group name to
-                        * the list of all included filters in that group.
-                        * We do this so that the direct relationship in the
-                        * models are consistently item->items rather than
-                        * mixing item->group with item->item.
-                        *
-                        * @param {Object} obj Conflict definition
-                        * @return {Object} Expanded conflict definition
-                        */
-                       expandConflictDefinitions = function ( obj ) {
-                               var result = {};
-
-                               // eslint-disable-next-line no-jquery/no-each-util
-                               $.each( obj, function ( key, conflicts ) {
-                                       var filterName,
-                                               adjustedConflicts = {};
-
-                                       conflicts.forEach( function ( conflict ) {
-                                               var filter;
-
-                                               if ( conflict.filter ) {
-                                                       filterName = model.groups[ conflict.group ].getPrefixedName( conflict.filter );
-                                                       filter = model.getItemByName( filterName );
-
-                                                       // Rename
-                                                       adjustedConflicts[ filterName ] = $.extend(
+                       $.each( obj, function ( key, conflicts ) {
+                               var filterName,
+                                       adjustedConflicts = {};
+
+                               conflicts.forEach( function ( conflict ) {
+                                       var filter;
+
+                                       if ( conflict.filter ) {
+                                               filterName = model.groups[ conflict.group ].getPrefixedName( conflict.filter );
+                                               filter = model.getItemByName( filterName );
+
+                                               // Rename
+                                               adjustedConflicts[ filterName ] = $.extend(
+                                                       {},
+                                                       conflict,
+                                                       {
+                                                               filter: filterName,
+                                                               item: filter
+                                                       }
+                                               );
+                                       } else {
+                                               // This conflict is for an entire group. Split it up to
+                                               // represent each filter
+
+                                               // Get the relevant group items
+                                               model.groups[ conflict.group ].getItems().forEach( function ( groupItem ) {
+                                                       // Rebuild the conflict
+                                                       adjustedConflicts[ groupItem.getName() ] = $.extend(
                                                                {},
                                                                conflict,
                                                                {
-                                                                       filter: filterName,
-                                                                       item: filter
+                                                                       filter: groupItem.getName(),
+                                                                       item: groupItem
                                                                }
                                                        );
-                                               } else {
-                                                       // This conflict is for an entire group. Split it up to
-                                                       // represent each filter
-
-                                                       // Get the relevant group items
-                                                       model.groups[ conflict.group ].getItems().forEach( function ( groupItem ) {
-                                                               // Rebuild the conflict
-                                                               adjustedConflicts[ groupItem.getName() ] = $.extend(
-                                                                       {},
-                                                                       conflict,
-                                                                       {
-                                                                               filter: groupItem.getName(),
-                                                                               item: groupItem
-                                                                       }
-                                                               );
-                                                       } );
-                                               }
-                                       } );
-
-                                       result[ key ] = adjustedConflicts;
-                               } );
-
-                               return result;
-                       };
-
-               // Reset
-               this.clearItems();
-               this.groups = {};
-               this.views = {};
-
-               // Clone
-               filterGroups = OO.copy( filterGroups );
-
-               // Normalize definition from the server
-               filterGroups.forEach( function ( data ) {
-                       var i;
-                       // What's this information needs to be normalized
-                       data.whatsThis = {
-                               body: data.whatsThisBody,
-                               header: data.whatsThisHeader,
-                               linkText: data.whatsThisLinkText,
-                               url: data.whatsThisUrl
-                       };
-
-                       // Title is a msg-key
-                       data.title = data.title ? mw.msg( data.title ) : data.name;
-
-                       // Filters are given to us with msg-keys, we need
-                       // to translate those before we hand them off
-                       for ( i = 0; i < data.filters.length; i++ ) {
-                               data.filters[ i ].label = data.filters[ i ].label ? mw.msg( data.filters[ i ].label ) : data.filters[ i ].name;
-                               data.filters[ i ].description = data.filters[ i ].description ? mw.msg( data.filters[ i ].description ) : '';
-                       }
-               } );
-
-               // Collect views
-               allViews = $.extend( true, {
-                       default: {
-                               title: mw.msg( 'rcfilters-filterlist-title' ),
-                               groups: filterGroups
-                       }
-               }, views );
-
-               // Go over all views
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( allViews, function ( viewName, viewData ) {
-                       // Define the view
-                       model.views[ viewName ] = {
-                               name: viewData.name,
-                               title: viewData.title,
-                               trigger: viewData.trigger
-                       };
-
-                       // Go over groups
-                       viewData.groups.forEach( function ( groupData ) {
-                               var group = groupData.name;
-
-                               if ( !model.groups[ group ] ) {
-                                       model.groups[ group ] = new FilterGroup(
-                                               group,
-                                               $.extend( true, {}, groupData, { view: viewName } )
-                                       );
-                               }
-
-                               model.groups[ group ].initializeFilters( groupData.filters, groupData.default );
-                               items = items.concat( model.groups[ group ].getItems() );
-
-                               // Prepare conflicts
-                               if ( groupData.conflicts ) {
-                                       // Group conflicts
-                                       groupConflictMap[ group ] = groupData.conflicts;
-                               }
-
-                               groupData.filters.forEach( function ( itemData ) {
-                                       var filterItem = model.groups[ group ].getItemByParamName( itemData.name );
-                                       // Filter conflicts
-                                       if ( itemData.conflicts ) {
-                                               filterConflictMap[ filterItem.getName() ] = itemData.conflicts;
+                                               } );
                                        }
                                } );
-                       } );
-               } );
-
-               // Add item references to the model, for lookup
-               this.addItems( items );
 
-               // Expand conflicts
-               groupConflictResult = expandConflictDefinitions( groupConflictMap );
-               filterConflictResult = expandConflictDefinitions( filterConflictMap );
-
-               // Set conflicts for groups
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( groupConflictResult, function ( group, conflicts ) {
-                       model.groups[ group ].setConflicts( conflicts );
-               } );
+                               result[ key ] = adjustedConflicts;
+                       } );
 
-               // Set conflicts for items
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( filterConflictResult, function ( filterName, conflicts ) {
-                       var filterItem = model.getItemByName( filterName );
-                       // set conflicts for items in the group
-                       filterItem.setConflicts( conflicts );
-               } );
+                       return result;
+               };
+
+       // Reset
+       this.clearItems();
+       this.groups = {};
+       this.views = {};
+
+       // Clone
+       filterGroups = OO.copy( filterGroups );
+
+       // Normalize definition from the server
+       filterGroups.forEach( function ( data ) {
+               var i;
+               // What's this information needs to be normalized
+               data.whatsThis = {
+                       body: data.whatsThisBody,
+                       header: data.whatsThisHeader,
+                       linkText: data.whatsThisLinkText,
+                       url: data.whatsThisUrl
+               };
+
+               // Title is a msg-key
+               data.title = data.title ? mw.msg( data.title ) : data.name;
+
+               // Filters are given to us with msg-keys, we need
+               // to translate those before we hand them off
+               for ( i = 0; i < data.filters.length; i++ ) {
+                       data.filters[ i ].label = data.filters[ i ].label ? mw.msg( data.filters[ i ].label ) : data.filters[ i ].name;
+                       data.filters[ i ].description = data.filters[ i ].description ? mw.msg( data.filters[ i ].description ) : '';
+               }
+       } );
 
-               // Create a map between known parameters and their models
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.groups, function ( group, groupModel ) {
-                       if (
-                               groupModel.getType() === 'send_unselected_if_any' ||
-                               groupModel.getType() === 'boolean' ||
-                               groupModel.getType() === 'any_value'
-                       ) {
-                               // Individual filters
-                               groupModel.getItems().forEach( function ( filterItem ) {
-                                       model.parameterMap[ filterItem.getParamName() ] = filterItem;
-                               } );
-                       } else if (
-                               groupModel.getType() === 'string_options' ||
-                               groupModel.getType() === 'single_option'
-                       ) {
-                               // Group
-                               model.parameterMap[ groupModel.getName() ] = groupModel;
+       // Collect views
+       allViews = $.extend( true, {
+               default: {
+                       title: mw.msg( 'rcfilters-filterlist-title' ),
+                       groups: filterGroups
+               }
+       }, views );
+
+       // Go over all views
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( allViews, function ( viewName, viewData ) {
+               // Define the view
+               model.views[ viewName ] = {
+                       name: viewData.name,
+                       title: viewData.title,
+                       trigger: viewData.trigger
+               };
+
+               // Go over groups
+               viewData.groups.forEach( function ( groupData ) {
+                       var group = groupData.name;
+
+                       if ( !model.groups[ group ] ) {
+                               model.groups[ group ] = new FilterGroup(
+                                       group,
+                                       $.extend( true, {}, groupData, { view: viewName } )
+                               );
                        }
-               } );
-
-               this.setSearch( '' );
-
-               this.updateHighlightedState();
 
-               // Finish initialization
-               this.emit( 'initialize' );
-       };
+                       model.groups[ group ].initializeFilters( groupData.filters, groupData.default );
+                       items = items.concat( model.groups[ group ].getItems() );
 
-       /**
-        * Update filter view model state based on a parameter object
-        *
-        * @param {Object} params Parameters object
-        */
-       FiltersViewModel.prototype.updateStateFromParams = function ( params ) {
-               var filtersValue;
-               // For arbitrary numeric single_option values make sure the values
-               // are normalized to fit within the limits
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.getFilterGroups(), function ( groupName, groupModel ) {
-                       params[ groupName ] = groupModel.normalizeArbitraryValue( params[ groupName ] );
-               } );
-
-               // Update filter values
-               filtersValue = this.getFiltersFromParameters( params );
-               Object.keys( filtersValue ).forEach( function ( filterName ) {
-                       this.getItemByName( filterName ).setValue( filtersValue[ filterName ] );
-               }.bind( this ) );
-
-               // Update highlight state
-               this.getItemsSupportingHighlights().forEach( function ( filterItem ) {
-                       var color = params[ filterItem.getName() + '_color' ];
-                       if ( color ) {
-                               filterItem.setHighlightColor( color );
-                       } else {
-                               filterItem.clearHighlightColor();
+                       // Prepare conflicts
+                       if ( groupData.conflicts ) {
+                               // Group conflicts
+                               groupConflictMap[ group ] = groupData.conflicts;
                        }
-               } );
-               this.updateHighlightedState();
-
-               // Check all filter interactions
-               this.reassessFilterInteractions();
-       };
-
-       /**
-        * Get a representation of an empty (falsey) parameter state
-        *
-        * @return {Object} Empty parameter state
-        */
-       FiltersViewModel.prototype.getEmptyParameterState = function () {
-               if ( !this.emptyParameterState ) {
-                       this.emptyParameterState = $.extend(
-                               true,
-                               {},
-                               this.getParametersFromFilters( {} ),
-                               this.getEmptyHighlightParameters()
-                       );
-               }
-               return this.emptyParameterState;
-       };
-
-       /**
-        * Get a representation of only the non-falsey parameters
-        *
-        * @param {Object} [parameters] A given parameter state to minimize. If not given the current
-        *  state of the system will be used.
-        * @return {Object} Empty parameter state
-        */
-       FiltersViewModel.prototype.getMinimizedParamRepresentation = function ( parameters ) {
-               var result = {};
-
-               parameters = parameters ? $.extend( true, {}, parameters ) : this.getCurrentParameterState();
-
-               // Params
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.getEmptyParameterState(), function ( param, value ) {
-                       if ( parameters[ param ] !== undefined && parameters[ param ] !== value ) {
-                               result[ param ] = parameters[ param ];
-                       }
-               } );
 
-               // Highlights
-               Object.keys( this.getEmptyHighlightParameters() ).forEach( function ( param ) {
-                       if ( parameters[ param ] ) {
-                               // If a highlight parameter is not undefined and not null
-                               // add it to the result
-                               result[ param ] = parameters[ param ];
-                       }
+                       groupData.filters.forEach( function ( itemData ) {
+                               var filterItem = model.groups[ group ].getItemByParamName( itemData.name );
+                               // Filter conflicts
+                               if ( itemData.conflicts ) {
+                                       filterConflictMap[ filterItem.getName() ] = itemData.conflicts;
+                               }
+                       } );
                } );
-
-               return result;
-       };
-
-       /**
-        * Get a representation of the full parameter list, including all base values
-        *
-        * @return {Object} Full parameter representation
-        */
-       FiltersViewModel.prototype.getExpandedParamRepresentation = function () {
-               return $.extend(
+       } );
+
+       // Add item references to the model, for lookup
+       this.addItems( items );
+
+       // Expand conflicts
+       groupConflictResult = expandConflictDefinitions( groupConflictMap );
+       filterConflictResult = expandConflictDefinitions( filterConflictMap );
+
+       // Set conflicts for groups
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( groupConflictResult, function ( group, conflicts ) {
+               model.groups[ group ].setConflicts( conflicts );
+       } );
+
+       // Set conflicts for items
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( filterConflictResult, function ( filterName, conflicts ) {
+               var filterItem = model.getItemByName( filterName );
+               // set conflicts for items in the group
+               filterItem.setConflicts( conflicts );
+       } );
+
+       // Create a map between known parameters and their models
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.groups, function ( group, groupModel ) {
+               if (
+                       groupModel.getType() === 'send_unselected_if_any' ||
+                       groupModel.getType() === 'boolean' ||
+                       groupModel.getType() === 'any_value'
+               ) {
+                       // Individual filters
+                       groupModel.getItems().forEach( function ( filterItem ) {
+                               model.parameterMap[ filterItem.getParamName() ] = filterItem;
+                       } );
+               } else if (
+                       groupModel.getType() === 'string_options' ||
+                       groupModel.getType() === 'single_option'
+               ) {
+                       // Group
+                       model.parameterMap[ groupModel.getName() ] = groupModel;
+               }
+       } );
+
+       this.setSearch( '' );
+
+       this.updateHighlightedState();
+
+       // Finish initialization
+       this.emit( 'initialize' );
+};
+
+/**
+ * Update filter view model state based on a parameter object
+ *
+ * @param {Object} params Parameters object
+ */
+FiltersViewModel.prototype.updateStateFromParams = function ( params ) {
+       var filtersValue;
+       // For arbitrary numeric single_option values make sure the values
+       // are normalized to fit within the limits
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.getFilterGroups(), function ( groupName, groupModel ) {
+               params[ groupName ] = groupModel.normalizeArbitraryValue( params[ groupName ] );
+       } );
+
+       // Update filter values
+       filtersValue = this.getFiltersFromParameters( params );
+       Object.keys( filtersValue ).forEach( function ( filterName ) {
+               this.getItemByName( filterName ).setValue( filtersValue[ filterName ] );
+       }.bind( this ) );
+
+       // Update highlight state
+       this.getItemsSupportingHighlights().forEach( function ( filterItem ) {
+               var color = params[ filterItem.getName() + '_color' ];
+               if ( color ) {
+                       filterItem.setHighlightColor( color );
+               } else {
+                       filterItem.clearHighlightColor();
+               }
+       } );
+       this.updateHighlightedState();
+
+       // Check all filter interactions
+       this.reassessFilterInteractions();
+};
+
+/**
+ * Get a representation of an empty (falsey) parameter state
+ *
+ * @return {Object} Empty parameter state
+ */
+FiltersViewModel.prototype.getEmptyParameterState = function () {
+       if ( !this.emptyParameterState ) {
+               this.emptyParameterState = $.extend(
                        true,
                        {},
-                       this.getEmptyParameterState(),
-                       this.getCurrentParameterState()
+                       this.getParametersFromFilters( {} ),
+                       this.getEmptyHighlightParameters()
                );
-       };
-
-       /**
-        * Get a parameter representation of the current state of the model
-        *
-        * @param {boolean} [removeStickyParams] Remove sticky filters from final result
-        * @return {Object} Parameter representation of the current state of the model
-        */
-       FiltersViewModel.prototype.getCurrentParameterState = function ( removeStickyParams ) {
-               var state = this.getMinimizedParamRepresentation( $.extend(
-                       true,
-                       {},
-                       this.getParametersFromFilters( this.getSelectedState() ),
-                       this.getHighlightParameters()
-               ) );
-
-               if ( removeStickyParams ) {
-                       state = this.removeStickyParams( state );
+       }
+       return this.emptyParameterState;
+};
+
+/**
+ * Get a representation of only the non-falsey parameters
+ *
+ * @param {Object} [parameters] A given parameter state to minimize. If not given the current
+ *  state of the system will be used.
+ * @return {Object} Empty parameter state
+ */
+FiltersViewModel.prototype.getMinimizedParamRepresentation = function ( parameters ) {
+       var result = {};
+
+       parameters = parameters ? $.extend( true, {}, parameters ) : this.getCurrentParameterState();
+
+       // Params
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.getEmptyParameterState(), function ( param, value ) {
+               if ( parameters[ param ] !== undefined && parameters[ param ] !== value ) {
+                       result[ param ] = parameters[ param ];
                }
-
-               return state;
-       };
-
-       /**
-        * Delete sticky parameters from given object.
-        *
-        * @param {Object} paramState Parameter state
-        * @return {Object} Parameter state without sticky parameters
-        */
-       FiltersViewModel.prototype.removeStickyParams = function ( paramState ) {
-               this.getStickyParams().forEach( function ( paramName ) {
-                       delete paramState[ paramName ];
-               } );
-
-               return paramState;
-       };
-
-       /**
-        * Turn the highlight feature on or off
-        */
-       FiltersViewModel.prototype.updateHighlightedState = function () {
-               this.toggleHighlight( this.getHighlightedItems().length > 0 );
-       };
-
-       /**
-        * Get the object that defines groups by their name.
-        *
-        * @return {Object} Filter groups
-        */
-       FiltersViewModel.prototype.getFilterGroups = function () {
-               return this.groups;
-       };
-
-       /**
-        * Get the object that defines groups that match a certain view by their name.
-        *
-        * @param {string} [view] Requested view. If not given, uses current view
-        * @return {Object} Filter groups matching a display group
-        */
-       FiltersViewModel.prototype.getFilterGroupsByView = function ( view ) {
-               var result = {};
-
-               view = view || this.getCurrentView();
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.groups, function ( groupName, groupModel ) {
-                       if ( groupModel.getView() === view ) {
-                               result[ groupName ] = groupModel;
-                       }
-               } );
-
-               return result;
-       };
-
-       /**
-        * Get an array of filters matching the given display group.
-        *
-        * @param {string} [view] Requested view. If not given, uses current view
-        * @return {mw.rcfilters.dm.FilterItem} Filter items matching the group
-        */
-       FiltersViewModel.prototype.getFiltersByView = function ( view ) {
-               var groups,
-                       result = [];
-
-               view = view || this.getCurrentView();
-
-               groups = this.getFilterGroupsByView( view );
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( groups, function ( groupName, groupModel ) {
-                       result = result.concat( groupModel.getItems() );
-               } );
-
-               return result;
-       };
-
-       /**
-        * Get the trigger for the requested view.
-        *
-        * @param {string} view View name
-        * @return {string} View trigger, if exists
-        */
-       FiltersViewModel.prototype.getViewTrigger = function ( view ) {
-               return ( this.views[ view ] && this.views[ view ].trigger ) || '';
-       };
-
-       /**
-        * Get the value of a specific parameter
-        *
-        * @param {string} name Parameter name
-        * @return {number|string} Parameter value
-        */
-       FiltersViewModel.prototype.getParamValue = function ( name ) {
-               return this.parameters[ name ];
-       };
-
-       /**
-        * Get the current selected state of the filters
-        *
-        * @param {boolean} [onlySelected] return an object containing only the filters with a value
-        * @return {Object} Filters selected state
-        */
-       FiltersViewModel.prototype.getSelectedState = function ( onlySelected ) {
-               var i,
-                       items = this.getItems(),
-                       result = {};
-
-               for ( i = 0; i < items.length; i++ ) {
-                       if ( !onlySelected || items[ i ].getValue() ) {
-                               result[ items[ i ].getName() ] = items[ i ].getValue();
-                       }
+       } );
+
+       // Highlights
+       Object.keys( this.getEmptyHighlightParameters() ).forEach( function ( param ) {
+               if ( parameters[ param ] ) {
+                       // If a highlight parameter is not undefined and not null
+                       // add it to the result
+                       result[ param ] = parameters[ param ];
                }
-
-               return result;
-       };
-
-       /**
-        * Get the current full state of the filters
-        *
-        * @return {Object} Filters full state
-        */
-       FiltersViewModel.prototype.getFullState = function () {
-               var i,
-                       items = this.getItems(),
-                       result = {};
-
-               for ( i = 0; i < items.length; i++ ) {
-                       result[ items[ i ].getName() ] = {
-                               selected: items[ i ].isSelected(),
-                               conflicted: items[ i ].isConflicted(),
-                               included: items[ i ].isIncluded()
-                       };
+       } );
+
+       return result;
+};
+
+/**
+ * Get a representation of the full parameter list, including all base values
+ *
+ * @return {Object} Full parameter representation
+ */
+FiltersViewModel.prototype.getExpandedParamRepresentation = function () {
+       return $.extend(
+               true,
+               {},
+               this.getEmptyParameterState(),
+               this.getCurrentParameterState()
+       );
+};
+
+/**
+ * Get a parameter representation of the current state of the model
+ *
+ * @param {boolean} [removeStickyParams] Remove sticky filters from final result
+ * @return {Object} Parameter representation of the current state of the model
+ */
+FiltersViewModel.prototype.getCurrentParameterState = function ( removeStickyParams ) {
+       var state = this.getMinimizedParamRepresentation( $.extend(
+               true,
+               {},
+               this.getParametersFromFilters( this.getSelectedState() ),
+               this.getHighlightParameters()
+       ) );
+
+       if ( removeStickyParams ) {
+               state = this.removeStickyParams( state );
+       }
+
+       return state;
+};
+
+/**
+ * Delete sticky parameters from given object.
+ *
+ * @param {Object} paramState Parameter state
+ * @return {Object} Parameter state without sticky parameters
+ */
+FiltersViewModel.prototype.removeStickyParams = function ( paramState ) {
+       this.getStickyParams().forEach( function ( paramName ) {
+               delete paramState[ paramName ];
+       } );
+
+       return paramState;
+};
+
+/**
+ * Turn the highlight feature on or off
+ */
+FiltersViewModel.prototype.updateHighlightedState = function () {
+       this.toggleHighlight( this.getHighlightedItems().length > 0 );
+};
+
+/**
+ * Get the object that defines groups by their name.
+ *
+ * @return {Object} Filter groups
+ */
+FiltersViewModel.prototype.getFilterGroups = function () {
+       return this.groups;
+};
+
+/**
+ * Get the object that defines groups that match a certain view by their name.
+ *
+ * @param {string} [view] Requested view. If not given, uses current view
+ * @return {Object} Filter groups matching a display group
+ */
+FiltersViewModel.prototype.getFilterGroupsByView = function ( view ) {
+       var result = {};
+
+       view = view || this.getCurrentView();
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.groups, function ( groupName, groupModel ) {
+               if ( groupModel.getView() === view ) {
+                       result[ groupName ] = groupModel;
                }
-
-               return result;
-       };
-
-       /**
-        * Get an object representing default parameters state
-        *
-        * @return {Object} Default parameter values
-        */
-       FiltersViewModel.prototype.getDefaultParams = function () {
-               var result = {};
-
-               // Get default filter state
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.groups, function ( name, model ) {
-                       if ( !model.isSticky() ) {
-                               $.extend( true, result, model.getDefaultParams() );
-                       }
-               } );
-
-               return result;
-       };
-
-       /**
-        * Get a parameter representation of all sticky parameters
-        *
-        * @return {Object} Sticky parameter values
-        */
-       FiltersViewModel.prototype.getStickyParams = function () {
-               var result = [];
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.groups, function ( name, model ) {
-                       if ( model.isSticky() ) {
-                               if ( model.isPerGroupRequestParameter() ) {
-                                       result.push( name );
-                               } else {
-                                       // Each filter is its own param
-                                       result = result.concat( model.getItems().map( function ( filterItem ) {
-                                               return filterItem.getParamName();
-                                       } ) );
-                               }
-                       }
-               } );
-
-               return result;
-       };
-
-       /**
-        * Get a parameter representation of all sticky parameters
-        *
-        * @return {Object} Sticky parameter values
-        */
-       FiltersViewModel.prototype.getStickyParamsValues = function () {
-               var result = {};
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.groups, function ( name, model ) {
-                       if ( model.isSticky() ) {
-                               $.extend( true, result, model.getParamRepresentation() );
-                       }
-               } );
-
-               return result;
-       };
-
-       /**
-        * Analyze the groups and their filters and output an object representing
-        * the state of the parameters they represent.
-        *
-        * @param {Object} [filterDefinition] An object defining the filter values,
-        *  keyed by filter names.
-        * @return {Object} Parameter state object
-        */
-       FiltersViewModel.prototype.getParametersFromFilters = function ( filterDefinition ) {
-               var groupItemDefinition,
-                       result = {},
-                       groupItems = this.getFilterGroups();
-
-               if ( filterDefinition ) {
-                       groupItemDefinition = {};
-                       // Filter definition is "flat", but in effect
-                       // each group needs to tell us its result based
-                       // on the values in it. We need to split this list
-                       // back into groupings so we can "feed" it to the
-                       // loop below, and we need to expand it so it includes
-                       // all filters (set to false)
-                       this.getItems().forEach( function ( filterItem ) {
-                               groupItemDefinition[ filterItem.getGroupName() ] = groupItemDefinition[ filterItem.getGroupName() ] || {};
-                               groupItemDefinition[ filterItem.getGroupName() ][ filterItem.getName() ] = filterItem.coerceValue( filterDefinition[ filterItem.getName() ] );
-                       } );
+       } );
+
+       return result;
+};
+
+/**
+ * Get an array of filters matching the given display group.
+ *
+ * @param {string} [view] Requested view. If not given, uses current view
+ * @return {mw.rcfilters.dm.FilterItem} Filter items matching the group
+ */
+FiltersViewModel.prototype.getFiltersByView = function ( view ) {
+       var groups,
+               result = [];
+
+       view = view || this.getCurrentView();
+
+       groups = this.getFilterGroupsByView( view );
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( groups, function ( groupName, groupModel ) {
+               result = result.concat( groupModel.getItems() );
+       } );
+
+       return result;
+};
+
+/**
+ * Get the trigger for the requested view.
+ *
+ * @param {string} view View name
+ * @return {string} View trigger, if exists
+ */
+FiltersViewModel.prototype.getViewTrigger = function ( view ) {
+       return ( this.views[ view ] && this.views[ view ].trigger ) || '';
+};
+
+/**
+ * Get the value of a specific parameter
+ *
+ * @param {string} name Parameter name
+ * @return {number|string} Parameter value
+ */
+FiltersViewModel.prototype.getParamValue = function ( name ) {
+       return this.parameters[ name ];
+};
+
+/**
+ * Get the current selected state of the filters
+ *
+ * @param {boolean} [onlySelected] return an object containing only the filters with a value
+ * @return {Object} Filters selected state
+ */
+FiltersViewModel.prototype.getSelectedState = function ( onlySelected ) {
+       var i,
+               items = this.getItems(),
+               result = {};
+
+       for ( i = 0; i < items.length; i++ ) {
+               if ( !onlySelected || items[ i ].getValue() ) {
+                       result[ items[ i ].getName() ] = items[ i ].getValue();
                }
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( groupItems, function ( group, model ) {
-                       $.extend(
-                               result,
-                               model.getParamRepresentation(
-                                       groupItemDefinition ?
-                                               groupItemDefinition[ group ] : null
-                               )
-                       );
-               } );
-
-               return result;
-       };
-
-       /**
-        * This is the opposite of the #getParametersFromFilters method; this goes over
-        * the given parameters and translates into a selected/unselected value in the filters.
-        *
-        * @param {Object} params Parameters query object
-        * @return {Object} Filter state object
-        */
-       FiltersViewModel.prototype.getFiltersFromParameters = function ( params ) {
-               var groupMap = {},
-                       model = this,
-                       result = {};
-
-               // Go over the given parameters, break apart to groupings
-               // The resulting object represents the group with its parameter
-               // values. For example:
-               // {
-               //    group1: {
-               //       param1: "1",
-               //       param2: "0",
-               //       param3: "1"
-               //    },
-               //    group2: "param4|param5"
-               // }
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( params, function ( paramName, paramValue ) {
-                       var groupName,
-                               itemOrGroup = model.parameterMap[ paramName ];
-
-                       if ( itemOrGroup ) {
-                               groupName = itemOrGroup instanceof FilterItem ?
-                                       itemOrGroup.getGroupName() : itemOrGroup.getName();
-
-                               groupMap[ groupName ] = groupMap[ groupName ] || {};
-                               groupMap[ groupName ][ paramName ] = paramValue;
-                       }
-               } );
-
-               // Go over all groups, so we make sure we get the complete output
-               // even if the parameters don't include a certain group
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.groups, function ( groupName, groupModel ) {
-                       result = $.extend( true, {}, result, groupModel.getFilterRepresentation( groupMap[ groupName ] ) );
-               } );
-
-               return result;
-       };
-
-       /**
-        * Get the highlight parameters based on current filter configuration
-        *
-        * @return {Object} Object where keys are `<filter name>_color` and values
-        *                  are the selected highlight colors.
-        */
-       FiltersViewModel.prototype.getHighlightParameters = function () {
-               var highlightEnabled = this.isHighlightEnabled(),
-                       result = {};
-
-               this.getItems().forEach( function ( filterItem ) {
-                       if ( filterItem.isHighlightSupported() ) {
-                               result[ filterItem.getName() + '_color' ] = highlightEnabled && filterItem.isHighlighted() ?
-                                       filterItem.getHighlightColor() :
-                                       null;
+       }
+
+       return result;
+};
+
+/**
+ * Get the current full state of the filters
+ *
+ * @return {Object} Filters full state
+ */
+FiltersViewModel.prototype.getFullState = function () {
+       var i,
+               items = this.getItems(),
+               result = {};
+
+       for ( i = 0; i < items.length; i++ ) {
+               result[ items[ i ].getName() ] = {
+                       selected: items[ i ].isSelected(),
+                       conflicted: items[ i ].isConflicted(),
+                       included: items[ i ].isIncluded()
+               };
+       }
+
+       return result;
+};
+
+/**
+ * Get an object representing default parameters state
+ *
+ * @return {Object} Default parameter values
+ */
+FiltersViewModel.prototype.getDefaultParams = function () {
+       var result = {};
+
+       // Get default filter state
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.groups, function ( name, model ) {
+               if ( !model.isSticky() ) {
+                       $.extend( true, result, model.getDefaultParams() );
+               }
+       } );
+
+       return result;
+};
+
+/**
+ * Get a parameter representation of all sticky parameters
+ *
+ * @return {Object} Sticky parameter values
+ */
+FiltersViewModel.prototype.getStickyParams = function () {
+       var result = [];
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.groups, function ( name, model ) {
+               if ( model.isSticky() ) {
+                       if ( model.isPerGroupRequestParameter() ) {
+                               result.push( name );
+                       } else {
+                               // Each filter is its own param
+                               result = result.concat( model.getItems().map( function ( filterItem ) {
+                                       return filterItem.getParamName();
+                               } ) );
                        }
-               } );
-
-               return result;
-       };
-
-       /**
-        * Get an object representing the complete empty state of highlights
-        *
-        * @return {Object} Object containing all the highlight parameters set to their negative value
-        */
-       FiltersViewModel.prototype.getEmptyHighlightParameters = function () {
-               var result = {};
-
+               }
+       } );
+
+       return result;
+};
+
+/**
+ * Get a parameter representation of all sticky parameters
+ *
+ * @return {Object} Sticky parameter values
+ */
+FiltersViewModel.prototype.getStickyParamsValues = function () {
+       var result = {};
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.groups, function ( name, model ) {
+               if ( model.isSticky() ) {
+                       $.extend( true, result, model.getParamRepresentation() );
+               }
+       } );
+
+       return result;
+};
+
+/**
+ * Analyze the groups and their filters and output an object representing
+ * the state of the parameters they represent.
+ *
+ * @param {Object} [filterDefinition] An object defining the filter values,
+ *  keyed by filter names.
+ * @return {Object} Parameter state object
+ */
+FiltersViewModel.prototype.getParametersFromFilters = function ( filterDefinition ) {
+       var groupItemDefinition,
+               result = {},
+               groupItems = this.getFilterGroups();
+
+       if ( filterDefinition ) {
+               groupItemDefinition = {};
+               // Filter definition is "flat", but in effect
+               // each group needs to tell us its result based
+               // on the values in it. We need to split this list
+               // back into groupings so we can "feed" it to the
+               // loop below, and we need to expand it so it includes
+               // all filters (set to false)
                this.getItems().forEach( function ( filterItem ) {
-                       if ( filterItem.isHighlightSupported() ) {
-                               result[ filterItem.getName() + '_color' ] = null;
-                       }
+                       groupItemDefinition[ filterItem.getGroupName() ] = groupItemDefinition[ filterItem.getGroupName() ] || {};
+                       groupItemDefinition[ filterItem.getGroupName() ][ filterItem.getName() ] = filterItem.coerceValue( filterDefinition[ filterItem.getName() ] );
                } );
+       }
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( groupItems, function ( group, model ) {
+               $.extend(
+                       result,
+                       model.getParamRepresentation(
+                               groupItemDefinition ?
+                                       groupItemDefinition[ group ] : null
+                       )
+               );
+       } );
+
+       return result;
+};
+
+/**
+ * This is the opposite of the #getParametersFromFilters method; this goes over
+ * the given parameters and translates into a selected/unselected value in the filters.
+ *
+ * @param {Object} params Parameters query object
+ * @return {Object} Filter state object
+ */
+FiltersViewModel.prototype.getFiltersFromParameters = function ( params ) {
+       var groupMap = {},
+               model = this,
+               result = {};
+
+       // Go over the given parameters, break apart to groupings
+       // The resulting object represents the group with its parameter
+       // values. For example:
+       // {
+       //    group1: {
+       //       param1: "1",
+       //       param2: "0",
+       //       param3: "1"
+       //    },
+       //    group2: "param4|param5"
+       // }
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( params, function ( paramName, paramValue ) {
+               var groupName,
+                       itemOrGroup = model.parameterMap[ paramName ];
+
+               if ( itemOrGroup ) {
+                       groupName = itemOrGroup instanceof FilterItem ?
+                               itemOrGroup.getGroupName() : itemOrGroup.getName();
+
+                       groupMap[ groupName ] = groupMap[ groupName ] || {};
+                       groupMap[ groupName ][ paramName ] = paramValue;
+               }
+       } );
+
+       // Go over all groups, so we make sure we get the complete output
+       // even if the parameters don't include a certain group
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.groups, function ( groupName, groupModel ) {
+               result = $.extend( true, {}, result, groupModel.getFilterRepresentation( groupMap[ groupName ] ) );
+       } );
+
+       return result;
+};
+
+/**
+ * Get the highlight parameters based on current filter configuration
+ *
+ * @return {Object} Object where keys are `<filter name>_color` and values
+ *                  are the selected highlight colors.
+ */
+FiltersViewModel.prototype.getHighlightParameters = function () {
+       var highlightEnabled = this.isHighlightEnabled(),
+               result = {};
+
+       this.getItems().forEach( function ( filterItem ) {
+               if ( filterItem.isHighlightSupported() ) {
+                       result[ filterItem.getName() + '_color' ] = highlightEnabled && filterItem.isHighlighted() ?
+                               filterItem.getHighlightColor() :
+                               null;
+               }
+       } );
+
+       return result;
+};
+
+/**
+ * Get an object representing the complete empty state of highlights
+ *
+ * @return {Object} Object containing all the highlight parameters set to their negative value
+ */
+FiltersViewModel.prototype.getEmptyHighlightParameters = function () {
+       var result = {};
+
+       this.getItems().forEach( function ( filterItem ) {
+               if ( filterItem.isHighlightSupported() ) {
+                       result[ filterItem.getName() + '_color' ] = null;
+               }
+       } );
 
-               return result;
-       };
-
-       /**
-        * Get an array of currently applied highlight colors
-        *
-        * @return {string[]} Currently applied highlight colors
-        */
-       FiltersViewModel.prototype.getCurrentlyUsedHighlightColors = function () {
-               var result = [];
+       return result;
+};
 
-               if ( this.isHighlightEnabled() ) {
-                       this.getHighlightedItems().forEach( function ( filterItem ) {
-                               var color = filterItem.getHighlightColor();
+/**
+ * Get an array of currently applied highlight colors
+ *
+ * @return {string[]} Currently applied highlight colors
+ */
+FiltersViewModel.prototype.getCurrentlyUsedHighlightColors = function () {
+       var result = [];
 
-                               if ( result.indexOf( color ) === -1 ) {
-                                       result.push( color );
-                               }
-                       } );
-               }
+       if ( this.isHighlightEnabled() ) {
+               this.getHighlightedItems().forEach( function ( filterItem ) {
+                       var color = filterItem.getHighlightColor();
 
-               return result;
-       };
-
-       /**
-        * Sanitize value group of a string_option groups type
-        * Remove duplicates and make sure to only use valid
-        * values.
-        *
-        * @private
-        * @param {string} groupName Group name
-        * @param {string[]} valueArray Array of values
-        * @return {string[]} Array of valid values
-        */
-       FiltersViewModel.prototype.sanitizeStringOptionGroup = function ( groupName, valueArray ) {
-               var validNames = this.getGroupFilters( groupName ).map( function ( filterItem ) {
-                       return filterItem.getParamName();
+                       if ( result.indexOf( color ) === -1 ) {
+                               result.push( color );
+                       }
                } );
-
-               return mw.rcfilters.utils.normalizeParamOptions( valueArray, validNames );
-       };
-
-       /**
-        * Check whether no visible filter is selected.
-        *
-        * Filter groups that are hidden or sticky are not shown in the
-        * active filters area and therefore not included in this check.
-        *
-        * @return {boolean} No visible filter is selected
-        */
-       FiltersViewModel.prototype.areVisibleFiltersEmpty = function () {
-               // Check if there are either any selected items or any items
-               // that have highlight enabled
-               return !this.getItems().some( function ( filterItem ) {
-                       var visible = !filterItem.getGroupModel().isSticky() && !filterItem.getGroupModel().isHidden(),
-                               active = ( filterItem.isSelected() || filterItem.isHighlighted() );
-                       return visible && active;
+       }
+
+       return result;
+};
+
+/**
+ * Sanitize value group of a string_option groups type
+ * Remove duplicates and make sure to only use valid
+ * values.
+ *
+ * @private
+ * @param {string} groupName Group name
+ * @param {string[]} valueArray Array of values
+ * @return {string[]} Array of valid values
+ */
+FiltersViewModel.prototype.sanitizeStringOptionGroup = function ( groupName, valueArray ) {
+       var validNames = this.getGroupFilters( groupName ).map( function ( filterItem ) {
+               return filterItem.getParamName();
+       } );
+
+       return mw.rcfilters.utils.normalizeParamOptions( valueArray, validNames );
+};
+
+/**
+ * Check whether no visible filter is selected.
+ *
+ * Filter groups that are hidden or sticky are not shown in the
+ * active filters area and therefore not included in this check.
+ *
+ * @return {boolean} No visible filter is selected
+ */
+FiltersViewModel.prototype.areVisibleFiltersEmpty = function () {
+       // Check if there are either any selected items or any items
+       // that have highlight enabled
+       return !this.getItems().some( function ( filterItem ) {
+               var visible = !filterItem.getGroupModel().isSticky() && !filterItem.getGroupModel().isHidden(),
+                       active = ( filterItem.isSelected() || filterItem.isHighlighted() );
+               return visible && active;
+       } );
+};
+
+/**
+ * Check whether the invert state is a valid one. A valid invert state is one where
+ * there are actual namespaces selected.
+ *
+ * This is done to compare states to previous ones that may have had the invert model
+ * selected but effectively had no namespaces, so are not effectively different than
+ * ones where invert is not selected.
+ *
+ * @return {boolean} Invert is effectively selected
+ */
+FiltersViewModel.prototype.areNamespacesEffectivelyInverted = function () {
+       return this.getInvertModel().isSelected() &&
+               this.findSelectedItems().some( function ( itemModel ) {
+                       return itemModel.getGroupModel().getName() === 'namespace';
                } );
-       };
-
-       /**
-        * Check whether the invert state is a valid one. A valid invert state is one where
-        * there are actual namespaces selected.
-        *
-        * This is done to compare states to previous ones that may have had the invert model
-        * selected but effectively had no namespaces, so are not effectively different than
-        * ones where invert is not selected.
-        *
-        * @return {boolean} Invert is effectively selected
-        */
-       FiltersViewModel.prototype.areNamespacesEffectivelyInverted = function () {
-               return this.getInvertModel().isSelected() &&
-                       this.findSelectedItems().some( function ( itemModel ) {
-                               return itemModel.getGroupModel().getName() === 'namespace';
-                       } );
-       };
-
-       /**
-        * Get the item that matches the given name
-        *
-        * @param {string} name Filter name
-        * @return {mw.rcfilters.dm.FilterItem} Filter item
-        */
-       FiltersViewModel.prototype.getItemByName = function ( name ) {
-               return this.getItems().filter( function ( item ) {
-                       return name === item.getName();
-               } )[ 0 ];
-       };
-
-       /**
-        * Set all filters to false or empty/all
-        * This is equivalent to display all.
-        */
-       FiltersViewModel.prototype.emptyAllFilters = function () {
-               this.getItems().forEach( function ( filterItem ) {
-                       if ( !filterItem.getGroupModel().isSticky() ) {
-                               this.toggleFilterSelected( filterItem.getName(), false );
-                       }
-               }.bind( this ) );
-       };
-
-       /**
-        * Toggle selected state of one item
-        *
-        * @param {string} name Name of the filter item
-        * @param {boolean} [isSelected] Filter selected state
-        */
-       FiltersViewModel.prototype.toggleFilterSelected = function ( name, isSelected ) {
-               var item = this.getItemByName( name );
-
-               if ( item ) {
-                       item.toggleSelected( isSelected );
+};
+
+/**
+ * Get the item that matches the given name
+ *
+ * @param {string} name Filter name
+ * @return {mw.rcfilters.dm.FilterItem} Filter item
+ */
+FiltersViewModel.prototype.getItemByName = function ( name ) {
+       return this.getItems().filter( function ( item ) {
+               return name === item.getName();
+       } )[ 0 ];
+};
+
+/**
+ * Set all filters to false or empty/all
+ * This is equivalent to display all.
+ */
+FiltersViewModel.prototype.emptyAllFilters = function () {
+       this.getItems().forEach( function ( filterItem ) {
+               if ( !filterItem.getGroupModel().isSticky() ) {
+                       this.toggleFilterSelected( filterItem.getName(), false );
                }
-       };
-
-       /**
-        * Toggle selected state of items by their names
-        *
-        * @param {Object} filterDef Filter definitions
-        */
-       FiltersViewModel.prototype.toggleFiltersSelected = function ( filterDef ) {
-               Object.keys( filterDef ).forEach( function ( name ) {
-                       this.toggleFilterSelected( name, filterDef[ name ] );
-               }.bind( this ) );
-       };
-
-       /**
-        * Get a group model from its name
-        *
-        * @param {string} groupName Group name
-        * @return {mw.rcfilters.dm.FilterGroup} Group model
-        */
-       FiltersViewModel.prototype.getGroup = function ( groupName ) {
-               return this.groups[ groupName ];
-       };
-
-       /**
-        * Get all filters within a specified group by its name
-        *
-        * @param {string} groupName Group name
-        * @return {mw.rcfilters.dm.FilterItem[]} Filters belonging to this group
-        */
-       FiltersViewModel.prototype.getGroupFilters = function ( groupName ) {
-               return ( this.getGroup( groupName ) && this.getGroup( groupName ).getItems() ) || [];
-       };
-
-       /**
-        * Find items whose labels match the given string
-        *
-        * @param {string} query Search string
-        * @param {boolean} [returnFlat] Return a flat array. If false, the result
-        *  is an object whose keys are the group names and values are an array of
-        *  filters per group. If set to true, returns an array of filters regardless
-        *  of their groups.
-        * @return {Object} An object of items to show
-        *  arranged by their group names
-        */
-       FiltersViewModel.prototype.findMatches = function ( query, returnFlat ) {
-               var i, searchIsEmpty,
-                       groupTitle,
-                       result = {},
-                       flatResult = [],
-                       view = this.getViewByTrigger( query.substr( 0, 1 ) ),
-                       items = this.getFiltersByView( view );
-
-               // Normalize so we can search strings regardless of case and view
-               query = query.trim().toLowerCase();
-               if ( view !== 'default' ) {
-                       query = query.substr( 1 );
+       }.bind( this ) );
+};
+
+/**
+ * Toggle selected state of one item
+ *
+ * @param {string} name Name of the filter item
+ * @param {boolean} [isSelected] Filter selected state
+ */
+FiltersViewModel.prototype.toggleFilterSelected = function ( name, isSelected ) {
+       var item = this.getItemByName( name );
+
+       if ( item ) {
+               item.toggleSelected( isSelected );
+       }
+};
+
+/**
+ * Toggle selected state of items by their names
+ *
+ * @param {Object} filterDef Filter definitions
+ */
+FiltersViewModel.prototype.toggleFiltersSelected = function ( filterDef ) {
+       Object.keys( filterDef ).forEach( function ( name ) {
+               this.toggleFilterSelected( name, filterDef[ name ] );
+       }.bind( this ) );
+};
+
+/**
+ * Get a group model from its name
+ *
+ * @param {string} groupName Group name
+ * @return {mw.rcfilters.dm.FilterGroup} Group model
+ */
+FiltersViewModel.prototype.getGroup = function ( groupName ) {
+       return this.groups[ groupName ];
+};
+
+/**
+ * Get all filters within a specified group by its name
+ *
+ * @param {string} groupName Group name
+ * @return {mw.rcfilters.dm.FilterItem[]} Filters belonging to this group
+ */
+FiltersViewModel.prototype.getGroupFilters = function ( groupName ) {
+       return ( this.getGroup( groupName ) && this.getGroup( groupName ).getItems() ) || [];
+};
+
+/**
+ * Find items whose labels match the given string
+ *
+ * @param {string} query Search string
+ * @param {boolean} [returnFlat] Return a flat array. If false, the result
+ *  is an object whose keys are the group names and values are an array of
+ *  filters per group. If set to true, returns an array of filters regardless
+ *  of their groups.
+ * @return {Object} An object of items to show
+ *  arranged by their group names
+ */
+FiltersViewModel.prototype.findMatches = function ( query, returnFlat ) {
+       var i, searchIsEmpty,
+               groupTitle,
+               result = {},
+               flatResult = [],
+               view = this.getViewByTrigger( query.substr( 0, 1 ) ),
+               items = this.getFiltersByView( view );
+
+       // Normalize so we can search strings regardless of case and view
+       query = query.trim().toLowerCase();
+       if ( view !== 'default' ) {
+               query = query.substr( 1 );
+       }
+       // Trim again to also intercept cases where the spaces were after the trigger
+       // eg: '#   str'
+       query = query.trim();
+
+       // Check if the search if actually empty; this can be a problem when
+       // we use prefixes to denote different views
+       searchIsEmpty = query.length === 0;
+
+       // item label starting with the query string
+       for ( i = 0; i < items.length; i++ ) {
+               if (
+                       searchIsEmpty ||
+                       items[ i ].getLabel().toLowerCase().indexOf( query ) === 0 ||
+                       (
+                               // For tags, we want the parameter name to be included in the search
+                               view === 'tags' &&
+                               items[ i ].getParamName().toLowerCase().indexOf( query ) > -1
+                       )
+               ) {
+                       result[ items[ i ].getGroupName() ] = result[ items[ i ].getGroupName() ] || [];
+                       result[ items[ i ].getGroupName() ].push( items[ i ] );
+                       flatResult.push( items[ i ] );
                }
-               // Trim again to also intercept cases where the spaces were after the trigger
-               // eg: '#   str'
-               query = query.trim();
+       }
 
-               // Check if the search if actually empty; this can be a problem when
-               // we use prefixes to denote different views
-               searchIsEmpty = query.length === 0;
-
-               // item label starting with the query string
+       if ( $.isEmptyObject( result ) ) {
+               // item containing the query string in their label, description, or group title
                for ( i = 0; i < items.length; i++ ) {
+                       groupTitle = items[ i ].getGroupModel().getTitle();
                        if (
                                searchIsEmpty ||
-                               items[ i ].getLabel().toLowerCase().indexOf( query ) === 0 ||
+                               items[ i ].getLabel().toLowerCase().indexOf( query ) > -1 ||
+                               items[ i ].getDescription().toLowerCase().indexOf( query ) > -1 ||
+                               groupTitle.toLowerCase().indexOf( query ) > -1 ||
                                (
                                        // For tags, we want the parameter name to be included in the search
                                        view === 'tags' &&
                                flatResult.push( items[ i ] );
                        }
                }
-
-               if ( $.isEmptyObject( result ) ) {
-                       // item containing the query string in their label, description, or group title
-                       for ( i = 0; i < items.length; i++ ) {
-                               groupTitle = items[ i ].getGroupModel().getTitle();
-                               if (
-                                       searchIsEmpty ||
-                                       items[ i ].getLabel().toLowerCase().indexOf( query ) > -1 ||
-                                       items[ i ].getDescription().toLowerCase().indexOf( query ) > -1 ||
-                                       groupTitle.toLowerCase().indexOf( query ) > -1 ||
-                                       (
-                                               // For tags, we want the parameter name to be included in the search
-                                               view === 'tags' &&
-                                               items[ i ].getParamName().toLowerCase().indexOf( query ) > -1
-                                       )
-                               ) {
-                                       result[ items[ i ].getGroupName() ] = result[ items[ i ].getGroupName() ] || [];
-                                       result[ items[ i ].getGroupName() ].push( items[ i ] );
-                                       flatResult.push( items[ i ] );
-                               }
-                       }
+       }
+
+       return returnFlat ? flatResult : result;
+};
+
+/**
+ * Get items that are highlighted
+ *
+ * @return {mw.rcfilters.dm.FilterItem[]} Highlighted items
+ */
+FiltersViewModel.prototype.getHighlightedItems = function () {
+       return this.getItems().filter( function ( filterItem ) {
+               return filterItem.isHighlightSupported() &&
+                       filterItem.getHighlightColor();
+       } );
+};
+
+/**
+ * Get items that allow highlights even if they're not currently highlighted
+ *
+ * @return {mw.rcfilters.dm.FilterItem[]} Items supporting highlights
+ */
+FiltersViewModel.prototype.getItemsSupportingHighlights = function () {
+       return this.getItems().filter( function ( filterItem ) {
+               return filterItem.isHighlightSupported();
+       } );
+};
+
+/**
+ * Get all selected items
+ *
+ * @return {mw.rcfilters.dm.FilterItem[]} Selected items
+ */
+FiltersViewModel.prototype.findSelectedItems = function () {
+       var allSelected = [];
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.getFilterGroups(), function ( groupName, groupModel ) {
+               allSelected = allSelected.concat( groupModel.findSelectedItems() );
+       } );
+
+       return allSelected;
+};
+
+/**
+ * Get the current view
+ *
+ * @return {string} Current view
+ */
+FiltersViewModel.prototype.getCurrentView = function () {
+       return this.currentView;
+};
+
+/**
+ * Get the label for the current view
+ *
+ * @param {string} viewName View name
+ * @return {string} Label for the current view
+ */
+FiltersViewModel.prototype.getViewTitle = function ( viewName ) {
+       viewName = viewName || this.getCurrentView();
+
+       return this.views[ viewName ] && this.views[ viewName ].title;
+};
+
+/**
+ * Get the view that fits the given trigger
+ *
+ * @param {string} trigger Trigger
+ * @return {string} Name of view
+ */
+FiltersViewModel.prototype.getViewByTrigger = function ( trigger ) {
+       var result = 'default';
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( this.views, function ( name, data ) {
+               if ( data.trigger === trigger ) {
+                       result = name;
                }
-
-               return returnFlat ? flatResult : result;
-       };
-
-       /**
-        * Get items that are highlighted
-        *
-        * @return {mw.rcfilters.dm.FilterItem[]} Highlighted items
-        */
-       FiltersViewModel.prototype.getHighlightedItems = function () {
-               return this.getItems().filter( function ( filterItem ) {
-                       return filterItem.isHighlightSupported() &&
-                               filterItem.getHighlightColor();
-               } );
-       };
-
-       /**
-        * Get items that allow highlights even if they're not currently highlighted
-        *
-        * @return {mw.rcfilters.dm.FilterItem[]} Items supporting highlights
-        */
-       FiltersViewModel.prototype.getItemsSupportingHighlights = function () {
-               return this.getItems().filter( function ( filterItem ) {
-                       return filterItem.isHighlightSupported();
-               } );
-       };
-
-       /**
-        * Get all selected items
-        *
-        * @return {mw.rcfilters.dm.FilterItem[]} Selected items
-        */
-       FiltersViewModel.prototype.findSelectedItems = function () {
-               var allSelected = [];
-
+       } );
+
+       return result;
+};
+
+/**
+ * Return a version of the given string that is without any
+ * view triggers.
+ *
+ * @param {string} str Given string
+ * @return {string} Result
+ */
+FiltersViewModel.prototype.removeViewTriggers = function ( str ) {
+       if ( this.getViewFromString( str ) !== 'default' ) {
+               str = str.substr( 1 );
+       }
+
+       return str;
+};
+
+/**
+ * Get the view from the given string by a trigger, if it exists
+ *
+ * @param {string} str Given string
+ * @return {string} View name
+ */
+FiltersViewModel.prototype.getViewFromString = function ( str ) {
+       return this.getViewByTrigger( str.substr( 0, 1 ) );
+};
+
+/**
+ * Set the current search for the system.
+ * This also dictates what items and groups are visible according
+ * to the search in #findMatches
+ *
+ * @param {string} searchQuery Search query, including triggers
+ * @fires searchChange
+ */
+FiltersViewModel.prototype.setSearch = function ( searchQuery ) {
+       var visibleGroups, visibleGroupNames;
+
+       if ( this.searchQuery !== searchQuery ) {
+               // Check if the view changed
+               this.switchView( this.getViewFromString( searchQuery ) );
+
+               visibleGroups = this.findMatches( searchQuery );
+               visibleGroupNames = Object.keys( visibleGroups );
+
+               // Update visibility of items and groups
                // eslint-disable-next-line no-jquery/no-each-util
                $.each( this.getFilterGroups(), function ( groupName, groupModel ) {
-                       allSelected = allSelected.concat( groupModel.findSelectedItems() );
-               } );
-
-               return allSelected;
-       };
-
-       /**
-        * Get the current view
-        *
-        * @return {string} Current view
-        */
-       FiltersViewModel.prototype.getCurrentView = function () {
-               return this.currentView;
-       };
-
-       /**
-        * Get the label for the current view
-        *
-        * @param {string} viewName View name
-        * @return {string} Label for the current view
-        */
-       FiltersViewModel.prototype.getViewTitle = function ( viewName ) {
-               viewName = viewName || this.getCurrentView();
-
-               return this.views[ viewName ] && this.views[ viewName ].title;
-       };
-
-       /**
-        * Get the view that fits the given trigger
-        *
-        * @param {string} trigger Trigger
-        * @return {string} Name of view
-        */
-       FiltersViewModel.prototype.getViewByTrigger = function ( trigger ) {
-               var result = 'default';
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( this.views, function ( name, data ) {
-                       if ( data.trigger === trigger ) {
-                               result = name;
-                       }
+                       // Check if the group is visible at all
+                       groupModel.toggleVisible( visibleGroupNames.indexOf( groupName ) !== -1 );
+                       groupModel.setVisibleItems( visibleGroups[ groupName ] || [] );
                } );
 
-               return result;
-       };
-
-       /**
-        * Return a version of the given string that is without any
-        * view triggers.
-        *
-        * @param {string} str Given string
-        * @return {string} Result
-        */
-       FiltersViewModel.prototype.removeViewTriggers = function ( str ) {
-               if ( this.getViewFromString( str ) !== 'default' ) {
-                       str = str.substr( 1 );
-               }
-
-               return str;
-       };
-
-       /**
-        * Get the view from the given string by a trigger, if it exists
-        *
-        * @param {string} str Given string
-        * @return {string} View name
-        */
-       FiltersViewModel.prototype.getViewFromString = function ( str ) {
-               return this.getViewByTrigger( str.substr( 0, 1 ) );
-       };
-
-       /**
-        * Set the current search for the system.
-        * This also dictates what items and groups are visible according
-        * to the search in #findMatches
-        *
-        * @param {string} searchQuery Search query, including triggers
-        * @fires searchChange
-        */
-       FiltersViewModel.prototype.setSearch = function ( searchQuery ) {
-               var visibleGroups, visibleGroupNames;
-
-               if ( this.searchQuery !== searchQuery ) {
-                       // Check if the view changed
-                       this.switchView( this.getViewFromString( searchQuery ) );
-
-                       visibleGroups = this.findMatches( searchQuery );
-                       visibleGroupNames = Object.keys( visibleGroups );
-
-                       // Update visibility of items and groups
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( this.getFilterGroups(), function ( groupName, groupModel ) {
-                               // Check if the group is visible at all
-                               groupModel.toggleVisible( visibleGroupNames.indexOf( groupName ) !== -1 );
-                               groupModel.setVisibleItems( visibleGroups[ groupName ] || [] );
-                       } );
-
-                       this.searchQuery = searchQuery;
-                       this.emit( 'searchChange', this.searchQuery );
-               }
-       };
-
-       /**
-        * Get the current search
-        *
-        * @return {string} Current search query
-        */
-       FiltersViewModel.prototype.getSearch = function () {
-               return this.searchQuery;
-       };
-
-       /**
-        * Switch the current view
-        *
-        * @private
-        * @param {string} view View name
-        */
-       FiltersViewModel.prototype.switchView = function ( view ) {
-               if ( this.views[ view ] && this.currentView !== view ) {
-                       this.currentView = view;
-               }
-       };
-
-       /**
-        * Toggle the highlight feature on and off.
-        * Propagate the change to filter items.
-        *
-        * @param {boolean} enable Highlight should be enabled
-        * @fires highlightChange
-        */
-       FiltersViewModel.prototype.toggleHighlight = function ( enable ) {
-               enable = enable === undefined ? !this.highlightEnabled : enable;
-
-               if ( this.highlightEnabled !== enable ) {
-                       this.highlightEnabled = enable;
-                       this.emit( 'highlightChange', this.highlightEnabled );
-               }
-       };
-
-       /**
-        * Check if the highlight feature is enabled
-        * @return {boolean}
-        */
-       FiltersViewModel.prototype.isHighlightEnabled = function () {
-               return !!this.highlightEnabled;
-       };
-
-       /**
-        * Toggle the inverted namespaces property on and off.
-        * Propagate the change to namespace filter items.
-        *
-        * @param {boolean} enable Inverted property is enabled
-        */
-       FiltersViewModel.prototype.toggleInvertedNamespaces = function ( enable ) {
-               this.toggleFilterSelected( this.getInvertModel().getName(), enable );
-       };
-
-       /**
-        * Get the model object that represents the 'invert' filter
-        *
-        * @return {mw.rcfilters.dm.FilterItem}
-        */
-       FiltersViewModel.prototype.getInvertModel = function () {
-               return this.getGroup( 'invertGroup' ).getItemByParamName( 'invert' );
-       };
-
-       /**
-        * Set highlight color for a specific filter item
-        *
-        * @param {string} filterName Name of the filter item
-        * @param {string} color Selected color
-        */
-       FiltersViewModel.prototype.setHighlightColor = function ( filterName, color ) {
-               this.getItemByName( filterName ).setHighlightColor( color );
-       };
-
-       /**
-        * Clear highlight for a specific filter item
-        *
-        * @param {string} filterName Name of the filter item
-        */
-       FiltersViewModel.prototype.clearHighlightColor = function ( filterName ) {
-               this.getItemByName( filterName ).clearHighlightColor();
-       };
-
-       module.exports = FiltersViewModel;
-
-}() );
+               this.searchQuery = searchQuery;
+               this.emit( 'searchChange', this.searchQuery );
+       }
+};
+
+/**
+ * Get the current search
+ *
+ * @return {string} Current search query
+ */
+FiltersViewModel.prototype.getSearch = function () {
+       return this.searchQuery;
+};
+
+/**
+ * Switch the current view
+ *
+ * @private
+ * @param {string} view View name
+ */
+FiltersViewModel.prototype.switchView = function ( view ) {
+       if ( this.views[ view ] && this.currentView !== view ) {
+               this.currentView = view;
+       }
+};
+
+/**
+ * Toggle the highlight feature on and off.
+ * Propagate the change to filter items.
+ *
+ * @param {boolean} enable Highlight should be enabled
+ * @fires highlightChange
+ */
+FiltersViewModel.prototype.toggleHighlight = function ( enable ) {
+       enable = enable === undefined ? !this.highlightEnabled : enable;
+
+       if ( this.highlightEnabled !== enable ) {
+               this.highlightEnabled = enable;
+               this.emit( 'highlightChange', this.highlightEnabled );
+       }
+};
+
+/**
+ * Check if the highlight feature is enabled
+ * @return {boolean}
+ */
+FiltersViewModel.prototype.isHighlightEnabled = function () {
+       return !!this.highlightEnabled;
+};
+
+/**
+ * Toggle the inverted namespaces property on and off.
+ * Propagate the change to namespace filter items.
+ *
+ * @param {boolean} enable Inverted property is enabled
+ */
+FiltersViewModel.prototype.toggleInvertedNamespaces = function ( enable ) {
+       this.toggleFilterSelected( this.getInvertModel().getName(), enable );
+};
+
+/**
+ * Get the model object that represents the 'invert' filter
+ *
+ * @return {mw.rcfilters.dm.FilterItem}
+ */
+FiltersViewModel.prototype.getInvertModel = function () {
+       return this.getGroup( 'invertGroup' ).getItemByParamName( 'invert' );
+};
+
+/**
+ * Set highlight color for a specific filter item
+ *
+ * @param {string} filterName Name of the filter item
+ * @param {string} color Selected color
+ */
+FiltersViewModel.prototype.setHighlightColor = function ( filterName, color ) {
+       this.getItemByName( filterName ).setHighlightColor( color );
+};
+
+/**
+ * Clear highlight for a specific filter item
+ *
+ * @param {string} filterName Name of the filter item
+ */
+FiltersViewModel.prototype.clearHighlightColor = function ( filterName ) {
+       this.getItemByName( filterName ).clearHighlightColor();
+};
+
+module.exports = FiltersViewModel;
index 2dc578e..ae8ac5f 100644 (file)
-( function () {
-       /**
-        * RCFilter base item model
-        *
-        * @class mw.rcfilters.dm.ItemModel
-        * @mixins OO.EventEmitter
-        *
-        * @constructor
-        * @param {string} param Filter param name
-        * @param {Object} config Configuration object
-        * @cfg {string} [label] The label for the filter
-        * @cfg {string} [description] The description of the filter
-        * @cfg {string|Object} [labelPrefixKey] An i18n key defining the prefix label for this
-        *  group. If the prefix has 'invert' state, the parameter is expected to be an object
-        *  with 'default' and 'inverted' as keys.
-        * @cfg {boolean} [active=true] The filter is active and affecting the result
-        * @cfg {boolean} [selected] The item is selected
-        * @cfg {*} [value] The value of this item
-        * @cfg {string} [namePrefix='item_'] A prefix to add to the param name to act as a unique
-        *  identifier
-        * @cfg {string} [cssClass] The class identifying the results that match this filter
-        * @cfg {string[]} [identifiers] An array of identifiers for this item. They will be
-        *  added and considered in the view.
-        * @cfg {string} [defaultHighlightColor=null] If set, highlight this filter by default with this color
-        */
-       var ItemModel = function MwRcfiltersDmItemModel( param, config ) {
-               config = config || {};
-
-               // Mixin constructor
-               OO.EventEmitter.call( this );
-
-               this.param = param;
-               this.namePrefix = config.namePrefix || 'item_';
-               this.name = this.namePrefix + param;
-
-               this.label = config.label || this.name;
-               this.labelPrefixKey = config.labelPrefixKey;
-               this.description = config.description || '';
-               this.setValue( config.value || config.selected );
-
-               this.identifiers = config.identifiers || [];
-
-               // Highlight
-               this.cssClass = config.cssClass;
-               this.highlightColor = config.defaultHighlightColor || null;
+/**
+ * RCFilter base item model
+ *
+ * @class mw.rcfilters.dm.ItemModel
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {string} param Filter param name
+ * @param {Object} config Configuration object
+ * @cfg {string} [label] The label for the filter
+ * @cfg {string} [description] The description of the filter
+ * @cfg {string|Object} [labelPrefixKey] An i18n key defining the prefix label for this
+ *  group. If the prefix has 'invert' state, the parameter is expected to be an object
+ *  with 'default' and 'inverted' as keys.
+ * @cfg {boolean} [active=true] The filter is active and affecting the result
+ * @cfg {boolean} [selected] The item is selected
+ * @cfg {*} [value] The value of this item
+ * @cfg {string} [namePrefix='item_'] A prefix to add to the param name to act as a unique
+ *  identifier
+ * @cfg {string} [cssClass] The class identifying the results that match this filter
+ * @cfg {string[]} [identifiers] An array of identifiers for this item. They will be
+ *  added and considered in the view.
+ * @cfg {string} [defaultHighlightColor=null] If set, highlight this filter by default with this color
+ */
+var ItemModel = function MwRcfiltersDmItemModel( param, config ) {
+       config = config || {};
+
+       // Mixin constructor
+       OO.EventEmitter.call( this );
+
+       this.param = param;
+       this.namePrefix = config.namePrefix || 'item_';
+       this.name = this.namePrefix + param;
+
+       this.label = config.label || this.name;
+       this.labelPrefixKey = config.labelPrefixKey;
+       this.description = config.description || '';
+       this.setValue( config.value || config.selected );
+
+       this.identifiers = config.identifiers || [];
+
+       // Highlight
+       this.cssClass = config.cssClass;
+       this.highlightColor = config.defaultHighlightColor || null;
+};
+
+/* Initialization */
+
+OO.initClass( ItemModel );
+OO.mixinClass( ItemModel, OO.EventEmitter );
+
+/* Events */
+
+/**
+ * @event update
+ *
+ * The state of this filter has changed
+ */
+
+/* Methods */
+
+/**
+ * Return the representation of the state of this item.
+ *
+ * @return {Object} State of the object
+ */
+ItemModel.prototype.getState = function () {
+       return {
+               selected: this.isSelected()
        };
-
-       /* Initialization */
-
-       OO.initClass( ItemModel );
-       OO.mixinClass( ItemModel, OO.EventEmitter );
-
-       /* Events */
-
-       /**
-        * @event update
-        *
-        * The state of this filter has changed
-        */
-
-       /* Methods */
-
-       /**
-        * Return the representation of the state of this item.
-        *
-        * @return {Object} State of the object
-        */
-       ItemModel.prototype.getState = function () {
-               return {
-                       selected: this.isSelected()
-               };
-       };
-
-       /**
-        * Get the name of this filter
-        *
-        * @return {string} Filter name
-        */
-       ItemModel.prototype.getName = function () {
-               return this.name;
-       };
-
-       /**
-        * Get the message key to use to wrap the label. This message takes the label as a parameter.
-        *
-        * @param {boolean} inverted Whether this item should be considered inverted
-        * @return {string|null} Message key, or null if no message
-        */
-       ItemModel.prototype.getLabelMessageKey = function ( inverted ) {
-               if ( this.labelPrefixKey ) {
-                       if ( typeof this.labelPrefixKey === 'string' ) {
-                               return this.labelPrefixKey;
-                       }
-                       return this.labelPrefixKey[
-                               // Only use inverted-prefix if the item is selected
-                               // Highlight-only an inverted item makes no sense
-                               inverted && this.isSelected() ?
-                                       'inverted' : 'default'
-                       ];
+};
+
+/**
+ * Get the name of this filter
+ *
+ * @return {string} Filter name
+ */
+ItemModel.prototype.getName = function () {
+       return this.name;
+};
+
+/**
+ * Get the message key to use to wrap the label. This message takes the label as a parameter.
+ *
+ * @param {boolean} inverted Whether this item should be considered inverted
+ * @return {string|null} Message key, or null if no message
+ */
+ItemModel.prototype.getLabelMessageKey = function ( inverted ) {
+       if ( this.labelPrefixKey ) {
+               if ( typeof this.labelPrefixKey === 'string' ) {
+                       return this.labelPrefixKey;
                }
-               return null;
-       };
-
-       /**
-        * Get the param name or value of this filter
-        *
-        * @return {string} Filter param name
-        */
-       ItemModel.prototype.getParamName = function () {
-               return this.param;
-       };
-
-       /**
-        * Get the message representing the state of this model.
-        *
-        * @return {string} State message
-        */
-       ItemModel.prototype.getStateMessage = function () {
-               // Display description
-               return this.getDescription();
-       };
-
-       /**
-        * Get the label of this filter
-        *
-        * @return {string} Filter label
-        */
-       ItemModel.prototype.getLabel = function () {
-               return this.label;
-       };
-
-       /**
-        * Get the description of this filter
-        *
-        * @return {string} Filter description
-        */
-       ItemModel.prototype.getDescription = function () {
-               return this.description;
-       };
-
-       /**
-        * Get the default value of this filter
-        *
-        * @return {boolean} Filter default
-        */
-       ItemModel.prototype.getDefault = function () {
-               return this.default;
-       };
-
-       /**
-        * Get the selected state of this filter
-        *
-        * @return {boolean} Filter is selected
-        */
-       ItemModel.prototype.isSelected = function () {
-               return !!this.value;
-       };
-
-       /**
-        * Toggle the selected state of the item
-        *
-        * @param {boolean} [isSelected] Filter is selected
-        * @fires update
-        */
-       ItemModel.prototype.toggleSelected = function ( isSelected ) {
-               isSelected = isSelected === undefined ? !this.isSelected() : isSelected;
-               this.setValue( isSelected );
-       };
-
-       /**
-        * Get the value
-        *
-        * @return {*}
-        */
-       ItemModel.prototype.getValue = function () {
-               return this.value;
-       };
-
-       /**
-        * Convert a given value to the appropriate representation based on group type
-        *
-        * @param {*} value
-        * @return {*}
-        */
-       ItemModel.prototype.coerceValue = function ( value ) {
-               return this.getGroupModel().getType() === 'any_value' ? value : !!value;
-       };
-
-       /**
-        * Set the value
-        *
-        * @param {*} newValue
-        */
-       ItemModel.prototype.setValue = function ( newValue ) {
-               newValue = this.coerceValue( newValue );
-               if ( this.value !== newValue ) {
-                       this.value = newValue;
-                       this.emit( 'update' );
-               }
-       };
-
-       /**
-        * Set the highlight color
-        *
-        * @param {string|null} highlightColor
-        */
-       ItemModel.prototype.setHighlightColor = function ( highlightColor ) {
-               if ( !this.isHighlightSupported() ) {
-                       return;
-               }
-               // If the highlight color on the item and in the parameter is null/undefined, return early.
-               if ( !this.highlightColor && !highlightColor ) {
-                       return;
-               }
-
-               if ( this.highlightColor !== highlightColor ) {
-                       this.highlightColor = highlightColor;
-                       this.emit( 'update' );
-               }
-       };
-
-       /**
-        * Clear the highlight color
-        */
-       ItemModel.prototype.clearHighlightColor = function () {
-               this.setHighlightColor( null );
-       };
-
-       /**
-        * Get the highlight color, or null if none is configured
-        *
-        * @return {string|null}
-        */
-       ItemModel.prototype.getHighlightColor = function () {
-               return this.highlightColor;
-       };
-
-       /**
-        * Get the CSS class that matches changes that fit this filter
-        * or null if none is configured
-        *
-        * @return {string|null}
-        */
-       ItemModel.prototype.getCssClass = function () {
-               return this.cssClass;
-       };
-
-       /**
-        * Get the item's identifiers
-        *
-        * @return {string[]}
-        */
-       ItemModel.prototype.getIdentifiers = function () {
-               return this.identifiers;
-       };
-
-       /**
-        * Check if the highlight feature is supported for this filter
-        *
-        * @return {boolean}
-        */
-       ItemModel.prototype.isHighlightSupported = function () {
-               return !!this.getCssClass();
-       };
-
-       /**
-        * Check if the filter is currently highlighted
-        *
-        * @return {boolean}
-        */
-       ItemModel.prototype.isHighlighted = function () {
-               return !!this.getHighlightColor();
-       };
-
-       module.exports = ItemModel;
-}() );
+               return this.labelPrefixKey[
+                       // Only use inverted-prefix if the item is selected
+                       // Highlight-only an inverted item makes no sense
+                       inverted && this.isSelected() ?
+                               'inverted' : 'default'
+               ];
+       }
+       return null;
+};
+
+/**
+ * Get the param name or value of this filter
+ *
+ * @return {string} Filter param name
+ */
+ItemModel.prototype.getParamName = function () {
+       return this.param;
+};
+
+/**
+ * Get the message representing the state of this model.
+ *
+ * @return {string} State message
+ */
+ItemModel.prototype.getStateMessage = function () {
+       // Display description
+       return this.getDescription();
+};
+
+/**
+ * Get the label of this filter
+ *
+ * @return {string} Filter label
+ */
+ItemModel.prototype.getLabel = function () {
+       return this.label;
+};
+
+/**
+ * Get the description of this filter
+ *
+ * @return {string} Filter description
+ */
+ItemModel.prototype.getDescription = function () {
+       return this.description;
+};
+
+/**
+ * Get the default value of this filter
+ *
+ * @return {boolean} Filter default
+ */
+ItemModel.prototype.getDefault = function () {
+       return this.default;
+};
+
+/**
+ * Get the selected state of this filter
+ *
+ * @return {boolean} Filter is selected
+ */
+ItemModel.prototype.isSelected = function () {
+       return !!this.value;
+};
+
+/**
+ * Toggle the selected state of the item
+ *
+ * @param {boolean} [isSelected] Filter is selected
+ * @fires update
+ */
+ItemModel.prototype.toggleSelected = function ( isSelected ) {
+       isSelected = isSelected === undefined ? !this.isSelected() : isSelected;
+       this.setValue( isSelected );
+};
+
+/**
+ * Get the value
+ *
+ * @return {*}
+ */
+ItemModel.prototype.getValue = function () {
+       return this.value;
+};
+
+/**
+ * Convert a given value to the appropriate representation based on group type
+ *
+ * @param {*} value
+ * @return {*}
+ */
+ItemModel.prototype.coerceValue = function ( value ) {
+       return this.getGroupModel().getType() === 'any_value' ? value : !!value;
+};
+
+/**
+ * Set the value
+ *
+ * @param {*} newValue
+ */
+ItemModel.prototype.setValue = function ( newValue ) {
+       newValue = this.coerceValue( newValue );
+       if ( this.value !== newValue ) {
+               this.value = newValue;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Set the highlight color
+ *
+ * @param {string|null} highlightColor
+ */
+ItemModel.prototype.setHighlightColor = function ( highlightColor ) {
+       if ( !this.isHighlightSupported() ) {
+               return;
+       }
+       // If the highlight color on the item and in the parameter is null/undefined, return early.
+       if ( !this.highlightColor && !highlightColor ) {
+               return;
+       }
+
+       if ( this.highlightColor !== highlightColor ) {
+               this.highlightColor = highlightColor;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Clear the highlight color
+ */
+ItemModel.prototype.clearHighlightColor = function () {
+       this.setHighlightColor( null );
+};
+
+/**
+ * Get the highlight color, or null if none is configured
+ *
+ * @return {string|null}
+ */
+ItemModel.prototype.getHighlightColor = function () {
+       return this.highlightColor;
+};
+
+/**
+ * Get the CSS class that matches changes that fit this filter
+ * or null if none is configured
+ *
+ * @return {string|null}
+ */
+ItemModel.prototype.getCssClass = function () {
+       return this.cssClass;
+};
+
+/**
+ * Get the item's identifiers
+ *
+ * @return {string[]}
+ */
+ItemModel.prototype.getIdentifiers = function () {
+       return this.identifiers;
+};
+
+/**
+ * Check if the highlight feature is supported for this filter
+ *
+ * @return {boolean}
+ */
+ItemModel.prototype.isHighlightSupported = function () {
+       return !!this.getCssClass();
+};
+
+/**
+ * Check if the filter is currently highlighted
+ *
+ * @return {boolean}
+ */
+ItemModel.prototype.isHighlighted = function () {
+       return !!this.getHighlightColor();
+};
+
+module.exports = ItemModel;
index aa407b9..19de282 100644 (file)
-( function () {
-       var SavedQueryItemModel = require( './SavedQueryItemModel.js' ),
-               SavedQueriesModel;
-
-       /**
-        * View model for saved queries
-        *
-        * @class mw.rcfilters.dm.SavedQueriesModel
-        * @mixins OO.EventEmitter
-        * @mixins OO.EmitterList
-        *
-        * @constructor
-        * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters model
-        * @param {Object} [config] Configuration options
-        * @cfg {string} [default] Default query ID
-        */
-       SavedQueriesModel = function MwRcfiltersDmSavedQueriesModel( filtersModel, config ) {
-               config = config || {};
-
-               // Mixin constructor
-               OO.EventEmitter.call( this );
-               OO.EmitterList.call( this );
-
-               this.default = config.default;
-               this.filtersModel = filtersModel;
-               this.converted = false;
-
-               // Events
-               this.aggregate( { update: 'itemUpdate' } );
-       };
-
-       /* Initialization */
-
-       OO.initClass( SavedQueriesModel );
-       OO.mixinClass( SavedQueriesModel, OO.EventEmitter );
-       OO.mixinClass( SavedQueriesModel, OO.EmitterList );
-
-       /* Events */
-
-       /**
-        * @event initialize
-        *
-        * Model is initialized
-        */
-
-       /**
-        * @event itemUpdate
-        * @param {mw.rcfilters.dm.SavedQueryItemModel} Changed item
-        *
-        * An item has changed
-        */
-
-       /**
-        * @event default
-        * @param {string} New default ID
-        *
-        * The default has changed
-        */
-
-       /* Methods */
-
-       /**
-        * Initialize the saved queries model by reading it from the user's settings.
-        * The structure of the saved queries is:
-        * {
-        *    version: (string) Version number; if version 2, the query represents
-        *             parameters. Otherwise, the older version represented filters
-        *             and needs to be readjusted,
-        *    default: (string) Query ID
-        *    queries:{
-        *       query_id_1: {
-        *          data:{
-        *             filters: (Object) Minimal definition of the filters
-        *             highlights: (Object) Definition of the highlights
-        *          },
-        *          label: (optional) Name of this query
-        *       }
-        *    }
-        * }
-        *
-        * @param {Object} [savedQueries] An object with the saved queries with
-        *  the above structure.
-        * @fires initialize
-        */
-       SavedQueriesModel.prototype.initialize = function ( savedQueries ) {
-               var model = this;
-
-               savedQueries = savedQueries || {};
-
-               this.clearItems();
-               this.default = null;
-               this.converted = false;
-
-               if ( savedQueries.version !== '2' ) {
-                       // Old version dealt with filter names. We need to migrate to the new structure
-                       // The new structure:
-                       // {
-                       //   version: (string) '2',
-                       //   default: (string) Query ID,
-                       //   queries: {
-                       //     query_id: {
-                       //       label: (string) Name of the query
-                       //       data: {
-                       //         params: (object) Representing all the parameter states
-                       //         highlights: (object) Representing all the filter highlight states
-                       //     }
-                       //   }
-                       // }
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( savedQueries.queries || {}, function ( id, obj ) {
-                               if ( obj.data && obj.data.filters ) {
-                                       obj.data = model.convertToParameters( obj.data );
-                               }
-                       } );
-
-                       this.converted = true;
-                       savedQueries.version = '2';
-               }
-
-               // Initialize the query items
+var SavedQueryItemModel = require( './SavedQueryItemModel.js' ),
+       SavedQueriesModel;
+
+/**
+ * View model for saved queries
+ *
+ * @class mw.rcfilters.dm.SavedQueriesModel
+ * @mixins OO.EventEmitter
+ * @mixins OO.EmitterList
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters model
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [default] Default query ID
+ */
+SavedQueriesModel = function MwRcfiltersDmSavedQueriesModel( filtersModel, config ) {
+       config = config || {};
+
+       // Mixin constructor
+       OO.EventEmitter.call( this );
+       OO.EmitterList.call( this );
+
+       this.default = config.default;
+       this.filtersModel = filtersModel;
+       this.converted = false;
+
+       // Events
+       this.aggregate( { update: 'itemUpdate' } );
+};
+
+/* Initialization */
+
+OO.initClass( SavedQueriesModel );
+OO.mixinClass( SavedQueriesModel, OO.EventEmitter );
+OO.mixinClass( SavedQueriesModel, OO.EmitterList );
+
+/* Events */
+
+/**
+ * @event initialize
+ *
+ * Model is initialized
+ */
+
+/**
+ * @event itemUpdate
+ * @param {mw.rcfilters.dm.SavedQueryItemModel} Changed item
+ *
+ * An item has changed
+ */
+
+/**
+ * @event default
+ * @param {string} New default ID
+ *
+ * The default has changed
+ */
+
+/* Methods */
+
+/**
+ * Initialize the saved queries model by reading it from the user's settings.
+ * The structure of the saved queries is:
+ * {
+ *    version: (string) Version number; if version 2, the query represents
+ *             parameters. Otherwise, the older version represented filters
+ *             and needs to be readjusted,
+ *    default: (string) Query ID
+ *    queries:{
+ *       query_id_1: {
+ *          data:{
+ *             filters: (Object) Minimal definition of the filters
+ *             highlights: (Object) Definition of the highlights
+ *          },
+ *          label: (optional) Name of this query
+ *       }
+ *    }
+ * }
+ *
+ * @param {Object} [savedQueries] An object with the saved queries with
+ *  the above structure.
+ * @fires initialize
+ */
+SavedQueriesModel.prototype.initialize = function ( savedQueries ) {
+       var model = this;
+
+       savedQueries = savedQueries || {};
+
+       this.clearItems();
+       this.default = null;
+       this.converted = false;
+
+       if ( savedQueries.version !== '2' ) {
+               // Old version dealt with filter names. We need to migrate to the new structure
+               // The new structure:
+               // {
+               //   version: (string) '2',
+               //   default: (string) Query ID,
+               //   queries: {
+               //     query_id: {
+               //       label: (string) Name of the query
+               //       data: {
+               //         params: (object) Representing all the parameter states
+               //         highlights: (object) Representing all the filter highlight states
+               //     }
+               //   }
+               // }
                // eslint-disable-next-line no-jquery/no-each-util
                $.each( savedQueries.queries || {}, function ( id, obj ) {
-                       var normalizedData = obj.data,
-                               isDefault = String( savedQueries.default ) === String( id );
-
-                       if ( normalizedData && normalizedData.params ) {
-                               // Backwards-compat fix: Remove sticky parameters from
-                               // the given data, if they exist
-                               normalizedData.params = model.filtersModel.removeStickyParams( normalizedData.params );
-
-                               // Correct the invert state for effective selection
-                               if ( normalizedData.params.invert && !normalizedData.params.namespace ) {
-                                       delete normalizedData.params.invert;
-                               }
-
-                               model.cleanupHighlights( normalizedData );
-
-                               id = String( id );
-
-                               // Skip the addNewQuery method because we don't want to unnecessarily manipulate
-                               // the given saved queries unless we literally intend to (like in backwards compat fixes)
-                               // And the addNewQuery method also uses a minimization routine that checks for the
-                               // validity of items and minimizes the query. This isn't necessary for queries loaded
-                               // from the backend, and has the risk of removing values if they're temporarily
-                               // invalid (example: if we temporarily removed a cssClass from a filter in the backend)
-                               model.addItems( [
-                                       new SavedQueryItemModel(
-                                               id,
-                                               obj.label,
-                                               normalizedData,
-                                               { default: isDefault }
-                                       )
-                               ] );
-
-                               if ( isDefault ) {
-                                       model.default = id;
-                               }
+                       if ( obj.data && obj.data.filters ) {
+                               obj.data = model.convertToParameters( obj.data );
                        }
                } );
 
-               this.emit( 'initialize' );
-       };
-
-       /**
-        * Clean up highlight parameters.
-        * 'highlight' used to be stored, it's not inferred based on the presence of absence of
-        * filter colors.
-        *
-        * @param {Object} data Saved query data
-        */
-       SavedQueriesModel.prototype.cleanupHighlights = function ( data ) {
-               if (
-                       data.params.highlight === '0' &&
-                       data.highlights && Object.keys( data.highlights ).length
-               ) {
-                       data.highlights = {};
-               }
-               delete data.params.highlight;
-       };
-
-       /**
-        * Convert from representation of filters to representation of parameters
-        *
-        * @param {Object} data Query data
-        * @return {Object} New converted query data
-        */
-       SavedQueriesModel.prototype.convertToParameters = function ( data ) {
-               var newData = {},
-                       defaultFilters = this.filtersModel.getFiltersFromParameters( this.filtersModel.getDefaultParams() ),
-                       fullFilterRepresentation = $.extend( true, {}, defaultFilters, data.filters ),
-                       highlightEnabled = data.highlights.highlight;
-
-               delete data.highlights.highlight;
-
-               // Filters
-               newData.params = this.filtersModel.getMinimizedParamRepresentation(
-                       this.filtersModel.getParametersFromFilters( fullFilterRepresentation )
-               );
+               this.converted = true;
+               savedQueries.version = '2';
+       }
 
-               // Highlights: appending _color to keys
-               newData.highlights = {};
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( data.highlights, function ( highlightedFilterName, value ) {
-                       if ( value ) {
-                               newData.highlights[ highlightedFilterName + '_color' ] = data.highlights[ highlightedFilterName ];
-                       }
-               } );
+       // Initialize the query items
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( savedQueries.queries || {}, function ( id, obj ) {
+               var normalizedData = obj.data,
+                       isDefault = String( savedQueries.default ) === String( id );
 
-               // Add highlight
-               newData.params.highlight = String( Number( highlightEnabled || 0 ) );
-
-               return newData;
-       };
-
-       /**
-        * Add a query item
-        *
-        * @param {string} label Label for the new query
-        * @param {Object} fulldata Full data representation for the new query, combining highlights and filters
-        * @param {boolean} isDefault Item is default
-        * @param {string} [id] Query ID, if exists. If this isn't given, a random
-        *  new ID will be created.
-        * @return {string} ID of the newly added query
-        */
-       SavedQueriesModel.prototype.addNewQuery = function ( label, fulldata, isDefault, id ) {
-               var normalizedData = { params: {}, highlights: {} },
-                       highlightParamNames = Object.keys( this.filtersModel.getEmptyHighlightParameters() ),
-                       randomID = String( id || ( new Date() ).getTime() ),
-                       data = this.filtersModel.getMinimizedParamRepresentation( fulldata );
-
-               // Split highlight/params
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( data, function ( param, value ) {
-                       if ( param !== 'highlight' && highlightParamNames.indexOf( param ) > -1 ) {
-                               normalizedData.highlights[ param ] = value;
-                       } else {
-                               normalizedData.params[ param ] = value;
+               if ( normalizedData && normalizedData.params ) {
+                       // Backwards-compat fix: Remove sticky parameters from
+                       // the given data, if they exist
+                       normalizedData.params = model.filtersModel.removeStickyParams( normalizedData.params );
+
+                       // Correct the invert state for effective selection
+                       if ( normalizedData.params.invert && !normalizedData.params.namespace ) {
+                               delete normalizedData.params.invert;
                        }
-               } );
 
-               // Correct the invert state for effective selection
-               if ( normalizedData.params.invert && !this.filtersModel.areNamespacesEffectivelyInverted() ) {
-                       delete normalizedData.params.invert;
+                       model.cleanupHighlights( normalizedData );
+
+                       id = String( id );
+
+                       // Skip the addNewQuery method because we don't want to unnecessarily manipulate
+                       // the given saved queries unless we literally intend to (like in backwards compat fixes)
+                       // And the addNewQuery method also uses a minimization routine that checks for the
+                       // validity of items and minimizes the query. This isn't necessary for queries loaded
+                       // from the backend, and has the risk of removing values if they're temporarily
+                       // invalid (example: if we temporarily removed a cssClass from a filter in the backend)
+                       model.addItems( [
+                               new SavedQueryItemModel(
+                                       id,
+                                       obj.label,
+                                       normalizedData,
+                                       { default: isDefault }
+                               )
+                       ] );
+
+                       if ( isDefault ) {
+                               model.default = id;
+                       }
                }
-
-               // Add item
-               this.addItems( [
-                       new SavedQueryItemModel(
-                               randomID,
-                               label,
-                               normalizedData,
-                               { default: isDefault }
-                       )
-               ] );
-
-               if ( isDefault ) {
-                       this.setDefault( randomID );
+       } );
+
+       this.emit( 'initialize' );
+};
+
+/**
+ * Clean up highlight parameters.
+ * 'highlight' used to be stored, it's not inferred based on the presence of absence of
+ * filter colors.
+ *
+ * @param {Object} data Saved query data
+ */
+SavedQueriesModel.prototype.cleanupHighlights = function ( data ) {
+       if (
+               data.params.highlight === '0' &&
+               data.highlights && Object.keys( data.highlights ).length
+       ) {
+               data.highlights = {};
+       }
+       delete data.params.highlight;
+};
+
+/**
+ * Convert from representation of filters to representation of parameters
+ *
+ * @param {Object} data Query data
+ * @return {Object} New converted query data
+ */
+SavedQueriesModel.prototype.convertToParameters = function ( data ) {
+       var newData = {},
+               defaultFilters = this.filtersModel.getFiltersFromParameters( this.filtersModel.getDefaultParams() ),
+               fullFilterRepresentation = $.extend( true, {}, defaultFilters, data.filters ),
+               highlightEnabled = data.highlights.highlight;
+
+       delete data.highlights.highlight;
+
+       // Filters
+       newData.params = this.filtersModel.getMinimizedParamRepresentation(
+               this.filtersModel.getParametersFromFilters( fullFilterRepresentation )
+       );
+
+       // Highlights: appending _color to keys
+       newData.highlights = {};
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( data.highlights, function ( highlightedFilterName, value ) {
+               if ( value ) {
+                       newData.highlights[ highlightedFilterName + '_color' ] = data.highlights[ highlightedFilterName ];
                }
-
-               return randomID;
-       };
-
-       /**
-        * Remove query from model
-        *
-        * @param {string} queryID Query ID
-        */
-       SavedQueriesModel.prototype.removeQuery = function ( queryID ) {
-               var query = this.getItemByID( queryID );
-
-               if ( query ) {
-                       // Check if this item was the default
-                       if ( String( this.getDefault() ) === String( queryID ) ) {
-                               // Nulify the default
-                               this.setDefault( null );
-                       }
-
-                       this.removeItems( [ query ] );
+       } );
+
+       // Add highlight
+       newData.params.highlight = String( Number( highlightEnabled || 0 ) );
+
+       return newData;
+};
+
+/**
+ * Add a query item
+ *
+ * @param {string} label Label for the new query
+ * @param {Object} fulldata Full data representation for the new query, combining highlights and filters
+ * @param {boolean} isDefault Item is default
+ * @param {string} [id] Query ID, if exists. If this isn't given, a random
+ *  new ID will be created.
+ * @return {string} ID of the newly added query
+ */
+SavedQueriesModel.prototype.addNewQuery = function ( label, fulldata, isDefault, id ) {
+       var normalizedData = { params: {}, highlights: {} },
+               highlightParamNames = Object.keys( this.filtersModel.getEmptyHighlightParameters() ),
+               randomID = String( id || ( new Date() ).getTime() ),
+               data = this.filtersModel.getMinimizedParamRepresentation( fulldata );
+
+       // Split highlight/params
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( data, function ( param, value ) {
+               if ( param !== 'highlight' && highlightParamNames.indexOf( param ) > -1 ) {
+                       normalizedData.highlights[ param ] = value;
+               } else {
+                       normalizedData.params[ param ] = value;
                }
-       };
-
-       /**
-        * Get an item that matches the requested query
-        *
-        * @param {Object} fullQueryComparison Object representing all filters and highlights to compare
-        * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
-        */
-       SavedQueriesModel.prototype.findMatchingQuery = function ( fullQueryComparison ) {
-               // Minimize before comparison
-               fullQueryComparison = this.filtersModel.getMinimizedParamRepresentation( fullQueryComparison );
-
-               // Correct the invert state for effective selection
-               if ( fullQueryComparison.invert && !this.filtersModel.areNamespacesEffectivelyInverted() ) {
-                       delete fullQueryComparison.invert;
+       } );
+
+       // Correct the invert state for effective selection
+       if ( normalizedData.params.invert && !this.filtersModel.areNamespacesEffectivelyInverted() ) {
+               delete normalizedData.params.invert;
+       }
+
+       // Add item
+       this.addItems( [
+               new SavedQueryItemModel(
+                       randomID,
+                       label,
+                       normalizedData,
+                       { default: isDefault }
+               )
+       ] );
+
+       if ( isDefault ) {
+               this.setDefault( randomID );
+       }
+
+       return randomID;
+};
+
+/**
+ * Remove query from model
+ *
+ * @param {string} queryID Query ID
+ */
+SavedQueriesModel.prototype.removeQuery = function ( queryID ) {
+       var query = this.getItemByID( queryID );
+
+       if ( query ) {
+               // Check if this item was the default
+               if ( String( this.getDefault() ) === String( queryID ) ) {
+                       // Nulify the default
+                       this.setDefault( null );
                }
 
-               return this.getItems().filter( function ( item ) {
-                       return OO.compare(
-                               item.getCombinedData(),
-                               fullQueryComparison
-                       );
-               } )[ 0 ];
-       };
-
-       /**
-        * Get query by its identifier
-        *
-        * @param {string} queryID Query identifier
-        * @return {mw.rcfilters.dm.SavedQueryItemModel|undefined} Item matching
-        *  the search. Undefined if not found.
-        */
-       SavedQueriesModel.prototype.getItemByID = function ( queryID ) {
-               return this.getItems().filter( function ( item ) {
-                       return item.getID() === queryID;
-               } )[ 0 ];
-       };
-
-       /**
-        * Get the full data representation of the default query, if it exists
-        *
-        * @return {Object|null} Representation of the default params if exists.
-        *  Null if default doesn't exist or if the user is not logged in.
-        */
-       SavedQueriesModel.prototype.getDefaultParams = function () {
-               return ( !mw.user.isAnon() && this.getItemParams( this.getDefault() ) ) || {};
-       };
-
-       /**
-        * Get a full parameter representation of an item data
-        *
-        * @param  {Object} queryID Query ID
-        * @return {Object} Parameter representation
-        */
-       SavedQueriesModel.prototype.getItemParams = function ( queryID ) {
-               var item = this.getItemByID( queryID ),
-                       data = item ? item.getData() : {};
-
-               return !$.isEmptyObject( data ) ? this.buildParamsFromData( data ) : {};
-       };
-
-       /**
-        * Build a full parameter representation given item data and model sticky values state
-        *
-        * @param  {Object} data Item data
-        * @return {Object} Full param representation
-        */
-       SavedQueriesModel.prototype.buildParamsFromData = function ( data ) {
-               data = data || {};
-               // Return parameter representation
-               return this.filtersModel.getMinimizedParamRepresentation( $.extend( true, {},
-                       data.params,
-                       data.highlights
-               ) );
-       };
-
-       /**
-        * Get the object representing the state of the entire model and items
-        *
-        * @return {Object} Object representing the state of the model and items
-        */
-       SavedQueriesModel.prototype.getState = function () {
-               var obj = { queries: {}, version: '2' };
-
-               // Translate the items to the saved object
+               this.removeItems( [ query ] );
+       }
+};
+
+/**
+ * Get an item that matches the requested query
+ *
+ * @param {Object} fullQueryComparison Object representing all filters and highlights to compare
+ * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
+ */
+SavedQueriesModel.prototype.findMatchingQuery = function ( fullQueryComparison ) {
+       // Minimize before comparison
+       fullQueryComparison = this.filtersModel.getMinimizedParamRepresentation( fullQueryComparison );
+
+       // Correct the invert state for effective selection
+       if ( fullQueryComparison.invert && !this.filtersModel.areNamespacesEffectivelyInverted() ) {
+               delete fullQueryComparison.invert;
+       }
+
+       return this.getItems().filter( function ( item ) {
+               return OO.compare(
+                       item.getCombinedData(),
+                       fullQueryComparison
+               );
+       } )[ 0 ];
+};
+
+/**
+ * Get query by its identifier
+ *
+ * @param {string} queryID Query identifier
+ * @return {mw.rcfilters.dm.SavedQueryItemModel|undefined} Item matching
+ *  the search. Undefined if not found.
+ */
+SavedQueriesModel.prototype.getItemByID = function ( queryID ) {
+       return this.getItems().filter( function ( item ) {
+               return item.getID() === queryID;
+       } )[ 0 ];
+};
+
+/**
+ * Get the full data representation of the default query, if it exists
+ *
+ * @return {Object|null} Representation of the default params if exists.
+ *  Null if default doesn't exist or if the user is not logged in.
+ */
+SavedQueriesModel.prototype.getDefaultParams = function () {
+       return ( !mw.user.isAnon() && this.getItemParams( this.getDefault() ) ) || {};
+};
+
+/**
+ * Get a full parameter representation of an item data
+ *
+ * @param  {Object} queryID Query ID
+ * @return {Object} Parameter representation
+ */
+SavedQueriesModel.prototype.getItemParams = function ( queryID ) {
+       var item = this.getItemByID( queryID ),
+               data = item ? item.getData() : {};
+
+       return !$.isEmptyObject( data ) ? this.buildParamsFromData( data ) : {};
+};
+
+/**
+ * Build a full parameter representation given item data and model sticky values state
+ *
+ * @param  {Object} data Item data
+ * @return {Object} Full param representation
+ */
+SavedQueriesModel.prototype.buildParamsFromData = function ( data ) {
+       data = data || {};
+       // Return parameter representation
+       return this.filtersModel.getMinimizedParamRepresentation( $.extend( true, {},
+               data.params,
+               data.highlights
+       ) );
+};
+
+/**
+ * Get the object representing the state of the entire model and items
+ *
+ * @return {Object} Object representing the state of the model and items
+ */
+SavedQueriesModel.prototype.getState = function () {
+       var obj = { queries: {}, version: '2' };
+
+       // Translate the items to the saved object
+       this.getItems().forEach( function ( item ) {
+               obj.queries[ item.getID() ] = item.getState();
+       } );
+
+       if ( this.getDefault() ) {
+               obj.default = this.getDefault();
+       }
+
+       return obj;
+};
+
+/**
+ * Set a default query. Null to unset default.
+ *
+ * @param {string} itemID Query identifier
+ * @fires default
+ */
+SavedQueriesModel.prototype.setDefault = function ( itemID ) {
+       if ( this.default !== itemID ) {
+               this.default = itemID;
+
+               // Set for individual itens
                this.getItems().forEach( function ( item ) {
-                       obj.queries[ item.getID() ] = item.getState();
+                       item.toggleDefault( item.getID() === itemID );
                } );
 
-               if ( this.getDefault() ) {
-                       obj.default = this.getDefault();
-               }
-
-               return obj;
-       };
-
-       /**
-        * Set a default query. Null to unset default.
-        *
-        * @param {string} itemID Query identifier
-        * @fires default
-        */
-       SavedQueriesModel.prototype.setDefault = function ( itemID ) {
-               if ( this.default !== itemID ) {
-                       this.default = itemID;
-
-                       // Set for individual itens
-                       this.getItems().forEach( function ( item ) {
-                               item.toggleDefault( item.getID() === itemID );
-                       } );
-
-                       this.emit( 'default', itemID );
-               }
-       };
-
-       /**
-        * Get the default query ID
-        *
-        * @return {string} Default query identifier
-        */
-       SavedQueriesModel.prototype.getDefault = function () {
-               return this.default;
-       };
-
-       /**
-        * Check if the saved queries were converted
-        *
-        * @return {boolean} Saved queries were converted from the previous
-        *  version to the new version
-        */
-       SavedQueriesModel.prototype.isConverted = function () {
-               return this.converted;
-       };
-
-       module.exports = SavedQueriesModel;
-}() );
+               this.emit( 'default', itemID );
+       }
+};
+
+/**
+ * Get the default query ID
+ *
+ * @return {string} Default query identifier
+ */
+SavedQueriesModel.prototype.getDefault = function () {
+       return this.default;
+};
+
+/**
+ * Check if the saved queries were converted
+ *
+ * @return {boolean} Saved queries were converted from the previous
+ *  version to the new version
+ */
+SavedQueriesModel.prototype.isConverted = function () {
+       return this.converted;
+};
+
+module.exports = SavedQueriesModel;
index 1774391..27e93e3 100644 (file)
-( function () {
-       /**
-        * View model for a single saved query
-        *
-        * @class mw.rcfilters.dm.SavedQueryItemModel
-        * @mixins OO.EventEmitter
-        *
-        * @constructor
-        * @param {string} id Unique identifier
-        * @param {string} label Saved query label
-        * @param {Object} data Saved query data
-        * @param {Object} [config] Configuration options
-        * @cfg {boolean} [default] This item is the default
-        */
-       var SavedQueryItemModel = function MwRcfiltersDmSavedQueriesModel( id, label, data, config ) {
-               config = config || {};
-
-               // Mixin constructor
-               OO.EventEmitter.call( this );
-
-               this.id = id;
-               this.label = label;
-               this.data = data;
-               this.default = !!config.default;
+/**
+ * View model for a single saved query
+ *
+ * @class mw.rcfilters.dm.SavedQueryItemModel
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {string} id Unique identifier
+ * @param {string} label Saved query label
+ * @param {Object} data Saved query data
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [default] This item is the default
+ */
+var SavedQueryItemModel = function MwRcfiltersDmSavedQueriesModel( id, label, data, config ) {
+       config = config || {};
+
+       // Mixin constructor
+       OO.EventEmitter.call( this );
+
+       this.id = id;
+       this.label = label;
+       this.data = data;
+       this.default = !!config.default;
+};
+
+/* Initialization */
+
+OO.initClass( SavedQueryItemModel );
+OO.mixinClass( SavedQueryItemModel, OO.EventEmitter );
+
+/* Events */
+
+/**
+ * @event update
+ *
+ * Model has been updated
+ */
+
+/* Methods */
+
+/**
+ * Get an object representing the state of this item
+ *
+ * @return {Object} Object representing the current data state
+ *  of the object
+ */
+SavedQueryItemModel.prototype.getState = function () {
+       return {
+               data: this.getData(),
+               label: this.getLabel()
        };
-
-       /* Initialization */
-
-       OO.initClass( SavedQueryItemModel );
-       OO.mixinClass( SavedQueryItemModel, OO.EventEmitter );
-
-       /* Events */
-
-       /**
-        * @event update
-        *
-        * Model has been updated
-        */
-
-       /* Methods */
-
-       /**
-        * Get an object representing the state of this item
-        *
-        * @return {Object} Object representing the current data state
-        *  of the object
-        */
-       SavedQueryItemModel.prototype.getState = function () {
-               return {
-                       data: this.getData(),
-                       label: this.getLabel()
-               };
-       };
-
-       /**
-        * Get the query's identifier
-        *
-        * @return {string} Query identifier
-        */
-       SavedQueryItemModel.prototype.getID = function () {
-               return this.id;
-       };
-
-       /**
-        * Get query label
-        *
-        * @return {string} Query label
-        */
-       SavedQueryItemModel.prototype.getLabel = function () {
-               return this.label;
-       };
-
-       /**
-        * Update the query label
-        *
-        * @param {string} newLabel New label
-        */
-       SavedQueryItemModel.prototype.updateLabel = function ( newLabel ) {
-               if ( newLabel && this.label !== newLabel ) {
-                       this.label = newLabel;
-                       this.emit( 'update' );
-               }
-       };
-
-       /**
-        * Get query data
-        *
-        * @return {Object} Object representing parameter and highlight data
-        */
-       SavedQueryItemModel.prototype.getData = function () {
-               return this.data;
-       };
-
-       /**
-        * Get the combined data of this item as a flat object of parameters
-        *
-        * @return {Object} Combined parameter data
-        */
-       SavedQueryItemModel.prototype.getCombinedData = function () {
-               return $.extend( true, {}, this.data.params, this.data.highlights );
-       };
-
-       /**
-        * Check whether this item is the default
-        *
-        * @return {boolean} Query is set to be default
-        */
-       SavedQueryItemModel.prototype.isDefault = function () {
-               return this.default;
-       };
-
-       /**
-        * Toggle the default state of this query item
-        *
-        * @param {boolean} isDefault Query is default
-        */
-       SavedQueryItemModel.prototype.toggleDefault = function ( isDefault ) {
-               isDefault = isDefault === undefined ? !this.default : isDefault;
-
-               if ( this.default !== isDefault ) {
-                       this.default = isDefault;
-                       this.emit( 'update' );
-               }
-       };
-
-       module.exports = SavedQueryItemModel;
-}() );
+};
+
+/**
+ * Get the query's identifier
+ *
+ * @return {string} Query identifier
+ */
+SavedQueryItemModel.prototype.getID = function () {
+       return this.id;
+};
+
+/**
+ * Get query label
+ *
+ * @return {string} Query label
+ */
+SavedQueryItemModel.prototype.getLabel = function () {
+       return this.label;
+};
+
+/**
+ * Update the query label
+ *
+ * @param {string} newLabel New label
+ */
+SavedQueryItemModel.prototype.updateLabel = function ( newLabel ) {
+       if ( newLabel && this.label !== newLabel ) {
+               this.label = newLabel;
+               this.emit( 'update' );
+       }
+};
+
+/**
+ * Get query data
+ *
+ * @return {Object} Object representing parameter and highlight data
+ */
+SavedQueryItemModel.prototype.getData = function () {
+       return this.data;
+};
+
+/**
+ * Get the combined data of this item as a flat object of parameters
+ *
+ * @return {Object} Combined parameter data
+ */
+SavedQueryItemModel.prototype.getCombinedData = function () {
+       return $.extend( true, {}, this.data.params, this.data.highlights );
+};
+
+/**
+ * Check whether this item is the default
+ *
+ * @return {boolean} Query is set to be default
+ */
+SavedQueryItemModel.prototype.isDefault = function () {
+       return this.default;
+};
+
+/**
+ * Toggle the default state of this query item
+ *
+ * @param {boolean} isDefault Query is default
+ */
+SavedQueryItemModel.prototype.toggleDefault = function ( isDefault ) {
+       isDefault = isDefault === undefined ? !this.default : isDefault;
+
+       if ( this.default !== isDefault ) {
+               this.default = isDefault;
+               this.emit( 'update' );
+       }
+};
+
+module.exports = SavedQueryItemModel;
index a69dc55..4e5e0fe 100644 (file)
 /*!
  * JavaScript for Special:RecentChanges
  */
-( function () {
-
-       mw.rcfilters.HighlightColors = require( './HighlightColors.js' );
-       mw.rcfilters.ui.MainWrapperWidget = require( './ui/MainWrapperWidget.js' );
-
-       /**
-        * Get list of namespaces and remove unused ones
-        *
-        * @member mw.rcfilters
-        * @private
-        *
-        * @param {Array} unusedNamespaces Names of namespaces to remove
-        * @return {Array} Filtered array of namespaces
-        */
-       function getNamespaces( unusedNamespaces ) {
-               var i, length, name, id,
-                       namespaceIds = mw.config.get( 'wgNamespaceIds' ),
-                       namespaces = mw.config.get( 'wgFormattedNamespaces' );
-
-               for ( i = 0, length = unusedNamespaces.length; i < length; i++ ) {
-                       name = unusedNamespaces[ i ];
-                       id = namespaceIds[ name.toLowerCase() ];
-                       delete namespaces[ id ];
-               }
-
-               return namespaces;
+mw.rcfilters.HighlightColors = require( './HighlightColors.js' );
+mw.rcfilters.ui.MainWrapperWidget = require( './ui/MainWrapperWidget.js' );
+
+/**
+ * Get list of namespaces and remove unused ones
+ *
+ * @member mw.rcfilters
+ * @private
+ *
+ * @param {Array} unusedNamespaces Names of namespaces to remove
+ * @return {Array} Filtered array of namespaces
+ */
+function getNamespaces( unusedNamespaces ) {
+       var i, length, name, id,
+               namespaceIds = mw.config.get( 'wgNamespaceIds' ),
+               namespaces = mw.config.get( 'wgFormattedNamespaces' );
+
+       for ( i = 0, length = unusedNamespaces.length; i < length; i++ ) {
+               name = unusedNamespaces[ i ];
+               id = namespaceIds[ name.toLowerCase() ];
+               delete namespaces[ id ];
        }
 
-       /**
-        * @member mw.rcfilters
-        * @private
-        */
-       function init() {
-               var $topSection,
-                       mainWrapperWidget,
-                       conditionalViews = {},
-                       $initialFieldset = $( 'fieldset.cloptions' ),
-                       savedQueriesPreferenceName = mw.config.get( 'wgStructuredChangeFiltersSavedQueriesPreferenceName' ),
-                       daysPreferenceName = mw.config.get( 'wgStructuredChangeFiltersDaysPreferenceName' ),
-                       limitPreferenceName = mw.config.get( 'wgStructuredChangeFiltersLimitPreferenceName' ),
-                       activeFiltersCollapsedName = mw.config.get( 'wgStructuredChangeFiltersCollapsedPreferenceName' ),
-                       initialCollapsedState = mw.config.get( 'wgStructuredChangeFiltersCollapsedState' ),
-                       filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
-                       changesListModel = new mw.rcfilters.dm.ChangesListViewModel( $initialFieldset ),
-                       savedQueriesModel = new mw.rcfilters.dm.SavedQueriesModel( filtersModel ),
-                       specialPage = mw.config.get( 'wgCanonicalSpecialPageName' ),
-                       controller = new mw.rcfilters.Controller(
-                               filtersModel, changesListModel, savedQueriesModel,
-                               {
-                                       savedQueriesPreferenceName: savedQueriesPreferenceName,
-                                       daysPreferenceName: daysPreferenceName,
-                                       limitPreferenceName: limitPreferenceName,
-                                       collapsedPreferenceName: activeFiltersCollapsedName,
-                                       normalizeTarget: specialPage === 'Recentchangeslinked'
-                               }
-                       );
-
-               // TODO: The changesListWrapperWidget should be able to initialize
-               // after the model is ready.
-
-               if ( specialPage === 'Recentchanges' ) {
-                       $topSection = $( '.mw-recentchanges-toplinks' ).detach();
-               } else if ( specialPage === 'Watchlist' ) {
-                       $( '#contentSub, form#mw-watchlist-resetbutton' ).remove();
-                       $topSection = $( '.watchlistDetails' ).detach().contents();
-               } else if ( specialPage === 'Recentchangeslinked' ) {
-                       conditionalViews.recentChangesLinked = {
-                               groups: [
-                                       {
-                                               name: 'page',
-                                               type: 'any_value',
-                                               title: '',
-                                               hidden: true,
-                                               sticky: true,
-                                               filters: [
-                                                       {
-                                                               name: 'target',
-                                                               default: ''
-                                                       }
-                                               ]
-                                       },
-                                       {
-                                               name: 'toOrFrom',
-                                               type: 'boolean',
-                                               title: '',
-                                               hidden: true,
-                                               sticky: true,
-                                               filters: [
-                                                       {
-                                                               name: 'showlinkedto',
-                                                               default: false
-                                                       }
-                                               ]
-                                       }
-                               ]
-                       };
-               }
+       return namespaces;
+}
 
-               mainWrapperWidget = new mw.rcfilters.ui.MainWrapperWidget(
-                       controller,
-                       filtersModel,
-                       savedQueriesModel,
-                       changesListModel,
+/**
+ * @member mw.rcfilters
+ * @private
+ */
+function init() {
+       var $topSection,
+               mainWrapperWidget,
+               conditionalViews = {},
+               $initialFieldset = $( 'fieldset.cloptions' ),
+               savedQueriesPreferenceName = mw.config.get( 'wgStructuredChangeFiltersSavedQueriesPreferenceName' ),
+               daysPreferenceName = mw.config.get( 'wgStructuredChangeFiltersDaysPreferenceName' ),
+               limitPreferenceName = mw.config.get( 'wgStructuredChangeFiltersLimitPreferenceName' ),
+               activeFiltersCollapsedName = mw.config.get( 'wgStructuredChangeFiltersCollapsedPreferenceName' ),
+               initialCollapsedState = mw.config.get( 'wgStructuredChangeFiltersCollapsedState' ),
+               filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
+               changesListModel = new mw.rcfilters.dm.ChangesListViewModel( $initialFieldset ),
+               savedQueriesModel = new mw.rcfilters.dm.SavedQueriesModel( filtersModel ),
+               specialPage = mw.config.get( 'wgCanonicalSpecialPageName' ),
+               controller = new mw.rcfilters.Controller(
+                       filtersModel, changesListModel, savedQueriesModel,
                        {
-                               $wrapper: $( 'body' ),
-                               $topSection: $topSection,
-                               $filtersContainer: $( '.rcfilters-container' ),
-                               $changesListContainer: $( '.mw-changeslist, .mw-changeslist-empty' ),
-                               $formContainer: $initialFieldset,
-                               collapsed: initialCollapsedState
+                               savedQueriesPreferenceName: savedQueriesPreferenceName,
+                               daysPreferenceName: daysPreferenceName,
+                               limitPreferenceName: limitPreferenceName,
+                               collapsedPreferenceName: activeFiltersCollapsedName,
+                               normalizeTarget: specialPage === 'Recentchangeslinked'
                        }
                );
 
-               // Remove the -loading class that may have been added on the server side.
-               // If we are in fact going to load a default saved query, this .initialize()
-               // call will do that and add the -loading class right back.
-               $( 'body' ).removeClass( 'mw-rcfilters-ui-loading' );
-
-               controller.initialize(
-                       mw.config.get( 'wgStructuredChangeFilters' ),
-                       // All namespaces without Media namespace
-                       getNamespaces( [ 'Media' ] ),
-                       require( './config.json' ).RCFiltersChangeTags,
-                       conditionalViews
-               );
+       // TODO: The changesListWrapperWidget should be able to initialize
+       // after the model is ready.
+
+       if ( specialPage === 'Recentchanges' ) {
+               $topSection = $( '.mw-recentchanges-toplinks' ).detach();
+       } else if ( specialPage === 'Watchlist' ) {
+               $( '#contentSub, form#mw-watchlist-resetbutton' ).remove();
+               $topSection = $( '.watchlistDetails' ).detach().contents();
+       } else if ( specialPage === 'Recentchangeslinked' ) {
+               conditionalViews.recentChangesLinked = {
+                       groups: [
+                               {
+                                       name: 'page',
+                                       type: 'any_value',
+                                       title: '',
+                                       hidden: true,
+                                       sticky: true,
+                                       filters: [
+                                               {
+                                                       name: 'target',
+                                                       default: ''
+                                               }
+                                       ]
+                               },
+                               {
+                                       name: 'toOrFrom',
+                                       type: 'boolean',
+                                       title: '',
+                                       hidden: true,
+                                       sticky: true,
+                                       filters: [
+                                               {
+                                                       name: 'showlinkedto',
+                                                       default: false
+                                               }
+                                       ]
+                               }
+                       ]
+               };
+       }
 
-               mainWrapperWidget.initFormWidget( specialPage );
+       mainWrapperWidget = new mw.rcfilters.ui.MainWrapperWidget(
+               controller,
+               filtersModel,
+               savedQueriesModel,
+               changesListModel,
+               {
+                       $wrapper: $( 'body' ),
+                       $topSection: $topSection,
+                       $filtersContainer: $( '.rcfilters-container' ),
+                       $changesListContainer: $( '.mw-changeslist, .mw-changeslist-empty' ),
+                       $formContainer: $initialFieldset,
+                       collapsed: initialCollapsedState
+               }
+       );
 
-               $( 'a.mw-helplink' ).attr(
-                       'href',
-                       'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:New_filters_for_edit_review'
-               );
+       // Remove the -loading class that may have been added on the server side.
+       // If we are in fact going to load a default saved query, this .initialize()
+       // call will do that and add the -loading class right back.
+       $( 'body' ).removeClass( 'mw-rcfilters-ui-loading' );
 
-               controller.replaceUrl();
+       controller.initialize(
+               mw.config.get( 'wgStructuredChangeFilters' ),
+               // All namespaces without Media namespace
+               getNamespaces( [ 'Media' ] ),
+               require( './config.json' ).RCFiltersChangeTags,
+               conditionalViews
+       );
 
-               mainWrapperWidget.setTopSection( specialPage );
+       mainWrapperWidget.initFormWidget( specialPage );
 
-               /**
-                * Fired when initialization of the filtering interface for changes list is complete.
-                *
-                * @event structuredChangeFilters_ui_initialized
-                * @member mw.hook
-                */
-               mw.hook( 'structuredChangeFilters.ui.initialized' ).fire();
-       }
+       $( 'a.mw-helplink' ).attr(
+               'href',
+               'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:New_filters_for_edit_review'
+       );
 
-       // Import i18n messages from config
-       mw.messages.set( mw.config.get( 'wgStructuredChangeFiltersMessages' ) );
+       controller.replaceUrl();
 
-       // Early execute of init
-       if ( document.readyState === 'interactive' || document.readyState === 'complete' ) {
-               init();
-       } else {
-               $( init );
-       }
+       mainWrapperWidget.setTopSection( specialPage );
+
+       /**
+        * Fired when initialization of the filtering interface for changes list is complete.
+        *
+        * @event structuredChangeFilters_ui_initialized
+        * @member mw.hook
+        */
+       mw.hook( 'structuredChangeFilters.ui.initialized' ).fire();
+}
+
+// Import i18n messages from config
+mw.messages.set( mw.config.get( 'wgStructuredChangeFiltersMessages' ) );
 
-       module.exports = mw.rcfilters;
+// Early execute of init
+if ( document.readyState === 'interactive' || document.readyState === 'complete' ) {
+       init();
+} else {
+       $( init );
+}
 
-}() );
+module.exports = mw.rcfilters;
index b32fb38..5bf9916 100644 (file)
@@ -1,61 +1,59 @@
-( function () {
-       /**
-        * @class
-        * @singleton
-        */
-       mw.rcfilters = {
-               Controller: require( './Controller.js' ),
-               UriProcessor: require( './UriProcessor.js' ),
-               dm: {
-                       ChangesListViewModel: require( './dm/ChangesListViewModel.js' ),
-                       FilterGroup: require( './dm/FilterGroup.js' ),
-                       FilterItem: require( './dm/FilterItem.js' ),
-                       FiltersViewModel: require( './dm/FiltersViewModel.js' ),
-                       ItemModel: require( './dm/ItemModel.js' ),
-                       SavedQueriesModel: require( './dm/SavedQueriesModel.js' ),
-                       SavedQueryItemModel: require( './dm/SavedQueryItemModel.js' )
-               },
-               ui: {},
-               utils: {
-                       addArrayElementsUnique: function ( arr, elements ) {
-                               elements = Array.isArray( elements ) ? elements : [ elements ];
-
-                               elements.forEach( function ( element ) {
-                                       if ( arr.indexOf( element ) === -1 ) {
-                                               arr.push( element );
-                                       }
-                               } );
+/**
+ * @class
+ * @singleton
+ */
+mw.rcfilters = {
+       Controller: require( './Controller.js' ),
+       UriProcessor: require( './UriProcessor.js' ),
+       dm: {
+               ChangesListViewModel: require( './dm/ChangesListViewModel.js' ),
+               FilterGroup: require( './dm/FilterGroup.js' ),
+               FilterItem: require( './dm/FilterItem.js' ),
+               FiltersViewModel: require( './dm/FiltersViewModel.js' ),
+               ItemModel: require( './dm/ItemModel.js' ),
+               SavedQueriesModel: require( './dm/SavedQueriesModel.js' ),
+               SavedQueryItemModel: require( './dm/SavedQueryItemModel.js' )
+       },
+       ui: {},
+       utils: {
+               addArrayElementsUnique: function ( arr, elements ) {
+                       elements = Array.isArray( elements ) ? elements : [ elements ];
 
-                               return arr;
-                       },
-                       normalizeParamOptions: function ( givenOptions, legalOptions ) {
-                               var result = [];
-
-                               if ( givenOptions.indexOf( 'all' ) > -1 ) {
-                                       // If anywhere in the values there's 'all', we
-                                       // treat it as if only 'all' was selected.
-                                       // Example: param=valid1,valid2,all
-                                       // Result: param=all
-                                       return [ 'all' ];
+                       elements.forEach( function ( element ) {
+                               if ( arr.indexOf( element ) === -1 ) {
+                                       arr.push( element );
                                }
+                       } );
 
-                               // Get rid of any dupe and invalid parameter, only output
-                               // valid ones
-                               // Example: param=valid1,valid2,invalid1,valid1
-                               // Result: param=valid1,valid2
-                               givenOptions.forEach( function ( value ) {
-                                       if (
-                                               legalOptions.indexOf( value ) > -1 &&
-                                               result.indexOf( value ) === -1
-                                       ) {
-                                               result.push( value );
-                                       }
-                               } );
+                       return arr;
+               },
+               normalizeParamOptions: function ( givenOptions, legalOptions ) {
+                       var result = [];
 
-                               return result;
+                       if ( givenOptions.indexOf( 'all' ) > -1 ) {
+                               // If anywhere in the values there's 'all', we
+                               // treat it as if only 'all' was selected.
+                               // Example: param=valid1,valid2,all
+                               // Result: param=all
+                               return [ 'all' ];
                        }
+
+                       // Get rid of any dupe and invalid parameter, only output
+                       // valid ones
+                       // Example: param=valid1,valid2,invalid1,valid1
+                       // Result: param=valid1,valid2
+                       givenOptions.forEach( function ( value ) {
+                               if (
+                                       legalOptions.indexOf( value ) > -1 &&
+                                       result.indexOf( value ) === -1
+                               ) {
+                                       result.push( value );
+                               }
+                       } );
+
+                       return result;
                }
-       };
+       }
+};
 
-       module.exports = mw.rcfilters;
-}() );
+module.exports = mw.rcfilters;
index 9f9378a..557bb3c 100644 (file)
                        padding-right: 1.875em + 0.5em;
 
                        > .oo-ui-buttonWidget {
-                               top: 50%;
-                               .transform( translateY( -50% ) );
+                               top: 0.5em;
                        }
 
                        > .oo-ui-iconWidget {
-                               float: none;
-                               display: inline-block;
-                               margin: 0;
+                               vertical-align: top;
                        }
 
                        > .oo-ui-labelElement-label {
                                float: none;
                                display: inline-block;
+                               // Label doesn't wrap without `max-width`. First setting a pretty arbitrary percentage value.
+                               max-width: 80%;
+                               // Overwrite it with `calc` reduced by icon width and left margin combined.
+                               max-width: calc( ~'100% - 1.42857143em - 0.25em' );
+                               margin: 0 0 0 0.25em;
                                font-size: 1.2em;
-                               margin: 0;
                                font-weight: bold;
-                               vertical-align: middle;
+                               line-height: 1.25;
+                               vertical-align: top;
                        }
                }
        }
index 23b05e8..ac5bbae 100644 (file)
-( function () {
-       var ChangesLimitPopupWidget = require( './ChangesLimitPopupWidget.js' ),
-               DatePopupWidget = require( './DatePopupWidget.js' ),
-               ChangesLimitAndDateButtonWidget;
-
-       /**
-        * Widget defining the button controlling the popup for the number of results
-        *
-        * @class mw.rcfilters.ui.ChangesLimitAndDateButtonWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
-        * @param {Object} [config] Configuration object
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        */
-       ChangesLimitAndDateButtonWidget = function MwRcfiltersUiChangesLimitWidget( controller, model, config ) {
-               config = config || {};
-
-               // Parent
-               ChangesLimitAndDateButtonWidget.parent.call( this, config );
-
-               this.controller = controller;
-               this.model = model;
-
-               this.$overlay = config.$overlay || this.$element;
-
-               this.button = null;
-               this.limitGroupModel = null;
-               this.groupByPageItemModel = null;
-               this.daysGroupModel = null;
-
-               this.model.connect( this, {
-                       initialize: 'onModelInitialize'
+var ChangesLimitPopupWidget = require( './ChangesLimitPopupWidget.js' ),
+       DatePopupWidget = require( './DatePopupWidget.js' ),
+       ChangesLimitAndDateButtonWidget;
+
+/**
+ * Widget defining the button controlling the popup for the number of results
+ *
+ * @class mw.rcfilters.ui.ChangesLimitAndDateButtonWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {Object} [config] Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ */
+ChangesLimitAndDateButtonWidget = function MwRcfiltersUiChangesLimitWidget( controller, model, config ) {
+       config = config || {};
+
+       // Parent
+       ChangesLimitAndDateButtonWidget.parent.call( this, config );
+
+       this.controller = controller;
+       this.model = model;
+
+       this.$overlay = config.$overlay || this.$element;
+
+       this.button = null;
+       this.limitGroupModel = null;
+       this.groupByPageItemModel = null;
+       this.daysGroupModel = null;
+
+       this.model.connect( this, {
+               initialize: 'onModelInitialize'
+       } );
+
+       this.$element
+               .addClass( 'mw-rcfilters-ui-changesLimitAndDateButtonWidget' );
+};
+
+/* Initialization */
+
+OO.inheritClass( ChangesLimitAndDateButtonWidget, OO.ui.Widget );
+
+/**
+ * Respond to model initialize event
+ */
+ChangesLimitAndDateButtonWidget.prototype.onModelInitialize = function () {
+       var changesLimitPopupWidget, selectedItem, currentValue, datePopupWidget,
+               displayGroupModel = this.model.getGroup( 'display' );
+
+       this.limitGroupModel = this.model.getGroup( 'limit' );
+       this.groupByPageItemModel = displayGroupModel.getItemByParamName( 'enhanced' );
+       this.daysGroupModel = this.model.getGroup( 'days' );
+
+       // HACK: We need the model to be ready before we populate the button
+       // and the widget, because we require the filter items for the
+       // limit and their events. This addition is only done after the
+       // model is initialized.
+       // Note: This will be fixed soon!
+       if ( this.limitGroupModel && this.daysGroupModel ) {
+               changesLimitPopupWidget = new ChangesLimitPopupWidget(
+                       this.limitGroupModel,
+                       this.groupByPageItemModel
+               );
+
+               datePopupWidget = new DatePopupWidget(
+                       this.daysGroupModel,
+                       {
+                               label: mw.msg( 'rcfilters-date-popup-title' )
+                       }
+               );
+
+               selectedItem = this.limitGroupModel.findSelectedItems()[ 0 ];
+               currentValue = ( selectedItem && selectedItem.getLabel() ) ||
+                       mw.language.convertNumber( this.limitGroupModel.getDefaultParamValue() );
+
+               this.button = new OO.ui.PopupButtonWidget( {
+                       icon: 'settings',
+                       indicator: 'down',
+                       label: mw.msg( 'rcfilters-limit-and-date-label', currentValue ),
+                       $overlay: this.$overlay,
+                       popup: {
+                               width: 300,
+                               padded: false,
+                               anchor: false,
+                               align: 'backwards',
+                               $autoCloseIgnore: this.$overlay,
+                               $content: $( '<div>' ).append(
+                                       // TODO: Merge ChangesLimitPopupWidget with DatePopupWidget into one common widget
+                                       changesLimitPopupWidget.$element,
+                                       datePopupWidget.$element
+                               )
+                       }
                } );
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-changesLimitAndDateButtonWidget' );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( ChangesLimitAndDateButtonWidget, OO.ui.Widget );
-
-       /**
-        * Respond to model initialize event
-        */
-       ChangesLimitAndDateButtonWidget.prototype.onModelInitialize = function () {
-               var changesLimitPopupWidget, selectedItem, currentValue, datePopupWidget,
-                       displayGroupModel = this.model.getGroup( 'display' );
-
-               this.limitGroupModel = this.model.getGroup( 'limit' );
-               this.groupByPageItemModel = displayGroupModel.getItemByParamName( 'enhanced' );
-               this.daysGroupModel = this.model.getGroup( 'days' );
-
-               // HACK: We need the model to be ready before we populate the button
-               // and the widget, because we require the filter items for the
-               // limit and their events. This addition is only done after the
-               // model is initialized.
-               // Note: This will be fixed soon!
-               if ( this.limitGroupModel && this.daysGroupModel ) {
-                       changesLimitPopupWidget = new ChangesLimitPopupWidget(
-                               this.limitGroupModel,
-                               this.groupByPageItemModel
-                       );
-
-                       datePopupWidget = new DatePopupWidget(
-                               this.daysGroupModel,
-                               {
-                                       label: mw.msg( 'rcfilters-date-popup-title' )
-                               }
-                       );
-
-                       selectedItem = this.limitGroupModel.findSelectedItems()[ 0 ];
-                       currentValue = ( selectedItem && selectedItem.getLabel() ) ||
-                               mw.language.convertNumber( this.limitGroupModel.getDefaultParamValue() );
-
-                       this.button = new OO.ui.PopupButtonWidget( {
-                               icon: 'settings',
-                               indicator: 'down',
-                               label: mw.msg( 'rcfilters-limit-and-date-label', currentValue ),
-                               $overlay: this.$overlay,
-                               popup: {
-                                       width: 300,
-                                       padded: false,
-                                       anchor: false,
-                                       align: 'backwards',
-                                       $autoCloseIgnore: this.$overlay,
-                                       $content: $( '<div>' ).append(
-                                               // TODO: Merge ChangesLimitPopupWidget with DatePopupWidget into one common widget
-                                               changesLimitPopupWidget.$element,
-                                               datePopupWidget.$element
-                                       )
-                               }
-                       } );
-                       this.updateButtonLabel();
-
-                       // Events
-                       this.limitGroupModel.connect( this, { update: 'updateButtonLabel' } );
-                       this.daysGroupModel.connect( this, { update: 'updateButtonLabel' } );
-                       changesLimitPopupWidget.connect( this, {
-                               limit: 'onPopupLimit',
-                               groupByPage: 'onPopupGroupByPage'
-                       } );
-                       datePopupWidget.connect( this, { days: 'onPopupDays' } );
-
-                       this.$element.append( this.button.$element );
-               }
-       };
-
-       /**
-        * Respond to popup limit change event
-        *
-        * @param {string} filterName Chosen filter name
-        */
-       ChangesLimitAndDateButtonWidget.prototype.onPopupLimit = function ( filterName ) {
-               var item = this.limitGroupModel.getItemByName( filterName );
-
-               this.controller.toggleFilterSelect( filterName, true );
-               this.controller.updateLimitDefault( item.getParamName() );
-               this.button.popup.toggle( false );
-       };
-
-       /**
-        * Respond to popup limit change event
-        *
-        * @param {boolean} isGrouped The result set is grouped by page
-        */
-       ChangesLimitAndDateButtonWidget.prototype.onPopupGroupByPage = function ( isGrouped ) {
-               this.controller.toggleFilterSelect( this.groupByPageItemModel.getName(), isGrouped );
-               this.controller.updateGroupByPageDefault( isGrouped );
-               this.button.popup.toggle( false );
-       };
-
-       /**
-        * Respond to popup limit change event
-        *
-        * @param {string} filterName Chosen filter name
-        */
-       ChangesLimitAndDateButtonWidget.prototype.onPopupDays = function ( filterName ) {
-               var item = this.daysGroupModel.getItemByName( filterName );
-
-               this.controller.toggleFilterSelect( filterName, true );
-               this.controller.updateDaysDefault( item.getParamName() );
-               this.button.popup.toggle( false );
-       };
-
-       /**
-        * Respond to limit choose event
-        *
-        * @param {string} filterName Filter name
-        */
-       ChangesLimitAndDateButtonWidget.prototype.updateButtonLabel = function () {
-               var message,
-                       limit = this.limitGroupModel.findSelectedItems()[ 0 ],
-                       label = limit && limit.getLabel(),
-                       days = this.daysGroupModel.findSelectedItems()[ 0 ],
-                       daysParamName = Number( days.getParamName() ) < 1 ?
-                               'rcfilters-days-show-hours' :
-                               'rcfilters-days-show-days';
-
-               // Update the label
-               if ( label && days ) {
-                       message = mw.msg( 'rcfilters-limit-and-date-label', label,
-                               mw.msg( daysParamName, days.getLabel() )
-                       );
-                       this.button.setLabel( message );
-               }
-       };
-
-       module.exports = ChangesLimitAndDateButtonWidget;
-
-}() );
+               this.updateButtonLabel();
+
+               // Events
+               this.limitGroupModel.connect( this, { update: 'updateButtonLabel' } );
+               this.daysGroupModel.connect( this, { update: 'updateButtonLabel' } );
+               changesLimitPopupWidget.connect( this, {
+                       limit: 'onPopupLimit',
+                       groupByPage: 'onPopupGroupByPage'
+               } );
+               datePopupWidget.connect( this, { days: 'onPopupDays' } );
+
+               this.$element.append( this.button.$element );
+       }
+};
+
+/**
+ * Respond to popup limit change event
+ *
+ * @param {string} filterName Chosen filter name
+ */
+ChangesLimitAndDateButtonWidget.prototype.onPopupLimit = function ( filterName ) {
+       var item = this.limitGroupModel.getItemByName( filterName );
+
+       this.controller.toggleFilterSelect( filterName, true );
+       this.controller.updateLimitDefault( item.getParamName() );
+       this.button.popup.toggle( false );
+};
+
+/**
+ * Respond to popup limit change event
+ *
+ * @param {boolean} isGrouped The result set is grouped by page
+ */
+ChangesLimitAndDateButtonWidget.prototype.onPopupGroupByPage = function ( isGrouped ) {
+       this.controller.toggleFilterSelect( this.groupByPageItemModel.getName(), isGrouped );
+       this.controller.updateGroupByPageDefault( isGrouped );
+       this.button.popup.toggle( false );
+};
+
+/**
+ * Respond to popup limit change event
+ *
+ * @param {string} filterName Chosen filter name
+ */
+ChangesLimitAndDateButtonWidget.prototype.onPopupDays = function ( filterName ) {
+       var item = this.daysGroupModel.getItemByName( filterName );
+
+       this.controller.toggleFilterSelect( filterName, true );
+       this.controller.updateDaysDefault( item.getParamName() );
+       this.button.popup.toggle( false );
+};
+
+/**
+ * Respond to limit choose event
+ */
+ChangesLimitAndDateButtonWidget.prototype.updateButtonLabel = function () {
+       var message,
+               limit = this.limitGroupModel.findSelectedItems()[ 0 ],
+               label = limit && limit.getLabel(),
+               days = this.daysGroupModel.findSelectedItems()[ 0 ],
+               daysParamName = Number( days.getParamName() ) < 1 ?
+                       'rcfilters-days-show-hours' :
+                       'rcfilters-days-show-days';
+
+       // Update the label
+       if ( label && days ) {
+               message = mw.msg( 'rcfilters-limit-and-date-label', label,
+                       mw.msg( daysParamName, days.getLabel() )
+               );
+               this.button.setLabel( message );
+       }
+};
+
+module.exports = ChangesLimitAndDateButtonWidget;
index d78c42b..a0c0d80 100644 (file)
@@ -1,84 +1,82 @@
-( function () {
-       var ValuePickerWidget = require( './ValuePickerWidget.js' ),
-               ChangesLimitPopupWidget;
+var ValuePickerWidget = require( './ValuePickerWidget.js' ),
+       ChangesLimitPopupWidget;
 
-       /**
       * Widget defining the popup to choose number of results
       *
       * @class mw.rcfilters.ui.ChangesLimitPopupWidget
       * @extends OO.ui.Widget
       *
       * @constructor
       * @param {mw.rcfilters.dm.FilterGroup} limitModel Group model for 'limit'
       * @param {mw.rcfilters.dm.FilterItem} groupByPageItemModel Group model for 'limit'
       * @param {Object} [config] Configuration object
       */
-       ChangesLimitPopupWidget = function MwRcfiltersUiChangesLimitPopupWidget( limitModel, groupByPageItemModel, config ) {
-               config = config || {};
+/**
+ * Widget defining the popup to choose number of results
+ *
+ * @class mw.rcfilters.ui.ChangesLimitPopupWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.FilterGroup} limitModel Group model for 'limit'
+ * @param {mw.rcfilters.dm.FilterItem} groupByPageItemModel Group model for 'limit'
+ * @param {Object} [config] Configuration object
+ */
+ChangesLimitPopupWidget = function MwRcfiltersUiChangesLimitPopupWidget( limitModel, groupByPageItemModel, config ) {
+       config = config || {};
 
-               // Parent
-               ChangesLimitPopupWidget.parent.call( this, config );
+       // Parent
+       ChangesLimitPopupWidget.parent.call( this, config );
 
-               this.limitModel = limitModel;
-               this.groupByPageItemModel = groupByPageItemModel;
+       this.limitModel = limitModel;
+       this.groupByPageItemModel = groupByPageItemModel;
 
-               this.valuePicker = new ValuePickerWidget(
-                       this.limitModel,
-                       {
-                               label: mw.msg( 'rcfilters-limit-title' )
-                       }
-               );
+       this.valuePicker = new ValuePickerWidget(
+               this.limitModel,
+               {
+                       label: mw.msg( 'rcfilters-limit-title' )
+               }
+       );
 
-               this.groupByPageCheckbox = new OO.ui.CheckboxInputWidget( {
-                       selected: this.groupByPageItemModel.isSelected()
-               } );
+       this.groupByPageCheckbox = new OO.ui.CheckboxInputWidget( {
+               selected: this.groupByPageItemModel.isSelected()
+       } );
 
-               // Events
-               this.valuePicker.connect( this, { choose: [ 'emit', 'limit' ] } );
-               this.groupByPageCheckbox.connect( this, { change: [ 'emit', 'groupByPage' ] } );
-               this.groupByPageItemModel.connect( this, { update: 'onGroupByPageModelUpdate' } );
+       // Events
+       this.valuePicker.connect( this, { choose: [ 'emit', 'limit' ] } );
+       this.groupByPageCheckbox.connect( this, { change: [ 'emit', 'groupByPage' ] } );
+       this.groupByPageItemModel.connect( this, { update: 'onGroupByPageModelUpdate' } );
 
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-changesLimitPopupWidget' )
-                       .append(
-                               this.valuePicker.$element,
-                               new OO.ui.FieldLayout(
-                                       this.groupByPageCheckbox,
-                                       {
-                                               align: 'inline',
-                                               label: mw.msg( 'rcfilters-group-results-by-page' )
-                                       }
-                               ).$element
-                       );
-       };
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-changesLimitPopupWidget' )
+               .append(
+                       this.valuePicker.$element,
+                       new OO.ui.FieldLayout(
+                               this.groupByPageCheckbox,
+                               {
+                                       align: 'inline',
+                                       label: mw.msg( 'rcfilters-group-results-by-page' )
+                               }
+                       ).$element
+               );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( ChangesLimitPopupWidget, OO.ui.Widget );
+OO.inheritClass( ChangesLimitPopupWidget, OO.ui.Widget );
 
-       /* Events */
+/* Events */
 
-       /**
       * @event limit
       * @param {string} name Item name
       *
       * A limit item was chosen
       */
+/**
+ * @event limit
+ * @param {string} name Item name
+ *
+ * A limit item was chosen
+ */
 
-       /**
       * @event groupByPage
       * @param {boolean} isGrouped The results are grouped by page
       *
       * Results are grouped by page
       */
+/**
+ * @event groupByPage
+ * @param {boolean} isGrouped The results are grouped by page
+ *
+ * Results are grouped by page
+ */
 
-       /**
       * Respond to group by page model update
       */
-       ChangesLimitPopupWidget.prototype.onGroupByPageModelUpdate = function () {
-               this.groupByPageCheckbox.setSelected( this.groupByPageItemModel.isSelected() );
-       };
+/**
+ * Respond to group by page model update
+ */
+ChangesLimitPopupWidget.prototype.onGroupByPageModelUpdate = function () {
+       this.groupByPageCheckbox.setSelected( this.groupByPageItemModel.isSelected() );
+};
 
-       module.exports = ChangesLimitPopupWidget;
-}() );
+module.exports = ChangesLimitPopupWidget;
index ba7f4d1..78cd8f4 100644 (file)
-( function () {
-       /**
-        * List of changes
-        *
-        * @class mw.rcfilters.ui.ChangesListWrapperWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel View model
-        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListViewModel View model
-        * @param {mw.rcfilters.Controller} controller
-        * @param {jQuery} $changesListRoot Root element of the changes list to attach to
-        * @param {Object} [config] Configuration object
-        */
-       var ChangesListWrapperWidget = function MwRcfiltersUiChangesListWrapperWidget(
-               filtersViewModel,
-               changesListViewModel,
-               controller,
-               $changesListRoot,
-               config
-       ) {
-               config = $.extend( {}, config, {
-                       $element: $changesListRoot
-               } );
-
-               // Parent
-               ChangesListWrapperWidget.parent.call( this, config );
-
-               this.filtersViewModel = filtersViewModel;
-               this.changesListViewModel = changesListViewModel;
-               this.controller = controller;
-               this.highlightClasses = null;
-
-               // Events
-               this.filtersViewModel.connect( this, {
-                       itemUpdate: 'onItemUpdate',
-                       highlightChange: 'onHighlightChange'
-               } );
-               this.changesListViewModel.connect( this, {
-                       invalidate: 'onModelInvalidate',
-                       update: 'onModelUpdate'
-               } );
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget' )
-                       // We handle our own display/hide of the empty results message
-                       // We keep the timeout class here and remove it later, since at this
-                       // stage it is still needed to identify that the timeout occurred.
-                       .removeClass( 'mw-changeslist-empty' );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( ChangesListWrapperWidget, OO.ui.Widget );
-
-       /**
-        * Get all available highlight classes
-        *
-        * @return {string[]} An array of available highlight class names
-        */
-       ChangesListWrapperWidget.prototype.getHighlightClasses = function () {
-               if ( !this.highlightClasses || !this.highlightClasses.length ) {
-                       this.highlightClasses = this.filtersViewModel.getItemsSupportingHighlights()
-                               .map( function ( filterItem ) {
-                                       return filterItem.getCssClass();
-                               } );
-               }
-
-               return this.highlightClasses;
-       };
-
-       /**
-        * Respond to the highlight feature being toggled on and off
-        *
-        * @param {boolean} highlightEnabled
-        */
-       ChangesListWrapperWidget.prototype.onHighlightChange = function ( highlightEnabled ) {
-               if ( highlightEnabled ) {
-                       this.applyHighlight();
+/**
+ * List of changes
+ *
+ * @class mw.rcfilters.ui.ChangesListWrapperWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel View model
+ * @param {mw.rcfilters.dm.ChangesListViewModel} changesListViewModel View model
+ * @param {mw.rcfilters.Controller} controller
+ * @param {jQuery} $changesListRoot Root element of the changes list to attach to
+ * @param {Object} [config] Configuration object
+ */
+var ChangesListWrapperWidget = function MwRcfiltersUiChangesListWrapperWidget(
+       filtersViewModel,
+       changesListViewModel,
+       controller,
+       $changesListRoot,
+       config
+) {
+       config = $.extend( {}, config, {
+               $element: $changesListRoot
+       } );
+
+       // Parent
+       ChangesListWrapperWidget.parent.call( this, config );
+
+       this.filtersViewModel = filtersViewModel;
+       this.changesListViewModel = changesListViewModel;
+       this.controller = controller;
+
+       // Events
+       this.filtersViewModel.connect( this, {
+               itemUpdate: 'onItemUpdate',
+               highlightChange: 'onHighlightChange'
+       } );
+       this.changesListViewModel.connect( this, {
+               invalidate: 'onModelInvalidate',
+               update: 'onModelUpdate'
+       } );
+
+       this.$element
+               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget' )
+               // We handle our own display/hide of the empty results message
+               // We keep the timeout class here and remove it later, since at this
+               // stage it is still needed to identify that the timeout occurred.
+               .removeClass( 'mw-changeslist-empty' );
+};
+
+/* Initialization */
+
+OO.inheritClass( ChangesListWrapperWidget, OO.ui.Widget );
+
+/**
+ * Respond to the highlight feature being toggled on and off
+ *
+ * @param {boolean} highlightEnabled
+ */
+ChangesListWrapperWidget.prototype.onHighlightChange = function ( highlightEnabled ) {
+       if ( highlightEnabled ) {
+               this.applyHighlight();
+       } else {
+               this.clearHighlight();
+       }
+};
+
+/**
+ * Respond to a filter item model update
+ */
+ChangesListWrapperWidget.prototype.onItemUpdate = function () {
+       if ( this.controller.isInitialized() && this.filtersViewModel.isHighlightEnabled() ) {
+               // this.controller.isInitialized() is still false during page load,
+               // we don't want to clear/apply highlights at this stage.
+               this.clearHighlight();
+               this.applyHighlight();
+       }
+};
+
+/**
+ * Respond to changes list model invalidate
+ */
+ChangesListWrapperWidget.prototype.onModelInvalidate = function () {
+       $( 'body' ).addClass( 'mw-rcfilters-ui-loading' );
+};
+
+/**
+ * Respond to changes list model update
+ *
+ * @param {jQuery|string} $changesListContent The content of the updated changes list
+ * @param {jQuery} $fieldset The content of the updated fieldset
+ * @param {string} noResultsDetails Type of no result error
+ * @param {boolean} isInitialDOM Whether $changesListContent is the existing (already attached) DOM
+ * @param {boolean} from Timestamp of the new changes
+ */
+ChangesListWrapperWidget.prototype.onModelUpdate = function (
+       $changesListContent, $fieldset, noResultsDetails, isInitialDOM, from
+) {
+       var conflictItem,
+               $message = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results' ),
+               isEmpty = $changesListContent === 'NO_RESULTS',
+               // For enhanced mode, we have to load these modules, which are
+               // not loaded for the 'regular' mode in the backend
+               loaderPromise = mw.user.options.get( 'usenewrc' ) ?
+                       mw.loader.using( [ 'mediawiki.special.changeslist.enhanced', 'mediawiki.icon' ] ) :
+                       $.Deferred().resolve(),
+               widget = this;
+
+       this.$element.toggleClass( 'mw-changeslist', !isEmpty );
+       if ( isEmpty ) {
+               this.$element.empty();
+
+               if ( this.filtersViewModel.hasConflict() ) {
+                       conflictItem = this.filtersViewModel.getFirstConflictedItem();
+
+                       $message
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results-conflict' )
+                                               .text( mw.message( 'rcfilters-noresults-conflict' ).text() ),
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results-message' )
+                                               .text( mw.message( conflictItem.getCurrentConflictResultMessage() ).text() )
+                               );
                } else {
-                       this.clearHighlight();
-               }
-       };
+                       $message
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results-noresult' )
+                                               .text( mw.msg( this.getMsgKeyForNoResults( noResultsDetails ) ) )
+                               );
 
-       /**
-        * Respond to a filter item model update
-        */
-       ChangesListWrapperWidget.prototype.onItemUpdate = function () {
-               if ( this.controller.isInitialized() && this.filtersViewModel.isHighlightEnabled() ) {
-                       // this.controller.isInitialized() is still false during page load,
-                       // we don't want to clear/apply highlights at this stage.
-                       this.clearHighlight();
-                       this.applyHighlight();
+                       // remove all classes matching mw-changeslist-*
+                       this.$element.removeClass( function ( elementIndex, allClasses ) {
+                               return allClasses
+                                       .split( ' ' )
+                                       .filter( function ( className ) {
+                                               return className.indexOf( 'mw-changeslist-' ) === 0;
+                                       } )
+                                       .join( ' ' );
+                       );
                }
-       };
 
-       /**
-        * Respond to changes list model invalidate
-        */
-       ChangesListWrapperWidget.prototype.onModelInvalidate = function () {
-               $( 'body' ).addClass( 'mw-rcfilters-ui-loading' );
-       };
+               this.$element.append( $message );
+       } else {
+               if ( !isInitialDOM ) {
+                       this.$element.empty().append( $changesListContent );
 
-       /**
-        * Respond to changes list model update
-        *
-        * @param {jQuery|string} $changesListContent The content of the updated changes list
-        * @param {jQuery} $fieldset The content of the updated fieldset
-        * @param {string} noResultsDetails Type of no result error
-        * @param {boolean} isInitialDOM Whether $changesListContent is the existing (already attached) DOM
-        * @param {boolean} from Timestamp of the new changes
-        */
-       ChangesListWrapperWidget.prototype.onModelUpdate = function (
-               $changesListContent, $fieldset, noResultsDetails, isInitialDOM, from
-       ) {
-               var conflictItem,
-                       $message = $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results' ),
-                       isEmpty = $changesListContent === 'NO_RESULTS',
-                       // For enhanced mode, we have to load these modules, which are
-                       // not loaded for the 'regular' mode in the backend
-                       loaderPromise = mw.user.options.get( 'usenewrc' ) ?
-                               mw.loader.using( [ 'mediawiki.special.changeslist.enhanced', 'mediawiki.icon' ] ) :
-                               $.Deferred().resolve(),
-                       widget = this;
-
-               this.$element.toggleClass( 'mw-changeslist', !isEmpty );
-               if ( isEmpty ) {
-                       this.$element.empty();
-
-                       if ( this.filtersViewModel.hasConflict() ) {
-                               conflictItem = this.filtersViewModel.getFirstConflictedItem();
-
-                               $message
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results-conflict' )
-                                                       .text( mw.message( 'rcfilters-noresults-conflict' ).text() ),
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results-message' )
-                                                       .text( mw.message( conflictItem.getCurrentConflictResultMessage() ).text() )
-                                       );
-                       } else {
-                               $message
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-results-noresult' )
-                                                       .text( mw.msg( this.getMsgKeyForNoResults( noResultsDetails ) ) )
-                                       );
-
-                               // remove all classes matching mw-changeslist-*
-                               this.$element.removeClass( function ( elementIndex, allClasses ) {
-                                       return allClasses
-                                               .split( ' ' )
-                                               .filter( function ( className ) {
-                                                       return className.indexOf( 'mw-changeslist-' ) === 0;
-                                               } )
-                                               .join( ' ' );
-                               } );
+                       if ( from ) {
+                               this.emphasizeNewChanges( from );
                        }
-
-                       this.$element.append( $message );
-               } else {
-                       if ( !isInitialDOM ) {
-                               this.$element.empty().append( $changesListContent );
-
-                               if ( from ) {
-                                       this.emphasizeNewChanges( from );
-                               }
-                       }
-
-                       // Apply highlight
-                       this.applyHighlight();
-
                }
 
-               this.$element.prepend( $( '<div>' ).addClass( 'mw-changeslist-overlay' ) );
+               // Apply highlight
+               this.applyHighlight();
 
-               loaderPromise.done( function () {
-                       if ( !isInitialDOM && !isEmpty ) {
-                               // Make sure enhanced RC re-initializes correctly
-                               mw.hook( 'wikipage.content' ).fire( widget.$element );
-                       }
+       }
 
-                       $( 'body' ).removeClass( 'mw-rcfilters-ui-loading' );
-               } );
-       };
+       this.$element.prepend( $( '<div>' ).addClass( 'mw-changeslist-overlay' ) );
 
-       /** Toggles overlay class on changes list
-        *
-        * @param {boolean} isVisible True if overlay should be visible
-        */
-       ChangesListWrapperWidget.prototype.toggleOverlay = function ( isVisible ) {
-               this.$element.toggleClass( 'mw-rcfilters-ui-changesListWrapperWidget--overlaid', isVisible );
-       };
+       loaderPromise.done( function () {
+               if ( !isInitialDOM && !isEmpty ) {
+                       // Make sure enhanced RC re-initializes correctly
+                       mw.hook( 'wikipage.content' ).fire( widget.$element );
+               }
 
-       /**
-        * Map a reason for having no results to its message key
-        *
-        * @param {string} reason One of the NO_RESULTS_* "constant" that represent
-        *   a reason for having no results
-        * @return {string} Key for the message that explains why there is no results in this case
-        */
-       ChangesListWrapperWidget.prototype.getMsgKeyForNoResults = function ( reason ) {
-               var reasonMsgKeyMap = {
-                       NO_RESULTS_NORMAL: 'recentchanges-noresult',
-                       NO_RESULTS_TIMEOUT: 'recentchanges-timeout',
-                       NO_RESULTS_NETWORK_ERROR: 'recentchanges-network',
-                       NO_RESULTS_NO_TARGET_PAGE: 'recentchanges-notargetpage',
-                       NO_RESULTS_INVALID_TARGET_PAGE: 'allpagesbadtitle'
-               };
-               return reasonMsgKeyMap[ reason ];
+               $( 'body' ).removeClass( 'mw-rcfilters-ui-loading' );
+       } );
+};
+
+/** Toggles overlay class on changes list
+ *
+ * @param {boolean} isVisible True if overlay should be visible
+ */
+ChangesListWrapperWidget.prototype.toggleOverlay = function ( isVisible ) {
+       this.$element.toggleClass( 'mw-rcfilters-ui-changesListWrapperWidget--overlaid', isVisible );
+};
+
+/**
+ * Map a reason for having no results to its message key
+ *
+ * @param {string} reason One of the NO_RESULTS_* "constant" that represent
+ *   a reason for having no results
+ * @return {string} Key for the message that explains why there is no results in this case
+ */
+ChangesListWrapperWidget.prototype.getMsgKeyForNoResults = function ( reason ) {
+       var reasonMsgKeyMap = {
+               NO_RESULTS_NORMAL: 'recentchanges-noresult',
+               NO_RESULTS_TIMEOUT: 'recentchanges-timeout',
+               NO_RESULTS_NETWORK_ERROR: 'recentchanges-network',
+               NO_RESULTS_NO_TARGET_PAGE: 'recentchanges-notargetpage',
+               NO_RESULTS_INVALID_TARGET_PAGE: 'allpagesbadtitle'
        };
-
-       /**
-        * Emphasize the elements (or groups) newer than the 'from' parameter
-        * @param {string} from Anything newer than this is considered 'new'
-        */
-       ChangesListWrapperWidget.prototype.emphasizeNewChanges = function ( from ) {
-               var $firstNew,
-                       $indicator,
-                       $newChanges = $( [] ),
-                       selector = this.inEnhancedMode() ?
-                               'table.mw-enhanced-rc[data-mw-ts]' :
-                               'li[data-mw-ts]',
-                       set = this.$element.find( selector ),
-                       length = set.length;
-
-               set.each( function ( index ) {
-                       var $this = $( this ),
-                               ts = $this.data( 'mw-ts' );
-
-                       if ( ts >= from ) {
-                               $newChanges = $newChanges.add( $this );
-                               $firstNew = $this;
-
-                               // guards against putting the marker after the last element
-                               if ( index === ( length - 1 ) ) {
-                                       $firstNew = null;
-                               }
+       return reasonMsgKeyMap[ reason ];
+};
+
+/**
+ * Emphasize the elements (or groups) newer than the 'from' parameter
+ * @param {string} from Anything newer than this is considered 'new'
+ */
+ChangesListWrapperWidget.prototype.emphasizeNewChanges = function ( from ) {
+       var $firstNew,
+               $indicator,
+               $newChanges = $( [] ),
+               selector = this.inEnhancedMode() ?
+                       'table.mw-enhanced-rc[data-mw-ts]' :
+                       'li[data-mw-ts]',
+               set = this.$element.find( selector ),
+               length = set.length;
+
+       set.each( function ( index ) {
+               var $this = $( this ),
+                       ts = $this.data( 'mw-ts' );
+
+               if ( ts >= from ) {
+                       $newChanges = $newChanges.add( $this );
+                       $firstNew = $this;
+
+                       // guards against putting the marker after the last element
+                       if ( index === ( length - 1 ) ) {
+                               $firstNew = null;
                        }
-               } );
-
-               if ( $firstNew ) {
-                       $indicator = $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-previousChangesIndicator' );
-
-                       $firstNew.after( $indicator );
                }
-
-               // FIXME: Use CSS transition
-               // eslint-disable-next-line no-jquery/no-fade
-               $newChanges
-                       .hide()
-                       .fadeIn( 1000 );
-       };
-
-       /**
-        * In enhanced mode, we need to check whether the grouped results all have the
-        * same active highlights in order to see whether the "parent" of the group should
-        * be grey or highlighted normally.
-        *
-        * This is called every time highlights are applied.
-        */
-       ChangesListWrapperWidget.prototype.updateEnhancedParentHighlight = function () {
-               var activeHighlightClasses,
-                       $enhancedTopPageCell = this.$element.find( 'table.mw-enhanced-rc.mw-collapsible' );
-
-               activeHighlightClasses = this.filtersViewModel.getCurrentlyUsedHighlightColors().map( function ( color ) {
-                       return 'mw-rcfilters-highlight-color-' + color;
+       } );
+
+       if ( $firstNew ) {
+               $indicator = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-previousChangesIndicator' );
+
+               $firstNew.after( $indicator );
+       }
+
+       // FIXME: Use CSS transition
+       // eslint-disable-next-line no-jquery/no-fade
+       $newChanges
+               .hide()
+               .fadeIn( 1000 );
+};
+
+/**
+ * In enhanced mode, we need to check whether the grouped results all have the
+ * same active highlights in order to see whether the "parent" of the group should
+ * be grey or highlighted normally.
+ *
+ * This is called every time highlights are applied.
+ */
+ChangesListWrapperWidget.prototype.updateEnhancedParentHighlight = function () {
+       var activeHighlightClasses,
+               $enhancedTopPageCell = this.$element.find( 'table.mw-enhanced-rc.mw-collapsible' );
+
+       activeHighlightClasses = this.filtersViewModel.getCurrentlyUsedHighlightColors().map( function ( color ) {
+               return 'mw-rcfilters-highlight-color-' + color;
+       } );
+
+       // Go over top pages and their children, and figure out if all sub-pages have the
+       // same highlights between themselves. If they do, the parent should be highlighted
+       // with all colors. If classes are different, the parent should receive a grey
+       // background
+       $enhancedTopPageCell.each( function () {
+               var firstChildClasses, $rowsWithDifferentHighlights,
+                       $table = $( this );
+
+               // Collect the relevant classes from the first nested child
+               firstChildClasses = activeHighlightClasses.filter( function ( className ) {
+                       return $table.find( 'tr:nth-child(2)' ).hasClass( className );
                } );
-
-               // Go over top pages and their children, and figure out if all sub-pages have the
-               // same highlights between themselves. If they do, the parent should be highlighted
-               // with all colors. If classes are different, the parent should receive a grey
-               // background
-               $enhancedTopPageCell.each( function () {
-                       var firstChildClasses, $rowsWithDifferentHighlights,
-                               $table = $( this );
-
-                       // Collect the relevant classes from the first nested child
-                       firstChildClasses = activeHighlightClasses.filter( function ( className ) {
-                               return $table.find( 'tr:nth-child(2)' ).hasClass( className );
+               // Filter the non-head rows and see if they all have the same classes
+               // to the first row
+               $rowsWithDifferentHighlights = $table.find( 'tr:not(:first-child)' ).filter( function () {
+                       var classesInThisRow,
+                               $this = $( this );
+
+                       classesInThisRow = activeHighlightClasses.filter( function ( className ) {
+                               return $this.hasClass( className );
                        } );
-                       // Filter the non-head rows and see if they all have the same classes
-                       // to the first row
-                       $rowsWithDifferentHighlights = $table.find( 'tr:not(:first-child)' ).filter( function () {
-                               var classesInThisRow,
-                                       $this = $( this );
 
-                               classesInThisRow = activeHighlightClasses.filter( function ( className ) {
-                                       return $this.hasClass( className );
-                               } );
-
-                               return !OO.compare( firstChildClasses, classesInThisRow );
-                       } );
-
-                       // If classes are different, tag the row for using grey color
-                       $table.find( 'tr:first-child' )
-                               .toggleClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey', $rowsWithDifferentHighlights.length > 0 );
+                       return !OO.compare( firstChildClasses, classesInThisRow );
                } );
-       };
-
-       /**
-        * @return {boolean} Whether the changes are grouped by page
-        */
-       ChangesListWrapperWidget.prototype.inEnhancedMode = function () {
-               var uri = new mw.Uri();
-               return ( uri.query.enhanced !== undefined && Number( uri.query.enhanced ) ) ||
-                       ( uri.query.enhanced === undefined && Number( mw.user.options.get( 'usenewrc' ) ) );
-       };
-
-       /**
-        * Apply color classes based on filters highlight configuration
-        */
-       ChangesListWrapperWidget.prototype.applyHighlight = function () {
-               if ( !this.filtersViewModel.isHighlightEnabled() ) {
-                       return;
-               }
-
-               this.filtersViewModel.getHighlightedItems().forEach( function ( filterItem ) {
-                       var $elements = this.$element.find( '.' + filterItem.getCssClass() );
 
-                       // Add highlight class to all highlighted list items
-                       $elements
-                               .addClass(
-                                       'mw-rcfilters-highlighted ' +
-                                       'mw-rcfilters-highlight-color-' + filterItem.getHighlightColor()
-                               );
-
-                       // Track the filters for each item in .data( 'highlightedFilters' )
-                       $elements.each( function () {
-                               var filters = $( this ).data( 'highlightedFilters' );
-                               if ( !filters ) {
-                                       filters = [];
-                                       $( this ).data( 'highlightedFilters', filters );
-                               }
-                               if ( filters.indexOf( filterItem.getLabel() ) === -1 ) {
-                                       filters.push( filterItem.getLabel() );
-                               }
-                       } );
-               }.bind( this ) );
-               // Apply a title to each highlighted item, with a list of filters
-               this.$element.find( '.mw-rcfilters-highlighted' ).each( function () {
+               // If classes are different, tag the row for using grey color
+               $table.find( 'tr:first-child' )
+                       .toggleClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey', $rowsWithDifferentHighlights.length > 0 );
+       } );
+};
+
+/**
+ * @return {boolean} Whether the changes are grouped by page
+ */
+ChangesListWrapperWidget.prototype.inEnhancedMode = function () {
+       var uri = new mw.Uri();
+       return ( uri.query.enhanced !== undefined && Number( uri.query.enhanced ) ) ||
+               ( uri.query.enhanced === undefined && Number( mw.user.options.get( 'usenewrc' ) ) );
+};
+
+/**
+ * Apply color classes based on filters highlight configuration
+ */
+ChangesListWrapperWidget.prototype.applyHighlight = function () {
+       if ( !this.filtersViewModel.isHighlightEnabled() ) {
+               return;
+       }
+
+       this.filtersViewModel.getHighlightedItems().forEach( function ( filterItem ) {
+               var $elements = this.$element.find( '.' + filterItem.getCssClass() );
+
+               // Add highlight class to all highlighted list items
+               $elements
+                       .addClass(
+                               'mw-rcfilters-highlighted ' +
+                               'mw-rcfilters-highlight-color-' + filterItem.getHighlightColor()
+                       );
+
+               // Track the filters for each item in .data( 'highlightedFilters' )
+               $elements.each( function () {
                        var filters = $( this ).data( 'highlightedFilters' );
-
-                       if ( filters && filters.length ) {
-                               $( this ).attr( 'title', mw.msg(
-                                       'rcfilters-highlighted-filters-list',
-                                       filters.join( mw.msg( 'comma-separator' ) )
-                               ) );
+                       if ( !filters ) {
+                               filters = [];
+                               $( this ).data( 'highlightedFilters', filters );
+                       }
+                       if ( filters.indexOf( filterItem.getLabel() ) === -1 ) {
+                               filters.push( filterItem.getLabel() );
                        }
-
                } );
-               if ( this.inEnhancedMode() ) {
-                       this.updateEnhancedParentHighlight();
+       }.bind( this ) );
+       // Apply a title to each highlighted item, with a list of filters
+       this.$element.find( '.mw-rcfilters-highlighted' ).each( function () {
+               var filters = $( this ).data( 'highlightedFilters' );
+
+               if ( filters && filters.length ) {
+                       $( this ).attr( 'title', mw.msg(
+                               'rcfilters-highlighted-filters-list',
+                               filters.join( mw.msg( 'comma-separator' ) )
+                       ) );
                }
 
-               // Turn on highlights
-               this.$element.addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlighted' );
-       };
+       } );
+       if ( this.inEnhancedMode() ) {
+               this.updateEnhancedParentHighlight();
+       }
+
+       // Turn on highlights
+       this.$element.addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlighted' );
+};
+
+/**
+ * Remove all color classes
+ */
+ChangesListWrapperWidget.prototype.clearHighlight = function () {
+       // Remove highlight classes
+       mw.rcfilters.HighlightColors.forEach( function ( color ) {
+               this.$element
+                       .find( '.mw-rcfilters-highlight-color-' + color )
+                       .removeClass( 'mw-rcfilters-highlight-color-' + color );
+       }.bind( this ) );
 
-       /**
-        * Remove all color classes
-        */
-       ChangesListWrapperWidget.prototype.clearHighlight = function () {
-               // Remove highlight classes
-               mw.rcfilters.HighlightColors.forEach( function ( color ) {
-                       this.$element
-                               .find( '.mw-rcfilters-highlight-color-' + color )
-                               .removeClass( 'mw-rcfilters-highlight-color-' + color );
-               }.bind( this ) );
-
-               this.$element.find( '.mw-rcfilters-highlighted' )
-                       .removeAttr( 'title' )
-                       .removeData( 'highlightedFilters' )
-                       .removeClass( 'mw-rcfilters-highlighted' );
-
-               // Remove grey from enhanced rows
-               this.$element.find( '.mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey' )
-                       .removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey' );
-
-               // Turn off highlights
-               this.$element.removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlighted' );
-       };
+       this.$element.find( '.mw-rcfilters-highlighted' )
+               .removeAttr( 'title' )
+               .removeData( 'highlightedFilters' )
+               .removeClass( 'mw-rcfilters-highlighted' );
+
+       // Remove grey from enhanced rows
+       this.$element.find( '.mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey' )
+               .removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey' );
+
+       // Turn off highlights
+       this.$element.removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlighted' );
+};
 
-       module.exports = ChangesListWrapperWidget;
-}() );
+module.exports = ChangesListWrapperWidget;
index 490d54e..b6e21cf 100644 (file)
@@ -1,66 +1,64 @@
-( function () {
-       /**
-        * A widget representing a single toggle filter
-        *
-        * @class mw.rcfilters.ui.CheckboxInputWidget
-        * @extends OO.ui.CheckboxInputWidget
-        *
-        * @constructor
-        * @param {Object} config Configuration object
-        */
-       var CheckboxInputWidget = function MwRcfiltersUiCheckboxInputWidget( config ) {
-               config = config || {};
+/**
+ * A widget representing a single toggle filter
+ *
+ * @class mw.rcfilters.ui.CheckboxInputWidget
+ * @extends OO.ui.CheckboxInputWidget
+ *
+ * @constructor
+ * @param {Object} config Configuration object
+ */
+var CheckboxInputWidget = function MwRcfiltersUiCheckboxInputWidget( config ) {
+       config = config || {};
 
-               // Parent
-               CheckboxInputWidget.parent.call( this, config );
+       // Parent
+       CheckboxInputWidget.parent.call( this, config );
 
-               // Event
-               this.$input
-                       // HACK: This widget just pretends to be a checkbox for visual purposes.
-                       // In reality, all actions - setting to true or false, etc - are
-                       // decided by the model, and executed by the controller. This means
-                       // that we want to let the controller and model make the decision
-                       // of whether to check/uncheck this checkboxInputWidget, and for that,
-                       // we have to bypass the browser action that checks/unchecks it during
-                       // click.
-                       .on( 'click', false )
-                       .on( 'change', this.onUserChange.bind( this ) );
-       };
+       // Event
+       this.$input
+               // HACK: This widget just pretends to be a checkbox for visual purposes.
+               // In reality, all actions - setting to true or false, etc - are
+               // decided by the model, and executed by the controller. This means
+               // that we want to let the controller and model make the decision
+               // of whether to check/uncheck this checkboxInputWidget, and for that,
+               // we have to bypass the browser action that checks/unchecks it during
+               // click.
+               .on( 'click', false )
+               .on( 'change', this.onUserChange.bind( this ) );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( CheckboxInputWidget, OO.ui.CheckboxInputWidget );
+OO.inheritClass( CheckboxInputWidget, OO.ui.CheckboxInputWidget );
 
-       /* Events */
+/* Events */
 
-       /**
       * @event userChange
       * @param {boolean} Current state of the checkbox
       *
       * The user has checked or unchecked this checkbox
       */
+/**
+ * @event userChange
+ * @param {boolean} Current state of the checkbox
+ *
+ * The user has checked or unchecked this checkbox
+ */
 
-       /* Methods */
+/* Methods */
 
-       /**
       * @inheritdoc
       */
-       CheckboxInputWidget.prototype.onEdit = function () {
-               // Similarly to preventing defaults in 'click' event, we want
-               // to prevent this widget from deciding anything about its own
-               // state; it emits a change event and the model and controller
-               // make a decision about what its select state is.
-               // onEdit has a widget.$input.prop( 'checked' ) inside a setTimeout()
-               // so we really want to prevent that from messing with what
-               // the model decides the state of the widget is.
-       };
+/**
+ * @inheritdoc
+ */
+CheckboxInputWidget.prototype.onEdit = function () {
+       // Similarly to preventing defaults in 'click' event, we want
+       // to prevent this widget from deciding anything about its own
+       // state; it emits a change event and the model and controller
+       // make a decision about what its select state is.
+       // onEdit has a widget.$input.prop( 'checked' ) inside a setTimeout()
+       // so we really want to prevent that from messing with what
+       // the model decides the state of the widget is.
+};
 
-       /**
       * Respond to checkbox change by a user and emit 'userChange'.
       */
-       CheckboxInputWidget.prototype.onUserChange = function () {
-               this.emit( 'userChange', this.$input.prop( 'checked' ) );
-       };
+/**
+ * Respond to checkbox change by a user and emit 'userChange'.
+ */
+CheckboxInputWidget.prototype.onUserChange = function () {
+       this.emit( 'userChange', this.$input.prop( 'checked' ) );
+};
 
-       module.exports = CheckboxInputWidget;
-}() );
+module.exports = CheckboxInputWidget;
index 1ac0d49..226821c 100644 (file)
@@ -1,72 +1,70 @@
-( function () {
-       var ValuePickerWidget = require( './ValuePickerWidget.js' ),
-               DatePopupWidget;
+var ValuePickerWidget = require( './ValuePickerWidget.js' ),
+       DatePopupWidget;
 
-       /**
       * Widget defining the popup to choose date for the results
       *
       * @class mw.rcfilters.ui.DatePopupWidget
       * @extends OO.ui.Widget
       *
       * @constructor
       * @param {mw.rcfilters.dm.FilterGroup} model Group model for 'days'
       * @param {Object} [config] Configuration object
       */
-       DatePopupWidget = function MwRcfiltersUiDatePopupWidget( model, config ) {
-               config = config || {};
+/**
+ * Widget defining the popup to choose date for the results
+ *
+ * @class mw.rcfilters.ui.DatePopupWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.FilterGroup} model Group model for 'days'
+ * @param {Object} [config] Configuration object
+ */
+DatePopupWidget = function MwRcfiltersUiDatePopupWidget( model, config ) {
+       config = config || {};
 
-               // Parent
-               DatePopupWidget.parent.call( this, config );
-               // Mixin constructors
-               OO.ui.mixin.LabelElement.call( this, config );
+       // Parent
+       DatePopupWidget.parent.call( this, config );
+       // Mixin constructors
+       OO.ui.mixin.LabelElement.call( this, config );
 
-               this.model = model;
+       this.model = model;
 
-               this.hoursValuePicker = new ValuePickerWidget(
-                       this.model,
-                       {
-                               classes: [ 'mw-rcfilters-ui-datePopupWidget-hours' ],
-                               label: mw.msg( 'rcfilters-hours-title' ),
-                               itemFilter: function ( itemModel ) { return Number( itemModel.getParamName() ) < 1; }
-                       }
-               );
-               this.daysValuePicker = new ValuePickerWidget(
-                       this.model,
-                       {
-                               classes: [ 'mw-rcfilters-ui-datePopupWidget-days' ],
-                               label: mw.msg( 'rcfilters-days-title' ),
-                               itemFilter: function ( itemModel ) { return Number( itemModel.getParamName() ) >= 1; }
-                       }
-               );
+       this.hoursValuePicker = new ValuePickerWidget(
+               this.model,
+               {
+                       classes: [ 'mw-rcfilters-ui-datePopupWidget-hours' ],
+                       label: mw.msg( 'rcfilters-hours-title' ),
+                       itemFilter: function ( itemModel ) { return Number( itemModel.getParamName() ) < 1; }
+               }
+       );
+       this.daysValuePicker = new ValuePickerWidget(
+               this.model,
+               {
+                       classes: [ 'mw-rcfilters-ui-datePopupWidget-days' ],
+                       label: mw.msg( 'rcfilters-days-title' ),
+                       itemFilter: function ( itemModel ) { return Number( itemModel.getParamName() ) >= 1; }
+               }
+       );
 
-               // Events
-               this.hoursValuePicker.connect( this, { choose: [ 'emit', 'days' ] } );
-               this.daysValuePicker.connect( this, { choose: [ 'emit', 'days' ] } );
+       // Events
+       this.hoursValuePicker.connect( this, { choose: [ 'emit', 'days' ] } );
+       this.daysValuePicker.connect( this, { choose: [ 'emit', 'days' ] } );
 
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-datePopupWidget' )
-                       .append(
-                               this.$label
-                                       .addClass( 'mw-rcfilters-ui-datePopupWidget-title' ),
-                               this.hoursValuePicker.$element,
-                               this.daysValuePicker.$element
-                       );
-       };
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-datePopupWidget' )
+               .append(
+                       this.$label
+                               .addClass( 'mw-rcfilters-ui-datePopupWidget-title' ),
+                       this.hoursValuePicker.$element,
+                       this.daysValuePicker.$element
+               );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( DatePopupWidget, OO.ui.Widget );
-       OO.mixinClass( DatePopupWidget, OO.ui.mixin.LabelElement );
+OO.inheritClass( DatePopupWidget, OO.ui.Widget );
+OO.mixinClass( DatePopupWidget, OO.ui.mixin.LabelElement );
 
-       /* Events */
+/* Events */
 
-       /**
       * @event days
       * @param {string} name Item name
       *
       * A days item was chosen
       */
+/**
+ * @event days
+ * @param {string} name Item name
+ *
+ * A days item was chosen
+ */
 
-       module.exports = DatePopupWidget;
-}() );
+module.exports = DatePopupWidget;
index 1327755..fb591d0 100644 (file)
@@ -1,85 +1,83 @@
-( function () {
-       /**
-        * A button to configure highlight for a filter item
-        *
-        * @class mw.rcfilters.ui.FilterItemHighlightButton
-        * @extends OO.ui.PopupButtonWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller RCFilters controller
-        * @param {mw.rcfilters.dm.FilterItem} model Filter item model
-        * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker
-        * @param {Object} [config] Configuration object
-        */
-       var FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, highlightPopup, config ) {
-               config = config || {};
-
-               // Parent
-               FilterItemHighlightButton.parent.call( this, $.extend( true, {}, config, {
-                       icon: 'highlight',
-                       indicator: 'down'
-               } ) );
-
-               this.controller = controller;
-               this.model = model;
-               this.popup = highlightPopup;
-
-               // Event
-               this.model.connect( this, { update: 'updateUiBasedOnModel' } );
-               // This lives inside a MenuOptionWidget, which intercepts mousedown
-               // to select the item. We want to prevent that when we click the highlight
-               // button
-               this.$element.on( 'mousedown', function ( e ) {
-                       e.stopPropagation();
-               } );
-
-               this.updateUiBasedOnModel();
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-filterItemHighlightButton' );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( FilterItemHighlightButton, OO.ui.PopupButtonWidget );
-
-       /* Static Properties */
-
-       /**
-        * @static
-        */
-       FilterItemHighlightButton.static.cancelButtonMouseDownEvents = true;
-
-       /* Methods */
-
-       FilterItemHighlightButton.prototype.onAction = function () {
-               this.popup.setAssociatedButton( this );
-               this.popup.setFilterItem( this.model );
-
-               // Parent method
-               FilterItemHighlightButton.parent.prototype.onAction.call( this );
-       };
-
-       /**
-        * Respond to item model update event
-        */
-       FilterItemHighlightButton.prototype.updateUiBasedOnModel = function () {
-               var currentColor = this.model.getHighlightColor(),
-                       widget = this;
-
-               this.$icon.toggleClass(
-                       'mw-rcfilters-ui-filterItemHighlightButton-circle',
-                       currentColor !== null
-               );
-
-               mw.rcfilters.HighlightColors.forEach( function ( c ) {
-                       widget.$icon
-                               .toggleClass(
-                                       'mw-rcfilters-ui-filterItemHighlightButton-circle-color-' + c,
-                                       c === currentColor
-                               );
-               } );
-       };
-
-       module.exports = FilterItemHighlightButton;
-}() );
+/**
+ * A button to configure highlight for a filter item
+ *
+ * @class mw.rcfilters.ui.FilterItemHighlightButton
+ * @extends OO.ui.PopupButtonWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller RCFilters controller
+ * @param {mw.rcfilters.dm.FilterItem} model Filter item model
+ * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker
+ * @param {Object} [config] Configuration object
+ */
+var FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, highlightPopup, config ) {
+       config = config || {};
+
+       // Parent
+       FilterItemHighlightButton.parent.call( this, $.extend( true, {}, config, {
+               icon: 'highlight',
+               indicator: 'down'
+       } ) );
+
+       this.controller = controller;
+       this.model = model;
+       this.popup = highlightPopup;
+
+       // Event
+       this.model.connect( this, { update: 'updateUiBasedOnModel' } );
+       // This lives inside a MenuOptionWidget, which intercepts mousedown
+       // to select the item. We want to prevent that when we click the highlight
+       // button
+       this.$element.on( 'mousedown', function ( e ) {
+               e.stopPropagation();
+       } );
+
+       this.updateUiBasedOnModel();
+
+       this.$element
+               .addClass( 'mw-rcfilters-ui-filterItemHighlightButton' );
+};
+
+/* Initialization */
+
+OO.inheritClass( FilterItemHighlightButton, OO.ui.PopupButtonWidget );
+
+/* Static Properties */
+
+/**
+ * @static
+ */
+FilterItemHighlightButton.static.cancelButtonMouseDownEvents = true;
+
+/* Methods */
+
+FilterItemHighlightButton.prototype.onAction = function () {
+       this.popup.setAssociatedButton( this );
+       this.popup.setFilterItem( this.model );
+
+       // Parent method
+       FilterItemHighlightButton.parent.prototype.onAction.call( this );
+};
+
+/**
+ * Respond to item model update event
+ */
+FilterItemHighlightButton.prototype.updateUiBasedOnModel = function () {
+       var currentColor = this.model.getHighlightColor(),
+               widget = this;
+
+       this.$icon.toggleClass(
+               'mw-rcfilters-ui-filterItemHighlightButton-circle',
+               currentColor !== null
+       );
+
+       mw.rcfilters.HighlightColors.forEach( function ( c ) {
+               widget.$icon
+                       .toggleClass(
+                               'mw-rcfilters-ui-filterItemHighlightButton-circle-color-' + c,
+                               c === currentColor
+                       );
+       } );
+};
+
+module.exports = FilterItemHighlightButton;
index 1396341..3735af2 100644 (file)
-( function () {
-       /**
-        * Menu header for the RCFilters filters menu
-        *
-        * @class mw.rcfilters.ui.FilterMenuHeaderWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
-        * @param {Object} config Configuration object
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        */
-       var FilterMenuHeaderWidget = function MwRcfiltersUiFilterMenuHeaderWidget( controller, model, config ) {
-               config = config || {};
-
-               this.controller = controller;
-               this.model = model;
-               this.$overlay = config.$overlay || this.$element;
-
-               // Parent
-               FilterMenuHeaderWidget.parent.call( this, config );
-               OO.ui.mixin.LabelElement.call( this, $.extend( {
-                       label: mw.msg( 'rcfilters-filterlist-title' ),
-                       $label: $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-title' )
-               }, config ) );
-
-               // "Back" to default view button
-               this.backButton = new OO.ui.ButtonWidget( {
-                       icon: 'previous',
-                       framed: false,
-                       title: mw.msg( 'rcfilters-view-return-to-default-tooltip' ),
-                       classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-backButton' ]
-               } );
-               this.backButton.toggle( this.model.getCurrentView() !== 'default' );
-
-               // Help icon for Tagged edits
-               this.helpIcon = new OO.ui.ButtonWidget( {
-                       icon: 'helpNotice',
-                       framed: false,
-                       title: mw.msg( 'rcfilters-view-tags-help-icon-tooltip' ),
-                       classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-helpIcon' ],
-                       href: mw.util.getUrl( 'Special:Tags' ),
-                       target: '_blank'
-               } );
-               this.helpIcon.toggle( this.model.getCurrentView() === 'tags' );
-
-               // Highlight button
-               this.highlightButton = new OO.ui.ToggleButtonWidget( {
-                       icon: 'highlight',
-                       label: mw.message( 'rcfilters-highlightbutton-title' ).text(),
-                       classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-hightlightButton' ]
-               } );
-
-               // Invert namespaces button
-               this.invertNamespacesButton = new OO.ui.ToggleButtonWidget( {
-                       icon: '',
-                       classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-invertNamespacesButton' ]
-               } );
-               this.invertNamespacesButton.toggle( this.model.getCurrentView() === 'namespaces' );
-
-               // Events
-               this.backButton.connect( this, { click: 'onBackButtonClick' } );
-               this.highlightButton
-                       .connect( this, { click: 'onHighlightButtonClick' } );
-               this.invertNamespacesButton
-                       .connect( this, { click: 'onInvertNamespacesButtonClick' } );
-               this.model.connect( this, {
-                       highlightChange: 'onModelHighlightChange',
-                       searchChange: 'onModelSearchChange',
-                       initialize: 'onModelInitialize'
-               } );
-               this.view = this.model.getCurrentView();
-
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-table' )
-                                       .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-row' )
-                                                       .append(
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-back' )
-                                                                       .append( this.backButton.$element ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-title' )
-                                                                       .append( this.$label, this.helpIcon.$element ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-invert' )
-                                                                       .append( this.invertNamespacesButton.$element ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-highlight' )
-                                                                       .append( this.highlightButton.$element )
-                                                       )
-                                       )
-                       );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( FilterMenuHeaderWidget, OO.ui.Widget );
-       OO.mixinClass( FilterMenuHeaderWidget, OO.ui.mixin.LabelElement );
-
-       /* Methods */
-
-       /**
-        * Respond to model initialization event
-        *
-        * Note: need to wait for initialization before getting the invertModel
-        * and registering its update event. Creating all the models before the UI
-        * would help with that.
-        */
-       FilterMenuHeaderWidget.prototype.onModelInitialize = function () {
-               this.invertModel = this.model.getInvertModel();
-               this.updateInvertButton();
-               this.invertModel.connect( this, { update: 'updateInvertButton' } );
-       };
-
-       /**
-        * Respond to model update event
-        */
-       FilterMenuHeaderWidget.prototype.onModelSearchChange = function () {
-               var currentView = this.model.getCurrentView();
-
-               if ( this.view !== currentView ) {
-                       this.setLabel( this.model.getViewTitle( currentView ) );
-
-                       this.invertNamespacesButton.toggle( currentView === 'namespaces' );
-                       this.backButton.toggle( currentView !== 'default' );
-                       this.helpIcon.toggle( currentView === 'tags' );
-                       this.view = currentView;
-               }
-       };
-
-       /**
-        * Respond to model highlight change event
-        *
-        * @param {boolean} highlightEnabled Highlight is enabled
-        */
-       FilterMenuHeaderWidget.prototype.onModelHighlightChange = function ( highlightEnabled ) {
-               this.highlightButton.setActive( highlightEnabled );
-       };
-
-       /**
-        * Update the state of the invert button
-        */
-       FilterMenuHeaderWidget.prototype.updateInvertButton = function () {
-               this.invertNamespacesButton.setActive( this.invertModel.isSelected() );
-               this.invertNamespacesButton.setLabel(
-                       this.invertModel.isSelected() ?
-                               mw.msg( 'rcfilters-exclude-button-on' ) :
-                               mw.msg( 'rcfilters-exclude-button-off' )
+/**
+ * Menu header for the RCFilters filters menu
+ *
+ * @class mw.rcfilters.ui.FilterMenuHeaderWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ */
+var FilterMenuHeaderWidget = function MwRcfiltersUiFilterMenuHeaderWidget( controller, model, config ) {
+       config = config || {};
+
+       this.controller = controller;
+       this.model = model;
+       this.$overlay = config.$overlay || this.$element;
+
+       // Parent
+       FilterMenuHeaderWidget.parent.call( this, config );
+       OO.ui.mixin.LabelElement.call( this, $.extend( {
+               label: mw.msg( 'rcfilters-filterlist-title' ),
+               $label: $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-title' )
+       }, config ) );
+
+       // "Back" to default view button
+       this.backButton = new OO.ui.ButtonWidget( {
+               icon: 'previous',
+               framed: false,
+               title: mw.msg( 'rcfilters-view-return-to-default-tooltip' ),
+               classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-backButton' ]
+       } );
+       this.backButton.toggle( this.model.getCurrentView() !== 'default' );
+
+       // Help icon for Tagged edits
+       this.helpIcon = new OO.ui.ButtonWidget( {
+               icon: 'helpNotice',
+               framed: false,
+               title: mw.msg( 'rcfilters-view-tags-help-icon-tooltip' ),
+               classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-helpIcon' ],
+               href: mw.util.getUrl( 'Special:Tags' ),
+               target: '_blank'
+       } );
+       this.helpIcon.toggle( this.model.getCurrentView() === 'tags' );
+
+       // Highlight button
+       this.highlightButton = new OO.ui.ToggleButtonWidget( {
+               icon: 'highlight',
+               label: mw.message( 'rcfilters-highlightbutton-title' ).text(),
+               classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-hightlightButton' ]
+       } );
+
+       // Invert namespaces button
+       this.invertNamespacesButton = new OO.ui.ToggleButtonWidget( {
+               icon: '',
+               classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-invertNamespacesButton' ]
+       } );
+       this.invertNamespacesButton.toggle( this.model.getCurrentView() === 'namespaces' );
+
+       // Events
+       this.backButton.connect( this, { click: 'onBackButtonClick' } );
+       this.highlightButton
+               .connect( this, { click: 'onHighlightButtonClick' } );
+       this.invertNamespacesButton
+               .connect( this, { click: 'onInvertNamespacesButtonClick' } );
+       this.model.connect( this, {
+               highlightChange: 'onModelHighlightChange',
+               searchChange: 'onModelSearchChange',
+               initialize: 'onModelInitialize'
+       } );
+       this.view = this.model.getCurrentView();
+
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget' )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-table' )
+                               .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-row' )
+                                               .append(
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-back' )
+                                                               .append( this.backButton.$element ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-title' )
+                                                               .append( this.$label, this.helpIcon.$element ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-invert' )
+                                                               .append( this.invertNamespacesButton.$element ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-filterMenuHeaderWidget-header-highlight' )
+                                                               .append( this.highlightButton.$element )
+                                               )
+                               )
                );
-       };
-
-       FilterMenuHeaderWidget.prototype.onBackButtonClick = function () {
-               this.controller.switchView( 'default' );
-       };
-
-       /**
-        * Respond to highlight button click
-        */
-       FilterMenuHeaderWidget.prototype.onHighlightButtonClick = function () {
-               this.controller.toggleHighlight();
-       };
-
-       /**
-        * Respond to highlight button click
-        */
-       FilterMenuHeaderWidget.prototype.onInvertNamespacesButtonClick = function () {
-               this.controller.toggleInvertedNamespaces();
-       };
-
-       module.exports = FilterMenuHeaderWidget;
-}() );
+};
+
+/* Initialization */
+
+OO.inheritClass( FilterMenuHeaderWidget, OO.ui.Widget );
+OO.mixinClass( FilterMenuHeaderWidget, OO.ui.mixin.LabelElement );
+
+/* Methods */
+
+/**
+ * Respond to model initialization event
+ *
+ * Note: need to wait for initialization before getting the invertModel
+ * and registering its update event. Creating all the models before the UI
+ * would help with that.
+ */
+FilterMenuHeaderWidget.prototype.onModelInitialize = function () {
+       this.invertModel = this.model.getInvertModel();
+       this.updateInvertButton();
+       this.invertModel.connect( this, { update: 'updateInvertButton' } );
+};
+
+/**
+ * Respond to model update event
+ */
+FilterMenuHeaderWidget.prototype.onModelSearchChange = function () {
+       var currentView = this.model.getCurrentView();
+
+       if ( this.view !== currentView ) {
+               this.setLabel( this.model.getViewTitle( currentView ) );
+
+               this.invertNamespacesButton.toggle( currentView === 'namespaces' );
+               this.backButton.toggle( currentView !== 'default' );
+               this.helpIcon.toggle( currentView === 'tags' );
+               this.view = currentView;
+       }
+};
+
+/**
+ * Respond to model highlight change event
+ *
+ * @param {boolean} highlightEnabled Highlight is enabled
+ */
+FilterMenuHeaderWidget.prototype.onModelHighlightChange = function ( highlightEnabled ) {
+       this.highlightButton.setActive( highlightEnabled );
+};
+
+/**
+ * Update the state of the invert button
+ */
+FilterMenuHeaderWidget.prototype.updateInvertButton = function () {
+       this.invertNamespacesButton.setActive( this.invertModel.isSelected() );
+       this.invertNamespacesButton.setLabel(
+               this.invertModel.isSelected() ?
+                       mw.msg( 'rcfilters-exclude-button-on' ) :
+                       mw.msg( 'rcfilters-exclude-button-off' )
+       );
+};
+
+FilterMenuHeaderWidget.prototype.onBackButtonClick = function () {
+       this.controller.switchView( 'default' );
+};
+
+/**
+ * Respond to highlight button click
+ */
+FilterMenuHeaderWidget.prototype.onHighlightButtonClick = function () {
+       this.controller.toggleHighlight();
+};
+
+/**
+ * Respond to highlight button click
+ */
+FilterMenuHeaderWidget.prototype.onInvertNamespacesButtonClick = function () {
+       this.controller.toggleInvertedNamespaces();
+};
+
+module.exports = FilterMenuHeaderWidget;
index 4080f4d..b4b0e9d 100644 (file)
@@ -1,96 +1,94 @@
-( function () {
-       var ItemMenuOptionWidget = require( './ItemMenuOptionWidget.js' ),
-               FilterMenuOptionWidget;
+var ItemMenuOptionWidget = require( './ItemMenuOptionWidget.js' ),
+       FilterMenuOptionWidget;
 
-       /**
       * A widget representing a single toggle filter
       *
       * @class mw.rcfilters.ui.FilterMenuOptionWidget
       * @extends mw.rcfilters.ui.ItemMenuOptionWidget
       *
       * @constructor
       * @param {mw.rcfilters.Controller} controller RCFilters controller
       * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
       * @param {mw.rcfilters.dm.FilterItem} invertModel
       * @param {mw.rcfilters.dm.FilterItem} itemModel Filter item model
       * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker popup
       * @param {Object} config Configuration object
       */
-       FilterMenuOptionWidget = function MwRcfiltersUiFilterMenuOptionWidget(
-               controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
-       ) {
-               config = config || {};
+/**
+ * A widget representing a single toggle filter
+ *
+ * @class mw.rcfilters.ui.FilterMenuOptionWidget
+ * @extends mw.rcfilters.ui.ItemMenuOptionWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller RCFilters controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
+ * @param {mw.rcfilters.dm.FilterItem} invertModel
+ * @param {mw.rcfilters.dm.FilterItem} itemModel Filter item model
+ * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker popup
+ * @param {Object} config Configuration object
+ */
+FilterMenuOptionWidget = function MwRcfiltersUiFilterMenuOptionWidget(
+       controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
+) {
+       config = config || {};
 
-               this.controller = controller;
-               this.invertModel = invertModel;
-               this.model = itemModel;
+       this.controller = controller;
+       this.invertModel = invertModel;
+       this.model = itemModel;
 
-               // Parent
-               FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, highlightPopup, config );
+       // Parent
+       FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, highlightPopup, config );
 
-               // Event
-               this.model.getGroupModel().connect( this, { update: 'onGroupModelUpdate' } );
+       // Event
+       this.model.getGroupModel().connect( this, { update: 'onGroupModelUpdate' } );
 
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-filterMenuOptionWidget' );
-       };
+       this.$element
+               .addClass( 'mw-rcfilters-ui-filterMenuOptionWidget' );
+};
 
-       /* Initialization */
-       OO.inheritClass( FilterMenuOptionWidget, ItemMenuOptionWidget );
+/* Initialization */
+OO.inheritClass( FilterMenuOptionWidget, ItemMenuOptionWidget );
 
-       /* Static properties */
+/* Static properties */
 
-       // We do our own scrolling to top
-       FilterMenuOptionWidget.static.scrollIntoViewOnSelect = false;
+// We do our own scrolling to top
+FilterMenuOptionWidget.static.scrollIntoViewOnSelect = false;
 
-       /* Methods */
+/* Methods */
 
-       /**
       * @inheritdoc
       */
-       FilterMenuOptionWidget.prototype.updateUiBasedOnState = function () {
-               // Parent
-               FilterMenuOptionWidget.parent.prototype.updateUiBasedOnState.call( this );
+/**
+ * @inheritdoc
+ */
+FilterMenuOptionWidget.prototype.updateUiBasedOnState = function () {
+       // Parent
+       FilterMenuOptionWidget.parent.prototype.updateUiBasedOnState.call( this );
 
-               this.setCurrentMuteState();
-       };
+       this.setCurrentMuteState();
+};
 
-       /**
       * Respond to item group model update event
       */
-       FilterMenuOptionWidget.prototype.onGroupModelUpdate = function () {
-               this.setCurrentMuteState();
-       };
+/**
+ * Respond to item group model update event
+ */
+FilterMenuOptionWidget.prototype.onGroupModelUpdate = function () {
+       this.setCurrentMuteState();
+};
 
-       /**
-        * Set the current muted view of the widget based on its state
-        */
-       FilterMenuOptionWidget.prototype.setCurrentMuteState = function () {
-               if (
-                       this.model.getGroupModel().getView() === 'namespaces' &&
-                       this.invertModel.isSelected()
-               ) {
-                       // This is an inverted behavior than the other rules, specifically
-                       // for inverted namespaces
-                       this.setFlags( {
-                               muted: this.model.isSelected()
-                       } );
-               } else {
-                       this.setFlags( {
-                               muted: (
-                                       this.model.isConflicted() ||
-                                       (
-                                               // Item is also muted when any of the items in its group is active
-                                               this.model.getGroupModel().isActive() &&
-                                               // But it isn't selected
-                                               !this.model.isSelected() &&
-                                               // And also not included
-                                               !this.model.isIncluded()
-                                       )
+/**
+ * Set the current muted view of the widget based on its state
+ */
+FilterMenuOptionWidget.prototype.setCurrentMuteState = function () {
+       if (
+               this.model.getGroupModel().getView() === 'namespaces' &&
+               this.invertModel.isSelected()
+       ) {
+               // This is an inverted behavior than the other rules, specifically
+               // for inverted namespaces
+               this.setFlags( {
+                       muted: this.model.isSelected()
+               } );
+       } else {
+               this.setFlags( {
+                       muted: (
+                               this.model.isConflicted() ||
+                               (
+                                       // Item is also muted when any of the items in its group is active
+                                       this.model.getGroupModel().isActive() &&
+                                       // But it isn't selected
+                                       !this.model.isSelected() &&
+                                       // And also not included
+                                       !this.model.isIncluded()
                                )
-                       } );
-               }
-       };
+                       )
+               } );
+       }
+};
 
-       module.exports = FilterMenuOptionWidget;
-}() );
+module.exports = FilterMenuOptionWidget;
index 5b9e359..abcce81 100644 (file)
-( function () {
-       /**
-        * A widget representing a menu section for filter groups
-        *
-        * @class mw.rcfilters.ui.FilterMenuSectionOptionWidget
-        * @extends OO.ui.MenuSectionOptionWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller RCFilters controller
-        * @param {mw.rcfilters.dm.FilterGroup} model Filter group model
-        * @param {Object} config Configuration object
-        * @cfg {jQuery} [$overlay] Overlay
-        */
-       var FilterMenuSectionOptionWidget = function MwRcfiltersUiFilterMenuSectionOptionWidget( controller, model, config ) {
-               var whatsThisMessages,
-                       $header = $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-header' ),
-                       $popupContent = $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content' );
-
-               config = config || {};
-
-               this.controller = controller;
-               this.model = model;
-               this.$overlay = config.$overlay || this.$element;
-
-               // Parent
-               FilterMenuSectionOptionWidget.parent.call( this, $.extend( {
-                       label: this.model.getTitle(),
-                       $label: $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-header-title' )
-               }, config ) );
-
-               $header.append( this.$label );
-
-               if ( this.model.hasWhatsThis() ) {
-                       whatsThisMessages = this.model.getWhatsThis();
-
-                       // Create popup
-                       if ( whatsThisMessages.header ) {
-                               $popupContent.append(
-                                       ( new OO.ui.LabelWidget( {
-                                               label: mw.msg( whatsThisMessages.header ),
-                                               classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content-header' ]
-                                       } ) ).$element
-                               );
-                       }
-                       if ( whatsThisMessages.body ) {
-                               $popupContent.append(
-                                       ( new OO.ui.LabelWidget( {
-                                               label: mw.msg( whatsThisMessages.body ),
-                                               classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content-body' ]
-                                       } ) ).$element
-                               );
-                       }
-                       if ( whatsThisMessages.linkText && whatsThisMessages.url ) {
-                               $popupContent.append(
-                                       ( new OO.ui.ButtonWidget( {
-                                               framed: false,
-                                               flags: [ 'progressive' ],
-                                               href: whatsThisMessages.url,
-                                               label: mw.msg( whatsThisMessages.linkText ),
-                                               classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content-link' ]
-                                       } ) ).$element
-                               );
-                       }
-
-                       // Add button
-                       this.whatsThisButton = new OO.ui.PopupButtonWidget( {
-                               framed: false,
-                               label: mw.msg( 'rcfilters-filterlist-whatsthis' ),
-                               $overlay: this.$overlay,
-                               classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton' ],
-                               flags: [ 'progressive' ],
-                               popup: {
-                                       padded: false,
-                                       align: 'center',
-                                       position: 'above',
-                                       $content: $popupContent,
-                                       classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup' ]
-                               }
-                       } );
-
-                       $header
-                               .append( this.whatsThisButton.$element );
+/**
+ * A widget representing a menu section for filter groups
+ *
+ * @class mw.rcfilters.ui.FilterMenuSectionOptionWidget
+ * @extends OO.ui.MenuSectionOptionWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller RCFilters controller
+ * @param {mw.rcfilters.dm.FilterGroup} model Filter group model
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} [$overlay] Overlay
+ */
+var FilterMenuSectionOptionWidget = function MwRcfiltersUiFilterMenuSectionOptionWidget( controller, model, config ) {
+       var whatsThisMessages,
+               $header = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-header' ),
+               $popupContent = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content' );
+
+       config = config || {};
+
+       this.controller = controller;
+       this.model = model;
+       this.$overlay = config.$overlay || this.$element;
+
+       // Parent
+       FilterMenuSectionOptionWidget.parent.call( this, $.extend( {
+               label: this.model.getTitle(),
+               $label: $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-header-title' )
+       }, config ) );
+
+       $header.append( this.$label );
+
+       if ( this.model.hasWhatsThis() ) {
+               whatsThisMessages = this.model.getWhatsThis();
+
+               // Create popup
+               if ( whatsThisMessages.header ) {
+                       $popupContent.append(
+                               ( new OO.ui.LabelWidget( {
+                                       label: mw.msg( whatsThisMessages.header ),
+                                       classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content-header' ]
+                               } ) ).$element
+                       );
+               }
+               if ( whatsThisMessages.body ) {
+                       $popupContent.append(
+                               ( new OO.ui.LabelWidget( {
+                                       label: mw.msg( whatsThisMessages.body ),
+                                       classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content-body' ]
+                               } ) ).$element
+                       );
+               }
+               if ( whatsThisMessages.linkText && whatsThisMessages.url ) {
+                       $popupContent.append(
+                               ( new OO.ui.ButtonWidget( {
+                                       framed: false,
+                                       flags: [ 'progressive' ],
+                                       href: whatsThisMessages.url,
+                                       label: mw.msg( whatsThisMessages.linkText ),
+                                       classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup-content-link' ]
+                               } ) ).$element
+                       );
                }
 
-               // Events
-               this.model.connect( this, { update: 'updateUiBasedOnState' } );
-
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget' )
-                       .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-name-' + this.model.getName() )
-                       .append( $header );
-               this.updateUiBasedOnState();
-       };
-
-       /* Initialize */
-
-       OO.inheritClass( FilterMenuSectionOptionWidget, OO.ui.MenuSectionOptionWidget );
-
-       /* Methods */
-
-       /**
-        * Respond to model update event
-        */
-       FilterMenuSectionOptionWidget.prototype.updateUiBasedOnState = function () {
-               this.$element.toggleClass(
-                       'mw-rcfilters-ui-filterMenuSectionOptionWidget-active',
-                       this.model.isActive()
-               );
-               this.toggle( this.model.isVisible() );
-       };
-
-       /**
-        * Get the group name
-        *
-        * @return {string} Group name
-        */
-       FilterMenuSectionOptionWidget.prototype.getName = function () {
-               return this.model.getName();
-       };
-
-       module.exports = FilterMenuSectionOptionWidget;
-
-}() );
+               // Add button
+               this.whatsThisButton = new OO.ui.PopupButtonWidget( {
+                       framed: false,
+                       label: mw.msg( 'rcfilters-filterlist-whatsthis' ),
+                       $overlay: this.$overlay,
+                       classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton' ],
+                       flags: [ 'progressive' ],
+                       popup: {
+                               padded: false,
+                               align: 'center',
+                               position: 'above',
+                               $content: $popupContent,
+                               classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton-popup' ]
+                       }
+               } );
+
+               $header
+                       .append( this.whatsThisButton.$element );
+       }
+
+       // Events
+       this.model.connect( this, { update: 'updateUiBasedOnState' } );
+
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget' )
+               .addClass( 'mw-rcfilters-ui-filterMenuSectionOptionWidget-name-' + this.model.getName() )
+               .append( $header );
+       this.updateUiBasedOnState();
+};
+
+/* Initialize */
+
+OO.inheritClass( FilterMenuSectionOptionWidget, OO.ui.MenuSectionOptionWidget );
+
+/* Methods */
+
+/**
+ * Respond to model update event
+ */
+FilterMenuSectionOptionWidget.prototype.updateUiBasedOnState = function () {
+       this.$element.toggleClass(
+               'mw-rcfilters-ui-filterMenuSectionOptionWidget-active',
+               this.model.isActive()
+       );
+       this.toggle( this.model.isVisible() );
+};
+
+/**
+ * Get the group name
+ *
+ * @return {string} Group name
+ */
+FilterMenuSectionOptionWidget.prototype.getName = function () {
+       return this.model.getName();
+};
+
+module.exports = FilterMenuSectionOptionWidget;
index bda898b..98eea71 100644 (file)
@@ -1,50 +1,48 @@
-( function () {
-       var TagItemWidget = require( './TagItemWidget.js' ),
-               FilterTagItemWidget;
-
-       /**
-        * Extend OOUI's FilterTagItemWidget to also display a popup on hover.
-        *
-        * @class mw.rcfilters.ui.FilterTagItemWidget
-        * @extends mw.rcfilters.ui.TagItemWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
-        * @param {mw.rcfilters.dm.FilterItem} invertModel
-        * @param {mw.rcfilters.dm.FilterItem} itemModel Item model
-        * @param {Object} config Configuration object
-        */
-       FilterTagItemWidget = function MwRcfiltersUiFilterTagItemWidget(
-               controller, filtersViewModel, invertModel, itemModel, config
-       ) {
-               config = config || {};
-
-               FilterTagItemWidget.parent.call( this, controller, filtersViewModel, invertModel, itemModel, config );
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-filterTagItemWidget' );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( FilterTagItemWidget, TagItemWidget );
-
-       /* Methods */
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagItemWidget.prototype.setCurrentMuteState = function () {
-               this.setFlags( {
-                       muted: (
-                               !this.itemModel.isSelected() ||
-                               this.itemModel.isIncluded() ||
-                               this.itemModel.isFullyCovered()
-                       ),
-                       invalid: this.itemModel.isSelected() && this.itemModel.isConflicted()
-               } );
-       };
-
-       module.exports = FilterTagItemWidget;
-}() );
+var TagItemWidget = require( './TagItemWidget.js' ),
+       FilterTagItemWidget;
+
+/**
+ * Extend OOUI's FilterTagItemWidget to also display a popup on hover.
+ *
+ * @class mw.rcfilters.ui.FilterTagItemWidget
+ * @extends mw.rcfilters.ui.TagItemWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
+ * @param {mw.rcfilters.dm.FilterItem} invertModel
+ * @param {mw.rcfilters.dm.FilterItem} itemModel Item model
+ * @param {Object} config Configuration object
+ */
+FilterTagItemWidget = function MwRcfiltersUiFilterTagItemWidget(
+       controller, filtersViewModel, invertModel, itemModel, config
+) {
+       config = config || {};
+
+       FilterTagItemWidget.parent.call( this, controller, filtersViewModel, invertModel, itemModel, config );
+
+       this.$element
+               .addClass( 'mw-rcfilters-ui-filterTagItemWidget' );
+};
+
+/* Initialization */
+
+OO.inheritClass( FilterTagItemWidget, TagItemWidget );
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+FilterTagItemWidget.prototype.setCurrentMuteState = function () {
+       this.setFlags( {
+               muted: (
+                       !this.itemModel.isSelected() ||
+                       this.itemModel.isIncluded() ||
+                       this.itemModel.isFullyCovered()
+               ),
+               invalid: this.itemModel.isSelected() && this.itemModel.isConflicted()
+       } );
+};
+
+module.exports = FilterTagItemWidget;
index dc6fc12..085e22b 100644 (file)
-( function () {
-       var ViewSwitchWidget = require( './ViewSwitchWidget.js' ),
-               SaveFiltersPopupButtonWidget = require( './SaveFiltersPopupButtonWidget.js' ),
-               MenuSelectWidget = require( './MenuSelectWidget.js' ),
-               FilterTagItemWidget = require( './FilterTagItemWidget.js' ),
-               FilterTagMultiselectWidget;
-
-       /**
-        * List displaying all filter groups
-        *
-        * @class mw.rcfilters.ui.FilterTagMultiselectWidget
-        * @extends OO.ui.MenuTagMultiselectWidget
-        * @mixins OO.ui.mixin.PendingElement
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
-        * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
-        * @param {Object} config Configuration object
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        * @cfg {jQuery} [$wrapper] A jQuery object for the wrapper of the general
-        *  system. If not given, falls back to this widget's $element
-        * @cfg {boolean} [collapsed] Filter area is collapsed
-        */
-       FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, savedQueriesModel, config ) {
-               var rcFiltersRow,
-                       title = new OO.ui.LabelWidget( {
-                               label: mw.msg( 'rcfilters-activefilters' ),
-                               classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-title' ]
-                       } ),
-                       $contentWrapper = $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper' );
-
-               config = config || {};
-
-               this.controller = controller;
-               this.model = model;
-               this.queriesModel = savedQueriesModel;
-               this.$overlay = config.$overlay || this.$element;
-               this.$wrapper = config.$wrapper || this.$element;
-               this.matchingQuery = null;
-               this.currentView = this.model.getCurrentView();
-               this.collapsed = false;
-
-               // Parent
-               FilterTagMultiselectWidget.parent.call( this, $.extend( true, {
-                       label: mw.msg( 'rcfilters-filterlist-title' ),
-                       placeholder: mw.msg( 'rcfilters-empty-filter' ),
-                       inputPosition: 'outline',
-                       allowArbitrary: false,
-                       allowDisplayInvalidTags: false,
-                       allowReordering: false,
-                       $overlay: this.$overlay,
-                       menu: {
-                               // Our filtering is done through the model
-                               filterFromInput: false,
-                               hideWhenOutOfView: false,
-                               hideOnChoose: false,
-                               width: 650,
-                               footers: [
-                                       {
-                                               name: 'viewSelect',
-                                               sticky: false,
-                                               // View select menu, appears on default view only
-                                               $element: $( '<div>' )
-                                                       .append( new ViewSwitchWidget( this.controller, this.model ).$element ),
-                                               views: [ 'default' ]
-                                       },
-                                       {
-                                               name: 'feedback',
-                                               // Feedback footer, appears on all views
-                                               $element: $( '<div>' )
-                                                       .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
-                                                       )
-                                       }
-                               ]
-                       },
-                       input: {
-                               icon: 'menu',
-                               placeholder: mw.msg( 'rcfilters-search-placeholder' )
-                       }
-               }, config ) );
-
-               this.savedQueryTitle = new OO.ui.LabelWidget( {
-                       label: '',
-                       classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-savedQueryTitle' ]
-               } );
-
-               this.resetButton = new OO.ui.ButtonWidget( {
-                       framed: false,
-                       classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-resetButton' ]
-               } );
-
-               this.hideShowButton = new OO.ui.ButtonWidget( {
-                       framed: false,
-                       flags: [ 'progressive' ],
-                       classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-hideshowButton' ]
-               } );
-               this.toggleCollapsed( !!config.collapsed );
-
-               if ( !mw.user.isAnon() ) {
-                       this.saveQueryButton = new SaveFiltersPopupButtonWidget(
-                               this.controller,
-                               this.queriesModel,
+var ViewSwitchWidget = require( './ViewSwitchWidget.js' ),
+       SaveFiltersPopupButtonWidget = require( './SaveFiltersPopupButtonWidget.js' ),
+       MenuSelectWidget = require( './MenuSelectWidget.js' ),
+       FilterTagItemWidget = require( './FilterTagItemWidget.js' ),
+       FilterTagMultiselectWidget;
+
+/**
+ * List displaying all filter groups
+ *
+ * @class mw.rcfilters.ui.FilterTagMultiselectWidget
+ * @extends OO.ui.MenuTagMultiselectWidget
+ * @mixins OO.ui.mixin.PendingElement
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ * @cfg {jQuery} [$wrapper] A jQuery object for the wrapper of the general
+ *  system. If not given, falls back to this widget's $element
+ * @cfg {boolean} [collapsed] Filter area is collapsed
+ */
+FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, savedQueriesModel, config ) {
+       var rcFiltersRow,
+               title = new OO.ui.LabelWidget( {
+                       label: mw.msg( 'rcfilters-activefilters' ),
+                       classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-title' ]
+               } ),
+               $contentWrapper = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper' );
+
+       config = config || {};
+
+       this.controller = controller;
+       this.model = model;
+       this.queriesModel = savedQueriesModel;
+       this.$overlay = config.$overlay || this.$element;
+       this.$wrapper = config.$wrapper || this.$element;
+       this.matchingQuery = null;
+       this.currentView = this.model.getCurrentView();
+       this.collapsed = false;
+
+       // Parent
+       FilterTagMultiselectWidget.parent.call( this, $.extend( true, {
+               label: mw.msg( 'rcfilters-filterlist-title' ),
+               placeholder: mw.msg( 'rcfilters-empty-filter' ),
+               inputPosition: 'outline',
+               allowArbitrary: false,
+               allowDisplayInvalidTags: false,
+               allowReordering: false,
+               $overlay: this.$overlay,
+               menu: {
+                       // Our filtering is done through the model
+                       filterFromInput: false,
+                       hideWhenOutOfView: false,
+                       hideOnChoose: false,
+                       width: 650,
+                       footers: [
+                               {
+                                       name: 'viewSelect',
+                                       sticky: false,
+                                       // View select menu, appears on default view only
+                                       $element: $( '<div>' )
+                                               .append( new ViewSwitchWidget( this.controller, this.model ).$element ),
+                                       views: [ 'default' ]
+                               },
                                {
-                                       $overlay: this.$overlay
+                                       name: 'feedback',
+                                       // Feedback footer, appears on all views
+                                       $element: $( '<div>' )
+                                               .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.saveQueryButton.$element.on( 'mousedown', function ( e ) {
-                               e.stopPropagation();
-                       } );
-
-                       this.saveQueryButton.connect( this, {
-                               click: 'onSaveQueryButtonClick',
-                               saveCurrent: 'setSavedQueryVisibility'
-                       } );
-                       this.queriesModel.connect( this, {
-                               itemUpdate: 'onSavedQueriesItemUpdate',
-                               initialize: 'onSavedQueriesInitialize',
-                               default: 'reevaluateResetRestoreState'
-                       } );
+                       ]
+               },
+               input: {
+                       icon: 'menu',
+                       placeholder: mw.msg( 'rcfilters-search-placeholder' )
                }
+       }, config ) );
+
+       this.savedQueryTitle = new OO.ui.LabelWidget( {
+               label: '',
+               classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-savedQueryTitle' ]
+       } );
+
+       this.resetButton = new OO.ui.ButtonWidget( {
+               framed: false,
+               classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-resetButton' ]
+       } );
+
+       this.hideShowButton = new OO.ui.ButtonWidget( {
+               framed: false,
+               flags: [ 'progressive' ],
+               classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-hideshowButton' ]
+       } );
+       this.toggleCollapsed( !!config.collapsed );
+
+       if ( !mw.user.isAnon() ) {
+               this.saveQueryButton = new SaveFiltersPopupButtonWidget(
+                       this.controller,
+                       this.queriesModel,
+                       {
+                               $overlay: this.$overlay
+                       }
+               );
 
-               this.emptyFilterMessage = new OO.ui.LabelWidget( {
-                       label: mw.msg( 'rcfilters-empty-filter' ),
-                       classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-emptyFilters' ]
-               } );
-               this.$content.append( this.emptyFilterMessage.$element );
-
-               // Events
-               this.resetButton.connect( this, { click: 'onResetButtonClick' } );
-               this.hideShowButton.connect( this, { click: 'onHideShowButtonClick' } );
-               // Stop propagation for mousedown, so that the widget doesn't
-               // trigger the focus on the input and scrolls up when we click the reset button
-               this.resetButton.$element.on( 'mousedown', function ( e ) {
-                       e.stopPropagation();
-               } );
-               this.hideShowButton.$element.on( 'mousedown', function ( e ) {
+               this.saveQueryButton.$element.on( 'mousedown', function ( e ) {
                        e.stopPropagation();
                } );
-               this.model.connect( this, {
-                       initialize: 'onModelInitialize',
-                       update: 'onModelUpdate',
-                       searchChange: 'onModelSearchChange',
-                       itemUpdate: 'onModelItemUpdate',
-                       highlightChange: 'onModelHighlightChange'
-               } );
-               this.input.connect( this, { change: 'onInputChange' } );
-
-               // The filter list and button should appear side by side regardless of how
-               // wide the button is; the button also changes its width depending
-               // on language and its state, so the safest way to present both side
-               // by side is with a table layout
-               rcFiltersRow = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-row' )
-                       .append(
-                               this.$content
-                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-filters' )
-                       );
 
-               if ( !mw.user.isAnon() ) {
-                       rcFiltersRow.append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-save' )
-                                       .append( this.saveQueryButton.$element )
-                       );
-               }
-
-               // Add a selector at the right of the input
-               this.viewsSelectWidget = new OO.ui.ButtonSelectWidget( {
-                       classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select-widget' ],
-                       items: [
-                               new OO.ui.ButtonOptionWidget( {
-                                       framed: false,
-                                       data: 'namespaces',
-                                       icon: 'article',
-                                       label: mw.msg( 'namespaces' ),
-                                       title: mw.msg( 'rcfilters-view-namespaces-tooltip' )
-                               } ),
-                               new OO.ui.ButtonOptionWidget( {
-                                       framed: false,
-                                       data: 'tags',
-                                       icon: 'tag',
-                                       label: mw.msg( 'tags-title' ),
-                                       title: mw.msg( 'rcfilters-view-tags-tooltip' )
-                               } )
-                       ]
+               this.saveQueryButton.connect( this, {
+                       click: 'onSaveQueryButtonClick',
+                       saveCurrent: 'setSavedQueryVisibility'
                } );
-
-               // Rearrange the UI so the select widget is at the right of the input
-               this.$element.append(
-                       $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-table' )
-                               .append(
-                                       $( '<div>' )
-                                               .addClass( 'mw-rcfilters-ui-row' )
-                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views' )
-                                               .append(
-                                                       $( '<div>' )
-                                                               .addClass( 'mw-rcfilters-ui-cell' )
-                                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-input' )
-                                                               .append( this.input.$element ),
-                                                       $( '<div>' )
-                                                               .addClass( 'mw-rcfilters-ui-cell' )
-                                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select' )
-                                                               .append( this.viewsSelectWidget.$element )
-                                               )
-                               )
+               this.queriesModel.connect( this, {
+                       itemUpdate: 'onSavedQueriesItemUpdate',
+                       initialize: 'onSavedQueriesInitialize',
+                       default: 'reevaluateResetRestoreState'
+               } );
+       }
+
+       this.emptyFilterMessage = new OO.ui.LabelWidget( {
+               label: mw.msg( 'rcfilters-empty-filter' ),
+               classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-emptyFilters' ]
+       } );
+       this.$content.append( this.emptyFilterMessage.$element );
+
+       // Events
+       this.resetButton.connect( this, { click: 'onResetButtonClick' } );
+       this.hideShowButton.connect( this, { click: 'onHideShowButtonClick' } );
+       // Stop propagation for mousedown, so that the widget doesn't
+       // trigger the focus on the input and scrolls up when we click the reset button
+       this.resetButton.$element.on( 'mousedown', function ( e ) {
+               e.stopPropagation();
+       } );
+       this.hideShowButton.$element.on( 'mousedown', function ( e ) {
+               e.stopPropagation();
+       } );
+       this.model.connect( this, {
+               initialize: 'onModelInitialize',
+               update: 'onModelUpdate',
+               searchChange: 'onModelSearchChange',
+               itemUpdate: 'onModelItemUpdate',
+               highlightChange: 'onModelHighlightChange'
+       } );
+       this.input.connect( this, { change: 'onInputChange' } );
+
+       // The filter list and button should appear side by side regardless of how
+       // wide the button is; the button also changes its width depending
+       // on language and its state, so the safest way to present both side
+       // by side is with a table layout
+       rcFiltersRow = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-row' )
+               .append(
+                       this.$content
+                               .addClass( 'mw-rcfilters-ui-cell' )
+                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-filters' )
                );
 
-               // Event
-               this.viewsSelectWidget.connect( this, { choose: 'onViewsSelectWidgetChoose' } );
-
+       if ( !mw.user.isAnon() ) {
                rcFiltersRow.append(
                        $( '<div>' )
                                .addClass( 'mw-rcfilters-ui-cell' )
-                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-reset' )
-                               .append( this.resetButton.$element )
+                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-save' )
+                               .append( this.saveQueryButton.$element )
                );
-
-               // Build the content
-               $contentWrapper.append(
-                       $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top' )
-                               .append(
-                                       $( '<div>' )
-                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top-title' )
-                                               .append( title.$element ),
-                                       $( '<div>' )
-                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top-queryName' )
-                                               .append( this.savedQueryTitle.$element ),
-                                       $( '<div>' )
-                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top-hideshow' )
-                                               .append(
-                                                       this.hideShowButton.$element
-                                               )
-                               ),
-                       $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-table' )
-                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters' )
-                               .append( rcFiltersRow )
-               );
-
-               // Initialize
-               this.$handle.append( $contentWrapper );
-               this.emptyFilterMessage.toggle( this.isEmpty() );
-               this.savedQueryTitle.toggle( false );
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget' );
-
-               this.reevaluateResetRestoreState();
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( FilterTagMultiselectWidget, OO.ui.MenuTagMultiselectWidget );
-
-       /* Methods */
-
-       /**
-        * Override parent method to avoid unnecessary resize events.
-        */
-       FilterTagMultiselectWidget.prototype.updateIfHeightChanged = function () { };
-
-       /**
-        * Respond to view select widget choose event
-        *
-        * @param {OO.ui.ButtonOptionWidget} buttonOptionWidget Chosen widget
-        */
-       FilterTagMultiselectWidget.prototype.onViewsSelectWidgetChoose = function ( buttonOptionWidget ) {
-               this.controller.switchView( buttonOptionWidget.getData() );
-               this.viewsSelectWidget.selectItem( null );
+       }
+
+       // Add a selector at the right of the input
+       this.viewsSelectWidget = new OO.ui.ButtonSelectWidget( {
+               classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select-widget' ],
+               items: [
+                       new OO.ui.ButtonOptionWidget( {
+                               framed: false,
+                               data: 'namespaces',
+                               icon: 'article',
+                               label: mw.msg( 'namespaces' ),
+                               title: mw.msg( 'rcfilters-view-namespaces-tooltip' )
+                       } ),
+                       new OO.ui.ButtonOptionWidget( {
+                               framed: false,
+                               data: 'tags',
+                               icon: 'tag',
+                               label: mw.msg( 'tags-title' ),
+                               title: mw.msg( 'rcfilters-view-tags-tooltip' )
+                       } )
+               ]
+       } );
+
+       // Rearrange the UI so the select widget is at the right of the input
+       this.$element.append(
+               $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-table' )
+                       .append(
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-row' )
+                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views' )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-input' )
+                                                       .append( this.input.$element ),
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select' )
+                                                       .append( this.viewsSelectWidget.$element )
+                                       )
+                       )
+       );
+
+       // Event
+       this.viewsSelectWidget.connect( this, { choose: 'onViewsSelectWidgetChoose' } );
+
+       rcFiltersRow.append(
+               $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-cell' )
+                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-reset' )
+                       .append( this.resetButton.$element )
+       );
+
+       // Build the content
+       $contentWrapper.append(
+               $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top' )
+                       .append(
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top-title' )
+                                       .append( title.$element ),
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top-queryName' )
+                                       .append( this.savedQueryTitle.$element ),
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top-hideshow' )
+                                       .append(
+                                               this.hideShowButton.$element
+                                       )
+                       ),
+               $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-table' )
+                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters' )
+                       .append( rcFiltersRow )
+       );
+
+       // Initialize
+       this.$handle.append( $contentWrapper );
+       this.emptyFilterMessage.toggle( this.isEmpty() );
+       this.savedQueryTitle.toggle( false );
+
+       this.$element
+               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget' );
+
+       this.reevaluateResetRestoreState();
+};
+
+/* Initialization */
+
+OO.inheritClass( FilterTagMultiselectWidget, OO.ui.MenuTagMultiselectWidget );
+
+/* Methods */
+
+/**
+ * Override parent method to avoid unnecessary resize events.
+ */
+FilterTagMultiselectWidget.prototype.updateIfHeightChanged = function () { };
+
+/**
+ * Respond to view select widget choose event
+ *
+ * @param {OO.ui.ButtonOptionWidget} buttonOptionWidget Chosen widget
+ */
+FilterTagMultiselectWidget.prototype.onViewsSelectWidgetChoose = function ( buttonOptionWidget ) {
+       this.controller.switchView( buttonOptionWidget.getData() );
+       this.viewsSelectWidget.selectItem( null );
+       this.focus();
+};
+
+/**
+ * Respond to model search change event
+ *
+ * @param {string} value Search value
+ */
+FilterTagMultiselectWidget.prototype.onModelSearchChange = function ( value ) {
+       this.input.setValue( value );
+};
+
+/**
+ * Respond to input change event
+ *
+ * @param {string} value Value of the input
+ */
+FilterTagMultiselectWidget.prototype.onInputChange = function ( value ) {
+       this.controller.setSearch( value );
+};
+
+/**
+ * Respond to query button click
+ */
+FilterTagMultiselectWidget.prototype.onSaveQueryButtonClick = function () {
+       this.getMenu().toggle( false );
+};
+
+/**
+ * Respond to save query model initialization
+ */
+FilterTagMultiselectWidget.prototype.onSavedQueriesInitialize = function () {
+       this.setSavedQueryVisibility();
+};
+
+/**
+ * Respond to save query item change. Mainly this is done to update the label in case
+ * a query item has been edited
+ *
+ * @param {mw.rcfilters.dm.SavedQueryItemModel} item Saved query item
+ */
+FilterTagMultiselectWidget.prototype.onSavedQueriesItemUpdate = function ( item ) {
+       if ( this.matchingQuery === item ) {
+               // This means we just edited the item that is currently matched
+               this.savedQueryTitle.setLabel( item.getLabel() );
+       }
+};
+
+/**
+ * Respond to menu toggle
+ *
+ * @param {boolean} isVisible Menu is visible
+ */
+FilterTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
+       // Parent
+       FilterTagMultiselectWidget.parent.prototype.onMenuToggle.call( this );
+
+       if ( isVisible ) {
                this.focus();
-       };
-
-       /**
-        * Respond to model search change event
-        *
-        * @param {string} value Search value
-        */
-       FilterTagMultiselectWidget.prototype.onModelSearchChange = function ( value ) {
-               this.input.setValue( value );
-       };
-
-       /**
-        * Respond to input change event
-        *
-        * @param {string} value Value of the input
-        */
-       FilterTagMultiselectWidget.prototype.onInputChange = function ( value ) {
-               this.controller.setSearch( value );
-       };
-
-       /**
-        * Respond to query button click
-        */
-       FilterTagMultiselectWidget.prototype.onSaveQueryButtonClick = function () {
-               this.getMenu().toggle( false );
-       };
-
-       /**
-        * Respond to save query model initialization
-        */
-       FilterTagMultiselectWidget.prototype.onSavedQueriesInitialize = function () {
-               this.setSavedQueryVisibility();
-       };
-
-       /**
-        * Respond to save query item change. Mainly this is done to update the label in case
-        * a query item has been edited
-        *
-        * @param {mw.rcfilters.dm.SavedQueryItemModel} item Saved query item
-        */
-       FilterTagMultiselectWidget.prototype.onSavedQueriesItemUpdate = function ( item ) {
-               if ( this.matchingQuery === item ) {
-                       // This means we just edited the item that is currently matched
-                       this.savedQueryTitle.setLabel( item.getLabel() );
-               }
-       };
-
-       /**
-        * Respond to menu toggle
-        *
-        * @param {boolean} isVisible Menu is visible
-        */
-       FilterTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
-               // Parent
-               FilterTagMultiselectWidget.parent.prototype.onMenuToggle.call( this );
-
-               if ( isVisible ) {
-                       this.focus();
-
-                       mw.hook( 'RcFilters.popup.open' ).fire();
-
-                       if ( !this.getMenu().findSelectedItem() ) {
-                               // If there are no selected items, scroll menu to top
-                               // This has to be in a setTimeout so the menu has time
-                               // to be positioned and fixed
-                               setTimeout(
-                                       function () {
-                                               this.getMenu().scrollToTop();
-                                       }.bind( this )
-                               );
-                       }
-               } else {
-                       // Clear selection
-                       this.selectTag( null );
 
-                       // Clear the search
-                       this.controller.setSearch( '' );
+               mw.hook( 'RcFilters.popup.open' ).fire();
 
-                       // Log filter grouping
-                       this.controller.trackFilterGroupings( 'filtermenu' );
-
-                       this.blur();
-               }
-
-               this.input.setIcon( isVisible ? 'search' : 'menu' );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.onInputFocus = function () {
-               // Parent
-               FilterTagMultiselectWidget.parent.prototype.onInputFocus.call( this );
-
-               // Only scroll to top of the viewport if:
-               // - The widget is more than 20px from the top
-               // - The widget is not above the top of the viewport (do not scroll downwards)
-               //   (This isn't represented because >20 is, anyways and always, bigger than 0)
-               this.scrollToTop( this.$element, 0, { min: 20, max: Infinity } );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.doInputEscape = function () {
-               // Parent
-               FilterTagMultiselectWidget.parent.prototype.doInputEscape.call( this );
-
-               // Blur the input
-               this.input.$input.trigger( 'blur' );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.onMouseDown = function ( e ) {
-               if ( !this.collapsed && !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
-                       this.menu.toggle();
-
-                       return false;
-               }
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.onChangeTags = function () {
-               // If initialized, call parent method.
-               if ( this.controller.isInitialized() ) {
-                       FilterTagMultiselectWidget.parent.prototype.onChangeTags.call( this );
-               }
-
-               this.emptyFilterMessage.toggle( this.isEmpty() );
-       };
-
-       /**
-        * Respond to model initialize event
-        */
-       FilterTagMultiselectWidget.prototype.onModelInitialize = function () {
-               this.setSavedQueryVisibility();
-       };
-
-       /**
-        * Respond to model update event
-        */
-       FilterTagMultiselectWidget.prototype.onModelUpdate = function () {
-               this.updateElementsForView();
-       };
-
-       /**
-        * Update the elements in the widget to the current view
-        */
-       FilterTagMultiselectWidget.prototype.updateElementsForView = function () {
-               var view = this.model.getCurrentView(),
-                       inputValue = this.input.getValue().trim(),
-                       inputView = this.model.getViewByTrigger( inputValue.substr( 0, 1 ) );
-
-               if ( inputView !== 'default' ) {
-                       // We have a prefix already, remove it
-                       inputValue = inputValue.substr( 1 );
-               }
-
-               if ( inputView !== view ) {
-                       // Add the correct prefix
-                       inputValue = this.model.getViewTrigger( view ) + inputValue;
-               }
-
-               // Update input
-               this.input.setValue( inputValue );
-
-               if ( this.currentView !== view ) {
-                       this.scrollToTop( this.$element );
-                       this.currentView = view;
-               }
-       };
-
-       /**
-        * Set the visibility of the saved query button
-        */
-       FilterTagMultiselectWidget.prototype.setSavedQueryVisibility = function () {
-               if ( mw.user.isAnon() ) {
-                       return;
-               }
-
-               this.matchingQuery = this.controller.findQueryMatchingCurrentState();
-
-               this.savedQueryTitle.setLabel(
-                       this.matchingQuery ? this.matchingQuery.getLabel() : ''
-               );
-               this.savedQueryTitle.toggle( !!this.matchingQuery );
-               this.saveQueryButton.setDisabled( !!this.matchingQuery );
-               this.saveQueryButton.setTitle( !this.matchingQuery ?
-                       mw.msg( 'rcfilters-savedqueries-add-new-title' ) :
-                       mw.msg( 'rcfilters-savedqueries-already-saved' ) );
-
-               if ( this.matchingQuery ) {
-                       this.emphasize();
+               if ( !this.getMenu().findSelectedItem() ) {
+                       // If there are no selected items, scroll menu to top
+                       // This has to be in a setTimeout so the menu has time
+                       // to be positioned and fixed
+                       setTimeout(
+                               function () {
+                                       this.getMenu().scrollToTop();
+                               }.bind( this )
+                       );
                }
-       };
-
-       /**
-        * Respond to model itemUpdate event
-        * fixme: when a new state is applied to the model this function is called 60+ times in a row
-        *
-        * @param {mw.rcfilters.dm.FilterItem} item Filter item model
-        */
-       FilterTagMultiselectWidget.prototype.onModelItemUpdate = function ( item ) {
-               if ( !item.getGroupModel().isHidden() ) {
-                       if (
-                               item.isSelected() ||
-                               (
-                                       this.model.isHighlightEnabled() &&
-                                       item.getHighlightColor()
-                               )
-                       ) {
-                               this.addTag( item.getName(), item.getLabel() );
-                       } else {
-                               // Only attempt to remove the tag if we can find an item for it (T198140, T198231)
-                               if ( this.findItemFromData( item.getName() ) !== null ) {
-                                       this.removeTagByData( item.getName() );
-                               }
+       } else {
+               // Clear selection
+               this.selectTag( null );
+
+               // Clear the search
+               this.controller.setSearch( '' );
+
+               // Log filter grouping
+               this.controller.trackFilterGroupings( 'filtermenu' );
+
+               this.blur();
+       }
+
+       this.input.setIcon( isVisible ? 'search' : 'menu' );
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.onInputFocus = function () {
+       // Parent
+       FilterTagMultiselectWidget.parent.prototype.onInputFocus.call( this );
+
+       // Only scroll to top of the viewport if:
+       // - The widget is more than 20px from the top
+       // - The widget is not above the top of the viewport (do not scroll downwards)
+       //   (This isn't represented because >20 is, anyways and always, bigger than 0)
+       this.scrollToTop( this.$element, 0, { min: 20, max: Infinity } );
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.doInputEscape = function () {
+       // Parent
+       FilterTagMultiselectWidget.parent.prototype.doInputEscape.call( this );
+
+       // Blur the input
+       this.input.$input.trigger( 'blur' );
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.onMouseDown = function ( e ) {
+       if ( !this.collapsed && !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               this.menu.toggle();
+
+               return false;
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.onChangeTags = function () {
+       // If initialized, call parent method.
+       if ( this.controller.isInitialized() ) {
+               FilterTagMultiselectWidget.parent.prototype.onChangeTags.call( this );
+       }
+
+       this.emptyFilterMessage.toggle( this.isEmpty() );
+};
+
+/**
+ * Respond to model initialize event
+ */
+FilterTagMultiselectWidget.prototype.onModelInitialize = function () {
+       this.setSavedQueryVisibility();
+};
+
+/**
+ * Respond to model update event
+ */
+FilterTagMultiselectWidget.prototype.onModelUpdate = function () {
+       this.updateElementsForView();
+};
+
+/**
+ * Update the elements in the widget to the current view
+ */
+FilterTagMultiselectWidget.prototype.updateElementsForView = function () {
+       var view = this.model.getCurrentView(),
+               inputValue = this.input.getValue().trim(),
+               inputView = this.model.getViewByTrigger( inputValue.substr( 0, 1 ) );
+
+       if ( inputView !== 'default' ) {
+               // We have a prefix already, remove it
+               inputValue = inputValue.substr( 1 );
+       }
+
+       if ( inputView !== view ) {
+               // Add the correct prefix
+               inputValue = this.model.getViewTrigger( view ) + inputValue;
+       }
+
+       // Update input
+       this.input.setValue( inputValue );
+
+       if ( this.currentView !== view ) {
+               this.scrollToTop( this.$element );
+               this.currentView = view;
+       }
+};
+
+/**
+ * Set the visibility of the saved query button
+ */
+FilterTagMultiselectWidget.prototype.setSavedQueryVisibility = function () {
+       if ( mw.user.isAnon() ) {
+               return;
+       }
+
+       this.matchingQuery = this.controller.findQueryMatchingCurrentState();
+
+       this.savedQueryTitle.setLabel(
+               this.matchingQuery ? this.matchingQuery.getLabel() : ''
+       );
+       this.savedQueryTitle.toggle( !!this.matchingQuery );
+       this.saveQueryButton.setDisabled( !!this.matchingQuery );
+       this.saveQueryButton.setTitle( !this.matchingQuery ?
+               mw.msg( 'rcfilters-savedqueries-add-new-title' ) :
+               mw.msg( 'rcfilters-savedqueries-already-saved' ) );
+
+       if ( this.matchingQuery ) {
+               this.emphasize();
+       }
+};
+
+/**
+ * Respond to model itemUpdate event
+ * fixme: when a new state is applied to the model this function is called 60+ times in a row
+ *
+ * @param {mw.rcfilters.dm.FilterItem} item Filter item model
+ */
+FilterTagMultiselectWidget.prototype.onModelItemUpdate = function ( item ) {
+       if ( !item.getGroupModel().isHidden() ) {
+               if (
+                       item.isSelected() ||
+                       (
+                               this.model.isHighlightEnabled() &&
+                               item.getHighlightColor()
+                       )
+               ) {
+                       this.addTag( item.getName(), item.getLabel() );
+               } else {
+                       // Only attempt to remove the tag if we can find an item for it (T198140, T198231)
+                       if ( this.findItemFromData( item.getName() ) !== null ) {
+                               this.removeTagByData( item.getName() );
                        }
                }
-
-               this.setSavedQueryVisibility();
-
-               // Re-evaluate reset state
-               this.reevaluateResetRestoreState();
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.isAllowedData = function ( data ) {
-               return (
-                       this.model.getItemByName( data ) &&
-                       !this.isDuplicateData( data )
-               );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.onMenuChoose = function ( item ) {
-               this.controller.toggleFilterSelect( item.model.getName() );
-
-               // Select the tag if it exists, or reset selection otherwise
-               this.selectTag( this.findItemFromData( item.model.getName() ) );
-
-               this.focus();
-       };
-
-       /**
-        * Respond to highlightChange event
-        *
-        * @param {boolean} isHighlightEnabled Highlight is enabled
-        */
-       FilterTagMultiselectWidget.prototype.onModelHighlightChange = function ( isHighlightEnabled ) {
-               var highlightedItems = this.model.getHighlightedItems();
-
-               if ( isHighlightEnabled ) {
-                       // Add capsule widgets
-                       highlightedItems.forEach( function ( filterItem ) {
-                               this.addTag( filterItem.getName(), filterItem.getLabel() );
-                       }.bind( this ) );
-               } else {
-                       // Remove capsule widgets if they're not selected
-                       highlightedItems.forEach( function ( filterItem ) {
-                               if ( !filterItem.isSelected() ) {
-                                       // Only attempt to remove the tag if we can find an item for it (T198140, T198231)
-                                       if ( this.findItemFromData( filterItem.getName() ) !== null ) {
-                                               this.removeTagByData( filterItem.getName() );
-                                       }
+       }
+
+       this.setSavedQueryVisibility();
+
+       // Re-evaluate reset state
+       this.reevaluateResetRestoreState();
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.isAllowedData = function ( data ) {
+       return (
+               this.model.getItemByName( data ) &&
+               !this.isDuplicateData( data )
+       );
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.onMenuChoose = function ( item ) {
+       this.controller.toggleFilterSelect( item.model.getName() );
+
+       // Select the tag if it exists, or reset selection otherwise
+       this.selectTag( this.findItemFromData( item.model.getName() ) );
+
+       this.focus();
+};
+
+/**
+ * Respond to highlightChange event
+ *
+ * @param {boolean} isHighlightEnabled Highlight is enabled
+ */
+FilterTagMultiselectWidget.prototype.onModelHighlightChange = function ( isHighlightEnabled ) {
+       var highlightedItems = this.model.getHighlightedItems();
+
+       if ( isHighlightEnabled ) {
+               // Add capsule widgets
+               highlightedItems.forEach( function ( filterItem ) {
+                       this.addTag( filterItem.getName(), filterItem.getLabel() );
+               }.bind( this ) );
+       } else {
+               // Remove capsule widgets if they're not selected
+               highlightedItems.forEach( function ( filterItem ) {
+                       if ( !filterItem.isSelected() ) {
+                               // Only attempt to remove the tag if we can find an item for it (T198140, T198231)
+                               if ( this.findItemFromData( filterItem.getName() ) !== null ) {
+                                       this.removeTagByData( filterItem.getName() );
                                }
-                       }.bind( this ) );
-               }
-
-               this.setSavedQueryVisibility();
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.onTagSelect = function ( tagItem ) {
-               var menuOption = this.menu.getItemFromModel( tagItem.getModel() );
-
-               this.menu.setUserSelecting( true );
-               // Parent method
-               FilterTagMultiselectWidget.parent.prototype.onTagSelect.call( this, tagItem );
-
-               // Switch view
-               this.controller.resetSearchForView( tagItem.getView() );
-
-               this.selectTag( tagItem );
-               this.scrollToTop( menuOption.$element );
-
-               this.menu.setUserSelecting( false );
-       };
-
-       /**
-        * Select a tag by reference. This is what OO.ui.SelectWidget is doing.
-        * If no items are given, reset selection from all.
-        *
-        * @param {mw.rcfilters.ui.FilterTagItemWidget} [item] Tag to select,
-        *  omit to deselect all
-        */
-       FilterTagMultiselectWidget.prototype.selectTag = function ( item ) {
-               var i, len, selected;
-
-               for ( i = 0, len = this.items.length; i < len; i++ ) {
-                       selected = this.items[ i ] === item;
-                       if ( this.items[ i ].isSelected() !== selected ) {
-                               this.items[ i ].toggleSelected( selected );
                        }
+               }.bind( this ) );
+       }
+
+       this.setSavedQueryVisibility();
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.onTagSelect = function ( tagItem ) {
+       var menuOption = this.menu.getItemFromModel( tagItem.getModel() );
+
+       this.menu.setUserSelecting( true );
+       // Parent method
+       FilterTagMultiselectWidget.parent.prototype.onTagSelect.call( this, tagItem );
+
+       // Switch view
+       this.controller.resetSearchForView( tagItem.getView() );
+
+       this.selectTag( tagItem );
+       this.scrollToTop( menuOption.$element );
+
+       this.menu.setUserSelecting( false );
+};
+
+/**
+ * Select a tag by reference. This is what OO.ui.SelectWidget is doing.
+ * If no items are given, reset selection from all.
+ *
+ * @param {mw.rcfilters.ui.FilterTagItemWidget} [item] Tag to select,
+ *  omit to deselect all
+ */
+FilterTagMultiselectWidget.prototype.selectTag = function ( item ) {
+       var i, len, selected;
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               selected = this.items[ i ] === item;
+               if ( this.items[ i ].isSelected() !== selected ) {
+                       this.items[ i ].toggleSelected( selected );
                }
-       };
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.onTagRemove = function ( tagItem ) {
-               // Parent method
-               FilterTagMultiselectWidget.parent.prototype.onTagRemove.call( this, tagItem );
-
-               this.controller.clearFilter( tagItem.getName() );
-
-               tagItem.destroy();
-       };
-
-       /**
-        * Respond to click event on the reset button
-        */
-       FilterTagMultiselectWidget.prototype.onResetButtonClick = function () {
-               if ( this.model.areVisibleFiltersEmpty() ) {
-                       // Reset to default filters
-                       this.controller.resetToDefaults();
-               } else {
-                       // Reset to have no filters
-                       this.controller.emptyFilters();
-               }
-       };
-
-       /**
-        * Respond to hide/show button click
-        */
-       FilterTagMultiselectWidget.prototype.onHideShowButtonClick = function () {
-               this.toggleCollapsed();
-       };
-
-       /**
-        * Toggle the collapsed state of the filters widget
-        *
-        * @param {boolean} isCollapsed Widget is collapsed
-        */
-       FilterTagMultiselectWidget.prototype.toggleCollapsed = function ( isCollapsed ) {
-               isCollapsed = isCollapsed === undefined ? !this.collapsed : !!isCollapsed;
-
-               this.collapsed = isCollapsed;
-
-               if ( isCollapsed ) {
-                       // If we are collapsing, close the menu, in case it was open
-                       // We should make sure the menu closes before the rest of the elements
-                       // are hidden, otherwise there is an unknown error in jQuery as ooui
-                       // sets and unsets properties on the input (which is hidden at that point)
-                       this.menu.toggle( false );
-               }
-               this.input.setDisabled( isCollapsed );
-               this.hideShowButton.setLabel( mw.msg(
-                       isCollapsed ? 'rcfilters-activefilters-show' : 'rcfilters-activefilters-hide'
-               ) );
-               this.hideShowButton.setTitle( mw.msg(
-                       isCollapsed ? 'rcfilters-activefilters-show-tooltip' : 'rcfilters-activefilters-hide-tooltip'
-               ) );
-
-               // Toggle the wrapper class, so we have min height values correctly throughout
-               this.$wrapper.toggleClass( 'mw-rcfilters-collapsed', isCollapsed );
-
-               // Save the state
-               this.controller.updateCollapsedState( isCollapsed );
-       };
-
-       /**
-        * Reevaluate the restore state for the widget between setting to defaults and clearing all filters
-        */
-       FilterTagMultiselectWidget.prototype.reevaluateResetRestoreState = function () {
-               var defaultsAreEmpty = this.controller.areDefaultsEmpty(),
-                       currFiltersAreEmpty = this.model.areVisibleFiltersEmpty(),
-                       hideResetButton = currFiltersAreEmpty && defaultsAreEmpty;
-
-               this.resetButton.setIcon(
-                       currFiltersAreEmpty ? 'history' : 'trash'
-               );
-
-               this.resetButton.setLabel(
-                       currFiltersAreEmpty ? mw.msg( 'rcfilters-restore-default-filters' ) : ''
-               );
-               this.resetButton.setTitle(
-                       currFiltersAreEmpty ? null : mw.msg( 'rcfilters-clear-all-filters' )
-               );
-
-               this.resetButton.toggle( !hideResetButton );
-               this.emptyFilterMessage.toggle( currFiltersAreEmpty );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.createMenuWidget = function ( menuConfig ) {
-               return new MenuSelectWidget(
+       }
+};
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.onTagRemove = function ( tagItem ) {
+       // Parent method
+       FilterTagMultiselectWidget.parent.prototype.onTagRemove.call( this, tagItem );
+
+       this.controller.clearFilter( tagItem.getName() );
+
+       tagItem.destroy();
+};
+
+/**
+ * Respond to click event on the reset button
+ */
+FilterTagMultiselectWidget.prototype.onResetButtonClick = function () {
+       if ( this.model.areVisibleFiltersEmpty() ) {
+               // Reset to default filters
+               this.controller.resetToDefaults();
+       } else {
+               // Reset to have no filters
+               this.controller.emptyFilters();
+       }
+};
+
+/**
+ * Respond to hide/show button click
+ */
+FilterTagMultiselectWidget.prototype.onHideShowButtonClick = function () {
+       this.toggleCollapsed();
+};
+
+/**
+ * Toggle the collapsed state of the filters widget
+ *
+ * @param {boolean} isCollapsed Widget is collapsed
+ */
+FilterTagMultiselectWidget.prototype.toggleCollapsed = function ( isCollapsed ) {
+       isCollapsed = isCollapsed === undefined ? !this.collapsed : !!isCollapsed;
+
+       this.collapsed = isCollapsed;
+
+       if ( isCollapsed ) {
+               // If we are collapsing, close the menu, in case it was open
+               // We should make sure the menu closes before the rest of the elements
+               // are hidden, otherwise there is an unknown error in jQuery as ooui
+               // sets and unsets properties on the input (which is hidden at that point)
+               this.menu.toggle( false );
+       }
+       this.input.setDisabled( isCollapsed );
+       this.hideShowButton.setLabel( mw.msg(
+               isCollapsed ? 'rcfilters-activefilters-show' : 'rcfilters-activefilters-hide'
+       ) );
+       this.hideShowButton.setTitle( mw.msg(
+               isCollapsed ? 'rcfilters-activefilters-show-tooltip' : 'rcfilters-activefilters-hide-tooltip'
+       ) );
+
+       // Toggle the wrapper class, so we have min height values correctly throughout
+       this.$wrapper.toggleClass( 'mw-rcfilters-collapsed', isCollapsed );
+
+       // Save the state
+       this.controller.updateCollapsedState( isCollapsed );
+};
+
+/**
+ * Reevaluate the restore state for the widget between setting to defaults and clearing all filters
+ */
+FilterTagMultiselectWidget.prototype.reevaluateResetRestoreState = function () {
+       var defaultsAreEmpty = this.controller.areDefaultsEmpty(),
+               currFiltersAreEmpty = this.model.areVisibleFiltersEmpty(),
+               hideResetButton = currFiltersAreEmpty && defaultsAreEmpty;
+
+       this.resetButton.setIcon(
+               currFiltersAreEmpty ? 'history' : 'trash'
+       );
+
+       this.resetButton.setLabel(
+               currFiltersAreEmpty ? mw.msg( 'rcfilters-restore-default-filters' ) : ''
+       );
+       this.resetButton.setTitle(
+               currFiltersAreEmpty ? null : mw.msg( 'rcfilters-clear-all-filters' )
+       );
+
+       this.resetButton.toggle( !hideResetButton );
+       this.emptyFilterMessage.toggle( currFiltersAreEmpty );
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.createMenuWidget = function ( menuConfig ) {
+       return new MenuSelectWidget(
+               this.controller,
+               this.model,
+               menuConfig
+       );
+};
+
+/**
+ * @inheritdoc
+ */
+FilterTagMultiselectWidget.prototype.createTagItemWidget = function ( data ) {
+       var filterItem = this.model.getItemByName( data );
+
+       if ( filterItem ) {
+               return new FilterTagItemWidget(
                        this.controller,
                        this.model,
-                       menuConfig
+                       this.model.getInvertModel(),
+                       filterItem,
+                       {
+                               $overlay: this.$overlay
+                       }
                );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       FilterTagMultiselectWidget.prototype.createTagItemWidget = function ( data ) {
-               var filterItem = this.model.getItemByName( data );
-
-               if ( filterItem ) {
-                       return new FilterTagItemWidget(
-                               this.controller,
-                               this.model,
-                               this.model.getInvertModel(),
-                               filterItem,
-                               {
-                                       $overlay: this.$overlay
-                               }
-                       );
-               }
-       };
-
-       FilterTagMultiselectWidget.prototype.emphasize = function () {
-               if (
-                       !this.$handle.hasClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-animate' )
-               ) {
+       }
+};
+
+FilterTagMultiselectWidget.prototype.emphasize = function () {
+       if (
+               !this.$handle.hasClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-animate' )
+       ) {
+               this.$handle
+                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-emphasize' )
+                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-animate' );
+
+               setTimeout( function () {
                        this.$handle
-                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-emphasize' )
-                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-animate' );
+                               .removeClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-emphasize' );
 
                        setTimeout( function () {
                                this.$handle
-                                       .removeClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-emphasize' );
-
-                               setTimeout( function () {
-                                       this.$handle
-                                               .removeClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-animate' );
-                               }.bind( this ), 1000 );
-                       }.bind( this ), 500 );
-
-               }
-       };
-       /**
-        * Scroll the element to top within its container
-        *
-        * @private
-        * @param {jQuery} $element Element to position
-        * @param {number} [marginFromTop=0] When scrolling the entire widget to the top, leave this
-        *  much space (in pixels) above the widget.
-        * @param {Object} [threshold] Minimum distance from the top of the element to scroll at all
-        * @param {number} [threshold.min] Minimum distance above the element
-        * @param {number} [threshold.max] Minimum distance below the element
-        */
-       FilterTagMultiselectWidget.prototype.scrollToTop = function ( $element, marginFromTop, threshold ) {
-               var container = OO.ui.Element.static.getClosestScrollableContainer( $element[ 0 ], 'y' ),
-                       pos = OO.ui.Element.static.getRelativePosition( $element, $( container ) ),
-                       containerScrollTop = $( container ).scrollTop(),
-                       effectiveScrollTop = $( container ).is( 'body, html' ) ? 0 : containerScrollTop,
-                       newScrollTop = effectiveScrollTop + pos.top - ( marginFromTop || 0 );
-
-               // Scroll to item
-               if (
-                       threshold === undefined ||
+                                       .removeClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-animate' );
+                       }.bind( this ), 1000 );
+               }.bind( this ), 500 );
+
+       }
+};
+/**
+ * Scroll the element to top within its container
+ *
+ * @private
+ * @param {jQuery} $element Element to position
+ * @param {number} [marginFromTop=0] When scrolling the entire widget to the top, leave this
+ *  much space (in pixels) above the widget.
+ * @param {Object} [threshold] Minimum distance from the top of the element to scroll at all
+ * @param {number} [threshold.min] Minimum distance above the element
+ * @param {number} [threshold.max] Minimum distance below the element
+ */
+FilterTagMultiselectWidget.prototype.scrollToTop = function ( $element, marginFromTop, threshold ) {
+       var container = OO.ui.Element.static.getClosestScrollableContainer( $element[ 0 ], 'y' ),
+               pos = OO.ui.Element.static.getRelativePosition( $element, $( container ) ),
+               containerScrollTop = $( container ).scrollTop(),
+               effectiveScrollTop = $( container ).is( 'body, html' ) ? 0 : containerScrollTop,
+               newScrollTop = effectiveScrollTop + pos.top - ( marginFromTop || 0 );
+
+       // Scroll to item
+       if (
+               threshold === undefined ||
+               (
+                       (
+                               threshold.min === undefined ||
+                               newScrollTop - containerScrollTop >= threshold.min
+                       ) &&
                        (
-                               (
-                                       threshold.min === undefined ||
-                                       newScrollTop - containerScrollTop >= threshold.min
-                               ) &&
-                               (
-                                       threshold.max === undefined ||
-                                       newScrollTop - containerScrollTop <= threshold.max
-                               )
+                               threshold.max === undefined ||
+                               newScrollTop - containerScrollTop <= threshold.max
                        )
-               ) {
-                       $( container ).animate( {
-                               scrollTop: newScrollTop
-                       } );
-               }
-       };
+               )
+       ) {
+               $( container ).animate( {
+                       scrollTop: newScrollTop
+               } );
+       }
+};
 
-       module.exports = FilterTagMultiselectWidget;
-}() );
+module.exports = FilterTagMultiselectWidget;
index cb297f6..ce9656e 100644 (file)
-( function () {
-       var FilterTagMultiselectWidget = require( './FilterTagMultiselectWidget.js' ),
-               LiveUpdateButtonWidget = require( './LiveUpdateButtonWidget.js' ),
-               ChangesLimitAndDateButtonWidget = require( './ChangesLimitAndDateButtonWidget.js' ),
-               FilterWrapperWidget;
-
-       /**
-        * List displaying all filter groups
-        *
-        * @class mw.rcfilters.ui.FilterWrapperWidget
-        * @extends OO.ui.Widget
-        * @mixins OO.ui.mixin.PendingElement
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
-        * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
-        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
-        * @param {Object} [config] Configuration object
-        * @cfg {Object} [filters] A definition of the filter groups in this list
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        * @cfg {jQuery} [$wrapper] A jQuery object for the wrapper of the general
-        *  system. If not given, falls back to this widget's $element
-        * @cfg {boolean} [collapsed] Filter area is collapsed
-        */
-       FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget(
-               controller, model, savedQueriesModel, changesListModel, config
-       ) {
-               var $bottom;
-               config = config || {};
-
-               // Parent
-               FilterWrapperWidget.parent.call( this, config );
-               // Mixin constructors
-               OO.ui.mixin.PendingElement.call( this, config );
-
-               this.controller = controller;
-               this.model = model;
-               this.queriesModel = savedQueriesModel;
-               this.changesListModel = changesListModel;
-               this.$overlay = config.$overlay || this.$element;
-               this.$wrapper = config.$wrapper || this.$element;
-
-               this.filterTagWidget = new FilterTagMultiselectWidget(
-                       this.controller,
-                       this.model,
-                       this.queriesModel,
-                       {
-                               $overlay: this.$overlay,
-                               collapsed: config.collapsed,
-                               $wrapper: this.$wrapper
-                       }
+var FilterTagMultiselectWidget = require( './FilterTagMultiselectWidget.js' ),
+       LiveUpdateButtonWidget = require( './LiveUpdateButtonWidget.js' ),
+       ChangesLimitAndDateButtonWidget = require( './ChangesLimitAndDateButtonWidget.js' ),
+       FilterWrapperWidget;
+
+/**
+ * List displaying all filter groups
+ *
+ * @class mw.rcfilters.ui.FilterWrapperWidget
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.PendingElement
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
+ * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
+ * @param {Object} [config] Configuration object
+ * @cfg {Object} [filters] A definition of the filter groups in this list
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ * @cfg {jQuery} [$wrapper] A jQuery object for the wrapper of the general
+ *  system. If not given, falls back to this widget's $element
+ * @cfg {boolean} [collapsed] Filter area is collapsed
+ */
+FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget(
+       controller, model, savedQueriesModel, changesListModel, config
+) {
+       var $bottom;
+       config = config || {};
+
+       // Parent
+       FilterWrapperWidget.parent.call( this, config );
+       // Mixin constructors
+       OO.ui.mixin.PendingElement.call( this, config );
+
+       this.controller = controller;
+       this.model = model;
+       this.queriesModel = savedQueriesModel;
+       this.changesListModel = changesListModel;
+       this.$overlay = config.$overlay || this.$element;
+       this.$wrapper = config.$wrapper || this.$element;
+
+       this.filterTagWidget = new FilterTagMultiselectWidget(
+               this.controller,
+               this.model,
+               this.queriesModel,
+               {
+                       $overlay: this.$overlay,
+                       collapsed: config.collapsed,
+                       $wrapper: this.$wrapper
+               }
+       );
+
+       this.liveUpdateButton = new LiveUpdateButtonWidget(
+               this.controller,
+               this.changesListModel
+       );
+
+       this.numChangesAndDateWidget = new ChangesLimitAndDateButtonWidget(
+               this.controller,
+               this.model,
+               {
+                       $overlay: this.$overlay
+               }
+       );
+
+       this.showNewChangesLink = new OO.ui.ButtonWidget( {
+               icon: 'reload',
+               framed: false,
+               label: mw.msg( 'rcfilters-show-new-changes' ),
+               flags: [ 'progressive' ],
+               classes: [ 'mw-rcfilters-ui-filterWrapperWidget-showNewChanges' ]
+       } );
+
+       // Events
+       this.filterTagWidget.menu.connect( this, { toggle: [ 'emit', 'menuToggle' ] } );
+       this.changesListModel.connect( this, { newChangesExist: 'onNewChangesExist' } );
+       this.showNewChangesLink.connect( this, { click: 'onShowNewChangesClick' } );
+       this.showNewChangesLink.toggle( false );
+
+       // Initialize
+       this.$top = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-filterWrapperWidget-top' );
+
+       $bottom = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-filterWrapperWidget-bottom' )
+               .append(
+                       this.showNewChangesLink.$element,
+                       this.numChangesAndDateWidget.$element
                );
 
-               this.liveUpdateButton = new LiveUpdateButtonWidget(
-                       this.controller,
-                       this.changesListModel
-               );
+       if ( this.controller.pollingRate ) {
+               $bottom.prepend( this.liveUpdateButton.$element );
+       }
 
-               this.numChangesAndDateWidget = new ChangesLimitAndDateButtonWidget(
-                       this.controller,
-                       this.model,
-                       {
-                               $overlay: this.$overlay
-                       }
+       this.$element
+               .addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
+               .append(
+                       this.$top,
+                       this.filterTagWidget.$element,
+                       $bottom
                );
-
-               this.showNewChangesLink = new OO.ui.ButtonWidget( {
-                       icon: 'reload',
-                       framed: false,
-                       label: mw.msg( 'rcfilters-show-new-changes' ),
-                       flags: [ 'progressive' ],
-                       classes: [ 'mw-rcfilters-ui-filterWrapperWidget-showNewChanges' ]
-               } );
-
-               // Events
-               this.filterTagWidget.menu.connect( this, { toggle: [ 'emit', 'menuToggle' ] } );
-               this.changesListModel.connect( this, { newChangesExist: 'onNewChangesExist' } );
-               this.showNewChangesLink.connect( this, { click: 'onShowNewChangesClick' } );
-               this.showNewChangesLink.toggle( false );
-
-               // Initialize
-               this.$top = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget-top' );
-
-               $bottom = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget-bottom' )
-                       .append(
-                               this.showNewChangesLink.$element,
-                               this.numChangesAndDateWidget.$element
-                       );
-
-               if ( this.controller.pollingRate ) {
-                       $bottom.prepend( this.liveUpdateButton.$element );
-               }
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
-                       .append(
-                               this.$top,
-                               this.filterTagWidget.$element,
-                               $bottom
-                       );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( FilterWrapperWidget, OO.ui.Widget );
-       OO.mixinClass( FilterWrapperWidget, OO.ui.mixin.PendingElement );
-
-       /* Methods */
-
-       /**
-        * Set the content of the top section
-        *
-        * @param {jQuery} $topSectionElement
-        */
-       FilterWrapperWidget.prototype.setTopSection = function ( $topSectionElement ) {
-               this.$top.append( $topSectionElement );
-       };
-
-       /**
-        * Respond to the user clicking the 'show new changes' button
-        */
-       FilterWrapperWidget.prototype.onShowNewChangesClick = function () {
-               this.controller.showNewChanges();
-       };
-
-       /**
-        * Respond to changes list model newChangesExist
-        *
-        * @param {boolean} newChangesExist Whether new changes exist
-        */
-       FilterWrapperWidget.prototype.onNewChangesExist = function ( newChangesExist ) {
-               this.showNewChangesLink.toggle( newChangesExist );
-       };
-
-       module.exports = FilterWrapperWidget;
-}() );
+};
+
+/* Initialization */
+
+OO.inheritClass( FilterWrapperWidget, OO.ui.Widget );
+OO.mixinClass( FilterWrapperWidget, OO.ui.mixin.PendingElement );
+
+/* Methods */
+
+/**
+ * Set the content of the top section
+ *
+ * @param {jQuery} $topSectionElement
+ */
+FilterWrapperWidget.prototype.setTopSection = function ( $topSectionElement ) {
+       this.$top.append( $topSectionElement );
+};
+
+/**
+ * Respond to the user clicking the 'show new changes' button
+ */
+FilterWrapperWidget.prototype.onShowNewChangesClick = function () {
+       this.controller.showNewChanges();
+};
+
+/**
+ * Respond to changes list model newChangesExist
+ *
+ * @param {boolean} newChangesExist Whether new changes exist
+ */
+FilterWrapperWidget.prototype.onNewChangesExist = function ( newChangesExist ) {
+       this.showNewChangesLink.toggle( newChangesExist );
+};
+
+module.exports = FilterWrapperWidget;
index dbf1776..7d69fb6 100644 (file)
-( function () {
-       /**
-        * Wrapper for the RC form with hide/show links
-        * Must be constructed after the model is initialized.
-        *
-        * @class mw.rcfilters.ui.FormWrapperWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @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
-        */
-       var FormWrapperWidget = function MwRcfiltersUiFormWrapperWidget( filtersModel, changeListModel, controller, $formRoot, config ) {
-               config = config || {};
-
-               // Parent
-               FormWrapperWidget.parent.call( this, $.extend( {}, config, {
-                       $element: $formRoot
-               } ) );
-
-               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.changeListModel.connect( this, {
-                       invalidate: 'onChangesModelInvalidate',
-                       update: 'onChangesModelUpdate'
-               } );
-
-               // Initialize
-               this.cleanUpFieldset();
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-FormWrapperWidget' );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( FormWrapperWidget, OO.ui.Widget );
-
-       /**
-        * Respond to link click
-        *
-        * @param {jQuery.Event} e Event
-        * @return {boolean} false
-        */
-       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
-        */
-       FormWrapperWidget.prototype.onFormSubmit = function ( e ) {
-               var data = {};
-
-               // Collect all data from form
-               $( e.target ).find( 'input:not([type="hidden"],[type="submit"]), select' ).each( function () {
-                       var value = '';
-
-                       if ( !$( this ).is( ':checkbox' ) || $( this ).is( ':checked' ) ) {
-                               value = $( this ).val();
-                       }
-
-                       data[ $( this ).prop( 'name' ) ] = value;
-               } );
-
-               this.controller.updateChangesList( data );
-               return false;
-       };
-
-       /**
-        * Respond to model invalidate
-        */
-       FormWrapperWidget.prototype.onChangesModelInvalidate = function () {
-               this.$submitButton.prop( 'disabled', true );
-       };
-
-       /**
-        * 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
-        * @param {string} noResultsDetails Type of no result error
-        * @param {boolean} isInitialDOM Whether $changesListContent is the existing (already attached) DOM
-        */
-       FormWrapperWidget.prototype.onChangesModelUpdate = function ( $changesList, $fieldset, noResultsDetails, isInitialDOM ) {
-               this.$submitButton.prop( 'disabled', false );
-
-               // Replace the entire fieldset
-               this.$element.empty().append( $fieldset.contents() );
-
-               if ( !isInitialDOM ) {
-                       // Make sure enhanced RC re-initializes correctly
-                       mw.hook( 'wikipage.content' ).fire( this.$element );
+/**
+ * Wrapper for the RC form with hide/show links
+ * Must be constructed after the model is initialized.
+ *
+ * @class mw.rcfilters.ui.FormWrapperWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @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
+ */
+var FormWrapperWidget = function MwRcfiltersUiFormWrapperWidget( filtersModel, changeListModel, controller, $formRoot, config ) {
+       config = config || {};
+
+       // Parent
+       FormWrapperWidget.parent.call( this, $.extend( {}, config, {
+               $element: $formRoot
+       } ) );
+
+       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.changeListModel.connect( this, {
+               invalidate: 'onChangesModelInvalidate',
+               update: 'onChangesModelUpdate'
+       } );
+
+       // Initialize
+       this.cleanUpFieldset();
+       this.$element
+               .addClass( 'mw-rcfilters-ui-FormWrapperWidget' );
+};
+
+/* Initialization */
+
+OO.inheritClass( FormWrapperWidget, OO.ui.Widget );
+
+/**
+ * Respond to link click
+ *
+ * @param {jQuery.Event} e Event
+ * @return {boolean} false
+ */
+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
+ */
+FormWrapperWidget.prototype.onFormSubmit = function ( e ) {
+       var data = {};
+
+       // Collect all data from form
+       $( e.target ).find( 'input:not([type="hidden"],[type="submit"]), select' ).each( function () {
+               var value = '';
+
+               if ( !$( this ).is( ':checkbox' ) || $( this ).is( ':checked' ) ) {
+                       value = $( this ).val();
                }
 
-               this.cleanUpFieldset();
-       };
-
-       /**
-        * Clean up the old-style show/hide that we have implemented in the filter list
-        */
-       FormWrapperWidget.prototype.cleanUpFieldset = function () {
-               this.$element.find( '.clshowhideoption[data-feature-in-structured-ui=1]' ).each( function () {
-                       // 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 );
-               } );
-
-               // Hide namespaces and tags
-               this.$element.find( '.namespaceForm' ).detach();
-               this.$element.find( '.mw-tagfilter-label' ).closest( 'tr' ).detach();
-
-               // Hide Related Changes page name form
-               this.$element.find( '.targetForm' ).detach();
-
-               // misc: limit, days, watchlist info msg
-               this.$element.find( '.rclinks, .cldays, .wlinfo' ).detach();
-
-               if ( !this.$element.find( '.mw-recentchanges-table tr' ).length ) {
-                       this.$element.find( '.mw-recentchanges-table' ).detach();
-                       this.$element.find( 'hr' ).detach();
+               data[ $( this ).prop( 'name' ) ] = value;
+       } );
+
+       this.controller.updateChangesList( data );
+       return false;
+};
+
+/**
+ * Respond to model invalidate
+ */
+FormWrapperWidget.prototype.onChangesModelInvalidate = function () {
+       this.$submitButton.prop( 'disabled', true );
+};
+
+/**
+ * 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
+ * @param {string} noResultsDetails Type of no result error
+ * @param {boolean} isInitialDOM Whether $changesListContent is the existing (already attached) DOM
+ */
+FormWrapperWidget.prototype.onChangesModelUpdate = function ( $changesList, $fieldset, noResultsDetails, isInitialDOM ) {
+       this.$submitButton.prop( 'disabled', false );
+
+       // Replace the entire fieldset
+       this.$element.empty().append( $fieldset.contents() );
+
+       if ( !isInitialDOM ) {
+               // Make sure enhanced RC re-initializes correctly
+               mw.hook( 'wikipage.content' ).fire( this.$element );
+       }
+
+       this.cleanUpFieldset();
+};
+
+/**
+ * Clean up the old-style show/hide that we have implemented in the filter list
+ */
+FormWrapperWidget.prototype.cleanUpFieldset = function () {
+       this.$element.find( '.clshowhideoption[data-feature-in-structured-ui=1]' ).each( function () {
+               // 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 );
                }
-
-               // Get rid of all <br>s, which are inside rcshowhide
-               // If we still have content in rcshowhide, the <br>s are
-               // gone. Instead, the CSS now has a rule to mark all <span>s
-               // inside .rcshowhide with display:block; to simulate newlines
-               // where they're actually needed.
-               this.$element.find( 'br' ).detach();
-               if ( !this.$element.find( '.rcshowhide' ).contents().length ) {
-                       this.$element.find( '.rcshowhide' ).detach();
-               }
-
-               if ( this.$element.find( '.cloption' ).text().trim() === '' ) {
-                       this.$element.find( '.cloption-submit' ).detach();
-               }
-
-               this.$element.find(
-                       '.rclistfrom, .rcnotefrom, .rcoptions-listfromreset'
-               ).detach();
-
-               // Get rid of the legend
-               this.$element.find( 'legend' ).detach();
-
-               // Check if the element is essentially empty, and detach it if it is
-               if ( !this.$element.text().trim().length ) {
-                       this.$element.detach();
-               }
-       };
-
-       module.exports = FormWrapperWidget;
-}() );
+               // Remove the span itself
+               this.parentNode.removeChild( this );
+       } );
+
+       // Hide namespaces and tags
+       this.$element.find( '.namespaceForm' ).detach();
+       this.$element.find( '.mw-tagfilter-label' ).closest( 'tr' ).detach();
+
+       // Hide Related Changes page name form
+       this.$element.find( '.targetForm' ).detach();
+
+       // misc: limit, days, watchlist info msg
+       this.$element.find( '.rclinks, .cldays, .wlinfo' ).detach();
+
+       if ( !this.$element.find( '.mw-recentchanges-table tr' ).length ) {
+               this.$element.find( '.mw-recentchanges-table' ).detach();
+               this.$element.find( 'hr' ).detach();
+       }
+
+       // Get rid of all <br>s, which are inside rcshowhide
+       // If we still have content in rcshowhide, the <br>s are
+       // gone. Instead, the CSS now has a rule to mark all <span>s
+       // inside .rcshowhide with display:block; to simulate newlines
+       // where they're actually needed.
+       this.$element.find( 'br' ).detach();
+       if ( !this.$element.find( '.rcshowhide' ).contents().length ) {
+               this.$element.find( '.rcshowhide' ).detach();
+       }
+
+       if ( this.$element.find( '.cloption' ).text().trim() === '' ) {
+               this.$element.find( '.cloption-submit' ).detach();
+       }
+
+       this.$element.find(
+               '.rclistfrom, .rcnotefrom, .rcoptions-listfromreset'
+       ).detach();
+
+       // Get rid of the legend
+       this.$element.find( 'legend' ).detach();
+
+       // Check if the element is essentially empty, and detach it if it is
+       if ( !this.$element.text().trim().length ) {
+               this.$element.detach();
+       }
+};
+
+module.exports = FormWrapperWidget;
index 73b874c..12d53bb 100644 (file)
@@ -1,45 +1,43 @@
-( function () {
-       /**
-        * A group widget to allow for aggregation of events
-        *
-        * @class mw.rcfilters.ui.GroupWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {Object} [config] Configuration object
-        * @param {Object} [events] Events to aggregate. The object represent the
-        *  event name to aggregate and the event value to emit on aggregate for items.
-        */
-       var GroupWidget = function MwRcfiltersUiViewSwitchWidget( config ) {
-               var aggregate = {};
-
-               config = config || {};
-
-               // Parent constructor
-               GroupWidget.parent.call( this, config );
-
-               // Mixin constructors
-               OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
-
-               if ( config.events ) {
-                       // Aggregate events
-                       // eslint-disable-next-line no-jquery/no-each-util
-                       $.each( config.events, function ( eventName, eventEmit ) {
-                               aggregate[ eventName ] = eventEmit;
-                       } );
-
-                       this.aggregate( aggregate );
-               }
-
-               if ( Array.isArray( config.items ) ) {
-                       this.addItems( config.items );
-               }
-       };
-
-       /* Initialize */
-
-       OO.inheritClass( GroupWidget, OO.ui.Widget );
-       OO.mixinClass( GroupWidget, OO.ui.mixin.GroupWidget );
-
-       module.exports = GroupWidget;
-}() );
+/**
+ * A group widget to allow for aggregation of events
+ *
+ * @class mw.rcfilters.ui.GroupWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration object
+ * @cfg {Object} [events] Events to aggregate. The object represent the
+ *  event name to aggregate and the event value to emit on aggregate for items.
+ */
+var GroupWidget = function MwRcfiltersUiViewSwitchWidget( config ) {
+       var aggregate = {};
+
+       config = config || {};
+
+       // Parent constructor
+       GroupWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+
+       if ( config.events ) {
+               // Aggregate events
+               // eslint-disable-next-line no-jquery/no-each-util
+               $.each( config.events, function ( eventName, eventEmit ) {
+                       aggregate[ eventName ] = eventEmit;
+               } );
+
+               this.aggregate( aggregate );
+       }
+
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+};
+
+/* Initialize */
+
+OO.inheritClass( GroupWidget, OO.ui.Widget );
+OO.mixinClass( GroupWidget, OO.ui.mixin.GroupWidget );
+
+module.exports = GroupWidget;
index cb5f8eb..082b65b 100644 (file)
-( function () {
-       /**
-        * A widget representing a filter item highlight color picker
-        *
-        * @class mw.rcfilters.ui.HighlightColorPickerWidget
-        * @extends OO.ui.Widget
-        * @mixins OO.ui.mixin.LabelElement
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller RCFilters controller
-        * @param {Object} [config] Configuration object
-        */
-       var HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, config ) {
-               var colors = [ 'none' ].concat( mw.rcfilters.HighlightColors );
-               config = config || {};
-
-               // Parent
-               HighlightColorPickerWidget.parent.call( this, config );
-               // Mixin constructors
-               OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {
-                       label: mw.message( 'rcfilters-highlightmenu-title' ).text()
-               } ) );
-
-               this.controller = controller;
-
-               this.currentSelection = 'none';
-               this.buttonSelect = new OO.ui.ButtonSelectWidget( {
-                       items: colors.map( function ( color ) {
-                               return new OO.ui.ButtonOptionWidget( {
-                                       icon: color === 'none' ? 'check' : null,
-                                       data: color,
-                                       classes: [
-                                               'mw-rcfilters-ui-highlightColorPickerWidget-buttonSelect-color',
-                                               'mw-rcfilters-ui-highlightColorPickerWidget-buttonSelect-color-' + color
-                                       ],
-                                       framed: false
-                               } );
-                       } ),
-                       classes: 'mw-rcfilters-ui-highlightColorPickerWidget-buttonSelect'
-               } );
-
-               // Event
-               this.buttonSelect.connect( this, { choose: 'onChooseColor' } );
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget' )
-                       .append(
-                               this.$label
-                                       .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget-label' ),
-                               this.buttonSelect.$element
-                       );
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( HighlightColorPickerWidget, OO.ui.Widget );
-       OO.mixinClass( HighlightColorPickerWidget, OO.ui.mixin.LabelElement );
-
-       /* Events */
-
-       /**
-        * @event chooseColor
-        * @param {string} The chosen color
-        *
-        * A color has been chosen
-        */
-
-       /* Methods */
-
-       /**
-        * Bind the color picker to an item
-        * @param {mw.rcfilters.dm.FilterItem} filterItem
-        */
-       HighlightColorPickerWidget.prototype.setFilterItem = function ( filterItem ) {
-               if ( this.filterItem ) {
-                       this.filterItem.disconnect( this );
+/**
+ * A widget representing a filter item highlight color picker
+ *
+ * @class mw.rcfilters.ui.HighlightColorPickerWidget
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.LabelElement
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller RCFilters controller
+ * @param {Object} [config] Configuration object
+ */
+var HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, config ) {
+       var colors = [ 'none' ].concat( mw.rcfilters.HighlightColors );
+       config = config || {};
+
+       // Parent
+       HighlightColorPickerWidget.parent.call( this, config );
+       // Mixin constructors
+       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {
+               label: mw.message( 'rcfilters-highlightmenu-title' ).text()
+       } ) );
+
+       this.controller = controller;
+
+       this.currentSelection = 'none';
+       this.buttonSelect = new OO.ui.ButtonSelectWidget( {
+               items: colors.map( function ( color ) {
+                       return new OO.ui.ButtonOptionWidget( {
+                               icon: color === 'none' ? 'check' : null,
+                               data: color,
+                               classes: [
+                                       'mw-rcfilters-ui-highlightColorPickerWidget-buttonSelect-color',
+                                       'mw-rcfilters-ui-highlightColorPickerWidget-buttonSelect-color-' + color
+                               ],
+                               framed: false
+                       } );
+               } ),
+               classes: 'mw-rcfilters-ui-highlightColorPickerWidget-buttonSelect'
+       } );
+
+       // Event
+       this.buttonSelect.connect( this, { choose: 'onChooseColor' } );
+
+       this.$element
+               .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget' )
+               .append(
+                       this.$label
+                               .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget-label' ),
+                       this.buttonSelect.$element
+               );
+};
+
+/* Initialization */
+
+OO.inheritClass( HighlightColorPickerWidget, OO.ui.Widget );
+OO.mixinClass( HighlightColorPickerWidget, OO.ui.mixin.LabelElement );
+
+/* Events */
+
+/**
+ * @event chooseColor
+ * @param {string} The chosen color
+ *
+ * A color has been chosen
+ */
+
+/* Methods */
+
+/**
+ * Bind the color picker to an item
+ * @param {mw.rcfilters.dm.FilterItem} filterItem
+ */
+HighlightColorPickerWidget.prototype.setFilterItem = function ( filterItem ) {
+       if ( this.filterItem ) {
+               this.filterItem.disconnect( this );
+       }
+
+       this.filterItem = filterItem;
+       this.filterItem.connect( this, { update: 'updateUiBasedOnModel' } );
+       this.updateUiBasedOnModel();
+};
+
+/**
+ * Respond to item model update event
+ */
+HighlightColorPickerWidget.prototype.updateUiBasedOnModel = function () {
+       this.selectColor( this.filterItem.getHighlightColor() || 'none' );
+};
+
+/**
+ * Select the color for this widget
+ *
+ * @param {string} color Selected color
+ */
+HighlightColorPickerWidget.prototype.selectColor = function ( color ) {
+       var previousItem = this.buttonSelect.findItemFromData( this.currentSelection ),
+               selectedItem = this.buttonSelect.findItemFromData( color );
+
+       if ( this.currentSelection !== color ) {
+               this.currentSelection = color;
+
+               this.buttonSelect.selectItem( selectedItem );
+               if ( previousItem ) {
+                       previousItem.setIcon( null );
                }
 
-               this.filterItem = filterItem;
-               this.filterItem.connect( this, { update: 'updateUiBasedOnModel' } );
-               this.updateUiBasedOnModel();
-       };
-
-       /**
-        * Respond to item model update event
-        */
-       HighlightColorPickerWidget.prototype.updateUiBasedOnModel = function () {
-               this.selectColor( this.filterItem.getHighlightColor() || 'none' );
-       };
-
-       /**
-        * Select the color for this widget
-        *
-        * @param {string} color Selected color
-        */
-       HighlightColorPickerWidget.prototype.selectColor = function ( color ) {
-               var previousItem = this.buttonSelect.findItemFromData( this.currentSelection ),
-                       selectedItem = this.buttonSelect.findItemFromData( color );
-
-               if ( this.currentSelection !== color ) {
-                       this.currentSelection = color;
-
-                       this.buttonSelect.selectItem( selectedItem );
-                       if ( previousItem ) {
-                               previousItem.setIcon( null );
-                       }
-
-                       if ( selectedItem ) {
-                               selectedItem.setIcon( 'check' );
-                       }
+               if ( selectedItem ) {
+                       selectedItem.setIcon( 'check' );
                }
-       };
-
-       HighlightColorPickerWidget.prototype.onChooseColor = function ( button ) {
-               var color = button.data;
-               if ( color === 'none' ) {
-                       this.controller.clearHighlightColor( this.filterItem.getName() );
-               } else {
-                       this.controller.setHighlightColor( this.filterItem.getName(), color );
-               }
-               this.emit( 'chooseColor', color );
-       };
-
-       module.exports = HighlightColorPickerWidget;
-}() );
+       }
+};
+
+HighlightColorPickerWidget.prototype.onChooseColor = function ( button ) {
+       var color = button.data;
+       if ( color === 'none' ) {
+               this.controller.clearHighlightColor( this.filterItem.getName() );
+       } else {
+               this.controller.setHighlightColor( this.filterItem.getName(), color );
+       }
+       this.emit( 'chooseColor', color );
+};
+
+module.exports = HighlightColorPickerWidget;
index 4c467df..5a69013 100644 (file)
@@ -1,68 +1,65 @@
-( function () {
-       var HighlightColorPickerWidget = require( './HighlightColorPickerWidget.js' ),
-               HighlightPopupWidget;
-       /**
-        * A popup containing a color picker, for setting highlight colors.
-        *
-        * @class mw.rcfilters.ui.HighlightPopupWidget
-        * @extends OO.ui.PopupWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller RCFilters controller
-        * @param {Object} [config] Configuration object
-        */
-       HighlightPopupWidget = function MwRcfiltersUiHighlightPopupWidget( controller, config ) {
-               config = config || {};
+var HighlightColorPickerWidget = require( './HighlightColorPickerWidget.js' ),
+       HighlightPopupWidget;
+/**
+ * A popup containing a color picker, for setting highlight colors.
+ *
+ * @class mw.rcfilters.ui.HighlightPopupWidget
+ * @extends OO.ui.PopupWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller RCFilters controller
+ * @param {Object} [config] Configuration object
+ */
+HighlightPopupWidget = function MwRcfiltersUiHighlightPopupWidget( controller, config ) {
+       config = config || {};
 
-               // Parent
-               HighlightPopupWidget.parent.call( this, $.extend( {
-                       autoClose: true,
-                       anchor: false,
-                       padded: true,
-                       align: 'backwards',
-                       horizontalPosition: 'end',
-                       width: 290
-               }, config ) );
+       // Parent
+       HighlightPopupWidget.parent.call( this, $.extend( {
+               autoClose: true,
+               anchor: false,
+               padded: true,
+               align: 'backwards',
+               horizontalPosition: 'end',
+               width: 290
+       }, config ) );
 
-               this.colorPicker = new HighlightColorPickerWidget( controller );
+       this.colorPicker = new HighlightColorPickerWidget( controller );
 
-               this.colorPicker.connect( this, { chooseColor: 'onChooseColor' } );
+       this.colorPicker.connect( this, { chooseColor: 'onChooseColor' } );
 
-               this.$body.append( this.colorPicker.$element );
-       };
+       this.$body.append( this.colorPicker.$element );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( HighlightPopupWidget, OO.ui.PopupWidget );
+OO.inheritClass( HighlightPopupWidget, OO.ui.PopupWidget );
 
-       /* Methods */
+/* Methods */
 
-       /**
       * Set the button (or other widget) that this popup should hang off.
       *
       * @param {OO.ui.Widget} widget Widget the popup should orient itself to
       */
-       HighlightPopupWidget.prototype.setAssociatedButton = function ( widget ) {
-               this.setFloatableContainer( widget.$element );
-               this.$autoCloseIgnore = widget.$element;
-       };
+/**
+ * Set the button (or other widget) that this popup should hang off.
+ *
+ * @param {OO.ui.Widget} widget Widget the popup should orient itself to
+ */
+HighlightPopupWidget.prototype.setAssociatedButton = function ( widget ) {
+       this.setFloatableContainer( widget.$element );
+       this.$autoCloseIgnore = widget.$element;
+};
 
-       /**
       * Set the filter item that this popup should control the highlight color for.
       *
       * @param {mw.rcfilters.dm.FilterItem} item
       */
-       HighlightPopupWidget.prototype.setFilterItem = function ( item ) {
-               this.colorPicker.setFilterItem( item );
-       };
+/**
+ * Set the filter item that this popup should control the highlight color for.
+ *
+ * @param {mw.rcfilters.dm.FilterItem} item
+ */
+HighlightPopupWidget.prototype.setFilterItem = function ( item ) {
+       this.colorPicker.setFilterItem( item );
+};
 
-       /**
       * When the user chooses a color in the color picker, close the popup.
       */
-       HighlightPopupWidget.prototype.onChooseColor = function () {
-               this.toggle( false );
-       };
+/**
+ * When the user chooses a color in the color picker, close the popup.
+ */
+HighlightPopupWidget.prototype.onChooseColor = function () {
+       this.toggle( false );
+};
 
-       module.exports = HighlightPopupWidget;
-
-}() );
+module.exports = HighlightPopupWidget;
index 56ed628..710bd65 100644 (file)
-( function () {
-       var FilterItemHighlightButton = require( './FilterItemHighlightButton.js' ),
-               CheckboxInputWidget = require( './CheckboxInputWidget.js' ),
-               ItemMenuOptionWidget;
-
-       /**
-        * A widget representing a base toggle item
-        *
-        * @class mw.rcfilters.ui.ItemMenuOptionWidget
-        * @extends OO.ui.MenuOptionWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller RCFilters controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
-        * @param {mw.rcfilters.dm.ItemModel} invertModel
-        * @param {mw.rcfilters.dm.ItemModel} itemModel Item model
-        * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker
-        * @param {Object} config Configuration object
-        */
-       ItemMenuOptionWidget = function MwRcfiltersUiItemMenuOptionWidget(
-               controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
-       ) {
-               var layout,
-                       classes = [],
-                       $label = $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label' );
-
-               config = config || {};
-
-               this.controller = controller;
-               this.filtersViewModel = filtersViewModel;
-               this.invertModel = invertModel;
-               this.itemModel = itemModel;
-
-               // Parent
-               ItemMenuOptionWidget.parent.call( this, $.extend( {
-                       // Override the 'check' icon that OOUI defines
-                       icon: '',
-                       data: this.itemModel.getName(),
-                       label: this.itemModel.getLabel()
-               }, config ) );
-
-               this.checkboxWidget = new CheckboxInputWidget( {
-                       value: this.itemModel.getName(),
-                       selected: this.itemModel.isSelected()
-               } );
-
+var FilterItemHighlightButton = require( './FilterItemHighlightButton.js' ),
+       CheckboxInputWidget = require( './CheckboxInputWidget.js' ),
+       ItemMenuOptionWidget;
+
+/**
+ * A widget representing a base toggle item
+ *
+ * @class mw.rcfilters.ui.ItemMenuOptionWidget
+ * @extends OO.ui.MenuOptionWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller RCFilters controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
+ * @param {mw.rcfilters.dm.ItemModel} invertModel
+ * @param {mw.rcfilters.dm.ItemModel} itemModel Item model
+ * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker
+ * @param {Object} config Configuration object
+ */
+ItemMenuOptionWidget = function MwRcfiltersUiItemMenuOptionWidget(
+       controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
+) {
+       var layout,
+               classes = [],
+               $label = $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label' );
+
+       config = config || {};
+
+       this.controller = controller;
+       this.filtersViewModel = filtersViewModel;
+       this.invertModel = invertModel;
+       this.itemModel = itemModel;
+
+       // Parent
+       ItemMenuOptionWidget.parent.call( this, $.extend( {
+               // Override the 'check' icon that OOUI defines
+               icon: '',
+               data: this.itemModel.getName(),
+               label: this.itemModel.getLabel()
+       }, config ) );
+
+       this.checkboxWidget = new CheckboxInputWidget( {
+               value: this.itemModel.getName(),
+               selected: this.itemModel.isSelected()
+       } );
+
+       $label.append(
+               $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label-title' )
+                       .append( $( '<bdi>' ).append( this.$label ) )
+       );
+       if ( this.itemModel.getDescription() ) {
                $label.append(
                        $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label-title' )
-                               .append( $( '<bdi>' ).append( this.$label ) )
+                               .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label-desc' )
+                               .append( $( '<bdi>' ).text( this.itemModel.getDescription() ) )
                );
-               if ( this.itemModel.getDescription() ) {
-                       $label.append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label-desc' )
-                                       .append( $( '<bdi>' ).text( this.itemModel.getDescription() ) )
-                       );
+       }
+
+       this.highlightButton = new FilterItemHighlightButton(
+               this.controller,
+               this.itemModel,
+               highlightPopup,
+               {
+                       $overlay: config.$overlay || this.$element,
+                       title: mw.msg( 'rcfilters-highlightmenu-help' )
                }
-
-               this.highlightButton = new FilterItemHighlightButton(
-                       this.controller,
-                       this.itemModel,
-                       highlightPopup,
-                       {
-                               $overlay: config.$overlay || this.$element,
-                               title: mw.msg( 'rcfilters-highlightmenu-help' )
-                       }
-               );
-               this.highlightButton.toggle( this.filtersViewModel.isHighlightEnabled() );
-
-               this.excludeLabel = new OO.ui.LabelWidget( {
-                       label: mw.msg( 'rcfilters-filter-excluded' )
-               } );
-               this.excludeLabel.toggle(
-                       this.itemModel.getGroupModel().getView() === 'namespaces' &&
-                       this.itemModel.isSelected() &&
-                       this.invertModel.isSelected()
+       );
+       this.highlightButton.toggle( this.filtersViewModel.isHighlightEnabled() );
+
+       this.excludeLabel = new OO.ui.LabelWidget( {
+               label: mw.msg( 'rcfilters-filter-excluded' )
+       } );
+       this.excludeLabel.toggle(
+               this.itemModel.getGroupModel().getView() === 'namespaces' &&
+               this.itemModel.isSelected() &&
+               this.invertModel.isSelected()
+       );
+
+       layout = new OO.ui.FieldLayout( this.checkboxWidget, {
+               label: $label,
+               align: 'inline'
+       } );
+
+       // Events
+       this.filtersViewModel.connect( this, { highlightChange: 'updateUiBasedOnState' } );
+       this.invertModel.connect( this, { update: 'updateUiBasedOnState' } );
+       this.itemModel.connect( this, { update: 'updateUiBasedOnState' } );
+       // HACK: Prevent defaults on 'click' for the label so it
+       // doesn't steal the focus away from the input. This means
+       // we can continue arrow-movement after we click the label
+       // and is consistent with the checkbox *itself* also preventing
+       // defaults on 'click' as well.
+       layout.$label.on( 'click', false );
+
+       this.$element
+               .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget' )
+               .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-view-' + this.itemModel.getGroupModel().getView() )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-table' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-row' )
+                                               .append(
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-itemCheckbox' )
+                                                               .append( layout.$element ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-excludeLabel' )
+                                                               .append( this.excludeLabel.$element ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-highlightButton' )
+                                                               .append( this.highlightButton.$element )
+                                               )
+                               )
                );
 
-               layout = new OO.ui.FieldLayout( this.checkboxWidget, {
-                       label: $label,
-                       align: 'inline'
+       if ( this.itemModel.getIdentifiers() ) {
+               this.itemModel.getIdentifiers().forEach( function ( ident ) {
+                       classes.push( 'mw-rcfilters-ui-itemMenuOptionWidget-identifier-' + ident );
                } );
 
-               // Events
-               this.filtersViewModel.connect( this, { highlightChange: 'updateUiBasedOnState' } );
-               this.invertModel.connect( this, { update: 'updateUiBasedOnState' } );
-               this.itemModel.connect( this, { update: 'updateUiBasedOnState' } );
-               // HACK: Prevent defaults on 'click' for the label so it
-               // doesn't steal the focus away from the input. This means
-               // we can continue arrow-movement after we click the label
-               // and is consistent with the checkbox *itself* also preventing
-               // defaults on 'click' as well.
-               layout.$label.on( 'click', false );
-
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget' )
-                       .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-view-' + this.itemModel.getGroupModel().getView() )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-table' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-row' )
-                                                       .append(
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-itemCheckbox' )
-                                                                       .append( layout.$element ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-excludeLabel' )
-                                                                       .append( this.excludeLabel.$element ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-highlightButton' )
-                                                                       .append( this.highlightButton.$element )
-                                                       )
-                                       )
-                       );
-
-               if ( this.itemModel.getIdentifiers() ) {
-                       this.itemModel.getIdentifiers().forEach( function ( ident ) {
-                               classes.push( 'mw-rcfilters-ui-itemMenuOptionWidget-identifier-' + ident );
-                       } );
-
-                       this.$element.addClass( classes );
-               }
+               this.$element.addClass( classes );
+       }
 
-               this.updateUiBasedOnState();
-       };
+       this.updateUiBasedOnState();
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( ItemMenuOptionWidget, OO.ui.MenuOptionWidget );
+OO.inheritClass( ItemMenuOptionWidget, OO.ui.MenuOptionWidget );
 
-       /* Static properties */
+/* Static properties */
 
-       // We do our own scrolling to top
-       ItemMenuOptionWidget.static.scrollIntoViewOnSelect = false;
+// We do our own scrolling to top
+ItemMenuOptionWidget.static.scrollIntoViewOnSelect = false;
 
-       /* Methods */
+/* Methods */
 
-       /**
-        * Respond to item model update event
-        */
-       ItemMenuOptionWidget.prototype.updateUiBasedOnState = function () {
-               this.checkboxWidget.setSelected( this.itemModel.isSelected() );
-
-               this.highlightButton.toggle( this.filtersViewModel.isHighlightEnabled() );
-               this.excludeLabel.toggle(
-                       this.itemModel.getGroupModel().getView() === 'namespaces' &&
-                       this.itemModel.isSelected() &&
-                       this.invertModel.isSelected()
-               );
-               this.toggle( this.itemModel.isVisible() );
-       };
+/**
+ * Respond to item model update event
+ */
+ItemMenuOptionWidget.prototype.updateUiBasedOnState = function () {
+       this.checkboxWidget.setSelected( this.itemModel.isSelected() );
 
-       /**
-        * Get the name of this filter
-        *
-        * @return {string} Filter name
-        */
-       ItemMenuOptionWidget.prototype.getName = function () {
-               return this.itemModel.getName();
-       };
+       this.highlightButton.toggle( this.filtersViewModel.isHighlightEnabled() );
+       this.excludeLabel.toggle(
+               this.itemModel.getGroupModel().getView() === 'namespaces' &&
+               this.itemModel.isSelected() &&
+               this.invertModel.isSelected()
+       );
+       this.toggle( this.itemModel.isVisible() );
+};
 
-       ItemMenuOptionWidget.prototype.getModel = function () {
-               return this.itemModel;
-       };
+/**
+ * Get the name of this filter
+ *
+ * @return {string} Filter name
+ */
+ItemMenuOptionWidget.prototype.getName = function () {
+       return this.itemModel.getName();
+};
 
-       module.exports = ItemMenuOptionWidget;
+ItemMenuOptionWidget.prototype.getModel = function () {
+       return this.itemModel;
+};
 
-}() );
+module.exports = ItemMenuOptionWidget;
index 3ccb6e2..04289c7 100644 (file)
@@ -1,72 +1,69 @@
-( function () {
-       /**
-        * Widget for toggling live updates
-        *
-        * @class mw.rcfilters.ui.LiveUpdateButtonWidget
-        * @extends OO.ui.ToggleButtonWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller
-        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
-        * @param {Object} [config] Configuration object
-        */
-       var LiveUpdateButtonWidget = function MwRcfiltersUiLiveUpdateButtonWidget( controller, changesListModel, config ) {
-               config = config || {};
+/**
+ * Widget for toggling live updates
+ *
+ * @class mw.rcfilters.ui.LiveUpdateButtonWidget
+ * @extends OO.ui.ToggleButtonWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
+ * @param {Object} [config] Configuration object
+ */
+var LiveUpdateButtonWidget = function MwRcfiltersUiLiveUpdateButtonWidget( controller, changesListModel, config ) {
+       config = config || {};
 
-               // Parent
-               LiveUpdateButtonWidget.parent.call( this, $.extend( {
-                       label: mw.message( 'rcfilters-liveupdates-button' ).text()
-               }, config ) );
+       // Parent
+       LiveUpdateButtonWidget.parent.call( this, $.extend( {
+               label: mw.message( 'rcfilters-liveupdates-button' ).text()
+       }, config ) );
 
-               this.controller = controller;
-               this.model = changesListModel;
+       this.controller = controller;
+       this.model = changesListModel;
 
-               // Events
-               this.connect( this, { click: 'onClick' } );
-               this.model.connect( this, { liveUpdateChange: 'onLiveUpdateChange' } );
+       // Events
+       this.connect( this, { click: 'onClick' } );
+       this.model.connect( this, { liveUpdateChange: 'onLiveUpdateChange' } );
 
-               this.$element.addClass( 'mw-rcfilters-ui-liveUpdateButtonWidget' );
+       this.$element.addClass( 'mw-rcfilters-ui-liveUpdateButtonWidget' );
 
-               this.setState( false );
-       };
+       this.setState( false );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( LiveUpdateButtonWidget, OO.ui.ToggleButtonWidget );
+OO.inheritClass( LiveUpdateButtonWidget, OO.ui.ToggleButtonWidget );
 
-       /* Methods */
+/* Methods */
 
-       /**
       * Respond to the button being clicked
       */
-       LiveUpdateButtonWidget.prototype.onClick = function () {
-               this.controller.toggleLiveUpdate();
-       };
+/**
+ * Respond to the button being clicked
+ */
+LiveUpdateButtonWidget.prototype.onClick = function () {
+       this.controller.toggleLiveUpdate();
+};
 
-       /**
       * Set the button's state and change its appearance
       *
       * @param {boolean} enable Whether the 'live update' feature is now on/off
       */
-       LiveUpdateButtonWidget.prototype.setState = function ( enable ) {
-               this.setValue( enable );
-               this.setIcon( enable ? 'stop' : 'play' );
-               this.setTitle( mw.message(
-                       enable ?
-                               'rcfilters-liveupdates-button-title-on' :
-                               'rcfilters-liveupdates-button-title-off'
-               ).text() );
-       };
+/**
+ * Set the button's state and change its appearance
+ *
+ * @param {boolean} enable Whether the 'live update' feature is now on/off
+ */
+LiveUpdateButtonWidget.prototype.setState = function ( enable ) {
+       this.setValue( enable );
+       this.setIcon( enable ? 'stop' : 'play' );
+       this.setTitle( mw.message(
+               enable ?
+                       'rcfilters-liveupdates-button-title-on' :
+                       'rcfilters-liveupdates-button-title-off'
+       ).text() );
+};
 
-       /**
       * Respond to the 'live update' feature being turned on/off
       *
       * @param {boolean} enable Whether the 'live update' feature is now on/off
       */
-       LiveUpdateButtonWidget.prototype.onLiveUpdateChange = function ( enable ) {
-               this.setState( enable );
-       };
+/**
+ * Respond to the 'live update' feature being turned on/off
+ *
+ * @param {boolean} enable Whether the 'live update' feature is now on/off
+ */
+LiveUpdateButtonWidget.prototype.onLiveUpdateChange = function ( enable ) {
+       this.setState( enable );
+};
 
-       module.exports = LiveUpdateButtonWidget;
-
-}() );
+module.exports = LiveUpdateButtonWidget;
index bc1cac8..31edb77 100644 (file)
-( function () {
-       var SavedLinksListWidget = require( './SavedLinksListWidget.js' ),
-               FilterWrapperWidget = require( './FilterWrapperWidget.js' ),
-               ChangesListWrapperWidget = require( './ChangesListWrapperWidget.js' ),
-               RcTopSectionWidget = require( './RcTopSectionWidget.js' ),
-               RclTopSectionWidget = require( './RclTopSectionWidget.js' ),
-               WatchlistTopSectionWidget = require( './WatchlistTopSectionWidget.js' ),
-               FormWrapperWidget = require( './FormWrapperWidget.js' ),
-               MainWrapperWidget;
-
-       /**
-        * Wrapper for changes list content
-        *
-        * @class mw.rcfilters.ui.MainWrapperWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
-        * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
-        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
-        * @param {Object} config Configuration object
-        * @cfg {jQuery} $topSection Top section container
-        * @cfg {jQuery} $filtersContainer
-        * @cfg {jQuery} $changesListContainer
-        * @cfg {jQuery} $formContainer
-        * @cfg {boolean} [collapsed] Filter area is collapsed
-        * @cfg {jQuery} [$wrapper] A jQuery object for the wrapper of the general
-        *  system. If not given, falls back to this widget's $element
-        */
-       MainWrapperWidget = function MwRcfiltersUiMainWrapperWidget(
-               controller, model, savedQueriesModel, changesListModel, config
-       ) {
-               config = $.extend( {}, config );
-
-               // Parent
-               MainWrapperWidget.parent.call( this, config );
-
-               this.controller = controller;
-               this.model = model;
-               this.changesListModel = changesListModel;
-               this.$topSection = config.$topSection;
-               this.$filtersContainer = config.$filtersContainer;
-               this.$changesListContainer = config.$changesListContainer;
-               this.$formContainer = config.$formContainer;
-               this.$overlay = $( '<div>' ).addClass( 'mw-rcfilters-ui-overlay' );
-               this.$wrapper = config.$wrapper || this.$element;
-
-               this.savedLinksListWidget = new SavedLinksListWidget(
-                       controller, savedQueriesModel, { $overlay: this.$overlay }
-               );
-
-               this.filtersWidget = new FilterWrapperWidget(
-                       controller,
-                       model,
-                       savedQueriesModel,
-                       changesListModel,
-                       {
-                               $overlay: this.$overlay,
-                               $wrapper: this.$wrapper,
-                               collapsed: config.collapsed
-                       }
-               );
-
-               this.changesListWidget = new ChangesListWrapperWidget(
-                       model, changesListModel, controller, this.$changesListContainer );
+var SavedLinksListWidget = require( './SavedLinksListWidget.js' ),
+       FilterWrapperWidget = require( './FilterWrapperWidget.js' ),
+       ChangesListWrapperWidget = require( './ChangesListWrapperWidget.js' ),
+       RcTopSectionWidget = require( './RcTopSectionWidget.js' ),
+       RclTopSectionWidget = require( './RclTopSectionWidget.js' ),
+       WatchlistTopSectionWidget = require( './WatchlistTopSectionWidget.js' ),
+       FormWrapperWidget = require( './FormWrapperWidget.js' ),
+       MainWrapperWidget;
+
+/**
+ * Wrapper for changes list content
+ *
+ * @class mw.rcfilters.ui.MainWrapperWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
+ * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} $topSection Top section container
+ * @cfg {jQuery} $filtersContainer
+ * @cfg {jQuery} $changesListContainer
+ * @cfg {jQuery} $formContainer
+ * @cfg {boolean} [collapsed] Filter area is collapsed
+ * @cfg {jQuery} [$wrapper] A jQuery object for the wrapper of the general
+ *  system. If not given, falls back to this widget's $element
+ */
+MainWrapperWidget = function MwRcfiltersUiMainWrapperWidget(
+       controller, model, savedQueriesModel, changesListModel, config
+) {
+       config = $.extend( {}, config );
+
+       // Parent
+       MainWrapperWidget.parent.call( this, config );
+
+       this.controller = controller;
+       this.model = model;
+       this.changesListModel = changesListModel;
+       this.$topSection = config.$topSection;
+       this.$filtersContainer = config.$filtersContainer;
+       this.$changesListContainer = config.$changesListContainer;
+       this.$formContainer = config.$formContainer;
+       this.$overlay = $( '<div>' ).addClass( 'mw-rcfilters-ui-overlay' );
+       this.$wrapper = config.$wrapper || this.$element;
+
+       this.savedLinksListWidget = new SavedLinksListWidget(
+               controller, savedQueriesModel, { $overlay: this.$overlay }
+       );
+
+       this.filtersWidget = new FilterWrapperWidget(
+               controller,
+               model,
+               savedQueriesModel,
+               changesListModel,
+               {
+                       $overlay: this.$overlay,
+                       $wrapper: this.$wrapper,
+                       collapsed: config.collapsed
+               }
+       );
 
-               /* Events */
+       this.changesListWidget = new ChangesListWrapperWidget(
+               model, changesListModel, controller, this.$changesListContainer );
 
-               // Toggle changes list overlay when filters menu opens/closes. We use overlay on changes list
-               // to prevent users from accidentally clicking on links in results, while menu is opened.
-               // Overlay on changes list is not the same as this.$overlay
-               this.filtersWidget.connect( this, { menuToggle: this.onFilterMenuToggle.bind( this ) } );
+       /* Events */
 
-               // Initialize
-               this.$filtersContainer.append( this.filtersWidget.$element );
-               $( 'body' )
-                       .append( this.$overlay )
-                       .addClass( 'mw-rcfilters-ui-initialized' );
-       };
+       // Toggle changes list overlay when filters menu opens/closes. We use overlay on changes list
+       // to prevent users from accidentally clicking on links in results, while menu is opened.
+       // Overlay on changes list is not the same as this.$overlay
+       this.filtersWidget.connect( this, { menuToggle: this.onFilterMenuToggle.bind( this ) } );
 
-       /* Initialization */
+       // Initialize
+       this.$filtersContainer.append( this.filtersWidget.$element );
+       $( 'body' )
+               .append( this.$overlay )
+               .addClass( 'mw-rcfilters-ui-initialized' );
+};
 
-       OO.inheritClass( MainWrapperWidget, OO.ui.Widget );
+/* Initialization */
 
-       /* Methods */
+OO.inheritClass( MainWrapperWidget, OO.ui.Widget );
 
-       /**
-        * Set the content of the top section, depending on the type of special page.
-        *
-        * @param {string} specialPage
-        */
-       MainWrapperWidget.prototype.setTopSection = function ( specialPage ) {
-               var topSection;
+/* Methods */
 
-               if ( specialPage === 'Recentchanges' ) {
-                       topSection = new RcTopSectionWidget(
-                               this.savedLinksListWidget, this.$topSection
-                       );
-                       this.filtersWidget.setTopSection( topSection.$element );
-               }
+/**
+ * Set the content of the top section, depending on the type of special page.
+ *
+ * @param {string} specialPage
+ */
+MainWrapperWidget.prototype.setTopSection = function ( specialPage ) {
+       var topSection;
 
-               if ( specialPage === 'Recentchangeslinked' ) {
-                       topSection = new RclTopSectionWidget(
-                               this.savedLinksListWidget, this.controller,
-                               this.model.getGroup( 'toOrFrom' ).getItemByParamName( 'showlinkedto' ),
-                               this.model.getGroup( 'page' ).getItemByParamName( 'target' )
-                       );
+       if ( specialPage === 'Recentchanges' ) {
+               topSection = new RcTopSectionWidget(
+                       this.savedLinksListWidget, this.$topSection
+               );
+               this.filtersWidget.setTopSection( topSection.$element );
+       }
+
+       if ( specialPage === 'Recentchangeslinked' ) {
+               topSection = new RclTopSectionWidget(
+                       this.savedLinksListWidget, this.controller,
+                       this.model.getGroup( 'toOrFrom' ).getItemByParamName( 'showlinkedto' ),
+                       this.model.getGroup( 'page' ).getItemByParamName( 'target' )
+               );
 
-                       this.filtersWidget.setTopSection( topSection.$element );
-               }
+               this.filtersWidget.setTopSection( topSection.$element );
+       }
 
-               if ( specialPage === 'Watchlist' ) {
-                       topSection = new WatchlistTopSectionWidget(
-                               this.controller, this.changesListModel, this.savedLinksListWidget, this.$topSection
-                       );
+       if ( specialPage === 'Watchlist' ) {
+               topSection = new WatchlistTopSectionWidget(
+                       this.controller, this.changesListModel, this.savedLinksListWidget, this.$topSection
+               );
 
-                       this.filtersWidget.setTopSection( topSection.$element );
-               }
-       };
-
-       /**
-        * Filter menu toggle event listener
-        *
-        * @param {boolean} isVisible
-        */
-       MainWrapperWidget.prototype.onFilterMenuToggle = function ( isVisible ) {
-               this.changesListWidget.toggleOverlay( isVisible );
-       };
-
-       /**
-        * Initialize FormWrapperWidget
-        *
-        * @return {mw.rcfilters.ui.FormWrapperWidget} Form wrapper widget
-        */
-       MainWrapperWidget.prototype.initFormWidget = function () {
-               return new FormWrapperWidget(
-                       this.model, this.changesListModel, this.controller, this.$formContainer );
-       };
-
-       module.exports = MainWrapperWidget;
-}() );
+               this.filtersWidget.setTopSection( topSection.$element );
+       }
+};
+
+/**
+ * Filter menu toggle event listener
+ *
+ * @param {boolean} isVisible
+ */
+MainWrapperWidget.prototype.onFilterMenuToggle = function ( isVisible ) {
+       this.changesListWidget.toggleOverlay( isVisible );
+};
+
+/**
+ * Initialize FormWrapperWidget
+ *
+ * @return {mw.rcfilters.ui.FormWrapperWidget} Form wrapper widget
+ */
+MainWrapperWidget.prototype.initFormWidget = function () {
+       return new FormWrapperWidget(
+               this.model, this.changesListModel, this.controller, this.$formContainer );
+};
+
+module.exports = MainWrapperWidget;
index 3914337..c7fa334 100644 (file)
@@ -1,58 +1,55 @@
-( function () {
-       /**
-        * Button for marking all changes as seen on the Watchlist
-        *
-        * @class mw.rcfilters.ui.MarkSeenButtonWidget
-        * @extends OO.ui.ButtonWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller
-        * @param {mw.rcfilters.dm.ChangesListViewModel} model Changes list view model
-        * @param {Object} [config] Configuration object
-        */
-       var MarkSeenButtonWidget = function MwRcfiltersUiMarkSeenButtonWidget( controller, model, config ) {
-               config = config || {};
-
-               // Parent
-               MarkSeenButtonWidget.parent.call( this, $.extend( {
-                       label: mw.message( 'rcfilters-watchlist-markseen-button' ).text(),
-                       icon: 'checkAll'
-               }, config ) );
-
-               this.controller = controller;
-               this.model = model;
-
-               // Events
-               this.connect( this, { click: 'onClick' } );
-               this.model.connect( this, { update: 'onModelUpdate' } );
-
-               this.$element.addClass( 'mw-rcfilters-ui-markSeenButtonWidget' );
-
-               this.onModelUpdate();
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( MarkSeenButtonWidget, OO.ui.ButtonWidget );
-
-       /* Methods */
-
-       /**
-        * Respond to the button being clicked
-        */
-       MarkSeenButtonWidget.prototype.onClick = function () {
-               this.controller.markAllChangesAsSeen();
-               // assume there's no more unseen changes until the next model update
-               this.setDisabled( true );
-       };
-
-       /**
-        * Respond to the model being updated with new changes
-        */
-       MarkSeenButtonWidget.prototype.onModelUpdate = function () {
-               this.setDisabled( !this.model.hasUnseenWatchedChanges() );
-       };
-
-       module.exports = MarkSeenButtonWidget;
-
-}() );
+/**
+ * Button for marking all changes as seen on the Watchlist
+ *
+ * @class mw.rcfilters.ui.MarkSeenButtonWidget
+ * @extends OO.ui.ButtonWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.ChangesListViewModel} model Changes list view model
+ * @param {Object} [config] Configuration object
+ */
+var MarkSeenButtonWidget = function MwRcfiltersUiMarkSeenButtonWidget( controller, model, config ) {
+       config = config || {};
+
+       // Parent
+       MarkSeenButtonWidget.parent.call( this, $.extend( {
+               label: mw.message( 'rcfilters-watchlist-markseen-button' ).text(),
+               icon: 'checkAll'
+       }, config ) );
+
+       this.controller = controller;
+       this.model = model;
+
+       // Events
+       this.connect( this, { click: 'onClick' } );
+       this.model.connect( this, { update: 'onModelUpdate' } );
+
+       this.$element.addClass( 'mw-rcfilters-ui-markSeenButtonWidget' );
+
+       this.onModelUpdate();
+};
+
+/* Initialization */
+
+OO.inheritClass( MarkSeenButtonWidget, OO.ui.ButtonWidget );
+
+/* Methods */
+
+/**
+ * Respond to the button being clicked
+ */
+MarkSeenButtonWidget.prototype.onClick = function () {
+       this.controller.markAllChangesAsSeen();
+       // assume there's no more unseen changes until the next model update
+       this.setDisabled( true );
+};
+
+/**
+ * Respond to the model being updated with new changes
+ */
+MarkSeenButtonWidget.prototype.onModelUpdate = function () {
+       this.setDisabled( !this.model.hasUnseenWatchedChanges() );
+};
+
+module.exports = MarkSeenButtonWidget;
index 864d0cf..1e75020 100644 (file)
-( function () {
-       var FilterMenuHeaderWidget = require( './FilterMenuHeaderWidget.js' ),
-               HighlightPopupWidget = require( './HighlightPopupWidget.js' ),
-               FilterMenuSectionOptionWidget = require( './FilterMenuSectionOptionWidget.js' ),
-               FilterMenuOptionWidget = require( './FilterMenuOptionWidget.js' ),
-               MenuSelectWidget;
-
-       /**
-        * A floating menu widget for the filter list
-        *
-        * @class mw.rcfilters.ui.MenuSelectWidget
-        * @extends OO.ui.MenuSelectWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
-        * @param {Object} [config] Configuration object
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        * @cfg {Object[]} [footers] An array of objects defining the footers for
-        *  this menu, with a definition whether they appear per specific views.
-        *  The expected structure is:
-        *  [
-        *     {
-        *        name: {string} A unique name for the footer object
-        *        $element: {jQuery} A jQuery object for the content of the footer
-        *        views: {string[]} Optional. An array stating which views this footer is
-        *               active on. Use null or omit to display this on all views.
-        *     }
-        *  ]
-        */
-       MenuSelectWidget = function MwRcfiltersUiMenuSelectWidget( controller, model, config ) {
-               var header;
-
-               config = config || {};
-
-               this.controller = controller;
-               this.model = model;
-               this.currentView = '';
-               this.views = {};
-               this.userSelecting = false;
-
-               this.menuInitialized = false;
-               this.$overlay = config.$overlay || this.$element;
-               this.$body = $( '<div>' ).addClass( 'mw-rcfilters-ui-menuSelectWidget-body' );
-               this.footers = [];
-
-               // Parent
-               MenuSelectWidget.parent.call( this, $.extend( config, {
-                       $autoCloseIgnore: this.$overlay,
-                       width: 650,
-                       // Our filtering is done through the model
-                       filterFromInput: false
-               } ) );
-               this.setGroupElement(
-                       $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-menuSelectWidget-group' )
-               );
-               this.setClippableElement( this.$body );
-               this.setClippableContainer( this.$element );
-
-               header = new FilterMenuHeaderWidget(
-                       this.controller,
-                       this.model,
-                       {
-                               $overlay: this.$overlay
-                       }
+var FilterMenuHeaderWidget = require( './FilterMenuHeaderWidget.js' ),
+       HighlightPopupWidget = require( './HighlightPopupWidget.js' ),
+       FilterMenuSectionOptionWidget = require( './FilterMenuSectionOptionWidget.js' ),
+       FilterMenuOptionWidget = require( './FilterMenuOptionWidget.js' ),
+       MenuSelectWidget;
+
+/**
+ * A floating menu widget for the filter list
+ *
+ * @class mw.rcfilters.ui.MenuSelectWidget
+ * @extends OO.ui.MenuSelectWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {Object} [config] Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ * @cfg {Object[]} [footers] An array of objects defining the footers for
+ *  this menu, with a definition whether they appear per specific views.
+ *  The expected structure is:
+ *  [
+ *     {
+ *        name: {string} A unique name for the footer object
+ *        $element: {jQuery} A jQuery object for the content of the footer
+ *        views: {string[]} Optional. An array stating which views this footer is
+ *               active on. Use null or omit to display this on all views.
+ *     }
+ *  ]
+ */
+MenuSelectWidget = function MwRcfiltersUiMenuSelectWidget( controller, model, config ) {
+       var header;
+
+       config = config || {};
+
+       this.controller = controller;
+       this.model = model;
+       this.currentView = '';
+       this.views = {};
+       this.userSelecting = false;
+
+       this.menuInitialized = false;
+       this.$overlay = config.$overlay || this.$element;
+       this.$body = $( '<div>' ).addClass( 'mw-rcfilters-ui-menuSelectWidget-body' );
+       this.footers = [];
+
+       // Parent
+       MenuSelectWidget.parent.call( this, $.extend( config, {
+               $autoCloseIgnore: this.$overlay,
+               width: 650,
+               // Our filtering is done through the model
+               filterFromInput: false
+       } ) );
+       this.setGroupElement(
+               $( '<div>' )
+                       .addClass( 'mw-rcfilters-ui-menuSelectWidget-group' )
+       );
+       this.setClippableElement( this.$body );
+       this.setClippableContainer( this.$element );
+
+       header = new FilterMenuHeaderWidget(
+               this.controller,
+               this.model,
+               {
+                       $overlay: this.$overlay
+               }
+       );
+
+       this.noResults = new OO.ui.LabelWidget( {
+               label: mw.msg( 'rcfilters-filterlist-noresults' ),
+               classes: [ 'mw-rcfilters-ui-menuSelectWidget-noresults' ]
+       } );
+
+       // Events
+       this.model.connect( this, {
+               initialize: 'onModelInitialize',
+               searchChange: 'onModelSearchChange'
+       } );
+
+       // Initialization
+       this.$element
+               .addClass( 'mw-rcfilters-ui-menuSelectWidget' )
+               .append( header.$element )
+               .append(
+                       this.$body
+                               .append( this.$group, this.noResults.$element )
                );
 
-               this.noResults = new OO.ui.LabelWidget( {
-                       label: mw.msg( 'rcfilters-filterlist-noresults' ),
-                       classes: [ 'mw-rcfilters-ui-menuSelectWidget-noresults' ]
-               } );
-
-               // Events
-               this.model.connect( this, {
-                       initialize: 'onModelInitialize',
-                       searchChange: 'onModelSearchChange'
-               } );
-
-               // Initialization
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-menuSelectWidget' )
-                       .append( header.$element )
-                       .append(
-                               this.$body
-                                       .append( this.$group, this.noResults.$element )
-                       );
-
-               // Append all footers; we will control their visibility
-               // based on view
-               config.footers = config.footers || [];
-               config.footers.forEach( function ( footerData ) {
-                       var isSticky = footerData.sticky === undefined ? true : !!footerData.sticky,
-                               adjustedData = {
-                                       // Wrap the element with our own footer wrapper
-                                       $element: $( '<div>' )
-                                               .addClass( 'mw-rcfilters-ui-menuSelectWidget-footer' )
-                                               .addClass( 'mw-rcfilters-ui-menuSelectWidget-footer-' + footerData.name )
-                                               .append( footerData.$element ),
-                                       views: footerData.views
-                               };
-
-                       if ( !footerData.disabled ) {
-                               this.footers.push( adjustedData );
-
-                               if ( isSticky ) {
-                                       this.$element.append( adjustedData.$element );
-                               } else {
-                                       this.$body.append( adjustedData.$element );
-                               }
+       // Append all footers; we will control their visibility
+       // based on view
+       config.footers = config.footers || [];
+       config.footers.forEach( function ( footerData ) {
+               var isSticky = footerData.sticky === undefined ? true : !!footerData.sticky,
+                       adjustedData = {
+                               // Wrap the element with our own footer wrapper
+                               $element: $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-menuSelectWidget-footer' )
+                                       .addClass( 'mw-rcfilters-ui-menuSelectWidget-footer-' + footerData.name )
+                                       .append( footerData.$element ),
+                               views: footerData.views
+                       };
+
+               if ( !footerData.disabled ) {
+                       this.footers.push( adjustedData );
+
+                       if ( isSticky ) {
+                               this.$element.append( adjustedData.$element );
+                       } else {
+                               this.$body.append( adjustedData.$element );
                        }
-               }.bind( this ) );
-
-               // Switch to the correct view
-               this.updateView();
-       };
-
-       /* Initialize */
-
-       OO.inheritClass( MenuSelectWidget, OO.ui.MenuSelectWidget );
-
-       /* Events */
-
-       /* Methods */
-       MenuSelectWidget.prototype.onModelSearchChange = function () {
-               this.updateView();
-       };
-
-       /**
-        * @inheritdoc
-        */
-       MenuSelectWidget.prototype.toggle = function ( show ) {
-               this.lazyMenuCreation();
-               MenuSelectWidget.parent.prototype.toggle.call( this, show );
-               // Always open this menu downwards. FilterTagMultiselectWidget scrolls it into view.
-               this.setVerticalPosition( 'below' );
-       };
-
-       /**
-        * lazy creation of the menu
-        */
-       MenuSelectWidget.prototype.lazyMenuCreation = function () {
-               var widget = this,
-                       items = [],
-                       viewGroupCount = {},
-                       groups = this.model.getFilterGroups();
-
-               if ( this.menuInitialized ) {
-                       return;
                }
-
-               this.menuInitialized = true;
-
-               // Create shared popup for highlight buttons
-               this.highlightPopup = new HighlightPopupWidget( this.controller );
-               this.$overlay.append( this.highlightPopup.$element );
-
-               // Count groups per view
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( groups, function ( groupName, groupModel ) {
-                       if ( !groupModel.isHidden() ) {
-                               viewGroupCount[ groupModel.getView() ] = viewGroupCount[ groupModel.getView() ] || 0;
-                               viewGroupCount[ groupModel.getView() ]++;
-                       }
-               } );
-
-               // eslint-disable-next-line no-jquery/no-each-util
-               $.each( groups, function ( groupName, groupModel ) {
-                       var currentItems = [],
-                               view = groupModel.getView();
-
-                       if ( !groupModel.isHidden() ) {
-                               if ( viewGroupCount[ view ] > 1 ) {
-                                       // Only add a section header if there is more than
-                                       // one group
-                                       currentItems.push(
-                                               // Group section
-                                               new FilterMenuSectionOptionWidget(
-                                                       widget.controller,
-                                                       groupModel,
-                                                       {
-                                                               $overlay: widget.$overlay
-                                                       }
-                                               )
-                                       );
-                               }
-
-                               // Add items
-                               widget.model.getGroupFilters( groupName ).forEach( function ( filterItem ) {
-                                       currentItems.push(
-                                               new FilterMenuOptionWidget(
-                                                       widget.controller,
-                                                       widget.model,
-                                                       widget.model.getInvertModel(),
-                                                       filterItem,
-                                                       widget.highlightPopup,
-                                                       {
-                                                               $overlay: widget.$overlay
-                                                       }
-                                               )
-                                       );
-                               } );
-
-                               // Cache the items per view, so we can switch between them
-                               // without rebuilding the widgets each time
-                               widget.views[ view ] = widget.views[ view ] || [];
-                               widget.views[ view ] = widget.views[ view ].concat( currentItems );
-                               items = items.concat( currentItems );
-                       }
-               } );
-
-               this.addItems( items );
-               this.updateView();
-       };
-
-       /**
-        * Respond to model initialize event. Populate the menu from the model
-        */
-       MenuSelectWidget.prototype.onModelInitialize = function () {
-               this.menuInitialized = false;
-               // Set timeout for the menu to lazy build.
-               setTimeout( this.lazyMenuCreation.bind( this ) );
-       };
-
-       /**
-        * Update view
-        */
-       MenuSelectWidget.prototype.updateView = function () {
-               var viewName = this.model.getCurrentView();
-
-               if ( this.views[ viewName ] && this.currentView !== viewName ) {
-                       this.updateFooterVisibility( viewName );
-
-                       this.$element
-                               .data( 'view', viewName )
-                               .removeClass( 'mw-rcfilters-ui-menuSelectWidget-view-' + this.currentView )
-                               .addClass( 'mw-rcfilters-ui-menuSelectWidget-view-' + viewName );
-
-                       this.currentView = viewName;
-                       this.scrollToTop();
+       }.bind( this ) );
+
+       // Switch to the correct view
+       this.updateView();
+};
+
+/* Initialize */
+
+OO.inheritClass( MenuSelectWidget, OO.ui.MenuSelectWidget );
+
+/* Events */
+
+/* Methods */
+MenuSelectWidget.prototype.onModelSearchChange = function () {
+       this.updateView();
+};
+
+/**
+ * @inheritdoc
+ */
+MenuSelectWidget.prototype.toggle = function ( show ) {
+       this.lazyMenuCreation();
+       MenuSelectWidget.parent.prototype.toggle.call( this, show );
+       // Always open this menu downwards. FilterTagMultiselectWidget scrolls it into view.
+       this.setVerticalPosition( 'below' );
+};
+
+/**
+ * lazy creation of the menu
+ */
+MenuSelectWidget.prototype.lazyMenuCreation = function () {
+       var widget = this,
+               items = [],
+               viewGroupCount = {},
+               groups = this.model.getFilterGroups();
+
+       if ( this.menuInitialized ) {
+               return;
+       }
+
+       this.menuInitialized = true;
+
+       // Create shared popup for highlight buttons
+       this.highlightPopup = new HighlightPopupWidget( this.controller );
+       this.$overlay.append( this.highlightPopup.$element );
+
+       // Count groups per view
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( groups, function ( groupName, groupModel ) {
+               if ( !groupModel.isHidden() ) {
+                       viewGroupCount[ groupModel.getView() ] = viewGroupCount[ groupModel.getView() ] || 0;
+                       viewGroupCount[ groupModel.getView() ]++;
                }
-
-               this.postProcessItems();
-               this.clip();
-       };
-
-       /**
-        * Go over the available footers and decide which should be visible
-        * for this view
-        *
-        * @param {string} [currentView] Current view
-        */
-       MenuSelectWidget.prototype.updateFooterVisibility = function ( currentView ) {
-               currentView = currentView || this.model.getCurrentView();
-
-               this.footers.forEach( function ( data ) {
-                       data.$element.toggle(
-                               // This footer should only be shown if it is configured
-                               // for all views or for this specific view
-                               !data.views || data.views.length === 0 || data.views.indexOf( currentView ) > -1
-                       );
-               } );
-       };
-
-       /**
-        * Post-process items after the visibility changed. Make sure
-        * that we always have an item selected, and that the no-results
-        * widget appears if the menu is empty.
-        */
-       MenuSelectWidget.prototype.postProcessItems = function () {
-               var i,
-                       itemWasSelected = false,
-                       items = this.getItems();
-
-               // If we are not already selecting an item, always make sure
-               // that the top item is selected
-               if ( !this.userSelecting ) {
-                       // Select the first item in the list
-                       for ( i = 0; i < items.length; i++ ) {
-                               if (
-                                       !( items[ i ] instanceof OO.ui.MenuSectionOptionWidget ) &&
-                                       items[ i ].isVisible()
-                               ) {
-                                       itemWasSelected = true;
-                                       this.selectItem( items[ i ] );
-                                       break;
-                               }
+       } );
+
+       // eslint-disable-next-line no-jquery/no-each-util
+       $.each( groups, function ( groupName, groupModel ) {
+               var currentItems = [],
+                       view = groupModel.getView();
+
+               if ( !groupModel.isHidden() ) {
+                       if ( viewGroupCount[ view ] > 1 ) {
+                               // Only add a section header if there is more than
+                               // one group
+                               currentItems.push(
+                                       // Group section
+                                       new FilterMenuSectionOptionWidget(
+                                               widget.controller,
+                                               groupModel,
+                                               {
+                                                       $overlay: widget.$overlay
+                                               }
+                                       )
+                               );
                        }
 
-                       if ( !itemWasSelected ) {
-                               this.selectItem( null );
-                       }
+                       // Add items
+                       widget.model.getGroupFilters( groupName ).forEach( function ( filterItem ) {
+                               currentItems.push(
+                                       new FilterMenuOptionWidget(
+                                               widget.controller,
+                                               widget.model,
+                                               widget.model.getInvertModel(),
+                                               filterItem,
+                                               widget.highlightPopup,
+                                               {
+                                                       $overlay: widget.$overlay
+                                               }
+                                       )
+                               );
+                       } );
+
+                       // Cache the items per view, so we can switch between them
+                       // without rebuilding the widgets each time
+                       widget.views[ view ] = widget.views[ view ] || [];
+                       widget.views[ view ] = widget.views[ view ].concat( currentItems );
+                       items = items.concat( currentItems );
                }
+       } );
+
+       this.addItems( items );
+       this.updateView();
+};
+
+/**
+ * Respond to model initialize event. Populate the menu from the model
+ */
+MenuSelectWidget.prototype.onModelInitialize = function () {
+       this.menuInitialized = false;
+       // Set timeout for the menu to lazy build.
+       setTimeout( this.lazyMenuCreation.bind( this ) );
+};
+
+/**
+ * Update view
+ */
+MenuSelectWidget.prototype.updateView = function () {
+       var viewName = this.model.getCurrentView();
+
+       if ( this.views[ viewName ] && this.currentView !== viewName ) {
+               this.updateFooterVisibility( viewName );
 
-               this.noResults.toggle( !this.getItems().some( function ( item ) {
-                       return item.isVisible();
-               } ) );
-       };
-
-       /**
-        * Get the option widget that matches the model given
-        *
-        * @param {mw.rcfilters.dm.ItemModel} model Item model
-        * @return {mw.rcfilters.ui.ItemMenuOptionWidget} Option widget
-        */
-       MenuSelectWidget.prototype.getItemFromModel = function ( model ) {
-               this.lazyMenuCreation();
-               return this.views[ model.getGroupModel().getView() ].filter( function ( item ) {
-                       return item.getName() === model.getName();
-               } )[ 0 ];
-       };
-
-       /**
-        * @inheritdoc
-        */
-       MenuSelectWidget.prototype.onDocumentKeyDown = function ( e ) {
-               var nextItem,
-                       currentItem = this.findHighlightedItem() || this.findSelectedItem();
-
-               // Call parent
-               MenuSelectWidget.parent.prototype.onDocumentKeyDown.call( this, e );
-
-               // We want to select the item on arrow movement
-               // rather than just highlight it, like the menu
-               // does by default
-               if ( !this.isDisabled() && this.isVisible() ) {
-                       switch ( e.keyCode ) {
-                               case OO.ui.Keys.UP:
-                               case OO.ui.Keys.LEFT:
-                                       // Get the next item
-                                       nextItem = this.findRelativeSelectableItem( currentItem, -1 );
-                                       break;
-                               case OO.ui.Keys.DOWN:
-                               case OO.ui.Keys.RIGHT:
-                                       // Get the next item
-                                       nextItem = this.findRelativeSelectableItem( currentItem, 1 );
-                                       break;
+               this.$element
+                       .data( 'view', viewName )
+                       .removeClass( 'mw-rcfilters-ui-menuSelectWidget-view-' + this.currentView )
+                       .addClass( 'mw-rcfilters-ui-menuSelectWidget-view-' + viewName );
+
+               this.currentView = viewName;
+               this.scrollToTop();
+       }
+
+       this.postProcessItems();
+       this.clip();
+};
+
+/**
+ * Go over the available footers and decide which should be visible
+ * for this view
+ *
+ * @param {string} [currentView] Current view
+ */
+MenuSelectWidget.prototype.updateFooterVisibility = function ( currentView ) {
+       currentView = currentView || this.model.getCurrentView();
+
+       this.footers.forEach( function ( data ) {
+               data.$element.toggle(
+                       // This footer should only be shown if it is configured
+                       // for all views or for this specific view
+                       !data.views || data.views.length === 0 || data.views.indexOf( currentView ) > -1
+               );
+       } );
+};
+
+/**
+ * Post-process items after the visibility changed. Make sure
+ * that we always have an item selected, and that the no-results
+ * widget appears if the menu is empty.
+ */
+MenuSelectWidget.prototype.postProcessItems = function () {
+       var i,
+               itemWasSelected = false,
+               items = this.getItems();
+
+       // If we are not already selecting an item, always make sure
+       // that the top item is selected
+       if ( !this.userSelecting ) {
+               // Select the first item in the list
+               for ( i = 0; i < items.length; i++ ) {
+                       if (
+                               !( items[ i ] instanceof OO.ui.MenuSectionOptionWidget ) &&
+                               items[ i ].isVisible()
+                       ) {
+                               itemWasSelected = true;
+                               this.selectItem( items[ i ] );
+                               break;
                        }
+               }
 
-                       nextItem = nextItem && nextItem.constructor.static.selectable ?
-                               nextItem : null;
-
-                       // Select the next item
-                       this.selectItem( nextItem );
+               if ( !itemWasSelected ) {
+                       this.selectItem( null );
                }
-       };
-
-       /**
-        * Scroll to the top of the menu
-        */
-       MenuSelectWidget.prototype.scrollToTop = function () {
-               this.$body.scrollTop( 0 );
-       };
-
-       /**
-        * Set whether the user is currently selecting an item.
-        * This is important when the user selects an item that is in between
-        * different views, and makes sure we do not re-select a different
-        * item (like the item on top) when this is happening.
-        *
-        * @param {boolean} isSelecting User is selecting
-        */
-       MenuSelectWidget.prototype.setUserSelecting = function ( isSelecting ) {
-               this.userSelecting = !!isSelecting;
-       };
-
-       module.exports = MenuSelectWidget;
-}() );
+       }
+
+       this.noResults.toggle( !this.getItems().some( function ( item ) {
+               return item.isVisible();
+       } ) );
+};
+
+/**
+ * Get the option widget that matches the model given
+ *
+ * @param {mw.rcfilters.dm.ItemModel} model Item model
+ * @return {mw.rcfilters.ui.ItemMenuOptionWidget} Option widget
+ */
+MenuSelectWidget.prototype.getItemFromModel = function ( model ) {
+       this.lazyMenuCreation();
+       return this.views[ model.getGroupModel().getView() ].filter( function ( item ) {
+               return item.getName() === model.getName();
+       } )[ 0 ];
+};
+
+/**
+ * @inheritdoc
+ */
+MenuSelectWidget.prototype.onDocumentKeyDown = function ( e ) {
+       var nextItem,
+               currentItem = this.findHighlightedItem() || this.findSelectedItem();
+
+       // Call parent
+       MenuSelectWidget.parent.prototype.onDocumentKeyDown.call( this, e );
+
+       // We want to select the item on arrow movement
+       // rather than just highlight it, like the menu
+       // does by default
+       if ( !this.isDisabled() && this.isVisible() ) {
+               switch ( e.keyCode ) {
+                       case OO.ui.Keys.UP:
+                       case OO.ui.Keys.LEFT:
+                               // Get the next item
+                               nextItem = this.findRelativeSelectableItem( currentItem, -1 );
+                               break;
+                       case OO.ui.Keys.DOWN:
+                       case OO.ui.Keys.RIGHT:
+                               // Get the next item
+                               nextItem = this.findRelativeSelectableItem( currentItem, 1 );
+                               break;
+               }
+
+               nextItem = nextItem && nextItem.constructor.static.selectable ?
+                       nextItem : null;
+
+               // Select the next item
+               this.selectItem( nextItem );
+       }
+};
+
+/**
+ * Scroll to the top of the menu
+ */
+MenuSelectWidget.prototype.scrollToTop = function () {
+       this.$body.scrollTop( 0 );
+};
+
+/**
+ * Set whether the user is currently selecting an item.
+ * This is important when the user selects an item that is in between
+ * different views, and makes sure we do not re-select a different
+ * item (like the item on top) when this is happening.
+ *
+ * @param {boolean} isSelecting User is selecting
+ */
+MenuSelectWidget.prototype.setUserSelecting = function ( isSelecting ) {
+       this.userSelecting = !!isSelecting;
+};
+
+module.exports = MenuSelectWidget;
index 6de9c40..3d56fba 100644 (file)
-( function () {
-       /**
-        * Top section (between page title and filters) on Special:Recentchanges
-        *
-        * @class mw.rcfilters.ui.RcTopSectionWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
-        * @param {jQuery} $topLinks Content of the community-defined links
-        * @param {Object} [config] Configuration object
-        */
-       var RcTopSectionWidget = function MwRcfiltersUiRcTopSectionWidget(
-               savedLinksListWidget, $topLinks, config
-       ) {
-               var toplinksTitle,
-                       topLinksCookieName = 'rcfilters-toplinks-collapsed-state',
-                       topLinksCookie = mw.cookie.get( topLinksCookieName ),
-                       topLinksCookieValue = topLinksCookie || 'collapsed',
-                       widget = this;
+/**
+ * Top section (between page title and filters) on Special:Recentchanges
+ *
+ * @class mw.rcfilters.ui.RcTopSectionWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
+ * @param {jQuery} $topLinks Content of the community-defined links
+ * @param {Object} [config] Configuration object
+ */
+var RcTopSectionWidget = function MwRcfiltersUiRcTopSectionWidget(
+       savedLinksListWidget, $topLinks, config
+) {
+       var toplinksTitle,
+               topLinksCookieName = 'rcfilters-toplinks-collapsed-state',
+               topLinksCookie = mw.cookie.get( topLinksCookieName ),
+               topLinksCookieValue = topLinksCookie || 'collapsed',
+               widget = this;
 
-               config = config || {};
+       config = config || {};
 
-               // Parent
-               RcTopSectionWidget.parent.call( this, config );
+       // Parent
+       RcTopSectionWidget.parent.call( this, config );
 
-               this.$topLinks = $topLinks;
+       this.$topLinks = $topLinks;
 
-               toplinksTitle = new OO.ui.ButtonWidget( {
-                       framed: false,
-                       indicator: topLinksCookieValue === 'collapsed' ? 'down' : 'up',
-                       flags: [ 'progressive' ],
-                       label: $( '<span>' ).append( mw.message( 'rcfilters-other-review-tools' ).parse() ).contents()
-               } );
+       toplinksTitle = new OO.ui.ButtonWidget( {
+               framed: false,
+               indicator: topLinksCookieValue === 'collapsed' ? 'down' : 'up',
+               flags: [ 'progressive' ],
+               label: $( '<span>' ).append( mw.message( 'rcfilters-other-review-tools' ).parse() ).contents()
+       } );
 
-               this.$topLinks
-                       .makeCollapsible( {
-                               collapsed: topLinksCookieValue === 'collapsed',
-                               $customTogglers: toplinksTitle.$element
-                       } )
-                       .on( 'beforeExpand.mw-collapsible', function () {
-                               mw.cookie.set( topLinksCookieName, 'expanded' );
-                               toplinksTitle.setIndicator( 'up' );
-                               widget.switchTopLinks( 'expanded' );
-                       } )
-                       .on( 'beforeCollapse.mw-collapsible', function () {
-                               mw.cookie.set( topLinksCookieName, 'collapsed' );
-                               toplinksTitle.setIndicator( 'down' );
-                               widget.switchTopLinks( 'collapsed' );
-                       } );
+       this.$topLinks
+               .makeCollapsible( {
+                       collapsed: topLinksCookieValue === 'collapsed',
+                       $customTogglers: toplinksTitle.$element
+               } )
+               .on( 'beforeExpand.mw-collapsible', function () {
+                       mw.cookie.set( topLinksCookieName, 'expanded' );
+                       toplinksTitle.setIndicator( 'up' );
+                       widget.switchTopLinks( 'expanded' );
+               } )
+               .on( 'beforeCollapse.mw-collapsible', function () {
+                       mw.cookie.set( topLinksCookieName, 'collapsed' );
+                       toplinksTitle.setIndicator( 'down' );
+                       widget.switchTopLinks( 'collapsed' );
+               } );
 
-               this.$topLinks.find( '.mw-recentchanges-toplinks-title' )
-                       .replaceWith( toplinksTitle.$element.removeAttr( 'tabIndex' ) );
+       this.$topLinks.find( '.mw-recentchanges-toplinks-title' )
+               .replaceWith( toplinksTitle.$element.removeAttr( 'tabIndex' ) );
 
-               // Create two positions for the toplinks to toggle between
-               // in the table (first cell) or up above it
-               this.$top = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-topLinks-top' );
-               this.$tableTopLinks = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-cell' )
-                       .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-topLinks-table' );
+       // Create two positions for the toplinks to toggle between
+       // in the table (first cell) or up above it
+       this.$top = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-topLinks-top' );
+       this.$tableTopLinks = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-cell' )
+               .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-topLinks-table' );
 
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-rcTopSectionWidget' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-table' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-row' )
-                                                       .append(
-                                                               this.$tableTopLinks,
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-rcTopSectionWidget' )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-table' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-row' )
+                                               .append(
+                                                       this.$tableTopLinks,
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-table-placeholder' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' ),
+                                                       !mw.user.isAnon() ?
                                                                $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-table-placeholder' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' ),
-                                                               !mw.user.isAnon() ?
-                                                                       $( '<div>' )
-                                                                               .addClass( 'mw-rcfilters-ui-cell' )
-                                                                               .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-savedLinks' )
-                                                                               .append( savedLinksListWidget.$element ) :
-                                                                       null
-                                                       )
-                                       )
-                       );
+                                                                       .addClass( 'mw-rcfilters-ui-cell' )
+                                                                       .addClass( 'mw-rcfilters-ui-rcTopSectionWidget-savedLinks' )
+                                                                       .append( savedLinksListWidget.$element ) :
+                                                               null
+                                               )
+                               )
+               );
 
-               // Hack: For jumpiness reasons, this should be a sibling of -head
-               $( '.rcfilters-head' ).before( this.$top );
+       // Hack: For jumpiness reasons, this should be a sibling of -head
+       $( '.rcfilters-head' ).before( this.$top );
 
-               // Initialize top links position
-               widget.switchTopLinks( topLinksCookieValue );
-       };
+       // Initialize top links position
+       widget.switchTopLinks( topLinksCookieValue );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( RcTopSectionWidget, OO.ui.Widget );
+OO.inheritClass( RcTopSectionWidget, OO.ui.Widget );
 
-       /**
       * Switch the top links widget from inside the table (when collapsed)
       * to the 'top' (when open)
       *
       * @param {string} [state] The state of the top links widget: 'expanded' or 'collapsed'
       */
-       RcTopSectionWidget.prototype.switchTopLinks = function ( state ) {
-               state = state || 'expanded';
+/**
+ * Switch the top links widget from inside the table (when collapsed)
+ * to the 'top' (when open)
+ *
+ * @param {string} [state] The state of the top links widget: 'expanded' or 'collapsed'
+ */
+RcTopSectionWidget.prototype.switchTopLinks = function ( state ) {
+       state = state || 'expanded';
 
-               if ( state === 'expanded' ) {
-                       this.$top.append( this.$topLinks );
-               } else {
-                       this.$tableTopLinks.append( this.$topLinks );
-               }
-               this.$topLinks.toggleClass( 'mw-recentchanges-toplinks-collapsed', state === 'collapsed' );
-       };
+       if ( state === 'expanded' ) {
+               this.$top.append( this.$topLinks );
+       } else {
+               this.$tableTopLinks.append( this.$topLinks );
+       }
+       this.$topLinks.toggleClass( 'mw-recentchanges-toplinks-collapsed', state === 'collapsed' );
+};
 
-       module.exports = RcTopSectionWidget;
-}() );
+module.exports = RcTopSectionWidget;
index 6eb0d5b..382b54c 100644 (file)
@@ -1,82 +1,80 @@
-( function () {
-       /**
-        * Widget to select and display target page on Special:RecentChangesLinked (AKA Related Changes)
-        *
-        * @class mw.rcfilters.ui.RclTargetPageWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller
-        * @param {mw.rcfilters.dm.FilterItem} targetPageModel
-        * @param {Object} [config] Configuration object
-        */
-       var RclTargetPageWidget = function MwRcfiltersUiRclTargetPageWidget(
-               controller, targetPageModel, config
-       ) {
-               config = config || {};
+/**
+ * Widget to select and display target page on Special:RecentChangesLinked (AKA Related Changes)
+ *
+ * @class mw.rcfilters.ui.RclTargetPageWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.FilterItem} targetPageModel
+ * @param {Object} [config] Configuration object
+ */
+var RclTargetPageWidget = function MwRcfiltersUiRclTargetPageWidget(
+       controller, targetPageModel, config
+) {
+       config = config || {};
 
-               // Parent
-               RclTargetPageWidget.parent.call( this, config );
+       // Parent
+       RclTargetPageWidget.parent.call( this, config );
 
-               this.controller = controller;
-               this.model = targetPageModel;
+       this.controller = controller;
+       this.model = targetPageModel;
 
-               this.titleSearch = new mw.widgets.TitleInputWidget( {
-                       validate: false,
-                       placeholder: mw.msg( 'rcfilters-target-page-placeholder' ),
-                       showImages: true,
-                       showDescriptions: true,
-                       addQueryInput: false
-               } );
+       this.titleSearch = new mw.widgets.TitleInputWidget( {
+               validate: false,
+               placeholder: mw.msg( 'rcfilters-target-page-placeholder' ),
+               showImages: true,
+               showDescriptions: true,
+               addQueryInput: false
+       } );
 
-               // Events
-               this.model.connect( this, { update: 'updateUiBasedOnModel' } );
+       // Events
+       this.model.connect( this, { update: 'updateUiBasedOnModel' } );
 
-               this.titleSearch.$input.on( {
-                       blur: this.onLookupInputBlur.bind( this )
-               } );
+       this.titleSearch.$input.on( {
+               blur: this.onLookupInputBlur.bind( this )
+       } );
 
-               this.titleSearch.lookupMenu.connect( this, {
-                       choose: 'onLookupMenuItemChoose'
-               } );
+       this.titleSearch.lookupMenu.connect( this, {
+               choose: 'onLookupMenuItemChoose'
+       } );
 
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-rclTargetPageWidget' )
-                       .append( this.titleSearch.$element );
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-rclTargetPageWidget' )
+               .append( this.titleSearch.$element );
 
-               this.updateUiBasedOnModel();
-       };
+       this.updateUiBasedOnModel();
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( RclTargetPageWidget, OO.ui.Widget );
+OO.inheritClass( RclTargetPageWidget, OO.ui.Widget );
 
-       /* Methods */
+/* Methods */
 
-       /**
       * Respond to the user choosing a title
       */
-       RclTargetPageWidget.prototype.onLookupMenuItemChoose = function () {
-               this.titleSearch.$input.trigger( 'blur' );
-       };
+/**
+ * Respond to the user choosing a title
+ */
+RclTargetPageWidget.prototype.onLookupMenuItemChoose = function () {
+       this.titleSearch.$input.trigger( 'blur' );
+};
 
-       /**
       * Respond to titleSearch $input blur
       */
-       RclTargetPageWidget.prototype.onLookupInputBlur = function () {
-               this.controller.setTargetPage( this.titleSearch.getQueryValue() );
-       };
+/**
+ * Respond to titleSearch $input blur
+ */
+RclTargetPageWidget.prototype.onLookupInputBlur = function () {
+       this.controller.setTargetPage( this.titleSearch.getQueryValue() );
+};
 
-       /**
       * Respond to the model being updated
       */
-       RclTargetPageWidget.prototype.updateUiBasedOnModel = function () {
-               var title = mw.Title.newFromText( this.model.getValue() ),
-                       text = title ? title.toText() : this.model.getValue();
-               this.titleSearch.setValue( text );
-               this.titleSearch.setTitle( text );
-       };
+/**
+ * Respond to the model being updated
+ */
+RclTargetPageWidget.prototype.updateUiBasedOnModel = function () {
+       var title = mw.Title.newFromText( this.model.getValue() ),
+               text = title ? title.toText() : this.model.getValue();
+       this.titleSearch.setValue( text );
+       this.titleSearch.setTitle( text );
+};
 
-       module.exports = RclTargetPageWidget;
-}() );
+module.exports = RclTargetPageWidget;
index e2c58d0..46f2de9 100644 (file)
@@ -1,76 +1,74 @@
-( function () {
-       /**
-        * Widget to select to view changes that link TO or FROM the target page
-        * on Special:RecentChangesLinked (AKA Related Changes)
-        *
-        * @class mw.rcfilters.ui.RclToOrFromWidget
-        * @extends OO.ui.DropdownWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller
-        * @param {mw.rcfilters.dm.FilterItem} showLinkedToModel model this widget is bound to
-        * @param {Object} [config] Configuration object
-        */
-       var RclToOrFromWidget = function MwRcfiltersUiRclToOrFromWidget(
-               controller, showLinkedToModel, config
-       ) {
-               config = config || {};
+/**
+ * Widget to select to view changes that link TO or FROM the target page
+ * on Special:RecentChangesLinked (AKA Related Changes)
+ *
+ * @class mw.rcfilters.ui.RclToOrFromWidget
+ * @extends OO.ui.DropdownWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.FilterItem} showLinkedToModel model this widget is bound to
+ * @param {Object} [config] Configuration object
+ */
+var RclToOrFromWidget = function MwRcfiltersUiRclToOrFromWidget(
+       controller, showLinkedToModel, config
+) {
+       config = config || {};
 
-               this.showLinkedFrom = new OO.ui.MenuOptionWidget( {
-                       data: 'from', // default (showlinkedto=0)
-                       label: new OO.ui.HtmlSnippet( mw.msg( 'rcfilters-filter-showlinkedfrom-option-label' ) )
-               } );
-               this.showLinkedTo = new OO.ui.MenuOptionWidget( {
-                       data: 'to', // showlinkedto=1
-                       label: new OO.ui.HtmlSnippet( mw.msg( 'rcfilters-filter-showlinkedto-option-label' ) )
-               } );
+       this.showLinkedFrom = new OO.ui.MenuOptionWidget( {
+               data: 'from', // default (showlinkedto=0)
+               label: new OO.ui.HtmlSnippet( mw.msg( 'rcfilters-filter-showlinkedfrom-option-label' ) )
+       } );
+       this.showLinkedTo = new OO.ui.MenuOptionWidget( {
+               data: 'to', // showlinkedto=1
+               label: new OO.ui.HtmlSnippet( mw.msg( 'rcfilters-filter-showlinkedto-option-label' ) )
+       } );
 
-               // Parent
-               RclToOrFromWidget.parent.call( this, $.extend( {
-                       classes: [ 'mw-rcfilters-ui-rclToOrFromWidget' ],
-                       menu: { items: [ this.showLinkedFrom, this.showLinkedTo ] }
-               }, config ) );
+       // Parent
+       RclToOrFromWidget.parent.call( this, $.extend( {
+               classes: [ 'mw-rcfilters-ui-rclToOrFromWidget' ],
+               menu: { items: [ this.showLinkedFrom, this.showLinkedTo ] }
+       }, config ) );
 
-               this.controller = controller;
-               this.model = showLinkedToModel;
+       this.controller = controller;
+       this.model = showLinkedToModel;
 
-               this.getMenu().connect( this, { choose: 'onUserChooseItem' } );
-               this.model.connect( this, { update: 'onModelUpdate' } );
+       this.getMenu().connect( this, { choose: 'onUserChooseItem' } );
+       this.model.connect( this, { update: 'onModelUpdate' } );
 
-               // force an initial update of the component based on the state
-               this.onModelUpdate();
-       };
+       // force an initial update of the component based on the state
+       this.onModelUpdate();
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( RclToOrFromWidget, OO.ui.DropdownWidget );
+OO.inheritClass( RclToOrFromWidget, OO.ui.DropdownWidget );
 
-       /* Methods */
+/* Methods */
 
-       /**
       * Respond to the user choosing an item in the menu
       *
       * @param {OO.ui.MenuOptionWidget} chosenItem
       */
-       RclToOrFromWidget.prototype.onUserChooseItem = function ( chosenItem ) {
-               this.controller.setShowLinkedTo( chosenItem.getData() === 'to' );
-       };
+/**
+ * Respond to the user choosing an item in the menu
+ *
+ * @param {OO.ui.MenuOptionWidget} chosenItem
+ */
+RclToOrFromWidget.prototype.onUserChooseItem = function ( chosenItem ) {
+       this.controller.setShowLinkedTo( chosenItem.getData() === 'to' );
+};
 
-       /**
       * Respond to model update
       */
-       RclToOrFromWidget.prototype.onModelUpdate = function () {
-               this.getMenu().selectItem(
-                       this.model.isSelected() ?
-                               this.showLinkedTo :
-                               this.showLinkedFrom
-               );
-               this.setLabel( mw.msg(
-                       this.model.isSelected() ?
-                               'rcfilters-filter-showlinkedto-label' :
-                               'rcfilters-filter-showlinkedfrom-label'
-               ) );
-       };
+/**
+ * Respond to model update
+ */
+RclToOrFromWidget.prototype.onModelUpdate = function () {
+       this.getMenu().selectItem(
+               this.model.isSelected() ?
+                       this.showLinkedTo :
+                       this.showLinkedFrom
+       );
+       this.setLabel( mw.msg(
+               this.model.isSelected() ?
+                       'rcfilters-filter-showlinkedto-label' :
+                       'rcfilters-filter-showlinkedfrom-label'
+       ) );
+};
 
-       module.exports = RclToOrFromWidget;
-}() );
+module.exports = RclToOrFromWidget;
index d968b9e..560f3d8 100644 (file)
@@ -1,73 +1,71 @@
-( function () {
-       var RclToOrFromWidget = require( './RclToOrFromWidget.js' ),
-               RclTargetPageWidget = require( './RclTargetPageWidget.js' ),
-               RclTopSectionWidget;
+var RclToOrFromWidget = require( './RclToOrFromWidget.js' ),
+       RclTargetPageWidget = require( './RclTargetPageWidget.js' ),
+       RclTopSectionWidget;
 
-       /**
       * Top section (between page title and filters) on Special:RecentChangesLinked (AKA RelatedChanges)
       *
       * @class mw.rcfilters.ui.RclTopSectionWidget
       * @extends OO.ui.Widget
       *
       * @constructor
       * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
       * @param {mw.rcfilters.Controller} controller
       * @param {mw.rcfilters.dm.FilterItem} showLinkedToModel Model for 'showlinkedto' parameter
       * @param {mw.rcfilters.dm.FilterItem} targetPageModel Model for 'target' parameter
       * @param {Object} [config] Configuration object
       */
-       RclTopSectionWidget = function MwRcfiltersUiRclTopSectionWidget(
-               savedLinksListWidget, controller, showLinkedToModel, targetPageModel, config
-       ) {
-               var toOrFromWidget,
-                       targetPage;
-               config = config || {};
+/**
+ * Top section (between page title and filters) on Special:RecentChangesLinked (AKA RelatedChanges)
+ *
+ * @class mw.rcfilters.ui.RclTopSectionWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.FilterItem} showLinkedToModel Model for 'showlinkedto' parameter
+ * @param {mw.rcfilters.dm.FilterItem} targetPageModel Model for 'target' parameter
+ * @param {Object} [config] Configuration object
+ */
+RclTopSectionWidget = function MwRcfiltersUiRclTopSectionWidget(
+       savedLinksListWidget, controller, showLinkedToModel, targetPageModel, config
+) {
+       var toOrFromWidget,
+               targetPage;
+       config = config || {};
 
-               // Parent
-               RclTopSectionWidget.parent.call( this, config );
+       // Parent
+       RclTopSectionWidget.parent.call( this, config );
 
-               this.controller = controller;
+       this.controller = controller;
 
-               toOrFromWidget = new RclToOrFromWidget( controller, showLinkedToModel );
-               targetPage = new RclTargetPageWidget( controller, targetPageModel );
+       toOrFromWidget = new RclToOrFromWidget( controller, showLinkedToModel );
+       targetPage = new RclTargetPageWidget( controller, targetPageModel );
 
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-rclTopSectionWidget' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-table' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-row' )
-                                                       .append(
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-rclTopSectionWidget' )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-table' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-row' )
+                                               .append(
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .append( toOrFromWidget.$element )
+                                               ),
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-row' )
+                                               .append(
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .append( targetPage.$element ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-table-placeholder' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' ),
+                                                       !mw.user.isAnon() ?
                                                                $( '<div>' )
                                                                        .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .append( toOrFromWidget.$element )
-                                                       ),
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-row' )
-                                                       .append(
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .append( targetPage.$element ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-table-placeholder' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' ),
-                                                               !mw.user.isAnon() ?
-                                                                       $( '<div>' )
-                                                                               .addClass( 'mw-rcfilters-ui-cell' )
-                                                                               .addClass( 'mw-rcfilters-ui-rclTopSectionWidget-savedLinks' )
-                                                                               .append( savedLinksListWidget.$element ) :
-                                                                       null
-                                                       )
-                                       )
-                       );
-       };
+                                                                       .addClass( 'mw-rcfilters-ui-rclTopSectionWidget-savedLinks' )
+                                                                       .append( savedLinksListWidget.$element ) :
+                                                               null
+                                               )
+                               )
+               );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( RclTopSectionWidget, OO.ui.Widget );
+OO.inheritClass( RclTopSectionWidget, OO.ui.Widget );
 
-       module.exports = RclTopSectionWidget;
-}() );
+module.exports = RclTopSectionWidget;
index 8c3d550..1c66c6e 100644 (file)
-( function () {
-       /**
-        * Save filters widget. This widget is displayed in the tag area
-        * and allows the user to save the current state of the system
-        * as a new saved filter query they can later load or set as
-        * default.
-        *
-        * @class mw.rcfilters.ui.SaveFiltersPopupButtonWidget
-        * @extends OO.ui.PopupButtonWidget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.SavedQueriesModel} model View model
-        * @param {Object} [config] Configuration object
-        */
-       var SaveFiltersPopupButtonWidget = function MwRcfiltersUiSaveFiltersPopupButtonWidget( controller, model, config ) {
-               var layout,
-                       checkBoxLayout,
-                       $popupContent = $( '<div>' );
-
-               config = config || {};
-
-               this.controller = controller;
-               this.model = model;
-
-               // Parent
-               SaveFiltersPopupButtonWidget.parent.call( this, $.extend( {
-                       framed: false,
-                       icon: 'bookmark',
-                       title: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
-                       popup: {
-                               classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup' ],
-                               padded: true,
-                               head: true,
-                               label: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
-                               $content: $popupContent
-                       }
-               }, config ) );
-               // // HACK: Add an icon to the popup head label
-               this.popup.$head.prepend( ( new OO.ui.IconWidget( { icon: 'bookmark' } ) ).$element );
-
-               this.input = new OO.ui.TextInputWidget( {
-                       placeholder: mw.msg( 'rcfilters-savedqueries-new-name-placeholder' )
-               } );
-               layout = new OO.ui.FieldLayout( this.input, {
-                       label: mw.msg( 'rcfilters-savedqueries-new-name-label' ),
-                       align: 'top'
-               } );
-
-               this.setAsDefaultCheckbox = new OO.ui.CheckboxInputWidget();
-               checkBoxLayout = new OO.ui.FieldLayout( this.setAsDefaultCheckbox, {
-                       label: mw.msg( 'rcfilters-savedqueries-setdefault' ),
-                       align: 'inline'
-               } );
-
-               this.applyButton = new OO.ui.ButtonWidget( {
-                       label: mw.msg( 'rcfilters-savedqueries-apply-label' ),
-                       classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-apply' ],
-                       flags: [ 'primary', 'progressive' ]
-               } );
-               this.cancelButton = new OO.ui.ButtonWidget( {
-                       label: mw.msg( 'rcfilters-savedqueries-cancel-label' ),
-                       classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-cancel' ]
-               } );
-
-               $popupContent
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-layout' )
-                                       .append( layout.$element ),
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-options' )
-                                       .append( checkBoxLayout.$element ),
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons' )
-                                       .append(
-                                               this.cancelButton.$element,
-                                               this.applyButton.$element
-                                       )
-                       );
-
-               // Events
-               this.popup.connect( this, {
-                       ready: 'onPopupReady'
-               } );
-               this.input.connect( this, {
-                       change: 'onInputChange',
-                       enter: 'onInputEnter'
-               } );
-               this.input.$input.on( {
-                       keyup: this.onInputKeyup.bind( this )
-               } );
-               this.setAsDefaultCheckbox.connect( this, { change: 'onSetAsDefaultChange' } );
-               this.cancelButton.connect( this, { click: 'onCancelButtonClick' } );
-               this.applyButton.connect( this, { click: 'onApplyButtonClick' } );
-
-               // Initialize
-               this.applyButton.setDisabled( !this.input.getValue() );
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget' );
-       };
-
-       /* Initialization */
-       OO.inheritClass( SaveFiltersPopupButtonWidget, OO.ui.PopupButtonWidget );
-
-       /**
-        * Respond to input enter event
-        */
-       SaveFiltersPopupButtonWidget.prototype.onInputEnter = function () {
-               this.apply();
-       };
-
-       /**
-        * Respond to input change event
-        *
-        * @param {string} value Input value
-        */
-       SaveFiltersPopupButtonWidget.prototype.onInputChange = function ( value ) {
-               value = value.trim();
-
-               this.applyButton.setDisabled( !value );
-       };
-
-       /**
-        * Respond to input keyup event, this is the way to intercept 'escape' key
-        *
-        * @param {jQuery.Event} e Event data
-        * @return {boolean} false
-        */
-       SaveFiltersPopupButtonWidget.prototype.onInputKeyup = function ( e ) {
-               if ( e.which === OO.ui.Keys.ESCAPE ) {
-                       this.popup.toggle( false );
-                       return false;
+/**
+ * Save filters widget. This widget is displayed in the tag area
+ * and allows the user to save the current state of the system
+ * as a new saved filter query they can later load or set as
+ * default.
+ *
+ * @class mw.rcfilters.ui.SaveFiltersPopupButtonWidget
+ * @extends OO.ui.PopupButtonWidget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.SavedQueriesModel} model View model
+ * @param {Object} [config] Configuration object
+ */
+var SaveFiltersPopupButtonWidget = function MwRcfiltersUiSaveFiltersPopupButtonWidget( controller, model, config ) {
+       var layout,
+               checkBoxLayout,
+               $popupContent = $( '<div>' );
+
+       config = config || {};
+
+       this.controller = controller;
+       this.model = model;
+
+       // Parent
+       SaveFiltersPopupButtonWidget.parent.call( this, $.extend( {
+               framed: false,
+               icon: 'bookmark',
+               title: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
+               popup: {
+                       classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup' ],
+                       padded: true,
+                       head: true,
+                       label: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
+                       $content: $popupContent
                }
-       };
-
-       /**
-        * Respond to popup ready event
-        */
-       SaveFiltersPopupButtonWidget.prototype.onPopupReady = function () {
-               this.input.focus();
-       };
-
-       /**
-        * Respond to "set as default" checkbox change
-        * @param {boolean} checked State of the checkbox
-        */
-       SaveFiltersPopupButtonWidget.prototype.onSetAsDefaultChange = function ( checked ) {
-               var messageKey = checked ?
-                       'rcfilters-savedqueries-apply-and-setdefault-label' :
-                       'rcfilters-savedqueries-apply-label';
-
-               this.applyButton
-                       .setIcon( checked ? 'pushPin' : null )
-                       .setLabel( mw.msg( messageKey ) );
-       };
-
-       /**
-        * Respond to cancel button click event
-        */
-       SaveFiltersPopupButtonWidget.prototype.onCancelButtonClick = function () {
+       }, config ) );
+       // // HACK: Add an icon to the popup head label
+       this.popup.$head.prepend( ( new OO.ui.IconWidget( { icon: 'bookmark' } ) ).$element );
+
+       this.input = new OO.ui.TextInputWidget( {
+               placeholder: mw.msg( 'rcfilters-savedqueries-new-name-placeholder' )
+       } );
+       layout = new OO.ui.FieldLayout( this.input, {
+               label: mw.msg( 'rcfilters-savedqueries-new-name-label' ),
+               align: 'top'
+       } );
+
+       this.setAsDefaultCheckbox = new OO.ui.CheckboxInputWidget();
+       checkBoxLayout = new OO.ui.FieldLayout( this.setAsDefaultCheckbox, {
+               label: mw.msg( 'rcfilters-savedqueries-setdefault' ),
+               align: 'inline'
+       } );
+
+       this.applyButton = new OO.ui.ButtonWidget( {
+               label: mw.msg( 'rcfilters-savedqueries-apply-label' ),
+               classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-apply' ],
+               flags: [ 'primary', 'progressive' ]
+       } );
+       this.cancelButton = new OO.ui.ButtonWidget( {
+               label: mw.msg( 'rcfilters-savedqueries-cancel-label' ),
+               classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-cancel' ]
+       } );
+
+       $popupContent
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-layout' )
+                               .append( layout.$element ),
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-options' )
+                               .append( checkBoxLayout.$element ),
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons' )
+                               .append(
+                                       this.cancelButton.$element,
+                                       this.applyButton.$element
+                               )
+               );
+
+       // Events
+       this.popup.connect( this, {
+               ready: 'onPopupReady'
+       } );
+       this.input.connect( this, {
+               change: 'onInputChange',
+               enter: 'onInputEnter'
+       } );
+       this.input.$input.on( {
+               keyup: this.onInputKeyup.bind( this )
+       } );
+       this.setAsDefaultCheckbox.connect( this, { change: 'onSetAsDefaultChange' } );
+       this.cancelButton.connect( this, { click: 'onCancelButtonClick' } );
+       this.applyButton.connect( this, { click: 'onApplyButtonClick' } );
+
+       // Initialize
+       this.applyButton.setDisabled( !this.input.getValue() );
+       this.$element
+               .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget' );
+};
+
+/* Initialization */
+OO.inheritClass( SaveFiltersPopupButtonWidget, OO.ui.PopupButtonWidget );
+
+/**
+ * Respond to input enter event
+ */
+SaveFiltersPopupButtonWidget.prototype.onInputEnter = function () {
+       this.apply();
+};
+
+/**
+ * Respond to input change event
+ *
+ * @param {string} value Input value
+ */
+SaveFiltersPopupButtonWidget.prototype.onInputChange = function ( value ) {
+       value = value.trim();
+
+       this.applyButton.setDisabled( !value );
+};
+
+/**
+ * Respond to input keyup event, this is the way to intercept 'escape' key
+ *
+ * @param {jQuery.Event} e Event data
+ * @return {boolean} false
+ */
+SaveFiltersPopupButtonWidget.prototype.onInputKeyup = function ( e ) {
+       if ( e.which === OO.ui.Keys.ESCAPE ) {
                this.popup.toggle( false );
-       };
-
-       /**
-        * Respond to apply button click event
-        */
-       SaveFiltersPopupButtonWidget.prototype.onApplyButtonClick = function () {
-               this.apply();
-       };
-
-       /**
-        * Apply and add the new quick link
-        */
-       SaveFiltersPopupButtonWidget.prototype.apply = function () {
-               var label = this.input.getValue().trim();
-
-               // This condition is more for sanity-check, since the
-               // apply button should be disabled if the label is empty
-               if ( label ) {
-                       this.controller.saveCurrentQuery( label, this.setAsDefaultCheckbox.isSelected() );
-                       this.input.setValue( '' );
-                       this.setAsDefaultCheckbox.setSelected( false );
-                       this.popup.toggle( false );
-
-                       this.emit( 'saveCurrent' );
-               }
-       };
+               return false;
+       }
+};
+
+/**
+ * Respond to popup ready event
+ */
+SaveFiltersPopupButtonWidget.prototype.onPopupReady = function () {
+       this.input.focus();
+};
+
+/**
+ * Respond to "set as default" checkbox change
+ * @param {boolean} checked State of the checkbox
+ */
+SaveFiltersPopupButtonWidget.prototype.onSetAsDefaultChange = function ( checked ) {
+       var messageKey = checked ?
+               'rcfilters-savedqueries-apply-and-setdefault-label' :
+               'rcfilters-savedqueries-apply-label';
+
+       this.applyButton
+               .setIcon( checked ? 'pushPin' : null )
+               .setLabel( mw.msg( messageKey ) );
+};
+
+/**
+ * Respond to cancel button click event
+ */
+SaveFiltersPopupButtonWidget.prototype.onCancelButtonClick = function () {
+       this.popup.toggle( false );
+};
+
+/**
+ * Respond to apply button click event
+ */
+SaveFiltersPopupButtonWidget.prototype.onApplyButtonClick = function () {
+       this.apply();
+};
+
+/**
+ * Apply and add the new quick link
+ */
+SaveFiltersPopupButtonWidget.prototype.apply = function () {
+       var label = this.input.getValue().trim();
+
+       // This condition is more for sanity-check, since the
+       // apply button should be disabled if the label is empty
+       if ( label ) {
+               this.controller.saveCurrentQuery( label, this.setAsDefaultCheckbox.isSelected() );
+               this.input.setValue( '' );
+               this.setAsDefaultCheckbox.setSelected( false );
+               this.popup.toggle( false );
+
+               this.emit( 'saveCurrent' );
+       }
+};
 
-       module.exports = SaveFiltersPopupButtonWidget;
-}() );
+module.exports = SaveFiltersPopupButtonWidget;
index ceb5ef8..806b9a3 100644 (file)
-( function () {
-       /**
-        * Quick links menu option widget
-        *
-        * @class mw.rcfilters.ui.SavedLinksListItemWidget
-        * @extends OO.ui.Widget
-        * @mixins OO.ui.mixin.LabelElement
-        * @mixins OO.ui.mixin.IconElement
-        * @mixins OO.ui.mixin.TitledElement
-        *
-        * @constructor
-        * @param {mw.rcfilters.dm.SavedQueryItemModel} model View model
-        * @param {Object} [config] Configuration object
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        */
-       var SavedLinksListItemWidget = function MwRcfiltersUiSavedLinksListWidget( model, config ) {
-               config = config || {};
-
-               this.model = model;
-
-               // Parent
-               SavedLinksListItemWidget.parent.call( this, $.extend( {
-                       data: this.model.getID()
-               }, config ) );
-
-               // Mixin constructors
-               OO.ui.mixin.LabelElement.call( this, $.extend( {
-                       label: this.model.getLabel()
-               }, config ) );
-               OO.ui.mixin.IconElement.call( this, $.extend( {
-                       icon: ''
-               }, config ) );
-               OO.ui.mixin.TitledElement.call( this, $.extend( {
-                       title: this.model.getLabel()
-               }, config ) );
-
-               this.edit = false;
-               this.$overlay = config.$overlay || this.$element;
-
-               this.popupButton = new OO.ui.ButtonWidget( {
-                       classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-button' ],
-                       icon: 'ellipsis',
-                       framed: false
-               } );
-               this.menu = new OO.ui.MenuSelectWidget( {
-                       classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-menu' ],
-                       widget: this.popupButton,
-                       width: 200,
-                       horizontalPosition: 'end',
-                       $floatableContainer: this.popupButton.$element,
-                       items: [
-                               new OO.ui.MenuOptionWidget( {
-                                       data: 'edit',
-                                       icon: 'edit',
-                                       label: mw.msg( 'rcfilters-savedqueries-rename' )
-                               } ),
-                               new OO.ui.MenuOptionWidget( {
-                                       data: 'delete',
-                                       icon: 'trash',
-                                       label: mw.msg( 'rcfilters-savedqueries-remove' )
-                               } ),
-                               new OO.ui.MenuOptionWidget( {
-                                       data: 'default',
-                                       icon: 'pushPin',
-                                       label: mw.msg( 'rcfilters-savedqueries-setdefault' )
-                               } )
-                       ]
-               } );
-
-               this.editInput = new OO.ui.TextInputWidget( {
-                       classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-input' ]
-               } );
-               this.saveButton = new OO.ui.ButtonWidget( {
-                       icon: 'check',
-                       flags: [ 'primary', 'progressive' ]
-               } );
+/**
+ * Quick links menu option widget
+ *
+ * @class mw.rcfilters.ui.SavedLinksListItemWidget
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.TitledElement
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.SavedQueryItemModel} model View model
+ * @param {Object} [config] Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ */
+var SavedLinksListItemWidget = function MwRcfiltersUiSavedLinksListWidget( model, config ) {
+       config = config || {};
+
+       this.model = model;
+
+       // Parent
+       SavedLinksListItemWidget.parent.call( this, $.extend( {
+               data: this.model.getID()
+       }, config ) );
+
+       // Mixin constructors
+       OO.ui.mixin.LabelElement.call( this, $.extend( {
+               label: this.model.getLabel()
+       }, config ) );
+       OO.ui.mixin.IconElement.call( this, $.extend( {
+               icon: ''
+       }, config ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {
+               title: this.model.getLabel()
+       }, config ) );
+
+       this.edit = false;
+       this.$overlay = config.$overlay || this.$element;
+
+       this.popupButton = new OO.ui.ButtonWidget( {
+               classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-button' ],
+               icon: 'ellipsis',
+               framed: false
+       } );
+       this.menu = new OO.ui.MenuSelectWidget( {
+               classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-menu' ],
+               widget: this.popupButton,
+               width: 200,
+               horizontalPosition: 'end',
+               $floatableContainer: this.popupButton.$element,
+               items: [
+                       new OO.ui.MenuOptionWidget( {
+                               data: 'edit',
+                               icon: 'edit',
+                               label: mw.msg( 'rcfilters-savedqueries-rename' )
+                       } ),
+                       new OO.ui.MenuOptionWidget( {
+                               data: 'delete',
+                               icon: 'trash',
+                               label: mw.msg( 'rcfilters-savedqueries-remove' )
+                       } ),
+                       new OO.ui.MenuOptionWidget( {
+                               data: 'default',
+                               icon: 'pushPin',
+                               label: mw.msg( 'rcfilters-savedqueries-setdefault' )
+                       } )
+               ]
+       } );
+
+       this.editInput = new OO.ui.TextInputWidget( {
+               classes: [ 'mw-rcfilters-ui-savedLinksListItemWidget-input' ]
+       } );
+       this.saveButton = new OO.ui.ButtonWidget( {
+               icon: 'check',
+               flags: [ 'primary', 'progressive' ]
+       } );
+       this.toggleEdit( false );
+
+       // Events
+       this.model.connect( this, { update: 'onModelUpdate' } );
+       this.popupButton.connect( this, { click: 'onPopupButtonClick' } );
+       this.menu.connect( this, {
+               choose: 'onMenuChoose'
+       } );
+       this.saveButton.connect( this, { click: 'save' } );
+       this.editInput.connect( this, {
+               change: 'onInputChange',
+               enter: 'save'
+       } );
+       this.editInput.$input.on( {
+               blur: this.onInputBlur.bind( this ),
+               keyup: this.onInputKeyup.bind( this )
+       } );
+       this.$element.on( { click: this.onClick.bind( this ) } );
+       this.$label.on( { click: this.onClick.bind( this ) } );
+       this.$icon.on( { click: this.onDefaultIconClick.bind( this ) } );
+       // Prevent propagation on mousedown for the save button
+       // so the menu doesn't close
+       this.saveButton.$element.on( { mousedown: function () {
+               return false;
+       } } );
+
+       // Initialize
+       this.toggleDefault( !!this.model.isDefault() );
+       this.$overlay.append( this.menu.$element );
+       this.$element
+               .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget' )
+               .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-query-' + this.model.getID() )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-table' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-row' )
+                                               .append(
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-content' )
+                                                               .append(
+                                                                       this.$label
+                                                                               .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-label' ),
+                                                                       this.editInput.$element,
+                                                                       this.saveButton.$element
+                                                               ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-icon' )
+                                                               .append( this.$icon ),
+                                                       this.popupButton.$element
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                               )
+                               )
+               );
+};
+
+/* Initialization */
+OO.inheritClass( SavedLinksListItemWidget, OO.ui.Widget );
+OO.mixinClass( SavedLinksListItemWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( SavedLinksListItemWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( SavedLinksListItemWidget, OO.ui.mixin.TitledElement );
+
+/* Events */
+
+/**
+ * @event delete
+ *
+ * The delete option was selected for this item
+ */
+
+/**
+ * @event default
+ * @param {boolean} default Item is default
+ *
+ * The 'make default' option was selected for this item
+ */
+
+/**
+ * @event edit
+ * @param {string} newLabel New label for the query
+ *
+ * The label has been edited
+ */
+
+/* Methods */
+
+/**
+ * Respond to model update event
+ */
+SavedLinksListItemWidget.prototype.onModelUpdate = function () {
+       this.setLabel( this.model.getLabel() );
+       this.toggleDefault( this.model.isDefault() );
+};
+
+/**
+ * Respond to click on the element or label
+ *
+ * @fires click
+ */
+SavedLinksListItemWidget.prototype.onClick = function () {
+       if ( !this.editing ) {
+               this.emit( 'click' );
+       }
+};
+
+/**
+ * Respond to click on the 'default' icon. Open the submenu where the
+ * default state can be changed.
+ *
+ * @return {boolean} false
+ */
+SavedLinksListItemWidget.prototype.onDefaultIconClick = function () {
+       this.menu.toggle();
+       return false;
+};
+
+/**
+ * Respond to popup button click event
+ */
+SavedLinksListItemWidget.prototype.onPopupButtonClick = function () {
+       this.menu.toggle();
+};
+
+/**
+ * Respond to menu choose event
+ *
+ * @param {OO.ui.MenuOptionWidget} item Chosen item
+ * @fires delete
+ * @fires default
+ */
+SavedLinksListItemWidget.prototype.onMenuChoose = function ( item ) {
+       var action = item.getData();
+
+       if ( action === 'edit' ) {
+               this.toggleEdit( true );
+       } else if ( action === 'delete' ) {
+               this.emit( 'delete' );
+       } else if ( action === 'default' ) {
+               this.emit( 'default', !this.default );
+       }
+       // Reset selected
+       this.menu.selectItem( null );
+       // Close the menu
+       this.menu.toggle( false );
+};
+
+/**
+ * Respond to input keyup event, this is the way to intercept 'escape' key
+ *
+ * @param {jQuery.Event} e Event data
+ * @return {boolean} false
+ */
+SavedLinksListItemWidget.prototype.onInputKeyup = function ( e ) {
+       if ( e.which === OO.ui.Keys.ESCAPE ) {
+               // Return the input to the original label
+               this.editInput.setValue( this.getLabel() );
                this.toggleEdit( false );
-
-               // Events
-               this.model.connect( this, { update: 'onModelUpdate' } );
-               this.popupButton.connect( this, { click: 'onPopupButtonClick' } );
-               this.menu.connect( this, {
-                       choose: 'onMenuChoose'
-               } );
-               this.saveButton.connect( this, { click: 'save' } );
-               this.editInput.connect( this, {
-                       change: 'onInputChange',
-                       enter: 'save'
-               } );
-               this.editInput.$input.on( {
-                       blur: this.onInputBlur.bind( this ),
-                       keyup: this.onInputKeyup.bind( this )
-               } );
-               this.$element.on( { click: this.onClick.bind( this ) } );
-               this.$label.on( { click: this.onClick.bind( this ) } );
-               this.$icon.on( { click: this.onDefaultIconClick.bind( this ) } );
-               // Prevent propagation on mousedown for the save button
-               // so the menu doesn't close
-               this.saveButton.$element.on( { mousedown: function () {
-                       return false;
-               } } );
-
-               // Initialize
-               this.toggleDefault( !!this.model.isDefault() );
-               this.$overlay.append( this.menu.$element );
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget' )
-                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-query-' + this.model.getID() )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-table' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-row' )
-                                                       .append(
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-content' )
-                                                                       .append(
-                                                                               this.$label
-                                                                                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-label' ),
-                                                                               this.editInput.$element,
-                                                                               this.saveButton.$element
-                                                                       ),
-                                                               $( '<div>' )
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                                       .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-icon' )
-                                                                       .append( this.$icon ),
-                                                               this.popupButton.$element
-                                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                       )
-                                       )
-                       );
-       };
-
-       /* Initialization */
-       OO.inheritClass( SavedLinksListItemWidget, OO.ui.Widget );
-       OO.mixinClass( SavedLinksListItemWidget, OO.ui.mixin.LabelElement );
-       OO.mixinClass( SavedLinksListItemWidget, OO.ui.mixin.IconElement );
-       OO.mixinClass( SavedLinksListItemWidget, OO.ui.mixin.TitledElement );
-
-       /* Events */
-
-       /**
-        * @event delete
-        *
-        * The delete option was selected for this item
-        */
-
-       /**
-        * @event default
-        * @param {boolean} default Item is default
-        *
-        * The 'make default' option was selected for this item
-        */
-
-       /**
-        * @event edit
-        * @param {string} newLabel New label for the query
-        *
-        * The label has been edited
-        */
-
-       /* Methods */
-
-       /**
-        * Respond to model update event
-        */
-       SavedLinksListItemWidget.prototype.onModelUpdate = function () {
-               this.setLabel( this.model.getLabel() );
-               this.toggleDefault( this.model.isDefault() );
-       };
-
-       /**
-        * Respond to click on the element or label
-        *
-        * @fires click
-        */
-       SavedLinksListItemWidget.prototype.onClick = function () {
-               if ( !this.editing ) {
-                       this.emit( 'click' );
-               }
-       };
-
-       /**
-        * Respond to click on the 'default' icon. Open the submenu where the
-        * default state can be changed.
-        *
-        * @return {boolean} false
-        */
-       SavedLinksListItemWidget.prototype.onDefaultIconClick = function () {
-               this.menu.toggle();
                return false;
-       };
-
-       /**
-        * Respond to popup button click event
-        */
-       SavedLinksListItemWidget.prototype.onPopupButtonClick = function () {
-               this.menu.toggle();
-       };
-
-       /**
-        * Respond to menu choose event
-        *
-        * @param {OO.ui.MenuOptionWidget} item Chosen item
-        * @fires delete
-        * @fires default
-        */
-       SavedLinksListItemWidget.prototype.onMenuChoose = function ( item ) {
-               var action = item.getData();
-
-               if ( action === 'edit' ) {
-                       this.toggleEdit( true );
-               } else if ( action === 'delete' ) {
-                       this.emit( 'delete' );
-               } else if ( action === 'default' ) {
-                       this.emit( 'default', !this.default );
-               }
-               // Reset selected
-               this.menu.selectItem( null );
-               // Close the menu
-               this.menu.toggle( false );
-       };
-
-       /**
-        * Respond to input keyup event, this is the way to intercept 'escape' key
-        *
-        * @param {jQuery.Event} e Event data
-        * @return {boolean} false
-        */
-       SavedLinksListItemWidget.prototype.onInputKeyup = function ( e ) {
-               if ( e.which === OO.ui.Keys.ESCAPE ) {
-                       // Return the input to the original label
-                       this.editInput.setValue( this.getLabel() );
-                       this.toggleEdit( false );
-                       return false;
-               }
-       };
-
-       /**
-        * Respond to blur event on the input
-        */
-       SavedLinksListItemWidget.prototype.onInputBlur = function () {
-               this.save();
-
-               // Whether the save succeeded or not, the input-blur event
-               // means we need to cancel editing mode
+       }
+};
+
+/**
+ * Respond to blur event on the input
+ */
+SavedLinksListItemWidget.prototype.onInputBlur = function () {
+       this.save();
+
+       // Whether the save succeeded or not, the input-blur event
+       // means we need to cancel editing mode
+       this.toggleEdit( false );
+};
+
+/**
+ * Respond to input change event
+ *
+ * @param {string} value Input value
+ */
+SavedLinksListItemWidget.prototype.onInputChange = function ( value ) {
+       value = value.trim();
+
+       this.saveButton.setDisabled( !value );
+};
+
+/**
+ * Save the name of the query
+ *
+ * @fires edit
+ */
+SavedLinksListItemWidget.prototype.save = function () {
+       var value = this.editInput.getValue().trim();
+
+       if ( value ) {
+               this.emit( 'edit', value );
                this.toggleEdit( false );
-       };
-
-       /**
-        * Respond to input change event
-        *
-        * @param {string} value Input value
-        */
-       SavedLinksListItemWidget.prototype.onInputChange = function ( value ) {
-               value = value.trim();
-
-               this.saveButton.setDisabled( !value );
-       };
-
-       /**
-        * Save the name of the query
-        *
-        * @param {string} [value] The value to save
-        * @fires edit
-        */
-       SavedLinksListItemWidget.prototype.save = function () {
-               var value = this.editInput.getValue().trim();
-
-               if ( value ) {
-                       this.emit( 'edit', value );
-                       this.toggleEdit( false );
-               }
-       };
-
-       /**
-        * Toggle edit mode on this widget
-        *
-        * @param {boolean} isEdit Widget is in edit mode
-        */
-       SavedLinksListItemWidget.prototype.toggleEdit = function ( isEdit ) {
-               isEdit = isEdit === undefined ? !this.editing : isEdit;
-
-               if ( this.editing !== isEdit ) {
-                       this.$element.toggleClass( 'mw-rcfilters-ui-savedLinksListItemWidget-edit', isEdit );
-                       this.editInput.setValue( this.getLabel() );
-
-                       this.editInput.toggle( isEdit );
-                       this.$label.toggleClass( 'oo-ui-element-hidden', isEdit );
-                       this.$icon.toggleClass( 'oo-ui-element-hidden', isEdit );
-                       this.popupButton.toggle( !isEdit );
-                       this.saveButton.toggle( isEdit );
-
-                       if ( isEdit ) {
-                               this.editInput.$input.trigger( 'focus' );
-                       }
-                       this.editing = isEdit;
-               }
-       };
-
-       /**
-        * Toggle default this widget
-        *
-        * @param {boolean} isDefault This item is default
-        */
-       SavedLinksListItemWidget.prototype.toggleDefault = function ( isDefault ) {
-               isDefault = isDefault === undefined ? !this.default : isDefault;
-
-               if ( this.default !== isDefault ) {
-                       this.default = isDefault;
-                       this.setIcon( this.default ? 'pushPin' : '' );
-                       this.menu.findItemFromData( 'default' ).setLabel(
-                               this.default ?
-                                       mw.msg( 'rcfilters-savedqueries-unsetdefault' ) :
-                                       mw.msg( 'rcfilters-savedqueries-setdefault' )
-                       );
+       }
+};
+
+/**
+ * Toggle edit mode on this widget
+ *
+ * @param {boolean} isEdit Widget is in edit mode
+ */
+SavedLinksListItemWidget.prototype.toggleEdit = function ( isEdit ) {
+       isEdit = isEdit === undefined ? !this.editing : isEdit;
+
+       if ( this.editing !== isEdit ) {
+               this.$element.toggleClass( 'mw-rcfilters-ui-savedLinksListItemWidget-edit', isEdit );
+               this.editInput.setValue( this.getLabel() );
+
+               this.editInput.toggle( isEdit );
+               this.$label.toggleClass( 'oo-ui-element-hidden', isEdit );
+               this.$icon.toggleClass( 'oo-ui-element-hidden', isEdit );
+               this.popupButton.toggle( !isEdit );
+               this.saveButton.toggle( isEdit );
+
+               if ( isEdit ) {
+                       this.editInput.$input.trigger( 'focus' );
                }
-       };
-
-       /**
-        * Get item ID
-        *
-        * @return {string} Query identifier
-        */
-       SavedLinksListItemWidget.prototype.getID = function () {
-               return this.model.getID();
-       };
-
-       module.exports = SavedLinksListItemWidget;
-
-}() );
+               this.editing = isEdit;
+       }
+};
+
+/**
+ * Toggle default this widget
+ *
+ * @param {boolean} isDefault This item is default
+ */
+SavedLinksListItemWidget.prototype.toggleDefault = function ( isDefault ) {
+       isDefault = isDefault === undefined ? !this.default : isDefault;
+
+       if ( this.default !== isDefault ) {
+               this.default = isDefault;
+               this.setIcon( this.default ? 'pushPin' : '' );
+               this.menu.findItemFromData( 'default' ).setLabel(
+                       this.default ?
+                               mw.msg( 'rcfilters-savedqueries-unsetdefault' ) :
+                               mw.msg( 'rcfilters-savedqueries-setdefault' )
+               );
+       }
+};
+
+/**
+ * Get item ID
+ *
+ * @return {string} Query identifier
+ */
+SavedLinksListItemWidget.prototype.getID = function () {
+       return this.model.getID();
+};
+
+module.exports = SavedLinksListItemWidget;
index 5422daf..a29a93f 100644 (file)
-( function () {
-       var GroupWidget = require( './GroupWidget.js' ),
-               SavedLinksListItemWidget = require( './SavedLinksListItemWidget.js' ),
-               SavedLinksListWidget;
-
-       /**
-        * Quick links widget
-        *
-        * @class mw.rcfilters.ui.SavedLinksListWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller Controller
-        * @param {mw.rcfilters.dm.SavedQueriesModel} model View model
-        * @param {Object} [config] Configuration object
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        */
-       SavedLinksListWidget = function MwRcfiltersUiSavedLinksListWidget( controller, model, config ) {
-               var $labelNoEntries = $( '<div>' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-savedLinksListWidget-placeholder-title' )
-                                       .text( mw.msg( 'rcfilters-quickfilters-placeholder-title' ) ),
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-savedLinksListWidget-placeholder-description' )
-                                       .text( mw.msg( 'rcfilters-quickfilters-placeholder-description' ) )
-                       );
-
-               config = config || {};
-
-               // Parent
-               SavedLinksListWidget.parent.call( this, config );
-
-               this.controller = controller;
-               this.model = model;
-               this.$overlay = config.$overlay || this.$element;
-
-               this.placeholderItem = new OO.ui.DecoratedOptionWidget( {
-                       classes: [ 'mw-rcfilters-ui-savedLinksListWidget-placeholder' ],
-                       label: $labelNoEntries,
-                       icon: 'bookmark'
-               } );
-
-               this.menu = new GroupWidget( {
-                       events: {
-                               click: 'menuItemClick',
-                               delete: 'menuItemDelete',
-                               default: 'menuItemDefault',
-                               edit: 'menuItemEdit'
-                       },
-                       classes: [ 'mw-rcfilters-ui-savedLinksListWidget-menu' ],
-                       items: [ this.placeholderItem ]
-               } );
-               this.button = new OO.ui.PopupButtonWidget( {
-                       classes: [ 'mw-rcfilters-ui-savedLinksListWidget-button' ],
-                       label: mw.msg( 'rcfilters-quickfilters' ),
-                       icon: 'bookmark',
-                       indicator: 'down',
-                       $overlay: this.$overlay,
-                       popup: {
-                               width: 300,
-                               anchor: false,
-                               align: 'backwards',
-                               $autoCloseIgnore: this.$overlay,
-                               $content: this.menu.$element
-                       }
-               } );
-
-               // Events
-               this.model.connect( this, {
-                       add: 'onModelAddItem',
-                       remove: 'onModelRemoveItem'
-               } );
-               this.menu.connect( this, {
-                       menuItemClick: 'onMenuItemClick',
-                       menuItemDelete: 'onMenuItemRemove',
-                       menuItemDefault: 'onMenuItemDefault',
-                       menuItemEdit: 'onMenuItemEdit'
-               } );
-
-               this.placeholderItem.toggle( this.model.isEmpty() );
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-savedLinksListWidget' )
-                       .append( this.button.$element );
-       };
-
-       /* Initialization */
-       OO.inheritClass( SavedLinksListWidget, OO.ui.Widget );
-
-       /* Methods */
-
-       /**
-        * Respond to menu item click event
-        *
-        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
-        */
-       SavedLinksListWidget.prototype.onMenuItemClick = function ( item ) {
-               this.controller.applySavedQuery( item.getID() );
-               this.button.popup.toggle( false );
-       };
-
-       /**
-        * Respond to menu item remove event
-        *
-        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
-        */
-       SavedLinksListWidget.prototype.onMenuItemRemove = function ( item ) {
-               this.controller.removeSavedQuery( item.getID() );
-       };
-
-       /**
-        * Respond to menu item default event
-        *
-        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
-        * @param {boolean} isDefault Item is default
-        */
-       SavedLinksListWidget.prototype.onMenuItemDefault = function ( item, isDefault ) {
-               this.controller.setDefaultSavedQuery( isDefault ? item.getID() : null );
-       };
-
-       /**
-        * Respond to menu item edit event
-        *
-        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
-        * @param {string} newLabel New label
-        */
-       SavedLinksListWidget.prototype.onMenuItemEdit = function ( item, newLabel ) {
-               this.controller.renameSavedQuery( item.getID(), newLabel );
-       };
-
-       /**
-        * Respond to menu add item event
-        *
-        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
-        */
-       SavedLinksListWidget.prototype.onModelAddItem = function ( item ) {
-               if ( this.menu.findItemFromData( item.getID() ) ) {
-                       return;
+var GroupWidget = require( './GroupWidget.js' ),
+       SavedLinksListItemWidget = require( './SavedLinksListItemWidget.js' ),
+       SavedLinksListWidget;
+
+/**
+ * Quick links widget
+ *
+ * @class mw.rcfilters.ui.SavedLinksListWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.SavedQueriesModel} model View model
+ * @param {Object} [config] Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ */
+SavedLinksListWidget = function MwRcfiltersUiSavedLinksListWidget( controller, model, config ) {
+       var $labelNoEntries = $( '<div>' )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-savedLinksListWidget-placeholder-title' )
+                               .text( mw.msg( 'rcfilters-quickfilters-placeholder-title' ) ),
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-savedLinksListWidget-placeholder-description' )
+                               .text( mw.msg( 'rcfilters-quickfilters-placeholder-description' ) )
+               );
+
+       config = config || {};
+
+       // Parent
+       SavedLinksListWidget.parent.call( this, config );
+
+       this.controller = controller;
+       this.model = model;
+       this.$overlay = config.$overlay || this.$element;
+
+       this.placeholderItem = new OO.ui.DecoratedOptionWidget( {
+               classes: [ 'mw-rcfilters-ui-savedLinksListWidget-placeholder' ],
+               label: $labelNoEntries,
+               icon: 'bookmark'
+       } );
+
+       this.menu = new GroupWidget( {
+               events: {
+                       click: 'menuItemClick',
+                       delete: 'menuItemDelete',
+                       default: 'menuItemDefault',
+                       edit: 'menuItemEdit'
+               },
+               classes: [ 'mw-rcfilters-ui-savedLinksListWidget-menu' ],
+               items: [ this.placeholderItem ]
+       } );
+       this.button = new OO.ui.PopupButtonWidget( {
+               classes: [ 'mw-rcfilters-ui-savedLinksListWidget-button' ],
+               label: mw.msg( 'rcfilters-quickfilters' ),
+               icon: 'bookmark',
+               indicator: 'down',
+               $overlay: this.$overlay,
+               popup: {
+                       width: 300,
+                       anchor: false,
+                       align: 'backwards',
+                       $autoCloseIgnore: this.$overlay,
+                       $content: this.menu.$element
                }
-
-               this.menu.addItems( [
-                       new SavedLinksListItemWidget( item, { $overlay: this.$overlay } )
-               ] );
-               this.placeholderItem.toggle( this.model.isEmpty() );
-       };
-
-       /**
-        * Respond to menu remove item event
-        *
-        * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
-        */
-       SavedLinksListWidget.prototype.onModelRemoveItem = function ( item ) {
-               this.menu.removeItems( [ this.menu.findItemFromData( item.getID() ) ] );
-               this.placeholderItem.toggle( this.model.isEmpty() );
-       };
-
-       module.exports = SavedLinksListWidget;
-}() );
+       } );
+
+       // Events
+       this.model.connect( this, {
+               add: 'onModelAddItem',
+               remove: 'onModelRemoveItem'
+       } );
+       this.menu.connect( this, {
+               menuItemClick: 'onMenuItemClick',
+               menuItemDelete: 'onMenuItemRemove',
+               menuItemDefault: 'onMenuItemDefault',
+               menuItemEdit: 'onMenuItemEdit'
+       } );
+
+       this.placeholderItem.toggle( this.model.isEmpty() );
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-savedLinksListWidget' )
+               .append( this.button.$element );
+};
+
+/* Initialization */
+OO.inheritClass( SavedLinksListWidget, OO.ui.Widget );
+
+/* Methods */
+
+/**
+ * Respond to menu item click event
+ *
+ * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+ */
+SavedLinksListWidget.prototype.onMenuItemClick = function ( item ) {
+       this.controller.applySavedQuery( item.getID() );
+       this.button.popup.toggle( false );
+};
+
+/**
+ * Respond to menu item remove event
+ *
+ * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+ */
+SavedLinksListWidget.prototype.onMenuItemRemove = function ( item ) {
+       this.controller.removeSavedQuery( item.getID() );
+};
+
+/**
+ * Respond to menu item default event
+ *
+ * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+ * @param {boolean} isDefault Item is default
+ */
+SavedLinksListWidget.prototype.onMenuItemDefault = function ( item, isDefault ) {
+       this.controller.setDefaultSavedQuery( isDefault ? item.getID() : null );
+};
+
+/**
+ * Respond to menu item edit event
+ *
+ * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+ * @param {string} newLabel New label
+ */
+SavedLinksListWidget.prototype.onMenuItemEdit = function ( item, newLabel ) {
+       this.controller.renameSavedQuery( item.getID(), newLabel );
+};
+
+/**
+ * Respond to menu add item event
+ *
+ * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+ */
+SavedLinksListWidget.prototype.onModelAddItem = function ( item ) {
+       if ( this.menu.findItemFromData( item.getID() ) ) {
+               return;
+       }
+
+       this.menu.addItems( [
+               new SavedLinksListItemWidget( item, { $overlay: this.$overlay } )
+       ] );
+       this.placeholderItem.toggle( this.model.isEmpty() );
+};
+
+/**
+ * Respond to menu remove item event
+ *
+ * @param {mw.rcfilters.ui.SavedLinksListItemWidget} item Menu item
+ */
+SavedLinksListWidget.prototype.onModelRemoveItem = function ( item ) {
+       this.menu.removeItems( [ this.menu.findItemFromData( item.getID() ) ] );
+       this.placeholderItem.toggle( this.model.isEmpty() );
+};
+
+module.exports = SavedLinksListWidget;
index d66c5b5..985e2c5 100644 (file)
-( function () {
-       /**
-        * Extend OOUI's TagItemWidget to also display a popup on hover.
-        *
-        * @class mw.rcfilters.ui.TagItemWidget
-        * @extends OO.ui.TagItemWidget
-        * @mixins OO.ui.mixin.PopupElement
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller
-        * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
-        * @param {mw.rcfilters.dm.FilterItem} invertModel
-        * @param {mw.rcfilters.dm.FilterItem} itemModel Item model
-        * @param {Object} config Configuration object
-        * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
-        */
-       var TagItemWidget = function MwRcfiltersUiTagItemWidget(
-               controller, filtersViewModel, invertModel, itemModel, config
-       ) {
-               // Configuration initialization
-               config = config || {};
-
-               this.controller = controller;
-               this.invertModel = invertModel;
-               this.filtersViewModel = filtersViewModel;
-               this.itemModel = itemModel;
-               this.selected = false;
-
-               TagItemWidget.parent.call( this, $.extend( {
-                       data: this.itemModel.getName()
-               }, config ) );
-
-               this.$overlay = config.$overlay || this.$element;
-               this.popupLabel = new OO.ui.LabelWidget();
-
-               // Mixin constructors
-               OO.ui.mixin.PopupElement.call( this, $.extend( {
-                       popup: {
-                               padded: false,
-                               align: 'center',
-                               position: 'above',
-                               $content: $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-tagItemWidget-popup-content' )
-                                       .append( this.popupLabel.$element ),
-                               $floatableContainer: this.$element,
-                               classes: [ 'mw-rcfilters-ui-tagItemWidget-popup' ]
-                       }
-               }, config ) );
-
-               this.popupTimeoutShow = null;
-               this.popupTimeoutHide = null;
-
-               this.$highlight = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-tagItemWidget-highlight' );
-
-               // Add title attribute with the item label to 'x' button
-               this.closeButton.setTitle( mw.msg( 'rcfilters-tag-remove', this.itemModel.getLabel() ) );
-
-               // Events
-               this.filtersViewModel.connect( this, { highlightChange: 'updateUiBasedOnState' } );
-               this.invertModel.connect( this, { update: 'updateUiBasedOnState' } );
-               this.itemModel.connect( this, { update: 'updateUiBasedOnState' } );
-
-               // Initialization
-               this.$overlay.append( this.popup.$element );
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-tagItemWidget' )
-                       .prepend( this.$highlight )
-                       .attr( 'aria-haspopup', 'true' )
-                       .on( 'mouseenter', this.onMouseEnter.bind( this ) )
-                       .on( 'mouseleave', this.onMouseLeave.bind( this ) );
-
-               this.updateUiBasedOnState();
-       };
-
-       /* Initialization */
-
-       OO.inheritClass( TagItemWidget, OO.ui.TagItemWidget );
-       OO.mixinClass( TagItemWidget, OO.ui.mixin.PopupElement );
-
-       /* Methods */
-
-       /**
-        * Respond to model update event
-        */
-       TagItemWidget.prototype.updateUiBasedOnState = function () {
-               // Update label if needed
-               var labelMsg = this.itemModel.getLabelMessageKey( this.invertModel.isSelected() );
-               if ( labelMsg ) {
-                       this.setLabel( $( '<div>' ).append(
-                               $( '<bdi>' ).html(
-                                       mw.message( labelMsg, mw.html.escape( this.itemModel.getLabel() ) ).parse()
-                               )
-                       ).contents() );
-               } else {
-                       this.setLabel(
-                               $( '<bdi>' ).append(
-                                       this.itemModel.getLabel()
-                               )
-                       );
-               }
-
-               this.setCurrentMuteState();
-               this.setHighlightColor();
-       };
-
-       /**
-        * Set the current highlight color for this item
-        */
-       TagItemWidget.prototype.setHighlightColor = function () {
-               var selectedColor = this.filtersViewModel.isHighlightEnabled() && this.itemModel.isHighlighted ?
-                       this.itemModel.getHighlightColor() :
-                       null;
-
-               this.$highlight
-                       .attr( 'data-color', selectedColor )
-                       .toggleClass(
-                               'mw-rcfilters-ui-tagItemWidget-highlight-highlighted',
-                               !!selectedColor
-                       );
-       };
-
-       /**
-        * Set the current mute state for this item
-        */
-       TagItemWidget.prototype.setCurrentMuteState = function () {};
-
-       /**
-        * Respond to mouse enter event
-        */
-       TagItemWidget.prototype.onMouseEnter = function () {
-               var labelText = this.itemModel.getStateMessage();
-
-               if ( labelText ) {
-                       this.popupLabel.setLabel( labelText );
-
-                       // 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
-        */
-       TagItemWidget.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
-        */
-       TagItemWidget.prototype.toggleSelected = function ( isSelected ) {
-               isSelected = isSelected !== undefined ? isSelected : !this.selected;
-
-               if ( this.selected !== isSelected ) {
-                       this.selected = isSelected;
-
-                       this.$element.toggleClass( 'mw-rcfilters-ui-tagItemWidget-selected', this.selected );
+/**
+ * Extend OOUI's TagItemWidget to also display a popup on hover.
+ *
+ * @class mw.rcfilters.ui.TagItemWidget
+ * @extends OO.ui.TagItemWidget
+ * @mixins OO.ui.mixin.PopupElement
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
+ * @param {mw.rcfilters.dm.FilterItem} invertModel
+ * @param {mw.rcfilters.dm.FilterItem} itemModel Item model
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ */
+var TagItemWidget = function MwRcfiltersUiTagItemWidget(
+       controller, filtersViewModel, invertModel, itemModel, config
+) {
+       // Configuration initialization
+       config = config || {};
+
+       this.controller = controller;
+       this.invertModel = invertModel;
+       this.filtersViewModel = filtersViewModel;
+       this.itemModel = itemModel;
+       this.selected = false;
+
+       TagItemWidget.parent.call( this, $.extend( {
+               data: this.itemModel.getName()
+       }, config ) );
+
+       this.$overlay = config.$overlay || this.$element;
+       this.popupLabel = new OO.ui.LabelWidget();
+
+       // Mixin constructors
+       OO.ui.mixin.PopupElement.call( this, $.extend( {
+               popup: {
+                       padded: false,
+                       align: 'center',
+                       position: 'above',
+                       $content: $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-tagItemWidget-popup-content' )
+                               .append( this.popupLabel.$element ),
+                       $floatableContainer: this.$element,
+                       classes: [ 'mw-rcfilters-ui-tagItemWidget-popup' ]
                }
-       };
-
-       /**
-        * Get the selected state of this widget
-        *
-        * @return {boolean} Tag is selected
-        */
-       TagItemWidget.prototype.isSelected = function () {
-               return this.selected;
-       };
-
-       /**
-        * Get item name
-        *
-        * @return {string} Filter name
-        */
-       TagItemWidget.prototype.getName = function () {
-               return this.itemModel.getName();
-       };
-
-       /**
-        * Get item model
-        *
-        * @return {string} Filter model
-        */
-       TagItemWidget.prototype.getModel = function () {
-               return this.itemModel;
-       };
-
-       /**
-        * Get item view
-        *
-        * @return {string} Filter view
-        */
-       TagItemWidget.prototype.getView = function () {
-               return this.itemModel.getGroupModel().getView();
-       };
-
-       /**
-        * Remove and destroy external elements of this widget
-        */
-       TagItemWidget.prototype.destroy = function () {
-               // Destroy the popup
-               this.popup.$element.detach();
-
-               // Disconnect events
-               this.itemModel.disconnect( this );
-               this.closeButton.disconnect( this );
-       };
-
-       module.exports = TagItemWidget;
-}() );
+       }, config ) );
+
+       this.popupTimeoutShow = null;
+       this.popupTimeoutHide = null;
+
+       this.$highlight = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-tagItemWidget-highlight' );
+
+       // Add title attribute with the item label to 'x' button
+       this.closeButton.setTitle( mw.msg( 'rcfilters-tag-remove', this.itemModel.getLabel() ) );
+
+       // Events
+       this.filtersViewModel.connect( this, { highlightChange: 'updateUiBasedOnState' } );
+       this.invertModel.connect( this, { update: 'updateUiBasedOnState' } );
+       this.itemModel.connect( this, { update: 'updateUiBasedOnState' } );
+
+       // Initialization
+       this.$overlay.append( this.popup.$element );
+       this.$element
+               .addClass( 'mw-rcfilters-ui-tagItemWidget' )
+               .prepend( this.$highlight )
+               .attr( 'aria-haspopup', 'true' )
+               .on( 'mouseenter', this.onMouseEnter.bind( this ) )
+               .on( 'mouseleave', this.onMouseLeave.bind( this ) );
+
+       this.updateUiBasedOnState();
+};
+
+/* Initialization */
+
+OO.inheritClass( TagItemWidget, OO.ui.TagItemWidget );
+OO.mixinClass( TagItemWidget, OO.ui.mixin.PopupElement );
+
+/* Methods */
+
+/**
+ * Respond to model update event
+ */
+TagItemWidget.prototype.updateUiBasedOnState = function () {
+       // Update label if needed
+       var labelMsg = this.itemModel.getLabelMessageKey( this.invertModel.isSelected() );
+       if ( labelMsg ) {
+               this.setLabel( $( '<div>' ).append(
+                       $( '<bdi>' ).html(
+                               mw.message( labelMsg, mw.html.escape( this.itemModel.getLabel() ) ).parse()
+                       )
+               ).contents() );
+       } else {
+               this.setLabel(
+                       $( '<bdi>' ).append(
+                               this.itemModel.getLabel()
+                       )
+               );
+       }
+
+       this.setCurrentMuteState();
+       this.setHighlightColor();
+};
+
+/**
+ * Set the current highlight color for this item
+ */
+TagItemWidget.prototype.setHighlightColor = function () {
+       var selectedColor = this.filtersViewModel.isHighlightEnabled() && this.itemModel.isHighlighted ?
+               this.itemModel.getHighlightColor() :
+               null;
+
+       this.$highlight
+               .attr( 'data-color', selectedColor )
+               .toggleClass(
+                       'mw-rcfilters-ui-tagItemWidget-highlight-highlighted',
+                       !!selectedColor
+               );
+};
+
+/**
+ * Set the current mute state for this item
+ */
+TagItemWidget.prototype.setCurrentMuteState = function () {};
+
+/**
+ * Respond to mouse enter event
+ */
+TagItemWidget.prototype.onMouseEnter = function () {
+       var labelText = this.itemModel.getStateMessage();
+
+       if ( labelText ) {
+               this.popupLabel.setLabel( labelText );
+
+               // 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
+ */
+TagItemWidget.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
+ */
+TagItemWidget.prototype.toggleSelected = function ( isSelected ) {
+       isSelected = isSelected !== undefined ? isSelected : !this.selected;
+
+       if ( this.selected !== isSelected ) {
+               this.selected = isSelected;
+
+               this.$element.toggleClass( 'mw-rcfilters-ui-tagItemWidget-selected', this.selected );
+       }
+};
+
+/**
+ * Get the selected state of this widget
+ *
+ * @return {boolean} Tag is selected
+ */
+TagItemWidget.prototype.isSelected = function () {
+       return this.selected;
+};
+
+/**
+ * Get item name
+ *
+ * @return {string} Filter name
+ */
+TagItemWidget.prototype.getName = function () {
+       return this.itemModel.getName();
+};
+
+/**
+ * Get item model
+ *
+ * @return {string} Filter model
+ */
+TagItemWidget.prototype.getModel = function () {
+       return this.itemModel;
+};
+
+/**
+ * Get item view
+ *
+ * @return {string} Filter view
+ */
+TagItemWidget.prototype.getView = function () {
+       return this.itemModel.getGroupModel().getView();
+};
+
+/**
+ * Remove and destroy external elements of this widget
+ */
+TagItemWidget.prototype.destroy = function () {
+       // Destroy the popup
+       this.popup.$element.detach();
+
+       // Disconnect events
+       this.itemModel.disconnect( this );
+       this.closeButton.disconnect( this );
+};
+
+module.exports = TagItemWidget;
index ebd81c8..3ce63ee 100644 (file)
-( function () {
-       /**
-        * Widget defining the behavior used to choose from a set of values
-        * in a single_value group
-        *
-        * @class mw.rcfilters.ui.ValuePickerWidget
-        * @extends OO.ui.Widget
-        * @mixins OO.ui.mixin.LabelElement
-        *
-        * @constructor
-        * @param {mw.rcfilters.dm.FilterGroup} model Group model
-        * @param {Object} [config] Configuration object
-        * @cfg {Function} [itemFilter] A filter function for the items from the
-        *  model. If not given, all items will be included. The function must
-        *  handle item models and return a boolean whether the item is included
-        *  or not. Example: function ( itemModel ) { return itemModel.isSelected(); }
-        */
-       var ValuePickerWidget = function MwRcfiltersUiValuePickerWidget( model, config ) {
-               config = config || {};
-
-               // Parent
-               ValuePickerWidget.parent.call( this, config );
-               // Mixin constructors
-               OO.ui.mixin.LabelElement.call( this, config );
-
-               this.model = model;
-               this.itemFilter = config.itemFilter || function () {
-                       return true;
-               };
-
-               // Build the selection from the item models
-               this.selectWidget = new OO.ui.ButtonSelectWidget();
-               this.initializeSelectWidget();
-
-               // Events
-               this.model.connect( this, { update: 'onModelUpdate' } );
-               this.selectWidget.connect( this, { choose: 'onSelectWidgetChoose' } );
-
-               // Initialize
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-valuePickerWidget' )
-                       .append(
-                               this.$label
-                                       .addClass( 'mw-rcfilters-ui-valuePickerWidget-title' ),
-                               this.selectWidget.$element
-                       );
+/**
+ * Widget defining the behavior used to choose from a set of values
+ * in a single_value group
+ *
+ * @class mw.rcfilters.ui.ValuePickerWidget
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.LabelElement
+ *
+ * @constructor
+ * @param {mw.rcfilters.dm.FilterGroup} model Group model
+ * @param {Object} [config] Configuration object
+ * @cfg {Function} [itemFilter] A filter function for the items from the
+ *  model. If not given, all items will be included. The function must
+ *  handle item models and return a boolean whether the item is included
+ *  or not. Example: function ( itemModel ) { return itemModel.isSelected(); }
+ */
+var ValuePickerWidget = function MwRcfiltersUiValuePickerWidget( model, config ) {
+       config = config || {};
+
+       // Parent
+       ValuePickerWidget.parent.call( this, config );
+       // Mixin constructors
+       OO.ui.mixin.LabelElement.call( this, config );
+
+       this.model = model;
+       this.itemFilter = config.itemFilter || function () {
+               return true;
        };
 
-       /* Initialization */
-
-       OO.inheritClass( ValuePickerWidget, OO.ui.Widget );
-       OO.mixinClass( ValuePickerWidget, OO.ui.mixin.LabelElement );
-
-       /* Events */
-
-       /**
-        * @event choose
-        * @param {string} name Item name
-        *
-        * An item has been chosen
-        */
-
-       /* Methods */
-
-       /**
-        * Respond to model update event
-        */
-       ValuePickerWidget.prototype.onModelUpdate = function () {
-               this.selectCurrentModelItem();
-       };
-
-       /**
-        * Respond to select widget choose event
-        *
-        * @param {OO.ui.ButtonOptionWidget} chosenItem Chosen item
-        * @fires choose
-        */
-       ValuePickerWidget.prototype.onSelectWidgetChoose = function ( chosenItem ) {
-               this.emit( 'choose', chosenItem.getData() );
-       };
-
-       /**
-        * Initialize the select widget
-        */
-       ValuePickerWidget.prototype.initializeSelectWidget = function () {
-               var items = this.model.getItems()
-                       .filter( this.itemFilter )
-                       .map( function ( filterItem ) {
-                               return new OO.ui.ButtonOptionWidget( {
-                                       data: filterItem.getName(),
-                                       label: filterItem.getLabel()
-                               } );
+       // Build the selection from the item models
+       this.selectWidget = new OO.ui.ButtonSelectWidget();
+       this.initializeSelectWidget();
+
+       // Events
+       this.model.connect( this, { update: 'onModelUpdate' } );
+       this.selectWidget.connect( this, { choose: 'onSelectWidgetChoose' } );
+
+       // Initialize
+       this.$element
+               .addClass( 'mw-rcfilters-ui-valuePickerWidget' )
+               .append(
+                       this.$label
+                               .addClass( 'mw-rcfilters-ui-valuePickerWidget-title' ),
+                       this.selectWidget.$element
+               );
+};
+
+/* Initialization */
+
+OO.inheritClass( ValuePickerWidget, OO.ui.Widget );
+OO.mixinClass( ValuePickerWidget, OO.ui.mixin.LabelElement );
+
+/* Events */
+
+/**
+ * @event choose
+ * @param {string} name Item name
+ *
+ * An item has been chosen
+ */
+
+/* Methods */
+
+/**
+ * Respond to model update event
+ */
+ValuePickerWidget.prototype.onModelUpdate = function () {
+       this.selectCurrentModelItem();
+};
+
+/**
+ * Respond to select widget choose event
+ *
+ * @param {OO.ui.ButtonOptionWidget} chosenItem Chosen item
+ * @fires choose
+ */
+ValuePickerWidget.prototype.onSelectWidgetChoose = function ( chosenItem ) {
+       this.emit( 'choose', chosenItem.getData() );
+};
+
+/**
+ * Initialize the select widget
+ */
+ValuePickerWidget.prototype.initializeSelectWidget = function () {
+       var items = this.model.getItems()
+               .filter( this.itemFilter )
+               .map( function ( filterItem ) {
+                       return new OO.ui.ButtonOptionWidget( {
+                               data: filterItem.getName(),
+                               label: filterItem.getLabel()
                        } );
+               } );
 
-               this.selectWidget.clearItems();
-               this.selectWidget.addItems( items );
+       this.selectWidget.clearItems();
+       this.selectWidget.addItems( items );
 
-               this.selectCurrentModelItem();
-       };
+       this.selectCurrentModelItem();
+};
 
-       /**
       * Select the current item that corresponds with the model item
       * that is currently selected
       */
-       ValuePickerWidget.prototype.selectCurrentModelItem = function () {
-               var selectedItem = this.model.findSelectedItems()[ 0 ];
+/**
+ * Select the current item that corresponds with the model item
+ * that is currently selected
+ */
+ValuePickerWidget.prototype.selectCurrentModelItem = function () {
+       var selectedItem = this.model.findSelectedItems()[ 0 ];
 
-               if ( selectedItem ) {
-                       this.selectWidget.selectItemByData( selectedItem.getName() );
-               }
-       };
+       if ( selectedItem ) {
+               this.selectWidget.selectItemByData( selectedItem.getName() );
+       }
+};
 
-       module.exports = ValuePickerWidget;
-}() );
+module.exports = ValuePickerWidget;
index c00d414..e366277 100644 (file)
@@ -1,84 +1,82 @@
-( function () {
-       var GroupWidget = require( './GroupWidget.js' ),
-               ViewSwitchWidget;
+var GroupWidget = require( './GroupWidget.js' ),
+       ViewSwitchWidget;
 
-       /**
       * A widget for the footer for the default view, allowing to switch views
       *
       * @class mw.rcfilters.ui.ViewSwitchWidget
       * @extends OO.ui.Widget
       *
       * @constructor
       * @param {mw.rcfilters.Controller} controller Controller
       * @param {mw.rcfilters.dm.FiltersViewModel} model View model
       * @param {Object} [config] Configuration object
       */
-       ViewSwitchWidget = function MwRcfiltersUiViewSwitchWidget( controller, model, config ) {
-               config = config || {};
+/**
+ * A widget for the footer for the default view, allowing to switch views
+ *
+ * @class mw.rcfilters.ui.ViewSwitchWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {Object} [config] Configuration object
+ */
+ViewSwitchWidget = function MwRcfiltersUiViewSwitchWidget( controller, model, config ) {
+       config = config || {};
 
-               // Parent
-               ViewSwitchWidget.parent.call( this, config );
+       // Parent
+       ViewSwitchWidget.parent.call( this, config );
 
-               this.controller = controller;
-               this.model = model;
+       this.controller = controller;
+       this.model = model;
 
-               this.buttons = new GroupWidget( {
-                       events: {
-                               click: 'buttonClick'
-                       },
-                       items: [
-                               new OO.ui.ButtonWidget( {
-                                       data: 'namespaces',
-                                       icon: 'article',
-                                       label: mw.msg( 'namespaces' )
-                               } ),
-                               new OO.ui.ButtonWidget( {
-                                       data: 'tags',
-                                       icon: 'tag',
-                                       label: mw.msg( 'rcfilters-view-tags' )
-                               } )
-                       ]
-               } );
+       this.buttons = new GroupWidget( {
+               events: {
+                       click: 'buttonClick'
+               },
+               items: [
+                       new OO.ui.ButtonWidget( {
+                               data: 'namespaces',
+                               icon: 'article',
+                               label: mw.msg( 'namespaces' )
+                       } ),
+                       new OO.ui.ButtonWidget( {
+                               data: 'tags',
+                               icon: 'tag',
+                               label: mw.msg( 'rcfilters-view-tags' )
+                       } )
+               ]
+       } );
 
-               // Events
-               this.model.connect( this, { update: 'onModelUpdate' } );
-               this.buttons.connect( this, { buttonClick: 'onButtonClick' } );
+       // Events
+       this.model.connect( this, { update: 'onModelUpdate' } );
+       this.buttons.connect( this, { buttonClick: 'onButtonClick' } );
 
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-viewSwitchWidget' )
-                       .append(
-                               new OO.ui.LabelWidget( {
-                                       label: mw.msg( 'rcfilters-advancedfilters' )
-                               } ).$element,
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-viewSwitchWidget-buttons' )
-                                       .append( this.buttons.$element )
-                       );
-       };
+       this.$element
+               .addClass( 'mw-rcfilters-ui-viewSwitchWidget' )
+               .append(
+                       new OO.ui.LabelWidget( {
+                               label: mw.msg( 'rcfilters-advancedfilters' )
+                       } ).$element,
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-viewSwitchWidget-buttons' )
+                               .append( this.buttons.$element )
+               );
+};
 
-       /* Initialize */
+/* Initialize */
 
-       OO.inheritClass( ViewSwitchWidget, OO.ui.Widget );
+OO.inheritClass( ViewSwitchWidget, OO.ui.Widget );
 
-       /**
       * Respond to model update event
       */
-       ViewSwitchWidget.prototype.onModelUpdate = function () {
-               var currentView = this.model.getCurrentView();
+/**
+ * Respond to model update event
+ */
+ViewSwitchWidget.prototype.onModelUpdate = function () {
+       var currentView = this.model.getCurrentView();
 
-               this.buttons.getItems().forEach( function ( buttonWidget ) {
-                       buttonWidget.setActive( buttonWidget.getData() === currentView );
-               } );
-       };
+       this.buttons.getItems().forEach( function ( buttonWidget ) {
+               buttonWidget.setActive( buttonWidget.getData() === currentView );
+       } );
+};
 
-       /**
       * Respond to button switch click
       *
       * @param {OO.ui.ButtonWidget} buttonWidget Clicked button
       */
-       ViewSwitchWidget.prototype.onButtonClick = function ( buttonWidget ) {
-               this.controller.switchView( buttonWidget.getData() );
-       };
+/**
+ * Respond to button switch click
+ *
+ * @param {OO.ui.ButtonWidget} buttonWidget Clicked button
+ */
+ViewSwitchWidget.prototype.onButtonClick = function ( buttonWidget ) {
+       this.controller.switchView( buttonWidget.getData() );
+};
 
-       module.exports = ViewSwitchWidget;
-}() );
+module.exports = ViewSwitchWidget;
index 16c0533..7796148 100644 (file)
@@ -1,88 +1,86 @@
-( function () {
-       var MarkSeenButtonWidget = require( './MarkSeenButtonWidget.js' ),
-               WatchlistTopSectionWidget;
-       /**
-        * Top section (between page title and filters) on Special:Watchlist
-        *
-        * @class mw.rcfilters.ui.WatchlistTopSectionWidget
-        * @extends OO.ui.Widget
-        *
-        * @constructor
-        * @param {mw.rcfilters.Controller} controller
-        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
-        * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
-        * @param {jQuery} $watchlistDetails Content of the 'details' section that includes watched pages count
-        * @param {Object} [config] Configuration object
-        */
-       WatchlistTopSectionWidget = function MwRcfiltersUiWatchlistTopSectionWidget(
-               controller, changesListModel, savedLinksListWidget, $watchlistDetails, config
-       ) {
-               var editWatchlistButton,
-                       markSeenButton,
-                       $topTable,
-                       $bottomTable,
-                       $separator;
-               config = config || {};
+var MarkSeenButtonWidget = require( './MarkSeenButtonWidget.js' ),
+       WatchlistTopSectionWidget;
+/**
+ * Top section (between page title and filters) on Special:Watchlist
+ *
+ * @class mw.rcfilters.ui.WatchlistTopSectionWidget
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
+ * @param {mw.rcfilters.ui.SavedLinksListWidget} savedLinksListWidget
+ * @param {jQuery} $watchlistDetails Content of the 'details' section that includes watched pages count
+ * @param {Object} [config] Configuration object
+ */
+WatchlistTopSectionWidget = function MwRcfiltersUiWatchlistTopSectionWidget(
+       controller, changesListModel, savedLinksListWidget, $watchlistDetails, config
+) {
+       var editWatchlistButton,
+               markSeenButton,
+               $topTable,
+               $bottomTable,
+               $separator;
+       config = config || {};
 
-               // Parent
-               WatchlistTopSectionWidget.parent.call( this, config );
+       // Parent
+       WatchlistTopSectionWidget.parent.call( this, config );
 
-               editWatchlistButton = new OO.ui.ButtonWidget( {
-                       label: mw.msg( 'rcfilters-watchlist-edit-watchlist-button' ),
-                       icon: 'edit',
-                       href: require( '../config.json' ).StructuredChangeFiltersEditWatchlistUrl
-               } );
-               markSeenButton = new MarkSeenButtonWidget( controller, changesListModel );
+       editWatchlistButton = new OO.ui.ButtonWidget( {
+               label: mw.msg( 'rcfilters-watchlist-edit-watchlist-button' ),
+               icon: 'edit',
+               href: require( '../config.json' ).StructuredChangeFiltersEditWatchlistUrl
+       } );
+       markSeenButton = new MarkSeenButtonWidget( controller, changesListModel );
 
-               $topTable = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-table' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-row' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-watchlistDetails' )
-                                                       .append( $watchlistDetails )
-                                       )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-editWatchlistButton' )
-                                                       .append( editWatchlistButton.$element )
-                                       )
-                       );
+       $topTable = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-table' )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-row' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                               .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-watchlistDetails' )
+                                               .append( $watchlistDetails )
+                               )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                               .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-editWatchlistButton' )
+                                               .append( editWatchlistButton.$element )
+                               )
+               );
 
-               $bottomTable = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-table' )
-                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-savedLinksTable' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-row' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                       .append( markSeenButton.$element )
-                                       )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-savedLinks' )
-                                                       .append( savedLinksListWidget.$element )
-                                       )
-                       );
+       $bottomTable = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-table' )
+               .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-savedLinksTable' )
+               .append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-row' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                               .append( markSeenButton.$element )
+                               )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                               .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-savedLinks' )
+                                               .append( savedLinksListWidget.$element )
+                               )
+               );
 
-               $separator = $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-separator' );
+       $separator = $( '<div>' )
+               .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget-separator' );
 
-               this.$element
-                       .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget' )
-                       .append( $topTable, $separator, $bottomTable );
-       };
+       this.$element
+               .addClass( 'mw-rcfilters-ui-watchlistTopSectionWidget' )
+               .append( $topTable, $separator, $bottomTable );
+};
 
-       /* Initialization */
+/* Initialization */
 
-       OO.inheritClass( WatchlistTopSectionWidget, OO.ui.Widget );
+OO.inheritClass( WatchlistTopSectionWidget, OO.ui.Widget );
 
-       module.exports = WatchlistTopSectionWidget;
-}() );
+module.exports = WatchlistTopSectionWidget;
diff --git a/resources/src/mediawiki.rollback.confirmation.js b/resources/src/mediawiki.rollback.confirmation.js
new file mode 100644 (file)
index 0000000..5be49f0
--- /dev/null
@@ -0,0 +1,27 @@
+/*!
+ * JavaScript for rollback confirmation prompt
+ */
+( function () {
+
+       var postRollback = function ( url ) {
+               var $form = $( '<form>', {
+                       action: url,
+                       method: 'post'
+               } );
+               $form.appendTo( 'body' ).trigger( 'submit' );
+       };
+
+       $( '#mw-content-text' ).confirmable( {
+               i18n: {
+                       confirm: mw.msg( 'rollback-confirmation-confirm' ),
+                       yes: mw.msg( 'rollback-confirmation-yes' ),
+                       no: mw.msg( 'rollback-confirmation-no' )
+               },
+               delegate: '.mw-rollback-link a[data-mw="interface"]',
+               handler: function ( e ) {
+                       e.preventDefault();
+                       postRollback( $( this ).attr( 'href' ) );
+               }
+       } );
+
+}() );
index db9265a..a33595c 100644 (file)
@@ -184,7 +184,6 @@ p img {
 }
 
 ul {
-       list-style-type: square;
        margin: 0.3em 0 0 1.6em;
        padding: 0;
 }
index 02e380a..58657db 100644 (file)
        }
 
        $( function () {
-               // This code is also loaded on the "block succeeded" page where there is no form,
-               // so username and expiry fields might also be missing.
-               var blockTargetWidget = infuseIfExists( $( '#mw-bi-target' ) ),
-                       anonOnlyField = infuseIfExists( $( '#mw-input-wpHardBlock' ).closest( '.oo-ui-fieldLayout' ) ),
-                       enableAutoblockField = infuseIfExists( $( '#mw-input-wpAutoBlock' ).closest( '.oo-ui-fieldLayout' ) ),
-                       hideUserWidget = infuseIfExists( $( '#mw-input-wpHideUser' ) ),
-                       hideUserField = infuseIfExists( $( '#mw-input-wpHideUser' ).closest( '.oo-ui-fieldLayout' ) ),
-                       watchUserField = infuseIfExists( $( '#mw-input-wpWatch' ).closest( '.oo-ui-fieldLayout' ) ),
-                       expiryWidget = infuseIfExists( $( '#mw-input-wpExpiry' ) ),
-                       editingWidget = infuseIfExists( $( '#mw-input-wpEditing' ) ),
-                       editingRestrictionWidget = infuseIfExists( $( '#mw-input-wpEditingRestriction' ) ),
-                       preventTalkPageEdit = infuseIfExists( $( '#mw-input-wpDisableUTEdit' ) ),
-                       pageRestrictionsWidget = infuseIfExists( $( '#mw-input-wpPageRestrictions' ) ),
-                       namespaceRestrictionsWidget = infuseIfExists( $( '#mw-input-wpNamespaceRestrictions' ) ),
-                       createAccountWidget = infuseIfExists( $( '#mw-input-wpCreateAccount' ) ),
-                       userChangedCreateAccount = false,
-                       updatingBlockOptions = false;
+               var blockTargetWidget, anonOnlyWidget, enableAutoblockWidget, hideUserWidget, watchUserWidget,
+                       expiryWidget, editingWidget, editingRestrictionWidget, preventTalkPageEditWidget,
+                       pageRestrictionsWidget, namespaceRestrictionsWidget, createAccountWidget, data,
+                       enablePartialBlocks, blockAllowsUTEdit, userChangedCreateAccount, updatingBlockOptions;
 
                function updateBlockOptions() {
                        var blocktarget = blockTargetWidget.getValue().trim(),
                                // infinityValues are the values the SpecialBlock class accepts as infinity (sf. wfIsInfinity)
                                infinityValues = [ 'infinite', 'indefinite', 'infinity', 'never' ],
                                isIndefinite = infinityValues.indexOf( expiryValue ) !== -1,
-                               // editingRestrictionWidget only exists if partial blocks is enabled; if not, block must be sitewide
-                               editingRestrictionValue = editingRestrictionWidget ? editingRestrictionWidget.getValue() : 'sitewide',
-                               editingIsSelected = editingWidget ? editingWidget.isSelected() : false,
+                               editingRestrictionValue = enablePartialBlocks ? editingRestrictionWidget.getValue() : 'sitewide',
+                               editingIsSelected = editingWidget.isSelected(),
                                isSitewide = editingIsSelected && editingRestrictionValue === 'sitewide';
 
-                       if ( enableAutoblockField ) {
-                               enableAutoblockField.toggle( !isNonEmptyIp );
+                       enableAutoblockWidget.setDisabled( isNonEmptyIp );
+                       if ( enableAutoblockWidget.isDisabled() ) {
+                               enableAutoblockWidget.setSelected( false );
+                       }
+
+                       anonOnlyWidget.setDisabled( !isIp && !isEmpty );
+                       if ( anonOnlyWidget.isDisabled() ) {
+                               anonOnlyWidget.setSelected( false );
                        }
-                       if ( hideUserField ) {
-                               hideUserField.toggle( !isNonEmptyIp && isIndefinite && isSitewide );
-                               if ( !hideUserField.isVisible() ) {
+
+                       if ( hideUserWidget ) {
+                               hideUserWidget.setDisabled( isNonEmptyIp || !isIndefinite || !isSitewide );
+                               if ( hideUserWidget.isDisabled() ) {
                                        hideUserWidget.setSelected( false );
                                }
                        }
-                       if ( anonOnlyField ) {
-                               anonOnlyField.toggle( isIp || isEmpty );
-                       }
-                       if ( watchUserField ) {
-                               watchUserField.toggle( !isIpRange || isEmpty );
+
+                       if ( watchUserWidget ) {
+                               watchUserWidget.setDisabled( isIpRange && !isEmpty );
+                               if ( watchUserWidget.isDisabled() ) {
+                                       watchUserWidget.setSelected( false );
+                               }
                        }
-                       if ( editingRestrictionWidget ) {
+
+                       if ( enablePartialBlocks ) {
                                editingRestrictionWidget.setDisabled( !editingIsSelected );
-                       }
-                       if ( pageRestrictionsWidget ) {
                                pageRestrictionsWidget.setDisabled( !editingIsSelected || isSitewide );
-                       }
-                       if ( namespaceRestrictionsWidget ) {
                                namespaceRestrictionsWidget.setDisabled( !editingIsSelected || isSitewide );
+                               if ( blockAllowsUTEdit ) {
+                                       // This option is disabled for partial blocks unless a namespace restriction
+                                       // for the User_talk namespace is in place.
+                                       preventTalkPageEditWidget.setDisabled(
+                                               editingIsSelected &&
+                                               editingRestrictionValue === 'partial' &&
+                                               namespaceRestrictionsWidget.getValue().indexOf(
+                                                       String( mw.config.get( 'wgNamespaceIds' ).user_talk )
+                                               ) === -1
+                                       );
+                               }
                        }
-                       if ( preventTalkPageEdit && namespaceRestrictionsWidget ) {
-                               // This option is disabled for partial blocks unless a namespace restriction
-                               // for the User_talk namespace is in place.
-                               preventTalkPageEdit.setDisabled(
-                                       editingIsSelected &&
-                                       editingRestrictionValue === 'partial' &&
-                                       namespaceRestrictionsWidget.getValue().indexOf(
-                                               String( mw.config.get( 'wgNamespaceIds' ).user_talk )
-                                       ) === -1
-                               );
-                       }
+
                        if ( !userChangedCreateAccount ) {
                                updatingBlockOptions = true;
                                createAccountWidget.setSelected( isSitewide );
 
                }
 
+               // This code is also loaded on the "block succeeded" page where there is no form,
+               // so check for block target widget; if it exists, the form is present
+               blockTargetWidget = infuseIfExists( $( '#mw-bi-target' ) );
+
                if ( blockTargetWidget ) {
-                       // Bind functions so they're checked whenever stuff changes
+                       data = require( './config.json' );
+                       enablePartialBlocks = data.EnablePartialBlocks;
+                       blockAllowsUTEdit = data.BlockAllowsUTEdit;
+                       userChangedCreateAccount = mw.config.get( 'wgCreateAccountDirty' );
+                       updatingBlockOptions = false;
+
+                       // Always present if blockTargetWidget is present
+                       editingWidget = OO.ui.infuse( $( '#mw-input-wpEditing' ) );
+                       expiryWidget = OO.ui.infuse( $( '#mw-input-wpExpiry' ) );
+                       createAccountWidget = OO.ui.infuse( $( '#mw-input-wpCreateAccount' ) );
+                       enableAutoblockWidget = OO.ui.infuse( $( '#mw-input-wpAutoBlock' ) );
+                       anonOnlyWidget = OO.ui.infuse( $( '#mw-input-wpHardBlock' ) );
                        blockTargetWidget.on( 'change', updateBlockOptions );
+                       editingWidget.on( 'change', updateBlockOptions );
                        expiryWidget.on( 'change', updateBlockOptions );
-                       if ( editingWidget ) {
-                               editingWidget.on( 'change', updateBlockOptions );
-                       }
-                       if ( editingRestrictionWidget ) {
-                               editingRestrictionWidget.on( 'change', updateBlockOptions );
-                       }
-                       if ( namespaceRestrictionsWidget ) {
-                               namespaceRestrictionsWidget.on( 'change', updateBlockOptions );
-                       }
-
                        createAccountWidget.on( 'change', function () {
                                if ( !updatingBlockOptions ) {
                                        userChangedCreateAccount = true;
                                }
                        } );
 
-                       // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
+                       // Present for certain rights
+                       watchUserWidget = infuseIfExists( $( '#mw-input-wpWatch' ) );
+                       hideUserWidget = infuseIfExists( $( '#mw-input-wpHideUser' ) );
+
+                       // Present for certain global configs
+                       if ( enablePartialBlocks ) {
+                               editingRestrictionWidget = OO.ui.infuse( $( '#mw-input-wpEditingRestriction' ) );
+                               pageRestrictionsWidget = OO.ui.infuse( $( '#mw-input-wpPageRestrictions' ) );
+                               namespaceRestrictionsWidget = OO.ui.infuse( $( '#mw-input-wpNamespaceRestrictions' ) );
+                               editingRestrictionWidget.on( 'change', updateBlockOptions );
+                               namespaceRestrictionsWidget.on( 'change', updateBlockOptions );
+                       }
+                       if ( blockAllowsUTEdit ) {
+                               preventTalkPageEditWidget = infuseIfExists( $( '#mw-input-wpDisableUTEdit' ) );
+                       }
+
                        updateBlockOptions();
                }
        } );
diff --git a/resources/src/mediawiki.special.changeslist.less b/resources/src/mediawiki.special.changeslist.less
deleted file mode 100644 (file)
index ce43855..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Styling for Special:Watchlist and Special:RecentChanges
- */
-
-.mw-changeslist-line-watched .mw-title {
-       font-weight: bold;
-}
-
-/*
- * Titles, including username links, and also tag names
- * are prone to getting jumbled up
- * with other titles, usernames, etc. in mixed RTL-LTR environment.
- */
-.mw-changeslist .mw-tag-marker,
-.mw-changeslist .mw-title {
-       unicode-bidi: embed;
-}
-
-/* Colored watchlist and recent changes numbers */
-.mw-plusminus-pos {
-       color: #006400; /* dark green */
-}
-
-.mw-plusminus-neg {
-       color: #8b0000; /* dark red */
-}
-
-.mw-plusminus-null {
-       color: #a2a9b1; /* gray */
-}
-
-/*
- * Bidi-isolate these numbers.
- * See https://phabricator.wikimedia.org/T93484
- */
-.mw-plusminus-pos,
-.mw-plusminus-neg,
-.mw-plusminus-null {
-       unicode-bidi: -moz-isolate;
-       unicode-bidi: isolate;
-}
-
-/* Prevent FOUC if legend is initially collapsed */
-.mw-changeslist-legend.mw-collapsed .mw-collapsible-content {
-       display: none;
-}
-
-.mw-changeslist-legend.mw-collapsed {
-       margin-bottom: 0;
-}
-
-/* Prevent pushing down the content if legend is collapsed */
-.mw-changeslist-legend.mw-collapsed ~ ul:first-of-type > li:first-child,
-.mw-changeslist-legend.mw-collapsed + h4 + div > table.mw-changeslist-line:first-child {
-       clear: right;
-}
-
-/* Hide RCFilters highlight containers if RCFilters is not enabled.
-   This is overridden in mw.ui.rcfilters.ChangesListWrapperWidget.less if RCFilters is enabled. */
-.mw-rcfilters-ui-highlights {
-       display: none;
-}
diff --git a/resources/src/mediawiki.special.changeslist/changeslist.less b/resources/src/mediawiki.special.changeslist/changeslist.less
new file mode 100644 (file)
index 0000000..f24d1f2
--- /dev/null
@@ -0,0 +1,24 @@
+.client-js .mw-input-hidden {
+       display: none;
+}
+
+/*
+ * Titles, including username links, and also tag names
+ * are prone to getting jumbled up
+ * with other titles, usernames, etc. in mixed RTL-LTR environment.
+ */
+.mw-changeslist .mw-tag-marker,
+.mw-changeslist .mw-title {
+       unicode-bidi: embed;
+}
+
+/*
+ * Bidi-isolate these numbers.
+ * See https://phabricator.wikimedia.org/T93484
+ */
+.mw-plusminus-pos,
+.mw-plusminus-neg,
+.mw-plusminus-null {
+       unicode-bidi: -moz-isolate;
+       unicode-bidi: isolate;
+}
diff --git a/resources/src/mediawiki.special.changeslist/default.less b/resources/src/mediawiki.special.changeslist/default.less
new file mode 100644 (file)
index 0000000..203beee
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Styling for Special:Watchlist and Special:RecentChanges
+ */
+
+/* Make sure namespace label is aligned correctly on mobile when checkboxes are displayed */
+.mw-label.mw-namespace-label {
+       vertical-align: top;
+}
+
+.mw-changeslist-line-watched .mw-title {
+       font-weight: bold;
+}
+
+/* Colored watchlist and recent changes numbers */
+.mw-plusminus-pos {
+       color: #006400; /* dark green */
+}
+
+.mw-plusminus-neg {
+       color: #8b0000; /* dark red */
+}
+
+.mw-plusminus-null {
+       color: #a2a9b1; /* gray */
+}
+
+/* Prevent FOUC if legend is initially collapsed */
+.mw-changeslist-legend.mw-collapsed .mw-collapsible-content {
+       display: none;
+}
+
+.mw-changeslist-legend.mw-collapsed {
+       margin-bottom: 0;
+}
+
+/* Prevent pushing down the content if legend is collapsed */
+.mw-changeslist-legend.mw-collapsed ~ ul:first-of-type > li:first-child,
+.mw-changeslist-legend.mw-collapsed + h4 + div > table.mw-changeslist-line:first-child {
+       clear: right;
+}
+
+/* Hide RCFilters highlight containers if RCFilters is not enabled.
+   This is overridden in mw.ui.rcfilters.ChangesListWrapperWidget.less if RCFilters is enabled. */
+.mw-rcfilters-ui-highlights {
+       display: none;
+}
index ffa9e42..71b343c 100644 (file)
@@ -3,9 +3,7 @@
  */
 ( function () {
        $( function () {
-               var $preferences, tabs, wrapper, previousTab, switchingNoHash;
-
-               $preferences = $( '#preferences' );
+               var tabs, previousTab, switchingNoHash;
 
                // Make sure the accessibility tip is focussable so that keyboard users take notice,
                // but hide it by default to reduce visual clutter.
                        } )
                        .insertBefore( '.mw-htmlform-ooui-wrapper' );
 
-               tabs = new OO.ui.IndexLayout( {
-                       expanded: false,
-                       // Do not remove focus from the tabs menu after choosing a tab
-                       autoFocus: false
-               } );
-
-               mw.config.get( 'wgPreferencesTabs' ).forEach( function ( tabConfig ) {
-                       var panel, $panelContents;
-
-                       panel = new OO.ui.TabPanelLayout( tabConfig.name, {
-                               expanded: false,
-                               label: tabConfig.label
-                       } );
-                       $panelContents = $( '#mw-prefsection-' + tabConfig.name );
-
-                       // Hide the unnecessary PHP PanelLayouts
-                       // (Do not use .remove(), as that would remove event handlers for everything inside them)
-                       $panelContents.parent().detach();
+               tabs = OO.ui.infuse( $( '.mw-prefs-tabs' ) );
 
-                       panel.$element.append( $panelContents );
-                       tabs.addTabPanels( [ panel ] );
-
-                       // Remove duplicate labels
-                       // (This must be after .addTabPanels(), otherwise the tab item doesn't exist yet)
-                       $panelContents.children( 'legend' ).remove();
-                       $panelContents.attr( 'aria-labelledby', panel.getTabItem().getElementId() );
-               } );
-
-               wrapper = new OO.ui.PanelLayout( {
-                       expanded: false,
-                       padded: false,
-                       framed: true
-               } );
-               wrapper.$element.append( tabs.$element );
-               $preferences.prepend( wrapper.$element );
-               $( '.mw-prefs-faketabs' ).remove();
+               tabs.$element.addClass( 'mw-prefs-tabs-infused' );
 
                function enhancePanel( panel ) {
                        if ( !panel.$element.data( 'mw-section-infused' ) ) {
-                               // mw-htmlform-autoinfuse-lazy class has been removed by replacing faketabs
+                               panel.$element.removeClass( 'mw-htmlform-autoinfuse-lazy' );
                                mw.hook( 'htmlform.enhance' ).fire( panel.$element );
                                panel.$element.data( 'mw-section-infused', true );
                        }
@@ -75,7 +40,7 @@
                        // Changing the hash apparently causes keyboard focus to be lost?
                        // Save and restore it. This makes no sense though.
                        active = document.activeElement;
-                       location.hash = '#mw-prefsection-' + panel.getName();
+                       location.hash = '#' + panel.getName();
                        if ( active ) {
                                active.focus();
                        }
@@ -86,7 +51,7 @@
 
                /**
                 * @ignore
-                * @param {string} name the name of a tab without the prefix ("mw-prefsection-")
+                * @param {string} name The name of a tab
                 * @param {boolean} [noHash] A hash will be set according to the current
                 *  open section. Use this flag to suppress this.
                 */
                                matchedElement, parentSection;
                        if ( hash.match( /^#mw-prefsection-[\w]+$/ ) ) {
                                mw.storage.session.remove( 'mwpreferences-prevTab' );
-                               switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
+                               switchPrefTab( hash.slice( 1 ) );
                        } else if ( hash.match( /^#mw-[\w-]+$/ ) ) {
                                matchedElement = document.getElementById( hash.slice( 1 ) );
                                parentSection = $( matchedElement ).parent().closest( '[id^="mw-prefsection-"]' );
                                if ( parentSection.length ) {
                                        mw.storage.session.remove( 'mwpreferences-prevTab' );
                                        // Switch to proper tab and scroll to selected item.
-                                       switchPrefTab( parentSection.attr( 'id' ).replace( 'mw-prefsection-', '' ), true );
+                                       switchPrefTab( parentSection.attr( 'id' ), true );
                                        matchedElement.scrollIntoView();
                                }
                        }
                        if ( hash.match( /^#mw-[\w-]+/ ) ) {
                                detectHash();
                        } else if ( hash === '' ) {
-                               switchPrefTab( 'personal', true );
+                               switchPrefTab( 'mw-prefsection-personal', true );
                        }
                } )
                        // Run the function immediately to select the proper tab on startup.
index b1931f4..532b9ca 100644 (file)
        overflow: hidden;
 }
 
-/* Most outer Panellayout:
- * Decrease contrast of `border` slightly as padding/border combination is sufficient
- * accessibility wise and focus of content is more important here. */
-#preferences .oo-ui-panelLayout-framed {
-       border-color: #c8ccd1;
-}
+.mw-prefs-tabs {
+       .mw-prefs-fieldset-wrapper {
+               padding-left: 0;
+               padding-right: 0;
+
+               &:first-child {
+                       padding-top: 0;
+               }
 
-#preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       border-width: 0;
-       border-radius: 0;
-       padding-left: 0;
-       padding-right: 0;
-       box-shadow: none;
+               &:last-child {
+                       padding-bottom: 0;
+               }
+       }
 }
 
-.mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu a {
-       color: inherit;
-       text-decoration: none;
+.mw-prefs-tabs-wrapper.oo-ui-panelLayout-framed,
+.mw-prefs-tabs > .oo-ui-menuLayout-content > .oo-ui-indexLayout-stackLayout > .oo-ui-tabPanelLayout {
+       /* Decrease contrast of `border` slightly as padding/border combination is sufficient
+        * accessibility wise and focus of content is more important here. */
+       border-color: #c8ccd1;
 }
 
-/* Disabled JavaScript */
+/* JavaScript disabled */
 .client-nojs {
-       /* Adjust the borders: frame each prefsection instead of the
-        * whole tabLayout wrapper */
-       #preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed:first-child {
-               border-color: #c8ccd1;
-               border-width: 1px 0 0;
-       }
-
-       #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed:last-child {
-               padding-bottom: 0;
-               margin-bottom: 0;
-       }
-
-       /* Fake Tabs to address reflow */
-       .mw-prefs-faketabs {
+       // Disable .oo-ui-panelLayout-framed on outer wrapper
+       .mw-prefs-tabs-wrapper {
                border-width: 0;
                border-radius: 0;
-               .box-shadow( none );
+       }
 
-               > .oo-ui-menuLayout > .oo-ui-menuLayout-content > .oo-ui-stackLayout {
-                       margin-bottom: 1em;
+       .mw-prefs-tabs {
+               // Hide the tab menu when JS is disabled as we can't use this feature
+               > .oo-ui-menuLayout-menu {
+                       display: none;
                }
 
-               /* Hide the tab menu when JS is disabled as we can't use this feature */
-               > .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
-                       display: none;
+               .mw-prefs-section-fieldset {
+                       // <legend> is hard to style, so apply border to top of group
+                       > .oo-ui-fieldsetLayout-group {
+                               padding-top: 1.5em;
+                               border-top: 1px solid #c8ccd1;
+                       }
+
+                       // Remove spacing between legend and underline
+                       &.oo-ui-labelElement > .oo-ui-fieldsetLayout-header > .oo-ui-labelElement-label {
+                               margin-bottom: 0;
+                       }
+               }
+
+               // Spacing between sections
+               > .oo-ui-menuLayout-content > .oo-ui-indexLayout-stackLayout > .oo-ui-tabPanelLayout {
+                       margin-bottom: 1em;
                }
        }
 }
 
-/* Enabled JavaScript
- * Hide top level legends when JS is enabled, as they will not be visible
- * when the real tabLayout is built */
-.client-js #preferences {
+/* JavaScript enabled */
+.client-js .mw-prefs-tabs {
        .oo-ui-tabPanelLayout {
-               padding-top: 0.5em;
+               // Panels don't need borders as the IndexLayout is inside a framed wrapper.
+               border: 0;
 
-               & > fieldset > legend {
+               // Hide section legend, only used in nojs mode
+               > fieldset > legend {
                        display: none;
                }
        }
 
-       .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-               margin-top: 2.286em; /* equals `32px` at `font-size: 14px;` */
-               margin-bottom: 0;
-               border-width: 0;
-               border-radius: 0;
-               padding: 0;
-               box-shadow: none;
-
-               &:first-child {
-                       margin-top: 0.85714286em;
-               }
-
-               .oo-ui-panelLayout-framed:first-child {
-                       margin-top: 0;
+       // Hide all but the first panel before infusion
+       &:not( .mw-prefs-tabs-infused ) {
+               .oo-ui-tabPanelLayout:not( :first-child ) {
+                       display: none;
                }
        }
-
-       > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
-               margin-bottom: 1em;
-       }
 }
 
 /* Make the "Basic information" section more compact */
index 8885883..310832d 100644 (file)
@@ -10,7 +10,7 @@
         */
        rc = {
                /**
-                * Handler to disable/enable the namespace selector checkboxes when the
+                * Handler to hide/show the namespace selector checkboxes when the
                 * special 'all' namespace is selected/unselected respectively.
                 */
                updateCheckboxes: function () {
                        var isAllNS = $select.val() === '';
 
                        // Iterates over checkboxes and propagate the selected option
-                       $checkboxes.prop( 'disabled', isAllNS );
+                       $checkboxes.toggleClass( 'mw-input-hidden', isAllNS );
                },
 
                init: function () {
                        $select = $( '#namespace' );
-                       $checkboxes = $( '#nsassociated, #nsinvert' );
+                       $checkboxes = $( '#nsassociated, #nsinvert' ).closest( '.mw-input-with-label' );
 
-                       // Bind to change event, and trigger once to set the initial state of the checkboxes.
-                       rc.updateCheckboxes();
+                       // Bind to change event of the checkboxes.
+                       // The initial state is already set in HTML.
                        $select.on( 'change', rc.updateCheckboxes );
                }
        };
index 777f5e9..fff2d4e 100644 (file)
@@ -30,7 +30,7 @@
                updateForCheckbox();
        } );
 
-       // Check if the username is invalid or already taken
+       // Check if the username is invalid or already taken; show username normalisation warning
        mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
                var $usernameInput = $root.find( '#wpName2' ),
                        $passwordInput = $root.find( '#wpPassword2' ),
                        // We could just use .then() if we didn't have to pass on .abort()…
                        var d, apiPromise;
 
+                       // Leading/trailing/multiple whitespace characters are always stripped in usernames,
+                       // this should not require a warning. We do warn about underscores.
+                       username = username.replace( / +/g, ' ' ).trim();
+
                        d = $.Deferred();
                        apiPromise = api.get( {
                                action: 'query',
                                                                return m.html;
                                                        } ) : []
                                                } );
+                                       } else if ( userinfo.name !== username ) {
+                                               d.resolve( { valid: true, messages: [
+                                                       mw.message( 'createacct-normalization', username, userinfo.name ).parseDom()
+                                               ] } );
                                        } else {
                                                d.resolve( { valid: true, messages: [] } );
                                        }
index 4dc4c27..923b595 100644 (file)
@@ -1,3 +1,6 @@
+/*!
+ * Styles for Special:ApiSandbox
+ */
 .client-js .mw-apisandbox-nojs {
        display: none;
 }
index d7ee3da..6d12722 100644 (file)
@@ -1,10 +1,12 @@
-/* Special:Block styles */
+/*!
+ * Styles for Special:Block
+ */
 
-// OOUIHTMLForm styles
-@ooui-font-size-browser: 16; // Assumed browser default of `16px`
-@ooui-font-size-base: 0.875em; // Equals `14px` at browser default of `16px`
+// OOUIHTMLForm specifics
+@ooui-font-size-browser: 16; // Assumed browser default of `16px`.
+@ooui-font-size-base: 0.875em; // Equals `14px` at browser default of `16px`.
 
-@ooui-spacing-radio-label: 26 / @ooui-font-size-browser / @ooui-font-size-base; // Equals `1.85714286em`≈`26px`
+@ooui-spacing-radio-label: 26 / @ooui-font-size-browser / @ooui-font-size-base; // Equals `1.85714286em`≈`26px`.
 
 body.mw-special-Block {
        .mw-block-editing-restriction.oo-ui-fieldLayout {
index 87b7a8b..38b4078 100644 (file)
@@ -1,3 +1,6 @@
+/*!
+ * Styles for Special:ComparePages
+ */
 @import 'mediawiki.mixins';
 
 .mw-special-ComparePages .mw-htmlform-ooui-wrapper {
index 204009c..8964a13 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * Styling for Special:EditTags and action=editchangetags
+ * Styles for Special:EditTags and action=editchangetags
  */
 #mw-edittags-tags-selector td {
        vertical-align: top;
index 835cab8..8d72b11 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * Styling for Special:NewPages
+ * Styles for Special:NewPages
  */
 
 // OOUIHTMLForm styles
index 7ef75d0..7240bd4 100644 (file)
@@ -1,4 +1,8 @@
-/* Distinguish actual data from information about it being hidden visually */
+/*!
+ * Styles for Special:PagesWithProp
+ */
+
+/* Distinguish actual data from information about it being hidden visually. */
 .prop-value-hidden {
        font-style: italic;
 }
index e053b6c..3798f1e 100644 (file)
@@ -1,6 +1,9 @@
-/* Special:AllMessages */
+/*!
+ * Styles shared across various special pages.
+ */
 @import 'mediawiki.mixins';
 
+/* Special:AllMessages */
 /* Visually hide repeating text, but leave in for better form navigation on screen readers */
 .mw-special-Allmessages .mw-htmlform-ooui .oo-ui-fieldsetLayout:first-child .oo-ui-fieldsetLayout-header {
        .mixin-screen-reader-text();
 .mw-passwordpolicies-table tr {
        vertical-align: top;
 }
+
+.passwordpolicies-policy-flags {
+       font-size: 90%;
+}
index 626a7e8..0a5796e 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * Styling for Special:Upload
+ * Styles for Special:Upload
  */
 .mw-destfile-warning {
        border: 1px solid #fde29b;
index 14ad695..06a74f5 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * Styling for Special:UserRights
+ * Styles for Special:UserRights
  */
 .mw-userrights-nested {
        margin-left: 1.2em;
index c9861c2..1660bd2 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * Styling for elements generated by JavaScript on Special:Watchlist
+ * Styles for elements generated by JavaScript on Special:Watchlist
  */
 .mw-changelist-line-inner-unwatched {
        text-decoration: line-through;
index a1646a8..92b4b8a 100644 (file)
@@ -43,7 +43,7 @@
 
        * {
                // Reset font sizes, see T74727
-               font: inherit;
+               font-size: inherit;
                vertical-align: middle;
        }
 
@@ -74,7 +74,7 @@
                        background-origin: border-box;
                        background-position: center center;
                        background-repeat: no-repeat;
-                       .background-size( 0, 0 );
+                       background-size: 0 0;
                        .box-sizing( border-box );
                        position: absolute;
                        // Ensure alignment of checkbox to middle of the text in long labels, see T85241
@@ -90,7 +90,7 @@
                // Apply a checkmark on the pseudo `:before` element when the input is checked
                &:checked + label:before {
                        .background-image-svg( 'images/checkbox-checked.svg', 'images/checkbox-checked.png' );
-                       .background-size( 90%, 90% );
+                       background-size: 90% 90%;
                }
 
                &:enabled {
index 09bf9ca..5fa8e5a 100644 (file)
        // This specifies styling for individual field validation error messages.
        // Show them below the fields to prevent line break glitches, and leave
        // some space between the field and the error message box.
-       .mw-ui-vform-field .error {
-               display: block;
-               margin-top: 5px;
+       .mw-ui-vform-field {
+               .error,
+               .warning {
+                       display: block;
+                       margin-top: 5px;
+               }
        }
 }
 
index d9b7c6d..c0865c6 100644 (file)
@@ -44,7 +44,7 @@
 
        * {
                // reset font sizes (see T74727)
-               font: inherit;
+               font-size: inherit;
                vertical-align: middle;
        }
 
index d9b1227..5f629e7 100644 (file)
                },
 
                /**
-                * Get an automatically generated random ID (persisted in sessionStorage)
+                * Retrieve a random ID persisted in sessionStorage, generating it if needed
                 *
-                * This ID is ephemeral for everyone, staying in their browser only until they
-                * close their browsing session.
+                * This ID is stored in sessionStorage and persists within a single tab,
+                * including between page views through links and form submissions,
+                * and when going forwards/backwards in browser history, and when restoring
+                * a closed tab, or restoring a closed browser session.
+                *
+                * This is different from session cookies, because it is not shared between
+                * tabs of the same browser. Two simultaneous pageviews in the same browser
+                * can have different session IDs. The ID is also not re-used when opening
+                * a new tab to a website after fully closing others.
+                *
+                * See https://phabricator.wikimedia.org/T118063#4547178 and
+                * https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage
+                * for more information.
                 *
                 * @return {string} Random session ID
                 */
                        var userGroups = mw.config.get( 'wgUserGroups', [] );
 
                        // Uses promise for backwards compatibility
-                       return $.Deferred().resolve( userGroups ).done( callback );
+                       return $.Deferred().resolve( userGroups ).then( callback );
                },
 
                /**
                        return getUserInfo().then(
                                function ( userInfo ) { return userInfo.rights; },
                                function () { return []; }
-                       ).done( callback );
+                       ).then( callback );
                }
        } );
 
index 3bfeb8d..81cf433 100644 (file)
                        // eslint-disable-next-line no-restricted-properties
                        v = v.normalize();
                }
-               re = new RegExp( '^\\s*' + v.replace( /([\\{}()|.?*+\-^$\[\]])/g, '\\$1' ), 'i' ); // eslint-disable-line no-useless-escape
+               re = new RegExp( '^\\s*' + mw.RegExp.escape( v ), 'i' );
                for ( k in this.values ) {
                        k = +k;
                        if ( !isNaN( k ) && re.test( this.values[ k ] ) ) {
index ffc1818..b53b58f 100644 (file)
@@ -19,6 +19,7 @@
         * @mixins OO.ui.mixin.IconElement
         * @mixins OO.ui.mixin.IndicatorElement
         * @mixins OO.ui.mixin.PendingElement
+        * @mixins OO.ui.mixin.FlaggedElement
         *
         * @constructor
         * @param {Object} [config] Configuration options
@@ -70,6 +71,7 @@
                OO.ui.mixin.IconElement.call( this, config );
                OO.ui.mixin.IndicatorElement.call( this, config );
                OO.ui.mixin.PendingElement.call( this, config );
+               OO.ui.mixin.FlaggedElement.call( this, config );
 
                // Properties
                this.$handle = $( '<span>' );
        OO.mixinClass( mw.widgets.datetime.DateTimeInputWidget, OO.ui.mixin.IconElement );
        OO.mixinClass( mw.widgets.datetime.DateTimeInputWidget, OO.ui.mixin.IndicatorElement );
        OO.mixinClass( mw.widgets.datetime.DateTimeInputWidget, OO.ui.mixin.PendingElement );
+       OO.mixinClass( mw.widgets.datetime.DateTimeInputWidget, OO.ui.mixin.FlaggedElement );
 
        /* Static properties */
 
index f66b0d2..753a5c7 100644 (file)
@@ -2,7 +2,7 @@
 
        /**
         * Provides various methods needed for formatting dates and times. This
-        * implementation implments the [Discordian calendar][1], mainly for testing with
+        * implementation implements the [Discordian calendar][1], mainly for testing with
         * something very different from the usual Gregorian calendar.
         *
         * Being intended mainly for testing, niceties like i18n and better
index 63da95a..453bf03 100644 (file)
         *
         * @param {OO.ui.TextInputWidget} textInputWidget Text input widget
         * @param {number} [limit] Byte limit, defaults to $input's maxlength
+        * @param {Function} [filterFunction] Function to call on the string before assessing the length.
         */
-       mw.widgets.visibleByteLimit = function ( textInputWidget, limit ) {
+       mw.widgets.visibleByteLimit = function ( textInputWidget, limit, filterFunction ) {
                limit = limit || +textInputWidget.$input.attr( 'maxlength' );
+               if ( !filterFunction || typeof filterFunction !== 'function' ) {
+                       filterFunction = undefined;
+               }
 
                function updateCount() {
-                       var remaining = limit - byteLength( textInputWidget.getValue() );
+                       var value = textInputWidget.getValue(),
+                               remaining;
+                       if ( filterFunction ) {
+                               value = filterFunction( value );
+                       }
+                       remaining = limit - byteLength( value );
                        if ( remaining > 99 ) {
                                remaining = '';
                        } else {
@@ -32,7 +41,7 @@
                updateCount();
 
                // Actually enforce limit
-               textInputWidget.$input.byteLimit( limit );
+               textInputWidget.$input.byteLimit( limit, filterFunction );
        };
 
        /**
         * Uses jQuery#codePointLimit to enforce the limit.
         *
         * @param {OO.ui.TextInputWidget} textInputWidget Text input widget
-        * @param {number} [limit] Byte limit, defaults to $input's maxlength
+        * @param {number} [limit] Code point limit, defaults to $input's maxlength
+        * @param {Function} [filterFunction] Function to call on the string before assessing the length.
         */
-       mw.widgets.visibleCodePointLimit = function ( textInputWidget, limit ) {
+       mw.widgets.visibleCodePointLimit = function ( textInputWidget, limit, filterFunction ) {
                limit = limit || +textInputWidget.$input.attr( 'maxlength' );
+               if ( !filterFunction || typeof filterFunction !== 'function' ) {
+                       filterFunction = undefined;
+               }
 
                function updateCount() {
-                       var remaining = limit - codePointLength( textInputWidget.getValue() );
+                       var value = textInputWidget.getValue(),
+                               remaining;
+                       if ( filterFunction ) {
+                               value = filterFunction( value );
+                       }
+                       remaining = limit - codePointLength( value );
                        if ( remaining > 99 ) {
                                remaining = '';
                        } else {
@@ -60,7 +78,7 @@
                updateCount();
 
                // Actually enforce limit
-               textInputWidget.$input.codePointLimit( limit );
+               textInputWidget.$input.codePointLimit( limit, filterFunction );
        };
 
 }() );
index aaa5da5..e8ac592 100644 (file)
 
                this.calculateSizing( this.data );
 
-               // Get wiki default thumbnail size
-               this.defaultThumbSize = mw.config.get( 'wgVisualEditorConfig' )
-                       .defaultUserOptions.defaultthumbsize;
-
                // Initialization
                this.setLabel( new mw.Title( this.data.title ).getNameText() );
                this.$label.addClass( 'mw-widget-mediaResultWidget-nameLabel' );
index 3a71760..c25db2f 100644 (file)
                        focusout: this.onBlur.bind( this )
                } );
                this.calendar.$element.on( {
+                       focusout: this.onBlur.bind( this ),
                        click: this.onCalendarClick.bind( this ),
                        keypress: this.onCalendarKeyPress.bind( this )
                } );
index 3758bd7..647c983 100644 (file)
 .mw-widget-dateInputWidget {
        &.oo-ui-textInputWidget {
                display: inline-block;
-               position: relative;
-               width: 21em;
-               margin-top: 0.25em;
+               max-width: 21em;
                // .oo-ui-inline-spacing( 0.5em ); already inherited from `.oo-ui-inputWidget`
-               margin-bottom: 0.25em;
-               margin-left: 0;
+
+               .oo-ui-labelElement-label {
+                       line-height: @line-height-widget-singleline;
+               }
        }
 
        // Note that this block applies to both the PHP widget and the JS widget
diff --git a/resources/src/mediawiki.widgets/mw.widgets.NamespacesMenuOptionWidget.js b/resources/src/mediawiki.widgets/mw.widgets.NamespacesMenuOptionWidget.js
new file mode 100644 (file)
index 0000000..24f52af
--- /dev/null
@@ -0,0 +1,37 @@
+/*!
+ * MediaWiki Widgets - NamespacesMenuOptionWidget class.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+( function () {
+
+       /**
+        * Creates an mw.widgets.NamespacesMenuOptionWidget object
+        *
+        * This MenuOptionWidget widget returns an item match text that includes
+        * both the label and the data, so the menu can filter on either.
+        *
+        * @class
+        * @extends OO.ui.MenuOptionWidget
+        *
+        * @constructor
+        * @param {Object} [config] Configuration options
+        */
+       mw.widgets.NamespacesMenuOptionWidget = function MwWidgetsNamespacesMenuOptionWidget( config ) {
+               // Parent
+               mw.widgets.NamespacesMenuOptionWidget.parent.call( this, config );
+       };
+
+       /* Setup */
+
+       OO.inheritClass( mw.widgets.NamespacesMenuOptionWidget, OO.ui.MenuOptionWidget );
+
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.NamespacesMenuOptionWidget.prototype.getMatchText = function () {
+               return this.getData() + ' ' + this.getLabel();
+       };
+
+}() );
index e5adc29..d4e9b1c 100644 (file)
                        {
                                clearInputOnChoose: true,
                                inputPosition: 'inline',
-                               allowEditTags: false
+                               allowEditTags: false,
+                               menu: {
+                                       filterMode: 'substring'
+                               }
                        },
                        config,
                        {
        OO.inheritClass( mw.widgets.NamespacesMultiselectWidget, OO.ui.MenuTagMultiselectWidget );
        OO.mixinClass( mw.widgets.NamespacesMultiselectWidget, OO.ui.mixin.PendingElement );
 
+       /* Methods */
+
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.NamespacesMultiselectWidget.prototype.createMenuOptionWidget = function ( data, label, icon ) {
+               return new mw.widgets.NamespacesMenuOptionWidget( {
+                       data: data,
+                       label: label || data,
+                       icon: icon
+               } );
+       };
+
 }() );
index 65cf316..f961da2 100644 (file)
         */
        function fnv132( str ) {
                var hash = 0x811C9DC5,
-                       i;
+                       i = 0;
 
                /* eslint-disable no-bitwise */
-               for ( i = 0; i < str.length; i++ ) {
+               for ( ; i < str.length; i++ ) {
                        hash += ( hash << 1 ) + ( hash << 4 ) + ( hash << 7 ) + ( hash << 8 ) + ( hash << 24 );
                        hash ^= str.charCodeAt( i );
                }
                 * @private
                 * @class
                 */
-               StringSet = window.Set || function StringSet() {
+               StringSet = window.Set || function () {
                        var set = Object.create( null );
-                       this.add = function ( value ) {
-                               set[ value ] = true;
-                       };
-                       this.has = function ( value ) {
-                               return value in set;
+                       return {
+                               add: function ( value ) {
+                                       set[ value ] = true;
+                               },
+                               has: function ( value ) {
+                                       return value in set;
+                               }
                        };
                };
        }
                         *             'dependencies': ['required.foo', 'bar.also', ...]
                         *             'group': 'somegroup', (or) null
                         *             'source': 'local', (or) 'anotherwiki'
-                        *             'skip': 'return !!window.Example', (or) null
+                        *             'skip': 'return !!window.Example', (or) null, (or) boolean result of skip
                         *             'module': export Object
                         *
                         *             // Set from execute() or mw.loader.state()
                         *             'state': 'registered', 'loaded', 'loading', 'ready', 'error', or 'missing'
                         *
                         *             // Optionally added at run-time by mw.loader.implement()
-                        *             'skipped': true
                         *             'script': closure, array of urls, or string
                         *             'style': { ... } (see #execute)
                         *             'messages': { 'key': 'value', ... }
 
                        /**
                         * @private
-                        * @param {Array} modules List of module names
+                        * @param {string[]} modules List of module names
                         * @return {string} Hash of concatenated version hashes.
                         */
                        function getCombinedVersion( modules ) {
                         * execute the module or job now.
                         *
                         * @private
-                        * @param {Array} modules Names of modules to be checked
+                        * @param {string[]} modules Names of modules to be checked
                         * @return {boolean} True if all modules are in state 'ready', false otherwise
                         */
                        function allReady( modules ) {
-                               var i;
-                               for ( i = 0; i < modules.length; i++ ) {
+                               var i = 0;
+                               for ( ; i < modules.length; i++ ) {
                                        if ( mw.loader.getState( modules[ i ] ) !== 'ready' ) {
                                                return false;
                                        }
                         * @return {boolean} True if no modules are in state 'error' or 'missing', false otherwise
                         */
                        function anyFailed( modules ) {
-                               var i, state;
-                               for ( i = 0; i < modules.length; i++ ) {
+                               var state,
+                                       i = 0;
+                               for ( ; i < modules.length; i++ ) {
                                        state = mw.loader.getState( modules[ i ] );
                                        if ( state === 'error' || state === 'missing' ) {
                                                return true;
                         *  dependencies, such that later modules depend on earlier modules. The array
                         *  contains the module names. If the array contains already some module names,
                         *  this function appends its result to the pre-existing array.
-                        * @param {StringSet} [unresolved] Used to track the current dependency
-                        *  chain, and to report loops in the dependency graph.
-                        * @throws {Error} If any unregistered module or a dependency loop is encountered
+                        * @param {StringSet} [unresolved] Used to detect loops in the dependency graph.
+                        * @throws {Error} If an unknown module or a circular dependency is encountered
                         */
                        function sortDependencies( module, resolved, unresolved ) {
-                               var i, deps, skip;
+                               var i, skip, deps;
 
                                if ( !( module in registry ) ) {
-                                       throw new Error( 'Unknown dependency: ' + module );
+                                       throw new Error( 'Unknown module: ' + module );
                                }
 
-                               if ( registry[ module ].skip !== null ) {
+                               if ( typeof registry[ module ].skip === 'string' ) {
                                        // eslint-disable-next-line no-new-func
-                                       skip = new Function( registry[ module ].skip );
-                                       registry[ module ].skip = null;
-                                       if ( skip() ) {
-                                               registry[ module ].skipped = true;
+                                       skip = ( new Function( registry[ module ].skip )() );
+                                       registry[ module ].skip = !!skip;
+                                       if ( skip ) {
                                                registry[ module ].dependencies = [];
                                                setAndPropagate( module, 'ready' );
                                                return;
                                        }
                                }
 
-                               if ( resolved.indexOf( module ) !== -1 ) {
-                                       // Module already resolved; nothing to do
-                                       return;
-                               }
                                // Create unresolved if not passed in
                                if ( !unresolved ) {
                                        unresolved = new StringSet();
                                }
 
-                               // Add base modules
-                               if ( baseModules.indexOf( module ) === -1 ) {
-                                       for ( i = 0; i < baseModules.length; i++ ) {
-                                               if ( resolved.indexOf( baseModules[ i ] ) === -1 ) {
-                                                       resolved.push( baseModules[ i ] );
-                                               }
-                                       }
-                               }
-
-                               // Tracks down dependencies
+                               // Track down dependencies
                                deps = registry[ module ].dependencies;
                                unresolved.add( module );
                                for ( i = 0; i < deps.length; i++ ) {
                                                sortDependencies( deps[ i ], resolved, unresolved );
                                        }
                                }
+
                                resolved.push( module );
                        }
 
                         * @throws {Error} If an unregistered module or a dependency loop is encountered
                         */
                        function resolve( modules ) {
-                               var i, resolved = [];
-                               for ( i = 0; i < modules.length; i++ ) {
+                               // Always load base modules
+                               var resolved = baseModules.slice(),
+                                       i = 0;
+                               for ( ; i < modules.length; i++ ) {
                                        sortDependencies( modules[ i ], resolved );
                                }
                                return resolved;
                         * @return {Array} List of dependencies.
                         */
                        function resolveStubbornly( modules ) {
-                               var i, saved, resolved = [];
-                               for ( i = 0; i < modules.length; i++ ) {
+                               var saved,
+                                       // Always load base modules
+                                       resolved = baseModules.slice(),
+                                       i = 0;
+                               for ( ; i < modules.length; i++ ) {
                                        saved = resolved.slice();
                                        try {
                                                sortDependencies( modules[ i ], resolved );
                                        if ( script.parentNode ) {
                                                script.parentNode.removeChild( script );
                                        }
-                                       script = null;
                                        if ( callback ) {
                                                callback();
                                                callback = null;
                         * to a query string of the form `foo.bar,baz|bar.baz,quux`.
                         *
                         * See `ResourceLoader::makePackedModulesString()` in PHP, of which this is a port.
-                        * On the server, unpacking is done by `ResourceLoaderContext::expandModuleNames()`.
+                        * On the server, unpacking is done by `ResourceLoader::expandModuleNames()`.
                         *
                         * Note: This is only half of the logic, the other half has to be in #batchRequest(),
                         * because its implementation needs to keep track of potential string size in order
                         * @param {string[]} batch
                         */
                        function batchRequest( batch ) {
-                               var reqBase, splits, maxQueryLength, b, bSource, bGroup,
+                               var reqBase, splits, b, bSource, bGroup,
                                        source, group, i, modules, sourceLoadScript,
                                        currReqBase, currReqBaseLength, moduleMap, currReqModules, l,
                                        lastDotIndex, prefix, suffix, bytesAdded;
                                        lang: mw.config.get( 'wgUserLanguage' ),
                                        debug: mw.config.get( 'debug' )
                                };
-                               maxQueryLength = mw.config.get( 'wgResourceLoaderMaxQueryLength', 2000 );
 
                                // Split module list by source and by group.
                                splits = Object.create( null );
                                                                modules[ i ].length + 3; // '%7C'.length == 3
 
                                                        // If the url would become too long, create a new one, but don't create empty requests
-                                                       if ( maxQueryLength > 0 && currReqModules.length && l + bytesAdded > maxQueryLength ) {
+                                                       if ( currReqModules.length && l + bytesAdded > mw.loader.maxQueryLength ) {
                                                                // Dispatch what we've got...
                                                                doRequest();
                                                                // .. and start again.
                                                                moduleMap = Object.create( null );
                                                                currReqModules = [];
 
-                                                               mw.track( 'resourceloader.splitRequest', { maxQueryLength: maxQueryLength } );
+                                                               mw.track( 'resourceloader.splitRequest', { maxQueryLength: mw.loader.maxQueryLength } );
                                                        }
                                                        if ( !moduleMap[ prefix ] ) {
                                                                moduleMap[ prefix ] = [];
                                 */
                                moduleRegistry: registry,
 
+                               /**
+                                * Exposed for testing and debugging only.
+                                *
+                                * @see #batchRequest
+                                * @property
+                                * @private
+                                */
+                               maxQueryLength: $VARS.maxQueryLength,
+
                                /**
                                 * @inheritdoc #newStyleTag
                                 * @method
                                 * @private
                                 */
                                work: function () {
-                                       var q, batch, implementations, sourceModules;
-
-                                       batch = [];
+                                       var implementations, sourceModules,
+                                               batch = [],
+                                               q = 0;
 
                                        // Appends a list of modules from the queue to the batch
-                                       for ( q = 0; q < queue.length; q++ ) {
+                                       for ( ; q < queue.length; q++ ) {
                                                // Only load modules which are registered
                                                if ( queue[ q ] in registry && registry[ queue[ q ] ].state === 'registered' ) {
                                                        // Prevent duplicate entries
                                 *  "text/javascript"; if no type is provided, text/javascript is assumed.
                                 */
                                load: function ( modules, type ) {
-                                       var filtered, l;
+                                       var l;
 
                                        // Allow calling with a url or single dependency as a string
                                        if ( typeof modules === 'string' ) {
                                                modules = [ modules ];
                                        }
 
-                                       // Filter out top-level modules that are unknown or failed to load before.
-                                       filtered = modules.filter( function ( module ) {
-                                               var state = mw.loader.getState( module );
-                                               return state !== 'error' && state !== 'missing';
-                                       } );
-                                       // Resolve remaining list using the known dependency tree.
-                                       // This also filters out modules with unknown dependencies. (T36853)
-                                       filtered = resolveStubbornly( filtered );
-                                       // Some modules are not yet ready, add to module load queue.
-                                       enqueue( filtered, undefined, undefined );
+                                       // Resolve modules into flat list for internal queuing.
+                                       // This also filters out unknown modules and modules with
+                                       // unknown dependencies, allowing the rest to continue. (T36853)
+                                       enqueue( resolveStubbornly( modules ), undefined, undefined );
                                },
 
                                /**
                                                                return;
                                                        }
                                                } catch ( e ) {
-                                                       mw.trackError( 'resourceloader.exception', {
-                                                               exception: e,
-                                                               source: 'store-localstorage-init'
-                                                       } );
+                                                       // Perhaps localStorage was disabled by the user, or got corrupted.
+                                                       // See point 3 and 4 below. (T195647)
                                                }
 
                                                // If we get here, one of four things happened:
index bebf4dc..240757c 100644 (file)
  *
  * Other browsers that pass the check are considered Grade X.
  *
- * @param {string} [str] User agent, defaults to navigator.userAgent
+ * @private
+ * @param {string} ua User agent string
  * @return {boolean} User agent is compatible with MediaWiki JS
  */
-function isCompatible( str ) {
-       var ua = str || navigator.userAgent;
+function isCompatible( ua ) {
        return !!(
                // https://caniuse.com/#feat=es5
                // https://caniuse.com/#feat=use-strict
@@ -76,7 +76,7 @@ function isCompatible( str ) {
        );
 }
 
-if ( !isCompatible() ) {
+if ( !isCompatible( navigator.userAgent ) ) {
        // Handle Grade C
        // Undo speculative Grade A <html> class. See ResourceLoaderClientHtml::getDocumentAttributes().
        document.documentElement.className = document.documentElement.className
index 2feb438..e24c4c5 100644 (file)
@@ -17,7 +17,7 @@ class TestSetup {
                global $wgDevelopmentWarnings;
                global $wgSessionProviders, $wgSessionPbkdf2Iterations;
                global $wgJobTypeConf;
-               global $wgAuthManagerConfig, $wgAuth;
+               global $wgAuthManagerConfig;
 
                // wfWarn should cause tests to fail
                $wgDevelopmentWarnings = true;
@@ -87,7 +87,6 @@ class TestSetup {
                        ],
                        'secondaryauth' => [],
                ];
-               $wgAuth = new MediaWiki\Auth\AuthManagerAuthPlugin();
 
                // T46192 Do not attempt to send a real e-mail
                Hooks::clear( 'AlternateUserMailer' );
index f742a1b..861111a 100644 (file)
@@ -156,6 +156,7 @@ $wgAutoloadClasses += [
        # tests/phpunit/includes/specialpage
        'SpecialPageTestHelper' => "$testDir/phpunit/includes/specialpage/SpecialPageTestHelper.php",
        'AbstractChangesListSpecialPageTestCase' => "$testDir/phpunit/includes/specialpage/AbstractChangesListSpecialPageTestCase.php",
+       'FormSpecialPageTestCase' => "$testDir/phpunit/includes/specialpage/FormSpecialPageTestCase.php",
 
        # tests/phpunit/includes/specials
        'SpecialPageTestBase' => "$testDir/phpunit/includes/specials/SpecialPageTestBase.php",
@@ -170,6 +171,7 @@ $wgAutoloadClasses += [
        'MediaWiki\Tests\Revision\RevisionRecordTests' => "$testDir/phpunit/includes/Revision/RevisionRecordTests.php",
        'MediaWiki\Tests\Revision\RevisionStoreDbTestBase' => "$testDir/phpunit/includes/Revision/RevisionStoreDbTestBase.php",
        'MediaWiki\Tests\Revision\PreMcrSchemaOverride' => "$testDir/phpunit/includes/Revision/PreMcrSchemaOverride.php",
+       'MediaWiki\Tests\Revision\RevisionStoreRecordTest' => "$testDir/phpunit/includes/Revision/RevisionStoreRecordTest.php",
 
        # tests/phpunit/languages
        'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",
@@ -178,6 +180,7 @@ $wgAutoloadClasses += [
        'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php",
 
        # tests/phpunit/maintenance
+       'MediaWiki\Tests\Maintenance\DumpAsserter' => "$testDir/phpunit/maintenance/DumpAsserter.php",
        'MediaWiki\Tests\Maintenance\DumpTestCase' => "$testDir/phpunit/maintenance/DumpTestCase.php",
        'MediaWiki\Tests\Maintenance\MaintenanceBaseTestCase' => "$testDir/phpunit/maintenance/MaintenanceBaseTestCase.php",
 
index 4730005..3c7cb14 100644 (file)
@@ -40,10 +40,10 @@ class FirejailCommandIntegrationTest extends PHPUnit\Framework\TestCase {
         * @dataProvider provideExecute
         */
        public function testExecute( $testCommand, $flag ) {
-               if ( preg_match( '/^sudo /', $testCommand ) ) {
-                       if ( Shell::command( 'sudo', '-n', 'ls', '/' )->execute()->getExitCode() ) {
-                               $this->markTestSkipped( 'need passwordless sudo' );
-                       }
+               if ( preg_match( '/^sudo /', $testCommand )
+                       && Shell::command( 'sudo', '-n', 'ls', '/' )->execute()->getExitCode()
+               ) {
+                       $this->markTestSkipped( 'need passwordless sudo' );
                }
 
                $command = new FirejailCommand( 'firejail' );
index fbeed97..caa19b1 100644 (file)
@@ -47,7 +47,7 @@ class ParserTestResultNormalizer {
 
        /**
         * The point of this function is to produce a normalized DOM in which
-        * Tidy's output matches the output of html5depurate. Tidy both trims
+        * Tidy's output matches the output of RemexHtml. Tidy both trims
         * and pretty-prints, so this requires fairly aggressive treatment.
         *
         * In particular, note that Tidy converts <pre>x</pre> to <pre>\nx\n</pre>,
index 0e6a3ee..b40b769 100644 (file)
@@ -282,7 +282,6 @@ class ParserTestRunner {
                $setup['wgHtml5'] = true;
                $setup['wgDisableLangConversion'] = false;
                $setup['wgDisableTitleConversion'] = false;
-               $setup['wgMediaInTargetLanguage'] = false;
 
                // "extra language links"
                // see https://gerrit.wikimedia.org/r/111390
@@ -389,10 +388,10 @@ class ParserTestRunner {
                        100 => 'MemoryAlpha',
                        101 => 'MemoryAlpha_talk'
                ];
-               // Changing wgExtraNamespaces invalidates caches in MWNamespace and
-               // any live Language object, both on setup and teardown
+               // Changing wgExtraNamespaces invalidates caches in NamespaceInfo and any live Language
+               // object, both on setup and teardown
                $reset = function () {
-                       MWNamespace::clearCaches();
+                       MediaWikiServices::getInstance()->resetServiceForTesting( 'NamespaceInfo' );
                        MediaWikiServices::getInstance()->getContentLanguage()->resetNamespaces();
                };
                $setup[] = $reset;
@@ -939,12 +938,7 @@ class ParserTestRunner {
         */
        private static function getOptionValue( $key, $opts, $default ) {
                $key = strtolower( $key );
-
-               if ( isset( $opts[$key] ) ) {
-                       return $opts[$key];
-               } else {
-                       return $default;
-               }
+               return $opts[$key] ?? $default;
        }
 
        /**
@@ -1090,7 +1084,6 @@ class ParserTestRunner {
                                + [ 'ISBN' => true, 'PMID' => true, 'RFC' => true ],
                        // Test with legacy encoding by default until HTML5 is very stable and default
                        'wgFragmentMode' => [ 'legacy' ],
-                       'wgMediaInTargetLanguage' => self::getOptionValue( 'wgMediaInTargetLanguage', $opts, false ),
                ];
 
                $nonIncludable = self::getOptionValue( 'wgNonincludableNamespaces', $opts, false );
index a73d036..0facec2 100644 (file)
@@ -37,7 +37,7 @@
 # You can also set the following parser properties via test options:
 #  wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel,
 #  wgLinkHolderBatchSize, wgRawHtml, wgInterwikiMagic,
-#  wgEnableMagicLinks, wgMediaInTargetLanguage
+#  wgEnableMagicLinks
 #
 # For testing purposes, temporary articles can created:
 # !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle
@@ -431,7 +431,6 @@ b
 b
 </p>
 <hr />
-
 !! end
 
 !! test
@@ -458,7 +457,6 @@ b
 b
 </p>
 <hr />
-
 !! end
 
 !! test
@@ -505,7 +503,6 @@ b
 b
 </p>
 <hr />
-
 !! end
 
 !! test
@@ -543,7 +540,6 @@ a
 </p><p><br />
 </p>
 <h1><span class="mw-headline" id="b_2">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
-
 !! end
 
 !! test
@@ -643,7 +639,6 @@ C</nowiki>==
 <h2><span id="A_B.0AC"></span><span class="mw-headline" id="A_B
 C">A B
 C</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: A B&#10;C">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <h2 id="A_B
 C"><span id="A_B.0AC" typeof="mw:FallbackId"></span>A <span typeof="mw:Nowiki">B
@@ -668,7 +663,6 @@ Simple list
 !! html
 <ul><li>Item 1</li>
 <li>Item 2</li></ul>
-
 !! end
 
 !! test
@@ -705,7 +699,6 @@ Italics and bold
 <li>plain<b>bold<i>bold-italic</i></b>plain</li>
 <li>plain l'<i>italic</i>plain</li>
 <li>plain l'<b>bold</b> plain</li></ul>
-
 !! end
 
 # this example taken from the [[simple:Moon]] article (T49326)
@@ -1461,7 +1454,6 @@ Non-word characters are valid in extension tags (T19663)
 array (
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tåg" data-mw='{"name":"tåg","attrs":{},"body":{"extsrc":"tåg"}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -1575,7 +1567,6 @@ nowiki 3
 <li>There is nowiki.</li></ol>
 <ul><li>There is not nowiki.</li>
 <li>There is nowiki.</li></ul>
-
 !! html/parsoid
 <dl><dd data-parsoid='{}'>There is not nowiki.</dd>
 <dd data-parsoid='{}'>There is <span typeof="mw:Nowiki">nowiki</span>.</dd></dl>
@@ -1808,7 +1799,6 @@ Comment whitespace
 !! wikitext
 <!-- returns a single newline, not nothing, since the newline after > is not stripped -->
 !! html
-
 !! end
 
 !! test
@@ -1816,7 +1806,6 @@ Comment semantics and delimiters
 !! wikitext
 <!-- --><!----><!-----><!------>
 !! html/php
-
 !! html/parsoid
 <!-- --><!----><!--&#x2D;--><!--&#x2D;&#x2D;-->
 !! end
@@ -1827,7 +1816,6 @@ Comment semantics and delimiters, redux
 <!-- In SGML every "foo" here would actually show up in the text -- foo -- bar
 -- foo -- funky huh? ... -->
 !! html/php
-
 !! html/parsoid
 <!-- In SGML every "foo" here would actually show up in the text &#x2D;&#x2D; foo &#x2D;&#x2D; bar
 &#x2D;&#x2D; foo &#x2D;&#x2D; funky huh? ... -->
@@ -1870,7 +1858,6 @@ parsoid=wt2html,html2html
 !! wikitext
 <!--This comment will run out to the end of the document
 !! html/php
-
 !! html/parsoid
 <!--This comment will run out to the end of the document-->
 !! end
@@ -1980,7 +1967,6 @@ parsoid=wt2html,wt2wt
 !! html/php
 <ul><li>a</li>
 <li>b</li></ul>
-
 !! html/parsoid
 <!--c1--><ul>
 <li>a
@@ -2086,7 +2072,6 @@ b <div>foo</div>
 !! html
 a <div>foo</div>
 b <div>foo</div>
-
 !! html+tidy
 <p>a </p><div>foo</div><p>
 b </p><div>foo</div>
@@ -2101,7 +2086,6 @@ b <blockquote>foo</blockquote>
 !! html
 a <blockquote>foo</blockquote>
 b <blockquote>foo</blockquote>
-
 !! html+tidy
 <p>a </p><blockquote><p>foo</p></blockquote><p>
 b </p><blockquote><p>foo</p></blockquote>
 d e
 </p>
 x <div>foo</div> z
-
 !! html+tidy
 <div>foo</div><p> a
 </p><p>b
 c
 d e
 </p><p>
-x </p><div>foo</div><p> z
-</p>
+x </p><div>foo</div><p> z</p>
 !! end
 
 !! test
@@ -2160,7 +2142,6 @@ b
 <p><br />
 </p>
 <div>e</div>
-
 !! html+tidy
 <div></div>
 <p><br />
@@ -2243,7 +2224,6 @@ No paragraph necessary for SOL transparent template
 !! html/php
 <span><div>foo</div></span>
 <span><div>foo</div></span>
-
 !! html/parsoid
 <span data-parsoid='{"stx":"html"}'><div data-parsoid='{"stx":"html"}'>foo</div></span>
 <link rel="mw:PageProp/Category" href="./Category:Foo"/>
@@ -2458,7 +2438,6 @@ Ident preformatting with inline content
 &lt;cite&gt;
 &lt;em&gt;
 </pre>
-
 !! end
 
 !! test
@@ -2472,7 +2451,6 @@ Regression with preformatted in <center>
 <pre>Blah
 </pre>
 </center>
-
 !! end
 
 !! test
@@ -2496,7 +2474,6 @@ T54763: Preformatted in <blockquote>
 </p>
 </td></tr></table>
 </blockquote>
-
 !! end
 
 !! test
@@ -2513,7 +2490,6 @@ Bar
 </p><p>Bar
 </p>
 </blockquote>
-
 !! end
 
 !! test
@@ -2527,7 +2503,6 @@ Foo <del>bar</del> <ins>baz</ins> quux
 <p>Foo <del>bar</del> <ins>baz</ins> quux
 </p>
 </blockquote>
-
 !! html+tidy
 <blockquote>
 <p>Foo <del>bar</del> <ins>baz</ins> quux
@@ -2543,7 +2518,6 @@ T17491: <ins>/<del> in blockquote (2)
 !! html
 <blockquote>Foo <del>bar</del> <ins>baz</ins> quux
 </blockquote>
-
 !! html+tidy
 <blockquote><p>Foo <del>bar</del> <ins>baz</ins> quux
 </p></blockquote>
@@ -2555,7 +2529,6 @@ T17491: <ins>/<del> in blockquote (2)
 <pre style="background: blue; color:white">Bluescreen of WikiDeath</pre>
 !! html
 <pre style="background: blue; color:white">Bluescreen of WikiDeath</pre>
-
 !! end
 
 !! test
@@ -2564,7 +2537,6 @@ T17491: <ins>/<del> in blockquote (2)
 <pre width="8">Narrow screen goodies</pre>
 !! html
 <pre width="8">Narrow screen goodies</pre>
-
 !! end
 
 !! test
@@ -2573,7 +2545,6 @@ T17491: <ins>/<del> in blockquote (2)
 <pre width="8" onmouseover="alert(document.cookie)">Narrow screen goodies</pre>
 !! html
 <pre width="8">Narrow screen goodies</pre>
-
 !! end
 
 !! test
@@ -2582,7 +2553,6 @@ Entities inside <pre>
 <pre>&lt;</pre>
 !! html
 <pre>&lt;</pre>
-
 !! end
 
 !! test
@@ -2591,7 +2561,6 @@ Entities inside <pre>
 <pre width="8" style="border-width: expression(alert(document.cookie))">Narrow screen goodies</pre>
 !! html
 <pre width="8" style="/* insecure input */">Narrow screen goodies</pre>
-
 !! end
 
 !! test
@@ -2612,7 +2581,6 @@ Entities inside <pre>
 
 </pre>
 <pre>&lt;nowiki&gt;Foo&lt;/nowiki&gt;</pre>
-
 !! end
 
 !! test
@@ -2621,7 +2589,6 @@ Entities inside <pre>
 {{#tag:pre|Foo <nowiki>&rarr;bar</nowiki>}}
 !! html/php
 <pre>Foo &#8594;bar</pre>
-
 !! html/parsoid
 <pre about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"#tag:pre","function":"tag"},"params":{"1":{"wt":"Foo &lt;nowiki>&amp;rarr;bar&lt;/nowiki>"}},"i":0}}]}'>Foo <span typeof="mw:Entity">→</span>bar</pre>
 !! end
@@ -2730,8 +2697,7 @@ Templates: Indent-Pre: 1a. Templates that break a line should suppress <pre>
 !! wikitext
  {{echo|}}
 !! html
-
-!!end
+!! end
 
 !!test
 Templates: Indent-Pre: 1b. Templates that break a line should suppress <pre>
@@ -2854,7 +2820,6 @@ parsoid=wt2html,html2html
 two">hi</pre>
 !! html/php
 <pre class="one two">hi</pre>
-
 !! html/parsoid
 <pre class="one two" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"one two"},"body":{"extsrc":"hi"}}'>hi</pre>
 !! end
@@ -2886,7 +2851,6 @@ parsoid=wt2html
 !! html/php
 <pre>x</pre>
 <table>&lt;pre </table>
-
 !! html/php+tidy
 <pre>x</pre>
 &lt;pre <table></table>
@@ -2920,7 +2884,6 @@ parsoid=wt2html
 <pre style="width:50%;" >{{echo|foo}}</pre>
 !! html/php
 <pre style="width:50%;">{{echo|foo}}</pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/pre" about="#mwt2" style="width:50%;" data-mw='{"name":"pre","attrs":{"style":"width:50%;"},"body":{"extsrc":"{{echo|foo}}"}}'>{{echo|foo}}</pre>
 !! end
@@ -2931,7 +2894,6 @@ Self-closed pre
 <pre />
 !! html/php
 <pre></pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{}}'></pre>
 !! end
@@ -3014,7 +2976,6 @@ Templates: Strip leading and trailing whitespace from named-param values
 </p><p>c
 </p>
 <ul><li>d</li></ul>
-
 !! end
 
 !! test
@@ -3408,7 +3369,6 @@ c
 <td>foo</td>
 <td>bar
 </td></tr></table>
-
 !!end
 
 !!test
@@ -3424,7 +3384,6 @@ c
 <tr>
 <td>foo
 </td></tr></table>
-
 !!end
 
 !!test
@@ -3441,7 +3400,6 @@ c
 <tr>
 <th>bar
 </th></tr></table>
-
 !!end
 
 !!test
@@ -3458,7 +3416,6 @@ c
 <tr>
 <td>b
 </td></tr></table>
-
 !! html/parsoid
 <pre>a</pre>
  <table>
@@ -3517,7 +3474,6 @@ a
  </td>
  </tr>
  </table>
-
 !! end
 
 !! test
@@ -3556,7 +3512,6 @@ parsoid=wt2html,html2html
 <pre>bam
 </pre>
 </td></tr></table>
-
 !! html/parsoid
 <table>
  <tbody><tr><th>
@@ -3606,7 +3561,6 @@ parsoid=wt2html,html2html
 <pre>a <span>foo</span>
 </pre>
  b <div> foo </div>
-
 !! html/parsoid
 <pre>a <span data-parsoid='{"stx":"html"}'>foo</span></pre>
 <!-- comment --> <p>b </p><div data-parsoid='{"stx":"html"}'> foo </div>
@@ -3730,7 +3684,6 @@ array (
  <pre class="123">hi</pre>
 !! html/php
  <pre class="123">hi</pre>
-
 !! html/parsoid
  <pre class="123" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"123"},"body":{"extsrc":"hi"}}'>hi</pre>
 !! end
@@ -3749,7 +3702,6 @@ Render paragraphs when indent-pre is suppressed in blocklevels
 </p><p> bar
 </p>
 </blockquote>
-
 !!end
 
 !!test
@@ -3768,7 +3720,6 @@ Render paragraphs when indent-pre is suppressed in blocklevels
 <tr>
 <td>foo
 </td></tr></table>
-
 !!end
 
 ## NOTE: the leading white-space chars on empty line are significant
@@ -4004,7 +3955,6 @@ HTML-pre: 2: indented text
 <pre>
  foo
 </pre>
-
 !!end
 
 !!test
@@ -4025,7 +3975,6 @@ HTML-pre: 3: other wikitext
 '' no-italic ''
 [[ NoLink ]]
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"\n* foo\n# bar\n= no-h =\n&#39;&#39; no-italic &#39;&#39;\n[[ NoLink ]]\n"}}'>* foo
 # bar
@@ -4045,7 +3994,6 @@ Simple definition
 !! html
 <dl><dt>name</dt>
 <dd>Definition</dd></dl>
-
 !! end
 
 !! test
@@ -4054,7 +4002,6 @@ Definition list for indentation only
 :Indented text
 !! html
 <dl><dd>Indented text</dd></dl>
-
 !! end
 
 !! test
@@ -4064,7 +4011,6 @@ Definition list with no space
 !! html
 <dl><dt>name</dt>
 <dd>Definition</dd></dl>
-
 !!end
 
 !! test
@@ -4074,7 +4020,6 @@ Definition list with URL link
 !! html
 <dl><dt><a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a></dt>
 <dd>definition</dd></dl>
-
 !! end
 
 !! test
@@ -4084,7 +4029,6 @@ Definition list with bracketed URL link
 !! html
 <dl><dt><a rel="nofollow" class="external text" href="http://www.example.com/">Example</a></dt>
 <dd>Something about it</dd></dl>
-
 !! end
 
 !! test
@@ -4094,7 +4038,6 @@ Definition list with wikilink containing colon
 !! html
 <dl><dt><a href="/index.php?title=Help:FAQ&amp;action=edit&amp;redlink=1" class="new" title="Help:FAQ (page does not exist)">Help:FAQ</a></dt>
 <dd>The least-read page on Wikipedia</dd></dl>
-
 !! end
 
 # At Brion's and JeLuF's insistence... :)
@@ -4105,7 +4048,6 @@ Definition list with news link containing colon
 !! html/php
 <dl><dt><a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a></dt>
 <dd>This isn't even a real newsgroup!</dd></dl>
-
 !! html/parsoid
 <dl><dt><a rel="mw:ExtLink" class="external free" href="news:alt.wikipedia.rox" data-parsoid='{"stx":"url"}'>news:alt.wikipedia.rox</a></dt><dd data-parsoid='{"stx":"row"}'>This isn't even a real newsgroup!</dd></dl>
 !! end
@@ -4116,7 +4058,6 @@ Malformed definition list with colon
 ;news:alt.wikipedia.rox -- don't crash or enter an infinite loop
 !! html
 <dl><dt><a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop</dt></dl>
-
 !! end
 
 !! test
@@ -4126,7 +4067,6 @@ Definition lists: colon in external link text
 !! html
 <dl><dt><a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia :The Next Generation</a></dt>
 <dd>OK, I made that up</dd></dl>
-
 !! end
 
 !! test
@@ -4135,7 +4075,6 @@ Definition lists: colon in HTML attribute
 ;<b style="display: inline">bold</b>
 !! html
 <dl><dt><b style="display: inline">bold</b></dt></dl>
-
 !! end
 
 !! test
@@ -4145,7 +4084,6 @@ Definition lists: self-closed tag
 !! html
 <dl><dt>one<br />two</dt>
 <dd>two-line fun</dd></dl>
-
 !! end
 
 !! test
@@ -4155,7 +4093,6 @@ Definition lists: ignore colons inside tags
 !! html
 <dl><dt>one <b>two&#160;: tag <i>fun:</i>:</b></dt>
 <dd>def</dd></dl>
-
 !! end
 
 !! test
@@ -4188,7 +4125,6 @@ T13748: Literal closing tags
 <dt>test 2</dt>
 <dd>test test test test test</dd>
 </dl>
-
 !! end
 
 !! test
@@ -4204,7 +4140,6 @@ Definition and unordered list using wiki syntax nested in unordered list using h
 <dd>description</dd></dl>
 <ul><li>unordered</li></ul>
 </li></ul>
-
 !! end
 
 !! test
@@ -4230,7 +4165,6 @@ Nested definition lists using html syntax
 <dl><dt>x</dt>
 <dd>a</dd>
 <dd>b</dd></dl>
-
 !! end
 
 !! test
@@ -4243,7 +4177,6 @@ Definition Lists: No nesting: Multiple dd's
 <dl><dt>x</dt>
 <dd>a</dd>
 <dd>b</dd></dl>
-
 !! end
 
 !! test
@@ -4256,7 +4189,6 @@ Definition Lists: Indentation: Regular
 <dl><dd>i1
 <dl><dd>i2
 <dl><dd>i3</dd></dl></dd></dl></dd></dl>
-
 !! end
 
 !! test
@@ -4267,7 +4199,6 @@ Definition Lists: Indentation: Missing 1st level
 !! html
 <dl><dd><dl><dd>i2
 <dl><dd>i3</dd></dl></dd></dl></dd></dl>
-
 !! end
 
 !! test
@@ -4276,7 +4207,6 @@ Definition Lists: Indentation: Multi-level indent
 :::i3
 !! html
 <dl><dd><dl><dd><dl><dd>i3</dd></dl></dd></dl></dd></dl>
-
 !! end
 
 !! test
@@ -4370,7 +4300,6 @@ Definition Lists: Hacky use to indent tables (WS-insensitive)
 <tr>
 <td>a
 </td></tr></table></dd></dl>
-
 !! html/parsoid
 <dl><dd><table>
 <tbody><tr><td>a</td></tr>
@@ -4436,7 +4365,6 @@ Table / list interaction: indented table with lists in table contents
 <td>c
 <ul><li>d</li></ul>
 </td></tr></table></dd></dl>
-
 !! end
 
 !!test
@@ -4466,7 +4394,6 @@ Table / list interaction: lists nested in tables nested in indented lists
 </td></tr></table></dd></dl>
 <ul><li>e</li>
 <li>f</li></ul>
-
 !!end
 
 !! test
@@ -4492,8 +4419,6 @@ Definition Lists: Nesting: Multi-level (Parsoid only)
     </dl>
   </dt>
 </dl>
-
-
 !! end
 
 
@@ -4529,7 +4454,6 @@ Definition Lists: Nesting: Test 4
 !! html
 <dl><dd><dl><dd><dl><dt>t3</dt>
 <dd>d3</dd></dl></dd></dl></dd></dl>
-
 !! end
 
 
@@ -4549,7 +4473,6 @@ Definition Lists: Mixed Lists: Test 1
 <dl><dd><dl><dt><ul><li>foo</li>
 <li>bar</li></ul></dt></dl>
 <dl><dt>baz</dt></dl></dd></dl>
-
 !! html/php+tidy
 <dl><dd><dl><dt><ul><li>foo</li>
 <li>bar</li></ul></dt></dl>
@@ -4578,7 +4501,6 @@ Definition Lists: Mixed Lists: Test 2
 !! html
 <ul><li><dl><dd>d1</dd>
 <dd>d2</dd></dl></li></ul>
-
 !! end
 
 
@@ -4590,7 +4512,6 @@ Definition Lists: Mixed Lists: Test 3
 !! html
 <ul><li><dl><dd><dl><dd><dl><dd>d1</dd>
 <dd>d2</dd></dl></dd></dl></dd></dl></li></ul>
-
 !! end
 
 
@@ -4604,7 +4525,6 @@ Definition Lists: Mixed Lists: Test 4
 <dd>d2</dd>
 <dt>d3</dt>
 <dd>d4</dd></dl></li></ul>
-
 !! end
 
 
@@ -4616,7 +4536,6 @@ Definition Lists: Mixed Lists: Test 5
 !! html
 <ul><li><dl><dd>d1
 <dl><dd>d2</dd></dl></dd></dl></li></ul>
-
 !! end
 
 
@@ -4628,7 +4547,6 @@ Definition Lists: Mixed Lists: Test 6
 !! html
 <ol><li><ul><li><dl><dd>d1
 <dl><dd><dl><dd>d3</dd></dl></dd></dl></dd></dl></li></ul></li></ol>
-
 !! end
 
 
@@ -4640,7 +4558,6 @@ Definition Lists: Mixed Lists: Test 7
 !! html
 <dl><dd><ul><li>d1</li>
 <li>d2</li></ul></dd></dl>
-
 !! end
 
 
@@ -4652,7 +4569,6 @@ Definition Lists: Mixed Lists: Test 8
 !! html
 <dl><dd><ul><li>d1</li></ul>
 <dl><dd><ul><li>d2</li></ul></dd></dl></dd></dl>
-
 !! end
 
 
@@ -4663,7 +4579,6 @@ Definition Lists: Mixed Lists: Test 9
 !! html
 <ul><li><dl><dt>foo</dt>
 <dd>bar</dd></dl></li></ul>
-
 !! end
 
 
@@ -4674,7 +4589,6 @@ Definition Lists: Mixed Lists: Test 10
 !! html
 <ul><li><ol><li><dl><dt>foo</dt>
 <dd>bar</dd></dl></li></ol></li></ul>
-
 !! end
 
 # The Parsoid team disagrees with the PHP parser's seemingly-random
@@ -4692,7 +4606,6 @@ Definition Lists: Mixed Lists: Test 11
 <dl><dt>a</dt>
 <dd>
 <ul><li>b</li></ul></dd></dl>
-
 !! html/parsoid
 <dl><dt>a
 <dd><ul><li>b</li></ul></dd></dl>
@@ -4709,7 +4622,6 @@ Definition Lists: Mixed Lists: Test 12
 <dd><ul><li><dl><dt><dl><dt>bar</dt></dl></dd></dl></li></ul></dd></dl>
 <dl><dt>boo</dt>
 <dd>baz</dd></dl></li></ol></li></ul></li></ol></li></ul>
-
 !! html/php+tidy
 <ul><li><ol><li><ul><li><ol><li><dl><dt>foo</dt>
 <dd><ul><li><dl><dt><dl><dt>bar</dt></dl></dt></dl></li></ul></dd></dl></li></ol></li></ul>
@@ -4856,7 +4768,6 @@ Definition Lists: colons and tables 1
 <tr>
 <td>y
 </td></tr></table></dd></dl>
-
 !! html/parsoid
 <dl><dd><table>
 <tr>
@@ -5961,7 +5872,6 @@ Examples from RFC 2732, section 2:
 <li><a rel="nofollow" class="external free" href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a></li>
 <li><a rel="nofollow" class="external free" href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a></li>
 <li><a rel="nofollow" class="external free" href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a></li></ul>
-
 !! html/parsoid
 <p><a rel="mw:ExtLink" class="external free" href="http://[2404:130:0:1000::187:2]/index.php">http://[2404:130:0:1000::187:2]/index.php</a></p>
 
@@ -6025,7 +5935,6 @@ Examples from RFC 2732, section 2:
 <li><a rel="nofollow" class="external text" href="http://[::192.9.5.5]/ipng">5</a></li>
 <li><a rel="nofollow" class="external text" href="http://[::FFFF:129.144.52.38]:80/index.html">6</a></li>
 <li><a rel="nofollow" class="external text" href="http://[2010:836B:4179::836B:4179]">7</a></li></ul>
-
 !! html/parsoid
 <p><a rel="mw:ExtLink" class="external text" href="http://[2404:130:0:1000::187:2]/index.php">test</a></p>
 
@@ -6318,10 +6227,8 @@ parsoid=wt2html
 !! wikitext
 {||}
 !! html/php
-
 !! html/parsoid
 <table></table>
-
 !! end
 
 !! test
@@ -6377,7 +6284,6 @@ parsoid=wt2html
 <td>foo</td>
 </tr></tbody>
 </table>
-
 !! end
 
 !! test
@@ -6402,7 +6308,6 @@ A table with nothing but a caption
 <table>
 <caption>caption
 </caption><tr><td></td></tr></table>
-
 !! html/parsoid
 <table><caption>caption</caption></table>
 !! end
@@ -6422,7 +6327,6 @@ A table with caption with default-spaced attributes and a table row
 <tr>
 <td>foo
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6443,7 +6347,6 @@ A table with captions with non-default spaced attributes and a table row
 <tr>
 <td>foo
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6468,7 +6371,6 @@ Table td-cell syntax variations
 <td>style='color:red;'</td>
 <td>baz
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6489,7 +6391,6 @@ Simple table
 <td>3</td>
 <td>4
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6508,7 +6409,6 @@ Simple table but with multiple dashes for row wikitext
 <tr>
 <td>bar
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6579,7 +6479,6 @@ Multiplication table
 <td>10</td>
 <td>15
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6594,7 +6493,6 @@ Accept "||" in table headings
 <th>h1</th>
 <th>h2
 </th></tr></table>
-
 !! end
 
 !! test
@@ -6609,7 +6507,6 @@ Accept "!!" in table data
 <td>Foo!!</td>
 <td>
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'> Foo!! </td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'></td></tr>
@@ -6628,7 +6525,6 @@ Accept "||" in indented table headings
 <th>h1</th>
 <th>h2
 </th></tr></table></dd></dl>
-
 !! end
 
 !! test
@@ -6643,7 +6539,6 @@ Accept "!!" in templates
 <th>a b</th>
 <th>c
 </th></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><th typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[{"k":"1"}]]}' data-mw='{"parts":["!a ",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b!!c"}},"i":0}}]}'>a b</th><th about="#mwt1">c</th></tr>
@@ -6663,7 +6558,6 @@ b!!c
 <p>b!!c
 </p>
 </th></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><th>a
@@ -6705,7 +6599,6 @@ Accept empty attributes in td/th cells (td/th cells starting with leading ||)
 </th>
 <td>a
 </td></tr></table>
-
 !! end
 
 !!test
@@ -6721,7 +6614,6 @@ Accept "| !" at start of line in tables (ignore !-attribute)
 <tr>
 <td>bar
 </td></tr></table>
-
 !!end
 
 !!test
@@ -6760,7 +6652,6 @@ Allow +/- in 2nd and later cells in a row, in 1st cell when td-attrs are present
 </td>
 <td>-1
 </td></tr></table>
-
 !!end
 
 !! test
@@ -6788,7 +6679,6 @@ Table rowspan
 </td>
 <td>Cell 3, row 2
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6820,7 +6710,6 @@ Nested table
 </td>
 <td>the original table again
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6834,7 +6723,6 @@ Invalid attributes in table cell (T3830)
 <tr>
 <td>broken
 </td></tr></table>
-
 !! end
 
 !! test
@@ -6854,7 +6742,6 @@ Table cell attributes: Pipes protected by nowikis should be treated as a plain c
 </td>
 <td>title="foo|" bar
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><td title="foo">bar</td>
@@ -6881,7 +6768,6 @@ parsoid=wt2html,html2html
 </td>
 </tr>
 </table>
-
 !! html/parsoid
 <table><tbody>
 <tr>
@@ -6899,7 +6785,6 @@ Element attributes with double ! should not be broken up by <th>
 <tr>
 <th>hi <div class="!!">ha</div> ho
 </th></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><th>hi <div class="!!" data-parsoid='{"stx":"html"}'>ha</div> ho</th></tr>
@@ -6917,7 +6802,6 @@ Element attributes with double ! should not be broken up by <th>
 <tr>
 <td><div style="color: red !important;" data-contrived="put this here &#124;&#124;">hi</div>
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><td><div style="color: red !important;" data-contrived="put this here ||" data-parsoid='{"stx":"html"}'>hi</div></td></tr>
@@ -6939,7 +6823,6 @@ parsoid=wt2html
 <td>style="color: red !important;" data-contrived="put this here</td>
 <td>foo
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><td>style="color: red !important;" data-contrived="put this here</td><td data-parsoid='{"stx":"row","a":{"\"":null},"sa":{"\"":""},"autoInsertedEnd":true}'>foo</td></tr>
@@ -6998,7 +6881,6 @@ parsoid=wt2html
 </td>
 <td style="color:blue">2
 </td></tr></table>
-
 !! html/parsoid
 <table style="border:1px solid black">
 <tr>
@@ -7057,7 +6939,6 @@ parsoid={
 </td>
 <td align="center" style="color:red;">Foo
 </td></tr></table>
-
 !! end
 
 !! test
@@ -7074,7 +6955,6 @@ parsoid={
 <td>Bar</td>
 <td>Baz
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><td about="#mwt1" typeof="mw:Transclusion" style="color:red;" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_2","href":"./Template:Table_attribs_2"},"params":{},"i":0}}]}'>Foo</td>
@@ -7102,7 +6982,6 @@ parsoid={
 <td style="color:red;"><i>Bar</i></td>
 <td style="color:brown;"><i>Foo</i> and Baz
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><th align="center" style="color:red;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["!align=center ",{"template":{"target":{"wt":"table_header_cells","href":"./Template:Table_header_cells"},"params":{},"i":0}}]}'>Foo</th><th about="#mwt1" style="color:red;"><i about="#mwt1">Bar</i></th><th about="#mwt1" style="color:brown;"><i about="#mwt1">Foo</i> and Baz</th></tr><tr>
@@ -7130,7 +7009,6 @@ parsoid={
 <td style="color:red;"><i>Bar</i></td>
 <td style="color:brown;"><i>Foo</i> and Baz
 </td></tr></table>
-
 !! html/parsoid
 <table about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[],[],[],[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"tbl-start","href":"./Template:Tbl-start"},"params":{},"i":0}},"\n!align=center ",{"template":{"target":{"wt":"table_header_cells","href":"./Template:Table_header_cells"},"params":{},"i":1}},"\n|-\n|align=center ",{"template":{"target":{"wt":"table_cells","href":"./Template:Table_cells"},"params":{},"i":2}},"\n",{"template":{"target":{"wt":"tbl-end","href":"./Template:Tbl-end"},"params":{},"i":3}}]}'>
 <tbody><tr><th align="center" style="color:red;">Foo</th><th style="color:red;"><i>Bar</i></th><th style="color:brown;"><i>Foo</i> and Baz</th></tr>
@@ -7171,7 +7049,6 @@ parsoid=wt2html,html2html
 <tr>
 <th>foo
 </th></tr></table>
-
 !! end
 
 !! test
@@ -7191,7 +7068,6 @@ parsoid=wt2html,html2html
 <tr>
 <td>foo
 </td></tr></table>
-
 !! end
 
 !! test
@@ -7207,7 +7083,6 @@ parsoid=wt2html,html2html
 <tr>
 <td style="">hello
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><td style="">hello</td></tr>
@@ -7234,7 +7109,6 @@ Wikitext table with a lot of comments
 <tr>
 <td>
 </td></tr></table>
-
 !! end
 
 !! test
@@ -7271,7 +7145,6 @@ b
 <p>b
 </p>
 </td></tr></table>
-
 !! end
 
 !! test
@@ -7288,7 +7161,6 @@ Table cell with a single comment
 </td>
 <td>a
 </td></tr></table>
-
 !! end
 
 !! test
@@ -7306,14 +7178,12 @@ Table-cell after a comment-only-empty-line
 </td>
 <td>b
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'>a</td>
 <!--c1-->
 <!--c2--><td data-parsoid='{"autoInsertedEnd":true}'>b</td></tr>
 </tbody></table>
-
 !! end
 
 !! test
@@ -7336,7 +7206,6 @@ Build table with {{!}}
 <td>data</td>
 <td style="color:red;">second data
 </td></tr></table>
-
 !! end
 
 !! test
@@ -7371,7 +7240,6 @@ Build table with pipe as data
 <td>data with |</td>
 <td>second data with |
 </td></tr></table>
-
 !! end
 
 !! test
@@ -7398,7 +7266,6 @@ Build table with wikilink
 <td>data</td>
 <td>second data <a href="/wiki/Main_Page" title="Main Page">link|text with pipe</a>
 </td></tr></table>
-
 !! end
 
 # The expected HTML structure in this test is debatable. The PHP parser does
@@ -7433,7 +7300,6 @@ a
 
 a
 </table>
-
 !! html/php+tidy
 
 
@@ -7460,7 +7326,6 @@ parsoid=wt2html,html2html
 
 <ul><li>a</li></ul>
 </table>
-
 !! html/php+tidy
 <ul><li>a</li></ul><table>
 
@@ -7514,8 +7379,7 @@ parsoid=wt2html,wt2wt
 </p><table>
 <tbody><tr>
 <td>baz
-</td></tr></tbody></table><p><b>quux</b>
-</p>
+</td></tr></tbody></table><p><b>quux</b></p>
 !! end
 
 !! test
@@ -7556,7 +7420,6 @@ parsoid=wt2html,wt2wt
 <td>baz</td>
 <td>quux
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><th>foo</th><th>bar
@@ -8209,8 +8072,11 @@ Link containing double quotes and spaces
 File containing double quotes and spaces
 !! wikitext
 [[File:Cool "Gator".png]]
+!! html/php+tidy
+<p><a href="/index.php?title=Special:Upload&amp;wpDestFile=Cool_%22Gator%22.png" class="new" title="File:Cool &quot;Gator&quot;.png">File:Cool &quot;Gator&quot;.png</a>
+</p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Cool_%22Gator%22.png" data-parsoid='{"a":{"href":"./File:Cool_%22Gator%22.png"},"sa":{"href":"File:Cool \"Gator\".png"}}'><img resource='./File:Cool_"Gator".png' src="./Special:FilePath/Cool_%22Gator%22.png" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Cool_\"Gator\".png","height":"220","width":"220","src":"./Special:FilePath/Cool_%22Gator%22.png"},"sa":{"resource":"File:Cool \"Gator\".png","src":"./Special:FilePath/Cool_\"Gator\".png"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Cool_%22Gator%22.png"><span resource='./File:Cool_"Gator".png' data-parsoid='{"a":{"resource":"./File:Cool_\"Gator\".png"},"sa":{"resource":"File:Cool \"Gator\".png"}}'>File:Cool "Gator".png</span></a></figure-inline></p>
 !! end
 
 !! test
@@ -8241,6 +8107,7 @@ Link containing double-single-quotes '' in text embedded in italics (T6598 sanit
 </p>
 !! end
 
+## FIXME: Title part of filename is interpreted in php
 !! test
 Link with double quotes in title part (literal) and alternate part (interpreted)
 !! wikitext
@@ -8258,7 +8125,7 @@ Link with double quotes in title part (literal) and alternate part (interpreted)
 </p><p><a href="/index.php?title=%27%27Pentecoste%27%27&amp;action=edit&amp;redlink=1" class="new" title="&#39;&#39;Pentecoste&#39;&#39; (page does not exist)"><i>Pentecoste</i></a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Denys_Savchenko_''Pentecoste''.jpg"><img resource="./File:Denys_Savchenko_''Pentecoste''.jpg" src="./Special:FilePath/Denys_Savchenko_''Pentecoste''.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Denys_Savchenko_''Pentecoste''.jpg"><span resource="./File:Denys_Savchenko_''Pentecoste''.jpg" data-parsoid='{"a":{"resource":"./File:Denys_Savchenko_&apos;&apos;Pentecoste&apos;&apos;.jpg"},"sa":{"resource":"File:Denys_Savchenko_&apos;&apos;Pentecoste&apos;&apos;.jpg"}}'>File:Denys Savchenko ''Pentecoste''.jpg</span></a></figure-inline></p>
 <p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''">''Pentecoste''</a></p>
 <p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''">Pentecoste</a></p>
 <p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''"><i>Pentecoste</i></a></p>
@@ -8278,10 +8145,10 @@ Broken image links with HTML captions (T41700)
 <a href="/index.php?title=Special:Upload&amp;wpDestFile=Nonexistent" class="new" title="File:Nonexistent">abc</a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"&lt;script>&lt;/script>"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"&amp;lt;script>&amp;lt;/script>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"220","width":"220"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline>
-<figure-inline typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"100x100px"},{"ck":"caption","ak":"&lt;script>&lt;/script>"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"&amp;lt;script>&amp;lt;/script>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="100" width="100" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"100","width":"100"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline>
-<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"&amp;lt;"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"&lt;span typeof=\"mw:Entity\" data-parsoid=&#39;{\"src\":\"&amp;amp;lt;\",\"srcContent\":\"&amp;lt;\",\"dsr\":[107,111,null,null]}&#39;>&amp;lt;&lt;/span>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"220","width":"220"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline>
-<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"a&lt;i>b&lt;/i>c"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"a&lt;i data-parsoid=&#39;{\"stx\":\"html\",\"dsr\":[134,142,3,4]}&#39;>b&lt;/i>c"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"220","width":"220"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"&lt;script>&lt;/script>"}]}' data-mw='{"caption":"&amp;lt;script>&amp;lt;/script>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline>
+<figure-inline typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"100x100px"},{"ck":"caption","ak":"&lt;script>&lt;/script>"}]}' data-mw='{"caption":"&amp;lt;script>&amp;lt;/script>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-width="100" data-height="100" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"&amp;lt;"}]}' data-mw='{"caption":"&lt;span typeof=\"mw:Entity\" data-parsoid=&apos;{\"src\":\"&amp;amp;lt;\",\"srcContent\":\"&amp;lt;\",\"dsr\":[107,111,null,null]}&apos;>&amp;lt;&lt;/span>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"a&lt;i>b&lt;/i>c"}]}' data-mw='{"caption":"a&lt;i data-parsoid=&apos;{\"stx\":\"html\",\"dsr\":[134,142,3,4]}&apos;>b&lt;/i>c","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline></p>
 !! end
 
 !! test
@@ -8304,6 +8171,15 @@ Plain link to URL with link text
 </p>
 !! end
 
+!! test
+Plain link to URL containing special characters, with link text (see T213950).
+!! wikitext
+[[http://www.example.com/?q=%7Babc%7D Link text]]
+!! html
+<p>[<a rel="nofollow" class="external text" href="http://www.example.com/?q=%7Babc%7D">Link text</a>]
+</p>
+!! end
+
 !! test
 Plain link to protocol-relative URL
 !! wikitext
@@ -8866,7 +8742,6 @@ parsoid=wt2html,wt2wt
 !! html/php
 <ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li>
 <li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li></ul>
-
 !! html/php+tidy
 <ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li>
 <li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li></ul>
@@ -9724,8 +9599,7 @@ Handling html with a div self-closing tag
 <div title="">
 <div title="bar"></div>
 <div title="bar"></div>
-<div title="bar/">
-</div></div>
+<div title="bar/"></div></div>
 !! html/parsoid
 <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
 <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
@@ -9806,8 +9680,7 @@ foo <hr
 !! html+tidy
 <hr />
 <hr /><p>
-foo </p><hr /><p> bar
-</p>
+foo </p><hr /><p> bar</p>
 !! end
 
 !! test
@@ -9816,7 +9689,6 @@ Horizontal ruler -- 4+ dashes render hr
 ----
 !! html
 <hr />
-
 !! end
 
 !! test
@@ -9825,7 +9697,6 @@ Horizontal ruler -- eats additional dashes on the same line
 ---------
 !! html
 <hr />
-
 !! end
 
 !! test
@@ -9836,7 +9707,6 @@ Horizontal ruler -- does not collapse dashes on consecutive lines
 !! html
 <hr />
 <hr />
-
 !! end
 
 !! test
@@ -9854,10 +9724,8 @@ Horizontal ruler -- Supports content following dashes on same line
 ---- Foo
 !! html
 <hr /> Foo
-
 !! html+tidy
-<hr /><p> Foo
-</p>
+<hr /><p> Foo</p>
 !! end
 
 ###
@@ -9873,7 +9741,6 @@ Common list
 <ul><li>Common list</li>
 <li>item 2</li>
 <li>item 3</li></ul>
-
 !! end
 
 !! test
@@ -9886,7 +9753,6 @@ Numbered list
 <ol><li>Numbered list</li>
 <li>item 2</li>
 <li>item 3</li></ol>
-
 !! end
 
 # the switch from level 3 to ordered should not introduce a newline between
@@ -9924,7 +9790,6 @@ Mixed list
 <li>Level 1
 <ul><li><ul><li>Level 3</li></ul></li></ul></li></ul>
 <ol><li><ul><li><ul><li>Level 3, but ordered</li></ul></li></ul></li></ol>
-
 !! end
 
 !! test
@@ -9939,7 +9804,6 @@ Mixed list
 <li><ul><li>ho</li></ul></li>
 <li>hi
 <ul><li>ho</li></ul></li></ul>
-
 !! html/parsoid
 <ul><li>hi</li>
 <li><ul data-parsoid='{"stx":"html"}'><li data-parsoid='{"stx":"html"}'>ho</li></ul></li>
@@ -9955,7 +9819,6 @@ Mixed list
 !! html/php
 <dl><dt>hi</dt>
 <dd><li>ho</li></dd></dl>
-
 !! html/parsoid
 <dl><dt>hi</dt>
 <dd><li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>ho&lt;/li>"}},"i":0}}]}'>ho</li></dd></dl>
@@ -9969,7 +9832,6 @@ Nested lists 1
 !! html
 <ul><li>foo
 <ul><li>bar</li></ul></li></ul>
-
 !! end
 
 !! test
@@ -9980,7 +9842,6 @@ Nested lists 2
 !! html
 <ul><li><ul><li>foo</li></ul></li>
 <li>bar</li></ul>
-
 !! end
 
 !! test
@@ -9991,7 +9852,6 @@ Nested lists 3 (first element empty)
 !! html
 <ul><li>
 <ul><li>bar</li></ul></li></ul>
-
 !! end
 
 !! test
@@ -10002,7 +9862,6 @@ Nested lists 4 (first element empty)
 !! html
 <ul><li><ul><li></li></ul></li>
 <li>bar</li></ul>
-
 !! end
 
 !! test
@@ -10013,7 +9872,6 @@ Nested lists 5 (both elements empty)
 !! html
 <ul><li><ul><li></li></ul></li>
 <li></li></ul>
-
 !! end
 
 !! test
@@ -10024,7 +9882,6 @@ Nested lists 6 (both elements empty)
 !! html
 <ul><li>
 <ul><li></li></ul></li></ul>
-
 !! end
 
 !! test
@@ -10033,7 +9890,6 @@ Nested lists 7 (skip initial nesting levels)
 ***foo
 !! html
 <ul><li><ul><li><ul><li>foo</li></ul></li></ul></li></ul>
-
 !! end
 
 !! test
@@ -10048,7 +9904,6 @@ Nested lists 8 (multiple nesting transitions)
 <ul><li><ul><li>bar</li></ul></li>
 <li>baz</li></ul></li>
 <li>boo</li></ul>
-
 !! end
 
 # XXX this test should be moved to citeParserTests, since it depends
@@ -10073,7 +9928,6 @@ Nested lists 9 (extension interaction)
 <ul><li>foo</li>
 <li>bar</li>
 <li>baz</li></ul>
-
 !! end
 
 !! test
@@ -10094,7 +9948,6 @@ Nested lists 10 (list and span siblings: wt2wt regression)
 !! html
 <ul><li>foo bar</li>
 <li>baz</li></ul>
-
 !! end
 
 !! test
@@ -10107,7 +9960,6 @@ List items are not parsed correctly following a <pre> block (T2785)
 <ul><li><pre>foo</pre></li>
 <li><pre>bar</pre></li>
 <li>zar</li></ul>
-
 !! html/parsoid
 <ul><li><pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"foo"}}'>foo</pre></li>
 <li><pre typeof="mw:Extension/pre" about="#mwt4" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"bar"}}'>bar</pre></li>
@@ -10139,7 +9991,6 @@ List items from template
 <li>notSOL</li>
 <li>item 1</li>
 <li>item 2</li></ul>
-
 !! end
 
 !! test
@@ -10155,7 +10006,6 @@ List interrupted by empty line or heading
 <ul><li><ul><li>bar</li></ul></li></ul>
 <h2><span class="mw-headline" id="A_heading">A heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: A heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <ul><li>Another list item</li></ul>
-
 !!end
 
 !! test
@@ -10171,12 +10021,10 @@ Multiple list tags generated by templates
 </li>
 </li>
 
-
 !! html+tidy
 <li>a
 </li><li>b
-</li><li>c
-</li>
+</li><li>c</li>
 !! html/parsoid
 <li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":0}},"a"]}'>a</li>
 <li about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":0}},"b"]}'>b</li>
@@ -10235,7 +10083,6 @@ Single-comment whitespace lines dont break lists, and neither do multi-comment w
 <li>b</li>
 <li>c</li>
 <li>d</li></ul>
-
 !!end
 
 !!test
@@ -10254,7 +10101,6 @@ Replacing whitespace with tabs still doesn't break the list (gerrit 78327)
 <li>b</li>
 <li>c</li>
 <li>d</li></ul>
-
 !!end
 
 # FIXME: Parsoid has a dedicated DOM pass to mimic this Tidy-specific li-hack
@@ -10292,8 +10138,7 @@ parsoid=wt2html,wt2wt
 <li class="mw-empty-elt" data-parsoid='{"stx":"html","autoInsertedEnd":true}'></li><li data-parsoid='{"stx":"html"}'>not a li-hack
 </li>
 </ul>
-
-!!end
+!! end
 
 !! test
 Parsoid: Make sure nested lists are serialized on their own line even if HTML contains no newlines
@@ -10620,7 +10465,6 @@ Magic Words LOCAL (UTC)
 <li>1</li>
 <li>4</li>
 <li>19700101000203</li></ul>
-
 !! end
 
 !! test
@@ -10727,7 +10571,6 @@ parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBJECTSPACE}}
 !! html/*
-
 !! end
 
 !! test
@@ -10989,7 +10832,6 @@ parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SCRIPTPATH}}
 !! html/*
-
 !! end
 
 !! test
@@ -11148,7 +10990,6 @@ Namespace 0 {{ns:0}} (T6783)
 !! wikitext
 {{ns:0}}
 !! html
-
 !! end
 
 !! test
@@ -11156,7 +10997,6 @@ Namespace 0 {{ns:00}} (T6783)
 !! wikitext
 {{ns:00}}
 !! html
-
 !! end
 
 !! test
@@ -11694,7 +11534,6 @@ Templates with templated name
 <p>foo
 </p>
 <ul><li>item 1</li></ul>
-
 !! html/parsoid
 <p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"{{echo|echo}}","href":"./Template:Echo"},"params":{"1":{"wt":"foo"}},"i":0}}]}'>foo</p>
 <ul about="#mwt4" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"{{echo|inner list}} ","href":"./Template:Inner_list"},"params":{},"i":0}}]}'><li>item 1</li></ul>
@@ -11733,11 +11572,10 @@ Template with thumb image (with link in description)
 {{paramtest|param=[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]}}
 !! html/php
 This is a test template with parameter <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&amp;wpDestFile=Noimage.png" class="new" title="File:Noimage.png">File:Noimage.png</a>  <div class="thumbcaption"><a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">caption</a></div></div></div>
-
 !! html+tidy
 <p>This is a test template with parameter </p><div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&amp;wpDestFile=Noimage.png" class="new" title="File:Noimage.png">File:Noimage.png</a>  <div class="thumbcaption"><a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">caption</a></div></div></div>
 !! html/parsoid
-<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"paramtest","href":"./Template:Paramtest"},"params":{"param":{"wt":"[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]"}},"i":0}}]}'>This is a test template with parameter </p><figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" about="#mwt1" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Noimage.png" ><img resource="./File:Noimage.png" src="./Special:FilePath/Noimage.png" height="220" width="220"/></a><figcaption><a rel="mw:WikiLink" href="./No_link" title="No link">link</a> <a rel="mw:WikiLink" href="./No_link" title="No link">caption</a></figcaption></figure>
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"paramtest","href":"./Template:Paramtest"},"params":{"param":{"wt":"[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]"}},"i":0}}]}'>This is a test template with parameter </p><figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" about="#mwt1" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Noimage.png"><span resource="./File:Noimage.png" data-width="220">File:Noimage.png</span></a><figcaption><a rel="mw:WikiLink" href="./No_link" title="No link">link</a> <a rel="mw:WikiLink" href="./No_link" title="No link">caption</a></figcaption></figure>
 !! end
 
 !! article
@@ -11769,7 +11607,6 @@ T2553: link with two variables in a piped link
 <tr>
 <td>[[{{{1}}}|{{{2}}}]]
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><td>[[<span about="#mwt5" typeof="mw:Param" data-mw='{"parts":[{"templatearg":{"target":{"wt":"1"},"params":{},"i":0}}]}'>{{{1}}}</span>|<span about="#mwt2" typeof="mw:Param" data-mw='{"parts":[{"templatearg":{"target":{"wt":"2"},"params":{},"i":0}}]}'>{{{2}}}</span>]]</td></tr>
@@ -11797,7 +11634,6 @@ Abort table cell attribute parsing on wikilink
 <td>testing="<a href="/index.php?title=One&amp;action=edit&amp;redlink=1" class="new" title="One (page does not exist)">two</a>" |three</td>
 <td>four
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'>testing <a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"piped","a":{"href":"./One"},"sa":{"href":"one"}}'>two</a> |three</td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'>four</td>
@@ -11946,7 +11782,6 @@ foo {{table}}
 <td>3</td>
 <td>4
 </td></tr></table>
-
 !! end
 
 !! test
@@ -11966,7 +11801,6 @@ foo
 <td>3</td>
 <td>4
 </td></tr></table>
-
 !! end
 
 !! test
@@ -12140,13 +11974,16 @@ Template:Includes3
 </p>
 !! end
 
+# FIXME: Parsoid's markup for this is quite ugly.
 !! test
 <includeonly> and <noinclude> on a page
 !! wikitext
 Foo<noinclude>zar</noinclude><includeonly>bar</includeonly>
-!! html
+!! html/php+tidy
 <p>Foozar
 </p>
+!! html/parsoid
+<p>Foo<meta typeof="mw:Includes/NoInclude" data-parsoid="{}"/>zar</p><meta typeof="mw:Includes/NoInclude/End" data-parsoid="{}"/><meta typeof="mw:Includes/IncludeOnly" data-mw='{"src":"&lt;includeonly>bar&lt;/includeonly>"}' data-parsoid="{}"/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid="{}"/>
 !! end
 
 !! test
@@ -12203,7 +12040,6 @@ Unbalanced includeonly and noinclude tags
 </td>
 <td>d&lt;/includeonly&gt;&lt;/includeonly&gt;
 </td></tr></table>
-
 !!end
 
 !! article
@@ -12222,7 +12058,6 @@ T8563: Edit link generation for section shown by <includeonly>
 !! html
 <h2><span class="mw-headline" id="Includeonly_section">Includeonly section</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Includeonly_section&amp;action=edit&amp;section=T-1" title="Template:Includeonly section">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Section_T-1">Section T-1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Includeonly_section&amp;action=edit&amp;section=T-2" title="Template:Includeonly section">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 # Uses same input as the contents of [[Template:Includeonly section]]
@@ -12248,7 +12083,6 @@ T8563: Edit link generation for section suppressed by <includeonly>
 ==Section 1==
 !! html
 <h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -12306,7 +12140,6 @@ some* stuff
 </p>
 <ul><li>here</li></ul>
 <h3><span class="mw-headline" id="here">here</span></h3>
-
 !! html/parsoid
 <!-- comment --><meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/><!-- comment --><meta typeof="mw:Includes/NoInclude/End" data-parsoid='{"src":"&lt;/noinclude>"}'/><!-- comment --><h2 id="hu">hu</h2>
 
@@ -12320,7 +12153,6 @@ some* stuff
 <ul><li>here</li></ul>
 
 <meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>can have stuff&lt;/includeonly>"}' data-mw='{"src":"&lt;includeonly>can have stuff&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><h3 id="here">here</h3>
-
 !! end
 
 # TODO: test with DOM fragment reuse!
@@ -12467,7 +12299,6 @@ Parsoid: Merge double tds in nested transclusion content (T52603)
 <td>a
 </td></tr>
 </table>
-
 !!end
 
 ###
@@ -12558,7 +12389,6 @@ Preprocessor precedence 5: tplarg takes precedence over template
 {{Precedence5|Bullet}}
 !! html/php
 <ul><li>Bar</li></ul>
-
 !! html/parsoid
 <ul typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Precedence5","href":"./Template:Precedence5"},"params":{"1":{"wt":"Bullet"}},"i":0}}]}'><li>Bar</li></ul>
 !! end
@@ -12658,7 +12488,6 @@ Preprocessor precedence 9: groups of braces
 <dd>Four</dd>
 <dt>7</dt>
 <dd>{Bullet}</dd></dl>
-
 !! html/parsoid
 <dl about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Preprocessor precedence 9","href":"./Template:Preprocessor_precedence_9"},"params":{"1":{"wt":"Four"},"2":{"wt":"Bullet"},"3":{"wt":"1"},"4":{"wt":"2"}},"i":0}}]}'>
 <dt>4</dt>
@@ -12710,7 +12539,6 @@ language=zh
 <dd>-Three-</dd>
 <dt>7</dt>
 <dd>raw2</dd></dl>
-
 !! html/parsoid
 <dl about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Preprocessor precedence 10","href":"./Template:Preprocessor_precedence_10"},"params":{"1":{"wt":"Three"},"2":{"wt":"raw2"},"3":{"wt":"Bullet"},"4":{"wt":"1"},"5":{"wt":"2"}},"i":0}}]}'>
 <dt>1</dt>
@@ -13084,7 +12912,6 @@ Templates: 2. Inside a block tag
 !! html
 <div>Foo</div>
 <blockquote>Foo</blockquote>
-
 !! html+tidy
 <div>Foo</div>
 <blockquote><p>Foo</p></blockquote>
@@ -13124,7 +12951,6 @@ Templates: P-wrapping: 1c. Templates on consecutive lines
 <p>Foo
 </p>
 bar <div>baz</div>
-
 !! html+tidy
 <p>Foo
 </p><p>
@@ -13184,7 +13010,6 @@ Templates: Block Tags: 1. Multiple template uses
 {{echo|<div>Foo</div>}}<div>bar</div>{{echo|<div>baz</div>}}
 !! html
 <div>Foo</div><div>bar</div><div>baz</div>
-
 !!end
 
 !!test
@@ -13193,7 +13018,6 @@ Templates: Block Tags: 2. Back-to-back template uses
 {{echo|<div>Foo</div>}}{{echo|<div>bar</div>}}
 !! html
 <div>Foo</div><div>bar</div>
-
 !!end
 
 ## Parsoid drops empty elements in templates.
@@ -13280,13 +13104,20 @@ Templates: Links: 5. Nested templates (only outermost template should be marked)
 </p>
 !!end
 
+!! test
+File with template filename
+!! wikitext
+[[File:{{echo|Foobar.jpg}}]]
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"href"},{"html":"File:&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&apos;{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[7,26,null,null]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"Foobar.jpg\"}},\"i\":0}}]}&apos;>Foobar.jpg&lt;/span>"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:{{echo|Foobar.jpg}}"}}'/></a></figure-inline></p>
+!! end
+
 !!test
 Templates: HTML Tag: 1. Generation of HTML attr. key
 !! wikitext
 <div {{echo|style}}="color:red;">foo</div>
 !! html
 <div style="color:red;">foo</div>
-
 !!end
 
 !!test
@@ -13295,7 +13126,6 @@ Templates: HTML Tag: 2. Generation of HTML attr. value
 <div style={{echo|'color:red;'}}>foo</div>
 !! html
 <div style="color:red;">foo</div>
-
 !!end
 
 !!test
@@ -13304,7 +13134,6 @@ Templates: HTML Tag: 3. Generation of HTML attr key and value
 <div {{echo|style}}={{echo|'color:red;'}}>foo</div>
 !! html
 <div style="color:red;">foo</div>
-
 !!end
 
 !!test
@@ -13313,7 +13142,6 @@ Templates: HTML Tag: 4. Generation of starting piece of HTML attr value
 <div title="{{echo|This is a long title}} with just one piece templated">foo</div>
 !! html
 <div title="This is a long title with just one piece templated">foo</div>
-
 !!end
 
 !!test
@@ -13322,7 +13150,6 @@ Templates: HTML Tag: 5. Generation of middle piece of HTML attr value
 <div title="This is a long title with just {{echo|one piece}} templated">foo</div>
 !! html
 <div title="This is a long title with just one piece templated">foo</div>
-
 !!end
 
 !!test
@@ -13331,7 +13158,6 @@ Templates: HTML Tag: 6. Generation of end piece of HTML attr value
 <div title="This is a long title with just one piece {{echo|templated}}">foo</div>
 !! html
 <div title="This is a long title with just one piece templated">foo</div>
-
 !!end
 
 # SSS FIXME: While it is great we added support for all this,
@@ -13343,7 +13169,6 @@ Templates: HTML Tag: 7. Generation of partial attribute key string
 <div st{{echo|yle}}="color:red;">foo</div>
 !! html
 <div style="color:red;">foo</div>
-
 !!end
 
 !! test
@@ -13352,7 +13177,6 @@ Templates: HTML Tag: 8. Template-generated attribute (k=v)
 <div {{echo|1=id="v1"}}>bar</div>
 !! html
 <div id="v1">bar</div>
-
 !!end
 
 !! test
@@ -13361,7 +13185,6 @@ Templates: HTML Tag: 9. Multiple template-generated attributes
 <div {{echo|1=id="v1" title="foo"}}>bar</div>
 !! html
 <div id="v1" title="foo">bar</div>
-
 !!end
 
 !! test
@@ -13380,7 +13203,6 @@ Templates: Support for templates generating attributes and content
 <tr>
 <td>bar
 </td></tr></table>
-
 !! html/parsoid
 <table style="color:red;" title="T48811" about="#mwt1" typeof="mw:Transclusion mw:ExpandedAttrs" data-mw='{"parts":["{| ",{"template":{"target":{"wt":"mixed_attr_content_template","href":"./Template:Mixed_attr_content_template"},"params":{},"i":0}},"\n|-\n|bar\n|}"]}'>
 <tbody><tr>
@@ -13414,7 +13236,6 @@ Table cell with attribute before expanded attribute
 <div {{echo|style{{=}}"background:&#35;f9f9f9;"}}>foo</div>
 !! html/php
 <div style="background:#f9f9f9;">foo</div>
-
 !! html/parsoid
 <div style="background:#f9f9f9;" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html"}' data-mw='{"attribs":[[{"txt":"style","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[5,49,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"style{{=}}\\\"background:&amp;amp;#35;f9f9f9;\\\"\"}},\"i\":0}}]}&#39;>style&lt;/span>&lt;span typeof=\"mw:Nowiki\" about=\"#mwt1\" data-parsoid=\"{}\">=&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">\"background:&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=&#39;{\"src\":\"&amp;amp;#35;\",\"srcContent\":\"#\"}&#39;>#&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">f9f9f9;\"&lt;/span>"},{"html":""}]]}'>foo</div>
 !! end
@@ -13430,7 +13251,6 @@ Table cell with attribute before expanded attribute
 <tr>
 <td style="background:#f9f9f9;">Foo
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_3","href":"./Template:Table_attribs_3"},"params":{},"i":0}}]}'>Foo</td></tr>
@@ -13448,7 +13268,6 @@ Table cell with attribute before expanded attribute
 <tr>
 <td style="background:#f9f9f9;">Foo
 </td></tr></table>
-
 !! html/parsoid
 <table about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[],[],[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"tbl-start","href":"./Template:Tbl-start"},"params":{},"i":0}},"\n|",{"template":{"target":{"wt":"table_attribs_3","href":"./Template:Table_attribs_3"},"params":{},"i":1}},"\n",{"template":{"target":{"wt":"tbl-end","href":"./Template:Tbl-end"},"params":{},"i":2}}]}'>
 <tbody><tr><td style="background:#f9f9f9;">Foo</td></tr>
@@ -13467,7 +13286,6 @@ Table cell with attribute before expanded attribute
 <tr>
 <td style="background: red;">hi
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody><tr><td style="background:  red;" typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_6","href":"./Template:Table_attribs_6"},"params":{},"i":0}}," hi"]}'> hi</td></tr>
@@ -13480,7 +13298,6 @@ Templates: HTML Tables: 1. Generating start of a HTML table
 {{echo|<table><tr><td>foo</td>}}</tr></table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
 !!end
 
 !!test
@@ -13489,7 +13306,6 @@ Templates: HTML Tables: 2a. Generating middle of a HTML table
 <table><tr>{{echo|<td>foo</td>}}</tr></table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
 !!end
 
 !!test
@@ -13498,7 +13314,6 @@ Templates: HTML Tables: 2b. Generating middle of a HTML table
 <table>{{echo|<tr><td>foo</td></tr>}}</table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
 !!end
 
 !!test
@@ -13507,8 +13322,7 @@ Templates: HTML Tables: 3. Generating end of a HTML table
 <table><tr>{{echo|<td>foo</td></tr></table>}}
 !! html
 <table><tr><td>foo</td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: HTML Tables: 4a. Generating a single tag of a HTML table
@@ -13516,8 +13330,7 @@ Templates: HTML Tables: 4a. Generating a single tag of a HTML table
 {{echo|<table>}}<tr><td>foo</td></tr></table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: HTML Tables: 4b. Generating a single tag of a HTML table
@@ -13525,8 +13338,7 @@ Templates: HTML Tables: 4b. Generating a single tag of a HTML table
 <table>{{echo|<tr>}}<td>foo</td></tr></table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: HTML Tables: 4c. Generating a single tag of a HTML table
@@ -13534,8 +13346,7 @@ Templates: HTML Tables: 4c. Generating a single tag of a HTML table
 <table><tr>{{echo|<td>}}foo</td></tr></table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: HTML Tables: 4d. Generating a single tag of a HTML table
@@ -13543,8 +13354,7 @@ Templates: HTML Tables: 4d. Generating a single tag of a HTML table
 <table><tr><td>foo{{echo|</td>}}</tr></table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: HTML Tables: 4e. Generating a single tag of a HTML table
@@ -13552,8 +13362,7 @@ Templates: HTML Tables: 4e. Generating a single tag of a HTML table
 <table><tr><td>foo</td>{{echo|</tr>}}</table>
 !! html
 <table><tr><td>foo</td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: HTML Tables: 4f. Generating a single tag of a HTML table
@@ -13561,8 +13370,7 @@ Templates: HTML Tables: 4f. Generating a single tag of a HTML table
 <table><tr><td>foo</td></tr>{{echo|</table>}}
 !! html
 <table><tr><td>foo</td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: HTML Tables: 5. Proper fostering of categories from inside
@@ -13592,7 +13400,6 @@ Templates: Wiki Tables: 1a. Fostering of entire template content
 <table>
 a
 <tr><td></td></tr></table>
-
 !! html/php+tidy
 
 a
@@ -13618,7 +13425,6 @@ foo
 </p>
 </div>
 <tr><td></td></tr></table>
-
 !! html/php+tidy
 <div>
 <p>foo
@@ -13647,7 +13453,6 @@ Templates: Wiki Tables: 2. Fostering of partial template content
 a
 <div>b</div>
 <tr><td></td></tr></table>
-
 !! html/php+tidy
 
 a
@@ -13671,8 +13476,7 @@ Templates: Wiki Tables: 3. td-content via multiple templates
 <tr>
 <td>ab
 </td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: Wiki Tables: 4. Templated tags, no content
@@ -13682,8 +13486,7 @@ Templates: Wiki Tables: 4. Templated tags, no content
 !! html
 <table>
 <tr><td></td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: Wiki Tables: 5. Templated tags, regular td-tags
@@ -13696,8 +13499,7 @@ Templates: Wiki Tables: 5. Templated tags, regular td-tags
 <tr>
 <td>foo
 </td></tr></table>
-
-!!end
+!! end
 
 !!test
 Templates: Wiki Tables: 6. Templated tags, templated td-tags
@@ -13710,8 +13512,7 @@ Templates: Wiki Tables: 6. Templated tags, templated td-tags
 <tr>
 <td>foo
 </td></tr></table>
-
-!!end
+!! end
 
 ## This test case is very specific to Parsoid's internals
 ## and is hence only tested for Parsoid's code. Parsoid uses
@@ -13763,7 +13564,6 @@ unused}}}}
 !! html
 <ul><li>a <a href="/index.php?title=Template:Nonexistent&amp;action=edit&amp;redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a></li>
 <li>b <a href="/index.php?title=Template:Nonexistent&amp;action=edit&amp;redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a></li></ul>
-
 !!end
 
 !!test
@@ -13805,10 +13605,8 @@ Templates: Ugly nesting: 4. Divs opened/closed across templates
 a<div>b{{echo|c</div>d}}e
 !! html
 a<div>bc</div>de
-
 !! html+tidy
-<p>a</p><div>bc</div><p>de
-</p>
+<p>a</p><div>bc</div><p>de</p>
 !! end
 
 !! test
@@ -14685,9 +14483,8 @@ Right-aligned image
 [[File:Foobar.jpg|right]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
-<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
+<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
 !! end
 
 !! test
@@ -14696,7 +14493,6 @@ Image with caption
 [[File:Foobar.jpg|right|Caption text]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Caption text</figcaption></figure>
 !! end
@@ -14707,7 +14503,6 @@ Image with caption, T55312 #1
 [[File:Foobar.jpg|right|Caption page stuff]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption page stuff"><img alt="Caption page stuff" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Caption page stuff</figcaption></figure>
 !! end
@@ -14718,7 +14513,6 @@ Image with caption, T55312 #2
 [[File:Foobar.jpg|right|Caption page=]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption page="><img alt="Caption page=" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Caption page=</figcaption></figure>
 !! end
@@ -14729,7 +14523,6 @@ Image with caption, T55312 #3
 [[File:Foobar.jpg|right|Caption page=stuff]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption page=stuff"><img alt="Caption page=stuff" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Caption page=stuff</figcaption></figure>
 !! end
@@ -14742,7 +14535,6 @@ Image caption with pipe entity
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>one &#x7c; two</div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>one <i>two</i> &#x7c; three</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>one <span typeof="mw:Entity">|</span> two</figcaption></figure>
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>one <i>two</i> <span typeof="mw:Entity">|</span> three</figcaption></figure>
@@ -14759,7 +14551,6 @@ thumbsize=220
 ]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Caption <a href="/index.php?title=Link1&amp;action=edit&amp;redlink=1" class="new" title="Link1 (page does not exist)">Link1</a> [[]] <a href="/index.php?title=Link2&amp;action=edit&amp;redlink=1" class="new" title="Link2 (page does not exist)">Link2</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption [[Link1]]\n[[]]\n[[Link2]]\n"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption <a rel="mw:WikiLink" href="./Link1" title="Link1" data-parsoid='{"stx":"simple","a":{"href":"./Link1"},"sa":{"href":"Link1"}}'>Link1</a>
 [[]]
@@ -14806,7 +14597,6 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|right||Caption text]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Caption text</figcaption></figure>
 !! end
@@ -14817,9 +14607,8 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb|{{echo|137px}}|This is a caption]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:139px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" decoding="async" width="137" height="16" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/206px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/274px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is a caption</div></div></div>
-
 !! html/parsoid
-<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"{{echo|137px}}"},{"ck":"caption","ak":"This is a caption"}]}' data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["width",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[24,38,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"137px\"}},\"i\":0}}]}&#39;>137px&lt;/span>"}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"16","width":"137"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>This is a caption</figcaption></figure>
+<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"{{echo|137px}}"},{"ck":"caption","ak":"This is a caption"}]}' data-mw='{"attribs":[["width",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[24,38,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"137px\"}},\"i\":0}}]}&#39;>137px&lt;/span>"}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"16","width":"137"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>This is a caption</figcaption></figure>
 !! end
 
 !! test
@@ -14828,7 +14617,6 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|{{echo|thumb}}|{{echo|137px}}|This is a caption]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:139px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" decoding="async" width="137" height="16" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/206px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/274px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is a caption</div></div></div>
-
 !! html/parsoid
 <figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt3" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"{{echo|thumb}}"},{"ck":"width","ak":"{{echo|137px}}"},{"ck":"caption","ak":"This is a caption"}]}' data-mw='{"attribs":[["thumbnail",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[18,32,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"thumb\"}},\"i\":0}}]}&#39;>thumb&lt;/span>"}],["width",{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[33,47,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"137px\"}},\"i\":0}}]}&#39;>137px&lt;/span>"}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"16","width":"137"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>This is a caption</figcaption></figure>
 !! end
@@ -14852,7 +14640,6 @@ Image with multiple attributes from the same template
 [[File:Foobar.jpg|{{image_attribs}}]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image mw:Placeholder"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Caption text</figcaption></figure>
 !! end
@@ -14870,17 +14657,15 @@ thumbsize=220
 </p>
 123<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>456
 123<div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div>456
-
 !! html/php+tidy
 <p>123<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>456
 </p><p>
 123</p><div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div><p>456
-123</p><div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div><p>456
-</p>
+123</p><div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div><p>456</p>
 !! html/parsoid
 <p>123<figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline>456</p>
-<p>123</p><figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure><p>456
-123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></figure><p>456</p>
+<p>123</p><figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure><p>456
+123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption></figcaption></figure><p>456</p>
 !! end
 
 !! test
@@ -14889,7 +14674,6 @@ Image with multiple captions -- only last one is accepted
 [[File:Foobar.jpg|right|Caption1 - ignored|[[Caption2]] - ignored|Caption3 - accepted]]
 !! html/php
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption3 - accepted"><img alt="Caption3 - accepted" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Caption3 - accepted</figcaption></figure>
 !! end
@@ -14932,7 +14716,6 @@ Image with width attribute at different positions
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" decoding="async" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div>
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" decoding="async" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div>
 <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" decoding="async" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div>
-
 !! html/parsoid
 <figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
 <figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>Caption</figcaption></figure>
@@ -15093,7 +14876,6 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb|link=http://example.com/|Title]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="http://example.com/"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="http://example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>Title</figcaption></figure>
 !! end
@@ -15106,7 +14888,19 @@ thumbsize=220
 [[File:Foobar.jpg|thumbnail=Thumb.png|Title]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
+!! html/parsoid
+<figure class="mw-default-size" typeof="mw:Image/Thumb" about="#mwt1" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+!! end
 
+!! test
+Manually-specified thumbnail image (backwards compat)
+!! options
+thumbsize=220
+parsoid=html2wt
+!! wikitext
+[[File:Foobar.jpg|thumbnail=Thumb.png|Title]]
+!! html/php
+<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
 !! end
@@ -15120,9 +14914,8 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb=Thumb.png|link=Main_Page|Title]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
 !! end
 
 !! test
@@ -15134,9 +14927,8 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb=Thumb.png|link=http://example.com|Title]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="http://example.com"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="http://example.com"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="http://example.com"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
 !! end
 
 !! test
@@ -15148,9 +14940,8 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb=Thumb.png|link=|Title]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" />  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><span><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></span><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><span><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></span><figcaption>Title</figcaption></figure>
 !! end
 
 !! test
@@ -15162,9 +14953,8 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb=Thumb.png|link=Main_Page|alt=alttext|Title]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="alttext" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./Main_Page"><img alt="alttext" resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="./Main_Page"><img alt="alttext" resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
 !! end
 
 !! test
@@ -15175,7 +14965,6 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|frame|left|This is a test image [[Main Page]]]]
 !! html/php
 <div class="thumb tleft"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption">This is a test image <a href="/wiki/Main_Page" title="Main Page">Main Page</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-left" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>This is a test image <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></figcaption></figure>
 !! end
@@ -15188,7 +14977,6 @@ parsoid=wt2html,wt2wt,html2html
 [[Image:Foobar.jpg|frame|left|This is a test image [[Main Page]]|alt=Altitude]]
 !! html/php
 <div class="thumb tleft"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Altitude" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption">This is a test image <a href="/wiki/Main_Page" title="Main Page">Main Page</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-left" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img alt="Altitude" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>This is a test image <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></figcaption></figure>
 !! end
@@ -15206,7 +14994,7 @@ Image with wiki markup in implicit alt
 !! html/parsoid
 <p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"testing &#39;&#39;&#39;bold&#39;&#39;&#39; in alt"}]}' data-mw='{"caption":"testing &lt;b data-parsoid=&#39;{\"dsr\":[27,37,3,3]}&#39;>bold&lt;/b> in alt"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a></figure-inline></p>
 
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=testing &#39;&#39;&#39;bold&#39;&#39;&#39; in alt"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img alt="testing bold in alt" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"testing bold in alt","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=testing &#39;&#39;&#39;bold&#39;&#39;&#39; in alt","resource":"Image:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=testing &apos;&apos;&apos;bold&apos;&apos;&apos; in alt"}]}' data-mw='{"attribs":[["alt",{"html":"alt=testing &lt;b data-parsoid=&apos;{\"dsr\":[79,89,3,3]}&apos;>bold&lt;/b> in alt","txt":"testing bold in alt"}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"Image:Foobar.jpg"}}'><img alt="testing bold in alt" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a></figure-inline></p>
 !! end
 
 !! test
@@ -15215,17 +15003,12 @@ Alt image option should handle most kinds of wikitext without barfing
 [[Image:Foobar.jpg|thumb|This is the image caption|alt=This is a [[link]] and a {{echo|''bold template''}}.]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="This is a link and a bold template." src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is the image caption</div></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"This is the image caption"},{"ck":"alt","ak":"alt=This is a [[link]] and a {{echo|&apos;&apos;bold template&apos;&apos;}}."}]}' data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["alt",{"html":"alt=This is a &lt;a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid=&apos;{\"stx\":\"simple\",\"a\":{\"href\":\"./Link\"},\"sa\":{\"href\":\"link\"},\"dsr\":[65,73,2,2]}&apos;>link&lt;/a> and a &lt;i about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&apos;{\"dsr\":[80,106,null,null],\"pi\":[[{\"k\":\"1\"}]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;apos;&amp;apos;bold template&amp;apos;&amp;apos;\"}},\"i\":0}}]}&#39;>bold template&lt;/i>."}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img alt="This is a link and a bold template." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"alt":"This is a link and a bold template.","resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"alt":"alt=This is a [[link]] and a {{echo|&#39;&#39;bold template&#39;&#39;}}.","resource":"Image:Foobar.jpg"}}'/></a><figcaption>This is the image caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"This is the image caption"},{"ck":"alt","ak":"alt=This is a [[link]] and a {{echo|&apos;&apos;bold template&apos;&apos;}}."}]}' data-mw='{"attribs":[["alt",{"html":"alt=This is a &lt;a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid=&apos;{\"stx\":\"simple\",\"a\":{\"href\":\"./Link\"},\"sa\":{\"href\":\"link\"},\"dsr\":[65,73,2,2]}&apos;>link&lt;/a> and a &lt;i about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&apos;{\"dsr\":[80,106,null,null],\"pi\":[[{\"k\":\"1\"}]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;apos;&amp;apos;bold template&amp;apos;&amp;apos;\"}},\"i\":0}}]}&apos;>bold template&lt;/i>.","txt":"This is a link and a bold template."}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"Image:Foobar.jpg"}}'><img alt="This is a link and a bold template." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a><figcaption>This is the image caption</figcaption></figure>
 !! end
 
 !! test
 Ampersand in alt attribute (T206940)
-!! options
-parsoid = {
-  "nativeGallery": true
-}
 !! wikitext
 [[File:Foobar.jpg|alt=&amp;amp;]]
 
@@ -15244,19 +15027,53 @@ File:Foobar.jpg|alt=&amp;amp;
                </div></li>
 </ul>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="&amp;amp;" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:Entity\" data-parsoid=&apos;{\"src\":\"&amp;amp;amp;\",\"srcContent\":\"&amp;amp;\",\"dsr\":[22,27,null,null]}&apos;>&amp;amp;&lt;/span>amp;","txt":"&amp;amp;"}]]}'><a href="./File:Foobar.jpg"><img alt="&amp;amp;" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 
 <!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="&amp;amp;" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt5" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;">
+<div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:Entity\" data-parsoid=&apos;{\"src\":\"&amp;amp;amp;\",\"srcContent\":\"&amp;amp;\",\"dsr\":[109,114,null,null]}&apos;>&amp;amp;&lt;/span>amp;","txt":"&amp;amp;"}]]}'><a href="./File:Foobar.jpg"><img alt="&amp;amp;" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 <div class="gallerytext"></div>
 </li>
 </ul>
 !! end
 
+## FIXME: The inconsistency in the gallery extension on the php side is T49646
+!! test
+Link with encoded pipe in alt option
+!! options
+parsoid={
+  "modes": ["wt2html", "html2html"]
+}
+!! wikitext
+[[File:Foobar.jpg|alt=http://testing.123?4=5&vert;6|caption]]
+
+<!-- consistency with gallery extension -->
+<gallery>
+File:Foobar.jpg|alt=http://testing.123?4=5&vert;6|caption
+</gallery>
+!! html/php+tidy
+<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="http://testing.123?4=5|6" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
+</p>
+<ul class="gallery mw-gallery-traditional">
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="http://testing.123?4=5&amp;vert;6%7Ccaption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+                       </div>
+               </div></li>
+</ul>
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=http://testing.123?4=5&amp;vert;6"},{"ck":"caption","ak":"caption"}]}' data-mw='{"attribs":[["alt",{"html":"alt=&lt;a rel=\"mw:ExtLink\" href=\"http://testing.123?4=5%7C6\" data-parsoid=&apos;{\"stx\":\"url\",\"a\":{\"href\":\"http://testing.123?4=5%7C6\"},\"sa\":{\"href\":\"http://testing.123?4=5&amp;amp;vert;6\"},\"dsr\":[22,51,0,0]}&apos;>http://testing.123?4=5%7C6&lt;/a>","txt":"http://testing.123?4=5|6"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="http://testing.123?4=5|6" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+
+<!-- consistency with gallery extension -->
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt5" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=&lt;a rel=\"mw:ExtLink\" href=\"http://testing.123?4=5%7C6\" data-parsoid=&apos;{\"stx\":\"url\",\"a\":{\"href\":\"http://testing.123?4=5%7C6\"},\"sa\":{\"href\":\"http://testing.123?4=5&amp;amp;vert;6\"},\"dsr\":[137,166,0,0]}&apos;>http://testing.123?4=5%7C6&lt;/a>","txt":"http://testing.123?4=5|6"}]]}'><a href="./File:Foobar.jpg"><img alt="http://testing.123?4=5|6" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
+!! end
+
 !! test
 Italics markup in alt attribute (T206940)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 [[File:Foobar.jpg|alt=''x''|caption]]
 
@@ -15277,19 +15094,20 @@ File:Foobar.jpg|alt=''x''|caption
                </div></li>
 </ul>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=&apos;&apos;x&apos;&apos;"},{"ck":"caption","ak":"caption"}]}' data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"x","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=&apos;&apos;x&apos;&apos;","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=&apos;&apos;x&apos;&apos;"},{"ck":"caption","ak":"caption"}]}' data-mw='{"attribs":[["alt",{"html":"alt=&lt;i data-parsoid=&apos;{\"dsr\":[22,27,2,2]}&apos;>x&lt;/i>","txt":"x"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 
 <!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=&apos;&apos;x&apos;&apos;|caption\n"}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
-<div class="gallerytext">caption</div>
-</li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt5" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=&lt;i data-parsoid=&apos;{\"dsr\":[113,118,2,2]}&apos;>x&lt;/i>","txt":"x"}]]}'><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
 </ul>
 !! end
 
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
 !! test
 Nowiki markup in alt attribute (T206940)
+!! options
+parsoid=html2wt
 !! wikitext
 [[File:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption]]
 
@@ -15310,12 +15128,12 @@ File:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption
                </div></li>
 </ul>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>"},{"ck":"caption","ak":"caption"}],"dsr":[0,71,null,null]}' data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"&apos;&apos;x&apos;&apos;","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt5" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>"},{"ck":"caption","ak":"caption"}]}' data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[22,41,8,9]}&apos;>&apos;&apos;&lt;/span>x&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[42,61,8,9]}&apos;>&apos;&apos;&lt;/span>","txt":"&apos;&apos;x&apos;&apos;"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" /></a></figure-inline></p>
 
 <!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>|caption\n"}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt13" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>|caption\n"}}'>
+<li class="gallerybox" style="width: 155px;">
+<div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[147,166,8,9]}&apos;>&apos;&apos;&lt;/span>x&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[167,186,8,9]}&apos;>&apos;&apos;&lt;/span>","txt":"&apos;&apos;x&apos;&apos;"}]]}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 <div class="gallerytext">caption</div>
 </li>
 </ul>
@@ -15323,10 +15141,6 @@ File:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption
 
 !! test
 Nowiki markup in alt attribute (edited html, no data-parsoid) (T206940)
-!! options
-parsoid = {
-  "nativeGallery": true
-}
 !! wikitext
 [[File:Foobar.jpg|alt=<nowiki>''x''</nowiki>|caption]]
 
@@ -15347,19 +15161,23 @@ File:Foobar.jpg|alt=<nowiki>''x''</nowiki>|caption
                </div></li>
 </ul>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[22,44,8,9]}&apos;>&apos;&apos;x&apos;&apos;&lt;/span>","txt":"&apos;&apos;x&apos;&apos;"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 
 <!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt9" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;">
+<div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[130,152,8,9]}&apos;>&apos;&apos;x&apos;&apos;&lt;/span>","txt":"&apos;&apos;x&apos;&apos;"}]]}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 <div class="gallerytext">caption</div>
 </li>
 </ul>
 !! end
 
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
 !! test
 Ampersand in link attribute (T206940)
+!! options
+parsoid=html2wt
 !! wikitext
 [[File:Foobar.jpg|link=Foo &amp; bar]]
 
@@ -15391,10 +15209,6 @@ File:Foobar.jpg|link=Foo &amp; bar
 
 !! test
 Ampersand in link attribute (edited html, no data-parsoid) (T206940)
-!! options
-parsoid = {
-  "nativeGallery": true
-}
 !! wikitext
 [[File:Foobar.jpg|link=Foo_&_bar]]
 
@@ -15426,6 +15240,8 @@ File:Foobar.jpg|link=Foo_&_bar
 
 !! test
 Italics markup in link attribute (T206940)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 [[Foo''s bar''s]]
 
@@ -15469,7 +15285,7 @@ File:Foobar.jpg|link=''Main Page''|caption2
 <p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=&apos;&apos;Main Page&apos;&apos;"},{"ck":"caption","ak":"caption2"}]}' data-mw='{"caption":"caption2"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=&apos;&apos;Main Page&apos;&apos;"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 
 <!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=Foo&apos;&apos;s bar&apos;&apos;s|caption1\nFile:Foobar.jpg|link=&apos;&apos;Main Page&apos;&apos;|caption2\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox">
 <div class="thumb"><figure-inline typeof="mw:Image"><a href="./Foos_bars"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 <div class="gallerytext">caption1</div>
@@ -15481,8 +15297,12 @@ File:Foobar.jpg|link=''Main Page''|caption2
 </ul>
 !! end
 
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
 !! test
 Nowiki markup in link attribute (T206940)
+!! options
+parsoid=html2wt
 !! wikitext
 [[File:Foobar.jpg|link=Foo<nowiki>''</nowiki>s_bar<nowiki>''</nowiki>s|caption]]
 
@@ -15516,10 +15336,6 @@ File:Foobar.jpg|link=Foo<nowiki>''</nowiki>s_bar<nowiki>''</nowiki>s|caption
 
 !! test
 Nowiki markup in link attribute (edited html, no data-parsoid) (T206940)
-!! options
-parsoid = {
-  "nativeGallery": true
-}
 !! wikitext
 [[File:Foobar.jpg|link=Foo<nowiki>''s_bar''</nowiki>s|caption]]
 
@@ -15574,7 +15390,7 @@ File:Foobar.jpg|link=https://example.com?foo&params=bar
 <p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 
 <!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=https://example.com?foo&amp;params=bar\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox">
 <div class="thumb"><figure-inline typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 <div class="gallerytext"></div>
@@ -15650,7 +15466,6 @@ Image with heading and horizontal rule in caption
 ]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><h3><span class="mw-headline" id="Testing">Testing</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Testing">edit</a><span class="mw-editsection-bracket">]</span></span></h3> 123 <hr /></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"\n=== Testing ===\n123\n--------------\n"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>
 <h3 id="Testing">Testing</h3>
@@ -15697,7 +15512,6 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption">caption</div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption">caption</div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption">caption</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>caption</figcaption></figure>
 <figure class="mw-default-size" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>caption</figcaption></figure>
@@ -15716,7 +15530,6 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
@@ -15776,9 +15589,8 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb|50px]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:52px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" decoding="async" width="50" height="6" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/75px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/100px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div>
-
 !! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a><figcaption></figcaption></figure>
 !! end
 
 !! test
@@ -15792,10 +15604,9 @@ parsoid=wt2html,wt2wt,html2html
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:2002px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" decoding="async" width="2000" height="1500" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/3000px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/4000px-Foobar.svg.png 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div></div></div></div>
-
 !! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a><figcaption></figcaption></figure>
 !! end
 
 !! test
@@ -15845,12 +15656,11 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
+<figure class="mw-default-size" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
 !! end
 
 ###################
@@ -15894,7 +15704,6 @@ thumbsize=220
 [[File:Foobar.jpg|thumb|http://example.com]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" class="external free" href="http://example.com">http://example.com</a></figcaption></figure>
 !! end
@@ -15908,7 +15717,6 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.jpg|thumb|http://example.com|alt=Alteration]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Alteration" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img alt="Alteration" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" class="external free" href="http://example.com">http://example.com</a></figcaption></figure>
 !! end
@@ -15920,7 +15728,6 @@ SVG thumbnails with no language set
 [[File:Foobar.svg|thumb|caption]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" decoding="async" width="180" height="135" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/220px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>caption</figcaption></figure>
 !! end
@@ -15933,7 +15740,6 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.svg|thumb|caption|lang=de]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=File:Foobar.svg&amp;lang=de" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.png" decoding="async" width="180" height="135" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.png 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/220px-Foobar.svg.png" lang="de" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>caption</figcaption></figure>
 !! end
@@ -15946,7 +15752,6 @@ parsoid=wt2html,wt2wt,html2html
 [[File:Foobar.svg|thumb|caption|lang=invalid:language:code]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" decoding="async" width="180" height="135" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div>lang=invalid:language:code</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/220px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>lang=invalid:language:code</figcaption></figure>
 !! end
@@ -15955,7 +15760,6 @@ parsoid=wt2html,wt2wt,html2html
 SVG thumbnails in page language
 !! options
 language=ru
-wgMediaInTargetLanguage = true
 !! wikitext
 [[File:Foobar.svg]] [[File:Foobar.svg|lang=en]]
 !! html/php
@@ -15967,7 +15771,6 @@ wgMediaInTargetLanguage = true
 SVG thumbnails in page language not present in the file
 !! options
 language=de
-wgMediaInTargetLanguage = true
 !! wikitext
 [[File:Foobar.svg]] [[File:Foobar.svg|lang=ru]]
 !! html/php
@@ -15981,7 +15784,6 @@ T3887: A ISBN with a thumbnail
 [[File:Foobar.jpg|thumb|ISBN 1235467890]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a href="/wiki/Special:BookSources/1235467890" class="internal mw-magiclink-isbn">ISBN 1235467890</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="./Special:BookSources/1235467890" rel="mw:WikiLink">ISBN 1235467890</a></figcaption></figure>
 !! end
@@ -15992,7 +15794,6 @@ T3887: A RFC with a thumbnail
 [[File:Foobar.jpg|thumb|This is RFC 12354]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is <a href="https://tools.ietf.org/html/rfc12354" rel="mw:ExtLink" class="external mw-magiclink">RFC 12354</a></figcaption></figure>
 !! end
@@ -16003,7 +15804,6 @@ T3887: A mailto link with a thumbnail
 [[File:Foobar.jpg|thumb|Please mailto:nobody@example.com]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Please <a rel="nofollow" class="external free" href="mailto:nobody@example.com">mailto:nobody@example.com</a></div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>Please <a rel="mw:ExtLink" class="external free" href="mailto:nobody@example.com">mailto:nobody@example.com</a></figcaption></figure>
 !! end
@@ -16093,7 +15893,7 @@ Entities in file name and attributes
 <p><a href="/index.php?title=Special:Upload&amp;wpDestFile=7%25_solution.gif" class="new" title="File:7% solution.gif">7% solution</a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"manualthumb=7%25 solution.gif"},{"ck":"link","ak":"link=7%25 solution"},{"ck":"caption","ak":"[[7%25 solution]]"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"&lt;a rel=\"mw:WikiLink\" href=\"./7%25_solution\" title=\"7% solution\" data-parsoid=&#39;{\"stx\":\"simple\",\"a\":{\"href\":\"./7%25_solution\"},\"sa\":{\"href\":\"7%25 solution\"},\"dsr\":[74,91,2,2]}&#39;>7% solution&lt;/a>"}'><a href="./7%25_solution" data-parsoid='{"a":{"href":"./7%25_solution"},"sa":{"href":"link=7%25 solution"}}'><img resource="./File:7%25_solution.gif" src="./Special:FilePath/7%25_solution.gif" height="220" width="220" data-parsoid='{"a":{"resource":"./File:7%25_solution.gif","height":"220","width":"220"},"sa":{"resource":"File:7%25 solution.gif"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"manualthumb=7%25 solution.gif"},{"ck":"link","ak":"link=7%25 solution"},{"ck":"caption","ak":"[[7%25 solution]]"}]}' data-mw='{"attribs":[["link",{"txt":"7%25 solution"}]],"caption":"&lt;a rel=\"mw:WikiLink\" href=\"./7%25_solution\" title=\"7% solution\" data-parsoid=&apos;{\"stx\":\"simple\",\"a\":{\"href\":\"./7%25_solution\"},\"sa\":{\"href\":\"7%25 solution\"},\"dsr\":[74,91,2,2]}&apos;>7% solution&lt;/a>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/7%25_solution.gif"><span resource="./File:7%25_solution.gif" data-parsoid='{"a":{"resource":"./File:7%25_solution.gif"},"sa":{"resource":"File:7%25 solution.gif"}}'>File:7% solution.gif</span></a></figure-inline></p>
 !! end
 
 !! test
@@ -16126,7 +15926,6 @@ Image caption containing another image
 [[File:Foobar.jpg|thumb|This is a caption with another [[File:Thumb.png|image]] inside it!]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is a caption with another <a href="/wiki/File:Thumb.png" class="image" title="image"><img alt="image" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" /></a> inside it!</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is a caption with another <figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"image"}'><a href="./File:Thumb.png"><img resource="./File:Thumb.png" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a></figure-inline> inside it!</figcaption></figure>
 !! end
@@ -16150,7 +15949,6 @@ Image: caption containing leading space
 [[File:Foobar.jpg|thumb| bar]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>bar</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption> bar</figcaption></figure>
 !!end
@@ -16173,7 +15971,6 @@ parsoid=wt2html,wt2wt,html2html
 and some more text.]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" decoding="async" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is an example image thumbnail caption with a table <table> <tr> <th>Foo</th> <th>Bar </th></tr> <tr> <td>Foo1</td> <td>Bar1 </td></tr></table> and some more text.</div></div></div>
-
 !! html/parsoid
 <figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This is an example image thumbnail caption with a table
 <table>
@@ -16190,7 +15987,6 @@ T5090: External links other than http: in image captions
 [[File:Foobar.jpg|thumb|200x200px|This caption has [irc://example.net irc] and [https://example.com Secure] ext links in it.]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" decoding="async" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This caption has <a rel="nofollow" class="external text" href="irc://example.net">irc</a> and <a rel="nofollow" class="external text" href="https://example.com">Secure</a> ext links in it.</div></div></div>
-
 !! html/parsoid
 <figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This caption has <a rel="mw:ExtLink" class="external text" href="irc://example.net">irc</a> and <a rel="mw:ExtLink" class="external text" href="https://example.com">Secure</a> ext links in it.</figcaption></figure>
 !! end
@@ -16217,7 +16013,6 @@ language=es
 [[Archivo:Foobar.jpg|izquierda|enlace=foo|caption]]
 !! html/php
 <div class="floatleft"><a href="/wiki/Foo" title="caption"><img alt="caption" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-left" typeof="mw:Image"><a href="./Foo"><img resource="./Archivo:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>caption</figcaption></figure>
 !! end
@@ -16232,7 +16027,6 @@ language=es
 [[Archivo:Foobar.jpg|miniatura|izquierda|enlace=foo|caption]]
 !! html/php
 <div class="thumb tleft"><div class="thumbinner" style="width:222px;"><a href="/wiki/Foo" title="Foo"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/Archivo:Foobar.jpg" class="internal" title="Aumentar"></a></div>caption</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./Foo"><img resource="./Archivo:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
 !! end
@@ -16278,7 +16072,6 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tleft"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
 <div class="thumb tleft"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
@@ -16302,6 +16095,7 @@ Redirected image
 </p>
 !! end
 
+## FIXME: Parsoid needs to learn about this flag.
 !! test
 Missing image with uploads disabled
 !! options
@@ -16312,7 +16106,7 @@ wgEnableUploads=0
 <p><a href="/wiki/File:Foobaz.jpg" title="File:Foobaz.jpg">File:Foobaz.jpg</a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Foobaz.jpg"><img resource="./File:Foobaz.jpg" src="./Special:FilePath/Foobaz.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Foobaz.jpg"><span resource="./File:Foobaz.jpg">File:Foobaz.jpg</span></a></figure-inline></p>
 !! end
 
 # Parsoid-specific testing for images
@@ -17130,7 +16924,6 @@ parsoid=wt2html,html2html
 !! html/php
 <div>a
 <a href="/wiki/Foo" title="Foo">Foo</a></div>
-
 !! html/parsoid
 <link rel="mw:PageProp/Category" href="./Category:Foo"/><div>a
 
@@ -17386,7 +17179,6 @@ Some text
 <p>Some text
 </p>
 <h3><span class="mw-headline" id="Another_headline">Another headline</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Another headline">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
-
 !! end
 
 !! test
@@ -17411,7 +17203,6 @@ __FORCETOC__
 <h2><span class="mw-headline" id="Headline">Headline</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Headline">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Headline_2_2">Headline 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Headline 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Headline_3">Headline</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Headline">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 # perl -e 'print "="x$_," Level $_ heading","="x$_,"\n" for 1..10'
@@ -17472,7 +17263,6 @@ parsoid=wt2html
 <h6><span class="mw-headline" id=".3D.3DLevel_8_Heading.3D.3D">==Level 8 Heading==</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=8" title="Edit section: ==Level 8 Heading==">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 <h6><span class="mw-headline" id=".3D.3D.3DLevel_9_Heading.3D.3D.3D">===Level 9 Heading===</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=9" title="Edit section: ===Level 9 Heading===">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 <h6><span class="mw-headline" id=".3D.3D.3D.3DLevel_10_Heading.3D.3D.3D.3D">====Level 10 Heading====</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=10" title="Edit section: ====Level 10 Heading====">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
-
 !! html/parsoid
 <h1 id="Level_1_Heading" data-parsoid='{}'>Level 1 Heading</h1>
 <h2 id="Level_2_Heading" data-parsoid='{}'>Level 2 Heading</h2>
@@ -17522,7 +17312,6 @@ TOC regression (T11764)
 <h3><span class="mw-headline" id="title_1.2">title 1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: title 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
 <h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h3><span class="mw-headline" id="title_2.1">title 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: title 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
-
 !! end
 
 !! test
@@ -17538,7 +17327,6 @@ __FORCETOC__
 </div>
 
 <h2><span class="mw-headline" id="New_title"><span id="old-anchor"></span>New title</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: New title">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -17575,7 +17363,6 @@ wgMaxTocLevel=3
 <h3><span class="mw-headline" id="title_1.2">title 1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: title 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
 <h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h3><span class="mw-headline" id="title_2.1">title 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: title 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
-
 !! end
 
 !! test
@@ -17605,7 +17392,6 @@ wgMaxTocLevel=3
 <h4><span class="mw-headline" id="Section_1.1.1">Section 1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Section 1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4>
 <h4><span class="mw-headline" id="Section_1.1.1.1">Section 1.1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Section 1.1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4>
 <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 
@@ -17617,7 +17403,6 @@ Resolving duplicate section names
 !! html
 <h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Foo_bar_2">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -17628,7 +17413,6 @@ Resolving duplicate section names with differing case (T12721)
 !! html
 <h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Foo_Bar_2">Foo Bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! article
@@ -17650,7 +17434,6 @@ __NOTOC__
 <h3><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&amp;action=edit&amp;section=T-1" title="Template:Sections">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
 <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&amp;action=edit&amp;section=T-2" title="Template:Sections">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Section_4">Section 4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Section 4">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -17662,7 +17445,6 @@ __NOEDITSECTION__
 !! html
 <h2><span class="mw-headline" id="Section_1">Section 1</span></h2>
 <h2><span class="mw-headline" id="Section_2">Section 2</span></h2>
-
 !! end
 
 !! test
@@ -17671,7 +17453,6 @@ Link inside a section heading
 ==Section with a [[Main Page|link]] in it==
 !! html
 <h2><span class="mw-headline" id="Section_with_a_link_in_it">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Section with a link in it">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -17696,7 +17477,6 @@ __TOC__
 <h2><span class="mw-headline" id="title_1">title 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: title 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h3><span class="mw-headline" id="title_1.1">title 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: title 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
 <h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -17923,7 +17703,6 @@ parsoid=wt2html,wt2wt,html2html
 <h1><span class="mw-headline" id=".3Dfoo">=foo</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: =foo">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
 <h1><span class="mw-headline" id="italic_heading.3D"><i>italic</i> heading=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: italic heading=">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
 <h1><span class="mw-headline" id=".3Ditalic_heading">=<i>italic</i> heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: =italic heading">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
-
 !! html/parsoid
 <h1 id="foo="><span id="foo.3D" typeof="mw:FallbackId"></span>foo=</h1>
 <h1 id="=foo"><span id=".3Dfoo" typeof="mw:FallbackId"></span>=foo</h1>
@@ -17969,7 +17748,6 @@ __NOEDITSECTION__
 </span></h1>
 <h2><span class="mw-headline" id="Header_2.1">Header 2.1</span></h2>
 <h2><span class="mw-headline" id="Header_2.2">Header 2.2</span></h2>
-
 !! html/parsoid
 <h1 id="Header_1" data-parsoid='{"stx":"html"}'>Header 1</h1>
 <h2 id="Header_1.1" data-parsoid='{}'>Header 1.1</h2>
@@ -17996,7 +17774,6 @@ c3-->
 <h2><span class="mw-headline" id="foo">foo</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: foo">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="bar">bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="baz">baz</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: baz">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <h2 id="foo">foo</h2><!---->
 <h2 id="bar">bar</h2><!--c1-->
@@ -18055,7 +17832,6 @@ div with no attributes
 <div>HTML rocks</div>
 !! html
 <div>HTML rocks</div>
-
 !! end
 
 !! test
@@ -18064,7 +17840,6 @@ div with double-quoted attribute
 <div id="rock">HTML rocks</div>
 !! html
 <div id="rock">HTML rocks</div>
-
 !! end
 
 !! test
@@ -18073,7 +17848,6 @@ div with single-quoted attribute
 <div id='rock'>HTML rocks</div>
 !! html
 <div id="rock">HTML rocks</div>
-
 !! end
 
 !! test
@@ -18082,7 +17856,6 @@ div with unquoted attribute
 <div id=rock>HTML rocks</div>
 !! html
 <div id="rock">HTML rocks</div>
-
 !! end
 
 !! test
@@ -18091,8 +17864,7 @@ div with illegal double attributes
 <div id="a" id="b">HTML rocks</div>
 !! html
 <div id="b">HTML rocks</div>
-
-!!end
+!! end
 
 !! test
 div with empty attribute value, space before equals
@@ -18102,7 +17874,6 @@ parsoid=wt2html,html2html
 <div class =>HTML rocks</div>
 !! html/php
 <div class="">HTML rocks</div>
-
 !! html/parsoid
 <div class="" data-parsoid='{"stx":"html"}'>HTML rocks</div>
 !! end
@@ -18117,7 +17888,6 @@ parsoid=wt2html,html2html
 <div id= title=>HTML rocks</div>
 !! html/php
 <div id="title=">HTML rocks</div>
-
 !! html/parsoid
 <div id="title=" data-parsoid='{"stx":"html"}'>HTML rocks</div>
 !! end
@@ -18149,7 +17919,6 @@ parsoid=wt2html,html2html
 <tr>
 <td>hi
 </td></tr></table>
-
 !! html/parsoid
 <table title="id=">
 <tbody><tr><td>hi</td></tr>
@@ -18162,7 +17931,6 @@ div with braces in attribute value
 <div title="{}">Foo</div>
 !! html/php
 <div title="&#123;&#125;">Foo</div>
-
 !! html/parsoid
 <div title="{}">Foo</div>
 !! end
@@ -18175,7 +17943,6 @@ parsoid=wt2html,html2html
 <div class=>HTML rocks</div>
 !! html/php
 <div class="">HTML rocks</div>
-
 !! html/parsoid
 <div class="">HTML rocks</div>
 !! end
@@ -18186,8 +17953,7 @@ HTML multiple attributes correction
 <p class="error" class="awesome">Awesome!</p>
 !! html
 <p class="awesome">Awesome!</p>
-
-!!end
+!! end
 
 !! test
 Table multiple attributes correction
@@ -18200,8 +17966,7 @@ Table multiple attributes correction
 <tr>
 <th class="awesome">status
 </th></tr></table>
-
-!!end
+!! end
 
 !! test
 DIV IN UPPERCASE
@@ -18209,8 +17974,7 @@ DIV IN UPPERCASE
 <DIV ID="x">HTML ROCKS</DIV>
 !! html
 <div id="x">HTML ROCKS</div>
-
-!!end
+!! end
 
 !! test
 Non-ASCII pseudo-tags are rendered as text
@@ -18299,7 +18063,6 @@ parsoid=wt2html
 !! html/php
 <div style="style=">hi</div>
 <div>ho</div>
-
 !! html/parsoid
 <div style=" style=" data-parsoid='{"stx":"html","a":{"123\"":null},"sa":{"123\"":""}}'>hi</div>
 <div data-parsoid='{"stx":"html","a":{"=":null},"sa":{"=":""}}'>ho</div>
@@ -18441,7 +18204,6 @@ parsoid=wt2html,html2html
 [[Media:Foobar.jpg|Safe Link<div style=display:none>" onmouseover="alert(document.cookie)" onfoo="</div>]]
 !! html/php
 <a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link&lt;div style="display:none"&gt;" onmouseover="alert(document.cookie)" onfoo="&lt;/div&gt;</a>
-
 !! html/php+tidy
 <p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link</a></p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg"><div style="display:none">" onmouseover="alert(document.cookie)" onfoo="</div></a>
 !! html/parsoid
@@ -18516,7 +18278,7 @@ Image link to nonexistent file (T3850 - good)
 <p><a href="/index.php?title=Special:Upload&amp;wpDestFile=No_such.jpg" class="new" title="File:No such.jpg">File:No such.jpg</a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:No_such.jpg"><img resource="./File:No_such.jpg" src="./Special:FilePath/No_such.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/No_such.jpg"><span resource="./File:No_such.jpg">File:No such.jpg</span></a></figure-inline></p>
 !! end
 
 !! test
@@ -18694,7 +18456,6 @@ T4304: HTML attribute safety (safe template; regression T4309)
 <div title="{{test}}"></div>
 !! html/php
 <div title="This is a test template"></div>
-
 !! html/parsoid
 <div title="This is a test template" about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"title":"This is a test template"},"sa":{"title":"{{test}}"}}' data-mw='{"attribs":[[{"txt":"title"},{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[12,20,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"test\",\"href\":\"./Template:Test\"},\"params\":{},\"i\":0}}]}&#39;>This is a test template&lt;/span>"}]]}'></div>
 !! end
@@ -18706,7 +18467,6 @@ T4304: HTML attribute safety (dangerous template; 2309)
 <div title="{{dangerous attribute}}"></div>
 !! html/php
 <div title=""></div>
-
 !! html/parsoid
 <div title='" onmouseover="alert(document.cookie)' about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"title":"\" onmouseover=\"alert(document.cookie)"},"sa":{"title":"{{dangerous attribute}}"}}' data-mw='{"attribs":[[{"txt":"title"},{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[12,35,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"dangerous attribute\",\"href\":\"./Template:Dangerous_attribute\"},\"params\":{},\"i\":0}}]}&#39;>\" onmouseover=\"alert(document.cookie)&lt;/span>"}]]}'></div>
 !! end
@@ -18717,7 +18477,6 @@ T4304: HTML attribute safety (dangerous style template; 2309)
 <div style="{{dangerous style attribute}}"></div>
 !! html/php
 <div style="/* insecure input */"></div>
-
 !! html/parsoid
 <div style="/* insecure input */" about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"{{dangerous style attribute}}"}}' data-mw='{"attribs":[[{"txt":"style"},{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[12,41,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"dangerous style attribute\",\"href\":\"./Template:Dangerous_style_attribute\"},\"params\":{},\"i\":0}}]}&#39;>border-size: expression(alert(document.cookie))&lt;/span>"}]]}'></div>
 !! end
@@ -18728,7 +18487,6 @@ T4304: HTML attribute safety (safe parameter; 2309)
 {{div style|width: 200px}}
 !! html/php
 <div style="float: right; width: 200px">Magic div</div>
-
 !! html/parsoid
 <div style="float: right; width: 200px" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","a":{"style":"float: right; width: 200px"},"sa":{"style":"float: right; {{{1}}}"},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"div style","href":"./Template:Div_style"},"params":{"1":{"wt":"width: 200px"}},"i":0}}]}'>Magic div</div>
 !! end
@@ -18739,7 +18497,6 @@ T4304: HTML attribute safety (unsafe parameter; 2309)
 {{div style|width: expression(alert(document.cookie))}}
 !! html/php
 <div style="/* insecure input */">Magic div</div>
-
 !! html/parsoid
 <div style="/* insecure input */" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"float: right; {{{1}}}"},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"div style","href":"./Template:Div_style"},"params":{"1":{"wt":"width: expression(alert(document.cookie))"}},"i":0}}]}'>Magic div</div>
 !! end
@@ -18751,7 +18508,6 @@ T4304: HTML attribute safety (unsafe breakout parameter; 2309)
 {{div style|"><script>alert(document.cookie)</script>}}
 !! html
 <div style="float: right;">&lt;script&gt;alert(document.cookie)&lt;/script&gt;"&gt;Magic div</div>
-
 !! end
 
 ## Parsoid output here differs; needs investigation.
@@ -18761,7 +18517,6 @@ T4304: HTML attribute safety (unsafe breakout parameter 2; 2309)
 {{div style|" ><script>alert(document.cookie)</script>}}
 !! html
 <div style="float: right;">&lt;script&gt;alert(document.cookie)&lt;/script&gt;"&gt;Magic div</div>
-
 !! end
 
 !! test
@@ -18770,7 +18525,6 @@ T4304: HTML attribute safety (link)
 <div title="[[Main Page]]"></div>
 !! html/php
 <div title="&#91;&#91;Main Page&#93;&#93;"></div>
-
 !! html/parsoid
 <div title="[[Main Page]]"></div>
 !! end
@@ -18781,7 +18535,6 @@ T4304: HTML attribute safety (italics)
 <div title="''foobar''"></div>
 !! html
 <div title="&#39;&#39;foobar&#39;&#39;"></div>
-
 !! end
 
 !! test
@@ -18790,7 +18543,6 @@ T4304: HTML attribute safety (bold)
 <div title="'''foobar'''"></div>
 !! html
 <div title="&#39;&#39;&#39;foobar&#39;&#39;&#39;"></div>
-
 !! end
 
 !! test
@@ -18799,7 +18551,6 @@ T4304: HTML attribute safety (ISBN)
 <div title="ISBN 1234567890"></div>
 !! html
 <div title="&#73;SBN 1234567890"></div>
-
 !! end
 
 !! test
@@ -18808,7 +18559,6 @@ T4304: HTML attribute safety (RFC)
 <div title="RFC 1234"></div>
 !! html
 <div title="&#82;FC 1234"></div>
-
 !! end
 
 !! test
@@ -18817,7 +18567,6 @@ T4304: HTML attribute safety (PMID)
 <div title="PMID 1234567890"></div>
 !! html
 <div title="&#80;MID 1234567890"></div>
-
 !! end
 
 !! test
@@ -18826,7 +18575,6 @@ T4304: HTML attribute safety (web link)
 <div title="http://example.com/"></div>
 !! html
 <div title="http&#58;//example.com/"></div>
-
 !! end
 
 !! test
@@ -18835,7 +18583,6 @@ T4304: HTML attribute safety (named web link)
 <div title="[http://example.com/ link]"></div>
 !! html/php
 <div title="&#91;http&#58;//example.com/ link&#93;"></div>
-
 !! html/parsoid
 <div title="[http://example.com/ link]"></div>
 !! end
@@ -18846,7 +18593,6 @@ T5244: HTML attribute safety (extension; safe)
 <div style="<nowiki>background:blue</nowiki>"></div>
 !! html/php
 <div style="background:blue"></div>
-
 !! html/parsoid
 <div style="background:blue" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"style":"background:blue"},"sa":{"style":"&lt;nowiki>background:blue&lt;/nowiki>"}}' data-mw='{"attribs":[[{"txt":"style"},{"html":"&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[12,44,8,9]}&apos;>background:blue&lt;/span>"}]]}'></div>
 !! end
@@ -18857,7 +18603,6 @@ T5244: HTML attribute safety (extension; unsafe)
 <div style="<nowiki>border-left:expression(alert(document.cookie))</nowiki>"></div>
 !! html/php
 <div style="/* insecure input */"></div>
-
 !! html/parsoid
 <div style="/* insecure input */" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"&lt;nowiki>border-left:expression(alert(document.cookie))&lt;/nowiki>"}}' data-mw='{"attribs":[[{"txt":"style"},{"html":"&lt;span typeof=\"mw:Nowiki\" data-parsoid=&apos;{\"dsr\":[12,75,8,9]}&apos;>border-left:expression(alert(document.cookie))&lt;/span>"}]]}'></div>
 !! end
@@ -18870,7 +18615,6 @@ MSIE CSS safety test: spurious slash
 <div style="background-image:u\rl(javascript:alert('boo'))">evil</div>
 !! html/php
 <div style="/* insecure input */">evil</div>
-
 !! html/parsoid
 <div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:u\\rl(javascript:alert(&#39;boo&#39;))"}}'>evil</div>
 !! end
@@ -18881,7 +18625,6 @@ MSIE CSS safety test: hex code
 <div style="background-image:u\72l(javascript:alert('boo'))">evil</div>
 !! html/php
 <div style="/* insecure input */">evil</div>
-
 !! html/parsoid
 <div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:u\\72l(javascript:alert(&#39;boo&#39;))"}}'>evil</div>
 !! end
@@ -18892,7 +18635,6 @@ MSIE CSS safety test: comment in url
 <div style="background-image:u/**/rl(javascript:alert('boo'))">evil</div>
 !! html/php
 <div style="background-image:u rl(javascript:alert(&#39;boo&#39;))">evil</div>
-
 !! html/parsoid
 <div style="background-image:u rl(javascript:alert('boo'))" data-parsoid='{"stx":"html","a":{"style":"background-image:u rl(javascript:alert(&#39;boo&#39;))"},"sa":{"style":"background-image:u/**/rl(javascript:alert(&#39;boo&#39;))"}}'>evil</div>
 !! end
@@ -18903,7 +18645,6 @@ MSIE CSS safety test: comment in expression
 <div style="background-image:expres/**/sion(alert('boo4'))">evil4</div>
 !! html/php
 <div style="background-image:expres sion(alert(&#39;boo4&#39;))">evil4</div>
-
 !! html/parsoid
 <div style="background-image:expres sion(alert('boo4'))" data-parsoid='{"stx":"html","a":{"style":"background-image:expres sion(alert(&#39;boo4&#39;))"},"sa":{"style":"background-image:expres/**/sion(alert(&#39;boo4&#39;))"}}'>evil4</div>
 !! end
@@ -18914,7 +18655,6 @@ CSS safety test (all browsers): vertical tab (T57332 / CVE-2013-4567)
 <p style="font-size: 100px; background-image:url\b(https://www.google.com/images/srpr/logo6w.png)">A</p>
 !! html/php
 <p style="/* invalid control char */">A</p>
-
 !! html/parsoid
 <p style="/* invalid control char */" data-parsoid='{"stx":"html","a":{"style":"/* invalid control char */"},"sa":{"style":"font-size: 100px; background-image:url\\b(https://www.google.com/images/srpr/logo6w.png)"}}'>A</p>
 !! end
@@ -18927,7 +18667,6 @@ MSIE 6 CSS safety test: Fullwidth (T57332)
 !! html/php
 <p style="/* insecure input */">A</p>
 <div style="/* insecure input */">B</div>
-
 !! html/parsoid
 <p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expression((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>A</p>
 <div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"top:EXPRESSION(alert())"}}'>B</div>
@@ -18941,7 +18680,6 @@ MSIE 6 CSS safety test: IPA extensions (T57332)
 !! html/php
 <div style="/* insecure input */">A</div>
 <p style="/* insecure input */">B</p>
-
 !! html/parsoid
 <div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:uʀʟ(javascript:alert())"}}'>A</div>
 <p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expʀessɪoɴ((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>B</p>
@@ -18957,7 +18695,6 @@ MSIE 6 CSS safety test: sup/sub script (T57332)
 <div style="/* insecure input */">A</div>
 <div style="/* insecure input */">B</div>
 <p style="/* insecure input */">C</p>
-
 !! html/parsoid
 <div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:url⁽javascript:alert())"}}'>A</div>
 <div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:url₍javascript:alert())"}}'>B</div>
@@ -18974,7 +18711,6 @@ title="&#100;&#97;&#116;&#97;&#58;&#116;&#101;&#120;&#116;&#47;&#104;&#116;&#109
 style="-o-link:attr(title);-o-link-source:current">X</div>
 !! html/php
 <div title="data:text/html,&lt;img src=1 onerror=alert(1)&gt;" style="/* insecure input */">X</div>
-
 !! html/parsoid
 <div title="data:text/html,&lt;img src=1 onerror=alert(1)>" style="/* insecure input */" data-parsoid='{"stx":"html","a":{"title":"data:text/html,&lt;img src=1 onerror=alert(1)>","style":"/* insecure input */"},"sa":{"title":"&amp;#100;&amp;#97;&amp;#116;&amp;#97;&amp;#58;&amp;#116;&amp;#101;&amp;#120;&amp;#116;&amp;#47;&amp;#104;&amp;#116;&amp;#109;&amp;#108;&amp;#44;&amp;#60;&amp;#105;&amp;#109;&amp;#103;&amp;#32;&amp;#115;&amp;#114;&amp;#99;&amp;#61;&amp;#49;&amp;#32;&amp;#111;&amp;#110;&amp;#101;&amp;#114;&amp;#114;&amp;#111;&amp;#114;&amp;#61;&amp;#97;&amp;#108;&amp;#101;&amp;#114;&amp;#116;&amp;#40;&amp;#49;&amp;#41;&amp;#62;","style":"-o-link:attr(title);-o-link-source:current"}}'>X</div>
 !! end
@@ -18997,7 +18733,6 @@ MSIE 6 CSS safety test: Repetition markers (T57332)
 <p style="/* insecure input */">E</p>
 <p style="/* insecure input */">F</p>
 <p style="/* insecure input */">G</p>
-
 !! html/parsoid
 <p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expres〱ion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>A</p>
 <p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expresゝion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>B</p>
@@ -19019,8 +18754,7 @@ Table attribute legitimate extension
 <tr>
 <th style="color:blue">status
 </th></tr></table>
-
-!!end
+!! end
 
 !! test
 Table attribute safety
@@ -19033,7 +18767,6 @@ Table attribute safety
 <tr>
 <th style="/* insecure input */">status
 </th></tr></table>
-
 !! end
 
 !! test
@@ -19042,7 +18775,6 @@ CSS line continuation 1
 <div style="background-image: u\&#10;rl(test.jpg);"></div>
 !! html
 <div style="/* insecure input */"></div>
-
 !! end
 
 !! test
@@ -19051,7 +18783,6 @@ CSS line continuation 2
 <div style="background-image: u\&#13;rl(test.jpg); "></div>
 !! html
 <div style="/* invalid control char */"></div>
-
 !! end
 
 !! article
@@ -19066,7 +18797,6 @@ Expansion of multi-line templates in attribute values (T8255)
 <div style="background: {{identity|#00FF00}}">-</div>
 !! html
 <div style="background: #00FF00">-</div>
-
 !! end
 
 !! test
@@ -19076,7 +18806,6 @@ Expansion of multi-line templates in attribute values (T8255 sanity check)
 #00FF00">-</div>
 !! html/php
 <div style="background: #00FF00">-</div>
-
 !! html/parsoid
 <div style="background:
 #00FF00">-</div>
@@ -19088,7 +18817,6 @@ Expansion of multi-line templates in attribute values (T8255 sanity check 2)
 <div style="background: &#10;#00FF00">-</div>
 !! html
 <div style="background: &#10;#00FF00">-</div>
-
 !! end
 
 !! test
@@ -19114,7 +18842,6 @@ Parser hook: empty input
 array (
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":""}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19132,7 +18859,6 @@ NULL
 array (
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19147,7 +18873,6 @@ NULL
 array (
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19162,7 +18887,6 @@ Parser hook: basic input
 array (
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"input"}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19180,7 +18904,6 @@ parsoid=wt2html,html2html
 array (
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"input"}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19198,7 +18921,6 @@ parsoid=wt2html,html2html
 array (
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"input"}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19215,13 +18937,11 @@ parsoid=wt2html
 array (
 )
 </pre>&lt;/tag&gt;
-
 !! html/php+tidy
 <pre>'<tag>'
 array (
 )
-</tag></pre><p>&lt;/tag&gt;
-</p>
+</tag></pre><p>&lt;/tag&gt;</p>
 !! html/parsoid
 <pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"&lt;tag>"}}'></pre><p>&lt;/tag></p>
 !! end
@@ -19240,7 +18960,6 @@ array (
   'square' => '',
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{"width":"200","height":"100","depth":"50","square":""},"body":{"extsrc":""}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19262,7 +18981,6 @@ array (
   'square' => '',
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{"width":"200","height":"100","depth":"50","square":""},"body":{"extsrc":""}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19278,7 +18996,6 @@ array (
   'filename' => '/tmp/bla',
 )
 </pre>
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{"filename":"/tmp/bla"},"body":{"extsrc":""}}' data-parsoid='{}' about="#mwt2"></pre>
 !! end
@@ -19297,7 +19014,6 @@ array (
   'foo' => 'bar',
 )
 </pre>text
-
 !! html/parsoid
 <pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{"foo":"bar"}}'></pre><p>text</p>
 !! end
@@ -19367,7 +19083,6 @@ Goodbye
 array (
 )
 </pre>
-
 !! end
 
 ###
@@ -19468,8 +19183,7 @@ parsoid=wt2html
 !! wikitext
 Table not started</td></tr></table>
 !! html+tidy
-<p>Table not started
-</p>
+<p>Table not started</p>
 !! end
 
 !! test
@@ -19542,7 +19256,6 @@ Sanitizer: Validating that <meta> and <link> work, but only for Microdata
        <link itemprop="hello" href="http&#58;//example.org" />
 </p>
 </div>
-
 !! end
 
 !! test
@@ -19629,7 +19342,7 @@ language=sr variant=sr-el
 !! html/parsoid
 <p><meta typeof="mw:LanguageVariant" data-mw-variant='{"add":true,"oneway":[{"f":"foAjrjvi","l":"sr-el","t":"\" onload=\"alert(1)\" data-foo=\""}]}'/></p>
 
-<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="./Датотека:Foobar.jpg"><img alt="foAjrjvi" resource="./Датотека:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"foAjrjvi","resource":"./Датотека:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=-{}-foAjrjvi-{}-","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&apos;{\"disabled\":{\"t\":\"\"}}&apos; data-parsoid=&apos;{\"fl\":[],\"dsr\":[76,80,null,2]}&apos;>&lt;/span>foAjrjvi&lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&apos;{\"disabled\":{\"t\":\"\"}}&apos; data-parsoid=&apos;{\"fl\":[],\"dsr\":[88,92,null,2]}&apos;>&lt;/span>","txt":"foAjrjvi"}]]}'><a href="./Датотека:Foobar.jpg"><img alt="foAjrjvi" resource="./Датотека:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./Датотека:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 !! end
 
 !! test
@@ -19657,8 +19370,7 @@ Punctuation: CSS !important (T13874)
 <div style="width:50% !important">important</div>
 !! html
 <div style="width:50% !important">important</div>
-
-!!end
+!! end
 
 !! test
 Punctuation: CSS ! important (T13874; with space after)
@@ -19666,8 +19378,7 @@ Punctuation: CSS ! important (T13874; with space after)
 <div style="width:50% ! important">important</div>
 !! html
 <div style="width:50%&#32;! important">important</div>
-
-!!end
+!! end
 
 !! test
 HTML bullet list, closed tags (T7497)
@@ -19681,13 +19392,11 @@ HTML bullet list, closed tags (T7497)
 <li>One</li>
 <li>Two</li>
 </ul>
-
 !! html/parsoid
 <ul data-parsoid='{"stx":"html"}'>
 <li data-parsoid='{"stx":"html"}'>One</li>
 <li data-parsoid='{"stx":"html"}'>Two</li>
 </ul>
-
 !! end
 
 !! test
@@ -19707,7 +19416,6 @@ HTML bullet list, unclosed tags (T7497)
 <li data-parsoid='{"stx":"html","autoInsertedEnd":true}'>One</li>
 <li data-parsoid='{"stx":"html","autoInsertedEnd":true}'>Two</li>
 </ul>
-
 !! end
 
 !! test
@@ -19722,13 +19430,11 @@ HTML ordered list, closed tags (T7497)
 <li>One</li>
 <li>Two</li>
 </ol>
-
 !! html/parsoid
 <ol data-parsoid='{"stx":"html"}'>
 <li data-parsoid='{"stx":"html"}'>One</li>
 <li data-parsoid='{"stx":"html"}'>Two</li>
 </ol>
-
 !! end
 
 !! test
@@ -19749,7 +19455,6 @@ HTML ordered list, unclosed tags (T7497)
 <li data-parsoid='{"stx":"html","autoInsertedEnd":true}'>One</li>
 <li data-parsoid='{"stx":"html","autoInsertedEnd":true}'>Two</li>
 </ol>
-
 !! end
 
 !! test
@@ -19774,7 +19479,6 @@ HTML nested bullet list, closed tags (T7497)
 </ul>
 </li>
 </ul>
-
 !! html/parsoid
 <ul data-parsoid='{"stx":"html"}'>
 <li data-parsoid='{"stx":"html"}'>One</li>
@@ -19831,7 +19535,6 @@ HTML nested ordered list, closed tags (T7497)
 </ol>
 </li>
 </ol>
-
 !! end
 
 !! test
@@ -19854,7 +19557,6 @@ HTML nested ordered list, open tags (T7497)
 <li>Sub-two
 </ol>
 </ol>
-
 !! html/parsoid
 <ol>
 <li>One
@@ -19868,7 +19570,6 @@ HTML nested ordered list, open tags (T7497)
 </ol>
 </li>
 </ol>
-
 !! end
 
 !! test
@@ -19879,7 +19580,6 @@ HTML ordered list item with parameters oddity
 !! html
 <ol><li id="fragment">One</li>
 </ol>
-
 !! end
 
 # parsoid doesn't explicitly mark autonumbered links, see T55505
@@ -19928,7 +19628,6 @@ Fuzz testing: Parser13
 </td>
 </tr>
 </table>
-
 !! end
 
 # Note that Parsoid output differs from the PHP parser here: the PHP
@@ -19947,7 +19646,6 @@ http://<div id="toc" class="toc"><input type="checkbox" role="button" id="toctog
 </ul>
 </div>
 
-
 !! html/php+tidy
 <h2><span class="mw-headline" id="onmouseover.3D">onmouseover=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: onmouseover=">edit</a><span class="mw-editsection-bracket">]</span></span></h2><p>
 http://</p><div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
@@ -19972,7 +19670,6 @@ parsoid=wt2html,html2html
 <table style="&#95;_TOC&#95;_">
 <tr><td></td></tr>
 </table>
-
 !! html/php+tidy
 <h2><span class="mw-headline" id="a">a</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: a">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <table style="&#95;_TOC&#95;_">
@@ -20017,7 +19714,6 @@ Fuzz testing: Parser21
 </td>
 </tr>
 </table>
-
 !! end
 
 !! test
@@ -20032,7 +19728,6 @@ http://===r:::https://b
 <table>
 <tr><td></td></tr>
 </table>
-
 !! end
 
 ## Remex doesn't account for fostered content.
@@ -20062,7 +19757,6 @@ MOVE YOUR MOUSE CURSOR OVER THIS TEXT
 </td>
 </tr>
 </table>
-
 !! html/php+tidy
 
 {{{|
@@ -20074,8 +19768,7 @@ MOVE YOUR MOUSE CURSOR OVER THIS TEXT
 <td>
 </td>
 </tr>
-</tbody></table><p><u class="&#124;">
-</u></p>
+</tbody></table>
 !! html/parsoid
 <p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>
 {{{|
@@ -20138,7 +19831,6 @@ Fuzz testing: URL adjacent extension (no space, dirty; pre)
 http://example.com<pre>junk</pre>
 !! html/php
 <a rel="nofollow" class="external free" href="http://example.com">http://example.com</a><pre>junk</pre>
-
 !! html/php+tidy
 <p><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></p><pre>junk</pre>
 !! html/parsoid
@@ -20151,9 +19843,8 @@ Fuzz testing: image with bogus manual thumbnail
 [[Image:foobar.jpg|thumbnail= ]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;">Error creating thumbnail:   <div class="thumbcaption"></div></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"manualthumb","ak":"thumbnail= "}]}' data-mw='{"errors":[{"key":"apierror-invalidtitle","message":"Invalid thumbnail title.","params":{"name":""}}],"thumb":""}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"Image:foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="./Special:FilePath/Foobar.jpg" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"220"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure>
+<figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"manualthumb","ak":"thumbnail= "}]}' data-mw='{"attribs":[["manualthumb",{"txt":""}]],"errors":[{"key":"apierror-invalidtitle","message":"Invalid thumbnail title.","params":{"name":""}}]}'><a href="./Special:FilePath/Foobar.jpg"><span resource="./File:Foobar.jpg" data-parsoid='{"a":{"resource":"./File:Foobar.jpg"},"sa":{"resource":"Image:foobar.jpg"}}'>File:Foobar.jpg</span></a><figcaption></figcaption></figure>
 !! end
 
 # Parsoid will emit the newline literally in wt2wt; see next test case.
@@ -20165,7 +19856,6 @@ parsoid=wt2html
 <pre dir="&#10;"></pre>
 !! html/php
 <pre dir="&#10;"></pre>
-
 !! html/parsoid
 <pre dir="
 " typeof="mw:Extension/pre" about="#mwt2"data-mw='{"name":"pre","attrs":{"dir":"\n"},"body":{"extsrc":""}}'></pre>
@@ -20183,7 +19873,6 @@ parsoid=html2wt
 "></pre>
 !! html/php
 <pre dir=""></pre>
-
 !! end
 
 !! test
@@ -20192,7 +19881,6 @@ Templates in extension attributes are not expanded
 <pre dir="{{echo|ltr}}"></pre>
 !! html/php
 <pre dir="{{echo|ltr}}"></pre>
-
 !! html/parsoid
 <pre dir="{{echo|ltr}}" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"dir":"{{echo|ltr}}"},"body":{"extsrc":""}}'></pre>
 !! end
@@ -20216,7 +19904,6 @@ Parsing optional HTML elements (T8171)
     </td><td> And yet som tabular data</td>
   </tr>
 </table>
-
 !! end
 
 !! test
@@ -20238,7 +19925,6 @@ Correct handling of <td>, <tr> (T8171)
     <td> And yet som tabular data</td>
   </tr>
 </table>
-
 !! end
 
 
@@ -20316,7 +20002,6 @@ Special page transclusion
 !! html
 <ul class="mw-prefixindex-list"><li><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></li>
 </ul>
-
 !! end
 
 !! test
@@ -20330,7 +20015,6 @@ Special page transclusion twice (T7021)
 </ul>
 <ul class="mw-prefixindex-list"><li><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></li>
 </ul>
-
 !! end
 
 !! test
@@ -20722,8 +20406,7 @@ section=2
 <!-- -->==sec1==
 ==sec2==
 !! html/php
-
-!!end
+!! end
 
 # Formerly testing for T4607, now resolved by the use of unmarked sections
 # instead of respecting HTML-style headings
@@ -21203,7 +20886,6 @@ Handling of &#x0A; in URLs
 *irc://&#x0A;a
 !! html/php
 <ul><li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul>
-
 !! html/parsoid
 <ul><li><a rel="mw:ExtLink" class="external free" href="irc://%0Aa" data-parsoid='{"stx":"url","a":{"href":"irc://%0Aa"},"sa":{"href":"irc://&amp;#x0A;a"}}'>irc://%0Aa</a></li></ul>
 !! end
@@ -21214,7 +20896,6 @@ Handling of %0A in URLs
 *irc://%0Aa
 !! html/php
 <ul><li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul>
-
 !! html/parsoid
 <ul><li><a rel="mw:ExtLink" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul>
 !! end
@@ -21331,7 +21012,6 @@ title=[[Parser test]]
 <li></li>
 <li></li>
 <li><a href="/index.php?title=Template:Dynamic&amp;action=edit&amp;redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a></li></ul>
-
 !! end
 ### Note: Above tests excludes the "{{NUMBEROFADMINS}}" magic word because it generates a MySQL error when included.
 
@@ -21349,10 +21029,9 @@ File:File:Foobar.jpg
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{"extsrc":"\nFile:File:Foobar.jpg\n"}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:File:Foobar.jpg"><img resource="./File:File:Foobar.jpg" src="./Special:FilePath/File:Foobar.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<ul class="gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/File:Foobar.jpg"><span resource="./File:File:Foobar.jpg" data-width="120" data-height="120">File:File:Foobar.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
 
@@ -21361,8 +21040,7 @@ File:File:Foobar.jpg
 Gallery
 !! options
 parsoid={
-  "modes": ["wt2html"],
-  "nativeGallery": true
+  "modes": ["wt2html"]
 }
 !! wikitext
 <gallery>
@@ -21412,15 +21090,14 @@ image4    |300px| centre
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image1.png"><img resource="./File:Image1.png" src="./Special:FilePath/Image1.png" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image2.gif"><img resource="./File:Image2.gif" src="./Special:FilePath/Image2.gif" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image3"><img resource="./File:Image3" src="./Special:FilePath/Image3" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image4"><img resource="./File:Image4" src="./Special:FilePath/Image4" height="300" width="300"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image5.svg"><img resource="./File:Image5.svg" src="./Special:FilePath/Image5.svg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"> <a rel="mw:ExtLink" class="external free" href="http://///////">http://///////</a></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:*_image6"><img resource="./File:*_image6" src="./Special:FilePath/*_image6" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image1.png"><span resource="./File:Image1.png" data-width="120" data-height="120">File:Image1.png</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image2.gif"><span resource="./File:Image2.gif" data-width="120" data-height="120">File:Image2.gif</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image3"><span resource="./File:Image3" data-width="120" data-height="120">File:Image3</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image4"><span resource="./File:Image4" data-width="300">File:Image4</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image5.svg"><span resource="./File:Image5.svg" data-width="120" data-height="120">File:Image5.svg</span></a></figure-inline></div><div class="gallerytext"> <a rel="mw:ExtLink" class="external free" href="http://///////">http://///////</a></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/*_image6"><span resource="./File:*_image6" data-width="120" data-height="120">File:* image6</span></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
 
@@ -21428,8 +21105,7 @@ image4    |300px| centre
 Gallery (with options, html)
 !! options
 parsoid={
-  "modes": ["wt2html", "html2html"],
-  "nativeGallery": true
+  "modes": ["wt2html", "html2html"]
 }
 !! wikitext
 <gallery widths="70px" heights="40px" perrow="2" caption="Foo [[Main Page]]">
@@ -21474,24 +21150,23 @@ image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" style="max-width: 226px; _width: 226px;" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"widths":"70px","heights":"40px","perrow":"2"},"body":{}}'>
 <li class="gallerycaption">Foo <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext">caption</div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
 <li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">some <b>caption</b> <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></div></li>
 <li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
 <li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="This is a foo-bar." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">blabla.</div></li>
 </ul>
 !! end
 
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
 !! test
 Gallery (with options, extsrc)
 !! options
-parsoid={
-  "nativeGallery": false
-}
+parsoid=html2wt
 !! wikitext
 <gallery widths="70px" heights="40px" perrow="2" caption="Foo [[Main Page]]">
 File:Nonexistent.jpg|caption
@@ -21535,12 +21210,11 @@ image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" style="max-width: 226px; _width: 226px;" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"widths":"70px","heights":"40px","perrow":"2","caption":"Foo [[Main Page]]"},"body":{"extsrc":"\nFile:Nonexistent.jpg|caption\nFile:Nonexistent.jpg\nimage:foobar.jpg|some &#39;&#39;&#39;caption&#39;&#39;&#39; [[Main Page]]\nimage:foobar.jpg\nimage:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.\n"}}'>
+<ul class="gallery mw-gallery-traditional" style="max-width: 226px; _width: 226px;" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"widths":"70px","heights":"40px","perrow":"2","caption":"Foo [[Main Page]]"},"body":{"extsrc":"\nFile:Nonexistent.jpg|caption\nFile:Nonexistent.jpg\nimage:foobar.jpg|some &apos;&apos;&apos;caption&apos;&apos;&apos; [[Main Page]]\nimage:foobar.jpg\nimage:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.\n"}}'>
 <li class="gallerycaption">Foo <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext">caption</div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
 <li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">some <b>caption</b> <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></div></li>
 <li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
 <li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="This is a foo-bar." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">blabla.</div></li>
@@ -21561,9 +21235,8 @@ File:Foobar.jpg
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70","heights":"40"},"body":{"extsrc":"\nFile:Foobar.jpg\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70","heights":"40"},"body":{}}'>
 <li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
@@ -21582,9 +21255,8 @@ File:Foobar.jpg
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70em","heights":"40em"},"body":{"extsrc":"\nFile:Foobar.jpg\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70em","heights":"40em"},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
@@ -21593,8 +21265,7 @@ File:Foobar.jpg
 Gallery with link that has fragment
 !! options
 parsoid={
-  "modes": ["wt2html", "html2html"],
-  "nativeGallery": true
+  "modes": ["wt2html", "html2html"]
 }
 !! wikitext
 <gallery>
@@ -21622,7 +21293,6 @@ image:foobar.jpg|link=Main Page#section|caption
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
@@ -21633,10 +21303,6 @@ image:foobar.jpg|link=Main Page#section|caption
 
 !! test
 Gallery with template inside caption
-!! options
-parsoid={
-  "nativeGallery": true
-}
 !! wikitext
 <gallery caption="{{echo|hi}}">
 File:Foobar.jpg|{{echo|ho}}
@@ -21652,7 +21318,6 @@ File:Foobar.jpg|{{echo|ho}}
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt6" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerycaption"><span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi"}},"i":0}}]}'>hi</span></li>
@@ -21662,8 +21327,12 @@ File:Foobar.jpg|{{echo|ho}}
 
 !! test
 Gallery with wikitext inside gallery caption
+!! options
+parsoid={
+  "modes": ["wt2html", "html2html"]
+}
 !! wikitext
-<gallery caption="# List item
+<gallery caption="# This should not be a list item
 
 Text '''bold''' [[link]] {{ns:-1}}
 
@@ -21672,7 +21341,7 @@ File:Foobar.jpg|Image caption
 </gallery>
 !! html/php
 <ul class="gallery mw-gallery-traditional">
-       <li class='gallerycaption'># List item Text <b>bold</b> <a href="/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> Special <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>File in gallery caption</div></div></div></li>
+       <li class='gallerycaption'># This should not be a list item Text <b>bold</b> <a href="/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> Special <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>File in gallery caption</div></div></div></li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
                        <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
                        <div class="gallerytext">
@@ -21681,15 +21350,15 @@ File:Foobar.jpg|Image caption
                        </div>
                </div></li>
 </ul>
-
+!! html/parsoid
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerycaption"># This should not be a list item Text <b>bold</b> <a rel="mw:WikiLink" href="./Link" title="Link">link</a> <span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"ns:-1","function":"ns"},"params":{},"i":0}}]}'>-1</span> <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>File in gallery caption</figcaption></figure></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">Image caption</div></li>
+</ul>
 !! end
 
 !! test
 Gallery with wikitext inside caption
-!! options
-parsoid={
-  "nativeGallery": true
-}
 !! wikitext
 <gallery>
 File:Foobar.jpg|alt=galleryalt|[[File:Foobar.jpg|alt=inneralt|20x20px|desc]]
@@ -21712,7 +21381,6 @@ File:Foobar.jpg|alt=galleryalt|{{Test|unamedParam|alt=param}}
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt6" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><figure-inline typeof="mw:Image" data-mw='{"caption":"desc"}'><a href="./File:Foobar.jpg"><img alt="inneralt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="2" width="20"/></a></figure-inline></div></li>
@@ -21722,10 +21390,6 @@ File:Foobar.jpg|alt=galleryalt|{{Test|unamedParam|alt=param}}
 
 !! test
 Gallery (with showfilename option)
-!! options
-parsoid={
-  "nativeGallery": true
-}
 !! wikitext
 <gallery showfilename="">
 File:Nonexistent.jpg|caption
@@ -21766,11 +21430,10 @@ some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a>
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"showfilename":""},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a>caption</div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a>caption</div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a></div></li>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Foobar.jpg" class="galleryfilename galleryfilename-truncate" title="File:Foobar.jpg">File:Foobar.jpg</a>some <b>caption</b> <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></div></li>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Foobar.jpg" class="galleryfilename galleryfilename-truncate" title="File:Foobar.jpg">File:Foobar.jpg</a></div></li>
 </ul>
@@ -21781,8 +21444,7 @@ some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a>
 Gallery (with namespace-less filenames)
 !! options
 parsoid={
-  "modes": ["wt2html", "html2html"],
-  "nativeGallery": true
+  "modes": ["wt2html", "html2html"]
 }
 !! wikitext
 <gallery>
@@ -21814,11 +21476,10 @@ foobar.jpg
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
@@ -21826,10 +21487,6 @@ foobar.jpg
 
 !! test
 Gallery override link with wikilink (T36852)
-!! options
-parsoid={
-  "nativeGallery": true
-}
 !! wikitext
 <gallery>
 File:Foobar.jpg|alt=galleryalt|link=Wikilink
@@ -21842,7 +21499,6 @@ File:Foobar.jpg|alt=galleryalt|link=Wikilink
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./Wikilink"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
@@ -21851,10 +21507,6 @@ File:Foobar.jpg|alt=galleryalt|link=Wikilink
 
 !! test
 Gallery override link with absolute external link (T36852)
-!! options
-parsoid={
-  "nativeGallery": true
-}
 !! wikitext
 <gallery>
 File:Foobar.jpg|alt=galleryalt|link=http://www.example.org
@@ -21867,17 +21519,19 @@ File:Foobar.jpg|alt=galleryalt|link=http://www.example.org
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="http://www.example.org"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
 
+## Putting the caption at the end here runs into T49646 on the php side
+## so reducing the modes this runs in Parsoid
 !! test
 Gallery override link with absolute external link with LanguageConverter
 !! options
 language=zh
+parsoid=wt2html,html2html
 !! wikitext
 <gallery>
 File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
@@ -21892,9 +21546,8 @@ File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="http://www.example.org"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
 </ul>
 !! end
@@ -21903,8 +21556,7 @@ File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
 Gallery override link with malicious javascript (T36852)
 !! options
 parsoid={
-  "modes": ["wt2html", "html2html"],
-  "nativeGallery": true
+  "modes": ["wt2html", "html2html"]
 }
 !! wikitext
 <gallery>
@@ -21918,20 +21570,17 @@ File:Foobar.jpg|alt=galleryalt|link=" onclick="alert('malicious javascript code!
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./%22_onclick=%22alert('malicious_javascript_code!');"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
 
-# Note that parsoid uses the invalid link as a caption, PHP does not.
 !! test
 Gallery with invalid title as link (T45964)
 !! options
 parsoid={
-  "modes": ["wt2html", "html2html"],
-  "nativeGallery": true
+  "modes": ["wt2html", "html2html"]
 }
 !! wikitext
 <gallery>
@@ -21945,10 +21594,9 @@ File:Foobar.jpg|link=<
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">link=&lt;</div></li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image" data-mw='{"attribs":[["link",{"txt":"&lt;"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
 
@@ -21956,8 +21604,7 @@ File:Foobar.jpg|link=<
 Serialize gallery without attrs in data-mw
 !! options
 parsoid={
-  "modes": ["html2wt"],
-  "nativeGallery": true
+  "modes": ["html2wt"]
 }
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","body":{}}'>
@@ -21972,10 +21619,6 @@ File:Test.png
 
 !! test
 Gallery with class and style attributes
-!! options
-parsoid={
-  "nativeGallery": true
-}
 !! wikitext
 <gallery class="center" style="text-align: center;">
 File:Foobar.jpg
@@ -21988,7 +21631,6 @@ File:Foobar.jpg
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional center" style="text-align: center;" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"class":"center","style":"text-align: center;"},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
@@ -21997,10 +21639,6 @@ File:Foobar.jpg
 
 !! test
 Gallery in slideshow mode
-!! options
-parsoid={
-  "nativeGallery": true
-}
 !! wikitext
 <gallery mode="slideshow" showthumbnails="">
 File:Foobar.jpg
@@ -22013,19 +21651,37 @@ File:Foobar.jpg
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
 <ul class="gallery mw-gallery-slideshow" data-showthumbnails="1" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"mode":"slideshow","showthumbnails":""},"body":{}}'>
 <li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
 </ul>
 !! end
 
+!! test
+Gallery in packed mode
+!! wikitext
+<gallery mode="packed">
+File:Foobar.jpg
+</gallery>
+!! html/php
+<ul class="gallery mw-gallery-packed">
+               <li class="gallerybox" style="width: 1061.3333333333px"><div style="width: 1061.3333333333px">
+                       <div class="thumb" style="width: 1059.3333333333px;"><div style="margin:0px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/1589px-Foobar.jpg" decoding="async" width="1060" height="120" srcset="http://example.com/images/3/3a/Foobar.jpg 1.5x" /></a></div></div>
+                       <div class="gallerytext">
+                       </div>
+               </div></li>
+</ul>
+!! html/parsoid
+<ul class="gallery mw-gallery-packed" typeof="mw:Extension/gallery" about="#mwt3" data-parsoid='{"dsr":[0,50,23,10]}' data-mw='{"name":"gallery","attrs":{"mode":"packed"},"body":{}}'>
+<li class="gallerybox" style="width: 1061px;"><div class="thumb" style="width: 1059px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1589px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="120" width="1059"/></a></figure-inline></div><div class="gallerytext"></div></li>
+</ul>
+!! end
+
 !! test
 Serialize gallery image captions on a line
 !! options
 parsoid={
-  "modes": ["html2wt"],
-  "nativeGallery": true
+  "modes": ["html2wt"]
 }
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
@@ -22233,9 +21889,8 @@ Centre-aligned image
 [[Image:foobar.jpg|centre]]
 !! html/php
 <div class="center"><div class="floatnone"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div></div>
-
 !! html/parsoid
-<figure class="mw-default-size mw-halign-center" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"center","ak":"centre"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure>
+<figure class="mw-default-size mw-halign-center" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"center","ak":"centre"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a><figcaption></figcaption></figure>
 !! end
 
 !! test
@@ -22244,9 +21899,8 @@ None-aligned image
 [[Image:foobar.jpg|none]]
 !! html/php
 <div class="floatnone"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
-
 !! html/parsoid
-<figure class="mw-default-size mw-halign-none" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure>
+<figure class="mw-default-size mw-halign-none" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a><figcaption></figcaption></figure>
 !! end
 
 !! test
@@ -22293,6 +21947,7 @@ Width-sized image (using px, with preceding whitespace - test regression from r3
 <p><figure-inline typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":" 640px"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="73" width="640" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"73","width":"640"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure-inline></p>
 !! end
 
+## FIXME: Parsoid mocking should include the page in the url to catch regressions
 !! test
 Image with page parameter
 !! options
@@ -22303,7 +21958,7 @@ djvu
 <p><a href="/index.php?title=File:LoremIpsum.djvu&amp;page=2" class="image"><img alt="LoremIpsum.djvu" src="http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-2480px-LoremIpsum.djvu.jpg" decoding="async" width="2480" height="3508" srcset="http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-3720px-LoremIpsum.djvu.jpg 1.5x, http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-4960px-LoremIpsum.djvu.jpg 2x" /></a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"page","ak":"page=2"}]}' data-mw='{"page":"2"}'><a href="./File:LoremIpsum.djvu" data-parsoid='{"a":{"href":"./File:LoremIpsum.djvu"},"sa":{"href":"File:LoremIpsum.djvu"}}'><img resource="./File:LoremIpsum.djvu" src="//example.com/images/5/5f/LoremIpsum.djvu" data-file-width="2480" data-file-height="3508" data-file-type="bitmap" height="3508" width="2480" data-parsoid='{"a":{"resource":"./File:LoremIpsum.djvu","height":"3508","width":"2480"},"sa":{"resource":"File:LoremIpsum.djvu"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"attribs":[["page",{"txt":"2"}]]}'><a href="./File:LoremIpsum.djvu" data-parsoid='{"a":{"href":"./File:LoremIpsum.djvu"},"sa":{"href":"File:LoremIpsum.djvu"}}'><img resource="./File:LoremIpsum.djvu" src="//example.com/images/5/5f/LoremIpsum.djvu" data-file-width="2480" data-file-height="3508" data-file-type="bitmap" height="3508" width="2480" data-parsoid='{"a":{"resource":"./File:LoremIpsum.djvu","height":"3508","width":"2480"},"sa":{"resource":"File:LoremIpsum.djvu"}}'/></a></figure-inline></p>
 !! end
 
 !! test
@@ -22322,11 +21977,9 @@ dt/dd/dl test
 :;;;::
 !! html/php
 <dl><dd><dl><dt><dl><dt><dl><dt><dl><dd><dl><dd></dt></dl></dd></dl></dd></dl></dd></dl></dd></dl></dd></dl>
-
 !! html/parsoid
 <dl><dd><dl><dt><dl><dt><dl><dt><dl><dd><dl><dd></dd></dl></dd></dl></dt></dl></dt></dl></dt></dl></dd></dl>
-
-!!end
+!! end
 
 # Images with the "|" character in external URLs in comment tags; Eats half the comment, leaves unmatched "</a>" tag.
 !! test
@@ -22335,7 +21988,6 @@ Images with the "|" character in the comment
 [[File:Foobar.jpg|thumb|An [http://test/?param1=|left|&param2=|x external] URL]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>An <a rel="nofollow" class="external text" href="http://test/?param1=%7Cleft%7C&amp;param2=%7Cx">external</a> URL</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>An <a rel="mw:ExtLink" class="external text" href="http://test/?param1=%7Cleft%7C&amp;param2=%7Cx" data-parsoid='{"a":{"href":"http://test/?param1=%7Cleft%7C&amp;param2=%7Cx"},"sa":{"href":"http://test/?param1=|left|&amp;param2=|x"}}'>external</a> URL</figcaption></figure>
 !! end
@@ -22481,7 +22133,6 @@ Definition list code coverage
 <dd>def</dd>
 <dt>title</dt>
 <dd>def</dd></dl>
-
 !! html/parsoid
 <dl><dt>title   </dt><dd>def</dd>
 <dt>title </dt><dd>def</dd>
@@ -22494,7 +22145,6 @@ Don't fall for the self-closing div
 <div>hello world</div/>
 !! html
 <div>hello world</div>
-
 !! end
 
 !! test
@@ -22549,7 +22199,6 @@ Inclusion of !userCanEdit() content
 {{MediaWiki:Fake}}
 !! html
 <h2><span class="mw-headline" id="header">header</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=MediaWiki:Fake&amp;action=edit&amp;section=T-1" title="MediaWiki:Fake">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 
@@ -22586,7 +22235,6 @@ Out-of-order TOC heading levels
 <h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
 <h5><span class="mw-headline" id="5">5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: 5">edit</a><span class="mw-editsection-bracket">]</span></span></h5>
 <h2><span class="mw-headline" id="2_2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 
@@ -23043,7 +22691,6 @@ conversion:
 цонверсион:
 </p>
 <h2><span class="mw-headline" id="Latinski">Латински</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Уредите одељак „Латински”">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <h2 id="-{Naslov}-"><span id="-.7BNaslov.7D-" typeof="mw:FallbackId"></span><span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"Naslov"}}'></span></h2>
 
@@ -23617,8 +23264,7 @@ language=zh variant=zh-cn
 !! html/php+tidy
 <span>ab<div>cd
 <span>ab<div>cd
-<span>ad
-</span></div></span></div></span>
+<span>ad</span></div></span></div></span>
 !! html/parsoid
 <span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<div typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"b&lt;div data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[10,16,5,0]}&apos;>c&lt;/div>"}}'></div>d
 
@@ -23824,7 +23470,6 @@ language=sr
 [[Датотека:Foobar.jpg|thumb|-{R|caption:}-]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="internal" title="Повећајте"></a></div>caption:</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"}]}'><a href="./Датотека:Foobar.jpg"><img resource="./Датотека:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"caption:"}}' data-parsoid='{"fl":["R"]}'></span></figcaption></figure>
 !! end
@@ -23837,7 +23482,6 @@ language=zh variant=zh-cn
 [[File:Foobar.jpg|thumb|-{|zh-cn:blog (hk: -{zh-hans|WEBJOURNAL}-, tw: -{zh-hans|WEBLOG}-)}-]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="放大"></a></div>blog (hk: WEBJOURNAL, tw: WEBLOG)</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><span typeof="mw:LanguageVariant" data-mw-variant='{"twoway":[{"l":"zh-cn","t":"blog (hk: &lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&#39;{\"filter\":{\"l\":[\"zh-hans\"],\"t\":\"WEBJOURNAL\"}}&#39; data-parsoid=&#39;{\"fl\":[\"zh-hans\"],\"dsr\":[43,65,null,2]}&#39;>&lt;/span>, tw: &lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&#39;{\"filter\":{\"l\":[\"zh-hans\"],\"t\":\"WEBLOG\"}}&#39; data-parsoid=&#39;{\"fl\":[\"zh-hans\"],\"dsr\":[71,89,null,2]}&#39;>&lt;/span>)"}]}'></span></figcaption></figure>
 !! end
@@ -23847,10 +23491,11 @@ language=zh variant=zh-cn
 Don't break gallery if language converter markup is inside.
 !! options
 language=zh
+parsoid=wt2html,html2html
 !! wikitext
 <gallery>
-File:foobar.jpg|[[File:foobar.jpg|20px|desc|alt=-{R|foo}-|-{R|bar}-]]|alt=-{R|bat}-
-File:foobar.jpg|{{Test|unamedParam|alt=-{R|param}-}}|alt=galleryalt
+File:Foobar.jpg|alt=-{R|bat}-|[[File:foobar.jpg|20px|desc|alt=-{R|foo}-|-{R|bar}-]]
+File:Foobar.jpg|alt=galleryalt|{{Test|unamedParam|alt=-{R|param}-}}
 </gallery>
 !! html/php
 <ul class="gallery mw-gallery-traditional">
@@ -23869,11 +23514,10 @@ File:foobar.jpg|{{Test|unamedParam|alt=-{R|param}-}}|alt=galleryalt
                        </div>
                </div></li>
 </ul>
-
 !! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt6" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:foobar.jpg|[[File:foobar.jpg|20px|desc|alt=-{R|foo}-|-{R|bar}-]]|alt=-{R|bat}-\nFile:foobar.jpg|{{Test|unamedParam|alt=-{R|param}-}}|alt=galleryalt\n"}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><figure-inline typeof="mw:Image" data-mw='{"caption":"&lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&#39;{\"disabled\":{\"t\":\"bar\"}}&#39; data-parsoid=&#39;{\"fl\":[\"R\"],\"dsr\":[68,77,null,2]}&#39;>&lt;/span>"}'><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="2" width="20"/></a></figure-inline></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><span about="#mwt4" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Test","href":"./Template:Test"},"params":{"1":{"wt":"unamedParam"},"alt":{"wt":"-{R|param}-"}},"i":0}}]}'>This is a test template</span></div></li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt6" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&apos;{\"disabled\":{\"t\":\"bat\"}}&apos; data-parsoid=&apos;{\"fl\":[\"R\"],\"dsr\":[84,93,null,2]}&apos;>&lt;/span>","txt":""}]]}'><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><figure-inline typeof="mw:Image mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["alt",{"html":"alt=&lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&apos;{\"disabled\":{\"t\":\"foo\"}}&apos; data-parsoid=&apos;{\"fl\":[\"R\"],\"dsr\":[58,67,null,2]}&apos;>&lt;/span>","txt":""}]],"caption":"&lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&apos;{\"disabled\":{\"t\":\"bar\"}}&apos; data-parsoid=&apos;{\"fl\":[\"R\"],\"dsr\":[68,77,null,2]}&apos;>&lt;/span>"}'><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="2" width="20"/></a></figure-inline></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Test","href":"./Template:Test"},"params":{"1":{"wt":"unamedParam"},"alt":{"wt":"-{R|param}-"}},"i":0}}]}'>This is a test template</span></div></li>
 </ul>
 !! end
 
@@ -23887,7 +23531,6 @@ language=zh variant=zh-cn
 !! html/php
 <dl><dt>AAA</dt>
 <dt>foo:bar</dt></dl>
-
 !! html/parsoid
 <dl><dt data-parsoid='{"dsr":[0,24,1,0]}'><span typeof="mw:LanguageVariant" data-parsoid='{"tSp":[6]}' data-mw-variant='{"twoway":[{"l":"zh-cn","t":"AAA"},{"l":"zh-tw","t":"BBB"}]}'></span></dt>
 <dt data-parsoid='{"dsr":[25,39,1,0]}'><span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"foo:bar"}}'></span></dt>
@@ -23905,8 +23548,7 @@ language=zh variant=zh-cn
 ;-{zh-cn:AAA
 !! html/php+tidy
 <dl><dt><b>foo:bar</b></dt><b>
-<dt>-{zh-cn:AAA</dt></b></dl><p><b>
-</b></p>
+<dt>-{zh-cn:AAA</dt></b></dl>
 !! html/parsoid
 <dl><dt data-parsoid='{}'><b data-parsoid='{"stx":"html","autoInsertedEnd":true}'>foo:bar</b></dt><b data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
 <dt data-parsoid='{}'>-{zh-cn</dt><dd data-parsoid='{"stx":"row"}'>AAA</dd></b></dl>
@@ -23921,7 +23563,6 @@ language=zh variant=zh-cn
 !! html/php
 <dl><dt>AAA foo:bar bat:baz</dt>
 <dd>def</dd></dl>
-
 !! html/parsoid
 <dl><dt data-parsoid='{"dsr":[0,49,1,0]}'><span typeof="mw:LanguageVariant" data-mw-variant='{"twoway":[{"l":"zh-cn","t":"AAA &lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&#39;{\"filter\":{\"l\":[\"zh-hans\"],\"t\":\"foo:bar\"}}&#39; data-parsoid=&#39;{\"fl\":[\"zh-hans\"],\"dsr\":[14,33,null,2]}&#39;>&lt;/span> &lt;span typeof=\"mw:LanguageVariant\" data-mw-variant=&#39;{\"disabled\":{\"t\":\"bat:baz\"}}&#39; data-parsoid=&#39;{\"fl\":[\"R\"],\"dsr\":[34,47,null,2]}&#39;>&lt;/span>"}]}'></span></dt>
 <dd data-parsoid='{"stx":"row","dsr":[49,53,1,0]}'>def</dd>
@@ -23945,7 +23586,6 @@ parsoid=wt2html,wt2wt,html2html
 <tr>
 <td>B
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tbody>
@@ -24078,7 +23718,6 @@ T2529: Uncovered bullet
 !! html
 <ul><li>Foo</li>
 <li>Bar</li></ul>
-
 !! end
 
 !! test
@@ -24088,7 +23727,6 @@ T2529: Uncovered bullet in a deeply nested list
 !! html
 <ul><li><ul><li><ul><li><ul><li><ul><li><ul><li><ul><li>Foo</li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li>
 <li>Bar</li></ul>
-
 !! end
 
 !! test
@@ -24121,7 +23759,6 @@ T2529: Uncovered bullet in parser function result
 !! html
 <ul><li>Foo</li>
 <li>bar</li></ul>
-
 !! end
 
 !! test
@@ -24177,7 +23814,6 @@ Morwen/13: Unclosed link followed by heading
 <p>[[link
 </p>
 <h2><span class="mw-headline" id="heading">heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -24189,7 +23825,6 @@ HHP2.1: Heuristics for headings in preprocessor parenthetical structures
 <p>{{foo|
 </p>
 <h1><span class="mw-headline" id="heading">heading</span></h1>
-
 !! end
 
 !! test
@@ -24201,7 +23836,6 @@ HHP2.2: Heuristics for headings in preprocessor parenthetical structures
 <p>{{foo|
 </p>
 <h2><span class="mw-headline" id="heading">heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -24223,7 +23857,6 @@ Line two</div>
 !! html
 <div>Line one
 Line two</div>
-
 !! end
 
 !! test
@@ -24238,7 +23871,6 @@ Line two</div>
 <p>Line one
 </p>
 Line two</div>
-
 !! end
 
 !! test
@@ -24253,7 +23885,6 @@ Line two
 <p>Line two
 </p>
 </div>
-
 !! end
 
 !! test
@@ -24270,7 +23901,6 @@ Line two
 </p><p>Line two
 </p>
 </div>
-
 !! end
 
 # doBlockLevels screws up this output and Remex cleans up as much as it can.
@@ -24298,7 +23928,6 @@ Line two</blockquote>
 !! html
 <blockquote>Line one
 Line two</blockquote>
-
 !! html+tidy
 <blockquote><p>Line one
 Line two</p></blockquote>
@@ -24316,7 +23945,6 @@ Line two</blockquote>
 <p>Line one
 </p>
 Line two</blockquote>
-
 !! html+tidy
 <blockquote>
 <p>Line one
@@ -24336,7 +23964,6 @@ Line two
 <p>Line two
 </p>
 </blockquote>
-
 !! html+tidy
 <blockquote><p>Line one
 </p><p>Line two
@@ -24358,7 +23985,6 @@ Line two
 </p><p>Line two
 </p>
 </blockquote>
-
 !! end
 
 ## This is a corner case interaction between the paragraph wrapping in the
@@ -24376,7 +24002,6 @@ Line two</div></blockquote>
 !! html
 <blockquote><div>Line one
 Line two</div></blockquote>
-
 !! end
 
 !! test
@@ -24391,7 +24016,6 @@ Line two</div></blockquote>
 <p>Line one
 </p>
 Line two</div></blockquote>
-
 !! end
 
 !! test
@@ -24406,7 +24030,6 @@ Line two
 <p>Line two
 </p>
 </div></blockquote>
-
 !! end
 
 !! test
@@ -24423,7 +24046,6 @@ Line two
 </p><p>Line two
 </p>
 </div></blockquote>
-
 !! end
 
 !! test
@@ -24447,7 +24069,6 @@ Free external link invading image caption
 [[Image:Foobar.jpg|thumb|http://x|hello]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>hello</div></div></div>
-
 !! html/parsoid
 <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"bogus","ak":"http://x"},{"ck":"caption","ak":"hello"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a><figcaption>hello</figcaption></figure>
 !! end
@@ -24525,6 +24146,49 @@ language=nl title=[[MediaWiki:Common.css]]
 </p>
 !! end
 
+!! test
+formatdate with invalid month
+!! wikitext
+{{#formatdate:2019-22-22|dmy}}
+!! html
+<p>2019-22-22
+</p>
+!! end
+
+!! test
+formatdate: dots in month name do not match any char (T220563)
+!! options
+language=de
+!! wikitext
+{{#formatdate:jun. 3|dmy}}
+{{#formatdate:junx 3|dmy}}
+!! html
+<p><span class="mw-formatted-date" title="06-03">3 Juni</span>
+junx 3
+</p>
+!! end
+
+!! test
+formatdate uses correct capitalisation in French
+!! options
+language=fr
+!! wikitext
+{{#formatdate:Juin 3|dmy}}
+!! html
+<p><span class="mw-formatted-date" title="06-03">3 juin</span>
+</p>
+!! end
+
+!! test
+formatdate uses correct capitalisation in English
+!! wikitext
+{{#formatdate:june 3|dmy}}
+!! html
+<p><span class="mw-formatted-date" title="06-03">3 June</span>
+</p>
+!! end
+
+
 #
 #
 #
@@ -24690,7 +24354,6 @@ Id starting with underscore
 <div id="_ref"></div>
 !! html/*
 <div id="_ref"></div>
-
 !! end
 
 !! test
@@ -24746,7 +24409,7 @@ Bad images - basic functionality
 [[File:Bad.jpg]]
 !! html/php+disabled
 !! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"bad-image","message":"This image is blacklisted in this context."}]}'><a href="./File:Bad.jpg"><img resource="./File:Bad.jpg" height="220" width="220"/></a></span></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Bad.jpg"><span resource="./File:Bad.jpg">File:Bad.jpg</span></a></figure-inline></p>
 !! end
 
 !! test
@@ -24761,7 +24424,7 @@ Bar foo
 </p>
 !! html/parsoid
 <p>Foo bar
-<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"bad-image","message":"This image is blacklisted in this context."}]}'><a href="./File:Bad.jpg"><img resource="./File:Bad.jpg" height="220" width="220"/></a></span>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Bad.jpg"><span resource="./File:Bad.jpg">File:Bad.jpg</span></a></figure-inline>
 Bar foo</p>
 !! end
 
@@ -24951,7 +24614,6 @@ paragraphs</indicator>
 04=<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/25px-Foobar.jpg" decoding="async" width="25" height="3" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/38px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg 2x" /></a>
 05=<ul><li>foo</li>
 <li>bar</li></ul>
-
 06=foo
 07=<pre>Preformatted
 </pre>
@@ -24961,7 +24623,6 @@ paragraphs</indicator>
 <tr>
 <td>cell
 </td></tr></table>
-
 10=<p>Two
 </p><p>paragraphs
 </p>
@@ -25025,13 +24686,11 @@ Play a bit with r67090 and T5158
 <div style="width:50% !important">&#160;</div>
 <div style="width:50% !important">&#160;</div>
 <div style="border&#32;: solid;">&#160;</div>
-
 !! html/parsoid
 <div style="width:50% !important" data-parsoid='{"stx":"html"}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
 <div style="width:50% !important" data-parsoid='{"stx":"html","a":{"style":"width:50% !important"},"sa":{"style":"width:50%&amp;nbsp;!important"}}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
 <div style="width:50% !important" data-parsoid='{"stx":"html","a":{"style":"width:50% !important"},"sa":{"style":"width:50%&amp;#160;!important"}}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
 <div style="border : solid;" data-parsoid='{"stx":"html"}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
-
 !! end
 
 !! test
@@ -25075,7 +24734,6 @@ HTML5 data attributes
 <p><span data-foo="bar">Baz</span>
 </p>
 <p data-abc-def_hij="">Quuz</p>
-
 !! html/parsoid
 <p><span data-foo="bar" data-parsoid='{"stx":"html"}'>Baz</span></p>
 <p data-abc-def_hij="" data-parsoid='{"stx":"html"}'>Quuz</p>
@@ -25084,12 +24742,11 @@ HTML5 data attributes
 !! test
 Strip reserved data attributes
 !! wikitext
-<div data-mw="foo" data-parsoid="bar" data-mw-someext="baz" data-ok="fred" data-ooui="xyzzy" data-bad:ns="ns">d</div>
+<div data-mw="foo" data-parsoid="bar" data-mw-someext="baz" data-ok="fred" data-object-id="123" data-ooui="xyzzy" data-bad:ns="ns">d</div>
 !! html/php
-<div data-ok="fred">d</div>
-
+<div data-ok="fred" data-object-id="123">d</div>
 !! html/parsoid
-<div data-x-data-mw="foo" data-x-data-parsoid="bar" data-x-data-mw-someext="baz" data-ok="fred" data-parsoid='{"stx":"html","a":{"data-ooui":null,"data-bad:ns":null},"sa":{"data-ooui":"xyzzy","data-bad:ns":"ns"}}'>d</div>
+<div data-x-data-mw="foo" data-x-data-parsoid="bar" data-x-data-mw-someext="baz" data-ok="fred" data-x-data-object-id="123" data-parsoid='{"stx":"html","a":{"data-ooui":null,"data-bad:ns":null},"sa":{"data-ooui":"xyzzy","data-bad:ns":"ns"}}'>d</div>
 !! end
 
 !! test
@@ -25108,7 +24765,7 @@ percent-encoding and + signs in internal links (T28410)
 !! html/parsoid
 <p><a rel="mw:WikiLink" href="./User:+%25" title="User:+%" data-parsoid='{"stx":"simple","a":{"href":"./User:+%25"},"sa":{"href":"User:+%"}}'>User:+%</a> <a rel="mw:WikiLink" href="./Page+title%25" title="Page+title%" data-parsoid='{"stx":"simple","a":{"href":"./Page+title%25"},"sa":{"href":"Page+title%"}}'>Page+title%</a>
 <a rel="mw:WikiLink" href="./%25+" title="%+" data-parsoid='{"stx":"simple","a":{"href":"./%25+"},"sa":{"href":"%+"}}'>%+</a> <a rel="mw:WikiLink" href="./%25+" title="%+" data-parsoid='{"stx":"piped","a":{"href":"./%25+"},"sa":{"href":"%+"}}'>%20</a> <a rel="mw:WikiLink" href="./%25+" title="%+" data-parsoid='{"stx":"simple","a":{"href":"./%25+"},"sa":{"href":"%+ "}}'>%+ </a> <a rel="mw:WikiLink" href="./%25+r" title="%+r" data-parsoid='{"stx":"simple","a":{"href":"./%25+r"},"sa":{"href":"%+r"}}'>%+r</a>
-<a rel="mw:WikiLink" href="./%25" title="%" data-parsoid='{"stx":"simple","a":{"href":"./%25"},"sa":{"href":"%"}}'>%</a> <a rel="mw:WikiLink" href="./+" title="+" data-parsoid='{"stx":"simple","a":{"href":"./+"},"sa":{"href":"+"}}'>+</a> <figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"foo"},{"ck":"caption","ak":"[[bar]]"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"&lt;a rel=\"mw:WikiLink\" href=\"./Bar\" title=\"Bar\" data-parsoid=&#39;{\"stx\":\"simple\",\"a\":{\"href\":\"./Bar\"},\"sa\":{\"href\":\"bar\"},\"dsr\":[94,101,2,2]}&#39;>bar&lt;/a>"}'><a href="./File:%25+abc9" data-parsoid='{"a":{"href":"./File:%25+abc9"},"sa":{}}'><img resource="./File:%25+abc9" src="./Special:FilePath/%25+abc9" height="220" width="220" data-parsoid='{"a":{"resource":"./File:%25+abc9","height":"220","width":"220"},"sa":{"resource":"File:%+abc%39"}}'/></a></figure-inline>
+<a rel="mw:WikiLink" href="./%25" title="%" data-parsoid='{"stx":"simple","a":{"href":"./%25"},"sa":{"href":"%"}}'>%</a> <a rel="mw:WikiLink" href="./+" title="+" data-parsoid='{"stx":"simple","a":{"href":"./+"},"sa":{"href":"+"}}'>+</a> <figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"foo"},{"ck":"caption","ak":"[[bar]]"}]}' data-mw='{"caption":"&lt;a rel=\"mw:WikiLink\" href=\"./Bar\" title=\"Bar\" data-parsoid=&apos;{\"stx\":\"simple\",\"a\":{\"href\":\"./Bar\"},\"sa\":{\"href\":\"bar\"},\"dsr\":[94,101,2,2]}&apos;>bar&lt;/a>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/%25+abc9"><span resource="./File:%25+abc9" data-parsoid='{"a":{"resource":"./File:%25+abc9"},"sa":{"resource":"File:%+abc%39"}}'>File:%+abc9</span></a></figure-inline>
 <a rel="mw:WikiLink" href="./3E" title="3E" data-parsoid='{"stx":"simple","a":{"href":"./3E"},"sa":{"href":"%33%45"}}'>3E</a> <a rel="mw:WikiLink" href="./3E+" title="3E+" data-parsoid='{"stx":"simple","a":{"href":"./3E+"},"sa":{"href":"%33%45+"}}'>3E+</a></p>
 !! end
 
@@ -25122,8 +24779,8 @@ Special characters in embedded file links (T29679)
 <a href="/index.php?title=Special:Upload&amp;wpDestFile=Does_not_exist.jpg" class="new" title="File:Does not exist.jpg">Title with &amp; ampersand</a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Contains_&amp;_ampersand.jpg"><img resource="./File:Contains_&amp;_ampersand.jpg" src="./Special:FilePath/Contains_&amp;_ampersand.jpg" height="220" width="220"/></a></figure-inline>
-<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"Title with &amp;amp; ampersand"}'><a href="./File:Does_not_exist.jpg"><img resource="./File:Does_not_exist.jpg" src="./Special:FilePath/Does_not_exist.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Contains_&amp;_ampersand.jpg"><span resource="./File:Contains_&amp;_ampersand.jpg" data-parsoid='{"a":{"resource":"./File:Contains_&amp;_ampersand.jpg"},"sa":{"resource":"File:Contains &amp; ampersand.jpg"}}'>File:Contains &amp; ampersand.jpg</span></a></figure-inline>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"caption":"Title with &amp;amp; ampersand","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Does_not_exist.jpg"><span resource="./File:Does_not_exist.jpg" data-parsoid='{"a":{"resource":"./File:Does_not_exist.jpg"},"sa":{"resource":"File:Does not exist.jpg"}}'>File:Does not exist.jpg</span></a></figure-inline></p>
 !! end
 
 !! test
@@ -25267,7 +24924,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="Lost_episodes"><i>Lost</i> episodes</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Lost episodes">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="Lost_episodes" data-parsoid='{}'><i>Lost</i> episodes</h2>
@@ -25288,7 +24944,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="should_be_bold_then_normal_text"><b>should be bold</b> then normal text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: should be bold then normal text">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="should_be_bold_then_normal_text" data-parsoid='{}'><b>should be bold</b> then normal text</h2>
@@ -25309,7 +24964,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="Image">Image <a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Image">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="Image" data-parsoid='{}'>Image <figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure-inline></h2>
@@ -25330,7 +24984,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="Quote"><blockquote>Quote</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/php+tidy
 <div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
 <ul>
@@ -25390,7 +25043,6 @@ __TOC__
 
 <h2><span class="mw-headline" id="Foo_Bar"><i>Foo</i> <b>Bar</b></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i> <blockquote>Bar</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/php+tidy
 <div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
 <ul>
@@ -25429,7 +25081,6 @@ __TOC__
 
 <h2><span class="mw-headline" id="Hello"><sup class="in-h2">Hello</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Hello">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="b.22.3EEvilbye"><sup class="a"> b"&gt;Evilbye</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: b&quot;&gt;Evilbye">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" />
 <h2 id="Hello"><sup class="in-h2" data-parsoid='{"stx":"html"}'>Hello</sup></h2>
@@ -25466,7 +25117,6 @@ __TOC__
 <h2><span class="mw-headline" id="The_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: The attributes on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: All attributes on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"><span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: Attributes after dir on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="C++" data-parsoid='{}'><span id="C.2B.2B" typeof="mw:FallbackId"></span><span dir="ltr">C++</span></h2>
@@ -25489,7 +25139,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="test"><bdi>test</bdi></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: test">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="test" data-parsoid='{}'><bdi>test</bdi></h2>
@@ -25508,7 +25157,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="test_test_test"><s>test</s> test <strike>test</strike></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: test test test">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="test_test_test" data-parsoid='{}'><s>test</s> test <strike>test</strike></h2>
@@ -25529,7 +25177,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="Style"><style>.foo {}</style>Style<style>.bar {}</style></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Style">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid="{}"/>
 <h2 id="Style" data-parsoid="{}"><style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo {}"}}'>.foo {}</style>Style<style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".bar {}"}}'>.bar {}</style></h2>
@@ -25550,7 +25197,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="Script"><script>alert(1);</script>Script<script>alert(1);</script></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Script">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="Script" data-parsoid='{}'><script typeof="mw:Extension/html" about="#mwt4" data-mw='{"name":"html","attrs":{},"body":{"extsrc":"&lt;script>alert(1);&lt;/script>"}}'>alert(1);</script>Script<script typeof="mw:Extension/html" about="#mwt6" data-mw='{"name":"html","attrs":{},"body":{"extsrc":"&lt;script>alert(1);&lt;/script>"}}'>alert(1);</script></h2>
@@ -25569,7 +25215,6 @@ __TOC__
 </div>
 
 <h2><span class="mw-headline" id="x">x</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: x">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="x" data-parsoid='{}'>x</h2>
@@ -25589,7 +25234,6 @@ title=[[Main Page]]
 {{int:T34057}}
 !! html
 <h2><span class="mw-headline" id="Headline_text">Headline text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Headline text">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -25708,7 +25352,6 @@ nowiki inside link inside heading (T20295)
 ==[[foo|x<nowiki>y</nowiki>z]]==
 !! html
 <h2><span class="mw-headline" id="xyz"><a href="/wiki/Foo" title="Foo">xyz</a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: xyz">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 !! test
@@ -25717,8 +25360,7 @@ new support for bdi element (T33817)
 <p dir="rtl" lang="he">ולדימיר לנין (ברוסית: <bdi lang="ru">Владимир Ленин</bdi>, 24 באפריל 1870–22 בינואר 1924) הוא מנהיג פוליטי קומוניסטי רוסי.</p>
 !! html
 <p dir="rtl" lang="he">ולדימיר לנין (ברוסית: <bdi lang="ru">Владимир Ленин</bdi>, 24 באפריל 1870–22 בינואר 1924) הוא מנהיג פוליטי קומוניסטי רוסי.</p>
-
-!!end
+!! end
 
 !! test
 Ignore pipe between table row attributes
@@ -25736,7 +25378,6 @@ Ignore pipe between table row attributes
 <tr id="foo" style="color: red">
 <td>bar
 </td></tr></table>
-
 !! end
 
 !!test
@@ -25865,7 +25506,6 @@ Lead
 <h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Section_4">Section 4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Section 4">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Section_5">Section 5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: Section 5">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! end
 
 
@@ -25950,7 +25590,7 @@ parsoid=wt2html,wt2wt
 !! html/parsoid
 <p><b>foo</b></p><b><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure></b><p><b>bar</b></p>
 
-<small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small>
+<small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a><figcaption></figcaption></figure></small>
 !! end
 
 !! test
@@ -25960,8 +25600,7 @@ parsoid=wt2html,wt2wt
 !! wikitext
 <small>'''foo[[File:Foobar.jpg|thumb|caption]]bar'''</small>
 !! html/php+tidy
-<p><small><b>foo</b></small></p><small><b><div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div></b></small><p><small><b>bar</b></small>
-</p>
+<p><small><b>foo</b></small></p><small><b><div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div></b></small><p><small><b>bar</b></small></p>
 !! html/parsoid
 <p><small><b>foo</b></small></p><small><b><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure></b></small><p><small><b>bar</b></small></p>
 !! end
@@ -25975,7 +25614,7 @@ parsoid=wt2html,wt2wt
 !! html/php+tidy
 <b><small><div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" decoding="async" width="300" height="34" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/450px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/600px-Foobar.jpg 2x" /></a></div></small></b>
 !! html/parsoid
-<b><small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small></b>
+<b><small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a><figcaption></figcaption></figure></small></b>
 !! end
 
 #### ----------------------------------------------------------------
@@ -26131,12 +25770,12 @@ parsoid=html2wt
 <h2>=foo=</h2>
 <h3>=foo=</h3>
 
-<h1 data-parsoid=''>=foo=</h1>
-<h2 data-parsoid=''>=foo=</h2>
-<h3 data-parsoid=''>=foo=</h3>
-<h4 data-parsoid=''>=foo=</h4>
-<h5 data-parsoid=''>=foo=</h5>
-<h6 data-parsoid=''>=foo=</h6>
+<h1 data-parsoid='{}'>=foo=</h1>
+<h2 data-parsoid='{}'>=foo=</h2>
+<h3 data-parsoid='{}'>=foo=</h3>
+<h4 data-parsoid='{}'>=foo=</h4>
+<h5 data-parsoid='{}'>=foo=</h5>
+<h6 data-parsoid='{}'>=foo=</h6>
 !! wikitext
 = =foo= =
 
@@ -26150,8 +25789,7 @@ parsoid=html2wt
 ====<nowiki>=foo=</nowiki>====
 =====<nowiki>=foo=</nowiki>=====
 ======<nowiki>=foo=</nowiki>======
-
-!!end
+!! end
 
 !! test
 Headings: 2. Outside heading nest on a single line <h1>foo</h1>*bar
@@ -26262,7 +25900,6 @@ parsoid=wt2html,html2html
 <h1><span class="mw-headline" id=".3D">=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: =">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
 <h1><span class="mw-headline" id=".3D.3D">==</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: ==">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
 <h2><span class="mw-headline" id=".3D_2">=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: =">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
-
 !! html/parsoid
 <p>=
 ==</p>
@@ -26394,7 +26031,6 @@ new
 
 ==A==
 a
-
 !! end
 
 !! test
@@ -26407,7 +26043,6 @@ parsoid=wt2html
 ===============
 !! html/php
 <h6><span id=".3D.3D.3D"></span><span class="mw-headline" id="===">===</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: ===">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
-
 !! html/parsoid
 <h6 id="==="><span id=".3D.3D.3D" typeof="mw:FallbackId"></span>===</h6>
 !! end
@@ -26751,7 +26386,6 @@ parsoid=html2wt
 </td>
 <td>a<i><div>b||c</div></i>
 </td></tr></table>
-
 !! end
 
 !! test
@@ -26763,7 +26397,6 @@ parsoid=html2wt
 <tr>
 <td>foo!!bar
 </td></tr></table>
-
 !! wikitext
 {|
 |foo!!bar
@@ -26779,7 +26412,6 @@ parsoid=html2wt
 <tr>
 <th>foo!bar
 </th></tr></table>
-
 !! wikitext
 {|
 !foo!bar
@@ -26815,7 +26447,6 @@ parsoid=html2wt
 </th>
 <th><i><span>foo!!bar</span></i>
 </th></tr></table>
-
 !! end
 
 !! test
@@ -26839,7 +26470,6 @@ parsoid=html2wt
 </th>
 <th>foo||bar
 </th></tr></table>
-
 !! end
 
 !! test
@@ -26854,7 +26484,6 @@ parsoid=html2wt
 <tr>
 <td>-bar
 </td></tr></table>
-
 !! wikitext
 {|
 !-bar
@@ -26875,7 +26504,6 @@ parsoid=html2wt
 <tr>
 <td>+bar
 </td></tr></table>
-
 !! wikitext
 {|
 !+bar
@@ -26938,7 +26566,6 @@ bar|baz
 <td>x
 <div>a|b</div>
 </td></tr></table>
-
 !! end
 
 !! test
@@ -26966,7 +26593,6 @@ parsoid=html2wt
 </td>
 <td>-2
 </td></tr></table>
-
 !! end
 
 !! test
@@ -26993,7 +26619,6 @@ parsoid=html2wt
 <td>x</td>
 <td>}
 </td></tr></table>
-
 !! end
 
 !! test
@@ -27088,7 +26713,6 @@ parsoid=html2wt
 </td>
 <td>bar&gt;
 </td></tr></table>
-
 !! end
 
 #### --------------- Links ----------------
@@ -27137,7 +26761,7 @@ parsoid=html2wt
 [[Foo|x <nowiki>[http://google.com g]</nowiki> x]]
 [[Foo|<nowiki>[[Bar]]</nowiki>]]
 [[Foo|<nowiki>x [[Bar]] x</nowiki>]]
-[[Foo|<nowiki>|Bar</nowiki>]]
+[[Foo||Bar]]
 [[Foo|<nowiki>]]bar</nowiki>]]
 [[Foo|<nowiki>[[bar</nowiki>]]
 [[Foo|<nowiki>x [[ y</nowiki>]]
@@ -27973,8 +27597,7 @@ parsoid=wt2html,html2html
 !! wikitext
 <div title="Hello world />Foo
 !! html/php+tidy
-<div title="Hello world"></div><p>Foo
-</p>
+<div title="Hello world"></div><p>Foo</p>
 !! html/parsoid
 <div title="Hello world " data-parsoid='{"stx":"html","selfClose":true}'></div><p>Foo</p>
 !! end
@@ -27992,13 +27615,11 @@ parsoid=wt2html,html2html
 <tr>
 <td title="Hello world">Foo
 </td></tr></table>
-
 !! html/parsoid
 <table>
 <tr>
 <td title="Hello world">Foo
 </td></tr></table>
-
 !! end
 
 !! test
@@ -28017,14 +27638,12 @@ parsoid=wt2html,html2html
 </td>
 <td style="color:red">Bar
 </td></tr></table>
-
 !! html/parsoid
 <table><tbody>
 <tr>
 <td title="Hello world">Foo
 </td><td style="color: red">Bar
 </td></tr></tbody></table>
-
 !! end
 
 !!test
@@ -28039,8 +27658,7 @@ Accept empty td cell attribute
 <td align="center">foo</td>
 <td>
 </td></tr></table>
-
-!!end
+!! end
 
 !!test
 Non-empty attributes in th-cells
@@ -28054,8 +27672,7 @@ Non-empty attributes in th-cells
 <th>Foo</th>
 <th style="color: red">Bar
 </th></tr></table>
-
-!!end
+!! end
 
 !!test
 Accept empty attributes in th-cells
@@ -28069,8 +27686,7 @@ Accept empty attributes in th-cells
 <th>foo</th>
 <th>bar
 </th></tr></table>
-
-!!end
+!! end
 
 !!test
 Empty table rows go away
@@ -28090,7 +27706,6 @@ Empty table rows go away
 </td></tr>
 
 </table>
-
 !! end
 
 ###
@@ -28109,7 +27724,6 @@ RT-ed inter-element separators should be valid separators
 <table>
 
 </table>
-
 !! html/parsoid
 <table>
 <tbody><tr class='mw-empty-elt' data-parsoid='{"startTagSrc":"|-","a":{"[[foo]]":null},"sa":{"[[foo]]":""},"autoInsertedEnd":true}'></tr>
@@ -28157,8 +27771,7 @@ Empty TD followed by TD with tpl-generated attribute
 </td>
 <td>foo
 </td></tr></table>
-
-!!end
+!! end
 
 !!test
 Indented table with an empty td
@@ -28176,8 +27789,7 @@ Indented table with an empty td
 </td>
 <td>foo
 </td></tr></table>
-
-!!end
+!! end
 
 !! test
 Indented table with blank lines in between (T85627)
@@ -28194,7 +27806,6 @@ Indented table with blank lines in between (T85627)
 <p><br /> 
 </p>
 </td></tr></table>
-
 !! html/parsoid
  <table>
  <tbody><tr><td>foo
@@ -28216,7 +27827,6 @@ Indented block & table
 <tr>
 <td>foo
 </td></tr></table>
-
 !! html/parsoid
  <div data-parsoid='{"stx":"html"}'>foo</div>
  <table><tbody>
@@ -28237,7 +27847,6 @@ Indent and comment before table row
 <tr>
 <td>there
 </td></tr></table>
-
 !! html/parsoid
 <table>
  <!--hi--><tbody><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'>
@@ -28291,8 +27900,7 @@ Empty TR followed by mixed-ws-comment line should RT correctly
 <tr>
 <!--c--> </tr><!--d-->
 </tbody></table>
-
-!!end
+!! end
 
 !!test
 Multi-line image caption generated by templates with/without trailing newlines
@@ -28557,8 +28165,7 @@ parsoid=wt2wt,wt2html
 !! wikitext
 <table>{{echo|hi</table>hello}}
 !! html/php+tidy
-hi<table></table><p>hello
-</p>
+hi<table></table><p>hello</p>
 !! html/parsoid
 <p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE_html","pi":[[{"k":"1"}]]}' data-mw='{"parts":["&lt;table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;/table>hello"}},"i":0}}]}'>hi</p><table about="#mwt2"></table><p about="#mwt2">hello</p>
 !! end
@@ -28584,6 +28191,7 @@ parsoid=wt2html
 !! end
 
 # Parsoid only for T66747
+# (Also core doesn't define {{#if}} in default install)
 !! test
 Properly encapsulate empty-content transclusions in fosterable positions
 !! wikitext
@@ -28610,7 +28218,6 @@ hello
 {{OpenTable}}
 |}
 !! html/parsoid
-
 !! end
 
 !! test
@@ -28922,6 +28529,7 @@ parsoid={
 !! test
 Image: Modifying alt attribute of an image (T58400)
 !! options
+disabled
 parsoid={
   "modes": ["wt2wt"],
   "changes": [
@@ -28979,7 +28587,7 @@ Image: Block level image should have \n before and after
 456
 !! html/parsoid
 <p>123</p>
-<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150"/></a></figure>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150"/></a><figcaption></figcaption></figure>
 <p>456</p>
 !! end
 
@@ -28991,7 +28599,7 @@ Image: New block level image should have \n before and after (existing content)
 456
 !! html/parsoid
 <p>123</p>
-<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"right","ak":"right"},{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"150x150px"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"17","width":"150"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"right","ak":"right"},{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"150x150px"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"17","width":"150"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption></figcaption></figure>
 <p>456</p>
 !! end
 
@@ -29073,7 +28681,7 @@ Image: Invalid title as link
 <p><a href="/wiki/File:Foobar.jpg" class="image" title="link=&lt;"><img alt="link=&lt;" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=&lt;"}]}' data-mw='{"caption":"link=&amp;lt;"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=&lt;"}]}' data-mw='{"attribs":[["link",{"txt":"&lt;"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 !! end
 
 !! test
@@ -29090,11 +28698,11 @@ Various link types in alt and link options
 </p><p><a href="http://en.wikipedia.org/wiki/Foo" title="caption"><img alt="wikipedia:Foo" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
 </p>
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=[[Main Page]]"}}'><img alt="Main Page" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Main Page","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Main Page]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-mw='{"attribs":[["alt",{"html":"alt=&lt;a rel=\"mw:WikiLink\" href=\"./Main_Page\" title=\"Main Page\" data-parsoid=&apos;{\"stx\":\"simple\",\"a\":{\"href\":\"./Main_Page\"},\"sa\":{\"href\":\"Main Page\"},\"dsr\":[41,216,2,2]}&apos;>Main Page&lt;/a>","txt":"Main Page"}]],"caption":"caption"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=[[Main Page]]"}}'><img alt="Main Page" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Media:Thumb.png" data-parsoid='{"a":{"href":"./Media:Thumb.png"},"sa":{"href":"link=[[Media:Thumb.png]]"}}'><img alt="Media:Thumb.png" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Media:Thumb.png","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Media:Thumb.png]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["alt",{"html":"alt=&lt;a rel=\"mw:MediaLink\" href=\"//example.com/images/e/ea/Thumb.png\" resource=\"./Media:Thumb.png\" title=\"Thumb.png\" data-parsoid=&apos;{\"a\":{\"resource\":\"./Media:Thumb.png\"},\"sa\":{\"resource\":\"Media:Thumb.png\"},\"dsr\":[113,216,null,null]}&apos;>Media:Thumb.png&lt;/a>","txt":"Media:Thumb.png"}]],"caption":"caption"}'><a href="./Media:Thumb.png" data-parsoid='{"a":{"href":"./Media:Thumb.png"},"sa":{"href":"link=[[Media:Thumb.png]]"}}'><img alt="Media:Thumb.png" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"link=[[wikipedia:Foo]]"}}'><img alt="wikipedia:Foo" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"wikipedia:Foo","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[wikipedia:Foo]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt2" data-mw='{"attribs":[["alt",{"html":"alt=&lt;a rel=\"mw:WikiLink/Interwiki\" href=\"http://en.wikipedia.org/wiki/Foo\" title=\"wikipedia:Foo\" data-parsoid=&apos;{\"stx\":\"simple\",\"a\":{\"href\":\"http://en.wikipedia.org/wiki/Foo\"},\"sa\":{\"href\":\"wikipedia:Foo\"},\"isIW\":true,\"dsr\":[189,216,2,2]}&apos;>wikipedia:Foo&lt;/a>","txt":"wikipedia:Foo"}]],"caption":"caption"}'><a href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"link=[[wikipedia:Foo]]"}}'><img alt="wikipedia:Foo" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 !! end
 
 !! test
@@ -30424,6 +30032,28 @@ parsoid= {
 |}
 !! end
 
+## Don't necessarily expect this to roundtrip, but run serialization to catch crashers
+!! test
+File in link scenarios
+!! options
+parsoid={
+  "modes": ["wt2html","html2wt"],
+  "suppressErrors": true
+}
+!! wikitext
+[http://www.google.com [[File:Foobar.jpg|123]]]
+
+[http://www.google.com [[File:Foobar.jpg|thumb|123]]]
+!! html/php+tidy
+<p><a rel="nofollow" class="external text" href="http://www.google.com"></a><a href="/wiki/File:Foobar.jpg" class="image" title="123"><img alt="123" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
+</p>
+<a rel="nofollow" class="external text" href="http://www.google.com"></a><div class="thumb tright"><a rel="nofollow" class="external text" href="http://www.google.com"></a><div class="thumbinner" style="width:182px;"><a rel="nofollow" class="external text" href="http://www.google.com"></a><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>123</div></div></div>
+!! html/parsoid
+<p><a rel="mw:ExtLink" class="external text" href="http://www.google.com" data-parsoid='{"targetOff":23,"contentOffsets":[23,46]}'><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"123"}]}' data-mw='{"caption":"123"}'></figure-inline></a><a href="./File:Foobar.jpg" data-parsoid='{"misnested":true}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"},"misnested":true}'/></a></p>
+
+<a rel="mw:ExtLink" class="external autonumber" href="http://www.google.com" data-parsoid='{"targetOff":72,"contentOffsets":[72,101]}'></a><figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"123"}]}'><a rel="mw:ExtLink" class="external autonumber" href="http://www.google.com" data-parsoid='{"targetOff":72,"contentOffsets":[72,101]}'></a><a href="./File:Foobar.jpg" data-parsoid='{"misnested":true}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"},"misnested":true}'/></a><figcaption data-parsoid='{"misnested":true}'>123</figcaption></figure>
+!! end
+
 # --------------------------------------------
 # Tests spec'ing wikitext serialization norms |
 # --------------------------------------------
@@ -30754,7 +30384,6 @@ parsoid={
 
 [[foo]]
 x
-
 !! end
 
 !! test
@@ -31565,7 +31194,7 @@ Thumbnail output
 !! html/php+tidy
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Thumb.png" class="image"><img alt="Thumb.png" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Thumb.png" class="internal" title="Enlarge"></a></div></div></div></div>
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Thumb.png"><img resource="./File:Thumb.png" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Thumb.png"><img resource="./File:Thumb.png" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption></figcaption></figure>
 !! end
 
 !! test
@@ -31758,7 +31387,6 @@ Decoding of HTML entities in embedded HTML tags
 <table class="1&2&amp;3&amp;amp;4&amp;amp;amp;5"><tr><td>x</td></tr></table>
 !! html/php
 <table class="1&amp;2&amp;3&amp;amp;4&amp;amp;amp;5"><tr><td>x</td></tr></table>
-
 !! html/parsoid
 <table class="1&amp;2&amp;3&amp;amp;4&amp;amp;amp;5" data-parsoid='{"stx":"html","a":{"class":"1&amp;2&amp;3&amp;amp;4&amp;amp;amp;5"},"sa":{"class":"1&amp;2&amp;amp;3&amp;amp;amp;4&amp;amp;amp;amp;5"}}'><tbody><tr data-parsoid='{"stx":"html"}'><td data-parsoid='{"stx":"html"}'>x</td></tr></tbody></table>
 !! end
@@ -32014,6 +31642,21 @@ parsoid={
 [[stats:v2/#/fr.wikipedia.org/reading/page-views-by-country/normal%7Cmap%7C2-Year~2016060100~2018071100%7C~total|10]]
 !! end
 
+## FIXME: "gerrit" isn't in PHP's setupInterwikis
+!! test
+T199926: Hash only interwiki link
+!! wikitext
+[[meatball:Test#1/2]]
+[[gerrit:#/q/project:mediawiki/services/parsoid|Gerrit]]
+!! html/php+tidy
+<p><a href="http://www.usemod.com/cgi-bin/mb.pl?Test#1.2F2" class="extiw" title="meatball:Test">meatball:Test#1/2</a>
+<a href="/index.php?title=Gerrit:&amp;action=edit&amp;redlink=1" class="new" title="Gerrit: (page does not exist)">Gerrit</a>
+</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink/Interwiki" href="http://www.usemod.com/cgi-bin/mb.pl?Test#1.2F2" title="meatball:Test" data-parsoid='{"stx":"simple","a":{"href":"http://www.usemod.com/cgi-bin/mb.pl?Test#1.2F2"},"sa":{"href":"meatball:Test#1/2"},"isIW":true}'>meatball:Test#1/2</a>
+<a rel="mw:WikiLink/Interwiki" href="https://gerrit.wikimedia.org/#/q/project:mediawiki/services/parsoid">Gerrit</a></p>
+!! end
+
 !! test
 T179544: {{anchorencode:}} output should be always usable in links
 !! config
@@ -32033,6 +31676,7 @@ wgFragmentMode=[ 'html5' ]
 !! test
 Section wrapping for well-nested sections (no leading content)
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
 
 =3=
 f
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>b
+</p>
+<h2><span class="mw-headline" id="2.1">2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
+<h2><span class="mw-headline" id="2.2">2.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 2.2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>d
+</p>
+<h3><span class="mw-headline" id="2.2.1">2.2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: 2.2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
+<p>e
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>f
+</p>
 !! html/parsoid
-<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
 <p>a</p>
 
-</section><section data-mw-section-id="2"><h1 id="2">2</h1>
+</section><section data-mw-section-id="2"><h1 id="2" data-parsoid="{}">2</h1>
 <p>b</p>
 
-<section data-mw-section-id="3"><h2 id="2.1">2.1</h2>
+<section data-mw-section-id="3"><h2 id="2.1" data-parsoid="{}">2.1</h2>
 <p>c</p>
 
-</section><section data-mw-section-id="4"><h2 id="2.2">2.2</h2>
+</section><section data-mw-section-id="4"><h2 id="2.2" data-parsoid="{}">2.2</h2>
 <p>d</p>
 
-<section data-mw-section-id="5"><h3 id="2.2.1">2.2.1</h3>
+<section data-mw-section-id="5"><h3 id="2.2.1" data-parsoid="{}">2.2.1</h3>
 <p>e</p>
 
-</section></section></section><section data-mw-section-id="6"><h1 id="3">3</h1>
+</section></section></section><section data-mw-section-id="6"><h1 id="3" data-parsoid="{}">3</h1>
 <p>f</p>
 
 </section>
 !! test
 Section wrapping for well-nested sections (with leading content)
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
 
 ==2.1==
 c
+!! html/php+tidy
+<p>Para 1.
+</p><p>
+Para 2 with a </p><div>nested in it</div>
+<p>Para 3.
+</p>
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>b
+</p>
+<h2><span class="mw-headline" id="2.1">2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
 !! html/parsoid
 <section data-mw-section-id="0"><p>Para 1.</p>
 
 
 <p>Para 3.</p>
 
-</section><section data-mw-section-id="1"><h1 id="1">1</h1>
+</section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
 <p>a</p>
 
-</section><section data-mw-section-id="2"><h1 id="2">2</h1>
+</section><section data-mw-section-id="2"><h1 id="2" data-parsoid="{}">2</h1>
 <p>b</p>
 
-<section data-mw-section-id="3"><h2 id="2.1">2.1</h2>
+<section data-mw-section-id="3"><h2 id="2.1" data-parsoid="{}">2.1</h2>
 <p>c</p>
 
 </section></section>
 !! test
 Section wrapping with template-generated sections (good nesting 1)
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
 ==1.1==
 b
 }}
-
 ==1.2==
 c
 
 =2=
 d
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span></h2>
+<p>b
+</p>
+<h2><span class="mw-headline" id="1.2">1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>d
+</p>
 !! html/parsoid
-<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
 <p>a</p>
 
 <section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,33,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.1==\nb"}},"i":0}}]}'>1.1</h2><span about="#mwt1">
 </span><p about="#mwt1">b</p>
-</section><section data-mw-section-id="3"><h2 id="1.2">1.2</h2>
+</section><section data-mw-section-id="3"><h2 id="1.2" data-parsoid="{}">1.2</h2>
 <p>c</p>
 
-</section></section><section data-mw-section-id="4"><h1 id="2">2</h1>
+</section></section><section data-mw-section-id="4"><h1 id="2" data-parsoid="{}">2</h1>
 <p>d</p></section>
 !! end
 
 !! test
 Section wrapping with template-generated sections (good nesting 2)
 !! options
+notoc
 parsoid={
   "wrapSections": true,
   "modes": ["wt2html", "wt2wt"]
 }}
 =2=
 e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span></h2>
+<p>b
+</p>
+<h3><span class="mw-headline" id="1.1.1">1.1.1</span></h3>
+<p>d
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
 !! html/parsoid
 <section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
 <p>a</p>
 !! test
 Section wrapping with template-generated sections (good nesting 3)
 !! options
+notoc
 parsoid={
   "wrapSections": true,
   "modes": ["wt2html", "wt2wt"]
 }}
 =2=
 e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p><p>x
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span></h2>
+<p>b
+</p>
+<h2><span class="mw-headline" id="1.2">1.2</span></h2>
+<p>c
+</p>
+<h3><span class="mw-headline" id="1.2.1">1.2.1</span></h3>
+<p>d
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
 !! html/parsoid
 <section data-mw-section-id="0"></section><section data-mw-section-id="1" data-parsoid="{}"><h1 id="1"> 1 </h1>
 <p>a</p>
 !! test
 Section wrapping with template-generated sections (bad nesting 1)
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
@@ -32235,24 +31964,31 @@ parsoid={
 <div>
 a
 
-{{echo|
+{{echo|1=
 =1=
 b
 }}
 
 c
 </div>
+!! html/php+tidy
+<div>
+<p>a
+</p>
+<h1><span class="mw-headline" id="1">1</span></h1>
+<p>b
+</p><p>c
+</p>
+</div>
 !! html/parsoid
 <section data-mw-section-id="-1"></section><section data-mw-section-id="-2"><div data-parsoid='{"stx":"html"}'>
 <p>a</p>
 
-<span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"\n=1=\nb\n"}},"i":0}},"\n\nc\n"]}'>
-</span><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1" id="1">1</h1><span about="#mwt1">
-</span><p about="#mwt1">b
-</p><span about="#mwt1">
+<section data-mw-section-id="-1"><h1 about="#mwt1" typeof="mw:Transclusion" id="1" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"=1=\nb"}},"i":0}}]}'>1</h1><span about="#mwt1">
+</span><p about="#mwt1">b</p>
 
-</span><p about="#mwt1">c</p><span about="#mwt1">
-</span></section></div></section>
+<p>c</p>
+</section></div></section>
 !! end
 
 # Because of section-wrapping and template-wrapping interactions,
 !! test
 Section wrapping with template-generated sections (bad nesting 2)
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
 
 =3=
 e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span></h1>
+<p>b
+</p>
+<h2><span class="mw-headline" id="2.1">2.1</span></h2>
+<p>c
+</p><p>d
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
 !! html/parsoid
-<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
 <p>a</p>
 
 </section><section data-mw-section-id="-1"><h1 about="#mwt1" typeof="mw:Transclusion" id="2" data-parsoid='{"dsr":[9,45,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"=2=\nb\n==2.1==\nc"}},"i":0}},"\n\nd\n\n"]}'>2</h1><span about="#mwt1">
 
 </span><p about="#mwt1">d</p><span about="#mwt1">
 
-</span></section></section><section data-mw-section-id="4"><h1 id="3">3</h1>
+</span></section></section><section data-mw-section-id="4"><h1 id="3" data-parsoid="{}">3</h1>
 <p>e</p></section>
 !! end
 
 !! test
 Section wrapping with template-generated sections (bad nesting 3)
 !! options
+notoc
 parsoid={
   "wrapSections": true,
   "modes": ["wt2html", "wt2wt"]
 
 =3=
 e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.2">1.2</span></h2>
+<p>b
+</p>
+<h1><span class="mw-headline" id="2">2</span></h1>
+<p>c
+</p><p>d
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
 !! html/parsoid
 <section data-mw-section-id="0"></section><section data-mw-section-id="1" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["=1=\na\n\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.2==\nb\n=2=\nc"}},"i":0}},"\n\nd\n\n"]}'><h1 id="1">1</h1>
 <p>a</p>
 !! test
 Section wrapping with uneditable lead section + div wrapping multiple sections
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
 
 ==3.1==
 e
+!! html/php+tidy
+<p>foo
+</p>
+<div style="border:1px solid red;">
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>b
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>c
+</p>
+</div>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>d
+</p>
+<h2><span class="mw-headline" id="3.1">3.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: 3.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>e
+</p>
 !! html/parsoid
 <section data-mw-section-id="-1"><p>foo</p>
 
 </section><section data-mw-section-id="-2"><div style="border:1px solid red;">
-<section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
 <p>a</p>
 
-<section data-mw-section-id="2"><h2 id="1.1">1.1</h2>
+<section data-mw-section-id="2"><h2 id="1.1" data-parsoid="{}">1.1</h2>
 <p>b</p>
 
-</section></section><section data-mw-section-id="-1"><h1 id="2">2</h1>
+</section></section><section data-mw-section-id="-1"><h1 id="2" data-parsoid="{}">2</h1>
 <p>c</p>
 </section></div>
 
-</section><section data-mw-section-id="4"><h1 id="3">3</h1>
+</section><section data-mw-section-id="4"><h1 id="3" data-parsoid="{}">3</h1>
 <p>d</p>
 
-<section data-mw-section-id="5"><h2 id="3.1">3.1</h2>
+<section data-mw-section-id="5"><h2 id="3.1" data-parsoid="{}">3.1</h2>
 <p>e</p>
 </section></section>
 !! end
 !! test
 Section wrapping with editable lead section + div overlapping multiple sections
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
 
 ==3.1==
 g
+!! html/php+tidy
+<p>foo
+</p>
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<div style="border:1px solid red;">
+<p>b
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>d
+</p>
+</div>
+<p>e
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>f
+</p>
+<h2><span class="mw-headline" id="3.1">3.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: 3.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>g
+</p>
 !! html/parsoid
 <section data-mw-section-id="0"><p>foo</p>
 
-</section><section data-mw-section-id="-1"><h1 id="1">1</h1>
+</section><section data-mw-section-id="-1"><h1 id="1" data-parsoid="{}">1</h1>
 <p>a</p>
 </section><section data-mw-section-id="-2"><div style="border:1px solid red;">
 <p>b</p>
 
-<section data-mw-section-id="2"><h2 id="1.1">1.1</h2>
+<section data-mw-section-id="2"><h2 id="1.1" data-parsoid="{}">1.1</h2>
 <p>c</p>
 
-</section><section data-mw-section-id="-1"><h1 id="2">2</h1>
+</section><section data-mw-section-id="-1"><h1 id="2" data-parsoid="{}">2</h1>
 <p>d</p>
 </section></div>
 <p>e</p>
 
-</section><section data-mw-section-id="4"><h1 id="3">3</h1>
+</section><section data-mw-section-id="4"><h1 id="3" data-parsoid="{}">3</h1>
 <p>f</p>
 
-<section data-mw-section-id="5"><h2 id="3.1">3.1</h2>
+<section data-mw-section-id="5"><h2 id="3.1" data-parsoid="{}">3.1</h2>
 <p>g</p>
 </section></section>
 !! end
 !! test
 HTML header tags should not be wrapped in section tags
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
@@ -32451,21 +32268,30 @@ foo
 <h1>c</h1>
 
 =d=
+!! html/php+tidy
+<p>foo
+</p>
+
+<h1><span class="mw-headline" id="a">a</span></h1>
+<h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<h1><span class="mw-headline" id="c">c</span></h1>
+<h1><span class="mw-headline" id="d">d</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: d">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
 !! html/parsoid
 <section data-mw-section-id="0"><p>foo</p>
 
 <h1 id="a" data-parsoid='{"stx":"html"}'>a</h1>
 
-</section><section data-mw-section-id="1"><h1 id="b">b</h1>
+</section><section data-mw-section-id="1"><h1 id="b" data-parsoid="{}">b</h1>
 
 <h1 id="c" data-parsoid='{"stx":"html"}'>c</h1>
 
-</section><section data-mw-section-id="2"><h1 id="d">d</h1></section>
+</section><section data-mw-section-id="2"><h1 id="d" data-parsoid="{}">d</h1></section>
 !! end
 
 !! test
 Lead section containing only whitespace and comments.
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
 
 =2=
 b
+!! html/php+tidy
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>b
+</p>
 !! html/parsoid
 <section data-mw-section-id="0" data-parsoid="{}">
 <!-- this is a comment, presumably significant to editors -->
-</section><section data-mw-section-id="1"><h1 id="1">1</h1>
+</section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
 <p>a</p>
 
-</section><section data-mw-section-id="2"><h1 id="2">2</h1>
-<p>b</p></section>
+</section><section data-mw-section-id="2"><h1 id="2" data-parsoid="{}">2</h1>
+<p>b</p>
+</section>
 !! end
 
 !! test
-Pseudo-sections emitted by templates should have id -2 
+Pseudo-sections emitted by templates should have id -2
 !! options
+notoc
 parsoid={
   "wrapSections": true
 }
@@ -32500,6 +32335,13 @@ foo
 ==b==
 </div>
 }}
+!! html/php+tidy
+<p>foo
+</p>
+<div>
+<h2><span class="mw-headline" id="a">a</span></h2>
+<h2><span class="mw-headline" id="b">b</span></h2>
+</div>
 !! html/parsoid
 <section data-mw-section-id="-1"><p>foo</p>
 </section><section data-mw-section-id="-2"><div about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;div>\n==a==\n==b==\n&lt;/div>\n"}},"i":0}}]}'>
@@ -32509,6 +32351,118 @@ foo
 </span></section>
 !! end
 
+!! test
+T213468: Transcluded sections don't get PHP section numbers
+!! options
+notoc
+parsoid={
+  "wrapSections": true
+}
+!! wikitext
+==PHP section=1==
+{{echo|1=
+== This is counted as if it were section 2 ==
+}}
+==PHP section=3==
+!! html/php+tidy
+<h2><span class="mw-headline" id="PHP_section.3D1">PHP section=1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: PHP section=1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_2">This is counted as if it were section 2</span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D3">PHP section=3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: PHP section=3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! html/parsoid
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h2 id="PHP_section=1" data-parsoid="{}"><span id="PHP_section.3D1" typeof="mw:FallbackId"></span>PHP section=1</h2>
+</section><section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="This_is_counted_as_if_it_were_section_2" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== This is counted as if it were section 2 =="}},"i":0}}]}'>This is counted as if it were section 2</h2>
+</section><section data-mw-section-id="3"><h2 id="PHP_section=3" data-parsoid="{}"><span id="PHP_section.3D3" typeof="mw:FallbackId"></span>PHP section=3</h2></section>
+!! end
+
+!! test
+T213468: Corner cases in edit section ID assignment in tokenizer
+!! options
+notoc
+parsoid={
+  "wrapSections": true
+}
+!! wikitext
+==PHP section=1==
+{{echo|Not a section|
+== This is counted as if it were section 2 ==
+}}
+==PHP section=3==
+{{echo3|1=
+== This is counted as if it were section 4 ==
+}}
+==PHP section=5==
+{{#tag:p|Not a section|data-ignored=
+== This is counted as if it were section 6 ==
+}}
+==PHP section=7==
+{{echo|1=Not a ==heading==}}
+==PHP section=8==
+[[File:Foobar.jpg|thumb|
+==This is section 9, even though it's in a caption==
+]]
+==PHP section=10==
+!! html/php+tidy
+
+<h2><span class="mw-headline" id="PHP_section.3D1">PHP section=1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: PHP section=1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>Not a section
+</p>
+<h2><span class="mw-headline" id="PHP_section.3D3">PHP section=3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: PHP section=3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_4">This is counted as if it were section 4</span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_4_2">This is counted as if it were section 4</span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_4_3">This is counted as if it were section 4</span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D5">PHP section=5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: PHP section=5">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p data-ignored="== This is counted as if it were section 6 ==">Not a section</p>
+<h2><span class="mw-headline" id="PHP_section.3D7">PHP section=7</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=7" title="Edit section: PHP section=7">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>Not a ==heading==
+</p>
+<h2><span class="mw-headline" id="PHP_section.3D8">PHP section=8</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=8" title="Edit section: PHP section=8">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><h2><span class="mw-headline" id="This_is_section_9.2C_even_though_it.27s_in_a_caption">This is section 9, even though it's in a caption</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=9" title="Edit section: This is section 9, even though it&#039;s in a caption">edit</a><span class="mw-editsection-bracket">]</span></span></h2></div></div></div>
+<h2><span class="mw-headline" id="PHP_section.3D10">PHP section=10</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=10" title="Edit section: PHP section=10">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! html/parsoid
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h2 id="PHP_section=1" data-parsoid="{}"><span id="PHP_section.3D1" typeof="mw:FallbackId"></span>PHP section=1</h2>
+<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"},{"k":"2"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Not a section"},"2":{"wt":"\n== This is counted as if it were section 2 ==\n"}},"i":0}}]}'>Not a section</p>
+</section><section data-mw-section-id="3"><h2 id="PHP_section=3" data-parsoid="{}"><span id="PHP_section.3D3" typeof="mw:FallbackId"></span>PHP section=3</h2>
+</section><section data-mw-section-id="-1" about="#mwt5" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":["",{"template":{"target":{"wt":"echo3","href":"./Template:Echo3"},"params":{"1":{"wt":"== This is counted as if it were section 4 =="}},"i":0}},"\n"]}'><h2 about="#mwt2" typeof="mw:Transclusion" id="This_is_counted_as_if_it_were_section_4" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo3","href":"./Template:Echo3"},"params":{"1":{"wt":"== This is counted as if it were section 4 =="}},"i":0}}]}'>This is counted as if it were section 4</h2><span about="#mwt2">
+</span></section><section data-mw-section-id="-1" about="#mwt5"><h2 about="#mwt2" id="This_is_counted_as_if_it_were_section_4_2">This is counted as if it were section 4</h2><span about="#mwt2">
+</span></section><section data-mw-section-id="-1" about="#mwt5"><h2 about="#mwt2" id="This_is_counted_as_if_it_were_section_4_3">This is counted as if it were section 4</h2>
+</section><section data-mw-section-id="5"><h2 id="PHP_section=5" data-parsoid="{}"><span id="PHP_section.3D5" typeof="mw:FallbackId"></span>PHP section=5</h2>
+<p data-ignored=" This is counted as if it were section 6 " about="#mwt3" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"},{"k":"data-ignored","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"#tag:p","function":"tag"},"params":{"1":{"wt":"Not a section"},"data-ignored":{"wt":"== This is counted as if it were section 6 =="}},"i":0}}]}'>Not a section</p>
+</section><section data-mw-section-id="7"><h2 id="PHP_section=7" data-parsoid="{}"><span id="PHP_section.3D7" typeof="mw:FallbackId"></span>PHP section=7</h2>
+<p about="#mwt4" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","named":true}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Not a ==heading=="}},"i":0}}]}'>Not a ==heading==</p>
+</section><section data-mw-section-id="8"><h2 id="PHP_section=8" data-parsoid="{}"><span id="PHP_section.3D8" typeof="mw:FallbackId"></span>PHP section=8</h2>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"\n== This is counted as if it were section 9 ==\n"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>
+<section data-mw-section-id="-1"><h2 id="This_is_section_9,_even_though_it's_in_a_caption" data-parsoid="{}"><span id="This_is_section_9.2C_even_though_it.27s_in_a_caption" typeof="mw:FallbackId"></span>This is section 9, even though it's in a caption</h2>
+</section></figcaption></figure>
+</section><section data-mw-section-id="10"><h2 id="PHP_section=10" data-parsoid="{}"><span id="PHP_section.3D10" typeof="mw:FallbackId" data-parsoid='{"dsr":[412,412]}'></span>PHP section=10</h2></section>
+!! end
+
+!! test
+T215628: Section numbering and <includeonly> and <noinclude> on a page
+!! options
+notoc
+parsoid={
+  "wrapSections": true
+}
+!! wikitext
+==PHP section=1==
+<noinclude>
+==PHP section=2==
+</noinclude>
+==PHP section=3==
+<includeonly>
+==This is not counted as section 4==
+</includeonly>
+==PHP section=4==
+!! html/php+tidy
+
+<h2><span class="mw-headline" id="PHP_section.3D1">PHP section=1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: PHP section=1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D2">PHP section=2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: PHP section=2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D3">PHP section=3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: PHP section=3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D4">PHP section=4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: PHP section=4">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! html/parsoid
+PARSOID HAS A BUG HERE: T215628
+!! end
+
 ##########################################################################
 Tests demonstrating white-space insensitivity in input wikitext
 for wikitext headings, wikitext list items, and wikitext table captions,
diff --git a/tests/phan/config.php b/tests/phan/config.php
deleted file mode 100644 (file)
index fa351ea..0000000
+++ /dev/null
@@ -1,468 +0,0 @@
-<?php
-
-// If xdebug is enabled, we need to increase the nesting level for phan
-ini_set( 'xdebug.max_nesting_level', 1000 );
-
-/**
- * This configuration will be read and overlayed on top of the
- * default configuration. Command line arguments will be applied
- * after this file is read.
- *
- * @see src/Phan/Config.php
- * See Config for all configurable options.
- *
- * A Note About Paths
- * ==================
- *
- * Files referenced from this file should be defined as
- *
- * ```
- *   Config::projectPath('relative_path/to/file')
- * ```
- *
- * where the relative path is relative to the root of the
- * project which is defined as either the working directory
- * of the phan executable or a path passed in via the CLI
- * '-d' flag.
- */
-return [
-       /**
-        * A list of individual files to include in analysis
-        * with a path relative to the root directory of the
-        * project. directory_list won't find .inc files so
-        * we augment it here.
-        */
-       'file_list' => array_merge(
-               function_exists( 'register_postsend_function' ) ? [] : [ 'tests/phan/stubs/hhvm.php' ],
-               function_exists( 'wikidiff2_do_diff' ) ? [] : [ 'tests/phan/stubs/wikidiff.php' ],
-               function_exists( 'tideways_enable' ) ? [] : [ 'tests/phan/stubs/tideways.php' ],
-               class_exists( PEAR::class ) ? [] : [ 'tests/phan/stubs/mail.php' ],
-               class_exists( Memcached::class ) ? [] : [ 'tests/phan/stubs/memcached.php' ],
-               // Per composer.json, PHPUnit 6 is used for PHP 7.0+, PHPUnit 4 otherwise.
-               // Load the interface for the version of PHPUnit that isn't installed.
-               // Phan only supports PHP 7.0+ (and not HHVM), so we only need to stub PHPUnit 4.
-               class_exists( PHPUnit_TextUI_Command::class ) ? [] : [ 'tests/phan/stubs/phpunit4.php' ],
-               class_exists( ProfilerExcimer::class ) ? [] : [ 'tests/phan/stubs/excimer.php' ],
-               [
-                       'maintenance/7zip.inc',
-                       'maintenance/cleanupTable.inc',
-                       'maintenance/CodeCleanerGlobalsPass.inc',
-                       'maintenance/commandLine.inc',
-                       'maintenance/sqlite.inc',
-                       'maintenance/userDupes.inc',
-                       'maintenance/language/checkLanguage.inc',
-                       'maintenance/language/languages.inc',
-               ]
-       ),
-
-       /**
-        * A list of directories that should be parsed for class and
-        * method information. After excluding the directories
-        * defined in exclude_analysis_directory_list, the remaining
-        * files will be statically analyzed for errors.
-        *
-        * Thus, both first-party and third-party code being used by
-        * your application should be included in this list.
-        */
-       'directory_list' => [
-               'includes/',
-               'languages/',
-               'maintenance/',
-               'mw-config/',
-               'resources/',
-               'vendor/',
-       ],
-
-       /**
-        * A file list that defines files that will be excluded
-        * from parsing and analysis and will not be read at all.
-        *
-        * This is useful for excluding hopelessly unanalyzable
-        * files that can't be removed for whatever reason.
-        */
-       'exclude_file_list' => [],
-
-       /**
-        * A list of directories holding code that we want
-        * to parse, but not analyze. Also works for individual
-        * files.
-        */
-       "exclude_analysis_directory_list" => [
-               'vendor/',
-               'tests/phan/stubs/',
-               // The referenced classes are not available in vendor, only when
-               // included from composer.
-               'includes/composer/',
-               // Directly references classes that only exist in Translate extension
-               'maintenance/language/',
-               // External class
-               'includes/libs/jsminplus.php',
-       ],
-
-       /**
-        * Backwards Compatibility Checking. This is slow
-        * and expensive, but you should consider running
-        * it before upgrading your version of PHP to a
-        * new version that has backward compatibility
-        * breaks.
-        */
-       'backward_compatibility_checks' => false,
-
-       /**
-        * A set of fully qualified class-names for which
-        * a call to parent::__construct() is required
-        */
-       'parent_constructor_required' => [
-       ],
-
-       /**
-        * Run a quick version of checks that takes less
-        * time at the cost of not running as thorough
-        * an analysis. You should consider setting this
-        * to true only when you wish you had more issues
-        * to fix in your code base.
-        *
-        * In quick-mode the scanner doesn't rescan a function
-        * or a method's code block every time a call is seen.
-        * This means that the problem here won't be detected:
-        *
-        * ```php
-        * <?php
-        * function test($arg):int {
-        *    return $arg;
-        * }
-        * test("abc");
-        * ```
-        *
-        * This would normally generate:
-        *
-        * ```sh
-        * test.php:3 TypeError return string but `test()` is declared to return int
-        * ```
-        *
-        * The initial scan of the function's code block has no
-        * type information for `$arg`. It isn't until we see
-        * the call and rescan test()'s code block that we can
-        * detect that it is actually returning the passed in
-        * `string` instead of an `int` as declared.
-        */
-       'quick_mode' => false,
-
-       /**
-        * By default, Phan will not analyze all node types
-        * in order to save time. If this config is set to true,
-        * Phan will dig deeper into the AST tree and do an
-        * analysis on all nodes, possibly finding more issues.
-        *
-        * See \Phan\Analysis::shouldVisit for the set of skipped
-        * nodes.
-        */
-       'should_visit_all_nodes' => true,
-
-       /**
-        * If enabled, check all methods that override a
-        * parent method to make sure its signature is
-        * compatible with the parent's. This check
-        * can add quite a bit of time to the analysis.
-        */
-       'analyze_signature_compatibility' => true,
-
-       // Emit all issues. They are then suppressed via
-       // suppress_issue_types, rather than a minimum
-       // severity.
-       "minimum_severity" => 0,
-
-       /**
-        * If true, missing properties will be created when
-        * they are first seen. If false, we'll report an
-        * error message if there is an attempt to write
-        * to a class property that wasn't explicitly
-        * defined.
-        */
-       'allow_missing_properties' => false,
-
-       /**
-        * Allow null to be cast as any type and for any
-        * type to be cast to null. Setting this to false
-        * will cut down on false positives.
-        */
-       'null_casts_as_any_type' => true,
-
-       /**
-        * If enabled, scalars (int, float, bool, string, null)
-        * are treated as if they can cast to each other.
-        *
-        * MediaWiki is pretty lax and uses many scalar
-        * types interchangably.
-        */
-       'scalar_implicit_cast' => true,
-
-       /**
-        * If true, seemingly undeclared variables in the global
-        * scope will be ignored. This is useful for projects
-        * with complicated cross-file globals that you have no
-        * hope of fixing.
-        */
-       'ignore_undeclared_variables_in_global_scope' => true,
-
-       /**
-        * Set to true in order to attempt to detect dead
-        * (unreferenced) code. Keep in mind that the
-        * results will only be a guess given that classes,
-        * properties, constants and methods can be referenced
-        * as variables (like `$class->$property` or
-        * `$class->$method()`) in ways that we're unable
-        * to make sense of.
-        */
-       'dead_code_detection' => false,
-
-       /**
-        * If true, the dead code detection rig will
-        * prefer false negatives (not report dead code) to
-        * false positives (report dead code that is not
-        * actually dead) which is to say that the graph of
-        * references will create too many edges rather than
-        * too few edges when guesses have to be made about
-        * what references what.
-        */
-       'dead_code_detection_prefer_false_negative' => true,
-
-       /**
-        * If disabled, Phan will not read docblock type
-        * annotation comments (such as for @return, @param,
-        * @var, @suppress, @deprecated) and only rely on
-        * types expressed in code.
-        */
-       'read_type_annotations' => true,
-
-       /**
-        * If a file path is given, the code base will be
-        * read from and written to the given location in
-        * order to attempt to save some work from being
-        * done. Only changed files will get analyzed if
-        * the file is read
-        */
-       'stored_state_file_path' => null,
-
-       /**
-        * Set to true in order to ignore issue suppression.
-        * This is useful for testing the state of your code, but
-        * unlikely to be useful outside of that.
-        */
-       'disable_suppression' => false,
-
-       /**
-        * If set to true, we'll dump the AST instead of
-        * analyzing files
-        */
-       'dump_ast' => false,
-
-       /**
-        * If set to a string, we'll dump the fully qualified lowercase
-        * function and method signatures instead of analyzing files.
-        */
-       'dump_signatures_file' => null,
-
-       /**
-        * If true (and if stored_state_file_path is set) we'll
-        * look at the list of files passed in and expand the list
-        * to include files that depend on the given files
-        */
-       'expand_file_list' => false,
-
-       // Include a progress bar in the output
-       'progress_bar' => false,
-
-       /**
-        * The probability of actually emitting any progress
-        * bar update. Setting this to something very low
-        * is good for reducing network IO and filling up
-        * your terminal's buffer when running phan on a
-        * remote host.
-        */
-       'progress_bar_sample_rate' => 0.005,
-
-       /**
-        * The number of processes to fork off during the analysis
-        * phase.
-        */
-       'processes' => 1,
-
-       /**
-        * Add any issue types (such as 'PhanUndeclaredMethod')
-        * to this black-list to inhibit them from being reported.
-        */
-       'suppress_issue_types' => [
-               // approximate error count: 29
-               "PhanCommentParamOnEmptyParamList",
-               // approximate error count: 33
-               "PhanCommentParamWithoutRealParam",
-               // approximate error count: 8
-               "PhanDeprecatedClass",
-               // approximate error count: 415
-               "PhanDeprecatedFunction",
-               // approximate error count: 25
-               "PhanDeprecatedProperty",
-               // approximate error count: 17
-               "PhanNonClassMethodCall",
-               // approximate error count: 888
-               "PhanParamSignatureMismatch",
-               // approximate error count: 7
-               "PhanParamSignatureMismatchInternal",
-               // approximate error count: 1
-               "PhanParamSignatureRealMismatchTooFewParameters",
-               // approximate error count: 125
-               "PhanParamTooMany",
-               // approximate error count: 3
-               "PhanParamTooManyInternal",
-               // approximate error count: 1
-               "PhanRedefineFunctionInternal",
-               // approximate error count: 2
-               "PhanTraitParentReference",
-               // approximate error count: 3
-               "PhanTypeComparisonFromArray",
-               // approximate error count: 2
-               "PhanTypeComparisonToArray",
-               // approximate error count: 218
-               "PhanTypeMismatchArgument",
-               // approximate error count: 13
-               "PhanTypeMismatchArgumentInternal",
-               // approximate error count: 5
-               "PhanTypeMismatchDimAssignment",
-               // approximate error count: 2
-               "PhanTypeMismatchDimEmpty",
-               // approximate error count: 1
-               "PhanTypeMismatchDimFetch",
-               // approximate error count: 14
-               "PhanTypeMismatchForeach",
-               // approximate error count: 56
-               "PhanTypeMismatchProperty",
-               // approximate error count: 74
-               "PhanTypeMismatchReturn",
-               // approximate error count: 5
-               "PhanTypeNonVarPassByRef",
-               // approximate error count: 32
-               "PhanUndeclaredConstant",
-               // approximate error count: 233
-               "PhanUndeclaredMethod",
-               // approximate error count: 1224
-               "PhanUndeclaredProperty",
-               // approximate error count: 58
-               "PhanUndeclaredVariableDim",
-       ],
-
-       /**
-        * If empty, no filter against issues types will be applied.
-        * If this white-list is non-empty, only issues within the list
-        * will be emitted by Phan.
-        */
-       'whitelist_issue_types' => [
-               // 'PhanAccessMethodPrivate',
-               // 'PhanAccessMethodProtected',
-               // 'PhanAccessNonStaticToStatic',
-               // 'PhanAccessPropertyPrivate',
-               // 'PhanAccessPropertyProtected',
-               // 'PhanAccessSignatureMismatch',
-               // 'PhanAccessSignatureMismatchInternal',
-               // 'PhanAccessStaticToNonStatic',
-               // 'PhanCompatibleExpressionPHP7',
-               // 'PhanCompatiblePHP7',
-               // 'PhanContextNotObject',
-               // 'PhanDeprecatedClass',
-               // 'PhanDeprecatedFunction',
-               // 'PhanDeprecatedProperty',
-               // 'PhanEmptyFile',
-               // 'PhanNonClassMethodCall',
-               // 'PhanNoopArray',
-               // 'PhanNoopClosure',
-               // 'PhanNoopConstant',
-               // 'PhanNoopProperty',
-               // 'PhanNoopVariable',
-               // 'PhanParamRedefined',
-               // 'PhanParamReqAfterOpt',
-               // 'PhanParamSignatureMismatch',
-               // 'PhanParamSignatureMismatchInternal',
-               // 'PhanParamSpecial1',
-               // 'PhanParamSpecial2',
-               // 'PhanParamSpecial3',
-               // 'PhanParamSpecial4',
-               // 'PhanParamTooFew',
-               // 'PhanParamTooFewInternal',
-               // 'PhanParamTooMany',
-               // 'PhanParamTooManyInternal',
-               // 'PhanParamTypeMismatch',
-               // 'PhanParentlessClass',
-               // 'PhanRedefineClass',
-               // 'PhanRedefineClassInternal',
-               // 'PhanRedefineFunction',
-               // 'PhanRedefineFunctionInternal',
-               // 'PhanStaticCallToNonStatic',
-               // 'PhanSyntaxError',
-               // 'PhanTraitParentReference',
-               // 'PhanTypeArrayOperator',
-               // 'PhanTypeArraySuspicious',
-               // 'PhanTypeComparisonFromArray',
-               // 'PhanTypeComparisonToArray',
-               // 'PhanTypeConversionFromArray',
-               // 'PhanTypeInstantiateAbstract',
-               // 'PhanTypeInstantiateInterface',
-               // 'PhanTypeInvalidLeftOperand',
-               // 'PhanTypeInvalidRightOperand',
-               // 'PhanTypeMismatchArgument',
-               // 'PhanTypeMismatchArgumentInternal',
-               // 'PhanTypeMismatchDefault',
-               // 'PhanTypeMismatchForeach',
-               // 'PhanTypeMismatchProperty',
-               // 'PhanTypeMismatchReturn',
-               // 'PhanTypeMissingReturn',
-               // 'PhanTypeNonVarPassByRef',
-               // 'PhanTypeParentConstructorCalled',
-               // 'PhanTypeVoidAssignment',
-               // 'PhanUnanalyzable',
-               // 'PhanUndeclaredClass',
-               // 'PhanUndeclaredClassCatch',
-               // 'PhanUndeclaredClassConstant',
-               // 'PhanUndeclaredClassInstanceof',
-               // 'PhanUndeclaredClassMethod',
-               // 'PhanUndeclaredClassReference',
-               // 'PhanUndeclaredConstant',
-               // 'PhanUndeclaredExtendedClass',
-               // 'PhanUndeclaredFunction',
-               // 'PhanUndeclaredInterface',
-               // 'PhanUndeclaredMethod',
-               // 'PhanUndeclaredProperty',
-               // 'PhanUndeclaredStaticMethod',
-               // 'PhanUndeclaredStaticProperty',
-               // 'PhanUndeclaredTrait',
-               // 'PhanUndeclaredTypeParameter',
-               // 'PhanUndeclaredTypeProperty',
-               // 'PhanUndeclaredVariable',
-               // 'PhanUnreferencedClass',
-               // 'PhanUnreferencedConstant',
-               // 'PhanUnreferencedMethod',
-               // 'PhanUnreferencedProperty',
-               // 'PhanVariableUseClause',
-       ],
-
-       /**
-        * Override to hardcode existence and types of (non-builtin) globals in the global scope.
-        * Class names must be prefixed with '\\'.
-        * (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 'int'])
-        */
-       'globals_type_map' => [
-               'IP' => 'string',
-       ],
-
-       // Emit issue messages with markdown formatting
-       'markdown_issue_messages' => false,
-
-       /**
-        * Enable or disable support for generic templated
-        * class types.
-        */
-       'generic_types_enabled' => true,
-
-       // A list of plugin files to execute
-       'plugins' => [
-       ],
-];
diff --git a/tests/phan/stubs/README b/tests/phan/stubs/README
deleted file mode 100644 (file)
index c458ab5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-These stubs describe how code that is not available at analysis time should be
-used. No implementations are necessary, just define the classes and their
-methods and use phpdoc to describe what arguments are allowed.
diff --git a/tests/phan/stubs/excimer.php b/tests/phan/stubs/excimer.php
deleted file mode 100644 (file)
index af3a673..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-// phpcs:ignoreFile
-
-class ExcimerProfiler {
-       public function __construct() {
-       }
-       public function setPeriod( $period ) {
-       }
-       public function setEventType( $event_type ) {
-       }
-       public function setMaxDepth( $maxDepth ) {
-       }
-       public function setFlushCallback( $callback, $max_samples ) {
-       }
-       public function clearFlushCallback() {
-       }
-       public function start() {
-       }
-       public function stop() {
-       }
-       public function getLog() {
-       }
-       public function flush() {
-       }
-}
-
-class ExcimerLog {
-       private final function __construct() {
-       }
-       function formatCollapsed() {
-       }
-       function aggregateByFunction() {
-       }
-       function getEventCount() {
-       }
-       function current() {
-       }
-       function key() {
-       }
-       function next() {
-       }
-       function rewind() {
-       }
-       function valid() {
-       }
-       function count() {
-       }
-       function offsetExists( $offset ) {
-       }
-       function offsetGet( $offset ) {
-       }
-       function offsetSet( $offset, $value ) {
-       }
-       function offsetUnset( $offset ) {
-       }
-
-}
-
-class ExcimerLogEntry {
-       private final function __construct() {
-       }
-       function getTimestamp() {
-       }
-       function getEventCount() {
-       }
-       function getTrace() {
-       }
-}
-
-class ExcimerTimer {
-       function setEventType( $event_type ) {
-       }
-       function setInterval( $interval ) {
-       }
-       function setPeriod( $period ) {
-       }
-       function setCallback( $callback ) {
-       }
-       function start() {
-       }
-       function stop() {
-       }
-       function getTime() {
-       }
-}
diff --git a/tests/phan/stubs/hhvm.php b/tests/phan/stubs/hhvm.php
deleted file mode 100644 (file)
index 364ebda..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-// phpcs:ignoreFile
-
-/**
- * @param callable $callback
- * @param mixed ...$parameters
- */
-function register_postsend_function( $callback ) {
-}
diff --git a/tests/phan/stubs/mail.php b/tests/phan/stubs/mail.php
deleted file mode 100644 (file)
index ba1efb9..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-
-/**
- * Minimal set of classes necessary for UserMailer to be happy. Types
- * taken from documentation at pear.php.net.
- * phpcs:ignoreFile
- */
-
-class PEAR {
-       /**
-        * @param mixed $data
-        * @return bool
-        */
-       public static function isError( $data ) {
-       }
-}
-
-class PEAR_Error {
-       /**
-        * @return string
-        */
-       public function getMessage() {
-       }
-}
-
-class Mail {
-       /**
-        * @param string $driver
-        * @param array $params
-        * @return self
-        */
-       static public function factory( $driver, array $params = [] ) {
-       }
-
-       /**
-        * @param mixed $recipients
-        * @param array $headers
-        * @param string $body
-        * @return bool|PEAR_Error
-        */
-       public function send( $recipients, array $headers, $body ) {
-       }
-}
-
-class Mail_smtp extends Mail {
-}
-
-class Mail_mime {
-       /**
-        * @param mixed $params
-        */
-       public function __construct( $params = [] ) {
-       }
-
-       /**
-        * @param string $data
-        * @param bool $isfile
-        * @param bool $append
-        * @return bool|PEAR_Error
-        */
-       public function setTXTBody( $data, $isfile = false, $append = false ) {
-       }
-
-       /**
-        * @param string $data
-        * @param bool $isfile
-        * @return bool|PEAR_Error
-        */
-       public function setHTMLBody( $data, $isfile = false ) {
-       }
-
-       /**
-        * @param array|null $parms
-        * @param mixed $filename
-        * @param bool $skip_head
-        * @return string|bool|PEAR_Error
-        */
-       public function get( $params = null, $filename = null, $skip_head = false ) {
-       }
-
-       /**
-        * @param array|null $xtra_headers
-        * @param bool $overwrite
-        * @param bool $skip_content
-        * @return array
-        */
-       public function headers( array $xtra_headers = null, $overwrite = false, $skip_content = false ) {
-       }
-}
diff --git a/tests/phan/stubs/memcached.php b/tests/phan/stubs/memcached.php
deleted file mode 100644 (file)
index 0f8859d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-/**
- * The phpstorm stubs package includes the Memcached class with two parameters and docs saying
- * that they are optional. Phan can not detect this and thus throws an error for a usage with
- * no params. So we have this small stub just for the constructor to allow no params.
- * @see https://secure.php.net/manual/en/memcached.construct.php
- * phpcs:ignoreFile
- */
-
-class Memcached {
-
-       public function __construct() {
-       }
-
-}
diff --git a/tests/phan/stubs/phpunit4.php b/tests/phan/stubs/phpunit4.php
deleted file mode 100644 (file)
index e5e88e6..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-
-/**
- * Some old classes from PHPUnit 4 that MediaWiki (conditionally) references.
- *
- * phpcs:ignoreFile
- */
-
-class PHPUnit_TextUI_Command {
-
-}
diff --git a/tests/phan/stubs/tideways.php b/tests/phan/stubs/tideways.php
deleted file mode 100644 (file)
index 34ac735..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-/**
- * Minimal set of classes necessary for Xhprof using tideways
- * phpcs:ignoreFile
- */
-
-function tideways_enable(){
-}
-
-function tideways_disable(){
-}
diff --git a/tests/phan/stubs/wikidiff.php b/tests/phan/stubs/wikidiff.php
deleted file mode 100644 (file)
index 02bcd1f..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-// phpcs:ignoreFile
-
-/**
- * @param string $text1
- * @param string $text2
- * @param int $numContextLines
- * @param int $movedParagraphDetectionCutoff
- * @return string
- */
-function wikidiff2_do_diff( $text1, $text2, $numContextLines, $movedParagraphDetectionCutoff = 0 ) {
-}
-
-/**
- * @param string $text1
- * @param string $text2
- * @param int $numContextLines
- * @param int $maxMovedLines
- * @return string
- */
-function wikidiff2_inline_diff( $text1, $text2, $numContextLines, $maxMovedLines = 25 ) {
-}
index def08ff..aa383e2 100644 (file)
@@ -27,8 +27,8 @@ trait HamcrestPHPUnitIntegration {
         * Wrapper around Hamcrest's assertThat, which marks the assertion
         * for PHPUnit so the test is not marked as risky
         */
-       public function assertThatHamcrest( /* ... */ ) {
-               call_user_func_array( 'assertThat', func_get_args() );
+       public function assertThatHamcrest( ...$args ) {
+               assertThat( ...$args );
                $this->addToAssertionCount( 1 );
        }
 }
index adb0196..8f34180 100644 (file)
@@ -14,8 +14,6 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
        private $originalSpi;
        /** @var Spi|null */
        private $spi;
-       /** @var array|null */
-       private $lastTestLogs;
 
        /**
         * A test started.
@@ -29,6 +27,40 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
                LoggerFactory::registerProvider( $this->spi );
        }
 
+       public function addRiskyTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addError( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addWarning( PHPUnit_Framework_Test $test, PHPUnit\Framework\Warning $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addFailure( PHPUnit_Framework_Test $test,
+               PHPUnit_Framework_AssertionFailedError $e, $time
+       ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       private function augmentTestWithLogs( PHPUnit_Framework_Test $test ) {
+               if ( $this->spi ) {
+                       $logs = $this->spi->getLogs();
+                       $formatted = $this->formatLogs( $logs );
+                       $test->_formattedMediaWikiLogs = $formatted;
+               }
+       }
+
        /**
         * A test ended.
         *
@@ -36,7 +68,6 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
         * @param float $time
         */
        public function endTest( PHPUnit_Framework_Test $test, $time ) {
-               $this->lastTestLogs = $this->spi->getLogs();
                LoggerFactory::registerProvider( $this->originalSpi );
                $this->originalSpi = null;
                $this->spi = null;
@@ -46,15 +77,17 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
         * Get string formatted logs generated during the last
         * test to execute.
         *
+        * @param array $logs
         * @return string
         */
-       public function getLog() {
-               $logs = $this->lastTestLogs;
-               if ( !$logs ) {
-                       return '';
-               }
+       private function formatLogs( array $logs ) {
                $message = [];
                foreach ( $logs as $log ) {
+                       if ( $log['channel'] === 'PHPUnitCommand' ) {
+                               // Don't print the log of PHPUnit events while running PHPUnit,
+                               // because PHPUnit is already printing those already.
+                               continue;
+                       }
                        $message[] = sprintf(
                                '[%s] [%s] %s %s',
                                $log['channel'],
index 5d139ff..6b1d817 100644 (file)
@@ -2,7 +2,6 @@
 
 class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
        private $cliArgs;
-       private $logListener;
 
        public function __construct( $ignorableOptions, $cliArgs ) {
                $ignore = function ( $arg ) {
@@ -21,22 +20,19 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
 
                // Add our own listeners
                $this->arguments['listeners'][] = new MediaWikiPHPUnitTestListener;
-               $this->logListener = new MediaWikiLoggerPHPUnitTestListener;
-               $this->arguments['listeners'][] = $this->logListener;
+               $this->arguments['listeners'][] = new MediaWikiLoggerPHPUnitTestListener;
 
                // Output only to stderr to avoid "Headers already sent" problems
                $this->arguments['stderr'] = true;
 
-               // We could create a printer instance and avoid passing the
-               // listener statically, but then we have to recreate the
-               // appropriate arguments handling + defaults.
+               // Use a custom result printer that includes per-test logging output
+               // when nothing is provided.
                if ( !isset( $this->arguments['printer'] ) ) {
                        $this->arguments['printer'] = MediaWikiPHPUnitResultPrinter::class;
                }
        }
 
        protected function createRunner() {
-               MediaWikiPHPUnitResultPrinter::setLogListener( $this->logListener );
                $runner = new MediaWikiTestRunner;
                $runner->setMwCliArgs( $this->cliArgs );
                return $runner;
index e796752..d0ac8ff 100644 (file)
@@ -1,17 +1,13 @@
 <?php
 
 class MediaWikiPHPUnitResultPrinter extends PHPUnit_TextUI_ResultPrinter {
-       /** @var MediaWikiLoggerPHPUnitTestListener */
-       private static $logListener;
-
-       public static function setLogListener( MediaWikiLoggerPHPUnitTestListener $logListener ) {
-               self::$logListener = $logListener;
-       }
-
        protected function printDefectTrace( PHPUnit_Framework_TestFailure $defect ) {
-               $log = self::$logListener->getLog();
-               if ( $log ) {
-                       $this->write( "=== Logs generated by test case\n{$log}\n===\n" );
+               $test = $defect->failedTest();
+               if ( $test !== null && isset( $test->_formattedMediaWikiLogs ) ) {
+                       $log = $test->_formattedMediaWikiLogs;
+                       if ( $log ) {
+                               $this->write( "=== Logs generated by test case\n{$log}\n===\n" );
+                       }
                }
                parent::printDefectTrace( $defect );
        }
index 35f396e..fd0cea1 100644 (file)
@@ -361,6 +361,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        public static function resetNonServiceCaches() {
                global $wgRequest, $wgJobClasses;
 
+               User::resetGetDefaultOptionsForTestsOnly();
                foreach ( $wgJobClasses as $type => $class ) {
                        JobQueueGroup::singleton()->get( $type )->delete();
                }
@@ -400,7 +401,8 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        self::$useTemporaryTables = !$this->getCliArg( 'use-normal-tables' );
                        self::$reuseDB = $this->getCliArg( 'reuse-db' );
 
-                       $this->db = wfGetDB( DB_MASTER );
+                       $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+                       $this->db = $lb->getConnection( DB_MASTER );
 
                        $this->checkDbIsSupported();
 
@@ -542,6 +544,24 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                $this->tmpFiles = array_merge( $this->tmpFiles, (array)$files );
        }
 
+       // @todo Make const when we no longer support HHVM (T192166)
+       private static $namespaceAffectingSettings = [
+               'wgAllowImageMoving',
+               'wgCanonicalNamespaceNames',
+               'wgCapitalLinkOverrides',
+               'wgCapitalLinks',
+               'wgContentNamespaces',
+               'wgExtensionMessagesFiles',
+               'wgExtensionNamespaces',
+               'wgExtraNamespaces',
+               'wgExtraSignatureNamespaces',
+               'wgNamespaceContentModels',
+               'wgNamespaceProtection',
+               'wgNamespacesWithSubpages',
+               'wgNonincludableNamespaces',
+               'wgRestrictionLevels',
+       ];
+
        protected function tearDown() {
                global $wgRequest, $wgSQLMode;
 
@@ -586,8 +606,8 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        ini_set( $name, $value );
                }
                if (
-                       array_key_exists( 'wgExtraNamespaces', $this->mwGlobals ) ||
-                       in_array( 'wgExtraNamespaces', $this->mwGlobalsToUnset )
+                       array_intersect( self::$namespaceAffectingSettings, array_keys( $this->mwGlobals ) ) ||
+                       array_intersect( self::$namespaceAffectingSettings, $this->mwGlobalsToUnset )
                ) {
                        $this->resetNamespaces();
                }
@@ -729,7 +749,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        $GLOBALS[$key] = $value;
                }
 
-               if ( array_key_exists( 'wgExtraNamespaces', $pairs ) ) {
+               if ( array_intersect( self::$namespaceAffectingSettings, array_keys( $pairs ) ) ) {
                        $this->resetNamespaces();
                }
        }
@@ -760,14 +780,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                                . 'instance has been replaced by test code.' );
                }
 
-               MWNamespace::clearCaches();
                Language::clearCaches();
-
-               // We can't have the TitleFormatter holding on to an old Language object either
-               // @todo We shouldn't need to reset all the aliases here.
-               $this->localServices->resetServiceForTesting( 'TitleFormatter' );
-               $this->localServices->resetServiceForTesting( 'TitleParser' );
-               $this->localServices->resetServiceForTesting( '_MediaWikiTitleCodec' );
        }
 
        /**
@@ -1363,6 +1376,9 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        JobQueueGroup::singleton()->get( $type )->delete();
                }
 
+               // T219673: close any connections from code that failed to call reuseConnection()
+               // or is still holding onto a DBConnRef instance (e.g. in a singleton).
+               MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->closeAll();
                CloneDatabase::changePrefix( self::$oldTablePrefix );
 
                self::$oldTablePrefix = false;
@@ -1453,12 +1469,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * @note this method only works when first called. Subsequent calls have no effect,
         * even if using different parameters.
         *
-        * @param Database $db The database connection
+        * @param IMaintainableDatabase $db The database connection
         * @param string $prefix The prefix to use for the new table set (aka schema).
         *
         * @throws MWException If the database table prefix is already $prefix
         */
-       public static function setupTestDB( Database $db, $prefix ) {
+       public static function setupTestDB( IMaintainableDatabase $db, $prefix ) {
                if ( self::$dbSetup ) {
                        return;
                }
@@ -1595,7 +1611,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                $this->ensureMockDatabaseConnection( $db );
 
                $oldOverrides = $oldOverrides + self::$schemaOverrideDefaults;
-               $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
+               $originalTables = $this->listOriginalTables( $db );
 
                // Drop tables that need to be restored or removed.
                $tablesToDrop = array_merge( $oldOverrides['create'], $oldOverrides['alter'] );
@@ -1611,6 +1627,10 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
 
                if ( $tablesToRestore ) {
                        $this->recloneMockTables( $db, $tablesToRestore );
+
+                       // Reset the restored tables, mainly for the side effect of
+                       // re-calling $this->addCoreDBData() if necessary.
+                       $this->resetDB( $db, $tablesToRestore );
                }
        }
 
@@ -1625,6 +1645,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
 
                if ( $oldOverrides['alter'] || $oldOverrides['create'] || $oldOverrides['drop'] ) {
                        $this->undoSchemaOverrides( $db, $oldOverrides );
+                       unset( $db->_schemaOverrides );
                }
 
                // Determine new overrides.
@@ -1656,7 +1677,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                $this->ensureMockDatabaseConnection( $db );
 
                // Drop the tables that will be created by the schema scripts.
-               $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
+               $originalTables = $this->listOriginalTables( $db );
                $tablesToDrop = array_intersect( $originalTables, $overrides['create'] );
 
                if ( $tablesToDrop ) {
@@ -1701,29 +1722,36 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        }
 
        /**
-        * Lists all tables in the live database schema.
+        * Lists all tables in the live database schema, without a prefix.
         *
         * @param IMaintainableDatabase $db
-        * @param string $prefix Either 'prefixed' or 'unprefixed'
         * @return array
         */
-       private function listOriginalTables( IMaintainableDatabase $db, $prefix = 'prefixed' ) {
+       private function listOriginalTables( IMaintainableDatabase $db ) {
                if ( !isset( $db->_originalTablePrefix ) ) {
                        throw new LogicException( 'No original table prefix know, cannot list tables!' );
                }
 
                $originalTables = $db->listTables( $db->_originalTablePrefix, __METHOD__ );
-               if ( $prefix === 'unprefixed' ) {
-                       $originalPrefixRegex = '/^' . preg_quote( $db->_originalTablePrefix, '/' ) . '/';
-                       $originalTables = array_map(
-                               function ( $pt ) use ( $originalPrefixRegex ) {
-                                       return preg_replace( $originalPrefixRegex, '', $pt );
-                               },
-                               $originalTables
-                       );
-               }
 
-               return $originalTables;
+               $unittestPrefixRegex = '/^' . preg_quote( $this->dbPrefix(), '/' ) . '/';
+               $originalPrefixRegex = '/^' . preg_quote( $db->_originalTablePrefix, '/' ) . '/';
+
+               $originalTables = array_filter(
+                       $originalTables,
+                       function ( $pt ) use ( $unittestPrefixRegex ) {
+                               return !preg_match( $unittestPrefixRegex, $pt );
+                       }
+               );
+
+               $originalTables = array_map(
+                       function ( $pt ) use ( $originalPrefixRegex ) {
+                               return preg_replace( $originalPrefixRegex, '', $pt );
+                       },
+                       $originalTables
+               );
+
+               return array_unique( $originalTables );
        }
 
        /**
@@ -1741,7 +1769,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        throw new LogicException( 'No original table prefix know, cannot restore tables!' );
                }
 
-               $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
+               $originalTables = $this->listOriginalTables( $db );
                $tables = array_intersect( $tables, $originalTables );
 
                $dbClone = new CloneDatabase( $db, $tables, $db->tablePrefix(), $db->_originalTablePrefix );
@@ -1769,6 +1797,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        if ( array_intersect( $tablesUsed, $userTables ) ) {
                                $tablesUsed = array_unique( array_merge( $tablesUsed, $userTables ) );
                                TestUserRegistry::clear();
+
+                               // Reset $wgUser, which is probably 127.0.0.1, as its loaded data is probably not valid
+                               // @todo Should we start setting $wgUser to something nondeterministic
+                               //  to encourage tests to be updated to not depend on it?
+                               global $wgUser;
+                               $wgUser->clearInstanceCache( $wgUser->mFrom );
                        }
                        if ( array_intersect( $tablesUsed, $pageTables ) ) {
                                $tablesUsed = array_unique( array_merge( $tablesUsed, $pageTables ) );
@@ -1889,7 +1923,17 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * @param IDatabase $target
         */
        public function copyTestData( IDatabase $source, IDatabase $target ) {
-               $tables = self::listOriginalTables( $source, 'unprefixed' );
+               if ( $this->db->getType() === 'sqlite' ) {
+                       // SQLite uses a non-temporary copy of the searchindex table for testing,
+                       // which gets deleted and re-created when setting up the secondary connection,
+                       // causing "Error 17" when trying to copy the data. See T191863#4130112.
+                       throw new RuntimeException(
+                               'Setting up a secondary database connection with test data is currently not'
+                               . 'with SQLite. You may want to use markTestSkippedIfDbType() to bypass this issue.'
+                       );
+               }
+
+               $tables = self::listOriginalTables( $source );
 
                foreach ( $tables as $table ) {
                        $res = $source->select( $table, '*', [], __METHOD__ );
index 79ce634..1ef0c91 100644 (file)
@@ -130,4 +130,18 @@ trait PHPUnit4And6Compat {
                        // ->disallowMockingUnknownTypes()
                        ->getMock();
        }
+
+       /**
+        * Marks the current test as risky. This
+        * is a forward port of the markAsRisky function that
+        * was introduced in PHPUnit 5.7.6.
+        */
+       public function markAsRisky() {
+               if ( is_callable( 'parent::markAsRisky' ) ) {
+                       return parent::markAsRisky();
+               }
+
+               // "risky" tests are not supported in phpunit 4, so just ignore
+       }
+
 }
index cadd0ff..c7fb48b 100644 (file)
@@ -26,6 +26,7 @@ abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
                        $options = [ 'lang' => $options ];
                }
                $options += [
+                       'debug' => 'true',
                        'lang' => 'en',
                        'dir' => 'ltr',
                        'skin' => 'vector',
@@ -35,6 +36,7 @@ abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
                ];
                $resourceLoader = $rl ?: new ResourceLoader();
                $request = new FauxRequest( [
+                               'debug' => $options['debug'],
                                'lang' => $options['lang'],
                                'modules' => $options['modules'],
                                'only' => $options['only'],
@@ -58,9 +60,6 @@ abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
                        // Avoid influence from wgInvalidateCacheOnLocalSettingsChange
                        'CacheEpoch' => '20140101000000',
 
-                       // For ResourceLoader::__construct()
-                       'ResourceLoaderSources' => [],
-
                        // For wfScript()
                        'ScriptPath' => '/w',
                        'Script' => '/w/index.php',
index a5c8ef6..79cb5be 100644 (file)
@@ -14,16 +14,21 @@ EOF;
        require_once __DIR__ . "/phpunit.php";
 }
 
-class MediaWikiPHPUnitBootstrap {
-       public function __destruct() {
-               // Return to real wiki db, so profiling data is preserved
-               MediaWikiTestCase::teardownTestDB();
+// The PHPUnit_TextUI_TestRunner class will run each test suite and may call
+// exit() with an exit status code. As such, we cannot run code "after the last test"
+// by adding statements to PHPUnitMaintClass::execute or MediaWikiPHPUnitCommand::run.
+// Instead, we work around it by registering a shutdown callback from the bootstrap
+// file, which runs before PHPUnit starts.
+// @todo Once we use PHPUnit 8 or higher, use the 'AfterLastTestHook' feature.
+// https://phpunit.readthedocs.io/en/8.0/extending-phpunit.html#available-hook-interfaces
+register_shutdown_function( function () {
+       // This will:
+       // - clear the temporary job queue.
+       // - allow extensions to delete any temporary tables they created.
+       // - restore ability to connect to the real database,
+       //   (for logging profiling data).
+       MediaWikiTestCase::teardownTestDB();
 
-               // Log profiling data, e.g. in the database or UDP
-               wfLogProfilingData();
-       }
-
-}
-
-// This will be destructed after all tests have been run
-$mediawikiPHPUnitBootstrap = new MediaWikiPHPUnitBootstrap();
+       // Log profiling data, e.g. in the database or UDP
+       wfLogProfilingData();
+} );
index 2789571..d20fcff 100644 (file)
@@ -34,15 +34,20 @@ class ReleaseNotesTest extends MediaWikiTestCase {
                }
 
                // Also test the README and similar files
-               $otherFiles = [ "$IP/COPYING", "$IP/FAQ", "$IP/INSTALL", "$IP/README", "$IP/SECURITY" ];
+               $otherFiles = [
+                       "$IP/COPYING",
+                       "$IP/FAQ",
+                       "$IP/HISTORY",
+                       "$IP/INSTALL",
+                       "$IP/README",
+                       "$IP/SECURITY"
+               ];
 
                foreach ( $otherFiles as $index => $fileName ) {
                        $this->assertFileLength( "Help", $fileName );
                }
        }
 
-       /**
-        */
        private function assertFileLength( $type, $fileName ) {
                $file = file( $fileName, FILE_IGNORE_NEW_LINES );
 
@@ -51,16 +56,13 @@ class ReleaseNotesTest extends MediaWikiTestCase {
                        "$type file '$fileName' is inaccessible."
                );
 
-               $lines = count( $file );
-
-               for ( $i = 0; $i < $lines; $i++ ) {
-                       $line = $file[$i];
-
+               foreach ( $file as $i => $line ) {
+                       $num = $i + 1;
                        $this->assertLessThanOrEqual(
                                // FILE_IGNORE_NEW_LINES drops the \n at the EOL, so max length is 80 not 81.
                                80,
                                mb_strlen( $line ),
-                               "$type file '$fileName' line $i is longer than 80 chars:\n\t'$line'"
+                               "$type file '$fileName' line $num, is longer than 80 chars:\n\t'$line'"
                        );
                }
        }
index 15c70bc..1f2b13c 100644 (file)
@@ -593,7 +593,6 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
                        ] ],
                        'revision' => [ 'revision', 'rev_user', 'rev_id', [
                                'rev_page' => 42,
-                               'rev_text_id' => 42,
                                'rev_len' => 0,
                                'rev_timestamp' => $db->timestamp(),
                        ] ],
@@ -679,7 +678,6 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
                        $m->getInsertValuesWithTempTable( $this->db, 'rev_user', $userIdentity );
                $extraFields = [
                        'rev_page' => 42,
-                       'rev_text_id' => 42,
                        'rev_len' => 0,
                        'rev_timestamp' => $this->db->timestamp(),
                ] + $cFields;
index 1f11ef2..7874688 100644 (file)
@@ -94,7 +94,7 @@ class BlockTest extends MediaWikiLangTestCase {
                $madeAt = wfTimestamp( TS_MW );
 
                // delta to stop one-off errors when things happen to go over a second mark.
-               $delta = abs( $madeAt - $block->mTimestamp );
+               $delta = abs( $madeAt - $block->getTimestamp() );
                $this->assertLessThan(
                        2,
                        $delta,
@@ -302,8 +302,8 @@ class BlockTest extends MediaWikiLangTestCase {
                        $block = new Block();
                        $block->setTarget( $target );
                        $block->setBlocker( $blocker );
-                       $block->mReason = $insBlock['desc'];
-                       $block->mExpiry = 'infinity';
+                       $block->setReason( $insBlock['desc'] );
+                       $block->setExpiry( 'infinity' );
                        $block->isCreateAccountBlocked( $insBlock['ACDisable'] );
                        $block->isHardblock( $insBlock['isHardblock'] );
                        $block->isAutoblocking( $insBlock['isAutoBlocking'] );
@@ -369,61 +369,8 @@ class BlockTest extends MediaWikiLangTestCase {
                $xffblocks = Block::getBlocksForIPList( $list, true );
                $this->assertEquals( $exCount, count( $xffblocks ), 'Number of blocks for ' . $xff );
                $block = Block::chooseBlock( $xffblocks, $list );
-               $this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff );
-       }
-
-       /**
-        * @covers Block::__construct
-        */
-       public function testDeprecatedConstructor() {
-               $this->hideDeprecated( 'Block::__construct with multiple arguments' );
-               $username = 'UnthinkablySecretRandomUsername';
-               $reason = 'being irrational';
-
-               # Set up the target
-               $u = User::newFromName( $username );
-               if ( $u->getId() == 0 ) {
-                       $u->addToDatabase();
-                       TestUser::setPasswordForUser( $u, 'TotallyObvious' );
-               }
-               unset( $u );
-
-               # Make sure the user isn't blocked
-               $this->assertNull(
-                       Block::newFromTarget( $username ),
-                       "$username should not be blocked"
-               );
-
-               # Perform the block
-               $block = new Block(
-                       /* address */ $username,
-                       /* user */ 0,
-                       /* by */ $this->getTestSysop()->getUser()->getId(),
-                       /* reason */ $reason,
-                       /* timestamp */ 0,
-                       /* auto */ false,
-                       /* expiry */ 0
-               );
-               $block->insert();
-
-               # Check target
                $this->assertEquals(
-                       $block->getTarget()->getName(),
-                       $username,
-                       "Target should be set properly"
-               );
-
-               # Check supplied parameter
-               $this->assertEquals(
-                       $block->mReason,
-                       $reason,
-                       "Reason should be non-default"
-               );
-
-               # Check default parameter
-               $this->assertFalse(
-                       (bool)$block->appliesToRight( 'createaccount' ),
-                       "Account creation should not be blocked by default"
+                       $exResult, $block->getReason(), 'Correct block type for XFF header ' . $xff
                );
        }
 
diff --git a/tests/phpunit/includes/CategoryTest.php b/tests/phpunit/includes/CategoryTest.php
new file mode 100644 (file)
index 0000000..60fb144
--- /dev/null
@@ -0,0 +1,287 @@
+<?php
+
+/**
+ * @group Database
+ * @group Category
+ */
+class CategoryTest extends MediaWikiTestCase {
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( [
+                       'wgAllowUserJs' => false,
+                       'wgDefaultLanguageVariant' => false,
+                       'wgMetaNamespace' => 'Project',
+               ] );
+               $this->setUserLang( 'en' );
+               $this->setContentLang( 'en' );
+       }
+
+       /**
+        * @covers Category::initialize()
+        */
+       public function testInitialize_idNotExist() {
+               $category = Category::newFromID( -1 );
+               $this->assertFalse( $category->getName() );
+       }
+
+       public function provideInitializeVariants() {
+               return [
+                       // Existing title
+                       [ 'newFromName', 'Example', 'getID', 1 ],
+                       [ 'newFromName', 'Example', 'getName', 'Example' ],
+                       [ 'newFromName', 'Example', 'getPageCount', 3 ],
+                       [ 'newFromName', 'Example', 'getSubcatCount', 4 ],
+                       [ 'newFromName', 'Example', 'getFileCount', 5 ],
+
+                       // Non-existing title
+                       [ 'newFromName', 'NoExample', 'getID', 0 ],
+                       [ 'newFromName', 'NoExample', 'getName', 'NoExample' ],
+                       [ 'newFromName', 'NoExample', 'getPageCount', 0 ],
+                       [ 'newFromName', 'NoExample', 'getSubcatCount', 0 ],
+                       [ 'newFromName', 'NoExample', 'getFileCount', 0 ],
+
+                       // Existing ID
+                       [ 'newFromID', 1, 'getID', 1 ],
+                       [ 'newFromID', 1, 'getName', 'Example' ],
+                       [ 'newFromID', 1, 'getPageCount', 3 ],
+                       [ 'newFromID', 1, 'getSubcatCount', 4 ],
+                       [ 'newFromID', 1, 'getFileCount', 5 ]
+               ];
+       }
+
+       /**
+        * @covers Category::initialize()
+        * @dataProvider provideInitializeVariants
+        */
+       public function testInitialize( $createFunction, $createParam, $testFunction, $expected ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'category',
+                       [
+                               [
+                                       'cat_id' => 1,
+                                       'cat_title' => 'Example',
+                                       'cat_pages' => 3,
+                                       'cat_subcats' => 4,
+                                       'cat_files' => 5
+                               ]
+                       ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               $category = Category::{$createFunction}( $createParam );
+               $this->assertEquals( $expected, $category->{$testFunction}() );
+
+               $dbw->delete( 'category', '*', __METHOD__ );
+       }
+
+       /**
+        * @covers Category::newFromName()
+        * @covers Category::getName()
+        */
+       public function testNewFromName_validTitle() {
+               $category = Category::newFromName( 'Example' );
+               $this->assertSame( 'Example', $category->getName() );
+       }
+
+       /**
+        * @covers Category::newFromName()
+        */
+       public function testNewFromName_invalidTitle() {
+               $this->assertFalse( Category::newFromName( '#' ) );
+       }
+
+       /**
+        * @covers Category::newFromTitle()
+        */
+       public function testNewFromTitle() {
+               $title = Title::newFromText( 'Category:Example' );
+               $category = Category::newFromTitle( $title );
+               $this->assertSame( 'Example', $category->getName() );
+       }
+
+       /**
+        * @covers Category::newFromID()
+        * @covers Category::getID()
+        */
+       public function testNewFromID() {
+               $category = Category::newFromID( 5 );
+               $this->assertSame( 5, $category->getID() );
+       }
+
+       /**
+        * @covers Category::newFromRow()
+        */
+       public function testNewFromRow_found() {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'category',
+                       [
+                               [
+                                       'cat_id' => 1,
+                                       'cat_title' => 'Example',
+                                       'cat_pages' => 3,
+                                       'cat_subcats' => 4,
+                                       'cat_files' => 5
+                               ]
+                       ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               $category = Category::newFromRow( $dbw->selectRow(
+                       'category',
+                       [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
+                       [ 'cat_id' => 1 ],
+                       __METHOD__
+               ) );
+
+               $this->assertEquals( 1, $category->getID() );
+
+               $dbw->delete( 'category', '*', __METHOD__ );
+       }
+
+       /**
+        * @covers Category::newFromRow()
+        */
+       public function testNewFromRow_notFoundWithoutTitle() {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'category',
+                       [
+                               [
+                                       'cat_id' => 1,
+                                       'cat_title' => 'Example',
+                                       'cat_pages' => 3,
+                                       'cat_subcats' => 4,
+                                       'cat_files' => 5
+                               ]
+                       ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               $row = $dbw->selectRow(
+                       'category',
+                       [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
+                       [ 'cat_id' => 1 ],
+                       __METHOD__
+               );
+               $row->cat_title = null;
+
+               $this->assertFalse( Category::newFromRow( $row ) );
+
+               $dbw->delete( 'category', '*', __METHOD__ );
+       }
+
+       /**
+        * @covers Category::newFromRow()
+        */
+       public function testNewFromRow_notFoundWithTitle() {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'category',
+                       [
+                               [
+                                       'cat_id' => 1,
+                                       'cat_title' => 'Example',
+                                       'cat_pages' => 3,
+                                       'cat_subcats' => 4,
+                                       'cat_files' => 5
+                               ]
+                       ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               $row = $dbw->selectRow(
+                       'category',
+                       [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
+                       [ 'cat_id' => 1 ],
+                       __METHOD__
+               );
+               $row->cat_title = null;
+
+               $category = Category::newFromRow(
+                       $row,
+                       Title::newFromText( NS_CATEGORY, 'Example' )
+               );
+
+               $this->assertFalse( $category->getID() );
+
+               $dbw->delete( 'category', '*', __METHOD__ );
+       }
+
+       /**
+        * @covers Category::getPageCount()
+        */
+       public function testGetPageCount() {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'category',
+                       [
+                               [
+                                       'cat_id' => 1,
+                                       'cat_title' => 'Example',
+                                       'cat_pages' => 3,
+                                       'cat_subcats' => 4,
+                                       'cat_files' => 5
+                               ]
+                       ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               $category = Category::newFromID( 1 );
+               $this->assertEquals( 3, $category->getPageCount() );
+
+               $dbw->delete( 'category', '*', __METHOD__ );
+       }
+
+       /**
+        * @covers Category::getSubcatCount()
+        */
+       public function testGetSubcatCount() {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'category',
+                       [
+                               [
+                                       'cat_id' => 1,
+                                       'cat_title' => 'Example',
+                                       'cat_pages' => 3,
+                                       'cat_subcats' => 4,
+                                       'cat_files' => 5
+                               ]
+                       ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               $category = Category::newFromID( 1 );
+               $this->assertEquals( 4, $category->getSubcatCount() );
+
+               $dbw->delete( 'category', '*', __METHOD__ );
+       }
+
+       /**
+        * @covers Category::getFileCount()
+        */
+       public function testGetFileCount() {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->insert( 'category',
+                       [
+                               [
+                                       'cat_id' => 1,
+                                       'cat_title' => 'Example',
+                                       'cat_pages' => 3,
+                                       'cat_subcats' => 4,
+                                       'cat_files' => 5
+                               ]
+                       ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               $category = Category::newFromID( 1 );
+               $this->assertEquals( 5, $category->getFileCount() );
+
+               $dbw->delete( 'category', '*', __METHOD__ );
+       }
+}
index 22fe3ce..9443b19 100644 (file)
@@ -14,6 +14,7 @@ class GlobalTest extends MediaWikiTestCase {
                unlink( $readOnlyFile );
 
                $this->setMwGlobals( [
+                       'wgReadOnly' => null,
                        'wgReadOnlyFile' => $readOnlyFile,
                        'wgUrlProtocols' => [
                                'http://',
@@ -108,10 +109,6 @@ class GlobalTest extends MediaWikiTestCase {
         * @covers ::wfReadOnly
         */
        public function testReadOnlyEmpty() {
-               global $wgReadOnly;
-               $wgReadOnly = null;
-
-               MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode()->clearCache();
                $this->assertFalse( wfReadOnly() );
                $this->assertFalse( wfReadOnly() );
        }
@@ -121,23 +118,17 @@ class GlobalTest extends MediaWikiTestCase {
         * @covers ::wfReadOnly
         */
        public function testReadOnlySet() {
-               global $wgReadOnly, $wgReadOnlyFile;
-
-               $readOnlyMode = MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode();
-               $readOnlyMode->clearCache();
+               global $wgReadOnlyFile;
 
                $f = fopen( $wgReadOnlyFile, "wt" );
                fwrite( $f, 'Message' );
                fclose( $f );
-               $wgReadOnly = null; # Check on $wgReadOnlyFile
+
+               // Reset the service to avoid cached results
+               $this->overrideMwServices();
 
                $this->assertTrue( wfReadOnly() );
                $this->assertTrue( wfReadOnly() ); # Check cached
-
-               unlink( $wgReadOnlyFile );
-               $readOnlyMode->clearCache();
-               $this->assertFalse( wfReadOnly() );
-               $this->assertFalse( wfReadOnly() );
        }
 
        /**
@@ -146,9 +137,12 @@ class GlobalTest extends MediaWikiTestCase {
         */
        public function testReadOnlyGlobalChange() {
                $this->assertFalse( wfReadOnlyReason() );
+
                $this->setMwGlobals( [
                        'wgReadOnly' => 'reason'
                ] );
+               $this->overrideMwServices();
+
                $this->assertSame( 'reason', wfReadOnlyReason() );
        }
 
index 34e5593..438d3e7 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 
-
 /**
  * @group Database
  */
@@ -286,6 +285,48 @@ class LinkerTest extends MediaWikiLangTestCase {
                );
        }
 
+       /**
+        * @covers Linker::generateRollback
+        * @dataProvider provideCasesForRollbackGeneration
+        */
+       public function testGenerateRollback( $rollbackEnabled, $expectedModules ) {
+               $this->markTestSkippedIfDbType( 'postgres' );
+
+               $context = RequestContext::getMain();
+               $user = $context->getUser();
+               $user->setOption( 'showrollbackconfirmation', $rollbackEnabled );
+
+               $pageData = $this->insertPage( 'Rollback_Test_Page' );
+               $page = WikiPage::factory( $pageData['title'] );
+
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( \MediaWiki\Revision\SlotRecord::MAIN,
+                       new TextContent( 'Technical Wishes 123!' )
+               );
+               $summary = CommentStoreComment::newUnsavedComment( 'Some comment!' );
+               $updater->saveRevision( $summary );
+
+               $rollbackOutput = Linker::generateRollback( $page->getRevision(), $context );
+               $modules = $context->getOutput()->getModules();
+
+               $this->assertEquals( $expectedModules, $modules );
+               $this->assertContains( 'rollback 1 edit', $rollbackOutput );
+       }
+
+       public static function provideCasesForRollbackGeneration() {
+               return [
+                       [
+                               true,
+                               [ 'mediawiki.page.rollback.confirmation' ]
+
+                       ],
+                       [
+                               false,
+                               []
+                       ]
+               ];
+       }
+
        public static function provideCasesForFormatLinksInComment() {
                // phpcs:disable Generic.Files.LineLength
                return [
diff --git a/tests/phpunit/includes/MWNamespaceTest.php b/tests/phpunit/includes/MWNamespaceTest.php
deleted file mode 100644 (file)
index 1b91a87..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-<?php
-/**
- * @author Antoine Musso
- * @copyright Copyright © 2011, Antoine Musso
- * @file
- */
-
-class MWNamespaceTest extends MediaWikiTestCase {
-
-       protected function setUp() {
-               parent::setUp();
-
-               $this->setMwGlobals( [
-                       'wgContentNamespaces' => [ NS_MAIN ],
-                       'wgNamespacesWithSubpages' => [
-                               NS_TALK => true,
-                               NS_USER => true,
-                               NS_USER_TALK => true,
-                       ],
-                       'wgCapitalLinks' => true,
-                       'wgCapitalLinkOverrides' => [],
-                       'wgNonincludableNamespaces' => [],
-               ] );
-       }
-
-       /**
-        * @todo Write more texts, handle $wgAllowImageMoving setting
-        * @covers MWNamespace::isMovable
-        */
-       public function testIsMovable() {
-               $this->assertFalse( MWNamespace::isMovable( NS_SPECIAL ) );
-       }
-
-       private function assertIsSubject( $ns ) {
-               $this->assertTrue( MWNamespace::isSubject( $ns ) );
-       }
-
-       private function assertIsNotSubject( $ns ) {
-               $this->assertFalse( MWNamespace::isSubject( $ns ) );
-       }
-
-       /**
-        * Please make sure to change testIsTalk() if you change the assertions below
-        * @covers MWNamespace::isSubject
-        */
-       public function testIsSubject() {
-               // Special namespaces
-               $this->assertIsSubject( NS_MEDIA );
-               $this->assertIsSubject( NS_SPECIAL );
-
-               // Subject pages
-               $this->assertIsSubject( NS_MAIN );
-               $this->assertIsSubject( NS_USER );
-               $this->assertIsSubject( 100 ); # user defined
-
-               // Talk pages
-               $this->assertIsNotSubject( NS_TALK );
-               $this->assertIsNotSubject( NS_USER_TALK );
-               $this->assertIsNotSubject( 101 ); # user defined
-       }
-
-       private function assertIsTalk( $ns ) {
-               $this->assertTrue( MWNamespace::isTalk( $ns ) );
-       }
-
-       private function assertIsNotTalk( $ns ) {
-               $this->assertFalse( MWNamespace::isTalk( $ns ) );
-       }
-
-       /**
-        * Reverse of testIsSubject().
-        * Please update testIsSubject() if you change assertions below
-        * @covers MWNamespace::isTalk
-        */
-       public function testIsTalk() {
-               // Special namespaces
-               $this->assertIsNotTalk( NS_MEDIA );
-               $this->assertIsNotTalk( NS_SPECIAL );
-
-               // Subject pages
-               $this->assertIsNotTalk( NS_MAIN );
-               $this->assertIsNotTalk( NS_USER );
-               $this->assertIsNotTalk( 100 ); # user defined
-
-               // Talk pages
-               $this->assertIsTalk( NS_TALK );
-               $this->assertIsTalk( NS_USER_TALK );
-               $this->assertIsTalk( 101 ); # user defined
-       }
-
-       /**
-        * @covers MWNamespace::getSubject
-        */
-       public function testGetSubject() {
-               // Special namespaces are their own subjects
-               $this->assertEquals( NS_MEDIA, MWNamespace::getSubject( NS_MEDIA ) );
-               $this->assertEquals( NS_SPECIAL, MWNamespace::getSubject( NS_SPECIAL ) );
-
-               $this->assertEquals( NS_MAIN, MWNamespace::getSubject( NS_TALK ) );
-               $this->assertEquals( NS_USER, MWNamespace::getSubject( NS_USER_TALK ) );
-       }
-
-       /**
-        * Regular getTalk() calls
-        * Namespaces without a talk page (NS_MEDIA, NS_SPECIAL) are tested in
-        * the function testGetTalkExceptions()
-        * @covers MWNamespace::getTalk
-        */
-       public function testGetTalk() {
-               $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_MAIN ) );
-               $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_TALK ) );
-               $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER ) );
-               $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER_TALK ) );
-       }
-
-       /**
-        * Exceptions with getTalk()
-        * NS_MEDIA does not have talk pages. MediaWiki raise an exception for them.
-        * @expectedException MWException
-        * @covers MWNamespace::getTalk
-        */
-       public function testGetTalkExceptionsForNsMedia() {
-               $this->assertNull( MWNamespace::getTalk( NS_MEDIA ) );
-       }
-
-       /**
-        * Exceptions with getTalk()
-        * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them.
-        * @expectedException MWException
-        * @covers MWNamespace::getTalk
-        */
-       public function testGetTalkExceptionsForNsSpecial() {
-               $this->assertNull( MWNamespace::getTalk( NS_SPECIAL ) );
-       }
-
-       /**
-        * Regular getAssociated() calls
-        * Namespaces without an associated page (NS_MEDIA, NS_SPECIAL) are tested in
-        * the function testGetAssociatedExceptions()
-        * @covers MWNamespace::getAssociated
-        */
-       public function testGetAssociated() {
-               $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) );
-               $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) );
-       }
-
-       # ## Exceptions with getAssociated()
-       # ## NS_MEDIA and NS_SPECIAL do not have talk pages. MediaWiki raises
-       # ## an exception for them.
-       /**
-        * @expectedException MWException
-        * @covers MWNamespace::getAssociated
-        */
-       public function testGetAssociatedExceptionsForNsMedia() {
-               $this->assertNull( MWNamespace::getAssociated( NS_MEDIA ) );
-       }
-
-       /**
-        * @expectedException MWException
-        * @covers MWNamespace::getAssociated
-        */
-       public function testGetAssociatedExceptionsForNsSpecial() {
-               $this->assertNull( MWNamespace::getAssociated( NS_SPECIAL ) );
-       }
-
-       /**
-        * Test MWNamespace::equals
-        * Note if we add a namespace registration system with keys like 'MAIN'
-        * we should add tests here for equivilance on things like 'MAIN' == 0
-        * and 'MAIN' == NS_MAIN.
-        * @covers MWNamespace::equals
-        */
-       public function testEquals() {
-               $this->assertTrue( MWNamespace::equals( NS_MAIN, NS_MAIN ) );
-               $this->assertTrue( MWNamespace::equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN'
-               $this->assertTrue( MWNamespace::equals( NS_USER, NS_USER ) );
-               $this->assertTrue( MWNamespace::equals( NS_USER, 2 ) );
-               $this->assertTrue( MWNamespace::equals( NS_USER_TALK, NS_USER_TALK ) );
-               $this->assertTrue( MWNamespace::equals( NS_SPECIAL, NS_SPECIAL ) );
-               $this->assertFalse( MWNamespace::equals( NS_MAIN, NS_TALK ) );
-               $this->assertFalse( MWNamespace::equals( NS_USER, NS_USER_TALK ) );
-               $this->assertFalse( MWNamespace::equals( NS_PROJECT, NS_TEMPLATE ) );
-       }
-
-       /**
-        * @covers MWNamespace::subjectEquals
-        */
-       public function testSubjectEquals() {
-               $this->assertSameSubject( NS_MAIN, NS_MAIN );
-               $this->assertSameSubject( NS_MAIN, 0 ); // In case we make NS_MAIN 'MAIN'
-               $this->assertSameSubject( NS_USER, NS_USER );
-               $this->assertSameSubject( NS_USER, 2 );
-               $this->assertSameSubject( NS_USER_TALK, NS_USER_TALK );
-               $this->assertSameSubject( NS_SPECIAL, NS_SPECIAL );
-               $this->assertSameSubject( NS_MAIN, NS_TALK );
-               $this->assertSameSubject( NS_USER, NS_USER_TALK );
-
-               $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE );
-               $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN );
-       }
-
-       /**
-        * @covers MWNamespace::subjectEquals
-        */
-       public function testSpecialAndMediaAreDifferentSubjects() {
-               $this->assertDifferentSubject(
-                       NS_MEDIA, NS_SPECIAL,
-                       "NS_MEDIA and NS_SPECIAL are different subject namespaces"
-               );
-               $this->assertDifferentSubject(
-                       NS_SPECIAL, NS_MEDIA,
-                       "NS_SPECIAL and NS_MEDIA are different subject namespaces"
-               );
-       }
-
-       public function provideHasTalkNamespace() {
-               return [
-                       [ NS_MEDIA, false ],
-                       [ NS_SPECIAL, false ],
-
-                       [ NS_MAIN, true ],
-                       [ NS_TALK, true ],
-                       [ NS_USER, true ],
-                       [ NS_USER_TALK, true ],
-
-                       [ 100, true ],
-                       [ 101, true ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideHasTalkNamespace
-        * @covers MWNamespace::hasTalkNamespace
-        *
-        * @param int $index
-        * @param bool $expected
-        */
-       public function testHasTalkNamespace( $index, $expected ) {
-               $actual = MWNamespace::hasTalkNamespace( $index );
-               $this->assertSame( $actual, $expected, "NS $index" );
-       }
-
-       /**
-        * @dataProvider provideHasTalkNamespace
-        * @covers MWNamespace::canTalk
-        *
-        * @param int $index
-        * @param bool $expected
-        */
-       public function testCanTalk( $index, $expected ) {
-               $actual = MWNamespace::canTalk( $index );
-               $this->assertSame( $actual, $expected, "NS $index" );
-       }
-
-       private function assertIsContent( $ns ) {
-               $this->assertTrue( MWNamespace::isContent( $ns ) );
-       }
-
-       private function assertIsNotContent( $ns ) {
-               $this->assertFalse( MWNamespace::isContent( $ns ) );
-       }
-
-       /**
-        * @covers MWNamespace::isContent
-        */
-       public function testIsContent() {
-               // NS_MAIN is a content namespace per DefaultSettings.php
-               // and per function definition.
-
-               $this->assertIsContent( NS_MAIN );
-
-               // Other namespaces which are not expected to be content
-
-               $this->assertIsNotContent( NS_MEDIA );
-               $this->assertIsNotContent( NS_SPECIAL );
-               $this->assertIsNotContent( NS_TALK );
-               $this->assertIsNotContent( NS_USER );
-               $this->assertIsNotContent( NS_CATEGORY );
-               $this->assertIsNotContent( 100 );
-       }
-
-       /**
-        * Similar to testIsContent() but alters the $wgContentNamespaces
-        * global variable.
-        * @covers MWNamespace::isContent
-        */
-       public function testIsContentAdvanced() {
-               global $wgContentNamespaces;
-
-               // Test that user defined namespace #252 is not content
-               $this->assertIsNotContent( 252 );
-
-               // Bless namespace # 252 as a content namespace
-               $wgContentNamespaces[] = 252;
-
-               $this->assertIsContent( 252 );
-
-               // Makes sure NS_MAIN was not impacted
-               $this->assertIsContent( NS_MAIN );
-       }
-
-       private function assertIsWatchable( $ns ) {
-               $this->assertTrue( MWNamespace::isWatchable( $ns ) );
-       }
-
-       private function assertIsNotWatchable( $ns ) {
-               $this->assertFalse( MWNamespace::isWatchable( $ns ) );
-       }
-
-       /**
-        * @covers MWNamespace::isWatchable
-        */
-       public function testIsWatchable() {
-               // Specials namespaces are not watchable
-               $this->assertIsNotWatchable( NS_MEDIA );
-               $this->assertIsNotWatchable( NS_SPECIAL );
-
-               // Core defined namespaces are watchables
-               $this->assertIsWatchable( NS_MAIN );
-               $this->assertIsWatchable( NS_TALK );
-
-               // Additional, user defined namespaces are watchables
-               $this->assertIsWatchable( 100 );
-               $this->assertIsWatchable( 101 );
-       }
-
-       private function assertHasSubpages( $ns ) {
-               $this->assertTrue( MWNamespace::hasSubpages( $ns ) );
-       }
-
-       private function assertHasNotSubpages( $ns ) {
-               $this->assertFalse( MWNamespace::hasSubpages( $ns ) );
-       }
-
-       /**
-        * @covers MWNamespace::hasSubpages
-        */
-       public function testHasSubpages() {
-               global $wgNamespacesWithSubpages;
-
-               // Special namespaces:
-               $this->assertHasNotSubpages( NS_MEDIA );
-               $this->assertHasNotSubpages( NS_SPECIAL );
-
-               // Namespaces without subpages
-               $this->assertHasNotSubpages( NS_MAIN );
-
-               $wgNamespacesWithSubpages[NS_MAIN] = true;
-               $this->assertHasSubpages( NS_MAIN );
-
-               $wgNamespacesWithSubpages[NS_MAIN] = false;
-               $this->assertHasNotSubpages( NS_MAIN );
-
-               // Some namespaces with subpages
-               $this->assertHasSubpages( NS_TALK );
-               $this->assertHasSubpages( NS_USER );
-               $this->assertHasSubpages( NS_USER_TALK );
-       }
-
-       /**
-        * @covers MWNamespace::getContentNamespaces
-        */
-       public function testGetContentNamespaces() {
-               global $wgContentNamespaces;
-
-               $this->assertEquals(
-                       [ NS_MAIN ],
-                       MWNamespace::getContentNamespaces(),
-                       '$wgContentNamespaces is an array with only NS_MAIN by default'
-               );
-
-               # test !is_array( $wgcontentNamespaces )
-               $wgContentNamespaces = '';
-               $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
-
-               $wgContentNamespaces = false;
-               $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
-
-               $wgContentNamespaces = null;
-               $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
-
-               $wgContentNamespaces = 5;
-               $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
-
-               # test $wgContentNamespaces === []
-               $wgContentNamespaces = [];
-               $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
-
-               # test !in_array( NS_MAIN, $wgContentNamespaces )
-               $wgContentNamespaces = [ NS_USER, NS_CATEGORY ];
-               $this->assertEquals(
-                       [ NS_MAIN, NS_USER, NS_CATEGORY ],
-                       MWNamespace::getContentNamespaces(),
-                       'NS_MAIN is forced in $wgContentNamespaces even if unwanted'
-               );
-
-               # test other cases, return $wgcontentNamespaces as is
-               $wgContentNamespaces = [ NS_MAIN ];
-               $this->assertEquals(
-                       [ NS_MAIN ],
-                       MWNamespace::getContentNamespaces()
-               );
-
-               $wgContentNamespaces = [ NS_MAIN, NS_USER, NS_CATEGORY ];
-               $this->assertEquals(
-                       [ NS_MAIN, NS_USER, NS_CATEGORY ],
-                       MWNamespace::getContentNamespaces()
-               );
-       }
-
-       /**
-        * @covers MWNamespace::getSubjectNamespaces
-        */
-       public function testGetSubjectNamespaces() {
-               $subjectsNS = MWNamespace::getSubjectNamespaces();
-               $this->assertContains( NS_MAIN, $subjectsNS,
-                       "Talk namespaces should have NS_MAIN" );
-               $this->assertNotContains( NS_TALK, $subjectsNS,
-                       "Talk namespaces should have NS_TALK" );
-
-               $this->assertNotContains( NS_MEDIA, $subjectsNS,
-                       "Talk namespaces should not have NS_MEDIA" );
-               $this->assertNotContains( NS_SPECIAL, $subjectsNS,
-                       "Talk namespaces should not have NS_SPECIAL" );
-       }
-
-       /**
-        * @covers MWNamespace::getTalkNamespaces
-        */
-       public function testGetTalkNamespaces() {
-               $talkNS = MWNamespace::getTalkNamespaces();
-               $this->assertContains( NS_TALK, $talkNS,
-                       "Subject namespaces should have NS_TALK" );
-               $this->assertNotContains( NS_MAIN, $talkNS,
-                       "Subject namespaces should not have NS_MAIN" );
-
-               $this->assertNotContains( NS_MEDIA, $talkNS,
-                       "Subject namespaces should not have NS_MEDIA" );
-               $this->assertNotContains( NS_SPECIAL, $talkNS,
-                       "Subject namespaces should not have NS_SPECIAL" );
-       }
-
-       private function assertIsCapitalized( $ns ) {
-               $this->assertTrue( MWNamespace::isCapitalized( $ns ) );
-       }
-
-       private function assertIsNotCapitalized( $ns ) {
-               $this->assertFalse( MWNamespace::isCapitalized( $ns ) );
-       }
-
-       /**
-        * Some namespaces are always capitalized per code definition
-        * in MWNamespace::$alwaysCapitalizedNamespaces
-        * @covers MWNamespace::isCapitalized
-        */
-       public function testIsCapitalizedHardcodedAssertions() {
-               // NS_MEDIA and NS_FILE are treated the same
-               $this->assertEquals(
-                       MWNamespace::isCapitalized( NS_MEDIA ),
-                       MWNamespace::isCapitalized( NS_FILE ),
-                       'NS_MEDIA and NS_FILE have same capitalization rendering'
-               );
-
-               // Boths are capitalized by default
-               $this->assertIsCapitalized( NS_MEDIA );
-               $this->assertIsCapitalized( NS_FILE );
-
-               // Always capitalized namespaces
-               // @see MWNamespace::$alwaysCapitalizedNamespaces
-               $this->assertIsCapitalized( NS_SPECIAL );
-               $this->assertIsCapitalized( NS_USER );
-               $this->assertIsCapitalized( NS_MEDIAWIKI );
-       }
-
-       /**
-        * Follows up for testIsCapitalizedHardcodedAssertions() but alter the
-        * global $wgCapitalLink setting to have extended coverage.
-        *
-        * MWNamespace::isCapitalized() rely on two global settings:
-        *   $wgCapitalLinkOverrides = []; by default
-        *   $wgCapitalLinks = true; by default
-        * This function test $wgCapitalLinks
-        *
-        * Global setting correctness is tested against the NS_PROJECT and
-        * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials
-        * @covers MWNamespace::isCapitalized
-        */
-       public function testIsCapitalizedWithWgCapitalLinks() {
-               global $wgCapitalLinks;
-
-               $this->assertIsCapitalized( NS_PROJECT );
-               $this->assertIsCapitalized( NS_PROJECT_TALK );
-
-               $wgCapitalLinks = false;
-
-               // hardcoded namespaces (see above function) are still capitalized:
-               $this->assertIsCapitalized( NS_SPECIAL );
-               $this->assertIsCapitalized( NS_USER );
-               $this->assertIsCapitalized( NS_MEDIAWIKI );
-
-               // setting is correctly applied
-               $this->assertIsNotCapitalized( NS_PROJECT );
-               $this->assertIsNotCapitalized( NS_PROJECT_TALK );
-       }
-
-       /**
-        * Counter part for MWNamespace::testIsCapitalizedWithWgCapitalLinks() now
-        * testing the $wgCapitalLinkOverrides global.
-        *
-        * @todo split groups of assertions in autonomous testing functions
-        * @covers MWNamespace::isCapitalized
-        */
-       public function testIsCapitalizedWithWgCapitalLinkOverrides() {
-               global $wgCapitalLinkOverrides;
-
-               // Test default settings
-               $this->assertIsCapitalized( NS_PROJECT );
-               $this->assertIsCapitalized( NS_PROJECT_TALK );
-
-               // hardcoded namespaces (see above function) are capitalized:
-               $this->assertIsCapitalized( NS_SPECIAL );
-               $this->assertIsCapitalized( NS_USER );
-               $this->assertIsCapitalized( NS_MEDIAWIKI );
-
-               // Hardcoded namespaces remains capitalized
-               $wgCapitalLinkOverrides[NS_SPECIAL] = false;
-               $wgCapitalLinkOverrides[NS_USER] = false;
-               $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false;
-
-               $this->assertIsCapitalized( NS_SPECIAL );
-               $this->assertIsCapitalized( NS_USER );
-               $this->assertIsCapitalized( NS_MEDIAWIKI );
-
-               $wgCapitalLinkOverrides[NS_PROJECT] = false;
-               $this->assertIsNotCapitalized( NS_PROJECT );
-
-               $wgCapitalLinkOverrides[NS_PROJECT] = true;
-               $this->assertIsCapitalized( NS_PROJECT );
-
-               unset( $wgCapitalLinkOverrides[NS_PROJECT] );
-               $this->assertIsCapitalized( NS_PROJECT );
-       }
-
-       /**
-        * @covers MWNamespace::hasGenderDistinction
-        */
-       public function testHasGenderDistinction() {
-               // Namespaces with gender distinctions
-               $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER ) );
-               $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER_TALK ) );
-
-               // Other ones, "genderless"
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA ) );
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_SPECIAL ) );
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN ) );
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK ) );
-       }
-
-       /**
-        * @covers MWNamespace::isNonincludable
-        */
-       public function testIsNonincludable() {
-               global $wgNonincludableNamespaces;
-
-               $wgNonincludableNamespaces = [ NS_USER ];
-
-               $this->assertTrue( MWNamespace::isNonincludable( NS_USER ) );
-               $this->assertFalse( MWNamespace::isNonincludable( NS_TEMPLATE ) );
-       }
-
-       private function assertSameSubject( $ns1, $ns2, $msg = '' ) {
-               $this->assertTrue( MWNamespace::subjectEquals( $ns1, $ns2 ), $msg );
-       }
-
-       private function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
-               $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2 ), $msg );
-       }
-
-       public function provideGetCategoryLinkType() {
-               return [
-                       [ NS_MAIN, 'page' ],
-                       [ NS_TALK, 'page' ],
-                       [ NS_USER, 'page' ],
-                       [ NS_USER_TALK, 'page' ],
-
-                       [ NS_FILE, 'file' ],
-                       [ NS_FILE_TALK, 'page' ],
-
-                       [ NS_CATEGORY, 'subcat' ],
-                       [ NS_CATEGORY_TALK, 'page' ],
-
-                       [ 100, 'page' ],
-                       [ 101, 'page' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideGetCategoryLinkType
-        * @covers MWNamespace::getCategoryLinkType
-        *
-        * @param int $index
-        * @param string $expected
-        */
-       public function testGetCategoryLinkType( $index, $expected ) {
-               $actual = MWNamespace::getCategoryLinkType( $index );
-               $this->assertSame( $expected, $actual, "NS $index" );
-       }
-}
index 1cd40ed..8fa0cd6 100644 (file)
@@ -11,7 +11,7 @@ use Wikimedia\Services\ServiceDisabledException;
  * @group MediaWiki
  */
 class MediaWikiServicesTest extends MediaWikiTestCase {
-       private $deprecatedServices = [ 'CryptRand' ];
+       private $deprecatedServices = [];
 
        /**
         * @return Config
@@ -364,7 +364,7 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                } ) );
 
                $sortedNames = $names;
-               sort( $sortedNames );
+               natcasesort( $sortedNames );
 
                $this->assertSame( $sortedNames, $names,
                        'Please keep service getters sorted alphabetically' );
index 7bb5c38..097aef7 100644 (file)
@@ -12,6 +12,14 @@ class OutputPageTest extends MediaWikiTestCase {
        const SCREEN_MEDIA_QUERY = 'screen and (min-width: 982px)';
        const SCREEN_ONLY_MEDIA_QUERY = 'only screen and (min-width: 982px)';
 
+       // @codingStandardsIgnoreStart Generic.Files.LineLength
+       const RSS_RC_LINK = '<link rel="alternate" type="application/rss+xml" title=" RSS feed" href="/w/index.php?title=Special:RecentChanges&amp;feed=rss"/>';
+       const ATOM_RC_LINK = '<link rel="alternate" type="application/atom+xml" title=" Atom feed" href="/w/index.php?title=Special:RecentChanges&amp;feed=atom"/>';
+
+       const RSS_TEST_LINK = '<link rel="alternate" type="application/rss+xml" title="&quot;Test&quot; RSS feed" href="fake-link"/>';
+       const ATOM_TEST_LINK = '<link rel="alternate" type="application/atom+xml" title="&quot;Test&quot; Atom feed" href="fake-link"/>';
+       // @codingStandardsIgnoreEnd
+
        // Ensure that we don't affect the global ResourceLoader state.
        protected function setUp() {
                parent::setUp();
@@ -51,6 +59,64 @@ class OutputPageTest extends MediaWikiTestCase {
                ];
        }
 
+       private function setupFeedLinks( $feed, $types ) {
+               $outputPage = $this->newInstance( [
+                       'AdvertisedFeedTypes' => $types,
+                       'Feed' => $feed,
+                       'OverrideSiteFeed' => false,
+                       'Script' => '/w',
+                       'Sitename' => false,
+               ] );
+               $outputPage->setTitle( Title::makeTitle( NS_MAIN, 'Test' ) );
+               $this->setMwGlobals( [
+                       'wgScript' => '/w/index.php',
+               ] );
+               return $outputPage;
+       }
+
+       private function assertFeedLinks( $outputPage, $message, $present, $non_present ) {
+               $links = $outputPage->getHeadLinksArray();
+               foreach ( $present as $link ) {
+                       $this->assertContains( $link, $links, $message );
+               }
+               foreach ( $non_present as $link ) {
+                       $this->assertNotContains( $link, $links, $message );
+               }
+       }
+
+       private function assertFeedUILinks( $outputPage, $ui_links ) {
+               if ( $ui_links ) {
+                       $this->assertTrue( $outputPage->isSyndicated(), 'Syndication should be offered' );
+                       $this->assertGreaterThan( 0, count( $outputPage->getSyndicationLinks() ),
+                               'Some syndication links should be there' );
+               } else {
+                       $this->assertFalse( $outputPage->isSyndicated(), 'No syndication should be offered' );
+                       $this->assertEquals( 0, count( $outputPage->getSyndicationLinks() ),
+                               'No syndication links should be there' );
+               }
+       }
+
+       public static function provideFeedLinkData() {
+               return [
+                       [
+                               true, [ 'rss' ], 'Only RSS RC link should be offerred',
+                               [ self::RSS_RC_LINK ], [ self::ATOM_RC_LINK ]
+                       ],
+                       [
+                               true, [ 'atom' ], 'Only Atom RC link should be offerred',
+                               [ self::ATOM_RC_LINK ], [ self::RSS_RC_LINK ]
+                       ],
+                       [
+                               true, [], 'No RC feed formats should be offerred',
+                               [], [ self::ATOM_RC_LINK, self::RSS_RC_LINK ]
+                       ],
+                       [
+                               false, [ 'atom' ], 'No RC feeds should be offerred',
+                               [], [ self::ATOM_RC_LINK, self::RSS_RC_LINK ]
+                       ],
+               ];
+       }
+
        /**
         * @covers OutputPage::setCopyrightUrl
         * @covers OutputPage::getHeadLinksArray
@@ -65,6 +131,67 @@ class OutputPageTest extends MediaWikiTestCase {
                );
        }
 
+       /**
+        * @dataProvider provideFeedLinkData
+        * @covers OutputPage::getHeadLinksArray
+        */
+       public function testRecentChangesFeed( $feed, $advertised_feed_types,
+                               $message, $present, $non_present ) {
+               $outputPage = $this->setupFeedLinks( $feed, $advertised_feed_types );
+               $this->assertFeedLinks( $outputPage, $message, $present, $non_present );
+       }
+
+       public static function provideAdditionalFeedData() {
+               return [
+                       [
+                               true, [ 'atom' ], 'Additional Atom feed should be offered',
+                               'atom',
+                               [ self::ATOM_TEST_LINK, self::ATOM_RC_LINK ],
+                               [ self::RSS_TEST_LINK, self::RSS_RC_LINK ],
+                               true,
+                       ],
+                       [
+                               true, [ 'rss' ], 'Additional RSS feed should be offered',
+                               'rss',
+                               [ self::RSS_TEST_LINK, self::RSS_RC_LINK ],
+                               [ self::ATOM_TEST_LINK, self::ATOM_RC_LINK ],
+                               true,
+                       ],
+                       [
+                               true, [ 'rss' ], 'Additional Atom feed should NOT be offered with RSS enabled',
+                               'atom',
+                               [ self::RSS_RC_LINK ],
+                               [ self::RSS_TEST_LINK, self::ATOM_TEST_LINK, self::ATOM_RC_LINK ],
+                               false,
+                       ],
+                       [
+                               false, [ 'atom' ], 'Additional Atom feed should NOT be offered, all feeds disabled',
+                               'atom',
+                               [],
+                               [
+                                       self::RSS_TEST_LINK, self::ATOM_TEST_LINK,
+                                       self::ATOM_RC_LINK, self::ATOM_RC_LINK,
+                               ],
+                               false,
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideAdditionalFeedData
+        * @covers OutputPage::getHeadLinksArray
+        * @covers OutputPage::addFeedLink
+        * @covers OutputPage::getSyndicationLinks
+        * @covers OutputPage::isSyndicated
+        */
+       public function testAdditionalFeeds( $feed, $advertised_feed_types, $message,
+                       $additional_feed_type, $present, $non_present, $any_ui_links ) {
+               $outputPage = $this->setupFeedLinks( $feed, $advertised_feed_types );
+               $outputPage->addFeedLink( $additional_feed_type, 'fake-link' );
+               $this->assertFeedLinks( $outputPage, $message, $present, $non_present );
+               $this->assertFeedUILinks( $outputPage, $any_ui_links );
+       }
+
        // @todo How to test setStatusCode?
 
        /**
@@ -797,7 +924,7 @@ class OutputPageTest extends MediaWikiTestCase {
         * @covers OutputPage::isSyndicated
         */
        public function testSetSyndicated() {
-               $op = $this->newInstance();
+               $op = $this->newInstance( [ 'Feed' => true ] );
                $this->assertFalse( $op->isSyndicated() );
 
                $op->setSyndicated();
@@ -805,6 +932,12 @@ class OutputPageTest extends MediaWikiTestCase {
 
                $op->setSyndicated( false );
                $this->assertFalse( $op->isSyndicated() );
+
+               $op = $this->newInstance(); // Feed => false by default
+               $this->assertFalse( $op->isSyndicated() );
+
+               $op->setSyndicated();
+               $this->assertFalse( $op->isSyndicated() );
        }
 
        /**
@@ -814,7 +947,7 @@ class OutputPageTest extends MediaWikiTestCase {
         * @covers OutputPage::getSyndicationLinks()
         */
        public function testFeedLinks() {
-               $op = $this->newInstance();
+               $op = $this->newInstance( [ 'Feed' => true ] );
                $this->assertSame( [], $op->getSyndicationLinks() );
 
                $op->addFeedLink( 'not a supported format', 'abc' );
@@ -839,6 +972,13 @@ class OutputPageTest extends MediaWikiTestCase {
                        $expected[$type] = $op->getTitle()->getLocalURL( "feed=$type&apples=oranges" );
                }
                $this->assertSame( $expected, $op->getSyndicationLinks() );
+
+               $op = $this->newInstance(); // Feed => false by default
+               $this->assertSame( [], $op->getSyndicationLinks() );
+
+               $op->addFeedLink( $feedTypes[0], 'def' );
+               $this->assertFalse( $op->isSyndicated() );
+               $this->assertSame( [], $op->getSyndicationLinks() );
        }
 
        /**
@@ -1486,7 +1626,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        "<p><b>Bold</b>\n</p>",
                                ], 'No section edit links' => [
                                        [ '== Title ==' ],
-                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>\n",
+                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>",
                                ],
                        ],
                        'addWikiTextWithTitle' => [
@@ -1515,7 +1655,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        '<p>* Not a list</p>',
                                ], 'No section edit links' => [
                                        [ '== Title ==' ],
-                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>\n",
+                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>",
                                ], 'With title at start' => [
                                        [ '* {{PAGENAME}}', true, Title::newFromText( 'Talk:Some page' ) ],
                                        "<ul><li>Some page</li></ul>\n",
@@ -1531,10 +1671,10 @@ class OutputPageTest extends MediaWikiTestCase {
                                // Preferred interface: output is tidied
                                'SpecialNewimages' => [
                                        [ "<p lang='en' dir='ltr'>\nMy message" ],
-                                       '<p lang="en" dir="ltr">' . "\nMy message\n</p>"
+                                       '<p lang="en" dir="ltr">' . "\nMy message</p>"
                                ], 'List at start' => [
                                        [ '* List' ],
-                                       "<ul><li>List</li></ul>\n",
+                                       "<ul><li>List</li></ul>",
                                ], 'List not at start' => [
                                        [ '* <b>Not a list', false ],
                                        '<p>* <b>Not a list</b></p>',
@@ -1546,7 +1686,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        "<p>* Some page</p>",
                                ], 'EditPage' => [
                                        [ "<div class='mw-editintro'>{{PAGENAME}}", true, Title::newFromText( 'Talk:Some page' ) ],
-                                       '<div class="mw-editintro">' . "Some page\n</div>"
+                                       '<div class="mw-editintro">' . "Some page</div>"
                                ],
                        ],
                        'wrapWikiTextAsInterface' => [
@@ -1555,7 +1695,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        "<div class=\"wrapperClass\"><p>text\n</p></div>"
                                ], 'Spurious </div>' => [
                                        [ 'wrapperClass', 'text</div><div>more' ],
-                                       "<div class=\"wrapperClass\"><p>text</p><div>more\n</div></div>"
+                                       "<div class=\"wrapperClass\"><p>text</p><div>more</div></div>"
                                ], 'Extra newlines would break <p> wrappers' => [
                                        [ 'two classes', "1\n\n2\n\n3" ],
                                        "<div class=\"two classes\"><p>1\n</p><p>2\n</p><p>3\n</p></div>"
@@ -1744,7 +1884,6 @@ class OutputPageTest extends MediaWikiTestCase {
        // @todo Make sure to test the following in addParserOutputMetadata() as well when we add tests
        // for them:
        //   * addModules()
-       //   * addModuleScripts()
        //   * addModuleStyles()
        //   * addJsConfigVars()
        //   * enableOOUI()
@@ -1830,12 +1969,12 @@ class OutputPageTest extends MediaWikiTestCase {
                return [
                        'List at start of line (content)' => [
                                [ '* List', true, false ],
-                               "<div class=\"mw-parser-output\"><ul><li>List</li></ul>\n</div>",
-                               "<ul><li>List</li></ul>\n",
+                               "<div class=\"mw-parser-output\"><ul><li>List</li></ul></div>",
+                               "<ul><li>List</li></ul>",
                        ],
                        'List at start of line (interface)' => [
                                [ '* List', true, true ],
-                               "<ul><li>List</li></ul>\n",
+                               "<ul><li>List</li></ul>",
                        ],
                        'List not at start (content)' => [
                                [ "* ''Not'' list", false, false ],
@@ -1873,9 +2012,8 @@ class OutputPageTest extends MediaWikiTestCase {
                        'No section edit links' => [
                                [ '== Header ==' ],
                                '<div class="mw-parser-output"><h2><span class="mw-headline" id="Header">' .
-                                       "Header</span></h2>\n</div>",
-                               '<h2><span class="mw-headline" id="Header">Header</span></h2>' .
-                                       "\n",
+                                       "Header</span></h2></div>",
+                               '<h2><span class="mw-headline" id="Header">Header</span></h2>',
                        ]
                ];
        }
@@ -1926,7 +2064,7 @@ class OutputPageTest extends MediaWikiTestCase {
                return [
                        'List at start of line' => [
                                [ '* List', true ],
-                               "<ul><li>List</li></ul>\n",
+                               "<ul><li>List</li></ul>",
                        ],
                        'List not at start' => [
                                [ "* ''Not'' list", false ],
@@ -1945,8 +2083,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        ],
                        'No section edit links' => [
                                [ '== Header ==' ],
-                               '<h2><span class="mw-headline" id="Header">Header</span></h2>' .
-                                       "\n",
+                               '<h2><span class="mw-headline" id="Header">Header</span></h2>',
                        ]
                ];
        }
@@ -2575,14 +2712,14 @@ class OutputPageTest extends MediaWikiTestCase {
                        [
                                [ 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS ],
                                "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
-                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback");'
+                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback");'
                                        . "});</script>"
                        ],
                        // Multiple only=styles load
                        [
                                [ [ 'test.baz', 'test.foo', 'test.bar' ], ResourceLoaderModule::TYPE_STYLES ],
 
-                               '<link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.bar%2Cbaz%2Cfoo&amp;only=styles&amp;skin=fallback"/>'
+                               '<link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?lang=en&amp;modules=test.bar%2Cbaz%2Cfoo&amp;only=styles&amp;skin=fallback"/>'
                        ],
                        // Private embed (only=scripts)
                        [
@@ -2607,14 +2744,14 @@ class OutputPageTest extends MediaWikiTestCase {
                        // noscript group
                        [
                                [ 'test.noscript', ResourceLoaderModule::TYPE_STYLES ],
-                               '<noscript><link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.noscript&amp;only=styles&amp;skin=fallback"/></noscript>'
+                               '<noscript><link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?lang=en&amp;modules=test.noscript&amp;only=styles&amp;skin=fallback"/></noscript>'
                        ],
                        // Load two modules in separate groups
                        [
                                [ [ 'test.group.foo', 'test.group.bar' ], ResourceLoaderModule::TYPE_COMBINED ],
                                "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
-                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
-                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
+                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
+                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
                                        . "});</script>"
                        ],
                ];
@@ -2678,13 +2815,13 @@ class OutputPageTest extends MediaWikiTestCase {
                        'default logged-out' => [
                                'exemptStyleModules' => [ 'site' => [ 'site.styles' ] ],
                                '<meta name="ResourceLoaderDynamicStyles" content=""/>' . "\n" .
-                               '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=en&amp;modules=site.styles&amp;only=styles&amp;skin=fallback"/>',
+                               '<link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=site.styles&amp;only=styles&amp;skin=fallback"/>',
                        ],
                        'default logged-in' => [
                                'exemptStyleModules' => [ 'site' => [ 'site.styles' ], 'user' => [ 'user.styles' ] ],
                                '<meta name="ResourceLoaderDynamicStyles" content=""/>' . "\n" .
-                               '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=en&amp;modules=site.styles&amp;only=styles&amp;skin=fallback"/>' . "\n" .
-                               '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=en&amp;modules=user.styles&amp;only=styles&amp;skin=fallback&amp;version=1ai9g6t"/>',
+                               '<link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=site.styles&amp;only=styles&amp;skin=fallback"/>' . "\n" .
+                               '<link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=user.styles&amp;only=styles&amp;skin=fallback&amp;version=1ai9g6t"/>',
                        ],
                        'custom modules' => [
                                'exemptStyleModules' => [
@@ -2692,10 +2829,10 @@ class OutputPageTest extends MediaWikiTestCase {
                                        'user' => [ 'user.styles', 'example.user' ],
                                ],
                                '<meta name="ResourceLoaderDynamicStyles" content=""/>' . "\n" .
-                               '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=en&amp;modules=example.site.a%2Cb&amp;only=styles&amp;skin=fallback"/>' . "\n" .
-                               '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=en&amp;modules=site.styles&amp;only=styles&amp;skin=fallback"/>' . "\n" .
-                               '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=en&amp;modules=example.user&amp;only=styles&amp;skin=fallback&amp;version=0a56zyi"/>' . "\n" .
-                               '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=en&amp;modules=user.styles&amp;only=styles&amp;skin=fallback&amp;version=1ai9g6t"/>',
+                               '<link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=example.site.a%2Cb&amp;only=styles&amp;skin=fallback"/>' . "\n" .
+                               '<link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=site.styles&amp;only=styles&amp;skin=fallback"/>' . "\n" .
+                               '<link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=example.user&amp;only=styles&amp;skin=fallback&amp;version=0a56zyi"/>' . "\n" .
+                               '<link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=user.styles&amp;only=styles&amp;skin=fallback&amp;version=1ai9g6t"/>',
                        ],
                ];
                // phpcs:enable
diff --git a/tests/phpunit/includes/Permissions/PermissionManagerTest.php b/tests/phpunit/includes/Permissions/PermissionManagerTest.php
new file mode 100644 (file)
index 0000000..7f5ec40
--- /dev/null
@@ -0,0 +1,1410 @@
+<?php
+
+namespace MediaWiki\Tests\Permissions;
+
+use Action;
+use Block;
+use MediaWikiLangTestCase;
+use RequestContext;
+use Title;
+use User;
+use MediaWiki\Block\Restriction\NamespaceRestriction;
+use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Permissions\PermissionManager;
+
+/**
+ * @group Database
+ *
+ * @covers \MediaWiki\Permissions\PermissionManager
+ */
+class PermissionManagerTest extends MediaWikiLangTestCase {
+
+       /**
+        * @var string
+        */
+       protected $userName, $altUserName;
+
+       /**
+        * @var Title
+        */
+       protected $title;
+
+       /**
+        * @var User
+        */
+       protected $user, $anonUser, $userUser, $altUser;
+
+       /**
+        * @var PermissionManager
+        */
+       protected $permissionManager;
+
+       /** Constant for self::testIsBlockedFrom */
+       const USER_TALK_PAGE = '<user talk page>';
+
+       protected function setUp() {
+               parent::setUp();
+
+               $localZone = 'UTC';
+               $localOffset = date( 'Z' ) / 60;
+
+               $this->setMwGlobals( [
+                       'wgLocaltimezone' => $localZone,
+                       'wgLocalTZoffset' => $localOffset,
+                       'wgNamespaceProtection' => [
+                               NS_MEDIAWIKI => 'editinterface',
+                       ],
+               ] );
+               // Without this testUserBlock will use a non-English context on non-English MediaWiki
+               // installations (because of how Title::checkUserBlock is implemented) and fail.
+               RequestContext::resetMain();
+
+               $this->userName = 'Useruser';
+               $this->altUserName = 'Altuseruser';
+               date_default_timezone_set( $localZone );
+
+               $this->title = Title::makeTitle( NS_MAIN, "Main Page" );
+               if ( !isset( $this->userUser ) || !( $this->userUser instanceof User ) ) {
+                       $this->userUser = User::newFromName( $this->userName );
+
+                       if ( !$this->userUser->getId() ) {
+                               $this->userUser = User::createNew( $this->userName, [
+                                       "email" => "test@example.com",
+                                       "real_name" => "Test User" ] );
+                               $this->userUser->load();
+                       }
+
+                       $this->altUser = User::newFromName( $this->altUserName );
+                       if ( !$this->altUser->getId() ) {
+                               $this->altUser = User::createNew( $this->altUserName, [
+                                       "email" => "alttest@example.com",
+                                       "real_name" => "Test User Alt" ] );
+                               $this->altUser->load();
+                       }
+
+                       $this->anonUser = User::newFromId( 0 );
+
+                       $this->user = $this->userUser;
+               }
+
+               $this->permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
+
+               $this->overrideMwServices();
+       }
+
+       protected function setUserPerm( $perm ) {
+               // Setting member variables is evil!!!
+
+               if ( is_array( $perm ) ) {
+                       $this->user->mRights = $perm;
+               } else {
+                       $this->user->mRights = [ $perm ];
+               }
+       }
+
+       protected function setTitle( $ns, $title = "Main_Page" ) {
+               $this->title = Title::makeTitle( $ns, $title );
+       }
+
+       protected function setUser( $userName = null ) {
+               if ( $userName === 'anon' ) {
+                       $this->user = $this->anonUser;
+               } elseif ( $userName === null || $userName === $this->userName ) {
+                       $this->user = $this->userUser;
+               } else {
+                       $this->user = $this->altUser;
+               }
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        *
+        * This test is failing per T201776.
+        *
+        * @group Broken
+        * @covers \MediaWiki\Permissions\PermissionManager::checkQuickPermissions
+        */
+       public function testQuickPermissions() {
+               $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
+               getFormattedNsText( NS_PROJECT );
+
+               $this->setUser( 'anon' );
+               $this->setTitle( NS_TALK );
+               $this->setUserPerm( "createtalk" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setTitle( NS_TALK );
+               $this->setUserPerm( "createpage" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [ [ "nocreatetext" ] ], $res );
+
+               $this->setTitle( NS_TALK );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
+
+               $this->setTitle( NS_MAIN );
+               $this->setUserPerm( "createpage" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setTitle( NS_MAIN );
+               $this->setUserPerm( "createtalk" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
+
+               $this->setUser( $this->userName );
+               $this->setTitle( NS_TALK );
+               $this->setUserPerm( "createtalk" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setTitle( NS_TALK );
+               $this->setUserPerm( "createpage" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
+
+               $this->setTitle( NS_TALK );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
+
+               $this->setTitle( NS_MAIN );
+               $this->setUserPerm( "createpage" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setTitle( NS_MAIN );
+               $this->setUserPerm( "createtalk" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
+
+               $this->setTitle( NS_MAIN );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'create', $this->user, $this->title );
+               $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
+
+               $this->setUser( 'anon' );
+               $this->setTitle( NS_USER, $this->userName . '' );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_USER, $this->userName . '/subpage' );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_USER, $this->userName . '' );
+               $this->setUserPerm( "move-rootuserpages" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_USER, $this->userName . '/subpage' );
+               $this->setUserPerm( "move-rootuserpages" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_USER, $this->userName . '' );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_USER, $this->userName . '/subpage' );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_USER, $this->userName . '' );
+               $this->setUserPerm( "move-rootuserpages" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_USER, $this->userName . '/subpage' );
+               $this->setUserPerm( "move-rootuserpages" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenologintext' ] ], $res );
+
+               $this->setUser( $this->userName );
+               $this->setTitle( NS_FILE, "img.png" );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], $res );
+
+               $this->setTitle( NS_FILE, "img.png" );
+               $this->setUserPerm( "movefile" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
+
+               $this->setUser( 'anon' );
+               $this->setTitle( NS_FILE, "img.png" );
+               $this->setUserPerm( "" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ], $res );
+
+               $this->setTitle( NS_FILE, "img.png" );
+               $this->setUserPerm( "movefile" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move', $this->user, $this->title );
+               $this->assertEquals( [ [ 'movenologintext' ] ], $res );
+
+               $this->setUser( $this->userName );
+               $this->setUserPerm( "move" );
+               $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
+
+               $this->setUserPerm( "" );
+               $this->runGroupPermissions(
+                       'move',
+                       [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ]
+               );
+
+               $this->setUser( 'anon' );
+               $this->setUserPerm( "move" );
+               $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
+
+               $this->setUserPerm( "" );
+               $this->runGroupPermissions(
+                       'move',
+                       [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ],
+                       [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ]
+               );
+
+               if ( $this->isWikitextNS( NS_MAIN ) ) {
+                       // NOTE: some content models don't allow moving
+                       // @todo find a Wikitext namespace for testing
+
+                       $this->setTitle( NS_MAIN );
+                       $this->setUser( 'anon' );
+                       $this->setUserPerm( "move" );
+                       $this->runGroupPermissions( 'move', [] );
+
+                       $this->setUserPerm( "" );
+                       $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ],
+                               [ [ 'movenologintext' ] ] );
+
+                       $this->setUser( $this->userName );
+                       $this->setUserPerm( "" );
+                       $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ] );
+
+                       $this->setUserPerm( "move" );
+                       $this->runGroupPermissions( 'move', [] );
+
+                       $this->setUser( 'anon' );
+                       $this->setUserPerm( 'move' );
+                       $res = $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title );
+                       $this->assertEquals( [], $res );
+
+                       $this->setUserPerm( '' );
+                       $res = $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title );
+                       $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
+               }
+
+               $this->setTitle( NS_USER );
+               $this->setUser( $this->userName );
+               $this->setUserPerm( [ "move", "move-rootuserpages" ] );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move-target', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setUserPerm( "move" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move-target', $this->user, $this->title );
+               $this->assertEquals( [ [ 'cant-move-to-user-page' ] ], $res );
+
+               $this->setUser( 'anon' );
+               $this->setUserPerm( [ "move", "move-rootuserpages" ] );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move-target', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setTitle( NS_USER, "User/subpage" );
+               $this->setUserPerm( [ "move", "move-rootuserpages" ] );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move-target', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setUserPerm( "move" );
+               $res = $this->permissionManager
+                       ->getPermissionErrors( 'move-target', $this->user, $this->title );
+               $this->assertEquals( [], $res );
+
+               $this->setUser( 'anon' );
+               $check = [
+                       'edit' => [
+                               [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ] ],
+                               [ [ 'badaccess-group0' ] ],
+                               [],
+                               true
+                       ],
+                       'protect' => [
+                               [ [
+                                       'badaccess-groups',
+                                       "[[$prefix:Administrators|Administrators]]", 1 ],
+                                       [ 'protect-cantedit'
+                                       ] ],
+                               [ [ 'badaccess-group0' ], [ 'protect-cantedit' ] ],
+                               [ [ 'protect-cantedit' ] ],
+                               false
+                       ],
+                       '' => [ [], [], [], true ]
+               ];
+
+               foreach ( [ "edit", "protect", "" ] as $action ) {
+                       $this->setUserPerm( null );
+                       $this->assertEquals( $check[$action][0],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, true ) );
+                       $this->assertEquals( $check[$action][0],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) );
+                       $this->assertEquals( $check[$action][0],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) );
+
+                       global $wgGroupPermissions;
+                       $old = $wgGroupPermissions;
+                       $wgGroupPermissions = [];
+
+                       $this->assertEquals( $check[$action][1],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, true ) );
+                       $this->assertEquals( $check[$action][1],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) );
+                       $this->assertEquals( $check[$action][1],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) );
+                       $wgGroupPermissions = $old;
+
+                       $this->setUserPerm( $action );
+                       $this->assertEquals( $check[$action][2],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, true ) );
+                       $this->assertEquals( $check[$action][2],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) );
+                       $this->assertEquals( $check[$action][2],
+                               $this->permissionManager
+                                       ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) );
+
+                       $this->setUserPerm( $action );
+                       $this->assertEquals( $check[$action][3],
+                               $this->permissionManager->userCan( $action, $this->user, $this->title, true ) );
+                       $this->assertEquals( $check[$action][3],
+                               $this->permissionManager->userCan( $action, $this->user, $this->title,
+                                       PermissionManager::RIGOR_QUICK ) );
+                       # count( User::getGroupsWithPermissions( $action ) ) < 1
+               }
+       }
+
+       protected function runGroupPermissions( $action, $result, $result2 = null ) {
+               global $wgGroupPermissions;
+
+               if ( $result2 === null ) {
+                       $result2 = $result;
+               }
+
+               $wgGroupPermissions['autoconfirmed']['move'] = false;
+               $wgGroupPermissions['user']['move'] = false;
+               $res = $this->permissionManager
+                       ->getPermissionErrors( $action, $this->user, $this->title );
+               $this->assertEquals( $result, $res );
+
+               $wgGroupPermissions['autoconfirmed']['move'] = true;
+               $wgGroupPermissions['user']['move'] = false;
+               $res = $this->permissionManager
+                       ->getPermissionErrors( $action, $this->user, $this->title );
+               $this->assertEquals( $result2, $res );
+
+               $wgGroupPermissions['autoconfirmed']['move'] = true;
+               $wgGroupPermissions['user']['move'] = true;
+               $res = $this->permissionManager
+                       ->getPermissionErrors( $action, $this->user, $this->title );
+               $this->assertEquals( $result2, $res );
+
+               $wgGroupPermissions['autoconfirmed']['move'] = false;
+               $wgGroupPermissions['user']['move'] = true;
+               $res = $this->permissionManager
+                       ->getPermissionErrors( $action, $this->user, $this->title );
+               $this->assertEquals( $result2, $res );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers MediaWiki\Permissions\PermissionManager::checkSpecialsAndNSPermissions
+        */
+       public function testSpecialsAndNSPermissions() {
+               global $wgNamespaceProtection;
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_SPECIAL );
+
+               $this->assertEquals( [ [ 'badaccess-group0' ], [ 'ns-specialprotected' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+
+               $this->setTitle( NS_MAIN );
+               $this->setUserPerm( 'bogus' );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+
+               $this->setTitle( NS_MAIN );
+               $this->setUserPerm( '' );
+               $this->assertEquals( [ [ 'badaccess-group0' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+
+               $wgNamespaceProtection[NS_USER] = [ 'bogus' ];
+
+               $this->setTitle( NS_USER );
+               $this->setUserPerm( '' );
+               $this->assertEquals( [ [ 'badaccess-group0' ],
+                       [ 'namespaceprotected', 'User', 'bogus' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+
+               $this->setTitle( NS_MEDIAWIKI );
+               $this->setUserPerm( 'bogus' );
+               $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+
+               $this->setTitle( NS_MEDIAWIKI );
+               $this->setUserPerm( 'bogus' );
+               $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+
+               $wgNamespaceProtection = null;
+
+               $this->setUserPerm( 'bogus' );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+               $this->assertEquals( true,
+                       $this->permissionManager->userCan( 'bogus', $this->user, $this->title ) );
+
+               $this->setUserPerm( '' );
+               $this->assertEquals( [ [ 'badaccess-group0' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'bogus', $this->user, $this->title ) );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testJsConfigEditPermissions() {
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_USER, $this->userName . '/test.js' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testJsonConfigEditPermissions() {
+               $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
+               getFormattedNsText( NS_PROJECT );
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_USER, $this->userName . '/test.json' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testCssConfigEditPermissions() {
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_USER, $this->userName . '/test.css' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testOtherJsConfigEditPermissions() {
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_USER, $this->altUserName . '/test.js' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testOtherJsonConfigEditPermissions() {
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_USER, $this->altUserName . '/test.json' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testOtherCssConfigEditPermissions() {
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_USER, $this->altUserName . '/test.css' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
+
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
+                       [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testOtherNonConfigEditPermissions() {
+               $this->setUser( $this->userName );
+
+               $this->setTitle( NS_USER, $this->altUserName . '/tempo' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ] ],
+
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       /**
+        * @todo This should use data providers like the other methods here.
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
+        */
+       public function testPatrolActionConfigEditPermissions() {
+               $this->setUser( 'anon' );
+               $this->setTitle( NS_USER, 'ToPatrolOrNotToPatrol' );
+               $this->runConfigEditPermissions(
+                       [ [ 'badaccess-group0' ] ],
+
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-group0' ] ],
+                       [ [ 'badaccess-groups' ] ]
+               );
+       }
+
+       protected function runConfigEditPermissions(
+               $resultNone,
+               $resultMyCss,
+               $resultMyJson,
+               $resultMyJs,
+               $resultUserCss,
+               $resultUserJson,
+               $resultUserJs,
+               $resultPatrol
+       ) {
+               $this->setUserPerm( '' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( $resultNone, $result );
+
+               $this->setUserPerm( 'editmyusercss' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( $resultMyCss, $result );
+
+               $this->setUserPerm( 'editmyuserjson' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( $resultMyJson, $result );
+
+               $this->setUserPerm( 'editmyuserjs' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( $resultMyJs, $result );
+
+               $this->setUserPerm( 'editusercss' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( $resultUserCss, $result );
+
+               $this->setUserPerm( 'edituserjson' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( $resultUserJson, $result );
+
+               $this->setUserPerm( 'edituserjs' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( $resultUserJs, $result );
+
+               $this->setUserPerm( '' );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'patrol', $this->user, $this->title );
+               $this->assertEquals( reset( $resultPatrol[0] ), reset( $result[0] ) );
+
+               $this->setUserPerm( [ 'edituserjs', 'edituserjson', 'editusercss' ] );
+               $result = $this->permissionManager
+                       ->getPermissionErrors( 'bogus', $this->user, $this->title );
+               $this->assertEquals( [ [ 'badaccess-group0' ] ], $result );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        *
+        * This test is failing per T201776.
+        *
+        * @group Broken
+        * @covers \MediaWiki\Permissions\PermissionManager::checkPageRestrictions
+        */
+       public function testPageRestrictions() {
+               $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
+               getFormattedNsText( NS_PROJECT );
+
+               $this->setTitle( NS_MAIN );
+               $this->title->mRestrictionsLoaded = true;
+               $this->setUserPerm( "edit" );
+               $this->title->mRestrictions = [ "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
+
+               $this->assertEquals( [],
+                       $this->permissionManager->getPermissionErrors( 'edit',
+                               $this->user, $this->title ) );
+
+               $this->assertEquals( true,
+                       $this->permissionManager->userCan( 'edit', $this->user, $this->title,
+                               PermissionManager::RIGOR_QUICK ) );
+
+               $this->title->mRestrictions = [ "edit" => [ 'bogus', "sysop", "protect", "" ],
+                       "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
+
+               $this->assertEquals( [ [ 'badaccess-group0' ],
+                       [ 'protectedpagetext', 'bogus', 'bogus' ],
+                       [ 'protectedpagetext', 'editprotected', 'bogus' ],
+                       [ 'protectedpagetext', 'protect', 'bogus' ] ],
+                       $this->permissionManager->getPermissionErrors( 'bogus',
+                               $this->user, $this->title ) );
+               $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
+                       [ 'protectedpagetext', 'editprotected', 'edit' ],
+                       [ 'protectedpagetext', 'protect', 'edit' ] ],
+                       $this->permissionManager->getPermissionErrors( 'edit',
+                               $this->user, $this->title ) );
+               $this->setUserPerm( "" );
+               $this->assertEquals( [ [ 'badaccess-group0' ],
+                       [ 'protectedpagetext', 'bogus', 'bogus' ],
+                       [ 'protectedpagetext', 'editprotected', 'bogus' ],
+                       [ 'protectedpagetext', 'protect', 'bogus' ] ],
+                       $this->permissionManager->getPermissionErrors( 'bogus',
+                               $this->user, $this->title ) );
+               $this->assertEquals( [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ],
+                       [ 'protectedpagetext', 'bogus', 'edit' ],
+                       [ 'protectedpagetext', 'editprotected', 'edit' ],
+                       [ 'protectedpagetext', 'protect', 'edit' ] ],
+                       $this->permissionManager->getPermissionErrors( 'edit',
+                               $this->user, $this->title ) );
+               $this->setUserPerm( [ "edit", "editprotected" ] );
+               $this->assertEquals( [ [ 'badaccess-group0' ],
+                       [ 'protectedpagetext', 'bogus', 'bogus' ],
+                       [ 'protectedpagetext', 'protect', 'bogus' ] ],
+                       $this->permissionManager->getPermissionErrors( 'bogus',
+                               $this->user, $this->title ) );
+               $this->assertEquals( [
+                       [ 'protectedpagetext', 'bogus', 'edit' ],
+                       [ 'protectedpagetext', 'protect', 'edit' ] ],
+                       $this->permissionManager->getPermissionErrors( 'edit',
+                               $this->user, $this->title ) );
+
+               $this->title->mCascadeRestriction = true;
+               $this->setUserPerm( "edit" );
+
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'bogus', $this->user, $this->title,
+                               PermissionManager::RIGOR_QUICK ) );
+
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'edit', $this->user, $this->title,
+                               PermissionManager::RIGOR_QUICK ) );
+
+               $this->assertEquals( [ [ 'badaccess-group0' ],
+                       [ 'protectedpagetext', 'bogus', 'bogus' ],
+                       [ 'protectedpagetext', 'editprotected', 'bogus' ],
+                       [ 'protectedpagetext', 'protect', 'bogus' ] ],
+                       $this->permissionManager->getPermissionErrors( 'bogus',
+                               $this->user, $this->title ) );
+               $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
+                       [ 'protectedpagetext', 'editprotected', 'edit' ],
+                       [ 'protectedpagetext', 'protect', 'edit' ] ],
+                       $this->permissionManager->getPermissionErrors( 'edit',
+                               $this->user, $this->title ) );
+
+               $this->setUserPerm( [ "edit", "editprotected" ] );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'bogus', $this->user, $this->title,
+                               PermissionManager::RIGOR_QUICK ) );
+
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'edit', $this->user, $this->title,
+                               PermissionManager::RIGOR_QUICK ) );
+
+               $this->assertEquals( [ [ 'badaccess-group0' ],
+                       [ 'protectedpagetext', 'bogus', 'bogus' ],
+                       [ 'protectedpagetext', 'protect', 'bogus' ],
+                       [ 'protectedpagetext', 'protect', 'bogus' ] ],
+                       $this->permissionManager->getPermissionErrors( 'bogus',
+                               $this->user, $this->title ) );
+               $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
+                       [ 'protectedpagetext', 'protect', 'edit' ],
+                       [ 'protectedpagetext', 'protect', 'edit' ] ],
+                       $this->permissionManager->getPermissionErrors( 'edit',
+                               $this->user, $this->title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Permissions\PermissionManager::checkCascadingSourcesRestrictions
+        */
+       public function testCascadingSourcesRestrictions() {
+               $this->setTitle( NS_MAIN, "test page" );
+               $this->setUserPerm( [ "edit", "bogus" ] );
+
+               $this->title->mCascadeSources = [
+                       Title::makeTitle( NS_MAIN, "Bogus" ),
+                       Title::makeTitle( NS_MAIN, "UnBogus" )
+               ];
+               $this->title->mCascadingRestrictions = [
+                       "bogus" => [ 'bogus', "sysop", "protect", "" ]
+               ];
+
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'bogus', $this->user, $this->title ) );
+               $this->assertEquals( [
+                       [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
+                       [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
+                       [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ] ],
+                       $this->permissionManager->getPermissionErrors( 'bogus', $this->user, $this->title ) );
+
+               $this->assertEquals( true,
+                       $this->permissionManager->userCan( 'edit', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager->getPermissionErrors( 'edit', $this->user, $this->title ) );
+       }
+
+       /**
+        * @todo This test method should be split up into separate test methods and
+        * data providers
+        * @covers \MediaWiki\Permissions\PermissionManager::checkActionPermissions
+        */
+       public function testActionPermissions() {
+               $this->setUserPerm( [ "createpage" ] );
+               $this->setTitle( NS_MAIN, "test page" );
+               $this->title->mTitleProtection['permission'] = '';
+               $this->title->mTitleProtection['user'] = $this->user->getId();
+               $this->title->mTitleProtection['expiry'] = 'infinity';
+               $this->title->mTitleProtection['reason'] = 'test';
+               $this->title->mCascadeRestriction = false;
+
+               $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'create', $this->user, $this->title ) );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'create', $this->user, $this->title ) );
+
+               $this->title->mTitleProtection['permission'] = 'editprotected';
+               $this->setUserPerm( [ 'createpage', 'protect' ] );
+               $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'create', $this->user, $this->title ) );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'create', $this->user, $this->title ) );
+
+               $this->setUserPerm( [ 'createpage', 'editprotected' ] );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'create', $this->user, $this->title ) );
+               $this->assertEquals( true,
+                       $this->permissionManager->userCan( 'create', $this->user, $this->title ) );
+
+               $this->setUserPerm( [ 'createpage' ] );
+               $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'create', $this->user, $this->title ) );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'create', $this->user, $this->title ) );
+
+               $this->setTitle( NS_MEDIA, "test page" );
+               $this->setUserPerm( [ "move" ] );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'move', $this->user, $this->title ) );
+               $this->assertEquals( [ [ 'immobile-source-namespace', 'Media' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move', $this->user, $this->title ) );
+
+               $this->setTitle( NS_HELP, "test page" );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move', $this->user, $this->title ) );
+               $this->assertEquals( true,
+                       $this->permissionManager->userCan( 'move', $this->user, $this->title ) );
+
+               $this->title->mInterwiki = "no";
+               $this->assertEquals( [ [ 'immobile-source-page' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move', $this->user, $this->title ) );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'move', $this->user, $this->title ) );
+
+               $this->setTitle( NS_MEDIA, "test page" );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'move-target', $this->user, $this->title ) );
+               $this->assertEquals( [ [ 'immobile-target-namespace', 'Media' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
+
+               $this->setTitle( NS_HELP, "test page" );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
+               $this->assertEquals( true,
+                       $this->permissionManager->userCan( 'move-target', $this->user, $this->title ) );
+
+               $this->title->mInterwiki = "no";
+               $this->assertEquals( [ [ 'immobile-target-page' ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
+               $this->assertEquals( false,
+                       $this->permissionManager->userCan( 'move-target', $this->user, $this->title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
+        */
+       public function testUserBlock() {
+               $this->setMwGlobals( [
+                       'wgEmailConfirmToEdit' => true,
+                       'wgEmailAuthentication' => true,
+               ] );
+
+               $this->overrideMwServices();
+               $this->permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
+
+               $this->setUserPerm( [
+                       'createpage',
+                       'edit',
+                       'move',
+                       'rollback',
+                       'patrol',
+                       'upload',
+                       'purge'
+               ] );
+               $this->setTitle( NS_HELP, "test page" );
+
+               # $wgEmailConfirmToEdit only applies to 'edit' action
+               $this->assertEquals( [],
+                       $this->permissionManager->getPermissionErrors( 'move-target',
+                               $this->user, $this->title ) );
+               $this->assertContains( [ 'confirmedittext' ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'edit', $this->user, $this->title ) );
+
+               $this->setMwGlobals( 'wgEmailConfirmToEdit', false );
+               $this->overrideMwServices();
+               $this->permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
+
+               $this->assertNotContains( [ 'confirmedittext' ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'edit', $this->user, $this->title ) );
+
+               # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
+               $this->assertEquals( [],
+                       $this->permissionManager->getPermissionErrors( 'move-target',
+                               $this->user, $this->title ) );
+
+               global $wgLang;
+               $prev = time();
+               $now = time() + 120;
+               $this->user->mBlockedby = $this->user->getId();
+               $this->user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $this->user->getId(),
+                       'reason' => 'no reason given',
+                       'timestamp' => $prev + 3600,
+                       'auto' => true,
+                       'expiry' => 0
+               ] );
+               $this->user->mBlock->mTimestamp = 0;
+               $this->assertEquals( [ [ 'autoblockedtext',
+                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                       'Useruser', null, 'infinite', '127.0.8.1',
+                       $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ] ],
+                       $this->permissionManager->getPermissionErrors( 'move-target',
+                               $this->user, $this->title ) );
+
+               $this->assertEquals( false, $this->permissionManager
+                       ->userCan( 'move-target', $this->user, $this->title ) );
+               // quickUserCan should ignore user blocks
+               $this->assertEquals( true, $this->permissionManager
+                       ->userCan( 'move-target', $this->user, $this->title,
+                               PermissionManager::RIGOR_QUICK ) );
+
+               global $wgLocalTZoffset;
+               $wgLocalTZoffset = -60;
+               $this->user->mBlockedby = $this->user->getName();
+               $this->user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $this->user->getId(),
+                       'reason' => 'no reason given',
+                       'timestamp' => $now,
+                       'auto' => false,
+                       'expiry' => 10,
+               ] );
+               $this->assertEquals( [ [ 'blockedtext',
+                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                       'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                       $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
+               # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
+               #   $user->blockedFor() == ''
+               #   $user->mBlock->mExpiry == 'infinity'
+
+               $this->user->mBlockedby = $this->user->getName();
+               $this->user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $this->user->getId(),
+                       'reason' => 'no reason given',
+                       'timestamp' => $now,
+                       'auto' => false,
+                       'expiry' => 10,
+                       'systemBlock' => 'test',
+               ] );
+
+               $errors = [ [ 'systemblockedtext',
+                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                       'Useruser', 'test', '23:00, 31 December 1969', '127.0.8.1',
+                       $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
+
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'edit', $this->user, $this->title ) );
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'rollback', $this->user, $this->title ) );
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'patrol', $this->user, $this->title ) );
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'upload', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'purge', $this->user, $this->title ) );
+
+               // partial block message test
+               $this->user->mBlockedby = $this->user->getName();
+               $this->user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $this->user->getId(),
+                       'reason' => 'no reason given',
+                       'timestamp' => $now,
+                       'sitewide' => false,
+                       'expiry' => 10,
+               ] );
+
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'edit', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'rollback', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'patrol', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'upload', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'purge', $this->user, $this->title ) );
+
+               $this->user->mBlock->setRestrictions( [
+                       ( new PageRestriction( 0, $this->title->getArticleID() ) )->setTitle( $this->title ),
+               ] );
+
+               $errors = [ [ 'blockedtext-partial',
+                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                       'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                       $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
+
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'edit', $this->user, $this->title ) );
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'rollback', $this->user, $this->title ) );
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'patrol', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'upload', $this->user, $this->title ) );
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'purge', $this->user, $this->title ) );
+
+               // Test no block.
+               $this->user->mBlockedby = null;
+               $this->user->mBlock = null;
+
+               $this->assertEquals( [],
+                       $this->permissionManager
+                               ->getPermissionErrors( 'edit', $this->user, $this->title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
+        *
+        * Tests to determine that the passed in permission does not get mixed up with
+        * an action of the same name.
+        */
+       public function testUserBlockAction() {
+               global $wgLang;
+
+               $tester = $this->getMockBuilder( Action::class )
+                                          ->disableOriginalConstructor()
+                                          ->getMock();
+               $tester->method( 'getName' )
+                          ->willReturn( 'tester' );
+               $tester->method( 'getRestriction' )
+                          ->willReturn( 'test' );
+               $tester->method( 'requiresUnblock' )
+                          ->willReturn( false );
+
+               $this->setMwGlobals( [
+                       'wgActions' => [
+                               'tester' => $tester,
+                       ],
+                       'wgGroupPermissions' => [
+                               '*' => [
+                                       'tester' => true,
+                               ],
+                       ],
+               ] );
+
+               $now = time();
+               $this->user->mBlockedby = $this->user->getName();
+               $this->user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $this->user->getId(),
+                       'reason' => 'no reason given',
+                       'timestamp' => $now,
+                       'auto' => false,
+                       'expiry' => 'infinity',
+               ] );
+
+               $errors = [ [ 'blockedtext',
+                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                       'Useruser', null, 'infinite', '127.0.8.1',
+                       $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
+
+               $this->assertEquals( $errors,
+                       $this->permissionManager
+                               ->getPermissionErrors( 'tester', $this->user, $this->title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Permissions\PermissionManager::isBlockedFrom
+        */
+       public function testBlockInstanceCache() {
+               // First, check the user isn't blocked
+               $user = $this->getMutableTestUser()->getUser();
+               $ut = Title::makeTitle( NS_USER_TALK, $user->getName() );
+               $this->assertNull( $user->getBlock( false ), 'sanity check' );
+               //$this->assertSame( '', $user->blockedBy(), 'sanity check' );
+               //$this->assertSame( '', $user->blockedFor(), 'sanity check' );
+               //$this->assertFalse( (bool)$user->isHidden(), 'sanity check' );
+               $this->assertFalse( $this->permissionManager
+                       ->isBlockedFrom( $user, $ut ), 'sanity check' );
+
+               // Block the user
+               $blocker = $this->getTestSysop()->getUser();
+               $block = new Block( [
+                       'hideName' => true,
+                       'allowUsertalk' => false,
+                       'reason' => 'Because',
+               ] );
+               $block->setTarget( $user );
+               $block->setBlocker( $blocker );
+               $res = $block->insert();
+               $this->assertTrue( (bool)$res['id'], 'sanity check: Failed to insert block' );
+
+               // Clear cache and confirm it loaded the block properly
+               $user->clearInstanceCache();
+               $this->assertInstanceOf( Block::class, $user->getBlock( false ) );
+               //$this->assertSame( $blocker->getName(), $user->blockedBy() );
+               //$this->assertSame( 'Because', $user->blockedFor() );
+               //$this->assertTrue( (bool)$user->isHidden() );
+               $this->assertTrue( $this->permissionManager->isBlockedFrom( $user, $ut ) );
+
+               // Unblock
+               $block->delete();
+
+               // Clear cache and confirm it loaded the not-blocked properly
+               $user->clearInstanceCache();
+               $this->assertNull( $user->getBlock( false ) );
+               //$this->assertSame( '', $user->blockedBy() );
+               //$this->assertSame( '', $user->blockedFor() );
+               //$this->assertFalse( (bool)$user->isHidden() );
+               $this->assertFalse( $this->permissionManager->isBlockedFrom( $user, $ut ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Permissions\PermissionManager::isBlockedFrom
+        * @dataProvider provideIsBlockedFrom
+        * @param string|null $title Title to test.
+        * @param bool $expect Expected result from User::isBlockedFrom()
+        * @param array $options Additional test options:
+        *  - 'blockAllowsUTEdit': (bool, default true) Value for $wgBlockAllowsUTEdit
+        *  - 'allowUsertalk': (bool, default false) Passed to Block::__construct()
+        *  - 'pageRestrictions': (array|null) If non-empty, page restriction titles for the block.
+        */
+       public function testIsBlockedFrom( $title, $expect, array $options = [] ) {
+               $this->setMwGlobals( [
+                       'wgBlockAllowsUTEdit' => $options['blockAllowsUTEdit'] ?? true,
+               ] );
+
+               $user = $this->getTestUser()->getUser();
+
+               if ( $title === self::USER_TALK_PAGE ) {
+                       $title = $user->getTalkPage();
+               } else {
+                       $title = Title::newFromText( $title );
+               }
+
+               $restrictions = [];
+               foreach ( $options['pageRestrictions'] ?? [] as $pagestr ) {
+                       $page = $this->getExistingTestPage(
+                               $pagestr === self::USER_TALK_PAGE ? $user->getTalkPage() : $pagestr
+                       );
+                       $restrictions[] = new PageRestriction( 0, $page->getId() );
+               }
+               foreach ( $options['namespaceRestrictions'] ?? [] as $ns ) {
+                       $restrictions[] = new NamespaceRestriction( 0, $ns );
+               }
+
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ),
+                       'allowUsertalk' => $options['allowUsertalk'] ?? false,
+                       'sitewide' => !$restrictions,
+               ] );
+               $block->setTarget( $user );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               if ( $restrictions ) {
+                       $block->setRestrictions( $restrictions );
+               }
+               $block->insert();
+
+               try {
+                       $this->assertSame( $expect, $this->permissionManager->isBlockedFrom( $user, $title ) );
+               } finally {
+                       $block->delete();
+               }
+       }
+
+       public static function provideIsBlockedFrom() {
+               return [
+                       'Sitewide block, basic operation' => [ 'Test page', true ],
+                       'Sitewide block, not allowing user talk' => [
+                               self::USER_TALK_PAGE, true, [
+                                       'allowUsertalk' => false,
+                               ]
+                       ],
+                       'Sitewide block, allowing user talk' => [
+                               self::USER_TALK_PAGE, false, [
+                                       'allowUsertalk' => true,
+                               ]
+                       ],
+                       'Sitewide block, allowing user talk but $wgBlockAllowsUTEdit is false' => [
+                               self::USER_TALK_PAGE, true, [
+                                       'allowUsertalk' => true,
+                                       'blockAllowsUTEdit' => false,
+                               ]
+                       ],
+                       'Partial block, blocking the page' => [
+                               'Test page', true, [
+                                       'pageRestrictions' => [ 'Test page' ],
+                               ]
+                       ],
+                       'Partial block, not blocking the page' => [
+                               'Test page 2', false, [
+                                       'pageRestrictions' => [ 'Test page' ],
+                               ]
+                       ],
+                       'Partial block, not allowing user talk but user talk page is not blocked' => [
+                               self::USER_TALK_PAGE, false, [
+                                       'allowUsertalk' => false,
+                                       'pageRestrictions' => [ 'Test page' ],
+                               ]
+                       ],
+                       'Partial block, allowing user talk but user talk page is blocked' => [
+                               self::USER_TALK_PAGE, true, [
+                                       'allowUsertalk' => true,
+                                       'pageRestrictions' => [ self::USER_TALK_PAGE ],
+                               ]
+                       ],
+                       'Partial block, user talk page is not blocked but $wgBlockAllowsUTEdit is false' => [
+                               self::USER_TALK_PAGE, false, [
+                                       'allowUsertalk' => false,
+                                       'pageRestrictions' => [ 'Test page' ],
+                                       'blockAllowsUTEdit' => false,
+                               ]
+                       ],
+                       'Partial block, user talk page is blocked and $wgBlockAllowsUTEdit is false' => [
+                               self::USER_TALK_PAGE, true, [
+                                       'allowUsertalk' => true,
+                                       'pageRestrictions' => [ self::USER_TALK_PAGE ],
+                                       'blockAllowsUTEdit' => false,
+                               ]
+                       ],
+                       'Partial user talk namespace block, not allowing user talk' => [
+                               self::USER_TALK_PAGE, true, [
+                                       'allowUsertalk' => false,
+                                       'namespaceRestrictions' => [ NS_USER_TALK ],
+                               ]
+                       ],
+                       'Partial user talk namespace block, allowing user talk' => [
+                               self::USER_TALK_PAGE, false, [
+                                       'allowUsertalk' => true,
+                                       'namespaceRestrictions' => [ NS_USER_TALK ],
+                               ]
+                       ],
+                       'Partial user talk namespace block, where $wgBlockAllowsUTEdit is false' => [
+                               self::USER_TALK_PAGE, true, [
+                                       'allowUsertalk' => true,
+                                       'namespaceRestrictions' => [ NS_USER_TALK ],
+                                       'blockAllowsUTEdit' => false,
+                               ]
+                       ],
+               ];
+       }
+
+}
index b14424f..2d91d4d 100644 (file)
@@ -167,28 +167,4 @@ class ReadOnlyModeTest extends MediaWikiTestCase {
                $rom->setReason( 'override' );
                $this->assertSame( 'override', $rom->getReason() );
        }
-
-       /**
-        * @covers ReadOnlyMode::clearCache
-        * @covers ConfiguredReadOnlyMode::clearCache
-        */
-       public function testClearCache() {
-               $fileName = $this->getNewTempFile();
-               unlink( $fileName );
-               $config = new HashConfig( [
-                       'ReadOnly' => null,
-                       'ReadOnlyFile' => $fileName,
-               ] );
-               $cro = new ConfiguredReadOnlyMode( $config );
-               $lb = $this->createLB( [ 'lbMessage' => false ] );
-               $rom = new ReadOnlyMode( $cro, $lb );
-
-               $this->assertSame( false, $rom->getReason(), 'initial' );
-
-               file_put_contents( $fileName, 'file' );
-               $this->assertSame( false, $rom->getReason(), 'stale' );
-
-               $rom->clearCache();
-               $this->assertSame( 'file', $rom->getReason(), 'fresh' );
-       }
 }
index 3efd372..8bf8606 100644 (file)
@@ -55,7 +55,7 @@ class McrReadNewRevisionStoreDbTest extends RevisionStoreDbTestBase {
                        [ 'rev_id' => $rev->getId(), 'rev_text_id > 0' ],
                        [ [ 1 ] ],
                        [],
-                       [ 'text' => [ 'INNER JOIN', [ 'rev_text_id = old_id' ] ] ]
+                       [ 'text' => [ 'JOIN', [ 'rev_text_id = old_id' ] ] ]
                );
 
                parent::assertRevisionExistsInDatabase( $rev );
index dbd271a..0110531 100644 (file)
@@ -45,7 +45,7 @@ trait McrSchemaOverride {
                        $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-slot_roles' );
                        $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-content_models' );
                        $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-content' );
-                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-slots.sql' );
+                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-slots' );
                }
 
                if ( !$this->hasPreMcrFields( $db ) ) {
index 0385708..68d3000 100644 (file)
@@ -55,7 +55,7 @@ class McrWriteBothRevisionStoreDbTest extends RevisionStoreDbTestBase {
                        [ 'rev_id' => $rev->getId(), 'rev_text_id > 0' ],
                        [ [ 1 ] ],
                        [],
-                       [ 'text' => [ 'INNER JOIN', [ 'rev_text_id = old_id' ] ] ]
+                       [ 'text' => [ 'JOIN', [ 'rev_text_id = old_id' ] ] ]
                );
 
                parent::assertRevisionExistsInDatabase( $rev );
index 59481f0..b9b7ad9 100644 (file)
@@ -80,7 +80,7 @@ class NoContentModelRevisionStoreDbTest extends RevisionStoreDbTestBase {
                                        ]
                                ),
                                'joins' => [
-                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
                                ],
                        ]
                ];
@@ -115,7 +115,7 @@ class NoContentModelRevisionStoreDbTest extends RevisionStoreDbTestBase {
                                        ]
                                ),
                                'joins' => [
-                                       'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ],
+                                       'text' => [ 'JOIN', [ 'rev_text_id=old_id' ] ],
                                ],
                        ]
                ];
index 4345335..b3c34c8 100644 (file)
@@ -38,7 +38,7 @@ class PreMcrRevisionStoreDbTest extends RevisionStoreDbTestBase {
                        [ 'rev_id' => $rev->getId(), 'rev_text_id > 0' ],
                        [ [ 1 ] ],
                        [],
-                       [ 'text' => [ 'INNER JOIN', [ 'rev_text_id = old_id' ] ] ]
+                       [ 'text' => [ 'JOIN', [ 'rev_text_id = old_id' ] ] ]
                );
 
                parent::assertRevisionExistsInDatabase( $rev );
index 9f1c69c..3ee61f7 100644 (file)
@@ -244,7 +244,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
-                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
                                        'user' => [
                                                'LEFT JOIN',
                                                [ 'actor_rev_user.actor_user != 0', 'user_id = actor_rev_user.actor_user' ],
@@ -289,7 +289,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                ),
                                'joins' => array_merge(
                                        [
-                                               'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                               'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
                                                'user' => [
                                                        'LEFT JOIN',
                                                        [
@@ -332,7 +332,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                ),
                                'joins' => array_merge(
                                        [
-                                               'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                               'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
                                                'user' => [
                                                        'LEFT JOIN',
                                                        [
@@ -401,7 +401,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                ),
                                'joins' => array_merge(
                                        [
-                                               'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                               'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
                                                'user' => [
                                                        'LEFT JOIN',
                                                        [
@@ -464,7 +464,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
-                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ] ],
                                        'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
                                        'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
                                        'comment_rev_comment'
@@ -517,7 +517,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
-                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ], ],
+                                       'page' => [ 'JOIN', [ 'page_id = rev_page' ], ],
                                        'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
                                        'comment_rev_comment'
                                                => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
@@ -571,7 +571,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        $this->getNewCommentQueryFields( 'rev' )
                                ),
                                'joins' => [
-                                       'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ],
+                                       'text' => [ 'JOIN', [ 'rev_text_id=old_id' ] ],
                                        'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
                                        'comment_rev_comment'
                                                => [ 'JOIN', 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ],
@@ -601,7 +601,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                ),
                                'joins' => [
                                        'page' => [
-                                               'INNER JOIN',
+                                               'JOIN',
                                                [ 'page_id = rev_page' ],
                                        ],
                                        'user' => [
@@ -612,7 +612,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                                ],
                                        ],
                                        'text' => [
-                                               'INNER JOIN',
+                                               'JOIN',
                                                [ 'rev_text_id=old_id' ],
                                        ],
                                        'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ],
@@ -686,7 +686,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'content_model',
                                ],
                                'joins' => [
-                                       'content' => [ 'INNER JOIN', [ 'slot_content_id = content_id' ] ],
+                                       'content' => [ 'JOIN', [ 'slot_content_id = content_id' ] ],
                                ],
                        ]
                ];
@@ -714,7 +714,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
                                        'model_name',
                                ],
                                'joins' => [
-                                       'content' => [ 'INNER JOIN', [ 'slot_content_id = content_id' ] ],
+                                       'content' => [ 'JOIN', [ 'slot_content_id = content_id' ] ],
                                        'content_models' => [ 'LEFT JOIN', [ 'content_model = model_id' ] ],
                                ],
                        ]
@@ -993,7 +993,7 @@ class RevisionQueryInfoTest extends MediaWikiTestCase {
        public function testRevisionPageJoinCond() {
                $this->hideDeprecated( 'Revision::pageJoinCond' );
                $this->assertEquals(
-                       [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                       [ 'JOIN', [ 'page_id = rev_page' ] ],
                        Revision::pageJoinCond()
                );
        }
diff --git a/tests/phpunit/includes/Revision/RevisionStoreCacheRecordTest.php b/tests/phpunit/includes/Revision/RevisionStoreCacheRecordTest.php
new file mode 100644 (file)
index 0000000..8684cd3
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+namespace MediaWiki\Tests\Revision;
+
+use Title;
+use MediaWiki\User\UserIdentityValue;
+use TextContent;
+use CommentStoreComment;
+use MediaWiki\Revision\RevisionStoreCacheRecord;
+use MediaWiki\Revision\RevisionSlots;
+use MediaWiki\Revision\SlotRecord;
+use MediaWiki\Revision\RevisionRecord;
+use MediaWiki\Revision\RevisionStoreRecord;
+
+/**
+ * @covers \MediaWiki\Revision\RevisionStoreCacheRecord
+ * @covers \MediaWiki\Revision\RevisionStoreRecord
+ * @covers \MediaWiki\Revision\RevisionRecord
+ */
+class RevisionStoreCacheRecordTest extends RevisionStoreRecordTest {
+
+       /**
+        * @param array $rowOverrides
+        * @param bool|callable callback function to use, or false for a default no-op callback
+        *
+        * @return RevisionStoreRecord
+        */
+       protected function newRevision( array $rowOverrides = [], $callback = false ) {
+               $title = Title::newFromText( 'Dummy' );
+               $title->resetArticleID( 17 );
+
+               $user = new UserIdentityValue( 11, 'Tester', 0 );
+               $comment = CommentStoreComment::newUnsavedComment( 'Hello World' );
+
+               $main = SlotRecord::newUnsaved( SlotRecord::MAIN, new TextContent( 'Lorem Ipsum' ) );
+               $aux = SlotRecord::newUnsaved( 'aux', new TextContent( 'Frumious Bandersnatch' ) );
+               $slots = new RevisionSlots( [ $main, $aux ] );
+
+               $row = [
+                       'rev_id' => '7',
+                       'rev_page' => strval( $title->getArticleID() ),
+                       'rev_timestamp' => '20200101000000',
+                       'rev_deleted' => 0,
+                       'rev_minor_edit' => 0,
+                       'rev_parent_id' => '5',
+                       'rev_len' => $slots->computeSize(),
+                       'rev_sha1' => $slots->computeSha1(),
+                       'rev_user' => '11',
+                       'page_latest' => '18',
+               ];
+
+               $row = array_merge( $row, $rowOverrides );
+
+               if ( !$callback ) {
+                       $callback = function ( $revId ) use ( $row ) {
+                               return (object)$row;
+                       };
+               }
+
+               return new RevisionStoreCacheRecord(
+                       $callback,
+                       $title,
+                       $user,
+                       $comment,
+                       (object)$row,
+                       $slots
+               );
+       }
+
+       public function testCallback() {
+               // Provide a callback that returns non-default values. Asserting the revision returns
+               // these values confirms callback execution and behavior. Also confirm the callback
+               // is only invoked once, even for multiple getter calls.
+               $rowOverrides = [
+                       'rev_deleted' => RevisionRecord::DELETED_TEXT,
+                       'rev_user' => 12,
+               ];
+               $callbackInvoked = 0;
+               $callback = function ( $revId ) use ( &$callbackInvoked, $rowOverrides ) {
+                       $callbackInvoked++;
+                       return (object)$rowOverrides;
+               };
+               $rev = $this->newRevision( [], $callback );
+
+               $this->assertSame( RevisionRecord::DELETED_TEXT, $rev->getVisibility() );
+               $this->assertSame( 12, $rev->getUser()->getId() );
+               $this->assertSame( 1, $callbackInvoked );
+       }
+
+}
index 018df48..51c483d 100644 (file)
@@ -14,6 +14,7 @@ use MediaWiki\Revision\IncompleteRevisionException;
 use MediaWiki\Revision\MutableRevisionRecord;
 use MediaWiki\Revision\RevisionArchiveRecord;
 use MediaWiki\Revision\RevisionRecord;
+use MediaWiki\Revision\RevisionStoreRecord;
 use MediaWiki\Revision\RevisionSlots;
 use MediaWiki\Revision\RevisionStore;
 use MediaWiki\Revision\SlotRecord;
@@ -1705,4 +1706,195 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
                $this->testNewMutableRevisionFromArray( $array );
        }
 
+       /**
+        * Creates a new revision for testing caching behavior
+        *
+        * @param WikiPage $page the page for the new revision
+        * @param RevisionStore $store store object to use for creating the revision
+        * @return bool|RevisionStoreRecord the revision created, or false if missing
+        */
+       private function createRevisionStoreCacheRecord( $page, $store ) {
+               $user = MediaWikiTestCase::getMutableTestUser()->getUser();
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( SlotRecord::MAIN, new WikitextContent( __METHOD__ ) );
+               $summary = CommentStoreComment::newUnsavedComment( __METHOD__ );
+               $rev = $updater->saveRevision( $summary, EDIT_NEW );
+               return $store->getKnownCurrentRevision( $page->getTitle(), $rev->getId() );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\RevisionStore::getKnownCurrentRevision
+        */
+       public function testGetKnownCurrentRevision_userNameChange() {
+               global $wgActorTableSchemaMigrationStage;
+
+               $this->overrideMwServices();
+               $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
+               $this->setService( 'MainWANObjectCache', $cache );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $page = $this->getNonexistingTestPage();
+               $rev = $this->createRevisionStoreCacheRecord( $page, $store );
+
+               // Grab the user name
+               $userNameBefore = $rev->getUser()->getName();
+
+               // Change the user name in the database, "behind the back" of the cache
+               $newUserName = "Renamed $userNameBefore";
+               $this->db->update( 'revision',
+                       [ 'rev_user_text' => $newUserName ],
+                       [ 'rev_id' => $rev->getId() ] );
+               $this->db->update( 'user',
+                       [ 'user_name' => $newUserName ],
+                       [ 'user_id' => $rev->getUser()->getId() ] );
+               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
+                       $this->db->update( 'actor',
+                               [ 'actor_name' => $newUserName ],
+                               [ 'actor_user' => $rev->getUser()->getId() ] );
+               }
+
+               // Reload the revision and regrab the user name.
+               $revAfter = $store->getKnownCurrentRevision( $page->getTitle(), $rev->getId() );
+               $userNameAfter = $revAfter->getUser()->getName();
+
+               // The two user names should be different.
+               // If they are the same, we are seeing a cached value, which is bad.
+               $this->assertNotSame( $userNameBefore, $userNameAfter );
+
+               // This is implied by the above assertion, but explicitly check it, for completeness
+               $this->assertSame( $newUserName, $userNameAfter );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\RevisionStore::getKnownCurrentRevision
+        */
+       public function testGetKnownCurrentRevision_revDelete() {
+               $this->overrideMwServices();
+               $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
+               $this->setService( 'MainWANObjectCache', $cache );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $page = $this->getNonexistingTestPage();
+               $rev = $this->createRevisionStoreCacheRecord( $page, $store );
+
+               // Grab the deleted bitmask
+               $deletedBefore = $rev->getVisibility();
+
+               // Change the deleted bitmask in the database, "behind the back" of the cache
+               $this->db->update( 'revision',
+                       [ 'rev_deleted' => RevisionRecord::DELETED_TEXT ],
+                       [ 'rev_id' => $rev->getId() ] );
+
+               // Reload the revision and regrab the visibility flag.
+               $revAfter = $store->getKnownCurrentRevision( $page->getTitle(), $rev->getId() );
+               $deletedAfter = $revAfter->getVisibility();
+
+               // The two deleted flags should be different.
+               // If they are the same, we are seeing a cached value, which is bad.
+               $this->assertNotSame( $deletedBefore, $deletedAfter );
+
+               // This is implied by the above assertion, but explicitly check it, for completeness
+               $this->assertSame( RevisionRecord::DELETED_TEXT, $deletedAfter );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\RevisionStore::newRevisionFromRow
+        */
+       public function testNewRevisionFromRow_userNameChange() {
+               global $wgActorTableSchemaMigrationStage;
+
+               $page = $this->getTestPage();
+               $text = __METHOD__;
+               /** @var Revision $rev */
+               $rev = $page->doEditContent(
+                       new WikitextContent( $text ),
+                       __METHOD__
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $record = $store->newRevisionFromRow(
+                       $this->revisionToRow( $rev ),
+                       [],
+                       $page->getTitle()
+               );
+
+               // Grab the user name
+               $userNameBefore = $record->getUser()->getName();
+
+               // Change the user name in the database
+               $newUserName = "Renamed $userNameBefore";
+               $this->db->update( 'revision',
+                       [ 'rev_user_text' => $newUserName ],
+                       [ 'rev_id' => $record->getId() ] );
+               $this->db->update( 'user',
+                       [ 'user_name' => $newUserName ],
+                       [ 'user_id' => $record->getUser()->getId() ] );
+               if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) {
+                       $this->db->update( 'actor',
+                               [ 'actor_name' => $newUserName ],
+                               [ 'actor_user' => $record->getUser()->getId() ] );
+               }
+
+               // Reload the record, passing $fromCache as true to force fresh info from the db,
+               // and regrab the user name
+               $recordAfter = $store->newRevisionFromRow(
+                       $this->revisionToRow( $rev ),
+                       [],
+                       $page->getTitle(),
+                       true
+               );
+               $userNameAfter = $recordAfter->getUser()->getName();
+
+               // The two user names should be different.
+               // If they are the same, we are seeing a cached value, which is bad.
+               $this->assertNotSame( $userNameBefore, $userNameAfter );
+
+               // This is implied by the above assertion, but explicitly check it, for completeness
+               $this->assertSame( $newUserName, $userNameAfter );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\RevisionStore::newRevisionFromRow
+        */
+       public function testNewRevisionFromRow_revDelete() {
+               $page = $this->getTestPage();
+               $text = __METHOD__;
+               /** @var Revision $rev */
+               $rev = $page->doEditContent(
+                       new WikitextContent( $text ),
+                       __METHOD__
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $record = $store->newRevisionFromRow(
+                       $this->revisionToRow( $rev ),
+                       [],
+                       $page->getTitle()
+               );
+
+               // Grab the deleted bitmask
+               $deletedBefore = $record->getVisibility();
+
+               // Change the deleted bitmask in the database
+               $this->db->update( 'revision',
+                       [ 'rev_deleted' => RevisionRecord::DELETED_TEXT ],
+                       [ 'rev_id' => $record->getId() ] );
+
+               // Reload the record, passing $fromCache as true to force fresh info from the db,
+               // and regrab the deleted bitmask
+               $recordAfter = $store->newRevisionFromRow(
+                       $this->revisionToRow( $rev ),
+                       [],
+                       $page->getTitle(),
+                       true
+               );
+               $deletedAfter = $recordAfter->getVisibility();
+
+               // The two deleted flags should be different, because we modified the database.
+               $this->assertNotSame( $deletedBefore, $deletedAfter );
+
+               // This is implied by the above assertion, but explicitly check it, for completeness
+               $this->assertSame( RevisionRecord::DELETED_TEXT, $deletedAfter );
+       }
+
 }
index c4b274d..5246e36 100644 (file)
@@ -21,6 +21,9 @@ use Wikimedia\Rdbms\LoadBalancer;
 use Wikimedia\TestingAccessWrapper;
 use WikitextContent;
 
+/**
+ * Tests RevisionStore
+ */
 class RevisionStoreTest extends MediaWikiTestCase {
 
        private function useTextId() {
@@ -525,12 +528,10 @@ class RevisionStoreTest extends MediaWikiTestCase {
                                'old_text' => 'Hello World',
                                'old_flags' => 'utf-8',
                        ];
-               } else {
-                       if ( !isset( $row['content'] ) && isset( $array['old_text'] ) ) {
-                               $row['content'] = [
-                                       'main' => new WikitextContent( $array['old_text'] ),
-                               ];
-                       }
+               } elseif ( !isset( $row['content'] ) && isset( $array['old_text'] ) ) {
+                       $row['content'] = [
+                               'main' => new WikitextContent( $array['old_text'] ),
+                       ];
                }
 
                return (object)$row;
index a17d21d..d7f4fd6 100644 (file)
@@ -26,6 +26,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                        [
                                'page',
                                'revision',
+                               'comment',
                                'ip_changes',
                                'text',
                                'archive',
@@ -1396,6 +1397,9 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $this->setService( 'MainWANObjectCache', $cache );
                $db = wfGetDB( DB_MASTER );
 
+               $now = 1553893742;
+               $cache->setMockTime( $now );
+
                // Get a fresh revision to use during testing
                $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
                $rev = $this->testPage->getRevision();
@@ -1410,6 +1414,8 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $cache->delete( $key, WANObjectCache::HOLDOFF_NONE );
                $this->assertFalse( $cache->get( $key ) );
 
+               ++$now;
+
                // Get the new revision and make sure it is in the cache and correct
                $newRev = Revision::newKnownCurrent( $db, $rev->getPage(), $rev->getId() );
                $this->assertRevEquals( $rev, $newRev );
index 64de854..228bcaa 100644 (file)
@@ -51,7 +51,7 @@ class RevisionMcrReadNewDbTest extends RevisionDbTestBase {
                        [
                                'tables' => [ 'text' ],
                                'fields' => [ 'old_id', 'old_text', 'old_flags', 'rev_text_id' ],
-                               'joins' => [ 'text' => [ 'INNER JOIN', 'old_id=rev_text_id' ] ]
+                               'joins' => [ 'text' => [ 'JOIN', 'old_id=rev_text_id' ] ]
                        ]
                ];
        }
index 74e8e1b..02e06f8 100644 (file)
@@ -8,7 +8,7 @@ class ServiceWiringTest extends MediaWikiTestCase {
                global $IP;
                $services = array_keys( require "$IP/includes/ServiceWiring.php" );
                $sortedServices = $services;
-               sort( $sortedServices );
+               natcasesort( $sortedServices );
 
                $this->assertSame( $sortedServices, $services,
                        'Please keep services sorted alphabetically' );
index a6a92c6..b0d89a6 100644 (file)
@@ -10,11 +10,11 @@ class SiteStatsTest extends MediaWikiTestCase {
                $this->setService( 'MainWANObjectCache', $cache );
                $jobq = JobQueueGroup::singleton();
 
-               $jobq->push( new NullJob( Title::newMainPage(), [] ) );
+               $jobq->push( Job::factory( 'null', Title::newMainPage(), [] ) );
                $this->assertEquals( 1, SiteStats::jobs(),
                         'A single job enqueued bumps jobscount stat to 1' );
 
-               $jobq->push( new NullJob( Title::newMainPage(), [] ) );
+               $jobq->push( Job::factory( 'null', Title::newMainPage(), [] ) );
                $this->assertEquals( 1, SiteStats::jobs(),
                        'SiteStats::jobs() count does not reflect addition ' .
                        'of a second job (cached)'
index 1517964..f42e557 100644 (file)
@@ -62,23 +62,23 @@ class NameTableStoreTest extends MediaWikiTestCase {
                        ->getMock();
                $mock->expects( $this->exactly( $insertCalls ) )
                        ->method( 'insert' )
-                       ->willReturnCallback( function () {
-                               return call_user_func_array( [ $this->db, 'insert' ], func_get_args() );
+                       ->willReturnCallback( function ( ...$args ) {
+                               return call_user_func_array( [ $this->db, 'insert' ], $args );
                        } );
                $mock->expects( $this->exactly( $selectCalls ) )
                        ->method( 'select' )
-                       ->willReturnCallback( function () {
-                               return call_user_func_array( [ $this->db, 'select' ], func_get_args() );
+                       ->willReturnCallback( function ( ...$args ) {
+                               return call_user_func_array( [ $this->db, 'select' ], $args );
                        } );
                $mock->expects( $this->exactly( $insertCalls ) )
                        ->method( 'affectedRows' )
-                       ->willReturnCallback( function () {
-                               return call_user_func_array( [ $this->db, 'affectedRows' ], func_get_args() );
+                       ->willReturnCallback( function ( ...$args ) {
+                               return call_user_func_array( [ $this->db, 'affectedRows' ], $args );
                        } );
                $mock->expects( $this->any() )
                        ->method( 'insertId' )
-                       ->willReturnCallback( function () {
-                               return call_user_func_array( [ $this->db, 'insertId' ], func_get_args() );
+                       ->willReturnCallback( function ( ...$args ) {
+                               return call_user_func_array( [ $this->db, 'insertId' ], $args );
                        } );
                return $mock;
        }
@@ -208,7 +208,7 @@ class NameTableStoreTest extends MediaWikiTestCase {
 
        public function provideGetName() {
                return [
-                       [ new HashBagOStuff(), 3, 3 ],
+                       [ new HashBagOStuff(), 3, 2 ],
                        [ new EmptyBagOStuff(), 3, 3 ],
                ];
        }
@@ -216,27 +216,35 @@ class NameTableStoreTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideGetName
         */
-       public function testGetName( $cacheBag, $insertCalls, $selectCalls ) {
+       public function testGetName( BagOStuff $cacheBag, $insertCalls, $selectCalls ) {
+               $now = microtime( true );
+               $cacheBag->setMockTime( $now );
+               // Check for operations to in-memory cache (IMC) and persistent cache (PC)
                $store = $this->getNameTableSqlStore( $cacheBag, $insertCalls, $selectCalls );
 
                // Get 1 ID and make sure getName returns correctly
-               $fooId = $store->acquireId( 'foo' );
-               $this->assertSame( 'foo', $store->getName( $fooId ) );
+               $fooId = $store->acquireId( 'foo' ); // regen PC, set IMC, update IMC, tombstone PC
+               $now += 0.01;
+               $this->assertSame( 'foo', $store->getName( $fooId ) ); // use IMC
+               $now += 0.01;
 
                // Get another ID and make sure getName returns correctly
-               $barId = $store->acquireId( 'bar' );
-               $this->assertSame( 'bar', $store->getName( $barId ) );
+               $barId = $store->acquireId( 'bar' ); // update IMC, tombstone PC
+               $now += 0.01;
+               $this->assertSame( 'bar', $store->getName( $barId ) ); // use IMC
+               $now += 0.01;
 
                // Blitz the cache and make sure it still returns
-               TestingAccessWrapper::newFromObject( $store )->tableCache = null;
-               $this->assertSame( 'foo', $store->getName( $fooId ) );
-               $this->assertSame( 'bar', $store->getName( $barId ) );
+               TestingAccessWrapper::newFromObject( $store )->tableCache = null; // clear IMC
+               $this->assertSame( 'foo', $store->getName( $fooId ) ); // regen interim PC, set IMC
+               $this->assertSame( 'bar', $store->getName( $barId ) ); // use IMC
 
                // Blitz the cache again and get another ID and make sure getName returns correctly
-               TestingAccessWrapper::newFromObject( $store )->tableCache = null;
-               $bazId = $store->acquireId( 'baz' );
-               $this->assertSame( 'baz', $store->getName( $bazId ) );
-               $this->assertSame( 'baz', $store->getName( $bazId ) );
+               TestingAccessWrapper::newFromObject( $store )->tableCache = null; // clear IMC
+               $bazId = $store->acquireId( 'baz' ); // set IMC using interim PC, update IMC, tombstone PC
+               $now += 0.01;
+               $this->assertSame( 'baz', $store->getName( $bazId ) ); // uses IMC
+               $this->assertSame( 'baz', $store->getName( $bazId ) ); // uses IMC
        }
 
        public function testGetName_masterFallback() {
index 25dc9b3..abd70b2 100644 (file)
@@ -31,30 +31,6 @@ class TitleMethodsTest extends MediaWikiLangTestCase {
                );
        }
 
-       public static function provideEquals() {
-               return [
-                       [ 'Main Page', 'Main Page', true ],
-                       [ 'Main Page', 'Not The Main Page', false ],
-                       [ 'Main Page', 'Project:Main Page', false ],
-                       [ 'File:Example.png', 'Image:Example.png', true ],
-                       [ 'Special:Version', 'Special:Version', true ],
-                       [ 'Special:Version', 'Special:Recentchanges', false ],
-                       [ 'Special:Version', 'Main Page', false ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideEquals
-        * @covers Title::equals
-        */
-       public function testEquals( $titleA, $titleB, $expectedBool ) {
-               $titleA = Title::newFromText( $titleA );
-               $titleB = Title::newFromText( $titleB );
-
-               $this->assertEquals( $expectedBool, $titleA->equals( $titleB ) );
-               $this->assertEquals( $expectedBool, $titleB->equals( $titleA ) );
-       }
-
        public static function provideInNamespace() {
                return [
                        [ 'Main Page', NS_MAIN, true ],
index 1157331..f7ffe8d 100644 (file)
@@ -6,8 +6,8 @@ use MediaWiki\MediaWikiServices;
 /**
  * @group Database
  *
- * @covers Title::getUserPermissionsErrors
- * @covers Title::getUserPermissionsErrorsInternal
+ * @covers \MediaWiki\Permissions\PermissionManager::getPermissionErrors
+ * @covers \MediaWiki\Permissions\PermissionManager::getPermissionErrorsInternal
  */
 class TitlePermissionTest extends MediaWikiLangTestCase {
 
@@ -104,7 +104,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
         * This test is failing per T201776.
         *
         * @group Broken
-        * @covers Title::checkQuickPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkQuickPermissions
         */
        public function testQuickPermissions() {
                $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
@@ -395,7 +395,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkSpecialsAndNSPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkSpecialsAndNSPermissions
         */
        public function testSpecialsAndNSPermissions() {
                global $wgNamespaceProtection;
@@ -452,7 +452,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testJsConfigEditPermissions() {
                $this->setUser( $this->userName );
@@ -475,7 +475,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testJsonConfigEditPermissions() {
                $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
@@ -500,7 +500,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testCssConfigEditPermissions() {
                $this->setUser( $this->userName );
@@ -523,7 +523,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testOtherJsConfigEditPermissions() {
                $this->setUser( $this->userName );
@@ -546,7 +546,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testOtherJsonConfigEditPermissions() {
                $this->setUser( $this->userName );
@@ -569,7 +569,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testOtherCssConfigEditPermissions() {
                $this->setUser( $this->userName );
@@ -592,7 +592,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testOtherNonConfigEditPermissions() {
                $this->setUser( $this->userName );
@@ -614,7 +614,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
 
        /**
         * @todo This should use data providers like the other methods here.
-        * @covers Title::checkUserConfigPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
         */
        public function testPatrolActionConfigEditPermissions() {
                $this->setUser( 'anon' );
@@ -687,7 +687,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
         * This test is failing per T201776.
         *
         * @group Broken
-        * @covers Title::checkPageRestrictions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkPageRestrictions
         */
        public function testPageRestrictions() {
                $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
@@ -780,7 +780,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        }
 
        /**
-        * @covers Title::checkCascadingSourcesRestrictions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkCascadingSourcesRestrictions
         */
        public function testCascadingSourcesRestrictions() {
                $this->setTitle( NS_MAIN, "test page" );
@@ -811,7 +811,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
-        * @covers Title::checkActionPermissions
+        * @covers \MediaWiki\Permissions\PermissionManager::checkActionPermissions
         */
        public function testActionPermissions() {
                $this->setUserPerm( [ "createpage" ] );
@@ -885,13 +885,14 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        }
 
        /**
-        * @covers Title::checkUserBlock
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
         */
        public function testUserBlock() {
                $this->setMwGlobals( [
                        'wgEmailConfirmToEdit' => true,
                        'wgEmailAuthentication' => true,
                ] );
+               $this->overrideMwServices();
 
                $this->setUserPerm( [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ] );
                $this->setTitle( NS_HELP, "test page" );
@@ -903,6 +904,8 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
 
                $this->setMwGlobals( 'wgEmailConfirmToEdit', false );
+               $this->overrideMwServices();
+
                $this->assertNotContains( [ 'confirmedittext' ],
                        $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
 
@@ -923,7 +926,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        'auto' => true,
                        'expiry' => 0
                ] );
-               $this->user->mBlock->mTimestamp = 0;
+               $this->user->mBlock->setTimestamp( 0 );
                $this->assertEquals( [ [ 'autoblockedtext',
                                '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
                                'Useruser', null, 'infinite', '127.0.8.1',
@@ -1037,4 +1040,54 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->assertEquals( [],
                        $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
        }
+
+       /**
+        * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
+        *
+        * Tests to determine that the passed in permission does not get mixed up with
+        * an action of the same name.
+        */
+       public function testUserBlockAction() {
+               global $wgLang;
+
+               $tester = $this->getMockBuilder( Action::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $tester->method( 'getName' )
+                       ->willReturn( 'tester' );
+               $tester->method( 'getRestriction' )
+                       ->willReturn( 'test' );
+               $tester->method( 'requiresUnblock' )
+                       ->willReturn( false );
+
+               $this->setMwGlobals( [
+                       'wgActions' => [
+                               'tester' => $tester,
+                       ],
+                       'wgGroupPermissions' => [
+                               '*' => [
+                                       'tester' => true,
+                               ],
+                       ],
+               ] );
+
+               $now = time();
+               $this->user->mBlockedby = $this->user->getName();
+               $this->user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $this->user->getId(),
+                       'reason' => 'no reason given',
+                       'timestamp' => $now,
+                       'auto' => false,
+                       'expiry' => 'infinity',
+               ] );
+
+               $errors = [ [ 'blockedtext',
+                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                               'Useruser', null, 'infinite', '127.0.8.1',
+                               $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
+
+               $this->assertEquals( $errors,
+                       $this->title->getUserPermissionsErrors( 'tester', $this->user ) );
+       }
 }
index 9c1d5af..149c25b 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -289,7 +290,6 @@ class TitleTest extends MediaWikiTestCase {
         * @param array|string|bool $expected Required error
         * @dataProvider provideTestIsValidMoveOperation
         * @covers Title::isValidMoveOperation
-        * @covers Title::validateFileMoveOperation
         */
        public function testIsValidMoveOperation( $source, $target, $expected ) {
                $this->setMwGlobals( 'wgContentHandlerUseDB', false );
@@ -315,7 +315,6 @@ class TitleTest extends MediaWikiTestCase {
                        [ 'Test', 'Special:FooBar', 'immobile-target-namespace' ],
                        [ 'MediaWiki:Common.js', 'Help:Some wikitext page', 'bad-target-model' ],
                        [ 'Page', 'File:Test.jpg', 'nonfile-cannot-move-to-file' ],
-                       // for Title::validateFileMoveOperation
                        [ 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ],
                ];
        }
@@ -328,7 +327,7 @@ class TitleTest extends MediaWikiTestCase {
         * @param string $action
         * @param array|string|bool $expected Required error
         *
-        * @covers Title::checkReadPermissions
+        * @covers \Mediawiki\Permissions\PermissionManager::checkReadPermissions
         * @dataProvider dataWgWhitelistReadRegexp
         */
        public function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) {
@@ -566,6 +565,32 @@ class TitleTest extends MediaWikiTestCase {
                $this->assertEquals( $value->getFragment(), $title->getFragment() );
        }
 
+       /**
+        * @covers Title::newFromLinkTarget
+        * @dataProvider provideNewFromTitleValue
+        */
+       public function testNewFromLinkTarget( LinkTarget $value ) {
+               $title = Title::newFromLinkTarget( $value );
+
+               $dbkey = str_replace( ' ', '_', $value->getText() );
+               $this->assertEquals( $dbkey, $title->getDBkey() );
+               $this->assertEquals( $value->getNamespace(), $title->getNamespace() );
+               $this->assertEquals( $value->getFragment(), $title->getFragment() );
+       }
+
+       /**
+        * @covers Title::newFromLinkTarget
+        */
+       public function testNewFromLinkTarget_clone() {
+               $title = Title::newFromText( __METHOD__ );
+               $this->assertSame( $title, Title::newFromLinkTarget( $title ) );
+
+               // The Title::NEW_CLONE flag should ensure that a fresh instance is returned.
+               $clone = Title::newFromLinkTarget( $title, Title::NEW_CLONE );
+               $this->assertNotSame( $title, $clone );
+               $this->assertTrue( $clone->equals( $title ) );
+       }
+
        public static function provideGetTitleValue() {
                return [
                        [ 'Foo' ],
@@ -983,4 +1008,93 @@ class TitleTest extends MediaWikiTestCase {
                        [ 'Main Page', false ],
                ];
        }
+
+       public function provideEquals() {
+               yield [
+                       Title::newFromText( 'Main Page' ),
+                       Title::newFromText( 'Main Page' ),
+                       true
+               ];
+               yield [
+                       Title::newFromText( 'Main Page' ),
+                       Title::newFromText( 'Not The Main Page' ),
+                       false
+               ];
+               yield [
+                       Title::newFromText( 'Main Page' ),
+                       Title::newFromText( 'Project:Main Page' ),
+                       false
+               ];
+               yield [
+                       Title::newFromText( 'File:Example.png' ),
+                       Title::newFromText( 'Image:Example.png' ),
+                       true
+               ];
+               yield [
+                       Title::newFromText( 'Special:Version' ),
+                       Title::newFromText( 'Special:Version' ),
+                       true
+               ];
+               yield [
+                       Title::newFromText( 'Special:Version' ),
+                       Title::newFromText( 'Special:Recentchanges' ),
+                       false
+               ];
+               yield [
+                       Title::newFromText( 'Special:Version' ),
+                       Title::newFromText( 'Main Page' ),
+                       false
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
+                       Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
+                       true
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
+                       Title::makeTitle( NS_MAIN, 'Bar', '', '' ),
+                       false
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
+                       Title::makeTitle( NS_TALK, 'Foo', '', '' ),
+                       false
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
+                       Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
+                       true
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
+                       Title::makeTitle( NS_MAIN, 'Foo', 'Baz', '' ),
+                       true
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
+                       Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
+                       true
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
+                       Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
+                       true
+               ];
+               yield [
+                       Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
+                       Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
+                       false
+               ];
+       }
+
+       /**
+        * @covers Title::equals
+        * @dataProvider provideEquals
+        */
+       public function testEquals( Title $firstValue, /* LinkTarget */ $secondValue, $expectedSame ) {
+               $this->assertSame(
+                       $expectedSame,
+                       $firstValue->equals( $secondValue )
+               );
+       }
 }
index e87e434..1608b9c 100644 (file)
@@ -237,13 +237,13 @@ class WikiMapTest extends MediaWikiLangTestCase {
 
        public function provideGetWikiIdFromDomain() {
                return [
-                       [ 'db-prefix', 'db-prefix' ],
+                       [ 'db-prefix_', 'db-prefix_' ],
                        [ wfWikiID(), wfWikiID() ],
-                       [ new DatabaseDomain( 'db-dash', null, 'prefix' ), 'db-dash-prefix' ],
+                       [ new DatabaseDomain( 'db-dash', null, 'prefix_' ), 'db-dash-prefix_' ],
                        [ wfWikiID(), wfWikiID() ],
-                       [ new DatabaseDomain( 'db-dash', null, 'prefix' ), 'db-dash-prefix' ],
-                       [ new DatabaseDomain( 'db', 'mediawiki', 'prefix' ), 'db-prefix' ], // schema ignored
-                       [ new DatabaseDomain( 'db', 'custom', 'prefix' ), 'db-custom-prefix' ],
+                       [ new DatabaseDomain( 'db-dash', null, 'prefix_' ), 'db-dash-prefix_' ],
+                       [ new DatabaseDomain( 'db', 'mediawiki', 'prefix_' ), 'db-prefix_' ], // schema ignored
+                       [ new DatabaseDomain( 'db', 'custom', 'prefix_' ), 'db-custom-prefix_' ],
                ];
        }
 
@@ -260,16 +260,19 @@ class WikiMapTest extends MediaWikiLangTestCase {
         * @covers WikiMap::getCurrentWikiDbDomain()
         */
        public function testIsCurrentWikiDomain() {
-               $this->assertTrue( WikiMap::isCurrentWikiDbDomain( wfWikiID() ) );
+               $this->setMwGlobals( 'wgDBmwschema', 'mediawiki' );
 
-               $localDomain = DatabaseDomain::newFromId( wfWikiID() );
+               $localDomain = WikiMap::getCurrentWikiDbDomain()->getId();
+               $this->assertTrue( WikiMap::isCurrentWikiDbDomain( $localDomain ) );
+
+               $localDomain = DatabaseDomain::newFromId( $localDomain );
                $domain1 = new DatabaseDomain(
                        $localDomain->getDatabase(), 'someschema', $localDomain->getTablePrefix() );
                $domain2 = new DatabaseDomain(
                        $localDomain->getDatabase(), null, $localDomain->getTablePrefix() );
 
-               $this->assertTrue( WikiMap::isCurrentWikiDbDomain( $domain1 ), 'Schema ignored' );
-               $this->assertTrue( WikiMap::isCurrentWikiDbDomain( $domain2 ), 'Schema ignored' );
+               $this->assertFalse( WikiMap::isCurrentWikiDbDomain( $domain1 ), 'Schema not ignored' );
+               $this->assertFalse( WikiMap::isCurrentWikiDbDomain( $domain2 ), 'Null schema not ignored' );
 
                $this->assertTrue( WikiMap::isCurrentWikiDbDomain( WikiMap::getCurrentWikiDbDomain() ) );
        }
@@ -279,15 +282,15 @@ class WikiMapTest extends MediaWikiLangTestCase {
                        [ 'db', 'db', null, '' ],
                        [ 'db-schema-','db', 'schema', '' ],
                        [ 'db','db', 'mediawiki', '' ], // common b/c case
-                       [ 'db-prefix', 'db', null, 'prefix' ],
-                       [ 'db-schema-prefix', 'db', 'schema', 'prefix' ],
-                       [ 'db-prefix', 'db', 'mediawiki', 'prefix' ], // common b/c case
+                       [ 'db-prefix_', 'db', null, 'prefix_' ],
+                       [ 'db-schema-prefix_', 'db', 'schema', 'prefix_' ],
+                       [ 'db-prefix_', 'db', 'mediawiki', 'prefix_' ], // common b/c case
                        // Bad hyphen cases (best effort support)
                        [ 'db-stuff', 'db-stuff', null, '' ],
-                       [ 'db-stuff-prefix', 'db-stuff', null, 'prefix' ],
+                       [ 'db-stuff-prefix_', 'db-stuff', null, 'prefix_' ],
                        [ 'db-stuff-schema-', 'db-stuff', 'schema', '' ],
-                       [ 'db-stuff-schema-prefix', 'db-stuff', 'schema', 'prefix' ],
-                       [ 'db-stuff-prefix', 'db-stuff', 'mediawiki', 'prefix' ] // common b/c case
+                       [ 'db-stuff-schema-prefix_', 'db-stuff', 'schema', 'prefix_' ],
+                       [ 'db-stuff-prefix_', 'db-stuff', 'mediawiki', 'prefix_' ] // common b/c case
                ];
        }
 
index 4600551..0dc64df 100644 (file)
@@ -1297,6 +1297,8 @@ class ApiBaseTest extends ApiTestCase {
        public function testErrorArrayToStatus() {
                $mock = new MockApi();
 
+               $msg = new Message( 'mainpage' );
+
                // Sanity check empty array
                $expect = Status::newGood();
                $this->assertEquals( $expect, $mock->errorArrayToStatus( [] ) );
@@ -1307,12 +1309,16 @@ class ApiBaseTest extends ApiTestCase {
                $expect->fatal( 'autoblockedtext' );
                $expect->fatal( 'systemblockedtext' );
                $expect->fatal( 'mainpage' );
+               $expect->fatal( $msg );
+               $expect->fatal( $msg, 'foobar' );
                $expect->fatal( 'parentheses', 'foobar' );
                $this->assertEquals( $expect, $mock->errorArrayToStatus( [
                        [ 'blockedtext' ],
                        [ 'autoblockedtext' ],
                        [ 'systemblockedtext' ],
                        'mainpage',
+                       $msg,
+                       [ $msg, 'foobar' ],
                        [ 'parentheses', 'foobar' ],
                ] ) );
 
@@ -1333,12 +1339,16 @@ class ApiBaseTest extends ApiTestCase {
                $expect->fatal( ApiMessage::create( 'apierror-autoblocked', 'autoblocked', $blockinfo ) );
                $expect->fatal( ApiMessage::create( 'apierror-systemblocked', 'blocked', $blockinfo ) );
                $expect->fatal( 'mainpage' );
+               $expect->fatal( $msg );
+               $expect->fatal( $msg, 'foobar' );
                $expect->fatal( 'parentheses', 'foobar' );
                $this->assertEquals( $expect, $mock->errorArrayToStatus( [
                        [ 'blockedtext' ],
                        [ 'autoblockedtext' ],
                        [ 'systemblockedtext' ],
                        'mainpage',
+                       $msg,
+                       [ $msg, 'foobar' ],
                        [ 'parentheses', 'foobar' ],
                ], $user ) );
        }
@@ -1346,6 +1356,8 @@ class ApiBaseTest extends ApiTestCase {
        public function testAddBlockInfoToStatus() {
                $mock = new MockApi();
 
+               $msg = new Message( 'mainpage' );
+
                // Sanity check empty array
                $expect = Status::newGood();
                $test = Status::newGood();
@@ -1358,6 +1370,8 @@ class ApiBaseTest extends ApiTestCase {
                $expect->fatal( 'autoblockedtext' );
                $expect->fatal( 'systemblockedtext' );
                $expect->fatal( 'mainpage' );
+               $expect->fatal( $msg );
+               $expect->fatal( $msg, 'foobar' );
                $expect->fatal( 'parentheses', 'foobar' );
                $test = clone $expect;
                $mock->addBlockInfoToStatus( $test );
@@ -1380,12 +1394,16 @@ class ApiBaseTest extends ApiTestCase {
                $expect->fatal( ApiMessage::create( 'apierror-autoblocked', 'autoblocked', $blockinfo ) );
                $expect->fatal( ApiMessage::create( 'apierror-systemblocked', 'blocked', $blockinfo ) );
                $expect->fatal( 'mainpage' );
+               $expect->fatal( $msg );
+               $expect->fatal( $msg, 'foobar' );
                $expect->fatal( 'parentheses', 'foobar' );
                $test = Status::newGood();
                $test->fatal( 'blockedtext' );
                $test->fatal( 'autoblockedtext' );
                $test->fatal( 'systemblockedtext' );
                $test->fatal( 'mainpage' );
+               $test->fatal( $msg );
+               $test->fatal( $msg, 'foobar' );
                $test->fatal( 'parentheses', 'foobar' );
                $mock->addBlockInfoToStatus( $test, $user );
                $this->assertEquals( $expect, $test );
index a26f8a8..7274a54 100644 (file)
@@ -62,7 +62,7 @@ class ApiBlockTest extends ApiTestCase {
                $this->assertTrue( !is_null( $block ), 'Block is valid' );
 
                $this->assertSame( $this->mUser->getName(), (string)$block->getTarget() );
-               $this->assertSame( 'Some reason', $block->mReason );
+               $this->assertSame( 'Some reason', $block->getReason() );
 
                return $ret;
        }
@@ -131,8 +131,8 @@ class ApiBlockTest extends ApiTestCase {
                        __METHOD__,
                        [],
                        [
-                               'change_tag' => [ 'INNER JOIN', 'ct_log_id = log_id' ],
-                               'change_tag_def' => [ 'INNER JOIN', 'ctd_id = ct_tag_id' ],
+                               'change_tag' => [ 'JOIN', 'ct_log_id = log_id' ],
+                               'change_tag_def' => [ 'JOIN', 'ctd_id = ct_tag_id' ],
                        ]
                ) );
        }
index 803eefb..c68954c 100644 (file)
@@ -128,8 +128,8 @@ class ApiDeleteTest extends ApiTestCase {
                        __METHOD__,
                        [],
                        [
-                               'change_tag' => [ 'INNER JOIN', 'ct_log_id = log_id' ],
-                               'change_tag_def' => [ 'INNER JOIN', 'ctd_id = ct_tag_id' ]
+                               'change_tag' => [ 'JOIN', 'ct_log_id = log_id' ],
+                               'change_tag_def' => [ 'JOIN', 'ctd_id = ct_tag_id' ]
                        ]
                ) );
        }
index 1706ad1..aeb829d 100644 (file)
@@ -1349,7 +1349,7 @@ class ApiEditPageTest extends ApiTestCase {
                        'ctd_name',
                        [ 'ct_rev_id' => $revId ],
                        __METHOD__,
-                       [ 'change_tag_def' => [ 'INNER JOIN', 'ctd_id = ct_tag_id' ] ]
+                       [ 'change_tag_def' => [ 'JOIN', 'ctd_id = ct_tag_id' ] ]
                        )
                );
        }
index b9c49b1..d437a52 100644 (file)
@@ -17,6 +17,7 @@ class ApiMoveTest extends ApiTestCase {
        protected function assertMoved( $from, $to, $id, $opts = null ) {
                $opts = (array)$opts;
 
+               Title::clearCaches();
                $fromTitle = Title::newFromText( $from );
                $toTitle = Title::newFromText( $to );
 
index b20d43e..f8399a3 100644 (file)
@@ -650,7 +650,6 @@ class ApiParseTest extends ApiTestCase {
                        function ( $parser ) {
                                $output = $parser->getOutput();
                                $output->addModules( [ 'foo', 'bar' ] );
-                               $output->addModuleScripts( [ 'baz', 'quuz' ] );
                                $output->addModuleStyles( [ 'aaa', 'zzz' ] );
                                $output->addJsConfigVars( [ 'x' => 'y', 'z' => -3 ] );
                        }
@@ -663,7 +662,7 @@ class ApiParseTest extends ApiTestCase {
                ] );
 
                $this->assertSame( [ 'foo', 'bar' ], $res[0]['parse']['modules'] );
-               $this->assertSame( [ 'baz', 'quuz' ], $res[0]['parse']['modulescripts'] );
+               $this->assertSame( [], $res[0]['parse']['modulescripts'] );
                $this->assertSame( [ 'aaa', 'zzz' ], $res[0]['parse']['modulestyles'] );
                $this->assertSame( [ 'x' => 'y', 'z' => -3 ], $res[0]['parse']['jsconfigvars'] );
                $this->assertSame( '{"x":"y","z":-3}', $res[0]['parse']['encodedjsconfigvars'] );
index d3a4ed4..55f4a33 100644 (file)
@@ -590,7 +590,10 @@ class ApiQuerySiteinfoTest extends ApiTestCase {
        }
 
        public function testVariables() {
-               $this->assertSame( MagicWord::getVariableIDs(), $this->doQuery( 'variables' ) );
+               $this->assertSame(
+                       MediaWikiServices::getInstance()->getMagicWordFactory()->getVariableIDs(),
+                       $this->doQuery( 'variables' )
+               );
        }
 
        public function testProtocols() {
index 5ef3b04..a63f8aa 100644 (file)
@@ -331,6 +331,8 @@ class ApiStashEditTest extends ApiTestCase {
                $cache = ObjectCache::getLocalClusterInstance();
 
                $editInfo = $cache->get( $key );
+               $outputKey = $cache->makeKey( 'stashed-edit-output', $editInfo->outputID );
+               $editInfo->output = $cache->get( $outputKey );
                $editInfo->output->setCacheTime( wfTimestamp( TS_MW,
                        wfTimestamp( TS_UNIX, $editInfo->output->getCacheTime() ) - $howOld - 1 ) );
 
index 9a27cf1..4377207 100644 (file)
@@ -26,7 +26,6 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                ];
 
                $this->setMwGlobals( [
-                       'wgAuth' => new MediaWiki\Auth\AuthManagerAuthPlugin,
                        'wgRequest' => new FauxRequest( [] ),
                        'wgUser' => self::$users['sysop']->getUser(),
                ] );
index 6ebd835..ea39da7 100644 (file)
@@ -127,8 +127,8 @@ class ApiUnblockTest extends ApiTestCase {
                        __METHOD__,
                        [],
                        [
-                               'change_tag' => [ 'INNER JOIN', 'ct_log_id = log_id' ],
-                               'change_tag_def' => [ 'INNER JOIN', 'ctd_id = ct_tag_id' ],
+                               'change_tag' => [ 'JOIN', 'ct_log_id = log_id' ],
+                               'change_tag_def' => [ 'JOIN', 'ctd_id = ct_tag_id' ],
                        ]
                ) );
        }
index 8cc0217..5889f82 100644 (file)
@@ -206,7 +206,7 @@ class ApiUserrightsTest extends ApiTestCase {
                                        'log_title' => strtr( $user->getName(), ' ', '_' )
                                ],
                                __METHOD__,
-                               [ 'change_tag_def' => [ 'INNER JOIN', 'ctd_id = ct_tag_id' ] ]
+                               [ 'change_tag_def' => [ 'JOIN', 'ctd_id = ct_tag_id' ] ]
                        )
                );
        }
index 08af755..7869bbd 100644 (file)
@@ -32,14 +32,14 @@ STR;
 
        /**
         * Merges all requests parameter + expected values into one
-        * @param array $v,... List of arrays, each of which contains exactly two
+        * @param array ...$arrays List of arrays, each of which contains exactly two
         * @return array
         */
-       protected function merge( /*...*/ ) {
+       protected function merge( ...$arrays ) {
                $request = [];
                $expected = [];
-               foreach ( func_get_args() as $v ) {
-                       list( $req, $exp ) = $this->validateRequestExpectedPair( $v );
+               foreach ( $arrays as $array ) {
+                       list( $req, $exp ) = $this->validateRequestExpectedPair( $array );
                        $request = array_merge_recursive( $request, $req );
                        $this->mergeExpected( $expected, $exp );
                }
index e67d405..49601cb 100644 (file)
@@ -142,7 +142,7 @@ class AbstractPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCa
                $this->assertNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
 
                $manager->removeAuthenticationSessionData( null );
-               $status = \Status::newGood();
+               $status = \Status::newGood( [ 'suggestChangeOnLogin' => true ] );
                $status->error( 'testing' );
                $providerPriv->setPasswordResetFlag( 'Foo', $status );
                $ret = $manager->getAuthenticationSessionData( 'reset-pass' );
index e8981ec..d5e1879 100644 (file)
@@ -34,12 +34,6 @@ class AuthManagerTest extends \MediaWikiTestCase {
        /** @var TestingAccessWrapper */
        protected $managerPriv;
 
-       protected function setUp() {
-               parent::setUp();
-
-               $this->setMwGlobals( [ 'wgAuth' => null ] );
-       }
-
        /**
         * Sets a mock on a hook
         * @param string $hook
@@ -2352,8 +2346,6 @@ class AuthManagerTest extends \MediaWikiTestCase {
        }
 
        public function testAutoAccountCreation() {
-               global $wgHooks;
-
                // PHPUnit seems to have a bug where it will call the ->with()
                // callbacks for our hooks again after the test is run (WTF?), which
                // breaks here because $username no longer matches $user by the end of
@@ -2771,15 +2763,10 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $session->clear();
                $username = self::usernameForCreation();
                $user = \User::newFromName( $username );
-               $this->hook( 'AuthPluginAutoCreate', $this->once() )
-                       ->with( $callback );
-               $this->hideDeprecated( 'AuthPluginAutoCreate hook (used in ' .
-                               get_class( $wgHooks['AuthPluginAutoCreate'][0] ) . '::onAuthPluginAutoCreate)' );
                $this->hook( 'LocalUserCreated', $this->once() )
                        ->with( $callback, $this->equalTo( true ) );
                $ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
                $this->unhook( 'LocalUserCreated' );
-               $this->unhook( 'AuthPluginAutoCreate' );
                $this->assertEquals( \Status::newGood(), $ret );
                $this->assertNotEquals( 0, $user->getId() );
                $this->assertEquals( $username, $user->getName() );
diff --git a/tests/phpunit/includes/auth/AuthPluginPrimaryAuthenticationProviderTest.php b/tests/phpunit/includes/auth/AuthPluginPrimaryAuthenticationProviderTest.php
deleted file mode 100644 (file)
index 44e9799..0000000
+++ /dev/null
@@ -1,716 +0,0 @@
-<?php
-
-namespace MediaWiki\Auth;
-
-/**
- * @group AuthManager
- * @covers \MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider
- */
-class AuthPluginPrimaryAuthenticationProviderTest extends \MediaWikiTestCase {
-       public function testConstruction() {
-               $plugin = new AuthManagerAuthPlugin();
-               try {
-                       $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-                       $this->fail( 'Expected exception not thrown' );
-               } catch ( \InvalidArgumentException $ex ) {
-                       $this->assertSame(
-                               'Trying to wrap AuthManagerAuthPlugin in AuthPluginPrimaryAuthenticationProvider ' .
-                                       'makes no sense.',
-                               $ex->getMessage()
-                       );
-               }
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals(
-                       [ new PasswordAuthenticationRequest ],
-                       $provider->getAuthenticationRequests( AuthManager::ACTION_LOGIN, [] )
-               );
-
-               $req = $this->createMock( PasswordAuthenticationRequest::class );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin, get_class( $req ) );
-               $this->assertEquals(
-                       [ $req ],
-                       $provider->getAuthenticationRequests( AuthManager::ACTION_LOGIN, [] )
-               );
-
-               $reqType = get_class( $this->createMock( AuthenticationRequest::class ) );
-               try {
-                       $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin, $reqType );
-                       $this->fail( 'Expected exception not thrown' );
-               } catch ( \InvalidArgumentException $ex ) {
-                       $this->assertSame(
-                               "$reqType is not a MediaWiki\\Auth\\PasswordAuthenticationRequest",
-                               $ex->getMessage()
-                       );
-               }
-       }
-
-       public function testOnUserSaveSettings() {
-               $user = \User::newFromName( 'UTSysop' );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'updateExternalDB' )
-                       ->with( $this->identicalTo( $user ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               \Hooks::run( 'UserSaveSettings', [ $user ] );
-       }
-
-       public function testOnUserGroupsChanged() {
-               $user = \User::newFromName( 'UTSysop' );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'updateExternalDBGroups' )
-                       ->with(
-                               $this->identicalTo( $user ),
-                               $this->identicalTo( [ 'added' ] ),
-                               $this->identicalTo( [ 'removed' ] )
-                       );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               \Hooks::run( 'UserGroupsChanged', [ $user, [ 'added' ], [ 'removed' ], false, false, [], [] ] );
-       }
-
-       public function testOnUserLoggedIn() {
-               $user = \User::newFromName( 'UTSysop' );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->exactly( 2 ) )->method( 'updateUser' )
-                       ->with( $this->identicalTo( $user ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               \Hooks::run( 'UserLoggedIn', [ $user ] );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'updateUser' )
-                       ->will( $this->returnCallback( function ( &$user ) {
-                               $user = \User::newFromName( 'UTSysop' );
-                       } ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               try {
-                       \Hooks::run( 'UserLoggedIn', [ $user ] );
-                       $this->fail( 'Expected exception not thrown' );
-               } catch ( \UnexpectedValueException $ex ) {
-                       $this->assertSame(
-                               get_class( $plugin ) . '::updateUser() tried to replace $user!',
-                               $ex->getMessage()
-                       );
-               }
-       }
-
-       public function testOnLocalUserCreated() {
-               $user = \User::newFromName( 'UTSysop' );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->exactly( 2 ) )->method( 'initUser' )
-                       ->with( $this->identicalTo( $user ), $this->identicalTo( false ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               \Hooks::run( 'LocalUserCreated', [ $user, false ] );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'initUser' )
-                       ->will( $this->returnCallback( function ( &$user ) {
-                               $user = \User::newFromName( 'UTSysop' );
-                       } ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               try {
-                       \Hooks::run( 'LocalUserCreated', [ $user, false ] );
-                       $this->fail( 'Expected exception not thrown' );
-               } catch ( \UnexpectedValueException $ex ) {
-                       $this->assertSame(
-                               get_class( $plugin ) . '::initUser() tried to replace $user!',
-                               $ex->getMessage()
-                       );
-               }
-       }
-
-       public function testGetUniqueId() {
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertSame(
-                       'MediaWiki\\Auth\\AuthPluginPrimaryAuthenticationProvider:' . get_class( $plugin ),
-                       $provider->getUniqueId()
-               );
-       }
-
-       /**
-        * @dataProvider provideGetAuthenticationRequests
-        * @param string $action
-        * @param array $response
-        * @param bool $allowPasswordChange
-        */
-       public function testGetAuthenticationRequests( $action, $response, $allowPasswordChange ) {
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->any() )->method( 'allowPasswordChange' )
-                       ->will( $this->returnValue( $allowPasswordChange ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals( $response, $provider->getAuthenticationRequests( $action, [] ) );
-       }
-
-       public static function provideGetAuthenticationRequests() {
-               $arr = [ new PasswordAuthenticationRequest() ];
-               return [
-                       [ AuthManager::ACTION_LOGIN, $arr, true ],
-                       [ AuthManager::ACTION_LOGIN, $arr, false ],
-                       [ AuthManager::ACTION_CREATE, $arr, true ],
-                       [ AuthManager::ACTION_CREATE, $arr, false ],
-                       [ AuthManager::ACTION_LINK, [], true ],
-                       [ AuthManager::ACTION_LINK, [], false ],
-                       [ AuthManager::ACTION_CHANGE, $arr, true ],
-                       [ AuthManager::ACTION_CHANGE, [], false ],
-                       [ AuthManager::ACTION_REMOVE, $arr, true ],
-                       [ AuthManager::ACTION_REMOVE, [], false ],
-               ];
-       }
-
-       public function testAuthentication() {
-               $req = new PasswordAuthenticationRequest();
-               $req->action = AuthManager::ACTION_LOGIN;
-               $reqs = [ PasswordAuthenticationRequest::class => $req ];
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'authenticate' ] )
-                       ->getMock();
-               $plugin->expects( $this->never() )->method( 'authenticate' );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAuthentication( [] )
-               );
-
-               $req->username = 'foo';
-               $req->password = null;
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAuthentication( $reqs )
-               );
-
-               $req->username = null;
-               $req->password = 'bar';
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAuthentication( $reqs )
-               );
-
-               $req->username = 'foo';
-               $req->password = 'bar';
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'userExists', 'authenticate' ] )
-                       ->getMock();
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'authenticate' )
-                       ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals(
-                       AuthenticationResponse::newPass( 'Foo', $req ),
-                       $provider->beginPrimaryAuthentication( $reqs )
-               );
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'userExists', 'authenticate' ] )
-                       ->getMock();
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->will( $this->returnValue( false ) );
-               $plugin->expects( $this->never() )->method( 'authenticate' );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAuthentication( $reqs )
-               );
-
-               $pluginUser = $this->getMockBuilder( \AuthPluginUser::class )
-                       ->setMethods( [ 'isLocked' ] )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-               $pluginUser->expects( $this->once() )->method( 'isLocked' )
-                       ->will( $this->returnValue( true ) );
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'userExists', 'getUserInstance', 'authenticate' ] )
-                       ->getMock();
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'getUserInstance' )
-                       ->will( $this->returnValue( $pluginUser ) );
-               $plugin->expects( $this->never() )->method( 'authenticate' );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAuthentication( $reqs )
-               );
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'userExists', 'authenticate' ] )
-                       ->getMock();
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'authenticate' )
-                       ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( false ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAuthentication( $reqs )
-               );
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'userExists', 'authenticate', 'strict' ] )
-                       ->getMock();
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'authenticate' )
-                       ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( false ) );
-               $plugin->expects( $this->any() )->method( 'strict' )->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $ret = $provider->beginPrimaryAuthentication( $reqs );
-               $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
-               $this->assertSame( 'wrongpassword', $ret->message->getKey() );
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'userExists', 'authenticate', 'strictUserAuth' ] )
-                       ->getMock();
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'authenticate' )
-                       ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( false ) );
-               $plugin->expects( $this->any() )->method( 'strictUserAuth' )
-                       ->with( $this->equalTo( 'Foo' ) )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $ret = $provider->beginPrimaryAuthentication( $reqs );
-               $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
-               $this->assertSame( 'wrongpassword', $ret->message->getKey() );
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'domainList', 'validDomain', 'setDomain', 'userExists', 'authenticate' ] )
-                       ->getMock();
-               $plugin->expects( $this->any() )->method( 'domainList' )
-                       ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
-               $plugin->expects( $this->any() )->method( 'validDomain' )
-                       ->will( $this->returnCallback( function ( $domain ) {
-                               return in_array( $domain, [ 'Domain1', 'Domain2' ] );
-                       } ) );
-               $plugin->expects( $this->once() )->method( 'setDomain' )
-                       ->with( $this->equalTo( 'Domain2' ) );
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'authenticate' )
-                       ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_LOGIN, [] );
-               $req->username = 'foo';
-               $req->password = 'bar';
-               $req->domain = 'Domain2';
-               $provider->beginPrimaryAuthentication( [ $req ] );
-       }
-
-       public function testTestUserExists() {
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->with( $this->equalTo( 'Foo' ) )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               $this->assertTrue( $provider->testUserExists( 'foo' ) );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->with( $this->equalTo( 'Foo' ) )
-                       ->will( $this->returnValue( false ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               $this->assertFalse( $provider->testUserExists( 'foo' ) );
-       }
-
-       public function testTestUserCanAuthenticate() {
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->with( $this->equalTo( 'Foo' ) )
-                       ->will( $this->returnValue( false ) );
-               $plugin->expects( $this->never() )->method( 'getUserInstance' );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertFalse( $provider->testUserCanAuthenticate( 'foo' ) );
-
-               $pluginUser = $this->getMockBuilder( \AuthPluginUser::class )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-               $pluginUser->expects( $this->once() )->method( 'isLocked' )
-                       ->will( $this->returnValue( true ) );
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->with( $this->equalTo( 'Foo' ) )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'getUserInstance' )
-                       ->with( $this->callback( function ( $user ) {
-                               $this->assertInstanceOf( \User::class, $user );
-                               $this->assertEquals( 'Foo', $user->getName() );
-                               return true;
-                       } ) )
-                       ->will( $this->returnValue( $pluginUser ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertFalse( $provider->testUserCanAuthenticate( 'foo' ) );
-
-               $pluginUser = $this->getMockBuilder( \AuthPluginUser::class )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-               $pluginUser->expects( $this->once() )->method( 'isLocked' )
-                       ->will( $this->returnValue( false ) );
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'userExists' )
-                       ->with( $this->equalTo( 'Foo' ) )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'getUserInstance' )
-                       ->with( $this->callback( function ( $user ) {
-                               $this->assertInstanceOf( \User::class, $user );
-                               $this->assertEquals( 'Foo', $user->getName() );
-                               return true;
-                       } ) )
-                       ->will( $this->returnValue( $pluginUser ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'foo' ) );
-       }
-
-       public function testProviderRevokeAccessForUser() {
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'userExists', 'setPassword' ] )
-                       ->getMock();
-               $plugin->expects( $this->once() )->method( 'userExists' )->willReturn( true );
-               $plugin->expects( $this->once() )->method( 'setPassword' )
-                       ->with( $this->callback( function ( $u ) {
-                               return $u instanceof \User && $u->getName() === 'Foo';
-                       } ), $this->identicalTo( null ) )
-                       ->willReturn( true );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $provider->providerRevokeAccessForUser( 'foo' );
-
-               $plugin = $this->getMockBuilder( \AuthPlugin::class )
-                       ->setMethods( [ 'domainList', 'userExists', 'setPassword' ] )
-                       ->getMock();
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [ 'D1', 'D2', 'D3' ] );
-               $plugin->expects( $this->exactly( 3 ) )->method( 'userExists' )
-                       ->willReturnCallback( function () use ( $plugin ) {
-                               return $plugin->getDomain() !== 'D2';
-                       } );
-               $plugin->expects( $this->exactly( 2 ) )->method( 'setPassword' )
-                       ->with( $this->callback( function ( $u ) {
-                               return $u instanceof \User && $u->getName() === 'Foo';
-                       } ), $this->identicalTo( null ) )
-                       ->willReturnCallback( function () use ( $plugin ) {
-                               $this->assertNotEquals( 'D2', $plugin->getDomain() );
-                               return $plugin->getDomain() !== 'D1';
-                       } );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               try {
-                       $provider->providerRevokeAccessForUser( 'foo' );
-                       $this->fail( 'Expected exception not thrown' );
-               } catch ( \UnexpectedValueException $ex ) {
-                       $this->assertSame(
-                               'AuthPlugin failed to reset password for Foo in the following domains: D1',
-                               $ex->getMessage()
-                       );
-               }
-       }
-
-       public function testProviderAllowsPropertyChange() {
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->any() )->method( 'allowPropChange' )
-                       ->will( $this->returnCallback( function ( $prop ) {
-                               return $prop === 'allow';
-                       } ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               $this->assertTrue( $provider->providerAllowsPropertyChange( 'allow' ) );
-               $this->assertFalse( $provider->providerAllowsPropertyChange( 'deny' ) );
-       }
-
-       /**
-        * @dataProvider provideProviderAllowsAuthenticationDataChange
-        * @param string $type
-        * @param bool|null $allow
-        * @param StatusValue $expect
-        */
-       public function testProviderAllowsAuthenticationDataChange( $type, $allow, $expect ) {
-               $domains = $type instanceof PasswordDomainAuthenticationRequest ? [ 'foo', 'bar' ] : [];
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( $domains );
-               $plugin->expects( $allow === null ? $this->never() : $this->once() )
-                       ->method( 'allowPasswordChange' )->will( $this->returnValue( $allow ) );
-               $plugin->expects( $this->any() )->method( 'validDomain' )
-                       ->willReturnCallback( function ( $d ) use ( $domains ) {
-                               return in_array( $d, $domains, true );
-                       } );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               if ( is_object( $type ) ) {
-                       $req = $type;
-               } else {
-                       $req = $this->createMock( $type );
-               }
-               $req->action = AuthManager::ACTION_CHANGE;
-               $req->username = 'UTSysop';
-               $req->password = 'Pa$$w0Rd!!!';
-               $req->retype = 'Pa$$w0Rd!!!';
-               $this->assertEquals( $expect, $provider->providerAllowsAuthenticationDataChange( $req ) );
-       }
-
-       public static function provideProviderAllowsAuthenticationDataChange() {
-               $domains = [ 'foo', 'bar' ];
-               $reqNoDomain = new PasswordDomainAuthenticationRequest( $domains );
-               $reqValidDomain = new PasswordDomainAuthenticationRequest( $domains );
-               $reqValidDomain->domain = 'foo';
-               $reqInvalidDomain = new PasswordDomainAuthenticationRequest( $domains );
-               $reqInvalidDomain->domain = 'invalid';
-
-               return [
-                       [ AuthenticationRequest::class, null, \StatusValue::newGood( 'ignored' ) ],
-                       [ new PasswordAuthenticationRequest, true, \StatusValue::newGood() ],
-                       [
-                               new PasswordAuthenticationRequest,
-                               false,
-                               \StatusValue::newFatal( 'authmanager-authplugin-setpass-denied' )
-                       ],
-                       [ $reqNoDomain, true, \StatusValue::newGood( 'ignored' ) ],
-                       [ $reqValidDomain, true, \StatusValue::newGood() ],
-                       [
-                               $reqInvalidDomain,
-                               true,
-                               \StatusValue::newFatal( 'authmanager-authplugin-setpass-bad-domain' )
-                       ],
-               ];
-       }
-
-       public function testProviderChangeAuthenticationData() {
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->never() )->method( 'setPassword' );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $provider->providerChangeAuthenticationData(
-                       $this->createMock( AuthenticationRequest::class )
-               );
-
-               $req = new PasswordAuthenticationRequest();
-               $req->action = AuthManager::ACTION_CHANGE;
-               $req->username = 'foo';
-               $req->password = 'bar';
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'setPassword' )
-                       ->with( $this->callback( function ( $u ) {
-                               return $u instanceof \User && $u->getName() === 'Foo';
-                       } ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $provider->providerChangeAuthenticationData( $req );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )->method( 'setPassword' )
-                       ->with( $this->callback( function ( $u ) {
-                               return $u instanceof \User && $u->getName() === 'Foo';
-                       } ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( false ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               try {
-                       $provider->providerChangeAuthenticationData( $req );
-                       $this->fail( 'Expected exception not thrown' );
-               } catch ( \ErrorPageError $e ) {
-                       $this->assertSame( 'authmanager-authplugin-setpass-failed-title', $e->title );
-                       $this->assertSame( 'authmanager-authplugin-setpass-failed-message', $e->msg );
-               }
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )
-                       ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
-               $plugin->expects( $this->any() )->method( 'validDomain' )
-                       ->will( $this->returnCallback( function ( $domain ) {
-                               return in_array( $domain, [ 'Domain1', 'Domain2' ] );
-                       } ) );
-               $plugin->expects( $this->once() )->method( 'setDomain' )
-                       ->with( $this->equalTo( 'Domain2' ) );
-               $plugin->expects( $this->once() )->method( 'setPassword' )
-                       ->with( $this->callback( function ( $u ) {
-                               return $u instanceof \User && $u->getName() === 'Foo';
-                       } ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_CREATE, [] );
-               $req->username = 'foo';
-               $req->password = 'bar';
-               $req->domain = 'Domain2';
-               $provider->providerChangeAuthenticationData( $req );
-       }
-
-       /**
-        * @dataProvider provideAccountCreationType
-        * @param bool $can
-        * @param string $expect
-        */
-       public function testAccountCreationType( $can, $expect ) {
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->once() )
-                       ->method( 'canCreateAccounts' )->will( $this->returnValue( $can ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               $this->assertSame( $expect, $provider->accountCreationType() );
-       }
-
-       public static function provideAccountCreationType() {
-               return [
-                       [ true, PrimaryAuthenticationProvider::TYPE_CREATE ],
-                       [ false, PrimaryAuthenticationProvider::TYPE_NONE ],
-               ];
-       }
-
-       public function testTestForAccountCreation() {
-               $user = \User::newFromName( 'foo' );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals(
-                       \StatusValue::newGood(),
-                       $provider->testForAccountCreation( $user, $user, [] )
-               );
-       }
-
-       public function testAccountCreation() {
-               $user = \User::newFromName( 'foo' );
-               $user->setEmail( 'email' );
-               $user->setRealName( 'realname' );
-
-               $req = new PasswordAuthenticationRequest();
-               $req->action = AuthManager::ACTION_CREATE;
-               $reqs = [ PasswordAuthenticationRequest::class => $req ];
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
-                       ->will( $this->returnValue( false ) );
-               $plugin->expects( $this->never() )->method( 'addUser' );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               try {
-                       $provider->beginPrimaryAccountCreation( $user, $user, [] );
-                       $this->fail( 'Expected exception was not thrown' );
-               } catch ( \BadMethodCallException $ex ) {
-                       $this->assertSame(
-                               'Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()
-                       );
-               }
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->never() )->method( 'addUser' );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAccountCreation( $user, $user, [] )
-               );
-
-               $req->username = 'foo';
-               $req->password = null;
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
-               );
-
-               $req->username = null;
-               $req->password = 'bar';
-               $this->assertEquals(
-                       AuthenticationResponse::newAbstain(),
-                       $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
-               );
-
-               $req->username = 'foo';
-               $req->password = 'bar';
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'addUser' )
-                       ->with(
-                               $this->callback( function ( $u ) {
-                                       return $u instanceof \User && $u->getName() === 'Foo';
-                               } ),
-                               $this->equalTo( 'bar' ),
-                               $this->equalTo( 'email' ),
-                               $this->equalTo( 'realname' )
-                       )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $this->assertEquals(
-                       AuthenticationResponse::newPass(),
-                       $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
-               );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
-               $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->once() )->method( 'addUser' )
-                       ->with(
-                               $this->callback( function ( $u ) {
-                                       return $u instanceof \User && $u->getName() === 'Foo';
-                               } ),
-                               $this->equalTo( 'bar' ),
-                               $this->equalTo( 'email' ),
-                               $this->equalTo( 'realname' )
-                       )
-                       ->will( $this->returnValue( false ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               $ret = $provider->beginPrimaryAccountCreation( $user, $user, $reqs );
-               $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
-               $this->assertSame( 'authmanager-authplugin-create-fail', $ret->message->getKey() );
-
-               $plugin = $this->createMock( \AuthPlugin::class );
-               $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
-                       ->will( $this->returnValue( true ) );
-               $plugin->expects( $this->any() )->method( 'domainList' )
-                       ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
-               $plugin->expects( $this->any() )->method( 'validDomain' )
-                       ->will( $this->returnCallback( function ( $domain ) {
-                               return in_array( $domain, [ 'Domain1', 'Domain2' ] );
-                       } ) );
-               $plugin->expects( $this->once() )->method( 'setDomain' )
-                       ->with( $this->equalTo( 'Domain2' ) );
-               $plugin->expects( $this->once() )->method( 'addUser' )
-                       ->with( $this->callback( function ( $u ) {
-                               return $u instanceof \User && $u->getName() === 'Foo';
-                       } ), $this->equalTo( 'bar' ) )
-                       ->will( $this->returnValue( true ) );
-               $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
-               list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_CREATE, [] );
-               $req->username = 'foo';
-               $req->password = 'bar';
-               $req->domain = 'Domain2';
-               $provider->beginPrimaryAccountCreation( $user, $user, [ $req ] );
-       }
-
-}
index bbc1192..14d7f09 100644 (file)
@@ -165,6 +165,7 @@ class CheckBlocksSecondaryAuthenticationProviderTest extends \MediaWikiTestCase
                        $user->saveSettings();
                }
                $this->setMwGlobals( [ 'wgUser' => $user ] );
+               \RequestContext::getMain()->setUser( $user );
                $newuser = \User::newFromName( 'RandomUser' );
 
                $provider = new CheckBlocksSecondaryAuthenticationProvider(
index e1b25a1..6d831f6 100644 (file)
@@ -38,11 +38,11 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                        $this->manager = new AuthManager( new \FauxRequest(), $config );
                }
                $this->validity = \Status::newGood();
-
                $provider = $this->getMockBuilder( LocalPasswordPrimaryAuthenticationProvider::class )
                        ->setMethods( [ 'checkPasswordValidity' ] )
                        ->setConstructorArgs( [ [ 'loginOnly' => $loginOnly ] ] )
                        ->getMock();
+
                $provider->expects( $this->any() )->method( 'checkPasswordValidity' )
                        ->will( $this->returnCallback( function () {
                                return $this->validity;
@@ -167,7 +167,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
                $this->manager->removeAuthenticationSessionData( null );
                $row->user_password_expires = null;
-               $status = \Status::newGood();
+               $status = \Status::newGood( [ 'suggestChangeOnLogin' => true ] );
                $status->error( 'testing' );
                $providerPriv->setPasswordResetFlag( $userName, $status, $row );
                $ret = $this->manager->getAuthenticationSessionData( 'reset-pass' );
@@ -184,6 +184,14 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                $this->assertNotNull( $ret );
                $this->assertSame( 'resetpass-validity', $ret->msg->getKey() );
                $this->assertTrue( $ret->hard );
+
+               $this->manager->removeAuthenticationSessionData( null );
+               $row->user_password_expires = null;
+               $status = \Status::newGood( [ 'suggestChangeOnLogin' => false, ] );
+               $status->error( 'testing' );
+               $providerPriv->setPasswordResetFlag( $userName, $status, $row );
+               $ret = $this->manager->getAuthenticationSessionData( 'reset-pass' );
+               $this->assertNull( $ret );
        }
 
        public function testAuthentication() {
@@ -275,6 +283,7 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
 
                // Successful auth with reset
                $this->manager->removeAuthenticationSessionData( null );
+               $this->validity = \Status::newGood( [ 'suggestChangeOnLogin' => true ] );
                $this->validity->error( 'arbitrary-warning' );
                $this->assertEquals(
                        AuthenticationResponse::newPass( $userName ),
@@ -664,5 +673,4 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                $ret = $provider->beginPrimaryAuthentication( $reqs );
                $this->assertEquals( AuthenticationResponse::PASS, $ret->status, 'new password is set' );
        }
-
 }
index cc2771c..fc1930a 100644 (file)
@@ -53,9 +53,8 @@ class UserDataAuthenticationRequestTest extends AuthenticationRequestTestCase {
         * @dataProvider provideLoadFromSubmission
         */
        public function testLoadFromSubmission(
-               array $args, array $data, $expectState /* $hiddenPref, $enableEmail */
+               array $args, array $data, $expectState, $hiddenPref = null, $enableEmail = null
        ) {
-               list( $args, $data, $expectState, $hiddenPref, $enableEmail ) = func_get_args();
                $this->setMwGlobals( 'wgHiddenPrefs', $hiddenPref );
                $this->setMwGlobals( 'wgEnableEmail', $enableEmail );
                parent::testLoadFromSubmission( $args, $data, $expectState );
index 4356240..8f54789 100644 (file)
@@ -29,7 +29,7 @@ class NamespaceRestrictionTest extends RestrictionTestCase {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        protected function getClass() {
                return NamespaceRestriction::class;
index ff68e6f..c547878 100644 (file)
@@ -61,7 +61,7 @@ class PageRestrictionTest extends RestrictionTestCase {
        }
 
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        protected function getClass() {
                return PageRestriction::class;
index c340c08..2fa662b 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\TestingAccessWrapper;
 
 /**
  * @group Database
@@ -58,6 +59,8 @@ class MessageCacheTest extends MediaWikiLangTestCase {
         * @param string $title Title of page to be created
         * @param string $lang Language and content of the created page
         * @param string|null $content Content of the created page, or null for a generic string
+        *
+        * @return Revision
         */
        protected function makePage( $title, $lang, $content = null ) {
                if ( $content === null ) {
@@ -70,7 +73,11 @@ class MessageCacheTest extends MediaWikiLangTestCase {
                $title = Title::newFromText( $title, NS_MEDIAWIKI );
                $wikiPage = new WikiPage( $title );
                $contentHandler = ContentHandler::makeContent( $content, $title );
-               $wikiPage->doEditContent( $contentHandler, "$lang translation test case" );
+               $status = $wikiPage->doEditContent( $contentHandler, "$lang translation test case" );
+
+               // sanity
+               $this->assertTrue( $status->isOK(), 'Create page ' . $title->getPrefixedDBkey() );
+               return $status->value['revision'];
        }
 
        /**
@@ -213,4 +220,42 @@ class MessageCacheTest extends MediaWikiLangTestCase {
 
                $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries" );
        }
+
+       /**
+        * Regression test for T218918
+        */
+       public function testLoadFromDB_fetchLatestRevision() {
+               // Create three revisions of the same message page.
+               // Must be an existing message key.
+               $key = 'Log';
+               $this->makePage( $key, 'de', 'Test eins' );
+               $this->makePage( $key, 'de', 'Test zwei' );
+               $r3 = $this->makePage( $key, 'de', 'Test drei' );
+
+               // Create an out-of-sequence revision by importing a
+               // revision with an old timestamp. Hacky.
+               $importRevision = new WikiRevision( new HashConfig() );
+               $importRevision->setTitle( $r3->getTitle() );
+               $importRevision->setComment( 'Imported edit' );
+               $importRevision->setTimestamp( '19991122001122' );
+               $importRevision->setText( 'IMPORTED OLD TEST' );
+               $importRevision->setUsername( 'ext>Alan Smithee' );
+
+               $importer = MediaWikiServices::getInstance()->getWikiRevisionOldRevisionImporterNoUpdates();
+               $importer->import( $importRevision );
+
+               // Now, load the message from the wiki page
+               MessageCache::destroyInstance();
+               $messageCache = MessageCache::singleton();
+               $messageCache->enable();
+               $messageCache = TestingAccessWrapper::newFromObject( $messageCache );
+
+               $cache = $messageCache->loadFromDB( 'de' );
+
+               $this->assertArrayHasKey( $key, $cache );
+
+               // Text in the cache has an extra space in front!
+               $this->assertSame( ' ' . 'Test drei', $cache[$key] );
+       }
+
 }
index ca3ac1b..7ad6541 100644 (file)
@@ -39,8 +39,8 @@ class CategoryMembershipChangeTest extends MediaWikiLangTestCase {
         */
        private static $pageName = 'CategoryMembershipChangeTestPage';
 
-       public static function newForCategorizationCallback() {
-               self::$lastNotifyArgs = func_get_args();
+       public static function newForCategorizationCallback( ...$args ) {
+               self::$lastNotifyArgs = $args;
                self::$notifyCallCounter += 1;
                return self::$mockRecentChange;
        }
index eff2c85..1511d46 100644 (file)
@@ -124,14 +124,14 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
                $html = $this->createCategorizationLine(
                        $this->getCategorizationChange( '20150629191735', 0, 0 )
                );
-               $this->assertNotContains( '(diff | hist)', strip_tags( $html ) );
+               $this->assertNotContains( 'diffhist', strip_tags( $html ) );
        }
 
        public function testCategorizationLineFormattingWithRevision() {
                $html = $this->createCategorizationLine(
                        $this->getCategorizationChange( '20150629191735', 1025, 1024 )
                );
-               $this->assertContains( '(diff | hist)', strip_tags( $html ) );
+               $this->assertContains( 'diffhist', strip_tags( $html ) );
        }
 
        /**
index b1857cc..8f914b7 100644 (file)
@@ -156,14 +156,15 @@ class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
 
                $this->assertValidHTML( $cacheEntry->usertalklink );
                $this->assertRegExp(
-                       '#^ <span class="mw-usertoollinks">\(.*<a .+>talk</a>.*\)</span>#',
+                       '#^ <span class="mw-usertoollinks mw-changeslist-links">.*<span><a .+>talk</a></span>.*</span>#',
                        $cacheEntry->usertalklink,
                        'verify user talk link'
                );
 
                $this->assertValidHTML( $cacheEntry->usertalklink );
                $this->assertRegExp(
-                       '#^ <span class="mw-usertoollinks">\(.*<a .+>contribs</a>.*\)</span>$#',
+                       '#^ <span class="mw-usertoollinks mw-changeslist-links">.*<span><a .+>' .
+                               'contribs</a></span>.*</span>$#',
                        $cacheEntry->usertalklink,
                        'verify user tool links'
                );
index e9058b6..1405680 100644 (file)
@@ -62,7 +62,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                // HACK if we call $dbr->buildGroupConcatField() now, it will return the wrong table names
                // We have to have the test runner call it instead
                $baseConcats = [ ',', [ 'change_tag', 'change_tag_def' ], 'ctd_name' ];
-               $joinConds = [ 'change_tag_def' => [ 'INNER JOIN', 'ct_tag_id=ctd_id' ] ];
+               $joinConds = [ 'change_tag_def' => [ 'JOIN', 'ct_tag_id=ctd_id' ] ];
                $groupConcats = [
                        'recentchanges' => array_merge( $baseConcats, [ 'ct_rc_id=rc_id', $joinConds ] ),
                        'logging' => array_merge( $baseConcats, [ 'ct_log_id=log_id', $joinConds ] ),
@@ -121,7 +121,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                        'tables' => [ 'recentchanges', 'change_tag' ],
                                        'fields' => [ 'rc_id', 'rc_timestamp', 'ts_tags' => $groupConcats['recentchanges'] ],
                                        'conds' => [ "rc_timestamp > '20170714183203'", 'ct_tag_id' => [ 1 ] ],
-                                       'join_conds' => [ 'change_tag' => [ 'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 'JOIN', 'ct_rc_id=rc_id' ] ],
                                        'options' => [ 'ORDER BY' => 'rc_timestamp DESC' ],
                                ]
                        ],
@@ -139,7 +139,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                        'tables' => [ 'logging', 'change_tag' ],
                                        'fields' => [ 'log_id', 'ts_tags' => $groupConcats['logging'] ],
                                        'conds' => [ "log_timestamp > '20170714183203'", 'ct_tag_id' => [ 1 ] ],
-                                       'join_conds' => [ 'change_tag' => [ 'INNER JOIN', 'ct_log_id=log_id' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 'JOIN', 'ct_log_id=log_id' ] ],
                                        'options' => [ 'ORDER BY log_timestamp DESC' ],
                                ]
                        ],
@@ -157,7 +157,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                        'tables' => [ 'revision', 'change_tag' ],
                                        'fields' => [ 'rev_id', 'rev_timestamp', 'ts_tags' => $groupConcats['revision'] ],
                                        'conds' => [ "rev_timestamp > '20170714183203'", 'ct_tag_id' => [ 1 ] ],
-                                       'join_conds' => [ 'change_tag' => [ 'INNER JOIN', 'ct_rev_id=rev_id' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 'JOIN', 'ct_rev_id=rev_id' ] ],
                                        'options' => [ 'ORDER BY' => 'rev_timestamp DESC' ],
                                ]
                        ],
@@ -175,7 +175,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                        'tables' => [ 'archive', 'change_tag' ],
                                        'fields' => [ 'ar_id', 'ar_timestamp', 'ts_tags' => $groupConcats['archive'] ],
                                        'conds' => [ "ar_timestamp > '20170714183203'", 'ct_tag_id' => [ 1 ] ],
-                                       'join_conds' => [ 'change_tag' => [ 'INNER JOIN', 'ct_rev_id=ar_rev_id' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 'JOIN', 'ct_rev_id=ar_rev_id' ] ],
                                        'options' => [ 'ORDER BY' => 'ar_timestamp DESC' ],
                                ]
                        ],
@@ -223,7 +223,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                        'tables' => [ 'recentchanges', 'change_tag' ],
                                        'fields' => [ 'rc_id', 'rc_timestamp', 'ts_tags' => $groupConcats['recentchanges'] ],
                                        'conds' => [ "rc_timestamp > '20170714183203'", 'ct_tag_id' => [ 1, 2 ] ],
-                                       'join_conds' => [ 'change_tag' => [ 'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 'JOIN', 'ct_rc_id=rc_id' ] ],
                                        'options' => [ 'ORDER BY' => 'rc_timestamp DESC', 'DISTINCT' ],
                                ]
                        ],
@@ -241,7 +241,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                        'tables' => [ 'recentchanges', 'change_tag' ],
                                        'fields' => [ 'rc_id', 'rc_timestamp', 'ts_tags' => $groupConcats['recentchanges'] ],
                                        'conds' => [ "rc_timestamp > '20170714183203'", 'ct_tag_id' => [ 1, 2 ] ],
-                                       'join_conds' => [ 'change_tag' => [ 'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 'JOIN', 'ct_rc_id=rc_id' ] ],
                                        'options' => [ 'DISTINCT', 'ORDER BY' => 'rc_timestamp DESC' ],
                                ]
                        ],
@@ -259,7 +259,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                        'tables' => [ 'recentchanges', 'change_tag' ],
                                        'fields' => [ 'rc_id', 'ts_tags' => $groupConcats['recentchanges'] ],
                                        'conds' => [ "rc_timestamp > '20170714183203'", 'ct_tag_id' => [ 1, 2 ] ],
-                                       'join_conds' => [ 'change_tag' => [ 'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 'JOIN', 'ct_rc_id=rc_id' ] ],
                                        'options' => [ 'ORDER BY rc_timestamp DESC', 'DISTINCT' ],
                                ]
                        ],
@@ -592,7 +592,13 @@ class ChangeTagsTest extends MediaWikiTestCase {
                                'ctd_user_defined' => 1
                        ],
                ];
-               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_user_defined' ], '' );
+               $res = $dbr->select(
+                       'change_tag_def',
+                       [ 'ctd_name', 'ctd_user_defined' ],
+                       '',
+                       __METHOD__,
+                       [ 'ORDER BY' => 'ctd_name' ]
+               );
                $this->assertEquals( $expected, iterator_to_array( $res, false ) );
        }
 }
index a8ea3f0..4eecd4d 100644 (file)
@@ -158,6 +158,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $handler = ContentHandler::getForTitle( $title );
                $lang = $handler->getPageLanguage( $title );
 
+               $this->assertInstanceOf( Language::class, $lang );
                $this->assertEquals( $expected->getCode(), $lang->getCode() );
        }
 
@@ -518,7 +519,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $customContentHandler->expects( $this->any() )
                        ->method( 'createDifferenceEngine' )
                        ->willReturn( $customDifferenceEngine );
-               /** @var $customContentHandler ContentHandler */
+               /** @var ContentHandler $customContentHandler */
                $slotDiffRenderer = $customContentHandler->getSlotDiffRenderer( RequestContext::getMain() );
                $this->assertInstanceOf( DifferenceEngineSlotDiffRenderer::class, $slotDiffRenderer );
                $this->assertSame(
@@ -552,7 +553,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $customContentHandler2->expects( $this->any() )
                        ->method( 'getSlotDiffRendererInternal' )
                        ->willReturn( $customSlotDiffRenderer );
-               /** @var $customContentHandler2 ContentHandler */
+               /** @var ContentHandler $customContentHandler2 */
                $slotDiffRenderer = $customContentHandler2->getSlotDiffRenderer( RequestContext::getMain() );
                $this->assertSame( $customSlotDiffRenderer, $slotDiffRenderer );
        }
@@ -576,7 +577,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $customContentHandler->expects( $this->any() )
                        ->method( 'createDifferenceEngine' )
                        ->willReturn( $customDifferenceEngine );
-               /** @var $customContentHandler ContentHandler */
+               /** @var ContentHandler $customContentHandler */
 
                $customSlotDiffRenderer = $this->getMockBuilder( SlotDiffRenderer::class )
                        ->disableOriginalConstructor()
@@ -591,7 +592,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $customContentHandler2->expects( $this->any() )
                        ->method( 'getSlotDiffRendererInternal' )
                        ->willReturn( $customSlotDiffRenderer );
-               /** @var $customContentHandler2 ContentHandler */
+               /** @var ContentHandler $customContentHandler2 */
 
                $customSlotDiffRenderer2 = $this->getMockBuilder( SlotDiffRenderer::class )
                        ->disableOriginalConstructor()
index 6d0a3d5..e1281cd 100644 (file)
@@ -37,14 +37,14 @@ class TextContentHandlerTest extends MediaWikiLangTestCase {
                        } );
 
                /**
-                * @var $mockEngine SearchEngine
+                * @var SearchEngine $mockEngine
                 */
                $fields = $handler->getFieldsForSearchIndex( $mockEngine );
                $mappedFields = [];
                foreach ( $fields as $name => $field ) {
                        $this->assertInstanceOf( SearchIndexField::class, $field );
                        /**
-                        * @var $field SearchIndexField
+                        * @var SearchIndexField $field
                         */
                        $mappedFields[$name] = $field->getMapping( $mockEngine );
                }
index 2fc7794..cd7cc10 100644 (file)
@@ -182,9 +182,10 @@ just a test"
         */
        public function testReplaceSection( $text, $section, $with, $sectionTitle, $expected ) {
                $content = $this->newContent( $text );
+               /** @var WikitextContent $c */
                $c = $content->replaceSection( $section, $this->newContent( $with ), $sectionTitle );
 
-               $this->assertEquals( $expected, is_null( $c ) ? null : $c->getText() );
+               $this->assertEquals( $expected, $c ? $c->getText() : null );
        }
 
        /**
index 6b1ed7f..e0b8111 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\DatabasePostgres;
 use Wikimedia\ScopedCallback;
@@ -179,4 +180,10 @@ class DatabasePostgresTest extends MediaWikiTestCase {
                $this->doTestInsertSelectIgnore();
        }
 
+       /**
+        * @covers \Wikimedia\Rdbms\DatabasePostgres::getAttributes
+        */
+       public function testAttributes() {
+               $this->assertTrue( DatabasePostgres::getAttributes()[Database::ATTR_SCHEMAS_AS_TABLE_GROUPS] );
+       }
 }
index e61bd05..63b24dc 100644 (file)
@@ -164,9 +164,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $this->assertEquals( 'foo', $db->tableName( 'foo' ) );
                $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) );
-               $db->tablePrefix( 'foo' );
+               $db->tablePrefix( 'foo_' );
                $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) );
-               $this->assertEquals( 'foobar', $db->tableName( 'bar' ) );
+               $this->assertEquals( 'foo_bar', $db->tableName( 'bar' ) );
        }
 
        /**
@@ -531,7 +531,7 @@ class DatabaseSqliteMock extends DatabaseSqlite {
                return Database::factory( 'SqliteMock', $p );
        }
 
-       function query( $sql, $fname = '', $tempIgnore = false ) {
+       function query( $sql, $fname = '', $flags = 0 ) {
                return true;
        }
 
index 65b82ab..fb4041d 100644 (file)
@@ -45,7 +45,7 @@ class DatabaseTestHelper extends Database {
        public function __construct( $testName, array $opts = [] ) {
                $this->testName = $testName;
 
-               $this->profiler = new ProfilerStub( [] );
+               $this->profiler = null;
                $this->trxProfiler = new TransactionProfiler();
                $this->cliMode = $opts['cliMode'] ?? true;
                $this->connLogger = new \Psr\Log\NullLogger();
@@ -108,7 +108,11 @@ class DatabaseTestHelper extends Database {
 
                // Handle some internal calls from the Database class
                $check = $fname;
-               if ( preg_match( '/^Wikimedia\\\\Rdbms\\\\Database::query \((.+)\)$/', $fname, $m ) ) {
+               if ( preg_match(
+                       '/^Wikimedia\\\\Rdbms\\\\Database::(?:query|beginIfImplied) \((.+)\)$/',
+                       $fname,
+                       $m
+               ) ) {
                        $check = $m[1];
                }
 
@@ -129,10 +133,10 @@ class DatabaseTestHelper extends Database {
                return $s;
        }
 
-       public function query( $sql, $fname = '', $tempIgnore = false ) {
+       public function query( $sql, $fname = '', $flags = 0 ) {
                $this->checkFunctionName( $fname );
 
-               return parent::query( $sql, $fname, $tempIgnore );
+               return parent::query( $sql, $fname, $flags );
        }
 
        public function tableExists( $table, $fname = __METHOD__ ) {
index 3d1bf59..7d13ac6 100644 (file)
@@ -23,7 +23,6 @@
  * @copyright © 2013 Wikimedia Foundation Inc.
  */
 
-use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\IMaintainableDatabase;
 use Wikimedia\Rdbms\LBFactory;
@@ -438,6 +437,13 @@ class LBFactoryTest extends MediaWikiTestCase {
                ] );
        }
 
+       /**
+        * @covers \Wikimedia\Rdbms\LoadBalancer::getConnection
+        * @covers \Wikimedia\Rdbms\DatabaseMysqlBase::doSelectDomain
+        * @covers \Wikimedia\Rdbms\DatabaseMysqlBase::selectDB
+        * @covers \Wikimedia\Rdbms\DatabaseMssql::selectDB
+        * @covers DatabaseOracle::selectDB
+        */
        public function testNiceDomains() {
                global $wgDBname;
 
@@ -518,6 +524,13 @@ class LBFactoryTest extends MediaWikiTestCase {
                $factory->destroy();
        }
 
+       /**
+        * @covers \Wikimedia\Rdbms\LoadBalancer::getConnection
+        * @covers \Wikimedia\Rdbms\DatabaseMysqlBase::doSelectDomain
+        * @covers \Wikimedia\Rdbms\DatabaseMysqlBase::selectDB
+        * @covers \Wikimedia\Rdbms\DatabaseMssql::selectDB
+        * @covers DatabaseOracle::selectDB
+        */
        public function testTrickyDomain() {
                global $wgDBname;
 
@@ -530,7 +543,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                $factory = $this->newLBFactoryMulti(
                        [ 'localDomain' => ( new DatabaseDomain( $dbname, null, '' ) )->getId() ],
                        [
-                               'dbName' => 'do_not_select_me' // explodes if DB is selected
+                               'dbname' => 'do_not_select_me' // explodes if DB is selected
                        ]
                );
                $lb = $factory->getMainLB();
@@ -584,46 +597,94 @@ class LBFactoryTest extends MediaWikiTestCase {
                $factory->destroy();
        }
 
+       /**
+        * @covers \Wikimedia\Rdbms\LoadBalancer::getConnection
+        * @covers \Wikimedia\Rdbms\DatabaseMysqlBase::doSelectDomain
+        * @covers \Wikimedia\Rdbms\DatabaseMysqlBase::selectDB
+        * @covers \Wikimedia\Rdbms\DatabaseMssql::selectDB
+        * @covers DatabaseOracle::selectDB
+        */
        public function testInvalidSelectDB() {
-               // FIXME: fails under sqlite
-               $this->markTestSkippedIfDbType( 'sqlite' );
+               if ( wfGetDB( DB_MASTER )->databasesAreIndependent() ) {
+                       $this->markTestSkipped( "Not applicable per databasesAreIndependent()" );
+               }
+
                $dbname = 'unittest-domain'; // explodes if DB is selected
                $factory = $this->newLBFactoryMulti(
                        [ 'localDomain' => ( new DatabaseDomain( $dbname, null, '' ) )->getId() ],
                        [
-                               'dbName' => 'do_not_select_me' // explodes if DB is selected
+                               'dbname' => 'do_not_select_me' // explodes if DB is selected
                        ]
                );
                $lb = $factory->getMainLB();
                /** @var IDatabase $db */
                $db = $lb->getConnection( DB_MASTER, [], '' );
 
-               if ( $db->getType() === 'sqlite' ) {
+               \Wikimedia\suppressWarnings();
+               try {
                        $this->assertFalse( $db->selectDB( 'garbage-db' ) );
-               } elseif ( $db->databasesAreIndependent() ) {
-                       try {
-                               $e = null;
-                               $db->selectDB( 'garbage-db' );
-                       } catch ( \Wikimedia\Rdbms\DBConnectionError $e ) {
-                               // expected
-                       }
-                       $this->assertInstanceOf( \Wikimedia\Rdbms\DBConnectionError::class, $e );
-                       $this->assertFalse( $db->isOpen() );
-               } else {
-                       \Wikimedia\suppressWarnings();
-                       try {
-                               $this->assertFalse( $db->selectDB( 'garbage-db' ) );
-                               $this->fail( "No error thrown." );
-                       } catch ( \Wikimedia\Rdbms\DBExpectedError $e ) {
-                               $this->assertEquals(
-                                       "Could not select database 'garbage-db'.",
-                                       $e->getMessage()
-                               );
-                       }
-                       \Wikimedia\restoreWarnings();
+                       $this->fail( "No error thrown." );
+               } catch ( \Wikimedia\Rdbms\DBQueryError $e ) {
+                       $this->assertRegExp( '/[\'"]garbage-db[\'"]/', $e->getMessage() );
+               }
+               \Wikimedia\restoreWarnings();
+       }
+
+       /**
+        * @covers \Wikimedia\Rdbms\DatabaseSqlite::selectDB
+        * @covers \Wikimedia\Rdbms\DatabasePostgres::selectDB
+        * @expectedException \Wikimedia\Rdbms\DBConnectionError
+        */
+       public function testInvalidSelectDBIndependant() {
+               $dbname = 'unittest-domain'; // explodes if DB is selected
+               $factory = $this->newLBFactoryMulti(
+                       [ 'localDomain' => ( new DatabaseDomain( $dbname, null, '' ) )->getId() ],
+                       [
+                               'dbname' => 'do_not_select_me' // explodes if DB is selected
+                       ]
+               );
+               $lb = $factory->getMainLB();
+
+               if ( !wfGetDB( DB_MASTER )->databasesAreIndependent() ) {
+                       $this->markTestSkipped( "Not applicable per databasesAreIndependent()" );
+               }
+
+               /** @var IDatabase $db */
+               $lb->getConnection( DB_MASTER, [], '' );
+       }
+
+       /**
+        * @covers \Wikimedia\Rdbms\DatabaseSqlite::selectDB
+        * @covers \Wikimedia\Rdbms\DatabasePostgres::selectDB
+        * @expectedException \Wikimedia\Rdbms\DBConnectionError
+        */
+       public function testInvalidSelectDBIndependant2() {
+               $dbname = 'unittest-domain'; // explodes if DB is selected
+               $factory = $this->newLBFactoryMulti(
+                       [ 'localDomain' => ( new DatabaseDomain( $dbname, null, '' ) )->getId() ],
+                       [
+                               'dbname' => 'do_not_select_me' // explodes if DB is selected
+                       ]
+               );
+               $lb = $factory->getMainLB();
+
+               if ( !wfGetDB( DB_MASTER )->databasesAreIndependent() ) {
+                       $this->markTestSkipped( "Not applicable per databasesAreIndependent()" );
                }
+
+               $db = $lb->getConnection( DB_MASTER );
+               \Wikimedia\suppressWarnings();
+               $db->selectDB( 'garbage-db' );
+               \Wikimedia\restoreWarnings();
        }
 
+       /**
+        * @covers \Wikimedia\Rdbms\LoadBalancer::getConnection
+        * @covers \Wikimedia\Rdbms\LoadBalancer::redefineLocalDomain
+        * @covers \Wikimedia\Rdbms\DatabaseMysqlBase::selectDB
+        * @covers \Wikimedia\Rdbms\DatabaseMssql::selectDB
+        * @covers DatabaseOracle::selectDB
+        */
        public function testRedefineLocalDomain() {
                global $wgDBname;
 
@@ -645,10 +706,10 @@ class LBFactoryTest extends MediaWikiTestCase {
                );
                unset( $conn1 );
 
-               $factory->redefineLocalDomain( 'somedb-prefix' );
-               $this->assertEquals( 'somedb-prefix', $factory->getLocalDomainID() );
+               $factory->redefineLocalDomain( 'somedb-prefix_' );
+               $this->assertEquals( 'somedb-prefix_', $factory->getLocalDomainID() );
 
-               $domain = new DatabaseDomain( $wgDBname, null, 'pref' );
+               $domain = new DatabaseDomain( $wgDBname, null, 'pref_' );
                $factory->redefineLocalDomain( $domain );
 
                $n = 0;
@@ -668,7 +729,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                $factory->destroy();
        }
 
-       private function quoteTable( Database $db, $table ) {
+       private function quoteTable( IDatabase $db, $table ) {
                if ( $db->getType() === 'sqlite' ) {
                        return $table;
                } else {
index 2c4e6b4..4291bcc 100644 (file)
@@ -32,7 +32,7 @@ use Wikimedia\Rdbms\LoadMonitorNull;
  * @covers \Wikimedia\Rdbms\LoadBalancer
  */
 class LoadBalancerTest extends MediaWikiTestCase {
-       private function makeServerConfig() {
+       private function makeServerConfig( $flags = DBO_DEFAULT ) {
                global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
 
                return [
@@ -44,7 +44,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                        'type' => $wgDBtype,
                        'dbDirectory' => $wgSQLiteDataDir,
                        'load' => 0,
-                       'flags' => DBO_TRX // REPEATABLE-READ for consistency
+                       'flags' => $flags
                ];
        }
 
@@ -57,7 +57,8 @@ class LoadBalancerTest extends MediaWikiTestCase {
 
                $called = false;
                $lb = new LoadBalancer( [
-                       'servers' => [ $this->makeServerConfig() ],
+                       // Simulate web request with DBO_TRX
+                       'servers' => [ $this->makeServerConfig( DBO_TRX ) ],
                        'queryLogger' => MediaWiki\Logger\LoggerFactory::getInstance( 'DBQuery' ),
                        'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() ),
                        'chronologyCallback' => function () use ( &$called ) {
@@ -71,8 +72,8 @@ class LoadBalancerTest extends MediaWikiTestCase {
                $this->assertSame( 'my_test_wiki', $lb->resolveDomainID( 'my_test_wiki' ) );
                $this->assertSame( $ld->getId(), $lb->resolveDomainID( false ) );
                $this->assertSame( $ld->getId(), $lb->resolveDomainID( $ld ) );
-
                $this->assertFalse( $called );
+
                $dbw = $lb->getConnection( DB_MASTER );
                $this->assertTrue( $called );
                $this->assertTrue( $dbw->getLBInfo( 'master' ), 'master shows as master' );
@@ -106,39 +107,10 @@ class LoadBalancerTest extends MediaWikiTestCase {
        }
 
        public function testWithReplica() {
-               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
-
-               $servers = [
-                       [ // master
-                               'host'        => $wgDBserver,
-                               'dbname'      => $wgDBname,
-                               'tablePrefix' => $this->dbPrefix(),
-                               'user'        => $wgDBuser,
-                               'password'    => $wgDBpassword,
-                               'type'        => $wgDBtype,
-                               'dbDirectory' => $wgSQLiteDataDir,
-                               'load'        => 0,
-                               'flags'       => DBO_TRX // REPEATABLE-READ for consistency
-                       ],
-                       [ // emulated replica
-                               'host'        => $wgDBserver,
-                               'dbname'      => $wgDBname,
-                               'tablePrefix' => $this->dbPrefix(),
-                               'user'        => $wgDBuser,
-                               'password'    => $wgDBpassword,
-                               'type'        => $wgDBtype,
-                               'dbDirectory' => $wgSQLiteDataDir,
-                               'load'        => 100,
-                               'flags'       => DBO_TRX // REPEATABLE-READ for consistency
-                       ]
-               ];
+               global $wgDBserver;
 
-               $lb = new LoadBalancer( [
-                       'servers' => $servers,
-                       'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() ),
-                       'queryLogger' => MediaWiki\Logger\LoggerFactory::getInstance( 'DBQuery' ),
-                       'loadMonitorClass' => LoadMonitorNull::class
-               ] );
+               // Simulate web request with DBO_TRX
+               $lb = $this->newMultiServerLocalLoadBalancer( DBO_TRX );
 
                $dbw = $lb->getConnection( DB_MASTER );
                $this->assertTrue( $dbw->getLBInfo( 'master' ), 'master shows as master' );
@@ -180,6 +152,51 @@ class LoadBalancerTest extends MediaWikiTestCase {
                $lb->closeAll();
        }
 
+       private function newSingleServerLocalLoadBalancer() {
+               global $wgDBname;
+
+               return new LoadBalancer( [
+                       'servers' => [ $this->makeServerConfig() ],
+                       'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() )
+               ] );
+       }
+
+       private function newMultiServerLocalLoadBalancer( $flags = DBO_DEFAULT ) {
+               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
+
+               $servers = [
+                       [ // master
+                               'host' => $wgDBserver,
+                               'dbname' => $wgDBname,
+                               'tablePrefix' => $this->dbPrefix(),
+                               'user' => $wgDBuser,
+                               'password' => $wgDBpassword,
+                               'type' => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
+                               'load' => 0,
+                               'flags' => $flags
+                       ],
+                       [ // emulated replica
+                               'host' => $wgDBserver,
+                               'dbname' => $wgDBname,
+                               'tablePrefix' => $this->dbPrefix(),
+                               'user' => $wgDBuser,
+                               'password' => $wgDBpassword,
+                               'type' => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
+                               'load' => 100,
+                               'flags' => $flags
+                       ]
+               ];
+
+               return new LoadBalancer( [
+                       'servers' => $servers,
+                       'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() ),
+                       'queryLogger' => MediaWiki\Logger\LoggerFactory::getInstance( 'DBQuery' ),
+                       'loadMonitorClass' => LoadMonitorNull::class
+               ] );
+       }
+
        private function assertWriteForbidden( Database $db ) {
                try {
                        $db->delete( 'some_table', [ 'id' => 57634126 ], __METHOD__ );
@@ -286,20 +303,20 @@ class LoadBalancerTest extends MediaWikiTestCase {
         * @covers LoadBalancer::getAnyOpenConnection()
         */
        function testOpenConnection() {
-               global $wgDBname;
-
-               $lb = new LoadBalancer( [
-                       'servers' => [ $this->makeServerConfig() ],
-                       'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() )
-               ] );
+               $lb = $this->newSingleServerLocalLoadBalancer();
 
                $i = $lb->getWriterIndex();
                $this->assertEquals( null, $lb->getAnyOpenConnection( $i ) );
+
                $conn1 = $lb->getConnection( $i );
                $this->assertNotEquals( null, $conn1 );
                $this->assertEquals( $conn1, $lb->getAnyOpenConnection( $i ) );
+               $this->assertFalse( $conn1->getFlag( DBO_TRX ) );
+
                $conn2 = $lb->getConnection( $i, [], false, $lb::CONN_TRX_AUTOCOMMIT );
                $this->assertNotEquals( null, $conn2 );
+               $this->assertFalse( $conn2->getFlag( DBO_TRX ) );
+
                if ( $lb->getServerAttributes( $i )[Database::ATTR_DB_LEVEL_LOCKING] ) {
                        $this->assertEquals( null,
                                $lb->getAnyOpenConnection( $i, $lb::CONN_TRX_AUTOCOMMIT ) );
@@ -343,7 +360,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                                'type' => $wgDBtype,
                                'dbDirectory' => $wgSQLiteDataDir,
                                'load' => 0,
-                               'flags' => DBO_TRX // REPEATABLE-READ for consistency
+                               'flags' => DBO_TRX // simulate a web request with DBO_TRX
                        ],
                ];
 
@@ -416,4 +433,60 @@ class LoadBalancerTest extends MediaWikiTestCase {
                $conn1->close();
                $conn2->close();
        }
+
+       public function testDBConnRefReadsMasterAndReplicaRoles() {
+               $lb = $this->newSingleServerLocalLoadBalancer();
+
+               $rConn = $lb->getConnectionRef( DB_REPLICA );
+               $wConn = $lb->getConnectionRef( DB_MASTER );
+               $wConn2 = $lb->getConnectionRef( 0 );
+
+               $v = [ 'value' => '1', '1' ];
+               $sql = 'SELECT MAX(1) AS value';
+               foreach ( [ $rConn, $wConn, $wConn2 ] as $conn ) {
+                       $conn->clearFlag( $conn::DBO_TRX );
+
+                       $res = $conn->query( $sql, __METHOD__ );
+                       $this->assertEquals( $v, $conn->fetchRow( $res ) );
+
+                       $res = $conn->query( $sql, __METHOD__, $conn::QUERY_REPLICA_ROLE );
+                       $this->assertEquals( $v, $conn->fetchRow( $res ) );
+               }
+
+               $wConn->getScopedLockAndFlush( 'key', __METHOD__, 1 );
+               $wConn2->getScopedLockAndFlush( 'key2', __METHOD__, 1 );
+       }
+
+       /**
+        * @expectedException \Wikimedia\Rdbms\DBReadOnlyRoleError
+        */
+       public function testDBConnRefWritesReplicaRole() {
+               $lb = $this->newSingleServerLocalLoadBalancer();
+
+               $rConn = $lb->getConnectionRef( DB_REPLICA );
+
+               $rConn->query( 'DELETE FROM sometesttable WHERE 1=0' );
+       }
+
+       /**
+        * @expectedException \Wikimedia\Rdbms\DBReadOnlyRoleError
+        */
+       public function testDBConnRefWritesReplicaRoleIndex() {
+               $lb = $this->newMultiServerLocalLoadBalancer();
+
+               $rConn = $lb->getConnectionRef( 1 );
+
+               $rConn->query( 'DELETE FROM sometesttable WHERE 1=0' );
+       }
+
+       /**
+        * @expectedException \Wikimedia\Rdbms\DBReadOnlyRoleError
+        */
+       public function testDBConnRefWritesReplicaRoleInsert() {
+               $lb = $this->newMultiServerLocalLoadBalancer();
+
+               $rConn = $lb->getConnectionRef( DB_REPLICA );
+
+               $rConn->insert( 'test', [ 't' => 1 ], __METHOD__ );
+       }
 }
index 7d0c839..b30c7a4 100644 (file)
@@ -3,6 +3,9 @@
 namespace MediaWiki\Logger\Monolog;
 
 /**
+ * Flay per https://phabricator.wikimedia.org/T218688.
+ *
+ * @group Broken
  * @covers \MediaWiki\Logger\Monolog\CeeFormatter
  */
 class CeeFormatterTest extends \PHPUnit\Framework\TestCase {
index 4f82ff1..ba31b4f 100644 (file)
@@ -313,14 +313,14 @@ class DifferenceEngineTest extends MediaWikiTestCase {
                $customContentHandler->expects( $this->any() )
                        ->method( 'createDifferenceEngine' )
                        ->willReturn( $customDifferenceEngine );
-               /** @var $customContentHandler ContentHandler */
+               /** @var ContentHandler $customContentHandler */
                $customContent = $this->getMockBuilder( Content::class )
                        ->setMethods( [ 'getContentHandler' ] )
                        ->getMockForAbstractClass();
                $customContent->expects( $this->any() )
                        ->method( 'getContentHandler' )
                        ->willReturn( $customContentHandler );
-               /** @var $customContent Content */
+               /** @var Content $customContent */
                $customContent2 = clone $customContent;
 
                $slotDiffRenderer = $customContentHandler->getSlotDiffRenderer( RequestContext::getMain() );
index fedfac6..eee4296 100644 (file)
@@ -202,7 +202,7 @@ class HttpTest extends MediaWikiTestCase {
 
        /**
         * Constant values are from PHP 5.3.28 using cURL 7.24.0
-        * @see https://secure.php.net/manual/en/curl.constants.php
+        * @see https://www.php.net/manual/en/curl.constants.php
         *
         * All constant values are present so that developers don’t need to remember
         * to add them if added at a later date. The commented out constants were
@@ -515,7 +515,7 @@ class MWHttpRequestTester extends MWHttpRequest {
                if ( !Http::$httpEngine ) {
                        Http::$httpEngine = 'guzzle';
                } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
-                       throw new DomainException( __METHOD__ . ': curl (https://secure.php.net/curl) is not ' .
+                       throw new DomainException( __METHOD__ . ': curl (https://www.php.net/curl) is not ' .
                                'installed, but Http::$httpEngine is set to "curl"' );
                }
 
@@ -528,7 +528,7 @@ class MWHttpRequestTester extends MWHttpRequest {
                                if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
                                        throw new DomainException( __METHOD__ .
                                                ': allow_url_fopen needs to be enabled for pure PHP HTTP requests to work. '
-                                                       . 'If possible, curl should be used instead. See https://secure.php.net/curl.' );
+                                                       . 'If possible, curl should be used instead. See https://www.php.net/curl.' );
                                }
 
                                return new PhpHttpRequestTester( $url, $options, $caller );
index b2e7ea4..232b46a 100644 (file)
@@ -18,7 +18,7 @@ class JobQueueMemoryTest extends PHPUnit\Framework\TestCase {
        private function newJobQueue() {
                return JobQueue::factory( [
                        'class' => JobQueueMemory::class,
-                       'wiki' => wfWikiID(),
+                       'domain' => WikiMap::getCurrentWikiDbDomain()->getId(),
                        'type' => 'null',
                ] );
        }
index 0421fe7..1baaa54 100644 (file)
@@ -31,7 +31,9 @@ class JobQueueTest extends MediaWikiTestCase {
                        $baseConfig = [ 'class' => JobQueueDBSingle::class ];
                }
                $baseConfig['type'] = 'null';
-               $baseConfig['wiki'] = wfWikiID();
+               $baseConfig['domain'] = WikiMap::getCurrentWikiDbDomain()->getId();
+               $baseConfig['stash'] = new HashBagOStuff();
+               $baseConfig['wanCache'] = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
                $variants = [
                        'queueRand' => [ 'order' => 'random', 'claimTTL' => 0 ],
                        'queueRandTTL' => [ 'order' => 'random', 'claimTTL' => 10 ],
@@ -75,7 +77,10 @@ class JobQueueTest extends MediaWikiTestCase {
                        $this->markTestSkipped( $desc );
                }
                $this->assertEquals( wfWikiID(), $queue->getWiki(), "Proper wiki ID ($desc)" );
-               $this->assertEquals( wfWikiID(), $queue->getDomain(), "Proper wiki ID ($desc)" );
+               $this->assertEquals(
+                       WikiMap::getCurrentWikiDbDomain()->getId(),
+                       $queue->getDomain(),
+                       "Proper wiki ID ($desc)" );
        }
 
        /**
@@ -375,12 +380,12 @@ class JobQueueTest extends MediaWikiTestCase {
        }
 
        function newJob( $i = 0, $rootJob = [] ) {
-               return new NullJob( Title::newMainPage(),
+               return Job::factory( 'null', Title::newMainPage(),
                        [ 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 0, 'i' => $i ] + $rootJob );
        }
 
        function newDedupedJob( $i = 0, $rootJob = [] ) {
-               return new NullJob( Title::newMainPage(),
+               return Job::factory( 'null', Title::newMainPage(),
                        [ 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 1, 'i' => $i ] + $rootJob );
        }
 }
index 0cab702..9fe3e3d 100644 (file)
@@ -29,31 +29,31 @@ class JobTest extends MediaWikiTestCase {
                return [
                        [
                                $this->getMockJob( false ),
-                               'someCommand  ' . $requestId
+                               'someCommand Special: ' . $requestId
                        ],
                        [
                                $this->getMockJob( [ 'key' => 'val' ] ),
-                               'someCommand  key=val ' . $requestId
+                               'someCommand Special: key=val ' . $requestId
                        ],
                        [
                                $this->getMockJob( [ 'key' => [ 'inkey' => 'inval' ] ] ),
-                               'someCommand  key={"inkey":"inval"} ' . $requestId
+                               'someCommand Special: key={"inkey":"inval"} ' . $requestId
                        ],
                        [
                                $this->getMockJob( [ 'val1' ] ),
-                               'someCommand  0=val1 ' . $requestId
+                               'someCommand Special: 0=val1 ' . $requestId
                        ],
                        [
                                $this->getMockJob( [ 'val1', 'val2' ] ),
-                               'someCommand  0=val1 1=val2 ' . $requestId
+                               'someCommand Special: 0=val1 1=val2 ' . $requestId
                        ],
                        [
                                $this->getMockJob( [ new stdClass() ] ),
-                               'someCommand  0=object(stdClass) ' . $requestId
+                               'someCommand Special: 0=object(stdClass) ' . $requestId
                        ],
                        [
                                $this->getMockJob( [ $mockToStringObj ] ),
-                               'someCommand  0={STRING_OBJ_VAL} ' . $requestId
+                               'someCommand Special: 0={STRING_OBJ_VAL} ' . $requestId
                        ],
                        [
                                $this->getMockJob( [
@@ -72,24 +72,26 @@ class JobTest extends MediaWikiTestCase {
                                        ],
                                        "triggeredRecursive" => true
                                ] ),
-                               'someCommand  pages={"932737":[0,"Robert_James_Waller"]} ' .
+                               'someCommand Special: pages={"932737":[0,"Robert_James_Waller"]} ' .
                                'rootJobSignature=45868e99bba89064e4483743ebb9b682ef95c1a7 ' .
                                'rootJobTimestamp=20160309110158 masterPos=' .
                                '{"file":"db1023-bin.001288","pos":"308257743","asOfTime":' .
                                // Embed dynamically because TestSetup sets serialize_precision=17
                                // which, in PHP 7.1 and 7.2, produces 1457521464.3814001 instead
-                               json_encode( 1457521464.3814 ) . '} ' . 'triggeredRecursive=1 ' .
+                               json_encode( 1457521464.3814 ) . '} triggeredRecursive=1 ' .
                                $requestId
                        ],
                ];
        }
 
        public function getMockJob( $params ) {
+               $title = new Title();
                $mock = $this->getMockForAbstractClass(
                        Job::class,
-                       [ 'someCommand', new Title(), $params ],
+                       [ 'someCommand', $title, $params ],
                        'SomeJob'
                );
+
                return $mock;
        }
 
@@ -115,7 +117,7 @@ class JobTest extends MediaWikiTestCase {
                return [
                        'class name' => [ 'NullJob' ],
                        'closure' => [ function ( Title $title, array $params ) {
-                               return new NullJob( $title, $params );
+                               return Job::factory( 'null', $title, $params );
                        } ],
                        'function' => [ [ $this, 'newNullJob' ] ],
                        'static function' => [ self::class . '::staticNullJob' ]
@@ -123,11 +125,91 @@ class JobTest extends MediaWikiTestCase {
        }
 
        public function newNullJob( Title $title, array $params ) {
-               return new NullJob( $title, $params );
+               return Job::factory( 'null', $title, $params );
        }
 
        public static function staticNullJob( Title $title, array $params ) {
-               return new NullJob( $title, $params );
+               return Job::factory( 'null', $title, $params );
+       }
+
+       /**
+        * @covers Job::factory
+        * @covers Job::__construct()
+        */
+       public function testJobSignatureGeneric() {
+               $testPage = Title::makeTitle( NS_PROJECT, 'x' );
+               $blankTitle = Title::makeTitle( NS_SPECIAL, '' );
+               $params = [ 'z' => 1, 'lives' => 1, 'usleep' => 0 ];
+               $paramsWithTitle = $params + [ 'namespace' => NS_PROJECT, 'title' => 'x' ];
+
+               $job = new NullJob( [ 'namespace' => NS_PROJECT, 'title' => 'x' ] + $params );
+               $this->assertEquals( $testPage->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertJobParamsMatch( $job, $paramsWithTitle );
+
+               $job = Job::factory( 'null', $testPage, $params );
+               $this->assertEquals( $blankTitle->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertJobParamsMatch( $job, $params );
+
+               $job = Job::factory( 'null', $paramsWithTitle );
+               $this->assertEquals( $testPage->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertJobParamsMatch( $job, $paramsWithTitle );
+
+               $job = Job::factory( 'null', $params );
+               $this->assertTrue( $blankTitle->equals( $job->getTitle() ) );
+               $this->assertJobParamsMatch( $job, $params );
+       }
+
+       /**
+        * @covers Job::factory
+        * @covers Job::__construct()
+        */
+       public function testJobSignatureTitleBased() {
+               $testPage = Title::makeTitle( NS_PROJECT, 'x' );
+               $blankTitle = Title::makeTitle( NS_SPECIAL, '' );
+               $params = [ 'z' => 1, 'causeAction' => 'unknown', 'causeAgent' => 'unknown' ];
+               $paramsWithTitle = $params + [ 'namespace' => NS_PROJECT, 'title' => 'x' ];
+
+               $job = new RefreshLinksJob( $testPage, $params );
+               $this->assertEquals( $testPage->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertSame( $testPage, $job->getTitle() );
+               $this->assertJobParamsMatch( $job, $paramsWithTitle );
+               $this->assertSame( $testPage, $job->getTitle() );
+
+               $job = Job::factory( 'refreshLinks', $testPage, $params );
+               $this->assertEquals( $testPage->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertJobParamsMatch( $job, $paramsWithTitle );
+
+               $job = Job::factory( 'refreshLinks', $paramsWithTitle );
+               $this->assertEquals( $testPage->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertJobParamsMatch( $job, $paramsWithTitle );
+
+               $job = Job::factory( 'refreshLinks', $params );
+               $this->assertTrue( $blankTitle->equals( $job->getTitle() ) );
+               $this->assertJobParamsMatch( $job, $params );
+       }
+
+       /**
+        * @covers Job::factory
+        * @covers Job::__construct()
+        */
+       public function testJobSignatureTitleBasedIncomplete() {
+               $testPage = Title::makeTitle( NS_PROJECT, 'x' );
+               $blankTitle = Title::makeTitle( NS_SPECIAL, '' );
+               $params = [ 'z' => 1, 'causeAction' => 'unknown', 'causeAgent' => 'unknown' ];
+
+               $job = new RefreshLinksJob( $testPage, $params + [ 'namespace' => 0 ] );
+               $this->assertEquals( $blankTitle->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertJobParamsMatch( $job, $params + [ 'namespace' => 0 ] );
+
+               $job = new RefreshLinksJob( $testPage, $params + [ 'title' => 'x' ] );
+               $this->assertEquals( $blankTitle->getPrefixedText(), $job->getTitle()->getPrefixedText() );
+               $this->assertJobParamsMatch( $job, $params + [ 'title' => 'x' ] );
        }
 
+       private function assertJobParamsMatch( IJobSpecification $job, array $params ) {
+               $actual = $job->getParams();
+               unset( $actual['requestId'] );
+
+               $this->assertEquals( $actual, $params );
+       }
 }
index 27cae8a..1a2941d 100644 (file)
@@ -51,13 +51,9 @@ class ClearUserWatchlistJobTest extends MediaWikiTestCase {
                $this->setMwGlobals( 'wgUpdateRowsPerQuery', 2 );
 
                JobQueueGroup::singleton()->push(
-                       new ClearUserWatchlistJob(
-                               null,
-                               [
-                                       'userId' => $user->getId(),
-                                       'maxWatchlistId' => $maxId,
-                               ]
-                       )
+                       new ClearUserWatchlistJob( [
+                               'userId' => $user->getId(), 'maxWatchlistId' => $maxId,
+                       ] )
                );
 
                $this->assertEquals( 1, JobQueueGroup::singleton()->getQueueSizes()['clearUserWatchlist'] );
index d5ac77b..12b6320 100644 (file)
@@ -133,9 +133,7 @@ class ArrayUtilsTest extends PHPUnit\Framework\TestCase {
         * @covers ArrayUtils::arrayDiffAssocRecursive
         * @dataProvider provideArrayDiffAssocRecursive
         */
-       function testArrayDiffAssocRecursive( $expected ) {
-               $args = func_get_args();
-               array_shift( $args );
+       function testArrayDiffAssocRecursive( $expected, ...$args ) {
                $this->assertEquals( call_user_func_array(
                        'ArrayUtils::arrayDiffAssocRecursive', $args
                ), $expected );
index f0f55fb..4a09a2e 100644 (file)
@@ -16,7 +16,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                parent::setUp();
 
                // type defined through parameter
-               if ( $this->getCliArg( 'use-bagostuff' ) ) {
+               if ( $this->getCliArg( 'use-bagostuff' ) !== null ) {
                        $name = $this->getCliArg( 'use-bagostuff' );
 
                        $this->cache = ObjectCache::newFromId( $name );
@@ -26,6 +26,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                }
 
                $this->cache->delete( $this->cache->makeKey( self::TEST_KEY ) );
+               $this->cache->delete( $this->cache->makeKey( self::TEST_KEY ) . ':lock' );
        }
 
        /**
@@ -64,14 +65,19 @@ class BagOStuffTest extends MediaWikiTestCase {
 
        /**
         * @covers BagOStuff::merge
-        * @covers BagOStuff::mergeViaLock
         * @covers BagOStuff::mergeViaCas
         */
        public function testMerge() {
-               $calls = 0;
                $key = $this->cache->makeKey( self::TEST_KEY );
-               $callback = function ( BagOStuff $cache, $key, $oldVal ) use ( &$calls ) {
+
+               $calls = 0;
+               $casRace = false; // emulate a race
+               $callback = function ( BagOStuff $cache, $key, $oldVal ) use ( &$calls, &$casRace ) {
                        ++$calls;
+                       if ( $casRace ) {
+                               // Uses CAS instead?
+                               $cache->set( $key, 'conflict', 5 );
+                       }
 
                        return ( $oldVal === false ) ? 'merged' : $oldVal . 'merged';
                };
@@ -87,67 +93,18 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->assertEquals( 'mergedmerged', $this->cache->get( $key ) );
 
                $calls = 0;
-               $this->cache->lock( $key );
-               $this->assertFalse( $this->cache->merge( $key, $callback, 1 ), 'Non-blocking merge' );
-               $this->cache->unlock( $key );
-               $this->assertEquals( 0, $calls );
-       }
-
-       /**
-        * @covers BagOStuff::merge
-        * @covers BagOStuff::mergeViaLock
-        */
-       public function testMerge_fork() {
-               $key = $this->cache->makeKey( self::TEST_KEY );
-               $callback = function ( BagOStuff $cache, $key, $oldVal ) {
-                       return ( $oldVal === false ) ? 'merged' : $oldVal . 'merged';
-               };
-               /*
-                * Test concurrent merges by forking this process, if:
-                * - not manually called with --use-bagostuff
-                * - pcntl_fork is supported by the system
-                * - cache type will correctly support calls over forks
-                */
-               $fork = (bool)$this->getCliArg( 'use-bagostuff' );
-               $fork &= function_exists( 'pcntl_fork' );
-               $fork &= !$this->cache instanceof HashBagOStuff;
-               $fork &= !$this->cache instanceof EmptyBagOStuff;
-               $fork &= !$this->cache instanceof MultiWriteBagOStuff;
-               if ( $fork ) {
-                       $pid = null;
-                       // Function to start merge(), run another merge() midway through, then finish
-                       $outerFunc = function ( BagOStuff $cache, $key, $oldVal ) use ( $callback, &$pid ) {
-                               $pid = pcntl_fork();
-                               if ( $pid == -1 ) {
-                                       return false;
-                               } elseif ( $pid ) {
-                                       pcntl_wait( $status );
-
-                                       return $callback( $cache, $key, $oldVal );
-                               } else {
-                                       $this->cache->merge( $key, $callback, 0, 1 );
-                                       // Bail out of the outer merge() in the child process since it does not
-                                       // need to attempt to write anything. Success is checked by the parent.
-                                       parent::tearDown(); // avoid phpunit notices
-                                       exit;
-                               }
-                       };
-
-                       // attempt a merge - this should fail
-                       $merged = $this->cache->merge( $key, $outerFunc, 0, 1 );
-
-                       if ( $pid == -1 ) {
-                               return; // can't fork, ignore this test...
-                       }
-
-                       // merge has failed because child process was merging (and we only attempted once)
-                       $this->assertFalse( $merged );
-
-                       // make sure the child's merge is completed and verify
-                       $this->assertEquals( $this->cache->get( $key ), 'mergedmerged' );
+               $casRace = true;
+               $this->assertFalse(
+                       $this->cache->merge( $key, $callback, 5, 1 ),
+                       'Non-blocking merge (CAS)'
+               );
+               if ( $this->cache instanceof MultiWriteBagOStuff ) {
+                       $wrapper = \Wikimedia\TestingAccessWrapper::newFromObject( $this->cache );
+                       $n = count( $wrapper->caches );
                } else {
-                       $this->markTestSkipped( 'No pcntl methods available' );
+                       $n = 1;
                }
+               $this->assertEquals( $n, $calls );
        }
 
        /**
@@ -266,6 +223,34 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->cache->delete( $key4 );
        }
 
+       /**
+        * @covers BagOStuff::setMulti
+        * @covers BagOStuff::deleteMulti
+        */
+       public function testSetDeleteMulti() {
+               $map = [
+                       $this->cache->makeKey( 'test-1' ) => 'Siberian',
+                       $this->cache->makeKey( 'test-2' ) => [ 'Huskies' ],
+                       $this->cache->makeKey( 'test-3' ) => [ 'are' => 'the' ],
+                       $this->cache->makeKey( 'test-4' ) => (object)[ 'greatest' => 'animal' ],
+                       $this->cache->makeKey( 'test-5' ) => 4,
+                       $this->cache->makeKey( 'test-6' ) => 'ever'
+               ];
+
+               $this->cache->setMulti( $map, 5 );
+               $this->assertEquals(
+                       $map,
+                       $this->cache->getMulti( array_keys( $map ) )
+               );
+
+               $this->assertTrue( $this->cache->deleteMulti( array_keys( $map ), 5 ) );
+
+               $this->assertEquals(
+                       [],
+                       $this->cache->getMulti( array_keys( $map ) )
+               );
+       }
+
        /**
         * @covers BagOStuff::getScopedLock
         */
index d0360a9..f953319 100644 (file)
@@ -11,7 +11,7 @@ class CachedBagOStuffTest extends PHPUnit\Framework\TestCase {
 
        /**
         * @covers CachedBagOStuff::__construct
-        * @covers CachedBagOStuff::doGet
+        * @covers CachedBagOStuff::get
         */
        public function testGetFromBackend() {
                $backend = new HashBagOStuff;
@@ -36,6 +36,7 @@ class CachedBagOStuffTest extends PHPUnit\Framework\TestCase {
                        $cache->set( "key$i", 1 );
                        $this->assertEquals( 1, $cache->get( "key$i" ) );
                        $this->assertEquals( 1, $backend->get( "key$i" ) );
+
                        $cache->delete( "key$i" );
                        $this->assertEquals( false, $cache->get( "key$i" ) );
                        $this->assertEquals( false, $backend->get( "key$i" ) );
@@ -67,7 +68,7 @@ class CachedBagOStuffTest extends PHPUnit\Framework\TestCase {
        }
 
        /**
-        * @covers CachedBagOStuff::doGet
+        * @covers CachedBagOStuff::get
         */
        public function testCacheBackendMisses() {
                $backend = new HashBagOStuff;
index d9b7e18..017d745 100644 (file)
@@ -121,6 +121,9 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
        }
 
        public function testProcessCache() {
+               $mockWallClock = 1549343530.2053;
+               $this->cache->setMockTime( $mockWallClock );
+
                $hit = 0;
                $callback = function () use ( &$hit ) {
                        ++$hit;
@@ -154,18 +157,28 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 6, $hit, "New values cached" );
 
                foreach ( $keys as $i => $key ) {
+                       // Should evict from process cache
                        $this->cache->delete( $key );
+                       $mockWallClock += 0.001; // cached values will be newer than tombstone
+                       // Get into cache (specific process cache group)
                        $this->cache->getWithSetCallback(
                                $key, 100, $callback, [ 'pcTTL' => 5, 'pcGroup' => $groups[$i] ] );
                }
-               $this->assertEquals( 9, $hit, "Values evicted" );
+               $this->assertEquals( 9, $hit, "Values evicted by delete()" );
 
-               $key = reset( $keys );
                // Get into cache (default process cache group)
+               $key = reset( $keys );
+               $this->cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+               $this->assertEquals( 9, $hit, "Value recently interim-cached" );
+
+               $mockWallClock += 0.2; // interim key not brand new
+               $this->cache->clearProcessCache();
                $this->cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
-               $this->assertEquals( 10, $hit, "Value calculated" );
+               $this->assertEquals( 10, $hit, "Value calculated (interim key not recent and reset)" );
                $this->cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
-               $this->assertEquals( 10, $hit, "Value cached" );
+               $this->assertEquals( 10, $hit, "Value process cached" );
+
+               $mockWallClock += 0.2; // interim key not brand new
                $outerCallback = function () use ( &$callback, $key ) {
                        $v = $this->cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
 
@@ -240,7 +253,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $t2 = $cache->getCheckKeyTime( $cKey2 );
                $this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
 
-               $mockWallClock += 0.01;
+               $mockWallClock += 0.2; // interim key is not brand new and check keys have past values
                $priorTime = $mockWallClock; // reference time
                $wasSet = 0;
                $v = $cache->getWithSetCallback(
@@ -437,9 +450,9 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                        return $value;
                };
 
-               $cache = new NearExpiringWANObjectCache( [
-                       'cache'        => new HashBagOStuff()
-               ] );
+               $cache = new NearExpiringWANObjectCache( [ 'cache' => new HashBagOStuff() ] );
+               $mockWallClock = 1549343530.2053;
+               $cache->setMockTime( $mockWallClock );
 
                $wasSet = 0;
                $key = wfRandomString();
@@ -447,6 +460,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $v = $cache->getWithSetCallback( $key, 20, $func, $opts );
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 1, $wasSet, "Value calculated" );
+
+               $mockWallClock += 0.2; // interim key is not brand new
                $v = $cache->getWithSetCallback( $key, 20, $func, $opts );
                $this->assertEquals( 2, $wasSet, "Value re-calculated" );
 
@@ -872,6 +887,9 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $key = wfRandomString();
                $value = wfRandomString();
 
+               $mockWallClock = 1549343530.2053;
+               $cache->setMockTime( $mockWallClock );
+
                $calls = 0;
                $func = function () use ( &$calls, $value, $cache, $key ) {
                        ++$calls;
@@ -892,6 +910,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1, $calls, 'Callback was not used' );
 
                $cache->delete( $key );
+               $mockWallClock += 0.001; // cached values will be newer than tombstone
                $ret = $cache->getWithSetCallback( $key, 30, $func,
                        [ 'lockTSE' => 5, 'checkKeys' => $checkKeys ] );
                $this->assertEquals( $value, $ret, 'Callback was used; interim saved' );
@@ -911,30 +930,77 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
        public function testLockTSESlow() {
                $cache = $this->cache;
                $key = wfRandomString();
+               $key2 = wfRandomString();
                $value = wfRandomString();
 
+               $mockWallClock = 1549343530.2053;
+               $cache->setMockTime( $mockWallClock );
+
                $calls = 0;
-               $func = function ( $oldValue, &$ttl, &$setOpts ) use ( &$calls, $value, $cache, $key ) {
+               $func = function ( $oldValue, &$ttl, &$setOpts ) use ( &$calls, $value, &$mockWallClock ) {
                        ++$calls;
-                       $setOpts['since'] = microtime( true ) - 10;
-                       // Immediately kill any mutex rather than waiting a second
-                       $cache->delete( $cache::MUTEX_KEY_PREFIX . $key );
+                       $setOpts['since'] = $mockWallClock - 10;
                        return $value;
                };
 
-               // Value should be marked as stale due to snapshot lag
+               // Value should be given a low logical TTL due to snapshot lag
                $curTTL = null;
-               $ret = $cache->getWithSetCallback( $key, 30, $func, [ 'lockTSE' => 5 ] );
+               $ret = $cache->getWithSetCallback( $key, 300, $func, [ 'lockTSE' => 5 ] );
                $this->assertEquals( $value, $ret );
                $this->assertEquals( $value, $cache->get( $key, $curTTL ), 'Value was populated' );
-               $this->assertLessThan( 0, $curTTL, 'Value has negative curTTL' );
+               $this->assertEquals( 1, $curTTL, 'Value has reduced logical TTL', 0.01 );
                $this->assertEquals( 1, $calls, 'Value was generated' );
 
+               $mockWallClock += 2; // low logical TTL expired
+
+               $ret = $cache->getWithSetCallback( $key, 300, $func, [ 'lockTSE' => 5 ] );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( 2, $calls, 'Callback used (mutex acquired)' );
+
+               $ret = $cache->getWithSetCallback( $key, 300, $func, [ 'lockTSE' => 5 ] );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( 2, $calls, 'Callback was not used (interim value used)' );
+
+               $mockWallClock += 2; // low logical TTL expired
                // Acquire a lock to verify that getWithSetCallback uses lockTSE properly
                $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
-               $ret = $cache->getWithSetCallback( $key, 30, $func, [ 'lockTSE' => 5 ] );
+
+               $ret = $cache->getWithSetCallback( $key, 300, $func, [ 'lockTSE' => 5 ] );
                $this->assertEquals( $value, $ret );
-               $this->assertEquals( 1, $calls, 'Callback was not used' );
+               $this->assertEquals( 2, $calls, 'Callback was not used (mutex not acquired)' );
+
+               $mockWallClock += 301; // physical TTL expired
+               // Acquire a lock to verify that getWithSetCallback uses lockTSE properly
+               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+
+               $ret = $cache->getWithSetCallback( $key, 300, $func, [ 'lockTSE' => 5 ] );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( 3, $calls, 'Callback was used (mutex not acquired, not in cache)' );
+
+               $calls = 0;
+               $func2 = function ( $oldValue, &$ttl, &$setOpts ) use ( &$calls, $value ) {
+                       ++$calls;
+                       $setOpts['lag'] = 15;
+                       return $value;
+               };
+
+               // Value should be given a low logical TTL due to replication lag
+               $curTTL = null;
+               $ret = $cache->getWithSetCallback( $key2, 300, $func2, [ 'lockTSE' => 5 ] );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( $value, $cache->get( $key2, $curTTL ), 'Value was populated' );
+               $this->assertEquals( 30, $curTTL, 'Value has reduced logical TTL', 0.01 );
+               $this->assertEquals( 1, $calls, 'Value was generated' );
+
+               $ret = $cache->getWithSetCallback( $key2, 300, $func2, [ 'lockTSE' => 5 ] );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( 1, $calls, 'Callback was used (not expired)' );
+
+               $mockWallClock += 31;
+
+               $ret = $cache->getWithSetCallback( $key2, 300, $func2, [ 'lockTSE' => 5 ] );
+               $this->assertEquals( $value, $ret );
+               $this->assertEquals( 2, $calls, 'Callback was used (mutex acquired)' );
        }
 
        /**
@@ -947,11 +1013,12 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $value = wfRandomString();
                $busyValue = wfRandomString();
 
+               $mockWallClock = 1549343530.2053;
+               $cache->setMockTime( $mockWallClock );
+
                $calls = 0;
                $func = function () use ( &$calls, $value, $cache, $key ) {
                        ++$calls;
-                       // Immediately kill any mutex rather than waiting a second
-                       $cache->delete( $cache::MUTEX_KEY_PREFIX . $key );
                        return $value;
                };
 
@@ -959,6 +1026,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( $value, $ret );
                $this->assertEquals( 1, $calls, 'Value was populated' );
 
+               $mockWallClock += 0.2; // interim keys not brand new
+
                // Acquire a lock to verify that getWithSetCallback uses busyValue properly
                $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
 
@@ -980,6 +1049,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 2, $calls, 'Callback was not used; used busy value' );
 
                $this->internalCache->delete( $cache::MUTEX_KEY_PREFIX . $key );
+               $mockWallClock += 0.001; // cached values will be newer than tombstone
                $ret = $cache->getWithSetCallback( $key, 30, $func,
                        [ 'lockTSE' => 30, 'busyValue' => $busyValue, 'checkKeys' => $checkKeys ] );
                $this->assertEquals( $value, $ret, 'Callback was used; saved interim' );
@@ -1300,6 +1370,9 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
        public function testInterimHoldOffCaching() {
                $cache = $this->cache;
 
+               $mockWallClock = 1549343530.2053;
+               $cache->setMockTime( $mockWallClock );
+
                $value = 'CRL-40-940';
                $wasCalled = 0;
                $func = function () use ( &$wasCalled, $value ) {
@@ -1314,10 +1387,16 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $v = $cache->getWithSetCallback( $key, 60, $func );
                $v = $cache->getWithSetCallback( $key, 60, $func );
                $this->assertEquals( 1, $wasCalled, 'Value cached' );
+
                $cache->delete( $key );
+               $mockWallClock += 0.001; // cached values will be newer than tombstone
                $v = $cache->getWithSetCallback( $key, 60, $func );
                $this->assertEquals( 2, $wasCalled, 'Value regenerated (got mutex)' ); // sets interim
                $v = $cache->getWithSetCallback( $key, 60, $func );
+               $this->assertEquals( 2, $wasCalled, 'Value interim cached' ); // reuses interim
+
+               $mockWallClock += 0.2; // interim key not brand new
+               $v = $cache->getWithSetCallback( $key, 60, $func );
                $this->assertEquals( 3, $wasCalled, 'Value regenerated (got mutex)' ); // sets interim
                // Lock up the mutex so interim cache is used
                $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
@@ -1762,14 +1841,14 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
 
        /**
         * @dataProvider statsKeyProvider
-        * @covers WANObjectCache::determineKeyClass
+        * @covers WANObjectCache::determineKeyClassForStats
         */
        public function testStatsKeyClass( $key, $class ) {
                $wanCache = TestingAccessWrapper::newFromObject( new WANObjectCache( [
                        'cache' => new HashBagOStuff
                ] ) );
 
-               $this->assertEquals( $class, $wanCache->determineKeyClass( $key ) );
+               $this->assertEquals( $class, $wanCache->determineKeyClassForStats( $key ) );
        }
 }
 
index e130b23..33e5c3b 100644 (file)
@@ -44,7 +44,27 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
                        ->disableOriginalConstructor()
                        ->getMock();
 
-               $db->method( 'select' )->willReturn( new FakeResultWrapper( [] ) );
+               $open = true;
+               $db->method( 'select' )->willReturnCallback( function () use ( &$open ) {
+                       if ( !$open ) {
+                               throw new LogicException( "Not open" );
+                       }
+
+                       return new FakeResultWrapper( [] );
+               } );
+               $db->method( 'close' )->willReturnCallback( function () use ( &$open ) {
+                       $open = false;
+
+                       return true;
+               } );
+               $db->method( 'isOpen' )->willReturnCallback( function () use ( &$open ) {
+                       return $open;
+               } );
+               $db->method( 'open' )->willReturnCallback( function () use ( &$open ) {
+                       $open = true;
+
+                       return $open;
+               } );
                $db->method( '__toString' )->willReturn( 'MOCK_DB' );
 
                return $db;
@@ -55,12 +75,12 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
         */
        private function getDBConnRef( ILoadBalancer $lb = null ) {
                $lb = $lb ?: $this->getLoadBalancerMock();
-               return new DBConnRef( $lb, $this->getDatabaseMock() );
+               return new DBConnRef( $lb, $this->getDatabaseMock(), DB_MASTER );
        }
 
        public function testConstruct() {
                $lb = $this->getLoadBalancerMock();
-               $ref = new DBConnRef( $lb, $this->getDatabaseMock() );
+               $ref = new DBConnRef( $lb, $this->getDatabaseMock(), DB_MASTER );
 
                $this->assertInstanceOf( ResultWrapper::class, $ref->select( 'whatever', '*' ) );
        }
@@ -79,10 +99,19 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
 
                $ref = new DBConnRef(
                        $lb,
-                       [ DB_MASTER, [ 'test' ], 'dummy', ILoadBalancer::CONN_TRX_AUTOCOMMIT ]
+                       [ DB_MASTER, [ 'test' ], 'dummy', ILoadBalancer::CONN_TRX_AUTOCOMMIT ],
+                       DB_MASTER
                );
 
                $this->assertInstanceOf( ResultWrapper::class, $ref->select( 'whatever', '*' ) );
+               $this->assertEquals( DB_MASTER, $ref->getReferenceRole() );
+
+               $ref2 = new DBConnRef(
+                       $lb,
+                       [ DB_MASTER, [ 'test' ], 'dummy', ILoadBalancer::CONN_TRX_AUTOCOMMIT ],
+                       DB_REPLICA
+               );
+               $this->assertEquals( DB_REPLICA, $ref2->getReferenceRole() );
        }
 
        public function testDestruct() {
@@ -104,7 +133,7 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
                $this->setExpectedException( InvalidArgumentException::class, '' );
 
                $lb = $this->getLoadBalancerMock();
-               new DBConnRef( $lb, 17 ); // bad constructor argument
+               new DBConnRef( $lb, 17, DB_REPLICA ); // bad constructor argument
        }
 
        /**
@@ -117,11 +146,14 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
                $lb->expects( $this->never() )
                        ->method( 'getConnection' );
 
-               $ref = new DBConnRef( $lb, [ DB_REPLICA, [], 'dummy', 0 ] );
+               $ref = new DBConnRef( $lb, [ DB_REPLICA, [], 'dummy', 0 ], DB_REPLICA );
 
                $this->assertSame( 'dummy', $ref->getDomainID() );
        }
 
+       /**
+        * @covers Wikimedia\Rdbms\DBConnRef::select
+        */
        public function testSelect() {
                // select should get passed through normally
                $ref = $this->getDBConnRef();
@@ -133,8 +165,59 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
                $this->assertInternalType( 'string', $ref->__toString() );
 
                $lb = $this->getLoadBalancerMock();
-               $ref = new DBConnRef( $lb, [ DB_MASTER, [], 'test', 0 ] );
+               $ref = new DBConnRef( $lb, [ DB_MASTER, [], 'test', 0 ], DB_MASTER );
                $this->assertInternalType( 'string', $ref->__toString() );
        }
 
+       /**
+        * @covers Wikimedia\Rdbms\DBConnRef::close
+        * @expectedException \Wikimedia\Rdbms\DBUnexpectedError
+        */
+       public function testClose() {
+               $lb = $this->getLoadBalancerMock();
+               $ref = new DBConnRef( $lb, [ DB_REPLICA, [], 'dummy', 0 ], DB_MASTER );
+               $ref->close();
+       }
+
+       /**
+        * @covers Wikimedia\Rdbms\DBConnRef::getReferenceRole
+        */
+       public function testGetReferenceRole() {
+               $lb = $this->getLoadBalancerMock();
+               $ref = new DBConnRef( $lb, [ DB_REPLICA, [], 'dummy', 0 ], DB_REPLICA );
+               $this->assertSame( DB_REPLICA, $ref->getReferenceRole() );
+
+               $ref = new DBConnRef( $lb, [ DB_MASTER, [], 'dummy', 0 ], DB_MASTER );
+               $this->assertSame( DB_MASTER, $ref->getReferenceRole() );
+
+               $ref = new DBConnRef( $lb, [ 1, [], 'dummy', 0 ], DB_REPLICA );
+               $this->assertSame( DB_REPLICA, $ref->getReferenceRole() );
+
+               $ref = new DBConnRef( $lb, [ 0, [], 'dummy', 0 ], DB_MASTER );
+               $this->assertSame( DB_MASTER, $ref->getReferenceRole() );
+       }
+
+       /**
+        * @covers Wikimedia\Rdbms\DBConnRef::getReferenceRole
+        * @expectedException Wikimedia\Rdbms\DBReadOnlyRoleError
+        * @dataProvider provideRoleExceptions
+        */
+       public function testRoleExceptions( $method, $args ) {
+               $lb = $this->getLoadBalancerMock();
+               $ref = new DBConnRef( $lb, [ DB_REPLICA, [], 'dummy', 0 ], DB_REPLICA );
+               $ref->$method( ...$args );
+       }
+
+       function provideRoleExceptions() {
+               return [
+                       [ 'insert', [ 'table', [ 'a' => 1 ] ] ],
+                       [ 'update', [ 'table', [ 'a' => 1 ], [ 'a' => 2 ] ] ],
+                       [ 'delete', [ 'table', [ 'a' => 1 ] ] ],
+                       [ 'replace', [ 'table', [ 'a' ], [ 'a' => 1 ] ] ],
+                       [ 'upsert', [ 'table', [ 'a' => 1 ], [ 'a' ], [ 'a = a + 1' ] ] ],
+                       [ 'lock', [ 'k', 'method' ] ],
+                       [ 'unlock', [ 'k', 'method' ] ],
+                       [ 'getScopedLockAndFlush', [ 'k', 'method', 1 ] ]
+               ];
+       }
 }
index b36fe11..b1d4fad 100644 (file)
@@ -13,7 +13,7 @@ class DatabaseDomainTest extends PHPUnit\Framework\TestCase {
        public static function provideConstruct() {
                return [
                        'All strings' =>
-                               [ 'foo', 'bar', 'baz', 'foo-bar-baz' ],
+                               [ 'foo', 'bar', 'baz_', 'foo-bar-baz_' ],
                        'Nothing' =>
                                [ null, null, '', '' ],
                        'Invalid $database' =>
@@ -23,9 +23,9 @@ class DatabaseDomainTest extends PHPUnit\Framework\TestCase {
                        'Invalid $prefix' =>
                                [ 'foo', 'bar', 0, '', true ],
                        'Dash' =>
-                               [ 'foo-bar', 'baz', 'baa', 'foo?hbar-baz-baa' ],
+                               [ 'foo-bar', 'baz', 'baa_', 'foo?hbar-baz-baa_' ],
                        'Question mark' =>
-                               [ 'foo?bar', 'baz', 'baa', 'foo??bar-baz-baa' ],
+                               [ 'foo?bar', 'baz', 'baa_', 'foo??bar-baz-baa_' ],
                ];
        }
 
@@ -53,17 +53,17 @@ class DatabaseDomainTest extends PHPUnit\Framework\TestCase {
                        'Basic' =>
                                [ 'foo', 'foo', null, '' ],
                        'db+prefix' =>
-                               [ 'foo-bar', 'foo', null, 'bar' ],
+                               [ 'foo-bar_', 'foo', null, 'bar_' ],
                        'db+schema+prefix' =>
-                               [ 'foo-bar-baz', 'foo', 'bar', 'baz' ],
+                               [ 'foo-bar-baz_', 'foo', 'bar', 'baz_' ],
                        '?h -> -' =>
-                               [ 'foo?hbar-baz-baa', 'foo-bar', 'baz', 'baa' ],
+                               [ 'foo?hbar-baz-baa_', 'foo-bar', 'baz', 'baa_' ],
                        '?? -> ?' =>
-                               [ 'foo??bar-baz-baa', 'foo?bar', 'baz', 'baa' ],
+                               [ 'foo??bar-baz-baa_', 'foo?bar', 'baz', 'baa_' ],
                        '? is left alone' =>
-                               [ 'foo?bar-baz-baa', 'foo?bar', 'baz', 'baa' ],
+                               [ 'foo?bar-baz-baa_', 'foo?bar', 'baz', 'baa_' ],
                        'too many parts' =>
-                               [ 'foo-bar-baz-baa', '', '', '', true ],
+                               [ 'foo-bar-baz-baa_', '', '', '', true ],
                        'from instance' =>
                                [ DatabaseDomain::newUnspecified(), null, null, '' ],
                ];
@@ -90,13 +90,13 @@ class DatabaseDomainTest extends PHPUnit\Framework\TestCase {
                        'Basic' =>
                                [ 'foo', 'foo', null, '' ],
                        'db+prefix' =>
-                               [ 'foo-bar', 'foo', null, 'bar' ],
+                               [ 'foo-bar_', 'foo', null, 'bar_' ],
                        'db+schema+prefix' =>
-                               [ 'foo-bar-baz', 'foo', 'bar', 'baz' ],
+                               [ 'foo-bar-baz_', 'foo', 'bar', 'baz_' ],
                        '?h -> -' =>
-                               [ 'foo?hbar-baz-baa', 'foo-bar', 'baz', 'baa' ],
+                               [ 'foo?hbar-baz-baa_', 'foo-bar', 'baz', 'baa_' ],
                        '?? -> ?' =>
-                               [ 'foo??bar-baz-baa', 'foo?bar', 'baz', 'baa' ],
+                               [ 'foo??bar-baz-baa_', 'foo?bar', 'baz', 'baa_' ],
                        'Nothing' =>
                                [ '', null, null, '' ],
                ];
@@ -136,23 +136,21 @@ class DatabaseDomainTest extends PHPUnit\Framework\TestCase {
                        'Basic' =>
                                [ 'foo', 'foo', null, '', true ],
                        'db+prefix' =>
-                               [ 'foo-bar', 'foo', null, 'bar', true ],
+                               [ 'foo-bar_', 'foo', null, 'bar_', true ],
                        'db+schema+prefix' =>
-                               [ 'foo-bar-baz', 'foo', 'bar', 'baz', true ],
+                               [ 'foo-bar-baz_', 'foo', 'bar', 'baz_', true ],
                        'db+dontcare_schema+prefix' =>
-                               [ 'foo-bar-baz', 'foo', null, 'baz', false ],
+                               [ 'foo-bar-baz_', 'foo', null, 'baz_', false ],
                        '?h -> -' =>
-                               [ 'foo?hbar-baz-baa', 'foo-bar', 'baz', 'baa', true ],
+                               [ 'foo?hbar-baz-baa_', 'foo-bar', 'baz', 'baa_', true ],
                        '?? -> ?' =>
-                               [ 'foo??bar-baz-baa', 'foo?bar', 'baz', 'baa', true ],
+                               [ 'foo??bar-baz-baa_', 'foo?bar', 'baz', 'baa_', true ],
                        'Nothing' =>
                                [ '', null, null, '', true ],
                        'dontcaredb+dontcaredbschema+prefix' =>
-                               [ 'mywiki-mediawiki-prefix', null, null, 'prefix', false ],
-                       'dontcaredb+schema+prefix' =>
-                               [ 'mywiki-schema-prefix', null, 'schema', 'prefix', false ],
+                               [ 'mywiki-mediawiki-prefix_', null, null, 'prefix_', false ],
                        'db+dontcareschema+prefix' =>
-                               [ 'mywiki-schema-prefix', 'mywiki', null, 'prefix', false ],
+                               [ 'mywiki-schema-prefix_', 'mywiki', null, 'prefix_', false ],
                        'postgres-db-jobqueue' =>
                                [ 'postgres-mediawiki-', 'postgres', null, '', false ]
                ];
@@ -178,13 +176,11 @@ class DatabaseDomainTest extends PHPUnit\Framework\TestCase {
        public static function provideIsCompatible2() {
                return [
                        'db+schema+prefix' =>
-                               [ 'mywiki-schema-prefix', 'thatwiki', 'schema', 'prefix' ],
+                               [ 'mywiki-schema-prefix_', 'thatwiki', 'schema', 'prefix_' ],
                        'dontcaredb+dontcaredbschema+prefix' =>
-                               [ 'thatwiki-mediawiki-otherprefix', null, null, 'prefix' ],
-                       'dontcaredb+schema+prefix' =>
-                               [ 'mywiki-otherschema-prefix', null, 'schema', 'prefix' ],
+                               [ 'thatwiki-mediawiki-otherprefix_', null, null, 'prefix_' ],
                        'db+dontcareschema+prefix' =>
-                               [ 'notmywiki-schema-prefix', 'mywiki', null, 'prefix' ],
+                               [ 'notmywiki-schema-prefix_', 'mywiki', null, 'prefix_' ],
                ];
        }
 
@@ -202,6 +198,20 @@ class DatabaseDomainTest extends PHPUnit\Framework\TestCase {
                $this->assertFalse( $fromId->isCompatible( $compareIdObj ), 'fromId equals string' );
        }
 
+       /**
+        * @expectedException InvalidArgumentException
+        */
+       public function testSchemaWithNoDB1() {
+               new DatabaseDomain( null, 'schema', '' );
+       }
+
+       /**
+        * @expectedException InvalidArgumentException
+        */
+       public function testSchemaWithNoDB2() {
+               DatabaseDomain::newFromId( '-schema-prefix' );
+       }
+
        /**
         * @covers Wikimedia\Rdbms\DatabaseDomain::isUnspecified
         */
index b28a5b9..414042d 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\DatabaseMssql;
 
 class DatabaseMssqlTest extends PHPUnit\Framework\TestCase {
@@ -52,4 +53,10 @@ class DatabaseMssqlTest extends PHPUnit\Framework\TestCase {
                $mockDb->buildSubstring( 'foo', $start, $length );
        }
 
+       /**
+        * @covers \Wikimedia\Rdbms\DatabaseMssql::getAttributes
+        */
+       public function testAttributes() {
+               $this->assertTrue( DatabaseMssql::getAttributes()[Database::ATTR_SCHEMAS_AS_TABLE_GROUPS] );
+       }
 }
index d739839..c0d2555 100644 (file)
@@ -1343,7 +1343,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
        }
 
        /**
-        * @covers Wikimedia\Rdbms\Database::registerTempTableOperation
+        * @covers Wikimedia\Rdbms\Database::registerTempTableWrite
         */
        public function testSessionTempTables() {
                $temp1 = $this->database->tableName( 'tmp_table_1' );
@@ -1853,7 +1853,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                } catch ( DBUnexpectedError $ex ) {
                        $this->assertSame(
                                'Invalid atomic section ended (got ' . __METHOD__ . ' but expected ' .
-                                       __METHOD__ . 'X' . ').',
+                                       __METHOD__ . 'X).',
                                $ex->getMessage()
                        );
                }
index bd1c112..8b24791 100644 (file)
@@ -13,6 +13,8 @@ use Wikimedia\Rdbms\DatabaseMssql;
 use Wikimedia\Rdbms\DBUnexpectedError;
 
 class DatabaseTest extends PHPUnit\Framework\TestCase {
+       /** @var DatabaseTestHelper */
+       private $db;
 
        use MediaWikiCoversValidator;
 
@@ -629,25 +631,45 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
         * @covers Wikimedia\Rdbms\Database::dbSchema
         */
        public function testSchemaAndPrefixMutators() {
+               $ud = DatabaseDomain::newUnspecified();
+
+               $this->assertEquals( $ud->getId(), $this->db->getDomainID() );
+
                $old = $this->db->tablePrefix();
                $oldDomain = $this->db->getDomainId();
                $this->assertInternalType( 'string', $old, 'Prefix is string' );
                $this->assertSame( $old, $this->db->tablePrefix(), "Prefix unchanged" );
-               $this->assertSame( $old, $this->db->tablePrefix( 'xxx' ) );
-               $this->assertSame( 'xxx', $this->db->tablePrefix(), "Prefix set" );
+               $this->assertSame( $old, $this->db->tablePrefix( 'xxx_' ) );
+               $this->assertSame( 'xxx_', $this->db->tablePrefix(), "Prefix set" );
                $this->db->tablePrefix( $old );
-               $this->assertNotEquals( 'xxx', $this->db->tablePrefix() );
+               $this->assertNotEquals( 'xxx_', $this->db->tablePrefix() );
                $this->assertSame( $oldDomain, $this->db->getDomainId() );
 
                $old = $this->db->dbSchema();
                $oldDomain = $this->db->getDomainId();
                $this->assertInternalType( 'string', $old, 'Schema is string' );
                $this->assertSame( $old, $this->db->dbSchema(), "Schema unchanged" );
+
+               $this->db->selectDB( 'y' );
                $this->assertSame( $old, $this->db->dbSchema( 'xxx' ) );
                $this->assertSame( 'xxx', $this->db->dbSchema(), "Schema set" );
                $this->db->dbSchema( $old );
                $this->assertNotEquals( 'xxx', $this->db->dbSchema() );
-               $this->assertSame( $oldDomain, $this->db->getDomainId() );
+               $this->assertSame( "y", $this->db->getDomainId() );
+       }
+
+       /**
+        * @covers Wikimedia\Rdbms\Database::tablePrefix
+        * @covers Wikimedia\Rdbms\Database::dbSchema
+        * @expectedException DBUnexpectedError
+        */
+       public function testSchemaWithNoDB() {
+               $ud = DatabaseDomain::newUnspecified();
+
+               $this->assertEquals( $ud->getId(), $this->db->getDomainID() );
+               $this->assertSame( '', $this->db->dbSchema() );
+
+               $this->db->dbSchema( 'xxx' );
        }
 
        /**
@@ -659,10 +681,10 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
                $oldSchema = $this->db->dbSchema();
                $oldPrefix = $this->db->tablePrefix();
 
-               $this->db->selectDomain( 'testselectdb-xxx' );
+               $this->db->selectDomain( 'testselectdb-xxx_' );
                $this->assertSame( 'testselectdb', $this->db->getDBname() );
                $this->assertSame( '', $this->db->dbSchema() );
-               $this->assertSame( 'xxx', $this->db->tablePrefix() );
+               $this->assertSame( 'xxx_', $this->db->tablePrefix() );
 
                $this->db->selectDomain( $oldDomain );
                $this->assertSame( $oldDatabase, $this->db->getDBname() );
@@ -670,10 +692,10 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
                $this->assertSame( $oldPrefix, $this->db->tablePrefix() );
                $this->assertSame( $oldDomain, $this->db->getDomainId() );
 
-               $this->db->selectDomain( 'testselectdb-schema-xxx' );
+               $this->db->selectDomain( 'testselectdb-schema-xxx_' );
                $this->assertSame( 'testselectdb', $this->db->getDBname() );
                $this->assertSame( 'schema', $this->db->dbSchema() );
-               $this->assertSame( 'xxx', $this->db->tablePrefix() );
+               $this->assertSame( 'xxx_', $this->db->tablePrefix() );
 
                $this->db->selectDomain( $oldDomain );
                $this->assertSame( $oldDatabase, $this->db->getDBname() );
index b55d869..46e23e3 100644 (file)
@@ -31,7 +31,7 @@ class PrefixingStatsdDataFactoryProxyTest extends PHPUnit\Framework\TestCase {
                );
                $innerFactory->expects( $this->once() )
                        ->method( $method )
-                       ->with( 'testprefix.' . 'metricname' );
+                       ->with( 'testprefix.metricname' );
 
                $proxy = new PrefixingStatsdDataFactoryProxy( $innerFactory, 'testprefix' );
                // 1,2,3,4 simply makes sure we provide enough parameters, without caring what they are
@@ -48,7 +48,7 @@ class PrefixingStatsdDataFactoryProxyTest extends PHPUnit\Framework\TestCase {
                );
                $innerFactory->expects( $this->once() )
                        ->method( $method )
-                       ->with( 'testprefix.' . 'metricname' );
+                       ->with( 'testprefix.metricname' );
 
                $proxy = new PrefixingStatsdDataFactoryProxy( $innerFactory, 'testprefix...' );
                // 1,2,3,4 simply makes sure we provide enough parameters, without caring what they are
index ad0c3d1..e3a200b 100644 (file)
@@ -4,7 +4,7 @@
  * @covers PageDataRequestHandler
  * @group PageData
  */
-class PageDataRequestHandlerTest extends \MediaWikiTestCase {
+class PageDataRequestHandlerTest extends \MediaWikiLangTestCase {
 
        /**
         * @var Title
@@ -19,9 +19,10 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->interfaceTitle = Title::newFromText( "Special:PageDataRequestHandlerTest" );
-
+               $this->interfaceTitle = Title::newFromText( __CLASS__ );
                $this->obLevel = ob_get_level();
+
+               $this->setMwGlobals( 'wgArticlePath', '/wiki/$1' );
        }
 
        protected function tearDown() {
@@ -44,7 +45,7 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
         * @return PageDataRequestHandler
         */
        protected function newHandler() {
-               return new PageDataRequestHandler( 'json' );
+               return new PageDataRequestHandler();
        }
 
        /**
@@ -76,9 +77,16 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
        public function handleRequestProvider() {
                $cases = [];
 
-               $cases[] = [ '', [], [], '!!', 400 ];
+               $cases[] = [ '', [], [], 'Invalid title', 400 ];
 
-               $cases[] = [ '', [ 'target' => 'Helsinki' ], [], '!!', 303,  [ 'Location' => '!.+!' ] ];
+               $cases[] = [
+                       '',
+                       [ 'target' => 'Helsinki' ],
+                       [],
+                       '',
+                       303,
+                       [ 'Location' => '?title=Helsinki&action=raw' ]
+               ];
 
                $subpageCases = [];
                foreach ( $cases as $c ) {
@@ -99,9 +107,9 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
                        '',
                        [ 'target' => 'Helsinki' ],
                        [ 'Accept' => 'text/HTML' ],
-                       '!!',
+                       '',
                        303,
-                       [ 'Location' => '!Helsinki$!' ]
+                       [ 'Location' => '/wiki/Helsinki' ]
                ];
 
                $cases[] = [
@@ -111,18 +119,18 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
                                'revision' => '4242',
                        ],
                        [ 'Accept' => 'text/HTML' ],
-                       '!!',
+                       '',
                        303,
-                       [ 'Location' => '!Helsinki(\?|&)oldid=4242!' ]
+                       [ 'Location' => '?title=Helsinki&oldid=4242' ]
                ];
 
                $cases[] = [
                        '/Helsinki',
                        [],
                        [],
-                       '!!',
+                       '',
                        303,
-                       [ 'Location' => '!Helsinki&action=raw!' ]
+                       [ 'Location' => '?title=Helsinki&action=raw' ]
                ];
 
                // #31: /Q5 with "Accept: text/foobar" triggers a 406
@@ -130,36 +138,59 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
                        'main/Helsinki',
                        [],
                        [ 'Accept' => 'text/foobar' ],
-                       '!!',
+                       'No matching format found',
                        406,
+               ];
+
+               $cases[] = [
+                       'no slash',
                        [],
+                       [ 'Accept' => 'text/HTML' ],
+                       'Invalid title',
+                       400,
+               ];
+
+               $cases[] = [
+                       'main',
+                       [],
+                       [ 'Accept' => 'text/HTML' ],
+                       'Invalid title',
+                       400,
+               ];
+
+               $cases[] = [
+                       'xyz/Helsinki',
+                       [],
+                       [ 'Accept' => 'text/HTML' ],
+                       'Invalid title',
+                       400,
                ];
 
                $cases[] = [
                        'main/Helsinki',
                        [],
                        [ 'Accept' => 'text/HTML' ],
-                       '!!',
+                       '',
                        303,
-                       [ 'Location' => '!Helsinki$!' ]
+                       [ 'Location' => '/wiki/Helsinki' ]
                ];
 
                $cases[] = [
                        '/Helsinki',
                        [],
                        [ 'Accept' => 'text/HTML' ],
-                       '!!',
+                       '',
                        303,
-                       [ 'Location' => '!Helsinki$!' ]
+                       [ 'Location' => '/wiki/Helsinki' ]
                ];
 
                $cases[] = [
                        'main/AC/DC',
                        [],
                        [ 'Accept' => 'text/HTML' ],
-                       '!!',
+                       '',
                        303,
-                       [ 'Location' => '!AC/DC$!' ]
+                       [ 'Location' => '/wiki/AC/DC' ]
                ];
 
                return $cases;
@@ -171,7 +202,7 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
         * @param string $subpage The subpage to request (or '')
         * @param array  $params  Request parameters
         * @param array  $headers  Request headers
-        * @param string $expectedOutput Regex to match the output against.
+        * @param string $expectedOutput
         * @param int $expectedStatusCode Expected HTTP status code.
         * @param string[] $expectedHeaders Expected HTTP response headers.
         */
@@ -179,7 +210,7 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
                $subpage,
                array $params,
                array $headers,
-               $expectedOutput,
+               $expectedOutput = '',
                $expectedStatusCode = 200,
                array $expectedHeaders = []
        ) {
@@ -201,22 +232,21 @@ class PageDataRequestHandlerTest extends \MediaWikiTestCase {
                                $output->output();
                        }
 
-                       $text = ob_get_contents();
-                       ob_end_clean();
+                       $text = ob_get_clean();
 
                        $this->assertEquals( $expectedStatusCode, $response->getStatusCode(), 'status code' );
-                       $this->assertRegExp( $expectedOutput, $text, 'output' );
+                       $this->assertSame( $expectedOutput, $text, 'output' );
 
                        foreach ( $expectedHeaders as $name => $exp ) {
                                $value = $response->getHeader( $name );
                                $this->assertNotNull( $value, "header: $name" );
                                $this->assertInternalType( 'string', $value, "header: $name" );
-                               $this->assertRegExp( $exp, $value, "header: $name" );
+                               $this->assertStringEndsWith( $exp, $value, "header: $name" );
                        }
                } catch ( HttpError $e ) {
                        ob_end_clean();
                        $this->assertEquals( $expectedStatusCode, $e->getStatusCode(), 'status code' );
-                       $this->assertRegExp( $expectedOutput, $e->getHTML(), 'error output' );
+                       $this->assertContains( $expectedOutput, $e->getHTML(), 'error output' );
                }
 
                // We always set "Access-Control-Allow-Origin: *"
index d550dcb..91ee276 100644 (file)
@@ -51,11 +51,10 @@ class LinkRendererTest extends MediaWikiLangTestCase {
 
                // Query added
                $this->assertEquals(
-                       '<a href="/w/index.php?title=Foobar&amp;foo=bar" ' . 'title="Foobar">Foobar</a>',
+                       '<a href="/w/index.php?title=Foobar&amp;foo=bar" title="Foobar">Foobar</a>',
                        $linkRenderer->makeKnownLink( $target, null, [], [ 'foo' => 'bar' ] )
                );
 
-               // forcearticlepath
                $linkRenderer->setForceArticlePath( true );
                $this->assertEquals(
                        '<a href="/wiki/Foobar?foo=bar" title="Foobar">Foobar</a>',
index 2b4067f..b393949 100644 (file)
@@ -134,7 +134,7 @@ class UploadLogFormatterTest extends LogFormatterTestCase {
                                        ],
                                ],
                                [
-                                       'text' => 'User uploaded File:File.png',
+                                       'text' => 'User reverted File:File.png to an old version',
                                        'api' => [
                                                'img_sha1' => 'hash',
                                                'img_timestamp' => '2015-01-01T00:00:00Z',
@@ -153,7 +153,7 @@ class UploadLogFormatterTest extends LogFormatterTestCase {
                                        'params' => [],
                                ],
                                [
-                                       'text' => 'User uploaded File:File.png',
+                                       'text' => 'User reverted File:File.png to an old version',
                                        'api' => [],
                                ],
                        ],
index dbc0d2f..d9b5d82 100644 (file)
@@ -25,7 +25,7 @@ class DjVuTest extends MediaWikiMediaTestCase {
        }
 
        public function testGetImageSize() {
-               $this->assertArrayEquals(
+               $this->assertSame(
                        [ 2480, 3508, 'DjVu', 'width="2480" height="3508"' ],
                        $this->handler->getImageSize( null, $this->filePath . '/LoremIpsum.djvu' ),
                        'Test file LoremIpsum.djvu should have a size of 2480 * 3508'
@@ -51,8 +51,8 @@ class DjVuTest extends MediaWikiMediaTestCase {
 
        public function testGetPageDimensions() {
                $file = $this->dataFile( 'LoremIpsum.djvu', 'image/x.djvu' );
-               $this->assertArrayEquals(
-                       [ 2480, 3508 ],
+               $this->assertSame(
+                       [ 'width' => 2480, 'height' => 3508 ],
                        $this->handler->getPageDimensions( $file, 1 ),
                        'Page 1 of test file LoremIpsum.djvu should have a size of 2480 * 3508'
                );
index 7a536df..2e9acfa 100644 (file)
@@ -70,16 +70,10 @@ abstract class MediaWikiMediaTestCase extends MediaWikiTestCase {
         *
         * File must be in the path returned by getFilePath()
         * @param string $name File name
-        * @param string|null $type MIME type [optional]
+        * @param string|false $type MIME type [optional]
         * @return UnregisteredLocalFile
         */
-       protected function dataFile( $name, $type = null ) {
-               if ( !$type ) {
-                       // Autodetect by file extension for the lazy.
-                       $magic = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
-                       $parts = explode( $name, '.' );
-                       $type = $magic->guessTypesForExtension( $parts[count( $parts ) - 1] );
-               }
+       protected function dataFile( $name, $type = false ) {
                return new UnregisteredLocalFile( false, $this->repo,
                        "mwstore://localtesting/data/$name", $type );
        }
index 7aef246..6b94d0a 100644 (file)
@@ -18,11 +18,6 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase {
         */
        public function testGetXMLMetadata( $infile, $expected ) {
                $r = new XMLReader();
-               if ( !method_exists( $r, 'readInnerXML' ) ) {
-                       $this->markTestSkipped( 'XMLReader::readInnerXML() does not exist (libxml >2.6.20 needed).' );
-
-                       return;
-               }
                $this->assertMetadata( $infile, $expected );
        }
 
index e4134b8..3a3feee 100644 (file)
@@ -71,7 +71,7 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
 
        protected function tearDown() {
                foreach ( $this->pagesToDelete as $p ) {
-                       /* @var $p WikiPage */
+                       /* @var WikiPage $p */
 
                        try {
                                if ( $p->exists() ) {
@@ -483,7 +483,7 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                'delete',
                                'delete',
                                'testing user 0 deletion',
-                               '0',
+                               null,
                                '127.0.0.1',
                                (string)$page->getTitle()->getNamespace(),
                                $page->getTitle()->getDBkey(),
@@ -851,7 +851,7 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
 
                # now, test the actual redirect
                $t = $page->getRedirectTarget();
-               $this->assertEquals( $target, is_null( $t ) ? null : $t->getFullText() );
+               $this->assertEquals( $target, $t ? $t->getFullText() : null );
        }
 
        /**
@@ -1109,9 +1109,10 @@ more stuff
                $page = $this->createPage( $title, $text, $model );
 
                $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
+               /** @var TextContent $c */
                $c = $page->replaceSectionContent( $section, $content, $sectionTitle );
 
-               $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getText() ) );
+               $this->assertEquals( $expected, $c ? trim( $c->getText() ) : null );
        }
 
        /**
@@ -1125,9 +1126,10 @@ more stuff
                $baseRevId = $page->getLatest();
 
                $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
+               /** @var TextContent $c */
                $c = $page->replaceSectionAtRev( $section, $content, $sectionTitle, $baseRevId );
 
-               $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getText() ) );
+               $this->assertEquals( $expected, $c ? trim( $c->getText() ) : null );
        }
 
        /**
index cb8257c..af2b9b7 100644 (file)
@@ -397,7 +397,6 @@ EOF
                $a->addHeadItem( '<foo1>' );
                $a->addHeadItem( '<bar1>', 'bar' );
                $a->addModules( 'test-module-a' );
-               $a->addModuleScripts( 'test-module-script-a' );
                $a->addModuleStyles( 'test-module-styles-a' );
                $b->addJsConfigVars( 'test-config-var-a', 'a' );
 
@@ -406,7 +405,6 @@ EOF
                $b->addHeadItem( '<foo2>' );
                $b->addHeadItem( '<bar2>', 'bar' );
                $b->addModules( 'test-module-b' );
-               $b->addModuleScripts( 'test-module-script-b' );
                $b->addModuleStyles( 'test-module-styles-b' );
                $b->addJsConfigVars( 'test-config-var-b', 'b' );
                $b->addJsConfigVars( 'test-config-var-a', 'X' );
@@ -421,10 +419,6 @@ EOF
                                'test-module-a',
                                'test-module-b',
                        ],
-                       'getModuleScripts' => [
-                               'test-module-script-a',
-                               'test-module-script-b',
-                       ],
                        'getModuleStyles' => [
                                'test-module-styles-a',
                                'test-module-styles-b',
index ad8aa1e..1f6f4e8 100644 (file)
@@ -527,6 +527,7 @@ class SanitizerTest extends MediaWikiTestCase {
                        ],
                        [ '1<span class="<?php">2</span>3', '123' ],
                        [ '1<span class="<?">2</span>3', '123' ],
+                       [ '<th>1</th><td>2</td>', '1 2' ],
                ];
        }
 
index 80881ad..ec7bafc 100644 (file)
@@ -35,10 +35,18 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                        'PasswordCannotMatchUsername' => true,
                ],
                'sysop' => [
-                       'MinimalPasswordLength' => 8,
+                       'MinimalPasswordLength' => [ 'value' => 8, 'suggestChangeOnLogin' => true ],
                        'MinimumPasswordLengthToLogin' => 1,
                        'PasswordCannotMatchUsername' => true,
                ],
+               'bureaucrat' => [
+                       'MinimalPasswordLength' => [
+                               'value' => 6,
+                               'suggestChangeOnLogin' => false,
+                               'forceChange' => true,
+                       ],
+                       'PasswordCannotMatchUsername' => true,
+               ],
                'default' => [
                        'MinimalPasswordLength' => 4,
                        'MinimumPasswordLengthToLogin' => 1,
@@ -67,7 +75,7 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                $user = $this->getTestUser( [ 'sysop' ] )->getUser();
                $this->assertArrayEquals(
                        [
-                               'MinimalPasswordLength' => 8,
+                               'MinimalPasswordLength' => [ 'value' => 8, 'suggestChangeOnLogin' => true ],
                                'MinimumPasswordLengthToLogin' => 1,
                                'PasswordCannotMatchUsername' => true,
                                'PasswordCannotMatchBlacklist' => true,
@@ -79,7 +87,11 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                $user = $this->getTestUser( [ 'sysop', 'checkuser' ] )->getUser();
                $this->assertArrayEquals(
                        [
-                               'MinimalPasswordLength' => [ 'value' => 10, 'forceChange' => true ],
+                               'MinimalPasswordLength' => [
+                                       'value' => 10,
+                                       'forceChange' => true,
+                                       'suggestChangeOnLogin' => true
+                               ],
                                'MinimumPasswordLengthToLogin' => 6,
                                'PasswordCannotMatchUsername' => true,
                                'PasswordCannotMatchBlacklist' => true,
@@ -92,13 +104,17 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
        public function testGetPoliciesForGroups() {
                $effective = UserPasswordPolicy::getPoliciesForGroups(
                        $this->policies,
-                       [ 'user', 'checkuser' ],
+                       [ 'user', 'checkuser', 'sysop' ],
                        $this->policies['default']
                );
 
                $this->assertArrayEquals(
                        [
-                               'MinimalPasswordLength' => [ 'value' => 10, 'forceChange' => true ],
+                               'MinimalPasswordLength' => [
+                                       'value' => 10,
+                                       'forceChange' => true,
+                                       'suggestChangeOnLogin' => true
+                               ],
                                'MinimumPasswordLengthToLogin' => 6,
                                'PasswordCannotMatchUsername' => true,
                                'PasswordCannotMatchBlacklist' => true,
@@ -125,12 +141,16 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                $success = Status::newGood( [] );
                $warning = Status::newGood( [] );
                $forceChange = Status::newGood( [ 'forceChange' => true ] );
+               $suggestChangeOnLogin = Status::newGood( [ 'suggestChangeOnLogin' => true ] );
                $fatal = Status::newGood( [] );
+
                // the message does not matter, we only test for state and value
                $warning->warning( 'invalid-password' );
                $forceChange->warning( 'invalid-password' );
+               $suggestChangeOnLogin->warning( 'invalid-password' );
                $warning->warning( 'invalid-password' );
                $fatal->fatal( 'invalid-password' );
+
                return [
                        'No groups, default policy, password too short to login' => [
                                [],
@@ -147,16 +167,21 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                                'abcdabcdabcd',
                                $success,
                        ],
-                       'Sysop with short password' => [
+                       'Sysop with short password and suggestChangeOnLogin set to true' => [
                                [ 'sysop' ],
                                'abcd',
-                               $warning,
+                               $suggestChangeOnLogin,
                        ],
                        'Checkuser with short password' => [
-                               [ 'sysop', 'checkuser' ],
+                               [ 'checkuser' ],
                                'abcdabcd',
                                $forceChange,
                        ],
+                       'Bureaucrat bad password with forceChange true, suggestChangeOnLogin false' => [
+                               [ 'bureaucrat' ],
+                               'short',
+                               $forceChange,
+                       ],
                        'Checkuser with too short password to login' => [
                                [ 'sysop', 'checkuser' ],
                                'abcd',
@@ -281,6 +306,29 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                                        ],
                                ], // max
                        ],
+                       'complex value in both p1 and p2 #2' => [
+                               [
+                                       'MinimalPasswordLength' => [
+                                               'value' => 8,
+                                               'foo' => 1,
+                                               'baz' => false,
+                                       ],
+                               ], // p1
+                               [
+                                       'MinimalPasswordLength' => [
+                                               'value' => 2,
+                                               'bar' => true
+                                       ],
+                               ], // p2
+                               [
+                                       'MinimalPasswordLength' => [
+                                               'value' => 8,
+                                               'foo' => 1,
+                                               'bar' => true,
+                                               'baz' => false,
+                                       ],
+                               ], // max
+                       ],
                ];
        }
 
index 19baf5a..28cd503 100644 (file)
@@ -78,7 +78,7 @@ class PoolCounterTest extends MediaWikiTestCase {
 // That call will die if the contructor is not public, unless we use disableOriginalConstructor(),
 // in which case we could not test the constructor.
 abstract class PoolCounterAbstractMock extends PoolCounter {
-       public function __construct() {
-               call_user_func_array( 'parent::__construct', func_get_args() );
+       public function __construct( ...$args ) {
+               call_user_func_array( 'parent::__construct', $args );
        }
 }
index 2eec5ce..94c0667 100644 (file)
@@ -27,7 +27,7 @@ use Wikimedia\TestingAccessWrapper;
 /**
  * @group Preferences
  */
-class DefaultPreferencesFactoryTest extends MediaWikiTestCase {
+class DefaultPreferencesFactoryTest extends \MediaWikiTestCase {
 
        /** @var IContextSource */
        protected $context;
@@ -83,6 +83,50 @@ class DefaultPreferencesFactoryTest extends MediaWikiTestCase {
                $this->assertEquals( $cssClass, $prefs['emailauthentication']['cssclass'] );
        }
 
+       /**
+        * @covers MediaWiki\Preferences\DefaultPreferencesFactory::renderingPreferences()
+        */
+       public function testShowRollbackConfIsHiddenForUsersWithoutRollbackRights() {
+               $userMock = $this->getMockBuilder( User::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $userMock->method( 'isAllowed' )
+                       ->willReturn( false );
+               $userMock->method( 'getEffectiveGroups' )
+                       ->willReturn( [] );
+               $userMock->method( 'getGroupMemberships' )
+                       ->willReturn( [] );
+               $userMock->method( 'getOptions' )
+                       ->willReturn( [ 'test' => 'yes' ] );
+
+               $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context );
+               $this->assertArrayNotHasKey( 'showrollbackconfirmation', $prefs );
+       }
+
+       /**
+        * @covers MediaWiki\Preferences\DefaultPreferencesFactory::renderingPreferences()
+        */
+       public function testShowRollbackConfIsShownForUsersWithRollbackRights() {
+               $userMock = $this->getMockBuilder( User::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $userMock->method( 'isAllowed' )
+                       ->willReturn( true );
+               $userMock->method( 'getEffectiveGroups' )
+                       ->willReturn( [] );
+               $userMock->method( 'getGroupMemberships' )
+                       ->willReturn( [] );
+               $userMock->method( 'getOptions' )
+                       ->willReturn( [ 'test' => 'yes' ] );
+
+               $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context );
+               $this->assertArrayHasKey( 'showrollbackconfirmation', $prefs );
+               $this->assertEquals(
+                       'rendering/advancedrendering',
+                       $prefs['showrollbackconfirmation']['section']
+               );
+       }
+
        public function emailAuthenticationProvider() {
                $userNoEmail = new User;
                $userEmailUnauthed = new User;
index 97ffd94..c210061 100644 (file)
@@ -8,10 +8,10 @@ class DerivativeResourceLoaderContextTest extends PHPUnit\Framework\TestCase {
 
        use MediaWikiCoversValidator;
 
-       protected static function getContext() {
+       protected static function makeContext() {
                $request = new FauxRequest( [
-                               'lang' => 'zh',
-                               'modules' => 'test.context',
+                               'lang' => 'qqx',
+                               'modules' => 'test.default',
                                'only' => 'scripts',
                                'skin' => 'fallback',
                                'target' => 'test',
@@ -19,123 +19,114 @@ class DerivativeResourceLoaderContextTest extends PHPUnit\Framework\TestCase {
                return new ResourceLoaderContext( new ResourceLoader(), $request );
        }
 
-       public function testGetInherited() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
-
-               // Request parameters
-               $this->assertEquals( $derived->getDebug(), false );
-               $this->assertEquals( $derived->getLanguage(), 'zh' );
-               $this->assertEquals( $derived->getModules(), [ 'test.context' ] );
-               $this->assertEquals( $derived->getOnly(), 'scripts' );
-               $this->assertEquals( $derived->getSkin(), 'fallback' );
-               $this->assertEquals( $derived->getUser(), null );
-
-               // Misc
-               $this->assertEquals( $derived->getDirection(), 'ltr' );
-               $this->assertEquals( $derived->getHash(), 'zh|fallback|||scripts|||||' );
-       }
-
-       public function testModules() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeModules() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getModules(), [ 'test.default' ], 'inherit from parent' );
 
                $derived->setModules( [ 'test.override' ] );
-               $this->assertEquals( $derived->getModules(), [ 'test.override' ] );
-       }
-
-       public function testLanguage() {
-               $context = self::getContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
-
-               $derived->setLanguage( 'nl' );
-               $this->assertEquals( $derived->getLanguage(), 'nl' );
+               $this->assertSame( $derived->getModules(), [ 'test.override' ] );
        }
 
-       public function testDirection() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeLanguageAndDirection() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getLanguage(), 'qqx', 'inherit from parent' );
 
                $derived->setLanguage( 'nl' );
-               $this->assertEquals( $derived->getDirection(), 'ltr' );
+               $this->assertSame( $derived->getLanguage(), 'nl' );
+               $this->assertSame( $derived->getDirection(), 'ltr' );
 
+               // Changing the language must clear cache of computed direction
                $derived->setLanguage( 'he' );
-               $this->assertEquals( $derived->getDirection(), 'rtl' );
+               $this->assertSame( $derived->getDirection(), 'rtl' );
+               $this->assertSame( $derived->getLanguage(), 'he' );
 
+               // Overriding the direction explicitly is allowed
                $derived->setDirection( 'ltr' );
-               $this->assertEquals( $derived->getDirection(), 'ltr' );
+               $this->assertSame( $derived->getDirection(), 'ltr' );
+               $this->assertSame( $derived->getLanguage(), 'he' );
        }
 
-       public function testSkin() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeSkin() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getSkin(), 'fallback', 'inherit from parent' );
 
-               $derived->setSkin( 'override' );
-               $this->assertEquals( $derived->getSkin(), 'override' );
+               $derived->setSkin( 'myskin' );
+               $this->assertSame( $derived->getSkin(), 'myskin' );
        }
 
-       public function testUser() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeUser() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getUser(), null, 'inherit from parent' );
 
-               $derived->setUser( 'Example' );
-               $this->assertEquals( $derived->getUser(), 'Example' );
+               $derived->setUser( 'MyUser' );
+               $this->assertSame( $derived->getUser(), 'MyUser' );
        }
 
-       public function testDebug() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeDebug() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getDebug(), false, 'inherit from parent' );
 
                $derived->setDebug( true );
-               $this->assertEquals( $derived->getDebug(), true );
+               $this->assertSame( $derived->getDebug(), true );
        }
 
-       public function testOnly() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeOnly() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getOnly(), 'scripts', 'inherit from parent' );
 
                $derived->setOnly( 'styles' );
-               $this->assertEquals( $derived->getOnly(), 'styles' );
+               $this->assertSame( $derived->getOnly(), 'styles' );
 
                $derived->setOnly( null );
-               $this->assertEquals( $derived->getOnly(), null );
+               $this->assertSame( $derived->getOnly(), null );
        }
 
-       public function testVersion() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeVersion() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getVersion(), null );
 
                $derived->setVersion( 'hw1' );
-               $this->assertEquals( $derived->getVersion(), 'hw1' );
+               $this->assertSame( $derived->getVersion(), 'hw1' );
        }
 
-       public function testRaw() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+       public function testChangeRaw() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getRaw(), false, 'inherit from parent' );
 
                $derived->setRaw( true );
-               $this->assertEquals( $derived->getRaw(), true );
+               $this->assertSame( $derived->getRaw(), true );
        }
 
-       public function testGetHash() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
-
-               $this->assertEquals( $derived->getHash(), 'zh|fallback|||scripts|||||' );
+       public function testChangeHash() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertSame( $derived->getHash(), 'qqx|fallback|||scripts|||||', 'inherit' );
 
                $derived->setLanguage( 'nl' );
                $derived->setUser( 'Example' );
                // Assert that subclass is able to clear parent class "hash" member
-               $this->assertEquals( $derived->getHash(), 'nl|fallback||Example|scripts|||||' );
+               $this->assertSame( $derived->getHash(), 'nl|fallback||Example|scripts|||||' );
        }
 
-       public function testContentOverrides() {
-               $derived = new DerivativeResourceLoaderContext( self::getContext() );
-
-               $this->assertNull( $derived->getContentOverrideCallback() );
+       public function testChangeContentOverrides() {
+               $derived = new DerivativeResourceLoaderContext( self::makeContext() );
+               $this->assertNull( $derived->getContentOverrideCallback(), 'default' );
 
                $override = function ( Title $t ) {
                        return null;
                };
                $derived->setContentOverrideCallback( $override );
-               $this->assertSame( $override, $derived->getContentOverrideCallback() );
+               $this->assertSame( $override, $derived->getContentOverrideCallback(), 'changed' );
 
                $derived2 = new DerivativeResourceLoaderContext( $derived );
-               $this->assertSame( $override, $derived2->getContentOverrideCallback() );
+               $this->assertSame(
+                       $override,
+                       $derived2->getContentOverrideCallback(),
+                       'change via a second derivative layer'
+               );
        }
 
-       public function testAccessors() {
-               $context = self::getContext();
+       public function testImmutableAccessors() {
+               $context = self::makeContext();
                $derived = new DerivativeResourceLoaderContext( $context );
                $this->assertSame( $derived->getRequest(), $context->getRequest() );
                $this->assertSame( $derived->getResourceLoader(), $context->getResourceLoader() );
index 70bf39f..e577643 100644 (file)
@@ -3,7 +3,7 @@
 use Wikimedia\TestingAccessWrapper;
 
 /**
- * @group Cache
+ * @group ResourceLoader
  * @covers MessageBlobStore
  */
 class MessageBlobStoreTest extends PHPUnit\Framework\TestCase {
@@ -13,64 +13,17 @@ class MessageBlobStoreTest extends PHPUnit\Framework\TestCase {
 
        protected function setUp() {
                parent::setUp();
-               // MediaWiki tests defaults $wgMainWANCache to CACHE_NONE.
-               // Use hash instead so that caching is observed
-               $this->wanCache = $this->getMockBuilder( WANObjectCache::class )
-                       ->setConstructorArgs( [ [
-                               'cache' => new HashBagOStuff(),
-                               'pool' => 'test',
-                               'relayer' => new EventRelayerNull( [] )
-                       ] ] )
-                       ->setMethods( [ 'makePurgeValue' ] )
-                       ->getMock();
-
-               $this->wanCache->expects( $this->any() )
-                       ->method( 'makePurgeValue' )
-                       ->will( $this->returnCallback( function ( $timestamp, $holdoff ) {
-                               // Disable holdoff as it messes with testing. Aside from a 0-second holdoff,
-                               // make sure that "time" passes between getMulti() check init and the set()
-                               // in recacheMessageBlob(). This especially matters for Windows clocks.
-                               $ts = (float)$timestamp - 0.0001;
-
-                               return WANObjectCache::PURGE_VAL_PREFIX . $ts . ':0';
-                       } ) );
-       }
-
-       protected function makeBlobStore( $methods = null, $rl = null ) {
-               $blobStore = $this->getMockBuilder( MessageBlobStore::class )
-                       ->setConstructorArgs( [ $rl ?? $this->createMock( ResourceLoader::class ) ] )
-                       ->setMethods( $methods )
-                       ->getMock();
-
-               $access = TestingAccessWrapper::newFromObject( $blobStore );
-               $access->wanCache = $this->wanCache;
-               return $blobStore;
-       }
-
-       protected function makeModule( array $messages ) {
-               $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] );
-               $module->setName( 'test.blobstore' );
-               return $module;
-       }
-
-       /** @covers MessageBlobStore::setLogger */
-       public function testSetLogger() {
-               $blobStore = $this->makeBlobStore();
-               $this->assertSame( null, $blobStore->setLogger( new Psr\Log\NullLogger() ) );
+               // MediaWiki's test wrapper sets $wgMainWANCache to CACHE_NONE.
+               // Use HashBagOStuff here so that we can observe caching.
+               $this->wanCache = new WANObjectCache( [
+                       'cache' => new HashBagOStuff()
+               ] );
+
+               $this->clock = 1301655600.000;
+               $this->wanCache->setMockTime( $this->clock );
        }
 
-       /** @covers MessageBlobStore::getResourceLoader */
-       public function testGetResourceLoader() {
-               // Call protected method
-               $blobStore = TestingAccessWrapper::newFromObject( $this->makeBlobStore() );
-               $this->assertInstanceOf(
-                       ResourceLoader::class,
-                       $blobStore->getResourceLoader()
-               );
-       }
-
-       /** @covers MessageBlobStore::fetchMessage */
-       public function testFetchMessage() {
+       public function testBlobCreation() {
                $module = $this->makeModule( [ 'mainpage' ] );
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
@@ -81,140 +34,153 @@ class MessageBlobStoreTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( '{"mainpage":"Main Page"}', $blob, 'Generated blob' );
        }
 
-       /** @covers MessageBlobStore::fetchMessage */
-       public function testFetchMessageFail() {
+       public function testBlobCreation_unknownMessage() {
                $module = $this->makeModule( [ 'i-dont-exist' ] );
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
-
                $blobStore = $this->makeBlobStore( null, $rl );
-               $blob = $blobStore->getBlob( $module, 'en' );
 
+               // Generating a blob should succeed without errors,
+               // even if a message is unknown.
+               $blob = $blobStore->getBlob( $module, 'en' );
                $this->assertEquals( '{"i-dont-exist":"\u29fci-dont-exist\u29fd"}', $blob, 'Generated blob' );
        }
 
-       public function testGetBlob() {
-               $module = $this->makeModule( [ 'foo' ] );
+       public function testMessageCachingAndPurging() {
+               $module = $this->makeModule( [ 'example' ] );
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
-
                $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
+
+               // Advance this new WANObjectCache instance to a normal state,
+               // by doing one "get" and letting its hold off period expire.
+               // Without this, the first real "get" would lazy-initialise the
+               // checkKey and thus reject the first "set".
+               $blobStore->getBlob( $module, 'en' );
+               $this->clock += 20;
+
+               // Arrange version 1 of a message
                $blobStore->expects( $this->once() )
                        ->method( 'fetchMessage' )
-                       ->will( $this->returnValue( 'Example' ) );
+                       ->will( $this->returnValue( 'First version' ) );
 
+               // Assert
                $blob = $blobStore->getBlob( $module, 'en' );
+               $this->assertEquals( '{"example":"First version"}', $blob, 'Blob for v1' );
 
-               $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' );
-       }
-
-       public function testGetBlobCached() {
-               $module = $this->makeModule( [ 'example' ] );
-               $rl = new ResourceLoader();
-               $rl->register( $module->getName(), $module );
-
+               // Arrange version 2
                $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
                $blobStore->expects( $this->once() )
                        ->method( 'fetchMessage' )
-                       ->will( $this->returnValue( 'First' ) );
+                       ->will( $this->returnValue( 'Second version' ) );
+               $this->clock += 20;
 
-               $module = $this->makeModule( [ 'example' ] );
+               // Assert
+               // We do not validate whether a cached message is up-to-date.
+               // Instead, changes to messages will send us a purge.
+               // When cache is not purged or expired, it must be used.
                $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
+               $this->assertEquals( '{"example":"First version"}', $blob, 'Reuse cached v1 blob' );
 
-               $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
-               $blobStore->expects( $this->never() )
-                       ->method( 'fetchMessage' )
-                       ->will( $this->returnValue( 'Second' ) );
+               // Purge cache
+               $blobStore->updateMessage( 'example' );
+               $this->clock += 20;
 
-               $module = $this->makeModule( [ 'example' ] );
+               // Assert
                $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"example":"First"}', $blob, 'Cache hit' );
+               $this->assertEquals( '{"example":"Second version"}', $blob, 'Updated blob for v2' );
        }
 
-       public function testUpdateMessage() {
+       public function testPurgeEverything() {
                $module = $this->makeModule( [ 'example' ] );
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
                $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
-               $blobStore->expects( $this->once() )
+               // Advance this new WANObjectCache instance to a normal state.
+               $blobStore->getBlob( $module, 'en' );
+               $this->clock += 20;
+
+               // Arrange version 1 and 2
+               $blobStore->expects( $this->exactly( 2 ) )
                        ->method( 'fetchMessage' )
-                       ->will( $this->returnValue( 'First' ) );
+                       ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
 
+               // Assert
                $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
+               $this->assertEquals( '{"example":"First"}', $blob, 'Blob for v1' );
 
-               $blobStore->updateMessage( 'example' );
+               $this->clock += 20;
 
-               $module = $this->makeModule( [ 'example' ] );
-               $rl = new ResourceLoader();
-               $rl->register( $module->getName(), $module );
-               $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
-               $blobStore->expects( $this->once() )
-                       ->method( 'fetchMessage' )
-                       ->will( $this->returnValue( 'Second' ) );
+               // Assert
+               $blob = $blobStore->getBlob( $module, 'en' );
+               $this->assertEquals( '{"example":"First"}', $blob, 'Blob for v1 again' );
+
+               // Purge everything
+               $blobStore->clear();
+               $this->clock += 20;
 
+               // Assert
                $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
+               $this->assertEquals( '{"example":"Second"}', $blob, 'Blob for v2' );
        }
 
-       public function testValidation() {
+       public function testValidateAgainstModuleRegistry() {
+               // Arrange version 1 of a module
                $module = $this->makeModule( [ 'foo' ] );
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
-
                $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
                $blobStore->expects( $this->once() )
                        ->method( 'fetchMessage' )
                        ->will( $this->returnValueMap( [
+                               // message key, language code, message value
                                [ 'foo', 'en', 'Hello' ],
                        ] ) );
 
+               // Assert
                $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"foo":"Hello"}', $blob, 'Generated blob' );
+               $this->assertEquals( '{"foo":"Hello"}', $blob, 'Blob for v1' );
 
-               // Now, imagine a change to the module is deployed. The module now contains
-               // message 'foo' and 'bar'. While updateMessage() was not called (since no
-               // message values were changed) it should detect the change in list of
-               // message keys.
+               // Arrange version 2 of module
+               // While message values may be out of date, the set of messages returned
+               // must always match the set of message keys required by the module.
+               // We do not receive purges for this because no messages were changed.
                $module = $this->makeModule( [ 'foo', 'bar' ] );
                $rl = new ResourceLoader();
                $rl->register( $module->getName(), $module );
-
                $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
                $blobStore->expects( $this->exactly( 2 ) )
                        ->method( 'fetchMessage' )
                        ->will( $this->returnValueMap( [
+                               // message key, language code, message value
                                [ 'foo', 'en', 'Hello' ],
                                [ 'bar', 'en', 'World' ],
                        ] ) );
 
+               // Assert
                $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' );
+               $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Blob for v2' );
        }
 
-       public function testClear() {
-               $module = $this->makeModule( [ 'example' ] );
-               $rl = new ResourceLoader();
-               $rl->register( $module->getName(), $module );
-               $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
-               $blobStore->expects( $this->exactly( 2 ) )
-                       ->method( 'fetchMessage' )
-                       ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
-
-               $now = microtime( true );
-               $this->wanCache->setMockTime( $now );
-
-               $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
+       public function testSetLoggedIsVoid() {
+               $blobStore = $this->makeBlobStore();
+               $this->assertSame( null, $blobStore->setLogger( new Psr\Log\NullLogger() ) );
+       }
 
-               $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
+       private function makeBlobStore( $methods = null, $rl = null ) {
+               $blobStore = $this->getMockBuilder( MessageBlobStore::class )
+                       ->setConstructorArgs( [ $rl ?? $this->createMock( ResourceLoader::class ) ] )
+                       ->setMethods( $methods )
+                       ->getMock();
 
-               $now += 1;
-               $blobStore->clear();
+               $access = TestingAccessWrapper::newFromObject( $blobStore );
+               $access->wanCache = $this->wanCache;
+               return $blobStore;
+       }
 
-               $blob = $blobStore->getBlob( $module, 'en' );
-               $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
+       private function makeModule( array $messages ) {
+               $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] );
+               $module->setName( 'test.blobstore' );
+               return $module;
        }
 }
index 70056ba..9ab3a2d 100644 (file)
@@ -4,112 +4,12 @@ use Wikimedia\TestingAccessWrapper;
 
 /**
  * @group ResourceLoader
+ * @covers ResourceLoaderClientHtml
  */
 class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
 
        use MediaWikiCoversValidator;
 
-       protected static function expandVariables( $text ) {
-               return strtr( $text, [
-                       '{blankVer}' => ResourceLoaderTestCase::BLANK_VERSION
-               ] );
-       }
-
-       protected static function makeContext( $extraQuery = [] ) {
-               $conf = new HashConfig( [
-                       'ResourceLoaderSources' => [],
-                       'ResourceModuleSkinStyles' => [],
-                       'ResourceModules' => [],
-                       'EnableJavaScriptTest' => false,
-                       'ResourceLoaderDebug' => false,
-                       'LoadScript' => '/w/load.php',
-               ] );
-               return new ResourceLoaderContext(
-                       new ResourceLoader( $conf ),
-                       new FauxRequest( array_merge( [
-                               'lang' => 'nl',
-                               'skin' => 'fallback',
-                               'user' => 'Example',
-                               'target' => 'phpunit',
-                       ], $extraQuery ) )
-               );
-       }
-
-       protected static function makeModule( array $options = [] ) {
-               return new ResourceLoaderTestModule( $options );
-       }
-
-       protected static function makeSampleModules() {
-               $modules = [
-                       'test' => [],
-                       'test.private' => [ 'group' => 'private' ],
-                       'test.shouldembed.empty' => [ 'shouldEmbed' => true, 'isKnownEmpty' => true ],
-                       'test.shouldembed' => [ 'shouldEmbed' => true ],
-                       'test.user' => [ 'group' => 'user' ],
-
-                       'test.styles.pure' => [ 'type' => ResourceLoaderModule::LOAD_STYLES ],
-                       'test.styles.mixed' => [],
-                       'test.styles.noscript' => [
-                               'type' => ResourceLoaderModule::LOAD_STYLES,
-                               'group' => 'noscript',
-                       ],
-                       'test.styles.user' => [
-                               'type' => ResourceLoaderModule::LOAD_STYLES,
-                               'group' => 'user',
-                       ],
-                       'test.styles.user.empty' => [
-                               'type' => ResourceLoaderModule::LOAD_STYLES,
-                               'group' => 'user',
-                               'isKnownEmpty' => true,
-                       ],
-                       'test.styles.private' => [
-                               'type' => ResourceLoaderModule::LOAD_STYLES,
-                               'group' => 'private',
-                               'styles' => '.private{}',
-                       ],
-                       'test.styles.shouldembed' => [
-                               'type' => ResourceLoaderModule::LOAD_STYLES,
-                               'shouldEmbed' => true,
-                               'styles' => '.shouldembed{}',
-                       ],
-                       'test.styles.deprecated' => [
-                               'type' => ResourceLoaderModule::LOAD_STYLES,
-                               'deprecated' => 'Deprecation message.',
-                       ],
-
-                       'test.scripts' => [],
-                       'test.scripts.user' => [ 'group' => 'user' ],
-                       'test.scripts.user.empty' => [ 'group' => 'user', 'isKnownEmpty' => true ],
-                       'test.scripts.raw' => [ 'isRaw' => true ],
-                       'test.scripts.shouldembed' => [ 'shouldEmbed' => true ],
-
-                       'test.ordering.a' => [ 'shouldEmbed' => false ],
-                       'test.ordering.b' => [ 'shouldEmbed' => false ],
-                       'test.ordering.c' => [ 'shouldEmbed' => true, 'styles' => '.orderingC{}' ],
-                       'test.ordering.d' => [ 'shouldEmbed' => true, 'styles' => '.orderingD{}' ],
-                       'test.ordering.e' => [ 'shouldEmbed' => false ],
-               ];
-               return array_map( function ( $options ) {
-                       return self::makeModule( $options );
-               }, $modules );
-       }
-
-       /**
-        * @covers ResourceLoaderClientHtml::getDocumentAttributes
-        */
-       public function testGetDocumentAttributes() {
-               $client = new ResourceLoaderClientHtml( self::makeContext() );
-               $this->assertInternalType( 'array', $client->getDocumentAttributes() );
-       }
-
-       /**
-        * @covers ResourceLoaderClientHtml::__construct
-        * @covers ResourceLoaderClientHtml::setModules
-        * @covers ResourceLoaderClientHtml::setModuleStyles
-        * @covers ResourceLoaderClientHtml::setModuleScripts
-        * @covers ResourceLoaderClientHtml::getData
-        * @covers ResourceLoaderClientHtml::getContext
-        */
        public function testGetData() {
                $context = self::makeContext();
                $context->getResourceLoader()->register( self::makeSampleModules() );
@@ -132,29 +32,30 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                        'test.styles.deprecated',
                        'test.unregistered.styles',
                ] );
-               $client->setModuleScripts( [
-                       'test.scripts',
-                       'test.scripts.user',
-                       'test.scripts.user.empty',
-                       'test.scripts.shouldembed',
-                       'test.unregistered.scripts',
-               ] );
 
                $expected = [
                        'states' => [
+                               // The below are NOT queued for loading via `mw.loader.load(Array)`.
+                               // Instead we tell the client to set their state to "loading" so that
+                               // if they are needed as dependencies, the client will not try to
+                               // load them on-demand, because the server is taking care of them already.
+                               // Either:
+                               // - Embedded as inline scripts in the HTML (e.g. user-private code, and
+                               //   previews). Once that script tag is reached, the state is "loaded".
+                               // - Loaded directly from the HTML with a dedicated HTTP request (e.g.
+                               //   user scripts, which vary by a 'user' and 'version' parameter that
+                               //   the static user-agnostic startup module won't have).
                                'test.private' => 'loading',
-                               'test.shouldembed.empty' => 'ready',
                                'test.shouldembed' => 'loading',
                                'test.user' => 'loading',
+                               // The below are known to the server to be empty scripts, or to be
+                               // synchronously loaded stylesheets. These start in the "ready" state.
+                               'test.shouldembed.empty' => 'ready',
                                'test.styles.pure' => 'ready',
                                'test.styles.user.empty' => 'ready',
                                'test.styles.private' => 'ready',
                                'test.styles.shouldembed' => 'ready',
                                'test.styles.deprecated' => 'ready',
-                               'test.scripts' => 'loading',
-                               'test.scripts.user' => 'loading',
-                               'test.scripts.user.empty' => 'ready',
-                               'test.scripts.shouldembed' => 'loading',
                        ],
                        'general' => [
                                'test',
@@ -163,11 +64,6 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                                'test.styles.pure',
                                'test.styles.deprecated',
                        ],
-                       'scripts' => [
-                               'test.scripts',
-                               'test.scripts.user',
-                               'test.scripts.shouldembed',
-                       ],
                        'embed' => [
                                'styles' => [ 'test.styles.private', 'test.styles.shouldembed' ],
                                'general' => [
@@ -189,13 +85,6 @@ Deprecation message.' ]
                $this->assertEquals( $expected, $access->getData() );
        }
 
-       /**
-        * @covers ResourceLoaderClientHtml::setConfig
-        * @covers ResourceLoaderClientHtml::setExemptStates
-        * @covers ResourceLoaderClientHtml::getHeadHtml
-        * @covers ResourceLoaderClientHtml::getLoad
-        * @covers ResourceLoader::makeLoaderStateScript
-        */
        public function testGetHeadHtml() {
                $context = self::makeContext();
                $context->getResourceLoader()->register( self::makeSampleModules() );
@@ -213,9 +102,6 @@ Deprecation message.' ]
                        'test.styles.private',
                        'test.styles.deprecated',
                ] );
-               $client->setModuleScripts( [
-                       'test.scripts',
-               ] );
                $client->setExemptStates( [
                        'test.exempt' => 'ready',
                ] );
@@ -224,24 +110,21 @@ Deprecation message.' ]
                $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
                        . '<script>(window.RLQ=window.RLQ||[]).push(function(){'
                        . 'mw.config.set({"key":"value"});'
-                       . 'mw.loader.state({"test.exempt":"ready","test.private":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.styles.deprecated":"ready","test.scripts":"loading"});'
+                       . 'mw.loader.state({"test.exempt":"ready","test.private":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.styles.deprecated":"ready"});'
                        . 'mw.loader.implement("test.private@{blankVer}",null,{"css":[]});'
                        . 'RLPAGEMODULES=["test"];mw.loader.load(RLPAGEMODULES);'
-                       . 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts\u0026only=scripts\u0026skin=fallback");'
                        . '});</script>' . "\n"
-                       . '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.styles.deprecated%2Cpure&amp;only=styles&amp;skin=fallback"/>' . "\n"
+                       . '<link rel="stylesheet" href="/w/load.php?lang=nl&amp;modules=test.styles.deprecated%2Cpure&amp;only=styles&amp;skin=fallback"/>' . "\n"
                        . '<style>.private{}</style>' . "\n"
-                       . '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback"></script>';
+                       . '<script async="" src="/w/load.php?lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback"></script>';
                // phpcs:enable
                $expected = self::expandVariables( $expected );
 
-               $this->assertEquals( $expected, $client->getHeadHtml() );
+               $this->assertSame( $expected, (string)$client->getHeadHtml() );
        }
 
        /**
         * Confirm that 'target' is passed down to the startup module's load url.
-        *
-        * @covers ResourceLoaderClientHtml::getHeadHtml
         */
        public function testGetHeadHtmlWithTarget() {
                $client = new ResourceLoaderClientHtml(
@@ -251,16 +134,14 @@ Deprecation message.' ]
 
                // phpcs:disable Generic.Files.LineLength
                $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
-                       . '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback&amp;target=example"></script>';
+                       . '<script async="" src="/w/load.php?lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback&amp;target=example"></script>';
                // phpcs:enable
 
-               $this->assertEquals( $expected, $client->getHeadHtml() );
+               $this->assertSame( $expected, (string)$client->getHeadHtml() );
        }
 
        /**
         * Confirm that 'safemode' is passed down to startup.
-        *
-        * @covers ResourceLoaderClientHtml::getHeadHtml
         */
        public function testGetHeadHtmlWithSafemode() {
                $client = new ResourceLoaderClientHtml(
@@ -270,16 +151,14 @@ Deprecation message.' ]
 
                // phpcs:disable Generic.Files.LineLength
                $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
-                       . '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=startup&amp;only=scripts&amp;safemode=1&amp;skin=fallback"></script>';
+                       . '<script async="" src="/w/load.php?lang=nl&amp;modules=startup&amp;only=scripts&amp;safemode=1&amp;skin=fallback"></script>';
                // phpcs:enable
 
-               $this->assertEquals( $expected, $client->getHeadHtml() );
+               $this->assertSame( $expected, (string)$client->getHeadHtml() );
        }
 
        /**
         * Confirm that a null 'target' is the same as no target.
-        *
-        * @covers ResourceLoaderClientHtml::getHeadHtml
         */
        public function testGetHeadHtmlWithNullTarget() {
                $client = new ResourceLoaderClientHtml(
@@ -289,16 +168,12 @@ Deprecation message.' ]
 
                // phpcs:disable Generic.Files.LineLength
                $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
-                       . '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback"></script>';
+                       . '<script async="" src="/w/load.php?lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback"></script>';
                // phpcs:enable
 
-               $this->assertEquals( $expected, $client->getHeadHtml() );
+               $this->assertSame( $expected, (string)$client->getHeadHtml() );
        }
 
-       /**
-        * @covers ResourceLoaderClientHtml::getBodyHtml
-        * @covers ResourceLoaderClientHtml::getLoad
-        */
        public function testGetBodyHtml() {
                $context = self::makeContext();
                $context->getResourceLoader()->register( self::makeSampleModules() );
@@ -312,16 +187,13 @@ Deprecation message.' ]
                $client->setModuleStyles( [
                        'test.styles.deprecated',
                ] );
-               $client->setModuleScripts( [
-                       'test.scripts',
-               ] );
                // phpcs:disable Generic.Files.LineLength
                $expected = '<script>(window.RLQ=window.RLQ||[]).push(function(){'
                        . 'mw.log.warn("This page is using the deprecated ResourceLoader module \"test.styles.deprecated\".\nDeprecation message.");'
                        . '});</script>';
                // phpcs:enable
 
-               $this->assertEquals( $expected, $client->getBodyHtml() );
+               $this->assertSame( $expected, (string)$client->getBodyHtml() );
        }
 
        public static function provideMakeLoad() {
@@ -331,18 +203,21 @@ Deprecation message.' ]
                                'context' => [],
                                'modules' => [ 'test.unknown' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
+                               'extra' => [],
                                'output' => '',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.styles.private' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
+                               'extra' => [],
                                'output' => '<style>.private{}</style>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.private' ],
                                'only' => ResourceLoaderModule::TYPE_COMBINED,
+                               'extra' => [],
                                'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.implement("test.private@{blankVer}",null,{"css":[]});});</script>',
                        ],
                        [
@@ -350,85 +225,98 @@ Deprecation message.' ]
                                // Eg. startup module
                                'modules' => [ 'test.scripts.raw' ],
                                'only' => ResourceLoaderModule::TYPE_SCRIPTS,
-                               'output' => '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.scripts.raw&amp;only=scripts&amp;skin=fallback"></script>',
+                               'extra' => [],
+                               'output' => '<script async="" src="/w/load.php?lang=nl&amp;modules=test.scripts.raw&amp;only=scripts&amp;skin=fallback"></script>',
                        ],
                        [
-                               'context' => [ 'sync' => true ],
+                               'context' => [],
                                'modules' => [ 'test.scripts.raw' ],
                                'only' => ResourceLoaderModule::TYPE_SCRIPTS,
-                               'output' => '<script src="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.scripts.raw&amp;only=scripts&amp;skin=fallback&amp;sync=1"></script>',
+                               'extra' => [ 'sync' => '1' ],
+                               'output' => '<script src="/w/load.php?lang=nl&amp;modules=test.scripts.raw&amp;only=scripts&amp;skin=fallback&amp;sync=1"></script>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.scripts.user' ],
                                'only' => ResourceLoaderModule::TYPE_SCRIPTS,
-                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts.user\u0026only=scripts\u0026skin=fallback\u0026user=Example\u0026version=0a56zyi");});</script>',
+                               'extra' => [],
+                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.load("/w/load.php?lang=nl\u0026modules=test.scripts.user\u0026only=scripts\u0026skin=fallback\u0026user=Example\u0026version=0a56zyi");});</script>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.user' ],
                                'only' => ResourceLoaderModule::TYPE_COMBINED,
-                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.user\u0026skin=fallback\u0026user=Example\u0026version=0a56zyi");});</script>',
+                               'extra' => [],
+                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.load("/w/load.php?lang=nl\u0026modules=test.user\u0026skin=fallback\u0026user=Example\u0026version=0a56zyi");});</script>',
                        ],
                        [
-                               'context' => [ 'debug' => true ],
+                               'context' => [ 'debug' => 'true' ],
                                'modules' => [ 'test.styles.pure', 'test.styles.mixed' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
+                               'extra' => [],
                                'output' => '<link rel="stylesheet" href="/w/load.php?debug=true&amp;lang=nl&amp;modules=test.styles.mixed&amp;only=styles&amp;skin=fallback"/>' . "\n"
                                        . '<link rel="stylesheet" href="/w/load.php?debug=true&amp;lang=nl&amp;modules=test.styles.pure&amp;only=styles&amp;skin=fallback"/>',
                        ],
                        [
-                               'context' => [ 'debug' => false ],
+                               'context' => [ 'debug' => 'false' ],
                                'modules' => [ 'test.styles.pure', 'test.styles.mixed' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
-                               'output' => '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.styles.mixed%2Cpure&amp;only=styles&amp;skin=fallback"/>',
+                               'extra' => [],
+                               'output' => '<link rel="stylesheet" href="/w/load.php?lang=nl&amp;modules=test.styles.mixed%2Cpure&amp;only=styles&amp;skin=fallback"/>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.styles.noscript' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
-                               'output' => '<noscript><link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.styles.noscript&amp;only=styles&amp;skin=fallback"/></noscript>',
+                               'extra' => [],
+                               'output' => '<noscript><link rel="stylesheet" href="/w/load.php?lang=nl&amp;modules=test.styles.noscript&amp;only=styles&amp;skin=fallback"/></noscript>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.shouldembed' ],
                                'only' => ResourceLoaderModule::TYPE_COMBINED,
+                               'extra' => [],
                                'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.implement("test.shouldembed@09p30q0",null,{"css":[]});});</script>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.styles.shouldembed' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
+                               'extra' => [],
                                'output' => '<style>.shouldembed{}</style>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.scripts.shouldembed' ],
                                'only' => ResourceLoaderModule::TYPE_SCRIPTS,
+                               'extra' => [],
                                'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.state({"test.scripts.shouldembed":"ready"});});</script>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test', 'test.shouldembed' ],
                                'only' => ResourceLoaderModule::TYPE_COMBINED,
-                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test\u0026skin=fallback");mw.loader.implement("test.shouldembed@09p30q0",null,{"css":[]});});</script>',
+                               'extra' => [],
+                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.load("/w/load.php?lang=nl\u0026modules=test\u0026skin=fallback");mw.loader.implement("test.shouldembed@09p30q0",null,{"css":[]});});</script>',
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.styles.pure', 'test.styles.shouldembed' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
+                               'extra' => [],
                                'output' =>
-                                       '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.styles.pure&amp;only=styles&amp;skin=fallback"/>' . "\n"
+                                       '<link rel="stylesheet" href="/w/load.php?lang=nl&amp;modules=test.styles.pure&amp;only=styles&amp;skin=fallback"/>' . "\n"
                                        . '<style>.shouldembed{}</style>'
                        ],
                        [
                                'context' => [],
                                'modules' => [ 'test.ordering.a', 'test.ordering.e', 'test.ordering.b', 'test.ordering.d', 'test.ordering.c' ],
                                'only' => ResourceLoaderModule::TYPE_STYLES,
+                               'extra' => [],
                                'output' =>
-                                       '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.ordering.a%2Cb&amp;only=styles&amp;skin=fallback"/>' . "\n"
+                                       '<link rel="stylesheet" href="/w/load.php?lang=nl&amp;modules=test.ordering.a%2Cb&amp;only=styles&amp;skin=fallback"/>' . "\n"
                                        . '<style>.orderingC{}.orderingD{}</style>' . "\n"
-                                       . '<link rel="stylesheet" href="/w/load.php?debug=false&amp;lang=nl&amp;modules=test.ordering.e&amp;only=styles&amp;skin=fallback"/>'
+                                       . '<link rel="stylesheet" href="/w/load.php?lang=nl&amp;modules=test.ordering.e&amp;only=styles&amp;skin=fallback"/>'
                        ],
                ];
                // phpcs:enable
@@ -436,21 +324,109 @@ Deprecation message.' ]
 
        /**
         * @dataProvider provideMakeLoad
-        * @covers ResourceLoaderClientHtml::makeLoad
-        * @covers ResourceLoaderClientHtml::makeContext
-        * @covers ResourceLoader::makeModuleResponse
+        * @covers ResourceLoaderClientHtml
         * @covers ResourceLoaderModule::getModuleContent
-        * @covers ResourceLoader::getCombinedVersion
-        * @covers ResourceLoader::createLoaderURL
-        * @covers ResourceLoader::createLoaderQuery
-        * @covers ResourceLoader::makeLoaderQuery
-        * @covers ResourceLoader::makeInlineScript
+        * @covers ResourceLoader
         */
-       public function testMakeLoad( array $extraQuery, array $modules, $type, $expected ) {
-               $context = self::makeContext( $extraQuery );
+       public function testMakeLoad(
+               array $contextQuery,
+               array $modules,
+               $type,
+               array $extraQuery,
+               $expected
+       ) {
+               $context = self::makeContext( $contextQuery );
                $context->getResourceLoader()->register( self::makeSampleModules() );
                $actual = ResourceLoaderClientHtml::makeLoad( $context, $modules, $type, $extraQuery, false );
                $expected = self::expandVariables( $expected );
-               $this->assertEquals( $expected, (string)$actual );
+               $this->assertSame( $expected, (string)$actual );
+       }
+
+       public function testGetDocumentAttributes() {
+               $client = new ResourceLoaderClientHtml( self::makeContext() );
+               $this->assertInternalType( 'array', $client->getDocumentAttributes() );
+       }
+
+       private static function expandVariables( $text ) {
+               return strtr( $text, [
+                       '{blankVer}' => ResourceLoaderTestCase::BLANK_VERSION
+               ] );
+       }
+
+       private static function makeContext( $extraQuery = [] ) {
+               $conf = new HashConfig( [
+                       'ResourceModuleSkinStyles' => [],
+                       'ResourceModules' => [],
+                       'EnableJavaScriptTest' => false,
+                       'LoadScript' => '/w/load.php',
+               ] );
+               return new ResourceLoaderContext(
+                       new ResourceLoader( $conf ),
+                       new FauxRequest( array_merge( [
+                               'lang' => 'nl',
+                               'skin' => 'fallback',
+                               'user' => 'Example',
+                               'target' => 'phpunit',
+                       ], $extraQuery ) )
+               );
+       }
+
+       private static function makeModule( array $options = [] ) {
+               return new ResourceLoaderTestModule( $options );
+       }
+
+       private static function makeSampleModules() {
+               $modules = [
+                       'test' => [],
+                       'test.private' => [ 'group' => 'private' ],
+                       'test.shouldembed.empty' => [ 'shouldEmbed' => true, 'isKnownEmpty' => true ],
+                       'test.shouldembed' => [ 'shouldEmbed' => true ],
+                       'test.user' => [ 'group' => 'user' ],
+
+                       'test.styles.pure' => [ 'type' => ResourceLoaderModule::LOAD_STYLES ],
+                       'test.styles.mixed' => [],
+                       'test.styles.noscript' => [
+                               'type' => ResourceLoaderModule::LOAD_STYLES,
+                               'group' => 'noscript',
+                       ],
+                       'test.styles.user' => [
+                               'type' => ResourceLoaderModule::LOAD_STYLES,
+                               'group' => 'user',
+                       ],
+                       'test.styles.user.empty' => [
+                               'type' => ResourceLoaderModule::LOAD_STYLES,
+                               'group' => 'user',
+                               'isKnownEmpty' => true,
+                       ],
+                       'test.styles.private' => [
+                               'type' => ResourceLoaderModule::LOAD_STYLES,
+                               'group' => 'private',
+                               'styles' => '.private{}',
+                       ],
+                       'test.styles.shouldembed' => [
+                               'type' => ResourceLoaderModule::LOAD_STYLES,
+                               'shouldEmbed' => true,
+                               'styles' => '.shouldembed{}',
+                       ],
+                       'test.styles.deprecated' => [
+                               'type' => ResourceLoaderModule::LOAD_STYLES,
+                               'deprecated' => 'Deprecation message.',
+                       ],
+
+                       'test.scripts' => [],
+                       'test.scripts.user' => [ 'group' => 'user' ],
+                       'test.scripts.user.empty' => [ 'group' => 'user', 'isKnownEmpty' => true ],
+                       'test.scripts.raw' => [ 'isRaw' => true ],
+                       'test.scripts.shouldembed' => [ 'shouldEmbed' => true ],
+
+                       'test.ordering.a' => [ 'shouldEmbed' => false ],
+                       'test.ordering.b' => [ 'shouldEmbed' => false ],
+                       'test.ordering.c' => [ 'shouldEmbed' => true, 'styles' => '.orderingC{}' ],
+                       'test.ordering.d' => [ 'shouldEmbed' => true, 'styles' => '.orderingD{}' ],
+                       'test.ordering.e' => [ 'shouldEmbed' => false ],
+               ];
+               return array_map( function ( $options ) {
+                       return self::makeModule( $options );
+               }, $modules );
        }
 }
index 1b7e0fe..5c53040 100644 (file)
@@ -2,10 +2,9 @@
 
 /**
  * See also:
- * - ResourceLoaderTest::testExpandModuleNames
  * - ResourceLoaderImageModuleTest::testContext
  *
- * @group Cache
+ * @group ResourceLoader
  * @covers ResourceLoaderContext
  */
 class ResourceLoaderContextTest extends PHPUnit\Framework\TestCase {
index 2ee85b5..d4b5ed6 100644 (file)
@@ -459,13 +459,12 @@ mw.loader.register( [
         * @covers ResourceLoader::makeLoaderRegisterScript
         */
        public function testGetModuleRegistrations( $case ) {
-               if ( isset( $case['sources'] ) ) {
-                       $this->setMwGlobals( 'wgResourceLoaderSources', $case['sources'] );
-               }
-
                $extraQuery = $case['extraQuery'] ?? [];
                $context = $this->getResourceLoaderContext( $extraQuery );
                $rl = $context->getResourceLoader();
+               if ( isset( $case['sources'] ) ) {
+                       $rl->addSource( $case['sources'] );
+               }
                $rl->register( $case['modules'] );
                $module = new ResourceLoaderStartUpModule();
                $out = ltrim( $case['out'], "\n" );
index f6bf7f1..7239afc 100644 (file)
@@ -288,12 +288,12 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
 
        /**
         * @dataProvider providePackedModules
-        * @covers ResourceLoaderContext::expandModuleNames
+        * @covers ResourceLoader::expandModuleNames
         */
        public function testExpandModuleNames( $desc, $modules, $packed, $unpacked = null ) {
                $this->assertEquals(
                        $unpacked ?: $modules,
-                       ResourceLoaderContext::expandModuleNames( $packed ),
+                       ResourceLoader::expandModuleNames( $packed ),
                        $desc
                );
        }
@@ -624,7 +624,6 @@ END
         * @covers ResourceLoader::getLoadScript
         */
        public function testGetLoadScript() {
-               $this->setMwGlobals( 'wgResourceLoaderSources', [] );
                $rl = new ResourceLoader();
                $sources = self::fakeSources();
                $rl->addSource( $sources );
@@ -767,11 +766,11 @@ END
                }, $scripts );
                $rl->register( $modules );
 
-               $this->setMwGlobals( 'wgResourceLoaderDebug', $debug );
                $context = $this->getResourceLoaderContext(
                        [
                                'modules' => implode( '|', array_keys( $modules ) ),
                                'only' => 'scripts',
+                               'debug' => $debug ? 'true' : 'false',
                        ],
                        $rl
                );
index d86e63d..0c6520e 100644 (file)
@@ -271,7 +271,7 @@ class SearchEngineTest extends MediaWikiLangTestCase {
         */
        public function testSearchIndexFields() {
                /**
-                * @var $mockEngine SearchEngine
+                * @var SearchEngine $mockEngine
                 */
                $mockEngine = $this->getMockBuilder( SearchEngine::class )
                        ->setMethods( [ 'makeSearchFieldMapping' ] )->getMock();
index 052c016..6ff6a97 100644 (file)
@@ -134,7 +134,7 @@ class SessionProviderTest extends MediaWikiTestCase {
                        $this->fail( 'Expected exception not thrown' );
                } catch ( \BadMethodCallException $ex ) {
                        $this->assertSame(
-                               'MediaWiki\\Session\\SessionProvider::preventSessionsForUser must be implmented ' .
+                               'MediaWiki\\Session\\SessionProvider::preventSessionsForUser must be implemented ' .
                                        'when canChangeUser() is false',
                                $ex->getMessage()
                        );
index ef8fb4e..1d87c90 100644 (file)
@@ -85,11 +85,6 @@ class TestUtils {
         */
        public static function getDummySession( $backend = null, $index = -1, $logger = null ) {
                $rc = new \ReflectionClass( Session::class );
-               if ( !method_exists( $rc, 'newInstanceWithoutConstructor' ) ) {
-                       \PHPUnit_Framework_Assert::markTestSkipped(
-                               'ReflectionClass::newInstanceWithoutConstructor isn\'t available'
-                       );
-               }
 
                if ( $backend === null ) {
                        $backend = new DummySessionBackend;
diff --git a/tests/phpunit/includes/site/FileBasedSiteLookupTest.php b/tests/phpunit/includes/site/FileBasedSiteLookupTest.php
deleted file mode 100644 (file)
index 69e0e38..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.25
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @covers FileBasedSiteLookup
- * @group Site
- *
- * @author Katie Filbert < aude.wiki@gmail.com >
- */
-class FileBasedSiteLookupTest extends PHPUnit\Framework\TestCase {
-
-       use MediaWikiCoversValidator;
-
-       protected function setUp() {
-               $this->cacheFile = $this->getCacheFile();
-       }
-
-       protected function tearDown() {
-               unlink( $this->cacheFile );
-       }
-
-       public function testGetSites() {
-               $sites = $this->getSites();
-               $cacheBuilder = $this->newSitesCacheFileBuilder( $sites );
-               $cacheBuilder->build();
-
-               $cache = new FileBasedSiteLookup( $this->cacheFile );
-               $this->assertEquals( $sites, $cache->getSites() );
-       }
-
-       public function testGetSite() {
-               $sites = $this->getSites();
-               $cacheBuilder = $this->newSitesCacheFileBuilder( $sites );
-               $cacheBuilder->build();
-
-               $cache = new FileBasedSiteLookup( $this->cacheFile );
-
-               $this->assertEquals( $sites->getSite( 'enwiktionary' ), $cache->getSite( 'enwiktionary' ) );
-       }
-
-       private function newSitesCacheFileBuilder( SiteList $sites ) {
-               return new SitesCacheFileBuilder(
-                       $this->getSiteLookup( $sites ),
-                       $this->cacheFile
-               );
-       }
-
-       private function getSiteLookup( SiteList $sites ) {
-               $siteLookup = $this->getMockBuilder( SiteLookup::class )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-
-               $siteLookup->expects( $this->any() )
-                       ->method( 'getSites' )
-                       ->will( $this->returnValue( $sites ) );
-
-               return $siteLookup;
-       }
-
-       private function getSites() {
-               $sites = [];
-
-               $site = new Site();
-               $site->setGlobalId( 'foobar' );
-               $sites[] = $site;
-
-               $site = new MediaWikiSite();
-               $site->setGlobalId( 'enwiktionary' );
-               $site->setGroup( 'wiktionary' );
-               $site->setLanguageCode( 'en' );
-               $site->addNavigationId( 'enwiktionary' );
-               $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" );
-               $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" );
-               $sites[] = $site;
-
-               return new SiteList( $sites );
-       }
-
-       private function getCacheFile() {
-               return tempnam( sys_get_temp_dir(), 'mw-test-sitelist' );
-       }
-
-}
diff --git a/tests/phpunit/includes/site/SitesCacheFileBuilderTest.php b/tests/phpunit/includes/site/SitesCacheFileBuilderTest.php
deleted file mode 100644 (file)
index 8c84ce5..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.25
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @covers SitesCacheFileBuilder
- * @group Site
- *
- * @author Katie Filbert < aude.wiki@gmail.com >
- */
-class SitesCacheFileBuilderTest extends PHPUnit\Framework\TestCase {
-
-       use MediaWikiCoversValidator;
-
-       protected function setUp() {
-               $this->cacheFile = $this->getCacheFile();
-       }
-
-       protected function tearDown() {
-               unlink( $this->cacheFile );
-       }
-
-       public function testBuild() {
-               $cacheBuilder = $this->newSitesCacheFileBuilder( $this->getSites() );
-               $cacheBuilder->build();
-
-               $contents = file_get_contents( $this->cacheFile );
-               $this->assertEquals( json_encode( $this->getExpectedData() ), $contents );
-       }
-
-       private function getExpectedData() {
-               return [
-                       'sites' => [
-                               'foobar' => [
-                                       'globalid' => 'foobar',
-                                       'type' => 'unknown',
-                                       'group' => 'none',
-                                       'source' => 'local',
-                                       'language' => null,
-                                       'localids' => [],
-                                       'config' => [],
-                                       'data' => [],
-                                       'forward' => false,
-                                       'internalid' => null,
-                                       'identifiers' => []
-                               ],
-                               'enwiktionary' => [
-                                       'globalid' => 'enwiktionary',
-                                       'type' => 'mediawiki',
-                                       'group' => 'wiktionary',
-                                       'source' => 'local',
-                                       'language' => 'en',
-                                       'localids' => [
-                                               'equivalent' => [ 'enwiktionary' ]
-                                       ],
-                                       'config' => [],
-                                       'data' => [
-                                               'paths' => [
-                                                       'page_path' => 'https://en.wiktionary.org/wiki/$1',
-                                                       'file_path' => 'https://en.wiktionary.org/w/$1'
-                                               ]
-                                       ],
-                                       'forward' => false,
-                                       'internalid' => null,
-                                       'identifiers' => [
-                                               [
-                                                       'type' => 'equivalent',
-                                                       'key' => 'enwiktionary'
-                                               ]
-                                       ]
-                               ]
-                       ]
-               ];
-       }
-
-       private function newSitesCacheFileBuilder( SiteList $sites ) {
-               return new SitesCacheFileBuilder(
-                       $this->getSiteLookup( $sites ),
-                       $this->cacheFile
-               );
-       }
-
-       private function getSiteLookup( SiteList $sites ) {
-               $siteLookup = $this->getMockBuilder( SiteLookup::class )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-
-               $siteLookup->expects( $this->any() )
-                       ->method( 'getSites' )
-                       ->will( $this->returnValue( $sites ) );
-
-               return $siteLookup;
-       }
-
-       private function getSites() {
-               $sites = [];
-
-               $site = new Site();
-               $site->setGlobalId( 'foobar' );
-               $sites[] = $site;
-
-               $site = new MediaWikiSite();
-               $site->setGlobalId( 'enwiktionary' );
-               $site->setGroup( 'wiktionary' );
-               $site->setLanguageCode( 'en' );
-               $site->addNavigationId( 'enwiktionary' );
-               $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" );
-               $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" );
-               $sites[] = $site;
-
-               return new SiteList( $sites );
-       }
-
-       private function getCacheFile() {
-               return tempnam( sys_get_temp_dir(), 'mw-test-sitelist' );
-       }
-
-}
index 584b141..2ce097b 100644 (file)
@@ -613,8 +613,7 @@ class ChangesListSpecialPageTest extends AbstractChangesListSpecialPageTestCase
                                'Learner1', 'Learner2', 'Learner3', 'Learner4',
                                'Experienced1',
                        ],
-                       $this->fetchUsers( [ 'learner', 'experienced' ], $now ),
-                       'Learner and more experienced'
+                       $this->fetchUsers( [ 'learner', 'experienced' ], $now )
                );
        }
 
diff --git a/tests/phpunit/includes/specialpage/FormSpecialPageTestCase.php b/tests/phpunit/includes/specialpage/FormSpecialPageTestCase.php
new file mode 100644 (file)
index 0000000..a3b5adb
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Factory for handling the special page list and generating SpecialPage objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @group SpecialPage
+ */
+abstract class FormSpecialPageTestCase extends SpecialPageTestBase {
+
+       /**
+        * @covers FormSpecialPage::checkExecutePermissions
+        */
+       public function testCheckExecutePermissionsSitewideBlock() {
+               $special = $this->newSpecialPage();
+               $checkExecutePermissions = $this->getMethod( $special, 'checkExecutePermissions' );
+
+               $user = clone $this->getTestUser()->getUser();
+               $user->mBlockedby = $user->getName();
+               $user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $user->getId(),
+                       'reason' => 'sitewide block',
+                       'timestamp' => time(),
+                       'sitewide' => true,
+                       'expiry' => 10,
+               ] );
+
+               $this->expectException( UserBlockedError::class );
+               $checkExecutePermissions( $user );
+       }
+
+       /**
+        * @covers FormSpecialPage::checkExecutePermissions
+        */
+       public function testCheckExecutePermissionsPartialBlock() {
+               $special = $this->newSpecialPage();
+               $checkExecutePermissions = $this->getMethod( $special, 'checkExecutePermissions' );
+
+               $user = clone $this->getTestUser()->getUser();
+               $user->mBlockedby = $user->getName();
+               $user->mBlock = new Block( [
+                       'address' => '127.0.8.1',
+                       'by' => $user->getId(),
+                       'reason' => 'partial block',
+                       'timestamp' => time(),
+                       'sitewide' => false,
+                       'expiry' => 10,
+               ] );
+
+               $this->assertNull( $checkExecutePermissions( $user ) );
+       }
+
+       /**
+        * Get a protected/private method.
+        *
+        * @param object $obj
+        * @param string $name
+        * @return callable
+        */
+       protected function getMethod( $obj, $name ) {
+               $method = new ReflectionMethod( $obj, $name );
+               $method->setAccessible( true );
+               return $method->getClosure( $obj );
+       }
+}
index 2eddb01..ec4bf0f 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\TestingAccessWrapper;
+
 /**
  * @covers SpecialPage
  *
@@ -101,4 +103,82 @@ class SpecialPageTest extends MediaWikiTestCase {
                $this->assertTrue( true );
        }
 
+       public function provideBuildPrevNextNavigation() {
+               yield [ 0, 20, false, false ];
+               yield [ 17, 20, false, false ];
+               yield [ 0, 17, false, false ];
+               yield [ 0, 20, true, 'Foo' ];
+               yield [ 17, 20, true, 'Föö_Bär' ];
+       }
+
+       /**
+        * @dataProvider provideBuildPrevNextNavigation
+        */
+       public function testBuildPrevNextNavigation( $offset, $limit, $atEnd, $subPage ) {
+               $this->setUserLang( Language::factory( 'qqx' ) ); // disable i18n
+
+               $specialPage = new SpecialPage( 'Watchlist' );
+               $specialPage = TestingAccessWrapper::newFromObject( $specialPage );
+
+               $html = $specialPage->buildPrevNextNavigation(
+                       $offset,
+                       $limit,
+                       [ 'x' => 25 ],
+                       $atEnd,
+                       $subPage
+               );
+
+               $this->assertStringStartsWith( '(viewprevnext:', $html );
+
+               preg_match_all( '!<a.*?</a>!', $html, $m, PREG_PATTERN_ORDER );
+               $links = $m[0];
+
+               foreach ( $links as $a ) {
+                       if ( $subPage ) {
+                               $this->assertContains( 'Special:Watchlist/' . wfUrlencode( $subPage ), $a );
+                       } else {
+                               $this->assertContains( 'Special:Watchlist', $a );
+                               $this->assertNotContains( 'Special:Watchlist/', $a );
+                       }
+                       $this->assertContains( 'x=25', $a );
+               }
+
+               $i = 0;
+
+               if ( $offset > 0 ) {
+                       $this->assertContains(
+                               'limit=' . $limit . '&amp;offset=' . max( 0, $offset - $limit ) . '&amp;',
+                               $links[ $i ]
+                       );
+                       $this->assertContains( 'title="(prevn-title: ' . $limit . ')"', $links[$i] );
+                       $this->assertContains( 'class="mw-prevlink"', $links[$i] );
+                       $this->assertContains( '>(prevn: ' . $limit . ')<', $links[$i] );
+                       $i += 1;
+               }
+
+               if ( !$atEnd ) {
+                       $this->assertContains(
+                               'limit=' . $limit . '&amp;offset=' . ( $offset + $limit ) . '&amp;',
+                               $links[ $i ]
+                       );
+                       $this->assertContains( 'title="(nextn-title: ' . $limit . ')"', $links[$i] );
+                       $this->assertContains( 'class="mw-nextlink"', $links[$i] );
+                       $this->assertContains( '>(nextn: ' . $limit . ')<', $links[$i] );
+                       $i += 1;
+               }
+
+               $this->assertCount( 5 + $i, $links );
+
+               $this->assertContains( 'limit=20&amp;offset=' . $offset, $links[$i] );
+               $this->assertContains( 'title="(shown-title: 20)"', $links[$i] );
+               $this->assertContains( 'class="mw-numlink"', $links[$i] );
+               $this->assertContains( '>20<', $links[$i] );
+               $i += 4;
+
+               $this->assertContains( 'limit=500&amp;offset=' . $offset, $links[$i] );
+               $this->assertContains( 'title="(shown-title: 500)"', $links[$i] );
+               $this->assertContains( 'class="mw-numlink"', $links[$i] );
+               $this->assertContains( '>500<', $links[$i] );
+       }
+
 }
index 4a171df..58f83de 100644 (file)
@@ -42,8 +42,7 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
                parent::__construct();
 
                foreach ( QueryPage::getPages() as $page ) {
-                       $class = $page[0];
-                       $name = $page[1];
+                       list( $class, $name ) = $page;
                        if ( !in_array( $class, $this->manualTest ) ) {
                                $this->queryPages[$class] =
                                        MediaWikiServices::getInstance()->getSpecialPageFactory()->getPage( $name );
index 8c8e270..182ca0d 100644 (file)
@@ -12,7 +12,7 @@ use Wikimedia\TestingAccessWrapper;
  */
 class SpecialBlockTest extends SpecialPageTestBase {
        /**
-        * {@inheritdoc}
+        * @inheritDoc
         */
        protected function newSpecialPage() {
                return new SpecialBlock();
@@ -91,7 +91,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertSame( $block->isCreateAccountBlocked(), $fields['CreateAccount']['default'] );
                $this->assertSame( $block->isAutoblocking(), $fields['AutoBlock']['default'] );
                $this->assertSame( !$block->isUsertalkEditAllowed(), $fields['DisableUTEdit']['default'] );
-               $this->assertSame( $block->mReason, $fields['Reason']['default'] );
+               $this->assertSame( $block->getReason(), $fields['Reason']['default'] );
                $this->assertSame( 'infinite', $fields['Expiry']['default'] );
        }
 
@@ -179,7 +179,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertTrue( $result );
 
                $block = Block::newFromTarget( $badActor );
-               $this->assertSame( $reason, $block->mReason );
+               $this->assertSame( $reason, $block->getReason() );
                $this->assertSame( $expiry, $block->getExpiry() );
        }
 
@@ -228,7 +228,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertTrue( $result );
 
                $block = Block::newFromTarget( $badActor );
-               $this->assertSame( $reason, $block->mReason );
+               $this->assertSame( $reason, $block->getReason() );
                $this->assertSame( $expiry, $block->getExpiry() );
                $this->assertSame( '1', $block->isAutoblocking() );
        }
@@ -277,7 +277,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertTrue( $result );
 
                $block = Block::newFromTarget( $badActor );
-               $this->assertSame( $reason, $block->mReason );
+               $this->assertSame( $reason, $block->getReason() );
                $this->assertSame( $expiry, $block->getExpiry() );
                $this->assertCount( 2, $block->getRestrictions() );
                $this->assertTrue( BlockRestriction::equals( $block->getRestrictions(), [
@@ -331,7 +331,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertTrue( $result );
 
                $block = Block::newFromTarget( $badActor );
-               $this->assertSame( $reason, $block->mReason );
+               $this->assertSame( $reason, $block->getReason() );
                $this->assertSame( $expiry, $block->getExpiry() );
                $this->assertFalse( $block->isSitewide() );
                $this->assertCount( 2, $block->getRestrictions() );
@@ -347,7 +347,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertTrue( $result );
 
                $block = Block::newFromTarget( $badActor );
-               $this->assertSame( $reason, $block->mReason );
+               $this->assertSame( $reason, $block->getReason() );
                $this->assertSame( $expiry, $block->getExpiry() );
                $this->assertFalse( $block->isSitewide() );
                $this->assertCount( 1, $block->getRestrictions() );
@@ -362,7 +362,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertTrue( $result );
 
                $block = Block::newFromTarget( $badActor );
-               $this->assertSame( $reason, $block->mReason );
+               $this->assertSame( $reason, $block->getReason() );
                $this->assertSame( $expiry, $block->getExpiry() );
                $this->assertFalse( $block->isSitewide() );
                $this->assertCount( 0, $block->getRestrictions() );
@@ -374,7 +374,7 @@ class SpecialBlockTest extends SpecialPageTestBase {
                $this->assertTrue( $result );
 
                $block = Block::newFromTarget( $badActor );
-               $this->assertSame( $reason, $block->mReason );
+               $this->assertSame( $reason, $block->getReason() );
                $this->assertSame( $expiry, $block->getExpiry() );
                $this->assertTrue( $block->isSitewide() );
                $this->assertCount( 0, $block->getRestrictions() );
diff --git a/tests/phpunit/includes/specials/SpecialPasswordResetTest.php b/tests/phpunit/includes/specials/SpecialPasswordResetTest.php
new file mode 100644 (file)
index 0000000..273b428
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+
+class SpecialPasswordResetTest extends FormSpecialPageTestCase {
+       /**
+        * {@inheritdoc}
+        */
+       protected function newSpecialPage() {
+               return new SpecialPasswordReset();
+       }
+}
index 28e26a0..642ae3e 100644 (file)
@@ -59,7 +59,44 @@ class SpecialWatchlistTest extends SpecialPageTestBase {
        /**
         * @dataProvider provideFetchOptionsFromRequest
         */
-       public function testFetchOptionsFromRequest( $expectedValues, $preferences, $inputParams ) {
+       public function testFetchOptionsFromRequest(
+               $expectedValuesDefaults, $expectedValues, $preferences, $inputParams
+       ) {
+               // $defaults and $allFalse are just to make the expected values below
+               // shorter by hiding the background.
+
+               $page = TestingAccessWrapper::newFromObject(
+                       $this->newSpecialPage()
+               );
+
+               $page->registerFilters();
+
+               // Does not consider $preferences, just wiki's defaults
+               $wikiDefaults = $page->getDefaultOptions()->getAllValues();
+
+               switch ( $expectedValuesDefaults ) {
+               case 'allFalse':
+                       $allFalse = $wikiDefaults;
+
+                       foreach ( $allFalse as $key => $value ) {
+                               if ( $value === true ) {
+                                       $allFalse[$key] = false;
+                               }
+                       }
+
+                       // This is not exposed on the form (only in preferences) so it
+                       // respects the preference.
+                       $allFalse['extended'] = true;
+
+                       $expectedValues += $allFalse;
+                       break;
+               case 'wikiDefaults':
+                       $expectedValues += $wikiDefaults;
+                       break;
+               default:
+                       $this->fail( "Unknown \$expectedValuesDefaults: $expectedValuesDefaults" );
+               }
+
                $page = TestingAccessWrapper::newFromObject(
                        $this->newSpecialPage()
                );
@@ -90,43 +127,21 @@ class SpecialWatchlistTest extends SpecialPageTestBase {
        }
 
        public function provideFetchOptionsFromRequest() {
-               // $defaults and $allFalse are just to make the expected values below
-               // shorter by hiding the background.
-
-               $page = TestingAccessWrapper::newFromObject(
-                       $this->newSpecialPage()
-               );
-
-               $page->registerFilters();
-
-               // Does not consider $preferences, just wiki's defaults
-               $wikiDefaults = $page->getDefaultOptions()->getAllValues();
-
-               $allFalse = $wikiDefaults;
-
-               foreach ( $allFalse as $key => &$value ) {
-                       if ( $value === true ) {
-                               $value = false;
-                       }
-               }
-
-               // This is not exposed on the form (only in preferences) so it
-               // respects the preference.
-               $allFalse['extended'] = true;
-
                return [
-                       [
-                               [
+                       'ignores casing' => [
+                               'expectedValuesDefaults' => 'wikiDefaults',
+                               'expectedValues' => [
                                        'hideminor' => true,
-                               ] + $wikiDefaults,
-                               [],
-                               [
+                               ],
+                               'preferences' => [],
+                               'inputParams' => [
                                        'hideMinor' => 1,
                                ],
                        ],
 
-                       [
-                               [
+                       'first two same as prefs, second two overriden' => [
+                               'expectedValuesDefaults' => 'wikiDefaults',
+                               'expectedValues' => [
                                        // First two same as prefs
                                        'hideminor' => true,
                                        'hidebots' => false,
@@ -135,38 +150,38 @@ class SpecialWatchlistTest extends SpecialPageTestBase {
                                        'hideanons' => false,
                                        'hideliu' => true,
                                        'userExpLevel' => 'registered'
-                               ] + $wikiDefaults,
-                               [
+                               ],
+                               'preferences' => [
                                        'watchlisthideminor' => 1,
                                        'watchlisthidebots' => 0,
 
                                        'watchlisthideanons' => 1,
                                        'watchlisthideliu' => 0,
                                ],
-                               [
+                               'inputParams' => [
                                        'hideanons' => 0,
                                        'hideliu' => 1,
                                ],
                        ],
 
-                       // Defaults/preferences for form elements are entirely ignored for
-                       // action=submit and omitted elements become false
-                       [
-                               [
+                       'Defaults/preferences for form elements are entirely ignored for '
+                       . 'action=submit and omitted elements become false' => [
+                               'expectedValuesDefaults' => 'allFalse',
+                               'expectedValues' => [
                                        'hideminor' => false,
                                        'hidebots' => true,
                                        'hideanons' => false,
                                        'hideliu' => true,
                                        'userExpLevel' => 'unregistered'
-                               ] + $allFalse,
-                               [
+                               ],
+                               'preferences' => [
                                        'watchlisthideminor' => 0,
                                        'watchlisthidebots' => 1,
 
                                        'watchlisthideanons' => 0,
                                        'watchlisthideliu' => 1,
                                ],
-                               [
+                               'inputParams' => [
                                        'hidebots' => 1,
                                        'hideliu' => 1,
                                        'action' => 'submit',
index 1810ef8..bd37c04 100644 (file)
@@ -16,13 +16,18 @@ class BlockListPagerTest extends MediaWikiTestCase {
         * @dataProvider formatValueEmptyProvider
         * @dataProvider formatValueDefaultProvider
         * @param string $name
-        * @param string $value
         * @param string $expected
         */
-       public function testFormatValue( $name, $value, $expected, $row = null ) {
+       public function testFormatValue( $name, $expected = null, $row = null ) {
                $this->setMwGlobals( [
                        'wgEnablePartialBlocks' => false,
                ] );
+               // Set the time to now so it does not get off during the test.
+               MWTimestamp::setFakeTime( MWTimestamp::time() );
+
+               $value = $name === 'ipb_timestamp' ? MWTimestamp::time() : '';
+               $expected = $expected ?? MWTimestamp::getInstance()->format( 'H:i, j F Y' );
+
                $row = $row ?: new stdClass;
                $pager = new BlockListPager( new SpecialPage(),  [] );
                $wrappedPager = TestingAccessWrapper::newFromObject( $pager );
@@ -30,6 +35,9 @@ class BlockListPagerTest extends MediaWikiTestCase {
 
                $formatted = $pager->formatValue( $name, $value );
                $this->assertEquals( $expected, $formatted );
+
+               // Reset the time.
+               MWTimestamp::setFakeTime( false );
        }
 
        /**
@@ -39,17 +47,13 @@ class BlockListPagerTest extends MediaWikiTestCase {
                return [
                        [
                                'test',
-                               '',
                                'Unable to format test',
                        ],
                        [
                                'ipb_timestamp',
-                               wfTimestamp( TS_UNIX ),
-                               date( 'H:i, j F Y' ),
                        ],
                        [
                                'ipb_expiry',
-                               '',
                                'infinite<br />0 minutes left',
                        ],
                ];
@@ -77,31 +81,26 @@ class BlockListPagerTest extends MediaWikiTestCase {
                return [
                        [
                                'test',
-                               '',
                                'Unable to format test',
                                $row,
                        ],
                        [
                                'ipb_timestamp',
-                               wfTimestamp( TS_UNIX ),
-                               date( 'H:i, j F Y' ),
+                               null,
                                $row,
                        ],
                        [
                                'ipb_expiry',
-                               '',
                                'infinite<br />0 minutes left',
                                $row,
                        ],
                        [
                                'ipb_by',
-                               '',
                                $row->ipb_by_text,
                                $row,
                        ],
                        [
                                'ipb_params',
-                               '',
                                '<ul><li>account creation disabled</li><li>cannot edit own talk page</li></ul>',
                                $row,
                        ]
index e576ea8..5ad8416 100644 (file)
@@ -2,7 +2,6 @@
 
 class RemexDriverTest extends MediaWikiTestCase {
        private static $remexTidyTestData = [
-               // Tests from Html5Depurate
                [
                        'Empty string',
                        "",
diff --git a/tests/phpunit/includes/title/NamespaceInfoTest.php b/tests/phpunit/includes/title/NamespaceInfoTest.php
new file mode 100644 (file)
index 0000000..cc7df8d
--- /dev/null
@@ -0,0 +1,613 @@
+<?php
+/**
+ * @author Antoine Musso
+ * @copyright Copyright © 2011, Antoine Musso
+ * @file
+ */
+
+use MediaWiki\MediaWikiServices;
+
+class NamespaceInfoTest extends MediaWikiTestCase {
+
+       /** @var NamespaceInfo */
+       private $obj;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( [
+                       'wgContentNamespaces' => [ NS_MAIN ],
+                       'wgNamespacesWithSubpages' => [
+                               NS_TALK => true,
+                               NS_USER => true,
+                               NS_USER_TALK => true,
+                       ],
+                       'wgCapitalLinks' => true,
+                       'wgCapitalLinkOverrides' => [],
+                       'wgNonincludableNamespaces' => [],
+               ] );
+
+               $this->obj = MediaWikiServices::getInstance()->getNamespaceInfo();
+       }
+
+       /**
+        * @todo Write more texts, handle $wgAllowImageMoving setting
+        * @covers NamespaceInfo::isMovable
+        */
+       public function testIsMovable() {
+               $this->assertFalse( $this->obj->isMovable( NS_SPECIAL ) );
+       }
+
+       private function assertIsSubject( $ns ) {
+               $this->assertTrue( $this->obj->isSubject( $ns ) );
+       }
+
+       private function assertIsNotSubject( $ns ) {
+               $this->assertFalse( $this->obj->isSubject( $ns ) );
+       }
+
+       /**
+        * Please make sure to change testIsTalk() if you change the assertions below
+        * @covers NamespaceInfo::isSubject
+        */
+       public function testIsSubject() {
+               // Special namespaces
+               $this->assertIsSubject( NS_MEDIA );
+               $this->assertIsSubject( NS_SPECIAL );
+
+               // Subject pages
+               $this->assertIsSubject( NS_MAIN );
+               $this->assertIsSubject( NS_USER );
+               $this->assertIsSubject( 100 ); # user defined
+
+               // Talk pages
+               $this->assertIsNotSubject( NS_TALK );
+               $this->assertIsNotSubject( NS_USER_TALK );
+               $this->assertIsNotSubject( 101 ); # user defined
+       }
+
+       private function assertIsTalk( $ns ) {
+               $this->assertTrue( $this->obj->isTalk( $ns ) );
+       }
+
+       private function assertIsNotTalk( $ns ) {
+               $this->assertFalse( $this->obj->isTalk( $ns ) );
+       }
+
+       /**
+        * Reverse of testIsSubject().
+        * Please update testIsSubject() if you change assertions below
+        * @covers NamespaceInfo::isTalk
+        */
+       public function testIsTalk() {
+               // Special namespaces
+               $this->assertIsNotTalk( NS_MEDIA );
+               $this->assertIsNotTalk( NS_SPECIAL );
+
+               // Subject pages
+               $this->assertIsNotTalk( NS_MAIN );
+               $this->assertIsNotTalk( NS_USER );
+               $this->assertIsNotTalk( 100 ); # user defined
+
+               // Talk pages
+               $this->assertIsTalk( NS_TALK );
+               $this->assertIsTalk( NS_USER_TALK );
+               $this->assertIsTalk( 101 ); # user defined
+       }
+
+       /**
+        * @covers NamespaceInfo::getSubject
+        */
+       public function testGetSubject() {
+               // Special namespaces are their own subjects
+               $this->assertEquals( NS_MEDIA, $this->obj->getSubject( NS_MEDIA ) );
+               $this->assertEquals( NS_SPECIAL, $this->obj->getSubject( NS_SPECIAL ) );
+
+               $this->assertEquals( NS_MAIN, $this->obj->getSubject( NS_TALK ) );
+               $this->assertEquals( NS_USER, $this->obj->getSubject( NS_USER_TALK ) );
+       }
+
+       /**
+        * Regular getTalk() calls
+        * Namespaces without a talk page (NS_MEDIA, NS_SPECIAL) are tested in
+        * the function testGetTalkExceptions()
+        * @covers NamespaceInfo::getTalk
+        */
+       public function testGetTalk() {
+               $this->assertEquals( NS_TALK, $this->obj->getTalk( NS_MAIN ) );
+               $this->assertEquals( NS_TALK, $this->obj->getTalk( NS_TALK ) );
+               $this->assertEquals( NS_USER_TALK, $this->obj->getTalk( NS_USER ) );
+               $this->assertEquals( NS_USER_TALK, $this->obj->getTalk( NS_USER_TALK ) );
+       }
+
+       /**
+        * Exceptions with getTalk()
+        * NS_MEDIA does not have talk pages. MediaWiki raise an exception for them.
+        * @expectedException MWException
+        * @covers NamespaceInfo::getTalk
+        */
+       public function testGetTalkExceptionsForNsMedia() {
+               $this->assertNull( $this->obj->getTalk( NS_MEDIA ) );
+       }
+
+       /**
+        * Exceptions with getTalk()
+        * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them.
+        * @expectedException MWException
+        * @covers NamespaceInfo::getTalk
+        */
+       public function testGetTalkExceptionsForNsSpecial() {
+               $this->assertNull( $this->obj->getTalk( NS_SPECIAL ) );
+       }
+
+       /**
+        * Regular getAssociated() calls
+        * Namespaces without an associated page (NS_MEDIA, NS_SPECIAL) are tested in
+        * the function testGetAssociatedExceptions()
+        * @covers NamespaceInfo::getAssociated
+        */
+       public function testGetAssociated() {
+               $this->assertEquals( NS_TALK, $this->obj->getAssociated( NS_MAIN ) );
+               $this->assertEquals( NS_MAIN, $this->obj->getAssociated( NS_TALK ) );
+       }
+
+       # ## Exceptions with getAssociated()
+       # ## NS_MEDIA and NS_SPECIAL do not have talk pages. MediaWiki raises
+       # ## an exception for them.
+       /**
+        * @expectedException MWException
+        * @covers NamespaceInfo::getAssociated
+        */
+       public function testGetAssociatedExceptionsForNsMedia() {
+               $this->assertNull( $this->obj->getAssociated( NS_MEDIA ) );
+       }
+
+       /**
+        * @expectedException MWException
+        * @covers NamespaceInfo::getAssociated
+        */
+       public function testGetAssociatedExceptionsForNsSpecial() {
+               $this->assertNull( $this->obj->getAssociated( NS_SPECIAL ) );
+       }
+
+       /**
+        * Note if we add a namespace registration system with keys like 'MAIN'
+        * we should add tests here for equivilance on things like 'MAIN' == 0
+        * and 'MAIN' == NS_MAIN.
+        * @covers NamespaceInfo::equals
+        */
+       public function testEquals() {
+               $this->assertTrue( $this->obj->equals( NS_MAIN, NS_MAIN ) );
+               $this->assertTrue( $this->obj->equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN'
+               $this->assertTrue( $this->obj->equals( NS_USER, NS_USER ) );
+               $this->assertTrue( $this->obj->equals( NS_USER, 2 ) );
+               $this->assertTrue( $this->obj->equals( NS_USER_TALK, NS_USER_TALK ) );
+               $this->assertTrue( $this->obj->equals( NS_SPECIAL, NS_SPECIAL ) );
+               $this->assertFalse( $this->obj->equals( NS_MAIN, NS_TALK ) );
+               $this->assertFalse( $this->obj->equals( NS_USER, NS_USER_TALK ) );
+               $this->assertFalse( $this->obj->equals( NS_PROJECT, NS_TEMPLATE ) );
+       }
+
+       /**
+        * @covers NamespaceInfo::subjectEquals
+        */
+       public function testSubjectEquals() {
+               $this->assertSameSubject( NS_MAIN, NS_MAIN );
+               $this->assertSameSubject( NS_MAIN, 0 ); // In case we make NS_MAIN 'MAIN'
+               $this->assertSameSubject( NS_USER, NS_USER );
+               $this->assertSameSubject( NS_USER, 2 );
+               $this->assertSameSubject( NS_USER_TALK, NS_USER_TALK );
+               $this->assertSameSubject( NS_SPECIAL, NS_SPECIAL );
+               $this->assertSameSubject( NS_MAIN, NS_TALK );
+               $this->assertSameSubject( NS_USER, NS_USER_TALK );
+
+               $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE );
+               $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN );
+       }
+
+       /**
+        * @covers NamespaceInfo::subjectEquals
+        */
+       public function testSpecialAndMediaAreDifferentSubjects() {
+               $this->assertDifferentSubject(
+                       NS_MEDIA, NS_SPECIAL,
+                       "NS_MEDIA and NS_SPECIAL are different subject namespaces"
+               );
+               $this->assertDifferentSubject(
+                       NS_SPECIAL, NS_MEDIA,
+                       "NS_SPECIAL and NS_MEDIA are different subject namespaces"
+               );
+       }
+
+       public function provideHasTalkNamespace() {
+               return [
+                       [ NS_MEDIA, false ],
+                       [ NS_SPECIAL, false ],
+
+                       [ NS_MAIN, true ],
+                       [ NS_TALK, true ],
+                       [ NS_USER, true ],
+                       [ NS_USER_TALK, true ],
+
+                       [ 100, true ],
+                       [ 101, true ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideHasTalkNamespace
+        * @covers NamespaceInfo::hasTalkNamespace
+        *
+        * @param int $index
+        * @param bool $expected
+        */
+       public function testHasTalkNamespace( $index, $expected ) {
+               $actual = $this->obj->hasTalkNamespace( $index );
+               $this->assertSame( $actual, $expected, "NS $index" );
+       }
+
+       /**
+        * @dataProvider provideHasTalkNamespace
+        * @covers MWNamespace::canTalk
+        *
+        * @param int $index
+        * @param bool $expected
+        */
+       public function testCanTalk( $index, $expected ) {
+               $this->hideDeprecated( 'MWNamespace::canTalk' );
+               $actual = MWNamespace::canTalk( $index );
+               $this->assertSame( $actual, $expected, "NS $index" );
+       }
+
+       private function assertIsContent( $ns ) {
+               $this->assertTrue( $this->obj->isContent( $ns ) );
+       }
+
+       private function assertIsNotContent( $ns ) {
+               $this->assertFalse( $this->obj->isContent( $ns ) );
+       }
+
+       /**
+        * @covers NamespaceInfo::isContent
+        */
+       public function testIsContent() {
+               // NS_MAIN is a content namespace per DefaultSettings.php
+               // and per function definition.
+
+               $this->assertIsContent( NS_MAIN );
+
+               // Other namespaces which are not expected to be content
+
+               $this->assertIsNotContent( NS_MEDIA );
+               $this->assertIsNotContent( NS_SPECIAL );
+               $this->assertIsNotContent( NS_TALK );
+               $this->assertIsNotContent( NS_USER );
+               $this->assertIsNotContent( NS_CATEGORY );
+               $this->assertIsNotContent( 100 );
+       }
+
+       /**
+        * Similar to testIsContent() but alters the $wgContentNamespaces
+        * global variable.
+        * @covers NamespaceInfo::isContent
+        */
+       public function testIsContentAdvanced() {
+               global $wgContentNamespaces;
+
+               // Test that user defined namespace #252 is not content
+               $this->assertIsNotContent( 252 );
+
+               // Bless namespace # 252 as a content namespace
+               $wgContentNamespaces[] = 252;
+
+               $this->assertIsContent( 252 );
+
+               // Makes sure NS_MAIN was not impacted
+               $this->assertIsContent( NS_MAIN );
+       }
+
+       private function assertIsWatchable( $ns ) {
+               $this->assertTrue( $this->obj->isWatchable( $ns ) );
+       }
+
+       private function assertIsNotWatchable( $ns ) {
+               $this->assertFalse( $this->obj->isWatchable( $ns ) );
+       }
+
+       /**
+        * @covers NamespaceInfo::isWatchable
+        */
+       public function testIsWatchable() {
+               // Specials namespaces are not watchable
+               $this->assertIsNotWatchable( NS_MEDIA );
+               $this->assertIsNotWatchable( NS_SPECIAL );
+
+               // Core defined namespaces are watchables
+               $this->assertIsWatchable( NS_MAIN );
+               $this->assertIsWatchable( NS_TALK );
+
+               // Additional, user defined namespaces are watchables
+               $this->assertIsWatchable( 100 );
+               $this->assertIsWatchable( 101 );
+       }
+
+       private function assertHasSubpages( $ns ) {
+               $this->assertTrue( $this->obj->hasSubpages( $ns ) );
+       }
+
+       private function assertHasNotSubpages( $ns ) {
+               $this->assertFalse( $this->obj->hasSubpages( $ns ) );
+       }
+
+       /**
+        * @covers NamespaceInfo::hasSubpages
+        */
+       public function testHasSubpages() {
+               global $wgNamespacesWithSubpages;
+
+               // Special namespaces:
+               $this->assertHasNotSubpages( NS_MEDIA );
+               $this->assertHasNotSubpages( NS_SPECIAL );
+
+               // Namespaces without subpages
+               $this->assertHasNotSubpages( NS_MAIN );
+
+               $wgNamespacesWithSubpages[NS_MAIN] = true;
+               $this->assertHasSubpages( NS_MAIN );
+
+               $wgNamespacesWithSubpages[NS_MAIN] = false;
+               $this->assertHasNotSubpages( NS_MAIN );
+
+               // Some namespaces with subpages
+               $this->assertHasSubpages( NS_TALK );
+               $this->assertHasSubpages( NS_USER );
+               $this->assertHasSubpages( NS_USER_TALK );
+       }
+
+       /**
+        * @covers NamespaceInfo::getContentNamespaces
+        */
+       public function testGetContentNamespaces() {
+               global $wgContentNamespaces;
+
+               $this->assertEquals(
+                       [ NS_MAIN ],
+                       $this->obj->getContentNamespaces(),
+                       '$wgContentNamespaces is an array with only NS_MAIN by default'
+               );
+
+               # test !is_array( $wgcontentNamespaces )
+               $wgContentNamespaces = '';
+               $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
+
+               $wgContentNamespaces = false;
+               $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
+
+               $wgContentNamespaces = null;
+               $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
+
+               $wgContentNamespaces = 5;
+               $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
+
+               # test $wgContentNamespaces === []
+               $wgContentNamespaces = [];
+               $this->assertEquals( [ NS_MAIN ], $this->obj->getContentNamespaces() );
+
+               # test !in_array( NS_MAIN, $wgContentNamespaces )
+               $wgContentNamespaces = [ NS_USER, NS_CATEGORY ];
+               $this->assertEquals(
+                       [ NS_MAIN, NS_USER, NS_CATEGORY ],
+                       $this->obj->getContentNamespaces(),
+                       'NS_MAIN is forced in $wgContentNamespaces even if unwanted'
+               );
+
+               # test other cases, return $wgcontentNamespaces as is
+               $wgContentNamespaces = [ NS_MAIN ];
+               $this->assertEquals(
+                       [ NS_MAIN ],
+                       $this->obj->getContentNamespaces()
+               );
+
+               $wgContentNamespaces = [ NS_MAIN, NS_USER, NS_CATEGORY ];
+               $this->assertEquals(
+                       [ NS_MAIN, NS_USER, NS_CATEGORY ],
+                       $this->obj->getContentNamespaces()
+               );
+       }
+
+       /**
+        * @covers NamespaceInfo::getSubjectNamespaces
+        */
+       public function testGetSubjectNamespaces() {
+               $subjectsNS = $this->obj->getSubjectNamespaces();
+               $this->assertContains( NS_MAIN, $subjectsNS,
+                       "Talk namespaces should have NS_MAIN" );
+               $this->assertNotContains( NS_TALK, $subjectsNS,
+                       "Talk namespaces should have NS_TALK" );
+
+               $this->assertNotContains( NS_MEDIA, $subjectsNS,
+                       "Talk namespaces should not have NS_MEDIA" );
+               $this->assertNotContains( NS_SPECIAL, $subjectsNS,
+                       "Talk namespaces should not have NS_SPECIAL" );
+       }
+
+       /**
+        * @covers NamespaceInfo::getTalkNamespaces
+        */
+       public function testGetTalkNamespaces() {
+               $talkNS = $this->obj->getTalkNamespaces();
+               $this->assertContains( NS_TALK, $talkNS,
+                       "Subject namespaces should have NS_TALK" );
+               $this->assertNotContains( NS_MAIN, $talkNS,
+                       "Subject namespaces should not have NS_MAIN" );
+
+               $this->assertNotContains( NS_MEDIA, $talkNS,
+                       "Subject namespaces should not have NS_MEDIA" );
+               $this->assertNotContains( NS_SPECIAL, $talkNS,
+                       "Subject namespaces should not have NS_SPECIAL" );
+       }
+
+       private function assertIsCapitalized( $ns ) {
+               $this->assertTrue( $this->obj->isCapitalized( $ns ) );
+       }
+
+       private function assertIsNotCapitalized( $ns ) {
+               $this->assertFalse( $this->obj->isCapitalized( $ns ) );
+       }
+
+       /**
+        * Some namespaces are always capitalized per code definition
+        * in NamespaceInfo::$alwaysCapitalizedNamespaces
+        * @covers NamespaceInfo::isCapitalized
+        */
+       public function testIsCapitalizedHardcodedAssertions() {
+               // NS_MEDIA and NS_FILE are treated the same
+               $this->assertEquals(
+                       $this->obj->isCapitalized( NS_MEDIA ),
+                       $this->obj->isCapitalized( NS_FILE ),
+                       'NS_MEDIA and NS_FILE have same capitalization rendering'
+               );
+
+               // Boths are capitalized by default
+               $this->assertIsCapitalized( NS_MEDIA );
+               $this->assertIsCapitalized( NS_FILE );
+
+               // Always capitalized namespaces
+               // @see NamespaceInfo::$alwaysCapitalizedNamespaces
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
+               $this->assertIsCapitalized( NS_MEDIAWIKI );
+       }
+
+       /**
+        * Follows up for testIsCapitalizedHardcodedAssertions() but alter the
+        * global $wgCapitalLink setting to have extended coverage.
+        *
+        * NamespaceInfo::isCapitalized() rely on two global settings:
+        *   $wgCapitalLinkOverrides = []; by default
+        *   $wgCapitalLinks = true; by default
+        * This function test $wgCapitalLinks
+        *
+        * Global setting correctness is tested against the NS_PROJECT and
+        * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials
+        * @covers NamespaceInfo::isCapitalized
+        */
+       public function testIsCapitalizedWithWgCapitalLinks() {
+               $this->assertIsCapitalized( NS_PROJECT );
+               $this->assertIsCapitalized( NS_PROJECT_TALK );
+
+               $this->setMwGlobals( 'wgCapitalLinks', false );
+
+               // hardcoded namespaces (see above function) are still capitalized:
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
+               $this->assertIsCapitalized( NS_MEDIAWIKI );
+
+               // setting is correctly applied
+               $this->assertIsNotCapitalized( NS_PROJECT );
+               $this->assertIsNotCapitalized( NS_PROJECT_TALK );
+       }
+
+       /**
+        * Counter part for NamespaceInfo::testIsCapitalizedWithWgCapitalLinks() now
+        * testing the $wgCapitalLinkOverrides global.
+        *
+        * @todo split groups of assertions in autonomous testing functions
+        * @covers NamespaceInfo::isCapitalized
+        */
+       public function testIsCapitalizedWithWgCapitalLinkOverrides() {
+               global $wgCapitalLinkOverrides;
+
+               // Test default settings
+               $this->assertIsCapitalized( NS_PROJECT );
+               $this->assertIsCapitalized( NS_PROJECT_TALK );
+
+               // hardcoded namespaces (see above function) are capitalized:
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
+               $this->assertIsCapitalized( NS_MEDIAWIKI );
+
+               // Hardcoded namespaces remains capitalized
+               $wgCapitalLinkOverrides[NS_SPECIAL] = false;
+               $wgCapitalLinkOverrides[NS_USER] = false;
+               $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false;
+
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
+               $this->assertIsCapitalized( NS_MEDIAWIKI );
+
+               $wgCapitalLinkOverrides[NS_PROJECT] = false;
+               $this->assertIsNotCapitalized( NS_PROJECT );
+
+               $wgCapitalLinkOverrides[NS_PROJECT] = true;
+               $this->assertIsCapitalized( NS_PROJECT );
+
+               unset( $wgCapitalLinkOverrides[NS_PROJECT] );
+               $this->assertIsCapitalized( NS_PROJECT );
+       }
+
+       /**
+        * @covers NamespaceInfo::hasGenderDistinction
+        */
+       public function testHasGenderDistinction() {
+               // Namespaces with gender distinctions
+               $this->assertTrue( $this->obj->hasGenderDistinction( NS_USER ) );
+               $this->assertTrue( $this->obj->hasGenderDistinction( NS_USER_TALK ) );
+
+               // Other ones, "genderless"
+               $this->assertFalse( $this->obj->hasGenderDistinction( NS_MEDIA ) );
+               $this->assertFalse( $this->obj->hasGenderDistinction( NS_SPECIAL ) );
+               $this->assertFalse( $this->obj->hasGenderDistinction( NS_MAIN ) );
+               $this->assertFalse( $this->obj->hasGenderDistinction( NS_TALK ) );
+       }
+
+       /**
+        * @covers NamespaceInfo::isNonincludable
+        */
+       public function testIsNonincludable() {
+               global $wgNonincludableNamespaces;
+
+               $wgNonincludableNamespaces = [ NS_USER ];
+
+               $this->assertTrue( $this->obj->isNonincludable( NS_USER ) );
+               $this->assertFalse( $this->obj->isNonincludable( NS_TEMPLATE ) );
+       }
+
+       private function assertSameSubject( $ns1, $ns2, $msg = '' ) {
+               $this->assertTrue( $this->obj->subjectEquals( $ns1, $ns2 ), $msg );
+       }
+
+       private function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
+               $this->assertFalse( $this->obj->subjectEquals( $ns1, $ns2 ), $msg );
+       }
+
+       public function provideGetCategoryLinkType() {
+               return [
+                       [ NS_MAIN, 'page' ],
+                       [ NS_TALK, 'page' ],
+                       [ NS_USER, 'page' ],
+                       [ NS_USER_TALK, 'page' ],
+
+                       [ NS_FILE, 'file' ],
+                       [ NS_FILE_TALK, 'page' ],
+
+                       [ NS_CATEGORY, 'subcat' ],
+                       [ NS_CATEGORY_TALK, 'page' ],
+
+                       [ 100, 'page' ],
+                       [ 101, 'page' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetCategoryLinkType
+        * @covers NamespaceInfo::getCategoryLinkType
+        *
+        * @param int $index
+        * @param string $expected
+        */
+       public function testGetCategoryLinkType( $index, $expected ) {
+               $actual = $this->obj->getCategoryLinkType( $index );
+               $this->assertSame( $expected, $actual, "NS $index" );
+       }
+}
index 4978b72..e8334d6 100644 (file)
@@ -133,6 +133,15 @@ class PasswordResetTest extends MediaWikiTestCase {
                                'globalBlock' => null,
                                'isAllowed' => true,
                        ],
+                       'blocked with an unknown system block type' => [
+                               'passwordResetRoutes' => [ 'username' => true ],
+                               'enableEmail' => true,
+                               'allowsAuthenticationDataChange' => true,
+                               'canEditPrivate' => true,
+                               'block' => new Block( [ 'systemBlock' => 'unknown' ] ),
+                               'globalBlock' => null,
+                               'isAllowed' => false,
+                       ],
                        'all OK' => [
                                'passwordResetRoutes' => [ 'username' => true ],
                                'enableEmail' => true,
index 863ff50..f84be3f 100644 (file)
@@ -599,7 +599,6 @@ class UserTest extends MediaWikiTestCase {
                ] );
 
                // 1. Log in a test user, and block them.
-               $userBlocker = $this->getTestSysop()->getUser();
                $user1tmp = $this->getTestUser()->getUser();
                $request1 = new FauxRequest();
                $request1->getSession()->setUser( $user1tmp );
@@ -610,7 +609,6 @@ class UserTest extends MediaWikiTestCase {
                ] );
                $block->setBlocker( $this->getTestSysop()->getUser() );
                $block->setTarget( $user1tmp );
-               $block->setBlocker( $userBlocker );
                $res = $block->insert();
                $this->assertTrue( (bool)$res['id'], 'Failed to insert block' );
                $user1 = User::newFromSession( $request1 );
@@ -682,14 +680,12 @@ class UserTest extends MediaWikiTestCase {
                ] );
 
                // 1. Log in a test user, and block them.
-               $userBlocker = $this->getTestSysop()->getUser();
                $testUser = $this->getTestUser()->getUser();
                $request1 = new FauxRequest();
                $request1->getSession()->setUser( $testUser );
                $block = new Block( [ 'enableAutoblock' => true ] );
                $block->setBlocker( $this->getTestSysop()->getUser() );
                $block->setTarget( $testUser );
-               $block->setBlocker( $userBlocker );
                $res = $block->insert();
                $this->assertTrue( (bool)$res['id'], 'Failed to insert block' );
                $user = User::newFromSession( $request1 );
@@ -729,14 +725,12 @@ class UserTest extends MediaWikiTestCase {
                ] );
 
                // 1. Log in a test user, and block them indefinitely.
-               $userBlocker = $this->getTestSysop()->getUser();
                $user1Tmp = $this->getTestUser()->getUser();
                $request1 = new FauxRequest();
                $request1->getSession()->setUser( $user1Tmp );
                $block = new Block( [ 'enableAutoblock' => true, 'expiry' => 'infinity' ] );
                $block->setBlocker( $this->getTestSysop()->getUser() );
                $block->setTarget( $user1Tmp );
-               $block->setBlocker( $userBlocker );
                $res = $block->insert();
                $this->assertTrue( (bool)$res['id'], 'Failed to insert block' );
                $user1 = User::newFromSession( $request1 );
@@ -763,7 +757,7 @@ class UserTest extends MediaWikiTestCase {
 
                // 3. Change the block's expiry (to 2 hours), and the cookie's should be changed also.
                $newExpiry = wfTimestamp() + 2 * 60 * 60;
-               $block->mExpiry = wfTimestamp( TS_MW, $newExpiry );
+               $block->setExpiry( wfTimestamp( TS_MW, $newExpiry ) );
                $block->update();
                $user2tmp = $this->getTestUser()->getUser();
                $request2 = new FauxRequest();
@@ -783,30 +777,36 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::getBlockedStatus
         */
        public function testSoftBlockRanges() {
-               global $wgUser;
-
-               $this->setMwGlobals( [
-                       'wgSoftBlockRanges' => [ '10.0.0.0/8' ],
-                       'wgUser' => null,
-               ] );
+               $setSessionUser = function ( User $user, WebRequest $request ) {
+                       $this->setMwGlobals( 'wgUser', $user );
+                       RequestContext::getMain()->setUser( $user );
+                       RequestContext::getMain()->setRequest( $request );
+                       TestingAccessWrapper::newFromObject( $user )->mRequest = $request;
+                       $request->getSession()->setUser( $user );
+               };
+               $this->setMwGlobals( 'wgSoftBlockRanges', [ '10.0.0.0/8' ] );
 
                // IP isn't in $wgSoftBlockRanges
+               $wgUser = new User();
                $request = new FauxRequest();
                $request->setIP( '192.168.0.1' );
-               $wgUser = User::newFromSession( $request );
+               $setSessionUser( $wgUser, $request );
                $this->assertNull( $wgUser->getBlock() );
 
                // IP is in $wgSoftBlockRanges
+               $wgUser = new User();
                $request = new FauxRequest();
                $request->setIP( '10.20.30.40' );
-               $wgUser = User::newFromSession( $request );
+               $setSessionUser( $wgUser, $request );
                $block = $wgUser->getBlock();
                $this->assertInstanceOf( Block::class, $block );
                $this->assertSame( 'wgSoftBlockRanges', $block->getSystemBlockType() );
 
                // Make sure the block is really soft
-               $request->getSession()->setUser( $this->getTestUser()->getUser() );
-               $wgUser = User::newFromSession( $request );
+               $wgUser = $this->getTestUser()->getUser();
+               $request = new FauxRequest();
+               $request->setIP( '10.20.30.40' );
+               $setSessionUser( $wgUser, $request );
                $this->assertFalse( $wgUser->isAnon(), 'sanity check' );
                $this->assertNull( $wgUser->getBlock() );
        }
@@ -829,14 +829,12 @@ class UserTest extends MediaWikiTestCase {
                ] );
 
                // 1. Log in a blocked test user.
-               $userBlocker = $this->getTestSysop()->getUser();
                $user1tmp = $this->getTestUser()->getUser();
                $request1 = new FauxRequest();
                $request1->getSession()->setUser( $user1tmp );
                $block = new Block( [ 'enableAutoblock' => true ] );
                $block->setBlocker( $this->getTestSysop()->getUser() );
                $block->setTarget( $user1tmp );
-               $block->setBlocker( $userBlocker );
                $res = $block->insert();
                $this->assertTrue( (bool)$res['id'], 'Failed to insert block' );
                $user1 = User::newFromSession( $request1 );
@@ -876,14 +874,12 @@ class UserTest extends MediaWikiTestCase {
                ] );
 
                // 1. Log in a blocked test user.
-               $userBlocker = $this->getTestSysop()->getUser();
                $user1tmp = $this->getTestUser()->getUser();
                $request1 = new FauxRequest();
                $request1->getSession()->setUser( $user1tmp );
                $block = new Block( [ 'enableAutoblock' => true ] );
                $block->setBlocker( $this->getTestSysop()->getUser() );
                $block->setTarget( $user1tmp );
-               $block->setBlocker( $userBlocker );
                $res = $block->insert();
                $this->assertTrue( (bool)$res['id'], 'Failed to insert block' );
                $user1 = User::newFromSession( $request1 );
@@ -1472,4 +1468,42 @@ class UserTest extends MediaWikiTestCase {
                // clean up
                $block->delete();
        }
+
+       /**
+        * @covers User::getFirstEditTimestamp
+        * @covers User::getLatestEditTimestamp
+        */
+       public function testGetFirstLatestEditTimestamp() {
+               $clock = MWTimestamp::convert( TS_UNIX, '20100101000000' );
+               MWTimestamp::setFakeTime( function () use ( &$clock ) {
+                       return $clock += 1000;
+               } );
+               try {
+                       $user = $this->getTestUser()->getUser();
+                       $firstRevision = self::makeEdit( $user, 'Help:UserTest_GetEditTimestamp', 'one', 'test' );
+                       $secondRevision = self::makeEdit( $user, 'Help:UserTest_GetEditTimestamp', 'two', 'test' );
+                       // Sanity check: revisions timestamp are different
+                       $this->assertNotEquals( $firstRevision->getTimestamp(), $secondRevision->getTimestamp() );
+
+                       $this->assertEquals( $firstRevision->getTimestamp(), $user->getFirstEditTimestamp() );
+                       $this->assertEquals( $secondRevision->getTimestamp(), $user->getLatestEditTimestamp() );
+               } finally {
+                       MWTimestamp::setFakeTime( false );
+               }
+       }
+
+       /**
+        * @param User $user
+        * @param string $title
+        * @param string $content
+        * @param string $comment
+        * @return \MediaWiki\Revision\RevisionRecord|null
+        */
+       private static function makeEdit( User $user, $title, $content, $comment ) {
+               $page = WikiPage::factory( Title::newFromText( $title ) );
+               $content = ContentHandler::makeContent( $content, $page->getTitle() );
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( 'main', $content );
+               return $updater->saveRevision( CommentStoreComment::newUnsavedComment( $comment ) );
+       }
 }
index 50e6c20..63c2b82 100644 (file)
@@ -72,7 +72,8 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                return new WatchedItemQueryService(
                        $this->getMockLoadBalancer( $mockDb ),
                        $this->getMockCommentStore(),
-                       $this->getMockActorMigration()
+                       $this->getMockActorMigration(),
+                       $this->getMockWatchedItemStore()
                );
        }
 
@@ -139,6 +140,22 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                return $mock;
        }
 
+       /**
+        * @param PHPUnit_Framework_MockObject_MockObject|Database $mockDb
+        * @return PHPUnit_Framework_MockObject_MockObject|WatchedItemStore
+        */
+       private function getMockWatchedItemStore() {
+               $mock = $this->getMockBuilder( WatchedItemStore::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mock->expects( $this->any() )
+                       ->method( 'getLatestNotificationTimestamp' )
+                       ->will( $this->returnCallback( function ( $timestamp ) {
+                               return $timestamp;
+                       } ) );
+               return $mock;
+       }
+
        /**
         * @param int $id
         * @return PHPUnit_Framework_MockObject_MockObject|User
@@ -187,8 +204,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                        } ) );
                $mock->expects( $this->any() )
                        ->method( 'isAllowedAny' )
-                       ->will( $this->returnCallback( function () use ( $notAllowedAction ) {
-                               $actions = func_get_args();
+                       ->will( $this->returnCallback( function ( ...$actions ) use ( $notAllowedAction ) {
                                return !in_array( $notAllowedAction, $actions );
                        } ) );
 
@@ -263,7 +279,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                                ],
                                [
                                        'watchlist' => [
-                                               'INNER JOIN',
+                                               'JOIN',
                                                [
                                                        'wl_namespace=rc_namespace',
                                                        'wl_title=rc_title'
@@ -386,7 +402,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                                ],
                                [
                                        'watchlist' => [
-                                               'INNER JOIN',
+                                               'JOIN',
                                                [
                                                        'wl_namespace=rc_namespace',
                                                        'wl_title=rc_title'
@@ -888,7 +904,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                $expectedJoinConds = array_merge(
                        [
                                'watchlist' => [
-                                       'INNER JOIN',
+                                       'JOIN',
                                        [
                                                'wl_namespace=rc_namespace',
                                                'wl_title=rc_title'
@@ -1121,7 +1137,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                                $this->isType( 'string' ),
                                $this->isType( 'array' ),
                                array_merge( [
-                                       'watchlist' => [ 'INNER JOIN', [ 'wl_namespace=rc_namespace', 'wl_title=rc_title' ] ],
+                                       'watchlist' => [ 'JOIN', [ 'wl_namespace=rc_namespace', 'wl_title=rc_title' ] ],
                                        'page' => [ 'LEFT JOIN', 'rc_cur_id=page_id' ],
                                ], $expectedExtraJoins )
                        )
@@ -1159,7 +1175,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                                [],
                                [
                                        'watchlist' => [
-                                               'INNER JOIN',
+                                               'JOIN',
                                                [
                                                        'wl_namespace=rc_namespace',
                                                        'wl_title=rc_title'
@@ -1282,7 +1298,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                                [],
                                [
                                        'watchlist' => [
-                                               'INNER JOIN',
+                                               'JOIN',
                                                [
                                                        'wl_namespace=rc_namespace',
                                                        'wl_title=rc_title'
@@ -1328,7 +1344,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                                [],
                                [
                                        'watchlist' => [
-                                               'INNER JOIN',
+                                               'JOIN',
                                                [
                                                        'wl_namespace=rc_namespace',
                                                        'wl_title=rc_title'
index 3102929..20dbedb 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\TestingAccessWrapper;
 
 /**
  * @author Addshore
@@ -167,6 +168,13 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
                        [ $title->getNamespace() => [ $title->getDBkey() => null ] ],
                        $store->getNotificationTimestampsBatch( $user, [ $title ] )
                );
+
+               // Run the job queue
+               JobQueueGroup::destroySingletons();
+               $jobs = new RunJobs;
+               $jobs->loadParamsAndArgs( null, [ 'quiet' => true ], null );
+               $jobs->execute();
+
                $this->assertEquals(
                        $initialVisitingWatchers,
                        $store->countVisitingWatchers( $title, '20150202020202' )
@@ -192,19 +200,28 @@ class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
 
                // setNotificationTimestampsForUser specifying a title
                $this->assertTrue(
-                       $store->setNotificationTimestampsForUser( $user, '20200202020202', [ $title ] )
+                       $store->setNotificationTimestampsForUser( $user, '20100202020202', [ $title ] )
                );
                $this->assertEquals(
-                       '20200202020202',
+                       '20100202020202',
                        $store->getWatchedItem( $user, $title )->getNotificationTimestamp()
                );
 
                // setNotificationTimestampsForUser not specifying a title
+               // This will try to use a DeferredUpdate; disable that
+               $mockCallback = function ( $callback ) {
+                       $callback();
+               };
+               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
                $this->assertTrue(
-                       $store->setNotificationTimestampsForUser( $user, '20210202020202' )
+                       $store->setNotificationTimestampsForUser( $user, '20110202020202' )
                );
+               // Because the operation above is normally deferred, it doesn't clear the cache
+               // Clear the cache manually
+               $wrappedStore = TestingAccessWrapper::newFromObject( $store );
+               $wrappedStore->uncacheUser( $user );
                $this->assertEquals(
-                       '20210202020202',
+                       '20110202020202',
                        $store->getWatchedItem( $user, $title )->getNotificationTimestamp()
                );
        }
index 240b3f5..2f95688 100644 (file)
@@ -59,6 +59,26 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                return $mock;
        }
 
+       /**
+        * @return PHPUnit_Framework_MockObject_MockObject|JobQueueGroup
+        */
+       private function getMockJobQueueGroup() {
+               $mock = $this->getMockBuilder( JobQueueGroup::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mock->expects( $this->any() )
+                       ->method( 'push' )
+                       ->will( $this->returnCallback( function ( Job $job ) {
+                               $job->run();
+                       } ) );
+               $mock->expects( $this->any() )
+                       ->method( 'lazyPush' )
+                       ->will( $this->returnCallback( function ( Job $job ) {
+                               $job->run();
+                       } ) );
+               return $mock;
+       }
+
        /**
         * @return PHPUnit_Framework_MockObject_MockObject|HashBagOStuff
         */
@@ -69,8 +89,8 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->getMock();
                $mock->expects( $this->any() )
                        ->method( 'makeKey' )
-                       ->will( $this->returnCallback( function () {
-                               return implode( ':', func_get_args() );
+                       ->will( $this->returnCallback( function ( ...$args ) {
+                               return implode( ':', $args );
                        } ) );
                return $mock;
        }
@@ -100,6 +120,9 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                $mock->expects( $this->any() )
                        ->method( 'getId' )
                        ->will( $this->returnValue( $id ) );
+               $mock->expects( $this->any() )
+                       ->method( 'getUserPage' )
+                       ->will( $this->returnValue( Title::makeTitle( NS_USER, 'MockUser' ) ) );
                return $mock;
        }
 
@@ -118,11 +141,16 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                return $fakeRow;
        }
 
-       private function newWatchedItemStore( LBFactory $lbFactory, HashBagOStuff $cache,
+       private function newWatchedItemStore(
+               LBFactory $lbFactory,
+               JobQueueGroup $queueGroup,
+               HashBagOStuff $cache,
                ReadOnlyMode $readOnlyMode
        ) {
                return new WatchedItemStore(
                        $lbFactory,
+                       $queueGroup,
+                       new HashBagOStuff(),
                        $cache,
                        $readOnlyMode,
                        1000
@@ -161,6 +189,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -193,6 +222,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -223,6 +253,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -254,6 +285,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -306,6 +338,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -373,6 +406,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -422,6 +456,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -504,6 +539,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -609,6 +645,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -663,6 +700,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -701,6 +739,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -736,6 +775,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -774,6 +814,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -805,6 +846,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $this->getMockCache(),
                        $this->getMockReadOnlyMode()
                );
@@ -864,6 +906,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -911,6 +954,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1005,6 +1049,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1038,6 +1083,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1059,6 +1105,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1072,6 +1119,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
        public function testAddWatchBatchForUser_readOnlyDBReturnsFalse() {
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $this->getMockDb() ),
+                       $this->getMockJobQueueGroup(),
                        $this->getMockCache(),
                        $this->getMockReadOnlyMode( true )
                );
@@ -1122,6 +1170,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1147,6 +1196,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1171,6 +1221,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1206,6 +1257,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1241,6 +1293,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1264,6 +1317,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1313,6 +1367,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1364,6 +1419,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1389,6 +1445,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1434,6 +1491,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1469,6 +1527,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1507,6 +1566,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1531,6 +1591,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1572,6 +1633,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1623,6 +1685,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $mockLoadBalancer,
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1637,6 +1700,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
        public function testGetWatchedItemsForUser_badSortOptionThrowsException() {
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $this->getMockDb() ),
+                       $this->getMockJobQueueGroup(),
                        $this->getMockCache(),
                        $this->getMockReadOnlyMode()
                );
@@ -1679,6 +1743,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1716,6 +1781,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1740,6 +1806,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1808,6 +1875,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1859,6 +1927,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1921,6 +1990,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1962,6 +2032,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -1989,6 +2060,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -2014,6 +2086,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -2048,6 +2121,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -2092,29 +2166,26 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
+               $mockQueueGroup = $this->getMockJobQueueGroup();
+               $mockQueueGroup->expects( $this->once() )
+                       ->method( 'lazyPush' )
+                       ->willReturnCallback( function ( ActivityUpdateJob $job ) {
+                               // don't run
+                       } );
+
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $mockQueueGroup,
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
 
-               // Note: This does not actually assert the job is correct
-               $callableCallCounter = 0;
-               $mockCallback = function ( $callable ) use ( &$callableCallCounter ) {
-                       $callableCallCounter++;
-                       $this->assertInternalType( 'callable', $callable );
-               };
-               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
-
                $this->assertTrue(
                        $store->resetNotificationTimestamp(
                                $user,
                                $title
                        )
                );
-               $this->assertEquals( 1, $callableCallCounter );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
        public function testResetNotificationTimestamp_noItemForced() {
@@ -2132,19 +2203,19 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
+               $mockQueueGroup = $this->getMockJobQueueGroup();
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $mockQueueGroup,
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
 
-               // Note: This does not actually assert the job is correct
-               $callableCallCounter = 0;
-               $mockCallback = function ( $callable ) use ( &$callableCallCounter ) {
-                       $callableCallCounter++;
-                       $this->assertInternalType( 'callable', $callable );
-               };
-               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
+               $mockQueueGroup->expects( $this->any() )
+                       ->method( 'lazyPush' )
+                       ->will( $this->returnCallback( function ( ActivityUpdateJob $job ) {
+                               // don't run
+                       } ) );
 
                $this->assertTrue(
                        $store->resetNotificationTimestamp(
@@ -2153,9 +2224,6 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                'force'
                        )
                );
-               $this->assertEquals( 1, $callableCallCounter );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
        /**
@@ -2179,20 +2247,11 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
        }
 
        private function verifyCallbackJob(
-               $callback,
+               ActivityUpdateJob $job,
                LinkTarget $expectedTitle,
                $expectedUserId,
                callable $notificationTimestampCondition
        ) {
-               $this->assertInternalType( 'callable', $callback );
-
-               $callbackReflector = new ReflectionFunction( $callback );
-               $vars = $callbackReflector->getStaticVariables();
-               $this->assertArrayHasKey( 'job', $vars );
-               $this->assertInstanceOf( ActivityUpdateJob::class, $vars['job'] );
-
-               /** @var ActivityUpdateJob $job */
-               $job = $vars['job'];
                $this->assertEquals( $expectedTitle->getDBkey(), $job->getTitle()->getDBkey() );
                $this->assertEquals( $expectedTitle->getNamespace(), $job->getTitle()->getNamespace() );
 
@@ -2225,26 +2284,28 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeTitle:1' );
 
+               $mockQueueGroup = $this->getMockJobQueueGroup();
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $mockQueueGroup,
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
 
-               $callableCallCounter = 0;
-               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
-                       function ( $callable ) use ( &$callableCallCounter, $title, $user ) {
-                               $callableCallCounter++;
-                               $this->verifyCallbackJob(
-                                       $callable,
-                                       $title,
-                                       $user->getId(),
-                                       function ( $time ) {
-                                               return $time === null;
-                                       }
-                               );
-                       }
-               );
+               $mockQueueGroup->expects( $this->any() )
+                       ->method( 'lazyPush' )
+                       ->will( $this->returnCallback(
+                               function ( ActivityUpdateJob $job ) use ( $title, $user ) {
+                                       $this->verifyCallbackJob(
+                                               $job,
+                                               $title,
+                                               $user->getId(),
+                                               function ( $time ) {
+                                                       return $time === null;
+                                               }
+                                       );
+                               }
+                       ) );
 
                $this->assertTrue(
                        $store->resetNotificationTimestamp(
@@ -2254,9 +2315,6 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                $oldid
                        )
                );
-               $this->assertEquals( 1, $callableCallCounter );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
        public function testResetNotificationTimestamp_oldidSpecifiedNotLatestRevisionForced() {
@@ -2293,26 +2351,28 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
+               $mockQueueGroup = $this->getMockJobQueueGroup();
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $mockQueueGroup,
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
 
-               $addUpdateCallCounter = 0;
-               $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
-                       function ( $callable ) use ( &$addUpdateCallCounter, $title, $user ) {
-                               $addUpdateCallCounter++;
-                               $this->verifyCallbackJob(
-                                       $callable,
-                                       $title,
-                                       $user->getId(),
-                                       function ( $time ) {
-                                               return $time !== null && $time > '20151212010101';
-                                       }
-                               );
-                       }
-               );
+               $mockQueueGroup->expects( $this->any() )
+                       ->method( 'lazyPush' )
+                       ->will( $this->returnCallback(
+                               function ( ActivityUpdateJob $job ) use ( $title, $user ) {
+                                       $this->verifyCallbackJob(
+                                               $job,
+                                               $title,
+                                               $user->getId(),
+                                               function ( $time ) {
+                                                       return $time !== null && $time > '20151212010101';
+                                               }
+                                       );
+                               }
+                       ) );
 
                $getTimestampCallCounter = 0;
                $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
@@ -2331,10 +2391,8 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                $oldid
                        )
                );
-               $this->assertEquals( 1, $addUpdateCallCounter );
-               $this->assertEquals( 1, $getTimestampCallCounter );
+               $this->assertEquals( 2, $getTimestampCallCounter );
 
-               ScopedCallback::consume( $scopedOverrideDeferred );
                ScopedCallback::consume( $scopedOverrideRevision );
        }
 
@@ -2368,26 +2426,28 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
+               $mockQueueGroup = $this->getMockJobQueueGroup();
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $mockQueueGroup,
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
 
-               $callableCallCounter = 0;
-               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
-                       function ( $callable ) use ( &$callableCallCounter, $title, $user ) {
-                               $callableCallCounter++;
-                               $this->verifyCallbackJob(
-                                       $callable,
-                                       $title,
-                                       $user->getId(),
-                                       function ( $time ) {
-                                               return $time === null;
-                                       }
-                               );
-                       }
-               );
+               $mockQueueGroup->expects( $this->any() )
+                       ->method( 'lazyPush' )
+                       ->will( $this->returnCallback(
+                               function ( ActivityUpdateJob $job ) use ( $title, $user ) {
+                                       $this->verifyCallbackJob(
+                                               $job,
+                                               $title,
+                                               $user->getId(),
+                                               function ( $time ) {
+                                                       return $time === null;
+                                               }
+                                       );
+                               }
+                       ) );
 
                $this->assertTrue(
                        $store->resetNotificationTimestamp(
@@ -2397,9 +2457,6 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                $oldid
                        )
                );
-               $this->assertEquals( 1, $callableCallCounter );
-
-               ScopedCallback::consume( $scopedOverride );
        }
 
        public function testResetNotificationTimestamp_futureNotificationTimestampForced() {
@@ -2436,26 +2493,28 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
+               $mockQueueGroup = $this->getMockJobQueueGroup();
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $mockQueueGroup,
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
 
-               $addUpdateCallCounter = 0;
-               $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
-                       function ( $callable ) use ( &$addUpdateCallCounter, $title, $user ) {
-                               $addUpdateCallCounter++;
-                               $this->verifyCallbackJob(
-                                       $callable,
-                                       $title,
-                                       $user->getId(),
-                                       function ( $time ) {
-                                               return $time === '30151212010101';
-                                       }
-                               );
-                       }
-               );
+               $mockQueueGroup->expects( $this->any() )
+                       ->method( 'lazyPush' )
+                       ->will( $this->returnCallback(
+                               function ( ActivityUpdateJob $job ) use ( $title, $user ) {
+                                       $this->verifyCallbackJob(
+                                               $job,
+                                               $title,
+                                               $user->getId(),
+                                               function ( $time ) {
+                                                       return $time === '30151212010101';
+                                               }
+                                       );
+                               }
+                       ) );
 
                $getTimestampCallCounter = 0;
                $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
@@ -2474,10 +2533,8 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                $oldid
                        )
                );
-               $this->assertEquals( 1, $addUpdateCallCounter );
-               $this->assertEquals( 1, $getTimestampCallCounter );
+               $this->assertEquals( 2, $getTimestampCallCounter );
 
-               ScopedCallback::consume( $scopedOverrideDeferred );
                ScopedCallback::consume( $scopedOverrideRevision );
        }
 
@@ -2515,26 +2572,28 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->method( 'delete' )
                        ->with( '0:SomeDbKey:1' );
 
+               $mockQueueGroup = $this->getMockJobQueueGroup();
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $mockQueueGroup,
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
 
-               $addUpdateCallCounter = 0;
-               $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
-                       function ( $callable ) use ( &$addUpdateCallCounter, $title, $user ) {
-                               $addUpdateCallCounter++;
-                               $this->verifyCallbackJob(
-                                       $callable,
-                                       $title,
-                                       $user->getId(),
-                                       function ( $time ) {
-                                               return $time === false;
-                                       }
-                               );
-                       }
-               );
+               $mockQueueGroup->expects( $this->any() )
+                       ->method( 'lazyPush' )
+                       ->will( $this->returnCallback(
+                               function ( ActivityUpdateJob $job ) use ( $title, $user ) {
+                                       $this->verifyCallbackJob(
+                                               $job,
+                                               $title,
+                                               $user->getId(),
+                                               function ( $time ) {
+                                                       return $time === false;
+                                               }
+                                       );
+                               }
+                       ) );
 
                $getTimestampCallCounter = 0;
                $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
@@ -2553,16 +2612,15 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                $oldid
                        )
                );
-               $this->assertEquals( 1, $addUpdateCallCounter );
-               $this->assertEquals( 1, $getTimestampCallCounter );
+               $this->assertEquals( 2, $getTimestampCallCounter );
 
-               ScopedCallback::consume( $scopedOverrideDeferred );
                ScopedCallback::consume( $scopedOverrideRevision );
        }
 
        public function testSetNotificationTimestampsForUser_anonUser() {
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $this->getMockDb() ),
+                       $this->getMockJobQueueGroup(),
                        $this->getMockCache(),
                        $this->getMockReadOnlyMode()
                );
@@ -2573,57 +2631,46 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                $user = $this->getMockNonAnonUserWithId( 1 );
                $timestamp = '20100101010101';
 
-               $mockDb = $this->getMockDb();
-               $mockDb->expects( $this->once() )
-                       ->method( 'update' )
-                       ->with(
-                               'watchlist',
-                               [ 'wl_notificationtimestamp' => 'TS' . $timestamp . 'TS' ],
-                               [ 'wl_user' => 1 ]
-                       )
-                       ->will( $this->returnValue( true ) );
-               $mockDb->expects( $this->exactly( 1 ) )
-                       ->method( 'timestamp' )
-                       ->will( $this->returnCallback( function ( $value ) {
-                               return 'TS' . $value . 'TS';
-                       } ) );
-
                $store = $this->newWatchedItemStore(
-                       $this->getMockLBFactory( $mockDb ),
+                       $this->getMockLBFactory( $this->getMockDb() ),
+                       $this->getMockJobQueueGroup(),
                        $this->getMockCache(),
                        $this->getMockReadOnlyMode()
                );
 
+               // Note: This does not actually assert the job is correct
+               $callableCallCounter = 0;
+               $mockCallback = function ( $callable ) use ( &$callableCallCounter ) {
+                       $callableCallCounter++;
+                       $this->assertInternalType( 'callable', $callable );
+               };
+               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
+
                $this->assertTrue(
                        $store->setNotificationTimestampsForUser( $user, $timestamp )
                );
+               $this->assertEquals( 1, $callableCallCounter );
        }
 
        public function testSetNotificationTimestampsForUser_nullTimestamp() {
                $user = $this->getMockNonAnonUserWithId( 1 );
                $timestamp = null;
 
-               $mockDb = $this->getMockDb();
-               $mockDb->expects( $this->once() )
-                       ->method( 'update' )
-                       ->with(
-                               'watchlist',
-                               [ 'wl_notificationtimestamp' => null ],
-                               [ 'wl_user' => 1 ]
-                       )
-                       ->will( $this->returnValue( true ) );
-               $mockDb->expects( $this->exactly( 0 ) )
-                       ->method( 'timestamp' )
-                       ->will( $this->returnCallback( function ( $value ) {
-                               return 'TS' . $value . 'TS';
-                       } ) );
-
                $store = $this->newWatchedItemStore(
-                       $this->getMockLBFactory( $mockDb ),
+                       $this->getMockLBFactory( $this->getMockDb() ),
+                       $this->getMockJobQueueGroup(),
                        $this->getMockCache(),
                        $this->getMockReadOnlyMode()
                );
 
+               // Note: This does not actually assert the job is correct
+               $callableCallCounter = 0;
+               $mockCallback = function ( $callable ) use ( &$callableCallCounter ) {
+                       $callableCallCounter++;
+                       $this->assertInternalType( 'callable', $callable );
+               };
+               $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
+
                $this->assertTrue(
                        $store->setNotificationTimestampsForUser( $user, $timestamp )
                );
@@ -2640,7 +2687,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->with(
                                'watchlist',
                                [ 'wl_notificationtimestamp' => 'TS' . $timestamp . 'TS' ],
-                               [ 'wl_user' => 1, 0 => 'makeWhereFrom2d return value' ]
+                               [ 'wl_user' => 1, 'wl_namespace' => 0, 'wl_title' => [ 'Foo', 'Bar' ] ]
                        )
                        ->will( $this->returnValue( true ) );
                $mockDb->expects( $this->exactly( 1 ) )
@@ -2649,16 +2696,12 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                                return 'TS' . $value . 'TS';
                        } ) );
                $mockDb->expects( $this->once() )
-                       ->method( 'makeWhereFrom2d' )
-                       ->with(
-                               [ [ 'Foo' => 1, 'Bar' => 1 ] ],
-                               $this->isType( 'string' ),
-                               $this->isType( 'string' )
-                       )
-                       ->will( $this->returnValue( 'makeWhereFrom2d return value' ) );
+                       ->method( 'affectedRows' )
+                       ->will( $this->returnValue( 2 ) );
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $this->getMockCache(),
                        $this->getMockReadOnlyMode()
                );
@@ -2702,6 +2745,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -2743,6 +2787,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
@@ -2787,6 +2832,7 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
 
                $store = $this->newWatchedItemStore(
                        $this->getMockLBFactory( $mockDb ),
+                       $this->getMockJobQueueGroup(),
                        $mockCache,
                        $this->getMockReadOnlyMode()
                );
diff --git a/tests/phpunit/maintenance/DumpAsserter.php b/tests/phpunit/maintenance/DumpAsserter.php
new file mode 100644 (file)
index 0000000..ad33f6e
--- /dev/null
@@ -0,0 +1,348 @@
+<?php
+
+namespace MediaWiki\Tests\Maintenance;
+
+use PHPUnit\Framework\Assert;
+use XMLReader;
+
+/**
+ * Helper for asserting the structure of an XML dump stream.
+ */
+class DumpAsserter {
+
+       /**
+        * Holds the XMLReader used for analyzing an XML dump
+        *
+        * @var XMLReader|null
+        */
+       protected $xml = null;
+
+       /**
+        * XML dump schema version
+        *
+        * @var string
+        */
+       protected $schemaVersion;
+
+       /**
+        * DumpAsserts constructor.
+        *
+        * @param string $schemaVersion see XML_DUMP_SCHEMA_VERSION_XX
+        */
+       public function __construct( $schemaVersion ) {
+               $this->schemaVersion = $schemaVersion;
+       }
+
+       /**
+        * Step the current XML reader until node end of given name is found.
+        *
+        * @param string $name Name of the closing element to look for
+        *   (e.g.: "mediawiki" when looking for </mediawiki>)
+        *
+        * @return bool True if the end node could be found. false otherwise.
+        */
+       public function skipToNodeEnd( $name ) {
+               while ( $this->xml->read() ) {
+                       if ( $this->xml->nodeType == XMLReader::END_ELEMENT &&
+                               $this->xml->name == $name
+                       ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Step the current XML reader to the first element start after the node
+        * end of a given name.
+        *
+        * @param string $name Name of the closing element to look for
+        *   (e.g.: "mediawiki" when looking for </mediawiki>)
+        *
+        * @return bool True if new element after the closing of $name could be
+        *   found. false otherwise.
+        */
+       public function skipPastNodeEnd( $name ) {
+               Assert::assertTrue( $this->skipToNodeEnd( $name ),
+                       "Skipping to end of $name" );
+               while ( $this->xml->read() ) {
+                       if ( $this->xml->nodeType == XMLReader::ELEMENT ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Opens an XML file to analyze and optionally skips past siteinfo.
+        *
+        * @param string $fname Name of file to analyze
+        * @param bool $skip_siteinfo (optional) If true, step the xml reader
+        *   to the first element after </siteinfo>
+        */
+       public function assertDumpStart( $fname, $skip_siteinfo = true ) {
+               $this->xml = new XMLReader();
+
+               Assert::assertTrue( $this->xml->open( $fname ),
+                       "Opening temporary file $fname via XMLReader failed" );
+               if ( $skip_siteinfo ) {
+                       Assert::assertTrue( $this->skipPastNodeEnd( "siteinfo" ),
+                               "Skipping past end of siteinfo" );
+               }
+       }
+
+       /**
+        * Asserts that the xml reader is at the final closing tag of an xml file and
+        * closes the reader.
+        *
+        * @param string $name (optional) the name of the final tag
+        *   (e.g.: "mediawiki" for </mediawiki>)
+        */
+       public function assertDumpEnd( $name = "mediawiki" ) {
+               $this->assertNodeEnd( $name, false );
+               if ( $this->xml->read() ) {
+                       $this->skipWhitespace();
+               }
+               Assert::assertEquals( $this->xml->nodeType, XMLReader::NONE,
+                       "No proper entity left to parse" );
+               $this->xml->close();
+       }
+
+       /**
+        * Steps the xml reader over white space
+        */
+       public function skipWhitespace() {
+               $cont = true;
+               while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE )
+                       || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
+                       $cont = $this->xml->read();
+               }
+       }
+
+       /**
+        * Asserts that the xml reader is at an element of given name, and optionally
+        * skips past it.
+        *
+        * @param string $name The name of the element to check for
+        *   (e.g.: "mediawiki" for <mediawiki>)
+        * @param bool $skip (optional) if true, skip past the found element
+        */
+       public function assertNodeStart( $name, $skip = true ) {
+               Assert::assertEquals( $name, $this->xml->name, "Node name" );
+               Assert::assertEquals( XMLReader::ELEMENT, $this->xml->nodeType, "Node type" );
+               if ( $skip ) {
+                       Assert::assertTrue( $this->xml->read(), "Skipping past start tag" );
+               }
+       }
+
+       /**
+        * Asserts that the xml reader is at an closing element of given name, and optionally
+        * skips past it.
+        *
+        * @param string $name The name of the closing element to check for
+        *   (e.g.: "mediawiki" for </mediawiki>)
+        * @param bool $skip (optional) if true, skip past the found element
+        */
+       public function assertNodeEnd( $name, $skip = true ) {
+               Assert::assertEquals( $name, $this->xml->name, "Node name" );
+               Assert::assertEquals( XMLReader::END_ELEMENT, $this->xml->nodeType, "Node type" );
+               if ( $skip ) {
+                       Assert::assertTrue( $this->xml->read(), "Skipping past end tag" );
+               }
+       }
+
+       /**
+        * Asserts that the xml reader is at an element of given tag that contains a given text,
+        * and skips over the element.
+        *
+        * @param string $name The name of the element to check for
+        *   (e.g.: "mediawiki" for <mediawiki>...</mediawiki>)
+        * @param string|bool $text If string, check if it equals the elements text.
+        *   If false, ignore the element's text
+        * @param bool $skip_ws (optional) if true, skip past white spaces that trail the
+        *   closing element.
+        */
+       public function assertTextNode( $name, $text, $skip_ws = true ) {
+               $this->assertNodeStart( $name );
+
+               if ( $text !== false ) {
+                       Assert::assertEquals( $text, $this->xml->value, "Text of node " . $name );
+               }
+               Assert::assertTrue( $this->xml->read(), "Skipping past processed text of " . $name );
+               $this->assertNodeEnd( $name );
+
+               if ( $skip_ws ) {
+                       $this->skipWhitespace();
+               }
+       }
+
+       /**
+        * Asserts that the xml reader is at the start of a page element and skips over the first
+        * tags, after checking them.
+        *
+        * Besides the opening page element, this function also checks for and skips over the
+        * title, ns, and id tags. Hence after this function, the xml reader is at the first
+        * revision of the current page.
+        *
+        * @param int $id Id of the page to assert
+        * @param int $ns Number of namespage to assert
+        * @param string $name Title of the current page
+        */
+       public function assertPageStart( $id, $ns, $name ) {
+               $this->assertNodeStart( "page" );
+               $this->skipWhitespace();
+
+               $this->assertTextNode( "title", $name );
+               $this->assertTextNode( "ns", $ns );
+               $this->assertTextNode( "id", $id );
+       }
+
+       /**
+        * Asserts that the xml reader is at the page's closing element and skips to the next
+        * element.
+        */
+       public function assertPageEnd() {
+               $this->assertNodeEnd( "page" );
+               $this->skipWhitespace();
+       }
+
+       /**
+        * Asserts that the xml reader is at a revision and checks its representation before
+        * skipping over it.
+        *
+        * @param int $id Id of the revision
+        * @param string $summary Summary of the revision
+        * @param int $text_id Id of the revision's text
+        * @param int $text_bytes Number of bytes in the revision's text
+        * @param string $text_sha1 The base36 SHA-1 of the revision's text
+        * @param string|bool $text (optional) The revision's string, or false to check for a
+        *            revision stub
+        * @param int|bool $parentid (optional) id of the parent revision
+        * @param string $model The expected content model id (default: CONTENT_MODEL_WIKITEXT)
+        * @param string $format The expected format model id (default: CONTENT_FORMAT_WIKITEXT)
+        */
+       public function assertRevision( $id, $summary, $text_id, $text_bytes,
+               $text_sha1, $text = false, $parentid = false,
+               $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT
+       ) {
+               $this->assertNodeStart( "revision" );
+               $this->skipWhitespace();
+
+               $this->assertTextNode( "id", $id );
+               if ( $parentid !== false ) {
+                       $this->assertTextNode( "parentid", $parentid );
+               }
+               $this->assertTextNode( "timestamp", false );
+
+               $this->assertNodeStart( "contributor" );
+               $this->skipWhitespace();
+               $this->assertTextNode( "username", false );
+               $this->assertTextNode( "id", false );
+               $this->assertNodeEnd( "contributor" );
+               $this->skipWhitespace();
+
+               $this->assertTextNode( "comment", $summary );
+               $this->skipWhitespace();
+
+               $this->assertTextNode( "model", $model );
+               $this->skipWhitespace();
+
+               $this->assertTextNode( "format", $format );
+               $this->skipWhitespace();
+
+               if ( $this->xml->name == "text" ) {
+                       // note: <text> tag may occur here or at the very end.
+                       $text_found = true;
+                       $this->assertText( $id, $text_id, $text_bytes, $text );
+               } else {
+                       $text_found = false;
+               }
+
+               $this->assertTextNode( "sha1", $text_sha1 );
+
+               if ( !$text_found ) {
+                       $this->assertText( $id, $text_id, $text_bytes, $text );
+               }
+
+               $this->assertNodeEnd( "revision" );
+               $this->skipWhitespace();
+       }
+
+       public function assertText( $id, $text_id, $text_bytes, $text ) {
+               $this->assertNodeStart( "text", false );
+               if ( $text_bytes !== false ) {
+                       Assert::assertEquals( $this->xml->getAttribute( "bytes" ), $text_bytes,
+                               "Attribute 'bytes' of revision " . $id );
+               }
+
+               if ( $text === false ) {
+                       // Testing for a stub
+                       Assert::assertEquals( $this->xml->getAttribute( "id" ), $text_id,
+                               "Text id of revision " . $id );
+                       Assert::assertFalse( $this->xml->hasValue, "Revision has text" );
+                       Assert::assertTrue( $this->xml->read(), "Skipping text start tag" );
+                       if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT )
+                               && ( $this->xml->name == "text" )
+                       ) {
+                               $this->xml->read();
+                       }
+                       $this->skipWhitespace();
+               } else {
+                       // Testing for a real dump
+                       Assert::assertTrue( $this->xml->read(), "Skipping text start tag" );
+                       Assert::assertEquals( $text, $this->xml->value, "Text of revision " . $id );
+                       Assert::assertTrue( $this->xml->read(), "Skipping past text" );
+                       $this->assertNodeEnd( "text" );
+                       $this->skipWhitespace();
+               }
+       }
+
+       /**
+        * asserts that the xml reader is at the beginning of a log entry and skips over
+        * it while analyzing it.
+        *
+        * @param int $id Id of the log entry
+        * @param string $user_name User name of the log entry's performer
+        * @param int $user_id User id of the log entry 's performer
+        * @param string|null $comment Comment of the log entry. If null, the comment text is ignored.
+        * @param string $type Type of the log entry
+        * @param string $subtype Subtype of the log entry
+        * @param string $title Title of the log entry's target
+        * @param array $parameters (optional) unserialized data accompanying the log entry
+        */
+       public function assertLogItem( $id, $user_name, $user_id, $comment, $type,
+               $subtype, $title, $parameters = []
+       ) {
+               $this->assertNodeStart( "logitem" );
+               $this->skipWhitespace();
+
+               $this->assertTextNode( "id", $id );
+               $this->assertTextNode( "timestamp", false );
+
+               $this->assertNodeStart( "contributor" );
+               $this->skipWhitespace();
+               $this->assertTextNode( "username", $user_name );
+               $this->assertTextNode( "id", $user_id );
+               $this->assertNodeEnd( "contributor" );
+               $this->skipWhitespace();
+
+               if ( $comment !== null ) {
+                       $this->assertTextNode( "comment", $comment );
+               }
+               $this->assertTextNode( "type", $type );
+               $this->assertTextNode( "action", $subtype );
+               $this->assertTextNode( "logtitle", $title );
+
+               $this->assertNodeStart( "params" );
+               $parameters_xml = unserialize( $this->xml->value );
+               Assert::assertEquals( $parameters, $parameters_xml );
+               Assert::assertTrue( $this->xml->read(), "Skipping past processed text of params" );
+               $this->assertNodeEnd( "params" );
+               $this->skipWhitespace();
+
+               $this->assertNodeEnd( "logitem" );
+               $this->skipWhitespace();
+       }
+}
index 4b7a7eb..7647915 100644 (file)
@@ -3,11 +3,12 @@
 namespace MediaWiki\Tests\Maintenance;
 
 use ContentHandler;
+use DOMDocument;
 use ExecutableFinder;
 use MediaWikiLangTestCase;
-use Page;
 use User;
-use XMLReader;
+use WikiExporter;
+use WikiPage;
 use MWException;
 
 /**
@@ -28,13 +29,6 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         */
        protected $exceptionFromAddDBData = null;
 
-       /**
-        * Holds the XMLReader used for analyzing an XML dump
-        *
-        * @var XMLReader|null
-        */
-       protected $xml = null;
-
        /** @var bool|null Whether the 'gzip' utility is available */
        protected static $hasGzip = null;
 
@@ -58,7 +52,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
        /**
         * Adds a revision to a page, while returning the resuting revision's id
         *
-        * @param Page $page Page to add the revision to
+        * @param WikiPage $page Page to add the revision to
         * @param string $text Revisions text
         * @param string $summary Revisions summary
         * @param string $model The model ID (defaults to wikitext)
@@ -66,10 +60,15 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         * @throws MWException
         * @return array
         */
-       protected function addRevision( Page $page, $text, $summary, $model = CONTENT_MODEL_WIKITEXT ) {
+       protected function addRevision(
+               WikiPage $page,
+               $text,
+               $summary,
+               $model = CONTENT_MODEL_WIKITEXT
+       ) {
                $status = $page->doEditContent(
                        ContentHandler::makeContent( $text, $page->getTitle(), $model ),
-                       $summary
+                       $summary, 0, false, $this->getTestUser()->getUser()
                );
 
                if ( $status->isGood() ) {
@@ -108,6 +107,36 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
                );
        }
 
+       public static function setUpBeforeClass() {
+               parent::setUpBeforeClass();
+
+               if ( !function_exists( 'libxml_set_external_entity_loader' ) ) {
+                       return;
+               }
+
+               // The W3C is intentionally slow about returning schema files,
+               // see <https://www.w3.org/Help/Webmaster#slowdtd>.
+               // To work around that, we keep our own copies of the relevant schema files.
+               libxml_set_external_entity_loader(
+                       function ( $public, $system, $context ) {
+                               switch ( $system ) {
+                                       // if more schema files are needed, add them here.
+                                       case 'http://www.w3.org/2001/xml.xsd':
+                                               $file = __DIR__ . '/xml.xsd';
+                                               break;
+                                       default:
+                                               if ( is_file( $system ) ) {
+                                                       $file = $system;
+                                               } else {
+                                                       return null;
+                                               }
+                               }
+
+                               return $file;
+                       }
+               );
+       }
+
        /**
         * Default set up function.
         *
@@ -125,6 +154,21 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
                $this->setMwGlobals( 'wgUser', new User() );
        }
 
+       /**
+        * Returns the path to the XML schema file for the given schema version.
+        *
+        * @param string|null $schemaVersion
+        *
+        * @return string
+        */
+       protected function getXmlSchemaPath( $schemaVersion = null ) {
+               global $IP, $wgXmlDumpSchemaVersion;
+
+               $schemaVersion = $schemaVersion ?: $wgXmlDumpSchemaVersion;
+
+               return "$IP/docs/export-$schemaVersion.xsd";
+       }
+
        /**
         * Checks for test output consisting only of lines containing ETA announcements
         */
@@ -152,266 +196,62 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
        }
 
        /**
-        * Step the current XML reader until node end of given name is found.
-        *
-        * @param string $name Name of the closing element to look for
-        *   (e.g.: "mediawiki" when looking for </mediawiki>)
+        * @param null|string $schemaVersion
         *
-        * @return bool True if the end node could be found. false otherwise.
+        * @return DumpAsserter
         */
-       protected function skipToNodeEnd( $name ) {
-               while ( $this->xml->read() ) {
-                       if ( $this->xml->nodeType == XMLReader::END_ELEMENT &&
-                               $this->xml->name == $name
-                       ) {
-                               return true;
-                       }
-               }
-
-               return false;
+       protected function getDumpAsserter( $schemaVersion = null ) {
+               $schemaVersion = $schemaVersion ?: WikiExporter::schemaVersion();
+               return new DumpAsserter( $schemaVersion );
        }
 
        /**
-        * Step the current XML reader to the first element start after the node
-        * end of a given name.
-        *
-        * @param string $name Name of the closing element to look for
-        *   (e.g.: "mediawiki" when looking for </mediawiki>)
-        *
-        * @return bool True if new element after the closing of $name could be
-        *   found. false otherwise.
+        * Checks an XML file against an XSD schema.
         */
-       protected function skipPastNodeEnd( $name ) {
-               $this->assertTrue( $this->skipToNodeEnd( $name ),
-                       "Skipping to end of $name" );
-               while ( $this->xml->read() ) {
-                       if ( $this->xml->nodeType == XMLReader::ELEMENT ) {
-                               return true;
-                       }
+       protected function assertDumpSchema( $fname, $schemaFile ) {
+               if ( !function_exists( 'libxml_use_internal_errors' ) ) {
+                       // Would be nice to leave a warning somehow.
+                       // We don't want to skip all of the test case that calls this, though.
+                       $this->markAsRisky();
+                       return;
                }
-
-               return false;
-       }
-
-       /**
-        * Opens an XML file to analyze and optionally skips past siteinfo.
-        *
-        * @param string $fname Name of file to analyze
-        * @param bool $skip_siteinfo (optional) If true, step the xml reader
-        *   to the first element after </siteinfo>
-        */
-       protected function assertDumpStart( $fname, $skip_siteinfo = true ) {
-               $this->xml = new XMLReader();
-               $this->assertTrue( $this->xml->open( $fname ),
-                       "Opening temporary file $fname via XMLReader failed" );
-               if ( $skip_siteinfo ) {
-                       $this->assertTrue( $this->skipPastNodeEnd( "siteinfo" ),
-                               "Skipping past end of siteinfo" );
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       // In HHVM, loading a schema from a file is disabled per default.
+                       // This is controlled by hhvm.libxml.ext_entity_whitelist which
+                       // cannot be read with ini_get(), see
+                       // <https://docs.hhvm.com/hhvm/configuration/INI-settings#xml>.
+                       // Would be nice to leave a warning somehow.
+                       // We don't want to skip all of the test case that calls this, though.
+                       $this->markAsRisky();
+                       return;
                }
-       }
 
-       /**
-        * Asserts that the xml reader is at the final closing tag of an xml file and
-        * closes the reader.
-        *
-        * @param string $name (optional) the name of the final tag
-        *   (e.g.: "mediawiki" for </mediawiki>)
-        */
-       protected function assertDumpEnd( $name = "mediawiki" ) {
-               $this->assertNodeEnd( $name, false );
-               if ( $this->xml->read() ) {
-                       $this->skipWhitespace();
-               }
-               $this->assertEquals( $this->xml->nodeType, XMLReader::NONE,
-                       "No proper entity left to parse" );
-               $this->xml->close();
-       }
+               $xml = new DOMDocument();
+               $this->assertTrue( $xml->load( $fname ),
+                       "Opening temporary file $fname via DOMDocument failed" );
 
-       /**
-        * Steps the xml reader over white space
-        */
-       protected function skipWhitespace() {
-               $cont = true;
-               while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE )
-                       || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
-                       $cont = $this->xml->read();
-               }
-       }
+               // Don't throw
+               $oldLibXmlInternalErrors = libxml_use_internal_errors( true );
 
-       /**
-        * Asserts that the xml reader is at an element of given name, and optionally
-        * skips past it.
-        *
-        * @param string $name The name of the element to check for
-        *   (e.g.: "mediawiki" for <mediawiki>)
-        * @param bool $skip (optional) if true, skip past the found element
-        */
-       protected function assertNodeStart( $name, $skip = true ) {
-               $this->assertEquals( $name, $this->xml->name, "Node name" );
-               $this->assertEquals( XMLReader::ELEMENT, $this->xml->nodeType, "Node type" );
-               if ( $skip ) {
-                       $this->assertTrue( $this->xml->read(), "Skipping past start tag" );
-               }
-       }
-
-       /**
-        * Asserts that the xml reader is at an closing element of given name, and optionally
-        * skips past it.
-        *
-        * @param string $name The name of the closing element to check for
-        *   (e.g.: "mediawiki" for </mediawiki>)
-        * @param bool $skip (optional) if true, skip past the found element
-        */
-       protected function assertNodeEnd( $name, $skip = true ) {
-               $this->assertEquals( $name, $this->xml->name, "Node name" );
-               $this->assertEquals( XMLReader::END_ELEMENT, $this->xml->nodeType, "Node type" );
-               if ( $skip ) {
-                       $this->assertTrue( $this->xml->read(), "Skipping past end tag" );
-               }
-       }
-
-       /**
-        * Asserts that the xml reader is at an element of given tag that contains a given text,
-        * and skips over the element.
-        *
-        * @param string $name The name of the element to check for
-        *   (e.g.: "mediawiki" for <mediawiki>...</mediawiki>)
-        * @param string|bool $text If string, check if it equals the elements text.
-        *   If false, ignore the element's text
-        * @param bool $skip_ws (optional) if true, skip past white spaces that trail the
-        *   closing element.
-        */
-       protected function assertTextNode( $name, $text, $skip_ws = true ) {
-               $this->assertNodeStart( $name );
-
-               if ( $text !== false ) {
-                       $this->assertEquals( $text, $this->xml->value, "Text of node " . $name );
-               }
-               $this->assertTrue( $this->xml->read(), "Skipping past processed text of " . $name );
-               $this->assertNodeEnd( $name );
-
-               if ( $skip_ws ) {
-                       $this->skipWhitespace();
-               }
-       }
-
-       /**
-        * Asserts that the xml reader is at the start of a page element and skips over the first
-        * tags, after checking them.
-        *
-        * Besides the opening page element, this function also checks for and skips over the
-        * title, ns, and id tags. Hence after this function, the xml reader is at the first
-        * revision of the current page.
-        *
-        * @param int $id Id of the page to assert
-        * @param int $ns Number of namespage to assert
-        * @param string $name Title of the current page
-        */
-       protected function assertPageStart( $id, $ns, $name ) {
-               $this->assertNodeStart( "page" );
-               $this->skipWhitespace();
-
-               $this->assertTextNode( "title", $name );
-               $this->assertTextNode( "ns", $ns );
-               $this->assertTextNode( "id", $id );
-       }
+               // NOTE: if this reports "Invalid Schema", the schema may be referencing an external
+               // entity (typically, another schema) that needs to be mapped in the
+               // libxml_set_external_entity_loader callback defined in setUpBeforeClass() above!
+               // Or $schemaFile doesn't point to a schema file, or the schema is indeed just broken.
+               if ( !$xml->schemaValidate( $schemaFile ) ) {
+                       $errorText = '';
 
-       /**
-        * Asserts that the xml reader is at the page's closing element and skips to the next
-        * element.
-        */
-       protected function assertPageEnd() {
-               $this->assertNodeEnd( "page" );
-               $this->skipWhitespace();
-       }
-
-       /**
-        * Asserts that the xml reader is at a revision and checks its representation before
-        * skipping over it.
-        *
-        * @param int $id Id of the revision
-        * @param string $summary Summary of the revision
-        * @param int $text_id Id of the revision's text
-        * @param int $text_bytes Number of bytes in the revision's text
-        * @param string $text_sha1 The base36 SHA-1 of the revision's text
-        * @param string|bool $text (optional) The revision's string, or false to check for a
-        *            revision stub
-        * @param int|bool $parentid (optional) id of the parent revision
-        * @param string $model The expected content model id (default: CONTENT_MODEL_WIKITEXT)
-        * @param string $format The expected format model id (default: CONTENT_FORMAT_WIKITEXT)
-        */
-       protected function assertRevision( $id, $summary, $text_id, $text_bytes,
-               $text_sha1, $text = false, $parentid = false,
-               $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT
-       ) {
-               $this->assertNodeStart( "revision" );
-               $this->skipWhitespace();
-
-               $this->assertTextNode( "id", $id );
-               if ( $parentid !== false ) {
-                       $this->assertTextNode( "parentid", $parentid );
-               }
-               $this->assertTextNode( "timestamp", false );
-
-               $this->assertNodeStart( "contributor" );
-               $this->skipWhitespace();
-               $this->assertTextNode( "ip", false );
-               $this->assertNodeEnd( "contributor" );
-               $this->skipWhitespace();
-
-               $this->assertTextNode( "comment", $summary );
-               $this->skipWhitespace();
-
-               $this->assertTextNode( "model", $model );
-               $this->skipWhitespace();
-
-               $this->assertTextNode( "format", $format );
-               $this->skipWhitespace();
-
-               if ( $this->xml->name == "text" ) {
-                       // note: <text> tag may occur here or at the very end.
-                       $text_found = true;
-                       $this->assertText( $id, $text_id, $text_bytes, $text );
-               } else {
-                       $text_found = false;
-               }
+                       foreach ( libxml_get_errors() as $error ) {
+                               $errorText .= "\nline {$error->line}: {$error->message}";
+                       }
 
-               $this->assertTextNode( "sha1", $text_sha1 );
+                       libxml_clear_errors();
 
-               if ( !$text_found ) {
-                       $this->assertText( $id, $text_id, $text_bytes, $text );
+                       $this->fail(
+                               "Failed asserting that $fname conforms to the schema in $schemaFile:\n$errorText"
+                       );
                }
 
-               $this->assertNodeEnd( "revision" );
-               $this->skipWhitespace();
+               libxml_use_internal_errors( $oldLibXmlInternalErrors );
        }
 
-       protected function assertText( $id, $text_id, $text_bytes, $text ) {
-               $this->assertNodeStart( "text", false );
-               if ( $text_bytes !== false ) {
-                       $this->assertEquals( $this->xml->getAttribute( "bytes" ), $text_bytes,
-                               "Attribute 'bytes' of revision " . $id );
-               }
-
-               if ( $text === false ) {
-                       // Testing for a stub
-                       $this->assertEquals( $this->xml->getAttribute( "id" ), $text_id,
-                               "Text id of revision " . $id );
-                       $this->assertFalse( $this->xml->hasValue, "Revision has text" );
-                       $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
-                       if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT )
-                               && ( $this->xml->name == "text" )
-                       ) {
-                               $this->xml->read();
-                       }
-                       $this->skipWhitespace();
-               } else {
-                       // Testing for a real dump
-                       $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
-                       $this->assertEquals( $text, $this->xml->value, "Text of revision " . $id );
-                       $this->assertTrue( $this->xml->read(), "Skipping past text" );
-                       $this->assertNodeEnd( "text" );
-                       $this->skipWhitespace();
-               }
-       }
 }
index 38a513e..e059834 100644 (file)
@@ -130,45 +130,46 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
                $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT );
 
                // Checking for correctness of the dumped data
-               $this->assertDumpStart( $nameFull );
+               $asserter = $this->getDumpAsserter();
+               $asserter->assertDumpStart( $nameFull );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
+               $asserter->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" );
+               $asserter->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
                        $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
                        "BackupDumperTestP1Text1" );
-               $this->assertPageEnd();
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" );
-               $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
+               $asserter->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" );
+               $asserter->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
                        $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
                        "BackupDumperTestP2Text1" );
-               $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
+               $asserter->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
                        $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
                        "BackupDumperTestP2Text2", $this->revId2_1 );
-               $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
+               $asserter->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
                        $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
                        "BackupDumperTestP2Text3", $this->revId2_2 );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
+               $asserter->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
                        $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
                        "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
+               $asserter->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" );
+               $asserter->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
                        $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
                        "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
                        false,
                        "BackupTextPassTestModel",
                        "text/plain" );
-               $this->assertPageEnd();
+               $asserter->assertPageEnd();
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
        }
 
        function testPrefetchPlain() {
@@ -202,49 +203,50 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
                $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT );
 
                // Checking for correctness of the dumped data
-               $this->assertDumpStart( $nameFull );
+               $asserter = $this->getDumpAsserter();
+               $asserter->assertDumpStart( $nameFull );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" );
+               $asserter->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" );
                // Prefetch kicks in. This is still the SHA-1 of the original text,
                // But the actual text (with different SHA-1) comes from prefetch.
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
+               $asserter->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
                        $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
                        "Prefetch_________1Text1" );
-               $this->assertPageEnd();
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" );
-               $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
+               $asserter->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" );
+               $asserter->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
                        $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
                        "BackupDumperTestP2Text1" );
-               $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
+               $asserter->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
                        $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
                        "BackupDumperTestP2Text2", $this->revId2_1 );
                // Prefetch kicks in. This is still the SHA-1 of the original text,
                // But the actual text (with different SHA-1) comes from prefetch.
-               $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
+               $asserter->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
                        $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
                        "Prefetch_________2Text3", $this->revId2_2 );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
+               $asserter->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
                        $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
                        "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
+               $asserter->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" );
+               $asserter->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
                        $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
                        "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
                        false,
                        "BackupTextPassTestModel",
                        "text/plain" );
-               $this->assertPageEnd();
+               $asserter->assertPageEnd();
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
        }
 
        /**
@@ -329,6 +331,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
                $lookingForPage = 1;
                $checkpointFiles = 0;
 
+               $asserter = $this->getDumpAsserter();
+
                // Each run of the following loop body tries to handle exactly 1 /page/ (not
                // iteration of stub content). $i is only increased after having treated page 4.
                for ( $i = 0; $i < $iterations; ) {
@@ -346,7 +350,7 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
                                if ( $checkpointFormat == "gzip" ) {
                                        $this->gunzip( $nameOutputDir . "/" . $fname );
                                }
-                               $this->assertDumpStart( $nameOutputDir . "/" . $fname );
+                               $asserter->assertDumpStart( $nameOutputDir . "/" . $fname );
                                $fileOpened = true;
                                $checkpointFiles++;
                        }
@@ -355,51 +359,90 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
                        switch ( $lookingForPage ) {
                                case 1:
                                        // Page 1
-                                       $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN,
-                                               "BackupDumperTestP1" );
-                                       $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1",
-                                               $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
-                                               "BackupDumperTestP1Text1" );
-                                       $this->assertPageEnd();
+                                       $asserter->assertPageStart(
+                                               $this->pageId1 + $i * self::$numOfPages,
+                                               NS_MAIN,
+                                               "BackupDumperTestP1"
+                                       );
+                                       $asserter->assertRevision(
+                                               $this->revId1_1 + $i * self::$numOfRevs,
+                                               "BackupDumperTestP1Summary1",
+                                               $this->textId1_1,
+                                               false,
+                                               "0bolhl6ol7i6x0e7yq91gxgaan39j87",
+                                               "BackupDumperTestP1Text1"
+                                       );
+                                       $asserter->assertPageEnd();
 
                                        $lookingForPage = 2;
                                        break;
 
                                case 2:
                                        // Page 2
-                                       $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN,
-                                               "BackupDumperTestP2" );
-                                       $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1",
-                                               $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
-                                               "BackupDumperTestP2Text1" );
-                                       $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2",
-                                               $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
-                                               "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs );
-                                       $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3",
-                                               $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
-                                               "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs );
-                                       $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs,
+                                       $asserter->assertPageStart(
+                                               $this->pageId2 + $i * self::$numOfPages,
+                                               NS_MAIN,
+                                               "BackupDumperTestP2"
+                                       );
+                                       $asserter->assertRevision(
+                                               $this->revId2_1 + $i * self::$numOfRevs,
+                                               "BackupDumperTestP2Summary1",
+                                               $this->textId2_1,
+                                               false,
+                                               "jprywrymfhysqllua29tj3sc7z39dl2",
+                                               "BackupDumperTestP2Text1"
+                                       );
+                                       $asserter->assertRevision(
+                                               $this->revId2_2 + $i * self::$numOfRevs,
+                                               "BackupDumperTestP2Summary2",
+                                               $this->textId2_2,
+                                               false,
+                                               "b7vj5ks32po5m1z1t1br4o7scdwwy95",
+                                               "BackupDumperTestP2Text2",
+                                               $this->revId2_1 + $i * self::$numOfRevs
+                                       );
+                                       $asserter->assertRevision(
+                                               $this->revId2_3 + $i * self::$numOfRevs,
+                                               "BackupDumperTestP2Summary3",
+                                               $this->textId2_3,
+                                               false,
+                                               "jfunqmh1ssfb8rs43r19w98k28gg56r",
+                                               "BackupDumperTestP2Text3",
+                                               $this->revId2_2 + $i * self::$numOfRevs
+                                       );
+                                       $asserter->assertRevision(
+                                               $this->revId2_4 + $i * self::$numOfRevs,
                                                "BackupDumperTestP2Summary4 extra",
-                                               $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                                               $this->textId2_4,
+                                               false,
+                                               "6o1ciaxa6pybnqprmungwofc4lv00wv",
                                                "BackupDumperTestP2Text4 some additional Text",
-                                               $this->revId2_3 + $i * self::$numOfRevs );
-                                       $this->assertPageEnd();
+                                               $this->revId2_3 + $i * self::$numOfRevs
+                                       );
+                                       $asserter->assertPageEnd();
 
                                        $lookingForPage = 4;
                                        break;
 
                                case 4:
                                        // Page 4
-                                       $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK,
-                                               "Talk:BackupDumperTestP1" );
-                                       $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs,
+                                       $asserter->assertPageStart(
+                                               $this->pageId4 + $i * self::$numOfPages,
+                                               NS_TALK,
+                                               "Talk:BackupDumperTestP1"
+                                       );
+                                       $asserter->assertRevision(
+                                               $this->revId4_1 + $i * self::$numOfRevs,
                                                "Talk BackupDumperTestP1 Summary1",
-                                               $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
+                                               $this->textId4_1,
+                                               false,
+                                               "nktofwzd0tl192k3zfepmlzxoax1lpe",
                                                "TALK ABOUT BACKUPDUMPERTESTP1 TEXT1",
                                                false,
                                                "BackupTextPassTestModel",
-                                               "text/plain" );
-                                       $this->assertPageEnd();
+                                               "text/plain"
+                                       );
+                                       $asserter->assertPageEnd();
 
                                        $lookingForPage = 1;
 
@@ -415,7 +458,7 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
                        if ( $this->xml->nodeType == XMLReader::END_ELEMENT
                                && $this->xml->name == "mediawiki"
                        ) {
-                               $this->assertDumpEnd();
+                               $asserter->assertDumpEnd();
                                $fileOpened = false;
                        }
                }
@@ -518,6 +561,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
 
                $content = $header;
                $iterations = intval( $iterations );
+               $username = $this->getTestUser()->getUser()->getName();
+               $userid = $this->getTestUser()->getUser()->getId();
                for ( $i = 0; $i < $iterations; $i++ ) {
                        $page1 = '  <page>
     <title>BackupDumperTestP1</title>
@@ -527,7 +572,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
       <id>' . ( $this->revId1_1 + $i * self::$numOfRevs ) . '</id>
       <timestamp>2012-04-01T16:46:05Z</timestamp>
       <contributor>
-        <ip>127.0.0.1</ip>
+        <username>' . $username . '</username>
+        <id>' . $userid . '</id>
       </contributor>
       <comment>BackupDumperTestP1Summary1</comment>
       <model>wikitext</model>
@@ -545,7 +591,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
       <id>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</id>
       <timestamp>2012-04-01T16:46:05Z</timestamp>
       <contributor>
-        <ip>127.0.0.1</ip>
+        <username>' . $username . '</username>
+        <id>' . $userid . '</id>
       </contributor>
       <comment>BackupDumperTestP2Summary1</comment>
       <model>wikitext</model>
@@ -558,7 +605,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
       <parentid>' . ( $this->revId2_1 + $i * self::$numOfRevs ) . '</parentid>
       <timestamp>2012-04-01T16:46:05Z</timestamp>
       <contributor>
-        <ip>127.0.0.1</ip>
+        <username>' . $username . '</username>
+        <id>' . $userid . '</id>
       </contributor>
       <comment>BackupDumperTestP2Summary2</comment>
       <model>wikitext</model>
@@ -571,7 +619,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
       <parentid>' . ( $this->revId2_2 + $i * self::$numOfRevs ) . '</parentid>
       <timestamp>2012-04-01T16:46:05Z</timestamp>
       <contributor>
-        <ip>127.0.0.1</ip>
+        <username>' . $username . '</username>
+        <id>' . $userid . '</id>
       </contributor>
       <comment>BackupDumperTestP2Summary3</comment>
       <model>wikitext</model>
@@ -584,7 +633,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
       <parentid>' . ( $this->revId2_3 + $i * self::$numOfRevs ) . '</parentid>
       <timestamp>2012-04-01T16:46:05Z</timestamp>
       <contributor>
-        <ip>127.0.0.1</ip>
+        <username>' . $username . '</username>
+        <id>' . $userid . '</id>
       </contributor>
       <comment>BackupDumperTestP2Summary4 extra</comment>
       <model>wikitext</model>
@@ -604,7 +654,8 @@ class TextPassDumperDatabaseTest extends DumpTestCase {
       <id>' . ( $this->revId4_1 + $i * self::$numOfRevs ) . '</id>
       <timestamp>2012-04-01T16:46:05Z</timestamp>
       <contributor>
-        <ip>127.0.0.1</ip>
+        <username>' . $username . '</username>
+        <id>' . $userid . '</id>
       </contributor>
       <comment>Talk BackupDumperTestP1 Summary1</comment>
       <model>BackupTextPassTestModel</model>
index 9357451..811f1ee 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace MediaWiki\Tests\Maintenance;
 
+use Exception;
 use MediaWiki\MediaWikiServices;
 use DumpBackup;
 use ManualLogEntry;
@@ -98,53 +99,6 @@ class BackupDumperLoggerTest extends DumpTestCase {
                }
        }
 
-       /**
-        * asserts that the xml reader is at the beginning of a log entry and skips over
-        * it while analyzing it.
-        *
-        * @param int $id Id of the log entry
-        * @param string $user_name User name of the log entry's performer
-        * @param int $user_id User id of the log entry 's performer
-        * @param string|null $comment Comment of the log entry. If null, the comment text is ignored.
-        * @param string $type Type of the log entry
-        * @param string $subtype Subtype of the log entry
-        * @param string $title Title of the log entry's target
-        * @param array $parameters (optional) unserialized data accompanying the log entry
-        */
-       private function assertLogItem( $id, $user_name, $user_id, $comment, $type,
-               $subtype, $title, $parameters = []
-       ) {
-               $this->assertNodeStart( "logitem" );
-               $this->skipWhitespace();
-
-               $this->assertTextNode( "id", $id );
-               $this->assertTextNode( "timestamp", false );
-
-               $this->assertNodeStart( "contributor" );
-               $this->skipWhitespace();
-               $this->assertTextNode( "username", $user_name );
-               $this->assertTextNode( "id", $user_id );
-               $this->assertNodeEnd( "contributor" );
-               $this->skipWhitespace();
-
-               if ( $comment !== null ) {
-                       $this->assertTextNode( "comment", $comment );
-               }
-               $this->assertTextNode( "type", $type );
-               $this->assertTextNode( "action", $subtype );
-               $this->assertTextNode( "logtitle", $title );
-
-               $this->assertNodeStart( "params" );
-               $parameters_xml = unserialize( $this->xml->value );
-               $this->assertEquals( $parameters, $parameters_xml );
-               $this->assertTrue( $this->xml->read(), "Skipping past processed text of params" );
-               $this->assertNodeEnd( "params" );
-               $this->skipWhitespace();
-
-               $this->assertNodeEnd( "logitem" );
-               $this->skipWhitespace();
-       }
-
        function testPlain() {
                // Preparing the dump
                $fname = $this->getNewTempFile();
@@ -159,9 +113,12 @@ class BackupDumperLoggerTest extends DumpTestCase {
                $dumper->dump( WikiExporter::LOGS, WikiExporter::TEXT );
 
                // Analyzing the dumped data
-               $this->assertDumpStart( $fname );
+               $this->assertDumpSchema( $fname, $this->getXmlSchemaPath() );
+
+               $asserter = $this->getDumpAsserter();
+               $asserter->assertDumpStart( $fname );
 
-               $this->assertLogItem( $this->logId1, "BackupDumperLogUserA",
+               $asserter->assertLogItem( $this->logId1, "BackupDumperLogUserA",
                        $this->userId1, null, "type", "subtype", "PageA" );
 
                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
@@ -169,15 +126,15 @@ class BackupDumperLoggerTest extends DumpTestCase {
                $namespace = $contLang->getNsText( NS_TALK );
                $this->assertInternalType( 'string', $namespace );
                $this->assertGreaterThan( 0, strlen( $namespace ) );
-               $this->assertLogItem( $this->logId2, "BackupDumperLogUserB",
+               $asserter->assertLogItem( $this->logId2, "BackupDumperLogUserB",
                        $this->userId2, "SomeComment", "supress", "delete",
                        $namespace . ":PageB" );
 
-               $this->assertLogItem( $this->logId3, "BackupDumperLogUserB",
+               $asserter->assertLogItem( $this->logId3, "BackupDumperLogUserB",
                        $this->userId2, "SomeOtherComment", "move", "delete",
                        "PageA", [ 'key1' => 1, 3 => 'value3' ] );
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
        }
 
        function testXmlDumpsBackupUseCaseLogging() {
@@ -211,9 +168,12 @@ class BackupDumperLoggerTest extends DumpTestCase {
                // Analyzing the dumped data
                $this->gunzip( $fname );
 
-               $this->assertDumpStart( $fname );
+               $this->assertDumpSchema( $fname, $this->getXmlSchemaPath() );
+
+               $asserter = $this->getDumpAsserter();
+               $asserter->assertDumpStart( $fname );
 
-               $this->assertLogItem( $this->logId1, "BackupDumperLogUserA",
+               $asserter->assertLogItem( $this->logId1, "BackupDumperLogUserA",
                        $this->userId1, null, "type", "subtype", "PageA" );
 
                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
@@ -221,15 +181,15 @@ class BackupDumperLoggerTest extends DumpTestCase {
                $namespace = $contLang->getNsText( NS_TALK );
                $this->assertInternalType( 'string', $namespace );
                $this->assertGreaterThan( 0, strlen( $namespace ) );
-               $this->assertLogItem( $this->logId2, "BackupDumperLogUserB",
+               $asserter->assertLogItem( $this->logId2, "BackupDumperLogUserB",
                        $this->userId2, "SomeComment", "supress", "delete",
                        $namespace . ":PageB" );
 
-               $this->assertLogItem( $this->logId3, "BackupDumperLogUserB",
+               $asserter->assertLogItem( $this->logId3, "BackupDumperLogUserB",
                        $this->userId2, "SomeOtherComment", "move", "delete",
                        "PageA", [ 'key1' => 1, 3 => 'value3' ] );
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
 
                // Currently, no reporting is implemented. Alert via failure, once
                // this changes.
index 000b50f..17c8757 100644 (file)
@@ -3,9 +3,16 @@
 namespace MediaWiki\Tests\Maintenance;
 
 use DumpBackup;
+use Exception;
+use MediaWiki\MediaWikiServices;
+use MediaWikiTestCase;
+use MWException;
 use Title;
 use WikiExporter;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\LoadBalancer;
 use WikiPage;
+use XmlDumpWriter;
 
 /**
  * Tests for page dumps of BackupDumper
@@ -27,6 +34,11 @@ class BackupDumperPageTest extends DumpTestCase {
        private $revId4_1, $textId4_1;
        private $namespace, $talk_namespace;
 
+       /**
+        * @var LoadBalancer|null
+        */
+       private $streamingLoadBalancer = null;
+
        function addDBData() {
                // be sure, titles created here using english namespace names
                $this->setContentLang( 'en' );
@@ -101,154 +113,359 @@ class BackupDumperPageTest extends DumpTestCase {
                        "Page ids increasing without holes" );
        }
 
-       function testFullTextPlain() {
+       function tearDown() {
+               parent::tearDown();
+
+               if ( isset( $this->streamingLoadBalancer ) ) {
+                       $this->streamingLoadBalancer->closeAll();
+               }
+       }
+
+       /**
+        * Returns a new database connection which is separate from the conenctions returned
+        * by the default LoadBalancer instance.
+        *
+        * @return IDatabase
+        */
+       private function newStreamingDBConnection() {
+               // Create a *new* LoadBalancer, so no connections are shared
+               if ( !$this->streamingLoadBalancer ) {
+                       $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+
+                       $this->streamingLoadBalancer = $lbFactory->newMainLB();
+               }
+
+               $db = $this->streamingLoadBalancer->getConnection( DB_REPLICA );
+
+               // Make sure the DB connection has the fake table clones and the fake table prefix
+               MediaWikiTestCase::setupDatabaseWithTestPrefix( $db );
+
+               // Make sure the DB connection has all the test data
+               $this->copyTestData( $this->db, $db );
+
+               return $db;
+       }
+
+       /**
+        * @param array $argv
+        * @param int $startId
+        * @param int $endId
+        *
+        * @return DumpBackup
+        */
+       private function newDumpBackup( $argv, $startId, $endId ) {
+               $dumper = new DumpBackup( $argv );
+               $dumper->startId = $startId;
+               $dumper->endId = $endId;
+               $dumper->reporting = false;
+
+               // NOTE: The copyTestData() method used by newStreamingDBConnection()
+               // doesn't work with SQLite (T217607).
+               // But DatabaseSqlite doesn't support streaming anyway, so just skip that part.
+               if ( $this->db->getType() === 'sqlite' ) {
+                       $dumper->setDB( $this->db );
+               } else {
+                       $dumper->setDB( $this->newStreamingDBConnection() );
+               }
+
+               return $dumper;
+       }
+
+       public function schemaVersionProvider() {
+               foreach ( XmlDumpWriter::$supportedSchemas as $schemaVersion ) {
+                       yield [ $schemaVersion ];
+               }
+       }
+
+       /**
+        * @dataProvider schemaVersionProvider
+        */
+       function testFullTextPlain( $schemaVersion ) {
                // Preparing the dump
                $fname = $this->getNewTempFile();
 
-               $dumper = new DumpBackup();
-               $dumper->loadWithArgv( [ '--full', '--quiet', '--output', 'file:' . $fname ] );
-               $dumper->startId = $this->pageId1;
-               $dumper->endId = $this->pageId4 + 1;
-               $dumper->setDB( $this->db );
+               $dumper = $this->newDumpBackup(
+                       [ '--full', '--quiet', '--output', 'file:' . $fname, '--schema-version', $schemaVersion ],
+                       $this->pageId1,
+                       $this->pageId4 + 1
+               );
 
                // Performing the dump
                $dumper->execute();
 
                // Checking the dumped data
-               $this->assertDumpStart( $fname );
+               $this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
+               $asserter = $this->getDumpAsserter( $schemaVersion );
+
+               $asserter->assertDumpStart( $fname );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
-                       $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
-                       "BackupDumperTestP1Text1" );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId1,
+                       $this->namespace,
+                       $this->pageTitle1->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId1_1,
+                       "BackupDumperTestP1Summary1",
+                       $this->textId1_1,
+                       23,
+                       "0bolhl6ol7i6x0e7yq91gxgaan39j87",
+                       "BackupDumperTestP1Text1"
+               );
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
-               $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
-                       $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2",
-                       "BackupDumperTestP2Text1" );
-               $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
-                       $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
-                       "BackupDumperTestP2Text2", $this->revId2_1 );
-               $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
-                       $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r",
-                       "BackupDumperTestP2Text3", $this->revId2_2 );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
-                       $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv",
-                       "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId2,
+                       $this->namespace,
+                       $this->pageTitle2->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId2_1,
+                       "BackupDumperTestP2Summary1",
+                       $this->textId2_1,
+                       23,
+                       "jprywrymfhysqllua29tj3sc7z39dl2",
+                       "BackupDumperTestP2Text1"
+               );
+               $asserter->assertRevision(
+                       $this->revId2_2,
+                       "BackupDumperTestP2Summary2",
+                       $this->textId2_2,
+                       23,
+                       "b7vj5ks32po5m1z1t1br4o7scdwwy95",
+                       "BackupDumperTestP2Text2",
+                       $this->revId2_1
+               );
+               $asserter->assertRevision(
+                       $this->revId2_3,
+                       "BackupDumperTestP2Summary3",
+                       $this->textId2_3,
+                       23,
+                       "jfunqmh1ssfb8rs43r19w98k28gg56r",
+                       "BackupDumperTestP2Text3",
+                       $this->revId2_2
+               );
+               $asserter->assertRevision(
+                       $this->revId2_4,
+                       "BackupDumperTestP2Summary4 extra",
+                       $this->textId2_4,
+                       44,
+                       "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                       "BackupDumperTestP2Text4 some additional Text",
+                       $this->revId2_3
+               );
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart(
+               $asserter->assertPageStart(
                        $this->pageId4,
                        $this->talk_namespace,
                        $this->pageTitle4->getPrefixedText()
                );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
-                       $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe",
-                       "Talk about BackupDumperTestP1 Text1" );
-               $this->assertPageEnd();
+               $asserter->assertRevision(
+                       $this->revId4_1,
+                       "Talk BackupDumperTestP1 Summary1",
+                       $this->textId4_1,
+                       35,
+                       "nktofwzd0tl192k3zfepmlzxoax1lpe",
+                       "Talk about BackupDumperTestP1 Text1",
+                       false,
+                       CONTENT_MODEL_WIKITEXT,
+                       CONTENT_FORMAT_WIKITEXT,
+                       $schemaVersion
+               );
+               $asserter->assertPageEnd();
+
+               $asserter->assertDumpEnd();
 
-               $this->assertDumpEnd();
+               // FIXME: add multi-slot test case!
        }
 
-       function testFullStubPlain() {
+       /**
+        * @dataProvider schemaVersionProvider
+        */
+       function testFullStubPlain( $schemaVersion ) {
                // Preparing the dump
                $fname = $this->getNewTempFile();
 
-               $dumper = new DumpBackup();
-               $dumper->loadWithArgv( [ '--full', '--quiet', '--output', 'file:' . $fname, '--stub' ] );
-               $dumper->startId = $this->pageId1;
-               $dumper->endId = $this->pageId4 + 1;
-               $dumper->setDB( $this->db );
+               $dumper = $this->newDumpBackup(
+                       [
+                               '--full',
+                               '--quiet',
+                               '--output',
+                               'file:' . $fname,
+                               '--stub',
+                               '--schema-version', $schemaVersion,
+                       ],
+                       $this->pageId1,
+                       $this->pageId4 + 1
+               );
 
                // Performing the dump
                $dumper->execute();
 
                // Checking the dumped data
-               $this->assertDumpStart( $fname );
+               $this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
+               $asserter = $this->getDumpAsserter( $schemaVersion );
+
+               $asserter->assertDumpStart( $fname );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
-                       $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId1,
+                       $this->namespace,
+                       $this->pageTitle1->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId1_1,
+                       "BackupDumperTestP1Summary1",
+                       $this->textId1_1,
+                       23,
+                       "0bolhl6ol7i6x0e7yq91gxgaan39j87"
+               );
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
-               $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
-                       $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" );
-               $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
-                       $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 );
-               $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
-                       $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
-                       $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId2,
+                       $this->namespace,
+                       $this->pageTitle2->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId2_1,
+                       "BackupDumperTestP2Summary1",
+                       $this->textId2_1,
+                       23,
+                       "jprywrymfhysqllua29tj3sc7z39dl2"
+               );
+               $asserter->assertRevision(
+                       $this->revId2_2,
+                       "BackupDumperTestP2Summary2",
+                       $this->textId2_2,
+                       23,
+                       "b7vj5ks32po5m1z1t1br4o7scdwwy95",
+                       false,
+                       $this->revId2_1
+               );
+               $asserter->assertRevision(
+                       $this->revId2_3,
+                       "BackupDumperTestP2Summary3",
+                       $this->textId2_3,
+                       23,
+                       "jfunqmh1ssfb8rs43r19w98k28gg56r",
+                       false,
+                       $this->revId2_2
+               );
+               $asserter->assertRevision(
+                       $this->revId2_4,
+                       "BackupDumperTestP2Summary4 extra",
+                       $this->textId2_4,
+                       44,
+                       "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                       false,
+                       $this->revId2_3
+               );
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart(
+               $asserter->assertPageStart(
                        $this->pageId4,
                        $this->talk_namespace,
                        $this->pageTitle4->getPrefixedText()
                );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
-                       $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
-               $this->assertPageEnd();
+               $asserter->assertRevision(
+                       $this->revId4_1,
+                       "Talk BackupDumperTestP1 Summary1",
+                       $this->textId4_1,
+                       35,
+                       "nktofwzd0tl192k3zfepmlzxoax1lpe"
+               );
+               $asserter->assertPageEnd();
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
        }
 
-       function testCurrentStubPlain() {
+       /**
+        * @dataProvider schemaVersionProvider
+        */
+       function testCurrentStubPlain( $schemaVersion ) {
                // Preparing the dump
                $fname = $this->getNewTempFile();
 
-               $dumper = new DumpBackup( [ '--output', 'file:' . $fname ] );
-               $dumper->startId = $this->pageId1;
-               $dumper->endId = $this->pageId4 + 1;
-               $dumper->reporting = false;
-               $dumper->setDB( $this->db );
+               $dumper = $this->newDumpBackup(
+                       [ '--output', 'file:' . $fname, '--schema-version', $schemaVersion ],
+                       $this->pageId1,
+                       $this->pageId4 + 1
+               );
 
                // Performing the dump
                $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
 
                // Checking the dumped data
-               $this->assertDumpStart( $fname );
+               $this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
+
+               $asserter = $this->getDumpAsserter( $schemaVersion );
+               $asserter->assertDumpStart( $fname );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
-                       $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId1,
+                       $this->namespace,
+                       $this->pageTitle1->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId1_1,
+                       "BackupDumperTestP1Summary1",
+                       $this->textId1_1,
+                       23,
+                       "0bolhl6ol7i6x0e7yq91gxgaan39j87"
+               );
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
-                       $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId2,
+                       $this->namespace,
+                       $this->pageTitle2->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId2_4,
+                       "BackupDumperTestP2Summary4 extra",
+                       $this->textId2_4,
+                       44,
+                       "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                       false,
+                       $this->revId2_3
+               );
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart(
+               $asserter->assertPageStart(
                        $this->pageId4,
                        $this->talk_namespace,
                        $this->pageTitle4->getPrefixedText()
                );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
-                       $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
-               $this->assertPageEnd();
+               $asserter->assertRevision(
+                       $this->revId4_1,
+                       "Talk BackupDumperTestP1 Summary1",
+                       $this->textId4_1,
+                       35,
+                       "nktofwzd0tl192k3zfepmlzxoax1lpe"
+               );
+               $asserter->assertPageEnd();
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
        }
 
        function testCurrentStubGzip() {
@@ -257,45 +474,67 @@ class BackupDumperPageTest extends DumpTestCase {
                // Preparing the dump
                $fname = $this->getNewTempFile();
 
-               $dumper = new DumpBackup( [ '--output', 'gzip:' . $fname ] );
-               $dumper->startId = $this->pageId1;
-               $dumper->endId = $this->pageId4 + 1;
-               $dumper->reporting = false;
-               $dumper->setDB( $this->db );
+               $dumper = $this->newDumpBackup(
+                       [ '--output', 'gzip:' . $fname ],
+                       $this->pageId1,
+                       $this->pageId4 + 1
+               );
 
                // Performing the dump
                $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
 
                // Checking the dumped data
                $this->gunzip( $fname );
-               $this->assertDumpStart( $fname );
+
+               $asserter = $this->getDumpAsserter();
+               $asserter->assertDumpStart( $fname );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
-                       $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId1,
+                       $this->namespace,
+                       $this->pageTitle1->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId1_1,
+                       "BackupDumperTestP1Summary1",
+                       $this->textId1_1,
+                       23,
+                       "0bolhl6ol7i6x0e7yq91gxgaan39j87"
+               );
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
-                       $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId2,
+                       $this->namespace,
+                       $this->pageTitle2->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId2_4,
+                       "BackupDumperTestP2Summary4 extra",
+                       $this->textId2_4,
+                       44,
+                       "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                       false,
+                       $this->revId2_3
+               );
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart(
+               $asserter->assertPageStart(
                        $this->pageId4,
                        $this->talk_namespace,
                        $this->pageTitle4->getPrefixedText()
                );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
+               $asserter->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
                        $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
-               $this->assertPageEnd();
+               $asserter->assertPageEnd();
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
        }
 
        /**
@@ -308,22 +547,27 @@ class BackupDumperPageTest extends DumpTestCase {
         *
         * We reproduce such a setup with our mini fixture, although we omit
         * chunks, and all the other gimmicks of xmldumps-backup.
+        *
+        * @dataProvider schemaVersionProvider
         */
-       function testXmlDumpsBackupUseCase() {
+       function testXmlDumpsBackupUseCase( $schemaVersion ) {
                $this->checkHasGzip();
 
                $fnameMetaHistory = $this->getNewTempFile();
                $fnameMetaCurrent = $this->getNewTempFile();
                $fnameArticles = $this->getNewTempFile();
 
-               $dumper = new DumpBackup( [ "--full", "--stub", "--output=gzip:" . $fnameMetaHistory,
-                       "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
-                       "--output=gzip:" . $fnameArticles, "--filter=latest",
-                       "--filter=notalk", "--filter=namespace:!NS_USER",
-                       "--reporting=1000" ] );
-               $dumper->startId = $this->pageId1;
-               $dumper->endId = $this->pageId4 + 1;
-               $dumper->setDB( $this->db );
+               $dumper = $this->newDumpBackup(
+                       [ "--full", "--stub", "--output=gzip:" . $fnameMetaHistory,
+                               "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
+                               "--output=gzip:" . $fnameArticles, "--filter=latest",
+                               "--filter=notalk", "--filter=namespace:!NS_USER",
+                               "--reporting=1000", '--schema-version', $schemaVersion
+                       ],
+                       $this->pageId1,
+                       $this->pageId4 + 1
+               );
+               $dumper->reporting = true;
 
                // xmldumps-backup uses reporting. We will not check the exact reported
                // message, as they are dependent on the processing power of the used
@@ -342,89 +586,187 @@ class BackupDumperPageTest extends DumpTestCase {
                // Checking meta-history -------------------------------------------------
 
                $this->gunzip( $fnameMetaHistory );
-               $this->assertDumpStart( $fnameMetaHistory );
+               $this->assertDumpSchema( $fnameMetaHistory, $this->getXmlSchemaPath( $schemaVersion ) );
+
+               $asserter = $this->getDumpAsserter( $schemaVersion );
+               $asserter->assertDumpStart( $fnameMetaHistory );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
-                       $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId1,
+                       $this->namespace,
+                       $this->pageTitle1->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId1_1,
+                       "BackupDumperTestP1Summary1",
+                       $this->textId1_1,
+                       23,
+                       "0bolhl6ol7i6x0e7yq91gxgaan39j87"
+               );
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
-               $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1",
-                       $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" );
-               $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2",
-                       $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 );
-               $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3",
-                       $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
-                       $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId2,
+                       $this->namespace,
+                       $this->pageTitle2->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId2_1,
+                       "BackupDumperTestP2Summary1",
+                       $this->textId2_1,
+                       23,
+                       "jprywrymfhysqllua29tj3sc7z39dl2"
+               );
+               $asserter->assertRevision(
+                       $this->revId2_2,
+                       "BackupDumperTestP2Summary2",
+                       $this->textId2_2,
+                       23,
+                       "b7vj5ks32po5m1z1t1br4o7scdwwy95",
+                       false,
+                       $this->revId2_1
+               );
+               $asserter->assertRevision(
+                       $this->revId2_3,
+                       "BackupDumperTestP2Summary3",
+                       $this->textId2_3,
+                       23,
+                       "jfunqmh1ssfb8rs43r19w98k28gg56r",
+                       false,
+                       $this->revId2_2
+               );
+               $asserter->assertRevision(
+                       $this->revId2_4,
+                       "BackupDumperTestP2Summary4 extra",
+                       $this->textId2_4,
+                       44,
+                       "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                       false,
+                       $this->revId2_3
+               );
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart(
+               $asserter->assertPageStart(
                        $this->pageId4,
                        $this->talk_namespace,
-                       $this->pageTitle4->getPrefixedText()
+                       $this->pageTitle4->getPrefixedText( $schemaVersion )
                );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
-                       $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
-               $this->assertPageEnd();
+               $asserter->assertRevision(
+                       $this->revId4_1,
+                       "Talk BackupDumperTestP1 Summary1",
+                       $this->textId4_1,
+                       35,
+                       "nktofwzd0tl192k3zfepmlzxoax1lpe"
+               );
+               $asserter->assertPageEnd();
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
 
                // Checking meta-current -------------------------------------------------
 
                $this->gunzip( $fnameMetaCurrent );
-               $this->assertDumpStart( $fnameMetaCurrent );
+               $this->assertDumpSchema( $fnameMetaCurrent, $this->getXmlSchemaPath( $schemaVersion ) );
+
+               $asserter = $this->getDumpAsserter( $schemaVersion );
+               $asserter->assertDumpStart( $fnameMetaCurrent );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
-                       $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId1,
+                       $this->namespace,
+                       $this->pageTitle1->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId1_1,
+                       "BackupDumperTestP1Summary1",
+                       $this->textId1_1,
+                       23,
+                       "0bolhl6ol7i6x0e7yq91gxgaan39j87"
+               );
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
-                       $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId2,
+                       $this->namespace,
+                       $this->pageTitle2->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId2_4,
+                       "BackupDumperTestP2Summary4 extra",
+                       $this->textId2_4,
+                       44,
+                       "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                       false,
+                       $this->revId2_3
+               );
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
 
                // Page 4
-               $this->assertPageStart(
+               $asserter->assertPageStart(
                        $this->pageId4,
                        $this->talk_namespace,
                        $this->pageTitle4->getPrefixedText()
                );
-               $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1",
-                       $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" );
-               $this->assertPageEnd();
+               $asserter->assertRevision(
+                       $this->revId4_1,
+                       "Talk BackupDumperTestP1 Summary1",
+                       $this->textId4_1,
+                       35,
+                       "nktofwzd0tl192k3zfepmlzxoax1lpe"
+               );
+               $asserter->assertPageEnd();
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
 
                // Checking articles -------------------------------------------------
 
                $this->gunzip( $fnameArticles );
-               $this->assertDumpStart( $fnameArticles );
+               $this->assertDumpSchema( $fnameArticles, $this->getXmlSchemaPath( $schemaVersion ) );
+
+               $asserter = $this->getDumpAsserter( $schemaVersion );
+               $asserter->assertDumpStart( $fnameArticles );
 
                // Page 1
-               $this->assertPageStart( $this->pageId1, $this->namespace, $this->pageTitle1->getPrefixedText() );
-               $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1",
-                       $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId1,
+                       $this->namespace,
+                       $this->pageTitle1->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId1_1,
+                       "BackupDumperTestP1Summary1",
+                       $this->textId1_1,
+                       23,
+                       "0bolhl6ol7i6x0e7yq91gxgaan39j87"
+               );
+               $asserter->assertPageEnd();
 
                // Page 2
-               $this->assertPageStart( $this->pageId2, $this->namespace, $this->pageTitle2->getPrefixedText() );
-               $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra",
-                       $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 );
-               $this->assertPageEnd();
+               $asserter->assertPageStart(
+                       $this->pageId2,
+                       $this->namespace,
+                       $this->pageTitle2->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId2_4,
+                       "BackupDumperTestP2Summary4 extra",
+                       $this->textId2_4,
+                       44,
+                       "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                       false,
+                       $this->revId2_3
+               );
+               $asserter->assertPageEnd();
 
                // Page 3
                // -> Page is marked deleted. Hence not visible
@@ -432,7 +774,7 @@ class BackupDumperPageTest extends DumpTestCase {
                // Page 4
                // -> Page is not in $this->namespace. Hence not visible
 
-               $this->assertDumpEnd();
+               $asserter->assertDumpEnd();
 
                $this->expectETAOutput();
        }
index f5a47d5..521705e 100644 (file)
@@ -242,7 +242,7 @@ class CategoryChangesAsRdfTest extends MediaWikiLangTestCase {
                $this->assertFileContains( $testFileName, $sparql );
 
                $processed = $processedProperty->getValue( $dumpScript );
-               $expectedProcessed = $preProcessed;
+               $expectedProcessed = array_keys( $preProcessed );
                foreach ( $result as $row ) {
                        if ( isset( $row->_processed ) ) {
                                $this->assertArrayHasKey( $row->_processed, $processed,
@@ -250,7 +250,7 @@ class CategoryChangesAsRdfTest extends MediaWikiLangTestCase {
                                $expectedProcessed[] = $row->_processed;
                        }
                }
-               $this->assertArrayEquals( $expectedProcessed, array_keys( $processed ),
+               $this->assertSame( $expectedProcessed, array_keys( $processed ),
                        'Processed array has wrong items' );
        }
 
index 7cbda3c..8eadb0e 100644 (file)
@@ -4,6 +4,7 @@ namespace MediaWiki\Tests\Maintenance;
 
 use ContentHandler;
 use FetchText;
+use MediaWiki\Storage\RevisionRecord;
 use MediaWikiTestCase;
 use MWException;
 use Title;
@@ -104,12 +105,12 @@ class FetchTextTest extends MediaWikiTestCase {
        private $fetchText;
 
        /**
-        * Adds a revision to a page, while returning the resuting text's id
+        * Adds a revision to a page and returns the main slot's blob address
         *
         * @param WikiPage $page The page to add the revision to
         * @param string $text The revisions text
         * @param string $summary The revisions summare
-        * @return int
+        * @return string
         * @throws MWException
         */
        private function addRevision( $page, $text, $summary ) {
@@ -120,15 +121,14 @@ class FetchTextTest extends MediaWikiTestCase {
 
                if ( $status->isGood() ) {
                        $value = $status->getValue();
-                       $revision = $value['revision'];
-                       $id = $revision->getTextId();
 
-                       if ( $id > 0 ) {
-                               return $id;
-                       }
+                       /** @var RevisionRecord $revision */
+                       $revision = $value['revision-record'];
+                       $address = $revision->getSlot( 'main' )->getAddress();
+                       return $address;
                }
 
-               throw new MWException( "Could not determine text id" );
+               throw new MWException( "Could not create revision" );
        }
 
        function addDBDataOnce() {
@@ -211,6 +211,11 @@ class FetchTextTest extends MediaWikiTestCase {
                        self::$textId2 . "\n23\nFetchTextTestPage2Text1" );
        }
 
+       function testExistingInteger() {
+               $this->assertFilter( (int)preg_replace( '/^tt:/', '', self::$textId2 ),
+                       self::$textId2 . "\n23\nFetchTextTestPage2Text1" );
+       }
+
        function testExistingSeveral() {
                $this->assertFilter(
                        implode( "\n", [
@@ -233,36 +238,52 @@ class FetchTextTest extends MediaWikiTestCase {
        }
 
        function testNonExisting() {
-               $this->assertFilter( self::$textId5 + 10, ( self::$textId5 + 10 ) . "\n-1\n" );
+               \Wikimedia\suppressWarnings();
+               $this->assertFilter( 'tt:77889911', 'tt:77889911' . "\n-1\n" );
+               \Wikimedia\suppressWarnings( true );
+       }
+
+       function testNonExistingInteger() {
+               \Wikimedia\suppressWarnings();
+               $this->assertFilter( '77889911', 'tt:77889911' . "\n-1\n" );
+               \Wikimedia\suppressWarnings( true );
+       }
+
+       function testBadBlobAddressWithColon() {
+               $this->assertFilter( 'foo:bar', 'foo:bar' . "\n-1\n" );
        }
 
        function testNegativeInteger() {
-               $this->assertFilter( "-42", "-42\n-1\n" );
+               $this->assertFilter( "-42", "tt:-42\n-1\n" );
        }
 
        function testFloatingPointNumberExisting() {
-               // float -> int -> revision
-               $this->assertFilter( self::$textId3 + 0.14159,
+               // float -> int -> address -> revision
+               $id = intval( preg_replace( '/^tt:/', '', self::$textId3 ) ) + 0.14159;
+               $this->assertFilter( 'tt:' . intval( $id ),
                        self::$textId3 . "\n23\nFetchTextTestPage2Text2" );
        }
 
        function testFloatingPointNumberNonExisting() {
-               $this->assertFilter( self::$textId5 + 3.14159,
-                       ( self::$textId5 + 3 ) . "\n-1\n" );
+               \Wikimedia\suppressWarnings();
+               $id = intval( preg_replace( '/^tt:/', '', self::$textId5 ) ) + 3.14159;
+               $this->assertFilter( $id, 'tt:' . intval( $id ) . "\n-1\n" );
+               \Wikimedia\suppressWarnings( true );
        }
 
        function testCharacters() {
-               $this->assertFilter( "abc", "0\n-1\n" );
+               $this->assertFilter( "abc", "abc\n-1\n" );
        }
 
        function testMix() {
-               $this->assertFilter( "ab\n" . self::$textId4 . ".5cd\n\nefg\n" . self::$textId2
+               $this->assertFilter( "ab\n" . self::$textId4 . ".5cd\n\nefg\nfoo:bar\n" . self::$textId2
                                . "\n" . self::$textId3,
                        implode( "", [
-                               "0\n-1\n",
-                               self::$textId4 . "\n23\nFetchTextTestPage2Text3",
-                               "0\n-1\n",
-                               "0\n-1\n",
+                               "ab\n-1\n",
+                               self::$textId4 . ".5cd\n-1\n",
+                               "\n-1\n",
+                               "efg\n-1\n",
+                               "foo:bar\n-1\n",
                                self::$textId2 . "\n23\nFetchTextTestPage2Text1",
                                self::$textId3 . "\n23\nFetchTextTestPage2Text2"
                        ] ) );
diff --git a/tests/phpunit/maintenance/xml.xsd b/tests/phpunit/maintenance/xml.xsd
new file mode 100644 (file)
index 0000000..aea7d0d
--- /dev/null
@@ -0,0 +1,287 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" 
+  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+  xmlns   ="http://www.w3.org/1999/xhtml"
+  xml:lang="en">
+
+ <xs:annotation>
+  <xs:documentation>
+   <div>
+    <h1>About the XML namespace</h1>
+
+    <div class="bodytext">
+     <p>
+      This schema document describes the XML namespace, in a form
+      suitable for import by other schema documents.
+     </p>
+     <p>
+      See <a href="http://www.w3.org/XML/1998/namespace.html">
+      http://www.w3.org/XML/1998/namespace.html</a> and
+      <a href="http://www.w3.org/TR/REC-xml">
+      http://www.w3.org/TR/REC-xml</a> for information 
+      about this namespace.
+     </p>
+     <p>
+      Note that local names in this namespace are intended to be
+      defined only by the World Wide Web Consortium or its subgroups.
+      The names currently defined in this namespace are listed below.
+      They should not be used with conflicting semantics by any Working
+      Group, specification, or document instance.
+     </p>
+     <p>   
+      See further below in this document for more information about <a
+      href="#usage">how to refer to this schema document from your own
+      XSD schema documents</a> and about <a href="#nsversioning">the
+      namespace-versioning policy governing this schema document</a>.
+     </p>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>lang (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose value
+       is a language code for the natural language of the content of
+       any element; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML specification.</p>
+     
+    </div>
+    <div>
+     <h4>Notes</h4>
+     <p>
+      Attempting to install the relevant ISO 2- and 3-letter
+      codes as the enumerated possible values is probably never
+      going to be a realistic possibility.  
+     </p>
+     <p>
+      See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+       http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+      and the IANA language subtag registry at
+      <a href="http://www.iana.org/assignments/language-subtag-registry">
+       http://www.iana.org/assignments/language-subtag-registry</a>
+      for further information.
+     </p>
+     <p>
+      The union allows for the 'un-declaration' of xml:lang with
+      the empty string.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+   <xs:union memberTypes="xs:language">
+    <xs:simpleType>    
+     <xs:restriction base="xs:string">
+      <xs:enumeration value=""/>
+     </xs:restriction>
+    </xs:simpleType>
+   </xs:union>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>space (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose
+       value is a keyword indicating what whitespace processing
+       discipline is intended for the content of the element; its
+       value is inherited.  This name is reserved by virtue of its
+       definition in the XML specification.</p>
+     
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+   <xs:restriction base="xs:NCName">
+    <xs:enumeration value="default"/>
+    <xs:enumeration value="preserve"/>
+   </xs:restriction>
+  </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>base (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose value
+       provides a URI to be used as the base for interpreting any
+       relative URIs in the scope of the element on which it
+       appears; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML Base specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+      for information about this attribute.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="id" type="xs:ID">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>id (as an attribute name)</h3> 
+      <p>
+       denotes an attribute whose value
+       should be interpreted as if declared to be of type ID.
+       This name is reserved by virtue of its definition in the
+       xml:id specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+      for information about this attribute.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+  <xs:attribute ref="xml:base"/>
+  <xs:attribute ref="xml:lang"/>
+  <xs:attribute ref="xml:space"/>
+  <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div>
+   
+    <h3>Father (in any context at all)</h3> 
+
+    <div class="bodytext">
+     <p>
+      denotes Jon Bosak, the chair of 
+      the original XML Working Group.  This name is reserved by 
+      the following decision of the W3C XML Plenary and 
+      XML Coordination groups:
+     </p>
+     <blockquote>
+       <p>
+       In appreciation for his vision, leadership and
+       dedication the W3C XML Plenary on this 10th day of
+       February, 2000, reserves for Jon Bosak in perpetuity
+       the XML name "xml:Father".
+       </p>
+     </blockquote>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div xml:id="usage" id="usage">
+    <h2><a name="usage">About this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      This schema defines attributes and an attribute group suitable
+      for use by schemas wishing to allow <code>xml:base</code>,
+      <code>xml:lang</code>, <code>xml:space</code> or
+      <code>xml:id</code> attributes on elements they define.
+     </p>
+     <p>
+      To enable this, such a schema must import this schema for
+      the XML namespace, e.g. as follows:
+     </p>
+     <pre>
+          &lt;schema . . .>
+           . . .
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+     </pre>
+     <p>
+      or
+     </p>
+     <pre>
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+     </pre>
+     <p>
+      Subsequently, qualified reference to any of the attributes or the
+      group defined below will have the desired effect, e.g.
+     </p>
+     <pre>
+          &lt;type . . .>
+           . . .
+           &lt;attributeGroup ref="xml:specialAttrs"/>
+     </pre>
+     <p>
+      will define a type which will schema-validate an instance element
+      with any of those attributes.
+     </p>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div id="nsversioning" xml:id="nsversioning">
+    <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+    <div class="bodytext">
+     <p>
+      In keeping with the XML Schema WG's standard versioning
+      policy, this schema document will persist at
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd</a>.
+     </p>
+     <p>
+      At the date of issue it can also be found at
+      <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd</a>.
+     </p>
+     <p>
+      The schema document at that URI may however change in the future,
+      in order to remain compatible with the latest version of XML
+      Schema itself, or with the XML namespace itself.  In other words,
+      if the XML Schema or XML namespaces change, the version of this
+      document at <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd 
+      </a> 
+      will change accordingly; the version at 
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd 
+      </a> 
+      will not change.
+     </p>
+     <p>
+      Previous dated (and unchanging) versions of this schema 
+      document are at:
+     </p>
+     <ul>
+      <li><a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2007/08/xml.xsd">
+       http://www.w3.org/2007/08/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2004/10/xml.xsd">
+       http://www.w3.org/2004/10/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2001/03/xml.xsd">
+       http://www.w3.org/2001/03/xml.xsd</a></li>
+     </ul>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
+
index 4c64291..2453353 100644 (file)
@@ -500,10 +500,8 @@ class ApiStructureTest extends MediaWikiTestCase {
                                                if ( $value instanceof $type ) {
                                                        return;
                                                }
-                                       } else {
-                                               if ( gettype( $value ) === $type ) {
-                                                       return;
-                                               }
+                                       } elseif ( gettype( $value ) === $type ) {
+                                               return;
                                        }
                                } else {
                                        // Array whose values have specified types, recurse
index 75e21ae..2ae6a78 100644 (file)
@@ -112,14 +112,12 @@ class AutoLoaderStructureTest extends MediaWikiTestCase {
                                // 'class Foo {}'
                                $class = $fileNamespace . $match['class'];
                                $classesInFile[$class] = true;
+                       } elseif ( !empty( $match['original'] ) ) {
+                               // 'class_alias( "Foo", "Bar" );'
+                               $aliasesInFile[$match['alias']] = $match['original'];
                        } else {
-                               if ( !empty( $match['original'] ) ) {
-                                       // 'class_alias( "Foo", "Bar" );'
-                                       $aliasesInFile[$match['alias']] = $match['original'];
-                               } else {
-                                       // 'class_alias( Foo::class, "Bar" );'
-                                       $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
-                               }
+                               // 'class_alias( Foo::class, "Bar" );'
+                               $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
                        }
                }
 
index a7d947e..57b063d 100644 (file)
@@ -54,6 +54,17 @@ class AvailableRightsTest extends PHPUnit\Framework\TestCase {
                );
        }
 
+       /**
+        * Test, if for all rights an action- message exist,
+        * which is used on Special:ListGroupRights as help text
+        * Extensions and core
+        *
+        * @coversNothing
+        */
+       public function testAllActionsWithMessages() {
+               $this->checkMessagesExist( 'action-' );
+       }
+
        /**
         * Test, if for all rights a right- message exist,
         * which is used on Special:ListGroupRights as help text
@@ -62,27 +73,34 @@ class AvailableRightsTest extends PHPUnit\Framework\TestCase {
         * @coversNothing
         */
        public function testAllRightsWithMessage() {
+               $this->checkMessagesExist( 'right-' );
+       }
+
+       /**
+        * @param string $prefix
+        */
+       private function checkMessagesExist( $prefix ) {
                // Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights
                $allRights = User::getAllRights();
                $allMessageKeys = Language::getMessageKeysFor( 'en' );
 
-               $rightsWithMessage = [];
+               $messagesToCheck = [];
                foreach ( $allMessageKeys as $message ) {
                        // === 0: must be at beginning of string (position 0)
-                       if ( strpos( $message, 'right-' ) === 0 ) {
-                               $rightsWithMessage[] = substr( $message, strlen( 'right-' ) );
+                       if ( strpos( $message, $prefix ) === 0 ) {
+                               $messagesToCheck[] = substr( $message, strlen( $prefix ) );
                        }
                }
 
                $missing = array_diff(
                        $allRights,
-                       $rightsWithMessage
+                       $messagesToCheck
                );
 
                $this->assertEquals(
                        [],
                        $missing,
-                       'Each user rights (core/extensions) has a corresponding right- message.'
+                       "Each user right (core/extensions) has a corresponding $prefix message."
                );
        }
 }
diff --git a/tests/phpunit/structure/PasswordPolicyStructureTest.php b/tests/phpunit/structure/PasswordPolicyStructureTest.php
new file mode 100644 (file)
index 0000000..60ce575
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @coversNothing
+ */
+class PasswordPolicyStructureTest extends MediaWikiTestCase {
+
+       public function provideChecks() {
+               global $wgPasswordPolicy;
+
+               foreach ( $wgPasswordPolicy['checks'] as $name => $callback ) {
+                       yield [ $name ];
+               }
+       }
+
+       public function provideFlags() {
+               global $wgPasswordPolicy;
+
+               // This won't actually find all flags, just the ones in use. Can't really be helped,
+               // other than adding the core flags here.
+               $flags = [ 'forceChange', 'suggestChangeOnLogin' ];
+               foreach ( $wgPasswordPolicy['policies'] as $group => $checks ) {
+                       foreach ( $checks as $check => $settings ) {
+                               if ( is_array( $settings ) ) {
+                                       $flags = array_unique(
+                                               array_merge( $flags, array_diff( array_keys( $settings ), [ 'value' ] ) )
+                                       );
+                               }
+                       }
+               }
+
+               foreach ( $flags as $flag ) {
+                       yield [ $flag ];
+               }
+       }
+
+       /** @dataProvider provideChecks */
+       public function testCheckMessage( $check ) {
+               $msg = wfMessage( 'passwordpolicies-policy-' . strtolower( $check ) );
+               $this->assertTrue( $msg->exists() );
+       }
+
+       /** @dataProvider provideFlags */
+       public function testFlagMessage( $flag ) {
+               $msg = wfMessage( 'passwordpolicies-policyflag-' . strtolower( $flag ) );
+               $this->assertTrue( $msg->exists() );
+       }
+
+}
index 776dee1..f41ab3a 100644 (file)
@@ -155,7 +155,7 @@ class ResourcesTest extends MediaWikiTestCase {
                $css = file_get_contents( $basepath . 'comments.css' );
                $files = CSSMin::getLocalFileReferences( $css, $basepath );
                $expected = [ $basepath . 'not-commented.gif' ];
-               $this->assertArrayEquals(
+               $this->assertSame(
                        $expected,
                        $files,
                        'Url(...) expression in comment should be omitted.'
index c08fe2f..97797ca 100644 (file)
@@ -32,8 +32,14 @@ class SpecialPageFatalTest extends MediaWikiTestCase {
 
                try {
                        $executor->executeSpecialPage( $page, '', null, null, $user );
+               } catch ( \PHPUnit\Framework\Error\Error $error ) {
+                       // Let phpunit settings working:
+                       // - convertErrorsToExceptions="true"
+                       // - convertNoticesToExceptions="true"
+                       // - convertWarningsToExceptions="true"
+                       throw $error;
                } catch ( Exception $e ) {
-                       // Exceptions are allowed
+                       // Other exceptions are allowed
                }
 
                // If the page fataled phpunit will have already died
index 77461c5..28547d1 100644 (file)
@@ -113,7 +113,7 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
                        $testsName = $extensionName . '__' . basename( $fileName, '.txt' );
                        $parserTestClassName = ucfirst( $testsName );
 
-                       // Official spec for class names: https://secure.php.net/manual/en/language.oop5.basic.php
+                       // Official spec for class names: https://www.php.net/manual/en/language.oop5.basic.php
                        // Prepend 'ParserTest_' to be paranoid about it not starting with a number
                        $parserTestClassName = 'ParserTest_' .
                                preg_replace( '/[^a-zA-Z0-9_\x7f-\xff]/', '_', $parserTestClassName );
index 599b733..6b5a487 100644 (file)
@@ -7,6 +7,7 @@ use Wikimedia\Rdbms\LoadBalancer;
 /**
  * @covers MediaWikiTestCase
  * @group MediaWikiTestCaseTest
+ * @group Database
  *
  * @author Addshore
  */
@@ -173,4 +174,38 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
 
                $this->assertSame( $logger1, $logger2 );
        }
+
+       /**
+        * @covers MediaWikiTestCase::setupDatabaseWithTestPrefix
+        * @covers MediaWikiTestCase::copyTestData
+        */
+       public function testCopyTestData() {
+               $this->markTestSkippedIfDbType( 'sqlite' );
+
+               $this->tablesUsed[] = 'objectcache';
+               $this->db->insert(
+                       'objectcache',
+                       [ 'keyname' => __METHOD__, 'value' => 'TEST', 'exptime' => $this->db->timestamp( 11 ) ],
+                       __METHOD__
+               );
+
+               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               $lb = $lbFactory->newMainLB();
+               $db = $lb->getConnection( DB_REPLICA, DBO_TRX );
+
+               // sanity
+               $this->assertNotSame( $this->db, $db );
+
+               // Make sure the DB connection has the fake table clones and the fake table prefix
+               MediaWikiTestCase::setupDatabaseWithTestPrefix( $db, $this->dbPrefix(), false );
+
+               $this->assertSame( $this->db->tablePrefix(), $db->tablePrefix(), 'tablePrefix' );
+
+               // Make sure the DB connection has all the test data
+               $this->copyTestData( $this->db, $db );
+
+               $value = $db->selectField( 'objectcache', 'value', [ 'keyname' => __METHOD__ ], __METHOD__ );
+               $this->assertSame( 'TEST', $value, 'Copied Data' );
+       }
+
 }
index d6ede4f..4969a8b 100644 (file)
@@ -41,7 +41,6 @@ return [
                        'tests/qunit/suites/resources/jquery/jquery.color.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js',
-                       'tests/qunit/suites/resources/jquery/jquery.hidpi.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.highlightText.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.lengthLimit.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js',
@@ -101,7 +100,6 @@ return [
                        'jquery.color',
                        'jquery.colorUtil',
                        'jquery.getAttrs',
-                       'jquery.hidpi',
                        'jquery.highlightText',
                        'jquery.lengthLimit',
                        'jquery.makeCollapsible',
index 2238fce..9f57190 100644 (file)
@@ -77,8 +77,8 @@ mw.loader.implement( 'testUrlOrder.b', function () {} );
 
 $response = '';
 
-// Does not support the full behaviour of ResourceLoaderContext::expandModuleNames(),
-// Only supports dotless module names joined by comma,
+// Does not support the full behaviour of the real load.php.
+// This only supports dotless module names joined by comma,
 // with the exception of the hardcoded cases for testUrl*.
 if ( isset( $_GET['modules'] ) ) {
        if ( $_GET['modules'] === 'testUrlInc,testUrlIncDump|testUrlInc.a,b' ) {
diff --git a/tests/qunit/data/mediawiki.loader.getScript.example.js b/tests/qunit/data/mediawiki.loader.getScript.example.js
new file mode 100644 (file)
index 0000000..e5e4759
--- /dev/null
@@ -0,0 +1 @@
+mw.getScriptExampleScriptLoaded = true;
diff --git a/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js b/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js
deleted file mode 100644 (file)
index cb09180..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-( function () {
-       QUnit.module( 'jquery.hidpi', QUnit.newMwEnvironment() );
-
-       QUnit.test( 'devicePixelRatio', function ( assert ) {
-               var devicePixelRatio = $.devicePixelRatio();
-               assert.strictEqual( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
-       } );
-
-       QUnit.test( 'bracketedDevicePixelRatio', function ( assert ) {
-               var ratio = $.bracketedDevicePixelRatio();
-               assert.strictEqual( typeof ratio, 'number', '$.bracketedDevicePixelRatio() returns a number' );
-       } );
-
-       QUnit.test( 'bracketDevicePixelRatio', function ( assert ) {
-               assert.strictEqual( $.bracketDevicePixelRatio( 0.75 ), 1, '0.75 gives 1' );
-               assert.strictEqual( $.bracketDevicePixelRatio( 1 ), 1, '1 gives 1' );
-               assert.strictEqual( $.bracketDevicePixelRatio( 1.25 ), 1.5, '1.25 gives 1.5' );
-               assert.strictEqual( $.bracketDevicePixelRatio( 1.5 ), 1.5, '1.5 gives 1.5' );
-               assert.strictEqual( $.bracketDevicePixelRatio( 1.75 ), 2, '1.75 gives 2' );
-               assert.strictEqual( $.bracketDevicePixelRatio( 2 ), 2, '2 gives 2' );
-               assert.strictEqual( $.bracketDevicePixelRatio( 2.5 ), 2, '2.5 gives 2' );
-               assert.strictEqual( $.bracketDevicePixelRatio( 3 ), 2, '3 gives 2' );
-       } );
-
-       QUnit.test( 'matchSrcSet', function ( assert ) {
-               var srcset = 'onefive.png 1.5x, two.png 2x';
-
-               // Nice exact matches
-               assert.strictEqual( $.matchSrcSet( 1, srcset ), null, '1.0 gives no match' );
-               assert.strictEqual( $.matchSrcSet( 1.5, srcset ), 'onefive.png', '1.5 gives match' );
-               assert.strictEqual( $.matchSrcSet( 2, srcset ), 'two.png', '2 gives match' );
-
-               // Non-exact matches; should return the next-biggest specified
-               assert.strictEqual( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' );
-               assert.strictEqual( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
-               assert.strictEqual( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
-       } );
-}() );
index 458df92..aafcd5b 100644 (file)
@@ -3,7 +3,7 @@
 
        // TODO: verify checkboxes == [ 'nsassociated', 'nsinvert' ]
 
-       QUnit.test( '"all" namespace disable checkboxes', function ( assert ) {
+       QUnit.test( '"all" namespace hides checkboxes', function ( assert ) {
                var selectHtml, $env, $options,
                        rc = require( 'mediawiki.special.recentchanges' );
 
                        + '<option value="4">ProjectName</option>'
                        + '<option value="5">ProjectName talk</option>'
                        + '</select>'
+                       + '<span class="mw-input-with-label mw-input-hidden">'
                        + '<input name="invert" type="checkbox" value="1" id="nsinvert" title="no title" />'
                        + '<label for="nsinvert" title="no title">Invert selection</label>'
+                       + '</span>'
+                       + '<span class="mw-input-with-label mw-input-hidden">'
                        + '<input name="associated" type="checkbox" value="1" id="nsassociated" title="no title" />'
                        + '<label for="nsassociated" title="no title">Associated namespace</label>'
+                       + '</span>'
                        + '<input type="submit" value="Go" />'
                        + '<input type="hidden" value="Special:RecentChanges" name="title" />';
 
 
                // TODO abstract the double strictEquals
 
-               // At first checkboxes are enabled
-               assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), false );
-               assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
+               // At first checkboxes are hidden
+               assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
+               assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
 
                // Initiate the recentchanges module
                rc.init();
 
                // By default
-               assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), true );
-               assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), true );
+               assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
+               assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
 
                // select second option...
                $options = $( '#namespace' ).find( 'option' );
                $options.eq( 1 ).prop( 'selected', true );
                $( '#namespace' ).trigger( 'change' );
 
-               // ... and checkboxes should be enabled again
-               assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), false );
-               assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
+               // ... and checkboxes should be visible again
+               assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), false );
+               assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), false );
 
                // select first option ( 'all' namespace)...
                $options.eq( 1 ).removeProp( 'selected' );
                $options.eq( 0 ).prop( 'selected', true );
                $( '#namespace' ).trigger( 'change' );
 
-               // ... and checkboxes should now be disabled
-               assert.strictEqual( $( '#nsinvert' ).prop( 'disabled' ), true );
-               assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), true );
+               // ... and checkboxes should now be hidden
+               assert.strictEqual( $( '#nsinvert' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
+               assert.strictEqual( $( '#nsassociated' ).closest( '.mw-input-with-label' ).hasClass( 'mw-input-hidden' ), true );
 
                // DOM cleanup
                $env.remove();
index 4606cbd..b3f04b7 100644 (file)
@@ -2,23 +2,31 @@
 
        var NOW = 9012, // miliseconds
                DEFAULT_DURATION = 5678, // seconds
+               jqcookie,
+               defaults = {
+                       prefix: 'mywiki',
+                       domain: 'example.org',
+                       path: '/path',
+                       expires: DEFAULT_DURATION,
+                       secure: false
+               },
+               setDefaults = require( 'mediawiki.cookie' ).setDefaults,
                expiryDate = new Date();
 
        expiryDate.setTime( NOW + ( DEFAULT_DURATION * 1000 ) );
 
-       QUnit.module( 'mediawiki.cookie', QUnit.newMwEnvironment( {
-               setup: function () {
-                       this.stub( $, 'cookie' ).returns( null );
-
-                       this.sandbox.useFakeTimers( NOW );
+       QUnit.module( 'mediawiki.cookie', {
+               beforeEach: function () {
+                       jqcookie = sinon.stub( $, 'cookie' ).returns( null );
+                       this.clock = sinon.useFakeTimers( NOW );
+                       this.savedDefaults = setDefaults( defaults );
                },
-               config: {
-                       wgCookiePrefix: 'mywiki',
-                       wgCookieDomain: 'example.org',
-                       wgCookiePath: '/path',
-                       wgCookieExpiration: DEFAULT_DURATION
+               afterEach: function () {
+                       jqcookie.restore();
+                       this.clock.restore();
+                       setDefaults( this.savedDefaults );
                }
-       } ) );
+       } );
 
        QUnit.test( 'set( key, value )', function ( assert ) {
                var call;
@@ -26,7 +34,7 @@
                // Simple case
                mw.cookie.set( 'foo', 'bar' );
 
-               call = $.cookie.lastCall.args;
+               call = jqcookie.lastCall.args;
                assert.strictEqual( call[ 0 ], 'mywikifoo' );
                assert.strictEqual( call[ 1 ], 'bar' );
                assert.deepEqual( call[ 2 ], {
                } );
 
                mw.cookie.set( 'foo', null );
-               call = $.cookie.lastCall.args;
+               call = jqcookie.lastCall.args;
                assert.strictEqual( call[ 1 ], null, 'null removes cookie' );
 
                mw.cookie.set( 'foo', undefined );
-               call = $.cookie.lastCall.args;
+               call = jqcookie.lastCall.args;
                assert.strictEqual( call[ 1 ], 'undefined', 'undefined is value' );
 
                mw.cookie.set( 'foo', false );
-               call = $.cookie.lastCall.args;
+               call = jqcookie.lastCall.args;
                assert.strictEqual( call[ 1 ], 'false', 'false is a value' );
 
                mw.cookie.set( 'foo', 0 );
-               call = $.cookie.lastCall.args;
+               call = jqcookie.lastCall.args;
                assert.strictEqual( call[ 1 ], '0', '0 is value' );
        } );
 
                date.setTime( 1234 );
 
                mw.cookie.set( 'foo', 'bar' );
-               options = $.cookie.lastCall.args[ 2 ];
+               options = jqcookie.lastCall.args[ 2 ];
                assert.deepEqual( options.expires, expiryDate, 'default expiration' );
 
                mw.cookie.set( 'foo', 'bar', date );
-               options = $.cookie.lastCall.args[ 2 ];
+               options = jqcookie.lastCall.args[ 2 ];
                assert.strictEqual( options.expires, date, 'custom expiration as Date' );
 
                date = new Date();
                date.setDate( date.getDate() + 1 );
 
                mw.cookie.set( 'foo', 'bar', 86400 );
-               options = $.cookie.lastCall.args[ 2 ];
+               options = jqcookie.lastCall.args[ 2 ];
                assert.deepEqual( options.expires, date, 'custom expiration as lifetime in seconds' );
 
                mw.cookie.set( 'foo', 'bar', null );
-               options = $.cookie.lastCall.args[ 2 ];
+               options = jqcookie.lastCall.args[ 2 ];
                assert.strictEqual( options.expires, undefined, 'null forces session cookie' );
 
-               // Per DefaultSettings.php, when wgCookieExpiration is 0, the default should
-               // be session cookies
-               mw.config.set( 'wgCookieExpiration', 0 );
+               // Per DefaultSettings.php, if wgCookieExpiration is 0,
+               // then the default should be session cookies
+               setDefaults( $.extend( {}, defaults, { expires: 0 } ) );
 
                mw.cookie.set( 'foo', 'bar' );
-               options = $.cookie.lastCall.args[ 2 ];
+               options = jqcookie.lastCall.args[ 2 ];
                assert.strictEqual( options.expires, undefined, 'wgCookieExpiration=0 results in session cookies by default' );
 
                mw.cookie.set( 'foo', 'bar', date );
-               options = $.cookie.lastCall.args[ 2 ];
+               options = jqcookie.lastCall.args[ 2 ];
                assert.strictEqual( options.expires, date, 'custom expiration (with wgCookieExpiration=0)' );
        } );
 
                        secure: true
                } );
 
-               call = $.cookie.lastCall.args;
+               call = jqcookie.lastCall.args;
                assert.strictEqual( call[ 0 ], 'myPrefixfoo' );
                assert.deepEqual( call[ 2 ], {
                        expires: expiryDate,
                        secure: true
                } );
 
-               call = $.cookie.lastCall.args;
+               call = jqcookie.lastCall.args;
                assert.strictEqual( call[ 0 ], 'myPrefixfoo' );
                assert.deepEqual( call[ 2 ], {
                        expires: date,
 
                mw.cookie.get( 'foo' );
 
-               key = $.cookie.lastCall.args[ 0 ];
+               key = jqcookie.lastCall.args[ 0 ];
                assert.strictEqual( key, 'mywikifoo', 'Default prefix' );
 
                mw.cookie.get( 'foo', undefined );
-               key = $.cookie.lastCall.args[ 0 ];
+               key = jqcookie.lastCall.args[ 0 ];
                assert.strictEqual( key, 'mywikifoo', 'Use default prefix for undefined' );
 
                mw.cookie.get( 'foo', null );
-               key = $.cookie.lastCall.args[ 0 ];
+               key = jqcookie.lastCall.args[ 0 ];
                assert.strictEqual( key, 'mywikifoo', 'Use default prefix for null' );
 
                mw.cookie.get( 'foo', '' );
-               key = $.cookie.lastCall.args[ 0 ];
+               key = jqcookie.lastCall.args[ 0 ];
                assert.strictEqual( key, 'foo', 'Don\'t use default prefix for empty string' );
 
                value = mw.cookie.get( 'foo' );
        QUnit.test( 'get( key ) - with value', function ( assert ) {
                var value;
 
-               $.cookie.returns( 'bar' );
+               jqcookie.returns( 'bar' );
 
                value = mw.cookie.get( 'foo' );
                assert.strictEqual( value, 'bar', 'Return value of cookie' );
 
                mw.cookie.get( 'foo', 'bar' );
 
-               key = $.cookie.lastCall.args[ 0 ];
+               key = jqcookie.lastCall.args[ 0 ];
                assert.strictEqual( key, 'barfoo' );
        } );
 
index cb028a9..ed1288b 100644 (file)
@@ -15,6 +15,7 @@
                        };
                },
                teardown: function () {
+                       mw.loader.maxQueryLength = 2000;
                        // Teardown for StringSet shim test
                        if ( this.nativeSet ) {
                                window.Set = this.nativeSet;
@@ -24,6 +25,7 @@
                        // exposed for cross-file mocks.
                        delete mw.loader.testCallback;
                        delete mw.loader.testFail;
+                       delete mw.getScriptExampleScriptLoaded;
                }
        } ) );
 
                assert.deepEqual(
                        [ {
                                topic: 'resourceloader.exception',
-                               error: 'Unknown dependency: test.load.unreg',
+                               error: 'Unknown module: test.load.unreg',
                                source: 'resolve'
                        } ],
                        capture
                assert.deepEqual(
                        [ {
                                topic: 'resourceloader.exception',
-                               error: 'Unknown dependency: test.load.missingdep2',
+                               error: 'Unknown module: test.load.missingdep2',
                                source: 'resolve'
                        } ],
                        capture
 
        QUnit.test( '.implement( package files )', function ( assert ) {
                var done = assert.async(),
-                       initJsRan = false;
+                       initJsRan = false,
+                       counter = 41;
                mw.loader.implement(
                        'test.implement.packageFiles',
                        {
                                files: {
                                        'resources/src/foo/data/hello.json': { hello: 'world' },
                                        'resources/src/foo/foo.js': function ( require, module ) {
-                                               window.mwTestFooJsCounter = window.mwTestFooJsCounter || 41;
-                                               window.mwTestFooJsCounter++;
-                                               module.exports = { answer: window.mwTestFooJsCounter };
+                                               counter++;
+                                               module.exports = { answer: counter };
                                        },
                                        'resources/src/bar/bar.js': function ( require, module ) {
                                                var core = require( './core.js' );
                        [ 'testUrlIncDump', 'dump', [], null, 'testloader' ]
                ] );
 
-               mw.config.set( 'wgResourceLoaderMaxQueryLength', 10 );
+               mw.loader.maxQueryLength = 10;
 
                return mw.loader.using( [ 'testUrlIncDump', 'testUrlInc' ] ).then( function ( require ) {
                        assert.propEqual(
                } );
        } );
 
+       QUnit.test( '.getScript() - success', function ( assert ) {
+               var scriptUrl = QUnit.fixurl(
+                       mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/mediawiki.loader.getScript.example.js'
+               );
+
+               return mw.loader.getScript( scriptUrl ).then(
+                       function () {
+                               assert.strictEqual( mw.getScriptExampleScriptLoaded, true, 'Data attached to a global object is available' );
+                       }
+               );
+       } );
+
+       QUnit.test( '.getScript() - failure', function ( assert ) {
+               assert.rejects(
+                       mw.loader.getScript( 'https://example.test/not-found' ),
+                       /Failed to load script/,
+                       'Descriptive error message'
+               );
+       } );
+
 }() );
index 1e35211..2487672 100644 (file)
@@ -2,6 +2,7 @@
        QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment( {
                setup: function () {
                        this.server = this.sandbox.useFakeServer();
+                       this.server.respondImmediately = true;
                        // Cannot stub by simple assignment because read-only.
                        // Instead, stub in tests by using 'delete', and re-create
                        // in teardown using the original descriptor (including its
                assert.strictEqual( mw.user.id(), 'John', 'user.id()' );
        } );
 
-       QUnit.test( 'getUserInfo', function ( assert ) {
+       QUnit.test( 'getGroups (callback)', function ( assert ) {
+               var done = assert.async();
                mw.config.set( 'wgUserGroups', [ '*', 'user' ] );
 
                mw.user.getGroups( function ( groups ) {
                        assert.deepEqual( groups, [ '*', 'user' ], 'Result' );
+                       done();
                } );
+       } );
+
+       QUnit.test( 'getGroups (Promise)', function ( assert ) {
+               mw.config.set( 'wgUserGroups', [ '*', 'user' ] );
+
+               return mw.user.getGroups().then( function ( groups ) {
+                       assert.deepEqual( groups, [ '*', 'user' ], 'Result' );
+               } );
+       } );
+
+       QUnit.test( 'getRights (callback)', function ( assert ) {
+               var done = assert.async();
+
+               this.server.respond( [ 200, { 'Content-Type': 'application/json' },
+                       '{ "query": { "userinfo": { "groups": [ "unused" ], "rights": [ "read", "edit", "createtalk" ] } } }'
+               ] );
 
                mw.user.getRights( function ( rights ) {
                        assert.deepEqual( rights, [ 'read', 'edit', 'createtalk' ], 'Result (callback)' );
+                       done();
                } );
+       } );
 
-               mw.user.getRights().done( function ( rights ) {
-                       assert.deepEqual( rights, [ 'read', 'edit', 'createtalk' ], 'Result (promise)' );
-               } );
+       QUnit.test( 'getRights (Promise)', function ( assert ) {
+               this.server.respond( [ 200, { 'Content-Type': 'application/json' },
+                       '{ "query": { "userinfo": { "groups": [ "unused" ], "rights": [ "read", "edit", "createtalk" ] } } }'
+               ] );
 
-               this.server.respondWith( /meta=userinfo/, function ( request ) {
-                       request.respond( 200, { 'Content-Type': 'application/json' },
-                               '{ "query": { "userinfo": { "groups": [ "unused" ], "rights": [ "read", "edit", "createtalk" ] } } }'
-                       );
+               return mw.user.getRights().then( function ( rights ) {
+                       assert.deepEqual( rights, [ 'read', 'edit', 'createtalk' ], 'Result (promise)' );
                } );
-
-               this.server.respond();
        } );
 
        QUnit.test( 'generateRandomSessionId', function ( assert ) {
index 38cd062..dd766c8 100644 (file)
@@ -7,7 +7,8 @@
                "mocha": true
        },
        "globals": {
-               "browser": false
+               "browser": false,
+               "mw": false
        },
        "rules": {
                "no-console": 0
index acaf3ea..da5e909 100644 (file)
@@ -1,11 +1,43 @@
-const Page = require( 'wdio-mediawiki/Page' );
+const Page = require( 'wdio-mediawiki/Page' ),
+       Api = require( 'wdio-mediawiki/Api' );
 
 class HistoryPage extends Page {
+       get heading() { return browser.element( '#firstHeading' ); }
+       get headingText() { return browser.getText( '#firstHeading' ); }
        get comment() { return browser.element( '#pagehistory .comment' ); }
+       get rollback() { return browser.element( '.mw-rollback-link' ); }
+       get rollbackLink() { return browser.element( '.mw-rollback-link a' ); }
+       get rollbackConfirmable() { return browser.element( '.mw-rollback-link .jquery-confirmable-text' ); }
+       get rollbackConfirmableYes() { return browser.element( '.mw-rollback-link .jquery-confirmable-button-yes' ); }
+       get rollbackConfirmableNo() { return browser.element( '.mw-rollback-link .jquery-confirmable-button-no' ); }
+       get rollbackNonJsConfirmable() { return browser.element( '.mw-htmlform .oo-ui-fieldsetLayout-header .oo-ui-labelElement-label' ); }
+       get rollbackNonJsConfirmableYes() { return browser.element( '.mw-htmlform .mw-htmlform-submit-buttons button' ); }
 
        open( title ) {
                super.openTitle( title, { action: 'history' } );
        }
+
+       vandalizePage( name, content ) {
+               let vandalUsername = 'Evil_' + browser.options.username;
+
+               browser.call( function () {
+                       return Api.edit( name, content );
+               } );
+
+               browser.call( function () {
+                       return Api.createAccount(
+                               vandalUsername, browser.options.password
+                       );
+               } );
+
+               browser.call( function () {
+                       Api.edit(
+                               name,
+                               'Vandalized: ' + content,
+                               vandalUsername
+                       );
+               } );
+       }
 }
 
 module.exports = new HistoryPage();
index 3b24298..4604ca3 100644 (file)
@@ -5,7 +5,7 @@ const assert = require( 'assert' ),
        EditPage = require( '../pageobjects/edit.page' ),
        HistoryPage = require( '../pageobjects/history.page' ),
        UndoPage = require( '../pageobjects/undo.page' ),
-       UserLoginPage = require( '../pageobjects/userlogin.page' ),
+       UserLoginPage = require( 'wdio-mediawiki/LoginPage' ),
        Util = require( 'wdio-mediawiki/Util' );
 
 describe( 'Page', function () {
@@ -80,7 +80,7 @@ describe( 'Page', function () {
 
                // check
                assert.strictEqual( EditPage.heading.getText(), name );
-               assert.strictEqual( EditPage.displayedContent.getText(), editContent );
+               assert( EditPage.displayedContent.getText().match( new RegExp( editContent ) ) );
        } );
 
        it( 'should have history @daily', function () {
@@ -91,7 +91,7 @@ describe( 'Page', function () {
 
                // check
                HistoryPage.open( name );
-               assert.strictEqual( HistoryPage.comment.getText(), `(Created page with "${content}")` );
+               assert.strictEqual( HistoryPage.comment.getText(), `Created or updated page with "${content}"` );
        } );
 
        it( 'should be deletable', function () {
diff --git a/tests/selenium/specs/rollback.js b/tests/selenium/specs/rollback.js
new file mode 100644 (file)
index 0000000..648e52f
--- /dev/null
@@ -0,0 +1,145 @@
+const assert = require( 'assert' ),
+       HistoryPage = require( '../pageobjects/history.page' ),
+       UserLoginPage = require( 'wdio-mediawiki/LoginPage' ),
+       Util = require( 'wdio-mediawiki/Util' );
+
+describe( 'Rollback with confirmation', function () {
+       var content,
+               name;
+
+       before( function () {
+               // disable VisualEditor welcome dialog
+               browser.deleteCookie();
+               UserLoginPage.open();
+               browser.localStorage( 'POST', { key: 've-beta-welcome-dialog', value: '1' } );
+
+               // Enable rollback confirmation for admin user
+               // Requires user to log in again, handled by deleteCookie() call in beforeEach function
+               UserLoginPage.loginAdmin();
+
+               browser.pause( 300 );
+               browser.execute( function () {
+                       return ( new mw.Api() ).saveOption(
+                               'showrollbackconfirmation',
+                               '1'
+                       );
+               } );
+       } );
+
+       beforeEach( function () {
+               browser.deleteCookie();
+
+               content = Util.getTestString( 'beforeEach-content-' );
+               name = Util.getTestString( 'BeforeEach-name-' );
+
+               HistoryPage.vandalizePage( name, content );
+
+               UserLoginPage.loginAdmin();
+               HistoryPage.open( name );
+       } );
+
+       it( 'should offer rollback options for admin users', function () {
+               assert.strictEqual( HistoryPage.rollback.getText(), 'rollback 1 edit' );
+
+               HistoryPage.rollback.click();
+
+               assert.strictEqual( HistoryPage.rollbackConfirmable.getText(), 'Please confirm:' );
+               assert.strictEqual( HistoryPage.rollbackConfirmableYes.getText(), 'Rollback' );
+               assert.strictEqual( HistoryPage.rollbackConfirmableNo.getText(), 'Cancel' );
+       } );
+
+       it( 'should offer a way to cancel rollbacks', function () {
+               HistoryPage.rollback.click();
+
+               browser.pause( 300 );
+
+               HistoryPage.rollbackConfirmableNo.click();
+
+               browser.pause( 500 );
+
+               assert.strictEqual( HistoryPage.heading.getText(), 'Revision history of "' + name + '"' );
+       } );
+
+       it( 'should perform rollbacks after confirming intention', function () {
+               HistoryPage.rollback.click();
+
+               browser.pause( 300 );
+
+               HistoryPage.rollbackConfirmableYes.click();
+
+               // waitUntil indirectly asserts that the content we are looking for is present
+               browser.waitUntil( function () {
+                       return browser.getText( '#firstHeading' ) === 'Action complete';
+               }, 5000, 'Expected rollback page to appear.' );
+       } );
+
+       it( 'should verify rollbacks via GET requests are confirmed on a follow-up page', function () {
+               var rollbackActionUrl = HistoryPage.rollbackLink.getAttribute( 'href' );
+               browser.url( rollbackActionUrl );
+
+               browser.waitUntil( function () {
+                       return HistoryPage.rollbackNonJsConfirmable.getText() === 'Revert edits to this page?';
+               }, 5000, 'Expected rollback confirmation page to appear for GET-based rollbacks.' );
+
+               HistoryPage.rollbackNonJsConfirmableYes.click();
+
+               browser.waitUntil( function () {
+                       return browser.getText( '#firstHeading' ) === 'Action complete';
+               }, 5000, 'Expected rollback page to appear.' );
+       } );
+
+} );
+
+describe( 'Rollback without confirmation', function () {
+       var content,
+               name;
+
+       before( function () {
+               // disable VisualEditor welcome dialog
+               browser.deleteCookie();
+               UserLoginPage.open();
+               browser.localStorage( 'POST', { key: 've-beta-welcome-dialog', value: '1' } );
+
+               // Disable rollback confirmation for admin user
+               // Requires user to log in again, handled by deleteCookie() call in beforeEach function
+               UserLoginPage.loginAdmin();
+
+               browser.pause( 300 );
+               browser.execute( function () {
+                       return ( new mw.Api() ).saveOption(
+                               'showrollbackconfirmation',
+                               '0'
+                       );
+               } );
+       } );
+
+       beforeEach( function () {
+               browser.deleteCookie();
+
+               content = Util.getTestString( 'beforeEach-content-' );
+               name = Util.getTestString( 'BeforeEach-name-' );
+
+               HistoryPage.vandalizePage( name, content );
+
+               UserLoginPage.loginAdmin();
+               HistoryPage.open( name );
+       } );
+
+       it( 'should perform rollback via POST request without asking the user to confirm', function () {
+               HistoryPage.rollback.click();
+
+               // waitUntil indirectly asserts that the content we are looking for is present
+               browser.waitUntil( function () {
+                       return HistoryPage.headingText === 'Action complete';
+               }, 5000, 'Expected rollback page to appear.' );
+       } );
+
+       it( 'should perform rollback via GET request without asking the user to confirm', function () {
+               var rollbackActionUrl = HistoryPage.rollbackLink.getAttribute( 'href' );
+               browser.url( rollbackActionUrl );
+
+               browser.waitUntil( function () {
+                       return browser.getText( '#firstHeading' ) === 'Action complete';
+               }, 5000, 'Expected rollback page to appear.' );
+       } );
+} );
index f68fee9..7947ff5 100644 (file)
@@ -5,22 +5,31 @@ const MWBot = require( 'mwbot' );
 module.exports = {
        /**
         * Shortcut for `MWBot#edit( .. )`.
+        * Default username, password and base URL is used unless specified
         *
         * @since 1.0.0
         * @see <https://www.mediawiki.org/wiki/API:Edit>
         * @param {string} title
         * @param {string} content
+        * @param {string} username - Optional
+        * @param {string} password - Optional
+        * @param {baseUrl} baseUrl - Optional
         * @return {Object} Promise for API action=edit response data.
         */
-       edit( title, content ) {
+       edit( title,
+               content,
+               username = browser.options.username,
+               password = browser.options.password,
+               baseUrl = browser.options.baseUrl
+       ) {
                let bot = new MWBot();
 
                return bot.loginGetEditToken( {
-                       apiUrl: `${browser.options.baseUrl}/api.php`,
-                       username: browser.options.username,
-                       password: browser.options.password
+                       apiUrl: `${baseUrl}/api.php`,
+                       username: username,
+                       password: password
                } ).then( function () {
-                       return bot.edit( title, content, `Created page with "${content}"` );
+                       return bot.edit( title, content, `Created or updated page with "${content}"` );
                } );
        },